I have attached to this mail a ncr/sym driver update for linux-2.2.11.
The patch is against 2.2.11-pre3 and collects changes that I think quite 
safe for linux-stable.

The 'cc' to the scsi list is for people to check if (that?) the merge with
2.2.11-pre3 is ok. The jiffies clean-up will be available in a future
patch.

(By the way, this patch does not contain the latest version of the sym
driver which is currently 1.5d. That one will be proposed for 2.3 in a
couple of weeks). 

Summary of the changes in this patch:

Both sym53c8xx and ncr53c8xx:

- Fix the misdetection of SYM53C875E (was detected as a 876).
- Add 'hostid:#id' boot option.
- Move some data structures (nvram layouts and driver set-up) to 
  the sym53c8xx_defs.h file. So, the both drivers will share them.
- support for the SYM53C895A
- merge of driver 1.3f with linux-2.2.11-pre3 -> 1.3g

sym53c8xx only:
- remove the test against the connect bit from the scsi interrupt 
  handling.
- Fix the misdetection of SYM53C810 not A (was detected as a 810A).
- Call request_region() event if MMIO is used and not normal IO.
  This allows sym and the ncr driver to be loaded in any order 
  without any risk of attaching the same device.
- Support for any number of LUNs (64) (SPI2-compliant).
- Make SCRIPTS not use self-mastering for PCI.

ncr53c8xx only:
- Set MAX LUNS to 16 (instead of 8).
- merge of driver 3.2a-1 with linux-2.2.11-pre3 -> 3.2a-2

+ some other minor changes.

Regards,
   G�rard.
--- /mnt/linux-2.2.11-pre3/Documentation/Configure.help Tue Jul 20 23:21:41 1999
+++ linux/Documentation/Configure.help  Thu Jul 22 22:58:21 1999
@@ -4037,7 +4037,13 @@
   MB/s with wide FAST-40 LVD devices and controllers.
 
   Recent versions of the 53C8XX chips are better supported by the
-  option "SYM53C8XX SCSI support", below.
+  option "SYM53C8XX SCSI support", below. This option will configure 
+  a different driver.
+
+  If you want the kernel to select the recommended driver for each of 
+  of your NCR/SYM53C8XX controllers you may just configure both the 
+  NCR53C8XX and the SYM53C8XX options to Y, or if modules are preferred, 
+  load first the sym53c8xx.o module and then the ncr53c8xx.o module.
 
   Note: there is yet another driver for the 53c8xx family of controllers
   ("NCR53c7,8xx SCSI support" above). If you want to use them both,
--- /mnt/linux-2.2.11-pre3/drivers/scsi/ChangeLog.sym53c8xx     Sun May  9 12:51:17 
1999
+++ linux/drivers/scsi/ChangeLog.sym53c8xx      Sat Jul 24 12:40:08 1999
@@ -1,3 +1,40 @@
+Sat Jul 24  12:00 1999 Gerard Roudier ([EMAIL PROTECTED])
+       * version sym53c8xx-1.3g
+       - merge of driver 1.3f with linux-2.2.11-pre3
+       - remove the broken testing of the chip being connected to SCSI 
+         from the SCSI interrupt handling code.   
+
+Sun May 9  15:00 1999 Gerard Roudier ([EMAIL PROTECTED])
+       * version sym53c8xx-1.3f
+       - Fix the misdetection of SYM53C875E (was detected as a 876).
+       - Fix the misdetection of SYM53C810 not A (was detected as a 810A).
+       - Support for the 53C895A by Pamela Delaney <[EMAIL PROTECTED]>
+         The 53C895A contains all of the features of the 896 but has only 
+         one channel and has a 32 bit PCI bus. It does 64 bit PCI addressing 
+         using dual cycle PCI data transfers.
+       - Call request_region() event if MMIO is used and not normal IO.
+         This allows sym and the ncr driver to be loaded in any order 
+         without any risk of attaching the same device.
+       - Set the actual host ID used for each host in the scsi host data 
+         structure. The mid-layer SCSI driver needs this information.
+       - Miscellaneous minor fixes.
+
+Tue Apr 15  10:00 1999 Gerard Roudier ([EMAIL PROTECTED])
+       * version sym53c8xx-1.3e
+       - Support for any number of LUNs (64) (SPI2-compliant).
+         (Btw, this may only be ever usefull under linux-2.2 ;-))
+
+Sun Apr 11  10:00 1999 Gerard Roudier ([EMAIL PROTECTED])
+       * version sym53c8xx-1.3d
+       - Add 'hostid:#id' boot option. This option allows to change the 
+         default SCSI id the driver uses for controllers.
+       - Make SCRIPTS not use self-mastering for PCI.
+         There were still 2 places the driver used this feature of the 
+         53C8XX family.
+       - Move some data structures (nvram layouts and driver set-up) to 
+         the sym53c8xx_defs.h file. So, the both drivers will share them.
+       - Set MAX LUNS to 16 (instead of 8).
+
 Sat Mar 20  21:00 1999 Gerard Roudier ([EMAIL PROTECTED])
        * version sym53c8xx-1.3b
        - Add support for NCR PQS PDS.
--- /mnt/linux-2.2.11-pre3/drivers/scsi/sym53c8xx_defs.h        Sun May  9 12:51:17 
1999
+++ linux/drivers/scsi/sym53c8xx_defs.h Tue Jul 20 23:30:43 1999
@@ -271,7 +271,7 @@
 #define SCSI_NCR_TIMER_INTERVAL        (HZ)
 
 #if 1 /* defined CONFIG_SCSI_MULTI_LUN */
-#define SCSI_NCR_MAX_LUN       (8)
+#define SCSI_NCR_MAX_LUN       (16)
 #else
 #define SCSI_NCR_MAX_LUN       (1)
 #endif
@@ -384,6 +384,10 @@
 #define PCI_DEVICE_ID_NCR_53C896 0xb
 #endif
 
+#ifndef PCI_DEVICE_ID_NCR_53C895A
+#define PCI_DEVICE_ID_NCR_53C895A 0x12
+#endif
+
 /*
 **   NCR53C8XX devices features table.
 */
@@ -463,7 +467,10 @@
  {PCI_DEVICE_ID_NCR_53C875, 0x0f, "875",  6, 16, 5,                    \
  FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}\
  ,                                                                     \
