ChangeSet 1.879.9.9, 2003/01/06 16:35:55-08:00, mdharm-usb@one-eyed-alien.net [PATCH] USB storage: remove usb_stor_tranfer_length() This patch removes the (often troublesome) usb_stor_transfer_length() function. We've finally gotten all the command initiators to send the correct values in the srb->request_bufflen field, so this is no longer needed. There are probably some sanity checks that can also be removed now, but that's for a later patch. diff -Nru a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c --- a/drivers/usb/storage/freecom.c Wed Jan 8 12:00:53 2003 +++ b/drivers/usb/storage/freecom.c Wed Jan 8 12:00:53 2003 @@ -285,7 +285,7 @@ * and such will hang. */ US_DEBUGP("Device indicates that it has %d bytes available\n", le16_to_cpu (fst->Count)); - US_DEBUGP("SCSI requested %d\n", usb_stor_transfer_length(srb)); + US_DEBUGP("SCSI requested %d\n", srb->request_bufflen); /* Find the length we desire to read. */ switch (srb->cmnd[0]) { @@ -296,7 +296,7 @@ length = fst->Count; break; default: - length = usb_stor_transfer_length (srb); + length = srb->request_bufflen; } /* verify that this amount is legal */ diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c --- a/drivers/usb/storage/transport.c Wed Jan 8 12:00:53 2003 +++ b/drivers/usb/storage/transport.c Wed Jan 8 12:00:53 2003 @@ -56,307 +56,6 @@ #include /*********************************************************************** - * Helper routines - ***********************************************************************/ - -/* Calculate the length of the data transfer (not the command) for any - * given SCSI command - */ -unsigned int usb_stor_transfer_length(Scsi_Cmnd *srb) -{ - int i; - int doDefault = 0; - unsigned int len = 0; - unsigned int total = 0; - struct scatterlist *sg; - - /* This table tells us: - X = command not supported - L = return length in cmnd[4] (8 bits). - M = return length in cmnd[8] (8 bits). - G = return length in cmnd[3] and cmnd[4] (16 bits) - H = return length in cmnd[7] and cmnd[8] (16 bits) - I = return length in cmnd[8] and cmnd[9] (16 bits) - C = return length in cmnd[2] to cmnd[5] (32 bits) - D = return length in cmnd[6] to cmnd[9] (32 bits) - B = return length in blocksize so we use buff_len - R = return length in cmnd[2] to cmnd[4] (24 bits) - S = return length in cmnd[3] to cmnd[5] (24 bits) - T = return length in cmnd[6] to cmnd[8] (24 bits) - U = return length in cmnd[7] to cmnd[9] (24 bits) - 0-9 = fixed return length - V = 20 bytes - W = 24 bytes - Z = return length is mode dependant or not in command, use buff_len - */ - - static char *lengths = - - /* 0123456789ABCDEF 0123456789ABCDEF */ - - "00XLZ6XZBXBBXXXB" "00LBBLG0R0L0GG0X" /* 00-1F */ - "XXXXT8XXB4B0BBBB" "ZZZ0B00HCSSZTBHH" /* 20-3F */ - "M0HHB0X000H0HH0X" "XHH0HHXX0TH0H0XX" /* 40-5F */ - "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* 60-7F */ - "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* 80-9F */ - "X0XXX00XB0BXBXBB" "ZZZ0XUIDU000XHBX" /* A0-BF */ - "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* C0-DF */ - "XDXXXXXXXXXXXXXX" "XXW00HXXXXXXXXXX"; /* E0-FF */ - - /* Commands checked in table: - - CHANGE_DEFINITION 40 - COMPARE 39 - COPY 18 - COPY_AND_VERIFY 3a - ERASE 19 - ERASE_10 2c - ERASE_12 ac - EXCHANGE_MEDIUM a6 - FORMAT_UNIT 04 - GET_DATA_BUFFER_STATUS 34 - GET_MESSAGE_10 28 - GET_MESSAGE_12 a8 - GET_WINDOW 25 !!! Has more data than READ_CAPACITY, need to fix table - INITIALIZE_ELEMENT_STATUS 07 !!! REASSIGN_BLOCKS luckily uses buff_len - INQUIRY 12 - LOAD_UNLOAD 1b - LOCATE 2b - LOCK_UNLOCK_CACHE 36 - LOG_SELECT 4c - LOG_SENSE 4d - MEDIUM_SCAN 38 !!! This was M - MODE_SELECT6 15 - MODE_SELECT_10 55 - MODE_SENSE_6 1a - MODE_SENSE_10 5a - MOVE_MEDIUM a5 - OBJECT_POSITION 31 !!! Same as SEARCH_DATA_EQUAL - PAUSE_RESUME 4b - PLAY_AUDIO_10 45 - PLAY_AUDIO_12 a5 - PLAY_AUDIO_MSF 47 - PLAY_AUDIO_TRACK_INDEX 48 - PLAY_AUDIO_TRACK_RELATIVE_10 49 - PLAY_AUDIO_TRACK_RELATIVE_12 a9 - POSITION_TO_ELEMENT 2b - PRE-FETCH 34 - PREVENT_ALLOW_MEDIUM_REMOVAL 1e - PRINT 0a !!! Same as WRITE_6 but is always in bytes - READ_6 08 - READ_10 28 - READ_12 a8 - READ_BLOCK_LIMITS 05 - READ_BUFFER 3c - READ_CAPACITY 25 - READ_CDROM_CAPACITY 25 - READ_DEFECT_DATA 37 - READ_DEFECT_DATA_12 b7 - READ_ELEMENT_STATUS b8 !!! Think this is in bytes - READ_GENERATION 29 !!! Could also be M? - READ_HEADER 44 !!! This was L - READ_LONG 3e - READ_POSITION 34 !!! This should be V but conflicts with PRE-FETCH - READ_REVERSE 0f - READ_SUB-CHANNEL 42 !!! Is this in bytes? - READ_TOC 43 !!! Is this in bytes? - READ_UPDATED_BLOCK 2d - REASSIGN_BLOCKS 07 - RECEIVE 08 !!! Same as READ_6 probably in bytes though - RECEIVE_DIAGNOSTIC_RESULTS 1c - RECOVER_BUFFERED_DATA 14 !!! For PRINTERs this is bytes - RELEASE_UNIT 17 - REQUEST_SENSE 03 - REQUEST_VOLUME_ELEMENT_ADDRESS b5 !!! Think this is in bytes - RESERVE_UNIT 16 - REWIND 01 - REZERO_UNIT 01 - SCAN 1b !!! Conflicts with various commands, should be L - SEARCH_DATA_EQUAL 31 - SEARCH_DATA_EQUAL_12 b1 - SEARCH_DATA_LOW 30 - SEARCH_DATA_LOW_12 b0 - SEARCH_DATA_HIGH 32 - SEARCH_DATA_HIGH_12 b2 - SEEK_6 0b !!! Conflicts with SLEW_AND_PRINT - SEEK_10 2b - SEND 0a !!! Same as WRITE_6, probably in bytes though - SEND 2a !!! Similar to WRITE_10 but for scanners - SEND_DIAGNOSTIC 1d - SEND_MESSAGE_6 0a !!! Same as WRITE_6 - is in bytes - SEND_MESSAGE_10 2a !!! Same as WRITE_10 - is in bytes - SEND_MESSAGE_12 aa !!! Same as WRITE_12 - is in bytes - SEND_OPC 54 - SEND_VOLUME_TAG b6 !!! Think this is in bytes - SET_LIMITS 33 - SET_LIMITS_12 b3 - SET_WINDOW 24 - SLEW_AND_PRINT 0b !!! Conflicts with SEEK_6 - SPACE 11 - START_STOP_UNIT 1b - STOP_PRINT 1b - SYNCHRONIZE_BUFFER 10 - SYNCHRONIZE_CACHE 35 - TEST_UNIT_READY 00 - UPDATE_BLOCK 3d - VERIFY 13 - VERIFY 2f - VERIFY_12 af - WRITE_6 0a - WRITE_10 2a - WRITE_12 aa - WRITE_AND_VERIFY 2e - WRITE_AND_VERIFY_12 ae - WRITE_BUFFER 3b - WRITE_FILEMARKS 10 - WRITE_LONG 3f - WRITE_SAME 41 - */ - - if (srb->sc_data_direction == SCSI_DATA_WRITE) { - doDefault = 1; - } - else - switch (lengths[srb->cmnd[0]]) { - case 'L': - len = srb->cmnd[4]; - break; - - case 'M': - len = srb->cmnd[8]; - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - len = lengths[srb->cmnd[0]]-'0'; - break; - - case 'G': - len = (((unsigned int)srb->cmnd[3])<<8) | - srb->cmnd[4]; - break; - - case 'H': - len = (((unsigned int)srb->cmnd[7])<<8) | - srb->cmnd[8]; - break; - - case 'I': - len = (((unsigned int)srb->cmnd[8])<<8) | - srb->cmnd[9]; - break; - - case 'R': - len = (((unsigned int)srb->cmnd[2])<<16) | - (((unsigned int)srb->cmnd[3])<<8) | - srb->cmnd[4]; - break; - - case 'S': - len = (((unsigned int)srb->cmnd[3])<<16) | - (((unsigned int)srb->cmnd[4])<<8) | - srb->cmnd[5]; - break; - - case 'T': - len = (((unsigned int)srb->cmnd[6])<<16) | - (((unsigned int)srb->cmnd[7])<<8) | - srb->cmnd[8]; - break; - - case 'U': - len = (((unsigned int)srb->cmnd[7])<<16) | - (((unsigned int)srb->cmnd[8])<<8) | - srb->cmnd[9]; - break; - - case 'C': - len = (((unsigned int)srb->cmnd[2])<<24) | - (((unsigned int)srb->cmnd[3])<<16) | - (((unsigned int)srb->cmnd[4])<<8) | - srb->cmnd[5]; - break; - - case 'D': - len = (((unsigned int)srb->cmnd[6])<<24) | - (((unsigned int)srb->cmnd[7])<<16) | - (((unsigned int)srb->cmnd[8])<<8) | - srb->cmnd[9]; - break; - - case 'V': - len = 20; - break; - - case 'W': - len = 24; - break; - - case 'B': - /* Use buffer size due to different block sizes */ - doDefault = 1; - break; - - case 'X': - US_DEBUGP("Error: UNSUPPORTED COMMAND %02X\n", - srb->cmnd[0]); - doDefault = 1; - break; - - case 'Z': - /* Use buffer size due to mode dependence */ - doDefault = 1; - break; - - default: - US_DEBUGP("Error: COMMAND %02X out of range or table inconsistent (%c).\n", - srb->cmnd[0], lengths[srb->cmnd[0]] ); - doDefault = 1; - } - - if ( doDefault == 1 ) { - /* Are we going to scatter gather? */ - if (srb->use_sg) { - /* Add up the sizes of all the sg segments */ - sg = (struct scatterlist *) srb->request_buffer; - for (i = 0; i < srb->use_sg; i++) - total += sg[i].length; - len = total; - - /* Double-check to see if the advertised buffer - * length less than the actual buffer length -- - * in other words, we should tend towards the - * conservative side for data transfers. - */ - if (len > srb->request_bufflen) - len = srb->request_bufflen; - } - else - /* Just return the length of the buffer */ - len = srb->request_bufflen; - } - - /* According to the linux-scsi people, any command sent which - * violates this invariant is a bug. In the hopes of removing - * all the complex logic above, let's find them and eliminate them. - */ - if (len != srb->request_bufflen) { - printk(KERN_ERR "USB len=%d, request_bufflen=%d\n", len, srb->request_bufflen); - dump_stack(); - } - - return len; -} - -/*********************************************************************** * Data transfer routines ***********************************************************************/ @@ -1031,7 +730,7 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us) { - unsigned int transfer_length = usb_stor_transfer_length(srb); + unsigned int transfer_length = srb->request_bufflen; int result; /* COMMAND STAGE */ @@ -1115,7 +814,7 @@ */ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us) { - unsigned int transfer_length = usb_stor_transfer_length(srb); + unsigned int transfer_length = srb->request_bufflen; int result; /* COMMAND STAGE */ @@ -1186,7 +885,7 @@ { struct bulk_cb_wrap bcb; struct bulk_cs_wrap bcs; - unsigned int transfer_length = usb_stor_transfer_length(srb); + unsigned int transfer_length = srb->request_bufflen; int result; /* set up the command wrapper */ diff -Nru a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h --- a/drivers/usb/storage/transport.h Wed Jan 8 12:00:53 2003 +++ b/drivers/usb/storage/transport.h Wed Jan 8 12:00:53 2003 @@ -154,7 +154,6 @@ extern int usb_stor_Bulk_max_lun(struct us_data*); extern int usb_stor_Bulk_reset(struct us_data*); -extern unsigned int usb_stor_transfer_length(Scsi_Cmnd*); extern void usb_stor_invoke_transport(Scsi_Cmnd*, struct us_data*); extern void usb_stor_abort_transport(struct us_data*);