patch-2.2.11 linux/drivers/scsi/sym53c8xx.c
Next file: linux/drivers/scsi/sym53c8xx_defs.h
Previous file: linux/drivers/scsi/sym53c416.c
Back to the patch index
Back to the overall index
- Lines: 913
- Date:
Mon Aug 9 12:04:57 1999
- Orig file:
v2.2.10/linux/drivers/scsi/sym53c8xx.c
- Orig date:
Sat May 22 13:42:53 1999
diff -u --recursive --new-file v2.2.10/linux/drivers/scsi/sym53c8xx.c linux/drivers/scsi/sym53c8xx.c
@@ -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,
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)