- {PCI_DEVICE_ID_NCR_53C875, 0xff, "876",  6, 16, 5,                    \
+ {PCI_DEVICE_ID_NCR_53C875, 0x1f, "876",  6, 16, 5,                    \
+ FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}\
+ ,                                                                     \
+ {PCI_DEVICE_ID_NCR_53C875, 0x2f, "875E",  6, 16, 5,                   \
  FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM}\
  ,                                                                     \
  {PCI_DEVICE_ID_NCR_53C875J,0xff, "875J", 6, 16, 5,                    \
@@ -478,6 +485,10 @@
  {PCI_DEVICE_ID_NCR_53C896, 0xff, "896",  7, 31, 7,                    \
  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM|\
  FE_RAM8K|FE_64BIT|FE_IO256|FE_NOPM|FE_LEDC}\
+ ,                                                                     \
+ {PCI_DEVICE_ID_NCR_53C895A, 0xff, "895a",  6, 31, 7,                  \
+ FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM|\
+ FE_RAM8K|FE_64BIT|FE_IO256|FE_NOPM|FE_LEDC}\
 }
 
 /*
@@ -494,10 +505,46 @@
        PCI_DEVICE_ID_NCR_53C875J,      \
        PCI_DEVICE_ID_NCR_53C885,       \
        PCI_DEVICE_ID_NCR_53C895,       \
-       PCI_DEVICE_ID_NCR_53C896        \
+       PCI_DEVICE_ID_NCR_53C896,       \
+       PCI_DEVICE_ID_NCR_53C895A       \
 }
 
 /*
+**     Driver setup structure.
+**
+**     This structure is initialized from linux config options.
+**     It can be overridden at boot-up by the boot command line.
+*/
+#define SCSI_NCR_MAX_EXCLUDES 8
+struct ncr_driver_setup {
+       u_char  master_parity;
+       u_char  scsi_parity;
+       u_char  disconnection;
+       u_char  special_features;
+       u_char  ultra_scsi;
+       u_char  force_sync_nego;
+       u_char  reverse_probe;
+       u_char  pci_fix_up;
+       u_char  use_nvram;
+       u_char  verbose;
+       u_char  default_tags;
+       u_short default_sync;
+       u_short debug;
+       u_char  burst_max;
+       u_char  led_pin;
+       u_char  max_wide;
+       u_char  settle_delay;
+       u_char  diff_support;
+       u_char  irqm;
+       u_char  bus_check;
+       u_char  optimize;
+       u_char  recovery;
+       u_char  host_id;
+       u_int   excludes[SCSI_NCR_MAX_EXCLUDES];
+       char    tag_ctrl[100];
+};
+
+/*
 **     Initial setup.
 **     Can be overriden at startup by a command line.
 */
@@ -524,7 +571,8 @@
        0,                                      \
        1,                                      \
        0,                                      \
-       0                                       \
+       0,                                      \
+       255                                     \
 }
 
 /*
@@ -555,8 +603,138 @@
        1,                                      \
        1,                                      \
        0,                                      \
-       0                                       \
+       0,                                      \
+       255                                     \
 }
+
+#ifdef SCSI_NCR_NVRAM_SUPPORT
+/*
+**     Symbios NvRAM data format
+*/
+#define SYMBIOS_NVRAM_SIZE 368
+#define SYMBIOS_NVRAM_ADDRESS 0x100
+
+struct Symbios_nvram {
+/* Header 6 bytes */
+       u_short type;           /* 0x0000 */
+       u_short byte_count;     /* excluding header/trailer */
+       u_short checksum;
+
+/* Controller set up 20 bytes */
+       u_char  v_major;        /* 0x00 */
+       u_char  v_minor;        /* 0x30 */
+       u_int32 boot_crc;
+       u_short flags;
+#define SYMBIOS_SCAM_ENABLE    (1)
+#define SYMBIOS_PARITY_ENABLE  (1<<1)
+#define SYMBIOS_VERBOSE_MSGS   (1<<2)
+#define SYMBIOS_CHS_MAPPING    (1<<3)
+#define SYMBIOS_NO_NVRAM       (1<<3)  /* ??? */
+       u_short flags1;
+#define SYMBIOS_SCAN_HI_LO     (1)
+       u_short term_state;
+#define SYMBIOS_TERM_CANT_PROGRAM      (0)
+#define SYMBIOS_TERM_ENABLED           (1)
+#define SYMBIOS_TERM_DISABLED          (2)
+       u_short rmvbl_flags;
+#define SYMBIOS_RMVBL_NO_SUPPORT       (0)
+#define SYMBIOS_RMVBL_BOOT_DEVICE      (1)
+#define SYMBIOS_RMVBL_MEDIA_INSTALLED  (2)
+       u_char  host_id;
+       u_char  num_hba;        /* 0x04 */
+       u_char  num_devices;    /* 0x10 */
+       u_char  max_scam_devices;       /* 0x04 */
+       u_char  num_valid_scam_devives; /* 0x00 */
+       u_char  rsvd;
+
+/* Boot order 14 bytes * 4 */
+       struct Symbios_host{
+               u_short type;           /* 4:8xx / 0:nok */
+               u_short device_id;      /* PCI device id */
+               u_short vendor_id;      /* PCI vendor id */
+               u_char  bus_nr;         /* PCI bus number */
+               u_char  device_fn;      /* PCI device/function number << 3*/
+               u_short word8;
+               u_short flags;
+#define        SYMBIOS_INIT_SCAN_AT_BOOT       (1)
+               u_short io_port;        /* PCI io_port address */
+       } host[4];
+
+/* Targets 8 bytes * 16 */
+       struct Symbios_target {
+               u_char  flags;
+#define SYMBIOS_DISCONNECT_ENABLE      (1)
+#define SYMBIOS_SCAN_AT_BOOT_TIME      (1<<1)
+#define SYMBIOS_SCAN_LUNS              (1<<2)
+#define SYMBIOS_QUEUE_TAGS_ENABLED     (1<<3)
+               u_char  rsvd;
+               u_char  bus_width;      /* 0x08/0x10 */
+               u_char  sync_offset;
+               u_short sync_period;    /* 4*period factor */
+               u_short timeout;
+       } target[16];
+/* Scam table 8 bytes * 4 */
+       struct Symbios_scam {
+               u_short id;
+               u_short method;
+#define SYMBIOS_SCAM_DEFAULT_METHOD    (0)
+#define SYMBIOS_SCAM_DONT_ASSIGN       (1)
+#define SYMBIOS_SCAM_SET_SPECIFIC_ID   (2)
+#define SYMBIOS_SCAM_USE_ORDER_GIVEN   (3)
+               u_short status;
+#define SYMBIOS_SCAM_UNKNOWN           (0)
+#define SYMBIOS_SCAM_DEVICE_NOT_FOUND  (1)
+#define SYMBIOS_SCAM_ID_NOT_SET                (2)
+#define SYMBIOS_SCAM_ID_VALID          (3)
+               u_char  target_id;
+               u_char  rsvd;
+       } scam[4];
+
+       u_char  spare_devices[15*8];
+       u_char  trailer[6];             /* 0xfe 0xfe 0x00 0x00 0x00 0x00 */
+};
+typedef struct Symbios_nvram   Symbios_nvram;
+typedef struct Symbios_host    Symbios_host;
+typedef struct Symbios_target  Symbios_target;
+typedef struct Symbios_scam    Symbios_scam;
+
+/*
+**     Tekram NvRAM data format.
+*/
+#define TEKRAM_NVRAM_SIZE 64
+#define TEKRAM_NVRAM_ADDRESS 0
+
+struct Tekram_nvram {
+       struct Tekram_target {
+               u_char  flags;
+#define        TEKRAM_PARITY_CHECK             (1)
+#define TEKRAM_SYNC_NEGO               (1<<1)
+#define TEKRAM_DISCONNECT_ENABLE       (1<<2)
+#define        TEKRAM_START_CMD                (1<<3)
+#define TEKRAM_TAGGED_COMMANDS         (1<<4)
+#define TEKRAM_WIDE_NEGO               (1<<5)
+               u_char  sync_index;
+               u_short word2;
+       } target[16];
+       u_char  host_id;
+       u_char  flags;
+#define TEKRAM_MORE_THAN_2_DRIVES      (1)
+#define TEKRAM_DRIVES_SUP_1GB          (1<<1)
+#define        TEKRAM_RESET_ON_POWER_ON        (1<<2)
+#define TEKRAM_ACTIVE_NEGATION         (1<<3)
+#define TEKRAM_IMMEDIATE_SEEK          (1<<4)
+#define        TEKRAM_SCAN_LUNS                (1<<5)
+#define        TEKRAM_REMOVABLE_FLAGS          (3<<6)  /* 0: disable; 1: boot device; 
+2:all */
+       u_char  boot_delay_index;
+       u_char  max_tags_index;
+       u_short flags1;
+#define TEKRAM_F2_F6_ENABLED           (1)
+       u_short spare[29];
+};
+typedef struct Tekram_nvram    Tekram_nvram;
+typedef struct Tekram_target   Tekram_target;
+
+#endif /* SCSI_NCR_NVRAM_SUPPORT */
 
 /**************** ORIGINAL CONTENT of ncrreg.h from FreeBSD ******************/
 
--- /mnt/linux-2.2.11-pre3/drivers/scsi/sym53c8xx.c     Tue Jul 20 00:21:29 1999
+++ linux/drivers/scsi/sym53c8xx.c      Sat Jul 24 12:48:49 1999
@@ -55,7 +55,7 @@
 */
 
 /*
-**     April 2 1999, sym53c8xx version 1.3c
+**     July 24 1999, sym53c8xx version 1.3g
 **
 **     Supported SCSI features:
 **         Synchronous data transfers
@@ -71,6 +71,7 @@
 **             53C875    (Wide,   Fast 20,      on-board rom BIOS)
 **             53C876    (Wide,   Fast 20 Dual, on-board rom BIOS)
 **             53C895    (Wide,   Fast 40,      on-board rom BIOS)
+**             53C895A   (Wide,   Fast 40,      on-board rom BIOS)
 **             53C896    (Wide,   Fast 40 Dual, on-board rom BIOS)
 **
 **     Other features:
@@ -82,7 +83,7 @@
 /*
 **     Name and version of the driver
 */
-#define SCSI_NCR_DRIVER_NAME   "sym53c8xx - version 1.3c"
+#define SCSI_NCR_DRIVER_NAME   "sym53c8xx - version 1.3g"
 
 /* #define DEBUG_896R1 */
 #define SCSI_NCR_OPTIMIZE_896
