diff options
author | James Bottomley <James.Bottomley@steeleye.com> | 2006-06-13 22:31:19 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-06-19 20:34:01 -0400 |
commit | 67d59dfdeb21df2c16dcd478b66177e91178ecd0 (patch) | |
tree | ae85703651d81740f4a6cd398f9dd4d6aabe6a2f /drivers/scsi/53c700.c | |
parent | 6db874fbdbedba5e15e76cc03b42f52ea70338c0 (diff) |
[SCSI] 53c700: remove reliance on deprecated cmnd fields
This one's quite tricky. The 53c700 uses the now deprecated fields of
the command structure for saving the prior command when it does
autosense. To fix this, we have to add extra fields to the LUN to
accommodate a copy of the real command.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/53c700.c')
-rw-r--r-- | drivers/scsi/53c700.c | 86 |
1 files changed, 47 insertions, 39 deletions
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 4958c3b93c30..3c683dc23541 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c | |||
@@ -183,6 +183,10 @@ STATIC struct device_attribute *NCR_700_dev_attrs[]; | |||
183 | 183 | ||
184 | STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; | 184 | STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; |
185 | 185 | ||
186 | struct NCR_700_sense { | ||
187 | unsigned char cmnd[MAX_COMMAND_SIZE]; | ||
188 | }; | ||
189 | |||
186 | static char *NCR_700_phase[] = { | 190 | static char *NCR_700_phase[] = { |
187 | "", | 191 | "", |
188 | "after selection", | 192 | "after selection", |
@@ -537,6 +541,7 @@ find_empty_slot(struct NCR_700_Host_Parameters *hostdata) | |||
537 | * finish routine. If we cannot queue the command when it | 541 | * finish routine. If we cannot queue the command when it |
538 | * is properly build, we then change to NCR_700_SLOT_QUEUED */ | 542 | * is properly build, we then change to NCR_700_SLOT_QUEUED */ |
539 | slot->state = NCR_700_SLOT_BUSY; | 543 | slot->state = NCR_700_SLOT_BUSY; |
544 | slot->flags = 0; | ||
540 | hostdata->command_slot_count++; | 545 | hostdata->command_slot_count++; |
541 | 546 | ||
542 | return slot; | 547 | return slot; |
@@ -586,7 +591,7 @@ NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, struct scsi_cmnd *SCp, | |||
586 | if(SCp->sc_data_direction != DMA_NONE && | 591 | if(SCp->sc_data_direction != DMA_NONE && |
587 | SCp->sc_data_direction != DMA_BIDIRECTIONAL) { | 592 | SCp->sc_data_direction != DMA_BIDIRECTIONAL) { |
588 | if(SCp->use_sg) { | 593 | if(SCp->use_sg) { |
589 | dma_unmap_sg(hostdata->dev, SCp->buffer, | 594 | dma_unmap_sg(hostdata->dev, SCp->request_buffer, |
590 | SCp->use_sg, SCp->sc_data_direction); | 595 | SCp->use_sg, SCp->sc_data_direction); |
591 | } else { | 596 | } else { |
592 | dma_unmap_single(hostdata->dev, slot->dma_handle, | 597 | dma_unmap_single(hostdata->dev, slot->dma_handle, |
@@ -608,30 +613,23 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, | |||
608 | (struct NCR_700_command_slot *)SCp->host_scribble; | 613 | (struct NCR_700_command_slot *)SCp->host_scribble; |
609 | 614 | ||
610 | NCR_700_unmap(hostdata, SCp, slot); | 615 | NCR_700_unmap(hostdata, SCp, slot); |
611 | dma_unmap_single(hostdata->dev, slot->pCmd, | 616 | if (slot->flags == NCR_700_FLAG_AUTOSENSE) { |
612 | sizeof(SCp->cmnd), DMA_TO_DEVICE); | 617 | struct NCR_700_sense *sense = SCp->device->hostdata; |
613 | if(SCp->cmnd[0] == REQUEST_SENSE && SCp->cmnd[6] == NCR_700_INTERNAL_SENSE_MAGIC) { | ||
614 | #ifdef NCR_700_DEBUG | 618 | #ifdef NCR_700_DEBUG |
615 | printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", | 619 | printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", |
616 | SCp, SCp->cmnd[7], result); | 620 | SCp, SCp->cmnd[7], result); |
617 | scsi_print_sense("53c700", SCp); | 621 | scsi_print_sense("53c700", SCp); |
618 | 622 | ||
619 | #endif | 623 | #endif |
624 | dma_unmap_single(hostdata->dev, slot->dma_handle, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); | ||
620 | /* restore the old result if the request sense was | 625 | /* restore the old result if the request sense was |
621 | * successful */ | 626 | * successful */ |
622 | if(result == 0) | 627 | if(result == 0) |
623 | result = SCp->cmnd[7]; | 628 | result = sense->cmnd[7]; |
624 | /* now restore the original command */ | 629 | } else |
625 | memcpy((void *) SCp->cmnd, (void *) SCp->data_cmnd, | 630 | dma_unmap_single(hostdata->dev, slot->pCmd, |
626 | sizeof(SCp->data_cmnd)); | 631 | sizeof(SCp->cmnd), DMA_TO_DEVICE); |
627 | SCp->request_buffer = SCp->buffer; | 632 | |
628 | SCp->request_bufflen = SCp->bufflen; | ||
629 | SCp->use_sg = SCp->old_use_sg; | ||
630 | SCp->cmd_len = SCp->old_cmd_len; | ||
631 | SCp->sc_data_direction = SCp->sc_old_data_direction; | ||
632 | SCp->underflow = SCp->old_underflow; | ||
633 | |||
634 | } | ||
635 | free_slot(slot, hostdata); | 633 | free_slot(slot, hostdata); |
636 | #ifdef NCR_700_DEBUG | 634 | #ifdef NCR_700_DEBUG |
637 | if(NCR_700_get_depth(SCp->device) == 0 || | 635 | if(NCR_700_get_depth(SCp->device) == 0 || |
@@ -979,6 +977,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
979 | "broken device is looping in contingent allegiance: ignoring\n"); | 977 | "broken device is looping in contingent allegiance: ignoring\n"); |
980 | NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); | 978 | NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); |
981 | } else { | 979 | } else { |
980 | struct NCR_700_sense *sense = SCp->device->hostdata; | ||
982 | #ifdef NCR_DEBUG | 981 | #ifdef NCR_DEBUG |
983 | scsi_print_command(SCp); | 982 | scsi_print_command(SCp); |
984 | printk(" cmd %p has status %d, requesting sense\n", | 983 | printk(" cmd %p has status %d, requesting sense\n", |
@@ -992,27 +991,25 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
992 | * data associated with the command | 991 | * data associated with the command |
993 | * here */ | 992 | * here */ |
994 | NCR_700_unmap(hostdata, SCp, slot); | 993 | NCR_700_unmap(hostdata, SCp, slot); |
995 | 994 | dma_unmap_single(hostdata->dev, slot->pCmd, | |
996 | SCp->cmnd[0] = REQUEST_SENSE; | 995 | sizeof(SCp->cmnd), |
997 | SCp->cmnd[1] = (SCp->device->lun & 0x7) << 5; | 996 | DMA_TO_DEVICE); |
998 | SCp->cmnd[2] = 0; | 997 | |
999 | SCp->cmnd[3] = 0; | 998 | sense->cmnd[0] = REQUEST_SENSE; |
1000 | SCp->cmnd[4] = sizeof(SCp->sense_buffer); | 999 | sense->cmnd[1] = (SCp->device->lun & 0x7) << 5; |
1001 | SCp->cmnd[5] = 0; | 1000 | sense->cmnd[2] = 0; |
1002 | SCp->cmd_len = 6; | 1001 | sense->cmnd[3] = 0; |
1002 | sense->cmnd[4] = sizeof(SCp->sense_buffer); | ||
1003 | sense->cmnd[5] = 0; | ||
1003 | /* Here's a quiet hack: the | 1004 | /* Here's a quiet hack: the |
1004 | * REQUEST_SENSE command is six bytes, | 1005 | * REQUEST_SENSE command is six bytes, |
1005 | * so store a flag indicating that | 1006 | * so store a flag indicating that |
1006 | * this was an internal sense request | 1007 | * this was an internal sense request |
1007 | * and the original status at the end | 1008 | * and the original status at the end |
1008 | * of the command */ | 1009 | * of the command */ |
1009 | SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; | 1010 | sense->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; |
1010 | SCp->cmnd[7] = hostdata->status[0]; | 1011 | sense->cmnd[7] = hostdata->status[0]; |
1011 | SCp->use_sg = 0; | 1012 | slot->pCmd = dma_map_single(hostdata->dev, sense->cmnd, sizeof(sense->cmnd), DMA_TO_DEVICE); |
1012 | SCp->sc_data_direction = DMA_FROM_DEVICE; | ||
1013 | dma_sync_single_for_device(hostdata->dev, slot->pCmd, | ||
1014 | SCp->cmd_len, DMA_TO_DEVICE); | ||
1015 | SCp->request_bufflen = sizeof(SCp->sense_buffer); | ||
1016 | slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); | 1013 | slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); |
1017 | slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); | 1014 | slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); |
1018 | slot->SG[0].pAddr = bS_to_host(slot->dma_handle); | 1015 | slot->SG[0].pAddr = bS_to_host(slot->dma_handle); |
@@ -1024,6 +1021,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
1024 | 1021 | ||
1025 | /* queue the command for reissue */ | 1022 | /* queue the command for reissue */ |
1026 | slot->state = NCR_700_SLOT_QUEUED; | 1023 | slot->state = NCR_700_SLOT_QUEUED; |
1024 | slot->flags = NCR_700_FLAG_AUTOSENSE; | ||
1027 | hostdata->state = NCR_700_HOST_FREE; | 1025 | hostdata->state = NCR_700_HOST_FREE; |
1028 | hostdata->cmd = NULL; | 1026 | hostdata->cmd = NULL; |
1029 | } | 1027 | } |
@@ -1244,7 +1242,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
1244 | 1242 | ||
1245 | if(SCp->use_sg) { | 1243 | if(SCp->use_sg) { |
1246 | for(i = 0; i < SCp->use_sg + 1; i++) { | 1244 | for(i = 0; i < SCp->use_sg + 1; i++) { |
1247 | printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr); | 1245 | printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->request_buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr); |
1248 | } | 1246 | } |
1249 | } | 1247 | } |
1250 | } | 1248 | } |
@@ -1403,12 +1401,14 @@ NCR_700_start_command(struct scsi_cmnd *SCp) | |||
1403 | /* keep interrupts disabled until we have the command correctly | 1401 | /* keep interrupts disabled until we have the command correctly |
1404 | * set up so we cannot take a selection interrupt */ | 1402 | * set up so we cannot take a selection interrupt */ |
1405 | 1403 | ||
1406 | hostdata->msgout[0] = NCR_700_identify(SCp->cmnd[0] != REQUEST_SENSE, | 1404 | hostdata->msgout[0] = NCR_700_identify((SCp->cmnd[0] != REQUEST_SENSE && |
1405 | slot->flags != NCR_700_FLAG_AUTOSENSE), | ||
1407 | SCp->device->lun); | 1406 | SCp->device->lun); |
1408 | /* for INQUIRY or REQUEST_SENSE commands, we cannot be sure | 1407 | /* for INQUIRY or REQUEST_SENSE commands, we cannot be sure |
1409 | * if the negotiated transfer parameters still hold, so | 1408 | * if the negotiated transfer parameters still hold, so |
1410 | * always renegotiate them */ | 1409 | * always renegotiate them */ |
1411 | if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE) { | 1410 | if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE || |
1411 | slot->flags == NCR_700_FLAG_AUTOSENSE) { | ||
1412 | NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC); | 1412 | NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC); |
1413 | } | 1413 | } |
1414 | 1414 | ||
@@ -1417,7 +1417,8 @@ NCR_700_start_command(struct scsi_cmnd *SCp) | |||
1417 | * will refuse all tags, so send the request sense as untagged | 1417 | * will refuse all tags, so send the request sense as untagged |
1418 | * */ | 1418 | * */ |
1419 | if((hostdata->tag_negotiated & (1<<scmd_id(SCp))) | 1419 | if((hostdata->tag_negotiated & (1<<scmd_id(SCp))) |
1420 | && (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) { | 1420 | && (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE && |
1421 | slot->flags != NCR_700_FLAG_AUTOSENSE)) { | ||
1421 | count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]); | 1422 | count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]); |
1422 | } | 1423 | } |
1423 | 1424 | ||
@@ -1863,8 +1864,9 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) | |||
1863 | __u32 count = 0; | 1864 | __u32 count = 0; |
1864 | 1865 | ||
1865 | if(SCp->use_sg) { | 1866 | if(SCp->use_sg) { |
1866 | sg_count = dma_map_sg(hostdata->dev, SCp->buffer, | 1867 | sg_count = dma_map_sg(hostdata->dev, |
1867 | SCp->use_sg, direction); | 1868 | SCp->request_buffer, SCp->use_sg, |
1869 | direction); | ||
1868 | } else { | 1870 | } else { |
1869 | vPtr = dma_map_single(hostdata->dev, | 1871 | vPtr = dma_map_single(hostdata->dev, |
1870 | SCp->request_buffer, | 1872 | SCp->request_buffer, |
@@ -1879,7 +1881,7 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) | |||
1879 | for(i = 0; i < sg_count; i++) { | 1881 | for(i = 0; i < sg_count; i++) { |
1880 | 1882 | ||
1881 | if(SCp->use_sg) { | 1883 | if(SCp->use_sg) { |
1882 | struct scatterlist *sg = SCp->buffer; | 1884 | struct scatterlist *sg = SCp->request_buffer; |
1883 | 1885 | ||
1884 | vPtr = sg_dma_address(&sg[i]); | 1886 | vPtr = sg_dma_address(&sg[i]); |
1885 | count = sg_dma_len(&sg[i]); | 1887 | count = sg_dma_len(&sg[i]); |
@@ -2042,6 +2044,11 @@ NCR_700_slave_configure(struct scsi_device *SDp) | |||
2042 | struct NCR_700_Host_Parameters *hostdata = | 2044 | struct NCR_700_Host_Parameters *hostdata = |
2043 | (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; | 2045 | (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; |
2044 | 2046 | ||
2047 | SDp->hostdata = kmalloc(GFP_KERNEL, sizeof(struct NCR_700_sense)); | ||
2048 | |||
2049 | if (!SDp->hostdata) | ||
2050 | return -ENOMEM; | ||
2051 | |||
2045 | /* to do here: allocate memory; build a queue_full list */ | 2052 | /* to do here: allocate memory; build a queue_full list */ |
2046 | if(SDp->tagged_supported) { | 2053 | if(SDp->tagged_supported) { |
2047 | scsi_set_tag_type(SDp, MSG_ORDERED_TAG); | 2054 | scsi_set_tag_type(SDp, MSG_ORDERED_TAG); |
@@ -2065,7 +2072,8 @@ NCR_700_slave_configure(struct scsi_device *SDp) | |||
2065 | STATIC void | 2072 | STATIC void |
2066 | NCR_700_slave_destroy(struct scsi_device *SDp) | 2073 | NCR_700_slave_destroy(struct scsi_device *SDp) |
2067 | { | 2074 | { |
2068 | /* to do here: deallocate memory */ | 2075 | kfree(SDp->hostdata); |
2076 | SDp->hostdata = NULL; | ||
2069 | } | 2077 | } |
2070 | 2078 | ||
2071 | static int | 2079 | static int |