]> git.neil.brown.name Git - history.git/commitdiff
Import 1.1.68 1.1.68
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:45 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:45 +0000 (15:09 -0500)
66 files changed:
CREDITS
Makefile
drivers/block/cdu31a.c
drivers/char/console.c
drivers/net/MODULES
drivers/net/eexpress.c
drivers/net/plip.c
drivers/scsi/53c7,8xx.c
drivers/scsi/53c7,8xx.h
drivers/scsi/NCR5380.c
drivers/scsi/aha152x.c
drivers/scsi/aha152x.h
drivers/scsi/aha1542.c
drivers/scsi/aha1542.h
drivers/scsi/aha1740.c
drivers/scsi/aha1740.h
drivers/scsi/aha274x.c
drivers/scsi/aha274x.h
drivers/scsi/buslogic.c
drivers/scsi/buslogic.h
drivers/scsi/eata.c
drivers/scsi/eata.h
drivers/scsi/fdomain.c
drivers/scsi/fdomain.h
drivers/scsi/g_NCR5380.h
drivers/scsi/hosts.c
drivers/scsi/hosts.h
drivers/scsi/in2000.c
drivers/scsi/in2000.h
drivers/scsi/pas16.c
drivers/scsi/pas16.h
drivers/scsi/qlogic.c
drivers/scsi/qlogic.h
drivers/scsi/scsi.c
drivers/scsi/scsi.h
drivers/scsi/scsi_debug.h
drivers/scsi/scsi_ioctl.c
drivers/scsi/sd.c
drivers/scsi/sd.h
drivers/scsi/seagate.c
drivers/scsi/seagate.h
drivers/scsi/sg.c
drivers/scsi/sg.h
drivers/scsi/sr.c
drivers/scsi/t128.c
drivers/scsi/t128.h
drivers/scsi/u14-34f.c
drivers/scsi/u14-34f.h
drivers/scsi/ultrastor.c
drivers/scsi/ultrastor.h
drivers/scsi/wd7000.c
drivers/scsi/wd7000.h
fs/locks.c
fs/proc/array.c
fs/umsdos/emd.c
include/asm-i386/dma.h
include/linux/inet.h
include/linux/ioport.h
include/linux/ip.h
include/linux/mm.h
include/linux/tcp.h
init/main.c
kernel/ioport.c
modules/NET_MODULES
net/inet/proc.c
net/inet/sock.c

diff --git a/CREDITS b/CREDITS
index 77b5748fa3ef210cab553787d88f0b8de3404741..85510e49aab91d027a8f0c750c2f49b4fadf9d23 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -539,6 +539,13 @@ S: Ormond
 S: Victoria 3163
 S: Australia
 
+N: Pauline Middelink
+E: middelin@polyware.iaf.nl
+D: General low-level bug fixes, /proc fixes, identd support
+S: Boterkorfhoek 34
+S: 7546 JA  Enschede
+S: Netherlands
+
 N: Rick Miller
 E: rick@discus.mil.wi.us
 D: Linux Device Registrar (Major/minor numbers), "au-play", "bwBASIC"
index d4820462cd41f07db88740c48fa6b01b81ba7646..203a9b3dbfb945d306f3a405a0136eaafbe196e9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 67
+SUBLEVEL = 68
 
 ARCH = i386
 
index b7825abf92654562ab67df252105093f00f11e6b..e4d789e4d9ccfcfd40af7c8e7c3f230d5fe4c87a 100644 (file)
@@ -2773,7 +2773,7 @@ cdu31a_setup(char *strings,
    {
       irq_used = ints[2];
    }
-   if (*strings != '\0')
+   if ((strings != NULL) && (*strings != '\0'))
    {
       if (strcmp(strings, "PAS") == 0)
       {
index a12b321b452f9bcc49193edbca4ec986f607ab4b..7a48e787167e62e5637c1071a8e6b0178ee50e43 100644 (file)
@@ -2106,7 +2106,7 @@ void update_screen(int new_console)
        }
        lock = 1;
 #ifdef CONFIG_SELECTION
-       highlight_pointer(fg_console,-1);
+       clear_selection();
 #endif /* CONFIG_SELECTION */
        if (!console_blanked)
                get_scrmem(fg_console);
@@ -2148,7 +2148,7 @@ int do_screendump(int arg, int mode)
        /* mode 0 needs 2+wd*ht, modes 1 and 2 need 4+2*wd*ht */
        chcount=video_num_columns*video_num_lines;
        l = verify_area(mode==2 ? VERIFY_READ :VERIFY_WRITE,
-               buf, (2+chcount)*(1+mode!=0));
+               buf, (2+chcount)*(mode ? 2 : 1));
        if (l)
                return l;
        if (mode<2) {
@@ -2162,12 +2162,14 @@ int do_screendump(int arg, int mode)
                put_fs_byte(*sptr++,buf++);     
                        break;
            case 1:
+#ifdef CONFIG_SELECTION
+                       clear_selection();
+#endif
                        put_fs_byte((char)x,buf++); put_fs_byte((char)y,buf++); 
                        memcpy_tofs(buf,(char *)origin,2*chcount);
                        break;
            case 2:
-                       buf+=2; /* skip the the numnber 9 and console number */
-                       x=get_fs_byte(buf++); y=get_fs_byte(buf++);
+                       buf+=4; /* ioctl#, console#, x,y */
                        memcpy_fromfs((char *)origin,buf,2*chcount);
                        break;
            }
@@ -2356,7 +2358,6 @@ int set_selection(const int arg, struct tty_struct *tty)
                case 3: /* pointer highlight */
                        if (sel_cons != currcons)
                        {
-                               highlight_pointer(sel_cons,-1);
                                clear_selection();
                                sel_cons = currcons;
                        }
@@ -2491,7 +2492,8 @@ static void clear_selection()
  */
 
 #define colourmap ((char *)0xa0000)
-/* Pauline Middelink reports that we should use 0xA0000 for the bwmap as well.. */
+/* Pauline Middelink <middelin@polyware.iaf.nl> reports that we
+   should use 0xA0000 for the bwmap as well.. */
 #define blackwmap ((char *)0xa0000)
 #define cmapsz 8192
 #define seq_port_reg (0x3c4)
index d9c8ca454ca80efadb69c3c53b52611a929d4e32..6ef0c7d3b1f9402bda9336c48a261921b2be3d67 100644 (file)
@@ -3,5 +3,6 @@ MODULES = \
        de600.o \
        de620.o \
        3c501.o \
+       eexpress.o \
        plip.o \
        8390.o
index dde116f113c19eb654a77f8f55bbe1ebffa9ccbd..ace82ca4e6761eff66b47405a3e26d50df3af8d4 100644 (file)
@@ -17,6 +17,8 @@
        Move the theory of operation and memory map documentation.
        Rework the board error reset
        The statistics need to be updated correctly.
+
+        Modularized my Pauline Middelink <middelin@polyware.iaf.nl>
 */
 
 static char *version =
@@ -53,6 +55,10 @@ static char *version =
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#ifdef MODULE
+#include <linux/module.h>
+#include "../../tools/version.h"
+#endif
 
 #include <linux/malloc.h>
 
@@ -435,6 +441,9 @@ eexp_open(struct device *dev)
        dev->tbusy = 0;
        dev->interrupt = 0;
        dev->start = 1;
+#ifdef MODULE
+       MOD_INC_USE_COUNT;
+#endif
        return 0;
 }
 
@@ -647,6 +656,9 @@ eexp_close(struct device *dev)
 
        /* Update the statistics here. */
 
+#ifdef MODULE
+       MOD_DEC_USE_COUNT;
+#endif
        return 0;
 }
 
@@ -981,6 +993,32 @@ eexp_rx(struct device *dev)
        outw(saved_write_ptr, ioaddr + WRITE_PTR);
 }
 \f
+#ifdef MODULE
+char kernel_version[] = UTS_RELEASE;
+static struct device dev_eexpress = {
+       "        " /*"eexpress"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe };
+
+int
+init_module(void)
+{
+       if (register_netdev(&dev_eexpress) != 0)
+               return -EIO;
+       return 0;
+}
+
+void
+cleanup_module(void)
+{
+       if (MOD_IN_USE)
+               printk("express: device busy, remove delayed\n");
+       else
+       {
+               unregister_netdev(&dev_eexpress);
+               kfree_s(dev_eexpress.priv,sizeof(struct net_local));
+               dev_eexpress.priv=NULL;
+       }
+}
+#endif /* MODULE */
 /*
  * Local variables:
  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -I/usr/src/linux/drivers/net -Wall -Wstrict-prototypes -O6 -m486 -c eexpress.c"
index 63de01bf0280eb551964667f9c4d1eee9edc8931..f54135a47247dd058cfadcc3e8e1e5676834afbc 100644 (file)
@@ -545,7 +545,7 @@ plip_device_clear(struct device *dev)
     enable_irq(dev->irq);
 }
 
-/* PLIP_ERROR --- wait til other end setteled */
+/* PLIP_ERROR --- wait til other end settled */
 static int
 plip_error(struct device *dev)
 {
index 24d679201c563d2f37eadba13761089c88c1b58e..99a7d360d1de134176e716686186c58580f0022d 100644 (file)
@@ -2424,7 +2424,7 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
     tmp->select[0] = IDENTIFY (0, cmd->lun);
 #endif
     patch_dsa_32(tmp->dsa, dsa_msgout, 1, tmp->select);
-    patch_dsa_32(tmp->dsa, dsa_cmdout, 0, COMMAND_SIZE(cmd->cmnd[0]));
+    patch_dsa_32(tmp->dsa, dsa_cmdout, 0, cmd->cmd_len);
     patch_dsa_32(tmp->dsa, dsa_cmdout, 1, cmd->cmnd);
     patch_dsa_32(tmp->dsa, dsa_dataout, 0, cmd_dataout ? 
        cmd_dataout : hostdata->script + hostdata->E_other_transfer / 
@@ -3742,10 +3742,6 @@ int NCR53c7xx_reset (Scsi_Cmnd *cmd) {
     return SCSI_RESET_SNOOZE;
 }
 
-const char *NCR53c7xx_info (void) {
-    return("More info here\n");
-}
-
 /*
  * The NCR SDMS bios follows Annex A of the SCSI-CAM draft, and 
  * therefore shares the scsicam_bios_param function.
index 7793f99ac2284d927e71d06c4d916f38c990fef7..1eee787993f1ba733d36322ded5d76176c715312 100644 (file)
 #include <linux/scsicam.h>
 extern int NCR53c7xx_abort(Scsi_Cmnd *);
 extern int NCR53c7xx_detect(Scsi_Host_Template *tpnt);
-extern const char *NCR53c7xx_info(void);
 extern int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 extern int NCR53c7xx_reset(Scsi_Cmnd *);
 
-#define NCR53c7xx {NULL, "NCR53c{7,8}xx (rel 3)", NCR53c7xx_detect,    \
-       NULL, NCR53c7xx_info,                                           \
+#define NCR53c7xx {NULL, NULL, "NCR53c{7,8}xx (rel 3)", NCR53c7xx_detect,      \
+       NULL, NULL,                                             \
        NULL, NCR53c7xx_queue_command, NCR53c7xx_abort, NCR53c7xx_reset,\
         NULL, scsicam_bios_param,                                      \
        /* can queue */ 1, /* id */ 7, 255 /* old SG_ALL */,            \
index 19d13b3ddea3566a9e8e450c53942cb9171bd01e..f99f5875ec77804ad836fd8d4c1e40f98a435a2f 100644 (file)
@@ -2306,7 +2306,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) {
                msgout = NOP;
                break;
            case PHASE_CMDOUT:
-               len = COMMAND_SIZE(cmd->cmnd[0]);
+               len = cmd->cmd_len;
                data = cmd->cmnd;
                /* 
                 * XXX for performance reasons, on machines with a 
index 4107006c53793a5159e591df2230f4c89b2fce00..7ae1ee4a0b95fcb3129a32c7c11a921b17853987 100644 (file)
 #define P_BUSFREE  1
 #define P_PARITY   2
 
-static char *aha152x_id = AHA152X_REVID;
-
 static int port_base      = 0;
 static int this_host      = 0;
 static int can_disconnect = 0;
@@ -734,14 +732,6 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
   return 1;
 }
 
-/*
- *  return the name of the thing
- */
-const char *aha152x_info(void)
-{
-  return(aha152x_id);
-}
-
 /* 
  *  Queue a command and setup interrupts for a free bus.
  */
@@ -1590,14 +1580,14 @@ void aha152x_intr( int irqno )
           if(aha152x_debug & debug_cmd)
           {
             printk("DFIFOEMP, outsw (%d words), ",
-                   COMMAND_SIZE(current_SC->cmnd[0])>>1);
+                   current_SC->cmd_len >>1 );
             disp_ports();
           }
 #endif
   
           outsw( DATAPORT,
                  &current_SC->cmnd,
-                 COMMAND_SIZE(current_SC->cmnd[0])>>1 );
+               current_SC->cmd_len >>1 );
 
 #if defined(DEBUG_CMD)
          if(aha152x_debug & debug_cmd)
@@ -1622,7 +1612,7 @@ void aha152x_intr( int irqno )
 #if defined(DEBUG_CMD) || defined(DEBUG_INTR)
           if(debug_cmd & debug_intr)
             printk("sent %d/%d command bytes, ", GETSTCNT(),
-                   COMMAND_SIZE(current_SC->cmnd[0]));
+                   current_SC->cmd_len);
 #endif
 
         }
index 09cf73b2ea7d70457075176c7e832ef99c210275..b8c9ae9bd1b5906e8fb2a93eff8a9d7d2931192d 100644 (file)
@@ -12,7 +12,6 @@
 #include <asm/io.h>
 
 int        aha152x_detect(Scsi_Host_Template *);
-const char *aha152x_info(void);
 int        aha152x_command(Scsi_Cmnd *);
 int        aha152x_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int        aha152x_abort(Scsi_Cmnd *);
@@ -27,10 +26,11 @@ int        aha152x_biosparam(Disk *, int, int*);
 
 /* Initial value of Scsi_Host entry */
 #define AHA152X       { /* next */             NULL,                       \
+                       /* usage_count */       NULL,                       \
                        /* name */              AHA152X_REVID,              \
                        /* detect */            aha152x_detect,             \
                        /* release */           NULL,                       \
-                       /* info */              aha152x_info,               \
+                       /* info */              NULL,                       \
                        /* command */           aha152x_command,            \
                        /* queuecommand */      aha152x_queue,              \
                         /* abort */            aha152x_abort,              \
index 4079522e8116ce5b1df3e38f68f01aca5f9c0dbe..9011814f609bb1250896e0a6aacdedf19a005f98 100644 (file)
@@ -10,6 +10,8 @@
  *        have the bios enabled to use the aha1542.
  *  Modified by David Gentzel
  *       Don't call request_dma if dma mask is 0 (for BusLogic BT-445S VL-Bus controller).
+ *  Modified by Matti Aarnio
+ *        Accept parameters from LILO cmd-line. -- 1-Oct-94
  */
 
 #include <linux/kernel.h>
@@ -43,9 +45,38 @@ static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/aha
 /* The adaptec can be configured for quite a number of addresses, but
 I generally do not want the card poking around at random.  We allow
 two addresses - this allows people to use the Adaptec with a Midi
-card, which also used 0x330 */
+card, which also used 0x330 -- can be overriden with LILO! */
+
+#define MAXBOARDS 2    /* Increase this and the sizes of the
+                          arrays below, if you need more.. */
+
+static unsigned int bases[MAXBOARDS]={0x330, 0x334};
+
+/* set by aha1542_setup according to the command line */
+static int setup_called[MAXBOARDS]   = {0,0};
+static int setup_buson[MAXBOARDS]    = {0,0};
+static int setup_busoff[MAXBOARDS]   = {0,0};
+static int setup_dmaspeed[MAXBOARDS] = {-1,-1};
+
+static char *setup_str[MAXBOARDS] = {(char *)NULL,(char *)NULL};
+
+/*
+ * LILO params:  aha1542=<PORTBASE>[,<BUSON>,<BUSOFF>[,<DMASPEED>]]
+ *
+ * Where:  <PORTBASE> is any of the valid AHA addresses:
+ *                     0x130, 0x134, 0x230, 0x234, 0x330, 0x334
+ *        <BUSON>  is the time (in microsecs) that AHA spends on the AT-bus
+ *                 when transferring data.  1542A power-on default is 11us,
+ *                 valid values are in range: 2..15 (decimal)
+ *        <BUSOFF> is the time that AHA spends OFF THE BUS after while
+ *                 it is transferring data (not to monopolize the bus).
+ *                 Power-on default is 4us, valid range: 1..64 microseconds.
+ *        <DMASPEED> Default is jumper selected (1542A: on the J1),
+ *                 but experimenter can alter it with this.
+ *                 Valid values: 5, 6, 7, 8, 10 (MB/s)
+ *                 Factory default is 5 MB/s.
+ */
 
-static unsigned int bases[]={0x330, 0x334};
 
 /* The DMA-Controller.  We need to fool with this because we want to 
    be able to use the aha1542 without having to have the bios enabled */
@@ -253,6 +284,7 @@ static int aha1542_test_port(int bse, struct Scsi_Host * shpnt)
 
     /* In case some other card was probing here, reset interrupts */
     aha1542_intr_reset(bse);     /* reset interrupts, so they don't block */   
