patch-2.1.17 linux/drivers/scsi/wd33c93.c

Next file: linux/drivers/scsi/wd33c93.h
Previous file: linux/drivers/scsi/scsi.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.16/linux/drivers/scsi/wd33c93.c linux/drivers/scsi/wd33c93.c
@@ -68,11 +68,14 @@
  *
  */
 
+#include <linux/module.h>
+
 #include <asm/system.h>
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/version.h>
+#include <asm/irq.h>
 
 #if LINUX_VERSION_CODE >= 0x010300
 #include <linux/blk.h>
@@ -82,23 +85,19 @@
 
 #include "scsi.h"
 #include "hosts.h"
-#include "wd33c93.h"
 
-#ifdef MODULE
-#include <linux/module.h>
-#endif
 
-/* Leave this undefined for now - need to make some changes in the
- * a3000/a2019/gvp11 files to get it working right
- */
-/*#define PROC_INTERFACE*/     /* add code for /proc/scsi/wd33c93/xxx interface */
+#define PROC_INTERFACE     /* add code for /proc/scsi/wd33c93/xxx interface */
+#ifdef  PROC_INTERFACE
+#define PROC_STATISTICS    /* add code for keeping various real time stats */
+#endif
 
 #define SYNC_DEBUG         /* extra info on sync negotiation printed */
-#define DEBUGGING_ON       /* enable command-line debugging bitmask */
+#undef DEBUGGING_ON        /* enable command-line debugging bitmask */
 #define DEBUG_DEFAULTS 0   /* default debugging bitmask */
 
-#define WD33C93_VERSION    "1.21"
-#define WD33C93_DATE       "20/Apr/1996"
+#define WD33C93_VERSION    "1.23"
+#define WD33C93_DATE       "04/Nov/1996"
 
 #ifdef DEBUGGING_ON
 #define DB(f,a) if (hostdata->args & (f)) a;
@@ -106,9 +105,9 @@
 #define DB(f,a)
 #endif
 
-#define IS_DIR_OUT(cmd) ((cmd)->cmnd[0] == WRITE_6  || \
-                         (cmd)->cmnd[0] == WRITE_10 || \
-                         (cmd)->cmnd[0] == WRITE_12)
+
+#include "wd33c93.h"
+
 
 
 /*
@@ -123,6 +122,8 @@
  *                    negotiation on that device. To maintain backwards
  *                    compatibility, a command-line such as "wd33c93=255" will
  *                    be automatically translated to "wd33c93=nosync:0xff".
+ * -  nodma:x        -x = 1 to disable DMA, x = 0 to enable it. Argument is
+ *                    optional - if not present, same as "nodma:1".
  * -  period:ns      -ns is the minimum # of nanoseconds in a SCSI data transfer
  *                    period. Default is 500; acceptable values are 250 - 1000.
  * -  disconnect:x   -x = 0 to never allow disconnects, 2 to always allow them.
@@ -154,6 +155,8 @@
  *
  * Some amiboot examples (for insmod, use 'setup_strings' instead of 'wd33c93'):
  * -  wd33c93=nosync:255
+ * -  wd33c93=nodma
+ * -  wd33c93=nodma:1
  * -  wd33c93=disconnect:2,nosync:0x08,period:250
  * -  wd33c93=debug:0x1c
  */
@@ -161,10 +164,6 @@
 static char *setup_strings[] =
       {"","","","","","","","","","","",""};
 
-#ifdef PROC_INTERFACE
-unsigned long disc_allowed_total;
-unsigned long disc_taken_total;
-#endif
 
 
 inline uchar read_wd33c93(wd33c93_regs *regp,uchar reg_num)
@@ -228,6 +227,32 @@
 }
 
 
