void usb_stor_transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us) { /* send the command to the transport layer */ usb_stor_invoke_transport(srb, us); if (srb->result == SAM_STAT_GOOD) { /* Fix the INQUIRY data if necessary */ fix_inquiry_data(srb); /* Fix the READ CAPACITY result if necessary */ if (us->flags & US_FL_FIX_CAPACITY) fix_read_capacity(srb); } }
void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us) { /* fix some commands -- this is a form of mode translation * UFI devices only accept 12 byte long commands * * NOTE: This only works because a Scsi_Cmnd struct field contains * a unsigned char cmnd[16], so we know we have storage available */ /* Pad the ATAPI command with zeros */ for (; srb->cmd_len<12; srb->cmd_len++) srb->cmnd[srb->cmd_len] = 0; /* set command length to 12 bytes (this affects the transport layer) */ srb->cmd_len = 12; /* XXX We should be constantly re-evaluating the need for these */ /* determine the correct data length for these commands */ switch (srb->cmnd[0]) { /* for INQUIRY, UFI devices only ever return 36 bytes */ case INQUIRY: srb->cmnd[4] = 36; break; /* again, for MODE_SENSE_10, we get the minimum (8) */ case MODE_SENSE_10: srb->cmnd[7] = 0; srb->cmnd[8] = 8; break; /* for REQUEST_SENSE, UFI devices only ever return 18 bytes */ case REQUEST_SENSE: srb->cmnd[4] = 18; break; } /* end switch on cmnd[0] */ /* send the command to the transport layer */ usb_stor_invoke_transport(srb, us); if (srb->result == SAM_STAT_GOOD) { /* Fix the data for an INQUIRY, if necessary */ fix_inquiry_data(srb); } }
/*********************************************************************** * Protocol routines ***********************************************************************/ void UMAS_Qic157Command(SCSI_CMD_T *srb, UMAS_DATA_T *umas) { /* * Pad the ATAPI command with zeros * NOTE: This only works because a SCSI_CMD_T struct field contains * a uint8_t cmnd[12], so we know we have storage available */ for(; srb->cmd_len < 12; srb->cmd_len++) srb->cmnd[srb->cmd_len] = 0; /* set command length to 12 bytes */ srb->cmd_len = 12; /* send the command to the transport layer */ UMAS_InvokeTransport(srb, umas); /* fix the INQUIRY data if necessary */ fix_inquiry_data(srb); }
void usb_stor_qic157_command(Scsi_Cmnd *srb, struct us_data *us) { /* Pad the ATAPI command with zeros * * NOTE: This only works because a Scsi_Cmnd struct field contains * a unsigned char cmnd[16], so we know we have storage available */ for (; srb->cmd_len<12; srb->cmd_len++) srb->cmnd[srb->cmd_len] = 0; /* set command length to 12 bytes */ srb->cmd_len = 12; /* send the command to the transport layer */ usb_stor_invoke_transport(srb, us); if (srb->result == SAM_STAT_GOOD) { /* fix the INQUIRY data if necessary */ fix_inquiry_data(srb); } }
void UMAS_TransparentScsiCommand(SCSI_CMD_T *srb, UMAS_DATA_T *umas) { /* * This code supports devices which do not support {READ|WRITE}_6 * Apparently, neither Windows or MacOS will use these commands, * so some devices do not support them */ if(umas->flags & UMAS_FL_MODE_XLATE) { /* translate READ_6 to READ_10 */ if(srb->cmnd[0] == READ_6) { /* get the control */ srb->cmnd[9] = umas->srb.cmnd[5]; /* get the length */ srb->cmnd[8] = umas->srb.cmnd[6]; srb->cmnd[7] = 0; /* set the reserved area to 0 */ srb->cmnd[6] = 0; /* get LBA */ srb->cmnd[5] = umas->srb.cmnd[3]; srb->cmnd[4] = umas->srb.cmnd[2]; srb->cmnd[3] = 0; srb->cmnd[2] = 0; /* LUN and other info in cmnd[1] can stay */ /* fix command code */ srb->cmnd[0] = 0x28; UMAS_DEBUG("Changing READ_6 to READ_10\n"); UMAS_DEBUG_ShowCommand(srb); } /* translate WRITE_6 to WRITE_10 */ if(srb->cmnd[0] == WRITE_6) { /* get the control */ srb->cmnd[9] = umas->srb.cmnd[5]; /* get the length */ srb->cmnd[8] = umas->srb.cmnd[4]; srb->cmnd[7] = 0; /* set the reserved area to 0 */ srb->cmnd[6] = 0; /* get LBA */ srb->cmnd[5] = umas->srb.cmnd[3]; srb->cmnd[4] = umas->srb.cmnd[2]; srb->cmnd[3] = 0; srb->cmnd[2] = 0; /* LUN and other info in cmnd[1] can stay */ /* fix command code */ srb->cmnd[0] = 0x2A; UMAS_DEBUG("Changing WRITE_6 to WRITE_10\n"); UMAS_DEBUG_ShowCommand(&umas->srb); } } /* if (umas->flags & UMAS_FL_MODE_XLATE) */ /* send the command to the transport layer */ UMAS_InvokeTransport(srb, umas); /* fix the INQUIRY data if necessary */ fix_inquiry_data(srb); }
void UMAS_UfiCommand(SCSI_CMD_T *srb, UMAS_DATA_T *umas) { int old_cmnd = 0; /* * fix some commands -- this is a form of mode translation * UFI devices only accept 12 byte long commands * * NOTE: This only works because a SCSI_CMD_T struct field contains * a uint8_t cmnd[12], so we know we have storage available */ /* set command length to 12 bytes (this affects the transport layer) */ srb->cmd_len = 12; /* determine the correct (or minimum) data length for these commands */ switch(srb->cmnd[0]) { /* for INQUIRY, UFI devices only ever return 36 bytes */ case INQUIRY: srb->cmnd[4] = 36; break; /* change MODE_SENSE/MODE_SELECT from 6 to 10 byte commands */ case MODE_SENSE: case MODE_SELECT: /* save the command so we can tell what it was */ old_cmnd = srb->cmnd[0]; srb->cmnd[11] = 0; srb->cmnd[10] = 0; srb->cmnd[9] = 0; /* * If we're sending data, we send all. If getting data, * get the minimum */ if(srb->cmnd[0] == MODE_SELECT) srb->cmnd[8] = srb->cmnd[4]; else srb->cmnd[8] = 8; srb->cmnd[7] = 0; srb->cmnd[6] = 0; srb->cmnd[5] = 0; srb->cmnd[4] = 0; srb->cmnd[3] = 0; srb->cmnd[2] = srb->cmnd[2]; srb->cmnd[1] = srb->cmnd[1]; srb->cmnd[0] = srb->cmnd[0] | 0x40; break; /* again, for MODE_SENSE_10, we get the minimum (8) */ case MODE_SENSE_10: srb->cmnd[7] = 0; srb->cmnd[8] = 8; break; /* for REQUEST_SENSE, UFI devices only ever return 18 bytes */ case REQUEST_SENSE: srb->cmnd[4] = 18; break; /* change READ_6/WRITE_6 to READ_10/WRITE_10, which are UFI commands */ case WRITE_6: case READ_6: srb->cmnd[11] = 0; srb->cmnd[10] = 0; srb->cmnd[9] = 0; srb->cmnd[8] = srb->cmnd[4]; srb->cmnd[7] = 0; srb->cmnd[6] = 0; srb->cmnd[5] = srb->cmnd[3]; srb->cmnd[4] = srb->cmnd[2]; srb->cmnd[3] = srb->cmnd[1] & 0x1F; srb->cmnd[2] = 0; srb->cmnd[1] = srb->cmnd[1] & 0xE0; srb->cmnd[0] = srb->cmnd[0] | 0x20; break; } /* end switch on cmnd[0] */ /* convert MODE_SELECT data here */ if(old_cmnd == MODE_SELECT) usb_stor_scsiSense6to10(srb); /* send the command to the transport layer */ UMAS_InvokeTransport(srb, umas); /* Fix the MODE_SENSE data if we translated the command */ if((old_cmnd == MODE_SENSE) && (status_byte(srb->result) == GOOD)) usb_stor_scsiSense10to6(srb); /* Fix the data for an INQUIRY, if necessary */ fix_inquiry_data(srb); }
void UMAS_AtapiCommand(SCSI_CMD_T *srb, UMAS_DATA_T *umas) { int old_cmnd = 0; /* * Fix some commands -- this is a form of mode translation * ATAPI devices only accept 12 byte long commands * * NOTE: This only works because a SCSI_CMD_T struct field contains * a uint8_t cmnd[12], so we know we have storage available */ /* Pad the ATAPI command with zeros */ for(; srb->cmd_len < 12; srb->cmd_len++) srb->cmnd[srb->cmd_len] = 0; /* set command length to 12 bytes */ srb->cmd_len = 12; /* determine the correct (or minimum) data length for these commands */ switch(srb->cmnd[0]) { /* change MODE_SENSE/MODE_SELECT from 6 to 10 byte commands */ case MODE_SENSE: case MODE_SELECT: /* save the command so we can tell what it was */ old_cmnd = srb->cmnd[0]; srb->cmnd[11] = 0; srb->cmnd[10] = 0; srb->cmnd[9] = 0; srb->cmnd[8] = srb->cmnd[4]; srb->cmnd[7] = 0; srb->cmnd[6] = 0; srb->cmnd[5] = 0; srb->cmnd[4] = 0; srb->cmnd[3] = 0; srb->cmnd[2] = srb->cmnd[2]; srb->cmnd[1] = srb->cmnd[1]; srb->cmnd[0] = srb->cmnd[0] | 0x40; break; /* change READ_6/WRITE_6 to READ_10/WRITE_10, which are ATAPI commands */ case WRITE_6: case READ_6: srb->cmnd[11] = 0; srb->cmnd[10] = 0; srb->cmnd[9] = 0; srb->cmnd[8] = srb->cmnd[4]; srb->cmnd[7] = 0; srb->cmnd[6] = 0; srb->cmnd[5] = srb->cmnd[3]; srb->cmnd[4] = srb->cmnd[2]; srb->cmnd[3] = srb->cmnd[1] & 0x1F; srb->cmnd[2] = 0; srb->cmnd[1] = srb->cmnd[1] & 0xE0; srb->cmnd[0] = srb->cmnd[0] | 0x20; break; } /* end switch on cmnd[0] */ /* convert MODE_SELECT data here */ if(old_cmnd == MODE_SELECT) usb_stor_scsiSense6to10(srb); /* send the command to the transport layer */ UMAS_InvokeTransport(srb, umas); /* Fix the MODE_SENSE data if we translated the command */ if((old_cmnd == MODE_SENSE) && (status_byte(srb->result) == GOOD)) usb_stor_scsiSense10to6(srb); /* fix the INQUIRY data if necessary */ fix_inquiry_data(srb); }