]> git.neil.brown.name Git - history.git/commitdiff
Import 1.2.6 1.2.6
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:58 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:58 +0000 (15:09 -0500)
28 files changed:
CREDITS
Makefile
arch/i386/config.in
drivers/char/ChangeLog
drivers/char/serial.c
drivers/net/lance.c
drivers/net/ne.c
drivers/net/plip.c
drivers/scsi/53c7,8xx.c
drivers/scsi/53c7,8xx.h
drivers/scsi/53c7,8xx.scr
drivers/scsi/53c8xx_d.h
drivers/scsi/53c8xx_u.h
drivers/scsi/ChangeLog
drivers/scsi/Makefile
drivers/scsi/buslogic.c
drivers/scsi/eata_dma.c
fs/nfs/file.c
fs/select.c
include/asm-alpha/byteorder.h
include/asm-i386/byteorder.h
include/asm-mips/byteorder.h
include/asm-sparc/byteorder.h
include/linux/bios32.h
include/linux/ip.h
include/linux/tcp.h
kernel/ksyms.c
mm/swap.c

diff --git a/CREDITS b/CREDITS
index 7839c253c5c28a03b2c224aec273dd132737e327..46b3aa128851c6bf5b00938ba162e96efc9d71b2 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -683,6 +683,10 @@ E: ken@halcyon.com
 D: CDROM driver "sonycd535" (Sony CDU-535/531)
 S: 
 
+N: Frederic Potter 
+E: Frederic.Potter@masi.ibp.fr 
+D: Some PCI kernel support
+
 N: Stefan Probst
 E: snprobst@immd4.informatik.uni-erlangen.de
 D: The Linux Support Team Erlangen
index f3f107e4cfa91a2f5f0641ab2736c3a5af80a212..7e41d2985c3e3db18278111cc4ab1f53179b80b0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 2
-SUBLEVEL = 5
+SUBLEVEL = 6
 
 ARCH = i386
 
index 5b902b832a52ce6e97f9e2b030bd8f46c57b737e..e619e4835d1f1236d1ad10bf7a5cb75993ae9e0b 100644 (file)
@@ -74,6 +74,10 @@ bool 'Scsi tape support' CONFIG_CHR_DEV_ST n
 bool 'Scsi CDROM support' CONFIG_BLK_DEV_SR n
 bool 'Scsi generic support' CONFIG_CHR_DEV_SG n
 
+comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
+
+bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN n
+
 comment 'SCSI low-level drivers'
 
 bool 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n
index 7dc76adc341f27034c4f1ee2face2d140f90addc..a6a54c15421e580e96124eec73ef1f2bfe11cfc9 100644 (file)
@@ -4,7 +4,7 @@ Wed Apr 12 08:06:16 1995  Theodore Y. Ts'o  <tytso@localhost>
                rs_init):  Hangups are now scheduled via a separate tqueue
                structure in the async_struct structure, tqueue_hangup.
                This task is pushed on to the tq_schedule queue, so that
-               it is processed syncronously by the scheduler.
+               it is processed synchronously by the scheduler.
 
 Sat Feb 18 12:13:51 1995  Theodore Y. Ts'o  (tytso@rt-11)
 
index e70601bd83e99e8f41ee3c35ff90e9f365f9e38e..d424d4f6ace3cb4a37fbd5940146048d2582671b 100644 (file)
@@ -733,7 +733,7 @@ static void do_softint(void *private_)
 
 /*
  * This routine is called from the scheduler tqueue when the interrupt
- * routine has signalled that a hangup has occured.  The path of
+ * routine has signalled that a hangup has occurred.  The path of
  * hangup processing is:
  *
  *     serial interrupt routine -> (scheduler tqueue) ->
index 45bf92c8056e0aabdee696426a9ea81bc6c22d60..88c227e7ec81af379eb6141c54838e5162492ac9 100644 (file)
@@ -15,7 +15,7 @@
           Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
 */
 
-static char *version = "lance.c:v1.07 1/18/95 becker@cesdis.gsfc.nasa.gov\n";
+static char *version = "lance.c:v1.08 4/10/95 dplatt@3do.com\n";
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -203,12 +203,18 @@ struct lance_private {
        int dirty_rx, dirty_tx;         /* The ring entries to be free()ed. */
        int dma;
        struct enet_statistics stats;
-       char chip_version;                      /* See lance_chip_type. */
+       unsigned char chip_version;                     /* See lance_chip_type. */
        char tx_full;
        char lock;
        int pad0, pad1;                         /* Used for 8-byte alignment */
 };
 
+#define LANCE_MUST_PAD          0x00000001
+#define LANCE_ENABLE_AUTOSELECT 0x00000002
+#define LANCE_MUST_REINIT_RING  0x00000004
+#define LANCE_MUST_UNRESET      0x00000008
+#define LANCE_HAS_MISSED_FRAME  0x00000010
+
 /* A mapping from the chip ID number to the part number and features.
    These are from the datasheets -- in real life the '970 version
    reportedly has the same ID as the '965. */
@@ -217,14 +223,25 @@ static struct lance_chip_type {
        char *name;
        int flags;
 } chip_table[] = {
-       {0x0000, "LANCE 7990", 0},                      /* Ancient lance chip.  */
-       {0x0003, "PCnet/ISA 79C960", 0},        /* 79C960 PCnet/ISA.  */
-       {0x2260, "PCnet/ISA+ 79C961", 0},       /* 79C961 PCnet/ISA+, Plug-n-Play.  */
-       {0x2420, "PCnet/PCI 79C970", 0},        /* 79C970 or 79C974 PCnet-SCSI, PCI. */
+       {0x0000, "LANCE 7990",                          /* Ancient lance chip.  */
+               LANCE_MUST_PAD + LANCE_MUST_UNRESET},
+       {0x0003, "PCnet/ISA 79C960",            /* 79C960 PCnet/ISA.  */
+               LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
+                       LANCE_HAS_MISSED_FRAME},
+       {0x2260, "PCnet/ISA+ 79C961",           /* 79C961 PCnet/ISA+, Plug-n-Play.  */
+               LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
+                       LANCE_HAS_MISSED_FRAME},
+       {0x2420, "PCnet/PCI 79C970",            /* 79C970 or 79C974 PCnet-SCSI, PCI. */
+               LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
+                       LANCE_HAS_MISSED_FRAME},
        /* Bug: the PCnet/PCI actually uses the PCnet/VLB ID number, so just call
                it the PCnet32. */
-       {0x2430, "PCnet32", 0},                         /* 79C965 PCnet for VL bus. */
-       {0x0,    "PCnet (unknown)", 0},
+       {0x2430, "PCnet32",                                     /* 79C965 PCnet for VL bus. */
+               LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
+                       LANCE_HAS_MISSED_FRAME},
+       {0x0,    "PCnet (unknown)",
+               LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
+                       LANCE_HAS_MISSED_FRAME},
 };
 
 enum {OLD_LANCE = 0, PCNET_ISA=1, PCNET_ISAP=2, PCNET_PCI=3, PCNET_VLB=4, LANCE_UNKNOWN=5};
@@ -256,8 +273,6 @@ unsigned long lance_init(unsigned long mem_start, unsigned long mem_end)
        int *port;
 
 #if defined(CONFIG_PCI)
-#define AMD_VENDOR_ID 0x1022
-#define AMD_DEVICE_ID 0x2000
     if (pcibios_present()) {
            int pci_index;
                printk("lance.c: PCI bios is present, checking for devices...\n");
@@ -266,7 +281,8 @@ unsigned long lance_init(unsigned long mem_start, unsigned long mem_end)
                        unsigned long pci_ioaddr;
                        unsigned short pci_command;
 
-                       if (pcibios_find_device (AMD_VENDOR_ID, AMD_DEVICE_ID, pci_index,
+                       if (pcibios_find_device (PCI_VENDOR_ID_AMD,
+                                                                        PCI_DEVICE_ID_AMD_LANCE, pci_index,
                                                                         &pci_bus, &pci_device_fn) != 0)
                                break;
                        pcibios_read_config_byte(pci_bus, pci_device_fn,
@@ -522,7 +538,7 @@ unsigned long lance_probe1(int ioaddr, unsigned long mem_start)
                }
        }
 
-       if (lp->chip_version !=  OLD_LANCE) {
+       if (chip_table[lp->chip_version].flags & LANCE_ENABLE_AUTOSELECT) {
                /* Turn on auto-select of media (10baseT or BNC) so that the user
                   can watch the LEDs even if the board isn't opened. */
                outw(0x0002, ioaddr+LANCE_ADDR);
@@ -570,10 +586,10 @@ lance_open(struct device *dev)
        }
 
        /* Un-Reset the LANCE, needed only for the NE2100. */
-       if (lp->chip_version == OLD_LANCE)
+       if (chip_table[lp->chip_version].flags & LANCE_MUST_UNRESET)
                outw(0, ioaddr+LANCE_RESET);
 
-       if (lp->chip_version != OLD_LANCE) {
+       if (chip_table[lp->chip_version].flags & LANCE_ENABLE_AUTOSELECT) {
                /* This is 79C960-specific: Turn on auto-select of media (AUI, BNC). */
                outw(0x0002, ioaddr+LANCE_ADDR);
                outw(0x0002, ioaddr+LANCE_BUS_IF);
@@ -617,6 +633,33 @@ lance_open(struct device *dev)
        return 0;                                       /* Always succeed */
 }
 
+/* The LANCE has been halted for one reason or another (busmaster memory
+   arbitration error, Tx FIFO underflow, driver stopped it to reconfigure,
+   etc.).  Modern LANCE variants always reload their ring-buffer
+   configuration when restarted, so we must reinitialize our ring
+   context before restarting.  As part of this reinitialization,
+   find all packets still on the Tx ring and pretend that they had been
+   sent (in effect, drop the packets on the floor) - the higher-level
+   protocols will time out and retransmit.  It'd be better to shuffle
+   these skbs to a temp list and then actually re-Tx them after
+   restarting the chip, but I'm too lazy to do so right now.  dplatt@3do.com
+*/
+
+static void 
+lance_purge_tx_ring(struct device *dev)
+{
+       struct lance_private *lp = (struct lance_private *)dev->priv;
+       int i;
+
+       for (i = 0; i < TX_RING_SIZE; i++) {
+               if (lp->tx_skbuff[i]) {
+                       dev_kfree_skb(lp->tx_skbuff[i],FREE_WRITE);
+                       lp->tx_skbuff[i] = NULL;
+               }
+       }
+}
+
+
 /* Initialize the LANCE Rx and Tx rings. */
 static void
 lance_init_ring(struct device *dev)
@@ -647,12 +690,27 @@ lance_init_ring(struct device *dev)
        lp->init_block.tx_ring = (int)lp->tx_ring | TX_RING_LEN_BITS;
 }
 
+static void
+lance_restart(struct device *dev, unsigned int csr0_bits, int must_reinit)
+{
+       struct lance_private *lp = (struct lance_private *)dev->priv;
+
+       if (must_reinit ||
+               (chip_table[lp->chip_version].flags & LANCE_MUST_REINIT_RING)) {
+               lance_purge_tx_ring(dev);
+               lance_init_ring(dev);
+       }
+       outw(0x0000,    dev->base_addr + LANCE_ADDR);
+       outw(csr0_bits, dev->base_addr + LANCE_DATA);
+}
+
 static int
 lance_start_xmit(struct sk_buff *skb, struct device *dev)
 {
        struct lance_private *lp = (struct lance_private *)dev->priv;
        int ioaddr = dev->base_addr;
        int entry;
+       unsigned long flags;
 
        /* Transmitter timeout, serious problems. */
        if (dev->tbusy) {
@@ -681,8 +739,7 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev)
                        printk("\n");
                }
 #endif
-               lance_init_ring(dev);
-               outw(0x0043, ioaddr+LANCE_DATA);
+               lance_restart(dev, 0x0043, 1);
 
                dev->tbusy=0;
                dev->trans_start = jiffies;
@@ -728,7 +785,7 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev)
           with the "ownership" bits last. */
 
        /* The old LANCE chips doesn't automatically pad buffers to min. size. */
-       if (lp->chip_version == OLD_LANCE) {
+       if (chip_table[lp->chip_version].flags & LANCE_MUST_PAD) {
                lp->tx_ring[entry].length =
                        -(ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN);
        } else
@@ -758,13 +815,14 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev)
 
        dev->trans_start = jiffies;
 
+       save_flags(flags);
        cli();
        lp->lock = 0;
        if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base == 0)
                dev->tbusy=0;
        else
                lp->tx_full = 1;
-       sti();
+       restore_flags(flags);
 
        return 0;
 }
@@ -776,6 +834,7 @@ lance_interrupt(int irq, struct pt_regs * regs)
        struct device *dev = (struct device *)(irq2dev_map[irq]);
        struct lance_private *lp;
        int csr0, ioaddr, boguscnt=10;
+       int must_restart;
 
        if (dev == NULL) {
                printk ("lance_interrupt(): irq %d for unknown device.\n", irq);
@@ -795,6 +854,8 @@ lance_interrupt(int irq, struct pt_regs * regs)
                /* Acknowledge all of the current interrupt sources ASAP. */
                outw(csr0 & ~0x004f, dev->base_addr + LANCE_DATA);
 
+               must_restart = 0;
+
                if (lance_debug > 5)
                        printk("%s: interrupt  csr0=%#2.2x new csr=%#2.2x.\n",
                                   dev->name, csr0, inw(dev->base_addr + LANCE_DATA));
@@ -828,7 +889,7 @@ lance_interrupt(int irq, struct pt_regs * regs)
                                                printk("%s: Tx FIFO error! Status %4.4x.\n",
                                                           dev->name, csr0);
                                                /* Restart the chip. */
-                                               outw(0x0002, dev->base_addr + LANCE_DATA);
+                                               must_restart = 1;
                                        }
                                } else {
                                        if (status & 0x18000000)
@@ -871,7 +932,14 @@ lance_interrupt(int irq, struct pt_regs * regs)
                        printk("%s: Bus master arbitration failure, status %4.4x.\n",
                                   dev->name, csr0);
                        /* Restart the chip. */
-                       outw(0x0002, dev->base_addr + LANCE_DATA);
+                       must_restart = 1;
+               }
+
+               if (must_restart) {
+                       /* stop the chip to clear the error condition, then restart */
+                       outw(0x0000, dev->base_addr + LANCE_ADDR);
+                       outw(0x0004, dev->base_addr + LANCE_DATA);
+                       lance_restart(dev, 0x0002, 0);
                }
        }
 
@@ -961,7 +1029,7 @@ lance_close(struct device *dev)
        dev->start = 0;
        dev->tbusy = 1;
 