+/* The 33c93 needs to be told which direction a command transfers its
+ * data; we use this function to figure it out. Returns true if there
+ * will be a DATA_OUT phase with this command, false otherwise.
+ * (Thanks to Joerg Dorchain for the research and suggestion.)
+ */
+static int is_dir_out(Scsi_Cmnd *cmd)
+{
+   switch (cmd->cmnd[0]) {
+      case WRITE_6:           case WRITE_10:          case WRITE_12:
+      case WRITE_LONG:        case WRITE_SAME:        case WRITE_BUFFER:
+      case WRITE_VERIFY:      case WRITE_VERIFY_12:      
+      case COMPARE:           case COPY:              case COPY_VERIFY:
+      case SEARCH_EQUAL:      case SEARCH_HIGH:       case SEARCH_LOW:
+      case SEARCH_EQUAL_12:   case SEARCH_HIGH_12:    case SEARCH_LOW_12:      
+      case FORMAT_UNIT:       case REASSIGN_BLOCKS:   case RESERVE:
+      case MODE_SELECT:       case MODE_SELECT_10:    case LOG_SELECT:
+      case SEND_DIAGNOSTIC:   case CHANGE_DEFINITION: case UPDATE_BLOCK:
+      case SET_WINDOW:        case MEDIUM_SCAN:       case SEND_VOLUME_TAG:
+      case 0xea:
+         return 1;
+      default:
+         return 0;
+      }
+}
+
+
 
 static struct sx_period sx_table[] = {
    {  1, 0x20},
@@ -271,11 +296,9 @@
 {
 struct WD33C93_hostdata *hostdata;
 Scsi_Cmnd *tmp;
-unsigned long flags;
 
+   disable_irq(cmd->host->irq);
 
-   save_flags(flags);
-   cli();
    hostdata = (struct WD33C93_hostdata *)cmd->host->hostdata;
 
 DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld( ",cmd->target,cmd->cmnd[0],cmd->pid))
@@ -347,7 +370,7 @@
 
 DB(DB_QUEUE_COMMAND,printk(")Q-%ld ",cmd->pid))
 
-   restore_flags(flags);
+   enable_irq(cmd->host->irq);
    return 0;
 }
 
@@ -364,12 +387,9 @@
 struct WD33C93_hostdata *hostdata;
 wd33c93_regs *regp;
 Scsi_Cmnd *cmd, *prev;
-unsigned long flags;
 int i;
 
-
-   save_flags(flags);
-   cli();
+   disable_irq(instance->irq);
    hostdata = (struct WD33C93_hostdata *)instance->hostdata;
    regp = hostdata->regp;
 
@@ -379,7 +399,7 @@
 
 DB(DB_EXECUTE,printk(")EX-0 "))
 
-      restore_flags(flags);
+      enable_irq(instance->irq);
       return;
       }
 
@@ -403,7 +423,7 @@
 
 DB(DB_EXECUTE,printk(")EX-1 "))
 
-      restore_flags(flags);
+      enable_irq(instance->irq);
       return;
       }
 
@@ -414,11 +434,15 @@
    else
       hostdata->input_Q = (Scsi_Cmnd *)cmd->host_scribble;
 
+#ifdef PROC_STATISTICS
+   hostdata->cmd_cnt[cmd->target]++;
+#endif
+
    /*
     * Start the selection process
     */
 
-   if (IS_DIR_OUT(cmd))
+   if (is_dir_out(cmd))
       write_wd33c93(regp, WD_DESTINATION_ID, cmd->target);
    else
       write_wd33c93(regp, WD_DESTINATION_ID, cmd->target | DSTID_DPD);
@@ -471,8 +495,8 @@
 yes:
    cmd->SCp.phase = 1;
 
-#ifdef PROC_INTERFACE
-   disc_allowed_total++;
+#ifdef PROC_STATISTICS
+   hostdata->disc_allowed_cnt[cmd->target]++;
 #endif
 
 no:
@@ -546,13 +570,14 @@
 
       write_wd33c93(regp, WD_OWN_ID, cmd->cmd_len);
 
-   /* When doing a non-disconnect command, we can save ourselves a DATA
-    * phase interrupt later by setting everything up now.
+   /* When doing a non-disconnect command with DMA, we can save
+    * ourselves a DATA phase interrupt later by setting everything
+    * up ahead of time.
     */
 
-      if (cmd->SCp.phase == 0) {
+      if ((cmd->SCp.phase == 0) && (hostdata->no_dma == 0)) {
          if (hostdata->dma_setup(cmd,
-                     (IS_DIR_OUT(cmd))?DATA_OUT_DIR:DATA_IN_DIR))
+                     (is_dir_out(cmd))?DATA_OUT_DIR:DATA_IN_DIR))
             write_wd33c93_count(regp,0); /* guarantee a DATA_PHASE interrupt */
          else {
             write_wd33c93_count(regp, cmd->SCp.this_residual);
@@ -576,7 +601,7 @@
       
 DB(DB_EXECUTE,printk("%s%ld)EX-2 ",(cmd->SCp.phase)?"d:":"",cmd->pid))
 
-   restore_flags(flags);
+   enable_irq(instance->irq);
 }
 
 
