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