+
     outb(SRST|IRST/*|SCRST*/, CONTROL(bse));
 
     i = jiffies + 2;
@@ -302,14 +334,6 @@ static int aha1542_test_port(int bse, struct Scsi_Host * shpnt)
     return 0;                                  /* 0 = not ok */
 }
 
-static const char aha_ident[] = "Adaptec 1542";
-
-/* What's this little function for? */
-const char *aha1542_info(void)
-{
-    return aha_ident;
-}
-
 /* A "high" level interrupt handler */
 static void aha1542_intr_handle(int foo)
 {
@@ -513,7 +537,7 @@ int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
       printk("aha1542_command: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
     aha1542_stat();
     printk("aha1542_queuecommand: dumping scsi cmd:");
-    for (i = 0; i < (COMMAND_SIZE(*cmd)); i++) printk("%02x ", cmd[i]);
+    for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
     printk("\n");
     if (*cmd == WRITE_10 || *cmd == WRITE_6)
       return 0; /* we are still testing, so *don't* write */
@@ -549,7 +573,7 @@ int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
 
     memset(&ccb[mbo], 0, sizeof(struct ccb));
 
-    ccb[mbo].cdblen = COMMAND_SIZE(*cmd);     /* SCSI Command Descriptor Block Length */
+    ccb[mbo].cdblen = SCpnt->cmd_len;
 
     direction = 0;
     if (*cmd == READ_10 || *cmd == READ_6)
@@ -590,7 +614,6 @@ int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
        any2scsi(cptr[i].datalen, sgpnt[i].length);
       };
       any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));
-      if(((unsigned int) buff & 0xff000000)) goto baddma;
       any2scsi(ccb[mbo].dataptr, cptr);
 #ifdef DEBUG
       printk("cptr %x: ",cptr);
@@ -601,6 +624,7 @@ int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
       ccb[mbo].op = 0;       /* SCSI Initiator Command */
       SCpnt->host_scribble = NULL;
       any2scsi(ccb[mbo].datalen, bufflen);
+      if(((unsigned int) buff & 0xff000000)) goto baddma;
       any2scsi(ccb[mbo].dataptr, buff);
     };
     ccb[mbo].idlun = (target&7)<<5 | direction | (lun & 7); /*SCSI Target Id*/
@@ -813,6 +837,66 @@ static int aha1542_query(int base_io, int * transl)
   return 0;
 }
 
+/* called from init/main.c */
+void aha1542_setup( char *str, int *ints)
+{
+    char *ahausage = "aha1542: usage: aha1542=<PORTBASE>[,<BUSON>,<BUSOFF>[,<DMASPEED>]]\n";
+    static int setup_idx = 0;
+    int setup_portbase;
+
+    if(setup_idx >= MAXBOARDS)
+      {
+       printk("aha1542: aha1542_setup called too many times! Bad LILO params ?\n");
+       printk("   Entryline 1: %s\n",setup_str[0]);
+       printk("   Entryline 2: %s\n",setup_str[1]);
+       printk("   This line:   %s\n",str);
+       return;
+      }
+    if (ints[0] < 1 || ints[0] > 4)
+      {
+       printk("aha1542: %s\n", str );
+       printk(ahausage);
+       printk("aha1542: Wrong parameters may cause system malfunction.. We try anyway..\n");
+      }
+
+    setup_called[setup_idx]=ints[0];
+    setup_str[setup_idx]=str;
+
+    setup_portbase             = ints[0] >= 1 ? ints[1] : 0; /* Preserve the default value.. */
+    setup_buson   [setup_idx]  = ints[0] >= 2 ? ints[2] : 7;
+    setup_busoff  [setup_idx]  = ints[0] >= 3 ? ints[3] : 5;
+    if (ints[0] >= 4) {
+      int atbt = -1;
+      switch (ints[4]) {
+       case 5:
+           atbt = 0x00;
+           break;
+       case 6:
+           atbt = 0x04;
+           break;
+        case 7:
+           atbt = 0x01;
+           break;
+       case 8:
+           atbt = 0x02;
+           break;
+       case 10:
+           atbt = 0x03;
+           break;
+       default:
+           printk("aha1542: %s\n", str );
+           printk(ahausage);
+           printk("aha1542: Valid values for DMASPEED are 5-8, 10 MB/s.  Using jumper defaults.\n");
+           break;
+      }
+      setup_dmaspeed[setup_idx]  = atbt;
+    }
+
+    if (setup_portbase != 0)
+      bases[setup_idx] = setup_portbase;
+
+    ++setup_idx;
+}
 
 /* return non-zero on detection */
 int aha1542_detect(Scsi_Host_Template * tpnt)
@@ -826,12 +910,19 @@ int aha1542_detect(Scsi_Host_Template * tpnt)
     int indx;
 
     DEB(printk("aha1542_detect: \n"));
-    
+
     for(indx = 0; indx < sizeof(bases)/sizeof(bases[0]); indx++)
-           if(!check_region(bases[indx], 4)) { 
+           if(bases[indx] != 0 && !check_region(bases[indx], 4)) { 
                    shpnt = scsi_register(tpnt,
                                          sizeof(struct aha1542_hostdata));
 
+                   /* For now we do this - until kmalloc is more intelligent
+                      we are resigned to stupid hacks like this */
+                   if ((unsigned int) shpnt > 0xffffff) {
+                     printk("Invalid address for shpnt with 1542.\n");
+                     goto unregister;
+                   }
+
                    if(!aha1542_test_port(bases[indx], shpnt)) goto unregister;
 
 
@@ -841,6 +932,12 @@ int aha1542_detect(Scsi_Host_Template * tpnt)
            {
                    unchar oncmd[] = {CMD_BUSON_TIME, 7};
                    unchar offcmd[] = {CMD_BUSOFF_TIME, 5};
+
+                   if(setup_called[indx])
+                     {
+                       oncmd[1]  = setup_buson[indx];
+                       offcmd[1] = setup_busoff[indx];
+                     }
                    
                    aha1542_intr_reset(base_io);
                    aha1542_out(base_io, oncmd, 2);
@@ -848,6 +945,14 @@ int aha1542_detect(Scsi_Host_Template * tpnt)
                    aha1542_intr_reset(base_io);
                    aha1542_out(base_io, offcmd, 2);
                    WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
+                   if (setup_dmaspeed[indx] >= 0)
+                     {
+                       unchar dmacmd[] = {CMD_DMASPEED, 0};
+                       dmacmd[1] = setup_dmaspeed[indx];
+                       aha1542_intr_reset(base_io);
+                       aha1542_out(base_io, dmacmd, 2);
+                       WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
+                     }
                    while (0) {
                    fail:
                            printk("aha1542_detect: setting bus on/off-time failed\n");
@@ -889,6 +994,7 @@ int aha1542_detect(Scsi_Host_Template * tpnt)
                    }
                    aha_host[irq_level - 9] = shpnt;
                    shpnt->io_port = base_io;
+                   shpnt->n_io_port = 4;  /* Number of bytes of I/O space used */
                    shpnt->dma_channel = dma_chan;
                    shpnt->irq = irq_level;
                    HOSTDATA(shpnt)->bios_translation  = trans;
@@ -1120,3 +1226,12 @@ int aha1542_biosparam(Scsi_Disk * disk, int dev, int * ip)
 /*  if (ip[2] >= 1024) ip[2] = 1024; */
   return 0;
 }
+
+
+#ifdef MODULE
+/* Eventually this will go into an include file, but this will be later */
+Scsi_Host_Template driver_template = AHA1542;
+
+#include "scsi_module.c"
+#endif
+
index a41e755e57ff14b3bcfeb9a22900c28a2928c99f..005a1f1e8814e4cfe35a502079955cd3b623374f 100644 (file)
@@ -69,6 +69,7 @@
 #define CMD_EMBOI      0x05    /* Enable MailBox Out Interrupt */
 #define CMD_BUSON_TIME 0x07    /* Set Bus-On Time */
 #define CMD_BUSOFF_TIME        0x08    /* Set Bus-Off Time */
+#define CMD_DMASPEED   0x09    /* Set AT Bus Transfer Speed */
 #define CMD_RETDEVS    0x0a    /* Return Installed Devices */
 #define CMD_RETCONF    0x0b    /* Return Configuration Data */
 #define CMD_RETSETUP   0x0d    /* Return Setup Data */
@@ -132,7 +133,6 @@ int aha1542_detect(Scsi_Host_Template *);
 int aha1542_command(Scsi_Cmnd *);
 int aha1542_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int aha1542_abort(Scsi_Cmnd *);
-const char *aha1542_info(void);
 int aha1542_reset(Scsi_Cmnd *);
 int aha1542_biosparam(Disk *, int, int*);
 
@@ -144,11 +144,11 @@ int aha1542_biosparam(Disk *, int, int*);
        #define NULL 0
 #endif
 
-#define AHA1542 {  NULL,                               \
+#define AHA1542 {  NULL, NULL,                         \
                     "Adaptec 1542",                    \
                     aha1542_detect,                    \
                     NULL,                              \
-                    aha1542_info,                      \
+                    NULL,                              \
                     aha1542_command,                   \
                     aha1542_queuecommand,              \
                     aha1542_abort,                     \
index 8db54c9be99c760e025d81fcf76d991d4cb84c70..baf310de486066693af9d105c74a33f32cfd23b7 100644 (file)
@@ -163,12 +163,6 @@ int aha1740_test_port(void)
     return 0;
 }
 
-const char *aha1740_info(void)
-{
-    static char buffer[] = "Adaptec 174x (EISA)";
-    return buffer;
-}
-
 /* A "high" level interrupt handler */
 void aha1740_intr_handle(int foo)
 {
@@ -273,7 +267,7 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
         i = -1;
     printk("aha1740_queuecommand: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
     printk("scsi cmd:");
-    for (i = 0; i < (COMMAND_SIZE(*cmd)); i++) printk("%02x ", cmd[i]);
+    for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
     printk("\n");
 #endif
 
@@ -302,7 +296,7 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
     printk("Sending command (%d %x)...",ecbno, done);
 #endif
 
-    ecb[ecbno].cdblen = COMMAND_SIZE(*cmd);    /* SCSI Command Descriptor Block Length */
+    ecb[ecbno].cdblen = SCpnt->cmd_len;        /* SCSI Command Descriptor Block Length */
 
     direction = 0;
     if (*cmd == READ_10 || *cmd == READ_6)
index cb96ee4c18aa36e9031e8fa0d6b96ffcc62173b1..dae31cc1f081ca66fa7dccf913525385366ce3de 100644 (file)
@@ -156,7 +156,6 @@ int aha1740_detect(Scsi_Host_Template *);
 int aha1740_command(Scsi_Cmnd *);
 int aha1740_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int aha1740_abort(Scsi_Cmnd *);
-const char *aha1740_info(void);
 int aha1740_reset(Scsi_Cmnd *);
 int aha1740_biosparam(Disk *, int, int*);
 
@@ -167,11 +166,11 @@ int aha1740_biosparam(Disk *, int, int*);
 #define NULL 0
 #endif
 
-#define AHA1740 {NULL,                                 \
-                  "Adaptec 1740",                      \
+#define AHA1740 {NULL, NULL,                           \
+                  "Adaptec 174x (EISA)",               \
                   aha1740_detect,                      \
                   NULL,                                \
-                  aha1740_info,                        \
+                  NULL,                                \
                   aha1740_command,                     \
                   aha1740_queuecommand,                \
                   aha1740_abort,                       \
index 109c4e715534d520ad12de279e49fe8a0df161c0..abadeab39b8504719f355528cbf4446032547806 100644 (file)
@@ -1033,11 +1033,11 @@ int aha274x_detect(Scsi_Host_Template *template)
                        found += aha274x_register(template, type, base);
                }
        }
-       template->name = (char *)aha274x_info();
+       template->name = (char *)aha274x_info(NULL);
        return(found);
 }
 