@@ -586,7 +611,7 @@
 {
 uchar asr;
 
-DB(DB_TRANSFER,printk("(%p,%d,%s)",buf,cnt,data_in_dir?"in":"out"))
+DB(DB_TRANSFER,printk("(%p,%d,%s:",buf,cnt,data_in_dir?"in":"out"))
 
    write_wd33c93(regp, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
    write_wd33c93_count(regp,cnt);
@@ -620,6 +645,7 @@
 void transfer_bytes(wd33c93_regs *regp, Scsi_Cmnd *cmd, int data_in_dir)
 {
 struct WD33C93_hostdata *hostdata;
+unsigned long length;
 
    hostdata = (struct WD33C93_hostdata *)cmd->host->hostdata;
 
@@ -640,11 +666,27 @@
 
    write_wd33c93(regp,WD_SYNCHRONOUS_TRANSFER,hostdata->sync_xfer[cmd->target]);
 
-/* 'dma_setup()' will return TRUE if we can't do DMA. */
+/* 'hostdata->no_dma' is TRUE if we don't even want to try DMA.
+ * Update 'this_residual' and 'ptr' after 'transfer_pio()' returns.
+ */
+
+   if (hostdata->no_dma)
+      goto use_transfer_pio;
 
-   if (hostdata->dma_setup(cmd, data_in_dir)) {
-      transfer_pio(regp, (uchar *)&cmd->SCp.ptr, cmd->SCp.this_residual,
+/* 'dma_setup()' will return TRUE if we can't do DMA.
+ * Update 'this_residual' and 'ptr' after 'transfer_pio()' returns.
+ */
+
+   else if (hostdata->dma_setup(cmd, data_in_dir)) {
+use_transfer_pio:
+#ifdef PROC_STATISTICS
+      hostdata->pio_cnt++;
+#endif
+      transfer_pio(regp, (uchar *)cmd->SCp.ptr, cmd->SCp.this_residual,
                          data_in_dir, hostdata);
+      length = cmd->SCp.this_residual;
+      cmd->SCp.this_residual = read_wd33c93_count(regp);
+      cmd->SCp.ptr += (length - cmd->SCp.this_residual);
       }
 
 /* We are able to do DMA (in fact, the Amiga hardware is
@@ -657,6 +699,9 @@
  */
 
    else {
+#ifdef PROC_STATISTICS
+      hostdata->dma_cnt++;
+#endif
       write_wd33c93(regp, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_DMA);
       write_wd33c93_count(regp,cmd->SCp.this_residual);
 
@@ -679,11 +724,9 @@
 struct WD33C93_hostdata *hostdata;
 Scsi_Cmnd *patch, *cmd;
 wd33c93_regs *regp;
-unsigned long flags;
 uchar asr, sr, phs, id, lun, *ucp, msg;
 unsigned long length;
 
-
    hostdata = (struct WD33C93_hostdata *)instance->hostdata;
    regp = hostdata->regp;
 
@@ -691,10 +734,9 @@
    if (!(asr & ASR_INT) || (asr & ASR_BSY))
       return;
 
-/* OK - it should be safe to re-enable system interrupts */
-
-   save_flags(flags);
-   sti();
+#ifdef PROC_STATISTICS
+   hostdata->int_cnt++;
+#endif
 
    cmd = (Scsi_Cmnd *)hostdata->connected;   /* assume we're connected */
    sr = read_wd33c93(regp, WD_SCSI_STATUS);  /* clear the interrupt */
@@ -734,7 +776,7 @@
       case CSR_TIMEOUT:
 DB(DB_INTR,printk("TIMEOUT"))
 
-         cli();
+         disable_irq(instance->irq);
          if (hostdata->state == S_RUNNING_LEVEL2)
             hostdata->connected = NULL;
          else {
@@ -751,7 +793,7 @@
  * are commands waiting to be executed.
  */
 
-         sti();
+	 enable_irq(instance->irq);
          wd33c93_execute(instance);
          break;
 
@@ -759,7 +801,8 @@
 /* Note: this interrupt should not occur in a LEVEL2 command */
 
       case CSR_SELECT:
-         cli();
+	 disable_irq(instance->irq);
+
 DB(DB_INTR,printk("SELECT"))
          hostdata->connected = cmd = (Scsi_Cmnd *)hostdata->selecting;
          hostdata->selecting = NULL;
@@ -848,7 +891,7 @@
       case CSR_SRV_REQ  |PHS_MESS_IN:
 DB(DB_INTR,printk("MSG_IN="))
 
-         cli();
+         disable_irq(instance->irq);
          msg = read_1_byte(regp);
          sr = read_wd33c93(regp, WD_SCSI_STATUS);  /* clear interrupt */
 
@@ -997,7 +1040,7 @@
 /* Note: this interrupt will occur only after a LEVEL2 command */
 
       case CSR_SEL_XFER_DONE:
-         cli();
+         disable_irq(instance->irq);
 
 /* Make sure that reselection is enabled at this point - it may
  * have been turned off for the command that just completed.
@@ -1022,7 +1065,7 @@
 /* We are no longer  connected to a target - check to see if
  * there are commands waiting to be executed.
  */
-
+	    enable_irq(instance->irq);
             wd33c93_execute(instance);
             }
          else {
@@ -1081,7 +1124,7 @@
  * so we treat it as a normal command-complete-disconnect.
  */
 
-         cli();
+         disable_irq(instance->irq);
 
 /* Make sure that reselection is enabled at this point - it may
  * have been turned off for the command that just completed.
@@ -1106,13 +1149,13 @@
 /* We are no longer connected to a target - check to see if
  * there are commands waiting to be executed.
  */
-
+         enable_irq(instance->irq);
          wd33c93_execute(instance);
          break;
 
 
       case CSR_DISC:
-         cli();
+         disable_irq(instance->irq);
 
 /* Make sure that reselection is enabled at this point - it may
  * have been turned off for the command that just completed.
@@ -1142,8 +1185,8 @@
                hostdata->connected = NULL;
                hostdata->state = S_UNCONNECTED;
 
-#ifdef PROC_INTERFACE
-               disc_taken_total++;
+#ifdef PROC_STATISTICS
+               hostdata->disc_done_cnt[cmd->target]++;
 #endif
 
                break;
@@ -1155,7 +1198,7 @@
 /* We are no longer connected to a target - check to see if
  * there are commands waiting to be executed.
  */
-
+         enable_irq(instance->irq);
          wd33c93_execute(instance);
          break;
 
@@ -1163,7 +1206,7 @@
       case CSR_RESEL_AM:
 DB(DB_INTR,printk("RESEL"))
 
-         cli();
+         disable_irq(instance->irq);
 
    /* First we have to make sure this reselection didn't */
    /* happen during Arbitration/Selection of some other device. */
@@ -1243,7 +1286,7 @@
     * But we DO need to fix the DPD bit so it's correct for this command.
     */
 
-         if (IS_DIR_OUT(cmd))
+         if (is_dir_out(cmd))
             write_wd33c93(regp, WD_DESTINATION_ID, cmd->target);
          else
             write_wd33c93(regp, WD_DESTINATION_ID, cmd->target | DSTID_DPD);
@@ -1263,7 +1306,7 @@
          printk("--UNKNOWN INTERRUPT:%02x:%02x:%02x--",asr,sr,phs);
       }
 
-   restore_flags(flags);
+   enable_irq(instance->irq);
 
 DB(DB_INTR,printk("} "))
 
@@ -1319,7 +1362,6 @@
 int wd33c93_reset(Scsi_Cmnd *SCpnt)
 #endif
 {
-unsigned long flags;
 struct Scsi_Host *instance;
 struct WD33C93_hostdata *hostdata;
 int i;
@@ -1328,8 +1370,7 @@
    hostdata = (struct WD33C93_hostdata *)instance->hostdata;
 
    printk("scsi%d: reset. ", instance->host_no);
-   save_flags(flags);
-   cli();
+   disable_irq(instance->irq);
 
    ((struct WD33C93_hostdata *)instance->hostdata)->dma_stop(instance,NULL,0);
    for (i = 0; i < 8; i++) {
@@ -1348,7 +1389,7 @@
 
    reset_wd33c93(instance);
    SCpnt->result = DID_RESET << 16;
-   restore_flags(flags);
+   enable_irq(instance->irq);
    return 0;
 }
 
@@ -1360,10 +1401,8 @@
 struct WD33C93_hostdata *hostdata;
 wd33c93_regs *regp;
 Scsi_Cmnd *tmp, *prev;
-unsigned long flags;
 
-   save_flags (flags);
-   cli();
+   disable_irq(cmd->host->irq);
 
    instance = cmd->host;
    hostdata = (struct WD33C93_hostdata *)instance->hostdata;
@@ -1384,8 +1423,8 @@
          cmd->result = DID_ABORT << 16;
          printk("scsi%d: Abort - removing command %ld from input_Q. ",
            instance->host_no, cmd->pid);
+	 enable_irq(cmd->host->irq);
          cmd->scsi_done(cmd);
-         restore_flags(flags);
          return SCSI_ABORT_SUCCESS;
          }
       prev = tmp;
@@ -1453,12 +1492,12 @@
       hostdata->connected = NULL;
       hostdata->state = S_UNCONNECTED;
       cmd->result = DID_ABORT << 16;
-      cmd->scsi_done(cmd);
 
 /*      sti();*/
       wd33c93_execute (instance);
 
-      restore_flags(flags);
+      enable_irq(cmd->host->irq);
+      cmd->scsi_done(cmd);
       return SCSI_ABORT_SUCCESS;
       }
 
@@ -1474,7 +1513,7 @@
          printk("scsi%d: Abort - command %ld found on disconnected_Q - ",
                  instance->host_no, cmd->pid);
          printk("returning ABORT_SNOOZE. ");
-         restore_flags(flags);
+	 enable_irq(cmd->host->irq);
          return SCSI_ABORT_SNOOZE;
          }
       tmp = (Scsi_Cmnd *)tmp->host_scribble;
@@ -1493,7 +1532,7 @@
 /*   sti();*/
    wd33c93_execute (instance);
 
-   restore_flags(flags);
+   enable_irq(cmd->host->irq);
    printk("scsi%d: warning : SCSI command probably completed successfully"
       "         before abortion. ", instance->host_no);
    return SCSI_ABORT_NOT_RUNNING;
@@ -1606,6 +1645,11 @@
       hostdata->busy[i] = 0;
       hostdata->sync_xfer[i] = calc_sync_xfer(DEFAULT_SX_PER/4,DEFAULT_SX_OFF);
       hostdata->sync_stat[i] = SS_UNSET;  /* using default sync values */
+#ifdef PROC_STATISTICS
+      hostdata->cmd_cnt[i] = 0;
+      hostdata->disc_allowed_cnt[i] = 0;
+      hostdata->disc_done_cnt[i] = 0;
+#endif
       }
    hostdata->input_Q = NULL;
    hostdata->selecting = NULL;
@@ -1620,20 +1664,26 @@
    hostdata->outgoing_len = 0;
    hostdata->default_sx_per = DEFAULT_SX_PER;
    hostdata->no_sync = 0xff;     /* sync defaults to off */
+   hostdata->no_dma = 0;         /* default is DMA enabled */
 
 #ifdef PROC_INTERFACE
-   hostdata->proc = PR_VERSION|PR_INFO|PR_TOTALS|
+   hostdata->proc = PR_VERSION|PR_INFO|PR_STATISTICS|
                     PR_CONNECTED|PR_INPUTQ|PR_DISCQ|
                     PR_STOP;
-
-   disc_allowed_total = 0;
-   disc_taken_total = 0;
+#ifdef PROC_STATISTICS
+   hostdata->dma_cnt = 0;
+   hostdata->pio_cnt = 0;
+   hostdata->int_cnt = 0;
+#endif
 #endif
 
 
    if (check_setup_strings("nosync",&flags,&val,buf))
       hostdata->no_sync = val;
 
+   if (check_setup_strings("nodma",&flags,&val,buf))
+      hostdata->no_dma = (val == -1) ? 1 : val;
+
    if (check_setup_strings("period",&flags,&val,buf))
       hostdata->default_sx_per = sx_table[round_period((unsigned int)val)].period_ns;
 
@@ -1674,23 +1724,22 @@
    reset_wd33c93(instance);
    sti();
 
-   printk("wd33c93-%d: chip=%s microcode=%02x\n",instance->host_no,
+   printk("wd33c93-%d: chip=%s/%d no_sync=0x%x no_dma=%d\n",instance->host_no,
          (hostdata->chip==C_WD33C93)?"WD33c93":
          (hostdata->chip==C_WD33C93A)?"WD33c93A":
          (hostdata->chip==C_WD33C93B)?"WD33c93B":"unknown",
-         hostdata->microcode);
-
+         hostdata->microcode,hostdata->no_sync,hostdata->no_dma);
 #ifdef DEBUGGING_ON
-   printk("wd33c93-%d: setup_strings=",instance->host_no);
+   printk("           debug_flags=0x%02x setup_strings=",hostdata->args);
+#else
+   printk("           debugging=OFF setup_strings=");
+#endif
    for (i=0; i<MAX_SETUP_STRINGS; i++)
       printk("%s,",setup_strings[i]);
    printk("\n");
-   printk("wd33c93-%d: debug_flags = %04x\n",instance->host_no,hostdata->args);
-#endif
-   printk("wd33c93-%d: driver version %s - %s\n",instance->host_no,
-                     WD33C93_VERSION,WD33C93_DATE);
-   printk("wd33c93-%d: compiled on %s at %s\n",instance->host_no,
-                     __DATE__,__TIME__);
+   printk("           Version %s - %s, Compiled %s at %s\n",
+               WD33C93_VERSION,WD33C93_DATE,__DATE__,__TIME__);
+   MOD_INC_USE_COUNT;
 }
 
 
@@ -1708,7 +1757,7 @@
 int x,i;
 static int stop = 0;
 
-   for (instance=instance_list; instance; instance=instance->next) {
+   for (instance=scsi_hostlist; instance; instance=instance->next) {
       if (instance->host_no == hn)
          break;
       }
@@ -1725,6 +1774,7 @@
  *    period
  *    resync
  *    proc
+ *    nodma
  */
 
    if (in) {
@@ -1757,6 +1807,10 @@
          bp += 5;
          hd->proc = simple_strtoul(bp,NULL,0);
          }
+      else if (!strncmp(bp,"nodma:",6)) {
+         bp += 6;
+         hd->no_dma = simple_strtoul(bp,NULL,0);
+         }
       return len;
       }
 
@@ -1770,13 +1824,42 @@
       strcat(bp,tbuf);
       }
    if (hd->proc & PR_INFO) {
-      ;
+      sprintf(tbuf,"\nclock_freq=%02x no_sync=%02x no_dma=%d",
+            hd->clock_freq,hd->no_sync,hd->no_dma);
+      strcat(bp,tbuf);
+      strcat(bp,"\nsync_xfer[] =");
+      for (x=0; x<8; x++) {
+         sprintf(tbuf," %02x",hd->sync_xfer[x]);
+         strcat(bp,tbuf);
+         }
+      strcat(bp,"\nsync_stat[] =");
+      for (x=0; x<8; x++) {
+         sprintf(tbuf," %02x",hd->sync_stat[x]);
+         strcat(bp,tbuf);
+         }
       }
-   if (hd->proc & PR_TOTALS) {
-      sprintf(tbuf,"\n%ld disc_allowed, %ld disc_taken",
-            disc_allowed_total,disc_taken_total);
+#ifdef PROC_STATISTICS
+   if (hd->proc & PR_STATISTICS) {
+      strcat(bp,"\ncommands issued:    ");
+      for (x=0; x<8; x++) {
+         sprintf(tbuf," %ld",hd->cmd_cnt[x]);
+         strcat(bp,tbuf);
+         }
+      strcat(bp,"\ndisconnects allowed:");
+      for (x=0; x<8; x++) {
+         sprintf(tbuf," %ld",hd->disc_allowed_cnt[x]);
+         strcat(bp,tbuf);
+         }
+      strcat(bp,"\ndisconnects done:   ");
+      for (x=0; x<8; x++) {
+         sprintf(tbuf," %ld",hd->disc_done_cnt[x]);
+         strcat(bp,tbuf);
+         }
+      sprintf(tbuf,"\ninterrupts: %ld, DATA_PHASE ints: %ld DMA, %ld PIO",
+            hd->int_cnt,hd->dma_cnt,hd->pio_cnt);
       strcat(bp,tbuf);
       }
+#endif
    if (hd->proc & PR_CONNECTED) {
       strcat(bp,"\nconnected:     ");
       if (hd->connected) {
@@ -1827,12 +1910,11 @@
 
 }
 
-
 #ifdef MODULE
-
-Scsi_Host_Template driver_template = WD33C93;
-
-#include "scsi_module.c"
-
+int init_module(void) { return 0; }
+void cleanup_module(void) {}
+void wd33c93_release(void)
+{
+MOD_DEC_USE_COUNT;
+}
 #endif
-

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov