aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sun3_NCR5380.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sun3_NCR5380.c')
-rw-r--r--drivers/scsi/sun3_NCR5380.c98
1 files changed, 23 insertions, 75 deletions
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index 07eaef1c722b..7e12a2e4e0a3 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -49,13 +49,6 @@
49 * inside the execution of NCR5380_intr(), leading to recursive 49 * inside the execution of NCR5380_intr(), leading to recursive
50 * calls. 50 * calls.
51 * 51 *
52 * - I've added a function merge_contiguous_buffers() that tries to
53 * merge scatter-gather buffers that are located at contiguous
54 * physical addresses and can be processed with the same DMA setup.
55 * Since most scatter-gather operations work on a page (4K) of
56 * 4 buffers (1K), in more than 90% of all cases three interrupts and
57 * DMA setup actions are saved.
58 *
59 * - I've deleted all the stuff for AUTOPROBE_IRQ, REAL_DMA_POLL, PSEUDO_DMA 52 * - I've deleted all the stuff for AUTOPROBE_IRQ, REAL_DMA_POLL, PSEUDO_DMA
60 * and USLEEP, because these were messing up readability and will never be 53 * and USLEEP, because these were messing up readability and will never be
61 * needed for Atari SCSI. 54 * needed for Atari SCSI.
@@ -266,8 +259,9 @@ static struct scsi_host_template *the_template = NULL;
266 (struct NCR5380_hostdata *)(in)->hostdata 259 (struct NCR5380_hostdata *)(in)->hostdata
267#define HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata) 260#define HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata)
268 261
269#define NEXT(cmd) (*(struct scsi_cmnd **)&((cmd)->host_scribble)) 262#define NEXT(cmd) ((struct scsi_cmnd *)(cmd)->host_scribble)
270#define NEXTADDR(cmd) ((struct scsi_cmnd **)&((cmd)->host_scribble)) 263#define SET_NEXT(cmd, next) ((cmd)->host_scribble = (void *)(next))
264#define NEXTADDR(cmd) ((struct scsi_cmnd **)&((cmd)->host_scribble))
271 265
272#define HOSTNO instance->host_no 266#define HOSTNO instance->host_no
273#define H_NO(cmd) (cmd)->device->host->host_no 267#define H_NO(cmd) (cmd)->device->host->host_no
@@ -459,47 +453,6 @@ static void free_all_tags( void )
459 453
460 454
461/* 455/*
462 * Function: void merge_contiguous_buffers(struct scsi_cmnd *cmd)
463 *
464 * Purpose: Try to merge several scatter-gather requests into one DMA
465 * transfer. This is possible if the scatter buffers lie on
466 * physical contiguous addresses.
467 *
468 * Parameters: struct scsi_cmnd *cmd
469 * The command to work on. The first scatter buffer's data are
470 * assumed to be already transferred into ptr/this_residual.
471 */
472
473static void merge_contiguous_buffers(struct scsi_cmnd *cmd)
474{
475 unsigned long endaddr;
476#if (NDEBUG & NDEBUG_MERGING)
477 unsigned long oldlen = cmd->SCp.this_residual;
478 int cnt = 1;
479#endif
480
481 for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1;
482 cmd->SCp.buffers_residual &&
483 virt_to_phys(SGADDR(&(cmd->SCp.buffer[1]))) == endaddr; ) {
484
485 MER_PRINTK("VTOP(%p) == %08lx -> merging\n",
486 SGADDR(&(cmd->SCp.buffer[1])), endaddr);
487#if (NDEBUG & NDEBUG_MERGING)
488 ++cnt;
489#endif
490 ++cmd->SCp.buffer;
491 --cmd->SCp.buffers_residual;
492 cmd->SCp.this_residual += cmd->SCp.buffer->length;
493 endaddr += cmd->SCp.buffer->length;
494 }
495#if (NDEBUG & NDEBUG_MERGING)
496 if (oldlen != cmd->SCp.this_residual)
497 MER_PRINTK("merged %d buffers from %p, new length %08x\n",
498 cnt, cmd->SCp.ptr, cmd->SCp.this_residual);
499#endif
500}
501
502/*
503 * Function : void initialize_SCp(struct scsi_cmnd *cmd) 456 * Function : void initialize_SCp(struct scsi_cmnd *cmd)
504 * 457 *
505 * Purpose : initialize the saved data pointers for cmd to point to the 458 * Purpose : initialize the saved data pointers for cmd to point to the
@@ -520,11 +473,6 @@ static __inline__ void initialize_SCp(struct scsi_cmnd *cmd)
520 cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1; 473 cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1;
521 cmd->SCp.ptr = (char *) SGADDR(cmd->SCp.buffer); 474 cmd->SCp.ptr = (char *) SGADDR(cmd->SCp.buffer);
522 cmd->SCp.this_residual = cmd->SCp.buffer->length; 475 cmd->SCp.this_residual = cmd->SCp.buffer->length;
523
524 /* ++roman: Try to merge some scatter-buffers if they are at
525 * contiguous physical addresses.
526 */
527// merge_contiguous_buffers( cmd );
528 } else { 476 } else {
529 cmd->SCp.buffer = NULL; 477 cmd->SCp.buffer = NULL;
530 cmd->SCp.buffers_residual = 0; 478 cmd->SCp.buffers_residual = 0;
@@ -841,7 +789,7 @@ static char *lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, char *pos, char *buffer,
841 * 789 *
842 */ 790 */
843 791
844static int NCR5380_init (struct Scsi_Host *instance, int flags) 792static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
845{ 793{
846 int i; 794 int i;
847 SETUP_HOSTDATA(instance); 795 SETUP_HOSTDATA(instance);
@@ -889,6 +837,11 @@ static int NCR5380_init (struct Scsi_Host *instance, int flags)
889 return 0; 837 return 0;
890} 838}
891 839
840static void NCR5380_exit(struct Scsi_Host *instance)
841{
842 /* Empty, as we didn't schedule any delayed work */
843}
844
892/* 845/*
893 * Function : int NCR5380_queue_command (struct scsi_cmnd *cmd, 846 * Function : int NCR5380_queue_command (struct scsi_cmnd *cmd,
894 * void (*done)(struct scsi_cmnd *)) 847 * void (*done)(struct scsi_cmnd *))
@@ -962,7 +915,7 @@ static int NCR5380_queue_command_lck(struct scsi_cmnd *cmd,
962 * in a queue 915 * in a queue
963 */ 916 */
964 917
965 NEXT(cmd) = NULL; 918 SET_NEXT(cmd, NULL);
966 cmd->scsi_done = done; 919 cmd->scsi_done = done;
967 920
968 cmd->result = 0; 921 cmd->result = 0;
@@ -990,14 +943,14 @@ static int NCR5380_queue_command_lck(struct scsi_cmnd *cmd,
990 */ 943 */
991 if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) { 944 if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
992 LIST(cmd, hostdata->issue_queue); 945 LIST(cmd, hostdata->issue_queue);
993 NEXT(cmd) = hostdata->issue_queue; 946 SET_NEXT(cmd, hostdata->issue_queue);
994 hostdata->issue_queue = cmd; 947 hostdata->issue_queue = cmd;
995 } else { 948 } else {
996 for (tmp = (struct scsi_cmnd *)hostdata->issue_queue; 949 for (tmp = (struct scsi_cmnd *)hostdata->issue_queue;
997 NEXT(tmp); tmp = NEXT(tmp)) 950 NEXT(tmp); tmp = NEXT(tmp))
998 ; 951 ;
999 LIST(cmd, tmp); 952 LIST(cmd, tmp);
1000 NEXT(tmp) = cmd; 953 SET_NEXT(tmp, cmd);
1001 } 954 }
1002 955
1003 local_irq_restore(flags); 956 local_irq_restore(flags);
@@ -1105,12 +1058,12 @@ static void NCR5380_main (struct work_struct *bl)
1105 local_irq_disable(); 1058 local_irq_disable();
1106 if (prev) { 1059 if (prev) {
1107 REMOVE(prev, NEXT(prev), tmp, NEXT(tmp)); 1060 REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
1108 NEXT(prev) = NEXT(tmp); 1061 SET_NEXT(prev, NEXT(tmp));
1109 } else { 1062 } else {
1110 REMOVE(-1, hostdata->issue_queue, tmp, NEXT(tmp)); 1063 REMOVE(-1, hostdata->issue_queue, tmp, NEXT(tmp));
1111 hostdata->issue_queue = NEXT(tmp); 1064 hostdata->issue_queue = NEXT(tmp);
1112 } 1065 }
1113 NEXT(tmp) = NULL; 1066 SET_NEXT(tmp, NULL);
1114 1067
1115 /* reenable interrupts after finding one */ 1068 /* reenable interrupts after finding one */
1116 local_irq_restore(flags); 1069 local_irq_restore(flags);
@@ -1144,7 +1097,7 @@ static void NCR5380_main (struct work_struct *bl)
1144 } else { 1097 } else {
1145 local_irq_disable(); 1098 local_irq_disable();
1146 LIST(tmp, hostdata->issue_queue); 1099 LIST(tmp, hostdata->issue_queue);
1147 NEXT(tmp) = hostdata->issue_queue; 1100 SET_NEXT(tmp, hostdata->issue_queue);
1148 hostdata->issue_queue = tmp; 1101 hostdata->issue_queue = tmp;
1149#ifdef SUPPORT_TAGS 1102#ifdef SUPPORT_TAGS
1150 cmd_free_tag( tmp ); 1103 cmd_free_tag( tmp );
@@ -1439,7 +1392,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd,
1439 local_irq_restore(flags); 1392 local_irq_restore(flags);
1440 1393
1441 /* Wait for arbitration logic to complete */ 1394 /* Wait for arbitration logic to complete */
1442#if NCR_TIMEOUT 1395#ifdef NCR_TIMEOUT
1443 { 1396 {
1444 unsigned long timeout = jiffies + 2*NCR_TIMEOUT; 1397 unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
1445 1398
@@ -2070,11 +2023,6 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
2070 --cmd->SCp.buffers_residual; 2023 --cmd->SCp.buffers_residual;
2071 cmd->SCp.this_residual = cmd->SCp.buffer->length; 2024 cmd->SCp.this_residual = cmd->SCp.buffer->length;
2072 cmd->SCp.ptr = SGADDR(cmd->SCp.buffer); 2025 cmd->SCp.ptr = SGADDR(cmd->SCp.buffer);
2073
2074 /* ++roman: Try to merge some scatter-buffers if
2075 * they are at contiguous physical addresses.
2076 */
2077// merge_contiguous_buffers( cmd );
2078 INF_PRINTK("scsi%d: %d bytes and %d buffers left\n", 2026 INF_PRINTK("scsi%d: %d bytes and %d buffers left\n",
2079 HOSTNO, cmd->SCp.this_residual, 2027 HOSTNO, cmd->SCp.this_residual,
2080 cmd->SCp.buffers_residual); 2028 cmd->SCp.buffers_residual);
@@ -2274,7 +2222,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
2274 2222
2275 local_irq_save(flags); 2223 local_irq_save(flags);
2276 LIST(cmd,hostdata->issue_queue); 2224 LIST(cmd,hostdata->issue_queue);
2277 NEXT(cmd) = hostdata->issue_queue; 2225 SET_NEXT(cmd, hostdata->issue_queue);
2278 hostdata->issue_queue = (struct scsi_cmnd *) cmd; 2226 hostdata->issue_queue = (struct scsi_cmnd *) cmd;
2279 local_irq_restore(flags); 2227 local_irq_restore(flags);
2280 QU_PRINTK("scsi%d: REQUEST SENSE added to head of " 2228 QU_PRINTK("scsi%d: REQUEST SENSE added to head of "
@@ -2330,7 +2278,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
2330 local_irq_save(flags); 2278 local_irq_save(flags);
2331 cmd->device->disconnect = 1; 2279 cmd->device->disconnect = 1;
2332 LIST(cmd,hostdata->disconnected_queue); 2280 LIST(cmd,hostdata->disconnected_queue);
2333 NEXT(cmd) = hostdata->disconnected_queue; 2281 SET_NEXT(cmd, hostdata->disconnected_queue);
2334 hostdata->connected = NULL; 2282 hostdata->connected = NULL;
2335 hostdata->disconnected_queue = cmd; 2283 hostdata->disconnected_queue = cmd;
2336 local_irq_restore(flags); 2284 local_irq_restore(flags);
@@ -2589,12 +2537,12 @@ static void NCR5380_reselect (struct Scsi_Host *instance)
2589 ) { 2537 ) {
2590 if (prev) { 2538 if (prev) {
2591 REMOVE(prev, NEXT(prev), tmp, NEXT(tmp)); 2539 REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
2592 NEXT(prev) = NEXT(tmp); 2540 SET_NEXT(prev, NEXT(tmp));
2593 } else { 2541 } else {
2594 REMOVE(-1, hostdata->disconnected_queue, tmp, NEXT(tmp)); 2542 REMOVE(-1, hostdata->disconnected_queue, tmp, NEXT(tmp));
2595 hostdata->disconnected_queue = NEXT(tmp); 2543 hostdata->disconnected_queue = NEXT(tmp);
2596 } 2544 }
2597 NEXT(tmp) = NULL; 2545 SET_NEXT(tmp, NULL);
2598 break; 2546 break;
2599 } 2547 }
2600 } 2548 }
@@ -2762,7 +2710,7 @@ static int NCR5380_abort(struct scsi_cmnd *cmd)
2762 if (cmd == tmp) { 2710 if (cmd == tmp) {
2763 REMOVE(5, *prev, tmp, NEXT(tmp)); 2711 REMOVE(5, *prev, tmp, NEXT(tmp));
2764 (*prev) = NEXT(tmp); 2712 (*prev) = NEXT(tmp);
2765 NEXT(tmp) = NULL; 2713 SET_NEXT(tmp, NULL);
2766 tmp->result = DID_ABORT << 16; 2714 tmp->result = DID_ABORT << 16;
2767 local_irq_restore(flags); 2715 local_irq_restore(flags);
2768 ABRT_PRINTK("scsi%d: abort removed command from issue queue.\n", 2716 ABRT_PRINTK("scsi%d: abort removed command from issue queue.\n",
@@ -2835,7 +2783,7 @@ static int NCR5380_abort(struct scsi_cmnd *cmd)
2835 if (cmd == tmp) { 2783 if (cmd == tmp) {
2836 REMOVE(5, *prev, tmp, NEXT(tmp)); 2784 REMOVE(5, *prev, tmp, NEXT(tmp));
2837 *prev = NEXT(tmp); 2785 *prev = NEXT(tmp);
2838 NEXT(tmp) = NULL; 2786 SET_NEXT(tmp, NULL);
2839 tmp->result = DID_ABORT << 16; 2787 tmp->result = DID_ABORT << 16;
2840 /* We must unlock the tag/LUN immediately here, since the 2788 /* We must unlock the tag/LUN immediately here, since the
2841 * target goes to BUS FREE and doesn't send us another 2789 * target goes to BUS FREE and doesn't send us another
@@ -2943,7 +2891,7 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
2943 2891
2944 for (i = 0; (cmd = disconnected_queue); ++i) { 2892 for (i = 0; (cmd = disconnected_queue); ++i) {
2945 disconnected_queue = NEXT(cmd); 2893 disconnected_queue = NEXT(cmd);
2946 NEXT(cmd) = NULL; 2894 SET_NEXT(cmd, NULL);
2947 cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16); 2895 cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16);
2948 cmd->scsi_done( cmd ); 2896 cmd->scsi_done( cmd );
2949 } 2897 }