Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader.git] / modules / iopcore / cdvdman / mass_driver.c
blob4999c8128f471d834b8541ea2e1fd93e50322688
1 /*
2 * usb_driver - USB Mass Storage Driver code
3 */
5 #include <sysclib.h>
6 #include <thbase.h>
7 #include <thsemap.h>
8 #include <stdio.h>
9 #include <usbd.h>
11 //#define DEBUG //comment out this line when not debugging
13 #include "smsutils.h"
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
38 #define TAG_READ 40
39 #define TAG_START_STOP_UNIT 33
40 #define TAG_WRITE 42
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;
51 unsigned int tag;
52 unsigned int dataTransferLength;
53 unsigned char flags; //80->data in, 00->out
54 unsigned char lun;
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 = {
60 CBW_TAG,
61 -TAG_TEST_UNIT_READY,
62 0, //TUR_REPLY_LENGTH
63 0x80,
65 12,
66 { 0x00, //test unit ready operation code
67 0, //lun/reserved
68 0 ,0 ,0 ,0 , //reserved
69 0 ,0 , 0 , //reserved
70 0 ,0 ,0 //reserved
74 static cbw_packet cbw_request_sense = {
75 CBW_TAG,
76 -TAG_REQUEST_SENSE,
78 0x80,
80 12,
81 { 0x03, //request sense operation code
82 0, //lun/reserved
83 0 ,0 , //reserved
84 0 , //allocation length
85 0 ,0 ,0 ,0 , //reserved
86 0 ,0 ,0 //reserved
90 static cbw_packet cbw_inquiry = {
91 CBW_TAG,
92 -TAG_INQUIRY,
94 0x80,
96 12,
97 { 0x12, //inquiry operation code
98 0, //lun/reserved
99 0, //page code
100 0 , //reserved
101 0 , //inquiry reply length
102 0 ,0 ,0 ,0 , //reserved
103 0 ,0 ,0 //reserved
107 static cbw_packet cbw_start_stop_unit = {
108 CBW_TAG,
109 -TAG_START_STOP_UNIT,
110 0, //START_STOP_REPLY_LENGTH
111 0x80,
114 { 0x1B, //start stop unit operation code
115 1, //lun/reserved/immed
116 0, 0 , //reserved
117 1 , //reserved/LoEj/Start "Start the media and acquire the format type"
118 0 ,0 ,0 ,0 , //reserved
119 0 ,0 ,0 //reserved
123 static cbw_packet cbw_read_capacity = {
124 CBW_TAG,
125 -TAG_READ_CAPACITY,
127 0x80,
130 { 0x25, //read capacity operation code
131 0, //lun/reserved/RelAdr
132 0, 0 ,0 ,0 , //lba
133 0 , //reserved
134 0 ,0 , //reserved/PMI
135 0 ,0 ,0 //reserved
139 static cbw_packet cbw_read_sector = {
140 CBW_TAG,
141 -TAG_READ,
143 0x80,
146 { 0x28, //read operation code
147 0, //LUN/DPO/FUA/Reserved/Reldr
148 0, 0 ,0 ,0 , //lba
149 0 , //reserved
150 0 ,0 , //Transfer length MSB
151 0 ,0 ,0 //reserved
155 #ifdef VMC_DRIVER
156 static cbw_packet cbw_write_sector = {
157 CBW_TAG,
158 -TAG_WRITE,
160 0x00,
163 { 0x2A, //write operation code
164 0, //LUN/DPO/FUA/Reserved/Reldr
165 0, 0 ,0 ,0 , //lba
166 0 , //reserved
167 0 ,0 , //Transfer length MSB
168 0 ,0 ,0 //reserved
171 #endif
173 typedef struct _csw_packet
175 unsigned int signature;
176 unsigned int tag;
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
185 u8 iso_ecma_ansi;
186 u8 repsonse_data_format;
187 u8 additional_length;
188 u8 res[3];
189 u8 vendor[8];
190 u8 product[16];
191 u8 revision[4];
192 } inquiry_data __attribute__((packed));
194 typedef struct _sense_data
196 u8 error_code;
197 u8 res1;
198 u8 sense_key;
199 u8 information[4];
200 u8 add_sense_len;
201 u8 res3[4];
202 u8 add_sense_code;
203 u8 add_sense_qual;
204 u8 res4[4];
205 } sense_data __attribute__((packed));
207 typedef struct _read_capacity_data
209 u8 last_lba[4];
210 u8 block_length[4];
211 } read_capacity_data __attribute__((packed));
213 static UsbDriver driver;
215 //volatile int wait_for_connect = 1;
217 static int cb_sema;
219 #ifdef VMC_DRIVER
220 static int io_sema;
222 #define WAITIOSEMA(x) WaitSema(x)
223 #define SIGNALIOSEMA(x) SignalSema(x)
224 #else
225 #define WAITIOSEMA(x)
226 #define SIGNALIOSEMA(x)
227 #endif
229 typedef struct _usb_callback_data
231 int returnCode;
232 int returnSize;
233 } usb_callback_data;
235 static mass_dev g_mass_device;
237 #ifndef _4K_SECTORS
238 struct MSStoDSS_t {
239 int massSectorSize;
240 int shiftPos;
243 static struct MSStoDSS_t gMSStoDSS[4] = {
244 { 512 , 2 },
245 { 1024, 1 },
246 { 2048, 0 },
247 { 4096, -1 },
250 static int gShiftPos;
251 #else
252 static u8 _4K_buf[4096] __attribute__((aligned(64)));
253 #endif
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);
263 SignalSema(cb_sema);
266 static void usb_set_configuration(mass_dev* dev, int configNumber)
268 register int ret;
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);
276 } else {
277 WaitSema(cb_sema);
281 static void usb_set_interface(mass_dev* dev, int interface, int altSetting)
283 register int ret;
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);
291 } else {
292 WaitSema(cb_sema);
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;
304 } else {
305 endpoint = dev->bulkEpOAddr;
308 ret = UsbClearEndpointFeature(
309 dev->controlEp, //Config pipe
310 0, //HALT feature
311 endpoint,
312 usb_callback,
313 (void*)&cb_data
316 if (ret != USB_RC_OK) {
317 XPRINTF("mass_driver: Error - sending clear halt %d\n", ret);
318 } else {
319 WaitSema(cb_sema);
323 static void usb_bulk_reset(mass_dev* dev, int mode)
325 register int ret;
326 usb_callback_data cb_data;
328 //Call Bulk only mass storage reset
329 ret = UsbControlTransfer(
330 dev->controlEp, //default pipe
331 0x21, //bulk reset
332 0xFF,
334 dev->interfaceNumber, //interface number
335 0, //length
336 NULL, //data
337 usb_callback,
338 (void*) &cb_data
341 if (ret != USB_RC_OK) {
342 XPRINTF("mass_driver: Error - sending reset %d\n", ret);
343 } else {
344 WaitSema(cb_sema);
346 //clear bulk-in endpoint
347 if (mode & 0x01) {
348 usb_bulk_clear_halt(dev, 0);
351 //clear bulk-out endpoint
352 if (mode & 0x02) {
353 usb_bulk_clear_halt(dev, 1);
358 static int usb_bulk_status(mass_dev* dev, csw_packet* csw, int tag)
360 register int ret;
361 usb_callback_data cb_data;
363 csw->signature = CSW_TAG;
364 csw->tag = tag;
365 csw->dataResidue = 0;
366 csw->status = 0;
368 ret = UsbBulkTransfer(
369 dev->bulkEpI, //bulk input pipe
370 csw, //data ptr
371 13, //data length
372 usb_callback,
373 (void*)&cb_data
376 if (ret != USB_RC_OK) {
377 XPRINTF("mass_driver: Error - sending bulk status %d\n", ret);
378 return -1;
379 } else {
380 WaitSema(cb_sema);
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);
387 return 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)
394 register int ret;
395 csw_packet csw;
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 */
412 return ret;
415 static int usb_bulk_get_max_lun(mass_dev* dev)
417 register int ret;
418 usb_callback_data cb_data;
419 char max_lun;
421 //Call Bulk only mass storage reset
422 ret = UsbControlTransfer(
423 dev->controlEp, //default pipe
424 0xA1,
425 0xFE,
427 dev->interfaceNumber, //interface number
428 1, //length
429 &max_lun, //data
430 usb_callback,
431 (void*) &cb_data
434 if (ret != USB_RC_OK) {
435 XPRINTF("mass_driver: Error - get_max_lun %d\n", ret);
436 max_lun = -ret;
437 } else {
438 WaitSema(cb_sema);
441 return max_lun;
444 static void usb_bulk_command(mass_dev* dev, cbw_packet* packet )
446 register int ret;
447 usb_callback_data cb_data;
449 ret = UsbBulkTransfer(
450 dev->bulkEpO, //bulk output pipe
451 packet, //data ptr
452 31, //data length
453 usb_callback,
454 (void*)&cb_data
457 if (ret != USB_RC_OK) {
458 XPRINTF("mass_driver: Error - sending bulk command %d\n", ret);
459 } else {
460 WaitSema(cb_sema);
464 static int usb_bulk_transfer(int pipe, void* buffer, int transferSize)
466 register int ret;
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
481 usb_callback,
482 (void*)&cb_data
484 if (ret != USB_RC_OK) {
485 XPRINTF("mass_driver: Error - sending bulk data transfer %d\n", ret);
486 cb_data.returnCode = -1;
487 break;
488 } else {
489 WaitSema(cb_sema);
490 //XPRINTF("mass_driver: retCode=%i retSize=%i \n", cb_data.returnCode, cb_data.returnSize);
491 if (cb_data.returnCode > 0) {
492 break;
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)
504 register int ret;
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);
513 return ret;
516 inline int cbw_scsi_request_sense(mass_dev* dev, void *buffer, int size)
518 register int ret;
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);
529 if (ret != 0)
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);
534 return ret;
537 inline int cbw_scsi_inquiry(mass_dev* dev, void *buffer, int size)
539 register int ret;
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);
550 if (ret != 0)
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)
560 register int ret;
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);
569 return ret;
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
581 ret = 1;
582 retryCount = 6;
583 while (ret != 0 && retryCount > 0) {
584 usb_bulk_command(dev, cbw);
586 ret = usb_bulk_transfer(dev->bulkEpI, buffer, size);
587 if (ret != 0)
588 XPRINTF("mass_driver: cbw_scsi_read_capacity error from usb_bulk_transfer %d\n", ret);
590 //HACK HACK HACK !!!
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);
597 } else {
598 ret = usb_bulk_manage_status(dev, -TAG_READ_CAPACITY);
600 retryCount--;
603 return ret;
606 inline int cbw_scsi_read_sector(mass_dev* dev, unsigned int lba, void* buffer, int sectorSize, int sectorCount)
608 register int ret;
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);
624 if (ret != 0)
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);
629 return ret;
632 /* size should be a multiple of sector size */
633 int mass_stor_readSector(unsigned int lba, int nsectors, unsigned char* buffer)
635 int ret;
637 WAITIOSEMA(io_sema);
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);
645 return ret;
648 #ifdef VMC_DRIVER
649 int cbw_scsi_write_sector(mass_dev* dev, unsigned int lba, void* buffer, int sectorSize, int sectorCount)
651 register int ret;
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);
667 if (ret != 0)
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);
672 return ret;
675 int mass_stor_writeSector(unsigned int lba, int nsectors, unsigned char* buffer)
677 int ret;
679 WAITIOSEMA(io_sema);
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);
687 return ret;
689 #endif
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) {
695 /* out transfer */
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);
701 } else
702 /* in transfer */
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");
725 return 0;
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");
732 return 0;
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");
742 return 0;
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");
749 return 0;
751 /* get interface */
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
764 return 1;
767 int mass_stor_connect(int devId)
769 register int i, epCount;
770 UsbDeviceDescriptor *device;
771 UsbConfigDescriptor *config;
772 UsbInterfaceDescriptor *interface;
773 UsbEndpointDescriptor *endpoint;
774 mass_dev* dev;
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");
784 return 1;
787 dev->status = 0;
788 dev->sectorSize = 0;
790 dev->bulkEpI = -1;
791 dev->bulkEpO = -1;
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");
824 return -1;
827 /*store current configuration id - can't call set_configuration here */
828 dev->devId = devId;
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);
833 return 0;
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);
846 dev->bulkEpI = -1;
847 dev->bulkEpO = -1;
848 dev->controlEp = -1;
849 dev->status = 0;
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);
860 dev->devId = -1;
863 return 0;
866 int mass_stor_warmup(mass_dev *dev)
868 inquiry_data id;
869 sense_data sd;
870 read_capacity_data rcd;
871 register int stat;
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");
877 return -1;
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);
886 return -1;
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));
897 if (stat != 0)
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);
907 return -1;
913 stat = cbw_scsi_request_sense(dev, &sd, sizeof(sense_data));
914 if (stat != 0)
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);
923 return -1;
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);
930 #ifndef _4K_SECTORS
931 for (stat=0; stat<4; stat++) {
932 if (dev->sectorSize == gMSStoDSS[stat].massSectorSize) {
933 gShiftPos = gMSStoDSS[stat].shiftPos;
934 break;
937 #endif
939 return 0;
942 int mass_stor_configureDevice(void)
944 // give the USB driver some time to detect the device
945 register int i = 10000;
946 while (--i > 0)
947 DelayThread(100);
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)) {
953 int ret;
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);
959 if (ret < 0) {
960 XPRINTF("mass_driver: Error - failed to warmup device %d\n", dev->devId);
961 mass_stor_release(dev);
964 return 1;
967 return 0;
970 int mass_stor_init(void)
972 iop_sema_t smp;
973 register int ret;
975 g_mass_device.devId = -1;
977 smp.initial = 0;
978 smp.max = 1;
979 smp.option = 0;
980 smp.attr = 0;
981 cb_sema = CreateSema(&smp);
983 #ifdef VMC_DRIVER
984 smp.initial = 1;
985 smp.max = 1;
986 smp.option = 0;
987 smp.attr = 1;
988 io_sema = CreateSema(&smp);
989 #endif
991 driver.next = NULL;
992 driver.prev = NULL;
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);
1000 if (ret < 0) {
1001 XPRINTF("mass_driver: register driver failed! ret=%d\n", ret);
1002 return -1;
1005 return 0;
1008 //-------------------------------------------------------------------------
1009 int mass_stor_ReadCD(unsigned int lsn, unsigned int nsectors, void *buf, int part_num)
1011 register int r = 0;
1012 register u32 sectors, nbytes;
1013 u8 *p = (u8 *)buf;
1015 while (nsectors > 0) {
1016 sectors = nsectors;
1017 if (sectors > 2)
1018 sectors = 2;
1020 nbytes = sectors << 11;
1022 #ifndef _4K_SECTORS
1023 mass_stor_readSector(p_part_start[part_num] + (lsn << gShiftPos), sectors << gShiftPos, p);
1024 #else
1025 if (sectors == 1) {
1026 mass_stor_readSector(p_part_start[part_num] + (lsn >> 1), 1, _4K_buf);
1027 mips_memcpy(p, _4K_buf, nbytes);
1030 else {
1031 mass_stor_readSector(p_part_start[part_num] + (lsn >> 1), 1, p);
1033 #endif
1034 lsn += sectors;
1035 r += sectors;
1036 p += nbytes;
1037 nsectors -= sectors;
1038 ReadPos+=sectors;
1041 return 1;