15#include "mass_debug.h"
17#include "usbhd_common.h"
20#include "part_driver.h"
22#define getBI32(__buf) ((((u8 *)(__buf))[3] << 0) | (((u8 *)(__buf))[2] << 8) | (((u8 *)(__buf))[1] << 16) | (((u8 *)(__buf))[0] << 24))
24#define USB_SUBCLASS_MASS_RBC 0x01
25#define USB_SUBCLASS_MASS_ATAPI 0x02
26#define USB_SUBCLASS_MASS_QIC 0x03
27#define USB_SUBCLASS_MASS_UFI 0x04
28#define USB_SUBCLASS_MASS_SFF_8070I 0x05
29#define USB_SUBCLASS_MASS_SCSI 0x06
31#define USB_PROTOCOL_MASS_CBI 0x00
32#define USB_PROTOCOL_MASS_CBI_NO_CCI 0x01
33#define USB_PROTOCOL_MASS_BULK_ONLY 0x50
35#define TAG_TEST_UNIT_READY 0
36#define TAG_REQUEST_SENSE 3
38#define TAG_READ_CAPACITY 37
40#define TAG_START_STOP_UNIT 33
43#define USB_BLK_EP_IN 0
44#define USB_BLK_EP_OUT 1
46#define USB_XFER_MAX_RETRIES 8
47#define USB_IO_MAX_RETRIES 16
49#define CBW_TAG 0x43425355
50#define CSW_TAG 0x53425355
54 unsigned int signature;
56 unsigned int dataTransferLength;
59 unsigned char comLength;
60 unsigned char comData[16];
65 unsigned int signature;
67 unsigned int dataResidue;
73 u8 peripheral_device_type;
76 u8 response_data_format;
112#define USB_BLOCK_SIZE 4096
120 unsigned int remaining;
124static mass_dev g_mass_device[NUM_DEVICES];
126static void usb_callback(
int resultCode,
int bytes,
void *arg);
128static void usb_transfer_callback(
int resultCode,
int bytes,
void *arg);
129static void mass_stor_release(
mass_dev *dev);
131static void usb_callback(
int resultCode,
int bytes,
void *arg)
134 data->returnCode = resultCode;
135 data->returnSize = bytes;
136 XPRINTF(
"callback: res %d, bytes %d, arg %p \n", resultCode, bytes, arg);
137 SignalSema(data->sema);
144 len = data->remaining > USB_BLOCK_SIZE ? USB_BLOCK_SIZE : data->remaining;
145 ret = sceUsbdBulkTransfer(
149 &usb_transfer_callback,
154static void usb_transfer_callback(
int resultCode,
int bytes,
void *arg)
158 data->returnCode = resultCode;
160 data->remaining -= bytes;
161 data->buffer += bytes;
164 if ((resultCode ==
USB_RC_OK) && (data->remaining > 0)) {
167 ret = perform_bulk_transfer(data);
169 data->returnCode = ret;
170 SignalSema(data->sema);
173 SignalSema(data->sema);
177static int usb_set_configuration(
mass_dev *dev,
int configNumber)
182 cb_data.sema = dev->ioSema;
184 XPRINTF(
"setting configuration controlEp=%i, confNum=%i \n", dev->controlEp, configNumber);
185 ret = sceUsbdSetConfiguration(dev->controlEp, configNumber, usb_callback, (
void *)&cb_data);
188 WaitSema(cb_data.sema);
189 ret = cb_data.returnCode;
195static int usb_set_interface(
mass_dev *dev,
int interface,
int altSetting)
200 cb_data.sema = dev->ioSema;
202 XPRINTF(
"setting interface controlEp=%i, interface=%i altSetting=%i\n", dev->controlEp, interface, altSetting);
203 ret = sceUsbdSetInterface(dev->controlEp, interface, altSetting, usb_callback, (
void *)&cb_data);
206 WaitSema(cb_data.sema);
207 ret = cb_data.returnCode;
213static int usb_bulk_clear_halt(
mass_dev *dev,
int endpoint)
218 cb_data.sema = dev->ioSema;
220 ret = sceUsbdClearEndpointFeature(
223 (endpoint == USB_BLK_EP_IN) ? dev->bulkEpI : dev->bulkEpO,
228 WaitSema(cb_data.sema);
229 ret = cb_data.returnCode;
232 printf(
"USBHDFSD: Error - sending clear halt %d\n", ret);
238static void usb_bulk_reset(
mass_dev *dev,
int mode)
243 cb_data.sema = dev->ioSema;
246 ret = sceUsbdControlTransfer(
251 dev->interfaceNumber,
258 WaitSema(cb_data.sema);
259 ret = cb_data.returnCode;
264 ret = usb_bulk_clear_halt(dev, USB_BLK_EP_IN);
269 ret = usb_bulk_clear_halt(dev, USB_BLK_EP_OUT);
272 printf(
"USBHDFSD: Error - sending reset %d to device %d.\n", ret, dev->devId);
282 cb_data.sema = dev->ioSema;
284 csw->signature = CSW_TAG;
286 csw->dataResidue = 0;
289 ret = sceUsbdBulkTransfer(
297 WaitSema(cb_data.sema);
298 ret = cb_data.returnCode;
300 if (cb_data.returnSize != 13)
301 printf(
"USBHDFSD: bulk csw.status returnSize: %i != 13\n", cb_data.returnSize);
302 if (csw->dataResidue != 0)
303 printf(
"USBHDFSD: bulk csw.status residue: %u\n", csw->dataResidue);
304 XPRINTF(
"bulk csw result: %d, csw.status: %u\n", ret, csw->status);
318static int usb_bulk_manage_status(
mass_dev *dev,
unsigned int tag)
324 ret = usb_bulk_status(dev, &csw, tag);
326 usb_bulk_clear_halt(dev, USB_BLK_EP_IN);
328 printf(
"USBHDFSD: usb_bulk_manage_status error %d ...\n", ret);
329 ret = usb_bulk_status(dev, &csw, tag);
333 if (ret !=
USB_RC_OK || csw.signature != CSW_TAG || csw.tag != tag || csw.status == 2) {
334 printf(
"USBHDFSD: usb_bulk_manage_status call reset recovery ...\n");
335 usb_bulk_reset(dev, 3);
338 return ((ret ==
USB_RC_OK && csw.signature == CSW_TAG && csw.tag == tag) ? csw.status : -1);
341static int usb_bulk_get_max_lun(
mass_dev *dev)
347 cb_data.sema = dev->ioSema;
350 ret = sceUsbdControlTransfer(
355 dev->interfaceNumber,
362 WaitSema(cb_data.sema);
363 ret = cb_data.returnCode;
369 usb_bulk_clear_halt(dev, USB_BLK_EP_IN);
370 usb_bulk_clear_halt(dev, USB_BLK_EP_OUT);
384 printf(
"USBHDFSD: Rejecting I/O to offline device %d.\n", dev->devId);
388 cb_data.sema = dev->ioSema;
390 ret = sceUsbdBulkTransfer(
398 WaitSema(cb_data.sema);
399 ret = cb_data.returnCode;
402 printf(
"USBHDFSD: Error - sending bulk command %d. Calling reset recovery.\n", ret);
403 usb_bulk_reset(dev, 3);
409static int usb_bulk_transfer(
mass_dev *dev,
int direction,
void *buffer,
unsigned int transferSize)
414 cb_data.sema = dev->ioSema;
415 cb_data.pipe = (direction == USB_BLK_EP_IN) ? dev->bulkEpI : dev->bulkEpO;
416 cb_data.buffer = buffer;
417 cb_data.returnCode = 0;
418 cb_data.remaining = transferSize;
420 ret = perform_bulk_transfer(&cb_data);
422 WaitSema(cb_data.sema);
423 ret = cb_data.returnCode;
427 printf(
"USBHDFSD: Error - bulk data transfer %d. Clearing HALT state.\n", cb_data.returnCode);
428 usb_bulk_clear_halt(dev, direction);
434static int cbw_scsi_test_unit_ready(
mass_dev *dev)
439 -TAG_TEST_UNIT_READY,
461 XPRINTF(
"cbw_scsi_test_unit_ready\n");
463 for (result = -
EIO, retries = USB_XFER_MAX_RETRIES; retries > 0; retries--) {
464 if (usb_bulk_command(dev, &cbw) ==
USB_RC_OK) {
465 if ((result = usb_bulk_manage_status(dev, -TAG_TEST_UNIT_READY)) >= 0)
473static int cbw_scsi_request_sense(
mass_dev *dev,
void *buffer,
int size)
475 int rcode, result, retries;
500 cbw.dataTransferLength = size;
501 cbw.comData[4] = size;
503 XPRINTF(
"cbw_scsi_request_sense\n");
505 for (retries = USB_XFER_MAX_RETRIES; retries > 0; retries--) {
506 if (usb_bulk_command(dev, &cbw) ==
USB_RC_OK) {
507 rcode = usb_bulk_transfer(dev, USB_BLK_EP_IN, buffer, size);
508 result = usb_bulk_manage_status(dev, -TAG_REQUEST_SENSE);
518static int cbw_scsi_inquiry(
mass_dev *dev,
void *buffer,
int size)
520 int rcode, result, retries;
545 XPRINTF(
"cbw_scsi_inquiry\n");
547 cbw.dataTransferLength = size;
548 cbw.comData[4] = size;
550 for (retries = USB_XFER_MAX_RETRIES; retries > 0; retries--) {
551 if (usb_bulk_command(dev, &cbw) ==
USB_RC_OK) {
552 rcode = usb_bulk_transfer(dev, USB_BLK_EP_IN, buffer, size);
553 result = usb_bulk_manage_status(dev, -TAG_INQUIRY);
563static int cbw_scsi_start_stop_unit(
mass_dev *dev, u8 param)
568 -TAG_START_STOP_UNIT,
590 XPRINTF(
"cbw_scsi_start_stop_unit. param: %02x\n", param);
592 cbw.comData[4] = param;
594 for (result = -
EIO, retries = USB_XFER_MAX_RETRIES; retries > 0; retries--) {
595 if (usb_bulk_command(dev, &cbw) ==
USB_RC_OK) {
596 if ((result = usb_bulk_manage_status(dev, -TAG_START_STOP_UNIT)) == 0)
604static int cbw_scsi_read_capacity(
mass_dev *dev,
void *buffer,
int size)
606 int rcode, result, retries;
631 cbw.dataTransferLength = size;
633 XPRINTF(
"cbw_scsi_read_capacity\n");
635 for (retries = USB_XFER_MAX_RETRIES; retries > 0; retries--) {
636 if (usb_bulk_command(dev, &cbw) ==
USB_RC_OK) {
637 rcode = usb_bulk_transfer(dev, USB_BLK_EP_IN, buffer, size);
638 result = usb_bulk_manage_status(dev, -TAG_READ_CAPACITY);
648static int cbw_scsi_read_sector(
mass_dev *dev,
unsigned int lba,
void *buffer,
unsigned short int sectorCount)
674 XPRINTF(
"cbw_scsi_read_sector - 0x%08x %p 0x%04x\n", lba, buffer, sectorCount);
676 cbw.dataTransferLength = dev->sectorSize * sectorCount;
679 cbw.comData[2] = (lba & 0xFF000000) >> 24;
680 cbw.comData[3] = (lba & 0xFF0000) >> 16;
681 cbw.comData[4] = (lba & 0xFF00) >> 8;
682 cbw.comData[5] = (lba & 0xFF);
683 cbw.comData[7] = (sectorCount & 0xFF00) >> 8;
684 cbw.comData[8] = (sectorCount & 0xFF);
687 if (usb_bulk_command(dev, &cbw) ==
USB_RC_OK) {
690 rcode = usb_bulk_transfer(dev, USB_BLK_EP_IN, buffer, dev->sectorSize * sectorCount);
691 result = usb_bulk_manage_status(dev, -TAG_READ);
700static int cbw_scsi_write_sector(
mass_dev *dev,
unsigned int lba,
const void *buffer,
unsigned short int sectorCount)
726 XPRINTF(
"cbw_scsi_write_sector - 0x%08x %p 0x%04x\n", lba, buffer, sectorCount);
728 cbw.dataTransferLength = dev->sectorSize * sectorCount;
731 cbw.comData[2] = (lba & 0xFF000000) >> 24;
732 cbw.comData[3] = (lba & 0xFF0000) >> 16;
733 cbw.comData[4] = (lba & 0xFF00) >> 8;
734 cbw.comData[5] = (lba & 0xFF);
735 cbw.comData[7] = (sectorCount & 0xFF00) >> 8;
736 cbw.comData[8] = (sectorCount & 0xFF);
739 if (usb_bulk_command(dev, &cbw) ==
USB_RC_OK) {
742 rcode = usb_bulk_transfer(dev, USB_BLK_EP_OUT, (
void *)buffer, dev->sectorSize * sectorCount);
743 result = usb_bulk_manage_status(dev, -TAG_WRITE);
752static mass_dev *mass_stor_findDevice(
int devId,
int create)
756 XPRINTF(
"mass_stor_findDevice devId %i\n", devId);
757 for (i = 0; i < NUM_DEVICES; ++i) {
758 if (g_mass_device[i].devId == devId) {
759 XPRINTF(
"mass_stor_findDevice exists %i\n", i);
760 dev = &g_mass_device[i];
762 }
else if (create && dev == NULL && g_mass_device[i].devId == -1) {
763 dev = &g_mass_device[i];
770int mass_stor_readSector(
mass_dev *dev,
unsigned int sector,
unsigned char *buffer,
unsigned short int count)
774 for (retries = USB_IO_MAX_RETRIES; retries > 0; retries--) {
775 if (cbw_scsi_read_sector(dev, sector, buffer,
count) == 0)
782int mass_stor_writeSector(
mass_dev *dev,
unsigned int sector,
const unsigned char *buffer,
unsigned short int count)
786 for (retries = USB_IO_MAX_RETRIES; retries > 0; retries--) {
787 if (cbw_scsi_write_sector(dev, sector, buffer,
count) == 0)
797 if (endpoint->bmAttributes == USB_ENDPOINT_XFER_BULK) {
799 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT && dev->bulkEpO < 0) {
802 dev->bulkEpO = sceUsbdOpenPipeAligned(devId, endpoint);
803 XPRINTF(
"register Output endpoint id =%i addr=%02X packetSize=%i\n", dev->bulkEpO, endpoint->bEndpointAddress, (
unsigned short int)endpoint->wMaxPacketSizeHB << 8 | endpoint->wMaxPacketSizeLB);
806 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN && dev->bulkEpI < 0) {
811 dev->bulkEpI = sceUsbdOpenPipe(devId, endpoint);
812 XPRINTF(
"register Input endpoint id =%i addr=%02X packetSize=%i\n", dev->bulkEpI, endpoint->bEndpointAddress, (
unsigned short int)endpoint->wMaxPacketSizeHB << 8 | endpoint->wMaxPacketSizeLB);
817int mass_stor_probe(
int devId)
823 XPRINTF(
"probe: devId=%i\n", devId);
825 mass_dev *mass_device = mass_stor_findDevice(devId, 0);
829 printf(
"USBHDFSD: Error - no free device descriptors!\n");
835 if (device == NULL) {
836 printf(
"USBHDFSD: Error - Couldn't get device descriptor\n");
841 if (device->bNumConfigurations < 1) {
847 if (config == NULL) {
848 printf(
"USBHDFSD: Error - Couldn't get configuration descriptor\n");
852 XPRINTF(
"bNumInterfaces %d\n", config->bNumInterfaces);
853 if ((config->bNumInterfaces < 1) ||
855 printf(
"USBHDFSD: Error - No interfaces available\n");
860 XPRINTF(
"bInterfaceClass %X bInterfaceSubClass %X bInterfaceProtocol %X\n",
861 intf->bInterfaceClass, intf->bInterfaceSubClass, intf->bInterfaceProtocol);
863 if ((intf->bInterfaceClass != USB_CLASS_MASS_STORAGE) ||
864 (intf->bInterfaceSubClass != USB_SUBCLASS_MASS_SCSI &&
865 intf->bInterfaceSubClass != USB_SUBCLASS_MASS_SFF_8070I) ||
866 (intf->bInterfaceProtocol != USB_PROTOCOL_MASS_BULK_ONLY) ||
867 (intf->bNumEndpoints < 2)) {
873int mass_stor_connect(
int devId)
884 printf(
"USBHDFSD: connect: devId=%i\n", devId);
885 dev = mass_stor_findDevice(devId, 1);
888 printf(
"USBHDFSD: Error - no free device descriptors!\n");
893 if (dev->devId != -1) {
894 printf(
"USBHDFSD: Error - device descriptor in use!\n");
905 dev->controlEp = sceUsbdOpenPipe(devId, NULL);
914 dev->interfaceNumber = interface->bInterfaceNumber;
915 dev->interfaceAlt = interface->bAlternateSetting;
917 epCount = interface->bNumEndpoints;
919 usb_bulk_probeEndpoint(devId, dev, endpoint);
921 for (i = 1; i < epCount; i++) {
923 usb_bulk_probeEndpoint(devId, dev, endpoint);
927 if (dev->bulkEpI < 0 || dev->bulkEpO < 0) {
928 mass_stor_release(dev);
929 printf(
"USBHDFSD: Error - connect failed: not enough bulk endpoints! \n");
933 SemaData.initial = 0;
937 if ((dev->ioSema = CreateSema(&SemaData)) < 0) {
938 mass_stor_release(dev);
939 printf(
"USBHDFSD: Failed to allocate I/O semaphore.\n");
945 dev->configId = config->bConfigurationValue;
947 XPRINTF(
"connect ok: epI=%i, epO=%i \n", dev->bulkEpI, dev->bulkEpO);
949 if (dev->callback != NULL)
950 dev->callback(USBMASS_DEV_EV_CONN);
955static void mass_stor_release(
mass_dev *dev)
957 if (dev->bulkEpI >= 0) {
958 sceUsbdClosePipe(dev->bulkEpI);
961 if (dev->bulkEpO >= 0) {
962 sceUsbdClosePipe(dev->bulkEpO);
971int mass_stor_disconnect(
int devId)
974 dev = mass_stor_findDevice(devId, 0);
976 printf(
"USBHDFSD: disconnect: devId=%i\n", devId);
979 printf(
"USBHDFSD: Error - disconnect: no device storage!\n");
984 mass_stor_release(dev);
985 part_disconnect(dev);
986 scache_kill(dev->cache);
990 DeleteSema(dev->ioSema);
992 if (dev->callback != NULL)
993 dev->callback(USBMASS_DEV_EV_DISCONN);
999static int mass_stor_warmup(
mass_dev *dev)
1006 XPRINTF(
"mass_stor_warmup\n");
1009 printf(
"USBHDFSD: Error - no mass storage device found!\n");
1013 stat = usb_bulk_get_max_lun(dev);
1014 printf(
"USBHDFSD: usb_bulk_get_max_lun %d\n", stat);
1017 if ((stat = cbw_scsi_inquiry(dev, &
id,
sizeof(
inquiry_data))) < 0) {
1018 printf(
"USBHDFSD: Error - cbw_scsi_inquiry %d\n", stat);
1022 printf(
"USBHDFSD:\tVendor: %.8s\n"
1023 "\t\tProduct: %.16s\n"
1024 "\t\tRevision: %.4s\n",
1025 id.vendor,
id.product,
id.revision);
1027 while ((stat = cbw_scsi_test_unit_ready(dev)) != 0) {
1028 printf(
"USBHDFSD: cbw_scsi_test_unit_ready %d\n", stat);
1030 stat = cbw_scsi_request_sense(dev, &sd,
sizeof(
sense_data));
1032 printf(
"USBHDFSD: Error - cbw_scsi_request_sense %d\n", stat);
1034 if ((sd.error_code == 0x70) && (sd.sense_key != 0x00)) {
1035 printf(
"USBHDFSD: Sense Data key: %02X code: %02X qual: %02X\n", sd.sense_key, sd.add_sense_code, sd.add_sense_qual);
1037 if ((sd.sense_key == 0x02) && (sd.add_sense_code == 0x04) && (sd.add_sense_qual == 0x02)) {
1038 printf(
"USBHDFSD: Error - Additional initalization is required for this device!\n");
1039 if ((stat = cbw_scsi_start_stop_unit(dev, 1)) != 0) {
1040 printf(
"USBHDFSD: Error - cbw_scsi_start_stop_unit %d\n", stat);
1048 printf(
"USBHDFSD: Error - cbw_scsi_read_capacity %d\n", stat);
1052 dev->sectorSize = getBI32(&rcd.block_length);
1053 dev->maxLBA = getBI32(&rcd.last_lba);
1054 printf(
"USBHDFSD: sectorSize %u maxLBA %u\n", dev->sectorSize, dev->maxLBA);
1059static int mass_store_configureDevice(
mass_dev *dev)
1062 if ((ret = usb_set_configuration(dev, dev->configId)) !=
USB_RC_OK) {
1063 printf(
"USBHDFSD: Error - sending set_configuration %d\n", ret);
1067 if ((ret = usb_set_interface(dev, dev->interfaceNumber, dev->interfaceAlt)) !=
USB_RC_OK) {
1068 printf(
"USBHDFSD: Error - sending set_interface %d\n", ret);
1071 usb_bulk_clear_halt(dev, USB_BLK_EP_IN);
1072 usb_bulk_clear_halt(dev, USB_BLK_EP_OUT);
1082int mass_stor_configureNextDevice(
void)
1086 XPRINTF(
"configuring devices... \n");
1088 for (i = 0; i < NUM_DEVICES; ++i) {
1092 ret = mass_store_configureDevice(dev);
1094 mass_stor_release(dev);
1100 ret = mass_stor_warmup(dev);
1102 printf(
"USBHDFSD: Error - failed to warmup device %d\n", dev->devId);
1103 mass_stor_release(dev);
1107 dev->cache = scache_init(dev, dev->sectorSize);
1108 if (dev->cache == NULL) {
1109 printf(
"USBHDFSD: Error - scache_init failed \n");
1110 mass_stor_release(dev);
1114 return part_connect(dev) >= 0;
1124 for (i = 0; i < NUM_DEVICES; ++i) {
1125 g_mass_device[i].status = 0;
1126 g_mass_device[i].devId = -1;
1131 driver.
name =
"mass-stor";
1132 driver.probe = mass_stor_probe;
1133 driver.connect = mass_stor_connect;
1134 driver.disconnect = mass_stor_disconnect;
1136 ret = sceUsbdRegisterLdd(&driver);
1137 XPRINTF(
"registerDriver=%i \n", ret);
1139 printf(
"USBHDFSD: register driver failed! ret=%d\n", ret);
1151 if (device >= 0 && device < NUM_DEVICES) {
1152 pDev = &g_mass_device[device];
1154 info->status = pDev->status;
1155 info->SectorSize = pDev->sectorSize;
1156 info->MaxLBA = pDev->maxLBA;
1165int UsbMassRegisterCallback(
int device, usbmass_cb_t callback)
1169 if (device >= 0 && device < NUM_DEVICES) {
1170 g_mass_device[device].callback = callback;
1174 if (callback != NULL)
1175 callback(USBMASS_DEV_EV_CONN);
1183int mass_stor_stop_unit(
mass_dev *dev)
1187 if ((stat = cbw_scsi_start_stop_unit(dev, 0)) != 0) {
1188 printf(
"USBHDFSD: Error - cbw_scsi_start_stop_unit %d\n", stat);
1194void mass_store_stop_all(
void)
1198 for (i = 0; i < NUM_DEVICES; ++i) {
1202 if (mass_store_configureDevice(dev) !=
USB_RC_OK)
1206 mass_stor_stop_unit(dev);
u32 count
start sector of fragmented bd/file
#define USBMASS_DEV_STAT_CONN
#define USBMASS_DEV_STAT_ERR
#define USBMASS_DEV_STAT_CONF