diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/ncr53c8xx.c | 734 | ||||
-rw-r--r-- | drivers/scsi/ncr53c8xx.h | 1263 | ||||
-rw-r--r-- | drivers/scsi/sym53c8xx_comm.h | 792 | ||||
-rw-r--r-- | drivers/scsi/sym53c8xx_defs.h | 1320 |
4 files changed, 1995 insertions, 2114 deletions
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 8e1c77c81f6..32350707b94 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -131,7 +131,739 @@ #define NAME53C "ncr53c" #define NAME53C8XX "ncr53c8xx" -#include "sym53c8xx_comm.h" + +/*========================================================== +** +** Debugging tags +** +**========================================================== +*/ + +#define DEBUG_ALLOC (0x0001) +#define DEBUG_PHASE (0x0002) +#define DEBUG_QUEUE (0x0008) +#define DEBUG_RESULT (0x0010) +#define DEBUG_POINTER (0x0020) +#define DEBUG_SCRIPT (0x0040) +#define DEBUG_TINY (0x0080) +#define DEBUG_TIMING (0x0100) +#define DEBUG_NEGO (0x0200) +#define DEBUG_TAGS (0x0400) +#define DEBUG_SCATTER (0x0800) +#define DEBUG_IC (0x1000) + +/* +** Enable/Disable debug messages. +** Can be changed at runtime too. +*/ + +#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT +static int ncr_debug = SCSI_NCR_DEBUG_FLAGS; + #define DEBUG_FLAGS ncr_debug +#else + #define DEBUG_FLAGS SCSI_NCR_DEBUG_FLAGS +#endif + +static inline struct list_head *ncr_list_pop(struct list_head *head) +{ + if (!list_empty(head)) { + struct list_head *elem = head->next; + + list_del(elem); + return elem; + } + + return NULL; +} + +/*========================================================== +** +** Simple power of two buddy-like allocator. +** +** This simple code is not intended to be fast, but to +** provide power of 2 aligned memory allocations. +** Since the SCRIPTS processor only supplies 8 bit +** arithmetic, this allocator allows simple and fast +** address calculations from the SCRIPTS code. +** In addition, cache line alignment is guaranteed for +** power of 2 cache line size. +** Enhanced in linux-2.3.44 to provide a memory pool +** per pcidev to support dynamic dma mapping. (I would +** have preferred a real bus astraction, btw). +** +**========================================================== +*/ + +#define MEMO_SHIFT 4 /* 16 bytes minimum memory chunk */ +#if PAGE_SIZE >= 8192 +#define MEMO_PAGE_ORDER 0 /* 1 PAGE maximum */ +#else +#define MEMO_PAGE_ORDER 1 /* 2 PAGES maximum */ +#endif +#define MEMO_FREE_UNUSED /* Free unused pages immediately */ +#define MEMO_WARN 1 +#define MEMO_GFP_FLAGS GFP_ATOMIC +#define MEMO_CLUSTER_SHIFT (PAGE_SHIFT+MEMO_PAGE_ORDER) +#define MEMO_CLUSTER_SIZE (1UL << MEMO_CLUSTER_SHIFT) +#define MEMO_CLUSTER_MASK (MEMO_CLUSTER_SIZE-1) + +typedef u_long m_addr_t; /* Enough bits to bit-hack addresses */ +typedef struct device *m_bush_t; /* Something that addresses DMAable */ + +typedef struct m_link { /* Link between free memory chunks */ + struct m_link *next; +} m_link_s; + +typedef struct m_vtob { /* Virtual to Bus address translation */ + struct m_vtob *next; + m_addr_t vaddr; + m_addr_t baddr; +} m_vtob_s; +#define VTOB_HASH_SHIFT 5 +#define VTOB_HASH_SIZE (1UL << VTOB_HASH_SHIFT) +#define VTOB_HASH_MASK (VTOB_HASH_SIZE-1) +#define VTOB_HASH_CODE(m) \ + ((((m_addr_t) (m)) >> MEMO_CLUSTER_SHIFT) & VTOB_HASH_MASK) + +typedef struct m_pool { /* Memory pool of a given kind */ + m_bush_t bush; + m_addr_t (*getp)(struct m_pool *); + void (*freep)(struct m_pool *, m_addr_t); + int nump; + m_vtob_s *(vtob[VTOB_HASH_SIZE]); + struct m_pool *next; + struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1]; +} m_pool_s; + +static void *___m_alloc(m_pool_s *mp, int size) +{ + int i = 0; + int s = (1 << MEMO_SHIFT); + int j; + m_addr_t a; + m_link_s *h = mp->h; + + if (size > (PAGE_SIZE << MEMO_PAGE_ORDER)) + return NULL; + + while (size > s) { + s <<= 1; + ++i; + } + + j = i; + while (!h[j].next) { + if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) { + h[j].next = (m_link_s *)mp->getp(mp); + if (h[j].next) + h[j].next->next = NULL; + break; + } + ++j; + s <<= 1; + } + a = (m_addr_t) h[j].next; + if (a) { + h[j].next = h[j].next->next; + while (j > i) { + j -= 1; + s >>= 1; + h[j].next = (m_link_s *) (a+s); + h[j].next->next = NULL; + } + } +#ifdef DEBUG + printk("___m_alloc(%d) = %p\n", size, (void *) a); +#endif + return (void *) a; +} + +static void ___m_free(m_pool_s *mp, void *ptr, int size) +{ + int i = 0; + int s = (1 << MEMO_SHIFT); + m_link_s *q; + m_addr_t a, b; + m_link_s *h = mp->h; + +#ifdef DEBUG + printk("___m_free(%p, %d)\n", ptr, size); +#endif + + if (size > (PAGE_SIZE << MEMO_PAGE_ORDER)) + return; + + while (size > s) { + s <<= 1; + ++i; + } + + a = (m_addr_t) ptr; + + while (1) { +#ifdef MEMO_FREE_UNUSED + if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) { + mp->freep(mp, a); + break; + } +#endif + b = a ^ s; + q = &h[i]; + while (q->next && q->next != (m_link_s *) b) { + q = q->next; + } + if (!q->next) { + ((m_link_s *) a)->next = h[i].next; + h[i].next = (m_link_s *) a; + break; + } + q->next = q->next->next; + a = a & b; + s <<= 1; + ++i; + } +} + +static DEFINE_SPINLOCK(ncr53c8xx_lock); + +static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags) +{ + void *p; + + p = ___m_alloc(mp, size); + + if (DEBUG_FLAGS & DEBUG_ALLOC) + printk ("new %-10s[%4d] @%p.\n", name, size, p); + + if (p) + memset(p, 0, size); + else if (uflags & MEMO_WARN) + printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size); + + return p; +} + +#define __m_calloc(mp, s, n) __m_calloc2(mp, s, n, MEMO_WARN) + +static void __m_free(m_pool_s *mp, void *ptr, int size, char *name) +{ + if (DEBUG_FLAGS & DEBUG_ALLOC) + printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr); + + ___m_free(mp, ptr, size); + +} + +/* + * With pci bus iommu support, we use a default pool of unmapped memory + * for memory we donnot need to DMA from/to and one pool per pcidev for + * memory accessed by the PCI chip. `mp0' is the default not DMAable pool. + */ + +static m_addr_t ___mp0_getp(m_pool_s *mp) +{ + m_addr_t m = __get_free_pages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER); + if (m) + ++mp->nump; + return m; +} + +static void ___mp0_freep(m_pool_s *mp, m_addr_t m) +{ + free_pages(m, MEMO_PAGE_ORDER); + --mp->nump; +} + +static m_pool_s mp0 = {NULL, ___mp0_getp, ___mp0_freep}; + +/* + * DMAable pools. + */ + +/* + * With pci bus iommu support, we maintain one pool per pcidev and a + * hashed reverse table for virtual to bus physical address translations. + */ +static m_addr_t ___dma_getp(m_pool_s *mp) +{ + m_addr_t vp; + m_vtob_s *vbp; + + vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB"); + if (vbp) { + dma_addr_t daddr; + vp = (m_addr_t) dma_alloc_coherent(mp->bush, + PAGE_SIZE<<MEMO_PAGE_ORDER, + &daddr, GFP_ATOMIC); + if (vp) { + int hc = VTOB_HASH_CODE(vp); + vbp->vaddr = vp; + vbp->baddr = daddr; + vbp->next = mp->vtob[hc]; + mp->vtob[hc] = vbp; + ++mp->nump; + return vp; + } + } + if (vbp) + __m_free(&mp0, vbp, sizeof(*vbp), "VTOB"); + return 0; +} + +static void ___dma_freep(m_pool_s *mp, m_addr_t m) +{ + m_vtob_s **vbpp, *vbp; + int hc = VTOB_HASH_CODE(m); + + vbpp = &mp->vtob[hc]; + while (*vbpp && (*vbpp)->vaddr != m) + vbpp = &(*vbpp)->next; + if (*vbpp) { + vbp = *vbpp; + *vbpp = (*vbpp)->next; + dma_free_coherent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER, + (void *)vbp->vaddr, (dma_addr_t)vbp->baddr); + __m_free(&mp0, vbp, sizeof(*vbp), "VTOB"); + --mp->nump; + } +} + +static inline m_pool_s *___get_dma_pool(m_bush_t bush) +{ + m_pool_s *mp; + for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next); + return mp; +} + +static m_pool_s *___cre_dma_pool(m_bush_t bush) +{ + m_pool_s *mp; + mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL"); + if (mp) { + memset(mp, 0, sizeof(*mp)); + mp->bush = bush; + mp->getp = ___dma_getp; + mp->freep = ___dma_freep; + mp->next = mp0.next; + mp0.next = mp; + } + return mp; +} + +static void ___del_dma_pool(m_pool_s *p) +{ + struct m_pool **pp = &mp0.next; + + while (*pp && *pp != p) + pp = &(*pp)->next; + if (*pp) { + *pp = (*pp)->next; + __m_free(&mp0, p, sizeof(*p), "MPOOL"); + } +} + +static void *__m_calloc_dma(m_bush_t bush, int size, char *name) +{ + u_long flags; + struct m_pool *mp; + void *m = NULL; + + spin_lock_irqsave(&ncr53c8xx_lock, flags); + mp = ___get_dma_pool(bush); + if (!mp) + mp = ___cre_dma_pool(bush); + if (mp) + m = __m_calloc(mp, size, name); + if (mp && !mp->nump) + ___del_dma_pool(mp); + spin_unlock_irqrestore(&ncr53c8xx_lock, flags); + + return m; +} + +static void __m_free_dma(m_bush_t bush, void *m, int size, char *name) +{ + u_long flags; + struct m_pool *mp; + + spin_lock_irqsave(&ncr53c8xx_lock, flags); + mp = ___get_dma_pool(bush); + if (mp) + __m_free(mp, m, size, name); + if (mp && !mp->nump) + ___del_dma_pool(mp); + spin_unlock_irqrestore(&ncr53c8xx_lock, flags); +} + +static m_addr_t __vtobus(m_bush_t bush, void *m) +{ + u_long flags; + m_pool_s *mp; + int hc = VTOB_HASH_CODE(m); + m_vtob_s *vp = NULL; + m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK; + + spin_lock_irqsave(&ncr53c8xx_lock, flags); + mp = ___get_dma_pool(bush); + if (mp) { + vp = mp->vtob[hc]; + while (vp && (m_addr_t) vp->vaddr != a) + vp = vp->next; + } + spin_unlock_irqrestore(&ncr53c8xx_lock, flags); + return vp ? vp->baddr + (((m_addr_t) m) - a) : 0; +} + +#define _m_calloc_dma(np, s, n) __m_calloc_dma(np->dev, s, n) +#define _m_free_dma(np, p, s, n) __m_free_dma(np->dev, p, s, n) +#define m_calloc_dma(s, n) _m_calloc_dma(np, s, n) +#define m_free_dma(p, s, n) _m_free_dma(np, p, s, n) +#define _vtobus(np, p) __vtobus(np->dev, p) +#define vtobus(p) _vtobus(np, p) + +/* + * Deal with DMA mapping/unmapping. + */ + +/* To keep track of the dma mapping (sg/single) that has been set */ +#define __data_mapped SCp.phase +#define __data_mapping SCp.have_data_in + +static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd) +{ + switch(cmd->__data_mapped) { + case 2: + dma_unmap_sg(dev, cmd->buffer, cmd->use_sg, + cmd->sc_data_direction); + break; + case 1: + dma_unmap_single(dev, cmd->__data_mapping, + cmd->request_bufflen, + cmd->sc_data_direction); + break; + } + cmd->__data_mapped = 0; +} + +static u_long __map_scsi_single_data(struct device *dev, struct scsi_cmnd *cmd) +{ + dma_addr_t mapping; + + if (cmd->request_bufflen == 0) + return 0; + + mapping = dma_map_single(dev, cmd->request_buffer, + cmd->request_bufflen, + cmd->sc_data_direction); + cmd->__data_mapped = 1; + cmd->__data_mapping = mapping; + + return mapping; +} + +static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd) +{ + int use_sg; + + if (cmd->use_sg == 0) + return 0; + + use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg, + cmd->sc_data_direction); + cmd->__data_mapped = 2; + cmd->__data_mapping = use_sg; + + return use_sg; +} + +#define unmap_scsi_data(np, cmd) __unmap_scsi_data(np->dev, cmd) +#define map_scsi_single_data(np, cmd) __map_scsi_single_data(np->dev, cmd) +#define map_scsi_sg_data(np, cmd) __map_scsi_sg_data(np->dev, cmd) + +/*========================================================== +** +** Driver setup. +** +** This structure is initialized from linux config +** options. It can be overridden at boot-up by the boot +** command line. +** +**========================================================== +*/ +static struct ncr_driver_setup + driver_setup = SCSI_NCR_DRIVER_SETUP; + +#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT +static struct ncr_driver_setup + driver_safe_setup __initdata = SCSI_NCR_DRIVER_SAFE_SETUP; +#endif + +#define initverbose (driver_setup.verbose) +#define bootverbose (np->verbose) + + +/*=================================================================== +** +** Driver setup from the boot command line +** +**=================================================================== +*/ + +#ifdef MODULE +#define ARG_SEP ' ' +#else +#define ARG_SEP ',' +#endif + +#define OPT_TAGS 1 +#define OPT_MASTER_PARITY 2 +#define OPT_SCSI_PARITY 3 +#define OPT_DISCONNECTION 4 +#define OPT_SPECIAL_FEATURES 5 +#define OPT_UNUSED_1 6 +#define OPT_FORCE_SYNC_NEGO 7 +#define OPT_REVERSE_PROBE 8 +#define OPT_DEFAULT_SYNC 9 +#define OPT_VERBOSE 10 +#define OPT_DEBUG 11 +#define OPT_BURST_MAX 12 +#define OPT_LED_PIN 13 +#define OPT_MAX_WIDE 14 +#define OPT_SETTLE_DELAY 15 +#define OPT_DIFF_SUPPORT 16 +#define OPT_IRQM 17 +#define OPT_PCI_FIX_UP 18 +#define OPT_BUS_CHECK 19 +#define OPT_OPTIMIZE 20 +#define OPT_RECOVERY 21 +#define OPT_SAFE_SETUP 22 +#define OPT_USE_NVRAM 23 +#define OPT_EXCLUDE 24 +#define OPT_HOST_ID 25 + +#ifdef SCSI_NCR_IARB_SUPPORT +#define OPT_IARB 26 +#endif + +static char setup_token[] __initdata = + "tags:" "mpar:" + "spar:" "disc:" + "specf:" "ultra:" + "fsn:" "revprob:" + "sync:" "verb:" + "debug:" "burst:" + "led:" "wide:" + "settle:" "diff:" + "irqm:" "pcifix:" + "buschk:" "optim:" + "recovery:" + "safe:" "nvram:" + "excl:" "hostid:" +#ifdef SCSI_NCR_IARB_SUPPORT + "iarb:" +#endif + ; /* DONNOT REMOVE THIS ';' */ + +#ifdef MODULE +#define ARG_SEP ' ' +#else +#define ARG_SEP ',' +#endif + +static int __init get_setup_token(char *p) +{ + char *cur = setup_token; + char *pc; + int i = 0; + + while (cur != NULL && (pc = strchr(cur, ':')) != NULL) { + ++pc; + ++i; + if (!strncmp(p, cur, pc - cur)) + return i; + cur = pc; + } + return 0; +} + + +static int __init sym53c8xx__setup(char *str) +{ +#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT + char *cur = str; + char *pc, *pv; + int i, val, c; + int xi = 0; + + while (cur != NULL && (pc = strchr(cur, ':')) != NULL) { + char *pe; + + val = 0; + pv = pc; + c = *++pv; + + if (c == 'n') + val = 0; + else if (c == 'y') + val = 1; + else + val = (int) simple_strtoul(pv, &pe, 0); + + switch (get_setup_token(cur)) { + case OPT_TAGS: + driver_setup.default_tags = val; + if (pe && *pe == '/') { + i = 0; + while (*pe && *pe != ARG_SEP && + i < sizeof(driver_setup.tag_ctrl)-1) { + driver_setup.tag_ctrl[i++] = *pe++; + } + driver_setup.tag_ctrl[i] = '\0'; + } + break; + case OPT_MASTER_PARITY: + driver_setup.master_parity = val; + break; + case OPT_SCSI_PARITY: + driver_setup.scsi_parity = val; + break; + case OPT_DISCONNECTION: + driver_setup.disconnection = val; + break; + case OPT_SPECIAL_FEATURES: + driver_setup.special_features = val; + break; + case OPT_FORCE_SYNC_NEGO: + driver_setup.force_sync_nego = val; + break; + case OPT_REVERSE_PROBE: + driver_setup.reverse_probe = val; + break; + case OPT_DEFAULT_SYNC: + driver_setup.default_sync = val; + break; + case OPT_VERBOSE: + driver_setup.verbose = val; + break; + case OPT_DEBUG: + driver_setup.debug = val; + break; + case OPT_BURST_MAX: + driver_setup.burst_max = val; + break; + case OPT_LED_PIN: + driver_setup.led_pin = val; + break; + case OPT_MAX_WIDE: + driver_setup.max_wide = val? 1:0; + break; + case OPT_SETTLE_DELAY: + driver_setup.settle_delay = val; + break; + case OPT_DIFF_SUPPORT: + driver_setup.diff_support = val; + break; + case OPT_IRQM: + driver_setup.irqm = val; + break; + case OPT_PCI_FIX_UP: + driver_setup.pci_fix_up = val; + break; + case OPT_BUS_CHECK: + driver_setup.bus_check = val; + break; + case OPT_OPTIMIZE: + driver_setup.optimize = val; + break; + case OPT_RECOVERY: + driver_setup.recovery = val; + break; + case OPT_USE_NVRAM: + driver_setup.use_nvram = val; + break; + case OPT_SAFE_SETUP: + memcpy(&driver_setup, &driver_safe_setup, + sizeof(driver_setup)); + break; + case OPT_EXCLUDE: + if (xi < SCSI_NCR_MAX_EXCLUDES) + driver_setup.excludes[xi++] = val; + break; + case OPT_HOST_ID: + driver_setup.host_id = val; + break; +#ifdef SCSI_NCR_IARB_SUPPORT + case OPT_IARB: + driver_setup.iarb = val; + break; +#endif + default: + printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur); + break; + } + + if ((cur = strchr(cur, ARG_SEP)) != NULL) + ++cur; + } +#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */ + return 1; +} + +/*=================================================================== +** +** Get device queue depth from boot command line. +** +**=================================================================== +*/ +#define DEF_DEPTH (driver_setup.default_tags) +#define ALL_TARGETS -2 +#define NO_TARGET -1 +#define ALL_LUNS -2 +#define NO_LUN -1 + +static int device_queue_depth(int unit, int target, int lun) +{ + int c, h, t, u, v; + char *p = driver_setup.tag_ctrl; + char *ep; + + h = -1; + t = NO_TARGET; + u = NO_LUN; + while ((c = *p++) != 0) { + v = simple_strtoul(p, &ep, 0); + switch(c) { + case '/': + ++h; + t = ALL_TARGETS; + u = ALL_LUNS; + break; + case 't': + if (t != target) + t = (target == v) ? v : NO_TARGET; + u = ALL_LUNS; + break; + case 'u': + if (u != lun) + u = (lun == v) ? v : NO_LUN; + break; + case 'q': + if (h == unit && + (t == ALL_TARGETS || t == target) && + (u == ALL_LUNS || u == lun)) + return v; + break; + case '-': + t = ALL_TARGETS; + u = ALL_LUNS; + break; + default: + break; + } + p = ep; + } + return DEF_DEPTH; +} /*========================================================== diff --git a/drivers/scsi/ncr53c8xx.h b/drivers/scsi/ncr53c8xx.h index 05c7b83cef0..6a7bef2e611 100644 --- a/drivers/scsi/ncr53c8xx.h +++ b/drivers/scsi/ncr53c8xx.h @@ -2,6 +2,7 @@ ** Device driver for the PCI-SCSI NCR538XX controller family. ** ** Copyright (C) 1994 Wolfgang Stanglmeier +** Copyright (C) 1998-2001 Gerard Roudier <groudier@free.fr> ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by @@ -36,15 +37,1275 @@ ** And has been ported to NetBSD by ** Charles M. Hannum <mycroft@gnu.ai.mit.edu> ** +** NVRAM detection and reading. +** Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> +** +** Added support for MIPS big endian systems. +** Carsten Langgaard, carstenl@mips.com +** Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. +** +** Added support for HP PARISC big endian systems. +** Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. +** ******************************************************************************* */ #ifndef NCR53C8XX_H #define NCR53C8XX_H +#include <linux/config.h> #include <scsi/scsi_host.h> -#include "sym53c8xx_defs.h" +/* +** If you want a driver as small as possible, do not define the +** following options. +*/ +#define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT +#define SCSI_NCR_DEBUG_INFO_SUPPORT + +/* +** To disable integrity checking, do not define the +** following option. +*/ +#ifdef CONFIG_SCSI_NCR53C8XX_INTEGRITY_CHECK +# define SCSI_NCR_ENABLE_INTEGRITY_CHECK +#endif + +/* --------------------------------------------------------------------- +** Take into account kernel configured parameters. +** Most of these options can be overridden at startup by a command line. +** --------------------------------------------------------------------- +*/ + +/* + * For Ultra2 and Ultra3 SCSI support option, use special features. + * + * Value (default) means: + * bit 0 : all features enabled, except: + * bit 1 : PCI Write And Invalidate. + * bit 2 : Data Phase Mismatch handling from SCRIPTS. + * + * Use boot options ncr53c8xx=specf:1 if you want all chip features to be + * enabled by the driver. + */ +#define SCSI_NCR_SETUP_SPECIAL_FEATURES (3) + +#define SCSI_NCR_MAX_SYNC (80) + +/* + * Allow tags from 2 to 256, default 8 + */ +#ifdef CONFIG_SCSI_NCR53C8XX_MAX_TAGS +#if CONFIG_SCSI_NCR53C8XX_MAX_TAGS < 2 +#define SCSI_NCR_MAX_TAGS (2) +#elif CONFIG_SCSI_NCR53C8XX_MAX_TAGS > 256 +#define SCSI_NCR_MAX_TAGS (256) +#else +#define SCSI_NCR_MAX_TAGS CONFIG_SCSI_NCR53C8XX_MAX_TAGS +#endif +#else +#define SCSI_NCR_MAX_TAGS (8) +#endif + +/* + * Allow tagged command queuing support if configured with default number + * of tags set to max (see above). + */ +#ifdef CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS +#define SCSI_NCR_SETUP_DEFAULT_TAGS CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS +#elif defined CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE +#define SCSI_NCR_SETUP_DEFAULT_TAGS SCSI_NCR_MAX_TAGS +#else +#define SCSI_NCR_SETUP_DEFAULT_TAGS (0) +#endif + +/* + * Immediate arbitration + */ +#if defined(CONFIG_SCSI_NCR53C8XX_IARB) +#define SCSI_NCR_IARB_SUPPORT +#endif + +/* + * Sync transfer frequency at startup. + * Allow from 5Mhz to 80Mhz default 20 Mhz. + */ +#ifndef CONFIG_SCSI_NCR53C8XX_SYNC +#define CONFIG_SCSI_NCR53C8XX_SYNC (20) +#elif CONFIG_SCSI_NCR53C8XX_SYNC > SCSI_NCR_MAX_SYNC +#undef CONFIG_SCSI_NCR53C8XX_SYNC +#define CONFIG_SCSI_NCR53C8XX_SYNC SCSI_NCR_MAX_SYNC +#endif + +#if CONFIG_SCSI_NCR53C8XX_SYNC == 0 +#define SCSI_NCR_SETUP_DEFAULT_SYNC (255) +#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 5 +#define SCSI_NCR_SETUP_DEFAULT_SYNC (50) +#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 20 +#define SCSI_NCR_SETUP_DEFAULT_SYNC (250/(CONFIG_SCSI_NCR53C8XX_SYNC)) +#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 33 +#define SCSI_NCR_SETUP_DEFAULT_SYNC (11) +#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 40 +#define SCSI_NCR_SETUP_DEFAULT_SYNC (10) +#else +#define SCSI_NCR_SETUP_DEFAULT_SYNC (9) +#endif + +/* + * Disallow disconnections at boot-up + */ +#ifdef CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT +#define SCSI_NCR_SETUP_DISCONNECTION (0) +#else +#define SCSI_NCR_SETUP_DISCONNECTION (1) +#endif + +/* + * Force synchronous negotiation for all targets + */ +#ifdef CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO +#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO (1) +#else +#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO (0) +#endif + +/* + * Disable master parity checking (flawed hardwares need that) + */ +#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK +#define SCSI_NCR_SETUP_MASTER_PARITY (0) +#else +#define SCSI_NCR_SETUP_MASTER_PARITY (1) +#endif + +/* + * Disable scsi parity checking (flawed devices may need that) + */ +#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK +#define SCSI_NCR_SETUP_SCSI_PARITY (0) +#else +#define SCSI_NCR_SETUP_SCSI_PARITY (1) +#endif + +/* + * Settle time after reset at boot-up + */ +#define SCSI_NCR_SETUP_SETTLE_TIME (2) + +/* +** Bridge quirks work-around option defaulted to 1. +*/ +#ifndef SCSI_NCR_PCIQ_WORK_AROUND_OPT +#define SCSI_NCR_PCIQ_WORK_AROUND_OPT 1 +#endif + +/* +** Work-around common bridge misbehaviour. +** +** - Do not flush posted writes in the opposite +** direction on read. +** - May reorder DMA writes to memory. +** +** This option should not affect performances +** significantly, so it is the default. +*/ +#if SCSI_NCR_PCIQ_WORK_AROUND_OPT == 1 +#define SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM +#define SCSI_NCR_PCIQ_MAY_REORDER_WRITES +#define SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS + +/* +** Same as option 1, but also deal with +** misconfigured interrupts. +** +** - Edge triggerred instead of level sensitive. +** - No interrupt line connected. +** - IRQ number misconfigured. +** +** If no interrupt is delivered, the driver will +** catch the interrupt conditions 10 times per +** second. No need to say that this option is +** not recommended. +*/ +#elif SCSI_NCR_PCIQ_WORK_AROUND_OPT == 2 +#define SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM +#define SCSI_NCR_PCIQ_MAY_REORDER_WRITES +#define SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS +#define SCSI_NCR_PCIQ_BROKEN_INTR + +/* +** Some bridge designers decided to flush +** everything prior to deliver the interrupt. +** This option tries to deal with such a +** behaviour. +*/ +#elif SCSI_NCR_PCIQ_WORK_AROUND_OPT == 3 +#define SCSI_NCR_PCIQ_SYNC_ON_INTR +#endif + +/* +** Other parameters not configurable with "make config" +** Avoid to change these constants, unless you know what you are doing. +*/ + +#define SCSI_NCR_ALWAYS_SIMPLE_TAG +#define SCSI_NCR_MAX_SCATTER (127) +#define SCSI_NCR_MAX_TARGET (16) + +/* +** Compute some desirable value for CAN_QUEUE +** and CMD_PER_LUN. +** The driver will use lower values if these +** ones appear to be too large. +*/ +#define SCSI_NCR_CAN_QUEUE (8*SCSI_NCR_MAX_TAGS + 2*SCSI_NCR_MAX_TARGET) +#define SCSI_NCR_CMD_PER_LUN (SCSI_NCR_MAX_TAGS) + +#define SCSI_NCR_SG_TABLESIZE (SCSI_NCR_MAX_SCATTER) +#define SCSI_NCR_TIMER_INTERVAL (HZ) + +#if 1 /* defined CONFIG_SCSI_MULTI_LUN */ +#define SCSI_NCR_MAX_LUN (16) +#else +#define SCSI_NCR_MAX_LUN (1) +#endif + +/* + * IO functions definition for big/little endian CPU support. + * For now, the NCR is only supported in little endian addressing mode, + */ + +#ifdef __BIG_ENDIAN + +#define inw_l2b inw +#define inl_l2b inl +#define outw_b2l outw +#define outl_b2l outl + +#define readb_raw readb +#define writeb_raw writeb + +#if defined(SCSI_NCR_BIG_ENDIAN) +#define readw_l2b __raw_readw +#define readl_l2b __raw_readl +#define writew_b2l __raw_writew +#define writel_b2l __raw_writel +#define readw_raw __raw_readw +#define readl_raw __raw_readl +#define writew_raw __raw_writew +#define writel_raw __raw_writel +#else /* Other big-endian */ +#define readw_l2b readw +#define readl_l2b readl +#define writew_b2l writew +#define writel_b2l writel +#define readw_raw readw +#define readl_raw readl +#define writew_raw writew +#define writel_raw writel +#endif + +#else /* little endian */ + +#define inw_raw inw +#define inl_raw inl +#define outw_raw outw +#define outl_raw outl + +#define readb_raw readb +#define readw_raw readw +#define readl_raw readl +#define writeb_raw writeb +#define writew_raw writew +#define writel_raw writel + +#endif + +#if !defined(__hppa__) && !defined(__mips__) +#ifdef SCSI_NCR_BIG_ENDIAN +#error "The NCR in BIG ENDIAN addressing mode is not (yet) supported" +#endif +#endif + +#define MEMORY_BARRIER() mb() + + +/* + * If the NCR uses big endian addressing mode over the + * PCI, actual io register addresses for byte and word + * accesses must be changed according to lane routing. + * Btw, ncr_offb() and ncr_offw() macros only apply to + * constants and so donnot generate bloated code. + */ + +#if defined(SCSI_NCR_BIG_ENDIAN) + +#define ncr_offb(o) (((o)&~3)+((~((o)&3))&3)) +#define ncr_offw(o) (((o)&~3)+((~((o)&3))&2)) + +#else + +#define ncr_offb(o) (o) +#define ncr_offw(o) (o) + +#endif + +/* + * If the CPU and the NCR use same endian-ness addressing, + * no byte reordering is needed for script patching. + * Macro cpu_to_scr() is to be used for script patching. + * Macro scr_to_cpu() is to be used for getting a DWORD + * from the script. + */ + +#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN) + +#define cpu_to_scr(dw) cpu_to_le32(dw) +#define scr_to_cpu(dw) le32_to_cpu(dw) + +#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN) + +#define cpu_to_scr(dw) cpu_to_be32(dw) +#define scr_to_cpu(dw) be32_to_cpu(dw) + +#else + +#define cpu_to_scr(dw) (dw) +#define scr_to_cpu(dw) (dw) + +#endif + +/* + * Access to the controller chip. + * + * If the CPU and the NCR use same endian-ness addressing, + * no byte reordering is needed for accessing chip io + * registers. Functions suffixed by '_raw' are assumed + * to access the chip over the PCI without doing byte + * reordering. Functions suffixed by '_l2b' are + * assumed to perform little-endian to big-endian byte + * reordering, those suffixed by '_b2l' blah, blah, + * blah, ... + */ + +/* + * MEMORY mapped IO input / output + */ + +#define INB_OFF(o) readb_raw((char __iomem *)np->reg + ncr_offb(o)) +#define OUTB_OFF(o, val) writeb_raw((val), (char __iomem *)np->reg + ncr_offb(o)) + +#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN) + +#define INW_OFF(o) readw_l2b((char __iomem *)np->reg + ncr_offw(o)) +#define INL_OFF(o) readl_l2b((char __iomem *)np->reg + (o)) + +#define OUTW_OFF(o, val) writew_b2l((val), (char __iomem *)np->reg + ncr_offw(o)) +#define OUTL_OFF(o, val) writel_b2l((val), (char __iomem *)np->reg + (o)) + +#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN) + +#define INW_OFF(o) readw_b2l((char __iomem *)np->reg + ncr_offw(o)) +#define INL_OFF(o) readl_b2l((char __iomem *)np->reg + (o)) + +#define OUTW_OFF(o, val) writew_l2b((val), (char __iomem *)np->reg + ncr_offw(o)) +#define OUTL_OFF(o, val) writel_l2b((val), (char __iomem *)np->reg + (o)) + +#else + +#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS +/* Only 8 or 32 bit transfers allowed */ +#define INW_OFF(o) (readb((char __iomem *)np->reg + ncr_offw(o)) << 8 | readb((char __iomem *)np->reg + ncr_offw(o) + 1)) +#else +#define INW_OFF(o) readw_raw((char __iomem *)np->reg + ncr_offw(o)) +#endif +#define INL_OFF(o) readl_raw((char __iomem *)np->reg + (o)) + +#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS +/* Only 8 or 32 bit transfers allowed */ +#define OUTW_OFF(o, val) do { writeb((char)((val) >> 8), (char __iomem *)np->reg + ncr_offw(o)); writeb((char)(val), (char __iomem *)np->reg + ncr_offw(o) + 1); } while (0) +#else +#define OUTW_OFF(o, val) writew_raw((val), (char __iomem *)np->reg + ncr_offw(o)) +#endif +#define OUTL_OFF(o, val) writel_raw((val), (char __iomem *)np->reg + (o)) + +#endif + +#define INB(r) INB_OFF (offsetof(struct ncr_reg,r)) +#define INW(r) INW_OFF (offsetof(struct ncr_reg,r)) +#define INL(r) INL_OFF (offsetof(struct ncr_reg,r)) + +#define OUTB(r, val) OUTB_OFF (offsetof(struct ncr_reg,r), (val)) +#define OUTW(r, val) OUTW_OFF (offsetof(struct ncr_reg,r), (val)) +#define OUTL(r, val) OUTL_OFF (offsetof(struct ncr_reg,r), (val)) + +/* + * Set bit field ON, OFF + */ + +#define OUTONB(r, m) OUTB(r, INB(r) | (m)) +#define OUTOFFB(r, m) OUTB(r, INB(r) & ~(m)) +#define OUTONW(r, m) OUTW(r, INW(r) | (m)) +#define OUTOFFW(r, m) OUTW(r, INW(r) & ~(m)) +#define OUTONL(r, m) OUTL(r, INL(r) | (m)) +#define OUTOFFL(r, m) OUTL(r, INL(r) & ~(m)) + +/* + * We normally want the chip to have a consistent view + * of driver internal data structures when we restart it. + * Thus these macros. + */ +#define OUTL_DSP(v) \ + do { \ + MEMORY_BARRIER(); \ + OUTL (nc_dsp, (v)); \ + } while (0) + +#define OUTONB_STD() \ + do { \ + MEMORY_BARRIER(); \ + OUTONB (nc_dcntl, (STD|NOCOM)); \ + } while (0) + + +/* +** NCR53C8XX devices features table. +*/ +struct ncr_chip { + unsigned short revision_id; + unsigned char burst_max; /* log-base-2 of max burst */ + unsigned char offset_max; + unsigned char nr_divisor; + unsigned int features; +#define FE_LED0 (1<<0) +#define FE_WIDE (1<<1) /* Wide data transfers */ +#define FE_ULTRA (1<<2) /* Ultra speed 20Mtrans/sec */ +#define FE_DBLR (1<<4) /* Clock doubler present */ +#define FE_QUAD (1<<5) /* Clock quadrupler present */ +#define FE_ERL (1<<6) /* Enable read line */ +#define FE_CLSE (1<<7) /* Cache line size enable */ +#define FE_WRIE (1<<8) /* Write & Invalidate enable */ +#define FE_ERMP (1<<9) /* Enable read multiple */ +#define FE_BOF (1<<10) /* Burst opcode fetch */ +#define FE_DFS (1<<11) /* DMA fifo size */ +#define FE_PFEN (1<<12) /* Prefetch enable */ +#define FE_LDSTR (1<<13) /* Load/Store supported */ +#define FE_RAM (1<<14) /* On chip RAM present */ +#define FE_VARCLK (1<<15) /* SCSI clock may vary */ +#define FE_RAM8K (1<<16) /* On chip RAM sized 8Kb */ +#define FE_64BIT (1<<17) /* Have a 64-bit PCI interface */ +#define FE_IO256 (1<<18) /* Requires full 256 bytes in PCI space */ +#define FE_NOPM (1<<19) /* Scripts handles phase mismatch */ +#define FE_LEDC (1<<20) /* Hardware control of LED */ +#define FE_DIFF (1<<21) /* Support Differential SCSI */ +#define FE_66MHZ (1<<23) /* 66MHz PCI Support */ +#define FE_DAC (1<<24) /* Support DAC cycles (64 bit addressing) */ +#define FE_ISTAT1 (1<<25) /* Have ISTAT1, MBOX0, MBOX1 registers */ +#define FE_DAC_IN_USE (1<<26) /* Platform does DAC cycles */ +#define FE_EHP (1<<27) /* 720: Even host parity */ +#define FE_MUX (1<<28) /* 720: Multiplexed bus */ +#define FE_EA (1<<29) /* 720: Enable Ack */ + +#define FE_CACHE_SET (FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP) +#define FE_SCSI_SET (FE_WIDE|FE_ULTRA|FE_DBLR|FE_QUAD|F_CLK80) +#define FE_SPECIAL_SET (FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM) +}; + + +/* +** 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 { + u8 master_parity; + u8 scsi_parity; + u8 disconnection; + u8 special_features; + u8 force_sync_nego; + u8 reverse_probe; + u8 pci_fix_up; + u8 use_nvram; + u8 verbose; + u8 default_tags; + u16 default_sync; + u16 debug; + u8 burst_max; + u8 led_pin; + u8 max_wide; + u8 settle_delay; + u8 diff_support; + u8 irqm; + u8 bus_check; + u8 optimize; + u8 recovery; + u8 host_id; + u16 iarb; + u32 excludes[SCSI_NCR_MAX_EXCLUDES]; + char tag_ctrl[100]; +}; + +/* +** Initial setup. +** Can be overriden at startup by a command line. +*/ +#define SCSI_NCR_DRIVER_SETUP \ +{ \ + SCSI_NCR_SETUP_MASTER_PARITY, \ + SCSI_NCR_SETUP_SCSI_PARITY, \ + SCSI_NCR_SETUP_DISCONNECTION, \ + SCSI_NCR_SETUP_SPECIAL_FEATURES, \ + SCSI_NCR_SETUP_FORCE_SYNC_NEGO, \ + 0, \ + 0, \ + 1, \ + 0, \ + SCSI_NCR_SETUP_DEFAULT_TAGS, \ + SCSI_NCR_SETUP_DEFAULT_SYNC, \ + 0x00, \ + 7, \ + 0, \ + 1, \ + SCSI_NCR_SETUP_SETTLE_TIME, \ + 0, \ + 0, \ + 1, \ + 0, \ + 0, \ + 255, \ + 0x00 \ +} + +/* +** Boot fail safe setup. +** Override initial setup from boot command line: +** ncr53c8xx=safe:y +*/ +#define SCSI_NCR_DRIVER_SAFE_SETUP \ +{ \ + 0, \ + 1, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 1, \ + 2, \ + 0, \ + 255, \ + 0x00, \ + 255, \ + 0, \ + 0, \ + 10, \ + 1, \ + 1, \ + 1, \ + 0, \ + 0, \ + 255 \ +} + +/**************** ORIGINAL CONTENT of ncrreg.h from FreeBSD ******************/ + +/*----------------------------------------------------------------- +** +** The ncr 53c810 register structure. +** +**----------------------------------------------------------------- +*/ + +struct ncr_reg { +/*00*/ u8 nc_scntl0; /* full arb., ena parity, par->ATN */ + +/*01*/ u8 nc_scntl1; /* no reset */ + #define ISCON 0x10 /* connected to scsi */ + #define CRST 0x08 /* force reset */ + #define IARB 0x02 /* immediate arbitration */ + +/*02*/ u8 nc_scntl2; /* no disconnect expected */ + #define SDU 0x80 /* cmd: disconnect will raise error */ + #define CHM 0x40 /* sta: chained mode */ + #define WSS 0x08 /* sta: wide scsi send [W]*/ + #define WSR 0x01 /* sta: wide scsi received [W]*/ + +/*03*/ u8 nc_scntl3; /* cnf system clock dependent */ + #define EWS 0x08 /* cmd: enable wide scsi [W]*/ + #define ULTRA 0x80 /* cmd: ULTRA enable */ + /* bits 0-2, 7 rsvd for C1010 */ + +/*04*/ u8 nc_scid; /* cnf host adapter scsi address */ + #define RRE 0x40 /* r/w:e enable response to resel. */ + #define SRE 0x20 /* r/w:e enable response to select */ + +/*05*/ u8 nc_sxfer; /* ### Sync speed and count */ + /* bits 6-7 rsvd for C1010 */ + +/*06*/ u8 nc_sdid; /* ### Destination-ID */ + +/*07*/ u8 nc_gpreg; /* ??? IO-Pins */ + +/*08*/ u8 nc_sfbr; /* ### First byte in phase */ + +/*09*/ u8 nc_socl; + #define CREQ 0x80 /* r/w: SCSI-REQ */ + #define CACK 0x40 /* r/w: SCSI-ACK */ + #define CBSY 0x20 /* r/w: SCSI-BSY */ + #define CSEL 0x10 /* r/w: SCSI-SEL */ + #define CATN 0x08 /* r/w: SCSI-ATN */ + #define CMSG 0x04 /* r/w: SCSI-MSG */ + #define CC_D 0x02 /* r/w: SCSI-C_D */ + #define CI_O 0x01 /* r/w: SCSI-I_O */ + +/*0a*/ u8 nc_ssid; + +/*0b*/ u8 nc_sbcl; + +/*0c*/ u8 nc_dstat; + #define DFE 0x80 /* sta: dma fifo empty */ + #define MDPE 0x40 /* int: master data parity error */ + #define BF 0x20 /* int: script: bus fault */ + #define ABRT 0x10 /* int: script: command aborted */ + #define SSI 0x08 /* int: script: single step */ + #define SIR 0x04 /* int: script: interrupt instruct. */ + #define IID 0x01 /* int: script: illegal instruct. */ + +/*0d*/ u8 nc_sstat0; + #define ILF 0x80 /* sta: data in SIDL register lsb */ + #define ORF 0x40 /* sta: data in SODR register lsb */ + #define OLF 0x20 /* sta: data in SODL register lsb */ + #define AIP 0x10 /* sta: arbitration in progress */ + #define LOA 0x08 /* sta: arbitration lost */ + #define WOA 0x04 /* sta: arbitration won */ + #define IRST 0x02 /* sta: scsi reset signal */ + #define SDP 0x01 /* sta: scsi parity signal */ + +/*0e*/ u8 nc_sstat1; + #define FF3210 0xf0 /* sta: bytes in the scsi fifo */ + +/*0f*/ u8 nc_sstat2; + #define ILF1 0x80 /* sta: data in SIDL register msb[W]*/ + #define ORF1 0x40 /* sta: data in SODR register msb[W]*/ + #define OLF1 0x20 /* sta: data in SODL register msb[W]*/ + #define DM 0x04 /* sta: DIFFSENS mismatch (895/6 only) */ + #define LDSC 0x02 /* sta: disconnect & reconnect */ + +/*10*/ u8 nc_dsa; /* --> Base page */ +/*11*/ u8 nc_dsa1; +/*12*/ u8 nc_dsa2; +/*13*/ u8 nc_dsa3; + +/*14*/ u8 nc_istat; /* --> Main Command and status */ + #define CABRT 0x80 /* cmd: abort current operation */ + #define SRST 0x40 /* mod: reset chip */ + #define SIGP 0x20 /* r/w: message from host to ncr */ + #define SEM 0x10 /* r/w: message between host + ncr */ + #define CON 0x08 /* sta: connected to scsi */ + #define INTF 0x04 /* sta: int on the fly (reset by wr)*/ + #define SIP 0x02 /* sta: scsi-interrupt */ + #define DIP 0x01 /* sta: host/script interrupt */ + +/*15*/ u8 nc_istat1; /* 896 and later cores only */ + #define FLSH 0x04 /* sta: chip is flushing */ + #define SRUN 0x02 /* sta: scripts are running */ + #define SIRQD 0x01 /* r/w: disable INT pin */ + +/*16*/ u8 nc_mbox0; /* 896 and later cores only */ +/*17*/ u8 nc_mbox1; /* 896 and later cores only */ + +/*18*/ u8 nc_ctest0; + #define EHP 0x04 /* 720 even host parity */ +/*19*/ u8 nc_ctest1; + +/*1a*/ u8 nc_ctest2; + #define CSIGP 0x40 + /* bits 0-2,7 rsvd for C1010 */ + +/*1b*/ u8 nc_ctest3; + #define FLF 0x08 /* cmd: flush dma fifo */ + #define CLF 0x04 /* cmd: clear dma fifo */ + #define FM 0x02 /* mod: fetch pin mode */ + #define WRIE 0x01 /* mod: write and invalidate enable */ + /* bits 4-7 rsvd for C1010 */ + +/*1c*/ u32 nc_temp; /* ### Temporary stack */ + +/*20*/ u8 nc_dfifo; +/*21*/ u8 nc_ctest4; + #define MUX 0x80 /* 720 host bus multiplex mode */ + #define BDIS 0x80 /* mod: burst disable */ + #define MPEE 0x08 /* mod: master parity error enable */ + +/*22*/ u8 nc_ctest5; + #define DFS 0x20 /* mod: dma fifo size */ + /* bits 0-1, 3-7 rsvd for C1010 */ +/*23*/ u8 nc_ctest6; + +/*24*/ u32 nc_dbc; /* ### Byte count and command */ +/*28*/ u32 nc_dnad; /* ### Next command register */ +/*2c*/ u32 nc_dsp; /* --> Script Pointer */ +/*30*/ u32 nc_dsps; /* --> Script pointer save/opcode#2 */ + +/*34*/ u8 nc_scratcha; /* Temporary register a */ +/*35*/ u8 nc_scratcha1; +/*36*/ u8 nc_scratcha2; +/*37*/ u8 nc_scratcha3; + +/*38*/ u8 nc_dmode; + #define BL_2 0x80 /* mod: burst length shift value +2 */ + #define BL_1 0x40 /* mod: burst length shift value +1 */ + #define ERL 0x08 /* mod: enable read line */ + #define ERMP 0x04 /* mod: enable read multiple */ + #define BOF 0x02 /* mod: burst op code fetch */ + +/*39*/ u8 nc_dien; +/*3a*/ u8 nc_sbr; + +/*3b*/ u8 nc_dcntl; /* --> Script execution control */ + #define CLSE 0x80 /* mod: cache line size enable */ + #define PFF 0x40 /* cmd: pre-fetch flush */ + #define PFEN 0x20 /* mod: pre-fetch enable */ + #define EA 0x20 /* mod: 720 enable-ack */ + #define SSM 0x10 /* mod: single step mode */ + #define IRQM 0x08 /* mod: irq mode (1 = totem pole !) */ + #define STD 0x04 /* cmd: start dma mode */ + #define IRQD 0x02 /* mod: irq disable */ + #define NOCOM 0x01 /* cmd: protect sfbr while reselect */ + /* bits 0-1 rsvd for C1010 */ + +/*3c*/ u32 nc_adder; + +/*40*/ u16 nc_sien; /* -->: interrupt enable */ +/*42*/ u16 nc_sist; /* <--: interrupt status */ + #define SBMC 0x1000/* sta: SCSI Bus Mode Change (895/6 only) */ + #define STO 0x0400/* sta: timeout (select) */ + #define GEN 0x0200/* sta: timeout (general) */ + #define HTH 0x0100/* sta: timeout (handshake) */ + #define MA 0x80 /* sta: phase mismatch */ + #define CMP 0x40 /* sta: arbitration complete */ + #define SEL 0x20 /* sta: selected by another device */ + #define RSL 0x10 /* sta: reselected by another device*/ + #define SGE 0x08 /* sta: gross error (over/underflow)*/ + #define UDC 0x04 /* sta: unexpected disconnect */ + #define RST 0x02 /* sta: scsi bus reset detected */ + #define PAR 0x01 /* sta: scsi parity error */ + +/*44*/ u8 nc_slpar; +/*45*/ u8 nc_swide; +/*46*/ u8 nc_macntl; +/*47*/ u8 nc_gpcntl; +/*48*/ u8 nc_stime0; /* cmd: timeout for select&handshake*/ +/*49*/ u8 nc_stime1; /* cmd: timeout user defined */ +/*4a*/ u16 nc_respid; /* sta: Reselect-IDs */ + +/*4c*/ u8 nc_stest0; + +/*4d*/ u8 nc_stest1; + #define SCLK 0x80 /* Use the PCI clock as SCSI clock */ + #define DBLEN 0x08 /* clock doubler running */ + #define DBLSEL 0x04 /* clock doubler selected */ + + +/*4e*/ u8 nc_stest2; + #define ROF 0x40 /* reset scsi offset (after gross error!) */ + #define DIF 0x20 /* 720 SCSI differential mode */ + #define EXT 0x02 /* extended filtering */ + +/*4f*/ u8 nc_stest3; + #define TE 0x80 /* c: tolerAnt enable */ + #define HSC 0x20 /* c: Halt SCSI Clock */ + #define CSF 0x02 /* c: clear scsi fifo */ + +/*50*/ u16 nc_sidl; /* Lowlevel: latched from scsi data */ +/*52*/ u8 nc_stest4; + #define SMODE 0xc0 /* SCSI bus mode (895/6 only) */ + #define SMODE_HVD 0x40 /* High Voltage Differential */ + #define SMODE_SE 0x80 /* Single Ended */ + #define SMODE_LVD 0xc0 /* Low Voltage Differential */ + #define LCKFRQ 0x20 /* Frequency Lock (895/6 only) */ + /* bits 0-5 rsvd for C1010 */ + +/*53*/ u8 nc_53_; +/*54*/ u16 nc_sodl; /* Lowlevel: data out to scsi data */ +/*56*/ u8 nc_ccntl0; /* Chip Control 0 (896) */ + #define ENPMJ 0x80 /* Enable Phase Mismatch Jump */ + #define PMJCTL 0x40 /* Phase Mismatch Jump Control */ + #define ENNDJ 0x20 /* Enable Non Data PM Jump */ + #define DISFC 0x10 /* Disable Auto FIFO Clear */ + #define DILS 0x02 /* Disable Internal Load/Store */ + #define DPR 0x01 /* Disable Pipe Req */ + +/*57*/ u8 nc_ccntl1; /* Chip Control 1 (896) */ + #define ZMOD 0x80 /* High Impedance Mode */ + #define DIC 0x10 /* Disable Internal Cycles */ + #define DDAC 0x08 /* Disable Dual Address Cycle */ + #define XTIMOD 0x04 /* 64-bit Table Ind. Indexing Mode */ + #define EXTIBMV 0x02 /* Enable 64-bit Table Ind. BMOV */ + #define EXDBMV 0x01 /* Enable 64-bit Direct BMOV */ + +/*58*/ u16 nc_sbdl; /* Lowlevel: data from scsi data */ +/*5a*/ u16 nc_5a_; + +/*5c*/ u8 nc_scr0; /* Working register B */ +/*5d*/ u8 nc_scr1; /* */ +/*5e*/ u8 nc_scr2; /* */ +/*5f*/ u8 nc_scr3; /* */ + +/*60*/ u8 nc_scrx[64]; /* Working register C-R */ +/*a0*/ u32 nc_mmrs; /* Memory Move Read Selector */ +/*a4*/ u32 nc_mmws; /* Memory Move Write Selector */ +/*a8*/ u32 nc_sfs; /* Script Fetch Selector */ +/*ac*/ u32 nc_drs; /* DSA Relative Selector */ +/*b0*/ u32 nc_sbms; /* Static Block Move Selector */ +/*b4*/ u32 nc_dbms; /* Dynamic Block Move Selector */ +/*b8*/ u32 nc_dnad64; /* DMA Next Address 64 */ +/*bc*/ u16 nc_scntl4; /* C1010 only */ + #define U3EN 0x80 /* Enable Ultra 3 */ + #define AIPEN 0x40 /* Allow check upper byte lanes */ + #define XCLKH_DT 0x08 /* Extra clock of data hold on DT + transfer edge */ + #define XCLKH_ST 0x04 /* Extra clock of data hold on ST + transfer edge */ + +/*be*/ u8 nc_aipcntl0; /* Epat Control 1 C1010 only */ +/*bf*/ u8 nc_aipcntl1; /* AIP Control C1010_66 Only */ + +/*c0*/ u32 nc_pmjad1; /* Phase Mismatch Jump Address 1 */ +/*c4*/ u32 nc_pmjad2; /* Phase Mismatch Jump Address 2 */ +/*c8*/ u8 nc_rbc; /* Remaining Byte Count */ +/*c9*/ u8 nc_rbc1; /* */ +/*ca*/ u8 nc_rbc2; /* */ +/*cb*/ u8 nc_rbc3; /* */ + +/*cc*/ u8 nc_ua; /* Updated Address */ +/*cd*/ u8 nc_ua1; /* */ +/*ce*/ u8 nc_ua2; /* */ +/*cf*/ u8 nc_ua3; /* */ +/*d0*/ u32 nc_esa; /* Entry Storage Address */ +/*d4*/ u8 nc_ia; /* Instruction Address */ +/*d5*/ u8 nc_ia1; +/*d6*/ u8 nc_ia2; +/*d7*/ u8 nc_ia3; +/*d8*/ u32 nc_sbc; /* SCSI Byte Count (3 bytes only) */ +/*dc*/ u32 nc_csbc; /* Cumulative SCSI Byte Count */ + + /* Following for C1010 only */ +/*e0*/ u16 nc_crcpad; /* CRC Value */ +/*e2*/ u8 nc_crccntl0; /* CRC control register */ + #define SNDCRC 0x10 /* Send CRC Request */ +/*e3*/ u8 nc_crccntl1; /* CRC control register */ +/*e4*/ u32 nc_crcdata; /* CRC data register */ +/*e8*/ u32 nc_e8_; /* rsvd */ +/*ec*/ u32 nc_ec_; /* rsvd */ +/*f0*/ u16 nc_dfbc; /* DMA FIFO byte count */ + +}; + +/*----------------------------------------------------------- +** +** Utility macros for the script. +** +**----------------------------------------------------------- +*/ + +#define REGJ(p,r) (offsetof(struct ncr_reg, p ## r)) +#define REG(r) REGJ (nc_, r) + +typedef u32 ncrcmd; + +/*----------------------------------------------------------- +** +** SCSI phases +** +** DT phases illegal for ncr driver. +** +**----------------------------------------------------------- +*/ + +#define SCR_DATA_OUT 0x00000000 +#define SCR_DATA_IN 0x01000000 +#define SCR_COMMAND 0x02000000 +#define SCR_STATUS 0x03000000 +#define SCR_DT_DATA_OUT 0x04000000 +#define SCR_DT_DATA_IN 0x05000000 +#define SCR_MSG_OUT 0x06000000 +#define SCR_MSG_IN 0x07000000 + +#define SCR_ILG_OUT 0x04000000 +#define SCR_ILG_IN 0x05000000 + +/*----------------------------------------------------------- +** +** Data transfer via SCSI. +** +**----------------------------------------------------------- +** +** MOVE_ABS (LEN) +** <<start address>> +** +** MOVE_IND (LEN) +** <<dnad_offset>> +** +** MOVE_TBL +** <<dnad_offset>> +** +**----------------------------------------------------------- +*/ + +#define OPC_MOVE 0x08000000 + +#define SCR_MOVE_ABS(l) ((0x00000000 | OPC_MOVE) | (l)) +#define SCR_MOVE_IND(l) ((0x20000000 | OPC_MOVE) | (l)) +#define SCR_MOVE_TBL (0x10000000 | OPC_MOVE) + +#define SCR_CHMOV_ABS(l) ((0x00000000) | (l)) +#define SCR_CHMOV_IND(l) ((0x20000000) | (l)) +#define SCR_CHMOV_TBL (0x10000000) + +struct scr_tblmove { + u32 size; + u32 addr; +}; + +/*----------------------------------------------------------- +** +** Selection +** +**----------------------------------------------------------- +** +** SEL_ABS | SCR_ID (0..15) [ | REL_JMP] +** <<alternate_address>> +** +** SEL_TBL | << dnad_offset>> [ | REL_JMP] +** <<alternate_address>> +** +**----------------------------------------------------------- +*/ + +#define SCR_SEL_ABS 0x40000000 +#define SCR_SEL_ABS_ATN 0x41000000 +#define SCR_SEL_TBL 0x42000000 +#define SCR_SEL_TBL_ATN 0x43000000 + + +#ifdef SCSI_NCR_BIG_ENDIAN +struct scr_tblsel { + u8 sel_scntl3; + u8 sel_id; + u8 sel_sxfer; + u8 sel_scntl4; +}; +#else +struct scr_tblsel { + u8 sel_scntl4; + u8 sel_sxfer; + u8 sel_id; + u8 sel_scntl3; +}; +#endif + +#define SCR_JMP_REL 0x04000000 +#define SCR_ID(id) (((u32)(id)) << 16) + +/*----------------------------------------------------------- +** +** Waiting for Disconnect or Reselect +** +**----------------------------------------------------------- +** +** WAIT_DISC +** dummy: <<alternate_address>> +** +** WAIT_RESEL +** <<alternate_address>> +** +**----------------------------------------------------------- +*/ + +#define SCR_WAIT_DISC 0x48000000 +#define SCR_WAIT_RESEL 0x50000000 + +/*----------------------------------------------------------- +** +** Bit Set / Reset +** +**----------------------------------------------------------- +** +** SET (flags {|.. }) +** +** CLR (flags {|.. }) +** +**----------------------------------------------------------- +*/ + +#define SCR_SET(f) (0x58000000 | (f)) +#define SCR_CLR(f) (0x60000000 | (f)) + +#define SCR_CARRY 0x00000400 +#define SCR_TRG 0x00000200 +#define SCR_ACK 0x00000040 +#define SCR_ATN 0x00000008 + + + + +/*----------------------------------------------------------- +** +** Memory to memory move +** +**----------------------------------------------------------- +** +** COPY (bytecount) +** << source_address >> +** << destination_address >> +** +** SCR_COPY sets the NO FLUSH option by default. +** SCR_COPY_F does not set this option. +** +** For chips which do not support this option, +** ncr_copy_and_bind() will remove this bit. +**----------------------------------------------------------- +*/ + +#define SCR_NO_FLUSH 0x01000000 + +#define SCR_COPY(n) (0xc0000000 | SCR_NO_FLUSH | (n)) +#define SCR_COPY_F(n) (0xc0000000 | (n)) + +/*----------------------------------------------------------- +** +** Register move and binary operations +** +**----------------------------------------------------------- +** +** SFBR_REG (reg, op, data) reg = SFBR op data +** << 0 >> +** +** REG_SFBR (reg, op, data) SFBR = reg op data +** << 0 >> +** +** REG_REG (reg, op, data) reg = reg op data +** << 0 >> +** +**----------------------------------------------------------- +** On 810A, 860, 825A, 875, 895 and 896 chips the content +** of SFBR register can be used as data (SCR_SFBR_DATA). +** The 896 has additionnal IO registers starting at +** offset 0x80. Bit 7 of register offset is stored in +** bit 7 of the SCRIPTS instruction first DWORD. +**----------------------------------------------------------- +*/ + +#define SCR_REG_OFS(ofs) ((((ofs) & 0x7f) << 16ul) + ((ofs) & 0x80)) + +#define SCR_SFBR_REG(reg,op,data) \ + (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul)) + +#define SCR_REG_SFBR(reg,op,data) \ + (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul)) + +#define SCR_REG_REG(reg,op,data) \ + (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul)) + + +#define SCR_LOAD 0x00000000 +#define SCR_SHL 0x01000000 +#define SCR_OR 0x02000000 +#define SCR_XOR 0x03000000 +#define SCR_AND 0x04000000 +#define SCR_SHR 0x05000000 +#define SCR_ADD 0x06000000 +#define SCR_ADDC 0x07000000 + +#define SCR_SFBR_DATA (0x00800000>>8ul) /* Use SFBR as data */ + +/*----------------------------------------------------------- +** +** FROM_REG (reg) SFBR = reg +** << 0 >> +** +** TO_REG (reg) reg = SFBR +** << 0 >> +** +** LOAD_REG (reg, data) reg = <data> +** << 0 >> +** +** LOAD_SFBR(data) SFBR = <data> +** << 0 >> +** +**----------------------------------------------------------- +*/ + +#define SCR_FROM_REG(reg) \ + SCR_REG_SFBR(reg,SCR_OR,0) + +#define SCR_TO_REG(reg) \ + SCR_SFBR_REG(reg,SCR_OR,0) + +#define SCR_LOAD_REG(reg,data) \ + SCR_REG_REG(reg,SCR_LOAD,data) + +#define SCR_LOAD_SFBR(data) \ + (SCR_REG_SFBR (gpreg, SCR_LOAD, data)) + +/*----------------------------------------------------------- +** +** LOAD from memory to register. +** STORE from register to memory. +** +** Only supported by 810A, 860, 825A, 875, 895 and 896. +** +**----------------------------------------------------------- +** +** LOAD_ABS (LEN) +** <<start address>> +** +** LOAD_REL (LEN) (DSA relative) +** <<dsa_offset>> +** +**----------------------------------------------------------- +*/ + +#define SCR_REG_OFS2(ofs) (((ofs) & 0xff) << 16ul) +#define SCR_NO_FLUSH2 0x02000000 +#define SCR_DSA_REL2 0x10000000 + +#define SCR_LOAD_R(reg, how, n) \ + (0xe1000000 | how | (SCR_REG_OFS2(REG(reg))) | (n)) + +#define SCR_STORE_R(reg, how, n) \ + (0xe0000000 | how | (SCR_REG_OFS2(REG(reg))) | (n)) + +#define SCR_LOAD_ABS(reg, n) SCR_LOAD_R(reg, SCR_NO_FLUSH2, n) +#define SCR_LOAD_REL(reg, n) SCR_LOAD_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2, n) +#define SCR_LOAD_ABS_F(reg, n) SCR_LOAD_R(reg, 0, n) +#define SCR_LOAD_REL_F(reg, n) SCR_LOAD_R(reg, SCR_DSA_REL2, n) + +#define SCR_STORE_ABS(reg, n) SCR_STORE_R(reg, SCR_NO_FLUSH2, n) +#define SCR_STORE_REL(reg, n) SCR_STORE_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2,n) +#define SCR_STORE_ABS_F(reg, n) SCR_STORE_R(reg, 0, n) +#define SCR_STORE_REL_F(reg, n) SCR_STORE_R(reg, SCR_DSA_REL2, n) + + +/*----------------------------------------------------------- +** +** Waiting for Disconnect or Reselect +** +**----------------------------------------------------------- +** +** JUMP [ | IFTRUE/IFFALSE ( ... ) ] +** <<address>> +** +** JUMPR [ | IFTRUE/IFFALSE ( ... ) ] +** <<distance>> +** +** CALL [ | IFTRUE/IFFALSE ( ... ) ] +** <<address>> +** +** CALLR [ | IFTRUE/IFFALSE ( ... ) ] +** <<distance>> +** +** RETURN [ | IFTRUE/IFFALSE ( ... ) ] +** <<dummy>> +** +** INT [ | IFTRUE/IFFALSE ( ... ) ] +** <<ident>> +** +** INT_FLY [ | IFTRUE/IFFALSE ( ... ) ] +** <<ident>> +** +** Conditions: +** WHEN (phase) +** IF (phase) +** CARRYSET +** DATA (data, mask) +** +**----------------------------------------------------------- +*/ + +#define SCR_NO_OP 0x80000000 +#define SCR_JUMP 0x80080000 +#define SCR_JUMP64 0x80480000 +#define SCR_JUMPR 0x80880000 +#define SCR_CALL 0x88080000 +#define SCR_CALLR 0x88880000 +#define SCR_RETURN 0x90080000 +#define SCR_INT 0x98080000 +#define SCR_INT_FLY 0x98180000 + +#define IFFALSE(arg) (0x00080000 | (arg)) +#define IFTRUE(arg) (0x00000000 | (arg)) + +#define WHEN(phase) (0x00030000 | (phase)) +#define IF(phase) (0x00020000 | (phase)) + +#define DATA(D) (0x00040000 | ((D) & 0xff)) +#define MASK(D,M) (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff)) + +#define CARRYSET (0x00200000) + +/*----------------------------------------------------------- +** +** SCSI constants. +** +**----------------------------------------------------------- +*/ + +/* +** Messages +*/ + +#define M_COMPLETE COMMAND_COMPLETE +#define M_EXTENDED EXTENDED_MESSAGE +#define M_SAVE_DP SAVE_POINTERS +#define M_RESTORE_DP RESTORE_POINTERS +#define M_DISCONNECT DISCONNECT +#define M_ID_ERROR INITIATOR_ERROR +#define M_ABORT ABORT_TASK_SET +#define M_REJECT MESSAGE_REJECT +#define M_NOOP NOP +#define M_PARITY MSG_PARITY_ERROR +#define M_LCOMPLETE LINKED_CMD_COMPLETE +#define M_FCOMPLETE LINKED_FLG_CMD_COMPLETE +#define M_RESET TARGET_RESET +#define M_ABORT_TAG ABORT_TASK +#define M_CLEAR_QUEUE CLEAR_TASK_SET +#define M_INIT_REC INITIATE_RECOVERY +#define M_REL_REC RELEASE_RECOVERY +#define M_TERMINATE (0x11) +#define M_SIMPLE_TAG SIMPLE_QUEUE_TAG +#define M_HEAD_TAG HEAD_OF_QUEUE_TAG +#define M_ORDERED_TAG ORDERED_QUEUE_TAG +#define M_IGN_RESIDUE IGNORE_WIDE_RESIDUE +#define M_IDENTIFY (0x80) + +#define M_X_MODIFY_DP EXTENDED_MODIFY_DATA_POINTER +#define M_X_SYNC_REQ EXTENDED_SDTR +#define M_X_WIDE_REQ EXTENDED_WDTR +#define M_X_PPR_REQ EXTENDED_PPR + +/* +** Status +*/ + +#define S_GOOD (0x00) +#define S_CHECK_COND (0x02) +#define S_COND_MET (0x04) +#define S_BUSY (0x08) +#define S_INT (0x10) +#define S_INT_COND_MET (0x14) +#define S_CONFLICT (0x18) +#define S_TERMINATED (0x20) +#define S_QUEUE_FULL (0x28) +#define S_ILLEGAL (0xff) +#define S_SENSE (0x80) + +/* + * End of ncrreg from FreeBSD + */ /* Build a scatter/gather entry. diff --git a/drivers/scsi/sym53c8xx_comm.h b/drivers/scsi/sym53c8xx_comm.h deleted file mode 100644 index 20ae2b17df5..00000000000 --- a/drivers/scsi/sym53c8xx_comm.h +++ /dev/null @@ -1,792 +0,0 @@ -/****************************************************************************** -** High Performance device driver for the Symbios 53C896 controller. -** -** Copyright (C) 1998-2001 Gerard Roudier <groudier@free.fr> -** -** This driver also supports all the Symbios 53C8XX controller family, -** except 53C810 revisions < 16, 53C825 revisions < 16 and all -** revisions of 53C815 controllers. -** -** This driver is based on the Linux port of the FreeBSD ncr driver. -** -** Copyright (C) 1994 Wolfgang Stanglmeier -** -**----------------------------------------------------------------------------- -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -**----------------------------------------------------------------------------- -** -** The Linux port of the FreeBSD ncr driver has been achieved in -** november 1995 by: -** -** Gerard Roudier <groudier@free.fr> -** -** Being given that this driver originates from the FreeBSD version, and -** in order to keep synergy on both, any suggested enhancements and corrections -** received on Linux are automatically a potential candidate for the FreeBSD -** version. -** -** The original driver has been written for 386bsd and FreeBSD by -** Wolfgang Stanglmeier <wolf@cologne.de> -** Stefan Esser <se@mi.Uni-Koeln.de> -** -**----------------------------------------------------------------------------- -** -** Major contributions: -** -------------------- -** -** NVRAM detection and reading. -** Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> -** -******************************************************************************* -*/ - -/*========================================================== -** -** Debugging tags -** -**========================================================== -*/ - -#define DEBUG_ALLOC (0x0001) -#define DEBUG_PHASE (0x0002) -#define DEBUG_QUEUE (0x0008) -#define DEBUG_RESULT (0x0010) -#define DEBUG_POINTER (0x0020) -#define DEBUG_SCRIPT (0x0040) -#define DEBUG_TINY (0x0080) -#define DEBUG_TIMING (0x0100) -#define DEBUG_NEGO (0x0200) -#define DEBUG_TAGS (0x0400) -#define DEBUG_SCATTER (0x0800) -#define DEBUG_IC (0x1000) - -/* -** Enable/Disable debug messages. -** Can be changed at runtime too. -*/ - -#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT -static int ncr_debug = SCSI_NCR_DEBUG_FLAGS; - #define DEBUG_FLAGS ncr_debug -#else - #define DEBUG_FLAGS SCSI_NCR_DEBUG_FLAGS -#endif - -static inline struct list_head *ncr_list_pop(struct list_head *head) -{ - if (!list_empty(head)) { - struct list_head *elem = head->next; - - list_del(elem); - return elem; - } - - return NULL; -} - -#ifdef __sparc__ -#include <asm/irq.h> -#endif - -/*========================================================== -** -** Simple power of two buddy-like allocator. -** -** This simple code is not intended to be fast, but to -** provide power of 2 aligned memory allocations. -** Since the SCRIPTS processor only supplies 8 bit -** arithmetic, this allocator allows simple and fast -** address calculations from the SCRIPTS code. -** In addition, cache line alignment is guaranteed for -** power of 2 cache line size. -** Enhanced in linux-2.3.44 to provide a memory pool -** per pcidev to support dynamic dma mapping. (I would -** have preferred a real bus astraction, btw). -** -**========================================================== -*/ - -#define MEMO_SHIFT 4 /* 16 bytes minimum memory chunk */ -#if PAGE_SIZE >= 8192 -#define MEMO_PAGE_ORDER 0 /* 1 PAGE maximum */ -#else -#define MEMO_PAGE_ORDER 1 /* 2 PAGES maximum */ -#endif -#define MEMO_FREE_UNUSED /* Free unused pages immediately */ -#define MEMO_WARN 1 -#define MEMO_GFP_FLAGS GFP_ATOMIC -#define MEMO_CLUSTER_SHIFT (PAGE_SHIFT+MEMO_PAGE_ORDER) -#define MEMO_CLUSTER_SIZE (1UL << MEMO_CLUSTER_SHIFT) -#define MEMO_CLUSTER_MASK (MEMO_CLUSTER_SIZE-1) - -typedef u_long m_addr_t; /* Enough bits to bit-hack addresses */ -typedef struct device *m_bush_t; /* Something that addresses DMAable */ - -typedef struct m_link { /* Link between free memory chunks */ - struct m_link *next; -} m_link_s; - -typedef struct m_vtob { /* Virtual to Bus address translation */ - struct m_vtob *next; - m_addr_t vaddr; - m_addr_t baddr; -} m_vtob_s; -#define VTOB_HASH_SHIFT 5 -#define VTOB_HASH_SIZE (1UL << VTOB_HASH_SHIFT) -#define VTOB_HASH_MASK (VTOB_HASH_SIZE-1) -#define VTOB_HASH_CODE(m) \ - ((((m_addr_t) (m)) >> MEMO_CLUSTER_SHIFT) & VTOB_HASH_MASK) - -typedef struct m_pool { /* Memory pool of a given kind */ - m_bush_t bush; - m_addr_t (*getp)(struct m_pool *); - void (*freep)(struct m_pool *, m_addr_t); - int nump; - m_vtob_s *(vtob[VTOB_HASH_SIZE]); - struct m_pool *next; - struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1]; -} m_pool_s; - -static void *___m_alloc(m_pool_s *mp, int size) -{ - int i = 0; - int s = (1 << MEMO_SHIFT); - int j; - m_addr_t a; - m_link_s *h = mp->h; - - if (size > (PAGE_SIZE << MEMO_PAGE_ORDER)) - return NULL; - - while (size > s) { - s <<= 1; - ++i; - } - - j = i; - while (!h[j].next) { - if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) { - h[j].next = (m_link_s *)mp->getp(mp); - if (h[j].next) - h[j].next->next = NULL; - break; - } - ++j; - s <<= 1; - } - a = (m_addr_t) h[j].next; - if (a) { - h[j].next = h[j].next->next; - while (j > i) { - j -= 1; - s >>= 1; - h[j].next = (m_link_s *) (a+s); - h[j].next->next = NULL; - } - } -#ifdef DEBUG - printk("___m_alloc(%d) = %p\n", size, (void *) a); -#endif - return (void *) a; -} - -static void ___m_free(m_pool_s *mp, void *ptr, int size) -{ - int i = 0; - int s = (1 << MEMO_SHIFT); - m_link_s *q; - m_addr_t a, b; - m_link_s *h = mp->h; - -#ifdef DEBUG - printk("___m_free(%p, %d)\n", ptr, size); -#endif - - if (size > (PAGE_SIZE << MEMO_PAGE_ORDER)) - return; - - while (size > s) { - s <<= 1; - ++i; - } - - a = (m_addr_t) ptr; - - while (1) { -#ifdef MEMO_FREE_UNUSED - if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) { - mp->freep(mp, a); - break; - } -#endif - b = a ^ s; - q = &h[i]; - while (q->next && q->next != (m_link_s *) b) { - q = q->next; - } - if (!q->next) { - ((m_link_s *) a)->next = h[i].next; - h[i].next = (m_link_s *) a; - break; - } - q->next = q->next->next; - a = a & b; - s <<= 1; - ++i; - } -} - -static DEFINE_SPINLOCK(ncr53c8xx_lock); - -static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags) -{ - void *p; - - p = ___m_alloc(mp, size); - - if (DEBUG_FLAGS & DEBUG_ALLOC) - printk ("new %-10s[%4d] @%p.\n", name, size, p); - - if (p) - memset(p, 0, size); - else if (uflags & MEMO_WARN) - printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size); - - return p; -} - -#define __m_calloc(mp, s, n) __m_calloc2(mp, s, n, MEMO_WARN) - -static void __m_free(m_pool_s *mp, void *ptr, int size, char *name) -{ - if (DEBUG_FLAGS & DEBUG_ALLOC) - printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr); - - ___m_free(mp, ptr, size); - -} - -/* - * With pci bus iommu support, we use a default pool of unmapped memory - * for memory we donnot need to DMA from/to and one pool per pcidev for - * memory accessed by the PCI chip. `mp0' is the default not DMAable pool. - */ - -static m_addr_t ___mp0_getp(m_pool_s *mp) -{ - m_addr_t m = __get_free_pages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER); - if (m) - ++mp->nump; - return m; -} - -static void ___mp0_freep(m_pool_s *mp, m_addr_t m) -{ - free_pages(m, MEMO_PAGE_ORDER); - --mp->nump; -} - -static m_pool_s mp0 = {NULL, ___mp0_getp, ___mp0_freep}; - -/* - * DMAable pools. - */ - -/* - * With pci bus iommu support, we maintain one pool per pcidev and a - * hashed reverse table for virtual to bus physical address translations. - */ -static m_addr_t ___dma_getp(m_pool_s *mp) -{ - m_addr_t vp; - m_vtob_s *vbp; - - vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB"); - if (vbp) { - dma_addr_t daddr; - vp = (m_addr_t) dma_alloc_coherent(mp->bush, - PAGE_SIZE<<MEMO_PAGE_ORDER, - &daddr, GFP_ATOMIC); - if (vp) { - int hc = VTOB_HASH_CODE(vp); - vbp->vaddr = vp; - vbp->baddr = daddr; - vbp->next = mp->vtob[hc]; - mp->vtob[hc] = vbp; - ++mp->nump; - return vp; - } - } - if (vbp) - __m_free(&mp0, vbp, sizeof(*vbp), "VTOB"); - return 0; -} - -static void ___dma_freep(m_pool_s *mp, m_addr_t m) -{ - m_vtob_s **vbpp, *vbp; - int hc = VTOB_HASH_CODE(m); - - vbpp = &mp->vtob[hc]; - while (*vbpp && (*vbpp)->vaddr != m) - vbpp = &(*vbpp)->next; - if (*vbpp) { - vbp = *vbpp; - *vbpp = (*vbpp)->next; - dma_free_coherent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER, - (void *)vbp->vaddr, (dma_addr_t)vbp->baddr); - __m_free(&mp0, vbp, sizeof(*vbp), "VTOB"); - --mp->nump; - } -} - -static inline m_pool_s *___get_dma_pool(m_bush_t bush) -{ - m_pool_s *mp; - for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next); - return mp; -} - -static m_pool_s *___cre_dma_pool(m_bush_t bush) -{ - m_pool_s *mp; - mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL"); - if (mp) { - memset(mp, 0, sizeof(*mp)); - mp->bush = bush; - mp->getp = ___dma_getp; - mp->freep = ___dma_freep; - mp->next = mp0.next; - mp0.next = mp; - } - return mp; -} - -static void ___del_dma_pool(m_pool_s *p) -{ - struct m_pool **pp = &mp0.next; - - while (*pp && *pp != p) - pp = &(*pp)->next; - if (*pp) { - *pp = (*pp)->next; - __m_free(&mp0, p, sizeof(*p), "MPOOL"); - } -} - -static void *__m_calloc_dma(m_bush_t bush, int size, char *name) -{ - u_long flags; - struct m_pool *mp; - void *m = NULL; - - spin_lock_irqsave(&ncr53c8xx_lock, flags); - mp = ___get_dma_pool(bush); - if (!mp) - mp = ___cre_dma_pool(bush); - if (mp) - m = __m_calloc(mp, size, name); - if (mp && !mp->nump) - ___del_dma_pool(mp); - spin_unlock_irqrestore(&ncr53c8xx_lock, flags); - - return m; -} - -static void __m_free_dma(m_bush_t bush, void *m, int size, char *name) -{ - u_long flags; - struct m_pool *mp; - - spin_lock_irqsave(&ncr53c8xx_lock, flags); - mp = ___get_dma_pool(bush); - if (mp) - __m_free(mp, m, size, name); - if (mp && !mp->nump) - ___del_dma_pool(mp); - spin_unlock_irqrestore(&ncr53c8xx_lock, flags); -} - -static m_addr_t __vtobus(m_bush_t bush, void *m) -{ - u_long flags; - m_pool_s *mp; - int hc = VTOB_HASH_CODE(m); - m_vtob_s *vp = NULL; - m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK; - - spin_lock_irqsave(&ncr53c8xx_lock, flags); - mp = ___get_dma_pool(bush); - if (mp) { - vp = mp->vtob[hc]; - while (vp && (m_addr_t) vp->vaddr != a) - vp = vp->next; - } - spin_unlock_irqrestore(&ncr53c8xx_lock, flags); - return vp ? vp->baddr + (((m_addr_t) m) - a) : 0; -} - -#define _m_calloc_dma(np, s, n) __m_calloc_dma(np->dev, s, n) -#define _m_free_dma(np, p, s, n) __m_free_dma(np->dev, p, s, n) -#define m_calloc_dma(s, n) _m_calloc_dma(np, s, n) -#define m_free_dma(p, s, n) _m_free_dma(np, p, s, n) -#define _vtobus(np, p) __vtobus(np->dev, p) -#define vtobus(p) _vtobus(np, p) - -/* - * Deal with DMA mapping/unmapping. - */ - -/* To keep track of the dma mapping (sg/single) that has been set */ -#define __data_mapped SCp.phase -#define __data_mapping SCp.have_data_in - -static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd) -{ - switch(cmd->__data_mapped) { - case 2: - dma_unmap_sg(dev, cmd->buffer, cmd->use_sg, - cmd->sc_data_direction); - break; - case 1: - dma_unmap_single(dev, cmd->__data_mapping, - cmd->request_bufflen, - cmd->sc_data_direction); - break; - } - cmd->__data_mapped = 0; -} - -static u_long __map_scsi_single_data(struct device *dev, struct scsi_cmnd *cmd) -{ - dma_addr_t mapping; - - if (cmd->request_bufflen == 0) - return 0; - - mapping = dma_map_single(dev, cmd->request_buffer, - cmd->request_bufflen, - cmd->sc_data_direction); - cmd->__data_mapped = 1; - cmd->__data_mapping = mapping; - - return mapping; -} - -static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd) -{ - int use_sg; - - if (cmd->use_sg == 0) - return 0; - - use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg, - cmd->sc_data_direction); - cmd->__data_mapped = 2; - cmd->__data_mapping = use_sg; - - return use_sg; -} - -#define unmap_scsi_data(np, cmd) __unmap_scsi_data(np->dev, cmd) -#define map_scsi_single_data(np, cmd) __map_scsi_single_data(np->dev, cmd) -#define map_scsi_sg_data(np, cmd) __map_scsi_sg_data(np->dev, cmd) - -/*========================================================== -** -** Driver setup. -** -** This structure is initialized from linux config -** options. It can be overridden at boot-up by the boot -** command line. -** -**========================================================== -*/ -static struct ncr_driver_setup - driver_setup = SCSI_NCR_DRIVER_SETUP; - -#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT -static struct ncr_driver_setup - driver_safe_setup __initdata = SCSI_NCR_DRIVER_SAFE_SETUP; -#endif - -#define initverbose (driver_setup.verbose) -#define bootverbose (np->verbose) - - -/*=================================================================== -** -** Driver setup from the boot command line -** -**=================================================================== -*/ - -#ifdef MODULE -#define ARG_SEP ' ' -#else -#define ARG_SEP ',' -#endif - -#define OPT_TAGS 1 -#define OPT_MASTER_PARITY 2 -#define OPT_SCSI_PARITY 3 -#define OPT_DISCONNECTION 4 -#define OPT_SPECIAL_FEATURES 5 -#define OPT_UNUSED_1 6 -#define OPT_FORCE_SYNC_NEGO 7 -#define OPT_REVERSE_PROBE 8 -#define OPT_DEFAULT_SYNC 9 -#define OPT_VERBOSE 10 -#define OPT_DEBUG 11 -#define OPT_BURST_MAX 12 -#define OPT_LED_PIN 13 -#define OPT_MAX_WIDE 14 -#define OPT_SETTLE_DELAY 15 -#define OPT_DIFF_SUPPORT 16 -#define OPT_IRQM 17 -#define OPT_PCI_FIX_UP 18 -#define OPT_BUS_CHECK 19 -#define OPT_OPTIMIZE 20 -#define OPT_RECOVERY 21 -#define OPT_SAFE_SETUP 22 -#define OPT_USE_NVRAM 23 -#define OPT_EXCLUDE 24 -#define OPT_HOST_ID 25 - -#ifdef SCSI_NCR_IARB_SUPPORT -#define OPT_IARB 26 -#endif - -static char setup_token[] __initdata = - "tags:" "mpar:" - "spar:" "disc:" - "specf:" "ultra:" - "fsn:" "revprob:" - "sync:" "verb:" - "debug:" "burst:" - "led:" "wide:" - "settle:" "diff:" - "irqm:" "pcifix:" - "buschk:" "optim:" - "recovery:" - "safe:" "nvram:" - "excl:" "hostid:" -#ifdef SCSI_NCR_IARB_SUPPORT - "iarb:" -#endif - ; /* DONNOT REMOVE THIS ';' */ - -#ifdef MODULE -#define ARG_SEP ' ' -#else -#define ARG_SEP ',' -#endif - -static int __init get_setup_token(char *p) -{ - char *cur = setup_token; - char *pc; - int i = 0; - - while (cur != NULL && (pc = strchr(cur, ':')) != NULL) { - ++pc; - ++i; - if (!strncmp(p, cur, pc - cur)) - return i; - cur = pc; - } - return 0; -} - - -static int __init sym53c8xx__setup(char *str) -{ -#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT - char *cur = str; - char *pc, *pv; - int i, val, c; - int xi = 0; - - while (cur != NULL && (pc = strchr(cur, ':')) != NULL) { - char *pe; - - val = 0; - pv = pc; - c = *++pv; - - if (c == 'n') - val = 0; - else if (c == 'y') - val = 1; - else - val = (int) simple_strtoul(pv, &pe, 0); - - switch (get_setup_token(cur)) { - case OPT_TAGS: - driver_setup.default_tags = val; - if (pe && *pe == '/') { - i = 0; - while (*pe && *pe != ARG_SEP && - i < sizeof(driver_setup.tag_ctrl)-1) { - driver_setup.tag_ctrl[i++] = *pe++; - } - driver_setup.tag_ctrl[i] = '\0'; - } - break; - case OPT_MASTER_PARITY: - driver_setup.master_parity = val; - break; - case OPT_SCSI_PARITY: - driver_setup.scsi_parity = val; - break; - case OPT_DISCONNECTION: - driver_setup.disconnection = val; - break; - case OPT_SPECIAL_FEATURES: - driver_setup.special_features = val; - break; - case OPT_FORCE_SYNC_NEGO: - driver_setup.force_sync_nego = val; - break; - case OPT_REVERSE_PROBE: - driver_setup.reverse_probe = val; - break; - case OPT_DEFAULT_SYNC: - driver_setup.default_sync = val; - break; - case OPT_VERBOSE: - driver_setup.verbose = val; - break; - case OPT_DEBUG: - driver_setup.debug = val; - break; - case OPT_BURST_MAX: - driver_setup.burst_max = val; - break; - case OPT_LED_PIN: - driver_setup.led_pin = val; - break; - case OPT_MAX_WIDE: - driver_setup.max_wide = val? 1:0; - break; - case OPT_SETTLE_DELAY: - driver_setup.settle_delay = val; - break; - case OPT_DIFF_SUPPORT: - driver_setup.diff_support = val; - break; - case OPT_IRQM: - driver_setup.irqm = val; - break; - case OPT_PCI_FIX_UP: - driver_setup.pci_fix_up = val; - break; - case OPT_BUS_CHECK: - driver_setup.bus_check = val; - break; - case OPT_OPTIMIZE: - driver_setup.optimize = val; - break; - case OPT_RECOVERY: - driver_setup.recovery = val; - break; - case OPT_USE_NVRAM: - driver_setup.use_nvram = val; - break; - case OPT_SAFE_SETUP: - memcpy(&driver_setup, &driver_safe_setup, - sizeof(driver_setup)); - break; - case OPT_EXCLUDE: - if (xi < SCSI_NCR_MAX_EXCLUDES) - driver_setup.excludes[xi++] = val; - break; - case OPT_HOST_ID: - driver_setup.host_id = val; - break; -#ifdef SCSI_NCR_IARB_SUPPORT - case OPT_IARB: - driver_setup.iarb = val; - break; -#endif - default: - printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur); - break; - } - - if ((cur = strchr(cur, ARG_SEP)) != NULL) - ++cur; - } -#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */ - return 1; -} - -/*=================================================================== -** -** Get device queue depth from boot command line. -** -**=================================================================== -*/ -#define DEF_DEPTH (driver_setup.default_tags) -#define ALL_TARGETS -2 -#define NO_TARGET -1 -#define ALL_LUNS -2 -#define NO_LUN -1 - -static int device_queue_depth(int unit, int target, int lun) -{ - int c, h, t, u, v; - char *p = driver_setup.tag_ctrl; - char *ep; - - h = -1; - t = NO_TARGET; - u = NO_LUN; - while ((c = *p++) != 0) { - v = simple_strtoul(p, &ep, 0); - switch(c) { - case '/': - ++h; - t = ALL_TARGETS; - u = ALL_LUNS; - break; - case 't': - if (t != target) - t = (target == v) ? v : NO_TARGET; - u = ALL_LUNS; - break; - case 'u': - if (u != lun) - u = (lun == v) ? v : NO_LUN; - break; - case 'q': - if (h == unit && - (t == ALL_TARGETS || t == target) && - (u == ALL_LUNS || u == lun)) - return v; - break; - case '-': - t = ALL_TARGETS; - u = ALL_LUNS; - break; - default: - break; - } - p = ep; - } - return DEF_DEPTH; -} diff --git a/drivers/scsi/sym53c8xx_defs.h b/drivers/scsi/sym53c8xx_defs.h deleted file mode 100644 index 139cd0e12e6..00000000000 --- a/drivers/scsi/sym53c8xx_defs.h +++ /dev/null @@ -1,1320 +0,0 @@ -/****************************************************************************** -** High Performance device driver for the Symbios 53C896 controller. -** -** Copyright (C) 1998-2001 Gerard Roudier <groudier@free.fr> -** -** This driver also supports all the Symbios 53C8XX controller family, -** except 53C810 revisions < 16, 53C825 revisions < 16 and all -** revisions of 53C815 controllers. -** -** This driver is based on the Linux port of the FreeBSD ncr driver. -** -** Copyright (C) 1994 Wolfgang Stanglmeier -** -**----------------------------------------------------------------------------- -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -**----------------------------------------------------------------------------- -** -** The Linux port of the FreeBSD ncr driver has been achieved in -** november 1995 by: -** -** Gerard Roudier <groudier@free.fr> -** -** Being given that this driver originates from the FreeBSD version, and -** in order to keep synergy on both, any suggested enhancements and corrections -** received on Linux are automatically a potential candidate for the FreeBSD -** version. -** -** The original driver has been written for 386bsd and FreeBSD by -** Wolfgang Stanglmeier <wolf@cologne.de> -** Stefan Esser <se@mi.Uni-Koeln.de> -** -**----------------------------------------------------------------------------- -** -** Major contributions: -** -------------------- -** -** NVRAM detection and reading. -** Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> -** -** Added support for MIPS big endian systems. -** Carsten Langgaard, carstenl@mips.com -** Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. -** -** Added support for HP PARISC big endian systems. -** Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. -** -******************************************************************************* -*/ - -#ifndef SYM53C8XX_DEFS_H -#define SYM53C8XX_DEFS_H - -#include <linux/config.h> - -/* -** If you want a driver as small as possible, donnot define the -** following options. -*/ -#define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT -#define SCSI_NCR_DEBUG_INFO_SUPPORT - -/* -** To disable integrity checking, do not define the -** following option. -*/ -#ifdef CONFIG_SCSI_NCR53C8XX_INTEGRITY_CHECK -# define SCSI_NCR_ENABLE_INTEGRITY_CHECK -#endif - -/* --------------------------------------------------------------------- -** Take into account kernel configured parameters. -** Most of these options can be overridden at startup by a command line. -** --------------------------------------------------------------------- -*/ - -/* - * For Ultra2 and Ultra3 SCSI support option, use special features. - * - * Value (default) means: - * bit 0 : all features enabled, except: - * bit 1 : PCI Write And Invalidate. - * bit 2 : Data Phase Mismatch handling from SCRIPTS. - * - * Use boot options ncr53c8xx=specf:1 if you want all chip features to be - * enabled by the driver. - */ -#define SCSI_NCR_SETUP_SPECIAL_FEATURES (3) - -#define SCSI_NCR_MAX_SYNC (80) - -/* - * Allow tags from 2 to 256, default 8 - */ -#ifdef CONFIG_SCSI_NCR53C8XX_MAX_TAGS -#if CONFIG_SCSI_NCR53C8XX_MAX_TAGS < 2 -#define SCSI_NCR_MAX_TAGS (2) -#elif CONFIG_SCSI_NCR53C8XX_MAX_TAGS > 256 -#define SCSI_NCR_MAX_TAGS (256) -#else -#define SCSI_NCR_MAX_TAGS CONFIG_SCSI_NCR53C8XX_MAX_TAGS -#endif -#else -#define SCSI_NCR_MAX_TAGS (8) -#endif - -/* - * Allow tagged command queuing support if configured with default number - * of tags set to max (see above). - */ -#ifdef CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS -#define SCSI_NCR_SETUP_DEFAULT_TAGS CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS -#elif defined CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE -#define SCSI_NCR_SETUP_DEFAULT_TAGS SCSI_NCR_MAX_TAGS -#else -#define SCSI_NCR_SETUP_DEFAULT_TAGS (0) -#endif - -/* - * Immediate arbitration - */ -#if defined(CONFIG_SCSI_NCR53C8XX_IARB) -#define SCSI_NCR_IARB_SUPPORT -#endif - -/* - * Sync transfer frequency at startup. - * Allow from 5Mhz to 80Mhz default 20 Mhz. - */ -#ifndef CONFIG_SCSI_NCR53C8XX_SYNC -#define CONFIG_SCSI_NCR53C8XX_SYNC (20) -#elif CONFIG_SCSI_NCR53C8XX_SYNC > SCSI_NCR_MAX_SYNC -#undef CONFIG_SCSI_NCR53C8XX_SYNC -#define CONFIG_SCSI_NCR53C8XX_SYNC SCSI_NCR_MAX_SYNC -#endif - -#if CONFIG_SCSI_NCR53C8XX_SYNC == 0 -#define SCSI_NCR_SETUP_DEFAULT_SYNC (255) -#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 5 -#define SCSI_NCR_SETUP_DEFAULT_SYNC (50) -#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 20 -#define SCSI_NCR_SETUP_DEFAULT_SYNC (250/(CONFIG_SCSI_NCR53C8XX_SYNC)) -#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 33 -#define SCSI_NCR_SETUP_DEFAULT_SYNC (11) -#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 40 -#define SCSI_NCR_SETUP_DEFAULT_SYNC (10) -#else -#define SCSI_NCR_SETUP_DEFAULT_SYNC (9) -#endif - -/* - * Disallow disconnections at boot-up - */ -#ifdef CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT -#define SCSI_NCR_SETUP_DISCONNECTION (0) -#else -#define SCSI_NCR_SETUP_DISCONNECTION (1) -#endif - -/* - * Force synchronous negotiation for all targets - */ -#ifdef CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO -#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO (1) -#else -#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO (0) -#endif - -/* - * Disable master parity checking (flawed hardwares need that) - */ -#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK -#define SCSI_NCR_SETUP_MASTER_PARITY (0) -#else -#define SCSI_NCR_SETUP_MASTER_PARITY (1) -#endif - -/* - * Disable scsi parity checking (flawed devices may need that) - */ -#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK -#define SCSI_NCR_SETUP_SCSI_PARITY (0) -#else -#define SCSI_NCR_SETUP_SCSI_PARITY (1) -#endif - -/* - * Settle time after reset at boot-up - */ -#define SCSI_NCR_SETUP_SETTLE_TIME (2) - -/* -** Bridge quirks work-around option defaulted to 1. -*/ -#ifndef SCSI_NCR_PCIQ_WORK_AROUND_OPT -#define SCSI_NCR_PCIQ_WORK_AROUND_OPT 1 -#endif - -/* -** Work-around common bridge misbehaviour. -** -** - Do not flush posted writes in the opposite -** direction on read. -** - May reorder DMA writes to memory. -** -** This option should not affect performances -** significantly, so it is the default. -*/ -#if SCSI_NCR_PCIQ_WORK_AROUND_OPT == 1 -#define SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM -#define SCSI_NCR_PCIQ_MAY_REORDER_WRITES -#define SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS - -/* -** Same as option 1, but also deal with -** misconfigured interrupts. -** -** - Edge triggerred instead of level sensitive. -** - No interrupt line connected. -** - IRQ number misconfigured. -** -** If no interrupt is delivered, the driver will -** catch the interrupt conditions 10 times per -** second. No need to say that this option is -** not recommended. -*/ -#elif SCSI_NCR_PCIQ_WORK_AROUND_OPT == 2 -#define SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM -#define SCSI_NCR_PCIQ_MAY_REORDER_WRITES -#define SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS -#define SCSI_NCR_PCIQ_BROKEN_INTR - -/* -** Some bridge designers decided to flush -** everything prior to deliver the interrupt. -** This option tries to deal with such a -** behaviour. -*/ -#elif SCSI_NCR_PCIQ_WORK_AROUND_OPT == 3 -#define SCSI_NCR_PCIQ_SYNC_ON_INTR -#endif - -/* -** Other parameters not configurable with "make config" -** Avoid to change these constants, unless you know what you are doing. -*/ - -#define SCSI_NCR_ALWAYS_SIMPLE_TAG -#define SCSI_NCR_MAX_SCATTER (127) -#define SCSI_NCR_MAX_TARGET (16) - -/* -** Compute some desirable value for CAN_QUEUE -** and CMD_PER_LUN. -** The driver will use lower values if these -** ones appear to be too large. -*/ -#define SCSI_NCR_CAN_QUEUE (8*SCSI_NCR_MAX_TAGS + 2*SCSI_NCR_MAX_TARGET) -#define SCSI_NCR_CMD_PER_LUN (SCSI_NCR_MAX_TAGS) - -#define SCSI_NCR_SG_TABLESIZE (SCSI_NCR_MAX_SCATTER) -#define SCSI_NCR_TIMER_INTERVAL (HZ) - -#if 1 /* defined CONFIG_SCSI_MULTI_LUN */ -#define SCSI_NCR_MAX_LUN (16) -#else -#define SCSI_NCR_MAX_LUN (1) -#endif - -/* - * IO functions definition for big/little endian CPU support. - * For now, the NCR is only supported in little endian addressing mode, - */ - -#ifdef __BIG_ENDIAN - -#define inw_l2b inw -#define inl_l2b inl -#define outw_b2l outw -#define outl_b2l outl - -#define readb_raw readb -#define writeb_raw writeb - -#if defined(SCSI_NCR_BIG_ENDIAN) -#define readw_l2b __raw_readw -#define readl_l2b __raw_readl -#define writew_b2l __raw_writew -#define writel_b2l __raw_writel -#define readw_raw __raw_readw -#define readl_raw __raw_readl -#define writew_raw __raw_writew -#define writel_raw __raw_writel -#else /* Other big-endian */ -#define readw_l2b readw -#define readl_l2b readl -#define writew_b2l writew -#define writel_b2l writel -#define readw_raw readw -#define readl_raw readl -#define writew_raw writew -#define writel_raw writel -#endif - -#else /* little endian */ - -#define inw_raw inw -#define inl_raw inl -#define outw_raw outw -#define outl_raw outl - -#define readb_raw readb -#define readw_raw readw -#define readl_raw readl -#define writeb_raw writeb -#define writew_raw writew -#define writel_raw writel - -#endif - -#if !defined(__hppa__) && !defined(__mips__) -#ifdef SCSI_NCR_BIG_ENDIAN -#error "The NCR in BIG ENDIAN addressing mode is not (yet) supported" -#endif -#endif - -#define MEMORY_BARRIER() mb() - - -/* - * If the NCR uses big endian addressing mode over the - * PCI, actual io register addresses for byte and word - * accesses must be changed according to lane routing. - * Btw, ncr_offb() and ncr_offw() macros only apply to - * constants and so donnot generate bloated code. - */ - -#if defined(SCSI_NCR_BIG_ENDIAN) - -#define ncr_offb(o) (((o)&~3)+((~((o)&3))&3)) -#define ncr_offw(o) (((o)&~3)+((~((o)&3))&2)) - -#else - -#define ncr_offb(o) (o) -#define ncr_offw(o) (o) - -#endif - -/* - * If the CPU and the NCR use same endian-ness addressing, - * no byte reordering is needed for script patching. - * Macro cpu_to_scr() is to be used for script patching. - * Macro scr_to_cpu() is to be used for getting a DWORD - * from the script. - */ - -#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN) - -#define cpu_to_scr(dw) cpu_to_le32(dw) -#define scr_to_cpu(dw) le32_to_cpu(dw) - -#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN) - -#define cpu_to_scr(dw) cpu_to_be32(dw) -#define scr_to_cpu(dw) be32_to_cpu(dw) - -#else - -#define cpu_to_scr(dw) (dw) -#define scr_to_cpu(dw) (dw) - -#endif - -/* - * Access to the controller chip. - * - * If the CPU and the NCR use same endian-ness addressing, - * no byte reordering is needed for accessing chip io - * registers. Functions suffixed by '_raw' are assumed - * to access the chip over the PCI without doing byte - * reordering. Functions suffixed by '_l2b' are - * assumed to perform little-endian to big-endian byte - * reordering, those suffixed by '_b2l' blah, blah, - * blah, ... - */ - -/* - * MEMORY mapped IO input / output - */ - -#define INB_OFF(o) readb_raw((char __iomem *)np->reg + ncr_offb(o)) -#define OUTB_OFF(o, val) writeb_raw((val), (char __iomem *)np->reg + ncr_offb(o)) - -#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN) - -#define INW_OFF(o) readw_l2b((char __iomem *)np->reg + ncr_offw(o)) -#define INL_OFF(o) readl_l2b((char __iomem *)np->reg + (o)) - -#define OUTW_OFF(o, val) writew_b2l((val), (char __iomem *)np->reg + ncr_offw(o)) -#define OUTL_OFF(o, val) writel_b2l((val), (char __iomem *)np->reg + (o)) - -#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN) - -#define INW_OFF(o) readw_b2l((char __iomem *)np->reg + ncr_offw(o)) -#define INL_OFF(o) readl_b2l((char __iomem *)np->reg + (o)) - -#define OUTW_OFF(o, val) writew_l2b((val), (char __iomem *)np->reg + ncr_offw(o)) -#define OUTL_OFF(o, val) writel_l2b((val), (char __iomem *)np->reg + (o)) - -#else - -#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS -/* Only 8 or 32 bit transfers allowed */ -#define INW_OFF(o) (readb((char __iomem *)np->reg + ncr_offw(o)) << 8 | readb((char __iomem *)np->reg + ncr_offw(o) + 1)) -#else -#define INW_OFF(o) readw_raw((char __iomem *)np->reg + ncr_offw(o)) -#endif -#define INL_OFF(o) readl_raw((char __iomem *)np->reg + (o)) - -#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS -/* Only 8 or 32 bit transfers allowed */ -#define OUTW_OFF(o, val) do { writeb((char)((val) >> 8), (char __iomem *)np->reg + ncr_offw(o)); writeb((char)(val), (char __iomem *)np->reg + ncr_offw(o) + 1); } while (0) -#else -#define OUTW_OFF(o, val) writew_raw((val), (char __iomem *)np->reg + ncr_offw(o)) -#endif -#define OUTL_OFF(o, val) writel_raw((val), (char __iomem *)np->reg + (o)) - -#endif - -#define INB(r) INB_OFF (offsetof(struct ncr_reg,r)) -#define INW(r) INW_OFF (offsetof(struct ncr_reg,r)) -#define INL(r) INL_OFF (offsetof(struct ncr_reg,r)) - -#define OUTB(r, val) OUTB_OFF (offsetof(struct ncr_reg,r), (val)) -#define OUTW(r, val) OUTW_OFF (offsetof(struct ncr_reg,r), (val)) -#define OUTL(r, val) OUTL_OFF (offsetof(struct ncr_reg,r), (val)) - -/* - * Set bit field ON, OFF - */ - -#define OUTONB(r, m) OUTB(r, INB(r) | (m)) -#define OUTOFFB(r, m) OUTB(r, INB(r) & ~(m)) -#define OUTONW(r, m) OUTW(r, INW(r) | (m)) -#define OUTOFFW(r, m) OUTW(r, INW(r) & ~(m)) -#define OUTONL(r, m) OUTL(r, INL(r) | (m)) -#define OUTOFFL(r, m) OUTL(r, INL(r) & ~(m)) - -/* - * We normally want the chip to have a consistent view - * of driver internal data structures when we restart it. - * Thus these macros. - */ -#define OUTL_DSP(v) \ - do { \ - MEMORY_BARRIER(); \ - OUTL (nc_dsp, (v)); \ - } while (0) - -#define OUTONB_STD() \ - do { \ - MEMORY_BARRIER(); \ - OUTONB (nc_dcntl, (STD|NOCOM)); \ - } while (0) - - -/* -** NCR53C8XX devices features table. -*/ -struct ncr_chip { - unsigned short revision_id; - unsigned char burst_max; /* log-base-2 of max burst */ - unsigned char offset_max; - unsigned char nr_divisor; - unsigned int features; -#define FE_LED0 (1<<0) -#define FE_WIDE (1<<1) /* Wide data transfers */ -#define FE_ULTRA (1<<2) /* Ultra speed 20Mtrans/sec */ -#define FE_DBLR (1<<4) /* Clock doubler present */ -#define FE_QUAD (1<<5) /* Clock quadrupler present */ -#define FE_ERL (1<<6) /* Enable read line */ -#define FE_CLSE (1<<7) /* Cache line size enable */ -#define FE_WRIE (1<<8) /* Write & Invalidate enable */ -#define FE_ERMP (1<<9) /* Enable read multiple */ -#define FE_BOF (1<<10) /* Burst opcode fetch */ -#define FE_DFS (1<<11) /* DMA fifo size */ -#define FE_PFEN (1<<12) /* Prefetch enable */ -#define FE_LDSTR (1<<13) /* Load/Store supported */ -#define FE_RAM (1<<14) /* On chip RAM present */ -#define FE_VARCLK (1<<15) /* SCSI clock may vary */ -#define FE_RAM8K (1<<16) /* On chip RAM sized 8Kb */ -#define FE_64BIT (1<<17) /* Have a 64-bit PCI interface */ -#define FE_IO256 (1<<18) /* Requires full 256 bytes in PCI space */ -#define FE_NOPM (1<<19) /* Scripts handles phase mismatch */ -#define FE_LEDC (1<<20) /* Hardware control of LED */ -#define FE_DIFF (1<<21) /* Support Differential SCSI */ -#define FE_66MHZ (1<<23) /* 66MHz PCI Support */ -#define FE_DAC (1<<24) /* Support DAC cycles (64 bit addressing) */ -#define FE_ISTAT1 (1<<25) /* Have ISTAT1, MBOX0, MBOX1 registers */ -#define FE_DAC_IN_USE (1<<26) /* Platform does DAC cycles */ -#define FE_EHP (1<<27) /* 720: Even host parity */ -#define FE_MUX (1<<28) /* 720: Multiplexed bus */ -#define FE_EA (1<<29) /* 720: Enable Ack */ - -#define FE_CACHE_SET (FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP) -#define FE_SCSI_SET (FE_WIDE|FE_ULTRA|FE_DBLR|FE_QUAD|F_CLK80) -#define FE_SPECIAL_SET (FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM) -}; - - -/* -** 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 { - u8 master_parity; - u8 scsi_parity; - u8 disconnection; - u8 special_features; - u8 force_sync_nego; - u8 reverse_probe; - u8 pci_fix_up; - u8 use_nvram; - u8 verbose; - u8 default_tags; - u16 default_sync; - u16 debug; - u8 burst_max; - u8 led_pin; - u8 max_wide; - u8 settle_delay; - u8 diff_support; - u8 irqm; - u8 bus_check; - u8 optimize; - u8 recovery; - u8 host_id; - u16 iarb; - u32 excludes[SCSI_NCR_MAX_EXCLUDES]; - char tag_ctrl[100]; -}; - -/* -** Initial setup. -** Can be overriden at startup by a command line. -*/ -#define SCSI_NCR_DRIVER_SETUP \ -{ \ - SCSI_NCR_SETUP_MASTER_PARITY, \ - SCSI_NCR_SETUP_SCSI_PARITY, \ - SCSI_NCR_SETUP_DISCONNECTION, \ - SCSI_NCR_SETUP_SPECIAL_FEATURES, \ - SCSI_NCR_SETUP_FORCE_SYNC_NEGO, \ - 0, \ - 0, \ - 1, \ - 0, \ - SCSI_NCR_SETUP_DEFAULT_TAGS, \ - SCSI_NCR_SETUP_DEFAULT_SYNC, \ - 0x00, \ - 7, \ - 0, \ - 1, \ - SCSI_NCR_SETUP_SETTLE_TIME, \ - 0, \ - 0, \ - 1, \ - 0, \ - 0, \ - 255, \ - 0x00 \ -} - -/* -** Boot fail safe setup. -** Override initial setup from boot command line: -** ncr53c8xx=safe:y -*/ -#define SCSI_NCR_DRIVER_SAFE_SETUP \ -{ \ - 0, \ - 1, \ - 0, \ - 0, \ - 0, \ - 0, \ - 0, \ - 1, \ - 2, \ - 0, \ - 255, \ - 0x00, \ - 255, \ - 0, \ - 0, \ - 10, \ - 1, \ - 1, \ - 1, \ - 0, \ - 0, \ - 255 \ -} - -/**************** ORIGINAL CONTENT of ncrreg.h from FreeBSD ******************/ - -/*----------------------------------------------------------------- -** -** The ncr 53c810 register structure. -** -**----------------------------------------------------------------- -*/ - -struct ncr_reg { -/*00*/ u8 nc_scntl0; /* full arb., ena parity, par->ATN */ - -/*01*/ u8 nc_scntl1; /* no reset */ - #define ISCON 0x10 /* connected to scsi */ - #define CRST 0x08 /* force reset */ - #define IARB 0x02 /* immediate arbitration */ - -/*02*/ u8 nc_scntl2; /* no disconnect expected */ - #define SDU 0x80 /* cmd: disconnect will raise error */ - #define CHM 0x40 /* sta: chained mode */ - #define WSS 0x08 /* sta: wide scsi send [W]*/ - #define WSR 0x01 /* sta: wide scsi received [W]*/ - -/*03*/ u8 nc_scntl3; /* cnf system clock dependent */ - #define EWS 0x08 /* cmd: enable wide scsi [W]*/ - #define ULTRA 0x80 /* cmd: ULTRA enable */ - /* bits 0-2, 7 rsvd for C1010 */ - -/*04*/ u8 nc_scid; /* cnf host adapter scsi address */ - #define RRE 0x40 /* r/w:e enable response to resel. */ - #define SRE 0x20 /* r/w:e enable response to select */ - -/*05*/ u8 nc_sxfer; /* ### Sync speed and count */ - /* bits 6-7 rsvd for C1010 */ - -/*06*/ u8 nc_sdid; /* ### Destination-ID */ - -/*07*/ u8 nc_gpreg; /* ??? IO-Pins */ - -/*08*/ u8 nc_sfbr; /* ### First byte in phase */ - -/*09*/ u8 nc_socl; - #define CREQ 0x80 /* r/w: SCSI-REQ */ - #define CACK 0x40 /* r/w: SCSI-ACK */ - #define CBSY 0x20 /* r/w: SCSI-BSY */ - #define CSEL 0x10 /* r/w: SCSI-SEL */ - #define CATN 0x08 /* r/w: SCSI-ATN */ - #define CMSG 0x04 /* r/w: SCSI-MSG */ - #define CC_D 0x02 /* r/w: SCSI-C_D */ - #define CI_O 0x01 /* r/w: SCSI-I_O */ - -/*0a*/ u8 nc_ssid; - -/*0b*/ u8 nc_sbcl; - -/*0c*/ u8 nc_dstat; - #define DFE 0x80 /* sta: dma fifo empty */ - #define MDPE 0x40 /* int: master data parity error */ - #define BF 0x20 /* int: script: bus fault */ - #define ABRT 0x10 /* int: script: command aborted */ - #define SSI 0x08 /* int: script: single step */ - #define SIR 0x04 /* int: script: interrupt instruct. */ - #define IID 0x01 /* int: script: illegal instruct. */ - -/*0d*/ u8 nc_sstat0; - #define ILF 0x80 /* sta: data in SIDL register lsb */ - #define ORF 0x40 /* sta: data in SODR register lsb */ - #define OLF 0x20 /* sta: data in SODL register lsb */ - #define AIP 0x10 /* sta: arbitration in progress */ - #define LOA 0x08 /* sta: arbitration lost */ - #define WOA 0x04 /* sta: arbitration won */ - #define IRST 0x02 /* sta: scsi reset signal */ - #define SDP 0x01 /* sta: scsi parity signal */ - -/*0e*/ u8 nc_sstat1; - #define FF3210 0xf0 /* sta: bytes in the scsi fifo */ - -/*0f*/ u8 nc_sstat2; - #define ILF1 0x80 /* sta: data in SIDL register msb[W]*/ - #define ORF1 0x40 /* sta: data in SODR register msb[W]*/ - #define OLF1 0x20 /* sta: data in SODL register msb[W]*/ - #define DM 0x04 /* sta: DIFFSENS mismatch (895/6 only) */ - #define LDSC 0x02 /* sta: disconnect & reconnect */ - -/*10*/ u8 nc_dsa; /* --> Base page */ -/*11*/ u8 nc_dsa1; -/*12*/ u8 nc_dsa2; -/*13*/ u8 nc_dsa3; - -/*14*/ u8 nc_istat; /* --> Main Command and status */ - #define CABRT 0x80 /* cmd: abort current operation */ - #define SRST 0x40 /* mod: reset chip */ - #define SIGP 0x20 /* r/w: message from host to ncr */ - #define SEM 0x10 /* r/w: message between host + ncr */ - #define CON 0x08 /* sta: connected to scsi */ - #define INTF 0x04 /* sta: int on the fly (reset by wr)*/ - #define SIP 0x02 /* sta: scsi-interrupt */ - #define DIP 0x01 /* sta: host/script interrupt */ - -/*15*/ u8 nc_istat1; /* 896 and later cores only */ - #define FLSH 0x04 /* sta: chip is flushing */ - #define SRUN 0x02 /* sta: scripts are running */ - #define SIRQD 0x01 /* r/w: disable INT pin */ - -/*16*/ u8 nc_mbox0; /* 896 and later cores only */ -/*17*/ u8 nc_mbox1; /* 896 and later cores only */ - -/*18*/ u8 nc_ctest0; - #define EHP 0x04 /* 720 even host parity */ -/*19*/ u8 nc_ctest1; - -/*1a*/ u8 nc_ctest2; - #define CSIGP 0x40 - /* bits 0-2,7 rsvd for C1010 */ - -/*1b*/ u8 nc_ctest3; - #define FLF 0x08 /* cmd: flush dma fifo */ - #define CLF 0x04 /* cmd: clear dma fifo */ - #define FM 0x02 /* mod: fetch pin mode */ - #define WRIE 0x01 /* mod: write and invalidate enable */ - /* bits 4-7 rsvd for C1010 */ - -/*1c*/ u32 nc_temp; /* ### Temporary stack */ - -/*20*/ u8 nc_dfifo; -/*21*/ u8 nc_ctest4; - #define MUX 0x80 /* 720 host bus multiplex mode */ - #define BDIS 0x80 /* mod: burst disable */ - #define MPEE 0x08 /* mod: master parity error enable */ - -/*22*/ u8 nc_ctest5; - #define DFS 0x20 /* mod: dma fifo size */ - /* bits 0-1, 3-7 rsvd for C1010 */ -/*23*/ u8 nc_ctest6; - -/*24*/ u32 nc_dbc; /* ### Byte count and command */ -/*28*/ u32 nc_dnad; /* ### Next command register */ -/*2c*/ u32 nc_dsp; /* --> Script Pointer */ -/*30*/ u32 nc_dsps; /* --> Script pointer save/opcode#2 */ - -/*34*/ u8 nc_scratcha; /* Temporary register a */ -/*35*/ u8 nc_scratcha1; -/*36*/ u8 nc_scratcha2; -/*37*/ u8 nc_scratcha3; - -/*38*/ u8 nc_dmode; - #define BL_2 0x80 /* mod: burst length shift value +2 */ - #define BL_1 0x40 /* mod: burst length shift value +1 */ - #define ERL 0x08 /* mod: enable read line */ - #define ERMP 0x04 /* mod: enable read multiple */ - #define BOF 0x02 /* mod: burst op code fetch */ - -/*39*/ u8 nc_dien; -/*3a*/ u8 nc_sbr; - -/*3b*/ u8 nc_dcntl; /* --> Script execution control */ - #define CLSE 0x80 /* mod: cache line size enable */ - #define PFF 0x40 /* cmd: pre-fetch flush */ - #define PFEN 0x20 /* mod: pre-fetch enable */ - #define EA 0x20 /* mod: 720 enable-ack */ - #define SSM 0x10 /* mod: single step mode */ - #define IRQM 0x08 /* mod: irq mode (1 = totem pole !) */ - #define STD 0x04 /* cmd: start dma mode */ - #define IRQD 0x02 /* mod: irq disable */ - #define NOCOM 0x01 /* cmd: protect sfbr while reselect */ - /* bits 0-1 rsvd for C1010 */ - -/*3c*/ u32 nc_adder; - -/*40*/ u16 nc_sien; /* -->: interrupt enable */ -/*42*/ u16 nc_sist; /* <--: interrupt status */ - #define SBMC 0x1000/* sta: SCSI Bus Mode Change (895/6 only) */ - #define STO 0x0400/* sta: timeout (select) */ - #define GEN 0x0200/* sta: timeout (general) */ - #define HTH 0x0100/* sta: timeout (handshake) */ - #define MA 0x80 /* sta: phase mismatch */ - #define CMP 0x40 /* sta: arbitration complete */ - #define SEL 0x20 /* sta: selected by another device */ - #define RSL 0x10 /* sta: reselected by another device*/ - #define SGE 0x08 /* sta: gross error (over/underflow)*/ - #define UDC 0x04 /* sta: unexpected disconnect */ - #define RST 0x02 /* sta: scsi bus reset detected */ - #define PAR 0x01 /* sta: scsi parity error */ - -/*44*/ u8 nc_slpar; -/*45*/ u8 nc_swide; -/*46*/ u8 nc_macntl; -/*47*/ u8 nc_gpcntl; -/*48*/ u8 nc_stime0; /* cmd: timeout for select&handshake*/ -/*49*/ u8 nc_stime1; /* cmd: timeout user defined */ -/*4a*/ u16 nc_respid; /* sta: Reselect-IDs */ - -/*4c*/ u8 nc_stest0; - -/*4d*/ u8 nc_stest1; - #define SCLK 0x80 /* Use the PCI clock as SCSI clock */ - #define DBLEN 0x08 /* clock doubler running */ - #define DBLSEL 0x04 /* clock doubler selected */ - - -/*4e*/ u8 nc_stest2; - #define ROF 0x40 /* reset scsi offset (after gross error!) */ - #define DIF 0x20 /* 720 SCSI differential mode */ - #define EXT 0x02 /* extended filtering */ - -/*4f*/ u8 nc_stest3; - #define TE 0x80 /* c: tolerAnt enable */ - #define HSC 0x20 /* c: Halt SCSI Clock */ - #define CSF 0x02 /* c: clear scsi fifo */ - -/*50*/ u16 nc_sidl; /* Lowlevel: latched from scsi data */ -/*52*/ u8 nc_stest4; - #define SMODE 0xc0 /* SCSI bus mode (895/6 only) */ - #define SMODE_HVD 0x40 /* High Voltage Differential */ - #define SMODE_SE 0x80 /* Single Ended */ - #define SMODE_LVD 0xc0 /* Low Voltage Differential */ - #define LCKFRQ 0x20 /* Frequency Lock (895/6 only) */ - /* bits 0-5 rsvd for C1010 */ - -/*53*/ u8 nc_53_; -/*54*/ u16 nc_sodl; /* Lowlevel: data out to scsi data */ -/*56*/ u8 nc_ccntl0; /* Chip Control 0 (896) */ - #define ENPMJ 0x80 /* Enable Phase Mismatch Jump */ - #define PMJCTL 0x40 /* Phase Mismatch Jump Control */ - #define ENNDJ 0x20 /* Enable Non Data PM Jump */ - #define DISFC 0x10 /* Disable Auto FIFO Clear */ - #define DILS 0x02 /* Disable Internal Load/Store */ - #define DPR 0x01 /* Disable Pipe Req */ - -/*57*/ u8 nc_ccntl1; /* Chip Control 1 (896) */ - #define ZMOD 0x80 /* High Impedance Mode */ - #define DIC 0x10 /* Disable Internal Cycles */ - #define DDAC 0x08 /* Disable Dual Address Cycle */ - #define XTIMOD 0x04 /* 64-bit Table Ind. Indexing Mode */ - #define EXTIBMV 0x02 /* Enable 64-bit Table Ind. BMOV */ - #define EXDBMV 0x01 /* Enable 64-bit Direct BMOV */ - -/*58*/ u16 nc_sbdl; /* Lowlevel: data from scsi data */ -/*5a*/ u16 nc_5a_; - -/*5c*/ u8 nc_scr0; /* Working register B */ -/*5d*/ u8 nc_scr1; /* */ -/*5e*/ u8 nc_scr2; /* */ -/*5f*/ u8 nc_scr3; /* */ - -/*60*/ u8 nc_scrx[64]; /* Working register C-R */ -/*a0*/ u32 nc_mmrs; /* Memory Move Read Selector */ -/*a4*/ u32 nc_mmws; /* Memory Move Write Selector */ -/*a8*/ u32 nc_sfs; /* Script Fetch Selector */ -/*ac*/ u32 nc_drs; /* DSA Relative Selector */ -/*b0*/ u32 nc_sbms; /* Static Block Move Selector */ -/*b4*/ u32 nc_dbms; /* Dynamic Block Move Selector */ -/*b8*/ u32 nc_dnad64; /* DMA Next Address 64 */ -/*bc*/ u16 nc_scntl4; /* C1010 only */ - #define U3EN 0x80 /* Enable Ultra 3 */ - #define AIPEN 0x40 /* Allow check upper byte lanes */ - #define XCLKH_DT 0x08 /* Extra clock of data hold on DT - transfer edge */ - #define XCLKH_ST 0x04 /* Extra clock of data hold on ST - transfer edge */ - -/*be*/ u8 nc_aipcntl0; /* Epat Control 1 C1010 only */ -/*bf*/ u8 nc_aipcntl1; /* AIP Control C1010_66 Only */ - -/*c0*/ u32 nc_pmjad1; /* Phase Mismatch Jump Address 1 */ -/*c4*/ u32 nc_pmjad2; /* Phase Mismatch Jump Address 2 */ -/*c8*/ u8 nc_rbc; /* Remaining Byte Count */ -/*c9*/ u8 nc_rbc1; /* */ -/*ca*/ u8 nc_rbc2; /* */ -/*cb*/ u8 nc_rbc3; /* */ - -/*cc*/ u8 nc_ua; /* Updated Address */ -/*cd*/ u8 nc_ua1; /* */ -/*ce*/ u8 nc_ua2; /* */ -/*cf*/ u8 nc_ua3; /* */ -/*d0*/ u32 nc_esa; /* Entry Storage Address */ -/*d4*/ u8 nc_ia; /* Instruction Address */ -/*d5*/ u8 nc_ia1; -/*d6*/ u8 nc_ia2; -/*d7*/ u8 nc_ia3; -/*d8*/ u32 nc_sbc; /* SCSI Byte Count (3 bytes only) */ -/*dc*/ u32 nc_csbc; /* Cumulative SCSI Byte Count */ - - /* Following for C1010 only */ -/*e0*/ u16 nc_crcpad; /* CRC Value */ -/*e2*/ u8 nc_crccntl0; /* CRC control register */ - #define SNDCRC 0x10 /* Send CRC Request */ -/*e3*/ u8 nc_crccntl1; /* CRC control register */ -/*e4*/ u32 nc_crcdata; /* CRC data register */ -/*e8*/ u32 nc_e8_; /* rsvd */ -/*ec*/ u32 nc_ec_; /* rsvd */ -/*f0*/ u16 nc_dfbc; /* DMA FIFO byte count */ - -}; - -/*----------------------------------------------------------- -** -** Utility macros for the script. -** -**----------------------------------------------------------- -*/ - -#define REGJ(p,r) (offsetof(struct ncr_reg, p ## r)) -#define REG(r) REGJ (nc_, r) - -typedef u32 ncrcmd; - -/*----------------------------------------------------------- -** -** SCSI phases -** -** DT phases illegal for ncr driver. -** -**----------------------------------------------------------- -*/ - -#define SCR_DATA_OUT 0x00000000 -#define SCR_DATA_IN 0x01000000 -#define SCR_COMMAND 0x02000000 -#define SCR_STATUS 0x03000000 -#define SCR_DT_DATA_OUT 0x04000000 -#define SCR_DT_DATA_IN 0x05000000 -#define SCR_MSG_OUT 0x06000000 -#define SCR_MSG_IN 0x07000000 - -#define SCR_ILG_OUT 0x04000000 -#define SCR_ILG_IN 0x05000000 - -/*----------------------------------------------------------- -** -** Data transfer via SCSI. -** -**----------------------------------------------------------- -** -** MOVE_ABS (LEN) -** <<start address>> -** -** MOVE_IND (LEN) -** <<dnad_offset>> -** -** MOVE_TBL -** <<dnad_offset>> -** -**----------------------------------------------------------- -*/ - -#define OPC_MOVE 0x08000000 - -#define SCR_MOVE_ABS(l) ((0x00000000 | OPC_MOVE) | (l)) -#define SCR_MOVE_IND(l) ((0x20000000 | OPC_MOVE) | (l)) -#define SCR_MOVE_TBL (0x10000000 | OPC_MOVE) - -#define SCR_CHMOV_ABS(l) ((0x00000000) | (l)) -#define SCR_CHMOV_IND(l) ((0x20000000) | (l)) -#define SCR_CHMOV_TBL (0x10000000) - -struct scr_tblmove { - u32 size; - u32 addr; -}; - -/*----------------------------------------------------------- -** -** Selection -** -**----------------------------------------------------------- -** -** SEL_ABS | SCR_ID (0..15) [ | REL_JMP] -** <<alternate_address>> -** -** SEL_TBL | << dnad_offset>> [ | REL_JMP] -** <<alternate_address>> -** -**----------------------------------------------------------- -*/ - -#define SCR_SEL_ABS 0x40000000 -#define SCR_SEL_ABS_ATN 0x41000000 -#define SCR_SEL_TBL 0x42000000 -#define SCR_SEL_TBL_ATN 0x43000000 - - -#ifdef SCSI_NCR_BIG_ENDIAN -struct scr_tblsel { - u8 sel_scntl3; - u8 sel_id; - u8 sel_sxfer; - u8 sel_scntl4; -}; -#else -struct scr_tblsel { - u8 sel_scntl4; - u8 sel_sxfer; - u8 sel_id; - u8 sel_scntl3; -}; -#endif - -#define SCR_JMP_REL 0x04000000 -#define SCR_ID(id) (((u32)(id)) << 16) - -/*----------------------------------------------------------- -** -** Waiting for Disconnect or Reselect -** -**----------------------------------------------------------- -** -** WAIT_DISC -** dummy: <<alternate_address>> -** -** WAIT_RESEL -** <<alternate_address>> -** -**----------------------------------------------------------- -*/ - -#define SCR_WAIT_DISC 0x48000000 -#define SCR_WAIT_RESEL 0x50000000 - -/*----------------------------------------------------------- -** -** Bit Set / Reset -** -**----------------------------------------------------------- -** -** SET (flags {|.. }) -** -** CLR (flags {|.. }) -** -**----------------------------------------------------------- -*/ - -#define SCR_SET(f) (0x58000000 | (f)) -#define SCR_CLR(f) (0x60000000 | (f)) - -#define SCR_CARRY 0x00000400 -#define SCR_TRG 0x00000200 -#define SCR_ACK 0x00000040 -#define SCR_ATN 0x00000008 - - - - -/*----------------------------------------------------------- -** -** Memory to memory move -** -**----------------------------------------------------------- -** -** COPY (bytecount) -** << source_address >> -** << destination_address >> -** -** SCR_COPY sets the NO FLUSH option by default. -** SCR_COPY_F does not set this option. -** -** For chips which do not support this option, -** ncr_copy_and_bind() will remove this bit. -**----------------------------------------------------------- -*/ - -#define SCR_NO_FLUSH 0x01000000 - -#define SCR_COPY(n) (0xc0000000 | SCR_NO_FLUSH | (n)) -#define SCR_COPY_F(n) (0xc0000000 | (n)) - -/*----------------------------------------------------------- -** -** Register move and binary operations -** -**----------------------------------------------------------- -** -** SFBR_REG (reg, op, data) reg = SFBR op data -** << 0 >> -** -** REG_SFBR (reg, op, data) SFBR = reg op data -** << 0 >> -** -** REG_REG (reg, op, data) reg = reg op data -** << 0 >> -** -**----------------------------------------------------------- -** On 810A, 860, 825A, 875, 895 and 896 chips the content -** of SFBR register can be used as data (SCR_SFBR_DATA). -** The 896 has additionnal IO registers starting at -** offset 0x80. Bit 7 of register offset is stored in -** bit 7 of the SCRIPTS instruction first DWORD. -**----------------------------------------------------------- -*/ - -#define SCR_REG_OFS(ofs) ((((ofs) & 0x7f) << 16ul) + ((ofs) & 0x80)) - -#define SCR_SFBR_REG(reg,op,data) \ - (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul)) - -#define SCR_REG_SFBR(reg,op,data) \ - (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul)) - -#define SCR_REG_REG(reg,op,data) \ - (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul)) - - -#define SCR_LOAD 0x00000000 -#define SCR_SHL 0x01000000 -#define SCR_OR 0x02000000 -#define SCR_XOR 0x03000000 -#define SCR_AND 0x04000000 -#define SCR_SHR 0x05000000 -#define SCR_ADD 0x06000000 -#define SCR_ADDC 0x07000000 - -#define SCR_SFBR_DATA (0x00800000>>8ul) /* Use SFBR as data */ - -/*----------------------------------------------------------- -** -** FROM_REG (reg) SFBR = reg -** << 0 >> -** -** TO_REG (reg) reg = SFBR -** << 0 >> -** -** LOAD_REG (reg, data) reg = <data> -** << 0 >> -** -** LOAD_SFBR(data) SFBR = <data> -** << 0 >> -** -**----------------------------------------------------------- -*/ - -#define SCR_FROM_REG(reg) \ - SCR_REG_SFBR(reg,SCR_OR,0) - -#define SCR_TO_REG(reg) \ - SCR_SFBR_REG(reg,SCR_OR,0) - -#define SCR_LOAD_REG(reg,data) \ - SCR_REG_REG(reg,SCR_LOAD,data) - -#define SCR_LOAD_SFBR(data) \ - (SCR_REG_SFBR (gpreg, SCR_LOAD, data)) - -/*----------------------------------------------------------- -** -** LOAD from memory to register. -** STORE from register to memory. -** -** Only supported by 810A, 860, 825A, 875, 895 and 896. -** -**----------------------------------------------------------- -** -** LOAD_ABS (LEN) -** <<start address>> -** -** LOAD_REL (LEN) (DSA relative) -** <<dsa_offset>> -** -**----------------------------------------------------------- -*/ - -#define SCR_REG_OFS2(ofs) (((ofs) & 0xff) << 16ul) -#define SCR_NO_FLUSH2 0x02000000 -#define SCR_DSA_REL2 0x10000000 - -#define SCR_LOAD_R(reg, how, n) \ - (0xe1000000 | how | (SCR_REG_OFS2(REG(reg))) | (n)) - -#define SCR_STORE_R(reg, how, n) \ - (0xe0000000 | how | (SCR_REG_OFS2(REG(reg))) | (n)) - -#define SCR_LOAD_ABS(reg, n) SCR_LOAD_R(reg, SCR_NO_FLUSH2, n) -#define SCR_LOAD_REL(reg, n) SCR_LOAD_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2, n) -#define SCR_LOAD_ABS_F(reg, n) SCR_LOAD_R(reg, 0, n) -#define SCR_LOAD_REL_F(reg, n) SCR_LOAD_R(reg, SCR_DSA_REL2, n) - -#define SCR_STORE_ABS(reg, n) SCR_STORE_R(reg, SCR_NO_FLUSH2, n) -#define SCR_STORE_REL(reg, n) SCR_STORE_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2,n) -#define SCR_STORE_ABS_F(reg, n) SCR_STORE_R(reg, 0, n) -#define SCR_STORE_REL_F(reg, n) SCR_STORE_R(reg, SCR_DSA_REL2, n) - - -/*----------------------------------------------------------- -** -** Waiting for Disconnect or Reselect -** -**----------------------------------------------------------- -** -** JUMP [ | IFTRUE/IFFALSE ( ... ) ] -** <<address>> -** -** JUMPR [ | IFTRUE/IFFALSE ( ... ) ] -** <<distance>> -** -** CALL [ | IFTRUE/IFFALSE ( ... ) ] -** <<address>> -** -** CALLR [ | IFTRUE/IFFALSE ( ... ) ] -** <<distance>> -** -** RETURN [ | IFTRUE/IFFALSE ( ... ) ] -** <<dummy>> -** -** INT [ | IFTRUE/IFFALSE ( ... ) ] -** <<ident>> -** -** INT_FLY [ | IFTRUE/IFFALSE ( ... ) ] -** <<ident>> -** -** Conditions: -** WHEN (phase) -** IF (phase) -** CARRYSET -** DATA (data, mask) -** -**----------------------------------------------------------- -*/ - -#define SCR_NO_OP 0x80000000 -#define SCR_JUMP 0x80080000 -#define SCR_JUMP64 0x80480000 -#define SCR_JUMPR 0x80880000 -#define SCR_CALL 0x88080000 -#define SCR_CALLR 0x88880000 -#define SCR_RETURN 0x90080000 -#define SCR_INT 0x98080000 -#define SCR_INT_FLY 0x98180000 - -#define IFFALSE(arg) (0x00080000 | (arg)) -#define IFTRUE(arg) (0x00000000 | (arg)) - -#define WHEN(phase) (0x00030000 | (phase)) -#define IF(phase) (0x00020000 | (phase)) - -#define DATA(D) (0x00040000 | ((D) & 0xff)) -#define MASK(D,M) (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff)) - -#define CARRYSET (0x00200000) - -/*----------------------------------------------------------- -** -** SCSI constants. -** -**----------------------------------------------------------- -*/ - -/* -** Messages -*/ - -#define M_COMPLETE COMMAND_COMPLETE -#define M_EXTENDED EXTENDED_MESSAGE -#define M_SAVE_DP SAVE_POINTERS -#define M_RESTORE_DP RESTORE_POINTERS -#define M_DISCONNECT DISCONNECT -#define M_ID_ERROR INITIATOR_ERROR -#define M_ABORT ABORT_TASK_SET -#define M_REJECT MESSAGE_REJECT -#define M_NOOP NOP -#define M_PARITY MSG_PARITY_ERROR -#define M_LCOMPLETE LINKED_CMD_COMPLETE -#define M_FCOMPLETE LINKED_FLG_CMD_COMPLETE -#define M_RESET TARGET_RESET -#define M_ABORT_TAG ABORT_TASK -#define M_CLEAR_QUEUE CLEAR_TASK_SET -#define M_INIT_REC INITIATE_RECOVERY -#define M_REL_REC RELEASE_RECOVERY -#define M_TERMINATE (0x11) -#define M_SIMPLE_TAG SIMPLE_QUEUE_TAG -#define M_HEAD_TAG HEAD_OF_QUEUE_TAG -#define M_ORDERED_TAG ORDERED_QUEUE_TAG -#define M_IGN_RESIDUE IGNORE_WIDE_RESIDUE -#define M_IDENTIFY (0x80) - -#define M_X_MODIFY_DP EXTENDED_MODIFY_DATA_POINTER -#define M_X_SYNC_REQ EXTENDED_SDTR -#define M_X_WIDE_REQ EXTENDED_WDTR -#define M_X_PPR_REQ EXTENDED_PPR - -/* -** Status -*/ - -#define S_GOOD (0x00) -#define S_CHECK_COND (0x02) -#define S_COND_MET (0x04) -#define S_BUSY (0x08) -#define S_INT (0x10) -#define S_INT_COND_MET (0x14) -#define S_CONFLICT (0x18) -#define S_TERMINATED (0x20) -#define S_QUEUE_FULL (0x28) -#define S_ILLEGAL (0xff) -#define S_SENSE (0x80) - -/* - * End of ncrreg from FreeBSD - */ - -#endif /* defined SYM53C8XX_DEFS_H */ |