@@ -289,6 +290,21 @@
 
 /*==========================================================
 **
+**     This driver ensures that no PCI self-mastering will 
+**     be attempted by the PCI chip at any time, provided 
+**     that we can load the on-chip RAM from the C code.
+**     For now, I can only check that on x86, and the 
+**     the SCSI_NCR_PCI_MEM_NOT_SUPPORTED option is here 
+**     to provide previous behaviour for other platforms.
+**
+**==========================================================
+*/
+#if    !defined(__i386__)
+#define        SCSI_NCR_PCI_MEM_NOT_SUPPORTED
+#endif
+
+/*==========================================================
+**
 **     Configuration and Debugging
 **
 **==========================================================
@@ -354,7 +370,7 @@
 */
 
 #ifdef SCSI_NCR_MAX_LUN
-#define MAX_LUN    SCSI_NCR_MAX_LUN
+#define MAX_LUN    64
 #else
 #define MAX_LUN    (1)
 #endif
@@ -421,7 +437,7 @@
 **    Io mapped or memory mapped.
 */
 
-#if defined(SCSI_NCR_IOMAPPED)
+#if defined(SCSI_NCR_IOMAPPED) || defined(SCSI_NCR_PCI_MEM_NOT_SUPPORTED)
 #define NCR_IOMAPPED
 #endif
 
@@ -569,15 +585,19 @@
 #endif
 
 #ifdef __sparc__
-#define remap_pci_mem(base, size)      ((u_long) __va(base))
-#define unmap_pci_mem(vaddr, size)
-#define pcivtobus(p)                   ((p) & pci_dvma_mask)
+#  define ioremap(base, size)          ((u_long) __va(base))
+#  define iounmap(vaddr)
+#  define pcivtobus(p)                 ((p) & pci_dvma_mask)
+#  define memcpy_to_pci(a, b, c)       memcpy_toio((u_long) (a), (b), (c))
 #elif defined(__alpha__)
-#define pcivtobus(p)                   ((p) & 0xfffffffful)
-#else  /* __sparc__ */
-#define pcivtobus(p)                   (p)
+#  define pcivtobus(p)                 ((p) & 0xfffffffful)
+#  define memcpy_to_pci(a, b, c)       memcpy_toio((a), (b), (c))
+#else  /* others */
+#  define pcivtobus(p)                 (p)
+#  define memcpy_to_pci(a, b, c)       memcpy_toio((a), (b), (c))
+#endif
 
-#if !defined(NCR_IOMAPPED) || defined(__i386__)
+#ifndef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
 __initfunc(
 static u_long remap_pci_mem(u_long base, u_long size)
 )
@@ -596,8 +616,8 @@
        if (vaddr)
                iounmap((void *) (vaddr & PAGE_MASK));
 }
-#endif /* !NCR_IOMAPPED || __i386__ */
-#endif /* __sparc__ */
+
+#endif /* not def SCSI_NCR_PCI_MEM_NOT_SUPPORTED */
 
 /*
 **     Insert a delay in micro-seconds and milli-seconds.
@@ -768,7 +788,7 @@
        NCR_UNLOCK_DRIVER(flags);
 
        if (DEBUG_FLAGS & DEBUG_ALLOC)
-               printk ("new %s[%d] @%p.\n", name, size, p);
+               printk ("new %-10s[%4d] @%p.\n", name, size, p);
 
        if (p)
                memset(p, 0, size);
@@ -783,7 +803,7 @@
        u_long flags;
 
        if (DEBUG_FLAGS & DEBUG_ALLOC)
-               printk ("freeing %s[%d] @%p.\n", name, size, ptr);
+               printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr);
 
        NCR_LOCK_DRIVER(flags);
        __m_free(ptr, size);
@@ -839,34 +859,6 @@
 **     This structure is initialized from linux config options.
 **     It can be overridden at boot-up by the boot command line.
 */
-#define SCSI_NCR_MAX_EXCLUDES 8
-struct ncr_driver_setup {
-       u_char  master_parity;
-       u_char  scsi_parity;
-       u_char  disconnection;
-       u_char  special_features;
-       u_char  ultra_scsi;
-       u_char  force_sync_nego;
-       u_char  reverse_probe;
-       u_char  pci_fix_up;
-       u_char  use_nvram;
-       u_char  verbose;
-       u_char  default_tags;
-       u_short default_sync;
-       u_short debug;
-       u_char  burst_max;
-       u_char  led_pin;
-       u_char  max_wide;
-       u_char  settle_delay;
-       u_char  diff_support;
-       u_char  irqm;
-       u_char  bus_check;
-       u_char  optimize;
-       u_char  recovery;
-       u_int   excludes[SCSI_NCR_MAX_EXCLUDES];
-       char    tag_ctrl[100];
-};
-
 static struct ncr_driver_setup
        driver_setup                    = SCSI_NCR_DRIVER_SETUP;
 
@@ -896,134 +888,7 @@
 #define bootverbose (np->verbose)
 
 #ifdef SCSI_NCR_NVRAM_SUPPORT
-/*
-**     Symbios NvRAM data format
-*/
-#define SYMBIOS_NVRAM_SIZE 368
-#define SYMBIOS_NVRAM_ADDRESS 0x100
-
-struct Symbios_nvram {
-/* Header 6 bytes */
-       u_short type;           /* 0x0000 */
-       u_short byte_count;     /* excluding header/trailer */
-       u_short checksum;
-
-/* Controller set up 20 bytes */
-       u_char  v_major;        /* 0x00 */
-       u_char  v_minor;        /* 0x30 */
-       u_int32 boot_crc;
-       u_short flags;
-#define SYMBIOS_SCAM_ENABLE    (1)
-#define SYMBIOS_PARITY_ENABLE  (1<<1)
-#define SYMBIOS_VERBOSE_MSGS   (1<<2)
-#define SYMBIOS_CHS_MAPPING    (1<<3)
-#define SYMBIOS_NO_NVRAM       (1<<3)  /* ??? */
-       u_short flags1;
-#define SYMBIOS_SCAN_HI_LO     (1)
-       u_short term_state;
-#define SYMBIOS_TERM_CANT_PROGRAM      (0)
-#define SYMBIOS_TERM_ENABLED           (1)
-#define SYMBIOS_TERM_DISABLED          (2)
-       u_short rmvbl_flags;
-#define SYMBIOS_RMVBL_NO_SUPPORT       (0)
-#define SYMBIOS_RMVBL_BOOT_DEVICE      (1)
-#define SYMBIOS_RMVBL_MEDIA_INSTALLED  (2)
-       u_char  host_id;
-       u_char  num_hba;        /* 0x04 */
-       u_char  num_devices;    /* 0x10 */
-       u_char  max_scam_devices;       /* 0x04 */
-       u_char  num_valid_scam_devives; /* 0x00 */
-       u_char  rsvd;
-
-/* Boot order 14 bytes * 4 */
-       struct Symbios_host{
-               u_short type;           /* 4:8xx / 0:nok */
-               u_short device_id;      /* PCI device id */
-               u_short vendor_id;      /* PCI vendor id */
-               u_char  bus_nr;         /* PCI bus number */
-               u_char  device_fn;      /* PCI device/function number << 3*/
-               u_short word8;
-               u_short flags;
-#define        SYMBIOS_INIT_SCAN_AT_BOOT       (1)
-               u_short io_port;        /* PCI io_port address */
-       } host[4];
-
-/* Targets 8 bytes * 16 */
-       struct Symbios_target {
-               u_char  flags;
-#define SYMBIOS_DISCONNECT_ENABLE      (1)
-#define SYMBIOS_SCAN_AT_BOOT_TIME      (1<<1)
-#define SYMBIOS_SCAN_LUNS              (1<<2)
-#define SYMBIOS_QUEUE_TAGS_ENABLED     (1<<3)
-               u_char  rsvd;
-               u_char  bus_width;      /* 0x08/0x10 */
-               u_char  sync_offset;
-               u_short sync_period;    /* 4*period factor */
-               u_short timeout;
-       } target[16];
-/* Scam table 8 bytes * 4 */
-       struct Symbios_scam {
-               u_short id;
-               u_short method;
-#define SYMBIOS_SCAM_DEFAULT_METHOD    (0)
-#define SYMBIOS_SCAM_DONT_ASSIGN       (1)
-#define SYMBIOS_SCAM_SET_SPECIFIC_ID   (2)
-#define SYMBIOS_SCAM_USE_ORDER_GIVEN   (3)
-               u_short status;
-#define SYMBIOS_SCAM_UNKNOWN           (0)
-#define SYMBIOS_SCAM_DEVICE_NOT_FOUND  (1)
-#define SYMBIOS_SCAM_ID_NOT_SET                (2)
-#define SYMBIOS_SCAM_ID_VALID          (3)
-               u_char  target_id;
-               u_char  rsvd;
-       } scam[4];
-
-       u_char  spare_devices[15*8];
-       u_char  trailer[6];             /* 0xfe 0xfe 0x00 0x00 0x00 0x00 */
-};
-typedef struct Symbios_nvram   Symbios_nvram;
-typedef struct Symbios_host    Symbios_host;
-typedef struct Symbios_target  Symbios_target;
-typedef struct Symbios_scam    Symbios_scam;
-
-/*
-**     Tekram NvRAM data format.
-*/
-#define TEKRAM_NVRAM_SIZE 64
-#define TEKRAM_NVRAM_ADDRESS 0
-
-struct Tekram_nvram {
-       struct Tekram_target {
-               u_char  flags;
-#define        TEKRAM_PARITY_CHECK             (1)
-#define TEKRAM_SYNC_NEGO               (1<<1)
-#define TEKRAM_DISCONNECT_ENABLE       (1<<2)
-#define        TEKRAM_START_CMD                (1<<3)
-#define TEKRAM_TAGGED_COMMANDS         (1<<4)
-#define TEKRAM_WIDE_NEGO               (1<<5)
-               u_char  sync_index;
-               u_short word2;
-       } target[16];
-       u_char  host_id;
-       u_char  flags;
-#define TEKRAM_MORE_THAN_2_DRIVES      (1)
-#define TEKRAM_DRIVES_SUP_1GB          (1<<1)
-#define        TEKRAM_RESET_ON_POWER_ON        (1<<2)
-#define TEKRAM_ACTIVE_NEGATION         (1<<3)
-#define TEKRAM_IMMEDIATE_SEEK          (1<<4)
-#define        TEKRAM_SCAN_LUNS                (1<<5)
-#define        TEKRAM_REMOVABLE_FLAGS          (3<<6)  /* 0: disable; 1: boot device; 
2:all */
-       u_char  boot_delay_index;
-       u_char  max_tags_index;
-       u_short flags1;
-#define TEKRAM_F2_F6_ENABLED           (1)
-       u_short spare[29];
-};
-typedef struct Tekram_nvram    Tekram_nvram;
-typedef struct Tekram_target   Tekram_target;
-
 static u_char Tekram_sync[12] __initdata = {25,31,37,43,50,62,75,125,12,15,18,21};
