aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@steeleye.com>2006-06-13 22:31:19 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-06-19 20:34:01 -0400
commit67d59dfdeb21df2c16dcd478b66177e91178ecd0 (patch)
treeae85703651d81740f4a6cd398f9dd4d6aabe6a2f /drivers
parent6db874fbdbedba5e15e76cc03b42f52ea70338c0 (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')
-rw-r--r--drivers/scsi/53c700.c86
-rw-r--r--drivers/scsi/53c700.h2
2 files changed, 49 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
184STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; 184STATIC struct scsi_transport_template *NCR_700_transport_template = NULL;
185 185
186struct NCR_700_sense {
187 unsigned char cmnd[MAX_COMMAND_SIZE];
188};
189
186static char *NCR_700_phase[] = { 190static 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)
2065STATIC void 2072STATIC void
2066NCR_700_slave_destroy(struct scsi_device *SDp) 2073NCR_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
2071static int 2079static int
diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h
index a8c83bb03630..d8041952b1b5 100644
--- a/drivers/scsi/53c700.h
+++ b/drivers/scsi/53c700.h
@@ -163,6 +163,8 @@ struct NCR_700_command_slot {
163 #define NCR_700_SLOT_BUSY (1|NCR_700_SLOT_MAGIC) /* slot has command active on HA */ 163 #define NCR_700_SLOT_BUSY (1|NCR_700_SLOT_MAGIC) /* slot has command active on HA */
164 #define NCR_700_SLOT_QUEUED (2|NCR_700_SLOT_MAGIC) /* slot has command to be made active on HA */ 164 #define NCR_700_SLOT_QUEUED (2|NCR_700_SLOT_MAGIC) /* slot has command to be made active on HA */
165 __u8 state; 165 __u8 state;
166 #define NCR_700_FLAG_AUTOSENSE 0x01
167 __u8 flags;
166 int tag; 168 int tag;
167 __u32 resume_offset; 169 __u32 resume_offset;
168 struct scsi_cmnd *cmnd; 170 struct scsi_cmnd *cmnd;