-       if (lp->chip_version != OLD_LANCE) {
+       if (chip_table[lp->chip_version].flags & LANCE_HAS_MISSED_FRAME) {
                outw(112, ioaddr+LANCE_ADDR);
                lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
        }
@@ -991,14 +1059,16 @@ lance_get_stats(struct device *dev)
        struct lance_private *lp = (struct lance_private *)dev->priv;
        short ioaddr = dev->base_addr;
        short saved_addr;
+       unsigned long flags;
 
-       if (lp->chip_version != OLD_LANCE) {
+       if (chip_table[lp->chip_version].flags & LANCE_HAS_MISSED_FRAME) {
+               save_flags(flags);
                cli();
                saved_addr = inw(ioaddr+LANCE_ADDR);
                outw(112, ioaddr+LANCE_ADDR);
                lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
                outw(saved_addr, ioaddr+LANCE_ADDR);
-               sti();
+               restore_flags(flags);
        }
 
        return &lp->stats;
@@ -1015,11 +1085,9 @@ set_multicast_list(struct device *dev, int num_addrs, void *addrs)
 {
        short ioaddr = dev->base_addr;
 
-       /* We take the simple way out and always enable promiscuous mode. */
        outw(0, ioaddr+LANCE_ADDR);
        outw(0x0004, ioaddr+LANCE_DATA); /* Temporarily stop the lance.  */
 
-       outw(15, ioaddr+LANCE_ADDR);
        if (num_addrs >= 0) {
                short multicast_table[4];
                int i;
@@ -1029,15 +1097,17 @@ set_multicast_list(struct device *dev, int num_addrs, void *addrs)
                        outw(8 + i, ioaddr+LANCE_ADDR);
                        outw(multicast_table[i], ioaddr+LANCE_DATA);
                }
+               outw(15, ioaddr+LANCE_ADDR);
                outw(0x0000, ioaddr+LANCE_DATA); /* Unset promiscuous mode */
        } else {
                /* Log any net taps. */
                printk("%s: Promiscuous mode enabled.\n", dev->name);
+               outw(15, ioaddr+LANCE_ADDR);
                outw(0x8000, ioaddr+LANCE_DATA); /* Set promiscuous mode */
        }
 
-       outw(0, ioaddr+LANCE_ADDR);
-       outw(0x0142, ioaddr+LANCE_DATA); /* Resume normal operation. */
+       lance_restart(dev, 0x0142, 0); /*  Resume normal operation */
+
 }
 
 \f
index 63cc67628d5689dbb9804cff9b8bb51a7b57ae69..fe50f8a70a8a903f09baeb619083b80bcd167f3f 100644 (file)
@@ -376,7 +376,6 @@ ne_block_output(struct device *dev, int count,
 {
     int retries = 0;
     int nic_base = NE_BASE;
-    unsigned long flags;
 
     /* Round the count up for word writes.  Do we need to do this?
        What effect will an odd byte count have on the 8390?
@@ -412,19 +411,7 @@ ne_block_output(struct device *dev, int count,
     SLOW_DOWN_IO;
 #endif  /* rw_bugfix */
 
-   /*
-       Now the normal output. I believe that if we don't lock this, a
-       race condition will munge the remote byte count values, and then
-       the ne2k will hang the machine by holding I/O CH RDY because it
-       expects more data. Hopefully fixes the lockups. -- Paul Gortmaker.
-
-       Use save_flags/cli/restore_flags rather than cli/sti to avoid risk
-       of accidentally enabling interrupts which were disabled when we
-       were entered.   Dave Platt <dplatt@3do.com>
-    */
-
-    save_flags(flags);
-    cli();
+   /* Now the normal output. */
     outb_p(count & 0xff, nic_base + EN0_RCNTLO);
     outb_p(count >> 8,   nic_base + EN0_RCNTHI);
     outb_p(0x00, nic_base + EN0_RSARLO);
@@ -436,7 +423,6 @@ ne_block_output(struct device *dev, int count,
     } else {
        outsb(NE_BASE + NE_DATAPORT, buf, count);
     }
-    restore_flags(flags);
 
 #ifdef CONFIG_NE_SANITY
     /* This was for the ALPHA version only, but enough people have
index 46bd56a7631d29ff5b3caa1f9dce426760375e6e..bf2becd71e2a641eda28f21526b0666d010b81b3 100644 (file)
@@ -98,6 +98,7 @@ static char *version = "NET3 PLIP version 2.0 gniibe@mri.co.jp\n";
 #include <linux/ioport.h>
 #include <asm/bitops.h>
 #include <asm/irq.h>
+#include <asm/byteorder.h>
 
 /* Use 0 for production, 1 for verification, >2 for debug */
 #ifndef NET_DEBUG
@@ -165,26 +166,14 @@ struct plip_local {
        enum plip_nibble_state nibble;
        union {
                struct {
-#if defined(__i386__)
+#if defined(LITTLE_ENDIAN)
                        unsigned char lsb;
                        unsigned char msb;
-#elif defined(__mc68000__)
+#elif defined(BIG_ENDIAN)
                        unsigned char msb;
                        unsigned char lsb;
-#elif defined(__sparc__)
-                       unsigned char msb;
-                       unsigned char lsb;
-#elif defined(__MIPSEL__)
-                       unsigned char lsb;
-                       unsigned char msb;
-#elif defined(__MIPSEB__)
-                       unsigned char msb;
-                       unsigned char lsb;
-#elif defined(__alpha__)
-                       unsigned char lsb;
-                       unsigned char msb;
 #else
-#error "Adjust this structure to match your CPU"
+#error "Please fix the endianness defines in <asm/byteorder.h>"
 #endif                                         
                } b;
                unsigned short h;
index 8698173d6ce3743958d2562f9feb9dd6b5cd0eeb..a03e1019d84f286dc265b6de48fb323e700722f9 100644 (file)
@@ -5,8 +5,8 @@
  *       weed out brain damaged main boards.
  */
 
-#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1)
 
+#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1)
 /*
  * Define SCSI_MALLOC to use scsi_malloc instead of kmalloc.  Other than
  * preventing deadlock, I'm not sure why we'd want to do this.
@@ -20,7 +20,7 @@
  *     Hannover, Germany
  *     hm@ix.de
  *
- * Copyright 1993, 1994 Drew Eckhardt
+ * Copyright 1993, 1994, 1995 Drew Eckhardt
  *      Visionary Computing 
  *      (Unix and Linux consulting and custom programming)
  *      drew@Colorado.EDU
@@ -28,8 +28,6 @@
  *
  * TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
  * 
- * PRE-ALPHA
- *
  * For more information, please consult 
  *
  *
  *
  */
 
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
+#include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <linux/delay.h>
 static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result);
 static int NCR53c8xx_run_tests (struct Scsi_Host *host);
 static int NCR53c8xx_script_len;
+static int NCR53c8xx_dsa_len;
 static void NCR53c7x0_intr(int irq, struct pt_regs * regs);
+static int halt (struct Scsi_Host *host);
 static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd 
     *cmd);
 static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
@@ -190,40 +195,11 @@ static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
     NCR53c7x0_cmd *cmd);
 static void NCR53c8x0_soft_reset (struct Scsi_Host *host);
 
+static int perm_options = PERM_OPTIONS;
+
 static struct Scsi_Host *first_host = NULL;    /* Head of list of NCR boards */
 static Scsi_Host_Template *the_template = NULL;        
 
-/* Allocate storage space for constant messages, etc. */
-
-static long NCR53c7xx_zero = 0;                        
-static long NCR53c7xx_sink;
-static char NCR53c7xx_msg_reject = MESSAGE_REJECT;
-static char NCR53c7xx_msg_abort = ABORT;
-static char NCR53c7xx_msg_nop = NOP;
-
-/* Buffer for commands run before *malloc() works */
-/* 
- * XXX - if need be, replace this with normal wait.
- */
-static int scan_scsis_buf_busy = 0;
-static char scan_scsis_buf[512];
-
-
-/*
- * Spl-levels are evil. We shouldn't emulate braindamage.
- *             Linus
- */
-static int splx (int new_level)
-{
-    register int old_level, tmp;
-    save_flags(tmp);
-    old_level = (tmp & 0x200) ? 7 : 0;
-    if (new_level)
-       sti();
-    else 
-       cli();
-    return old_level;
-}
 
 /*
  * TODO : 
@@ -285,8 +261,7 @@ static int splx (int new_level)
  *
  * For the very similar chips, we should probably hack the fixup code
  * and interrupt code so that it works everywhere, but I suspect the 
- * NCR53c700 is going
- * to need it's own fixup routine.
+ * NCR53c700 is going to need it's own fixup routine.
  */
 
 /*
@@ -420,7 +395,8 @@ setup_wrapper(825)
  *     field of the hostdata structure MUST have been set.
  */
 
-static int NCR53c7x0_init (struct Scsi_Host *host) {
+static int 
+NCR53c7x0_init (struct Scsi_Host *host) {
     NCR53c7x0_local_declare();
     /* unsigned char tmp; */
     int i, j, ccf;
@@ -450,13 +426,19 @@ static int NCR53c7x0_init (struct Scsi_Host *host) {
        return -1;
     }
 
+    /* Assign constants accessed by NCR */
+    hostdata->NCR53c7xx_zero = 0;                      
+    hostdata->NCR53c7xx_msg_reject = MESSAGE_REJECT;
+    hostdata->NCR53c7xx_msg_abort = ABORT;
+    hostdata->NCR53c7xx_msg_nop = NOP;
+
     /*
      * Set up an interrupt handler if we aren't already sharing an IRQ
      * with another board.
      */
 
-    for (search = first_host; search && (search->hostt == the_template) &&
-       (search->irq != host->irq); search=search->next);
+    for (search = first_host; search && ((search->hostt != the_template) ||
+       (search->irq != host->irq)); search=search->next);
 
     if (!search) {
        if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx")) {
@@ -479,6 +461,10 @@ static int NCR53c7x0_init (struct Scsi_Host *host) {
     hostdata->istat = ((hostdata->chip / 100) == 8) ? 
        ISTAT_REG_800 : ISTAT_REG_700;
 
+/* Only the ISTAT register is readable when the NCR is running, so make 
+   sure it's halted. */
+    halt(host);
+
 /* 
  * XXX - the NCR53c700 uses bitfielded registers for SCID, SDID, etc,
  *     as does the 710 with one bit per SCSI ID.  Conversely, the NCR
@@ -523,9 +509,9 @@ static int NCR53c7x0_init (struct Scsi_Host *host) {
     hostdata->saved_dcntl = NCR53c7x0_read8(DCNTL_REG);
     
     if ((hostdata->chip / 100) == 8)
-       printk ("scsi%d : using %s interrupts.\n", host->host_no,
-           (hostdata->saved_dcntl & DCNTL_800_IRQM) ? "level active" : 
-           "edge triggered");
+       printk ("scsi%d : using %s interrupts\n", host->host_no,
+           (hostdata->saved_dcntl & DCNTL_800_IRQM) ? "edge triggered" :
+           "level active");
 
     /*
      * DMODE controls DMA burst length, and on 700 series chips,
@@ -547,8 +533,9 @@ static int NCR53c7x0_init (struct Scsi_Host *host) {
            case DMODE_BL_4: i = 4; break;
            case DMODE_BL_8: i = 8; break;
            case DMODE_BL_16: i = 16; break;
+            default: i = 0;
            }
-           printk ("scsi%d ; burst length %d\n", host->host_no, i);
+           printk ("scsi%d : burst length %d\n", host->host_no, i);
        }
     }
 
@@ -592,6 +579,7 @@ static int NCR53c7x0_init (struct Scsi_Host *host) {
      */
 
     for (i = 0; i < 8; ++i) {
+       hostdata->cmd_allocated[i] = 0;
        for (j = 0; j < 8; ++j)
            hostdata->busy[i][j] = 0;
        /* 
@@ -620,8 +608,8 @@ static int NCR53c7x0_init (struct Scsi_Host *host) {
 
     hostdata->issue_queue = hostdata->running_list = 
        hostdata->finished_queue = NULL;
-    hostdata->issue_dsa_head = 
-       hostdata->issue_dsa_tail = NULL;
+    hostdata->issue_dsa_head = NULL;
+    hostdata->issue_dsa_tail = NULL;
 
     if (hostdata->init_save_regs)
        hostdata->init_save_regs (host);
@@ -688,11 +676,11 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,
     struct Scsi_Host *instance;
     struct NCR53c7x0_hostdata *hostdata;
     char chip_str[80];
-    int script_len = 0, size = 0;
+    int script_len = 0, dsa_len = 0, size = 0, max_cmd_size = 0;
     int ok = 0;
 
     
-    options |= PERM_OPTIONS;
+    options |= perm_options;
 
     switch (chip) {
     case 825:
@@ -700,6 +688,7 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,
     case 815:
     case 810:
        script_len = NCR53c8xx_script_len;
+       dsa_len = NCR53c8xx_dsa_len;
        options |= OPTION_INTFLY;
        sprintf (chip_str, "NCR53c%d", chip);
        break;
@@ -718,7 +707,7 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,
     if ((chip / 100 == 8) && !pci_valid) 
        printk ("scsi-ncr53c7,8xx : for better reliability and performance, please use the\n" 
                "        PCI override instead.\n"
-               "        Syntax : ncr53c8{10,20,25}=pci,<bus>,<device>,<function>\n"
+               "        Syntax : ncr53c8{10,15,20,25}=pci,<bus>,<device>,<function>\n"
                "                 <bus> and <device> are usually 0.\n");
 
     if (options & OPTION_DEBUG_PROBE_ONLY) {
@@ -726,9 +715,50 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,
        return -1;
     }
 
-    size = sizeof(struct NCR53c7x0_hostdata) + script_len;
+    max_cmd_size = sizeof(struct NCR53c7x0_cmd) + dsa_len +
+       /* Size of dynamic part of command structure : */
+       2 * /* Worst case : we don't know if we need DATA IN or DATA out */
+               ( 2 * /* Current instructions per scatter/gather segment */ 
+                 tpnt->sg_tablesize + 
+                  3 /* Current startup / termination required per phase */
+               ) *
+       8 /* Each instruction is eight bytes */;
+    /* Note that alignment will be guaranteed, since we put the command
+       allocated at probe time after the fixed-up SCSI script, which 
+       consists of 32 bit words, aligned on a 32 bit boundary. */ 
+
+    /* Allocate fixed part of hostdata, dynamic part to hold appropriate
+       SCSI SCRIPT(tm) plus a single, maximum-sized NCR53c7x0_cmd structure.
+
+       We need a NCR53c7x0_cmd structure for scan_scsis() when we are 
+       not loaded as a module, and when we're loaded as a module, we 
+       can't use a non-dynamically allocated structure because modules
+       are vmalloc()'d, which can allow structures to cross page 
+       boundaries and breaks our physical/virtual address assumptions
+       for DMA.
+
+       So, we stick it past the end of our hostdata structure.
+
+       ASSUMPTION : 
+                Irregardless of how many simultaenous SCSI commands we allow,
+         the probe code only executes a _single_ instruction at a time,
+        so we only need one here, and don't need to allocate NCR53c7x0_cmd
+        structures for each target until we are no longer in scan_scsis
+        and kmalloc() has become functional (memory_init() happens 
+        after all device driver initialization).
+    */
+
+    size = sizeof(struct NCR53c7x0_hostdata) + script_len + max_cmd_size;
 
     instance = scsi_register (tpnt, size);
+    if (!instance)
+       return -1;
+
+
+    /* FIXME : if we ever support an ISA NCR53c7xx based board, we
+       need to check if the chip is running in a 16 bit mode, and if so 
+       unregister it if it is past the 16M (0x1000000) mark */
+       
     hostdata = (struct NCR53c7x0_hostdata *) 
        instance->hostdata;
     hostdata->size = size;
@@ -784,7 +814,18 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,
     instance->dma_channel = dma;
 
     hostdata->options = options;
-    
+    hostdata->dsa_size = dsa_len;
+    hostdata->max_cmd_size = max_cmd_size;
+    hostdata->num_cmds = 1;
+    /* Initialize single command */
+    hostdata->free = (struct NCR53c7x0_cmd *) 
+       (hostdata->script + hostdata->script_count);
+    hostdata->free->real = (void *) hostdata->free;
+    hostdata->free->size = max_cmd_size;
+    hostdata->free->free = NULL;
+    hostdata->free->next = NULL;
+
+
     return NCR53c7x0_init(instance);
 }
 
@@ -796,7 +837,7 @@ static int normal_init (Scsi_Host_Template *tpnt, int board, int chip,
  * Purpose : initializes a NCR53c800 family based on the PCI
  *     bus, device, and function location of it.  Allows 
  *     reprogramming of latency timer and determining addresses
- *     and weather bus mastering, etc. are OK.
+ *     and whether bus mastering, etc. are OK.
  *     
  *     Useful where a new NCR chip is backwards compatible with
  *     a supported chip, but the DEVICE ID has changed so it 
@@ -815,7 +856,8 @@ static int pci_init (Scsi_Host_Template *tpnt, int board, int chip,
     unsigned short vendor_id, device_id, command;
     unsigned long base, io_port; 
     unsigned char irq, revision;
-    int error, expected_chip, expected_id, max_revision, min_revision;
+    int error, expected_chip;
+    int expected_id = -1, max_revision = -1, min_revision = -1;
     int i;
 
     printk("scsi-ncr53c7,8xx : at PCI bus %d, device %d,  function %d\n",
@@ -870,6 +912,8 @@ static int pci_init (Scsi_Host_Template *tpnt, int board, int chip,
            io_port = 0;
        } else
            io_port &= PCI_BASE_ADDRESS_IO_MASK;
+    } else {
+       io_port = 0;
     }
 
     if (command & PCI_COMMAND_MEMORY) {
@@ -879,6 +923,8 @@ static int pci_init (Scsi_Host_Template *tpnt, int board, int chip,
            base = 0;
        } else 
            base &= PCI_BASE_ADDRESS_MEM_MASK;
+    } else {
+       base = 0;
     }
        
     if (!io_port && !base) {
@@ -932,7 +978,6 @@ static int pci_init (Scsi_Host_Template *tpnt, int board, int chip,
  */
 
 int NCR53c7xx_detect(Scsi_Host_Template *tpnt) {
-    short current_chip;
     int i;
     int current_override;
     int count;                 /* Number of boards detected */
@@ -979,6 +1024,7 @@ int NCR53c7xx_detect(Scsi_Host_Template *tpnt) {
 
 #include "53c8xx_d.h"
 static int NCR53c8xx_script_len = sizeof (SCRIPT);
+static int NCR53c8xx_dsa_len = A_dsa_end + Ent_dsa_zero - Ent_dsa_code_template;
 
 /* 
  * Function : static void NCR53c8x0_init_fixup (struct Scsi_Host *host)
@@ -989,7 +1035,8 @@ static int NCR53c8xx_script_len = sizeof (SCRIPT);
  *
  */
 
-static void NCR53c8x0_init_fixup (struct Scsi_Host *host) {
+static void 
+NCR53c8x0_init_fixup (struct Scsi_Host *host) {
     NCR53c7x0_local_declare();
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
        host->hostdata;
@@ -1008,6 +1055,16 @@ static void NCR53c8x0_init_fixup (struct Scsi_Host *host) {
     for (i = 0; i < PATCHES; ++i) 
        hostdata->script[LABELPATCHES[i]] += 
            (unsigned long) hostdata->script;
+    /* Fixup addresses of constants that used to be EXTERNAL */
+    
+    patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_abort, 
+       (long) &(hostdata->NCR53c7xx_msg_abort));
+    patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_reject, 
+       (long) &(hostdata->NCR53c7xx_msg_reject));
+    patch_abs_32 (hostdata->script, 0, NCR53c7xx_zero, 
+       (long) &(hostdata->NCR53c7xx_zero));
+    patch_abs_32 (hostdata->script, 0, NCR53c7xx_sink, 
+       (long) &(hostdata->NCR53c7xx_sink));
 
     /* 
      * Fixup absolutes set at boot-time.
@@ -1037,10 +1094,6 @@ static void NCR53c8x0_init_fixup (struct Scsi_Host *host) {
        ncr_to_ncr = memory_to_ncr = ncr_to_memory = tmp;
     }
 
-    printk ("scsi%d : m_to_n = 0x%x, n_to_m = 0x%x, n_to_n = 0x%x\n",
-           (int) host->host_no, (int) memory_to_ncr, (int) 
-           ncr_to_memory, ncr_to_ncr);
-
     patch_abs_32 (hostdata->script, 0, addr_scratch, base + SCRATCHA_REG_800);
     patch_abs_32 (hostdata->script, 0, addr_sfbr, base + SFBR_REG);
     patch_abs_32 (hostdata->script, 0, addr_temp, base + TEMP_REG);
@@ -1059,11 +1112,15 @@ static void NCR53c8x0_init_fixup (struct Scsi_Host *host) {
     patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_memory, ncr_to_memory);
     patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_ncr, ncr_to_ncr);
 
-    patch_abs_32 (hostdata->script, 0, issue_dsa_head, (long) &(hostdata->issue_dsa_head));
+    patch_abs_32 (hostdata->script, 0, issue_dsa_head, 
+       (long) &(hostdata->issue_dsa_head));
     patch_abs_32 (hostdata->script, 0, msg_buf, (long) &(hostdata->msg_buf));
-    patch_abs_32 (hostdata->script, 0, reconnect_dsa_head, (long) &(hostdata->reconnect_dsa_head));
-    patch_abs_32 (hostdata->script, 0, reselected_identify, (long) &(hostdata->reselected_identify));
-    patch_abs_32 (hostdata->script, 0, reselected_tag, (long) &(hostdata->reselected_tag));
+    patch_abs_32 (hostdata->script, 0, reconnect_dsa_head, 
+       (long) &(hostdata->reconnect_dsa_head));
+    patch_abs_32 (hostdata->script, 0, reselected_identify, 
+       (long) &(hostdata->reselected_identify));
+    patch_abs_32 (hostdata->script, 0, reselected_tag, 
+       (long) &(hostdata->reselected_tag));
 
     patch_abs_32 (hostdata->script, 0, test_dest, (long) &(hostdata->test_dest));
     patch_abs_32 (hostdata->script, 0, test_src, (long) &(hostdata->test_source));
@@ -1145,17 +1202,18 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
        host->hostdata;
     unsigned long timeout, start;
-    int old_level, failed, i;
+    int failed, i;
+    unsigned long flags;
+       
     NCR53c7x0_local_setup(host);
 
-    printk("scsi%d : testing\n", host->host_no);
-
     /* The NCR chip _must_ be idle to run the test scripts */
 
-    old_level = splx(0);
+    save_flags(flags);
+    cli();
     if (!hostdata->idle) {
        printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
-       splx(old_level);
+       restore_flags(flags);
        return -1;
     }
 
@@ -1181,7 +1239,7 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
        printk ("scsi%d : test 1", host->host_no);
        NCR53c7x0_write32 (DSP_REG, start);
        printk (" started\n");
-       splx(7);
+       sti();
 
        timeout = jiffies + 50; /* arbitrary */
        while ((hostdata->test_completed == -1) && jiffies < timeout);
@@ -1217,7 +1275,7 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
                (unsigned long) hostdata->script, start);
            printk ("scsi%d : DSPS = 0x%lx\n", host->host_no,
                (unsigned long) NCR53c7x0_read32(DSPS_REG));
-           splx(old_level);
+           restore_flags(flags);
            return -1;
        }
        hostdata->test_running = 0;
@@ -1253,10 +1311,10 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
        dsa[11] = (unsigned long) &msg;
 
        for (i = 0; i < 3; ++i) {
-           splx(0);
+           cli();
            if (!hostdata->idle) {
                printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
-               splx(old_level);
+               restore_flags(flags);
                return -1;
            }
 
@@ -1269,7 +1327,7 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
            hostdata->state = STATE_RUNNING;
            NCR53c7x0_write32 (DSA_REG, (unsigned long) dsa);
            NCR53c7x0_write32 (DSP_REG, start);
-           splx(7);
+           sti();
 
            timeout = jiffies + 500;    /* arbitrary */
            while ((hostdata->test_completed == -1) && jiffies < timeout);
@@ -1289,12 +1347,12 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
                    host->host_no, i);
                if (!hostdata->idle) {
                    printk("scsi%d : not idle\n", host->host_no);
-                   splx(old_level);
+                   restore_flags(flags);
                    return -1;
                }
            } else if (hostdata->test_completed == -1) {
                printk ("scsi%d : test 2 timed out\n", host->host_no);
-               splx(old_level);
+               restore_flags(flags);
                return -1;
            } 
            hostdata->test_running = 0;
@@ -1305,9 +1363,8 @@ static int NCR53c8xx_run_tests (struct Scsi_Host *host) {
        }
        }
     }
-    printk ("scsi%d : tests complete.\n", host->host_no);
 
-    splx(old_level);
+    restore_flags(flags);
     return 0;
 }
 
@@ -1364,11 +1421,12 @@ static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
     struct Scsi_Host *host = c->host;
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
        host->hostdata;
-    int old_level;
+    unsigned long flags;
     char **prev, *search;
     int i;
 
-    old_level = splx(0);
+    save_flags(flags);
+    cli();
     for (i = 0; i < 2; ++i) {
        for (search = (char *) (i ? hostdata->issue_dsa_head : 
                hostdata->reconnect_dsa_head), prev = (char **) (i ? 
@@ -1390,21 +1448,14 @@ static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
     if (hostdata->running_list == cmd)
        hostdata->running_list = cmd->next;
 
-    if (!scan_scsis_buf_busy) {
-#ifdef SCSI_MALLOC
-       scsi_free ((void *) cmd->real, cmd->size);
-#else
-       kfree_s (cmd->real, cmd->size);
-#endif
-    } else {
-       scan_scsis_buf_busy = 0;
-    }
+    cmd->next = hostdata->free;
+    hostdata->free = cmd;
 
     c->host_scribble = NULL;
     c->result = result;
     c->scsi_done(c);
 
-    splx(old_level);
+    restore_flags(flags);
 }
 
 /* 
@@ -1429,7 +1480,7 @@ static void intr_break (struct Scsi_Host *host, struct
     unsigned long *dsp;
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
        host->hostdata;         
-    int old_level;
+    unsigned long flags;
     NCR53c7x0_local_setup(host);
 
     /*
@@ -1437,8 +1488,8 @@ static void intr_break (struct Scsi_Host *host, struct
      * dump the appropriate debugging information to standard 
      * output.  
      */
-
-    old_level = splx(0);
+    save_flags(flags);
+    cli();
     dsp = (unsigned long *) NCR53c7x0_read32(DSP_REG);
     for (bp = hostdata->breakpoints; bp && bp->address != dsp; 
        bp = bp->next);
@@ -1460,7 +1511,7 @@ static void intr_break (struct Scsi_Host *host, struct
      * instruction in bytes.
      */
 
-    splx(old_level);
+    restore_flags(flags);
 }
 
 /*
@@ -1575,7 +1626,7 @@ static void synchronous (struct Scsi_Host *host, int target, char *msg) {
        hostdata->sync[target].select_indirect = (scntl3 << 24) | (target << 16) | 
                (sxfer << 8);
 
-       script = hostdata->sync[target].script;
+       script = (long *) hostdata->sync[target].script;
 
        /* XXX - add NCR53c7x0 code to reprogram SCF bits if we want to */
        if ((hostdata->chip / 100) == 8) {
@@ -1630,7 +1681,7 @@ static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
        printk ("scsi%d : message", host->host_no);
        if (cmd) 
            printk (" from target %d lun %d", c->target, c->lun);
-       print_msg (hostdata->msg_buf);
+       print_msg ((unsigned char *) hostdata->msg_buf);
        printk("\n");
        switch (hostdata->msg_buf[0]) {
        /* 
@@ -1665,7 +1716,8 @@ static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
         */
            if (cmd->flags & CMD_FLAG_SDTR) {
                cmd->flags &= ~CMD_FLAG_SDTR; 
-               synchronous (host, c->target, hostdata->msg_buf);
+               synchronous (host, c->target, (unsigned char *) 
+                   hostdata->msg_buf);
                hostdata->dsp = hostdata->script + hostdata->E_accept_message /
                    sizeof(long);
                hostdata->dsp_changed = 1;
@@ -1673,7 +1725,8 @@ static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
            } else {
                if (hostdata->options & OPTION_SYNCHRONOUS)  {
                    cmd->flags |= CMD_FLAG_DID_SDTR;
-                   synchronous (host, c->target, hostdata->msg_buf);
+                   synchronous (host, c->target, (unsigned char *)
+                       hostdata->msg_buf);
                } else {
                    hostdata->msg_buf[4] = 0;           /* 0 offset = async */
                }
@@ -1948,15 +2001,16 @@ static int debugger_fn_bc (struct Scsi_Host *host, struct debugger_token *token,
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
        instance->hostdata;
     struct NCR53c7x0_break *bp, **prev;
-    int old_level;
-    old_level = splx(0);
+    unsigned long flags;
+    save_flags(flags);
+    cli();
     for (bp = (struct NCR53c7x0_break *) instance->breakpoints,
            prev = (struct NCR53c7x0_break **) &instance->breakpoints;
            bp; prev = (struct NCR53c7x0_break **) &(bp->next),
            bp = (struct NCR53c7x0_break *) bp->next);
 
     if (!bp) {
-       splx(old_level);
+       restore_flags(flags);
        return -EIO;
     }
 
@@ -1969,7 +2023,7 @@ static int debugger_fn_bc (struct Scsi_Host *host, struct debugger_token *token,
     if (prev)
        *prev = bp->next;
 
-    splx(old_level);
+    restore_flags(flags);
     return 0;
 }
 
@@ -1981,7 +2035,7 @@ static int debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token,
     struct NCR53c7x0_break *bp;
     char buf[80];
     size_t len;
-    int old_level;
+    unsigned long flags;
     /* 
      * XXX - we need to insure that the processor is halted 
      * here in order to prevent a race condition.  So, if the 
@@ -1992,7 +2046,8 @@ static int debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token,
        host->host_no);
     debugger_kernel_write (host, buf, strlen(buf));
 
-    old_level=splx(0);
+    save_flags(flags);
+    cli();
     for (bp = (struct NCR53c7x0_break *) host->breakpoints;
            bp; bp = (struct NCR53c7x0_break *) bp->next); {
            sprintf (buf, "scsi%d : bp : success : at %08x, replaces %08x %08x",
@@ -2007,7 +2062,7 @@ static int debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token,
            len = strlen(buf);
            debugger_kernel_write (host, buf, len);
     }
-    splx(old_level);
+    restore_flags(flags);
     return 0;
 }
 
@@ -2018,20 +2073,21 @@ static int debugger_fn_bs (struct Scsi_Host *host, struct debugger_token *token,
     struct NCR53c7x0_break *bp;
     char buf[80];
     size_t len;
-    int old_level;
-    old_level=splx(0);
+    unsigned long flags;
+    save_flags(flags);
+    cli();
 
     if (hostdata->state != STATE_HALTED) {
        sprintf (buf, "scsi%d : bs : failure : NCR not halted\n", host->host_no);
        debugger_kernel_write (host, buf, strlen(buf));
-       splx(old_level);
+       restore_flags(flags);
        return -1;
     }
 
     if (!(bp = kmalloc (sizeof (struct NCR53c7x0_break)))) {
        printk ("scsi%d : kmalloc(%d) of breakpoint structure failed, try again\n",
            host->host_no, sizeof(struct NCR53c7x0_break));
-       splx(old_level);
+       restore_flags(flags);
        return -1;
     }
 
@@ -2043,7 +2099,7 @@ static int debugger_fn_bs (struct Scsi_Host *host, struct debugger_token *token,
     hostdata->breakpoints = bp->next;
     memcpy ((void *) bp->address, (void *) hostdata->E_debug_break, 8);
     
-    splx(old_level);
+    restore_flags(flags);
     return 0;
 }
 
@@ -2132,9 +2188,10 @@ static debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t
     buflen) {
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
        host->hostdata;
-    int copy, left, old_level;
-    
-    old_level = splx(0);
+    int copy, left;
+    unsigned long flags;
+    save_flags(flags);
+    cli();
     while (buflen) {
        left = (hostdata->debug_buf + hostdata->debug_size - 1) -
            hostdata->debug_write;
@@ -2147,7 +2204,7 @@ static debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t
            (hostdata->debug_buf + hostdata->debug_size))
            hosdata->debug_write = hostdata->debug_buf;
     }
-    (void) splx(old_level);
+    restore_flags(flags);
 }
 
 #endif /* def NCRDEBUG */
@@ -2164,7 +2221,8 @@ static debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t
  * 
  */
 
-static void NCR53c8x0_soft_reset (struct Scsi_Host *host) {
+static void 
+NCR53c8x0_soft_reset (struct Scsi_Host *host) {
     NCR53c7x0_local_declare();
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
        host->hostdata;
@@ -2187,14 +2245,18 @@ static void NCR53c8x0_soft_reset (struct Scsi_Host *host) {
 
 
     /* 
-     * Respond to selection and reselection by targets and 
-     * use our _initiator_ SCSI ID for arbitration. 
+     * Respond to reselection by targets and use our _initiator_ SCSI ID 
+     * for arbitration. If notyet, also respond to SCSI selection.
      *
      * XXX - Note : we must reprogram this when reselecting as 
      * a target.
      */
 
+#ifdef notyet
     NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE|SCID_800_SRE);
+#else
+    NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE);
+#endif
     NCR53c7x0_write8(RESPID_REG_800, hostdata->this_id_mask);
 
     /*
@@ -2222,8 +2284,7 @@ static void NCR53c8x0_soft_reset (struct Scsi_Host *host) {
 
     
     NCR53c7x0_write8(SIEN0_REG_800, ((hostdata->options & OPTION_PARITY) ?
-           SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_800_SEL |
-           SIEN_800_RESEL | SIEN_MA);
+           SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA);
     NCR53c7x0_write8(SIEN1_REG_800, SIEN1_800_STO | SIEN1_800_HTH);
 
     /* 
@@ -2243,11 +2304,13 @@ static void NCR53c8x0_soft_reset (struct Scsi_Host *host) {
 /*
  * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) 
  *
- * Purpose : Using scsi_malloc() if the system is initialized,
- *     scan_scsis_buf if not, allocate space to store the variable
- *     length NCR53c7x0_cmd structure.  Initialize it based on 
- *     the Scsi_Cmnd structure passed in, including dsa and 
- *     Linux field initialization, and dsa code relocation.
+ * Purpose : If we have not allready allocated enough NCR53c7x0_cmd
+ *     structures to satisfy any allowable number of simultaenous 
+ *     commands for this host; do so (using either scsi_malloc()
+ *     or kmalloc() depending on configuration), and add them to the 
+ *     hostdata free list.  Take the first structure off the free list, 
+ *     initialize it based on the Scsi_Cmnd structure passed in, 
+ *     including dsa and Linux field initialization, and dsa code relocation.
  *
  * Inputs : cmd - SCSI command
  *
@@ -2255,26 +2318,86 @@ static void NCR53c8x0_soft_reset (struct Scsi_Host *host) {
  *     NULL on failure.
  */
 
-static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
+static struct NCR53c7x0_cmd *
+create_cmd (Scsi_Cmnd *cmd) {
     NCR53c7x0_local_declare();
     struct Scsi_Host *host = cmd->host;
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
         host->hostdata;        
-    int size;                  /* Size of *tmp */
-    struct NCR53c7x0_cmd *tmp;         /* NCR53c7x0_cmd structure for this command */
+    struct NCR53c7x0_cmd *tmp = NULL;  /* NCR53c7x0_cmd structure for this command */
     int datain,                /* Number of instructions per phase */
        dataout;
     int data_transfer_instructions, /* Count of dynamic instructions */
-       i,                      /* Counter */
-       alignment;              /* Alignment adjustment (0 - 4) */
+       i;                      /* Counter */
     unsigned long *cmd_datain, /* Address of datain/dataout code */
        *cmd_dataout;           /* Incremented as we assemble */
+#ifdef notyet
     void *real;                        /* Real address */
+    int size;                  /* Size of *tmp */
+    int        alignment;              /* Alignment adjustment (0 - 4) */
+#endif
+    unsigned long flags;
     NCR53c7x0_local_setup(cmd->host);
 
+/* FIXME : when we start doing multiple simultaenous commands per LUN, 
+   we will need to either
+       - Do an attach_slave() and detach_slave() the right way (alocate
+         memory in attach_slave() as we do in scsi_register).
+       - Make sure this code works
+    with the former being cleaner.  At the same time, we can also go with
+    a per-device host_scribble, and introduce a NCR53c7x0_device structure
+    to replace the messy fixed length arrays we're starting to use. */
+
+#ifdef notyet
+
+    if (hostdata->num_commands < host->can_queue &&
+       !in_scan_scsis && 
+       !(hostdata->cmd_allocated[cmd->target] & (1 << cmd->lun))) {
+       for (i = host->hostt->cmd_per_lun - 1; i >= 0  --i) {
+#ifdef SCSI_MALLOC
+    /* scsi_malloc must allocate with a 512 byte granularity, but allways
+       returns buffers which are aligned on a 512 boundary */
+           size = (hostdata->max_cmd_size + 511) / 512 * 512;
+           tmp = (struct NCR53c7x0_cmd *) scsi_malloc (size);
+           if (!tmp)
+               break;
+           tmp->real = (void *) tmp; 
+#else
+    /* kmalloc() can allocate any size, but historically has returned 
+       unaligned addresses, so we need to allow for alignment */
+           size = hostdata->max_cmd_size + 4;
+           real = kmalloc (size, GFP_ATOMIC);
+           alignment = 4 - (((unsigned) real) & 3);
+           tmp = (struct NCR53c7x0_cmd *) (((char *) real) + alignment);
+           if (!tmp)
+               break;
+           tmp->real = real;
+#endif /* def SCSI_MALLOC */
+           tmp->size = size;                   
+           /* Insert all but last into list */
+           if (i > 0) {
+               tmp->next = hostdata->free;
+               hostdata->free = tmp;
+           }
+       }
+    }
+#endif /* def notyet */
+    if (!tmp) {
+       save_flags(flags);
+       cli();
+       tmp = (struct NCR53c7x0_cmd *) hostdata->free;
+       if (tmp) {
+           hostdata->free = tmp->next;
+           restore_flags(flags);
+       } else {
+           restore_flags(flags);
+           return NULL;
+       }
+    }
+
 
     /*
-     * Decide weather we need to generate commands for DATA IN,
+     * Decide whether we need to generate commands for DATA IN,
      * DATA OUT, neither, or both based on the SCSI command 
      */
 
@@ -2323,10 +2446,6 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
        datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
     }
 
-    /*
-     * Allocate memory for the NCR53c7x0_cmd structure.  
-     */
-
     /* 
      * For each data phase implemented, we need a JUMP instruction
      * to return control to other_transfer.  We also need a MOVE
@@ -2344,63 +2463,11 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
     if (data_transfer_instructions < 2)
        data_transfer_instructions = 2;
 
-    /* 
-     * We need enough space to store the base NCR53c7x0 structure,
-     * DSA, and data transfer instructions at 2 long words each,
-     * as well as padding out to the next 512 bytes for scsi_malloc.
-     *
-     * We also need to guarantee alignment of _4_ bytes. 
-     */
-
-#ifdef SCSI_MALLOC
-    size = ((sizeof (struct NCR53c7x0_cmd) + (hostdata->dsa_end - 
-       hostdata->dsa_start) + 2 * sizeof(long) * 
-       data_transfer_instructions + 4 + 511) / 512) * 512;             
-#else
-    size = sizeof (struct NCR53c7x0_cmd) + (hostdata->dsa_end - 
-       hostdata->dsa_start) + 2 * sizeof(long) * 
-       data_transfer_instructions + 4;
-#endif
-
-
-#if 0
-    if (size > 512) {
-       printk("scsi%d : size = %d\n", host->host_no, size);
-    }
-#endif
-
-#ifdef SCSI_MALLOC
-    real = in_scan_scsis ? NULL : scsi_malloc (size);
-#else
-    real = kmalloc (size, GFP_ATOMIC);
-#endif
-
-    if (!real) {
-       if (!scan_scsis_buf_busy && size <= sizeof(scan_scsis_buf)) {
-           scan_scsis_buf_busy = 1;
-           real = scan_scsis_buf;
-       } else {
-           panic ("scsi%d : scan_scsis_buf too small (need %d bytes)\n",
-               host->host_no, size);
-       }
-    }
-
-    alignment = 4 - (((unsigned) real) & 3);
-
-    tmp = (struct NCR53c7x0_cmd *) (((char *) real) + alignment);
-
-    tmp->real = real;
-
-
-    if (((unsigned long) tmp->dsa) & 0x3) 
-       panic ("scsi%d : pid %d dsa structure not dword aligned!\n",
-           host->host_no, cmd->pid);
 
     /*
      * Initialize Linux specific fields.
      */
 
-    tmp->size = size;                  
     tmp->cmd = cmd;
     tmp->next = NULL;
     tmp->prev = NULL;
@@ -2434,7 +2501,7 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
     patch_dsa_32(tmp->dsa, dsa_select, 0, hostdata->sync[cmd->target].
        select_indirect);
     /*
-     * XXX - we need to figure this size based on weather
+     * XXX - we need to figure this size based on whether
      * or not we'll be using any additional messages.
      */
     patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1);
@@ -2462,7 +2529,7 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
     patch_dsa_32(tmp->dsa, dsa_status, 1, &cmd->result);
     patch_dsa_32(tmp->dsa, dsa_msgout_other, 0, 1);
     patch_dsa_32(tmp->dsa, dsa_msgout_other, 1, 
-       &NCR53c7xx_msg_nop);
+       &(hostdata->NCR53c7xx_msg_nop));
 
     
     /*
@@ -2486,8 +2553,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
 #endif
 
 /* 
- * XXX - I'm undecided weather all of this nonsense is faster
- * in the long run, or weather I should just go and implement a loop
+ * XXX - I'm undecided whether all of this nonsense is faster
+ * in the long run, or whether I should just go and implement a loop
  * on the NCR chip using table indirect mode?
  *
  * In any case, this is how it _must_ be done for 53c700/700-66 chips,
@@ -2516,8 +2583,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
            cmd_datain[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL | 
                DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) | 
                DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE;
-           cmd_datain[3] = hostdata->script + hostdata->E_msg_in / 
-               sizeof(long);
+           cmd_datain[3] = (unsigned long) hostdata->script + 
+               hostdata->E_msg_in;
 #if 0
            print_insn (host, cmd_datain, "dynamic ", 1);
            print_insn (host, cmd_datain + 2, "dynamic ", 1);
@@ -2530,8 +2597,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
            cmd_dataout[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL | 
                DCMD_TCI_CD | DCMD_TCI_IO | DCMD_TCI_MSG) << 24) | 
                DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE | DBC_TCI_TRUE;
-           cmd_dataout[3] = hostdata->script + hostdata->E_msg_in /
-               sizeof(long);
+           cmd_dataout[3] = (unsigned long) hostdata->script + 
+               hostdata->E_msg_in;
 #if 0
            print_insn (host, cmd_dataout, "dynamic ", 1);
            print_insn (host, cmd_dataout + 2, "dynamic ", 1);
@@ -2548,8 +2615,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
     if (datain) {
        cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
            DBC_TCI_TRUE;
-       cmd_datain[1] = hostdata->script + hostdata->E_other_transfer
-           / sizeof(long);
+       cmd_datain[1] = (unsigned long) hostdata->script + 
+           hostdata->E_other_transfer;
 #if 0
        print_insn (host, cmd_datain, "dynamic jump ", 1);
 #endif
@@ -2567,8 +2634,8 @@ static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) {
     if (dataout) {
        cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
            DBC_TCI_TRUE;
-       cmd_dataout[1] = hostdata->script + hostdata->E_other_transfer
-           / sizeof(long);
+       cmd_dataout[1] = (unsigned long) hostdata->script + 
+           hostdata->E_other_transfer;
 #if 0
        print_insn (host, cmd_dataout, "dynamic jump ", 1);
 #endif
@@ -2603,7 +2670,7 @@ int NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
     struct Scsi_Host *host = cmd->host;
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
        host->hostdata;
-    int old_level;
+    unsigned long flags;
     unsigned char target_was_busy;
     NCR53c7x0_local_setup(host);
     
@@ -2671,7 +2738,8 @@ int NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
      * valid while the condition exists.
      */
 
-    old_level = splx(0);
+    save_flags(flags);
+    cli();
 
     /* 
      * Consider a target busy if there are _any_ commands running
@@ -2764,7 +2832,7 @@ int NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
            tmp->next; tmp = (struct NCR53c7x0_cmd *) tmp->next);
        tmp->next = tmp;
     }
-    splx(old_level);
+    restore_flags(flags);
     return 0;
 }
 
@@ -2848,9 +2916,9 @@ static void intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
     
     if (sstat0_sist0 & SSTAT0_UDC) {
        fatal = 1;
-       printk("scsi%d : target %d lun %d unexpected disconnect\n",
-           host->host_no, cmd->cmd->target, cmd->cmd->lun);
        if (cmd) {
+           printk("scsi%d : target %d lun %d unexpected disconnect\n",
+               host->host_no, cmd->cmd->target, cmd->cmd->lun);
            abnormal_finished(cmd, DID_ERROR << 16);
        }
        hostdata->dsp = hostdata->script + hostdata->E_schedule / 
@@ -2950,7 +3018,7 @@ static void NCR53c7x0_intr (int irq, struct pt_regs * regs) {
                                                   should terminate */
     int interrupted = 0;                       /* This HA generated 
                                                   an interrupt */
-    int old_level;                             
+    unsigned long flags;                               
 
 #ifdef NCR_DEBUG
     char buf[80];                              /* Debugging sprintf buffer */
@@ -3011,12 +3079,14 @@ static void NCR53c7x0_intr (int irq, struct pt_regs * regs) {
                     */
 
 
-                   old_level = splx(0);
+                   save_flags(flags);
+                   cli();
 restart:
                    for (cmd_prev_ptr = (struct NCR53c7x0_cmd **) 
-                       &(hostdata->running_list), cmd = (struct NCR53c7x0_cmd *)
-                       hostdata->running_list; cmd ; cmd_prev_ptr = 
-                       &(cmd->next), cmd = (struct NCR53c7x0_cmd *) cmd->next) {
+                        &(hostdata->running_list), cmd = 
+                         (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
+                         cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next), 
+                        cmd = (struct NCR53c7x0_cmd *) cmd->next) {
                        Scsi_Cmnd *tmp;
 
                        if (!cmd) {
@@ -3045,7 +3115,7 @@ restart:
                        if (cmd->prev)
                            cmd->prev->next = cmd->next;
                        if (cmd_prev_ptr)
-                           *cmd_prev_ptr = cmd->next;
+                           *cmd_prev_ptr = (struct NCR53c7x0_cmd *) cmd->next;
 
 #ifdef LUN_BUSY
                        /* Check for next command for target, add to issue queue */
@@ -3054,16 +3124,8 @@ restart:
 #endif
 
 
-                       if (!scan_scsis_buf_busy) {
-#ifdef SCSI_MALLOC
-                           scsi_free ((void *) cmd->real, cmd->size);
-#else
-                           kfree_s ((void *) cmd->real, cmd->size);
-#endif
-                       } else {
-                           scan_scsis_buf_busy = 0;
-                       }
-
+                       cmd->next = hostdata->free;
+                       hostdata->free = cmd;
 
                        tmp->host_scribble = NULL;
 
@@ -3081,7 +3143,7 @@ restart:
                        goto restart;
 
                    }
-                   splx(old_level);
+                   restore_flags(flags);
 
                    if (!search_found)  {
                        printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
@@ -3204,7 +3266,8 @@ restart:
  *
  */
 
-static int abort_connected (struct Scsi_Host *host) {
+static int 
+abort_connected (struct Scsi_Host *host) {
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
        host->hostdata;
 
@@ -3398,15 +3461,13 @@ static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
     NCR53c7x0_local_declare();
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
        host->hostdata;
-    unsigned char dstat,       /* DSTAT */     
-       dbc_dcmd;               /* DCMD (high eight bits) + DBC */
+    unsigned char dstat;       /* DSTAT */     
     unsigned long *dsp,
        *next_dsp,              /* Current dsp */
-       *dsa;
-       
-
-    int ipl,                   /* Old ipl from splx(0) */
-       tmp;
+       *dsa,
+       dbc_dcmd;               /* DCMD (high eight bits) + DBC */
+    int tmp;
+    unsigned long flags;
     NCR53c7x0_local_setup(host);
 
     if (!hostdata->dstat_valid) {
@@ -3460,12 +3521,13 @@ static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
        if (hostdata->options & OPTION_DEBUG_TRACE) {
        } else if (hostdata->options & OPTION_DEBUG_SINGLE) {
            print_insn (host, dsp, "s ", 0);
-           ipl = splx(0);
+           save_flags(flags);
+           cli();
 /* XXX - should we do this, or can we get away with writing dsp? */
 
            NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) & 
                ~DCNTL_SSM) | DCNTL_STD);
-           splx(ipl);
+           restore_flags(flags);
        } else {
            printk("scsi%d : unexpected single step interrupt at\n"
                   "         ", host->host_no);
@@ -3654,9 +3716,10 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
     struct Scsi_Host *host = cmd->host;
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) 
        host->hostdata;
-    int old_level;
+    unsigned long flags;
     struct NCR53c7x0_cmd *curr, **prev;
-    old_level = splx(0);
+    save_flags(flags);
+    cli();
 
 /*
  * The command could be hiding in the issue_queue.  This would be very
@@ -3668,28 +3731,23 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
  * pull the command out of the old queue, and call it aborted.
  */
 
-    for (curr = hostdata->issue_queue, prev = &(hostdata->issue_queue);
-       curr && curr->cmd != cmd; prev = &(curr->next), curr = curr->next);
+    for (curr = (struct NCR53c7x0_cmd *) hostdata->issue_queue, 
+         prev = (struct NCR53c7x0_cmd **) &(hostdata->issue_queue);
+        curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **)
+         &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
 
     if (curr) {
-       *prev = curr->next;
+       *prev = (struct NCR53c7x0_cmd *) curr->next;
 /* XXX - get rid of DLL ? */
        if (curr->prev)
            curr->prev->next = curr->next;
 
-       if (!scan_scsis_buf_busy) {
-#ifdef SCSI_MALLOC
-           scsi_free ((void *) curr->real, curr->size);
-#else
-           kfree_s ((void *) curr->real, curr->size);
-#endif
-       } else {
-           scan_scsis_buf_busy = 0;
-       }
+       curr->next = hostdata->free;
+       hostdata->free = curr;
 
        cmd->result = 0;
        cmd->scsi_done(cmd);
-       splx(old_level);
+       restore_flags(flags);
        return SCSI_ABORT_SUCCESS;
     }
 
@@ -3698,11 +3756,13 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
  * commands.  If this is the case, drastic measures are called for.  
  */ 
 
-    for (curr = hostdata->running_list, prev = &(hostdata->running_list);
-       curr && curr->cmd != cmd; prev = &(curr->next), curr = curr->next);
+    for (curr = (struct NCR53c7x0_cmd *) hostdata->running_list, 
+        prev = (struct NCR53c7x0_cmd **) &(hostdata->running_list);
+        curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **) 
+         &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
 
     if (curr) {
-       splx(old_level);
+       restore_flags(flags);
        printk ("scsi%d : DANGER : command in running list, can not abort.\n",
            cmd->host->host_no);
        return SCSI_ABORT_SNOOZE;
@@ -3715,16 +3775,8 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
  */
 
     curr = (struct NCR53c7x0_cmd *) cmd->host_scribble;
-
-    if (!scan_scsis_buf_busy) {
-#ifdef SCSI_MALLOC
-       scsi_free ((void *) curr->real, curr->size);
-#else
-       kfree_s ((void *) curr->real, curr->size);
-#endif
-    } else {
-       scan_scsis_buf_busy = 0;
-    }
+    curr->next = hostdata->free;
+    hostdata->free = curr;
 
     if (((cmd->result & 0xff00) == 0xff00) ||
        ((cmd->result & 0xff) == 0xff)) {
@@ -3734,7 +3786,7 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
            host->host_no);
     }
     cmd->scsi_done(cmd);
-    splx(old_level);
+    restore_flags(flags);
     return SCSI_ABORT_SNOOZE;
 }
 
@@ -3749,17 +3801,47 @@ int NCR53c7xx_abort (Scsi_Cmnd *cmd) {
  * Returns : 0 on success.
  */
  
-int NCR53c7xx_reset (Scsi_Cmnd *cmd) {
+int 
+NCR53c7xx_reset (Scsi_Cmnd *cmd) {
     NCR53c7x0_local_declare();
-    struct Scsi_Host *host = cmd ? cmd->host : NULL;
+    unsigned long flags;
+    int found;
+    struct NCR53c7x0_cmd * c;
+    Scsi_Cmnd *tmp;
+    struct Scsi_Host *host = cmd->host;
     struct NCR53c7x0_hostdata *hostdata = host ? 
-       (struct NCR53c7x0_hostdata *) host->hostdata : NULL;
-    if (host) NCR53c7x0_local_setup(host);
-    
+    (struct NCR53c7x0_hostdata *) host->hostdata : NULL;
+    NCR53c7x0_local_setup(host);
+    save_flags(flags);
+    halt (host);
+    NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
+    udelay(25);        /* Minimum ammount of time to assert RST */
+    NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
+    for (c = (struct NCR53c7x0_cmd *) hostdata->running_list, found = 0; c; 
+       c = (struct NCR53c7x0_cmd *) c->next)  {
+       tmp = c->cmd;
+       c->next = hostdata->free;
+       hostdata->free = c;
+
+       if (tmp == cmd)
+           found = 1; 
+       tmp->result = DID_RESET << 16;
+       tmp->scsi_done(tmp);
+    }
+    if (!found) {
+       c = (struct NCR53c7x0_cmd *) cmd->host_scribble;
+       if (c) {
+           c->next = hostdata->free;
+           hostdata->free = c;
+       }
+       cmd->result = DID_RESET << 16;
+       cmd->scsi_done(cmd);
+    }
+    restore_flags(flags);
 
     printk ("scsi%d : DANGER : NCR53c7xx_reset is NOP\n",
        cmd->host->host_no);
-    return SCSI_RESET_SNOOZE;
+    return SCSI_RESET_SUCCESS;
 }
 
 /*
@@ -3770,13 +3852,11 @@ int NCR53c7xx_reset (Scsi_Cmnd *cmd) {
 static void print_dsa (struct Scsi_Host *host, unsigned long *dsa) {
     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
        host->hostdata;
-    Scsi_Cmnd * cmd;
-    struct NCR53c7x0_cmd * c;
     int i, len;
     char *ptr;
 
     printk("scsi%d : dsa at 0x%x\n"
-           "        + %d : dsa_msgout length = %d, data = 0x%x\n" ,
+           "        + %ld : dsa_msgout length = %lu, data = 0x%lx\n" ,
            host->host_no, (unsigned) dsa, hostdata->dsa_msgout,
            dsa[hostdata->dsa_msgout / sizeof(long)],
            dsa[hostdata->dsa_msgout / sizeof(long) + 1]);
@@ -3790,3 +3870,108 @@ static void print_dsa (struct Scsi_Host *host, unsigned long *dsa) {
     }
 }
 
+/*
+ * Function : static int shutdown (struct Scsi_Host *host)
+ * 
+ * Purpose : does a clean (we hope) shutdown of the NCR SCSI 
+ *     chip.  Use prior to dumping core, unloading the NCR driver,
+ *     etc.
+ * 
+ * Returns : 0 on success
+ */
+#ifdef MODULE
+static int 
+shutdown (struct Scsi_Host *host) {
+    NCR53c7x0_local_declare();
+    unsigned long flags;
+    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
+       host->hostdata;
+    NCR53c7x0_local_setup(host);
+    save_flags (flags);
+    cli();
+    halt (host);
+    hostdata->soft_reset(host);
+/* 
+ * For now, we take the simplest solution : reset the SCSI bus. Eventually,
+ * - If a command is connected, kill it with an ABORT message
+ * - If commands are disconnected, connect to each target/LUN and 
+ *     do a ABORT, followed by a SOFT reset, followed by a hard 
+ *     reset.  
+ */
+    NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
+    udelay(25);        /* Minimum ammount of time to assert RST */
+    NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
+    restore_flags (flags);
+    return 0;
+}
+#endif
+
+
+/*
+ * Function : static int halt (struct Scsi_Host *host)
+ * 
+ * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
+ *
+ * Inputs : host - SCSI chip to halt
+ *
+ * Returns : 0 on success
+ */
+
+static int 
+halt (struct Scsi_Host *host) {
+    NCR53c7x0_local_declare();
+    unsigned long flags;
+    unsigned char istat, tmp;
+    struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
+       host->hostdata;
+    NCR53c7x0_local_setup(host);
+
+    save_flags(flags);
+    cli();
+    NCR53c7x0_write8(hostdata->istat, ISTAT_ABRT);
+    /* Eat interrupts until we find what we're looking for */
+    for (;;) {
+       istat = NCR53c7x0_read8 (hostdata->istat);
+       if (istat & ISTAT_SIP) {
+           if ((hostdata->chip / 100) == 8) {
+               tmp = NCR53c7x0_read8(SIST0_REG_800);
+               udelay(1);
+               tmp = NCR53c7x0_read8(SIST1_REG_800);
+           } else {
+               tmp = NCR53c7x0_read8(SSTAT0_REG);
+           }
+       } else if (istat & ISTAT_DIP) {
+            NCR53c7x0_write8(hostdata->istat, 0);
+           tmp = NCR53c7x0_read8(DSTAT_REG);
+           if (tmp & DSTAT_ABRT)
+               break;
+           else
+               panic("scsi%d: could not halt NCR chip\n", host->host_no);
+       }
+    }
+    hostdata->state = STATE_HALTED;
+    restore_flags(flags);
+    return 0;
+}
+
+#ifdef MODULE
+int NCR53c7x0_release(struct Scsi_Host *host) {
+    shutdown (host);
+/* FIXME : need to recursively free tpnt structure */
+    if (host->irq != IRQ_NONE)
+       {
+           int irq_count;
+           struct Scsi_Host *tmp;
+           for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next)
+               if (tmp->hostt == the_template && tmp->irq == host->irq)
+                   ++irq_count;
+           if (irq_count == 1)
+               free_irq(host->irq);
+       }
+    if (host->dma_channel != DMA_NONE)
+       free_dma(host->dma_channel);
+    return 1;
+}
+Scsi_Host_Template driver_template = NCR53c7xx;
+#include "scsi_module.c"
+#endif /* def MODULE */
index bc9f0731cf93baa43e9d95ad7b05e8ef201f03e4..a216b02c5b1ab17233d6e89e9d813b82024127ef 100644 (file)
  * array.
  */
 
-#ifdef HOSTS_C 
+#if defined(HOSTS_C) || defined(MODULE)
 #include <linux/scsicam.h>
 extern int NCR53c7xx_abort(Scsi_Cmnd *);
 extern int NCR53c7xx_detect(Scsi_Host_Template *tpnt);
 extern int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 extern int NCR53c7xx_reset(Scsi_Cmnd *);
-
-#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, 127 /* old SG_ALL */,            \
-       /* cmd per lun */ 1 , 0, 0, DISABLE_CLUSTERING}
+#ifdef MODULE
+extern int NCR53c7xx_release(struct Scsi_Host *);
 #else
+#define NCR53c7xx_release NULL
+#endif
+
+#define NCR53c7xx {NULL, NULL, "NCR53c{7,8}xx (rel 4)", NCR53c7xx_detect,      \
+       NULL, /* info */ NULL, /* command, depricated */ NULL,          \
+       NCR53c7xx_queue_command, NCR53c7xx_abort, NCR53c7xx_reset,      \
+        NULL /* slave attach */, scsicam_bios_param, /* can queue */ 1, \
+       /* id */ 7, 127 /* old SG_ALL */, /* cmd per lun */ 1 ,         \
+        /* present */ 0, /* unchecked isa dma */ 0, DISABLE_CLUSTERING} 
+#endif /* defined(HOSTS_C) || defined(MODULE) */ 
+
+#ifndef HOSTS_C
 /* Register addresses, ordered numerically */
 
 
@@ -932,6 +939,9 @@ struct NCR53c7x0_table_indirect {
 
 struct NCR53c7x0_cmd {
     void *real;                                /* Real, unaligned address */
+    void (* free)(void *);             /* Command to deallocate; NULL
+                                          for structures allocated with
+                                          scsi_register, etc. */
     Scsi_Cmnd *cmd;                    /* Associated Scsi_Cmnd 
                                           structure, Scsi_Cmnd points
                                           at NCR53c7x0_cmd using 
@@ -949,7 +959,11 @@ struct NCR53c7x0_cmd {
                                         */
 
 
-    struct NCR53c7x0_cmd *next, *prev; /* Linux maintained lists */
+    volatile struct NCR53c7x0_cmd *next, *prev;        
+                                        /* Linux maintained lists.  Note that
+                                          hostdata->free is a singly linked
+                                          list; the rest are doubly linked */
+                                        
 
 
     unsigned long *data_transfer_start;        /* Start of data transfer routines */
@@ -986,10 +1000,12 @@ struct NCR53c7x0_break {
 /* Indicates that the NCR is executing other code. */
 #define STATE_RUNNING  2               
 /* 
- * Indicates that the NCR was being aborted.  Only used when running 
- * NCR53c700 compatible scripts.  
+ * Indicates that the NCR was being aborted.
  */
 #define STATE_ABORTING 3
+/* 
+ * Indicates that the NCR was successfully aborted. */
+#define STATE_ABORTED 4
     
 
 /* 
@@ -1072,6 +1088,7 @@ struct NCR53c7x0_hostdata {
 
     int (* dstat_sir_intr)(struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
 
+    long dsa_size; /* Size of DSA structure */
 
     /*
      * Location of DSA fields for the SCSI SCRIPT corresponding to this 
@@ -1160,11 +1177,13 @@ struct NCR53c7x0_hostdata {
        *breakpoint_current;            /* Current breakpoint being stepped 
                                           through, NULL if we are running 
                                           normally. */
+#ifdef NCR_DEBUG
     int debug_size;                    /* Size of debug buffer */
     volatile int debug_count;          /* Current data count */
     volatile char *debug_buf;          /* Output ring buffer */
     volatile char *debug_write;                /* Current write pointer */
     volatile char *debug_read;         /* Current read pointer */
+#endif /* def NCR_DEBUG */
 
     /* XXX - primitive debugging junk, remove when working ? */
     int debug_print_limit;             /* Number of commands to print
@@ -1203,6 +1222,21 @@ struct NCR53c7x0_hostdata {
                                                   nexus, ONLY valid for
                                                   NCR53c700/NCR53c700-66
                                                 */
+
+    volatile struct NCR53c7x0_cmd *spare;      /* pointer to spare,
+                                                  allocated at probe time,
+                                                  which we can use for 
+                                                  initialization */
+    volatile struct NCR53c7x0_cmd *free;
+    int max_cmd_size;                          /* Maximum size of NCR53c7x0_cmd
+                                                  based on number of 
+                                                  scatter/gather segments, etc.
+                                                  */
+    volatile int num_cmds;                     /* Number of commands 
+                                                  allocated */
+    volatile unsigned char cmd_allocated[8];   /* Have we allocated commands
+                                                  for this target yet?  If not,
+                                                  do so ASAP */
     volatile unsigned char busy[8][8];         /* number of commands 
                                                   executing on each target
                                                 */
@@ -1226,13 +1260,21 @@ struct NCR53c7x0_hostdata {
     volatile unsigned char msg_buf[16];                /* buffer for messages
                                                   other than the command
                                                   complete message */
-    volatile struct NCR53c7x0_cmd *reconnect_dsa_head; 
+    volatile unsigned char *reconnect_dsa_head;        
                                                /* disconnected commands,
                                                   maintained by NCR */
     /* Data identifying nexus we are trying to match during reselection */
     volatile unsigned char reselected_identify; /* IDENTIFY message */
     volatile unsigned char reselected_tag;     /* second byte of queue tag 
                                                   message or 0 */
+    /* These were static variables before we moved them */
+
+    long NCR53c7xx_zero;
+    long NCR53c7xx_sink;
+    char NCR53c7xx_msg_reject;
+    char NCR53c7xx_msg_abort;
+    char NCR53c7xx_msg_nop;
+
     int script_count;                          /* Size of script in longs */
     unsigned long script[0];                   /* Relocated SCSI script */
 
index b648fe94dcda6a65c3cc12b92b18435f671c7082..52ab39b116c561e11d5b8fc6784bf836436de246 100644 (file)
@@ -221,10 +221,10 @@ ABSOLUTE int_test_1 = 0x04000000          ; Test 1 complete
 ABSOLUTE int_test_2 = 0x04010000               ; Test 2 complete
 ABSOLUTE int_test_3 = 0x04020000               ; Test 3 complete
                                                
-EXTERNAL NCR53c7xx_msg_abort           ; Pointer to abort message
-EXTERNAL NCR53c7xx_msg_reject          ; Pointer to reject message
-EXTERNAL NCR53c7xx_zero                        ; long with zero in it, use for source
-EXTERNAL NCR53c7xx_sink                        ; long to dump worthless data in
+ABSOLUTE NCR53c7xx_msg_abort = 0       ; Pointer to abort message
+ABSOLUTE NCR53c7xx_msg_reject = 0       ; Pointer to reject message
+ABSOLUTE NCR53c7xx_zero        = 0             ; long with zero in it, use for source
+ABSOLUTE NCR53c7xx_sink = 0            ; long to dump worthless data in
 
 ; Pointer to final bytes of multi-byte messages
 ABSOLUTE msg_buf = 0
@@ -881,13 +881,23 @@ selected:
 wait_reselect_failed:
 ; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
     MOVE CTEST2 & 0x40 TO SFBR 
-    JUMP selected, IF NOT 0x40
+    JUMP schedule, IF 0x40
+    MOVE SIST0 & 0x20 TO SFBR
+    JUMP selected, IF 0x20
+; FIXME : Something bogus happened, and we shouldn't fail silently.
     JUMP schedule
 
 select_failed:
-    MOVE ISTAT & 0x20 TO SFBR
-    JUMP reselected, IF NOT 0x20
-    MOVE ISTAT & 0xdf TO ISTAT
+; If SIGP is set, the user just gave us another command, and
+; we should restart or return to the scheduler.
+; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
+    MOVE CTEST2 & 0x40 TO SFBR 
+    JUMP select, IF 0x40
+; Otherwise, mask the selected and reselected bits off SIST0
+    MOVE SIST0 & 0x30 TO SFBR
+    JUMP selected, IF 0x20
+    JUMP reselected, IF 0x10 
+; FIXME : Something bogus happened, and we shouldn't fail silently.
     JUMP schedule
 
 ;
@@ -980,7 +990,10 @@ no_source_data:
 ; If DSP points here, and a phase mismatch is encountered, we need to 
 ; do a bus reset.
 ;
+    
+    MOVE SCNTL2 & 0x7f TO SCNTL2
     MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
+    WAIT DISCONNECT
     INT int_norm_aborted
 
 ;
index e2c80503722f8bcc30dd54f0b35ce6819456b25b..e74804f6edd84e9dd615ac3c232477dee46c61ce 100644 (file)
@@ -127,7 +127,7 @@ at 0x00000008 : */  0x78380000,0x00000000,
 /*
        CALL scratch_to_dsa
 
-at 0x0000000a : */     0x88080000,0x00000800,
+at 0x0000000a : */     0x88080000,0x00000830,
 /*
        JUMP reselected_check_next
 
@@ -283,10 +283,10 @@ ABSOLUTE int_test_1 = 0x04000000          ; Test 1 complete
 ABSOLUTE int_test_2 = 0x04010000               ; Test 2 complete
 ABSOLUTE int_test_3 = 0x04020000               ; Test 3 complete
                                                
-EXTERNAL NCR53c7xx_msg_abort           ; Pointer to abort message
-EXTERNAL NCR53c7xx_msg_reject          ; Pointer to reject message
-EXTERNAL NCR53c7xx_zero                        ; long with zero in it, use for source
-EXTERNAL NCR53c7xx_sink                        ; long to dump worthless data in
+ABSOLUTE NCR53c7xx_msg_abort = 0       ; Pointer to abort message
+ABSOLUTE NCR53c7xx_msg_reject = 0       ; Pointer to reject message
+ABSOLUTE NCR53c7xx_zero        = 0             ; long with zero in it, use for source
+ABSOLUTE NCR53c7xx_sink = 0            ; long to dump worthless data in
 
 ; Pointer to final bytes of multi-byte messages
 ABSOLUTE msg_buf = 0
@@ -325,7 +325,7 @@ dsa_schedule:
 ;
     CALL dsa_to_scratch
 
-at 0x0000002d : */     0x88080000,0x000007b8,
+at 0x0000002d : */     0x88080000,0x000007e8,
 /*
 ; XXX - we need to deal with the NCR53c710, which lacks an add with
 ;      carry instruction, by moving around the DSA alignment to avoid
@@ -370,7 +370,7 @@ at 0x0000003e : */  0xc0000004,0x00000000,0x00000000,
 ; And update the head pointer.
     CALL dsa_to_scratch
 
-at 0x00000041 : */     0x88080000,0x000007b8,
+at 0x00000041 : */     0x88080000,0x000007e8,
 /*
     MOVE dmode_ncr_to_memory TO DMODE  
 
@@ -422,7 +422,7 @@ at 0x00000051 : */  0x78380000,0x00000000,
 
     CALL scratch_to_dsa
 
-at 0x00000053 : */     0x88080000,0x00000800,
+at 0x00000053 : */     0x88080000,0x00000830,
 /*
 
 
@@ -514,7 +514,7 @@ at 0x00000065 : */  0x60000200,0x00000000,
 
     SELECT ATN FROM dsa_select, select_failed
 
-at 0x00000067 : */     0x4300003c,0x00000694,
+at 0x00000067 : */     0x4300003c,0x000006a4,
 /*
     JUMP select_msgout, WHEN MSG_OUT
 
@@ -539,7 +539,7 @@ at 0x0000006b : */  0x1e000000,0x00000040,
 
     CALL dsa_to_scratch
 
-at 0x0000006d : */     0x88080000,0x000007b8,
+at 0x0000006d : */     0x88080000,0x000007e8,
 /*
 
     MOVE SCRATCH0 + dsa_next TO SCRATCH0
@@ -711,7 +711,7 @@ at 0x00000099 : */  0x80080000,0x00000234,
 do_dataout:
     CALL dsa_to_scratch
 
-at 0x0000009b : */     0x88080000,0x000007b8,
+at 0x0000009b : */     0x88080000,0x000007e8,
 /*
     MOVE SCRATCH0 + dsa_dataout TO SCRATCH0    
 
@@ -756,7 +756,7 @@ at 0x000000af : */  0x80080000,0x00000000,
 do_datain:
     CALL dsa_to_scratch
 
-at 0x000000b1 : */     0x88080000,0x000007b8,
+at 0x000000b1 : */     0x88080000,0x000007e8,
 /*
     MOVE SCRATCH0 + dsa_datain TO SCRATCH0     
 
@@ -1100,7 +1100,7 @@ at 0x00000130 : */        0x60000040,0x00000000,
 /*
     MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT
 
-at 0x00000132 : */     0x0e000001,((unsigned long)&NCR53c7xx_msg_reject),
+at 0x00000132 : */     0x0e000001,0x00000000,
 /*
     RETURN
 
@@ -1295,7 +1295,7 @@ at 0x0000015a : */        0x0f000001,0x00000000,
 reselected_notag:    
     MOVE MEMORY 1, NCR53c7xx_zero, reselected_tag
 
-at 0x0000015c : */     0xc0000001,((unsigned long)&NCR53c7xx_zero),0x00000000,
+at 0x0000015c : */     0xc0000001,0x00000000,0x00000000,
 /*
 
 
@@ -1317,7 +1317,7 @@ at 0x00000164 : */        0x78380000,0x00000000,
 /*
     CALL scratch_to_dsa
 
-at 0x00000166 : */     0x88080000,0x00000800,
+at 0x00000166 : */     0x88080000,0x00000830,
 /*
 
     ; Fix the update-next pointer so that the reconnect_dsa_head
@@ -1477,31 +1477,53 @@ wait_reselect_failed:
 
 at 0x0000019f : */     0x741a4000,0x00000000,
 /*
-    JUMP selected, IF NOT 0x40
+    JUMP schedule, IF 0x40
 
-at 0x000001a1 : */     0x80040040,0x00000674,
+at 0x000001a1 : */     0x800c0040,0x00000130,
 /*
+    MOVE SIST0 & 0x20 TO SFBR
+
+at 0x000001a3 : */     0x74422000,0x00000000,
+/*
+    JUMP selected, IF 0x20
+
+at 0x000001a5 : */     0x800c0020,0x00000674,
+/*
+; FIXME : Something bogus happened, and we shouldn't fail silently.
     JUMP schedule
 
-at 0x000001a3 : */     0x80080000,0x00000130,
+at 0x000001a7 : */     0x80080000,0x00000130,
 /*
 
 select_failed:
-    MOVE ISTAT & 0x20 TO SFBR
+; If SIGP is set, the user just gave us another command, and
+; we should restart or return to the scheduler.
+; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
+    MOVE CTEST2 & 0x40 TO SFBR 
+
+at 0x000001a9 : */     0x741a4000,0x00000000,
+/*
+    JUMP select, IF 0x40
 
-at 0x000001a5 : */     0x74142000,0x00000000,
+at 0x000001ab : */     0x800c0040,0x00000194,
 /*
-    JUMP reselected, IF NOT 0x20
+; Otherwise, mask the selected and reselected bits off SIST0
+    MOVE SIST0 & 0x30 TO SFBR
 
-at 0x000001a7 : */     0x80040020,0x00000568,
+at 0x000001ad : */     0x74423000,0x00000000,
 /*
-    MOVE ISTAT & 0xdf TO ISTAT
+    JUMP selected, IF 0x20
 
-at 0x000001a9 : */     0x7c14df00,0x00000000,
+at 0x000001af : */     0x800c0020,0x00000674,
 /*
+    JUMP reselected, IF 0x10 
+
+at 0x000001b1 : */     0x800c0010,0x00000568,
+/*
+; FIXME : Something bogus happened, and we shouldn't fail silently.
     JUMP schedule
 
-at 0x000001ab : */     0x80080000,0x00000130,
+at 0x000001b3 : */     0x80080000,0x00000130,
 /*
 
 ;
@@ -1525,11 +1547,11 @@ ENTRY test_1
 test_1:
     MOVE MEMORY 4, test_src, test_dest
 
-at 0x000001ad : */     0xc0000004,0x00000000,0x00000000,
+at 0x000001b5 : */     0xc0000004,0x00000000,0x00000000,
 /*
     INT int_test_1
 
-at 0x000001b0 : */     0x98080000,0x04000000,
+at 0x000001b8 : */     0x98080000,0x04000000,
 /*
 
 ;
@@ -1540,61 +1562,61 @@ ENTRY test_2
 test_2:
     CLEAR TARGET
 
-at 0x000001b2 : */     0x60000200,0x00000000,
+at 0x000001ba : */     0x60000200,0x00000000,
 /*
     SELECT ATN FROM 0, test_2_fail
 
-at 0x000001b4 : */     0x43000000,0x00000720,
+at 0x000001bc : */     0x43000000,0x00000740,
 /*
     JUMP test_2_msgout, WHEN MSG_OUT
 
-at 0x000001b6 : */     0x860b0000,0x000006e0,
+at 0x000001be : */     0x860b0000,0x00000700,
 /*
 ENTRY test_2_msgout
 test_2_msgout:
     MOVE FROM 8, WHEN MSG_OUT
 
-at 0x000001b8 : */     0x1e000000,0x00000008,
+at 0x000001c0 : */     0x1e000000,0x00000008,
 /*
     MOVE FROM 16, WHEN CMD 
 
-at 0x000001ba : */     0x1a000000,0x00000010,
+at 0x000001c2 : */     0x1a000000,0x00000010,
 /*
     MOVE FROM 24, WHEN DATA_IN
 
-at 0x000001bc : */     0x19000000,0x00000018,
+at 0x000001c4 : */     0x19000000,0x00000018,
 /*
     MOVE FROM 32, WHEN STATUS
 
-at 0x000001be : */     0x1b000000,0x00000020,
+at 0x000001c6 : */     0x1b000000,0x00000020,
 /*
     MOVE FROM 40, WHEN MSG_IN
 
-at 0x000001c0 : */     0x1f000000,0x00000028,
+at 0x000001c8 : */     0x1f000000,0x00000028,
 /*
     MOVE SCNTL2 & 0x7f TO SCNTL2
 
-at 0x000001c2 : */     0x7c027f00,0x00000000,
+at 0x000001ca : */     0x7c027f00,0x00000000,
 /*
     CLEAR ACK
 
-at 0x000001c4 : */     0x60000040,0x00000000,
+at 0x000001cc : */     0x60000040,0x00000000,
 /*
     WAIT DISCONNECT
 
-at 0x000001c6 : */     0x48000000,0x00000000,
+at 0x000001ce : */     0x48000000,0x00000000,
 /*
 test_2_fail:
     INT int_test_2
 
-at 0x000001c8 : */     0x98080000,0x04010000,
+at 0x000001d0 : */     0x98080000,0x04010000,
 /*
 
 ENTRY debug_break
 debug_break:
     INT int_debug_break
 
-at 0x000001ca : */     0x98080000,0x03000000,
+at 0x000001d2 : */     0x98080000,0x03000000,
 /*
 
 ;
@@ -1610,26 +1632,26 @@ ENTRY target_abort
 target_abort:
     SET TARGET
 
-at 0x000001cc : */     0x58000200,0x00000000,
+at 0x000001d4 : */     0x58000200,0x00000000,
 /*
     DISCONNECT
 
-at 0x000001ce : */     0x48000000,0x00000000,
+at 0x000001d6 : */     0x48000000,0x00000000,
 /*
     CLEAR TARGET
 
-at 0x000001d0 : */     0x60000200,0x00000000,
+at 0x000001d8 : */     0x60000200,0x00000000,
 /*
     JUMP schedule
 
-at 0x000001d2 : */     0x80080000,0x00000130,
+at 0x000001da : */     0x80080000,0x00000130,
 /*
     
 ENTRY initiator_abort
 initiator_abort:
     SET ATN
 
-at 0x000001d4 : */     0x58000008,0x00000000,
+at 0x000001dc : */     0x58000008,0x00000000,
 /*
 ; In order to abort the currently established nexus, we 
 ; need to source/sink up to one byte of data in any SCSI phase, 
@@ -1637,60 +1659,69 @@ at 0x000001d4 : */      0x58000008,0x00000000,
 ; false->true
     JUMP no_eat_cmd, WHEN NOT CMD
 
-at 0x000001d6 : */     0x82030000,0x00000768,
+at 0x000001de : */     0x82030000,0x00000788,
 /*
     MOVE 1, NCR53c7xx_zero, WHEN CMD
 
-at 0x000001d8 : */     0x0a000001,((unsigned long)&NCR53c7xx_zero),
+at 0x000001e0 : */     0x0a000001,0x00000000,
 /*
 no_eat_cmd:
     JUMP no_eat_msg, WHEN NOT MSG_IN
 
-at 0x000001da : */     0x87030000,0x00000778,
+at 0x000001e2 : */     0x87030000,0x00000798,
 /*
     MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
 
-at 0x000001dc : */     0x0f000001,((unsigned long)&NCR53c7xx_sink),
+at 0x000001e4 : */     0x0f000001,0x00000000,
 /*
 no_eat_msg:
     JUMP no_eat_data, WHEN NOT DATA_IN
 
-at 0x000001de : */     0x81030000,0x00000788,
+at 0x000001e6 : */     0x81030000,0x000007a8,
 /*
     MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
 
-at 0x000001e0 : */     0x09000001,((unsigned long)&NCR53c7xx_sink),
+at 0x000001e8 : */     0x09000001,0x00000000,
 /*
 no_eat_data:
     JUMP no_eat_status, WHEN NOT STATUS
 
-at 0x000001e2 : */     0x83030000,0x00000798,
+at 0x000001ea : */     0x83030000,0x000007b8,
 /*
     MOVE 1, NCR53c7xx_sink, WHEN STATUS
 
-at 0x000001e4 : */     0x0b000001,((unsigned long)&NCR53c7xx_sink),
+at 0x000001ec : */     0x0b000001,0x00000000,
 /*
 no_eat_status:
     JUMP no_source_data, WHEN NOT DATA_OUT
 
-at 0x000001e6 : */     0x80030000,0x000007a8,
+at 0x000001ee : */     0x80030000,0x000007c8,
 /*
     MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
 
-at 0x000001e8 : */     0x08000001,((unsigned long)&NCR53c7xx_zero),
+at 0x000001f0 : */     0x08000001,0x00000000,
 /*
 no_source_data:
 ;
 ; If DSP points here, and a phase mismatch is encountered, we need to 
 ; do a bus reset.
 ;
+    
+    MOVE SCNTL2 & 0x7f TO SCNTL2
+
+at 0x000001f2 : */     0x7c027f00,0x00000000,
+/*
     MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
 
-at 0x000001ea : */     0x0e000001,((unsigned long)&NCR53c7xx_msg_abort),
+at 0x000001f4 : */     0x0e000001,0x00000000,
+/*
+    WAIT DISCONNECT
+
+at 0x000001f6 : */     0x48000000,0x00000000,
 /*
     INT int_norm_aborted
 
-at 0x000001ec : */     0x98080000,0x02040000,
+at 0x000001f8 : */     0x98080000,0x02040000,
 /*
 
 ;
@@ -1711,77 +1742,101 @@ at 0x000001ec : */     0x98080000,0x02040000,
 dsa_to_scratch:
     MOVE DSA0 TO SFBR
 
-at 0x000001ee : */     0x72100000,0x00000000,
+at 0x000001fa : */     0x72100000,0x00000000,
 /*
     MOVE SFBR TO SCRATCH0
 
-at 0x000001f0 : */     0x6a340000,0x00000000,
+at 0x000001fc : */     0x6a340000,0x00000000,
 /*
     MOVE DSA1 TO SFBR
 
-at 0x000001f2 : */     0x72110000,0x00000000,
+at 0x000001fe : */     0x72110000,0x00000000,
 /*
     MOVE SFBR TO SCRATCH1
 
-at 0x000001f4 : */     0x6a350000,0x00000000,
+at 0x00000200 : */     0x6a350000,0x00000000,
 /*
     MOVE DSA2 TO SFBR
 
-at 0x000001f6 : */     0x72120000,0x00000000,
+at 0x00000202 : */     0x72120000,0x00000000,
 /*
     MOVE SFBR TO SCRATCH2
 
-at 0x000001f8 : */     0x6a360000,0x00000000,
+at 0x00000204 : */     0x6a360000,0x00000000,
 /*
     MOVE DSA3 TO SFBR
 
-at 0x000001fa : */     0x72130000,0x00000000,
+at 0x00000206 : */     0x72130000,0x00000000,
 /*
     MOVE SFBR TO SCRATCH3
 
-at 0x000001fc : */     0x6a370000,0x00000000,
+at 0x00000208 : */     0x6a370000,0x00000000,
 /*
     RETURN
 
-at 0x000001fe : */     0x90080000,0x00000000,
+at 0x0000020a : */     0x90080000,0x00000000,
 /*
 
 scratch_to_dsa:
     MOVE SCRATCH0 TO SFBR
 
-at 0x00000200 : */     0x72340000,0x00000000,
+at 0x0000020c : */     0x72340000,0x00000000,
 /*
     MOVE SFBR TO DSA0
 
-at 0x00000202 : */     0x6a100000,0x00000000,
+at 0x0000020e : */     0x6a100000,0x00000000,
 /*
     MOVE SCRATCH1 TO SFBR
 
-at 0x00000204 : */     0x72350000,0x00000000,
+at 0x00000210 : */     0x72350000,0x00000000,
 /*
     MOVE SFBR TO DSA1
 
-at 0x00000206 : */     0x6a110000,0x00000000,
+at 0x00000212 : */     0x6a110000,0x00000000,
 /*
     MOVE SCRATCH2 TO SFBR
 
-at 0x00000208 : */     0x72360000,0x00000000,
+at 0x00000214 : */     0x72360000,0x00000000,
 /*
     MOVE SFBR TO DSA2
 
-at 0x0000020a : */     0x6a120000,0x00000000,
+at 0x00000216 : */     0x6a120000,0x00000000,
 /*
     MOVE SCRATCH3 TO SFBR
 
-at 0x0000020c : */     0x72370000,0x00000000,
+at 0x00000218 : */     0x72370000,0x00000000,
 /*
     MOVE SFBR TO DSA3
 
-at 0x0000020e : */     0x6a130000,0x00000000,
+at 0x0000021a : */     0x6a130000,0x00000000,
 /*
     RETURN
 
-at 0x00000210 : */     0x90080000,0x00000000,
+at 0x0000021c : */     0x90080000,0x00000000,
+};
+
+#define A_NCR53c7xx_msg_abort  0x00000000
+unsigned long A_NCR53c7xx_msg_abort_used[] = {
+       0x000001f5,
+};
+
+#define A_NCR53c7xx_msg_reject 0x00000000
+unsigned long A_NCR53c7xx_msg_reject_used[] = {
+       0x00000133,
+};
+
+#define A_NCR53c7xx_sink       0x00000000
+unsigned long A_NCR53c7xx_sink_used[] = {
+       0x000001e5,
+       0x000001e9,
+       0x000001ed,
+};
+
+#define A_NCR53c7xx_zero       0x00000000
+unsigned long A_NCR53c7xx_zero_used[] = {
+       0x0000015d,
+       0x000001e1,
+       0x000001f1,
 };
 
 #define A_addr_scratch 0x00000000
@@ -1940,7 +1995,7 @@ unsigned long A_dsa_temp_target_used[] = {
 
 #define A_int_debug_break      0x03000000
 unsigned long A_int_debug_break_used[] = {
-       0x000001cb,
+       0x000001d3,
 };
 
 #define A_int_debug_dsa_loaded 0x03030000
@@ -2013,7 +2068,7 @@ unsigned long A_int_msg_wdtr_used[] = {
 
 #define A_int_norm_aborted     0x02040000
 unsigned long A_int_norm_aborted_used[] = {
-       0x000001ed,
+       0x000001f9,
 };
 
 #define A_int_norm_command_complete    0x02020000
@@ -2038,12 +2093,12 @@ unsigned long A_int_norm_select_complete_used[] = {
 
 #define A_int_test_1   0x04000000
 unsigned long A_int_test_1_used[] = {
-       0x000001b1,
+       0x000001b9,
 };
 
 #define A_int_test_2   0x04010000
 unsigned long A_int_test_2_used[] = {
-       0x000001c9,
+       0x000001d1,
 };
 
 #define A_int_test_3   0x04020000
@@ -2087,26 +2142,26 @@ unsigned long A_reselected_tag_used[] = {
 
 #define A_test_dest    0x00000000
 unsigned long A_test_dest_used[] = {
-       0x000001af,
+       0x000001b7,
 };
 
 #define A_test_src     0x00000000
 unsigned long A_test_src_used[] = {
-       0x000001ae,
+       0x000001b6,
 };
 
 #define Ent_accept_message     0x000004d8
 #define Ent_cmdout_cmdout      0x0000022c
 #define Ent_command_complete   0x00000508
 #define Ent_command_complete_msgin     0x00000518
-#define Ent_debug_break        0x00000728
+#define Ent_debug_break        0x00000748
 #define Ent_dsa_code_check_reselect    0x00000038
 #define Ent_dsa_code_template  0x00000000
 #define Ent_dsa_code_template_end      0x000000b4
 #define Ent_dsa_jump_resume    0x00000088
 #define Ent_dsa_schedule       0x000000b4
 #define Ent_dsa_zero   0x00000090
-#define Ent_initiator_abort    0x00000750
+#define Ent_initiator_abort    0x00000770
 #define Ent_msg_in     0x00000354
 #define Ent_other_transfer     0x0000031c
 #define Ent_reject_message     0x000004b8
@@ -2115,10 +2170,10 @@ unsigned long A_test_src_used[] = {
 #define Ent_schedule   0x00000130
 #define Ent_select     0x00000194
 #define Ent_select_msgout      0x000001ac
-#define Ent_target_abort       0x00000730
-#define Ent_test_1     0x000006b4
-#define Ent_test_2     0x000006c8
-#define Ent_test_2_msgout      0x000006e0
+#define Ent_target_abort       0x00000750
+#define Ent_test_1     0x000006d4
+#define Ent_test_2     0x000006e8
+#define Ent_test_2_msgout      0x00000700
 unsigned long LABELPATCHES[] = {
        0x00000002,
        0x0000000b,
@@ -2178,18 +2233,21 @@ unsigned long LABELPATCHES[] = {
        0x0000017a,
        0x00000191,
        0x000001a2,
-       0x000001a4,
+       0x000001a6,
        0x000001a8,
        0x000001ac,
-       0x000001b5,
-       0x000001b7,
-       0x000001d3,
-       0x000001d7,
+       0x000001b0,
+       0x000001b2,
+       0x000001b4,
+       0x000001bd,
+       0x000001bf,
        0x000001db,
        0x000001df,
        0x000001e3,
        0x000001e7,
+       0x000001eb,
+       0x000001ef,
 };
 
-unsigned long INSTRUCTIONS     = 0x000000fe;
-unsigned long PATCHES  = 0x00000045;
+unsigned long INSTRUCTIONS     = 0x00000104;
+unsigned long PATCHES  = 0x00000048;
index a6645b3dae41b1264aaa43039cc577f2c971dbb0..9f0bf58b0c535951618a29895cfee4667b7d4815 100644 (file)
@@ -1,3 +1,7 @@
+#undef A_NCR53c7xx_msg_abort
+#undef A_NCR53c7xx_msg_reject
+#undef A_NCR53c7xx_sink
+#undef A_NCR53c7xx_zero
 #undef A_addr_scratch
 #undef A_addr_sfbr
 #undef A_addr_temp
index 95e566786dd5844116990e73514900990947bfc7..7a381fef0ed9e02f5cf5de3a69b6db4a76b02182 100644 (file)
@@ -1,3 +1,296 @@
+Wed Apr 12 15:25:52 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.2.5 released.
+
+       * buslogic.c: Update to version 1.15 (From Dave G, I expect).
+       Fixed interrupt routine to avoid races when handling multiple
+       complete commands per interrupt.  Seems to come up with faster
+       cards.
+
+       * eata_dma.c: Modularize.  Update to 2.3.5r.
+
+       * scsi.c: If we get a FMK, EOM, or ILI when attempting to scan
+       the bus, assume that it was just noise on the bus, and ignore
+       the device.
+
+       * scsi.h: Update and add a bunch of missing commands which we
+       were never using.
+
+       * sd.c: Use restore_flags in do_sd_request - this may result in
+       latency conditions, but it gets rid of races and crashes.
+       Do not save flags again when searching for a second command to
+       queue.
+
+       * st.c: Use bytes, not STP->buffer->buffer_size when reading
+       from tape.
+
+
+Tue Apr  4 09:42:08 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.2.4 released.
+
+       * st.c: Fix typo - restoring wrong flags.
+
+Wed Mar 29 06:55:12 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.2.3 released.
+
+       * st.c: Perform some waiting operations with interrupts off.
+       Is this correct???
+
+Wed Mar 22 10:34:26 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.2.2 released.
+
+       * aha152x.c: Modularize.  Add support for PCMCIA.
+
+       * eata.c: Update to version 2.0.  Fixed bug preventing media
+       detection.  If scsi_register_host returns NULL, fail gracefully.
+
+       * scsi.c: Detect as NEC (for photo-cd purposes) for the 84
+       and 25 models as "NEC_OLDCDR".
+
+       * scsi.h: Add define for NEC_OLDCDR
+
+       * sr.c: Add handling for NEC_OLDCDR.  Treat as unknown.
+
+       * u14-34f.c: Update to version 2.0.  Fixed same bug as in
+       eata.c.
+
+
+Mon Mar  6 11:11:20 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.2.0 released.  Yeah!!!
+
+       * Minor spelling/punctuation changes throughout.  Nothing
+       substantive.
+
+Mon Feb 20 21:33:03 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.1.95 released.
+
+       * qlogic.c: Update to version 0.41.
+
+       * seagate.c: Change some message to be more descriptive about what
+       we detected.
+
+       * sr.c: spelling/whitespace changes.
+
+Mon Feb 20 21:33:03 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.1.94 released.
+
+Mon Feb 20 08:57:17 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.1.93 released.
+
+       * hosts.h: Change io_port to long int from short.
+
+       * 53c7,8xx.c: crash on AEN fixed, SCSI reset is no longer a NOP,
+         NULL pointer panic on odd UDCs fixed, two bugs in diagnostic output 
+         fixed, should initialize correctly if left running, now loadable, 
+         new memory allocation, extraneous diagnostic output supressed,
+         splx() replaced with save/restore flags. [ Drew ]
+
+       * hosts.c, hosts.h, scsi_ioctl.c, sd.c, sd_ioctl.c, sg.c, sr.c,
+       sr_ioctl.c: Add special junk at end that Emacs will use for
+       formatting the file.
+
+       * qlogic.c: Update to v0.40a.  Improve parity handling.
+
+       * scsi.c: Add Hitachi DK312C to blacklist.  Change "};" to "}" in
+       many places.  Use scsi_init_malloc to get command block - may
+       need this to be dma compatible for some host adapters.
+       Restore interrupts after unregistering a host.
+
+       * sd.c: Use sti instead of restore flags - causes latency problems.
+
+       * seagate.c: Use controller_type to determine string used when
+       registering irq.
+
+       * sr.c: More photo-cd hacks to make sure we get the xa stuff right.
+       * sr.h, sr.c: Change is_xa to xa_flags field.
+
+       * st.c: Diable retries for write operations.
+
+Wed Feb 15 10:52:56 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.1.92 released.
+
+       * eata.c: Update to 1.17.
+
+       * eata_dma.c: Add more support for /proc/scsi, add HBA_interpret flag.
+
+       * hosts.c: If we remove last host registered, reuse host number.
+       When freeing memory from host being deregistered, free extra_bytes
+       too.
+
+       * scsi.c (scan_scsis): memset(SDpnt, 0) and set SCmd.device to SDpnt.
+       Change memory allocation to work around bugs in __get_dma_pages.
+       Do not free host if usage count is not zero (for modules).
+
+       * sr_ioctl.c: Increase IOCTL_TIMEOUT to 3000.
+
+       * st.c: Allow for ST_EXTRA_DEVS in st data structures.
+
+       * u14-34f.c: Update to 1.17.
+
+Thu Feb  9 10:11:16 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.1.91 released.
+
+       * eata.c: Update to 1.16.  Use wish_block instead of host->block.
+
+       * hosts.c: Initialize wish_block to 0.
+
+       * hosts.h: Add wish_block.
+
+       * scsi.c: Use wish_block as indicator that the host should be added
+       to block list.
+
+       * sg.c: Add SG_EXTRA_DEVS to number of slots.
+
+       * u14-34f.c: Use wish_block.
+
+Tue Feb  7 11:46:04 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.1.90 released.
+
+       * eata.c: Change naming from eata_* to eata2x_*.  Now at vers 1.15.
+       Update interrupt handler to take pt_regs as arg.  Allow blocking
+       even if loaded as module.  Initialize target_time_out array.
+       Do not put sti(); in timing loop.
+
+       * hosts.c: Do not reuse host numbers.
+       Use scsi_make_blocked_list to generate blocking list.
+
+       * script_asm.pl:  Beats me.  Don't know perl.  Something to do with
+       phase index.
+
+       * scsi.c (scsi_make_blocked_list): New function - code copied from
+       hosts.c.
+
+       * scsi.c: Update code to disable photo CD for Toshiba cdroms.
+       Use just manufacturer name, not model number.
+
+       * sr.c: Fix setting density for Toshiba drives.
+
+       * u14-34f.c: Clear target_time_out array during reset.
+
+Wed Feb  1 09:20:45 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.1.89 released.
+
+       * Makefile, u14-34f.c: Modulariz.e
+
+       * Makefile, eata.c: Modularize.  Now version 1.14
+
+       * NCR5380.c: Update interrupt handler with new arglist.  Minor
+       cleanups.
+
+       * eata_dma.c: Modularize.  Add hooks for /proc/scsi.  
+       New version 2.3.0a.
+       
+       * hosts.c: Initialize ->dma_channel and ->io_port when registering
+       a new host.
+
+       * qlogic.c: Modularize and add PCMCIA support.
+
+       * scsi.c: Add Hitachi to blacklist.
+
+       * scsi.c: Change default to no lun scan (too many problem devices).
+
+       * scsi.h: Define QUEUE_FULL condition.
+
+       * sd.c: Do not check for non-existant partition until after
+       new media check.
+
+       * sg.c: Undo previous change which was wrong.
+
+       * sr_ioctl.c: Increase IOCTL_TIMEOUT to 2000.
+
+       * st.c: Patches from Kai - improve filemark handling.
+
+Tue Jan 31 17:32:12 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.1.88 released.
+
+       * Throughout - spelling/grammar fixups.
+
+       * scsi.c: Make sure that all buffers are 16 byte aligned - some
+       drivers (buslogic) need this.
+
+       * scsi.c (scan_scsis): Remove message printed.
+
+       * scsi.c (scsi_init): Move message here.
+
+Mon Jan 30 06:40:25 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.1.87 released.
+
+       * sr.c: Photo-cd related changes. (Gerd Knorr??).
+
+       * st.c: Changes from Kai related to EOM detection.
+
+Mon Jan 23 23:53:10 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.1.86 released.
+
+       * 53c7,8xx.h: Change SG size to 127.
+
+       * eata_dma: Update to version 0i.
+
+       * scsi.c: Test for Toshiba XM-3401TA and exclude from detection
+       as toshiba drive - photo cd does not work with this drive.
+
+       * sr.c:  Update photocd code.
+
+Mon Jan 23 23:53:10 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.1.85 released.
+
+       * st.c, st_ioctl.c, sg.c, sd_ioctl.c, scsi_ioctl.c, hosts.c:
+       include linux/mm.h
+
+       * qlogic.c, buslogic.c, aha1542.c: Include linux/module.h.
+
+Sun Jan 22 22:08:46 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.1.84 released.
+
+       * Makefile: Support for loadable QLOGIC boards.
+
+       * aha152x.c: Update to version 1.8 from Juergen.
+
+       * eata_dma.c: Update from Michael Neuffer
+
+       * in2000.c: Fix biosparam to support large disks.
+
+       * qlogic.c: Minor changes (change sti -> restore_flags).
+
+Wed Jan 18 23:33:09 1995  Eric Youngdale  (eric@andante)
+
+       * Linux 1.1.83 released.
+
+       * aha1542.c(aha1542_intr_handle): Use arguments handed down to find
+       which irq.
+
+       * buslogic.c: Likewise.
+
+       * eata_dma.c: Use min of 2 cmd_per_lun for OCS_enabled boards.
+
+       * scsi.c: Make RECOVERED_ERROR a SUGGEST_IS_OK.
+
+       * sd.c: Fail if we are opening a non-existant partition.
+
+       * sr.c: Bump SR_TIMEOUT to 15000.
+       Do not probe for media size at boot time(hard on changers).
+       Flag device as needing sector size instead.
+
+       * sr_ioctl.c: Remove CDROMMULTISESSION_SYS ioctl.
+
+       * ultrastor.c: Fix bug in call to ultrastor_interrupt (wrong #args).
+
 Mon Jan 16 07:18:23 1995  Eric Youngdale  (eric@andante)
 
        * Linux 1.1.82 released.
index 15387c2fde123accbf6af4ec45756af27e20a5af..e90a96b057b19b05e8c677b746720acf321c57b3 100644 (file)
@@ -127,6 +127,8 @@ endif
 ifdef CONFIG_SCSI_NCR53C7xx
 SCSI_OBJS := $(SCSI_OBJS) 53c7,8xx.o 
 SCSI_SRCS := $(SCSI_SRCS) 53c7,8xx.c
+else
+SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) 53c7,8xx.o
 endif
 
 ifdef CONFIG_SCSI_PAS16
@@ -190,7 +192,7 @@ seagate.o: seagate.c
 
 53c8xx_d.h 53c8xx_u.h : 53c7,8xx.scr script_asm.pl
        ln 53c7,8xx.scr fake.c
-       $(CPP) -DCHIP=810 fake.c | grep -v ^# | perl script_asm.pl 
+       $(CPP) -traditional -DCHIP=810 fake.c | grep -v '^#' | perl script_asm.pl 
        mv script.h 53c8xx_d.h
        mv scriptu.h 53c8xx_u.h
        rm fake.c
index b3cfe7fcd44074dcc9fe2b621ca860d578427b2a..6c7e98af53be262b7eee653dca82506edf5829ba 100644 (file)
@@ -469,10 +469,7 @@ static void buslogic_interrupt(int irq, struct pt_regs * regs)
     interrupt_flags = inb(INTERRUPT(base));
 
     if (!(interrupt_flags & INTV))
-      {
-       buslogic_printk("interrupt received, but INTV not set\n");
-       return;
-      }
+      buslogic_printk("interrupt received, but INTV not set\n");
 
     /*
       Reset the Host Adapter Interrupt Register.  It appears to be
@@ -504,16 +501,27 @@ static void buslogic_interrupt(int irq, struct pt_regs * regs)
     while (mb[mbi].status != MBX_NOT_IN_USE && found < BUSLOGIC_MAILBOXES)
       {
        int mbo = (struct ccb *)mb[mbi].ccbptr - ccb;
-       int result = 0;
 
-       saved_mbo[found++] = mbo;
+       sctmp = HOSTDATA(shpnt)->sc[mbo];
+
+       /*
+         If sctmp has become NULL, higher level code must have aborted
+         this operation and called the necessary completion routine.
+       */
+
+       if (sctmp != NULL && mb[mbi].status != MBX_COMPLETION_NOT_FOUND)
+         {
+           int result = 0;
+
+           saved_mbo[found++] = mbo;
 
-       if (mb[mbi].status != MBX_COMPLETION_OK)
-         result = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
+           if (mb[mbi].status != MBX_COMPLETION_OK)
+             result = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
 
-       HOSTDATA(shpnt)->sc[mbo]->result = result;
+           sctmp->result = result;
 
-       mb[mbi].status = MBX_NOT_IN_USE;
+           mb[mbi].status = MBX_NOT_IN_USE;
+         }
 
        HOSTDATA(shpnt)->last_mbi_used = mbi;
 
@@ -535,6 +543,7 @@ static void buslogic_interrupt(int irq, struct pt_regs * regs)
       {
        int mbo = saved_mbo[i];
        sctmp = HOSTDATA(shpnt)->sc[mbo];
+       if (sctmp == NULL) continue;
        /*
          First, free any storage allocated for a scatter/gather
          data segment list.
@@ -542,14 +551,15 @@ static void buslogic_interrupt(int irq, struct pt_regs * regs)
        if (sctmp->host_scribble)
          scsi_free(sctmp->host_scribble, BUSLOGIC_SG_MALLOC);
        /*
-         Next, call the SCSI command completion handler.
+         Next, mark the SCSI Command as completed so it may be reused
+         for another command by buslogic_queuecommand.  This also signals
+         to buslogic_reset that the command is no longer active.
        */
-       sctmp->scsi_done(sctmp);
+       HOSTDATA(shpnt)->sc[mbo] = NULL;
        /*
-         Finally, mark the SCSI Command as completed so it may be reused
-         for another command by buslogic_queuecommand.
+         Finally, call the SCSI command completion handler.
        */
-       HOSTDATA(shpnt)->sc[mbo] = NULL;
+       sctmp->scsi_done(sctmp);
       }
 }
 
@@ -1344,7 +1354,7 @@ int buslogic_abort(Scsi_Cmnd *scpnt)
 #if 1
     static const unsigned char buscmd[] = { CMD_START_SCSI };
     struct mailbox *mb;
-    size_t mbi, mbo;
+    int mbi, mbo, last_mbi;
     unsigned long flags;
     unsigned int i;
 
@@ -1355,28 +1365,30 @@ int buslogic_abort(Scsi_Cmnd *scpnt)
     save_flags(flags);
     cli();
     mb = HOSTDATA(scpnt->host)->mb;
-    mbi = HOSTDATA(scpnt->host)->last_mbi_used + 1;
+    last_mbi = HOSTDATA(scpnt->host)->last_mbi_used;
+    mbi = last_mbi + 1;
     if (mbi >= 2 * BUSLOGIC_MAILBOXES)
        mbi = BUSLOGIC_MAILBOXES;
 
     do {
        if (mb[mbi].status != MBX_NOT_IN_USE)
            break;
+       last_mbi = mbi;
        mbi++;
        if (mbi >= 2 * BUSLOGIC_MAILBOXES)
            mbi = BUSLOGIC_MAILBOXES;
     } while (mbi != HOSTDATA(scpnt->host)->last_mbi_used);
-    restore_flags(flags);
 
     if (mb[mbi].status != MBX_NOT_IN_USE) {
-       buslogic_printk("lost interrupt discovered on irq %d"
+       buslogic_printk("lost interrupt discovered on irq %d"
                        " - attempting to recover...\n",
                        scpnt->host->irq);
-       {
-           buslogic_interrupt(scpnt->host->irq, NULL);
-           return SCSI_ABORT_SUCCESS;
-       }
+       HOSTDATA(scpnt->host)->last_mbi_used = last_mbi;
+       buslogic_interrupt(scpnt->host->irq, NULL);
+       restore_flags(flags);
+       return SCSI_ABORT_SUCCESS;
     }
+    restore_flags(flags);
 
     /* OK, no lost interrupt.  Try looking to see how many pending commands we
        think we have. */
index b7fd7606ba206b6df414bf30d176fbb9d06ee458..e103bc9f44195b89e2b603cc24f72cea648f2bf8 100644 (file)
@@ -710,7 +710,7 @@ int get_conf_PIO(struct eata_register *base, struct get_conf *buf)
            while (inb((uint) base + HA_RSTATUS) & HA_SDRQ) 
                inw((uint) base + HA_RDATA);
             if (warning == TRUE)
-                printk("Warning: HBA with IO on 0x%p dectected,\n"
+                printk("Warning: HBA with IO on 0x%p detected,\n"
                        "         this IO space is already allocated, probably by the IDE driver.\n"
                        "         This might lead to problems.", base);
            return (TRUE);
index 584a10d3298ec8824e0e546ea83ec623e7493911..cf8fe83cebb1d79ce628eb855bff7948e4bb5f54 100644 (file)
@@ -123,7 +123,7 @@ static int nfs_file_read(struct inode *inode, struct file *file, char *buf,
                if ((cache[i].inode_num == inode->i_ino)
                        && (cache[i].file_pos <= pos)
                        && (cache[i].file_pos + cache[i].len >= pos + count)
-                       && (abs(jiffies - cache[i].time) <= EXPIRE_CACHE))
+                       && (abs(jiffies - cache[i].time) < EXPIRE_CACHE))
                        break;
        if (i < READ_CACHE_SIZE) {
                ++cache[i].in_use;
index 6a80a7cf0fa5c738fc8231c2eb1c8c50b3d232fc..e06cc3e26b621e47bbf8551d7c2d426bd8168c90 100644 (file)
@@ -237,11 +237,10 @@ asmlinkage int sys_select( unsigned long *buffer )
        }
        current->timeout = timeout;
        i = do_select(n, &in, &out, &ex, &res_in, &res_out, &res_ex);
-       if (current->timeout > jiffies)
-               timeout = current->timeout - jiffies;
-       else
-               timeout = 0;
+       timeout = current->timeout - jiffies - 1;
        current->timeout = 0;
+       if ((long) timeout < 0)
+               timeout = 0;
        if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
                put_fs_long(timeout/HZ, (unsigned long *) &tvp->tv_sec);
                timeout %= HZ;
index f6199f30842bc73788df095bb4b3434bf8c3456f..c54bb983c653af5039fdf3aeccf9f81253a1c47f 100644 (file)
@@ -6,6 +6,9 @@
 #undef htonl
 #undef htons
 
+#define LITTLE_ENDIAN
+#define LITTLE_ENDIAN_BITFIELD
+
 extern unsigned long int       ntohl(unsigned long int);
 extern unsigned short int      ntohs(unsigned short int);
 extern unsigned long int       htonl(unsigned long int);
index 91fc543c50316c22538e64d963966aa2f8b3eb86..600ce124d3f5d2d8da17cdbcae4abe7b025e5aa2 100644 (file)
@@ -6,6 +6,9 @@
 #undef htonl
 #undef htons
 
+#define LITTLE_ENDIAN 1234
+#define LITTLE_ENDIAN_BITFIELD
+
 extern unsigned long int       ntohl(unsigned long int);
 extern unsigned short int      ntohs(unsigned short int);
 extern unsigned long int       htonl(unsigned long int);
index 990297c11bed3fac66309014b80400762f1f7680..f24f85bd2de67933d3ab145971b0ee73bb278ec6 100644 (file)
@@ -6,6 +6,16 @@
 #undef htonl
 #undef htons
 
+#ifdef MIPSEL
+#define LITTLE_ENDIAN
+#define LITTLE_ENDIAN_BITFIELD
+#elif MIPSEB
+#define BIG_ENDIAN
+#define BIG_ENDIAN_BITFIELD
+#else
+#error "MIPS but neither MIPSEL nor MIPSEB?"
+#endif
+
 extern unsigned long int       ntohl(unsigned long int);
 extern unsigned short int      ntohs(unsigned short int);
 extern unsigned long int       htonl(unsigned long int);
index e791b6ce7f8a42743e815bfb650bc2d2eb64c4a2..b734cf8a6e1cd1211f50e9cc0c473fd636e68aa9 100644 (file)
@@ -6,6 +6,9 @@
 #undef htonl
 #undef htons
 
+#define BIG_ENDIAN
+#define BIG_ENDIAN_BITFIELD
+
 extern unsigned long int       ntohl(unsigned long int);
 extern unsigned short int      ntohs(unsigned short int);
 extern unsigned long int       htonl(unsigned long int);
index 69f83e6fd75ee190f8e366380b9f38eb77f25e16..8106a01056e93700f5ec49a0c222fb22b13a4728 100644 (file)
@@ -48,5 +48,5 @@ extern int pcibios_write_config_word (unsigned char bus,
     unsigned char device_fn, unsigned char where, unsigned short value);
 extern pcibios_write_config_dword (unsigned char bus,
     unsigned char device_fn, unsigned char where, unsigned long value);
-
+extern char *pcibios_strerror (int error);
 #endif /* ndef BIOS32_H */
index bcc1bdea8b18d44007341ef05f364802c9822905..d12b92b1ecb4695d6d2026a045e6e3fa25b8082b 100644 (file)
@@ -16,7 +16,7 @@
  */
 #ifndef _LINUX_IP_H
 #define _LINUX_IP_H
-
+#include <asm/byteorder.h>
 
 #define IPOPT_END      0
 #define IPOPT_NOOP     1
@@ -34,26 +34,14 @@ struct timestamp {
        __u8    len;
        __u8    ptr;
        union {
-#if defined(__i386__)
-       __u8    flags:4,
-               overflow:4;
-#elif defined(__mc68000__)
-       __u8    overflow:4,
-               flags:4;
-#elif defined(__MIPSEL__) 
-       __u8    flags:4,
-               overflow:4;
-#elif defined(__MIPSEB__)
-       __u8    overflow:4,
-               flags:4;
-#elif defined(__alpha__)
+#if defined(LITTLE_ENDIAN_BITFIELD)
        __u8    flags:4,
                overflow:4;
-#elif defined(__sparc__)
+#elif defined(BIG_ENDIAN_BITFIELD)
        __u8    overflow:4,
                flags:4;
 #else
-#error "Adjust this structure to match your CPU"
+#error "Please fix <asm/byteorder.h>"
 #endif                                         
        __u8    full_char;
        } x;
@@ -84,26 +72,14 @@ struct options {
 
 
 struct iphdr {
-#if defined(__i386__)
-       __u8    ihl:4,
-               version:4;
-#elif defined (__mc68000__)
-       __u8    version:4,
-               ihl:4;
-#elif defined(__MIPSEL__)
-       __u8    ihl:4,
-               version:4;
-#elif defined(__MIPSEB__)
-       __u8    version:4,
-               ihl:4;
-#elif defined(__alpha__)
+#if defined(LITTLE_ENDIAN_BITFIELD)
        __u8    ihl:4,
                version:4;
-#elif defined (__sparc__)
+#elif defined (BIG_ENDIAN_BITFIELD)
        __u8    version:4,
                ihl:4;
 #else
-#error "Adjust this structure to match your CPU"
+#error "Please fix <asm/byteorder.h>"
 #endif
        __u8    tos;
        __u16   tot_len;
index 32ef0ad126fdfc5e747b96e6e2e683f73c8212be..a7cfa23619bb9765dd11495d6c46f290be18664b 100644 (file)
@@ -26,7 +26,7 @@ struct tcphdr {
        __u16   dest;
        __u32   seq;
        __u32   ack_seq;
-#if defined(__i386__)
+#if defined(LITTLE_ENDIAN_BITFIELD)
        __u16   res1:4,
                doff:4,
                fin:1,
@@ -36,47 +36,7 @@ struct tcphdr {
                ack:1,
                urg:1,
                res2:2;
-#elif defined(__mc68000__)
-       __u16   res2:2,
-               urg:1,
-               ack:1,
-               psh:1,
-               rst:1,
-               syn:1,
-               fin:1,
-               doff:4,
-               res1:4;
-#elif defined(__MIPSEL__)
-       __u16   res1:4,
-               doff:4,
-               fin:1,
-               syn:1,
-               rst:1,
-               psh:1,
-               ack:1,
-               urg:1,
-               res2:2;
-#elif defined(__MIPSEB__)
-       __u16   res2:2,
-               urg:1,
-               ack:1,
-               psh:1,
-               rst:1,
-               syn:1,
-               fin:1,
-               doff:4,
-               res1:4;
-#elif defined(__alpha__)
-       __u16   res1:4,
-               doff:4,
-               fin:1,
-               syn:1,
-               rst:1,
-               psh:1,
-               ack:1,
-               urg:1,
-               res2:2;
-#elif defined(__sparc__)
+#elif defined(BIG_ENDIAN_BITFIELD)
        __u16   res2:2,
                urg:1,
                ack:1,
@@ -87,7 +47,7 @@ struct tcphdr {
                doff:4,
                res1:4;
 #else
-#error "Adjust this structure for your cpu alignment rules"
+#error "Adjust your <asm/byteorder.h> defines"
 #endif 
        __u16   window;
        __u16   check;
index 05ea026fdfc6a6f727dac34ef3450a28f7508236..29c4bfd748a1541652923f580e8837fa9fb4968e 100644 (file)
 #include <linux/delay.h>
 #include <linux/config.h>
 
-#ifdef CONFIG_INET
+#ifdef CONFIG_NET
 #include <linux/net.h>
 #include <linux/netdevice.h>
+#ifdef CONFIG_INET
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include "../net/inet/protocol.h"
@@ -45,6 +46,7 @@
 #include "../drivers/net/slhc.h"
 #endif
 #endif
+#endif
 #ifdef CONFIG_PCI
 #include <linux/pci.h>
 #endif
@@ -105,6 +107,7 @@ struct symbol_table symbol_table = {
        X(pcibios_read_config_byte),
        X(pcibios_read_config_word),
        X(pcibios_read_config_dword),
+       X(pcibios_strerror),
        X(pcibios_write_config_byte),
        X(pcibios_write_config_word),
        X(pcibios_write_config_dword),
@@ -277,6 +280,7 @@ struct symbol_table symbol_table = {
        X(inet_add_protocol),
        X(inet_del_protocol),
 #if defined(CONFIG_PPP) || defined(CONFIG_SLIP)
+       /* VJ header compression */
        X(slhc_init),
        X(slhc_free),
        X(slhc_remember),
@@ -321,6 +325,11 @@ struct symbol_table symbol_table = {
 #endif
 #ifdef CONFIG_SCSI
        /* Supports loadable scsi drivers */
+       /* 
+        * in_scan_scsis is a hack, and should go away once the new 
+        * memory allocation code is in the NCR driver 
+        */
+       X(in_scan_scsis),
        X(scsi_register_module),
        X(scsi_unregister_module),
        X(scsi_free),
@@ -331,6 +340,8 @@ struct symbol_table symbol_table = {
         X(scsi_init_malloc),
         X(scsi_init_free),
        X(print_command),
+       X(print_msg),
+       X(print_status),
 #endif
        /* Added to make file system as module */
        X(set_writetime),
index b41c417f45cfb4407298cbf2743e04f72c0353bc..e1a9ce15ad53cd2eca5fb8ce487bf166d797be1d 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -523,7 +523,7 @@ static int swap_out(unsigned int priority)
        int loop, counter;
        struct task_struct *p;
 
-       counter = 2*nr_tasks >> priority;
+       counter = 6*nr_tasks >> priority;
        for(; counter >= 0; counter--) {
                /*
                 * Check that swap_task is suitable for swapping.  If not, look for
@@ -605,7 +605,7 @@ static int try_to_free_page(int priority)
                        if (swap_out(i))
                                return 1;
                        state = 0;
-               } while(--i);
+               } while(i--);
        }
        return 0;
 }