Ugh. Is there no way to convince the SCSI people to add an autosense request size field to the SRB?
History has told us that doing much of anything based on cmnd[0] is a good way to get bitten very badly... Matt On Mon, Dec 05, 2005 at 03:55:56PM -0800, Timothy Thelin wrote: > The sense data length for auto-sense behavior is now determined in a > separate function that is aware of SAT passthru returning 22 bytes of > sense data instead of the normal 18. 22 bytes is used only if the > device is SCSI/RBC and the previous command was a sat passthru command. > > Signed-off-by: Timothy Thelin <[EMAIL PROTECTED]> > > --- > > diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c > index 7ca896a..10d1b49 100644 > --- a/drivers/usb/storage/transport.c > +++ b/drivers/usb/storage/transport.c > @@ -521,6 +521,14 @@ int usb_stor_bulk_transfer_sg(struct us_ > * Transport routines > ***********************************************************************/ > > +static inline unsigned usb_stor_sense_data_len(struct scsi_cmnd *srb, struct > us_data *us) > +{ > + if ((us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI) && > + (srb->cmnd[0] == ATA_12 || srb->cmnd[0] == ATA_16)) > + return 22; > + return 18; > +} > + > /* Invoke the transport and basic error-handling/recovery methods > * > * This is used by the protocol layers to actually send the message to > @@ -611,9 +619,13 @@ void usb_stor_invoke_transport(struct sc > unsigned char old_cmd_len; > unsigned char old_cmnd[MAX_COMMAND_SIZE]; > int old_resid; > + unsigned sense_data_len; > > US_DEBUGP("Issuing auto-REQUEST_SENSE\n"); > > + /* get the length before the srb is changed */ > + sense_data_len = usb_stor_sense_data_len(srb, us); > + > /* save the old command */ > memcpy(old_cmnd, srb->cmnd, MAX_COMMAND_SIZE); > old_cmd_len = srb->cmd_len; > @@ -622,7 +634,7 @@ void usb_stor_invoke_transport(struct sc > memset(srb->cmnd, 0, MAX_COMMAND_SIZE); > srb->cmnd[0] = REQUEST_SENSE; > srb->cmnd[1] = old_cmnd[1] & 0xE0; > - srb->cmnd[4] = 18; > + srb->cmnd[4] = sense_data_len; > > /* FIXME: we must do the protocol translation here */ > if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI) > @@ -640,7 +652,7 @@ void usb_stor_invoke_transport(struct sc > > /* set the buffer length for transfer */ > old_request_bufflen = srb->request_bufflen; > - srb->request_bufflen = US_SENSE_SIZE; > + srb->request_bufflen = sense_data_len; > > /* set up for no scatter-gather use */ > old_sg = srb->use_sg; > diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h > index 98b0971..80e3a22 100644 > --- a/drivers/usb/storage/usb.h > +++ b/drivers/usb/storage/usb.h > @@ -117,7 +117,7 @@ enum { US_DO_ALL_FLAGS }; > */ > > #define US_IOBUF_SIZE 64 /* Size of the DMA-mapped I/O > buffer */ > -#define US_SENSE_SIZE 18 /* Size of the autosense data > buffer */ > +#define US_SENSE_SIZE 22 /* Size of the autosense data > buffer */ > > typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); > typedef int (*trans_reset)(struct us_data*); > -- Matthew Dharm Home: [EMAIL PROTECTED] Maintainer, Linux USB Mass Storage Driver E: You run this ship with Windows?! YOU IDIOT! L: Give me a break, it came bundled with the computer! -- ESR and Lan Solaris User Friendly, 12/8/1998
pgpi5Jr1FZs3x.pgp
Description: PGP signature