aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;