diff options
Diffstat (limited to 'drivers/scsi/53c700.c')
-rw-r--r-- | drivers/scsi/53c700.c | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index bff04797739a..24dfd54865ee 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c | |||
@@ -174,6 +174,7 @@ STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt); | |||
174 | STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt); | 174 | STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt); |
175 | STATIC void NCR_700_chip_setup(struct Scsi_Host *host); | 175 | STATIC void NCR_700_chip_setup(struct Scsi_Host *host); |
176 | STATIC void NCR_700_chip_reset(struct Scsi_Host *host); | 176 | STATIC void NCR_700_chip_reset(struct Scsi_Host *host); |
177 | STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt); | ||
177 | STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt); | 178 | STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt); |
178 | STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt); | 179 | STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt); |
179 | static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth); | 180 | static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth); |
@@ -183,10 +184,6 @@ STATIC struct device_attribute *NCR_700_dev_attrs[]; | |||
183 | 184 | ||
184 | STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; | 185 | STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; |
185 | 186 | ||
186 | struct NCR_700_sense { | ||
187 | unsigned char cmnd[MAX_COMMAND_SIZE]; | ||
188 | }; | ||
189 | |||
190 | static char *NCR_700_phase[] = { | 187 | static char *NCR_700_phase[] = { |
191 | "", | 188 | "", |
192 | "after selection", | 189 | "after selection", |
@@ -334,6 +331,7 @@ NCR_700_detect(struct scsi_host_template *tpnt, | |||
334 | tpnt->use_clustering = ENABLE_CLUSTERING; | 331 | tpnt->use_clustering = ENABLE_CLUSTERING; |
335 | tpnt->slave_configure = NCR_700_slave_configure; | 332 | tpnt->slave_configure = NCR_700_slave_configure; |
336 | tpnt->slave_destroy = NCR_700_slave_destroy; | 333 | tpnt->slave_destroy = NCR_700_slave_destroy; |
334 | tpnt->slave_alloc = NCR_700_slave_alloc; | ||
337 | tpnt->change_queue_depth = NCR_700_change_queue_depth; | 335 | tpnt->change_queue_depth = NCR_700_change_queue_depth; |
338 | tpnt->change_queue_type = NCR_700_change_queue_type; | 336 | tpnt->change_queue_type = NCR_700_change_queue_type; |
339 | 337 | ||
@@ -612,9 +610,10 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, | |||
612 | struct NCR_700_command_slot *slot = | 610 | struct NCR_700_command_slot *slot = |
613 | (struct NCR_700_command_slot *)SCp->host_scribble; | 611 | (struct NCR_700_command_slot *)SCp->host_scribble; |
614 | 612 | ||
615 | NCR_700_unmap(hostdata, SCp, slot); | 613 | dma_unmap_single(hostdata->dev, slot->pCmd, |
614 | sizeof(SCp->cmnd), DMA_TO_DEVICE); | ||
616 | if (slot->flags == NCR_700_FLAG_AUTOSENSE) { | 615 | if (slot->flags == NCR_700_FLAG_AUTOSENSE) { |
617 | struct NCR_700_sense *sense = SCp->device->hostdata; | 616 | char *cmnd = NCR_700_get_sense_cmnd(SCp->device); |
618 | #ifdef NCR_700_DEBUG | 617 | #ifdef NCR_700_DEBUG |
619 | printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", | 618 | printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", |
620 | SCp, SCp->cmnd[7], result); | 619 | SCp, SCp->cmnd[7], result); |
@@ -625,10 +624,9 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, | |||
625 | /* restore the old result if the request sense was | 624 | /* restore the old result if the request sense was |
626 | * successful */ | 625 | * successful */ |
627 | if(result == 0) | 626 | if(result == 0) |
628 | result = sense->cmnd[7]; | 627 | result = cmnd[7]; |
629 | } else | 628 | } else |
630 | dma_unmap_single(hostdata->dev, slot->pCmd, | 629 | NCR_700_unmap(hostdata, SCp, slot); |
631 | sizeof(SCp->cmnd), DMA_TO_DEVICE); | ||
632 | 630 | ||
633 | free_slot(slot, hostdata); | 631 | free_slot(slot, hostdata); |
634 | #ifdef NCR_700_DEBUG | 632 | #ifdef NCR_700_DEBUG |
@@ -970,14 +968,15 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
970 | status_byte(hostdata->status[0]) == COMMAND_TERMINATED) { | 968 | status_byte(hostdata->status[0]) == COMMAND_TERMINATED) { |
971 | struct NCR_700_command_slot *slot = | 969 | struct NCR_700_command_slot *slot = |
972 | (struct NCR_700_command_slot *)SCp->host_scribble; | 970 | (struct NCR_700_command_slot *)SCp->host_scribble; |
973 | if(SCp->cmnd[0] == REQUEST_SENSE) { | 971 | if(slot->flags == NCR_700_FLAG_AUTOSENSE) { |
974 | /* OOPS: bad device, returning another | 972 | /* OOPS: bad device, returning another |
975 | * contingent allegiance condition */ | 973 | * contingent allegiance condition */ |
976 | scmd_printk(KERN_ERR, SCp, | 974 | scmd_printk(KERN_ERR, SCp, |
977 | "broken device is looping in contingent allegiance: ignoring\n"); | 975 | "broken device is looping in contingent allegiance: ignoring\n"); |
978 | NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); | 976 | NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); |
979 | } else { | 977 | } else { |
980 | struct NCR_700_sense *sense = SCp->device->hostdata; | 978 | char *cmnd = |
979 | NCR_700_get_sense_cmnd(SCp->device); | ||
981 | #ifdef NCR_DEBUG | 980 | #ifdef NCR_DEBUG |
982 | scsi_print_command(SCp); | 981 | scsi_print_command(SCp); |
983 | printk(" cmd %p has status %d, requesting sense\n", | 982 | printk(" cmd %p has status %d, requesting sense\n", |
@@ -995,21 +994,21 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
995 | sizeof(SCp->cmnd), | 994 | sizeof(SCp->cmnd), |
996 | DMA_TO_DEVICE); | 995 | DMA_TO_DEVICE); |
997 | 996 | ||
998 | sense->cmnd[0] = REQUEST_SENSE; | 997 | cmnd[0] = REQUEST_SENSE; |
999 | sense->cmnd[1] = (SCp->device->lun & 0x7) << 5; | 998 | cmnd[1] = (SCp->device->lun & 0x7) << 5; |
1000 | sense->cmnd[2] = 0; | 999 | cmnd[2] = 0; |
1001 | sense->cmnd[3] = 0; | 1000 | cmnd[3] = 0; |
1002 | sense->cmnd[4] = sizeof(SCp->sense_buffer); | 1001 | cmnd[4] = sizeof(SCp->sense_buffer); |
1003 | sense->cmnd[5] = 0; | 1002 | cmnd[5] = 0; |
1004 | /* Here's a quiet hack: the | 1003 | /* Here's a quiet hack: the |
1005 | * REQUEST_SENSE command is six bytes, | 1004 | * REQUEST_SENSE command is six bytes, |
1006 | * so store a flag indicating that | 1005 | * so store a flag indicating that |
1007 | * this was an internal sense request | 1006 | * this was an internal sense request |
1008 | * and the original status at the end | 1007 | * and the original status at the end |
1009 | * of the command */ | 1008 | * of the command */ |
1010 | sense->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; | 1009 | cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; |
1011 | sense->cmnd[7] = hostdata->status[0]; | 1010 | cmnd[7] = hostdata->status[0]; |
1012 | slot->pCmd = dma_map_single(hostdata->dev, sense->cmnd, sizeof(sense->cmnd), DMA_TO_DEVICE); | 1011 | slot->pCmd = dma_map_single(hostdata->dev, cmnd, MAX_COMMAND_SIZE, DMA_TO_DEVICE); |
1013 | slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); | 1012 | slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); |
1014 | slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); | 1013 | slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); |
1015 | slot->SG[0].pAddr = bS_to_host(slot->dma_handle); | 1014 | slot->SG[0].pAddr = bS_to_host(slot->dma_handle); |
@@ -1531,7 +1530,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
1531 | 1530 | ||
1532 | /* clear all the negotiated parameters */ | 1531 | /* clear all the negotiated parameters */ |
1533 | __shost_for_each_device(SDp, host) | 1532 | __shost_for_each_device(SDp, host) |
1534 | SDp->hostdata = NULL; | 1533 | NCR_700_clear_flag(SDp, ~0); |
1535 | 1534 | ||
1536 | /* clear all the slots and their pending commands */ | 1535 | /* clear all the slots and their pending commands */ |
1537 | for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) { | 1536 | for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) { |
@@ -2036,7 +2035,17 @@ NCR_700_set_offset(struct scsi_target *STp, int offset) | |||
2036 | spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION; | 2035 | spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION; |
2037 | } | 2036 | } |
2038 | 2037 | ||
2038 | STATIC int | ||
2039 | NCR_700_slave_alloc(struct scsi_device *SDp) | ||
2040 | { | ||
2041 | SDp->hostdata = kzalloc(sizeof(struct NCR_700_Device_Parameters), | ||
2042 | GFP_KERNEL); | ||
2039 | 2043 | ||
2044 | if (!SDp->hostdata) | ||
2045 | return -ENOMEM; | ||
2046 | |||
2047 | return 0; | ||
2048 | } | ||
2040 | 2049 | ||
2041 | STATIC int | 2050 | STATIC int |
2042 | NCR_700_slave_configure(struct scsi_device *SDp) | 2051 | NCR_700_slave_configure(struct scsi_device *SDp) |
@@ -2044,11 +2053,6 @@ NCR_700_slave_configure(struct scsi_device *SDp) | |||
2044 | struct NCR_700_Host_Parameters *hostdata = | 2053 | struct NCR_700_Host_Parameters *hostdata = |
2045 | (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; | 2054 | (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; |
2046 | 2055 | ||
2047 | SDp->hostdata = kmalloc(sizeof(struct NCR_700_sense), GFP_KERNEL); | ||
2048 | |||
2049 | if (!SDp->hostdata) | ||
2050 | return -ENOMEM; | ||
2051 | |||
2052 | /* to do here: allocate memory; build a queue_full list */ | 2056 | /* to do here: allocate memory; build a queue_full list */ |
2053 | if(SDp->tagged_supported) { | 2057 | if(SDp->tagged_supported) { |
2054 | scsi_set_tag_type(SDp, MSG_ORDERED_TAG); | 2058 | scsi_set_tag_type(SDp, MSG_ORDERED_TAG); |