2 * usb_driver - USB Mass Storage Driver code
11 //#define DEBUG //comment out this line when not debugging
14 #include "usbd_macro.h"
15 #include "mass_debug.h"
16 #include "mass_common.h"
17 #include "mass_stor.h"
19 extern int *p_part_start
;
21 #define getBI32(__buf) ((((u8 *) (__buf))[3] << 0) | (((u8 *) (__buf))[2] << 8) | (((u8 *) (__buf))[1] << 16) | (((u8 *) (__buf))[0] << 24))
23 #define USB_SUBCLASS_MASS_RBC 0x01
24 #define USB_SUBCLASS_MASS_ATAPI 0x02
25 #define USB_SUBCLASS_MASS_QIC 0x03
26 #define USB_SUBCLASS_MASS_UFI 0x04
27 #define USB_SUBCLASS_MASS_SFF_8070I 0x05
28 #define USB_SUBCLASS_MASS_SCSI 0x06
30 #define USB_PROTOCOL_MASS_CBI 0x00
31 #define USB_PROTOCOL_MASS_CBI_NO_CCI 0x01
32 #define USB_PROTOCOL_MASS_BULK_ONLY 0x50
34 #define TAG_TEST_UNIT_READY 0
35 #define TAG_REQUEST_SENSE 3
36 #define TAG_INQUIRY 18
37 #define TAG_READ_CAPACITY 37
39 #define TAG_START_STOP_UNIT 33
42 #define DEVICE_DETECTED 1
43 #define DEVICE_CONFIGURED 2
45 #define CBW_TAG 0x43425355
46 #define CSW_TAG 0x53425355
48 typedef struct _cbw_packet
50 unsigned int signature
;
52 unsigned int dataTransferLength
;
53 unsigned char flags
; //80->data in, 00->out
55 unsigned char comLength
; //command data length
56 unsigned char comData
[16]; //command data
57 } cbw_packet
__attribute__((packed
));
59 static cbw_packet cbw_test_unit_ready
= {
66 { 0x00, //test unit ready operation code
68 0 ,0 ,0 ,0 , //reserved
74 static cbw_packet cbw_request_sense
= {
81 { 0x03, //request sense operation code
84 0 , //allocation length
85 0 ,0 ,0 ,0 , //reserved
90 static cbw_packet cbw_inquiry
= {
97 { 0x12, //inquiry operation code
101 0 , //inquiry reply length
102 0 ,0 ,0 ,0 , //reserved
107 static cbw_packet cbw_start_stop_unit
= {
109 -TAG_START_STOP_UNIT
,
110 0, //START_STOP_REPLY_LENGTH
114 { 0x1B, //start stop unit operation code
115 1, //lun/reserved/immed
117 1 , //reserved/LoEj/Start "Start the media and acquire the format type"
118 0 ,0 ,0 ,0 , //reserved
123 static cbw_packet cbw_read_capacity
= {
130 { 0x25, //read capacity operation code
131 0, //lun/reserved/RelAdr
134 0 ,0 , //reserved/PMI
139 static cbw_packet cbw_read_sector
= {
146 { 0x28, //read operation code
147 0, //LUN/DPO/FUA/Reserved/Reldr
150 0 ,0 , //Transfer length MSB
156 static cbw_packet cbw_write_sector
= {
163 { 0x2A, //write operation code
164 0, //LUN/DPO/FUA/Reserved/Reldr
167 0 ,0 , //Transfer length MSB
173 typedef struct _csw_packet
175 unsigned int signature
;
177 unsigned int dataResidue
;
178 unsigned char status
;
179 } csw_packet
__attribute__((packed
));
181 typedef struct _inquiry_data
183 u8 peripheral_device_type
; // 00h - Direct access (Floppy), 1Fh none (no FDD connected)
184 u8 removable_media
; // 80h - removeable
186 u8 repsonse_data_format
;
187 u8 additional_length
;
192 } inquiry_data
__attribute__((packed
));
194 typedef struct _sense_data
205 } sense_data
__attribute__((packed
));
207 typedef struct _read_capacity_data
211 } read_capacity_data
__attribute__((packed
));
213 static UsbDriver driver
;
215 //volatile int wait_for_connect = 1;
222 #define WAITIOSEMA(x) WaitSema(x)
223 #define SIGNALIOSEMA(x) SignalSema(x)
225 #define WAITIOSEMA(x)
226 #define SIGNALIOSEMA(x)
229 typedef struct _usb_callback_data
235 static mass_dev g_mass_device
;
243 static struct MSStoDSS_t gMSStoDSS
[4] = {
250 static int gShiftPos
;
252 static u8 _4K_buf
[4096] __attribute__((aligned(64)));
255 extern unsigned int ReadPos
;
257 static void usb_callback(int resultCode
, int bytes
, void *arg
)
259 usb_callback_data
* data
= (usb_callback_data
*) arg
;
260 data
->returnCode
= resultCode
;
261 data
->returnSize
= bytes
;
262 XPRINTF("mass_driver: callback: res %d, bytes %d, arg %p \n", resultCode
, bytes
, arg
);
266 static void usb_set_configuration(mass_dev
* dev
, int configNumber
)
269 usb_callback_data cb_data
;
271 XPRINTF("mass_driver: setting configuration controlEp=%i, confNum=%i \n", dev
->controlEp
, configNumber
);
272 ret
= UsbSetDeviceConfiguration(dev
->controlEp
, configNumber
, usb_callback
, (void*)&cb_data
);
274 if (ret
!= USB_RC_OK
) {
275 XPRINTF("mass_driver: Error - sending set_configuration %d\n", ret
);
281 static void usb_set_interface(mass_dev
* dev
, int interface
, int altSetting
)
284 usb_callback_data cb_data
;
286 XPRINTF("mass_driver: setting interface controlEp=%i, interface=%i altSetting=%i\n", dev
->controlEp
, interface
, altSetting
);
287 ret
= UsbSetInterface(dev
->controlEp
, interface
, altSetting
, usb_callback
, (void*)&cb_data
);
289 if (ret
!= USB_RC_OK
) {
290 XPRINTF("mass_driver: Error - sending set_interface %d\n", ret
);
296 static void usb_bulk_clear_halt(mass_dev
* dev
, int direction
)
298 register int ret
, endpoint
;
299 usb_callback_data cb_data
;
301 if (direction
== 0) {
302 endpoint
= dev
->bulkEpIAddr
;
303 //endpoint = dev->bulkEpI;
305 endpoint
= dev
->bulkEpOAddr
;
308 ret
= UsbClearEndpointFeature(
309 dev
->controlEp
, //Config pipe
316 if (ret
!= USB_RC_OK
) {
317 XPRINTF("mass_driver: Error - sending clear halt %d\n", ret
);
323 static void usb_bulk_reset(mass_dev
* dev
, int mode
)
326 usb_callback_data cb_data
;
328 //Call Bulk only mass storage reset
329 ret
= UsbControlTransfer(
330 dev
->controlEp
, //default pipe
334 dev
->interfaceNumber
, //interface number
341 if (ret
!= USB_RC_OK
) {
342 XPRINTF("mass_driver: Error - sending reset %d\n", ret
);
346 //clear bulk-in endpoint
348 usb_bulk_clear_halt(dev
, 0);
351 //clear bulk-out endpoint
353 usb_bulk_clear_halt(dev
, 1);
358 static int usb_bulk_status(mass_dev
* dev
, csw_packet
* csw
, int tag
)
361 usb_callback_data cb_data
;
363 csw
->signature
= CSW_TAG
;
365 csw
->dataResidue
= 0;
368 ret
= UsbBulkTransfer(
369 dev
->bulkEpI
, //bulk input pipe
376 if (ret
!= USB_RC_OK
) {
377 XPRINTF("mass_driver: Error - sending bulk status %d\n", ret
);
381 if (cb_data
.returnSize
!= 13)
382 XPRINTF("mass_driver: bulk csw.status returnSize: %i\n", cb_data
.returnSize
);
383 if (csw
->dataResidue
!= 0)
384 XPRINTF("mass_driver: bulk csw.status residue: %i\n", csw
->dataResidue
);
385 XPRINTF("mass_driver: bulk csw.status: %i\n", csw
->status
);
391 /* see flow chart in the usbmassbulk_10.pdf doc (page 15) */
392 int usb_bulk_manage_status(mass_dev
* dev
, int tag
)
397 //XPRINTF("mass_driver: usb_bulk_manage_status 1 ...\n");
398 ret
= usb_bulk_status(dev
, &csw
, tag
); /* Attempt to read CSW from bulk in endpoint */
399 if (ret
< 0) { /* STALL bulk in -OR- Bulk error */
400 usb_bulk_clear_halt(dev
, 0); /* clear the stall condition for bulk in */
402 XPRINTF("mass_driver: usb_bulk_manage_status stall ...\n");
403 ret
= usb_bulk_status(dev
, &csw
, tag
); /* Attempt to read CSW from bulk in endpoint */
406 /* CSW not valid or stalled or phase error */
407 if (csw
.signature
!= CSW_TAG
|| csw
.tag
!= tag
|| ret
== 2) {
408 XPRINTF("mass_driver: usb_bulk_manage_status call reset recovery ...\n");
409 usb_bulk_reset(dev
, 3); /* Perform reset recovery */
415 static int usb_bulk_get_max_lun(mass_dev
* dev
)
418 usb_callback_data cb_data
;
421 //Call Bulk only mass storage reset
422 ret
= UsbControlTransfer(
423 dev
->controlEp
, //default pipe
427 dev
->interfaceNumber
, //interface number
434 if (ret
!= USB_RC_OK
) {
435 XPRINTF("mass_driver: Error - get_max_lun %d\n", ret
);
444 static void usb_bulk_command(mass_dev
* dev
, cbw_packet
* packet
)
447 usb_callback_data cb_data
;
449 ret
= UsbBulkTransfer(
450 dev
->bulkEpO
, //bulk output pipe
457 if (ret
!= USB_RC_OK
) {
458 XPRINTF("mass_driver: Error - sending bulk command %d\n", ret
);
464 static int usb_bulk_transfer(int pipe
, void* buffer
, int transferSize
)
467 char* buf
= (char*) buffer
;
468 register int blockSize
= transferSize
;
469 register int offset
= 0;
470 usb_callback_data cb_data
;
472 while (transferSize
> 0) {
473 if (transferSize
< blockSize
) {
474 blockSize
= transferSize
;
477 ret
= UsbBulkTransfer(
478 pipe
, //bulk pipe epI(Read) epO(Write)
479 (buf
+ offset
), //data ptr
480 blockSize
, //data length
484 if (ret
!= USB_RC_OK
) {
485 XPRINTF("mass_driver: Error - sending bulk data transfer %d\n", ret
);
486 cb_data
.returnCode
= -1;
490 //XPRINTF("mass_driver: retCode=%i retSize=%i \n", cb_data.returnCode, cb_data.returnSize);
491 if (cb_data
.returnCode
> 0) {
494 offset
+= cb_data
.returnSize
;
495 transferSize
-= cb_data
.returnSize
;
499 return cb_data
.returnCode
;
502 inline int cbw_scsi_test_unit_ready(mass_dev
* dev
)
505 cbw_packet
*cbw
= &cbw_test_unit_ready
;
507 XPRINTF("mass_driver: cbw_scsi_test_unit_ready\n");
509 usb_bulk_command(dev
, cbw
);
511 ret
= usb_bulk_manage_status(dev
, -TAG_TEST_UNIT_READY
);
516 inline int cbw_scsi_request_sense(mass_dev
* dev
, void *buffer
, int size
)
519 cbw_packet
*cbw
= &cbw_request_sense
;
521 XPRINTF("mass_driver: cbw_scsi_request_sense\n");
523 cbw
->dataTransferLength
= size
; //REQUEST_SENSE_REPLY_LENGTH
524 cbw
->comData
[4] = size
; //allocation length
526 usb_bulk_command(dev
, cbw
);
528 ret
= usb_bulk_transfer(dev
->bulkEpI
, buffer
, size
);
530 XPRINTF("mass_driver: cbw_scsi_request_sense error from usb_bulk_transfer %d\n", ret
);
532 ret
= usb_bulk_manage_status(dev
, -TAG_REQUEST_SENSE
);
537 inline int cbw_scsi_inquiry(mass_dev
* dev
, void *buffer
, int size
)
540 cbw_packet
*cbw
= &cbw_inquiry
;
542 XPRINTF("mass_driver: cbw_scsi_inquiry\n");
544 cbw
->dataTransferLength
= size
; //INQUIRY_REPLY_LENGTH
545 cbw
->comData
[4] = size
; //inquiry reply length
547 usb_bulk_command(dev
, cbw
);
549 ret
= usb_bulk_transfer(dev
->bulkEpI
, buffer
, size
);
551 XPRINTF("mass_driver: cbw_scsi_inquiry error from usb_bulk_transfer %d\n", ret
);
553 usb_bulk_manage_status(dev
, -TAG_INQUIRY
);
555 return ret
; // TODO What to return???
558 inline int cbw_scsi_start_stop_unit(mass_dev
* dev
)
561 cbw_packet
*cbw
= &cbw_start_stop_unit
;
563 XPRINTF("mass_driver: cbw_scsi_start_stop_unit\n");
565 usb_bulk_command(dev
, cbw
);
567 ret
= usb_bulk_manage_status(dev
, -TAG_START_STOP_UNIT
);
572 inline int cbw_scsi_read_capacity(mass_dev
* dev
, void *buffer
, int size
)
574 register int ret
, retryCount
;
575 cbw_packet
*cbw
= &cbw_read_capacity
;
577 XPRINTF("mass_driver: cbw_scsi_read_capacity\n");
579 cbw
->dataTransferLength
= size
; //READ_CAPACITY_REPLY_LENGTH
583 while (ret
!= 0 && retryCount
> 0) {
584 usb_bulk_command(dev
, cbw
);
586 ret
= usb_bulk_transfer(dev
->bulkEpI
, buffer
, size
);
588 XPRINTF("mass_driver: cbw_scsi_read_capacity error from usb_bulk_transfer %d\n", ret
);
591 //according to usb doc we should allways
592 //attempt to read the CSW packet. But in some cases
593 //reading of CSW packet just freeze ps2....:-(
594 if (ret
== USB_RC_STALL
) {
595 XPRINTF("mass_driver: call reset recovery ...\n");
596 usb_bulk_reset(dev
, 1);
598 ret
= usb_bulk_manage_status(dev
, -TAG_READ_CAPACITY
);
606 inline int cbw_scsi_read_sector(mass_dev
* dev
, unsigned int lba
, void* buffer
, int sectorSize
, int sectorCount
)
609 cbw_packet
*cbw
= &cbw_read_sector
;
611 XPRINTF("mass_driver: cbw_scsi_read_sector\n");
613 cbw
->dataTransferLength
= sectorSize
* sectorCount
;
614 cbw
->comData
[2] = (lba
& 0xFF000000) >> 24; //lba 1 (MSB)
615 cbw
->comData
[3] = (lba
& 0xFF0000) >> 16; //lba 2
616 cbw
->comData
[4] = (lba
& 0xFF00) >> 8; //lba 3
617 cbw
->comData
[5] = (lba
& 0xFF); //lba 4 (LSB)
618 cbw
->comData
[7] = (sectorCount
& 0xFF00) >> 8; //Transfer length MSB
619 cbw
->comData
[8] = (sectorCount
& 0xFF); //Transfer length LSB
621 usb_bulk_command(dev
, cbw
);
623 ret
= usb_bulk_transfer(dev
->bulkEpI
, buffer
, sectorSize
* sectorCount
);
625 XPRINTF("mass_driver: cbw_scsi_read_sector error from usb_bulk_transfer %d\n", ret
);
627 ret
= usb_bulk_manage_status(dev
, -TAG_READ
);
632 /* size should be a multiple of sector size */
633 int mass_stor_readSector(unsigned int lba
, int nsectors
, unsigned char* buffer
)
639 mass_dev
* mass_device
= &g_mass_device
;
641 ret
= cbw_scsi_read_sector(mass_device
, lba
, buffer
, mass_device
->sectorSize
, nsectors
);
643 SIGNALIOSEMA(io_sema
);
649 int cbw_scsi_write_sector(mass_dev
* dev
, unsigned int lba
, void* buffer
, int sectorSize
, int sectorCount
)
652 cbw_packet
*cbw
= &cbw_write_sector
;
654 XPRINTF("mass_driver: cbw_scsi_write_sector\n");
656 cbw
->dataTransferLength
= sectorSize
* sectorCount
;
657 cbw
->comData
[2] = (lba
& 0xFF000000) >> 24; //lba 1 (MSB)
658 cbw
->comData
[3] = (lba
& 0xFF0000) >> 16; //lba 2
659 cbw
->comData
[4] = (lba
& 0xFF00) >> 8; //lba 3
660 cbw
->comData
[5] = (lba
& 0xFF); //lba 4 (LSB)
661 cbw
->comData
[7] = (sectorCount
& 0xFF00) >> 8; //Transfer length MSB
662 cbw
->comData
[8] = (sectorCount
& 0xFF); //Transfer length LSB
664 usb_bulk_command(dev
, cbw
);
666 ret
= usb_bulk_transfer(dev
->bulkEpO
, buffer
, sectorSize
* sectorCount
);
668 XPRINTF("mass_driver: cbw_scsi_write_sector error from usb_bulk_transfer %d\n", ret
);
670 ret
= usb_bulk_manage_status(dev
, -TAG_WRITE
);
675 int mass_stor_writeSector(unsigned int lba
, int nsectors
, unsigned char* buffer
)
681 mass_dev
* mass_device
= &g_mass_device
;
683 ret
= cbw_scsi_write_sector(mass_device
, lba
, buffer
, mass_device
->sectorSize
, nsectors
);
685 SIGNALIOSEMA(io_sema
);
691 /* test that endpoint is bulk endpoint and if so, update device info */
692 static void usb_bulk_probeEndpoint(int devId
, mass_dev
* dev
, UsbEndpointDescriptor
* endpoint
)
694 if (endpoint
->bmAttributes
== USB_ENDPOINT_XFER_BULK
) {
696 if ((endpoint
->bEndpointAddress
& 0x80) == 0 && dev
->bulkEpO
< 0) {
697 dev
->bulkEpOAddr
= endpoint
->bEndpointAddress
;
698 dev
->bulkEpO
= pUsbOpenEndpointAligned(devId
, endpoint
);
699 dev
->packetSzO
= endpoint
->wMaxPacketSizeHB
* 256 + endpoint
->wMaxPacketSizeLB
;
700 XPRINTF("mass_driver: register Output endpoint id =%i addr=%02X packetSize=%i\n", dev
->bulkEpO
,dev
->bulkEpOAddr
, dev
->packetSzO
);
703 if ((endpoint
->bEndpointAddress
& 0x80) != 0 && dev
->bulkEpI
< 0) {
704 dev
->bulkEpIAddr
= endpoint
->bEndpointAddress
;
705 dev
->bulkEpI
= pUsbOpenEndpointAligned(devId
, endpoint
);
706 dev
->packetSzI
= endpoint
->wMaxPacketSizeHB
* 256 + endpoint
->wMaxPacketSizeLB
;
707 XPRINTF("mass_driver: register Input endpoint id =%i addr=%02X packetSize=%i\n", dev
->bulkEpI
, dev
->bulkEpIAddr
, dev
->packetSzI
);
712 int mass_stor_probe(int devId
)
714 UsbDeviceDescriptor
*device
= NULL
;
715 UsbConfigDescriptor
*config
= NULL
;
716 UsbInterfaceDescriptor
*intf
= NULL
;
718 XPRINTF("mass_driver: probe: devId=%i\n", devId
);
720 mass_dev
* mass_device
= &g_mass_device
;
722 /* only one device supported */
723 if (mass_device
->status
& DEVICE_DETECTED
) {
724 XPRINTF("mass_driver: Error - only one mass storage device allowed ! \n");
728 /* get device descriptor */
729 device
= (UsbDeviceDescriptor
*)pUsbGetDeviceStaticDescriptor(devId
, NULL
, USB_DT_DEVICE
);
730 if (device
== NULL
) {
731 XPRINTF("mass_driver: Error - Couldn't get device descriptor\n");
735 /* Check if the device has at least one configuration */
736 if (device
->bNumConfigurations
< 1) { return 0; }
738 /* read configuration */
739 config
= (UsbConfigDescriptor
*)pUsbGetDeviceStaticDescriptor(devId
, device
, USB_DT_CONFIG
);
740 if (config
== NULL
) {
741 XPRINTF("mass_driver: Error - Couldn't get configuration descriptor\n");
744 /* check that at least one interface exists */
745 XPRINTF("mass_driver: bNumInterfaces %d\n", config
->bNumInterfaces
);
746 if ((config
->bNumInterfaces
< 1) ||
747 (config
->wTotalLength
< (sizeof(UsbConfigDescriptor
) + sizeof(UsbInterfaceDescriptor
)))) {
748 XPRINTF("mass_driver: Error - No interfaces available\n");
752 intf
= (UsbInterfaceDescriptor
*) ((char *) config
+ config
->bLength
); /* Get first interface */
753 XPRINTF("mass_driver: bInterfaceClass %X bInterfaceSubClass %X bInterfaceProtocol %X\n",
754 intf
->bInterfaceClass
, intf
->bInterfaceSubClass
, intf
->bInterfaceProtocol
);
756 if ((intf
->bInterfaceClass
!= USB_CLASS_MASS_STORAGE
) ||
757 (intf
->bInterfaceSubClass
!= USB_SUBCLASS_MASS_SCSI
&&
758 intf
->bInterfaceSubClass
!= USB_SUBCLASS_MASS_SFF_8070I
) ||
759 (intf
->bInterfaceProtocol
!= USB_PROTOCOL_MASS_BULK_ONLY
) ||
760 (intf
->bNumEndpoints
< 2)) { //one bulk endpoint is not enough because
761 return 0; //we send the CBW to te bulk out endpoint
767 int mass_stor_connect(int devId
)
769 register int i
, epCount
;
770 UsbDeviceDescriptor
*device
;
771 UsbConfigDescriptor
*config
;
772 UsbInterfaceDescriptor
*interface
;
773 UsbEndpointDescriptor
*endpoint
;
776 //wait_for_connect = 0;
778 XPRINTF("mass_driver: connect: devId=%i\n", devId
);
779 dev
= &g_mass_device
;
781 /* only one mass device allowed */
782 if (dev
->devId
!= -1) {
783 XPRINTF("mass_driver: Error - only one mass storage device allowed !\n");
793 /* open the config endpoint */
794 dev
->controlEp
= pUsbOpenEndpoint(devId
, NULL
);
796 device
= (UsbDeviceDescriptor
*)pUsbGetDeviceStaticDescriptor(devId
, NULL
, USB_DT_DEVICE
);
798 config
= (UsbConfigDescriptor
*)pUsbGetDeviceStaticDescriptor(devId
, device
, USB_DT_CONFIG
);
800 interface
= (UsbInterfaceDescriptor
*) ((char *) config
+ config
->bLength
); /* Get first interface */
802 // store interface numbers
803 dev
->interfaceNumber
= interface
->bInterfaceNumber
;
804 dev
->interfaceAlt
= interface
->bAlternateSetting
;
806 epCount
= interface
->bNumEndpoints
;
807 endpoint
= (UsbEndpointDescriptor
*) pUsbGetDeviceStaticDescriptor(devId
, NULL
, USB_DT_ENDPOINT
);
808 usb_bulk_probeEndpoint(devId
, dev
, endpoint
);
810 for (i
= 1; i
< epCount
; i
++) {
811 endpoint
= (UsbEndpointDescriptor
*) ((char *) endpoint
+ endpoint
->bLength
);
812 usb_bulk_probeEndpoint(devId
, dev
, endpoint
);
815 /* we do NOT have enough bulk endpoints */
816 if (dev
->bulkEpI
< 0 /* || dev->bulkEpO < 0 */ ) { /* the bulkOut is not needed now */
817 if (dev
->bulkEpI
>= 0) {
818 pUsbCloseEndpoint(dev
->bulkEpI
);
820 if (dev
->bulkEpO
>= 0) {
821 pUsbCloseEndpoint(dev
->bulkEpO
);
823 XPRINTF("mass_driver: Error - connect failed: not enough bulk endpoints! \n");
827 /*store current configuration id - can't call set_configuration here */
829 dev
->configId
= config
->bConfigurationValue
;
830 dev
->status
= DEVICE_DETECTED
;
831 XPRINTF("mass_driver: connect ok: epI=%i, epO=%i \n", dev
->bulkEpI
, dev
->bulkEpO
);
836 void mass_stor_release(mass_dev
*dev
)
838 if (dev
->bulkEpI
>= 0) {
839 pUsbCloseEndpoint(dev
->bulkEpI
);
842 if (dev
->bulkEpO
>= 0) {
843 pUsbCloseEndpoint(dev
->bulkEpO
);
852 int mass_stor_disconnect(int devId
)
854 mass_dev
* dev
= &g_mass_device
;
856 XPRINTF("mass_driver: disconnect: devId=%i\n", devId
);
858 if ((dev
->status
& DEVICE_DETECTED
) && devId
== dev
->devId
) {
859 mass_stor_release(dev
);
866 int mass_stor_warmup(mass_dev
*dev
)
870 read_capacity_data rcd
;
873 XPRINTF("mass_driver: mass_stor_warmup\n");
875 if (!(dev
->status
& DEVICE_DETECTED
)) {
876 XPRINTF("mass_driver: Error - no mass storage device found!\n");
880 stat
= usb_bulk_get_max_lun(dev
);
881 XPRINTF("mass_driver: usb_bulk_get_max_lun %d\n", stat
);
883 mips_memset(&id
, 0, sizeof(inquiry_data
));
884 if ((stat
= cbw_scsi_inquiry(dev
, &id
, sizeof(inquiry_data
))) < 0) {
885 XPRINTF("mass_driver: Error - cbw_scsi_inquiry %d\n", stat
);
889 XPRINTF("mass_driver: Vendor: %.8s\n", id
.vendor
);
890 XPRINTF("mass_driver: Product: %.16s\n", id
.product
);
891 XPRINTF("mass_driver: Revision: %.4s\n", id
.revision
);
893 while((stat
= cbw_scsi_test_unit_ready(dev
)) != 0) {
894 XPRINTF("mass_driver: Error - cbw_scsi_test_unit_ready %d\n", stat
);
896 stat
= cbw_scsi_request_sense(dev
, &sd
, sizeof(sense_data
));
898 XPRINTF("mass_driver: Error - cbw_scsi_request_sense %d\n", stat
);
900 if ((sd
.error_code
== 0x70) && (sd
.sense_key
!= 0x00)) {
901 XPRINTF("mass_driver: Sense Data key: %02X code: %02X qual: %02X\n", sd
.sense_key
, sd
.add_sense_code
, sd
.add_sense_qual
);
903 if ((sd
.sense_key
== 0x02) && (sd
.add_sense_code
== 0x04) && (sd
.add_sense_qual
== 0x02)) {
904 XPRINTF("mass_driver: Error - Additional initalization is required for this device!\n");
905 if ((stat
= cbw_scsi_start_stop_unit(dev
)) != 0) {
906 XPRINTF("mass_driver: Error - cbw_scsi_start_stop_unit %d\n", stat
);
913 stat
= cbw_scsi_request_sense(dev
, &sd
, sizeof(sense_data
));
915 XPRINTF("mass_driver: Error - cbw_scsi_request_sense %d\n", stat
);
917 if ((sd
.error_code
== 0x70) && (sd
.sense_key
!= 0x00)) {
918 XPRINTF("mass_driver: Sense Data key: %02X code: %02X qual: %02X\n", sd
.sense_key
, sd
.add_sense_code
, sd
.add_sense_qual
);
921 if ((stat
= cbw_scsi_read_capacity(dev
, &rcd
, sizeof(read_capacity_data
))) != 0) {
922 XPRINTF("mass_driver: Error - cbw_scsi_read_capacity %d\n", stat
);
926 dev
->sectorSize
= getBI32(&rcd
.block_length
);
927 dev
->maxLBA
= getBI32(&rcd
.last_lba
);
928 XPRINTF("mass_driver: sectorSize %d maxLBA %d\n", dev
->sectorSize
, dev
->maxLBA
);
931 for (stat
=0; stat
<4; stat
++) {
932 if (dev
->sectorSize
== gMSStoDSS
[stat
].massSectorSize
) {
933 gShiftPos
= gMSStoDSS
[stat
].shiftPos
;
942 int mass_stor_configureDevice(void)
944 // give the USB driver some time to detect the device
945 register int i
= 10000;
949 XPRINTF("mass_driver: configuring devices... \n");
951 mass_dev
*dev
= &g_mass_device
;
952 if (dev
->devId
!= -1 && (dev
->status
& DEVICE_DETECTED
) && !(dev
->status
& DEVICE_CONFIGURED
)) {
954 usb_set_configuration(dev
, dev
->configId
);
955 usb_set_interface(dev
, dev
->interfaceNumber
, dev
->interfaceAlt
);
956 dev
->status
|= DEVICE_CONFIGURED
;
958 ret
= mass_stor_warmup(dev
);
960 XPRINTF("mass_driver: Error - failed to warmup device %d\n", dev
->devId
);
961 mass_stor_release(dev
);
970 int mass_stor_init(void)
975 g_mass_device
.devId
= -1;
981 cb_sema
= CreateSema(&smp
);
988 io_sema
= CreateSema(&smp
);
993 driver
.name
= "mass-stor";
994 driver
.probe
= mass_stor_probe
;
995 driver
.connect
= mass_stor_connect
;
996 driver
.disconnect
= mass_stor_disconnect
;
998 ret
= pUsbRegisterDriver(&driver
);
999 XPRINTF("mass_driver: registerDriver=%i \n", ret
);
1001 XPRINTF("mass_driver: register driver failed! ret=%d\n", ret
);
1008 //-------------------------------------------------------------------------
1009 int mass_stor_ReadCD(unsigned int lsn
, unsigned int nsectors
, void *buf
, int part_num
)
1012 register u32 sectors
, nbytes
;
1015 while (nsectors
> 0) {
1020 nbytes
= sectors
<< 11;
1023 mass_stor_readSector(p_part_start
[part_num
] + (lsn
<< gShiftPos
), sectors
<< gShiftPos
, p
);
1026 mass_stor_readSector(p_part_start
[part_num
] + (lsn
>> 1), 1, _4K_buf
);
1027 mips_memcpy(p
, _4K_buf
, nbytes
);
1031 mass_stor_readSector(p_part_start
[part_num
] + (lsn
>> 1), 1, p
);
1037 nsectors
-= sectors
;