48#ifdef USB11_MASS_STORAGE
69#define USBMASS_CBI_PROTOCOL 0
70#define USBMASS_CBI_NOCOMPLETE_PROTOCOL 1
71#define USBMASS_BULKONLY_PROTOCOL 0x50
73#define USBMASS_SUBCLASS_RBC 0x01
74#define USBMASS_SUBCLASS_SFF8020 0x02
75#define USBMASS_SUBCLASS_QIC157 0x03
76#define USBMASS_SUBCLASS_UFI 0x04
77#define USBMASS_SUBCLASS_SFF8070 0x05
78#define USBMASS_SUBCLASS_SCSI 0x06
80#define USBMASS_CSW_PASS 0x00
81#define USBMASS_CSW_FAILED 0x01
82#define USBMASS_CSW_PHASEERR 0x02
84#define USBMASS_CBW_SIGNATURE 0x43425355
85#define USBMASS_CSW_SIGNATURE 0x53425355
91typedef struct usbmass_cbw_s {
92 uint8_t dCBWSignature0,dCBWSignature1,dCBWSignature2,dCBWSignature3;
93 uint8_t dCBWTag0,dCBWTag1,dCBWTag2,dCBWTag3;
94 uint8_t dCBWDataTransferLength0,dCBWDataTransferLength1,
95 dCBWDataTransferLength2,dCBWDataTransferLength3;
102typedef struct usbmass_csw_s {
103 uint8_t dCSWSignature0,dCSWSignature1,dCSWSignature2,dCSWSignature3;
104 uint8_t dCSWTag0,dCSWTag1,dCSWTag2,dCSWTag3;
105 uint8_t dCSWDataResidue0,dCSWDataResidue1,dCSWDataResidue2,dCSWDataResidue3;
109#define GETCBWFIELD(s,f) ((uint32_t)((s)->f##0) | ((uint32_t)((s)->f##1) << 8) | \
110 ((uint32_t)((s)->f##2) << 16) | ((uint32_t)((s)->f##3) << 24))
111#define PUTCBWFIELD(s,f,v) (s)->f##0 = (v & 0xFF); \
112 (s)->f##1 = ((v)>>8 & 0xFF); \
113 (s)->f##2 = ((v)>>16 & 0xFF); \
114 (s)->f##3 = ((v)>>24 & 0xFF);
117int usbmass_request_sense(
usbdev_t *dev);
126#define MAX_SECTORSIZE 2048
127typedef struct usbdisk_s {
141static int usbmass_detach(
usbdev_t *dev);
147typedef struct usbmass_softc_s {
158 "Mass-Storage Device",
178#define usbmass_mass_storage_reset(dev,ifc) \
179 usb_simple_request(dev,0x21,0xFF,ifc,0)
195static int usbmass_get_max_lun(
usbdev_t *dev,
int *lunp)
202 if (res < 0)
return res;
204 if (lunp) *lunp = (int) buf;
223static void usbmass_stall_recovery(
usbdev_t *dev)
225 usbmass_softc_t *softc;
231 usbmass_request_sense(dev);
249int usbmass_request_sense(
usbdev_t *dev)
255 usbmass_softc_t *softc;
265 cbw = (usbmass_cbw_t *) cbwcsw;
266 csw = (usbmass_csw_t *) cbwcsw;
272 PUTCBWFIELD(cbw,dCBWSignature,USBMASS_CBW_SIGNATURE);
273 PUTCBWFIELD(cbw,dCBWTag,softc->umass_curtag);
274 PUTCBWFIELD(cbw,dCBWDataTransferLength,18);
275 cbw->bmCBWFlags = 0x80;
277 cbw->bCBWCBLength = 12;
289 softc->umass_curtag++;
310 memset(csw,0,
sizeof(usbmass_csw_t));
350 usbmass_softc_t *softc;
355 sector = (
uint8_t *) HSADDR2PTR(buffer);
357 cbw = (usbmass_cbw_t *)
KMALLOC(
sizeof(usbmass_cbw_t),32);
358 csw = (usbmass_csw_t *)
KMALLOC(
sizeof(usbmass_csw_t),32);
364 PUTCBWFIELD(cbw,dCBWSignature,USBMASS_CBW_SIGNATURE);
365 PUTCBWFIELD(cbw,dCBWTag,softc->umass_curtag);
366 PUTCBWFIELD(cbw,dCBWDataTransferLength,(512*seccnt));
367 cbw->bmCBWFlags = 0x80;
369 cbw->bCBWCBLength = 10;
370 cbw->CBWCB[0] = 0x28;
372 cbw->CBWCB[2] = (sectornum >> 24) & 0xFF;
373 cbw->CBWCB[3] = (sectornum >> 16) & 0xFF;
374 cbw->CBWCB[4] = (sectornum >> 8) & 0xFF;
375 cbw->CBWCB[5] = (sectornum >> 0) & 0xFF;
378 cbw->CBWCB[8] = seccnt;
381 softc->umass_curtag++;
405 memset(csw,0,
sizeof(usbmass_csw_t));
414 usbmass_stall_recovery(dev);
423 usbmass_stall_recovery(dev);
432 usbmass_stall_recovery(dev);
439 printf(
"CSW: Signature=%08X Tag=%08X Residue=%08X Status=%02X\n",
440 GETCBWFIELD(csw,dCSWSignature),
441 GETCBWFIELD(csw,dCSWTag),
442 GETCBWFIELD(csw,dCSWDataResidue),
446 res = (csw->bCSWStatus == USBMASS_CSW_PASS) ? 0 : -1;
477 usbmass_softc_t *softc;
483 sector = (
uint8_t *) HSADDR2PTR(buffer);
485 cbw = (usbmass_cbw_t *) cbwcsw;
486 csw = (usbmass_csw_t *) cbwcsw;
492 PUTCBWFIELD(cbw,dCBWSignature,USBMASS_CBW_SIGNATURE);
493 PUTCBWFIELD(cbw,dCBWTag,softc->umass_curtag);
494 PUTCBWFIELD(cbw,dCBWDataTransferLength,(512*seccnt));
495 cbw->bmCBWFlags = 0x00;
497 cbw->bCBWCBLength = 10;
498 cbw->CBWCB[0] = 0x2A;
500 cbw->CBWCB[2] = (sectornum >> 24) & 0xFF;
501 cbw->CBWCB[3] = (sectornum >> 16) & 0xFF;
502 cbw->CBWCB[4] = (sectornum >> 8) & 0xFF;
503 cbw->CBWCB[5] = (sectornum >> 0) & 0xFF;
506 cbw->CBWCB[8] = seccnt;
509 softc->umass_curtag++;
529 memset(csw,0,
sizeof(usbmass_csw_t));
534 printf(
"CSW: Signature=%08X Tag=%08X Residue=%08X Status=%02X\n",
535 GETCBWFIELD(csw,dCSWSignature),
536 GETCBWFIELD(csw,dCSWTag),
537 GETCBWFIELD(csw,dCSWDataResidue),
541 res = (csw->bCSWStatus == USBMASS_CSW_PASS) ? 0 : -1;
569 usbmass_softc_t *softc;
579 cbw = (usbmass_cbw_t *) cbwcsw;
580 csw = (usbmass_csw_t *) cbwcsw;
588 PUTCBWFIELD(cbw,dCBWSignature,USBMASS_CBW_SIGNATURE);
589 PUTCBWFIELD(cbw,dCBWTag,softc->umass_curtag);
590 PUTCBWFIELD(cbw,dCBWDataTransferLength,8);
591 cbw->bmCBWFlags = 0x80;
593 cbw->bCBWCBLength = 10;
594 cbw->CBWCB[0] = 0x25;
605 softc->umass_curtag++;
614 usbmass_stall_recovery(dev);
627 usbmass_stall_recovery(dev);
637 memset(csw,0,
sizeof(usbmass_csw_t));
676 usbmass_softc_t *softc;
681 softc =
KMALLOC(
sizeof(usbmass_softc_t),0);
682 memset(softc,0,
sizeof(usbmass_softc_t));
686 if (ifdscr ==
NULL) {
692 console_log(
"USBMASS: Do not understand devices with SubClass 0x%02X, Protocol 0x%02X",
698 for (idx = 0; idx < 2; idx++) {
710 if (!indscr || !outdscr) {
730 softc->umass_curtag = 0x12345678;
740 sprintf(name,
"ud%c",
'a' + num); num++; num %= 26;
763static int usbmass_detach(
usbdev_t *dev)
765 usbmass_softc_t *softc;
793#define usbdisk_sectorshift(size) (((size)==2048)?11:9)
811static void usbdisk_probe(cfe_driver_t *drv,
812 unsigned long probe_a,
unsigned long probe_b,
818 softc = (usbdisk_t *)
KMALLOC(
sizeof(usbdisk_t),0);
820 memset(softc,0,
sizeof(usbdisk_t));
822 softc->usbdisk_sectorsize = 512;
823 softc->usbdisk_devtype = BLOCK_DEVTYPE_DISK;
824 softc->usbdisk_ttlsect = 0;
825 softc->usbdisk_unit = (int)probe_a;
827 xsprintf(descr,
"USB Disk unit %d",(
int)probe_a);
829 cfe_attach(drv,softc,
NULL,descr);
848static int usbdisk_open(cfe_devctx_t *ctx)
850 usbdisk_t *softc = ctx->dev_softc;
851 usbdev_t *dev = usbdisk_units[softc->usbdisk_unit];
855 if (!dev)
return CFE_ERR_NOTREADY;
857 usbmass_request_sense(dev);
859 res = usbmass_read_capacity(dev,&
size);
860 if (res < 0)
return res;
862 softc->usbdisk_ttlsect =
size;
882static int usbdisk_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
884 usbdisk_t *softc = ctx->dev_softc;
885 usbdev_t *dev = usbdisk_units[softc->usbdisk_unit];
893 unsigned char sector[MAX_SECTORSIZE];
896 if (!dev)
return CFE_ERR_NOTREADY;
898 sectorshift = usbdisk_sectorshift(softc->usbdisk_sectorsize);
900 bptr = buffer->buf_ptr;
901 blen = buffer->buf_length;
902 offset = buffer->buf_offset;
903 numsec = (blen + softc->usbdisk_sectorsize - 1) >> sectorshift;
905 if (offset & (softc->usbdisk_sectorsize-1)) {
906 lba = (offset >> sectorshift);
908 if (res < 0)
goto out;
909 amtcopy = softc->usbdisk_sectorsize - (offset & (softc->usbdisk_sectorsize-1));
910 if (amtcopy > blen) amtcopy = blen;
911 hs_memcpy_to_hs(bptr,§or[offset & (softc->usbdisk_sectorsize-1)],amtcopy);
917 if (blen >= softc->usbdisk_sectorsize) {
920 lba = (offset >> sectorshift);
921 seccnt = (blen >> sectorshift);
924 if (res < 0)
goto out;
926 amtcopy = seccnt << sectorshift;
933 lba = (offset >> sectorshift);
935 if (res < 0)
goto out;
937 hs_memcpy_to_hs(bptr,sector,amtcopy);
944 buffer->buf_retlen = bptr - buffer->buf_ptr;
963static int usbdisk_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat)
967 inpstat->inp_status = 1;
986static int usbdisk_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
988 usbdisk_t *softc = ctx->dev_softc;
989 usbdev_t *dev = usbdisk_units[softc->usbdisk_unit];
997 unsigned char sector[MAX_SECTORSIZE];
1000 if (!dev)
return CFE_ERR_NOTREADY;
1002 sectorshift = usbdisk_sectorshift(softc->usbdisk_sectorsize);
1004 bptr = buffer->buf_ptr;
1005 blen = buffer->buf_length;
1006 offset = buffer->buf_offset;
1007 numsec = (blen + softc->usbdisk_sectorsize - 1) >> sectorshift;
1009 if (offset & (softc->usbdisk_sectorsize-1)) {
1010 lba = (offset >> sectorshift);
1012 if (res < 0)
goto out;
1013 amtcopy = softc->usbdisk_sectorsize - (offset & (softc->usbdisk_sectorsize-1));
1014 if (amtcopy > blen) amtcopy = blen;
1015 hs_memcpy_from_hs(§or[offset & (softc->usbdisk_sectorsize-1)],bptr,amtcopy);
1016 res = usbmass_write_sector(dev,
lba,1,PTR2HSADDR(sector));
1017 if (res < 0)
goto out;
1023 while (blen >= softc->usbdisk_sectorsize) {
1024 amtcopy = softc->usbdisk_sectorsize;
1025 lba = (offset >> sectorshift);
1026 res = usbmass_write_sector(dev,
lba,1,bptr);
1027 if (res < 0)
goto out;
1034 lba = (offset >> sectorshift);
1036 if (res < 0)
goto out;
1038 hs_memcpy_from_hs(sector,bptr,amtcopy);
1039 res = usbmass_write_sector(dev,
lba,1,PTR2HSADDR(sector));
1040 if (res < 0)
goto out;
1047 buffer->buf_retlen = bptr - buffer->buf_ptr;
1067static int usbdisk_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
1069 usbdisk_t *softc = ctx->dev_softc;
1071 unsigned long long linfo;
1072 blockdev_info_t devinfo;
1074 switch ((
int)buffer->buf_ioctlcmd) {
1075 case IOCTL_BLOCK_GETBLOCKSIZE:
1076 info = softc->usbdisk_sectorsize;
1077 hs_memcpy_to_hs(buffer->buf_ptr,&info,
sizeof(info));
1079 case IOCTL_BLOCK_GETTOTALBLOCKS:
1080 linfo = softc->usbdisk_ttlsect;
1081 hs_memcpy_to_hs(buffer->buf_ptr,&linfo,
sizeof(linfo));
1083 case IOCTL_BLOCK_GETDEVTYPE:
1084 devinfo.blkdev_totalblocks = softc->usbdisk_ttlsect;
1085 devinfo.blkdev_blocksize = softc->usbdisk_sectorsize;
1086 devinfo.blkdev_devtype = softc->usbdisk_devtype;
1087 hs_memcpy_to_hs(buffer->buf_ptr,&devinfo,
sizeof(devinfo));
1108static int usbdisk_close(cfe_devctx_t *ctx)
1118#define MAX_SECTOR_PER_REQUEST 8
1120int usbmass_read(
struct bdev *dev,
void *
data,
lba_t lba,
int num)
1122 char * p = (
char *)
data;
1123 usbmass_softc_t *softc = dev->ctx;
1130 if (tl>MAX_SECTOR_PER_REQUEST) tl=MAX_SECTOR_PER_REQUEST;
1143int usbmass_write(
struct bdev *dev,
const void *
data,
lba_t lba,
int num)
1145 char * p = (
char *)
data;
1146 usbmass_softc_t *softc = dev->ctx;
1153 if (tl>MAX_SECTOR_PER_REQUEST) tl=MAX_SECTOR_PER_REQUEST;
1154 if (usbmass_write_sector(softc->dev,
lba, tl, PTR2HSADDR(p)))
#define console_log(fmt, x...)
#define KMALLOC(size, align)
uint8_t bConfigurationValue
uint8_t bInterfaceSubClass
uint8_t bInterfaceProtocol
usb_config_descr_t * ud_cfgdescr
#define USB_ENDPOINT_DESCRIPTOR_TYPE
#define USB_ENDPOINT_DIR_OUT(addr)
#define USB_INTERFACE_DESCRIPTOR_TYPE
void * usb_find_cfg_descr(usbdev_t *dev, int dtype, int idx)
int usb_std_request(usbdev_t *dev, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *buffer, int length)
int usb_wait_request(usbreq_t *ur)
usbreq_t * usb_make_request(usbdev_t *dev, int epaddr, uint8_t *buf, int length, int flags)
void usb_free_request(usbreq_t *ur)
int usb_clear_stall(usbdev_t *dev, int epaddr)
int usb_queue_request(usbreq_t *ur)
int usb_set_configuration(usbdev_t *dev, int config)
int usb_make_sync_request(usbdev_t *dev, int epaddr, uint8_t *buf, int length, int flags)
int usb_open_pipe(usbdev_t *dev, usb_endpoint_descr_t *epdesc)
int usbmass_read_sector(usbdev_t *dev, uint32_t sectornum, uint32_t seccnt, uint8_t *buffer)