static s32 __usbstorage_clearerrors(usbstorage_handle *dev, u8 lun) { s32 retval; u8 cmd[6]; u8 sense[SCSI_SENSE_REPLY_SIZE]; u8 status = 0; memset(cmd, 0, sizeof(cmd)); cmd[0] = SCSI_TEST_UNIT_READY; retval = __cycle(dev, lun, NULL, 0, cmd, 1, 0, &status, NULL); if (retval < 0) return retval; if (status) { cmd[0] = SCSI_REQUEST_SENSE; cmd[1] = lun << 5; cmd[4] = SCSI_SENSE_REPLY_SIZE; memset(sense, 0, SCSI_SENSE_REPLY_SIZE); retval = __cycle(dev, lun, sense, SCSI_SENSE_REPLY_SIZE, cmd, 6, 0, NULL, NULL); if (retval>=0) { switch (sense[2]&0xF) { case SCSI_SENSE_NOT_READY: return USBSTORAGE_EINIT; case SCSI_SENSE_MEDIUM_ERROR: case SCSI_SENSE_HARDWARE_ERROR: return USBSTORAGE_ESENSE; } } } return retval; }
static s32 __usbstorage_clearerrors(usbstorage_handle *dev, u8 lun) { s32 retval; u8 cmd[16]; u8 *sense= USB_Alloc(SCSI_SENSE_REPLY_SIZE); u8 status = 0; memset(cmd, 0, sizeof(cmd)); cmd[0] = SCSI_TEST_UNIT_READY; retval = __cycle(dev, lun, NULL, 0, cmd, 1, 1, &status, NULL); if(retval < 0) return retval; if(status != 0) { cmd[0] = SCSI_REQUEST_SENSE; cmd[1] = lun << 5; cmd[4] = SCSI_SENSE_REPLY_SIZE; cmd[5] = 0; memset(sense, 0, SCSI_SENSE_REPLY_SIZE); retval = __cycle(dev, lun, sense, SCSI_SENSE_REPLY_SIZE, cmd, 6, 0, NULL, NULL); if(retval < 0) goto error; status = sense[2] & 0x0F; if(status == SCSI_SENSE_NOT_READY || status == SCSI_SENSE_MEDIUM_ERROR || status == SCSI_SENSE_HARDWARE_ERROR) retval = USBSTORAGE_ESENSE; } error: USB_Free(sense); return retval; }
static s32 __usbstorage_clearerrors(struct ehci_hcd * ehci, usbstorage_handle *dev, u8 lun) { s32 retval; u8 cmd[16]; u8 *sense = USB_Alloc(SCSI_SENSE_REPLY_SIZE); u8 status = 0; memset(cmd, 0, sizeof (cmd)); cmd[0] = SCSI_TEST_UNIT_READY; int n; if (!sense) return -ENOMEM; for (n = 0; n < 5; n++) { retval = __cycle(ehci, dev, lun, NULL, 0, cmd, 6, 1, &status, NULL); #ifdef MEM_PRINT s_printf(" SCSI_TEST_UNIT_READY %i# ret %i\n", n, retval); #endif if (retval == -ENODEV) goto error; if (retval == 0) break; } if (retval < 0) goto error; if (status != 0) { cmd[0] = SCSI_REQUEST_SENSE; cmd[1] = lun << 5; cmd[4] = SCSI_SENSE_REPLY_SIZE; cmd[5] = 0; memset(sense, 0, SCSI_SENSE_REPLY_SIZE); retval = __cycle(ehci, dev, lun, sense, SCSI_SENSE_REPLY_SIZE, cmd, 6, 0, NULL, NULL); #ifdef MEM_PRINT s_printf(" SCSI_REQUEST_SENSE ret %i\n", retval); #endif if (retval < 0) goto error; status = sense[2] & 0x0F; #ifdef MEM_PRINT s_printf(" SCSI_REQUEST_SENSE status %x\n", status); #endif if (status == SCSI_SENSE_NOT_READY || status == SCSI_SENSE_MEDIUM_ERROR || status == SCSI_SENSE_HARDWARE_ERROR) retval = USBSTORAGE_ESENSE; } error: USB_Free(sense); return retval; }
s32 USBStorageOGC_Inquiry(usbstorage_handle *dev, u8 lun) { int n; s32 retval; u8 cmd[] = {SCSI_INQUIRY, lun << 5,0,0,36,0}; u8 response[36]; for(n=0;n<2;n++) { memset(response,0,36); retval = __cycle(dev, lun, response, 36, cmd, 6, 0, NULL, NULL); if(retval>=0) break; } if(retval>=0) retval=*response & 31; /* if(retval>=0) { switch(retval) { // info from http://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type case 5: // CDROM case 7: // optical memory device (e.g., some optical disks) __dvd_mounted = 1; break; default: __dvd_mounted = 0; break; } } */ return retval; }
int USBStorageOGC_ioctl(int request, ...) { int retval = 0; va_list ap; if(!__mounted) return -1; va_start(ap, request); switch (request) { case B_RAW_DEVICE_COMMAND: { u8 write; raw_device_command *rdc = va_arg(ap, raw_device_command *); write = (rdc->flags == B_RAW_DEVICE_DATA_IN) ? 0 : 1; retval = __cycle(&__usbfd, __lun, rdc->data, rdc->data_length, rdc->command, rdc->command_length, write, &rdc->scsi_status, NULL); break; } default: retval = -1; break; } va_end(ap); return retval; }
static s32 __usbstorage_start_stop(usbstorage_handle *dev, u8 lun, u8 start_stop) { #if 0 s32 retval; u8 cmd[16]; u8 status = 0; memset(cmd, 0, sizeof (cmd)); cmd[0] = SCSI_START_STOP; cmd[1] = (lun << 5) | 1; cmd[4] = start_stop & 3; cmd[5] = 0; //memset(sense, 0, SCSI_SENSE_REPLY_SIZE); retval = __cycle(dev, lun, NULL, 0, cmd, 6, 0, &status, NULL); // if(retval < 0) goto error; /* if(status == SCSI_SENSE_NOT_READY || status == SCSI_SENSE_MEDIUM_ERROR || status == SCSI_SENSE_HARDWARE_ERROR) retval = USBSTORAGE_ESENSE;*/ //error: return retval; #else return 0; #endif }
s32 USBStorage_Write(usbstorage_handle *dev, u8 lun, u32 sector, u16 n_sectors, const u8 *buffer) { u8 status = 0; s32 retval; u8 cmd[] = { SCSI_WRITE_10, lun << 5, sector >> 24, sector >> 16, sector >> 8, sector, 0, n_sectors >> 8, n_sectors, 0 }; if(lun >= dev->max_lun || dev->sector_size[lun] == 0) return IPC_EINVAL; // more than 60s since last use - make sure drive is awake if(ticks_to_secs(gettime() - usb_last_used) > 60) { usbtimeout = 10; if(method==0) { USB_ResumeDevice(dev->usb_fd); if(dev->bInterfaceSubClass == MASS_STORAGE_SCSI_COMMANDS) { retval = __usbstorage_clearerrors(dev, lun); if (retval < 0) return retval; retval = USBStorage_StartStop(dev, lun, 0, 1, 0); if (retval < 0) return retval; } } else if(method==2) { __usbstorage_clearerrors(dev, lun); } } retval = __cycle(dev, lun, (u8 *)buffer, n_sectors * dev->sector_size[lun], cmd, sizeof(cmd), 1, &status, NULL); if(retval > 0 && status != 0) retval = USBSTORAGE_ESTATUS; usb_last_used = gettime(); usbtimeout = USBSTORAGE_TIMEOUT; return retval; }
s32 USBStorage_Inquiry(usbstorage_handle *dev, u8 lun) { s32 retval; u8 cmd[] = {SCSI_INQUIRY, lun << 5,0,0,36,0}; u8 *response = USB_Alloc(36); USB_LOG("Inquiring about SCSI drive\n"); retval = __cycle(dev, lun, response, 36, cmd, 6, 0, NULL, NULL); //print_hex_dump_bytes("inquiry result:",DUMP_PREFIX_OFFSET,response,36); USB_Free(response); return retval; }
s32 USBStorage_Inquiry(struct ehci_hcd * ehci, usbstorage_handle *dev, u8 lun) { s32 retval; u8 cmd[] = {SCSI_INQUIRY, lun << 5, 0, 0, 36, 0}; u8 *response = USB_Alloc(36); if (!response) return -ENOMEM; retval = __cycle(ehci, dev, lun, response, 36, cmd, 6, 0, NULL, NULL); //print_hex_dump_bytes("inquiry result:",DUMP_PREFIX_OFFSET,response,36); USB_Free(response); return retval; }
s32 USBStorageOGC_ReadCapacity(usbstorage_handle *dev, u8 lun, u32 *sector_size, u32 *n_sectors) { s32 retval; u8 cmd[10] = {SCSI_READ_CAPACITY, lun<<5}; u8 response[8]; retval = __cycle(dev, lun, response, sizeof(response), cmd, sizeof(cmd), 0, NULL, NULL); if(retval >= 0) { if(n_sectors != NULL) memcpy(n_sectors, response, 4); if(sector_size != NULL) memcpy(sector_size, response + 4, 4); retval = USBSTORAGE_OK; } return retval; }
s32 USBStorage_ReadCapacity(struct ehci_hcd * ehci, usbstorage_handle *dev, u8 lun, u32 *sector_size, u32 *n_sectors) { s32 retval; u8 cmd[] = {SCSI_READ_CAPACITY, lun << 5}; u8 *response = USB_Alloc(8); u32 val; if (!response) return -ENOMEM; retval = __cycle(ehci, dev, lun, response, 8, cmd, 2, 0, NULL, NULL); if (retval >= 0) { memcpy(&val, response, 4); if (n_sectors != NULL) *n_sectors = be32_to_cpu(val); memcpy(&val, response + 4, 4); if (sector_size != NULL) *sector_size = be32_to_cpu(val); retval = USBSTORAGE_OK; } USB_Free(response); return retval; }
static s32 __USBStorage_Write(struct ehci_hcd * ehci, usbstorage_handle *dev, u8 lun, u32 sector, u16 n_sectors, const u8 *buffer) { u8 status = 0; s32 retval; u8 cmd[] = { SCSI_WRITE_10, lun << 5, sector >> 24, sector >> 16, sector >> 8, sector, 0, n_sectors >> 8, n_sectors, 0 }; if (lun >= dev->max_lun || dev->sector_size[lun] == 0) return -EINVAL; retval = __cycle(ehci, dev, lun, (u8 *) buffer, n_sectors * dev->sector_size[lun], cmd, sizeof (cmd), 1, &status, NULL); if (retval > 0 && status != 0) retval = USBSTORAGE_ESTATUS; return retval; }
s32 USBStorage_Read(usbstorage_handle *dev, u8 lun, u32 sector, u16 n_sectors, u8 *buffer) { u8 status = 0; s32 retval; u8 cmd[] = { SCSI_READ_10, lun << 5, sector >> 24, sector >> 16, sector >> 8, sector, 0, n_sectors >> 8, n_sectors, 0 }; if(lun >= dev->max_lun || dev->sector_size[lun] == 0) return -EINVAL; retval = __cycle(dev, lun, buffer, n_sectors * dev->sector_size[lun], cmd, sizeof(cmd), 0, &status, NULL); if(retval > 0 && status != 0) retval = USBSTORAGE_ESTATUS; return retval; }
s32 USBStorageOGC_Write(usbstorage_handle *dev, u8 lun, u32 sector, u16 n_sectors, const u8 *buffer) { u8 status = 0; s32 retval; u8 cmd[] = { SCSI_WRITE_10, lun << 5, sector >> 24, sector >> 16, sector >> 8, sector, 0, n_sectors >> 8, n_sectors, 0 }; if(lun >= dev->max_lun || dev->sector_size[lun] == 0) return IPC_EINVAL; // more than 60s since last use - make sure drive is awake if(ticks_to_secs(gettime() - usb_last_used) > 60) { usbtimeout = 10; USBStorageOGC_MountLUN(dev, lun); } retval = __cycle(dev, lun, (u8 *)buffer, n_sectors * dev->sector_size[lun], cmd, sizeof(cmd), 1, &status, NULL); if(retval > 0 && status != 0) retval = USBSTORAGE_ESTATUS; usb_last_used = gettime(); usbtimeout = USBSTORAGE_TIMEOUT; return retval; }
s32 USBStorage_Read(usbstorage_handle *dev, u8 lun, u32 sector, u16 n_sectors, u8 *buffer) { u8 status = 0; s32 retval; u8 cmd[] = { SCSI_READ_10, lun << 5, sector >> 24, sector >> 16, sector >> 8, sector, 0, n_sectors >> 8, n_sectors, 0 }; usb_log("USBStorage_Read sector: %i num: %i\n",sector,n_sectors); if(lun >= dev->max_lun || dev->sector_size[lun] == 0) return IPC_EINVAL; // more than 60s since last use - make sure drive is awake if(ticks_to_secs(gettime() - usb_last_used) > 60) { usbtimeout = 10; usb_log("usbtimeout = 10\n"); if(method==0) { retval = USB_ResumeDevice(dev->usb_fd); usb_log("USB_ResumeDevice ret: %i\n",retval); if(dev->bInterfaceSubClass == MASS_STORAGE_SCSI_COMMANDS) { retval = __usbstorage_clearerrors(dev, lun); usb_log("__usbstorage_clearerrors ret: %i\n",retval); if (retval < 0) return retval; retval = USBStorage_StartStop(dev, lun, 0, 1, 0); usb_log("USBStorage_StartStop ret: %i\n",retval); if (retval < 0) return retval; } } else if(method==2) { retval = __usbstorage_clearerrors(dev, lun); usb_log("__usbstorage_clearerrors ret: %i\n",retval); } else if(method==3) { retval = __usbstorage_clearerrors(dev, lun); usb_log("__usbstorage_clearerrors ret: %i\n",retval); retval = USBStorage_StartStop(dev, lun, 0, 1, 0); usb_log("USBStorage_StartStop ret: %i\n",retval); usleep(100); } } retval = __cycle(dev, lun, buffer, n_sectors * dev->sector_size[lun], cmd, sizeof(cmd), 0, &status, NULL); usb_log("USBStorage_Read __cycle ret: %i status: %i\n",retval,status); if(retval > 0 && status != 0) retval = USBSTORAGE_ESTATUS; usb_last_used = gettime(); usbtimeout = USBSTORAGE_TIMEOUT; usb_log("usbtimeout = %i\n",usbtimeout); return retval; }