-const char *aha274x_info(void)
+const char *aha274x_info(struct Scsi_Host * shost)
 {
        return("Adaptec AHA274x/284x (EISA/VL-bus -> Fast SCSI) "
               AHA274X_SEQ_VERSION "/"
@@ -1100,7 +1100,7 @@ void aha274x_buildscb(struct aha274x_host *p,
         *        little-endian format.
         */
        addr = cmd->cmnd;
-       scb->SCSI_cmd_length = COMMAND_SIZE(cmd->cmnd[0]);
+       scb->SCSI_cmd_length = cmd->cmd_len;
        memcpy(scb->SCSI_cmd_pointer, &addr, sizeof(scb->SCSI_cmd_pointer));
 
        if (cmd->use_sg) {
@@ -1155,7 +1155,7 @@ int aha274x_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
 #if 0
        debug("aha274x_queue: cmd 0x%x (size %u), target %d, lun %d\n",
              cmd->cmnd[0],
-             COMMAND_SIZE(cmd->cmnd[0]),
+             cmd->cmd_len,
              cmd->target,
              cmd->lun);
 #endif
index afb9c65783793c5a8c566450cb622a092b92a690..b2a1c9e1b2bc63bc379abfbf37d7a64232350eb1 100644 (file)
@@ -32,7 +32,8 @@
  */
 #define AHA274X        {                                               \
        NULL,                                                   \
-       "",                                                     \
+       NULL,                                                   \
+       NULL,                                                   \
        aha274x_detect,                                         \
        NULL,                                                   \
        aha274x_info,                                           \
@@ -57,6 +58,6 @@ extern int aha274x_detect(Scsi_Host_Template *);
 extern int aha274x_command(Scsi_Cmnd *);
 extern int aha274x_abort(Scsi_Cmnd *);
 extern int aha274x_reset(Scsi_Cmnd *);
-extern const char *aha274x_info(void);
+extern const char *aha274x_info(struct Scsi_Host *);
 
 #endif
index 068cbde813e6d72734f8bca553c1ff38dfe82d87..f3e49c8b9e7aeb9726dfea9047be5cffaec6a8a5 100644 (file)
@@ -8,17 +8,23 @@
  *     The original version of this driver was derived from aha1542.[ch] which
  *     is Copyright (C) 1992 Tommy Thorn.  Much has been reworked, but most of
  *     basic structure and substantial chunks of code still remain.
+ *
+ *     Thanks to the following individuals who have made contributions (of
+ *     (code, information, support, or testing) to this driver:
+ *             Eric Youngdale          Leonard Zubkoff
+ *             Tomas Hurka             Andrew Walker
  */
 
 /*
  * TODO:
- *     1. Cleanup error handling & reporting.
+ *     1. Clean up error handling & reporting.
  *     2. Find out why scatter/gather is limited to 16 requests per command.
- *     3. Add multiple outstanding requests.
- *     4. See if we can make good use of having more than one command per lun.
- *     5. Test/improve/fix abort & reset functions.
- *     6. Look at command linking.
- *     7. Allow multiple boards to share an IRQ if the bus allows (e.g. EISA).
+ *     3. Test/improve/fix abort & reset functions.
+ *     4. Look at command linking.
+ *     5. Allow multiple boards to share an IRQ if the bus allows (EISA, MCA,
+ *        and PCI).
+ *     6. Avoid using the 445S workaround for board revs >= D.
+ *     7. Get cmd_per_lun put in the Scsi_Host structure.
  */
 
 /*
@@ -39,8 +45,6 @@
  *     BT-542B - ISA first-party DMA with floppy support.
  *     BT-545S - 542B + FAST SCSI and active termination.
  *     BT-545D - 545S + differential termination.
- *     BT-445S - VESA bus-master FAST SCSI with active termination and floppy
- *               support.
  *     BT-640A - MCA bus-master with floppy support.
  *     BT-646S - 640A + FAST SCSI and active termination.
  *     BT-646D - 646S + differential termination.
  *     BT-747D - 747S + differential termination.
  *     BT-757S - 747S + WIDE SCSI.
  *     BT-757D - 747D + WIDE SCSI.
+ *     BT-445S - VESA bus-master FAST SCSI with active termination and floppy
+ *               support.
+ *     BT-445C - 445S + enhanced BIOS & firmware options.
  *     BT-946C - PCI bus-master FAST SCSI. (??? Nothing else known.)
  *
- *    Should you require further information on any of these boards, BusLogic
- *    can be reached at (408)492-9090.
+ *    ??? I believe other boards besides the 445 now have a "C" model, but I
+ *    have no facts on them.
  *
  *    This driver SHOULD support all of these boards.  It has only been tested
  *    with a 747S and 445S.
  *
+ *    Should you require further information on any of these boards, BusLogic
+ *    can be reached at (408)492-9090.  Their BBS # is (408)492-1984 (maybe BBS
+ *    stands for "Big Brother System"?).
+ *
  *    Places flagged with a triple question-mark are things which are either
  *    unfinished, questionable, or wrong.
  */
 #include "buslogic.h"
 
 #ifndef BUSLOGIC_DEBUG
-# define BUSLOGIC_DEBUG UD_ABORT
+# define BUSLOGIC_DEBUG 0
 #endif
 
-#define BUSLOGIC_VERSION "1.00"
+/* If different port addresses are needed (e.g. to install more than two
+   cards), you must define BUSLOGIC_PORT_OVERRIDE to be a comma-separated list
+   of the addresses which will be checked.  This can also be used to resolve a
+   conflict if the port-probing at a standard port causes problems with
+   another board. */
+/* #define BUSLOGIC_PORT_OVERRIDE 0x330, 0x334, 0x130, 0x134, 0x230, 0x234 */
+
+/* Define this to be either BIOS_TRANSLATION_DEFAULT or BIOS_TRANSLATION_BIG
+   if you wish to bypass the test for this, which uses an undocumented port.
+   The test is believed to fail on at least some AMI BusLogic clones. */
+/* #define BIOS_TRANSLATION_OVERRIDE BIOS_TRANSLATION_BIG */
+
+#define BUSLOGIC_VERSION "1.13"
 
 /* Not a random value - if this is too large, the system hangs for a long time
    waiting for something to happen if a board is not installed. */
+/* ??? I don't really like this as it will wait longer on slow machines.
+   Perhaps we should base this on the loops_per_second "Bogomips" value? */
 #define WAITNEXTTIMEOUT 3000000
 
 /* This is for the scsi_malloc call in buslogic_queuecommand. */
 /* Since the SG list is malloced, we have to limit the length. */
 #define BUSLOGIC_MAX_SG (BUSLOGIC_SG_MALLOC / sizeof (struct chain))
 
-/* The DMA-Controller.  We need to fool with this because we want to be able to
-   use an ISA BusLogic without having to have the BIOS enabled. */
-#define DMA_MODE_REG 0xD6
-#define DMA_MASK_REG 0xD4
-#define        CASCADE 0xC0
+/* ??? Arbitrary.  If we can dynamically allocate the mailbox arrays, I may
+   bump up this number. */
+#define BUSLOGIC_MAILBOXES 16
 
-#define BUSLOGIC_MAILBOXES 16  /* ??? Arbitrary? */
+#define BUSLOGIC_NONISA_CMDLUN 4       /* ??? Arbitrary (> 1) */
 
 /* BusLogic boards can be configured for quite a number of port addresses (six
    to be exact), but I generally do not want the driver poking around at
    random.  We allow two port addresses - this allows people to use a BusLogic
-   with a MIDI card, which frequently also uses 0x330.  If different port
-   addresses are needed (e.g. to install more than two cards), you must define
-   BUSLOGIC_PORT_OVERRIDE to be a list of the addresses which will be checked.
-   This can also be used to resolve a conflict if the port-probing at a
-   standard port causes problems with another board. */
+   with a MIDI card, which frequently also uses 0x330. */
 static const unsigned int bases[] = {
 #ifdef BUSLOGIC_PORT_OVERRIDE
     BUSLOGIC_PORT_OVERRIDE
@@ -129,10 +148,12 @@ static const unsigned int bases[] = {
 #define BIOS_TRANSLATION_BIG 1         /* Big disk (> 1G) case */
 
 struct hostdata {
-    unsigned char bus_type;
-    int bios_translation;      /* Mapping bios uses - for compatibility */
+    unsigned int bus_type;
+    unsigned int bios_translation: 1;  /* BIOS mapping (for compatibility) */
     size_t last_mbi_used;
     size_t last_mbo_used;
+    char model[7];
+    char firmware_rev[6];
     Scsi_Cmnd *sc[BUSLOGIC_MAILBOXES];
     struct mailbox mb[2 * BUSLOGIC_MAILBOXES];
     struct ccb ccbs[BUSLOGIC_MAILBOXES];
@@ -152,25 +173,28 @@ static int restart(struct Scsi_Host *shpnt);
 
 #define CHECK(cond) if (cond) ; else goto fail
 
-#define WAIT(port, mask, allof, noneof) \
-    CHECK(wait(port, mask, allof, noneof, WAITNEXTTIMEOUT, FALSE))
-#define WAIT_WHILE(port, mask) WAIT(port, mask, 0, mask)
-#define WAIT_UNTIL(port, mask) WAIT(port, mask, mask, 0)
-#define WAIT_FAST(port, mask, allof, noneof) \
-    CHECK(wait(port, mask, allof, noneof, 100, TRUE))
-#define WAIT_WHILE_FAST(port, mask) WAIT_FAST(port, mask, 0, mask)
-#define WAIT_UNTIL_FAST(port, mask) WAIT_FAST(port, mask, mask, 0)
+#define WAIT(port, allof, noneof) \
+    CHECK(wait(port, allof, noneof, WAITNEXTTIMEOUT, FALSE))
+#define WAIT_WHILE(port, mask) WAIT(port, 0, mask)
+#define WAIT_UNTIL(port, mask) WAIT(port, mask, 0)
+#define WAIT_FAST(port, allof, noneof) \
+    CHECK(wait(port, allof, noneof, 100, TRUE))
+#define WAIT_WHILE_FAST(port, mask) WAIT_FAST(port, 0, mask)
+#define WAIT_UNTIL_FAST(port, mask) WAIT_FAST(port, mask, 0)
 
 /* If delay != 0, we use the udelay call to regulate the amount of time we
-   wait. */
-static __inline__ int wait(unsigned short port, unsigned char mask,
+   wait.
+
+   This is inline as it is always called with constant arguments and hence
+   will be very well optimized. */
+static __inline__ int wait(unsigned short port,
                           unsigned char allof, unsigned char noneof,
                           unsigned int timeout, int delay)
 {
     int bits;
 
     for (;;) {
-       bits = inb(port) & mask;
+       bits = inb(port);
        if ((bits & allof) == allof && (bits & noneof) == 0)
            return TRUE;
        if (delay)
@@ -185,16 +209,12 @@ static void buslogic_prefix(void)
     printk("BusLogic SCSI: ");
 }
 
-#if BUSLOGIC_DEBUG
 static void buslogic_stat(unsigned int base)
 {
     int s = inb(STATUS(base)), i = inb(INTERRUPT(base));
 
-    printk("status=%02X intrflags=%02X\n", s, i);
+    buslogic_printk("status=%02X intrflags=%02X\n", s, i);
 }
-#else
-# define buslogic_stat(base)
-#endif
 
 /* This is a bit complicated, but we need to make sure that an interrupt
    routine does not send something out while we are in the middle of this.
@@ -231,45 +251,60 @@ static int buslogic_out(unsigned int base, const unsigned char *cmdp,
 }
 
 /* Only used at boot time, so we do not need to worry about latency as much
-   here. */
+   here.  This waits a very short period of time.  We use this if we are not
+   sure whether the board will respond to the command we just sent. */
 static int buslogic_in(unsigned int base, unsigned char *cmdp, size_t len)
 {
     cli();
     while (len--) {
-       WAIT_UNTIL(STATUS(base), DIRRDY);
+       WAIT_UNTIL_FAST(STATUS(base), DIRRDY);
        *cmdp++ = inb(DATA_IN(base));
     }
     sti();
     return FALSE;
   fail:
     sti();
+#if (BUSLOGIC_DEBUG & BD_IO)
     buslogic_printk("buslogic_in failed(%u): ", len + 1);
     buslogic_stat(base);
+#endif
     return TRUE;
 }
 
-#if 0
-/* Similar to buslogic_in, except that we wait a very short period of time.
-   We use this if we know the board is alive and awake, but we are not sure
-   whether the board will respond the the command we are about to send. */
-static int buslogic_in_fast(unsigned int base, unsigned char *cmdp, size_t len)
+static unsigned int makecode(unsigned int haerr, unsigned int scsierr)
 {
-    cli();
-    while (len--) {
-       WAIT_UNTIL_FAST(STATUS(base), DIRRDY);
-       *cmdp++ = inb(DATA_IN(base));
-    }
-    sti();
-    return FALSE;
-  fail:
-    sti();
-    return TRUE;
-}
+    unsigned int hosterr;
+    const char *errstr = NULL;
+#if (BUSLOGIC_DEBUG & BD_ERRORS) && defined(CONFIG_SCSI_CONSTANTS)
+    static const char *const buslogic_status[] = {
+    /* 00 */   "Command completed normally",
+    /* 01-07 */        NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    /* 08-09 */        NULL, NULL,
+    /* 0A */   "Linked command completed normally",
+    /* 0B */   "Linked command completed normally, interrupt generated",
+    /* 0C-0F */        NULL, NULL, NULL, NULL,
+    /* 10 */   NULL,
+    /* 11 */   "Selection timed out",
+    /* 12 */   "Data overrun/underrun",
+    /* 13 */   "Unexpected bus free",
+    /* 14 */   "Target bus phase sequence failure",
+    /* 15 */   "First byte of outgoing MB was invalid",
+    /* 16 */   "Invalid CCB Operation Code",
+    /* 17 */   "Linked CCB does not have the same LUN",
+    /* 18 */   "Invalid Target Direction received from Host",
+    /* 19 */   "Duplicate CCB Received in Target Mode",
+    /* 1A */   "Invalid CCB or Segment List Parameter",
+    /* 1B */   "Auto request sense failed",
+    /* 1C */   "SCSI-2 tagged queueing message was rejected by the target",
+    /* 1D-1F */        NULL, NULL, NULL,
+    /* 20 */   "Host adapter hardware failure",
+    /* 21 */   "Target did not respond to SCSI ATN and the HA SCSI bus reset",
+    /* 22 */   "Host adapter asserted a SCSI bus reset",
+    /* 23 */   "Other SCSI devices asserted a SCSI bus reset",
+    };
 #endif
 
-static unsigned int makecode(unsigned int hosterr, unsigned int scsierr)
-{
-    switch (hosterr) {
+    switch (haerr) {
       case 0x00:       /* Normal completion. */
       case 0x0A:       /* Linked command complete without error and linked
                           normally. */
@@ -280,7 +315,7 @@ static unsigned int makecode(unsigned int hosterr, unsigned int scsierr)
 
       case 0x11:       /* Selection time out: the initiator selection or
                           target reselection was not complete within the SCSI
-                          Time out period. */
+                          time out period. */
        hosterr = DID_TIME_OUT;
        break;
 
@@ -289,6 +324,10 @@ static unsigned int makecode(unsigned int hosterr, unsigned int scsierr)
                           target.  The host adapter will generate a SCSI
                           Reset Condition, notifying the host with a RSTS
                           interrupt. */
+      case 0x21:       /* The target did not respond to SCSI ATN and the host
+                          adapter consequently issued a SCSI bus reset to
+                          clear up the failure. */
+      case 0x22:       /* The host adapter asserted a SCSI bus reset. */
        hosterr = DID_RESET;
        break;
 
@@ -322,100 +361,38 @@ static unsigned int makecode(unsigned int hosterr, unsigned int scsierr)
       case 0x1C:       /* SCSI-2 tagged queueing message was rejected by the
                           target. */
       case 0x20:       /* The host adapter hardware failed. */
-      case 0x21:       /* The target did not respond to SCSI ATN and the host
-                          adapter consequently issued a SCSI bus reset to
-                          clear up the failure. */
-      case 0x22:       /* The host adapter asserted a SCSI bus reset. */
       case 0x23:       /* Other SCSI devices asserted a SCSI bus reset. */
-#if BUSLOGIC_DEBUG
-       buslogic_printk("%X %X\n", hosterr, scsierr);
-#endif
        hosterr = DID_ERROR;    /* ??? Couldn't find any better. */
        break;
 
       default:
-       buslogic_printk("makecode: unknown hoststatus %X\n", hosterr);
+#ifndef CONFIG_SCSI_CONSTANTS
+       errstr = "unknown hoststatus";
+#endif
+       hosterr = DID_ERROR;
        break;
     }
-    return (hosterr << 16) | scsierr;
-}
-
-static int test_port(unsigned int base, struct Scsi_Host *shpnt)
-{
-    unsigned int i;
-    unsigned char inquiry_cmd[] = { CMD_INQUIRY };
-    unsigned char inquiry_result[4];
-    unsigned char *cmdp;
-    int len;
-    volatile int debug = 0;
-
-    /* Quick and dirty test for presence of the card. */
-    if (inb(STATUS(base)) == 0xFF)
-       return TRUE;
-
-    /* Reset the adapter.  I ought to make a hard reset, but it's not really
-       necessary. */
-
-#if BUSLOGIC_DEBUG
-    buslogic_printk("test_port called\n");
-#endif
-
-    /* In case some other card was probing here, reset interrupts. */
-    INTR_RESET(base);  /* reset interrupts, so they don't block */
-
-    outb(RSOFT | RINT/* | RSBUS*/, CONTROL(base));
-
-    /* Wait a little bit for things to settle down. */
-    i = jiffies + 2;
-    while (i > jiffies);
-
-    debug = 1;
-    /* Expect INREQ and HARDY, any of the others are bad. */
-    WAIT(STATUS(base), STATMASK, INREQ | HARDY,
-        DACT | DFAIL | CMDINV | DIRRDY | CPRBSY);
-
-    debug = 2;
-    /* Shouldn't have generated any interrupts during reset. */
-    if (inb(INTERRUPT(base)) & INTRMASK)
-       goto fail;
-
-    /* Perform a host adapter inquiry instead so we do not need to set up the
-       mailboxes ahead of time. */
-    buslogic_out(base, inquiry_cmd, 1);
-
-    debug = 3;
-    len = 4;
-    cmdp = &inquiry_result[0];
-    while (len--) {
-       WAIT(STATUS(base), DIRRDY, DIRRDY, 0);
-       *cmdp++ = inb(DATA_IN(base));
+#if (BUSLOGIC_DEBUG & BD_ERRORS)
+# ifdef CONFIG_SCSI_CONSTANTS
+    if (hosterr != DID_OK) {
+       if (haerr < ARRAY_SIZE(buslogic_status))
+           errstr = buslogic_status[haerr];
+       if (errstr == NULL)
+           errstr = "unknown hoststatus";
     }
-
-    debug = 4;
-    /* Reading port should reset DIRRDY. */
-    if (inb(STATUS(base)) & DIRRDY)
-       goto fail;
-
-    debug = 5;
-    /* When CMDC, command is completed, and we're though testing. */
-    WAIT_UNTIL(INTERRUPT(base), CMDC);
-
-    /* now initialize adapter. */
-
-    debug = 6;
-    /* Clear interrupts. */
-    outb(RINT, CONTROL(base));
-
-    debug = 7;
-
-    return FALSE;                              /* 0 = ok */
-  fail:
-    return TRUE;                               /* 1 = not ok */
+# else
+    if (hosterr == DID_ERROR)
+       errstr = "";
+# endif
+#endif
+    if (errstr != NULL)
+       buslogic_printk("makecode: %s (%02X)\n", errstr, haerr);
+    return (hosterr << 16) | scsierr;
 }
 
 const char *buslogic_info(void)
 {
-    return "BusLogic SCSI Driver version " BUSLOGIC_VERSION;
+    return "BusLogic SCSI driver version " BUSLOGIC_VERSION;
 }
 
 /* A "high" level interrupt handler. */
@@ -442,7 +419,7 @@ static void buslogic_interrupt(int junk)
     ccb = HOSTDATA(shpnt)->ccbs;
     base = shpnt->io_port;
 
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_INTERRUPT)
     flag = inb(INTERRUPT(base));
 
     buslogic_printk("buslogic_interrupt: ");
@@ -469,15 +446,17 @@ static void buslogic_interrupt(int junk)
           probably do something special, but for now just printing a message
           is sufficient.  A SCSI reset detected is something that we really
           need to deal with in some way. */
-       if (flag & ~IMBL) {
+       if (flag & (MBOR | CMDC | RSTS)) {
+           buslogic_printk("Unusual flag:");
            if (flag & MBOR)
-               printk("MBOR ");
+               printk(" MBOR");
            if (flag & CMDC)
-               printk("CMDC ");
+               printk(" CMDC");
            if (flag & RSTS) {
                needs_restart = 1;
-               printk("RSTS ");
+               printk(" RSTS");
            }
+           printk("\n");
        }
 
        INTR_RESET(base);
@@ -522,7 +501,7 @@ static void buslogic_interrupt(int junk)
            return;
        }
 
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_INTERRUPT)
        if (ccb[mbo].tarstat || ccb[mbo].hastat)
            buslogic_printk("buslogic_interrupt: returning %08X (status %d)\n",
                            ((int)ccb[mbo].hastat << 16) | ccb[mbo].tarstat,
@@ -532,7 +511,7 @@ static void buslogic_interrupt(int junk)
        if (mbistatus == MBX_COMPLETION_NOT_FOUND)
            continue;
 
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_INTERRUPT)
        buslogic_printk("...done %u %u\n", mbo, mbi);
 #endif
 
@@ -540,7 +519,7 @@ static void buslogic_interrupt(int junk)
 
        if (!sctmp || !sctmp->scsi_done) {
            buslogic_printk("buslogic_interrupt: Unexpected interrupt\n");
-           buslogic_printk("tarstat=%02X, hastat=%02X id=%d lun=%d ccb#=%d\n",
+           buslogic_printk("tarstat=%02X, hastat=%02X id=%d lun=%d ccb#=%u\n",
                            ccb[mbo].tarstat, ccb[mbo].hastat,
                            ccb[mbo].id, ccb[mbo].lun, mbo);
            return;
@@ -550,26 +529,17 @@ static void buslogic_interrupt(int junk)
        if (sctmp->host_scribble)
            scsi_free(sctmp->host_scribble, BUSLOGIC_SG_MALLOC);
 
-#if 0  /* ??? */
-       /* Fetch the sense data, and tuck it away, in the required slot.  The
-          BusLogic automatically fetches it, and there is no guarantee that we
-          will still have it in the cdb when we come back. */
-       if (ccb[mbo].tarstat == 2)      /* ??? */
-           memcpy(sctmp->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen],
-                  sizeof sctmp->sense_buffer);
-#endif
-
        /* ??? more error checking left out here */
-       if (mbistatus != MBX_COMPLETION_OK)
+       if (mbistatus != MBX_COMPLETION_OK) {
            /* ??? This is surely wrong, but I don't know what's right. */
            errstatus = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
-       else
+       else
            errstatus = 0;
 
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_INTERRUPT)
        if (errstatus)
-           buslogic_printk("error: %08X %04X %04X\n",
-                           errstatus, ccb[mbo].hastat, ccb[mbo].tarstat);
+           buslogic_printk("error: %04X %04X\n",
+                           ccb[mbo].hastat, ccb[mbo].tarstat);
 
        if (status_byte(ccb[mbo].tarstat) == CHECK_CONDITION) {
            size_t i;
@@ -594,6 +564,7 @@ static void buslogic_interrupt(int junk)
     }
 }
 
+/* ??? Why does queuecommand return a value?  scsi.c never looks at it... */
 int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
 {
     static const unsigned char buscmd[] = { CMD_START_SCSI };
@@ -607,7 +578,7 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
     struct mailbox *mb;
     struct ccb *ccb;
 
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_COMMAND)
     if (target > 1) {
        scpnt->result = DID_TIME_OUT << 16;
        done(scpnt);
@@ -616,7 +587,7 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
 #endif
 
     if (*cmd == REQUEST_SENSE) {
-#ifndef DEBUG
+#if (BUSLOGIC_DEBUG & (BD_COMMAND | BD_ERRORS))
        if (bufflen != sizeof scpnt->sense_buffer) {
            buslogic_printk("Wrong buffer length supplied for request sense"
                            " (%d)\n",
@@ -628,7 +599,7 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
        return 0;
     }
 
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_COMMAND)
     {
        int i;
 
@@ -671,8 +642,7 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
            mbo = 0;
     } while (mbo != HOSTDATA(scpnt->host)->last_mbo_used);
 
-    if (mb[mbo].status != MBX_NOT_IN_USE
-       || HOSTDATA(scpnt->host)->sc[mbo]) {
+    if (mb[mbo].status != MBX_NOT_IN_USE || HOSTDATA(scpnt->host)->sc[mbo]) {
        /* ??? Instead of panicing, should we enable OMBR interrupts and
           sleep until we get one? */
        panic("buslogic.c: unable to find empty mailbox");
@@ -686,7 +656,7 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
 
     sti();
 
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_COMMAND)
     buslogic_printk("sending command (%d %08X)...", mbo, done);
 #endif
 
@@ -731,7 +701,7 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
        }
        ccb[mbo].datalen = scpnt->use_sg * sizeof (struct chain);
        ccb[mbo].dataptr = cptr;
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_COMMAND)
        {
            unsigned char *ptr;
 
@@ -756,7 +726,7 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
     ccb[mbo].linkptr = NULL;
     ccb[mbo].commlinkid = 0;
 
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_COMMAND)
     {
        size_t i;
 
@@ -768,7 +738,7 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
 #endif
 
     if (done) {
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_COMMAND)
        buslogic_printk("buslogic_queuecommand: now waiting for interrupt: ");
        buslogic_stat(scpnt->host->io_port);
 #endif
@@ -776,7 +746,7 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
        mb[mbo].status = MBX_ACTION_START;
        /* start scsi command */
        buslogic_out(scpnt->host->io_port, buscmd, sizeof buscmd);
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_COMMAND)
        buslogic_stat(scpnt->host->io_port);
 #endif
     } else
@@ -793,8 +763,8 @@ static void internal_done(Scsi_Cmnd *scpnt)
 
 int buslogic_command(Scsi_Cmnd *scpnt)
 {
-#if BUSLOGIC_DEBUG
-    buslogic_printk("buslogic_command: ..calling buslogic_queuecommand\n");
+#if (BUSLOGIC_DEBUG & BD_COMMAND)
+    buslogic_printk("buslogic_command: calling buslogic_queuecommand\n");
 #endif
 
     buslogic_queuecommand(scpnt, internal_done);
@@ -824,46 +794,43 @@ static int setup_mailboxes(unsigned int base, struct Scsi_Host *shpnt)
     }
     INTR_RESET(base);  /* reset interrupts, so they don't block */
 
-    /* If this fails, this must be an Adaptec board */
     if (buslogic_out(base, (unsigned char *)&cmd, sizeof cmd))
-       goto must_be_adaptec;
+       goto fail;
+    WAIT_UNTIL(INTERRUPT(base), CMDC);
 
-    /* Wait until host adapter is done messing around, and then check to see
-       if the command was accepted.  If it failed, this must be an Adaptec
-       board. */
-    WAIT_UNTIL(STATUS(base), HARDY);
-    if (inb(STATUS(base)) & CMDINV)
-       goto must_be_adaptec;
+    ok = TRUE;
 
-    WAIT_UNTIL(INTERRUPT(base), CMDC);
     while (0) {
       fail:
        buslogic_printk("buslogic_detect: failed setting up mailboxes\n");
     }
-    ok = TRUE;
-  must_be_adaptec:
+
     INTR_RESET(base);
-    if (!ok)
-       printk("- must be Adaptec\n");  /* So that the adaptec detect looks
-                                          clean */
-    return ok;
+
+    return !ok;
 }
 
 static int getconfig(unsigned int base, unsigned char *irq,
                     unsigned char *dma, unsigned char *id,
-                    unsigned char *bus_type, unsigned short *max_sg)
+                    char *bus_type, unsigned short *max_sg,
+                    const unsigned char **bios)
 {
     unsigned char inquiry_cmd[2];
     unsigned char inquiry_result[4];
     int i;
 
+#if (BUSLOGIC_DEBUG & BD_DETECT)
+    buslogic_printk("getconfig: called\n");
+#endif
+
     i = inb(STATUS(base));
     if (i & DIRRDY)
        i = inb(DATA_IN(base));
     inquiry_cmd[0] = CMD_RETCONF;
     buslogic_out(base, inquiry_cmd, 1);
-    buslogic_in(base, inquiry_result, 3);
-    WAIT_UNTIL(INTERRUPT(base), CMDC);
+    if (buslogic_in(base, inquiry_result, 3))
+       goto fail;
+    WAIT_UNTIL_FAST(INTERRUPT(base), CMDC);
     INTR_RESET(base);
     /* Defer using the DMA value until we know the bus type. */
     *dma = inquiry_result[0];
@@ -889,29 +856,27 @@ static int getconfig(unsigned int base, unsigned char *irq,
       default:
        buslogic_printk("Unable to determine BusLogic IRQ level."
                        "  Disabling board.\n");
-       return TRUE;
+       goto fail;
     }
     *id = inquiry_result[2] & 0x7;
 
+    /* I expected Adaptec boards to fail on this, but it doesn't happen... */
     inquiry_cmd[0] = CMD_INQEXTSETUP;
     inquiry_cmd[1] = 4;
-    if (buslogic_out(base, inquiry_cmd, 2)
-       || buslogic_in(base, inquiry_result, 4))
-       return TRUE;
-    WAIT_UNTIL(INTERRUPT(base), CMDC);
+    if (buslogic_out(base, inquiry_cmd, 2))
+       goto fail;
+    if (buslogic_in(base, inquiry_result, inquiry_cmd[1]))
+       goto fail;
+    WAIT_UNTIL_FAST(INTERRUPT(base), CMDC);
+    if (inb(STATUS(base)) & CMDINV)
+       goto fail;
     INTR_RESET(base);
 
-#ifdef BUSLOGIC_BUS_TYPE_OVERRIDE
-    *bus_type = BUS_TYPE_OVERRIDE;
-#else
     *bus_type = inquiry_result[0];
-#endif
     CHECK(*bus_type == 'A' || *bus_type == 'E' || *bus_type == 'M');
-#ifdef BUSLOGIC_BUS_TYPE_OVERRIDE
-    if (inquiry_result[0] != BUS_TYPE_OVERRIDE)
-       buslogic_printk("Overriding bus type %c with %c\n",
-                       inquiry_result[0], BUS_TYPE_OVERRIDE);
-#endif
+
+    *bios = (const unsigned char *)((unsigned int)inquiry_result[1] << 12);
+
     *max_sg = (inquiry_result[3] << 8) | inquiry_result[2];
 
     /* We only need a DMA channel for ISA boards.  Some other types of boards
@@ -935,60 +900,182 @@ static int getconfig(unsigned int base, unsigned char *irq,
          default:
            buslogic_printk("Unable to determine BusLogic DMA channel."
                            "  Disabling board.\n");
-           return TRUE;
+           goto fail;
        }
     else
        *dma = 0;
 
     while (0) {
       fail:
+#if (BUSLOGIC_DEBUG & BD_DETECT)
        buslogic_printk("buslogic_detect: query board settings\n");
+#endif
        return TRUE;
     }
 
     return FALSE;
 }
 
-static int get_translation(unsigned int base)
+/* Query the board.  This acts both as part of the detection sequence and as a
+   means to get necessary configuration information. */
+static int buslogic_query(unsigned int base, unsigned char *trans,
+                         unsigned char *irq, unsigned char *dma,
+                         unsigned char *id, char *bus_type,
+                         unsigned short *max_sg, const unsigned char **bios,
+                         char *model, char *firmware_rev)
 {
-    /* ??? Unlike UltraStor, I see no way of determining whether > 1G mapping
-       has been enabled.  However, it appears that BusLogic uses a mapping
-       scheme which varies with the disk size when > 1G mapping is enabled.
-       For disks <= 1G, this mapping is the same regardless of the setting of
-       > 1G mapping.  Therefore, we should be safe in always assuming that > 1G
-       mapping has been enabled. */
-    return BIOS_TRANSLATION_BIG;
-}
+    unsigned char inquiry_cmd[2];
+    unsigned char inquiry_result[6];
+    unsigned char geo;
+    unsigned int i;
 
-/* Query the board to find out the model. */
-static int buslogic_query(unsigned int base, int *trans)
-{
-    static const unsigned char inquiry_cmd[] = { CMD_INQUIRY };
-    unsigned char inquiry_result[4];
-    int i;
+#if (BUSLOGIC_DEBUG & BD_DETECT)
+    buslogic_printk("buslogic_query: called\n");
+#endif
 
-    i = inb(STATUS(base));
-    if (i & DIRRDY)
-       i = inb(DATA_IN(base));
-    buslogic_out(base, inquiry_cmd, sizeof inquiry_cmd);
-    buslogic_in(base, inquiry_result, 4);
-    WAIT_UNTIL(INTERRUPT(base), CMDC);
+    /* Quick and dirty test for presence of the card. */
+    if (inb(STATUS(base)) == 0xFF)
+       goto fail;
+
+    /* Check the GEOMETRY port early for quick bailout on Adaptec boards. */
+    geo = inb(GEOMETRY(base));
+#if (BUSLOGIC_DEBUG & BD_DETECT)
+    buslogic_printk("geometry bits: %02X\n", geo);
+#endif
+    /* Here is where we tell the men from the boys (i.e. Adaptec's don't
+       support the GEOMETRY port, the men do :-) */
+    if (geo == 0xFF)
+       goto fail;
+
+    /* In case some other card was probing here, reset interrupts. */
     INTR_RESET(base);
 
-#if 1  /* ??? Temporary */
-    buslogic_printk("Inquiry Bytes: %02X %02X %02X %02X\n",
-                   inquiry_result[0], inquiry_result[1],
-                   inquiry_result[2], inquiry_result[3]);
+    /* Reset the adapter.  I ought to make a hard reset, but it's not really
+       necessary. */
+    outb(RSOFT | RINT/* | RSBUS*/, CONTROL(base));
+
+    /* Wait a little bit for things to settle down. */
+    i = jiffies + 2;
+    while (i > jiffies);
+
+    /* Expect INREQ and HARDY, any of the others are bad. */
+    WAIT(STATUS(base), INREQ | HARDY, DACT | DFAIL | CMDINV | DIRRDY | CPRBSY);
+
+    /* Shouldn't have generated any interrupts during reset. */
+    if (inb(INTERRUPT(base)) & INTRMASK)
+       goto fail;
+
+    /* Getting the BusLogic firmware revision level is a bit tricky.  We get
+       the first two digits (d.d) from CMD_INQUIRY and then use two undocumented
+       commands to get the remaining digit and letter (d.ddl as in 3.31C). */
+
+    inquiry_cmd[0] = CMD_INQUIRY;
+    buslogic_out(base, inquiry_cmd, 1);
+    if (buslogic_in(base, inquiry_result, 4))
+       goto fail;
+    /* Reading port should reset DIRRDY. */
+    if (inb(STATUS(base)) & DIRRDY)
+       goto fail;
+    WAIT_UNTIL_FAST(INTERRUPT(base), CMDC);
+    INTR_RESET(base);
+    firmware_rev[0] = inquiry_result[2];
+    firmware_rev[1] = '.';
+    firmware_rev[2] = inquiry_result[3];
+    firmware_rev[3] = '\0';
+#if 0
+    buslogic_printk("Inquiry Bytes: %02X(%c) %02X(%c)\n",
+                   inquiry_result[0], inquiry_result[0],
+                   inquiry_result[1], inquiry_result[1]);
 #endif
 
+    if (getconfig(base, irq, dma, id, bus_type, max_sg, bios))
+       goto fail;
+
+    /* Set up defaults */
+#ifdef BIOS_TRANSLATION_OVERRIDE
+    *trans = BIOS_TRANSLATION_OVERRIDE;
+#else
+    *trans = BIOS_TRANSLATION_DEFAULT;
+#endif
+    model[0] = '\0';
+    model[6] = 0;
+
+    /* ??? Begin undocumented command use.
+       These may not be supported by clones. */
+
+    do {
+       /* ??? It appears as though AMI BusLogic clones don't implement this
+          feature.  As an experiment, if we read a 00 we ignore the GEO_GT_1GB
+          bit and skip all further undocumented commands. */
+       if (geo == 0x00)
+           break;
+#ifndef BIOS_TRANSLATION_OVERRIDE
+       *trans = ((geo & GEO_GT_1GB)
+                 ? BIOS_TRANSLATION_BIG : BIOS_TRANSLATION_DEFAULT);
+#endif
+
+       inquiry_cmd[0] = CMD_VER_NO_LAST;
+       buslogic_out(base, inquiry_cmd, 1);
+       if (buslogic_in(base, inquiry_result, 1))
+           break;
+       WAIT_UNTIL_FAST(INTERRUPT(base), CMDC);
+       INTR_RESET(base);
+       firmware_rev[3] = inquiry_result[0];
+       firmware_rev[4] = '\0';
+
+       inquiry_cmd[0] = CMD_VER_NO_LETTER;
+       buslogic_out(base, inquiry_cmd, 1);
+       if (buslogic_in(base, inquiry_result, 1))
+           break;
+       WAIT_UNTIL_FAST(INTERRUPT(base), CMDC);
+       INTR_RESET(base);
+       firmware_rev[4] = inquiry_result[0];
+       firmware_rev[5] = '\0';
+
+       /* Use undocumented command to get model number and revision. */
+
+       inquiry_cmd[0] = CMD_RET_MODEL_NO;
+       inquiry_cmd[1] = 6;
+       buslogic_out(base, inquiry_cmd, 2);
+       if (buslogic_in(base, inquiry_result, inquiry_cmd[1]))
+           break;
+       WAIT_UNTIL_FAST(INTERRUPT(base), CMDC);
+       INTR_RESET(base);
+       memcpy(model, inquiry_result, 5);
+       model[5] = '\0';
+       model[6] = inquiry_result[5];
+    } while (0);
+
+    /* ??? End undocumented command use. */
+
+    /* bus_type from getconfig doesn't differentiate between EISA/VESA.  We
+       override using the model number here. */
+    /* ??? What bus_type gets returned for PCI? */
+    switch (*bus_type) {
+      case 'E':
+       switch (model[0]) {
+         case '4':
+           *bus_type = 'V';
+           break;
+         case '7':
+           break;
+         default:
+           *bus_type = 'X';
+           break;
+       }
+       break;
+      default:
+       break;
+    }
+
     while (0) {
       fail:
+#if (BUSLOGIC_DEBUG & BD_DETECT)
        buslogic_printk("buslogic_query: query board settings\n");
+#endif
        return TRUE;
     }
 
-    *trans = get_translation(base);
-
     return FALSE;
 }
 
@@ -997,31 +1084,46 @@ int buslogic_detect(Scsi_Host_Template *tpnt)
 {
     unsigned char dma;
     unsigned char irq;
-    unsigned int base = 0;
+    unsigned int base;
     unsigned char id;
-    unsigned char bus_type;
+    char bus_type;
     unsigned short max_sg;
-    int trans;
-    struct Scsi_Host *shpnt = NULL;
+    unsigned char bios_translation;
+    const unsigned char *bios;
+    char *model;
+    char *firmware_rev;
+    struct Scsi_Host *shpnt;
+    size_t indx;
     int count = 0;
-    int indx;
 
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_DETECT)
     buslogic_printk("buslogic_detect:\n");
 #endif
 
     tpnt->can_queue = BUSLOGIC_MAILBOXES;
     for (indx = 0; indx < ARRAY_SIZE(bases); indx++)
-       if (!check_region(bases[indx], 3)) {
+       if (!check_region(bases[indx], 4)) {
            shpnt = scsi_register(tpnt, sizeof (struct hostdata));
 
            base = bases[indx];
 
-           if (test_port(base, shpnt))
+           model = HOSTDATA(shpnt)->model;
+           firmware_rev = HOSTDATA(shpnt)->firmware_rev;
+           if (buslogic_query(base, &bios_translation, &irq, &dma, &id,
+                              &bus_type, &max_sg, &bios, model, firmware_rev))
                goto unregister;
 
-           /* Set the Bus on/off-times as not to ruin floppy performance. */
-           {
+#if (BUSLOGIC_DEBUG & BD_DETECT)
+           buslogic_stat(base);
+#endif
+
+           if (setup_mailboxes(base, shpnt))
+               goto unregister;
+
+           /* Set the Bus on/off-times as not to ruin floppy performance.
+              CMD_BUSOFF_TIME is a noop for EISA boards (and possibly
+              others???). */
+           if (bus_type != 'E') {
                /* The default ON/OFF times for BusLogic adapters is 7/4. */
                static const unsigned char oncmd[] = { CMD_BUSON_TIME, 7 };
                static const unsigned char offcmd[] = { CMD_BUSOFF_TIME, 5 };
@@ -1029,9 +1131,6 @@ int buslogic_detect(Scsi_Host_Template *tpnt)
                INTR_RESET(base);
                buslogic_out(base, oncmd, sizeof oncmd);
                WAIT_UNTIL(INTERRUPT(base), CMDC);
-               /* CMD_BUSOFF_TIME is a noop for EISA boards, but as there is
-                  no way to to differentiate EISA from VESA we send it
-                  unconditionally. */
                INTR_RESET(base);
                buslogic_out(base, offcmd, sizeof offcmd);
                WAIT_UNTIL(INTERRUPT(base), CMDC);
@@ -1043,33 +1142,32 @@ int buslogic_detect(Scsi_Host_Template *tpnt)
                INTR_RESET(base);
            }
 
-           if (buslogic_query(base, &trans))
-               goto unregister;
-
-           if (getconfig(base, &irq, &dma, &id, &bus_type, &max_sg))
-               goto unregister;
-
-#if BUSLOGIC_DEBUG
-           buslogic_stat(base);
-#endif
-           /* Here is where we tell the men from the boys (i.e. an Adaptec
-              will fail in setup_mailboxes, the men will not :-) */
-           if (!setup_mailboxes(base, shpnt))
-               goto unregister;
-
-           printk("Configuring BusLogic %s HA at port 0x%03X, IRQ %u",
-                  (bus_type == 'A' ? "ISA"
-                   : (bus_type == 'E' ? "EISA/VESA" : "MCA")),
-                  base, irq);
+           buslogic_printk("Configuring %s HA at port 0x%03X, IRQ %u",
+                           (bus_type == 'A' ? "ISA"
+                            : (bus_type == 'E' ? "EISA"
+                               : (bus_type == 'M' ? "MCA"
+                                  : (bus_type == 'P' ? "PCI"
+                                     : (bus_type == 'V' ? "VESA"
+                                        : (bus_type == 'X' ? "EISA/VESA"
+                                           : "Unknown")))))),
+                           base, irq);
+           if (bios != NULL)
+               printk(", BIOS 0x%05X", (unsigned int)bios);
            if (dma != 0)
                printk(", DMA %u", dma);
            printk(", ID %u\n", id);
+           buslogic_printk("Model Number: %s",
+                           (model[0] ? model : "Unknown"));
+           if (model[0])
+               printk(" (revision %d)", model[6]);
+           printk("\n");
+           buslogic_printk("Firmware revision: %s\n", firmware_rev);
 
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_DETECT)
            buslogic_stat(base);
 #endif
 
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_DETECT)
            buslogic_printk("buslogic_detect: enable interrupt channel %d\n",
                            irq);
 #endif
@@ -1083,7 +1181,7 @@ int buslogic_detect(Scsi_Host_Template *tpnt)
            }
 
            if (dma) {
-               if (request_dma(dma,"buslogic")) {
+               if (request_dma(dma, "buslogic")) {
                    buslogic_printk("Unable to allocate DMA channel for "
                                    "BusLogic controller.\n");
                    free_irq(irq);
@@ -1091,36 +1189,63 @@ int buslogic_detect(Scsi_Host_Template *tpnt)
                    goto unregister;
                }
 
-               if (dma >= 5) {
-                   outb((dma - 4) | CASCADE, DMA_MODE_REG);
-                   outb(dma - 4, DMA_MASK_REG);
-               }
+               /* The DMA-Controller.  We need to fool with this because we
+                  want to be able to use an ISA BusLogic without having to
+                  have the BIOS enabled. */
+               set_dma_mode(dma, DMA_MODE_CASCADE);
+               enable_dma(dma);
            }
 
            host[irq - 9] = shpnt;
            shpnt->this_id = id;
-#ifdef CONFIG_NO_BUGGY_BUSLOGIC
            /* Only type 'A' (AT/ISA) bus adapters use unchecked DMA. */
            shpnt->unchecked_isa_dma = (bus_type == 'A');
+#ifndef CONFIG_NO_BUGGY_BUSLOGIC
+           /* There is a hardware bug in the BT-445S prior to revision D.
+              When the BIOS is enabled and you have more than 16MB of memory,
+              the card mishandles memory transfers over 16MB which (if viewed
+              as a 24-bit address) overlap with the BIOS address space.  For
+              example if you have the BIOS located at physical address
+              0xDC000 and a DMA transfer from the card to RAM starts at
+              physical address 0x10DC000 then the transfer is messed up.  To
+              be more precise every fourth byte of the transfer is messed up.
+              (This analysis courtesy of Tomas Hurka, author of the NeXTSTEP
+              BusLogic driver.) */
+
+           if (bus_type == 'V'                             /* 445 */
+               && firmware_rev[0] <= '3'                   /* S */
+               && bios != NULL) {                          /* BIOS enabled */
+#if 0
+               /* ??? Once LNZ's forbidden_addr stuff makes it into the higher
+                  level scsi code, we can use this instead. */
+               /* Avoid addresses which "mirror" the BIOS for DMA. */
+               shpnt->forbidden_addr = bios;
+               shpnt->forbidden_size = 16 * 1024;
 #else
-           /* Bugs in the firmware of the 445S with >16M.  This does not seem
-              to affect Revision E boards with firmware 3.37. */
-           shpnt->unchecked_isa_dma = 1;
+               /* Use double-buffering. */
+               shpnt->unchecked_isa_dma = TRUE;
 #endif
+           }
+#endif
+           /* Have to keep cmd_per_lun at 1 for ISA machines otherwise lots
+              of memory gets sucked up for bounce buffers.  */
+           /* ??? Unfortunately, cmd_per_lun is only in the
+              Scsi_Host_Template structure, not the Scsi_Host structure.
+              Therefore, this could cause high memory consumption if a system
+              has multiple BusLogic adapters which are a mix of ISA and
+              non-ISA. */
+           if (!shpnt->unchecked_isa_dma)
+               shpnt->hostt->cmd_per_lun = BUSLOGIC_NONISA_CMDLUN;
            shpnt->sg_tablesize = max_sg;
            if (shpnt->sg_tablesize > BUSLOGIC_MAX_SG)
                shpnt->sg_tablesize = BUSLOGIC_MAX_SG;
-           /* ??? If we can dynamically allocate the mailbox arrays, I'll
-              probably bump up this number. */
-           shpnt->hostt->can_queue = BUSLOGIC_MAILBOXES;
-           /* No known way to determine BIOS base address, but we don't
-              care since we don't use it anyway. */
-           shpnt->base = NULL;
+           /* ??? shpnt->base should really be "const unsigned char *"... */
+           shpnt->base = (unsigned char *)bios;
            shpnt->io_port = base;
            shpnt->dma_channel = dma;
            shpnt->irq = irq;
-           HOSTDATA(shpnt)->bios_translation = trans;
-           if (trans == BIOS_TRANSLATION_BIG)
+           HOSTDATA(shpnt)->bios_translation = bios_translation;
+           if (bios_translation == BIOS_TRANSLATION_BIG)
                buslogic_printk("Using extended bios translation.\n");
            HOSTDATA(shpnt)->last_mbi_used = 2 * BUSLOGIC_MAILBOXES - 1;
            HOSTDATA(shpnt)->last_mbo_used = BUSLOGIC_MAILBOXES - 1;
@@ -1134,7 +1259,7 @@ int buslogic_detect(Scsi_Host_Template *tpnt)
                    = { READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                size_t i;
 
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_DETECT)
                buslogic_printk("*** READ CAPACITY ***\n");
 #endif
                for (i = 0; i < sizeof buf; i++)
@@ -1146,7 +1271,7 @@ int buslogic_detect(Scsi_Host_Template *tpnt)
                                        i, *(int *)(buf + 4), *(int *)buf);
                    }
 
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_DETECT)
                buslogic_printk("*** NOW RUNNING MY OWN TEST ***\n");
 #endif
                for (i = 0; i < 4; i++) {
@@ -1164,7 +1289,7 @@ int buslogic_detect(Scsi_Host_Template *tpnt)
            }
 #endif
 
-           snarf_region(bases[indx], 3);       /* Register the IO ports that
+           snarf_region(bases[indx], 4);       /* Register the IO ports that
                                                   we use */
            count++;
            continue;
@@ -1292,7 +1417,7 @@ int buslogic_reset(Scsi_Cmnd *scpnt)
     static const unsigned char buscmd[] = { CMD_START_SCSI };
     unsigned int i;
 
-#if BUSLOGIC_DEBUG
+#if (BUSLOGIC_DEBUG & BD_RESET)
     buslogic_printk("buslogic_reset\n");
 #endif
 #if 0
@@ -1303,8 +1428,7 @@ int buslogic_reset(Scsi_Cmnd *scpnt)
     /* First locate the ccb for this command. */
     for (i = 0; i < BUSLOGIC_MAILBOXES; i++)
        if (HOSTDATA(scpnt->host)->sc[i] == scpnt) {
-           HOSTDATA(scpnt->host)->ccbs[i].op = 0x81;   /* ??? BUS DEVICE
-                                                          RESET */
+           HOSTDATA(scpnt->host)->ccbs[i].op = CCB_OP_BUS_RESET;
 
            /* Now tell the BusLogic to flush all pending commands for this
               target. */
@@ -1329,7 +1453,8 @@ int buslogic_reset(Scsi_Cmnd *scpnt)
                    sctmp->result = DID_RESET << 16;
                    if (sctmp->host_scribble)
                        scsi_free(sctmp->host_scribble, BUSLOGIC_SG_MALLOC);
-                   printk("Sending DID_RESET for target %d\n", scpnt->target);
+                   buslogic_printk("Sending DID_RESET for target %d\n",
+                                   scpnt->target);
                    sctmp->scsi_done(scpnt);
 
                    HOSTDATA(scpnt->host)->sc[i] = NULL;
@@ -1347,35 +1472,41 @@ int buslogic_reset(Scsi_Cmnd *scpnt)
     return SCSI_RESET_PUNT;
 }
 
+/* ??? This is probably not correct for series "C" boards.  I believe these
+   support separate mappings for each disk.  We would need to issue a
+   CMD_READ_FW_LOCAL_RAM command to check for the particular drive being
+   queried.  Note that series "C" boards can be differentiated by having
+   HOSTDATA(disk->device->host)->firmware_rev[0] >= '4'. */
 int buslogic_biosparam(Disk *disk, int dev, int *ip)
 {
-    /* ??? This truncates.  Should we round up to next MB? */
-    unsigned int mb = disk->capacity >> 11;
+    unsigned int size = disk->capacity;
 
     /* ip[0] == heads, ip[1] == sectors, ip[2] == cylinders */
     if (HOSTDATA(disk->device->host)->bios_translation == BIOS_TRANSLATION_BIG
-       && mb > 1024) {
-       if (mb > 4096) {
+       && size >= 0x200000) {          /* 1GB */
+       if (size >= 0x400000) {         /* 2GB */
+#if 0  /* ??? Used in earlier kernels, but disagrees with BusLogic info. */
+           if (mb >= 0x800000) {       /* 4GB */
+               ip[0] = 256;
+               ip[1] = 64;
+           } else {
+               ip[0] = 256;
+               ip[1] = 32;
+           }
+#else
            ip[0] = 256;
            ip[1] = 64;
-           ip[2] = mb >> 3;
-/*         if (ip[2] > 1024)
-               ip[2] = 1024; */
-       } else if (mb > 2048) {
-           ip[0] = 256;
-           ip[1] = 32;
-           ip[2] = mb >> 2;
+#endif
        } else {
            ip[0] = 128;
            ip[1] = 32;
-           ip[2] = mb >> 1;
        }
     } else {
        ip[0] = 64;
        ip[1] = 32;
-       ip[2] = mb;
-/*     if (ip[2] > 1024)
-           ip[2] = 1024; */
     }
+    ip[2] = size / (ip[0] * ip[1]);
+/*    if (ip[2] > 1024)
+       ip[2] = 1024; */
     return 0;
 }
index 585de430779af647df996e261bc233a24e2fbc2a..04ca8b01c03677f8719857765032f01632dd56e3 100644 (file)
@@ -20,15 +20,14 @@ int buslogic_reset(Scsi_Cmnd *);
 int buslogic_biosparam(Disk *, int, int *);
 
 #define BUSLOGIC_CMDLUN 1      /* Do not set this too high.  It sucks
-                                  up lots of memory on machines with > 16Mb
-                                  because of the huge number of bounce
-                                  buffers that need to be allocated.
+                                  up lots of memory on ISA machines
+                                  with > 16MB because of the huge number of
+                                  bounce buffers that need to be allocated.
                                   For boards that use non-ISA bus, we can
                                   bump this in the board detect routine.  
-                                                       10/8/94 ERY */
-                                  
+                                                       10/8/94 ERY */
 
-#define BUSLOGIC { NULL,                       \
+#define BUSLOGIC { NULL,                       \
                   "BusLogic",                  \
                   buslogic_detect,             \
                   NULL,                        \
@@ -65,8 +64,11 @@ int buslogic_biosparam(Disk *, int, int *);
 #define BD_ABORT       0x0001
 #define BD_COMMAND     0x0002
 #define BD_DETECT      0x0004
-#define BD_INTERRUPT   0x0008
-#define BD_RESET       0x0010
+#define BD_ERRORS      0x0008
+#define BD_INTERRUPT   0x0010
+#define BD_IO          0x0020
+#define BD_RESET       0x0040
+#define BD_UNDOCUMENTED        0x0080
 
 /* I/O Port interface */
 /* READ */
@@ -77,18 +79,27 @@ int buslogic_biosparam(Disk *, int, int *);
 #define HARDY 0x10             /* Host Adapter Ready */
 #define CPRBSY 0x08            /* Command/Parameter Register Busy */
 #define DIRRDY 0x04            /* Data In Register Ready */
+                               /* 0x02 is reserved */
 #define CMDINV 0x01            /* Command Invalid */
-#define STATMASK 0xFD          /* 0x02 is reserved */
 
 #define DATA_IN(base) (STATUS(base) + 1)
 
 #define INTERRUPT(base) (STATUS(base) + 2)
 #define INTV 0x80              /* Interrupt Valid */
+                               /* 0x70 are reserved */
 #define RSTS 0x08              /* SCSI Reset State */
 #define CMDC 0x04              /* Command Complete */
 #define MBOR 0x02              /* Mailbox Out Ready */
 #define IMBL 0x01              /* Incoming Mailbox Loaded */
-#define INTRMASK 0x8F          /* 0x70 are reserved */
+#define INTRMASK 0x8F
+
+/* This undocumented port returns a bitmask indicating geometry translation. */
+#define GEOMETRY(base) (STATUS(base) + 3)
+#define GEO_GT_1GB 0x80                /* > 1GB under DOS geometry mapping */
+                               /* 0x70 are unknown */
+#define GEO_XLATION_S_D1 0x0C  /* Disk 1 geometry ("S" models only) */
+#define GEO_XLATION_S_D0 0x03  /* Disk 0 geometry ("S" models only) */
+
 
 /* WRITE */
 #define CONTROL(base) STATUS(base)
@@ -96,6 +107,7 @@ int buslogic_biosparam(Disk *, int, int *);
 #define RSOFT 0x40             /* Soft Reset */
 #define RINT 0x20              /* Interrupt Reset */
 #define RSBUS 0x10             /* SCSI Bus Reset */
+                               /* 0x0F are reserved */
 
 #define COMMAND_PARAMETER(base) (STATUS(base) + 1)
 #define CMD_TSTCMDCINT 0x00    /* Test CMDC Interrupt */
@@ -120,7 +132,13 @@ int buslogic_biosparam(Disk *, int, int *);
 #define CMD_HA_DIAG 0x20       /* Host Adapter Diagnostic */
 #define CMD_HA_OPTIONS 0x21    /* Host Adapter Options */
 #define CMD_INITEXTMB 0x81     /* Initialize Extended Mailbox */
+#define CMD_VER_NO_LAST 0x84   /* Version Number Last Byte (undocumented) */
+#define CMD_VER_NO_LETTER 0x85 /* Version Number One Letter (undocumented) */
+#define CMD_RET_MODEL_NO 0x8B  /* Return Model Number (undocumented) */
 #define CMD_INQEXTSETUP 0x8D   /* Inquire Extended Set-up Information */
+#define CMD_ROUND_ROBIN 0x8F   /* Enable strict vs. half-assed round-robin
+                                  mailbox filling (undocumented) */
+#define CMD_READ_FW_LCL_RAM 0x91/* Read Firmware Local RAM (undocumented) */
 #define CMD_WRITE_INQ_BUF 0x9A /* Write Inquiry Data Buffer
                                   (Target Mode Only) */
 #define CMD_READ_INQ_BUF 0x9B  /* Read Inquiry Data Buffer
index d7d89d16d4f73606a33976a304846c348194f1c9..b6976e1bc7406583ed94ddfc3b16c587f6a8028d 100644 (file)
@@ -367,10 +367,6 @@ int eata_detect (Scsi_Host_Template * tpnt) {
    return j;
 }
 
-const char *eata_info (void) {
-   return driver_name;
-}
-
 static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
    unsigned int k;
    struct scatterlist * sgpnt;
@@ -471,7 +467,7 @@ int eata_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
       cpp->data_len = htonl(SCpnt->request_bufflen);
       }
 
-   memcpy(cpp->cdb, SCpnt->cmnd, COMMAND_SIZE(*SCpnt->cmnd));
+   memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);
 
    /* Send control packet to the board */
    if (do_dma(sh[j]->io_port, (unsigned int) cpp, SEND_CP_DMA)) {
index 164e437da9aba09ac91afe3aeb0bec765a456c42..27b86f3454af4c870fd46e16333ef0dd4d6ab0f0 100644 (file)
 int eata_detect(Scsi_Host_Template *);
 int eata_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int eata_abort(Scsi_Cmnd *);
-const char *eata_info(void);
 int eata_reset(Scsi_Cmnd *);
 int eata_bios_param(Disk *, int, int*);
 
 #define EATA {  NULL, /* Ptr for modules */                    \
+                 NULL, /* usage count for modules */          \
                 "EISA EATA 2.0A rev. " EATA_VERSION " by "     \
-                "Dario_Ballabio@milano.europe.dg.com.",\
+                "Dario_Ballabio@milano.europe.dg.com.",        \
                 eata_detect,                                  \
                 NULL, /* Release */                           \
-               eata_info,                                     \
+               NULL,                                          \
                NULL,                                          \
                eata_queuecommand,                             \
                eata_abort,                                    \
index 9caa24ecb83e43ccd1b5bb68e2f692f308d94a0f..6a315918778a7f540af8a71014b25f071c33cddf 100644 (file)
@@ -375,9 +375,9 @@ struct signature {
 
 #define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
 
-static void print_banner( void )
+static void print_banner( struct Scsi_Host * shpnt )
 {
-   printk( "%s", fdomain_16x0_info() );
+   printk( "%s", fdomain_16x0_info(shpnt) );
    printk( "Future Domain: BIOS version %d.%d, %s\n",
           bios_major, bios_minor,
           chip == tmc1800 ? "TMC-1800"
@@ -637,7 +637,7 @@ int fdomain_16x0_detect( Scsi_Host_Template *tpnt )
       return 0;                /* Cannot find valid set of ports */
    }
 
-   print_banner();
+   print_banner(NULL);
 
    SCSI_Mode_Cntl_port   = port_base + SCSI_Mode_Cntl;
    FIFO_Data_Count_port  = port_base + FIFO_Data_Count;
@@ -755,7 +755,7 @@ int fdomain_16x0_detect( Scsi_Host_Template *tpnt )
    return 1;
 }
 
-const char *fdomain_16x0_info(void)
+const char *fdomain_16x0_info(struct Scsi_Host * shpnt)
 {
    static char buffer[80];
    char        *pt;
@@ -1014,7 +1014,7 @@ void fdomain_16x0_intr( int unused )
    if (chip == tmc1800
        && !current_SC->SCp.have_data_in
        && (current_SC->SCp.sent_command
-          >= COMMAND_SIZE( current_SC->cmnd[ 0 ] ))) {
+          >= current_SC->cmd_len)) {
                                /* We have to get the FIFO direction
                                   correct, so I've made a table based
                                   on the SCSI Standard of which commands
@@ -1376,7 +1376,7 @@ void print_info( Scsi_Cmnd *SCpnt )
    unsigned int irr;
    unsigned int isr;
    
-   print_banner();
+   print_banner(SCpnt->host);
    switch (SCpnt->SCp.phase) {
    case in_arbitration: printk( "arbitration " ); break;
    case in_selection:   printk( "selection " );   break;
index d1ce605e0cd98579f34c83b2c2d96744124409ca..f82963d4edbc532ddf9df7043a8c16f05a736c91 100644 (file)
 int        fdomain_16x0_detect( Scsi_Host_Template * );
 int        fdomain_16x0_command( Scsi_Cmnd * );
 int        fdomain_16x0_abort( Scsi_Cmnd * );
-const char *fdomain_16x0_info( void );
+const char *fdomain_16x0_info( struct Scsi_Host * );
 int        fdomain_16x0_reset( Scsi_Cmnd * ); 
 int        fdomain_16x0_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) );
 int        fdomain_16x0_biosparam( Disk *, int, int * );
 
-#define FDOMAIN_16X0 { NULL,                             \
-                      "Future Domain TMC-16x0",         \
+#define FDOMAIN_16X0 { NULL, NULL,                            \
+                      NULL,                             \
                       fdomain_16x0_detect,              \
                       NULL,                             \
                       fdomain_16x0_info,                \
index 088537239548ff5e944db4048e9c61f83c677a1b..dd6408ed4324bd12b8b9a0cdb84ffebd81318c22 100644 (file)
@@ -35,7 +35,6 @@
 #ifndef ASM
 int generic_NCR5380_abort(Scsi_Cmnd *);
 int generic_NCR5380_detect(Scsi_Host_Template *);
-const char *generic_NCR5380_info(void);
 int generic_NCR5380_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int generic_NCR5380_reset(Scsi_Cmnd *);
 
@@ -54,8 +53,8 @@ int generic_NCR5380_reset(Scsi_Cmnd *);
 
 #ifdef HOSTS_C
 
-#define GENERIC_NCR5380 {NULL, "Trantor T128/T128F/T228",              \
-       generic_NCR5380_detect, NULL, generic_NCR5380_info, NULL,       \
+#define GENERIC_NCR5380 {NULL, NULL, "Trantor T128/T128F/T228",        \
+       generic_NCR5380_detect, NULL, NULL, NULL,       \
        generic_NCR5380_queue_command, generic_NCR5380_abort,           \
        generic_NCR5380_reset, NULL,                                    \
        NULL, /* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL,            \
index 64c4de82adbaa870e027cd1d5ee2a5bea450d68f..9488c1f1987b2df9e9c55daa69dacf64e581bd88 100644 (file)
@@ -227,6 +227,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){
        struct Scsi_Host * retval, *shpnt;
        retval = (struct Scsi_Host *)scsi_init_malloc(sizeof(struct Scsi_Host) + j);
        retval->host_busy = 0;
+       retval->block = NULL;
        if(j > 0xffff) panic("Too many extra bytes requested\n");
        retval->extra_bytes = j;
        retval->loaded_as_module = scsi_loadable_module_flag;
index 9eb51d170e39e830818f808dc159aa80706b5008..26b4e1c9fa7d3f7d488f15dfdc680b4ba923d029 100644 (file)
@@ -52,6 +52,9 @@ typedef struct  SHT
          /* Used with loadable modules so we can construct a linked list. */
          struct SHT * next;
 
+         /* Used with loadable modules so that we know when it is safe to unload */
+         int * usage_count;
+
        /*
                The name pointer is a pointer to the name of the SCSI
                device detected.
@@ -77,14 +80,18 @@ typedef struct  SHT
 
        int (* detect)(struct SHT *); 
 
-         /* Used with loadable modules to unload the host structures */
+         /* Used with loadable modules to unload the host structures.  Note:
+          there is a default action built into the modules code which may
+          be sufficient for most host adapters.  Thus you may not have to supply
+          this at all. */
        int (*release)(struct Scsi_Host *);
        /*
                The info function will return whatever useful
-               information the developer sees fit.              
+               information the developer sees fit.  If not provided, then
+               the name field will be used instead.
        */
 
-        const char *(* info)(void);
+        const char *(* info)(struct Scsi_Host *);
 
        /*
                The command function takes a target, a command (this is a SCSI 
@@ -221,6 +228,8 @@ typedef struct  SHT
        be two Scsi_Host entries, but only 1 Scsi_Host_Template entries.
 */
 
+#define SCSI_HOST_BLOCK 0x800
+
 struct Scsi_Host
        {
                struct Scsi_Host * next;
@@ -232,9 +241,15 @@ struct Scsi_Host
                Scsi_Cmnd *host_queue; 
                Scsi_Host_Template * hostt;
 
+               /* Pointer to a circularly linked list - this indicates the hosts
+                  that should be locked out of performing I/O while we have an active
+                  command on this host. */
+               struct Scsi_Host * block;
+
                /* These parameters should be set by the detect routine */
                unsigned char *base;
                short unsigned int io_port;
+               unsigned char n_io_port;
                unsigned char irq;
                unsigned char dma_channel;
                /*
index deca50baeed89701f6072de641b8bfb2ae68f427..7d9db4acb347896e021106c494b9b71525ae7579 100644 (file)
@@ -399,7 +399,7 @@ static void in2000_intr_handle(int foo)
        }                       /* end while intrpt active */
 }
 
-static int in2000_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
+int in2000_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
 {
     unchar direction;
     unchar *cmd = (unchar *) SCpnt->cmnd;
@@ -551,7 +551,7 @@ static void internal_done(Scsi_Cmnd * SCpnt)
     ++internal_done_flag;
 }
 
-static int in2000_command(Scsi_Cmnd * SCpnt)
+int in2000_command(Scsi_Cmnd * SCpnt)
 {
     in2000_queuecommand(SCpnt, internal_done);
 
@@ -560,7 +560,7 @@ static int in2000_command(Scsi_Cmnd * SCpnt)
     return internal_done_errcode;
 }
 
-static int in2000_detect(Scsi_Host_Template * tpnt)
+int in2000_detect(Scsi_Host_Template * tpnt)
 {
 /* Order chosen to reduce conflicts with some multi-port serial boards */
     int base_tab[] = { 0x220,0x200,0x110,0x100 };
@@ -632,7 +632,7 @@ static int in2000_detect(Scsi_Host_Template * tpnt)
     return 1;
 }
 
-static int in2000_abort(Scsi_Cmnd * SCpnt)
+int in2000_abort(Scsi_Cmnd * SCpnt)
 {
     DEB(printk("in2000_abort\n"));
     /*
@@ -649,7 +649,7 @@ static inline void delay( unsigned how_long )
     while (jiffies < time) ;
 }
 
-static int in2000_reset(Scsi_Cmnd * SCpnt)
+int in2000_reset(Scsi_Cmnd * SCpnt)
 {
     DEB(printk("in2000_reset called\n"));
     /*
@@ -671,7 +671,7 @@ static int in2000_reset(Scsi_Cmnd * SCpnt)
 #endif
 }
 
-static int in2000_biosparam(Disk * disk, int dev, int* iinfo)
+int in2000_biosparam(Disk * disk, int dev, int* iinfo)
        {
          int size = disk->capacity;
     DEB(printk("in2000_biosparam\n"));
index 7a55fb440198cc2c5cd96080bb853c500bec0e01..a7564391c736f3492ca5b282da42057d9fef4ae6 100644 (file)
 #define MAX_SENSE 14
 #define MAX_STATUS 32
 
-static int in2000_detect(Scsi_Host_Template *);
-static int in2000_command(Scsi_Cmnd *);
-static int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-static int in2000_abort(Scsi_Cmnd *);
-static int in2000_reset(Scsi_Cmnd *);
-static int in2000_biosparam(Disk *, int, int*);
+int in2000_detect(Scsi_Host_Template *);
+int in2000_command(Scsi_Cmnd *);
+int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+int in2000_abort(Scsi_Cmnd *);
+int in2000_reset(Scsi_Cmnd *);
+int in2000_biosparam(Disk *, int, int*);
 
 
 #ifndef NULL
@@ -108,7 +108,7 @@ static int in2000_biosparam(Disk *, int, int*);
 
 /* next may be "SG_NONE" or "SG_ALL" or nr. of (1k) blocks per R/W Cmd. */
 #define IN2000_SG SG_ALL
-#define IN2000 {NULL, "Always IN2000", in2000_detect, NULL,    \
+#define IN2000 {NULL, NULL, "Always IN2000", in2000_detect, NULL,      \
                NULL, in2000_command,           \
                in2000_queuecommand,            \
                in2000_abort,                   \
index 5dad9529c84ff7ffffc785651fdfc155080c8b2f..2ffbdf633734c0f0c9abcfdd3e61e25d55cda1e0 100644 (file)
@@ -525,17 +525,4 @@ static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src
        return 0;
 }
 
-/*
- * Function : const char *pas16_info(void)
- *
- * Purpose : provide further information about this driver.
- *
- * Returns : an empty string.
- */
-
-const char *pas16_info (void) {
-    static const char string[]="";
-    return string;
-}
-
 #include "NCR5380.c"
index 2dc04026b8d8278a16e3b0add9ed021ed1178429..b2aede01c28f5c4dc4a622089f585a05ea02b0ad 100644 (file)
 int pas16_abort(Scsi_Cmnd *);
 int pas16_biosparam(Disk *, int, int*);
 int pas16_detect(Scsi_Host_Template *);
-const char *pas16_info(void);
 int pas16_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int pas16_reset(Scsi_Cmnd *);
 
@@ -141,8 +140,8 @@ int pas16_reset(Scsi_Cmnd *);
 
 #ifdef HOSTS_C
 
-#define MV_PAS16 {NULL, "Pro Audio Spectrum-16 SCSI",                  \
-       pas16_detect, NULL, pas16_info,                                 \
+#define MV_PAS16 {NULL, NULL, "Pro Audio Spectrum-16 SCSI",            \
+       pas16_detect, NULL, NULL,                                       \
        NULL, pas16_queue_command, pas16_abort, pas16_reset, NULL,      \
        pas16_biosparam,                                                \
        /* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL,                  \
index f847393a0c8399b6608224a3dd3e07b309c275d8..826315a6b86bd26b60cfa717c6de508cb42b56f1 100644 (file)
@@ -258,7 +258,7 @@ unsigned int            i;
        outb(0x99, qbase + 5);  /* timer */
        outb(cmd->target, qbase + 4);
 
-       for (i = 0; i < COMMAND_SIZE(cmd->cmnd[0]); i++)
+       for (i = 0; i < cmd->cmd_len; i++)
                outb(cmd->cmnd[i], qbase + 2);
        qlcmd = cmd;
        outb(0x41, qbase + 3);  /* select and send command */
@@ -558,7 +558,7 @@ int qlogic_reset(Scsi_Cmnd * cmd)
 
 /*----------------------------------------------------------------*/
 /* return info string */
-const char     *qlogic_info()
+const char     *qlogic_info(struct Scsi_Host * host)
 {
        return qinfo;
 }
index aecb64ff3f0fb0da22bd4cfd8280a3e5cb85183c..eb30cfa9103fddd7d87991add5554a0f2753a9c6 100644 (file)
@@ -2,7 +2,7 @@
 #define _QLOGIC_H
 
 int qlogic_detect(Scsi_Host_Template * );
-const char * qlogic_info(void);
+const char * qlogic_info(struct Scsi_Host *);
 int qlogic_command(Scsi_Cmnd *);
 int qlogic_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
 int qlogic_abort(Scsi_Cmnd *);
@@ -14,6 +14,7 @@ int qlogic_biosparam(Disk *,int,int[]);
 #endif
 
 #define QLOGIC {               \
+       NULL,                   \
        NULL,                   \
        NULL,                   \
        qlogic_detect,          \
index 46b2b444c56c5bae4da827d65a749c2e04bd6d02..96dd21932108813ea5746e3a146e664bd268ecfa 100644 (file)
@@ -269,8 +269,10 @@ static void scan_scsis (struct Scsi_Host * shpnt)
          SCmd.target = dev;
          SCmd.lun = lun;
 
+         SCmd.request.sem = NULL;  /* Used for mutex if loading devices after boot */
          SCmd.request.dev = 0xffff; /* Mark not busy */
          SCmd.use_sg  = 0;
+         SCmd.cmd_len = 0;
          SCmd.old_use_sg  = 0;
          SCmd.transfersize = 0;
          SCmd.underflow = 0;
@@ -316,6 +318,7 @@ static void scan_scsis (struct Scsi_Host * shpnt)
          scsi_cmd[5] = 0;
          
          SCmd.request.dev = 0xffff; /* Mark not busy */
+         SCmd.cmd_len = 0;
          
          scsi_do_cmd (&SCmd,
                       (void *)  scsi_cmd, (void *) 
@@ -462,6 +465,7 @@ static void scan_scsis (struct Scsi_Host * shpnt)
                    scsi_cmd[5] = 0;
                    
                    SCmd.request.dev = 0xffff; /* Mark not busy */
+                   SCmd.cmd_len = 0;
                    
                    scsi_do_cmd (&SCmd,
                                 (void *)  scsi_cmd, (void *) 
@@ -527,10 +531,6 @@ static void scsi_times_out (Scsi_Cmnd * SCpnt)
                {
                case NORMAL_TIMEOUT:
                        if (!in_scan_scsis) {
-                             printk("scsi : aborting command due to timeout : pid %lu, scsi%d, id %d, lun %d ",
-                               SCpnt->pid, SCpnt->host->host_no, (int) SCpnt->target, (int) 
-                               SCpnt->lun);
-                               print_command (SCpnt->cmnd);
 #ifdef DEBUG_TIMEOUT
                          scsi_dump_status();
 #endif
@@ -572,10 +572,10 @@ Scsi_Cmnd * request_queueable (struct request * req, Scsi_Device * device)
   struct buffer_head * bh, *bhp;
 
   if (!device)
-    panic ("No device passed to allocate_device().\n");
+    panic ("No device passed to request_queueable().\n");
   
   if (req && req->dev <= 0)
-    panic("Invalid device in allocate_device");
+    panic("Invalid device in request_queueable");
   
   SCpnt =  device->host->host_queue;
     while(SCpnt){
@@ -629,6 +629,7 @@ Scsi_Cmnd * request_queueable (struct request * req, Scsi_Device * device)
   SCpnt->old_use_sg  = 0;
   SCpnt->transfersize = 0;
   SCpnt->underflow = 0;
+  SCpnt->cmd_len = 0;
   return SCpnt;
 }
 
@@ -734,6 +735,7 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, Scsi_Device * device,
   SCpnt->use_sg = 0;  /* Reset the scatter-gather flag */
   SCpnt->old_use_sg  = 0;
   SCpnt->transfersize = 0;      /* No default transfer size */
+  SCpnt->cmd_len = 0;
   SCpnt->underflow = 0;         /* Do not flag underflow conditions */
   return SCpnt;
 }
@@ -832,8 +834,10 @@ static void scsi_request_sense (Scsi_Cmnd * SCpnt)
        SCpnt->request_buffer = &SCpnt->sense_buffer;
        SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer);
        SCpnt->use_sg = 0;
+       SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
        internal_cmnd (SCpnt);
        SCpnt->use_sg = SCpnt->old_use_sg;
+       SCpnt->cmd_len = SCpnt->old_cmd_len;
        }
 
 
@@ -891,6 +895,11 @@ void scsi_do_cmd (Scsi_Cmnd * SCpnt, const void *cmnd ,
                         (host->host_busy >= host->can_queue));
            } else {
              host->host_busy++;
+             if (host->block) {
+               struct Scsi_Host * block;
+               for(block = host->block; block != host; block = block->block)
+                 block->host_busy |= ~SCSI_HOST_BLOCK;
+             }
              sti();
              break;
            };
@@ -924,6 +933,9 @@ void scsi_do_cmd (Scsi_Cmnd * SCpnt, const void *cmnd ,
        SCpnt->request_buffer = buffer;
        SCpnt->request_bufflen = bufflen;
        SCpnt->old_use_sg = SCpnt->use_sg;
+       if (SCpnt->cmd_len == 0)
+               SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
+       SCpnt->old_cmd_len = SCpnt->cmd_len;
 
        /* Start the timer ticking.  */
 
@@ -1329,6 +1341,7 @@ static void scsi_done (Scsi_Cmnd * SCpnt)
                            SCpnt->request_buffer = SCpnt->buffer;
                            SCpnt->request_bufflen = SCpnt->bufflen;
                            SCpnt->use_sg = SCpnt->old_use_sg;
+                           SCpnt->cmd_len = SCpnt->old_cmd_len;
                            internal_cmnd (SCpnt);
                          };
                        break;  
@@ -1337,14 +1350,29 @@ static void scsi_done (Scsi_Cmnd * SCpnt)
                }
 
        if (status == FINISHED) 
-               {
-               #ifdef DEBUG
-                       printk("Calling done function - at address %08x\n", SCpnt->done);
-               #endif
+         {
+#ifdef DEBUG
+               printk("Calling done function - at address %08x\n", SCpnt->done);
+#endif
                host->host_busy--; /* Indicate that we are free */
+               if (host->host_busy == 0 && host->block) {
+                 struct Scsi_Host * block;
+                 /*
+                  * Now remove the locks for all of the related hosts.
+                  */
+                 for(block = host->block; block != host; block = block->block)
+                     block->host_busy &= ~SCSI_HOST_BLOCK;
+                 /*
+                  * Now wake them up.  We do this in two separate stages to prevent
+                  * race conditions.
+                  */
+                 for(block = host->block; block != host; block = block->block)
+                     wake_up(&block->host_wait);
+               }
                wake_up(&host->host_wait);
                SCpnt->result = result | ((exit & 0xff) << 24);
                SCpnt->use_sg = SCpnt->old_use_sg;
+               SCpnt->cmd_len = SCpnt->old_cmd_len;
                SCpnt->done (SCpnt);
                }
 
@@ -1403,6 +1431,10 @@ int scsi_abort (Scsi_Cmnd * SCpnt, int why)
                          update_timeout(SCpnt, oldto);
                          return 0;
                        }
+                       printk("scsi : aborting command due to timeout : pid %lu, scsi%d, id %d, lun %d ",
+                              SCpnt->pid, SCpnt->host->host_no, (int) SCpnt->target, (int) 
+                              SCpnt->lun);
+                       print_command (SCpnt->cmnd);
                        SCpnt->abort_reason = why;
                        switch(host->hostt->abort(SCpnt)) {
                          /* We do not know how to abort.  Try waiting another
@@ -1787,6 +1819,8 @@ unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end
              SCpnt->request.dev = -1; /* Mark not busy */
              SCpnt->use_sg = 0;
              SCpnt->old_use_sg = 0;
+             SCpnt->old_cmd_len = 0;
+             SCpnt->timeout = 0;
               SCpnt->underflow = 0;
               SCpnt->transfersize = 0;
              SCpnt->host_scribble = NULL;
index cb0641fb8a5a2974badb4d24de0ebcbb9887bf5f..9eb8398769c6ba5068af8a6306f5340c454c472f 100644 (file)
@@ -428,6 +428,8 @@ typedef struct scsi_cmnd {
        struct Scsi_Host * host;
        Scsi_Device * device;
        unsigned char target, lun;
+       unsigned char cmd_len;
+       unsigned char old_cmd_len;
        struct scsi_cmnd *next, *prev;  
 
 /* These elements define the operation we are about to perform */
index cdaca4006aa4f25eff149fd10aa2983e860ea87d..25fe199ea05de2937542228c44b382f0140b616d 100644 (file)
@@ -7,7 +7,6 @@ int scsi_debug_command(Scsi_Cmnd *);
 int scsi_debug_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int scsi_debug_abort(Scsi_Cmnd *);
 int scsi_debug_biosparam(Disk *, int, int[]);
-const char *scsi_debug_info(void);
 int scsi_debug_reset(Scsi_Cmnd *);
 
 #ifndef NULL
@@ -16,8 +15,8 @@ int scsi_debug_reset(Scsi_Cmnd *);
 
 #define SCSI_DEBUG_MAILBOXES 8
 
-#define SCSI_DEBUG {NULL, "SCSI DEBUG", scsi_debug_detect, NULL,       \
-               scsi_debug_info, scsi_debug_command,            \
+#define SCSI_DEBUG {NULL, NULL, "SCSI DEBUG", scsi_debug_detect, NULL, \
+               NULL, scsi_debug_command,               \
                scsi_debug_queuecommand,                        \
                scsi_debug_abort,                               \
                scsi_debug_reset,                               \
index 05381fb90ae28bab2e97c94f1cd31e47fc03a217..c0be923c652b884179b3df4a8f9b175852b9fa44 100644 (file)
@@ -33,12 +33,17 @@ static int ioctl_probe(struct Scsi_Host * host, void *buffer)
        
        if ((temp = host->hostt->present) && buffer) {
                len = get_fs_long ((unsigned long *) buffer);
-               string = host->hostt->info();
-               slen = strlen(string);
-               if (len > slen)
-                       len = slen + 1;
-               verify_area(VERIFY_WRITE, buffer, len);
-               memcpy_tofs (buffer, string, len);
+               if(host->hostt->info)
+                 string = host->hostt->info(host);
+               else 
+                 string = host->hostt->name;
+               if(string) {
+                 slen = strlen(string);
+                 if (len > slen)
+                   len = slen + 1;
+                 verify_area(VERIFY_WRITE, buffer, len);
+                 memcpy_tofs (buffer, string, len);
+               }
        }
        return temp;
 }
index ec5cff927995b6f12faf9e65b9d2c47b551027b7..253f8d2dca03177dc312a6f59d2de47545273abf 100644 (file)
@@ -838,6 +838,7 @@ static int sd_init_onedisk(int i)
       cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
       memset ((void *) &cmd[2], 0, 8);
       SCpnt->request.dev = 0xffff;  /* Mark as really busy again */
+      SCpnt->cmd_len = 0;
       SCpnt->sense_buffer[0] = 0;
       SCpnt->sense_buffer[2] = 0;
       
@@ -863,6 +864,7 @@ static int sd_init_onedisk(int i)
          memset ((void *) &cmd[2], 0, 8);
          cmd[4] = 1; /* Start spin cycle */
          SCpnt->request.dev = 0xffff;  /* Mark as really busy again */
+         SCpnt->cmd_len = 0;
          SCpnt->sense_buffer[0] = 0;
          SCpnt->sense_buffer[2] = 0;
          
@@ -897,6 +899,7 @@ static int sd_init_onedisk(int i)
     memset ((void *) &cmd[2], 0, 8);
     memset ((void *) buffer, 0, 8);
     SCpnt->request.dev = 0xffff;  /* Mark as really busy again */
+    SCpnt->cmd_len = 0;
     SCpnt->sense_buffer[0] = 0;
     SCpnt->sense_buffer[2] = 0;
     
index 9656b01995d4f5a5b437ea54cecd46a13a6938ed..e35079f761076e8c65e68fcd722cd1d674cdda10 100644 (file)
@@ -39,6 +39,7 @@ typedef struct scsi_disk {
                unsigned char sector_bit_shift; /* power of 2 sectors per FS block */
                unsigned ten:1;                 /* support ten byte read / write */
                unsigned remap:1;               /* support remapping  */
+               unsigned has_part_table:1;      /* has partition table */
                } Scsi_Disk;
        
 extern Scsi_Disk * rscsi_disks;
index 5eb721bb5cd9442a87030022b66df6ed189b7de1..0b377911c572ca7188bf5bc0da052e41aeea8f50 100644 (file)
@@ -362,7 +362,7 @@ int seagate_st0x_detect (Scsi_Host_Template * tpnt)
                }
        }
         
-const char *seagate_st0x_info(void) {
+const char *seagate_st0x_info(struct Scsi_Host * shpnt) {
       static char buffer[256];
         sprintf(buffer, "scsi%d : %s at irq %d address %p options :"
 #ifdef ARBITRATE
@@ -525,7 +525,7 @@ int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt,  void (*done)(Scsi_Cmnd *))
  * Set linked command bit in control field of SCSI command.
  */
 
-         current_cmnd[COMMAND_SIZE(current_cmnd[0])] |= 0x01;
+         current_cmnd[SCpnt->cmd_len] |= 0x01;
          if (linked_connected) {
 #if (DEBUG & DEBUG_LINKED) 
            printk("scsi%d : using linked commands, current I_T_L nexus is ",
index 5abfd663679bf98d47ab7be0c2c5d60bace2a74d..abc1c930a0a55b4ca8223705d2668c50ed9847e5 100644 (file)
@@ -17,7 +17,7 @@ int seagate_st0x_command(Scsi_Cmnd *);
 int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 
 int seagate_st0x_abort(Scsi_Cmnd *);
-const char *seagate_st0x_info(void);
+const char *seagate_st0x_info(struct Scsi_Host *);
 int seagate_st0x_reset(Scsi_Cmnd *); 
 
 #ifndef NULL
@@ -26,7 +26,7 @@ int seagate_st0x_reset(Scsi_Cmnd *);
 
 int seagate_st0x_biosparam(Disk *, int, int*);
 
-#define SEAGATE_ST0X  {NULL, "Seagate ST-01/ST-02", seagate_st0x_detect, \
+#define SEAGATE_ST0X  {NULL, NULL, NULL, seagate_st0x_detect,          \
                         NULL,                                          \
                         seagate_st0x_info, seagate_st0x_command,       \
                         seagate_st0x_queue_command, seagate_st0x_abort, \
index 936a48b12be88a2a2f056213554e60c0a9c526d3..f60d1ffce1e45cbc32c33dbdf1a8f09bde020eeb 100644 (file)
@@ -220,6 +220,7 @@ static int sg_write(struct inode *inode,struct file *filp,char *buf,int count)
   int dev=MINOR(inode->i_rdev);
   Scsi_Cmnd *SCpnt;
   int bsize,size,amt,i;
+  unsigned char opcode;
   unsigned char cmnd[MAX_COMMAND_SIZE];
   struct scsi_generic *device=&scsi_generics[dev];
 
@@ -274,6 +275,9 @@ static int sg_write(struct inode *inode,struct file *filp,char *buf,int count)
   SCpnt->request.dev=dev;
   SCpnt->sense_buffer[0]=0;
   size=COMMAND_SIZE(get_fs_byte(buf));
+  size=COMMAND_SIZE(opcode);
+  if (opcode >= 0xc0 && device->header.twelve_byte) size = 12;
+  SCpnt->cmd_len = size;
   memcpy_fromfs(cmnd,buf,size);
   buf+=size;
   memcpy_fromfs(device->buff,buf,device->header.pack_len-size-sizeof(struct sg_header));
index 76c186ba6898d7784509d5ea3fa1cba795364e8b..ea4ae81932b7374114a87202b484295619d2f80e 100644 (file)
@@ -17,7 +17,8 @@ struct sg_header
   int reply_len;   /* maximum length <4096 of expected reply */
   int pack_id;     /* id number of packet */
   int result;      /* 0==ok, otherwise refer to errno codes */
-  int flags;                   /* for future use */
+  unsigned int twelve_byte:1; /* Force 12 byte command length for group 6 & 7 commands  */
+  unsigned int other_flags:31;                 /* for future use */
   unsigned char sense_buffer[16]; /* used only by reads */
   /* command follows then data for command */
  };
index f8cdab196b6124739e1e72b9443edd66dbfc51a2..82dfe55e0fa15c7cf0764618380cc043f5cb43ae 100644 (file)
@@ -325,9 +325,11 @@ static void sr_photocd(struct inode *inode)
       sec   = (unsigned long)buffer[16]/16*10 + (unsigned long)buffer[16]%16;
       frame = (unsigned long)buffer[17]/16*10 + (unsigned long)buffer[17]%16;
       sector = min*60*75 + sec*75 + frame;
-      sector-=CD_BLOCK_OFFSET;
       if (sector) {
-       printk("sr_photocd: multisession PhotoCD detected\n"); }}
+       sector -= CD_BLOCK_OFFSET;
+       printk("sr_photocd: multisession PhotoCD detected\n");
+      }
+    }
     scsi_free(buffer,512);
     SCpnt->request.dev = -1;
     break;
@@ -374,9 +376,11 @@ static void sr_photocd(struct inode *inode)
       sec   = (unsigned long)buffer[2]/16*10 + (unsigned long)buffer[2]%16;
       frame = (unsigned long)buffer[3]/16*10 + (unsigned long)buffer[3]%16;
       sector = min*60*75 + sec*75 + frame;
-      sector-=CD_BLOCK_OFFSET;
       if (sector) {
-        printk("sr_photocd: multisession PhotoCD detected: %lu\n",sector); }}
+        sector -= CD_BLOCK_OFFSET;
+        printk("sr_photocd: multisession PhotoCD detected: %lu\n",sector);
+      }
+    }
     scsi_free(buffer,512);
     SCpnt->request.dev = -1;
     break;
@@ -826,10 +830,11 @@ static void sr_init_done (Scsi_Cmnd * SCpnt)
 
 static void get_sectorsize(int i){
   unsigned char cmd[10];
-  unsigned char buffer[513];
+  unsigned char *buffer;
   int the_result, retries;
   Scsi_Cmnd * SCpnt;
   
+  buffer = (unsigned char *) scsi_malloc(512);
   SCpnt = allocate_device(NULL, scsi_CDs[i].device, 1);
 
   retries = 3;
@@ -838,6 +843,7 @@ static void get_sectorsize(int i){
     cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
     memset ((void *) &cmd[2], 0, 8);
     SCpnt->request.dev = 0xffff;  /* Mark as really busy */
+    SCpnt->cmd_len = 0;
     
     memset(buffer, 0, 8);
 
@@ -887,6 +893,7 @@ static void get_sectorsize(int i){
       scsi_CDs[i].capacity *= 4;
     scsi_CDs[i].needs_sector_size = 0;
   };
+  scsi_free(buffer, 512);
 }
 
 static void sr_init()
index 5022d9b8fcb5a65f65997b0eef62c9fda1d8b555..59a9643e1ab75cc3e865a4b55cefba87e273d7cb 100644 (file)
@@ -385,17 +385,4 @@ static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src
        return 0;
 }
 
-/*
- * Function : const char *t128_info(void)
- *
- * Purpose : provide further information about this driver.
- *
- * Returns : an empty string.
- */
-
-const char *t128_info (void) {
-    static const char string[]="";
-    return string;
-}
-
 #include "NCR5380.c"
index 59eebae62ebea161dee58feb0c187eea05b3a9ab..fcd4020563fa43a7b4f7b6ef5f85ec1c9a8975b3 100644 (file)
@@ -94,7 +94,6 @@
 int t128_abort(Scsi_Cmnd *);
 int t128_biosparam(Disk *, int, int*);
 int t128_detect(Scsi_Host_Template *);
-const char *t128_info(void);
 int t128_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int t128_reset(Scsi_Cmnd *);
 
@@ -118,8 +117,8 @@ int t128_reset(Scsi_Cmnd *);
 
 #ifdef HOSTS_C
 
-#define TRANTOR_T128 {NULL, "Trantor T128/T128F/T228", t128_detect, NULL,  \
-       t128_info,                                                      \
+#define TRANTOR_T128 {NULL, NULL, "Trantor T128/T128F/T228", t128_detect, NULL,  \
+       NULL,                                                   \
        NULL, t128_queue_command, t128_abort, t128_reset, NULL,         \
        t128_biosparam,                                                 \
        /* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL,                  \
index 61d336978166dd7f94f39fb1527f6469ad7a9c42..32cd24ab2c16fe164cf6177d1c6333a1fbbc2135 100644 (file)
@@ -416,10 +416,6 @@ int u14_34f_detect (Scsi_Host_Template * tpnt) {
    return j;
 }
 
-const char *u14_34f_info(void) {
-   return driver_name;
-}
-
 static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
    unsigned int k, data_len = 0;
    struct scatterlist * sgpnt;
@@ -506,7 +502,7 @@ int u14_34f_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
       cpp->data_len = SCpnt->request_bufflen;
       }
 
-   cpp->scsi_cdbs_len = COMMAND_SIZE(*(unsigned char *)SCpnt->cmnd);
+   cpp->scsi_cdbs_len = SCpnt->cmd_len;
    memcpy(cpp->scsi_cdbs, SCpnt->cmnd, cpp->scsi_cdbs_len);
 
    if (wait_on_busy(sh[j]->io_port)) {
index 9a0b6ebbb24319a30e168b963393f42c45f0b743..92d40121bb30d33290e20293c455a7bde4028689 100644 (file)
@@ -5,7 +5,6 @@
 #define _U14_34F_H
 
 int u14_34f_detect(Scsi_Host_Template *);
-const char *u14_34f_info(void);
 int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int u14_34f_abort(Scsi_Cmnd *);
 int u14_34f_reset(Scsi_Cmnd *);
@@ -14,12 +13,13 @@ int u14_34f_biosparam(Disk *, int, int *);
 #define U14_34F_VERSION "1.10.01"
 
 #define ULTRASTOR_14_34F {                                            \
+                NULL,                                                 \
                 NULL,                                                 \
                 "UltraStor 14F/34F rev. " U14_34F_VERSION " by "      \
                 "Dario_Ballabio@milano.europe.dg.com.",\
                 u14_34f_detect,                                       \
                 NULL,                                                 \
-                u14_34f_info,                                         \
+                NULL,                                                \
                 NULL,                                                 \
                 u14_34f_queuecommand,                                 \
                 u14_34f_abort,                                        \
index d6d6f898f53abb92a4e3148aafab9893ca380e46..9d7dca68c821bae34b3dc09615ce2d99b44d1d25 100644 (file)
@@ -620,7 +620,7 @@ int ultrastor_detect(Scsi_Host_Template * tpnt)
   return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt);
 }
 
-const char *ultrastor_info(void)
+const char *ultrastor_info(struct Scsi_Host * shpnt)
 {
     static char buf[64];
 
@@ -714,7 +714,7 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
     my_mscp->command_link = 0;         /*???*/
     my_mscp->scsi_command_link_id = 0; /*???*/
     my_mscp->length_of_sense_byte = sizeof SCpnt->sense_buffer;
-    my_mscp->length_of_scsi_cdbs = COMMAND_SIZE(*(unsigned char *)SCpnt->cmnd);
+    my_mscp->length_of_scsi_cdbs = SCpnt->cmd_len;
     memcpy(my_mscp->scsi_cdbs, SCpnt->cmnd, my_mscp->length_of_scsi_cdbs);
     my_mscp->adapter_status = 0;
     my_mscp->target_status = 0;
index 6df818fb19e4395e0c27210a92a8f3b748f3a281..b80a66924620baa771b7dfe08e33af5217cf1221 100644 (file)
@@ -14,7 +14,7 @@
 #define _ULTRASTOR_H
 
 int ultrastor_detect(Scsi_Host_Template *);
-const char *ultrastor_info(void);
+const char *ultrastor_info(struct Scsi_Host * shpnt);
 int ultrastor_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int ultrastor_abort(Scsi_Cmnd *);
 int ultrastor_reset(Scsi_Cmnd *);
@@ -29,8 +29,8 @@ int ultrastor_biosparam(Disk *, int, int *);
 #define ULTRASTOR_24F_PORT 0xC80
 
 
-#define ULTRASTOR_14F { NULL, /* Ptr for modules*/     \
-                         "UltraStor 14F/24F/34F",      \
+#define ULTRASTOR_14F { NULL, NULL, /* Ptr for modules*/ \
+                         NULL,                         \
                          ultrastor_detect,             \
                          NULL, /* Release */           \
                          ultrastor_info,               \
index b79290a24c9f68ff3b9bce544365032f5bbd6a91..c3eed4294d8b28e5f299e6a9b28f9308552b6658 100644 (file)
@@ -900,7 +900,7 @@ int wd7000_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
     register short cdblen;
     Adapter *host = (Adapter *) SCpnt->host->hostdata;
 
-    cdblen = COMMAND_SIZE(cdb[0]);
+    cdblen = SCpnt->cmd_len;
     idlun = ((SCpnt->target << 5) & 0xe0) | (SCpnt->lun & 7);
     SCpnt->scsi_done = done;
     SCpnt->SCp.phase = 1;
@@ -1206,18 +1206,6 @@ int wd7000_reset(Scsi_Cmnd * SCpnt)
 }
 
 
-/*
- *  The info routine in the WD7000 structure isn't per-adapter, so it can't
- *  really return any useful information about an adapter.  Because of this,
- *  I'm no longer using it to return rev. level.
- */
-const char *wd7000_info(void)
-{
-    static char info[] = "Western Digital WD-7000";
-    return info;
-}
-
-
 /*
  *  This was borrowed directly from aha1542.c, but my disks are organized
  *  this way, so I think it will work OK.  Someone who is ambitious can
index 8c727d5685561046c0459c0f3eb49c6f60f9f22d..d19cabf2144aaa6e774f8ed7cac68ec6768a33aa 100644 (file)
@@ -16,7 +16,6 @@ int wd7000_detect(Scsi_Host_Template *);
 int wd7000_command(Scsi_Cmnd *);
 int wd7000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int wd7000_abort(Scsi_Cmnd *);
-const char *wd7000_info(void);
 int wd7000_reset(Scsi_Cmnd *);
 int wd7000_biosparam(Disk *, int, int*);
 
@@ -38,11 +37,11 @@ int wd7000_biosparam(Disk *, int, int*);
 #define WD7000_Q    16
 #define WD7000_SG   16
 
-#define WD7000 { NULL, \
+#define WD7000 { NULL, NULL, \
        "Western Digital WD-7000",      \
        wd7000_detect,                  \
        NULL,                           \
-       wd7000_info,                    \
+       NULL,                           \
        wd7000_command,                 \
        wd7000_queuecommand,            \
        wd7000_abort,                   \
index 2687533644bf94f217aa7d08f26eef58f1685c3e..d1de73ad02ad379f8d265421aac13c198c4c26b9 100644 (file)
@@ -186,7 +186,7 @@ int locks_deadlocked(int my_pid,int blocked_pid)
                                if (ret_val) return -EDEADLOCK;
                        }
                        dlock_wait = dlock_wait->next;
-               } while (dlock_wait != fl->fl_wait);
+               } while (dlock_wait != NULL);
        }
        return 0;
 }
index 65628fd976693a49db3e01c9051f234d55f6c50a..6fd7bccbe6dca8b2fd5d0a0aa18f501529559bde 100644 (file)
@@ -12,7 +12,7 @@
  *                      make sure SET_PROCTITLE works. Also removed
  *                      bad '!' which forced address recalculation for
  *                      EVERY character on the current page.
- *                      <middelin@calvin.iaf.nl>
+ *                      <middelin@polyware.iaf.nl>
  */
 
 #include <linux/types.h>
index 176d4efa20129710fa9751078fdbc05cb9f9fe04..e4d6a947082944ae0ddfb48abb5d417f419810a0 100644 (file)
@@ -25,9 +25,10 @@ int umsdos_readdir_kmem(
        int count)
 {
        int ret;
+       int old_fs = get_fs();
        set_fs (KERNEL_DS);
        ret = msdos_readdir(inode,filp,dirent,count);
-       set_fs (USER_DS);
+       set_fs (old_fs);
        return ret;
 }
 /*
@@ -39,10 +40,11 @@ int umsdos_file_read_kmem(
        char *buf,
        int count)
 {
-       int ret;        
+       int ret;
+       int old_fs = get_fs();  
        set_fs (KERNEL_DS);
        ret = msdos_file_read(inode,filp,buf,count);
-       set_fs (USER_DS);
+       set_fs (old_fs);
        return ret;
 }
 /*
@@ -55,9 +57,10 @@ int umsdos_file_write_kmem(
        int count)
 {
        int ret;
+       int old_fs = get_fs();
        set_fs (KERNEL_DS);
        ret = msdos_file_write(inode,filp,buf,count);
-       set_fs (USER_DS);
+       set_fs (old_fs);
        return ret;
 }
 
@@ -208,7 +211,7 @@ int umsdos_writeentry (
        return ret;
 }
 
-#define CHUNK_SIZE (16*UMSDOS_REC_SIZE)
+#define CHUNK_SIZE (8*UMSDOS_REC_SIZE)
 struct find_buffer{
        char buffer[CHUNK_SIZE];
        int pos;        /* read offset in buffer */
index 8aa6c70d935538ca60b34c63cde54a0fee531737..63540f15942f0d33014eb37c40eb74869244d08e 100644 (file)
@@ -69,6 +69,9 @@
 
 #define MAX_DMA_CHANNELS       8
 
+/* The maximum address that we can perform a DMA transfer to on this platform */
+#define MAX_DMA_ADDRESS      0xffffff
+
 /* 8237 DMA controllers */
 #define IO_DMA1_BASE   0x00    /* 8 bit slave DMA, channels 0..3 */
 #define IO_DMA2_BASE   0xC0    /* 16 bit master DMA, ch 4(=slave input)..7 */
index d710d81793828d5937688f8d6de1467c6b57a88d..d8511a7ce9066d79248bf245da312eb3f89ecf7a 100644 (file)
 #ifndef _LINUX_INET_H
 #define _LINUX_INET_H
 
-#ifdef __i386__
+#if defined(__i386__)
 #define NET16(x)       ((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00))
-#endif
-#ifdef __mc680x0__
+#elif defined(__mc68000__)
 #define NET16(x)       (x)
+#elif defined(__alpha__)
+#define NET16(x)       ((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00))
+#else
+#error change this to match your machine
 #endif
 
 #ifdef __KERNEL__
index 1a2512b8eaef3992ed71b06fee7b39f7e8ab3a54..e5923f6ed5a2133abf9bea6efc1f7a3ef348a3f2 100644 (file)
 /*
  * Call check_region() before probing for your hardware.
  * Once you have found you hardware, register it with snarf_region().
+ * If you unload the driver, use release_region to free ports.
  */
 extern void reserve_setup(char *str, int *ints);
 extern int check_region(unsigned int from, unsigned int extent);
 extern void snarf_region(unsigned int from, unsigned int extent);
+extern void release_region(unsigned int from, unsigned int extent);
 
 
 #define HAVE_AUTOIRQ
index f99d1fa7c48d5e8dfc2c36e2b65c30a30b3e675e..1d3789638f12f3941add42fceb429dc764c7308e 100644 (file)
@@ -35,7 +35,7 @@ struct timestamp {
 #if defined(__i386__)  
                u8      flags:4,
                        overflow:4;
-#elif defined(__mc680x0__)
+#elif defined(__mc68000__)
                u8      overflow:4,
                        flags:4;
 #elif defined(__alpha__)
@@ -76,7 +76,7 @@ struct iphdr {
 #if defined(__i386__)
        u8      ihl:4,
                version:4;
-#elif defined (__mc680x0__)
+#elif defined (__mc68000__)
        u8      version:4,
                ihl:4;
 #elif defined (__alpha__)
index c2b86997dce04bb2233e47c6033eb25d12d1fc58..e2128f03305961ed559bec8851462548a76a153a 100644 (file)
@@ -234,6 +234,11 @@ extern unsigned short * mem_map;
 #define GFP_NOBUFFER   0x04
 #define GFP_NFS                0x05
 
+/* Flag - indicates that the buffer will be suitable for DMA.  Ignored on some
+   platforms, used as appropriate on others */
+
+#define GFP_DMA                0x80
+
 /*
  * vm_ops not present page codes for shared memory.
  *
index 7a9d0576d6f5c0b6113aede1787ef607a1139b6d..4acc22cae1da90f7e2c72e90665c971f507d90cb 100644 (file)
@@ -37,7 +37,7 @@ struct tcphdr {
                ack:1,
                urg:1,
                res2:2;
-#elif defined(__mc680x0__)
+#elif defined(__mc68000__)
        u16     res2:2,
                urg:1,
                ack:1,
index 5c83edcef9f7267a775f1c8229d9d430c86c47f4..ceaabb60ff9b8dc801e16a833a014e4c6de51caa 100644 (file)
@@ -92,6 +92,7 @@ extern void t128_setup(char *str, int *ints);
 extern void pas16_setup(char *str, int *ints);
 extern void generic_NCR5380_setup(char *str, int *intr);
 extern void aha152x_setup(char *str, int *ints);
+extern void aha1542_setup(char *str, int *ints);
 extern void aha274x_setup(char *str, int *ints);
 extern void scsi_luns_setup(char *str, int *ints);
 extern void sound_setup(char *str, int *ints);
@@ -211,6 +212,9 @@ struct {
 #ifdef CONFIG_SCSI_AHA152X
         { "aha152x=", aha152x_setup},
 #endif
+#ifdef CONFIG_SCSI_AHA1542
+        { "aha1542=", aha1542_setup},
+#endif
 #ifdef CONFIG_SCSI_AHA274X
         { "aha274x=", aha274x_setup},
 #endif
index 883e58c9c6405b73413751ccc52092e76f7a668e..c61690e3c71b7b3341456ed17462fe55b3e939fd 100644 (file)
@@ -165,6 +165,16 @@ void snarf_region(unsigned int from, unsigned int num)
        return;
 }
 
+void release_region(unsigned int from, unsigned int num)
+{
+       if (from > IO_BITMAP_SIZE*32)
+               return;
+       if (from + num > IO_BITMAP_SIZE*32)
+               num = IO_BITMAP_SIZE*32 - from;
+       set_bitmap(ioport_registrar, from, num, 0);
+       return;
+}
+
 int check_region(unsigned int from, unsigned int num)
 {
        if (from > IO_BITMAP_SIZE*32)
index 0d0b18ba582c9dd51bc387899965c29c4c8917eb..dabb26d0b7044a1e622f6c47aa227419bfe3f271 100644 (file)
@@ -1 +1 @@
-3c509.o de600.o de620.o 3c501.o plip.o 8390.o
+3c509.o de600.o de620.o 3c501.o eexpress.o plip.o 8390.o
index 78f3e7317a0da81ef31392eb52a0b264c02f49fe..c143924bd04beb19721f4170767284df0004ee48 100644 (file)
@@ -17,7 +17,7 @@
  * Fixes:
  *             Alan Cox        :       UDP sockets show the rxqueue/txqueue
  *                                     using hint flag for the netinfo.
- *     Pauline Middelink       :       Pidentd support
+ *     Pauline Middelink       :       identd support
  *             Alan Cox        :       Make /proc safer.
  *     Erik Schoenfelder       :       /proc/net/snmp
  *             Alan Cox        :       Handle dead sockets properly.
index 8dd6a36e5a3388b9c5e8af98dccfd838d2d2ea32..fd5f123bd1de4391113aeeda4eef0ba1482c724c 100644 (file)
@@ -46,7 +46,7 @@
  *             Alan Cox        :       Added RCVBUF,SNDBUF size setting. It suddenly occurred to me how easy it was so...
  *             Rick Sladkey    :       Relaxed UDP rules for matching packets.
  *             C.E.Hawkins     :       IFF_PROMISC/SIOCGHWADDR support
- *     Pauline Middelink       :       Pidentd support
+ *     Pauline Middelink       :       identd support
  *             Alan Cox        :       Fixed connect() taking signals I think.
  *             Alan Cox        :       SO_LINGER supported
  *             Alan Cox        :       Error reporting fixes