-
 #endif /* SCSI_NCR_NVRAM_SUPPORT */
 
 /*
@@ -1451,8 +1316,10 @@
        */
        u_int32         *luntbl;        /* lcbs bus address table       */
        u_int32         b_luntbl;       /* bus address of this table    */
-       lcb_p           lp[MAX_LUN];    /* The lcb's of this tcb        */
-
+       lcb_p           l0p;            /* lcb of LUN #0 (normal case)  */
+#if MAX_LUN > 1
+       lcb_p           *lmp;           /* Other lcb's [1..MAX_LUN]     */
+#endif
        /*----------------------------------------------------------------
        **      Target capabilities.
        **----------------------------------------------------------------
@@ -1649,6 +1516,18 @@
 };
 
 /*
+**     LUN control block lookup.
+**     We use a direct pointer for LUN #0, and a table of pointers 
+**     which is only allocated for devices that support LUN(s) > 0.
+*/
+#if MAX_LUN <= 1
+#define ncr_lp(np, tp, lun) (!lun) ? (tp)->l0p : 0
+#else
+#define ncr_lp(np, tp, lun) \
+       (!lun) ? (tp)->l0p : (tp)->lmp ? (tp)->lmp[(lun)] : 0
+#endif
+
+/*
 **     The status bytes are used by the host and the script processor.
 **
 **     The last four bytes (status[4]) are copied to the scratchb register
@@ -1907,11 +1786,15 @@
        **      Virtual and physical bus addresses of the chip.
        **----------------------------------------------------------------
        */
+#ifndef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
        u_long          base_va;        /* MMIO base virtual address    */
+       u_long          base2_va;       /* On-chip RAM virtual address  */
+#endif
        u_long          base_ba;        /* MMIO base bus address        */
        u_long          base_io;        /* IO space base address        */
        u_long          base_ws;        /* (MM)IO window size           */
-       u_long          base2_ba;       /* On-chip RAM bus address.     */
+       u_long          base2_ba;       /* On-chip RAM bus address      */
+       u_long          base2_ws;       /* On-chip RAM window size      */
        u_int           irq;            /* IRQ number                   */
        volatile                        /* Pointer to volatile for      */
        struct ncr_reg  *reg;           /*  memory mapped IO.           */
@@ -2111,12 +1994,6 @@
        ncrcmd  data_out2       [  4];
        ncrcmd  pm0_data        [ 16];
        ncrcmd  pm1_data        [ 16];
-
-       /* Data area */
-       ncrcmd  saved_dsa       [  1];
-       ncrcmd  done_pos        [  1];
-       ncrcmd  startpos        [  1];
-       ncrcmd  targtbl         [  1];
 };
 
 /*
@@ -2170,16 +2047,20 @@
        /* Data area */
        ncrcmd  pm0_data_addr   [  1];
        ncrcmd  pm1_data_addr   [  1];
+       ncrcmd  saved_dsa       [  1];
+       ncrcmd  done_pos        [  1];
+       ncrcmd  startpos        [  1];
+       ncrcmd  targtbl         [  1];
        /* End of data area */
 
+#ifdef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
        ncrcmd  start_ram       [  1];
        ncrcmd  script0_ba      [  4];
-
        ncrcmd  start_ram64     [  3];
        ncrcmd  script0_ba64    [  3];
        ncrcmd  scripth0_ba64   [  6];
        ncrcmd  ram_seg64       [  1];
-
+#endif
        ncrcmd  snooptest       [  6];
        ncrcmd  snoopend        [  2];
 };
@@ -2351,14 +2232,14 @@
        **      and the the next queue position points to the next JOB.
        */
        SCR_LOAD_ABS (scratcha, 4),
-               PADDR (startpos),
+               PADDRH (startpos),
        SCR_LOAD_ABS (dsa, 4),
