inline int cbw_scsi_start_stop_unit(mass_dev* dev) { int ret; cbw_packet cbw; XPRINTF("USBHDFSD: cbw_scsi_start_stop_unit\n"); cbw.signature = CBW_TAG; cbw.lun = 0; cbw.tag = -TAG_START_STOP_UNIT; cbw.dataTransferLength = 0; //START_STOP_REPLY_LENGTH cbw.flags = 0x80; //inquiry data will flow In cbw.comLength = 12; //scsi command packet cbw.comData[0] = 0x1B; //start stop unit operation code cbw.comData[1] = 1; //lun/reserved/immed cbw.comData[2] = 0; //reserved cbw.comData[3] = 0; //reserved cbw.comData[4] = 1; //reserved/LoEj/Start "Start the media and acquire the format type" cbw.comData[5] = 0; //reserved cbw.comData[6] = 0; //reserved cbw.comData[7] = 0; //reserved cbw.comData[8] = 0; //reserved cbw.comData[9] = 0; //reserved cbw.comData[10] = 0; //reserved cbw.comData[11] = 0; //reserved usb_bulk_command(dev, &cbw); ret = usb_bulk_manage_status(dev, -TAG_START_STOP_UNIT); return ret; }
inline int cbw_scsi_test_unit_ready(mass_dev* dev) { int ret; cbw_packet cbw; XPRINTF("USBHDFSD: cbw_scsi_test_unit_ready\n"); cbw.signature = CBW_TAG; cbw.lun = 0; cbw.tag = -TAG_TEST_UNIT_READY; cbw.dataTransferLength = 0; //TUR_REPLY_LENGTH cbw.flags = 0x80; //data will flow In cbw.comLength = 12; //scsi command packet cbw.comData[0] = 0x00; //test unit ready operation code cbw.comData[1] = 0; //lun/reserved cbw.comData[2] = 0; //reserved cbw.comData[3] = 0; //reserved cbw.comData[4] = 0; //reserved cbw.comData[5] = 0; //reserved cbw.comData[6] = 0; //reserved cbw.comData[7] = 0; //reserved cbw.comData[8] = 0; //reserved cbw.comData[9] = 0; //reserved cbw.comData[10] = 0; //reserved cbw.comData[11] = 0; //reserved usb_bulk_command(dev, &cbw); ret = usb_bulk_manage_status(dev, -TAG_TEST_UNIT_READY); return ret; }
inline int cbw_scsi_read_capacity(mass_dev* dev, void *buffer, int size) { int ret; cbw_packet cbw; int retryCount; XPRINTF("USBHDFSD: cbw_scsi_read_capacity\n"); cbw.signature = CBW_TAG; cbw.lun = 0; cbw.tag = -TAG_READ_CAPACITY; cbw.dataTransferLength = size; //READ_CAPACITY_REPLY_LENGTH cbw.flags = 0x80; //inquiry data will flow In cbw.comLength = 12; //scsi command packet cbw.comData[0] = 0x25; //read capacity operation code cbw.comData[1] = 0; //lun/reserved/RelAdr cbw.comData[2] = 0; //LBA 1 cbw.comData[3] = 0; //LBA 2 cbw.comData[4] = 0; //LBA 3 cbw.comData[5] = 0; //LBA 4 cbw.comData[6] = 0; //Reserved cbw.comData[7] = 0; //Reserved cbw.comData[8] = 0; //Reserved/PMI cbw.comData[9] = 0; //reserved cbw.comData[10] = 0; //reserved cbw.comData[11] = 0; //reserved ret = 1; retryCount = 6; while (ret != 0 && retryCount > 0) { usb_bulk_command(dev, &cbw); ret = usb_bulk_transfer(dev->bulkEpI, buffer, size); if (ret != 0) printf("USBHDFSD: cbw_scsi_read_capacity error from usb_bulk_transfer %d\n", ret); //HACK HACK HACK !!! //according to usb doc we should allways //attempt to read the CSW packet. But in some cases //reading of CSW packet just freeze ps2....:-( if (ret == USB_RC_STALL) { XPRINTF("USBHDFSD: call reset recovery ...\n"); usb_bulk_reset(dev, 1); } else { ret = usb_bulk_manage_status(dev, -TAG_READ_CAPACITY); } retryCount--; } return ret; }
static inline int cbw_scsi_write_sector(mass_dev* dev, unsigned int lba, const void* buffer, unsigned short int sectorCount) { int rcode, result; static cbw_packet cbw={ CBW_TAG, // cbw.signature -TAG_WRITE, // cbw.tag 0, // cbw.dataTransferLength 0, // cbw.flags 0, // cbw.lun 12, // cbw.comLength /* scsi command packet */ { 0x2A, //write operation code 0, //LUN/DPO/FUA/Reserved/Reldr 0, //lba 1 (MSB) 0, //lba 2 0, //lba 3 0, //lba 4 (LSB) 0, //Reserved 0, //Transfer length MSB 0, //Transfer length LSB 0, //reserved 0, //reserved 0, //reserved } }; XPRINTF("USBHDFSD: cbw_scsi_write_sector - 0x%08x %p 0x%04x\n", lba, buffer, sectorCount); cbw.dataTransferLength = dev->sectorSize * sectorCount; //scsi command packet cbw.comData[2] = (lba & 0xFF000000) >> 24; //lba 1 (MSB) cbw.comData[3] = (lba & 0xFF0000) >> 16; //lba 2 cbw.comData[4] = (lba & 0xFF00) >> 8; //lba 3 cbw.comData[5] = (lba & 0xFF); //lba 4 (LSB) cbw.comData[7] = (sectorCount & 0xFF00) >> 8; //Transfer length MSB cbw.comData[8] = (sectorCount & 0xFF); //Transfer length LSB result = -EIO; if(usb_bulk_command(dev, &cbw) == USB_RC_OK){ rcode = usb_bulk_transfer(dev, USB_BLK_EP_OUT, (void*)buffer, dev->sectorSize * sectorCount); result = usb_bulk_manage_status(dev, -TAG_WRITE); if(rcode != USB_RC_OK) result = -EIO; } return result; }
static inline int cbw_scsi_inquiry(mass_dev* dev, void *buffer, int size) { int rcode, result, retries; static cbw_packet cbw={ CBW_TAG, // cbw.signature -TAG_INQUIRY, // cbw.tag 0, // cbw.dataTransferLength 0x80, // cbw.flags 0, // cbw.lun 12, // cbw.comLength /* scsi command packet */ { 0x12, // inquiry operation code 0, // lun/reserved 0, // reserved 0, // reserved 0, // inquiry reply length 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved } }; XPRINTF("USBHDFSD: cbw_scsi_inquiry\n"); cbw.dataTransferLength = size; //INQUIRY_REPLY_LENGTH cbw.comData[4] = size; //inquiry reply length for(retries = USB_XFER_MAX_RETRIES; retries > 0; retries--){ if(usb_bulk_command(dev, &cbw) == USB_RC_OK){ rcode = usb_bulk_transfer(dev, USB_BLK_EP_IN, buffer, size); result = usb_bulk_manage_status(dev, -TAG_INQUIRY); if(rcode == USB_RC_OK && result == 0) return 0; } } return -EIO; }
static inline int cbw_scsi_request_sense(mass_dev* dev, void *buffer, int size) { int rcode, result, retries; static cbw_packet cbw={ CBW_TAG, // cbw.signature -TAG_REQUEST_SENSE, // cbw.tag 0, // cbw.dataTransferLength 0x80, // cbw.flags 0, // cbw.lun 12, // cbw.comLength /* scsi command packet */ { 0x03, // request sense operation code 0, // lun/reserved 0, // reserved 0, // reserved 0, // allocation length 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved } }; cbw.dataTransferLength = size; cbw.comData[4] = size; XPRINTF("USBHDFSD: cbw_scsi_request_sense\n"); for(retries = USB_XFER_MAX_RETRIES; retries > 0; retries--){ if(usb_bulk_command(dev, &cbw) == USB_RC_OK){ rcode = usb_bulk_transfer(dev, USB_BLK_EP_IN, buffer, size); result = usb_bulk_manage_status(dev, -TAG_REQUEST_SENSE); if(rcode == USB_RC_OK && result == 0) return 0; } } return -EIO; }
static inline int cbw_scsi_read_capacity(mass_dev* dev, void *buffer, int size) { int rcode, result, retries; static cbw_packet cbw={ CBW_TAG, // cbw.signature -TAG_READ_CAPACITY, // cbw.tag 0, // cbw.dataTransferLength 0x80, // cbw.flags 0, // cbw.lun 12, // cbw.comLength /* scsi command packet */ { 0x25, // read capacity operation code 0, // lun/reserved/RelAdr 0, // LBA 1 0, // LBA 2 0, // LBA 3 0, // LBA 4 0, // reserved 0, // reserved 0, // reserved/PMI 0, // reserved 0, // reserved 0, // reserved } }; cbw.dataTransferLength = size; XPRINTF("USBHDFSD: cbw_scsi_read_capacity\n"); for(retries = USB_XFER_MAX_RETRIES; retries > 0; retries--){ if(usb_bulk_command(dev, &cbw) == USB_RC_OK){ rcode = usb_bulk_transfer(dev, USB_BLK_EP_IN, buffer, size); result = usb_bulk_manage_status(dev, -TAG_READ_CAPACITY); if(rcode == USB_RC_OK && result == 0) return 0; } } return -EIO; }
static inline int cbw_scsi_start_stop_unit(mass_dev* dev) { int result, retries; static cbw_packet cbw={ CBW_TAG, // cbw.signature -TAG_START_STOP_UNIT, // cbw.tag 0, // cbw.dataTransferLength 0x80, // cbw.flags 0, // cbw.lun 12, // cbw.comLength /* scsi command packet */ { 0x1B, // start stop unit operation code 0, // lun/reserved/immed 0, // reserved 0, // reserved 1, // reserved/LoEj/Start "Start the media and acquire the format type" 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved } }; XPRINTF("USBHDFSD: cbw_scsi_start_stop_unit\n"); for(result = -EIO, retries = USB_XFER_MAX_RETRIES; retries > 0; retries--){ if(usb_bulk_command(dev, &cbw) == USB_RC_OK){ if((result = usb_bulk_manage_status(dev, -TAG_START_STOP_UNIT)) == 0) break; } } return result; }
static inline int cbw_scsi_test_unit_ready(mass_dev* dev) { int result, retries; static cbw_packet cbw={ CBW_TAG, // cbw.signature -TAG_TEST_UNIT_READY, // cbw.tag 0, // cbw.dataTransferLength 0x80, // cbw.flags 0, // cbw.lun 12, // cbw.comLength /* scsi command packet */ { 0x00, // test unit ready operation code 0, // lun/reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved 0, // reserved } }; XPRINTF("USBHDFSD: cbw_scsi_test_unit_ready\n"); for(result = -EIO, retries = USB_XFER_MAX_RETRIES; retries > 0; retries--){ if(usb_bulk_command(dev, &cbw) == USB_RC_OK){ if((result = usb_bulk_manage_status(dev, -TAG_TEST_UNIT_READY)) >= 0) break; } } return result; }
inline int cbw_scsi_inquiry(mass_dev* dev, void *buffer, int size) { int ret; cbw_packet cbw; XPRINTF("USBHDFSD: cbw_scsi_inquiry\n"); cbw.signature = CBW_TAG; cbw.lun = 0; cbw.tag = -TAG_INQUIRY; cbw.dataTransferLength = size; //INQUIRY_REPLY_LENGTH cbw.flags = 0x80; //inquiry data will flow In cbw.comLength = 12; //scsi command packet cbw.comData[0] = 0x12; //inquiry operation code cbw.comData[1] = 0; //lun/reserved cbw.comData[2] = 0; //page code cbw.comData[3] = 0; //reserved cbw.comData[4] = size; //inquiry reply length cbw.comData[5] = 0; //reserved cbw.comData[6] = 0; //reserved cbw.comData[7] = 0; //reserved cbw.comData[8] = 0; //reserved cbw.comData[9] = 0; //reserved cbw.comData[10] = 0; //reserved cbw.comData[11] = 0; //reserved usb_bulk_command(dev, &cbw); ret = usb_bulk_transfer(dev->bulkEpI, buffer, size); if (ret != 0) printf("USBHDFSD: cbw_scsi_inquiry error from usb_bulk_transfer %d\n", ret); usb_bulk_manage_status(dev, -TAG_INQUIRY); return ret; // TODO What to return??? }
inline int cbw_scsi_write_sector(mass_dev* dev, int lba, void* buffer, int sectorSize, int sectorCount) { int ret; cbw_packet cbw; XPRINTF("USBHDFSD: cbw_scsi_write_sector\n"); cbw.signature = CBW_TAG; cbw.lun = 0; cbw.tag = -TAG_WRITE; cbw.dataTransferLength = sectorSize * sectorCount; cbw.flags = 0x00; //write data will flow Out cbw.comLength = 12; //scsi command packet cbw.comData[0] = 0x2A; //write operation code cbw.comData[1] = 0; //LUN/DPO/FUA/Reserved/Reldr cbw.comData[2] = (lba & 0xFF000000) >> 24; //lba 1 (MSB) cbw.comData[3] = (lba & 0xFF0000) >> 16; //lba 2 cbw.comData[4] = (lba & 0xFF00) >> 8; //lba 3 cbw.comData[5] = (lba & 0xFF); //lba 4 (LSB) cbw.comData[6] = 0; //Reserved cbw.comData[7] = (sectorCount & 0xFF00) >> 8; //Transfer length MSB cbw.comData[8] = (sectorCount & 0xFF); //Transfer length LSB cbw.comData[9] = 0; //reserved cbw.comData[10] = 0; //reserved cbw.comData[11] = 0; //reserved usb_bulk_command(dev, &cbw); ret = usb_bulk_transfer(dev->bulkEpO, buffer, sectorSize * sectorCount); if (ret != 0) printf("USBHDFSD: cbw_scsi_write_sector error from usb_bulk_transfer %d\n", ret); ret = usb_bulk_manage_status(dev, -TAG_WRITE); return ret; }
inline int cbw_scsi_request_sense(mass_dev* dev, void *buffer, int size) { int ret; cbw_packet cbw; XPRINTF("USBHDFSD: cbw_scsi_request_sense\n"); cbw.signature = CBW_TAG; cbw.lun = 0; cbw.tag = -TAG_REQUEST_SENSE; cbw.dataTransferLength = size; //REQUEST_SENSE_REPLY_LENGTH cbw.flags = 0x80; //sense data will flow In cbw.comLength = 12; //scsi command packet cbw.comData[0] = 0x03; //request sense operation code cbw.comData[1] = 0; //lun/reserved cbw.comData[2] = 0; //reserved cbw.comData[3] = 0; //reserved cbw.comData[4] = size; //allocation length cbw.comData[5] = 0; //reserved cbw.comData[6] = 0; //reserved cbw.comData[7] = 0; //reserved cbw.comData[8] = 0; //reserved cbw.comData[9] = 0; //reserved cbw.comData[10] = 0; //reserved cbw.comData[11] = 0; //reserved usb_bulk_command(dev, &cbw); ret = usb_bulk_transfer(dev->bulkEpI, buffer, size); if (ret != 0) printf("USBHDFSD: cbw_scsi_request_sense error from usb_bulk_transfer %d\n", ret); ret = usb_bulk_manage_status(dev, -TAG_REQUEST_SENSE); return ret; }