aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_error.c
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2008-04-30 04:19:47 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-05-02 11:18:22 -0400
commit64a87b244b9297667ca80264aab849a36f494884 (patch)
tree554d78d1cfe594b92409a19b3ed1d32efcbd31cc /drivers/scsi/scsi_error.c
parent9f5de6b105bfa45911d46566df0b36720b648c42 (diff)
[SCSI] Let scsi_cmnd->cmnd use request->cmd buffer
- struct scsi_cmnd had a 16 bytes command buffer of its own. This is an unnecessary duplication and copy of request's cmd. It is probably left overs from the time that scsi_cmnd could function without a request attached. So clean that up. - Once above is done, few places, apart from scsi-ml, needed adjustments due to changing the data type of scsi_cmnd->cmnd. - Lots of drivers still use MAX_COMMAND_SIZE. So I have left that #define but equate it to BLK_MAX_CDB. The way I see it and is reflected in the patch below is. MAX_COMMAND_SIZE - means: The longest fixed-length (*) SCSI CDB as per the SCSI standard and is not related to the implementation. BLK_MAX_CDB. - The allocated space at the request level - I have audit all ISA drivers and made sure none use ->cmnd in a DMA Operation. Same audit was done by Andi Kleen. (*)fixed-length here means commands that their size can be determined by their opcode and the CDB does not carry a length specifier, (unlike the VARIABLE_LENGTH_CMD(0x7f) command). This is actually not exactly true and the SCSI standard also defines extended commands and vendor specific commands that can be bigger than 16 bytes. The kernel will support these using the same infrastructure used for VARLEN CDB's. So in effect MAX_COMMAND_SIZE means the maximum size command scsi-ml supports without specifying a cmd_len by ULD's Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r--drivers/scsi/scsi_error.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 221f31e36d26..334244c73955 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -626,7 +626,7 @@ static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
626 * @scmd: SCSI command structure to hijack 626 * @scmd: SCSI command structure to hijack
627 * @ses: structure to save restore information 627 * @ses: structure to save restore information
628 * @cmnd: CDB to send. Can be NULL if no new cmnd is needed 628 * @cmnd: CDB to send. Can be NULL if no new cmnd is needed
629 * @cmnd_size: size in bytes of @cmnd 629 * @cmnd_size: size in bytes of @cmnd (must be <= BLK_MAX_CDB)
630 * @sense_bytes: size of sense data to copy. or 0 (if != 0 @cmnd is ignored) 630 * @sense_bytes: size of sense data to copy. or 0 (if != 0 @cmnd is ignored)
631 * 631 *
632 * This function is used to save a scsi command information before re-execution 632 * This function is used to save a scsi command information before re-execution
@@ -648,12 +648,14 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
648 * command. 648 * command.
649 */ 649 */
650 ses->cmd_len = scmd->cmd_len; 650 ses->cmd_len = scmd->cmd_len;
651 memcpy(ses->cmnd, scmd->cmnd, sizeof(scmd->cmnd)); 651 ses->cmnd = scmd->cmnd;
652 ses->data_direction = scmd->sc_data_direction; 652 ses->data_direction = scmd->sc_data_direction;
653 ses->sdb = scmd->sdb; 653 ses->sdb = scmd->sdb;
654 ses->next_rq = scmd->request->next_rq; 654 ses->next_rq = scmd->request->next_rq;
655 ses->result = scmd->result; 655 ses->result = scmd->result;
656 656
657 scmd->cmnd = ses->eh_cmnd;
658 memset(scmd->cmnd, 0, BLK_MAX_CDB);
657 memset(&scmd->sdb, 0, sizeof(scmd->sdb)); 659 memset(&scmd->sdb, 0, sizeof(scmd->sdb));
658 scmd->request->next_rq = NULL; 660 scmd->request->next_rq = NULL;
659 661
@@ -665,14 +667,13 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
665 scmd->sdb.table.sgl = &ses->sense_sgl; 667 scmd->sdb.table.sgl = &ses->sense_sgl;
666 scmd->sc_data_direction = DMA_FROM_DEVICE; 668 scmd->sc_data_direction = DMA_FROM_DEVICE;
667 scmd->sdb.table.nents = 1; 669 scmd->sdb.table.nents = 1;
668 memset(scmd->cmnd, 0, sizeof(scmd->cmnd));
669 scmd->cmnd[0] = REQUEST_SENSE; 670 scmd->cmnd[0] = REQUEST_SENSE;
670 scmd->cmnd[4] = scmd->sdb.length; 671 scmd->cmnd[4] = scmd->sdb.length;
671 scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); 672 scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
672 } else { 673 } else {
673 scmd->sc_data_direction = DMA_NONE; 674 scmd->sc_data_direction = DMA_NONE;
674 if (cmnd) { 675 if (cmnd) {
675 memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); 676 BUG_ON(cmnd_size > BLK_MAX_CDB);
676 memcpy(scmd->cmnd, cmnd, cmnd_size); 677 memcpy(scmd->cmnd, cmnd, cmnd_size);
677 scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); 678 scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
678 } 679 }
@@ -705,7 +706,7 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)
705 * Restore original data 706 * Restore original data
706 */ 707 */
707 scmd->cmd_len = ses->cmd_len; 708 scmd->cmd_len = ses->cmd_len;
708 memcpy(scmd->cmnd, ses->cmnd, sizeof(scmd->cmnd)); 709 scmd->cmnd = ses->cmnd;
709 scmd->sc_data_direction = ses->data_direction; 710 scmd->sc_data_direction = ses->data_direction;
710 scmd->sdb = ses->sdb; 711 scmd->sdb = ses->sdb;
711 scmd->request->next_rq = ses->next_rq; 712 scmd->request->next_rq = ses->next_rq;
@@ -1774,8 +1775,8 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
1774 scmd->request = &req; 1775 scmd->request = &req;
1775 memset(&scmd->eh_timeout, 0, sizeof(scmd->eh_timeout)); 1776 memset(&scmd->eh_timeout, 0, sizeof(scmd->eh_timeout));
1776 1777
1777 memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); 1778 scmd->cmnd = req.cmd;
1778 1779
1779 scmd->scsi_done = scsi_reset_provider_done_command; 1780 scmd->scsi_done = scsi_reset_provider_done_command;
1780 memset(&scmd->sdb, 0, sizeof(scmd->sdb)); 1781 memset(&scmd->sdb, 0, sizeof(scmd->sdb));
1781 1782