aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/53c700.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/53c700.c')
-rw-r--r--drivers/scsi/53c700.c107
1 files changed, 56 insertions, 51 deletions
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index 6a0f9506ea0..3c683dc2354 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",
@@ -316,7 +320,7 @@ NCR_700_detect(struct scsi_host_template *tpnt,
316 BUG_ON(!dma_is_consistent(pScript) && L1_CACHE_BYTES < dma_get_cache_alignment()); 320 BUG_ON(!dma_is_consistent(pScript) && L1_CACHE_BYTES < dma_get_cache_alignment());
317 hostdata->slots = (struct NCR_700_command_slot *)(memory + SLOTS_OFFSET); 321 hostdata->slots = (struct NCR_700_command_slot *)(memory + SLOTS_OFFSET);
318 hostdata->dev = dev; 322 hostdata->dev = dev;
319 323
320 pSlots = pScript + SLOTS_OFFSET; 324 pSlots = pScript + SLOTS_OFFSET;
321 325
322 /* Fill in the missing routines from the host template */ 326 /* Fill in the missing routines from the host template */
@@ -332,19 +336,18 @@ NCR_700_detect(struct scsi_host_template *tpnt,
332 tpnt->slave_destroy = NCR_700_slave_destroy; 336 tpnt->slave_destroy = NCR_700_slave_destroy;
333 tpnt->change_queue_depth = NCR_700_change_queue_depth; 337 tpnt->change_queue_depth = NCR_700_change_queue_depth;
334 tpnt->change_queue_type = NCR_700_change_queue_type; 338 tpnt->change_queue_type = NCR_700_change_queue_type;
335 339
336 if(tpnt->name == NULL) 340 if(tpnt->name == NULL)
337 tpnt->name = "53c700"; 341 tpnt->name = "53c700";
338 if(tpnt->proc_name == NULL) 342 if(tpnt->proc_name == NULL)
339 tpnt->proc_name = "53c700"; 343 tpnt->proc_name = "53c700";
340
341 344
342 host = scsi_host_alloc(tpnt, 4); 345 host = scsi_host_alloc(tpnt, 4);
343 if (!host) 346 if (!host)
344 return NULL; 347 return NULL;
345 memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot) 348 memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot)
346 * NCR_700_COMMAND_SLOTS_PER_HOST); 349 * NCR_700_COMMAND_SLOTS_PER_HOST);
347 for(j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) { 350 for (j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) {
348 dma_addr_t offset = (dma_addr_t)((unsigned long)&hostdata->slots[j].SG[0] 351 dma_addr_t offset = (dma_addr_t)((unsigned long)&hostdata->slots[j].SG[0]
349 - (unsigned long)&hostdata->slots[0].SG[0]); 352 - (unsigned long)&hostdata->slots[0].SG[0]);
350 hostdata->slots[j].pSG = (struct NCR_700_SG_List *)((unsigned long)(pSlots + offset)); 353 hostdata->slots[j].pSG = (struct NCR_700_SG_List *)((unsigned long)(pSlots + offset));
@@ -355,14 +358,12 @@ NCR_700_detect(struct scsi_host_template *tpnt,
355 hostdata->slots[j].state = NCR_700_SLOT_FREE; 358 hostdata->slots[j].state = NCR_700_SLOT_FREE;
356 } 359 }
357 360
358 for(j = 0; j < sizeof(SCRIPT)/sizeof(SCRIPT[0]); j++) { 361 for (j = 0; j < ARRAY_SIZE(SCRIPT); j++)
359 script[j] = bS_to_host(SCRIPT[j]); 362 script[j] = bS_to_host(SCRIPT[j]);
360 }
361 363
362 /* adjust all labels to be bus physical */ 364 /* adjust all labels to be bus physical */
363 for(j = 0; j < PATCHES; j++) { 365 for (j = 0; j < PATCHES; j++)
364 script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]); 366 script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]);
365 }
366 /* now patch up fixed addresses. */ 367 /* now patch up fixed addresses. */
367 script_patch_32(script, MessageLocation, 368 script_patch_32(script, MessageLocation,
368 pScript + MSGOUT_OFFSET); 369 pScript + MSGOUT_OFFSET);
@@ -376,7 +377,7 @@ NCR_700_detect(struct scsi_host_template *tpnt,
376 dma_sync_single_for_device(hostdata->dev, pScript, sizeof(SCRIPT), DMA_TO_DEVICE); 377 dma_sync_single_for_device(hostdata->dev, pScript, sizeof(SCRIPT), DMA_TO_DEVICE);
377 hostdata->state = NCR_700_HOST_FREE; 378 hostdata->state = NCR_700_HOST_FREE;
378 hostdata->cmd = NULL; 379 hostdata->cmd = NULL;
379 host->max_id = 7; 380 host->max_id = 8;
380 host->max_lun = NCR_700_MAX_LUNS; 381 host->max_lun = NCR_700_MAX_LUNS;
381 BUG_ON(NCR_700_transport_template == NULL); 382 BUG_ON(NCR_700_transport_template == NULL);
382 host->transportt = NCR_700_transport_template; 383 host->transportt = NCR_700_transport_template;
@@ -385,17 +386,17 @@ NCR_700_detect(struct scsi_host_template *tpnt,
385 host->hostdata[0] = (unsigned long)hostdata; 386 host->hostdata[0] = (unsigned long)hostdata;
386 /* kick the chip */ 387 /* kick the chip */
387 NCR_700_writeb(0xff, host, CTEST9_REG); 388 NCR_700_writeb(0xff, host, CTEST9_REG);
388 if(hostdata->chip710) 389 if (hostdata->chip710)
389 hostdata->rev = (NCR_700_readb(host, CTEST8_REG)>>4) & 0x0f; 390 hostdata->rev = (NCR_700_readb(host, CTEST8_REG)>>4) & 0x0f;
390 else 391 else
391 hostdata->rev = (NCR_700_readb(host, CTEST7_REG)>>4) & 0x0f; 392 hostdata->rev = (NCR_700_readb(host, CTEST7_REG)>>4) & 0x0f;
392 hostdata->fast = (NCR_700_readb(host, CTEST9_REG) == 0); 393 hostdata->fast = (NCR_700_readb(host, CTEST9_REG) == 0);
393 if(banner == 0) { 394 if (banner == 0) {
394 printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley@HansenPartnership.com\n"); 395 printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley@HansenPartnership.com\n");
395 banner = 1; 396 banner = 1;
396 } 397 }
397 printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no, 398 printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no,
398 hostdata->chip710 ? "53c710" : 399 hostdata->chip710 ? "53c710" :
399 (hostdata->fast ? "53c700-66" : "53c700"), 400 (hostdata->fast ? "53c700-66" : "53c700"),
400 hostdata->rev, hostdata->differential ? 401 hostdata->rev, hostdata->differential ?
401 "(Differential)" : ""); 402 "(Differential)" : "");
@@ -540,6 +541,7 @@ find_empty_slot(struct NCR_700_Host_Parameters *hostdata)
540 * finish routine. If we cannot queue the command when it 541 * finish routine. If we cannot queue the command when it
541 * is properly build, we then change to NCR_700_SLOT_QUEUED */ 542 * is properly build, we then change to NCR_700_SLOT_QUEUED */
542 slot->state = NCR_700_SLOT_BUSY; 543 slot->state = NCR_700_SLOT_BUSY;
544 slot->flags = 0;
543 hostdata->command_slot_count++; 545 hostdata->command_slot_count++;
544 546
545 return slot; 547 return slot;
@@ -589,7 +591,7 @@ NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, struct scsi_cmnd *SCp,
589 if(SCp->sc_data_direction != DMA_NONE && 591 if(SCp->sc_data_direction != DMA_NONE &&
590 SCp->sc_data_direction != DMA_BIDIRECTIONAL) { 592 SCp->sc_data_direction != DMA_BIDIRECTIONAL) {
591 if(SCp->use_sg) { 593 if(SCp->use_sg) {
592 dma_unmap_sg(hostdata->dev, SCp->buffer, 594 dma_unmap_sg(hostdata->dev, SCp->request_buffer,
593 SCp->use_sg, SCp->sc_data_direction); 595 SCp->use_sg, SCp->sc_data_direction);
594 } else { 596 } else {
595 dma_unmap_single(hostdata->dev, slot->dma_handle, 597 dma_unmap_single(hostdata->dev, slot->dma_handle,
@@ -611,30 +613,23 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
611 (struct NCR_700_command_slot *)SCp->host_scribble; 613 (struct NCR_700_command_slot *)SCp->host_scribble;
612 614
613 NCR_700_unmap(hostdata, SCp, slot); 615 NCR_700_unmap(hostdata, SCp, slot);
614 dma_unmap_single(hostdata->dev, slot->pCmd, 616 if (slot->flags == NCR_700_FLAG_AUTOSENSE) {
615 sizeof(SCp->cmnd), DMA_TO_DEVICE); 617 struct NCR_700_sense *sense = SCp->device->hostdata;
616 if(SCp->cmnd[0] == REQUEST_SENSE && SCp->cmnd[6] == NCR_700_INTERNAL_SENSE_MAGIC) {
617#ifdef NCR_700_DEBUG 618#ifdef NCR_700_DEBUG
618 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",
619 SCp, SCp->cmnd[7], result); 620 SCp, SCp->cmnd[7], result);
620 scsi_print_sense("53c700", SCp); 621 scsi_print_sense("53c700", SCp);
621 622
622#endif 623#endif
624 dma_unmap_single(hostdata->dev, slot->dma_handle, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
623 /* restore the old result if the request sense was 625 /* restore the old result if the request sense was
624 * successful */ 626 * successful */
625 if(result == 0) 627 if(result == 0)
626 result = SCp->cmnd[7]; 628 result = sense->cmnd[7];
627 /* now restore the original command */ 629 } else
628 memcpy((void *) SCp->cmnd, (void *) SCp->data_cmnd, 630 dma_unmap_single(hostdata->dev, slot->pCmd,
629 sizeof(SCp->data_cmnd)); 631 sizeof(SCp->cmnd), DMA_TO_DEVICE);
630 SCp->request_buffer = SCp->buffer; 632
631 SCp->request_bufflen = SCp->bufflen;
632 SCp->use_sg = SCp->old_use_sg;
633 SCp->cmd_len = SCp->old_cmd_len;
634 SCp->sc_data_direction = SCp->sc_old_data_direction;
635 SCp->underflow = SCp->old_underflow;
636
637 }
638 free_slot(slot, hostdata); 633 free_slot(slot, hostdata);
639#ifdef NCR_700_DEBUG 634#ifdef NCR_700_DEBUG
640 if(NCR_700_get_depth(SCp->device) == 0 || 635 if(NCR_700_get_depth(SCp->device) == 0 ||
@@ -982,6 +977,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
982 "broken device is looping in contingent allegiance: ignoring\n"); 977 "broken device is looping in contingent allegiance: ignoring\n");
983 NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); 978 NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
984 } else { 979 } else {
980 struct NCR_700_sense *sense = SCp->device->hostdata;
985#ifdef NCR_DEBUG 981#ifdef NCR_DEBUG
986 scsi_print_command(SCp); 982 scsi_print_command(SCp);
987 printk(" cmd %p has status %d, requesting sense\n", 983 printk(" cmd %p has status %d, requesting sense\n",
@@ -995,27 +991,25 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
995 * data associated with the command 991 * data associated with the command
996 * here */ 992 * here */
997 NCR_700_unmap(hostdata, SCp, slot); 993 NCR_700_unmap(hostdata, SCp, slot);
998 994 dma_unmap_single(hostdata->dev, slot->pCmd,
999 SCp->cmnd[0] = REQUEST_SENSE; 995 sizeof(SCp->cmnd),
1000 SCp->cmnd[1] = (SCp->device->lun & 0x7) << 5; 996 DMA_TO_DEVICE);
1001 SCp->cmnd[2] = 0; 997
1002 SCp->cmnd[3] = 0; 998 sense->cmnd[0] = REQUEST_SENSE;
1003 SCp->cmnd[4] = sizeof(SCp->sense_buffer); 999 sense->cmnd[1] = (SCp->device->lun & 0x7) << 5;
1004 SCp->cmnd[5] = 0; 1000 sense->cmnd[2] = 0;
1005 SCp->cmd_len = 6; 1001 sense->cmnd[3] = 0;
1002 sense->cmnd[4] = sizeof(SCp->sense_buffer);
1003 sense->cmnd[5] = 0;
1006 /* Here's a quiet hack: the 1004 /* Here's a quiet hack: the
1007 * REQUEST_SENSE command is six bytes, 1005 * REQUEST_SENSE command is six bytes,
1008 * so store a flag indicating that 1006 * so store a flag indicating that
1009 * this was an internal sense request 1007 * this was an internal sense request
1010 * and the original status at the end 1008 * and the original status at the end
1011 * of the command */ 1009 * of the command */
1012 SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; 1010 sense->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
1013 SCp->cmnd[7] = hostdata->status[0]; 1011 sense->cmnd[7] = hostdata->status[0];
1014 SCp->use_sg = 0; 1012 slot->pCmd = dma_map_single(hostdata->dev, sense->cmnd, sizeof(sense->cmnd), DMA_TO_DEVICE);
1015 SCp->sc_data_direction = DMA_FROM_DEVICE;
1016 dma_sync_single_for_device(hostdata->dev, slot->pCmd,
1017 SCp->cmd_len, DMA_TO_DEVICE);
1018 SCp->request_bufflen = sizeof(SCp->sense_buffer);
1019 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);
1020 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));
1021 slot->SG[0].pAddr = bS_to_host(slot->dma_handle); 1015 slot->SG[0].pAddr = bS_to_host(slot->dma_handle);
@@ -1027,6 +1021,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
1027 1021
1028 /* queue the command for reissue */ 1022 /* queue the command for reissue */
1029 slot->state = NCR_700_SLOT_QUEUED; 1023 slot->state = NCR_700_SLOT_QUEUED;
1024 slot->flags = NCR_700_FLAG_AUTOSENSE;
1030 hostdata->state = NCR_700_HOST_FREE; 1025 hostdata->state = NCR_700_HOST_FREE;
1031 hostdata->cmd = NULL; 1026 hostdata->cmd = NULL;
1032 } 1027 }
@@ -1247,7 +1242,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
1247 1242
1248 if(SCp->use_sg) { 1243 if(SCp->use_sg) {
1249 for(i = 0; i < SCp->use_sg + 1; i++) { 1244 for(i = 0; i < SCp->use_sg + 1; i++) {
1250 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);
1251 } 1246 }
1252 } 1247 }
1253 } 1248 }
@@ -1406,12 +1401,14 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
1406 /* keep interrupts disabled until we have the command correctly 1401 /* keep interrupts disabled until we have the command correctly
1407 * set up so we cannot take a selection interrupt */ 1402 * set up so we cannot take a selection interrupt */
1408 1403
1409 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),
1410 SCp->device->lun); 1406 SCp->device->lun);
1411 /* for INQUIRY or REQUEST_SENSE commands, we cannot be sure 1407 /* for INQUIRY or REQUEST_SENSE commands, we cannot be sure
1412 * if the negotiated transfer parameters still hold, so 1408 * if the negotiated transfer parameters still hold, so
1413 * always renegotiate them */ 1409 * always renegotiate them */
1414 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) {
1415 NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC); 1412 NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
1416 } 1413 }
1417 1414
@@ -1420,7 +1417,8 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
1420 * will refuse all tags, so send the request sense as untagged 1417 * will refuse all tags, so send the request sense as untagged
1421 * */ 1418 * */
1422 if((hostdata->tag_negotiated & (1<<scmd_id(SCp))) 1419 if((hostdata->tag_negotiated & (1<<scmd_id(SCp)))
1423 && (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)) {
1424 count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]); 1422 count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]);
1425 } 1423 }
1426 1424
@@ -1866,8 +1864,9 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
1866 __u32 count = 0; 1864 __u32 count = 0;
1867 1865
1868 if(SCp->use_sg) { 1866 if(SCp->use_sg) {
1869 sg_count = dma_map_sg(hostdata->dev, SCp->buffer, 1867 sg_count = dma_map_sg(hostdata->dev,
1870 SCp->use_sg, direction); 1868 SCp->request_buffer, SCp->use_sg,
1869 direction);
1871 } else { 1870 } else {
1872 vPtr = dma_map_single(hostdata->dev, 1871 vPtr = dma_map_single(hostdata->dev,
1873 SCp->request_buffer, 1872 SCp->request_buffer,
@@ -1882,7 +1881,7 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
1882 for(i = 0; i < sg_count; i++) { 1881 for(i = 0; i < sg_count; i++) {
1883 1882
1884 if(SCp->use_sg) { 1883 if(SCp->use_sg) {
1885 struct scatterlist *sg = SCp->buffer; 1884 struct scatterlist *sg = SCp->request_buffer;
1886 1885
1887 vPtr = sg_dma_address(&sg[i]); 1886 vPtr = sg_dma_address(&sg[i]);
1888 count = sg_dma_len(&sg[i]); 1887 count = sg_dma_len(&sg[i]);
@@ -2045,6 +2044,11 @@ NCR_700_slave_configure(struct scsi_device *SDp)
2045 struct NCR_700_Host_Parameters *hostdata = 2044 struct NCR_700_Host_Parameters *hostdata =
2046 (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; 2045 (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
2047 2046
2047 SDp->hostdata = kmalloc(GFP_KERNEL, sizeof(struct NCR_700_sense));
2048
2049 if (!SDp->hostdata)
2050 return -ENOMEM;
2051
2048 /* to do here: allocate memory; build a queue_full list */ 2052 /* to do here: allocate memory; build a queue_full list */
2049 if(SDp->tagged_supported) { 2053 if(SDp->tagged_supported) {
2050 scsi_set_tag_type(SDp, MSG_ORDERED_TAG); 2054 scsi_set_tag_type(SDp, MSG_ORDERED_TAG);
@@ -2068,7 +2072,8 @@ NCR_700_slave_configure(struct scsi_device *SDp)
2068STATIC void 2072STATIC void
2069NCR_700_slave_destroy(struct scsi_device *SDp) 2073NCR_700_slave_destroy(struct scsi_device *SDp)
2070{ 2074{
2071 /* to do here: deallocate memory */ 2075 kfree(SDp->hostdata);
2076 SDp->hostdata = NULL;
2072} 2077}
2073 2078
2074static int 2079static int