-               PADDR (startpos),
+               PADDRH (startpos),
        SCR_LOAD_REL (temp, 4),
                4,
 }/*-------------------------< GETJOB_BEGIN >------------------*/,{
        SCR_STORE_ABS (temp, 4),
-               PADDR (startpos),
+               PADDRH (startpos),
        SCR_LOAD_REL (dsa, 4),
                0,
 }/*-------------------------< GETJOB_END >--------------------*/,{
@@ -2525,7 +2406,7 @@
        SCR_FROM_REG (sstat0),
                0,
        SCR_JUMPR ^ IFTRUE (MASK (IRST, IRST)),
-               -8,
+               -16,
        SCR_JUMP,
                PADDR (start),
 }/*-------------------------< CLRACK >----------------------*/,{
@@ -2668,11 +2549,11 @@
        **      the completed CCB will be lost.
        */
        SCR_STORE_ABS (dsa, 4),
-               PADDR (saved_dsa),
+               PADDRH (saved_dsa),
        SCR_LOAD_ABS (dsa, 4),
-               PADDR (done_pos),
+               PADDRH (done_pos),
        SCR_LOAD_ABS (scratcha, 4),
-               PADDR(saved_dsa),
+               PADDRH (saved_dsa),
        SCR_STORE_REL (scratcha, 4),
                0,
        /*
@@ -2687,7 +2568,7 @@
        SCR_INT_FLY,
                0,
        SCR_STORE_ABS (temp, 4),
-               PADDR (done_pos),
+               PADDRH (done_pos),
 }/*------------------------< DONE_END >-----------------*/,{
        SCR_JUMP,
                PADDR (start),
@@ -2809,7 +2690,7 @@
        SCR_LOAD_REG (dsa, 0xff),
                0,
        SCR_STORE_ABS (scratcha, 4),
-               PADDR (startpos),
+               PADDRH (startpos),
 }/*-------------------------< RESELECT >--------------------*/,{
        /*
        **      make the host status invalid.
@@ -2842,7 +2723,7 @@
        **      load the target control block address
        */
        SCR_LOAD_ABS (dsa, 4),
-               PADDR (targtbl),
+               PADDRH (targtbl),
        SCR_SFBR_REG (dsa, SCR_SHL, 0),
                0,
        SCR_REG_REG (dsa, SCR_SHL, 0),
@@ -3082,16 +2963,7 @@
                offsetof (struct ccb, phys.pm1.ret),
        SCR_RETURN,
                0,
-
-}/*-------------------------< SAVED_DSA >-------------------*/,{
-       SCR_DATA_ZERO,
-}/*-------------------------< DONE_POS >--------------------*/,{
-       SCR_DATA_ZERO,
-}/*-------------------------< STARTPOS >--------------------*/,{
-       SCR_DATA_ZERO,
-}/*-------------------------< TARGTBL >---------------------*/,{
-       SCR_DATA_ZERO,
-}/*--------------------------------------------------------*/
+}/*---------------------------------------------------------*/
 };
 
 static struct scripth scripth0 __initdata = {
@@ -3596,7 +3468,7 @@
        **      call the C code.
        */
        SCR_LOAD_ABS (scratcha, 4),
-               PADDR (startpos),
+               PADDRH (startpos),
        SCR_INT ^ IFTRUE (DATA (S_QUEUE_FULL)),
                SIR_BAD_STATUS,
        SCR_INT ^ IFTRUE (DATA (S_CHECK_COND)),
@@ -3737,6 +3609,25 @@
        SCR_DATA_ZERO,
 }/*-------------------------< PM1_DATA_ADDR >---------------*/,{
        SCR_DATA_ZERO,
+}/*-------------------------< SAVED_DSA >-------------------*/,{
+       SCR_DATA_ZERO,
+}/*-------------------------< DONE_POS >--------------------*/,{
+       SCR_DATA_ZERO,
+}/*-------------------------< STARTPOS >--------------------*/,{
+       SCR_DATA_ZERO,
+}/*-------------------------< TARGTBL >---------------------*/,{
+       SCR_DATA_ZERO,
+
+
+/*
+** We may use MEMORY MOVE instructions to load the on chip-RAM,
+** if it happens that mapping PCI memory is not possible.
+** But writing the RAM from the CPU is the preferred method, 
+** since PCI 2.2 seems to disallow PCI self-mastering.
+*/
+
+#ifdef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
+
 }/*-------------------------< START_RAM >-------------------*/,{
        /*
        **      Load the script into on-chip RAM, 
@@ -3776,6 +3667,9 @@
                PADDRH (start64),
 }/*-------------------------< RAM_SEG64 >--------------------*/,{
                0,
+
+#endif /* SCSI_NCR_PCI_MEM_NOT_SUPPORTED */
+
 }/*-------------------------< SNOOPTEST >-------------------*/,{
        /*
        **      Read the variable.
@@ -4793,11 +4687,22 @@
        if (np->base2_ba) {
                np->p_script    = pcivtobus(np->base2_ba);
                if (np->features & FE_RAM8K) {
+                       np->base2_ws = 8192;
                        np->p_scripth = np->p_script + 4096;
 #if BITS_PER_LONG > 32
                        np->scr_ram_seg = cpu_to_scr(np->base2_ba >> 32);
 #endif
                }
+               else
+                       np->base2_ws = 4096;
+#ifndef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
+               np->base2_va = remap_pci_mem(np->base2_ba, np->base2_ws);
+               if (!np->base2_va) {
+                       printk(KERN_ERR "%s: can't map PCI MEMORY region\n",
+                              ncr_name(np));
+                       goto attach_error;
+               }
+#endif
        }
 
        ncr_script_copy_and_bind (np, (ncrcmd *) &script0, (ncrcmd *) np->script0, 
sizeof(struct script));
@@ -4811,11 +4716,12 @@
        np->scripth0->pm1_data_addr[0] = 
                        cpu_to_scr(NCB_SCRIPT_PHYS(np, pm1_data));
 
+#ifdef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
        np->scripth0->script0_ba[0]     = cpu_to_scr(vtobus(np->script0));
        np->scripth0->script0_ba64[0]   = cpu_to_scr(vtobus(np->script0));
        np->scripth0->scripth0_ba64[0]  = cpu_to_scr(vtobus(np->scripth0));
        np->scripth0->ram_seg64[0]      = np->scr_ram_seg;
-
+#endif
        /*
        **      Prepare the idle and invalid task actions.
        */
@@ -4851,7 +4757,7 @@
        /*
        **      Prepare the target bus address array.
        */
-       np->script0->targtbl[0] = cpu_to_scr(vtobus(np->targtbl));
+       np->scripth0->targtbl[0] = cpu_to_scr(vtobus(np->targtbl));
        for (i = 0 ; i < MAX_TARGET ; i++) {
                np->targtbl[i] = cpu_to_scr(vtobus(&np->target[i]));
                np->target[i].b_luntbl = cpu_to_scr(vtobus(np->badluntbl));
@@ -4981,8 +4887,9 @@
        **      and return success.
        */
        instance->max_channel   = 0;
+       instance->this_id       = np->myaddr;
        instance->max_id        = np->maxwide ? 16 : 8;
-       instance->max_lun       = SCSI_NCR_MAX_LUN;
+       instance->max_lun       = MAX_LUN;
 #ifndef NCR_IOMAPPED
        instance->base          = (char *) np->reg;
 #endif
@@ -5026,9 +4933,11 @@
                free_irq(np->irq, np);
        if (np->base_io)
                release_region(np->base_io, np->base_ws);
-#ifndef NCR_IOMAPPED
+#ifndef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
        if (np->base_va)
                unmap_pci_mem(np->base_va, np->base_ws);
+       if (np->base2_va)
+               unmap_pci_mem(np->base2_va, np->base2_ws);
 #endif
        if (np->scripth0)
                m_free(np->scripth0, sizeof(struct scripth), "SCRIPTH");
@@ -5050,13 +4959,17 @@
        for (target = 0; target < MAX_TARGET ; target++) {
                tp = &np->target[target];
                for (lun = 0 ; lun < MAX_LUN ; lun++) {
-                       lp = tp->lp[lun];
+                       lp = ncr_lp(np, tp, lun);
                        if (!lp)
                                continue;
                        if (lp->tasktbl != &lp->tasktbl_0)
                                m_free(lp->tasktbl, 256, "TASKTBL");
                        m_free(lp, sizeof(*lp), "LCB");
                }
+#if MAX_LUN > 1
+               if (tp->lmp)
+                       m_free(tp->lmp, MAX_LUN * sizeof(lcb_p), "LMP");
+#endif 
        }
 
        m_free(np, sizeof(*np), "NCB");
@@ -5112,7 +5025,7 @@
 {
 /*     Scsi_Device        *device    = cmd->device; */
        tcb_p tp                      = &np->target[cmd->target];
-       lcb_p lp                      = tp->lp[cmd->lun];
+       lcb_p lp                      = ncr_lp(np, tp, cmd->lun);
        ccb_p cp;
 
        int     segments;
@@ -5941,7 +5854,7 @@
        cmd = cp->cmd;
        cp->cmd = NULL;
        tp = &np->target[cp->target];
-       lp = tp->lp[cp->lun];
+       lp = ncr_lp(np, tp, cp->lun);
 
        /*
        **      We donnot queue more than 1 ccb per target 
@@ -6274,7 +6187,7 @@
        **      Start at first entry.
        */
        np->squeueput = 0;
-       np->script0->startpos[0] = cpu_to_scr(phys);
+       np->scripth0->startpos[0] = cpu_to_scr(phys);
 
        /*
        **      Clear Done Queue
@@ -6289,7 +6202,7 @@
        /*
        **      Start at first entry.
        */
-       np->script0->done_pos[0] = cpu_to_scr(phys);
+       np->scripth0->done_pos[0] = cpu_to_scr(phys);
        np->dqueueget = 0;
 
        /*
@@ -6414,17 +6327,35 @@
        }
 
        /*
-       **    Start script processor.
+       **    Download SCSI SCRIPTS to on-chip RAM if present,
+       **    and start script processor.
+       **    We do the download preferently from the CPU.
+       **    For platforms that may not support PCI memory mapping,
+       **    we use a simple SCRIPTS that performs MEMORY MOVEs.
        */
        MEMORY_BARRIER();
        if (np->base2_ba) {
                if (bootverbose)
                        printk ("%s: Downloading SCSI SCRIPTS.\n",
                                ncr_name(np));
-               if (np->features & FE_RAM8K)
+#ifdef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
+               if (np->base2_ws == 8192)
                        phys = NCB_SCRIPTH0_PHYS (np, start_ram64);
                else
                        phys = NCB_SCRIPTH_PHYS (np, start_ram);
+#else
+               if (np->base2_ws == 8192) {
+                       memcpy_to_pci(np->base2_va + 4096,
+                                       np->scripth0, sizeof(struct scripth));
+                       OUTL (nc_mmws, np->scr_ram_seg);
+                       OUTL (nc_mmrs, np->scr_ram_seg);
+                       OUTL (nc_sfs,  np->scr_ram_seg);
+                       phys = NCB_SCRIPTH_PHYS (np, start64);
+               }
+               else
+                       phys = NCB_SCRIPT_PHYS (np, init);
+               memcpy_to_pci(np->base2_va, np->script0, sizeof(struct script));
+#endif /* SCSI_NCR_PCI_MEM_NOT_SUPPORTED */
        }
        else
                phys = NCB_SCRIPT_PHYS (np, init);
@@ -6729,7 +6660,7 @@
 static void ncr_setup_tags (ncb_p np, u_char tn, u_char ln)
 {
        tcb_p tp = &np->target[tn];
-       lcb_p lp = tp->lp[ln];
+       lcb_p lp = ncr_lp(np, tp, ln);
        u_char   reqtags, maxdepth;
 
        /*
@@ -6844,7 +6775,7 @@
                        if (!((np->user.target>>t)&1)) continue;
                        np->target[t].usrtags = np->user.data;
                        for (ln = 0; ln < MAX_LUN; ln++) {
-                               lcb_p lp = np->target[t].lp[ln];
+                               lcb_p lp = ncr_lp(np, &np->target[t], ln);
                                if (!lp)
                                        continue;
                                lp->maxtags = lp->numtags = np->user.data;
@@ -7339,17 +7270,9 @@
 {
        u_int32 dsp     = INL (nc_dsp);
        u_int32 dsa     = INL (nc_dsa);
-       u_char  scntl1  = INB (nc_scntl1);
        ccb_p cp        = ncr_ccb_from_dsa(np, dsa);
 
        /*
-       **      If we are connected to the SCSI BUS, we only 
-       **      can reset the BUS.
-       */
-       if (scntl1 & ISCON)
-               goto reset_all;
-
-       /*
        **      If we haven't been interrupted inside the SCRIPTS 
        **      critical pathes, we can safely restart the SCRIPTS 
        **      and trust the DSA value if it matches a CCB.
@@ -7920,7 +7843,7 @@
 {
        Scsi_Cmnd *cmd  = cp->cmd;
        tcb_p tp        = &np->target[cp->target];
-       lcb_p lp        = tp->lp[cp->lun];
+       lcb_p lp        = ncr_lp(np, tp, cp->lun);
        ccb_p           cp2;
        int             busyccbs = 1;
        u_int32         startp;
@@ -8167,8 +8090,8 @@
                **      message still exist, this should help.
                **      We just assume lun=0, 1 CCB, no tag.
                */
-               if (tp->lp[0]) { 
-                       OUTL (nc_dsa, scr_to_cpu(tp->lp[0]->tasktbl[0]));
+               if (tp->l0p) { 
+                       OUTL (nc_dsa, scr_to_cpu(tp->l0p->tasktbl[0]));
                        OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, resel_go));
                        return;
                }
@@ -8623,7 +8546,7 @@
 static ccb_p ncr_get_ccb (ncb_p np, u_char tn, u_char ln)
 {
        tcb_p tp = &np->target[tn];
-       lcb_p lp = tp->lp[ln];
+       lcb_p lp = ncr_lp(np, tp, ln);
        u_char tag = NO_TAG;
        XPT_QUEHEAD *qp;
        ccb_p cp = (ccb_p) 0;
@@ -8715,7 +8638,7 @@
 static void ncr_free_ccb (ncb_p np, ccb_p cp)
 {
        tcb_p tp = &np->target[cp->target];
-       lcb_p lp = tp->lp[cp->lun];
+       lcb_p lp = ncr_lp(np, tp, cp->lun);
 
        if (DEBUG_FLAGS & DEBUG_TAGS) {
                PRINT_LUN(np, cp->target, cp->lun);
@@ -8882,7 +8805,7 @@
 static lcb_p ncr_alloc_lcb (ncb_p np, u_char tn, u_char ln)
 {
        tcb_p tp = &np->target[tn];
-       lcb_p lp = tp->lp[ln];
+       lcb_p lp = ncr_lp(np, tp, ln);
 
        /*
        **      Already done, return.
@@ -8898,12 +8821,24 @@
                goto fail;
 
        /*
+       **      Allocate the table of pointers for LUN(s) > 0, if needed.
+       */
+       if (ln && !tp->lmp) {
+               tp->lmp = m_calloc(MAX_LUN * sizeof(lcb_p), "LMP", MEMO_WARN);
+               if (!tp->lmp)
+                       goto fail;
+       }
+
+       /*
        **      Allocate the lcb.
        */
        lp = m_calloc(sizeof(struct lcb), "LCB", MEMO_WARN);
        if (!lp)
                goto fail;
-       tp->lp[ln] = lp;
+       if (ln)
+               tp->lmp[ln] = lp;
+       else
+               tp->l0p = lp;
 
        /*
        **      Make it available to the chip.
@@ -8948,7 +8883,7 @@
 static lcb_p ncr_setup_lcb (ncb_p np, u_char tn, u_char ln, u_char *inq_data)
 {
        tcb_p tp = &np->target[tn];
-       lcb_p lp = tp->lp[ln];
+       lcb_p lp = ncr_lp(np, tp, ln);
        u_char inq_byte7;
        int i;
 
@@ -9624,6 +9559,7 @@
 #define OPT_SAFE_SETUP         22
 #define OPT_USE_NVRAM          23
 #define OPT_EXCLUDE            24
+#define OPT_HOST_ID            25
 
 static char setup_token[] __initdata = 
        "tags:"   "mpar:"
@@ -9638,7 +9574,7 @@
        "buschk:" "optim:"
        "recovery:"
        "safe:"   "nvram:"
-       "excl:";
+       "excl:"   "hostid:";
 
 #ifdef MODULE
 #define        ARG_SEP ' '
@@ -9772,6 +9708,9 @@
                        if (xi < SCSI_NCR_MAX_EXCLUDES)
                                driver_setup.excludes[xi++] = val;
                        break;
+               case OPT_HOST_ID:
+                       driver_setup.host_id = val;
+                       break;
                default:
                        printk("sym53c8xx_setup: unexpected boot option '%.*s' 
ignored\n", (int)(pc-cur+1), cur);
                        break;
@@ -9988,7 +9927,7 @@
                }
                ++index;
                devp = &devtbl[count];
-               devp->host_id = 255;
+               devp->host_id = driver_setup.host_id;
                devp->attach_done = 0;
                if (sym53c8xx_pci_init(tpnt, bus, device_fn, devp)) {
                        continue;
@@ -10221,18 +10160,18 @@
                if (revision > ncr_chip_table[i].revision_id)
                        continue;
                if (!(ncr_chip_table[i].features & FE_LDSTR))
-                       continue;
+                       break;
                chip = &device->chip;
                memcpy(chip, &ncr_chip_table[i], sizeof(*chip));
                chip->revision_id = revision;
                break;
        }
 
-#if defined(__i386__)
        /*
        **      Ignore Symbios chips controlled by SISL RAID controller.
        **      This controller sets value 0x52414944 at RAM end - 16.
        */
+#if defined(__i386__) && !defined(SCSI_NCR_PCI_MEM_NOT_SUPPORTED)
        if (chip && (base_2 & PCI_BASE_ADDRESS_MEM_MASK)) {
                unsigned int ram_size, ram_val;
                u_long ram_ptr;
@@ -10254,7 +10193,7 @@
                        }
                }
        }
-#endif
+#endif /* not def SCSI_NCR_PCI_MEM_NOT_SUPPORTED */
 
        if (!chip) {
                printk(NAME53C8XX ": not initializing, device not supported\n");
@@ -10341,8 +10280,15 @@
        /*
        **    Check availability of IO space, memory space.
        **    Enable master capability if not yet.
+       **
+       **    We shouldn't have to care about the IO region when 
+       **    we are using MMIO. But calling check_region() from 
+       **    both the ncr53c8xx and the sym53c8xx drivers prevents 
+       **    from attaching devices from the both drivers.
+       **    If you have a better idea, let me know.
        */
-#ifdef NCR_IOMAPPED
+/* #ifdef NCR_IOMAPPED */
+#if 1
        if (!(command & PCI_COMMAND_IO) || !(io_port & 1)) { 
                printk(NAME53C8XX ": I/O base address (0x%lx) disabled.\n",
                        (long) io_port);
@@ -10358,7 +10304,8 @@
        base    &= PCI_BASE_ADDRESS_MEM_MASK;
        base_2  &= PCI_BASE_ADDRESS_MEM_MASK;
 
-#ifdef NCR_IOMAPPED
+/* #ifdef NCR_IOMAPPED */
+#if 1
        if (io_port && check_region (io_port, 128)) {
                printk(NAME53C8XX ": IO region 0x%lx[0..127] is in use\n",
                        (long) io_port);
@@ -10366,7 +10313,8 @@
        }
        if (!io_port)
                return -1;
-#else
+#endif
+#ifndef NCR_IOMAPPED
        if (!base) {
                printk(NAME53C8XX ": MMIO base address disabled.\n");
                return -1;
@@ -10583,7 +10531,7 @@
 
                np = ((struct host_data *) host->hostdata)->ncb;
                tp = &np->target[device->id];
-               lp = tp->lp[device->lun];
+               lp = ncr_lp(np, tp, device->lun);
 
                /*
                **      Select queue depth from driver setup.
@@ -11403,8 +11351,8 @@
        nvram_stop(np, &gpreg);
        
 #ifdef SCSI_NCR_DEBUG_NVRAM
-printk("sym53c8xx: NvRAM marker=%x trailer=%x %x %x %x %x %x byte_count=%d/%d 
checksum=%x/%x\n",
-       nvram->start_marker,
+printk("sym53c8xx: NvRAM type=%x trailer=%x %x %x %x %x %x byte_count=%d/%d 
+checksum=%x/%x\n",
+       nvram->type,
        nvram->trailer[0], nvram->trailer[1], nvram->trailer[2],
        nvram->trailer[3], nvram->trailer[4], nvram->trailer[5],
        nvram->byte_count, sizeof(*nvram) - 12,
--- /mnt/linux-2.2.11-pre3/drivers/scsi/ChangeLog.ncr53c8xx     Sun May  9 12:51:17 
1999
+++ linux/drivers/scsi/ChangeLog.ncr53c8xx      Sat Jul 24 12:41:32 1999
@@ -1,3 +1,22 @@
+Wed Jul 21 1999 23:00 Gerard Roudier ([EMAIL PROTECTED])
+       * revision 3.2a-2
+       - merge of driver 3.2a-1 with linux-2.3.11-pre3
+
+Sun May 9  15:00 1999 Gerard Roudier ([EMAIL PROTECTED])
+       * revision 3.2a-1
+       - Fix the misdetection of SYM53C875E (was detected as a 876).
+       - Set the actual host ID used for each host in the scsi host data 
+         structure. The mid-layer SCSI driver needs this information.
+
+Sun Apr 11  10:00 1999 Gerard Roudier ([EMAIL PROTECTED])
+       * revision 3.2a
+       - Add 'hostid:#id' boot option. This option allows to change the 
+         default SCSI id the driver uses for controllers.
+       - Remove nvram layouts and driver set-up structures from the C source,
+         and use the one defined in sym53c8xx_defs.h file.
+         (shared by both drivers).
+       - Set for now MAX LUNS to 16 (instead of 8).
+
 Thu Mar 11  23:00 1999 Gerard Roudier ([EMAIL PROTECTED])
        * revision 3.2    (8xx-896 driver bundle)
        - Only define the host template in ncr53c8xx.h and include the 
--- /mnt/linux-2.2.11-pre3/drivers/scsi/README.ncr53c8xx        Sun May  9 12:51:17 
1999
+++ linux/drivers/scsi/README.ncr53c8xx Tue Jul 20 23:25:52 1999
@@ -4,7 +4,7 @@
 21 Rue Carnot
 95170 DEUIL LA BARRE - FRANCE
 
-10 March 1999
+9 May 1999
 ===============================================================================
 
 1.  Introduction
@@ -736,6 +736,13 @@
 Serial NVRAM
     nvram:n     do not look for serial NVRAM
     nvram:y     test controllers for onboard serial NVRAM
+    (alternate binary form)
+    mvram=<bits options>
+      0x01   look for NVRAM  (equivalent to nvram=y)
+      0x02   ignore NVRAM "Synchronous negotiation" parameters for all devices
+      0x04   ignore NVRAM "Wide negotiation"  parameter for all devices
+      0x08   ignore NVRAM "Scan at boot time" parameter for all devices
+      0x80   also attach controllers set to OFF in the NVRAM (sym53c8xx only)
 
 Check SCSI BUS 
     buschk:<option bits>
@@ -745,13 +752,23 @@
         0x1:   Check and donnot attach the controller on error.  
         0x2:   Check and just warn on error.
 
-Exclude hosts from being attached
+Exclude a host from being attached
     excl=<io_address>
 
     Prevent host at a given io address from being attached.
-    For example 'ncr53c8xx=excl:0xb400,excl:0xc000' indicate to the 
+    For example 'ncr53c8xx=excl:0xb400,excl:0xc000' indicates to the 
     ncr53c8xx driver not to attach hosts at address 0xb400 and 0xc000.
 
+Suggest a default SCSI id for hosts
+    hostid:255 no id suggested.
+    hostid:#x   (0 < x < 7) x suggested for hosts SCSI id.
+
+    If a host SCSI id is available from the NVRAM, the driver will ignore 
+    any value suggested as boot option. Otherwise, if a suggested value 
+    different from 255 has been supplied, it will use it. Otherwise, it will 
+    try to deduce the value previously set in the hardware and use value 
+    7 if the hardware value is zero.
+
 Boot fail safe
     safe:y     load the following assumed fail safe initial setup
 
@@ -837,7 +854,11 @@
 nvram:n     do not look for serial NVRAM
 nvram:y     test controllers for onboard serial NVRAM
 
-This option is described below (see 17. Serial NVRAM support).
+This option can also been entered as an hexadecimal value that allows 
+to control what information the driver will get from the NVRAM and what 
+information it will ignore.
+For details see '17. Serial NVRAM support'.
+
 When this option is enabled, the driver tries to detect all boards using 
 a Serial NVRAM. This memory is used to hold user set up parameters.
 
@@ -873,12 +894,17 @@
       0x02   ignore NVRAM "Synchronous negotiation" parameters for all devices
       0x04   ignore NVRAM "Wide negotiation"  parameter for all devices
       0x08   ignore NVRAM "Scan at boot time" parameter for all devices
+      0x80   also attach controllers set to OFF in the NVRAM (sym53c8xx only)
 
-My Atlas Wide only boots cleanly in 8 bits asynchronous data transfer 
-mode. However, it works flawlessly at 20 MB/second with the driver.
-Using "nvram=0x7" allows me to boot in 8 bits/async and to let the driver 
-use its setup for synchronous and wide negotiations.
-
+Option 0x80 is only supported by the sym53c8xx driver and is disabled by 
+default. Result is that, by default (option not set), the sym53c8xx driver 
+will not attach controllers set to OFF in the NVRAM.
+
+The ncr53c8xx always tries to attach all the controllers. Option 0x80 has 
+not been added to the ncr53c8xx driver, since it has been reported to 
+confuse users who use this driver since a long time. If you desire a 
+controller not to be attached by the ncr53c8xx driver at Linux boot, you 
+must use the 'excl' driver boot option.
 
 10.6 SCSI BUS checking boot option.
 
--- /mnt/linux-2.2.11-pre3/drivers/scsi/ncr53c8xx.c     Tue Jul 20 23:21:48 1999
+++ linux/drivers/scsi/ncr53c8xx.c      Wed Jul 21 23:36:51 1999
@@ -73,7 +73,7 @@
 */
 
 /*
-**     March 7 1999, version 3.2
+**     July 20 1999, version 3.2a-2
 **
 **     Supported SCSI-II features:
 **         Synchronous negotiation
@@ -91,6 +91,8 @@
 **             53C860          (8 bits, Fast 20,     no rom BIOS)
 **             53C875          (Wide,   Fast 20,     on board rom BIOS)
 **             53C895          (Wide,   Fast 40,     on board rom BIOS)
+**             53C895A         (Wide,   Fast 40,     on board rom BIOS)
+**             53C896          (Wide,   Fast 40,     on board rom BIOS)
 **
 **     Other features:
 **             Memory mapped IO (linux-1.3.X and above only)
@@ -101,7 +103,7 @@
 /*
 **     Name and version of the driver
 */
-#define SCSI_NCR_DRIVER_NAME   "ncr53c8xx - version 3.2"
+#define SCSI_NCR_DRIVER_NAME   "ncr53c8xx - version 3.2a-2"
 
 #define SCSI_NCR_DEBUG_FLAGS   (0)
 
@@ -737,34 +739,6 @@
 **     This structure is initialized from linux config options.
 **     It can be overridden at boot-up by the boot command line.
 */
-#define SCSI_NCR_MAX_EXCLUDES 8
-struct ncr_driver_setup {
-       u_char  master_parity;
-       u_char  scsi_parity;
-       u_char  disconnection;
-       u_char  special_features;
-       u_char  ultra_scsi;
-       u_char  force_sync_nego;
-       u_char  reverse_probe;
-       u_char  pci_fix_up;
-       u_char  use_nvram;
-       u_char  verbose;
-       u_char  default_tags;
-       u_short default_sync;
-       u_short debug;
-       u_char  burst_max;
-       u_char  led_pin;
-       u_char  max_wide;
-       u_char  settle_delay;
-       u_char  diff_support;
-       u_char  irqm;
-       u_char  bus_check;
-       u_char  optimize;
-       u_char  recovery;
-       u_int   excludes[SCSI_NCR_MAX_EXCLUDES];
-       char    tag_ctrl[100];
-};
-
 static struct ncr_driver_setup
        driver_setup                    = SCSI_NCR_DRIVER_SETUP;
 
@@ -794,108 +768,7 @@
 #define bootverbose (np->verbose)
 
 #ifdef SCSI_NCR_NVRAM_SUPPORT
-/*
-**     Symbios NvRAM data format
-*/
-#define SYMBIOS_NVRAM_SIZE 368
-#define SYMBIOS_NVRAM_ADDRESS 0x100
-
-struct Symbios_nvram {
-/* Header 6 bytes */
-       u_short start_marker;   /* 0x0000 */
-       u_short byte_count;     /* excluding header/trailer */
-       u_short checksum;
-
-/* Controller set up 20 bytes */
-       u_short word0;          /* 0x3000 */
-       u_short word2;          /* 0x0000 */
-       u_short word4;          /* 0x0000 */
-       u_short flags;
-#define SYMBIOS_SCAM_ENABLE    (1)
-#define SYMBIOS_PARITY_ENABLE  (1<<1)
-#define SYMBIOS_VERBOSE_MSGS   (1<<2)
-#define SYMBIOS_CHS_MAPPING    (1<<3)
-       u_short flags1;
-#define SYMBIOS_SCAN_HI_LO     (1)
-       u_short word10;         /* 0x00 */
-       u_short flags3;         /* 0x00 */
-#define SYMBIOS_REMOVABLE_FLAGS        (3)             /* 0=none, 1=bootable, 2=all 
*/
-       u_char  host_id;
-       u_char  byte15;         /* 0x04 */
-       u_short word16;         /* 0x0410 */
-       u_short word18;         /* 0x0000 */
-
-/* Boot order 14 bytes * 4 */
-       struct Symbios_host{
-               u_char  word0;          /* 0x0004:ok / 0x0000:nok */
-               u_short device_id;      /* PCI device id */
-               u_short vendor_id;      /* PCI vendor id */
-               u_char  byte6;          /* 0x00 */
-               u_char  device_fn;      /* PCI device/function number << 3*/
-               u_short word8;
-               u_short flags;
-#define        SYMBIOS_INIT_SCAN_AT_BOOT       (1)
-               u_short io_port;        /* PCI io_port address */
-       } host[4];
-
-/* Targets 8 bytes * 16 */
-       struct Symbios_target {
-               u_short flags;
-#define SYMBIOS_DISCONNECT_ENABLE      (1)
-#define SYMBIOS_SCAN_AT_BOOT_TIME      (1<<1)
-#define SYMBIOS_SCAN_LUNS              (1<<2)
-#define SYMBIOS_QUEUE_TAGS_ENABLED     (1<<3)
-               u_char  bus_width;      /* 0x08/0x10 */
-               u_char  sync_offset;
-               u_char  sync_period;    /* 4*period factor */
-               u_char  byte6;          /* 0x00 */
-               u_short timeout;
-       } target[16];
-       u_char  spare_devices[19*8];
-       u_char  trailer[6];             /* 0xfe 0xfe 0x00 0x00 0x00 0x00 */
-};
-typedef struct Symbios_nvram   Symbios_nvram;
-typedef struct Symbios_host    Symbios_host;
-typedef struct Symbios_target  Symbios_target;
-
-/*
-**     Tekram NvRAM data format.
-*/
-#define TEKRAM_NVRAM_SIZE 64
-#define TEKRAM_NVRAM_ADDRESS 0
-
-struct Tekram_nvram {
-       struct Tekram_target {
-               u_char  flags;
-#define        TEKRAM_PARITY_CHECK             (1)
-#define TEKRAM_SYNC_NEGO               (1<<1)
-#define TEKRAM_DISCONNECT_ENABLE       (1<<2)
-#define        TEKRAM_START_CMD                (1<<3)
-#define TEKRAM_TAGGED_COMMANDS         (1<<4)
-#define TEKRAM_WIDE_NEGO               (1<<5)
-               u_char  sync_index;
-               u_short word2;
-       } target[16];
-       u_char  host_id;
-       u_char  flags;
-#define TEKRAM_MORE_THAN_2_DRIVES      (1)
-#define TEKRAM_DRIVES_SUP_1GB          (1<<1)
-#define        TEKRAM_RESET_ON_POWER_ON        (1<<2)
-#define TEKRAM_ACTIVE_NEGATION         (1<<3)
-#define TEKRAM_IMMEDIATE_SEEK          (1<<4)
-#define        TEKRAM_SCAN_LUNS                (1<<5)
-#define        TEKRAM_REMOVABLE_FLAGS          (3<<6)  /* 0: disable; 1: boot device; 
2:all */
-       u_char  boot_delay_index;
-       u_char  max_tags_index;
-       u_short flags1;
-#define TEKRAM_F2_F6_ENABLED           (1)
-       u_short spare[29];
-};
-typedef struct Tekram_nvram    Tekram_nvram;
-typedef struct Tekram_target   Tekram_target;
-
 static u_char Tekram_sync[12] __initdata = {25,31,37,43,50,62,75,125,12,15,18,21};
-
 #endif /* SCSI_NCR_NVRAM_SUPPORT */
 
 /*
@@ -934,6 +807,7 @@
        ncr_slot  slot;
        ncr_chip  chip;
        ncr_nvram *nvram;
+       u_char    host_id;
        int attach_done;
 } ncr_device;
 
@@ -4246,9 +4120,11 @@
        /*
        **  Get SCSI addr of host adapter (set by bios?).
        */
-       if (!np->myaddr) np->myaddr = INB(nc_scid) & 0x07;
-       if (!np->myaddr) np->myaddr = SCSI_NCR_MYADDR;
-
+       if (np->myaddr == 255) {
+               np->myaddr = INB(nc_scid) & 0x07;
+               if (!np->myaddr)
+                       np->myaddr = SCSI_NCR_MYADDR;
+       }
 
 #endif /* SCSI_NCR_TRUST_BIOS_SETTING */
 
@@ -4520,6 +4396,7 @@
        np->clock_divn  = device->chip.nr_divisor;
        np->maxoffs     = device->chip.offset_max;
        np->maxburst    = device->chip.burst_max;
+       np->myaddr      = device->host_id;
 
        np->script0  = (struct script *)
                (((u_long) &host_data->script_data) & CACHE_LINE_MASK);
@@ -4607,6 +4484,7 @@
        **      Fill Linux host instance structure
        */
        instance->max_channel   = 0;
+       instance->this_id       = np->myaddr;
        instance->max_id        = np->maxwide ? 16 : 8;
        instance->max_lun       = SCSI_NCR_MAX_LUN;
 #ifndef NCR_IOMAPPED
@@ -9324,6 +9202,8 @@
                        if (xi < SCSI_NCR_MAX_EXCLUDES)
                                driver_setup.excludes[xi++] = val;
                }
+               else if (!strncmp(cur, "hostid:", 7))
+                       driver_setup.host_id    = val;
                else
                        printk("ncr53c8xx_setup: unexpected boot option '%.*s' 
ignored\n", (int)(pc-cur+1), cur);
 
@@ -10974,8 +10854,8 @@
        nvram_stop(np, &gpreg);
        
 #ifdef SCSI_NCR_DEBUG_NVRAM
-printk("ncr53c8xx: NvRAM marker=%x trailer=%x %x %x %x %x %x byte_count=%d/%d 
checksum=%x/%x\n",
-       nvram->start_marker,
+printk("ncr53c8xx: NvRAM type=%x trailer=%x %x %x %x %x %x byte_count=%d/%d 
+checksum=%x/%x\n",
+       nvram->type,
        nvram->trailer[0], nvram->trailer[1], nvram->trailer[2],
        nvram->trailer[3], nvram->trailer[4], nvram->trailer[5],
        nvram->byte_count, sizeof(*nvram) - 12,
@@ -10983,7 +10863,7 @@
 #endif
 
        /* check valid NVRAM signature, verify byte count and checksum */
-       if (nvram->start_marker == 0 &&
+       if (nvram->type == 0 &&
            !memcmp(nvram->trailer, Symbios_trailer, 6) &&
            nvram->byte_count == sizeof(*nvram) - 12 &&
            csum == nvram->checksum)

Reply via email to