Annotation of Gnu-Mach/linux/src/drivers/scsi/ncr53c8xx.c, revision 1.1

1.1     ! root        1: /******************************************************************************
        !             2: **  Device driver for the PCI-SCSI NCR538XX controller family.
        !             3: **
        !             4: **  Copyright (C) 1994  Wolfgang Stanglmeier
        !             5: **
        !             6: **  This program is free software; you can redistribute it and/or modify
        !             7: **  it under the terms of the GNU General Public License as published by
        !             8: **  the Free Software Foundation; either version 2 of the License, or
        !             9: **  (at your option) any later version.
        !            10: **
        !            11: **  This program is distributed in the hope that it will be useful,
        !            12: **  but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: **  GNU General Public License for more details.
        !            15: **
        !            16: **  You should have received a copy of the GNU General Public License
        !            17: **  along with this program; if not, write to the Free Software
        !            18: **  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            19: **
        !            20: **-----------------------------------------------------------------------------
        !            21: **
        !            22: **  This driver has been ported to Linux from the FreeBSD NCR53C8XX driver
        !            23: **  and is currently maintained by
        !            24: **
        !            25: **          Gerard Roudier              <[email protected]>
        !            26: **
        !            27: **  Being given that this driver originates from the FreeBSD version, and
        !            28: **  in order to keep synergy on both, any suggested enhancements and corrections
        !            29: **  received on Linux are automatically a potential candidate for the FreeBSD 
        !            30: **  version.
        !            31: **
        !            32: **  The original driver has been written for 386bsd and FreeBSD by
        !            33: **          Wolfgang Stanglmeier        <[email protected]>
        !            34: **          Stefan Esser                <[email protected]>
        !            35: **
        !            36: **  And has been ported to NetBSD by
        !            37: **          Charles M. Hannum           <[email protected]>
        !            38: **
        !            39: **-----------------------------------------------------------------------------
        !            40: **
        !            41: **                     Brief history
        !            42: **
        !            43: **  December 10 1995 by Gerard Roudier:
        !            44: **     Initial port to Linux.
        !            45: **
        !            46: **  June 23 1996 by Gerard Roudier:
        !            47: **     Support for 64 bits architectures (Alpha).
        !            48: **
        !            49: **  November 30 1996 by Gerard Roudier:
        !            50: **     Support for Fast-20 scsi.
        !            51: **     Support for large DMA fifo and 128 dwords bursting.
        !            52: **
        !            53: **  February 27 1997 by Gerard Roudier:
        !            54: **     Support for Fast-40 scsi.
        !            55: **     Support for on-Board RAM.
        !            56: **
        !            57: **  May 3 1997 by Gerard Roudier:
        !            58: **     Full support for scsi scripts instructions pre-fetching.
        !            59: **
        !            60: **  May 19 1997 by Richard Waltham <[email protected]>:
        !            61: **     Support for NvRAM detection and reading.
        !            62: **
        !            63: **  August 18 1997 by Cort <[email protected]>:
        !            64: **     Support for Power/PC (Big Endian).
        !            65: **
        !            66: *******************************************************************************
        !            67: */
        !            68: 
        !            69: /*
        !            70: **     30 January 1998, version 2.5f.1
        !            71: **
        !            72: **     Supported SCSI-II features:
        !            73: **         Synchronous negotiation
        !            74: **         Wide negotiation        (depends on the NCR Chip)
        !            75: **         Enable disconnection
        !            76: **         Tagged command queuing
        !            77: **         Parity checking
        !            78: **         Etc...
        !            79: **
        !            80: **     Supported NCR chips:
        !            81: **             53C810          (8 bits, Fast SCSI-2, no rom BIOS) 
        !            82: **             53C815          (8 bits, Fast SCSI-2, on board rom BIOS)
        !            83: **             53C820          (Wide,   Fast SCSI-2, no rom BIOS)
        !            84: **             53C825          (Wide,   Fast SCSI-2, on board rom BIOS)
        !            85: **             53C860          (8 bits, Fast 20,     no rom BIOS)
        !            86: **             53C875          (Wide,   Fast 20,     on board rom BIOS)
        !            87: **             53C895          (Wide,   Fast 40,     on board rom BIOS)
        !            88: **
        !            89: **     Other features:
        !            90: **             Memory mapped IO (linux-1.3.X and above only)
        !            91: **             Module
        !            92: **             Shared IRQ (since linux-1.3.72)
        !            93: */
        !            94: 
        !            95: #define SCSI_NCR_DEBUG_FLAGS   (0)             
        !            96: 
        !            97: #define NCR_GETCC_WITHMSG
        !            98: 
        !            99: /*==========================================================
        !           100: **
        !           101: **      Include files
        !           102: **
        !           103: **==========================================================
        !           104: */
        !           105: 
        !           106: #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
        !           107: 
        !           108: #ifdef MODULE
        !           109: #include <linux/module.h>
        !           110: #endif
        !           111: 
        !           112: #include <asm/dma.h>
        !           113: #include <asm/io.h>
        !           114: #include <asm/system.h>
        !           115: #include <linux/delay.h>
        !           116: #include <linux/signal.h>
        !           117: #include <linux/sched.h>
        !           118: #include <linux/errno.h>
        !           119: #include <linux/bios32.h>
        !           120: #include <linux/pci.h>
        !           121: #include <linux/string.h>
        !           122: #include <linux/malloc.h>
        !           123: #include <linux/mm.h>
        !           124: #include <linux/ioport.h>
        !           125: #include <linux/time.h>
        !           126: #include <linux/timer.h>
        !           127: #include <linux/stat.h>
        !           128: 
        !           129: #include <linux/version.h>
        !           130: #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,0)
        !           131: #include <linux/blk.h>
        !           132: #else
        !           133: #include "../block/blk.h"
        !           134: #endif
        !           135: 
        !           136: #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,35)
        !           137: #include <linux/init.h>
        !           138: #else
        !           139: #ifndef        __initdata
        !           140: #define        __initdata
        !           141: #endif
        !           142: #ifndef        __initfunc
        !           143: #define        __initfunc(__arginit) __arginit
        !           144: #endif
        !           145: #endif
        !           146: 
        !           147: #include "scsi.h"
        !           148: #include "hosts.h"
        !           149: #include "constants.h"
        !           150: #include "sd.h"
        !           151: 
        !           152: #include <linux/types.h>
        !           153: 
        !           154: /*
        !           155: **     Define the BSD style u_int32 type
        !           156: */
        !           157: typedef u32 u_int32;
        !           158: 
        !           159: #include "ncr53c8xx.h"
        !           160: 
        !           161: /*==========================================================
        !           162: **
        !           163: **     Configuration and Debugging
        !           164: **
        !           165: **==========================================================
        !           166: */
        !           167: 
        !           168: /*
        !           169: **    SCSI address of this device.
        !           170: **    The boot routines should have set it.
        !           171: **    If not, use this.
        !           172: */
        !           173: 
        !           174: #ifndef SCSI_NCR_MYADDR
        !           175: #define SCSI_NCR_MYADDR      (7)
        !           176: #endif
        !           177: 
        !           178: /*
        !           179: **    The maximum number of tags per logic unit.
        !           180: **    Used only for disk devices that support tags.
        !           181: */
        !           182: 
        !           183: #ifndef SCSI_NCR_MAX_TAGS
        !           184: #define SCSI_NCR_MAX_TAGS    (4)
        !           185: #endif
        !           186: 
        !           187: /*
        !           188: **    Number of targets supported by the driver.
        !           189: **    n permits target numbers 0..n-1.
        !           190: **    Default is 7, meaning targets #0..#6.
        !           191: **    #7 .. is myself.
        !           192: */
        !           193: 
        !           194: #ifdef SCSI_NCR_MAX_TARGET
        !           195: #define MAX_TARGET  (SCSI_NCR_MAX_TARGET)
        !           196: #else
        !           197: #define MAX_TARGET  (16)
        !           198: #endif
        !           199: 
        !           200: /*
        !           201: **    Number of logic units supported by the driver.
        !           202: **    n enables logic unit numbers 0..n-1.
        !           203: **    The common SCSI devices require only
        !           204: **    one lun, so take 1 as the default.
        !           205: */
        !           206: 
        !           207: #ifdef SCSI_NCR_MAX_LUN
        !           208: #define MAX_LUN    SCSI_NCR_MAX_LUN
        !           209: #else
        !           210: #define MAX_LUN    (1)
        !           211: #endif
        !           212: 
        !           213: /*
        !           214: **    Asynchronous pre-scaler (ns). Shall be 40
        !           215: */
        !           216:  
        !           217: #ifndef SCSI_NCR_MIN_ASYNC
        !           218: #define SCSI_NCR_MIN_ASYNC (40)
        !           219: #endif
        !           220: 
        !           221: /*
        !           222: **    The maximum number of jobs scheduled for starting.
        !           223: **    There should be one slot per target, and one slot
        !           224: **    for each tag of each target in use.
        !           225: **    The calculation below is actually quite silly ...
        !           226: */
        !           227: 
        !           228: #ifdef SCSI_NCR_CAN_QUEUE
        !           229: #define MAX_START   (SCSI_NCR_CAN_QUEUE + 4)
        !           230: #else
        !           231: #define MAX_START   (MAX_TARGET + 7 * SCSI_NCR_MAX_TAGS)
        !           232: #endif
        !           233: 
        !           234: /*
        !           235: **    The maximum number of segments a transfer is split into.
        !           236: */
        !           237: 
        !           238: #define MAX_SCATTER (SCSI_NCR_MAX_SCATTER)
        !           239: 
        !           240: /*
        !           241: **    Io mapped or memory mapped.
        !           242: */
        !           243: 
        !           244: #if defined(SCSI_NCR_IOMAPPED)
        !           245: #define NCR_IOMAPPED
        !           246: #endif
        !           247: 
        !           248: /*
        !           249: **     other
        !           250: */
        !           251: 
        !           252: #define NCR_SNOOP_TIMEOUT (1000000)
        !           253: 
        !           254: /*==========================================================
        !           255: **
        !           256: **     Defines for Linux.
        !           257: **
        !           258: **     Linux and Bsd kernel functions are quite different.
        !           259: **     These defines allow a minimum change of the original
        !           260: **     code.
        !           261: **
        !           262: **==========================================================
        !           263: */
        !           264: 
        !           265:  /*
        !           266:  **    Obvious definitions
        !           267:  */
        !           268: 
        !           269: #define printf         printk
        !           270: #define u_char         unsigned char
        !           271: #define u_short                unsigned short
        !           272: #define u_int          unsigned int
        !           273: #define u_long         unsigned long
        !           274: 
        !           275: typedef        u_long          vm_offset_t;
        !           276: typedef        int             vm_size_t;
        !           277: 
        !           278: #define bcopy(s, d, n) memcpy((d), (s), (n))
        !           279: #define bzero(d, n)    memset((d), 0, (n))
        !           280: 
        !           281: #ifndef offsetof
        !           282: #define offsetof(t, m) ((size_t) (&((t *)0)->m))
        !           283: #endif
        !           284: 
        !           285: /*
        !           286: **     Address translation
        !           287: **
        !           288: **     On Linux 1.3.X, virt_to_bus() must be used to translate
        !           289: **     virtual memory addresses of the kernel data segment into
        !           290: **     IO bus adresses.
        !           291: **     On i386 architecture, IO bus addresses match the physical
        !           292: **     addresses. But on other architectures they can be different.
        !           293: **     In the original Bsd driver, vtophys() is called to translate
        !           294: **     data addresses to IO bus addresses. In order to minimize
        !           295: **     change, I decide to define vtophys() as virt_to_bus().
        !           296: */
        !           297: 
        !           298: #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,0)
        !           299: #define vtophys(p)     virt_to_bus(p)
        !           300: 
        !           301: /*
        !           302: **     Memory mapped IO
        !           303: **
        !           304: **     Since linux-2.1, we must use ioremap() to map the io memory space.
        !           305: **     iounmap() to unmap it. That allows portability.
        !           306: **     Linux 1.3.X and 2.0.X allow to remap physical pages addresses greater 
        !           307: **     than the highest physical memory address to kernel virtual pages with 
        !           308: **     vremap() / vfree(). That was not portable but worked with i386 
        !           309: **     architecture.
        !           310: */
        !           311: 
        !           312: #ifndef NCR_IOMAPPED
        !           313: __initfunc(
        !           314: static vm_offset_t remap_pci_mem(u_long base, u_long size)
        !           315: )
        !           316: {
        !           317:        u_long page_base        = ((u_long) base) & PAGE_MASK;
        !           318:        u_long page_offs        = ((u_long) base) - page_base;
        !           319: #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,0)
        !           320:        u_long page_remapped    = (u_long) ioremap(page_base, page_offs+size);
        !           321: #else
        !           322:        u_long page_remapped    = (u_long) vremap(page_base, page_offs+size);
        !           323: #endif
        !           324: 
        !           325:        return (vm_offset_t) (page_remapped ? (page_remapped + page_offs) : 0UL);
        !           326: }
        !           327: 
        !           328: __initfunc(
        !           329: static void unmap_pci_mem(vm_offset_t vaddr, u_long size)
        !           330: )
        !           331: {
        !           332:        if (vaddr)
        !           333: #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,0)
        !           334:                iounmap((void *) (vaddr & PAGE_MASK));
        !           335: #else
        !           336:                vfree((void *) (vaddr & PAGE_MASK));
        !           337: #endif
        !           338: }
        !           339: #endif /* !NCR_IOMAPPED */
        !           340: 
        !           341: #else /* linux-1.2.13 */
        !           342: 
        !           343: /*
        !           344: **     Linux 1.2.X assumes that addresses (virtual, physical, bus)
        !           345: **     are the same.
        !           346: **
        !           347: **     I have not found how to do MMIO. It seems that only processes can
        !           348: **     map high physical pages to virtual (Xservers can do MMIO).
        !           349: */
        !           350: 
        !           351: #define vtophys(p)     ((u_long) (p))
        !           352: #endif
        !           353: 
        !           354: /*
        !           355: **     Insert a delay in micro-seconds.
        !           356: */
        !           357: 
        !           358: static void DELAY(long us)
        !           359: {
        !           360:        for (;us>1000;us-=1000) udelay(1000);
        !           361:        if (us) udelay(us);
        !           362: }
        !           363: 
        !           364: /*
        !           365: **     Internal data structure allocation.
        !           366: **
        !           367: **     Linux scsi memory poor pool is adjusted for the need of
        !           368: **     middle-level scsi driver.
        !           369: **     We allocate our control blocks in the kernel memory pool
        !           370: **     to avoid scsi pool shortage.
        !           371: **     I notice that kmalloc() returns NULL during host attach under
        !           372: **     Linux 1.2.13. But this ncr driver is reliable enough to
        !           373: **     accomodate with this joke.
        !           374: **
        !           375: **     kmalloc() only ensure 8 bytes boundary alignment.
        !           376: **     The NCR need better alignment for cache line bursting.
        !           377: **     The global header is moved betewen the NCB and CCBs and need 
        !           378: **     origin and destination addresses to have same lower four bits.
        !           379: **
        !           380: **     We use 32 boundary alignment for NCB and CCBs and offset multiple 
        !           381: **     of 32 for global header fields. That's too much but at least enough.
        !           382: */
        !           383: 
        !           384: #define ALIGN_SIZE(shift)      (1UL << shift)
        !           385: #define ALIGN_MASK(shift)      (~(ALIGN_SIZE(shift)-1))
        !           386: 
        !           387: #define NCB_ALIGN_SHIFT                5
        !           388: #define CCB_ALIGN_SHIFT                5
        !           389: #define LCB_ALIGN_SHIFT                5
        !           390: #define SCR_ALIGN_SHIFT                5
        !           391: 
        !           392: #define NCB_ALIGN_SIZE         ALIGN_SIZE(NCB_ALIGN_SHIFT)
        !           393: #define NCB_ALIGN_MASK         ALIGN_MASK(NCB_ALIGN_SHIFT)
        !           394: #define CCB_ALIGN_SIZE         ALIGN_SIZE(CCB_ALIGN_SHIFT)
        !           395: #define CCB_ALIGN_MASK         ALIGN_MASK(CCB_ALIGN_SHIFT)
        !           396: #define SCR_ALIGN_SIZE         ALIGN_SIZE(SCR_ALIGN_SHIFT)
        !           397: #define SCR_ALIGN_MASK         ALIGN_MASK(SCR_ALIGN_SHIFT)
        !           398: 
        !           399: static void *m_alloc(int size, int a_shift)
        !           400: {
        !           401:        u_long addr;
        !           402:        void *ptr;
        !           403:        u_long a_size, a_mask;
        !           404: 
        !           405:        if (a_shift < 3)
        !           406:                a_shift = 3;
        !           407: 
        !           408:        a_size  = ALIGN_SIZE(a_shift);
        !           409:        a_mask  = ALIGN_MASK(a_shift);
        !           410: 
        !           411:        ptr = (void *) kmalloc(size + a_size, GFP_ATOMIC);
        !           412:        if (ptr) {
        !           413:                addr    = (((u_long) ptr) + a_size) & a_mask;
        !           414:                *((void **) (addr - sizeof(void *))) = ptr;
        !           415:                ptr     = (void *) addr;
        !           416:        }
        !           417: 
        !           418:        return ptr;
        !           419: }
        !           420: 
        !           421: #ifdef MODULE
        !           422: static void m_free(void *ptr, int size)
        !           423: {
        !           424:        u_long addr;
        !           425: 
        !           426:        if (ptr) {
        !           427:                addr    = (u_long) ptr;
        !           428:                ptr     = *((void **) (addr - sizeof(void *)));
        !           429: 
        !           430:                kfree(ptr);
        !           431:        }
        !           432: }
        !           433: #endif
        !           434: 
        !           435: /*
        !           436: **     Transfer direction
        !           437: **
        !           438: **     Low-level scsi drivers under Linux do not receive the expected 
        !           439: **     data transfer direction from upper scsi drivers.
        !           440: **     The driver will only check actual data direction for common 
        !           441: **     scsi opcodes. Other ones may cause problem, since they may 
        !           442: **     depend on device type or be vendor specific.
        !           443: **     I would prefer to never trust the device for data direction, 
        !           444: **     but that is not possible.
        !           445: **
        !           446: **     The original driver requires the expected direction to be known.
        !           447: **     The Linux version of the driver has been enhanced in order to 
        !           448: **     be able to transfer data in the direction choosen by the target. 
        !           449: */
        !           450: 
        !           451: #define XferNone       0
        !           452: #define XferIn         1
        !           453: #define XferOut                2
        !           454: #define XferBoth       3
        !           455: static int guess_xfer_direction(int opcode);
        !           456: 
        !           457: /*
        !           458: **     Head of list of NCR boards
        !           459: **
        !           460: **     For kernel version < 1.3.70, host is retrieved by its irq level.
        !           461: **     For later kernels, the internal host control block address 
        !           462: **     (struct ncb) is used as device id parameter of the irq stuff.
        !           463: */
        !           464: 
        !           465: static struct Scsi_Host                *first_host     = NULL;
        !           466: static Scsi_Host_Template      *the_template   = NULL; 
        !           467: 
        !           468: 
        !           469: /*
        !           470: **     /proc directory entry and proc_info function
        !           471: */
        !           472: 
        !           473: #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,0)
        !           474: struct proc_dir_entry proc_scsi_ncr53c8xx = {
        !           475:     PROC_SCSI_NCR53C8XX, 9, "ncr53c8xx",
        !           476:     S_IFDIR | S_IRUGO | S_IXUGO, 2
        !           477: };
        !           478: # ifdef SCSI_NCR_PROC_INFO_SUPPORT
        !           479: int ncr53c8xx_proc_info(char *buffer, char **start, off_t offset,
        !           480:                        int length, int hostno, int func);
        !           481: # endif
        !           482: #endif
        !           483: 
        !           484: /*
        !           485: **     Table of target capabilities.
        !           486: **
        !           487: **     This bitmap is anded with the byte 7 of inquiry data on completion of
        !           488: **     INQUIRY command.
        !           489: **     The driver never see zeroed bits and will ignore the corresponding
        !           490: **     capabilities of the target.
        !           491: */
        !           492: 
        !           493: static struct {
        !           494:        unsigned char and_map[MAX_TARGET];
        !           495: } target_capabilities[SCSI_NCR_MAX_HOST] = { NCR53C8XX_TARGET_CAPABILITIES };
        !           496: 
        !           497: /*
        !           498: **     Driver setup.
        !           499: **
        !           500: **     This structure is initialized from linux config options.
        !           501: **     It can be overridden at boot-up by the boot command line.
        !           502: */
        !           503: struct ncr_driver_setup {
        !           504:        unsigned master_parity  : 1;
        !           505:        unsigned scsi_parity    : 1;
        !           506:        unsigned disconnection  : 1;
        !           507:        unsigned special_features : 2;
        !           508:        unsigned ultra_scsi     : 2;
        !           509:        unsigned force_sync_nego: 1;
        !           510:        unsigned reverse_probe: 1;
        !           511:        unsigned pci_fix_up: 4;
        !           512:        u_char  use_nvram;
        !           513:        u_char  verbose;
        !           514:        u_char  default_tags;
        !           515:        u_short default_sync;
        !           516:        u_short debug;
        !           517:        u_char  burst_max;
        !           518:        u_char  led_pin;
        !           519:        u_char  max_wide;
        !           520:        u_char  settle_delay;
        !           521:        u_char  diff_support;
        !           522:        u_char  irqm;
        !           523:        u_char  bus_check;
        !           524: };
        !           525: 
        !           526: static struct ncr_driver_setup
        !           527:        driver_setup                    = SCSI_NCR_DRIVER_SETUP;
        !           528: 
        !           529: #ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
        !           530: static struct ncr_driver_setup
        !           531:        driver_safe_setup __initdata    = SCSI_NCR_DRIVER_SAFE_SETUP;
        !           532: #ifdef MODULE
        !           533: char *ncr53c8xx = 0;   /* command line passed by insmod */
        !           534: #endif
        !           535: #endif
        !           536: 
        !           537: /*
        !           538: **     Other Linux definitions
        !           539: */
        !           540: 
        !           541: #define ScsiResult(host_code, scsi_code) (((host_code) << 16) + ((scsi_code) & 0x7f))
        !           542: 
        !           543: #if LINUX_VERSION_CODE >= LinuxVersionCode(2,0,0)
        !           544: static void ncr53c8xx_select_queue_depths(struct Scsi_Host *host, struct scsi_device *devlist);
        !           545: #endif
        !           546: 
        !           547: #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,70)
        !           548: static void ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs);
        !           549: #else
        !           550: static void ncr53c8xx_intr(int irq, struct pt_regs * regs);
        !           551: #endif
        !           552: 
        !           553: static void ncr53c8xx_timeout(unsigned long np);
        !           554: 
        !           555: #define initverbose (driver_setup.verbose)
        !           556: #define bootverbose (np->verbose)
        !           557: 
        !           558: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !           559: /*
        !           560: **     Symbios NvRAM data format
        !           561: */
        !           562: #define SYMBIOS_NVRAM_SIZE 368
        !           563: #define SYMBIOS_NVRAM_ADDRESS 0x100
        !           564: 
        !           565: struct Symbios_nvram {
        !           566: /* Header 6 bytes */
        !           567:        u_short start_marker;   /* 0x0000 */
        !           568:        u_short byte_count;     /* excluding header/trailer */
        !           569:        u_short checksum;
        !           570: 
        !           571: /* Controller set up 20 bytes */
        !           572:        u_short word0;          /* 0x3000 */
        !           573:        u_short word2;          /* 0x0000 */
        !           574:        u_short word4;          /* 0x0000 */
        !           575:        u_short flags;
        !           576: #define SYMBIOS_SCAM_ENABLE    (1)
        !           577: #define SYMBIOS_PARITY_ENABLE  (1<<1)
        !           578: #define SYMBIOS_VERBOSE_MSGS   (1<<2)
        !           579:        u_short flags1;
        !           580: #define SYMBIOS_SCAN_HI_LO     (1)
        !           581:        u_short word10;         /* 0x00 */
        !           582:        u_short flags3;         /* 0x00 */
        !           583: #define SYMBIOS_REMOVABLE_FLAGS        (3)             /* 0=none, 1=bootable, 2=all */
        !           584:        u_char  host_id;
        !           585:        u_char  byte15;         /* 0x04 */
        !           586:        u_short word16;         /* 0x0410 */
        !           587:        u_short word18;         /* 0x0000 */
        !           588: 
        !           589: /* Boot order 14 bytes * 4 */
        !           590:        struct Symbios_host{
        !           591:                u_char  word0;          /* 0x0004:ok / 0x0000:nok */
        !           592:                u_short device_id;      /* PCI device id */
        !           593:                u_short vendor_id;      /* PCI vendor id */
        !           594:                u_char  byte6;          /* 0x00 */
        !           595:                u_char  device_fn;      /* PCI device/function number << 3*/
        !           596:                u_short word8;
        !           597:                u_short flags;
        !           598: #define        SYMBIOS_INIT_SCAN_AT_BOOT       (1)
        !           599:                u_short io_port;        /* PCI io_port address */
        !           600:        } host[4];
        !           601: 
        !           602: /* Targets 8 bytes * 16 */
        !           603:        struct Symbios_target {
        !           604:                u_short flags;
        !           605: #define SYMBIOS_DISCONNECT_ENABLE      (1)
        !           606: #define SYMBIOS_SCAN_AT_BOOT_TIME      (1<<1)
        !           607: #define SYMBIOS_SCAN_LUNS              (1<<2)
        !           608: #define SYMBIOS_QUEUE_TAGS_ENABLED     (1<<3)
        !           609:                u_char  bus_width;      /* 0x08/0x10 */
        !           610:                u_char  sync_offset;
        !           611:                u_char  sync_period;    /* 4*period factor */
        !           612:                u_char  byte6;          /* 0x00 */
        !           613:                u_short timeout;
        !           614:        } target[16];
        !           615:        u_char  spare_devices[19*8];
        !           616:        u_char  trailer[6];             /* 0xfe 0xfe 0x00 0x00 0x00 0x00 */
        !           617: };
        !           618: typedef struct Symbios_nvram   Symbios_nvram;
        !           619: typedef struct Symbios_host    Symbios_host;
        !           620: typedef struct Symbios_target  Symbios_target;
        !           621: 
        !           622: /*
        !           623: **     Tekram NvRAM data format.
        !           624: */
        !           625: #define TEKRAM_NVRAM_SIZE 64
        !           626: #define TEKRAM_NVRAM_ADDRESS 0
        !           627: 
        !           628: struct Tekram_nvram {
        !           629:        struct Tekram_target {
        !           630:                u_char  flags;
        !           631: #define        TEKRAM_PARITY_CHECK             (1)
        !           632: #define TEKRAM_SYNC_NEGO               (1<<1)
        !           633: #define TEKRAM_DISCONNECT_ENABLE       (1<<2)
        !           634: #define        TEKRAM_START_CMD                (1<<3)
        !           635: #define TEKRAM_TAGGED_COMMANDS         (1<<4)
        !           636: #define TEKRAM_WIDE_NEGO               (1<<5)
        !           637:                u_char  sync_index;
        !           638:                u_short word2;
        !           639:        } target[16];
        !           640:        u_char  host_id;
        !           641:        u_char  flags;
        !           642: #define TEKRAM_MORE_THAN_2_DRIVES      (1)
        !           643: #define TEKRAM_DRIVES_SUP_1GB          (1<<1)
        !           644: #define        TEKRAM_RESET_ON_POWER_ON        (1<<2)
        !           645: #define TEKRAM_ACTIVE_NEGATION         (1<<3)
        !           646: #define TEKRAM_IMMEDIATE_SEEK          (1<<4)
        !           647: #define        TEKRAM_SCAN_LUNS                (1<<5)
        !           648: #define        TEKRAM_REMOVABLE_FLAGS          (3<<6)  /* 0: disable; 1: boot device; 2:all */
        !           649:        u_char  boot_delay_index;
        !           650:        u_char  max_tags_index;
        !           651:        u_short flags1;
        !           652: #define TEKRAM_F2_F6_ENABLED           (1)
        !           653:        u_short spare[29];
        !           654: };
        !           655: typedef struct Tekram_nvram    Tekram_nvram;
        !           656: typedef struct Tekram_target   Tekram_target;
        !           657: 
        !           658: static u_char Tekram_sync[12] __initdata = {25,31,37,43,50,62,75,125,12,15,18,21};
        !           659: 
        !           660: #endif /* SCSI_NCR_NVRAM_SUPPORT */
        !           661: 
        !           662: /*
        !           663: **     Structures used by ncr53c8xx_detect/ncr53c8xx_pci_init to 
        !           664: **     transmit device configuration to the ncr_attach() function.
        !           665: */
        !           666: typedef struct {
        !           667:        int     bus;
        !           668:        u_char  device_fn;
        !           669:        u_int   base;
        !           670:        u_int   base_2;
        !           671:        u_int   io_port;
        !           672:        int     irq;
        !           673: /* port and reg fields to use INB, OUTB macros */
        !           674:        u_int   port;
        !           675:        volatile struct ncr_reg *reg;
        !           676: } ncr_slot;
        !           677: 
        !           678: typedef struct {
        !           679:        int type;
        !           680: #define        SCSI_NCR_SYMBIOS_NVRAM  (1)
        !           681: #define        SCSI_NCR_TEKRAM_NVRAM   (2)
        !           682: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !           683:        union {
        !           684:                Symbios_nvram Symbios;
        !           685:                Tekram_nvram Tekram;
        !           686:        } data;
        !           687: #endif
        !           688: } ncr_nvram;
        !           689: 
        !           690: /*
        !           691: **     Structure used by ncr53c8xx_detect/ncr53c8xx_pci_init
        !           692: **     to save data on each detected board for ncr_attach().
        !           693: */
        !           694: typedef struct {
        !           695:        ncr_slot  slot;
        !           696:        ncr_chip  chip;
        !           697:        ncr_nvram *nvram;
        !           698:        int attach_done;
        !           699: } ncr_device;
        !           700: 
        !           701: /*==========================================================
        !           702: **
        !           703: **     Debugging tags
        !           704: **
        !           705: **==========================================================
        !           706: */
        !           707: 
        !           708: #define DEBUG_ALLOC    (0x0001)
        !           709: #define DEBUG_PHASE    (0x0002)
        !           710: #define DEBUG_POLL     (0x0004)
        !           711: #define DEBUG_QUEUE    (0x0008)
        !           712: #define DEBUG_RESULT   (0x0010)
        !           713: #define DEBUG_SCATTER  (0x0020)
        !           714: #define DEBUG_SCRIPT   (0x0040)
        !           715: #define DEBUG_TINY     (0x0080)
        !           716: #define DEBUG_TIMING   (0x0100)
        !           717: #define DEBUG_NEGO     (0x0200)
        !           718: #define DEBUG_TAGS     (0x0400)
        !           719: #define DEBUG_FREEZE   (0x0800)
        !           720: #define DEBUG_RESTART  (0x1000)
        !           721: 
        !           722: /*
        !           723: **    Enable/Disable debug messages.
        !           724: **    Can be changed at runtime too.
        !           725: */
        !           726: 
        !           727: #ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
        !           728:        #define DEBUG_FLAGS ncr_debug
        !           729: #else
        !           730:        #define DEBUG_FLAGS     SCSI_NCR_DEBUG_FLAGS
        !           731: #endif
        !           732: 
        !           733: 
        !           734: 
        !           735: /*==========================================================
        !           736: **
        !           737: **     assert ()
        !           738: **
        !           739: **==========================================================
        !           740: **
        !           741: **     modified copy from 386bsd:/usr/include/sys/assert.h
        !           742: **
        !           743: **----------------------------------------------------------
        !           744: */
        !           745: 
        !           746: #define        assert(expression) { \
        !           747:        if (!(expression)) { \
        !           748:                (void)printf(\
        !           749:                        "assertion \"%s\" failed: file \"%s\", line %d\n", \
        !           750:                        #expression, \
        !           751:                        __FILE__, __LINE__); \
        !           752:        } \
        !           753: }
        !           754: 
        !           755: /*==========================================================
        !           756: **
        !           757: **     Big/Little endian support.
        !           758: **
        !           759: **==========================================================
        !           760: */
        !           761: 
        !           762: /*
        !           763: **     If the NCR uses big endian addressing mode over the 
        !           764: **     PCI, actual io register addresses for byte and word 
        !           765: **     accesses must be changed according to lane routing.
        !           766: **     Btw, ncr_offb() and ncr_offw() macros only apply to 
        !           767: **     constants and so donnot generate bloated code.
        !           768: */
        !           769: 
        !           770: #if    defined(SCSI_NCR_BIG_ENDIAN)
        !           771: 
        !           772: #define ncr_offb(o)    (((o)&~3)+((~((o)&3))&3))
        !           773: #define ncr_offw(o)    (((o)&~3)+((~((o)&3))&2))
        !           774: 
        !           775: #else
        !           776: 
        !           777: #define ncr_offb(o)    (o)
        !           778: #define ncr_offw(o)    (o)
        !           779: 
        !           780: #endif
        !           781: 
        !           782: /*
        !           783: **     If the CPU and the NCR use same endian-ness adressing,
        !           784: **     no byte reordering is needed for script patching.
        !           785: **     Macro cpu_to_scr() is to be used for script patching.
        !           786: **     Macro scr_to_cpu() is to be used for getting a DWORD 
        !           787: **     from the script.
        !           788: */
        !           789: 
        !           790: #if    defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
        !           791: 
        !           792: #define cpu_to_scr(dw) cpu_to_le32(dw)
        !           793: #define scr_to_cpu(dw) le32_to_cpu(dw)
        !           794: 
        !           795: #elif  defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
        !           796: 
        !           797: #define cpu_to_scr(dw) cpu_to_be32(dw)
        !           798: #define scr_to_cpu(dw) be32_to_cpu(dw)
        !           799: 
        !           800: #else
        !           801: 
        !           802: #define cpu_to_scr(dw) (dw)
        !           803: #define scr_to_cpu(dw) (dw)
        !           804: 
        !           805: #endif
        !           806: 
        !           807: /*==========================================================
        !           808: **
        !           809: **     Access to the controller chip.
        !           810: **
        !           811: **     If NCR_IOMAPPED is defined, only IO are used by the driver.
        !           812: **
        !           813: **==========================================================
        !           814: */
        !           815: 
        !           816: /*
        !           817: **     If the CPU and the NCR use same endian-ness adressing,
        !           818: **     no byte reordering is needed for accessing chip io 
        !           819: **     registers. Functions suffixed by '_raw' are assumed 
        !           820: **     to access the chip over the PCI without doing byte 
        !           821: **     reordering. Functions suffixed by '_l2b' are 
        !           822: **     assumed to perform little-endian to big-endian byte 
        !           823: **     reordering, those suffixed by '_b2l' blah, blah,
        !           824: **     blah, ...
        !           825: */
        !           826: 
        !           827: #if defined(NCR_IOMAPPED)
        !           828: 
        !           829: /*
        !           830: **     IO mapped only input / ouput
        !           831: */
        !           832: 
        !           833: #define        INB_OFF(o)              inb (np->port + ncr_offb(o))
        !           834: #define        OUTB_OFF(o, val)        outb ((val), np->port + ncr_offb(o))
        !           835: 
        !           836: #if    defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
        !           837: 
        !           838: #define        INW_OFF(o)              inw_l2b (np->port + ncr_offw(o))
        !           839: #define        INL_OFF(o)              inl_l2b (np->port + (o))
        !           840: 
        !           841: #define        OUTW_OFF(o, val)        outw_b2l ((val), np->port + ncr_offw(o))
        !           842: #define        OUTL_OFF(o, val)        outl_b2l ((val), np->port + (o))
        !           843: 
        !           844: #elif  defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
        !           845: 
        !           846: #define        INW_OFF(o)              inw_b2l (np->port + ncr_offw(o))
        !           847: #define        INL_OFF(o)              inl_b2l (np->port + (o))
        !           848: 
        !           849: #define        OUTW_OFF(o, val)        outw_l2b ((val), np->port + ncr_offw(o))
        !           850: #define        OUTL_OFF(o, val)        outl_l2b ((val), np->port + (o))
        !           851: 
        !           852: #else
        !           853: 
        !           854: #define        INW_OFF(o)              inw_raw (np->port + ncr_offw(o))
        !           855: #define        INL_OFF(o)              inl_raw (np->port + (o))
        !           856: 
        !           857: #define        OUTW_OFF(o, val)        outw_raw ((val), np->port + ncr_offw(o))
        !           858: #define        OUTL_OFF(o, val)        outl_raw ((val), np->port + (o))
        !           859: 
        !           860: #endif /* ENDIANs */
        !           861: 
        !           862: #else  /* defined NCR_IOMAPPED */
        !           863: 
        !           864: /*
        !           865: **     MEMORY mapped IO input / output
        !           866: */
        !           867: 
        !           868: #define INB_OFF(o)             readb((char *)np->reg + ncr_offb(o))
        !           869: #define OUTB_OFF(o, val)       writeb((val), (char *)np->reg + ncr_offb(o))
        !           870: 
        !           871: #if    defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
        !           872: 
        !           873: #define INW_OFF(o)             readw_l2b((char *)np->reg + ncr_offw(o))
        !           874: #define INL_OFF(o)             readl_l2b((char *)np->reg + (o))
        !           875: 
        !           876: #define OUTW_OFF(o, val)       writew_b2l((val), (char *)np->reg + ncr_offw(o))
        !           877: #define OUTL_OFF(o, val)       writel_b2l((val), (char *)np->reg + (o))
        !           878: 
        !           879: #elif  defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
        !           880: 
        !           881: #define INW_OFF(o)             readw_b2l((char *)np->reg + ncr_offw(o))
        !           882: #define INL_OFF(o)             readl_b2l((char *)np->reg + (o))
        !           883: 
        !           884: #define OUTW_OFF(o, val)       writew_l2b((val), (char *)np->reg + ncr_offw(o))
        !           885: #define OUTL_OFF(o, val)       writel_l2b((val), (char *)np->reg + (o))
        !           886: 
        !           887: #else
        !           888: 
        !           889: #define INW_OFF(o)             readw_raw((char *)np->reg + ncr_offw(o))
        !           890: #define INL_OFF(o)             readl_raw((char *)np->reg + (o))
        !           891: 
        !           892: #define OUTW_OFF(o, val)       writew_raw((val), (char *)np->reg + ncr_offw(o))
        !           893: #define OUTL_OFF(o, val)       writel_raw((val), (char *)np->reg + (o))
        !           894: 
        !           895: #endif
        !           896: 
        !           897: #endif /* defined NCR_IOMAPPED */
        !           898: 
        !           899: #define INB(r)         INB_OFF (offsetof(struct ncr_reg,r))
        !           900: #define INW(r)         INW_OFF (offsetof(struct ncr_reg,r))
        !           901: #define INL(r)         INL_OFF (offsetof(struct ncr_reg,r))
        !           902: 
        !           903: #define OUTB(r, val)   OUTB_OFF (offsetof(struct ncr_reg,r), (val))
        !           904: #define OUTW(r, val)   OUTW_OFF (offsetof(struct ncr_reg,r), (val))
        !           905: #define OUTL(r, val)   OUTL_OFF (offsetof(struct ncr_reg,r), (val))
        !           906: 
        !           907: /*
        !           908: **     Set bit field ON, OFF 
        !           909: */
        !           910: 
        !           911: #define OUTONB(r, m)   OUTB(r, INB(r) | (m))
        !           912: #define OUTOFFB(r, m)  OUTB(r, INB(r) & ~(m))
        !           913: #define OUTONW(r, m)   OUTW(r, INW(r) | (m))
        !           914: #define OUTOFFW(r, m)  OUTW(r, INW(r) & ~(m))
        !           915: #define OUTONL(r, m)   OUTL(r, INL(r) | (m))
        !           916: #define OUTOFFL(r, m)  OUTL(r, INL(r) & ~(m))
        !           917: 
        !           918: 
        !           919: /*==========================================================
        !           920: **
        !           921: **     Command control block states.
        !           922: **
        !           923: **==========================================================
        !           924: */
        !           925: 
        !           926: #define HS_IDLE                (0)
        !           927: #define HS_BUSY                (1)
        !           928: #define HS_NEGOTIATE   (2)     /* sync/wide data transfer*/
        !           929: #define HS_DISCONNECT  (3)     /* Disconnected by target */
        !           930: 
        !           931: #define HS_COMPLETE    (4)
        !           932: #define HS_SEL_TIMEOUT (5)     /* Selection timeout      */
        !           933: #define HS_RESET       (6)     /* SCSI reset        */
        !           934: #define HS_ABORTED     (7)     /* Transfer aborted       */
        !           935: #define HS_TIMEOUT     (8)     /* Software timeout       */
        !           936: #define HS_FAIL                (9)     /* SCSI or PCI bus errors */
        !           937: #define HS_UNEXPECTED  (10)    /* Unexpected disconnect  */
        !           938: 
        !           939: #define HS_DONEMASK    (0xfc)
        !           940: 
        !           941: /*==========================================================
        !           942: **
        !           943: **     Software Interrupt Codes
        !           944: **
        !           945: **==========================================================
        !           946: */
        !           947: 
        !           948: #define        SIR_SENSE_RESTART       (1)
        !           949: #define        SIR_SENSE_FAILED        (2)
        !           950: #define        SIR_STALL_RESTART       (3)
        !           951: #define        SIR_STALL_QUEUE         (4)
        !           952: #define        SIR_NEGO_SYNC           (5)
        !           953: #define        SIR_NEGO_WIDE           (6)
        !           954: #define        SIR_NEGO_FAILED         (7)
        !           955: #define        SIR_NEGO_PROTO          (8)
        !           956: #define        SIR_REJECT_RECEIVED     (9)
        !           957: #define        SIR_REJECT_SENT         (10)
        !           958: #define        SIR_IGN_RESIDUE         (11)
        !           959: #define        SIR_MISSING_SAVE        (12)
        !           960: #define        SIR_DATA_IO_IS_OUT      (13)
        !           961: #define        SIR_DATA_IO_IS_IN       (14)
        !           962: #define        SIR_MAX                 (14)
        !           963: 
        !           964: /*==========================================================
        !           965: **
        !           966: **     Extended error codes.
        !           967: **     xerr_status field of struct ccb.
        !           968: **
        !           969: **==========================================================
        !           970: */
        !           971: 
        !           972: #define        XE_OK           (0)
        !           973: #define        XE_EXTRA_DATA   (1)     /* unexpected data phase */
        !           974: #define        XE_BAD_PHASE    (2)     /* illegal phase (4/5)   */
        !           975: 
        !           976: /*==========================================================
        !           977: **
        !           978: **     Negotiation status.
        !           979: **     nego_status field       of struct ccb.
        !           980: **
        !           981: **==========================================================
        !           982: */
        !           983: 
        !           984: #define NS_SYNC                (1)
        !           985: #define NS_WIDE                (2)
        !           986: 
        !           987: /*==========================================================
        !           988: **
        !           989: **     "Special features" of targets.
        !           990: **     quirks field            of struct tcb.
        !           991: **     actualquirks field      of struct ccb.
        !           992: **
        !           993: **==========================================================
        !           994: */
        !           995: 
        !           996: #define        QUIRK_AUTOSAVE  (0x01)
        !           997: #define        QUIRK_NOMSG     (0x02)
        !           998: #define QUIRK_NOSYNC   (0x10)
        !           999: #define QUIRK_NOWIDE16 (0x20)
        !          1000: #define        QUIRK_UPDATE    (0x80)
        !          1001: 
        !          1002: /*==========================================================
        !          1003: **
        !          1004: **     Capability bits in Inquire response byte 7.
        !          1005: **
        !          1006: **==========================================================
        !          1007: */
        !          1008: 
        !          1009: #define        INQ7_QUEUE      (0x02)
        !          1010: #define        INQ7_SYNC       (0x10)
        !          1011: #define        INQ7_WIDE16     (0x20)
        !          1012: 
        !          1013: /*==========================================================
        !          1014: **
        !          1015: **     Misc.
        !          1016: **
        !          1017: **==========================================================
        !          1018: */
        !          1019: 
        !          1020: #define CCB_MAGIC      (0xf2691ad2)
        !          1021: 
        !          1022: /*==========================================================
        !          1023: **
        !          1024: **     Declaration of structs.
        !          1025: **
        !          1026: **==========================================================
        !          1027: */
        !          1028: 
        !          1029: struct tcb;
        !          1030: struct lcb;
        !          1031: struct ccb;
        !          1032: struct ncb;
        !          1033: struct script;
        !          1034: 
        !          1035: typedef struct ncb * ncb_p;
        !          1036: typedef struct tcb * tcb_p;
        !          1037: typedef struct lcb * lcb_p;
        !          1038: typedef struct ccb * ccb_p;
        !          1039: 
        !          1040: struct link {
        !          1041:        ncrcmd  l_cmd;
        !          1042:        ncrcmd  l_paddr;
        !          1043: };
        !          1044: 
        !          1045: struct usrcmd {
        !          1046:        u_long  target;
        !          1047:        u_long  lun;
        !          1048:        u_long  data;
        !          1049:        u_long  cmd;
        !          1050: };
        !          1051: 
        !          1052: #define UC_SETSYNC      10
        !          1053: #define UC_SETTAGS     11
        !          1054: #define UC_SETDEBUG    12
        !          1055: #define UC_SETORDER    13
        !          1056: #define UC_SETWIDE     14
        !          1057: #define UC_SETFLAG     15
        !          1058: #define UC_CLEARPROF   16
        !          1059: 
        !          1060: #ifdef SCSI_NCR_DEBUG_ERROR_RECOVERY_SUPPORT
        !          1061: #define UC_DEBUG_ERROR_RECOVERY 17
        !          1062: #endif
        !          1063: 
        !          1064: #define        UF_TRACE        (0x01)
        !          1065: #define        UF_NODISC       (0x02)
        !          1066: #define        UF_NOSCAN       (0x04)
        !          1067: 
        !          1068: /*---------------------------------------
        !          1069: **
        !          1070: **     Timestamps for profiling
        !          1071: **
        !          1072: **---------------------------------------
        !          1073: */
        !          1074: 
        !          1075: struct tstamp {
        !          1076:        u_long start;
        !          1077:        u_long end;
        !          1078:        u_long select;
        !          1079:        u_long command;
        !          1080:        u_long status;
        !          1081:        u_long disconnect;
        !          1082:        u_long reselect;
        !          1083: };
        !          1084: 
        !          1085: /*
        !          1086: **     profiling data (per device)
        !          1087: */
        !          1088: 
        !          1089: struct profile {
        !          1090:        u_long  num_trans;
        !          1091:        u_long  num_kbytes;
        !          1092:        u_long  rest_bytes;
        !          1093:        u_long  num_disc;
        !          1094:        u_long  num_break;
        !          1095:        u_long  num_int;
        !          1096:        u_long  num_fly;
        !          1097:        u_long  ms_setup;
        !          1098:        u_long  ms_data;
        !          1099:        u_long  ms_disc;
        !          1100:        u_long  ms_post;
        !          1101: };
        !          1102: 
        !          1103: /*==========================================================
        !          1104: **
        !          1105: **     Declaration of structs:         target control block
        !          1106: **
        !          1107: **==========================================================
        !          1108: */
        !          1109: 
        !          1110: struct tcb {
        !          1111:        /*
        !          1112:        **      during reselection the ncr jumps to this point
        !          1113:        **      with SFBR set to the encoded target number
        !          1114:        **      with bit 7 set.
        !          1115:        **      if it's not this target, jump to the next.
        !          1116:        **
        !          1117:        **      JUMP  IF (SFBR != #target#)
        !          1118:        **      @(next tcb)
        !          1119:        */
        !          1120: 
        !          1121:        struct link   jump_tcb;
        !          1122: 
        !          1123:        /*
        !          1124:        **      load the actual values for the sxfer and the scntl3
        !          1125:        **      register (sync/wide mode).
        !          1126:        **
        !          1127:        **      SCR_COPY (1);
        !          1128:        **      @(sval field of this tcb)
        !          1129:        **      @(sxfer register)
        !          1130:        **      SCR_COPY (1);
        !          1131:        **      @(wval field of this tcb)
        !          1132:        **      @(scntl3 register)
        !          1133:        */
        !          1134: 
        !          1135:        ncrcmd  getscr[6];
        !          1136: 
        !          1137:        /*
        !          1138:        **      if next message is "identify"
        !          1139:        **      then load the message to SFBR,
        !          1140:        **      else load 0 to SFBR.
        !          1141:        **
        !          1142:        **      CALL
        !          1143:        **      <RESEL_LUN>
        !          1144:        */
        !          1145: 
        !          1146:        struct link   call_lun;
        !          1147: 
        !          1148:        /*
        !          1149:        **      now look for the right lun.
        !          1150:        **
        !          1151:        **      JUMP
        !          1152:        **      @(first ccb of this lun)
        !          1153:        */
        !          1154: 
        !          1155:        struct link   jump_lcb;
        !          1156: 
        !          1157:        /*
        !          1158:        **      pointer to interrupted getcc ccb
        !          1159:        */
        !          1160: 
        !          1161:        ccb_p   hold_cp;
        !          1162: 
        !          1163:        /*
        !          1164:        **      pointer to ccb used for negotiating.
        !          1165:        **      Avoid to start a nego for all queued commands 
        !          1166:        **      when tagged command queuing is enabled.
        !          1167:        */
        !          1168: 
        !          1169:        ccb_p   nego_cp;
        !          1170: 
        !          1171:        /*
        !          1172:        **      statistical data
        !          1173:        */
        !          1174: 
        !          1175:        u_long  transfers;
        !          1176:        u_long  bytes;
        !          1177: 
        !          1178:        /*
        !          1179:        **      user settable limits for sync transfer
        !          1180:        **      and tagged commands.
        !          1181:        **      These limits are read from the NVRAM if present.
        !          1182:        */
        !          1183: 
        !          1184:        u_char  usrsync;
        !          1185:        u_char  usrwide;
        !          1186:        u_char  usrtags;
        !          1187:        u_char  usrflag;
        !          1188: 
        !          1189:        u_char  numtags;
        !          1190:        u_char  maxtags;
        !          1191:        u_short num_good;
        !          1192: 
        !          1193:        /*
        !          1194:        **      negotiation of wide and synch transfer.
        !          1195:        **      device quirks.
        !          1196:        */
        !          1197: 
        !          1198: /*0*/  u_char  minsync;
        !          1199: /*1*/  u_char  sval;
        !          1200: /*2*/  u_short period;
        !          1201: /*0*/  u_char  maxoffs;
        !          1202: 
        !          1203: /*1*/  u_char  quirks;
        !          1204: 
        !          1205: /*2*/  u_char  widedone;
        !          1206: /*3*/  u_char  wval;
        !          1207:        /*
        !          1208:        **      inquire data
        !          1209:        */
        !          1210: #define MAX_INQUIRE 36
        !          1211:        u_char  inqdata[MAX_INQUIRE];
        !          1212: 
        !          1213:        /*
        !          1214:        **      the lcb's of this tcb
        !          1215:        */
        !          1216: 
        !          1217:        lcb_p   lp[MAX_LUN];
        !          1218: };
        !          1219: 
        !          1220: /*==========================================================
        !          1221: **
        !          1222: **     Declaration of structs:         lun control block
        !          1223: **
        !          1224: **==========================================================
        !          1225: */
        !          1226: 
        !          1227: struct lcb {
        !          1228:        /*
        !          1229:        **      during reselection the ncr jumps to this point
        !          1230:        **      with SFBR set to the "Identify" message.
        !          1231:        **      if it's not this lun, jump to the next.
        !          1232:        **
        !          1233:        **      JUMP  IF (SFBR != #lun#)
        !          1234:        **      @(next lcb of this target)
        !          1235:        */
        !          1236: 
        !          1237:        struct link     jump_lcb;
        !          1238: 
        !          1239:        /*
        !          1240:        **      if next message is "simple tag",
        !          1241:        **      then load the tag to SFBR,
        !          1242:        **      else load 0 to SFBR.
        !          1243:        **
        !          1244:        **      CALL
        !          1245:        **      <RESEL_TAG>
        !          1246:        */
        !          1247: 
        !          1248:        struct link     call_tag;
        !          1249: 
        !          1250:        /*
        !          1251:        **      now look for the right ccb.
        !          1252:        **
        !          1253:        **      JUMP
        !          1254:        **      @(first ccb of this lun)
        !          1255:        */
        !          1256: 
        !          1257:        struct link     jump_ccb;
        !          1258: 
        !          1259:        /*
        !          1260:        **      start of the ccb chain
        !          1261:        */
        !          1262: 
        !          1263:        ccb_p   next_ccb;
        !          1264: 
        !          1265:        /*
        !          1266:        **      Control of tagged queueing
        !          1267:        */
        !          1268: 
        !          1269:        u_char          reqccbs;
        !          1270:        u_char          actccbs;
        !          1271:        u_char          reqlink;
        !          1272:        u_char          actlink;
        !          1273:        u_char          usetags;
        !          1274:        u_char          lasttag;
        !          1275: 
        !          1276:        /*
        !          1277:        **      Linux specific fields:
        !          1278:        **      Number of active commands and current credit.
        !          1279:        **      Should be managed by the generic scsi driver
        !          1280:        */
        !          1281: 
        !          1282:        u_char          active;
        !          1283:        u_char          opennings;
        !          1284: 
        !          1285:        /*-----------------------------------------------
        !          1286:        **      Flag to force M_ORDERED_TAG on next command
        !          1287:        **      in order to avoid spurious timeout when
        !          1288:        **      M_SIMPLE_TAG is used for all operations.
        !          1289:        **-----------------------------------------------
        !          1290:        */
        !          1291:        u_char  force_ordered_tag;
        !          1292: #define NCR_TIMEOUT_INCREASE   (5*HZ)
        !          1293: };
        !          1294: 
        !          1295: /*==========================================================
        !          1296: **
        !          1297: **      Declaration of structs:     COMMAND control block
        !          1298: **
        !          1299: **==========================================================
        !          1300: **
        !          1301: **     This substructure is copied from the ccb to a
        !          1302: **     global address after selection (or reselection)
        !          1303: **     and copied back before disconnect.
        !          1304: **
        !          1305: **     These fields are accessible to the script processor.
        !          1306: **
        !          1307: **----------------------------------------------------------
        !          1308: */
        !          1309: 
        !          1310: struct head {
        !          1311:        /*
        !          1312:        **      Execution of a ccb starts at this point.
        !          1313:        **      It's a jump to the "SELECT" label
        !          1314:        **      of the script.
        !          1315:        **
        !          1316:        **      After successful selection the script
        !          1317:        **      processor overwrites it with a jump to
        !          1318:        **      the IDLE label of the script.
        !          1319:        */
        !          1320: 
        !          1321:        struct link     launch;
        !          1322: 
        !          1323:        /*
        !          1324:        **      Saved data pointer.
        !          1325:        **      Points to the position in the script
        !          1326:        **      responsible for the actual transfer
        !          1327:        **      of data.
        !          1328:        **      It's written after reception of a
        !          1329:        **      "SAVE_DATA_POINTER" message.
        !          1330:        **      The goalpointer points after
        !          1331:        **      the last transfer command.
        !          1332:        */
        !          1333: 
        !          1334:        u_int32         savep;
        !          1335:        u_int32         lastp;
        !          1336:        u_int32         goalp;
        !          1337: 
        !          1338:        /*
        !          1339:        **      The virtual address of the ccb
        !          1340:        **      containing this header.
        !          1341:        */
        !          1342: 
        !          1343:        ccb_p   cp;
        !          1344: 
        !          1345:        /*
        !          1346:        **      space for some timestamps to gather
        !          1347:        **      profiling data about devices and this driver.
        !          1348:        */
        !          1349: 
        !          1350:        struct tstamp   stamp;
        !          1351: 
        !          1352:        /*
        !          1353:        **      status fields.
        !          1354:        */
        !          1355: 
        !          1356:        u_char          scr_st[4];      /* script status */
        !          1357:        u_char          status[4];      /* host status. Must be the last */
        !          1358:                                        /* DWORD of the CCB header */
        !          1359: };
        !          1360: 
        !          1361: /*
        !          1362: **     The status bytes are used by the host and the script processor.
        !          1363: **
        !          1364: **     The byte corresponding to the host_status must be stored in the 
        !          1365: **     last DWORD of the CCB header since it is used for command 
        !          1366: **     completion (ncr_wakeup()). Doing so, we are sure that the header 
        !          1367: **     has been entirely copied back to the CCB when the host_status is 
        !          1368: **     seen complete by the CPU.
        !          1369: **
        !          1370: **     The last four bytes (status[4]) are copied to the scratchb register
        !          1371: **     (declared as scr0..scr3 in ncr_reg.h) just after the select/reselect,
        !          1372: **     and copied back just after disconnecting.
        !          1373: **     Inside the script the XX_REG are used.
        !          1374: **
        !          1375: **     The first four bytes (scr_st[4]) are used inside the script by 
        !          1376: **     "COPY" commands.
        !          1377: **     Because source and destination must have the same alignment
        !          1378: **     in a DWORD, the fields HAVE to be at the choosen offsets.
        !          1379: **             xerr_st         0       (0x34)  scratcha
        !          1380: **             sync_st         1       (0x05)  sxfer
        !          1381: **             wide_st         3       (0x03)  scntl3
        !          1382: */
        !          1383: 
        !          1384: /*
        !          1385: **     Last four bytes (script)
        !          1386: */
        !          1387: #define  QU_REG        scr0
        !          1388: #define  HS_REG        scr1
        !          1389: #define  HS_PRT        nc_scr1
        !          1390: #define  SS_REG        scr2
        !          1391: #define  PS_REG        scr3
        !          1392: 
        !          1393: /*
        !          1394: **     Last four bytes (host)
        !          1395: */
        !          1396: #define  actualquirks  phys.header.status[0]
        !          1397: #define  host_status   phys.header.status[1]
        !          1398: #define  scsi_status   phys.header.status[2]
        !          1399: #define  parity_status phys.header.status[3]
        !          1400: 
        !          1401: /*
        !          1402: **     First four bytes (script)
        !          1403: */
        !          1404: #define  xerr_st       header.scr_st[0]
        !          1405: #define  sync_st       header.scr_st[1]
        !          1406: #define  nego_st       header.scr_st[2]
        !          1407: #define  wide_st       header.scr_st[3]
        !          1408: 
        !          1409: /*
        !          1410: **     First four bytes (host)
        !          1411: */
        !          1412: #define  xerr_status   phys.xerr_st
        !          1413: #define  sync_status   phys.sync_st
        !          1414: #define  nego_status   phys.nego_st
        !          1415: #define  wide_status   phys.wide_st
        !          1416: 
        !          1417: /*==========================================================
        !          1418: **
        !          1419: **      Declaration of structs:     Data structure block
        !          1420: **
        !          1421: **==========================================================
        !          1422: **
        !          1423: **     During execution of a ccb by the script processor,
        !          1424: **     the DSA (data structure address) register points
        !          1425: **     to this substructure of the ccb.
        !          1426: **     This substructure contains the header with
        !          1427: **     the script-processor-changable data and
        !          1428: **     data blocks for the indirect move commands.
        !          1429: **
        !          1430: **----------------------------------------------------------
        !          1431: */
        !          1432: 
        !          1433: struct dsb {
        !          1434: 
        !          1435:        /*
        !          1436:        **      Header.
        !          1437:        **      Has to be the first entry,
        !          1438:        **      because it's jumped to by the
        !          1439:        **      script processor
        !          1440:        */
        !          1441: 
        !          1442:        struct head     header;
        !          1443: 
        !          1444:        /*
        !          1445:        **      Table data for Script
        !          1446:        */
        !          1447: 
        !          1448:        struct scr_tblsel  select;
        !          1449:        struct scr_tblmove smsg  ;
        !          1450:        struct scr_tblmove smsg2 ;
        !          1451:        struct scr_tblmove cmd   ;
        !          1452:        struct scr_tblmove scmd  ;
        !          1453:        struct scr_tblmove sense ;
        !          1454:        struct scr_tblmove data [MAX_SCATTER];
        !          1455: };
        !          1456: 
        !          1457: /*==========================================================
        !          1458: **
        !          1459: **      Declaration of structs:     Command control block.
        !          1460: **
        !          1461: **==========================================================
        !          1462: **
        !          1463: **     During execution of a ccb by the script processor,
        !          1464: **     the DSA (data structure address) register points
        !          1465: **     to this substructure of the ccb.
        !          1466: **     This substructure contains the header with
        !          1467: **     the script-processor-changable data and then
        !          1468: **     data blocks for the indirect move commands.
        !          1469: **
        !          1470: **----------------------------------------------------------
        !          1471: */
        !          1472: 
        !          1473: 
        !          1474: struct ccb {
        !          1475:        /*
        !          1476:        **      This field forces 32 bytes alignement for phys.header,
        !          1477:        **      in order to use cache line bursting when copying it 
        !          1478:        **      to the ncb.
        !          1479:        */
        !          1480: 
        !          1481:        struct link             filler[2];
        !          1482: 
        !          1483:        /*
        !          1484:        **      during reselection the ncr jumps to this point.
        !          1485:        **      If a "SIMPLE_TAG" message was received,
        !          1486:        **      then SFBR is set to the tag.
        !          1487:        **      else SFBR is set to 0
        !          1488:        **      If looking for another tag, jump to the next ccb.
        !          1489:        **
        !          1490:        **      JUMP  IF (SFBR != #TAG#)
        !          1491:        **      @(next ccb of this lun)
        !          1492:        */
        !          1493: 
        !          1494:        struct link             jump_ccb;
        !          1495: 
        !          1496:        /*
        !          1497:        **      After execution of this call, the return address
        !          1498:        **      (in  the TEMP register) points to the following
        !          1499:        **      data structure block.
        !          1500:        **      So copy it to the DSA register, and start
        !          1501:        **      processing of this data structure.
        !          1502:        **
        !          1503:        **      CALL
        !          1504:        **      <RESEL_TMP>
        !          1505:        */
        !          1506: 
        !          1507:        struct link             call_tmp;
        !          1508: 
        !          1509:        /*
        !          1510:        **      This is the data structure which is
        !          1511:        **      to be executed by the script processor.
        !          1512:        */
        !          1513: 
        !          1514:        struct dsb              phys;
        !          1515: 
        !          1516:        /*
        !          1517:        **      If a data transfer phase is terminated too early
        !          1518:        **      (after reception of a message (i.e. DISCONNECT)),
        !          1519:        **      we have to prepare a mini script to transfer
        !          1520:        **      the rest of the data.
        !          1521:        */
        !          1522: 
        !          1523:        ncrcmd                  patch[8];
        !          1524: 
        !          1525:        /*
        !          1526:        **      The general SCSI driver provides a
        !          1527:        **      pointer to a control block.
        !          1528:        */
        !          1529: 
        !          1530:        Scsi_Cmnd       *cmd;
        !          1531:        int data_len;
        !          1532: 
        !          1533:        /*
        !          1534:        **      We prepare a message to be sent after selection,
        !          1535:        **      and a second one to be sent after getcc selection.
        !          1536:        **      Contents are IDENTIFY and SIMPLE_TAG.
        !          1537:        **      While negotiating sync or wide transfer,
        !          1538:        **      a SDTM or WDTM message is appended.
        !          1539:        */
        !          1540: 
        !          1541:        u_char                  scsi_smsg [8];
        !          1542:        u_char                  scsi_smsg2[8];
        !          1543: 
        !          1544:        /*
        !          1545:        **      Lock this ccb.
        !          1546:        **      Flag is used while looking for a free ccb.
        !          1547:        */
        !          1548: 
        !          1549:        u_long          magic;
        !          1550: 
        !          1551:        /*
        !          1552:        **      Physical address of this instance of ccb
        !          1553:        */
        !          1554: 
        !          1555:        u_long          p_ccb;
        !          1556: 
        !          1557:        /*
        !          1558:        **      Completion time out for this job.
        !          1559:        **      It's set to time of start + allowed number of seconds.
        !          1560:        */
        !          1561: 
        !          1562:        u_long          tlimit;
        !          1563: 
        !          1564:        /*
        !          1565:        **      All ccbs of one hostadapter are chained.
        !          1566:        */
        !          1567: 
        !          1568:        ccb_p           link_ccb;
        !          1569: 
        !          1570:        /*
        !          1571:        **      All ccbs of one target/lun are chained.
        !          1572:        */
        !          1573: 
        !          1574:        ccb_p           next_ccb;
        !          1575: 
        !          1576:        /*
        !          1577:        **      Sense command
        !          1578:        */
        !          1579: 
        !          1580:        u_char          sensecmd[6];
        !          1581: 
        !          1582:        /*
        !          1583:        **      Tag for this transfer.
        !          1584:        **      It's patched into jump_ccb.
        !          1585:        **      If it's not zero, a SIMPLE_TAG
        !          1586:        **      message is included in smsg.
        !          1587:        */
        !          1588: 
        !          1589:        u_char                  tag;
        !          1590: 
        !          1591:        /*
        !          1592:        **      Number of segments of the scatter list.
        !          1593:        **      Used for recalculation of savep/goalp/lastp on 
        !          1594:        **      SIR_DATA_IO_IS_OUT interrupt.
        !          1595:        */
        !          1596:        
        !          1597:        u_char                  segments;
        !          1598: };
        !          1599: 
        !          1600: #define CCB_PHYS(cp,lbl)       (cp->p_ccb + offsetof(struct ccb, lbl))
        !          1601: 
        !          1602: /*==========================================================
        !          1603: **
        !          1604: **      Declaration of structs:     NCR device descriptor
        !          1605: **
        !          1606: **==========================================================
        !          1607: */
        !          1608: 
        !          1609: struct ncb {
        !          1610:        /*
        !          1611:        **      The global header.
        !          1612:        **      Accessible to both the host and the
        !          1613:        **      script-processor.
        !          1614:        **      Is 32 bytes aligned since ncb is, in order to 
        !          1615:        **      allow cache line bursting when copying it from or 
        !          1616:        **      to ccbs.
        !          1617:        */
        !          1618:        struct head     header;
        !          1619: 
        !          1620:        /*-----------------------------------------------
        !          1621:        **      Specific Linux fields
        !          1622:        **-----------------------------------------------
        !          1623:        */
        !          1624:        int    unit;                    /* Unit number                       */
        !          1625:        char   chip_name[8];            /* Chip name                         */
        !          1626:        char   inst_name[16];           /* Instance name                     */
        !          1627:        struct timer_list timer;        /* Timer link header                 */
        !          1628:        int     ncr_cache;              /* Cache test variable               */
        !          1629:        Scsi_Cmnd *waiting_list;        /* Waiting list header for commands  */
        !          1630:                                        /* that we can't put into the squeue */
        !          1631:        u_long  settle_time;            /* Reset in progess                  */
        !          1632:        u_char  release_stage;          /* Synchronisation stage on release  */
        !          1633:        u_char  verbose;                /* Boot verbosity for this controller*/
        !          1634: #ifdef SCSI_NCR_DEBUG_ERROR_RECOVERY_SUPPORT
        !          1635:        u_char  debug_error_recovery;
        !          1636:        u_char  stalling;
        !          1637:        u_char  assert_atn;
        !          1638: #endif
        !          1639: 
        !          1640:        /*-----------------------------------------------
        !          1641:        **      Added field to support differences
        !          1642:        **      between ncr chips.
        !          1643:        **      sv_xxx are some io register bit value at start-up and
        !          1644:        **      so assumed to have been set by the sdms bios.
        !          1645:        **      rv_xxx are the bit fields of io register that will keep 
        !          1646:        **      the features used by the driver.
        !          1647:        **-----------------------------------------------
        !          1648:        */
        !          1649:        u_short device_id;
        !          1650:        u_char  revision_id;
        !          1651: 
        !          1652:        u_char  sv_scntl0;
        !          1653:        u_char  sv_scntl3;
        !          1654:        u_char  sv_dmode;
        !          1655:        u_char  sv_dcntl;
        !          1656:        u_char  sv_ctest3;
        !          1657:        u_char  sv_ctest4;
        !          1658:        u_char  sv_ctest5;
        !          1659:        u_char  sv_gpcntl;
        !          1660:        u_char  sv_stest2;
        !          1661:        u_char  sv_stest4;
        !          1662: 
        !          1663:        u_char  rv_scntl0;
        !          1664:        u_char  rv_scntl3;
        !          1665:        u_char  rv_dmode;
        !          1666:        u_char  rv_dcntl;
        !          1667:        u_char  rv_ctest3;
        !          1668:        u_char  rv_ctest4;
        !          1669:        u_char  rv_ctest5;
        !          1670:        u_char  rv_stest2;
        !          1671: 
        !          1672:        u_char  scsi_mode;
        !          1673: 
        !          1674:        /*-----------------------------------------------
        !          1675:        **      Scripts ..
        !          1676:        **-----------------------------------------------
        !          1677:        **
        !          1678:        **      During reselection the ncr jumps to this point.
        !          1679:        **      The SFBR register is loaded with the encoded target id.
        !          1680:        **
        !          1681:        **      Jump to the first target.
        !          1682:        **
        !          1683:        **      JUMP
        !          1684:        **      @(next tcb)
        !          1685:        */
        !          1686:        struct link     jump_tcb;
        !          1687: 
        !          1688:        /*-----------------------------------------------
        !          1689:        **      Configuration ..
        !          1690:        **-----------------------------------------------
        !          1691:        **
        !          1692:        **      virtual and physical addresses
        !          1693:        **      of the 53c810 chip.
        !          1694:        */
        !          1695:        vm_offset_t     vaddr;
        !          1696:        vm_offset_t     paddr;
        !          1697: 
        !          1698:        vm_offset_t     vaddr2;
        !          1699:        vm_offset_t     paddr2;
        !          1700: 
        !          1701:        /*
        !          1702:        **      pointer to the chip's registers.
        !          1703:        */
        !          1704:        volatile
        !          1705:        struct ncr_reg* reg;
        !          1706: 
        !          1707:        /*
        !          1708:        **      A copy of the scripts, relocated for this ncb.
        !          1709:        */
        !          1710:        struct script   *script0;
        !          1711:        struct scripth  *scripth0;
        !          1712: 
        !          1713:        /*
        !          1714:        **      Scripts instance virtual address.
        !          1715:        */
        !          1716:        struct script   *script;
        !          1717:        struct scripth  *scripth;
        !          1718: 
        !          1719:        /*
        !          1720:        **      Scripts instance physical address.
        !          1721:        */
        !          1722:        u_long          p_script;
        !          1723:        u_long          p_scripth;
        !          1724: 
        !          1725:        /*
        !          1726:        **      The SCSI address of the host adapter.
        !          1727:        */
        !          1728:        u_char    myaddr;
        !          1729: 
        !          1730:        /*
        !          1731:        **      Max dwords burst supported by the adapter.
        !          1732:        */
        !          1733:        u_char          maxburst;       /* log base 2 of dwords burst   */
        !          1734: 
        !          1735:        /*
        !          1736:        **      timing parameters
        !          1737:        */
        !          1738:        u_char          minsync;        /* Minimum sync period factor   */
        !          1739:        u_char          maxsync;        /* Maximum sync period factor   */
        !          1740:        u_char          maxoffs;        /* Max scsi offset              */
        !          1741:        u_char          multiplier;     /* Clock multiplier (1,2,4)     */
        !          1742:        u_char          clock_divn;     /* Number of clock divisors     */
        !          1743:        u_long          clock_khz;      /* SCSI clock frequency in KHz  */
        !          1744:        u_int           features;       /* Chip features map            */
        !          1745: 
        !          1746: 
        !          1747:        /*-----------------------------------------------
        !          1748:        **      Link to the generic SCSI driver
        !          1749:        **-----------------------------------------------
        !          1750:        */
        !          1751: 
        !          1752:        /* struct scsi_link     sc_link; */
        !          1753: 
        !          1754:        /*-----------------------------------------------
        !          1755:        **      Job control
        !          1756:        **-----------------------------------------------
        !          1757:        **
        !          1758:        **      Commands from user
        !          1759:        */
        !          1760:        struct usrcmd   user;
        !          1761:        u_char          order;
        !          1762: 
        !          1763:        /*
        !          1764:        **      Target data
        !          1765:        */
        !          1766:        struct tcb      target[MAX_TARGET];
        !          1767: 
        !          1768:        /*
        !          1769:        **      Start queue.
        !          1770:        */
        !          1771:        u_int32         squeue [MAX_START];
        !          1772:        u_short         squeueput;
        !          1773:        u_short         actccbs;
        !          1774: 
        !          1775:        /*
        !          1776:        **      Timeout handler
        !          1777:        */
        !          1778: #if 0
        !          1779:        u_long          heartbeat;
        !          1780:        u_short         ticks;
        !          1781:        u_short         latetime;
        !          1782: #endif
        !          1783:        u_long          lasttime;
        !          1784: 
        !          1785:        /*-----------------------------------------------
        !          1786:        **      Debug and profiling
        !          1787:        **-----------------------------------------------
        !          1788:        **
        !          1789:        **      register dump
        !          1790:        */
        !          1791:        struct ncr_reg  regdump;
        !          1792:        u_long          regtime;
        !          1793: 
        !          1794:        /*
        !          1795:        **      Profiling data
        !          1796:        */
        !          1797:        struct profile  profile;
        !          1798:        u_long          disc_phys;
        !          1799:        u_long          disc_ref;
        !          1800: 
        !          1801:        /*
        !          1802:        **      The global control block.
        !          1803:        **      It's used only during the configuration phase.
        !          1804:        **      A target control block will be created
        !          1805:        **      after the first successful transfer.
        !          1806:        */
        !          1807:        struct ccb      *ccb;
        !          1808: 
        !          1809:        /*
        !          1810:        **      message buffers.
        !          1811:        **      Should be longword aligned,
        !          1812:        **      because they're written with a
        !          1813:        **      COPY script command.
        !          1814:        */
        !          1815:        u_char          msgout[8];
        !          1816:        u_char          msgin [8];
        !          1817:        u_int32         lastmsg;
        !          1818: 
        !          1819:        /*
        !          1820:        **      Buffer for STATUS_IN phase.
        !          1821:        */
        !          1822:        u_char          scratch;
        !          1823: 
        !          1824:        /*
        !          1825:        **      controller chip dependent maximal transfer width.
        !          1826:        */
        !          1827:        u_char          maxwide;
        !          1828: 
        !          1829:        /*
        !          1830:        **      option for M_IDENTIFY message: enables disconnecting
        !          1831:        */
        !          1832:        u_char          disc;
        !          1833: 
        !          1834:        /*
        !          1835:        **      address of the ncr control registers in io space
        !          1836:        */
        !          1837:        u_int           port;
        !          1838: 
        !          1839:        /*
        !          1840:        **      irq level
        !          1841:        */
        !          1842:        u_short         irq;
        !          1843: };
        !          1844: 
        !          1845: #define NCB_SCRIPT_PHYS(np,lbl)         (np->p_script  + offsetof (struct script, lbl))
        !          1846: #define NCB_SCRIPTH_PHYS(np,lbl) (np->p_scripth + offsetof (struct scripth, lbl))
        !          1847: 
        !          1848: /*==========================================================
        !          1849: **
        !          1850: **
        !          1851: **      Script for NCR-Processor.
        !          1852: **
        !          1853: **     Use ncr_script_fill() to create the variable parts.
        !          1854: **     Use ncr_script_copy_and_bind() to make a copy and
        !          1855: **     bind to physical addresses.
        !          1856: **
        !          1857: **
        !          1858: **==========================================================
        !          1859: **
        !          1860: **     We have to know the offsets of all labels before
        !          1861: **     we reach them (for forward jumps).
        !          1862: **     Therefore we declare a struct here.
        !          1863: **     If you make changes inside the script,
        !          1864: **     DON'T FORGET TO CHANGE THE LENGTHS HERE!
        !          1865: **
        !          1866: **----------------------------------------------------------
        !          1867: */
        !          1868: 
        !          1869: /*
        !          1870: **     Script fragments which are loaded into the on-board RAM 
        !          1871: **     of 825A, 875 and 895 chips.
        !          1872: */
        !          1873: struct script {
        !          1874:        ncrcmd  start           [  4];
        !          1875:        ncrcmd  start0          [  2];
        !          1876:        ncrcmd  start1          [  3];
        !          1877:        ncrcmd  startpos        [  1];
        !          1878:        ncrcmd  trysel          [  8];
        !          1879:        ncrcmd  skip            [  8];
        !          1880:        ncrcmd  skip2           [  3];
        !          1881:        ncrcmd  idle            [  2];
        !          1882:        ncrcmd  select          [ 22];
        !          1883:        ncrcmd  prepare         [  4];
        !          1884:        ncrcmd  loadpos         [ 14];
        !          1885:        ncrcmd  prepare2        [ 24];
        !          1886:        ncrcmd  setmsg          [  5];
        !          1887:        ncrcmd  clrack          [  2];
        !          1888:        ncrcmd  dispatch        [ 38];
        !          1889:        ncrcmd  no_data         [ 17];
        !          1890:        ncrcmd  checkatn        [ 10];
        !          1891:        ncrcmd  command         [ 15];
        !          1892:        ncrcmd  status          [ 27];
        !          1893:        ncrcmd  msg_in          [ 26];
        !          1894:        ncrcmd  msg_bad         [  6];
        !          1895:        ncrcmd  complete        [ 13];
        !          1896:        ncrcmd  cleanup         [ 12];
        !          1897:        ncrcmd  cleanup0        [ 11];
        !          1898:        ncrcmd  signal          [ 10];
        !          1899:        ncrcmd  save_dp         [  5];
        !          1900:        ncrcmd  restore_dp      [  5];
        !          1901:        ncrcmd  disconnect      [ 12];
        !          1902:        ncrcmd  disconnect0     [  5];
        !          1903:        ncrcmd  disconnect1     [ 23];
        !          1904:        ncrcmd  msg_out         [  9];
        !          1905:        ncrcmd  msg_out_done    [  7];
        !          1906:        ncrcmd  badgetcc        [  6];
        !          1907:        ncrcmd  reselect        [  8];
        !          1908:        ncrcmd  reselect1       [  8];
        !          1909:        ncrcmd  reselect2       [  8];
        !          1910:        ncrcmd  resel_tmp       [  5];
        !          1911:        ncrcmd  resel_lun       [ 18];
        !          1912:        ncrcmd  resel_tag       [ 24];
        !          1913:        ncrcmd  data_io         [  6];
        !          1914:        ncrcmd  data_in         [MAX_SCATTER * 4 + 4];
        !          1915: };
        !          1916: 
        !          1917: /*
        !          1918: **     Script fragments which stay in main memory for all chips.
        !          1919: */
        !          1920: struct scripth {
        !          1921:        ncrcmd  tryloop         [MAX_START*5+2];
        !          1922:        ncrcmd  msg_parity      [  6];
        !          1923:        ncrcmd  msg_reject      [  8];
        !          1924:        ncrcmd  msg_ign_residue [ 32];
        !          1925:        ncrcmd  msg_extended    [ 18];
        !          1926:        ncrcmd  msg_ext_2       [ 18];
        !          1927:        ncrcmd  msg_wdtr        [ 27];
        !          1928:        ncrcmd  msg_ext_3       [ 18];
        !          1929:        ncrcmd  msg_sdtr        [ 27];
        !          1930:        ncrcmd  msg_out_abort   [ 10];
        !          1931:        ncrcmd  getcc           [  4];
        !          1932:        ncrcmd  getcc1          [  5];
        !          1933: #ifdef NCR_GETCC_WITHMSG
        !          1934:        ncrcmd  getcc2          [ 33];
        !          1935: #else
        !          1936:        ncrcmd  getcc2          [ 14];
        !          1937: #endif
        !          1938:        ncrcmd  getcc3          [ 10];
        !          1939:        ncrcmd  data_out        [MAX_SCATTER * 4 + 4];
        !          1940:        ncrcmd  aborttag        [  4];
        !          1941:        ncrcmd  abort           [ 22];
        !          1942:        ncrcmd  snooptest       [  9];
        !          1943:        ncrcmd  snoopend        [  2];
        !          1944: };
        !          1945: 
        !          1946: /*==========================================================
        !          1947: **
        !          1948: **
        !          1949: **      Function headers.
        !          1950: **
        !          1951: **
        !          1952: **==========================================================
        !          1953: */
        !          1954: 
        !          1955: static void    ncr_alloc_ccb   (ncb_p np, u_long t, u_long l);
        !          1956: static void    ncr_complete    (ncb_p np, ccb_p cp);
        !          1957: static void    ncr_exception   (ncb_p np);
        !          1958: static void    ncr_free_ccb    (ncb_p np, ccb_p cp, u_long t, u_long l);
        !          1959: static void    ncr_getclock    (ncb_p np, int mult);
        !          1960: static void    ncr_selectclock (ncb_p np, u_char scntl3);
        !          1961: static ccb_p   ncr_get_ccb     (ncb_p np, u_long t,u_long l);
        !          1962: static void    ncr_init        (ncb_p np, int reset, char * msg, u_long code);
        !          1963: static int     ncr_int_sbmc    (ncb_p np);
        !          1964: static int     ncr_int_par     (ncb_p np);
        !          1965: static void    ncr_int_ma      (ncb_p np);
        !          1966: static void    ncr_int_sir     (ncb_p np);
        !          1967: static  void    ncr_int_sto     (ncb_p np);
        !          1968: static u_long  ncr_lookup      (char* id);
        !          1969: static void    ncr_negotiate   (struct ncb* np, struct tcb* tp);
        !          1970: static void    ncr_opennings   (ncb_p np, lcb_p lp, Scsi_Cmnd * xp);
        !          1971: 
        !          1972: #ifdef SCSI_NCR_PROFILE_SUPPORT
        !          1973: static void    ncb_profile     (ncb_p np, ccb_p cp);
        !          1974: #endif
        !          1975: 
        !          1976: static void    ncr_script_copy_and_bind
        !          1977:                                (ncb_p np, ncrcmd *src, ncrcmd *dst, int len);
        !          1978: static  void    ncr_script_fill (struct script * scr, struct scripth * scripth);
        !          1979: static int     ncr_scatter     (ccb_p cp, Scsi_Cmnd *cmd);
        !          1980: static void    ncr_setmaxtags  (ncb_p np, tcb_p tp, u_long numtags);
        !          1981: static void    ncr_getsync     (ncb_p np, u_char sfac, u_char *fakp, u_char *scntl3p);
        !          1982: static void    ncr_setsync     (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer);
        !          1983: static void    ncr_settags     (tcb_p tp, lcb_p lp);
        !          1984: static void    ncr_setwide     (ncb_p np, ccb_p cp, u_char wide, u_char ack);
        !          1985: static int     ncr_show_msg    (u_char * msg);
        !          1986: static int     ncr_snooptest   (ncb_p np);
        !          1987: static void    ncr_timeout     (ncb_p np);
        !          1988: static  void    ncr_wakeup      (ncb_p np, u_long code);
        !          1989: static void    ncr_start_reset (ncb_p np, int settle_delay);
        !          1990: static int     ncr_reset_scsi_bus (ncb_p np, int enab_int, int settle_delay);
        !          1991: 
        !          1992: #ifdef SCSI_NCR_USER_COMMAND_SUPPORT
        !          1993: static void    ncr_usercmd     (ncb_p np);
        !          1994: #endif
        !          1995: 
        !          1996: static int ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device);
        !          1997: 
        !          1998: static void insert_into_waiting_list(ncb_p np, Scsi_Cmnd *cmd);
        !          1999: static Scsi_Cmnd *retrieve_from_waiting_list(int to_remove, ncb_p np, Scsi_Cmnd *cmd);
        !          2000: static void process_waiting_list(ncb_p np, int sts);
        !          2001: 
        !          2002: #define remove_from_waiting_list(np, cmd) \
        !          2003:                retrieve_from_waiting_list(1, (np), (cmd))
        !          2004: #define requeue_waiting_list(np) process_waiting_list((np), DID_OK)
        !          2005: #define reset_waiting_list(np) process_waiting_list((np), DID_RESET)
        !          2006: 
        !          2007: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          2008: static int     ncr_get_Symbios_nvram   (ncr_slot *np, Symbios_nvram *nvram);
        !          2009: static int     ncr_get_Tekram_nvram    (ncr_slot *np, Tekram_nvram *nvram);
        !          2010: #endif
        !          2011: 
        !          2012: /*==========================================================
        !          2013: **
        !          2014: **
        !          2015: **      Global static data.
        !          2016: **
        !          2017: **
        !          2018: **==========================================================
        !          2019: */
        !          2020: 
        !          2021: #ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
        !          2022: static int ncr_debug = SCSI_NCR_DEBUG_FLAGS;
        !          2023: #endif
        !          2024: 
        !          2025: static inline char *ncr_name (ncb_p np)
        !          2026: {
        !          2027:        return np->inst_name;
        !          2028: }
        !          2029: 
        !          2030: 
        !          2031: /*==========================================================
        !          2032: **
        !          2033: **
        !          2034: **      Scripts for NCR-Processor.
        !          2035: **
        !          2036: **      Use ncr_script_bind for binding to physical addresses.
        !          2037: **
        !          2038: **
        !          2039: **==========================================================
        !          2040: **
        !          2041: **     NADDR generates a reference to a field of the controller data.
        !          2042: **     PADDR generates a reference to another part of the script.
        !          2043: **     RADDR generates a reference to a script processor register.
        !          2044: **     FADDR generates a reference to a script processor register
        !          2045: **             with offset.
        !          2046: **
        !          2047: **----------------------------------------------------------
        !          2048: */
        !          2049: 
        !          2050: #define        RELOC_SOFTC     0x40000000
        !          2051: #define        RELOC_LABEL     0x50000000
        !          2052: #define        RELOC_REGISTER  0x60000000
        !          2053: #define        RELOC_KVAR      0x70000000
        !          2054: #define        RELOC_LABELH    0x80000000
        !          2055: #define        RELOC_MASK      0xf0000000
        !          2056: 
        !          2057: #define        NADDR(label)    (RELOC_SOFTC | offsetof(struct ncb, label))
        !          2058: #define PADDR(label)    (RELOC_LABEL | offsetof(struct script, label))
        !          2059: #define PADDRH(label)   (RELOC_LABELH | offsetof(struct scripth, label))
        !          2060: #define        RADDR(label)    (RELOC_REGISTER | REG(label))
        !          2061: #define        FADDR(label,ofs)(RELOC_REGISTER | ((REG(label))+(ofs)))
        !          2062: #define        KVAR(which)     (RELOC_KVAR | (which))
        !          2063: 
        !          2064: #define        SCRIPT_KVAR_JIFFIES     (0)
        !          2065: 
        !          2066: #define        SCRIPT_KVAR_FIRST               SCRIPT_KVAR_JIFFIES
        !          2067: #define        SCRIPT_KVAR_LAST                SCRIPT_KVAR_JIFFIES
        !          2068: 
        !          2069: /*
        !          2070:  * Kernel variables referenced in the scripts.
        !          2071:  * THESE MUST ALL BE ALIGNED TO A 4-BYTE BOUNDARY.
        !          2072:  */
        !          2073: static void *script_kvars[] __initdata =
        !          2074:        { (void *)&jiffies };
        !          2075: 
        !          2076: static struct script script0 __initdata = {
        !          2077: /*--------------------------< START >-----------------------*/ {
        !          2078: #if 0
        !          2079:        /*
        !          2080:        **      Claim to be still alive ...
        !          2081:        */
        !          2082:        SCR_COPY (sizeof (((struct ncb *)0)->heartbeat)),
        !          2083:                KVAR(SCRIPT_KVAR_JIFFIES),
        !          2084:                NADDR (heartbeat),
        !          2085: #endif
        !          2086:        /*
        !          2087:        **      Make data structure address invalid.
        !          2088:        **      clear SIGP.
        !          2089:        */
        !          2090:        SCR_LOAD_REG (dsa, 0xff),
        !          2091:                0,
        !          2092:        SCR_FROM_REG (ctest2),
        !          2093:                0,
        !          2094: }/*-------------------------< START0 >----------------------*/,{
        !          2095:        /*
        !          2096:        **      Hook for interrupted GetConditionCode.
        !          2097:        **      Will be patched to ... IFTRUE by
        !          2098:        **      the interrupt handler.
        !          2099:        */
        !          2100:        SCR_INT ^ IFFALSE (0),
        !          2101:                SIR_SENSE_RESTART,
        !          2102: 
        !          2103: }/*-------------------------< START1 >----------------------*/,{
        !          2104:        /*
        !          2105:        **      Hook for stalled start queue.
        !          2106:        **      Will be patched to IFTRUE by the interrupt handler.
        !          2107:        */
        !          2108:        SCR_INT ^ IFFALSE (0),
        !          2109:                SIR_STALL_RESTART,
        !          2110:        /*
        !          2111:        **      Then jump to a certain point in tryloop.
        !          2112:        **      Due to the lack of indirect addressing the code
        !          2113:        **      is self modifying here.
        !          2114:        */
        !          2115:        SCR_JUMP,
        !          2116: }/*-------------------------< STARTPOS >--------------------*/,{
        !          2117:                PADDRH(tryloop),
        !          2118: }/*-------------------------< TRYSEL >----------------------*/,{
        !          2119:        /*
        !          2120:        **      Now:
        !          2121:        **      DSA: Address of a Data Structure
        !          2122:        **      or   Address of the IDLE-Label.
        !          2123:        **
        !          2124:        **      TEMP:   Address of a script, which tries to
        !          2125:        **              start the NEXT entry.
        !          2126:        **
        !          2127:        **      Save the TEMP register into the SCRATCHA register.
        !          2128:        **      Then copy the DSA to TEMP and RETURN.
        !          2129:        **      This is kind of an indirect jump.
        !          2130:        **      (The script processor has NO stack, so the
        !          2131:        **      CALL is actually a jump and link, and the
        !          2132:        **      RETURN is an indirect jump.)
        !          2133:        **
        !          2134:        **      If the slot was empty, DSA contains the address
        !          2135:        **      of the IDLE part of this script. The processor
        !          2136:        **      jumps to IDLE and waits for a reselect.
        !          2137:        **      It will wake up and try the same slot again
        !          2138:        **      after the SIGP bit becomes set by the host.
        !          2139:        **
        !          2140:        **      If the slot was not empty, DSA contains
        !          2141:        **      the address of the phys-part of a ccb.
        !          2142:        **      The processor jumps to this address.
        !          2143:        **      phys starts with head,
        !          2144:        **      head starts with launch,
        !          2145:        **      so actually the processor jumps to
        !          2146:        **      the lauch part.
        !          2147:        **      If the entry is scheduled for execution,
        !          2148:        **      then launch contains a jump to SELECT.
        !          2149:        **      If it's not scheduled, it contains a jump to IDLE.
        !          2150:        */
        !          2151:        SCR_COPY (4),
        !          2152:                RADDR (temp),
        !          2153:                RADDR (scratcha),
        !          2154:        SCR_COPY (4),
        !          2155:                RADDR (dsa),
        !          2156:                RADDR (temp),
        !          2157:        SCR_RETURN,
        !          2158:                0
        !          2159: 
        !          2160: }/*-------------------------< SKIP >------------------------*/,{
        !          2161:        /*
        !          2162:        **      This entry has been canceled.
        !          2163:        **      Next time use the next slot.
        !          2164:        */
        !          2165:        SCR_COPY (4),
        !          2166:                RADDR (scratcha),
        !          2167:                PADDR (startpos),
        !          2168:        /*
        !          2169:        **      patch the launch field.
        !          2170:        **      should look like an idle process.
        !          2171:        */
        !          2172:        SCR_COPY_F (4),
        !          2173:                RADDR (dsa),
        !          2174:                PADDR (skip2),
        !          2175:        SCR_COPY (8),
        !          2176:                PADDR (idle),
        !          2177: }/*-------------------------< SKIP2 >-----------------------*/,{
        !          2178:                0,
        !          2179:        SCR_JUMP,
        !          2180:                PADDR(start),
        !          2181: }/*-------------------------< IDLE >------------------------*/,{
        !          2182:        /*
        !          2183:        **      Nothing to do?
        !          2184:        **      Wait for reselect.
        !          2185:        */
        !          2186:        SCR_JUMP,
        !          2187:                PADDR(reselect),
        !          2188: 
        !          2189: }/*-------------------------< SELECT >----------------------*/,{
        !          2190:        /*
        !          2191:        **      DSA     contains the address of a scheduled
        !          2192:        **              data structure.
        !          2193:        **
        !          2194:        **      SCRATCHA contains the address of the script,
        !          2195:        **              which starts the next entry.
        !          2196:        **
        !          2197:        **      Set Initiator mode.
        !          2198:        **
        !          2199:        **      (Target mode is left as an exercise for the reader)
        !          2200:        */
        !          2201: 
        !          2202:        SCR_CLR (SCR_TRG),
        !          2203:                0,
        !          2204:        SCR_LOAD_REG (HS_REG, 0xff),
        !          2205:                0,
        !          2206: 
        !          2207:        /*
        !          2208:        **      And try to select this target.
        !          2209:        */
        !          2210:        SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select),
        !          2211:                PADDR (reselect),
        !          2212: 
        !          2213:        /*
        !          2214:        **      Now there are 4 possibilities:
        !          2215:        **
        !          2216:        **      (1) The ncr looses arbitration.
        !          2217:        **      This is ok, because it will try again,
        !          2218:        **      when the bus becomes idle.
        !          2219:        **      (But beware of the timeout function!)
        !          2220:        **
        !          2221:        **      (2) The ncr is reselected.
        !          2222:        **      Then the script processor takes the jump
        !          2223:        **      to the RESELECT label.
        !          2224:        **
        !          2225:        **      (3) The ncr completes the selection.
        !          2226:        **      Then it will execute the next statement.
        !          2227:        **
        !          2228:        **      (4) There is a selection timeout.
        !          2229:        **      Then the ncr should interrupt the host and stop.
        !          2230:        **      Unfortunately, it seems to continue execution
        !          2231:        **      of the script. But it will fail with an
        !          2232:        **      IID-interrupt on the next WHEN.
        !          2233:        */
        !          2234: 
        !          2235:        SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_IN)),
        !          2236:                0,
        !          2237: 
        !          2238:        /*
        !          2239:        **      Save target id to ctest0 register
        !          2240:        */
        !          2241: 
        !          2242:        SCR_FROM_REG (sdid),
        !          2243:                0,
        !          2244:        SCR_TO_REG (ctest0),
        !          2245:                0,
        !          2246:        /*
        !          2247:        **      Send the IDENTIFY and SIMPLE_TAG messages
        !          2248:        **      (and the M_X_SYNC_REQ message)
        !          2249:        */
        !          2250:        SCR_MOVE_TBL ^ SCR_MSG_OUT,
        !          2251:                offsetof (struct dsb, smsg),
        !          2252: #ifdef undef /* XXX better fail than try to deal with this ... */
        !          2253:        SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_OUT)),
        !          2254:                -16,
        !          2255: #endif
        !          2256:        SCR_CLR (SCR_ATN),
        !          2257:                0,
        !          2258:        SCR_COPY (1),
        !          2259:                RADDR (sfbr),
        !          2260:                NADDR (lastmsg),
        !          2261:        /*
        !          2262:        **      Selection complete.
        !          2263:        **      Next time use the next slot.
        !          2264:        */
        !          2265:        SCR_COPY (4),
        !          2266:                RADDR (scratcha),
        !          2267:                PADDR (startpos),
        !          2268: }/*-------------------------< PREPARE >----------------------*/,{
        !          2269:        /*
        !          2270:        **      The ncr doesn't have an indirect load
        !          2271:        **      or store command. So we have to
        !          2272:        **      copy part of the control block to a
        !          2273:        **      fixed place, where we can access it.
        !          2274:        **
        !          2275:        **      We patch the address part of a
        !          2276:        **      COPY command with the DSA-register.
        !          2277:        */
        !          2278:        SCR_COPY_F (4),
        !          2279:                RADDR (dsa),
        !          2280:                PADDR (loadpos),
        !          2281:        /*
        !          2282:        **      then we do the actual copy.
        !          2283:        */
        !          2284:        SCR_COPY (sizeof (struct head)),
        !          2285:        /*
        !          2286:        **      continued after the next label ...
        !          2287:        */
        !          2288: 
        !          2289: }/*-------------------------< LOADPOS >---------------------*/,{
        !          2290:                0,
        !          2291:                NADDR (header),
        !          2292:        /*
        !          2293:        **      Mark this ccb as not scheduled.
        !          2294:        */
        !          2295:        SCR_COPY (8),
        !          2296:                PADDR (idle),
        !          2297:                NADDR (header.launch),
        !          2298:        /*
        !          2299:        **      Set a time stamp for this selection
        !          2300:        */
        !          2301:        SCR_COPY (sizeof (u_long)),
        !          2302:                KVAR(SCRIPT_KVAR_JIFFIES),
        !          2303:                NADDR (header.stamp.select),
        !          2304:        /*
        !          2305:        **      load the savep (saved pointer) into
        !          2306:        **      the TEMP register (actual pointer)
        !          2307:        */
        !          2308:        SCR_COPY (4),
        !          2309:                NADDR (header.savep),
        !          2310:                RADDR (temp),
        !          2311:        /*
        !          2312:        **      Initialize the status registers
        !          2313:        */
        !          2314:        SCR_COPY (4),
        !          2315:                NADDR (header.status),
        !          2316:                RADDR (scr0),
        !          2317: 
        !          2318: }/*-------------------------< PREPARE2 >---------------------*/,{
        !          2319:        /*
        !          2320:        **      Load the synchronous mode register
        !          2321:        */
        !          2322:        SCR_COPY (1),
        !          2323:                NADDR (sync_st),
        !          2324:                RADDR (sxfer),
        !          2325:        /*
        !          2326:        **      Load the wide mode and timing register
        !          2327:        */
        !          2328:        SCR_COPY (1),
        !          2329:                NADDR (wide_st),
        !          2330:                RADDR (scntl3),
        !          2331:        /*
        !          2332:        **      Initialize the msgout buffer with a NOOP message.
        !          2333:        */
        !          2334:        SCR_LOAD_REG (scratcha, M_NOOP),
        !          2335:                0,
        !          2336:        SCR_COPY (1),
        !          2337:                RADDR (scratcha),
        !          2338:                NADDR (msgout),
        !          2339:        SCR_COPY (1),
        !          2340:                RADDR (scratcha),
        !          2341:                NADDR (msgin),
        !          2342:        /*
        !          2343:        **      Message in phase ?
        !          2344:        */
        !          2345:        SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
        !          2346:                PADDR (dispatch),
        !          2347:        /*
        !          2348:        **      Extended or reject message ?
        !          2349:        */
        !          2350:        SCR_FROM_REG (sbdl),
        !          2351:                0,
        !          2352:        SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)),
        !          2353:                PADDR (msg_in),
        !          2354:        SCR_JUMP ^ IFTRUE (DATA (M_REJECT)),
        !          2355:                PADDRH (msg_reject),
        !          2356:        /*
        !          2357:        **      normal processing
        !          2358:        */
        !          2359:        SCR_JUMP,
        !          2360:                PADDR (dispatch),
        !          2361: }/*-------------------------< SETMSG >----------------------*/,{
        !          2362:        SCR_COPY (1),
        !          2363:                RADDR (scratcha),
        !          2364:                NADDR (msgout),
        !          2365:        SCR_SET (SCR_ATN),
        !          2366:                0,
        !          2367: }/*-------------------------< CLRACK >----------------------*/,{
        !          2368:        /*
        !          2369:        **      Terminate possible pending message phase.
        !          2370:        */
        !          2371:        SCR_CLR (SCR_ACK),
        !          2372:                0,
        !          2373: 
        !          2374: }/*-----------------------< DISPATCH >----------------------*/,{
        !          2375:        SCR_FROM_REG (HS_REG),
        !          2376:                0,
        !          2377:        SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)),
        !          2378:                SIR_NEGO_FAILED,
        !          2379:        /*
        !          2380:        **      remove bogus output signals
        !          2381:        */
        !          2382:        SCR_REG_REG (socl, SCR_AND, CACK|CATN),
        !          2383:                0,
        !          2384:        SCR_RETURN ^ IFTRUE (WHEN (SCR_DATA_OUT)),
        !          2385:                0,
        !          2386:        /*
        !          2387:        **      DEL 397 - 53C875 Rev 3 - Part Number 609-0392410 - ITEM 4.
        !          2388:        **      Possible data corruption during Memory Write and Invalidate.
        !          2389:        **      This work-around resets the addressing logic prior to the 
        !          2390:        **      start of the first MOVE of a DATA IN phase.
        !          2391:        **      (See README.ncr53c8xx for more information)
        !          2392:        */
        !          2393:        SCR_JUMPR ^ IFFALSE (IF (SCR_DATA_IN)),
        !          2394:                20,
        !          2395:        SCR_COPY (4),
        !          2396:                RADDR (scratcha),
        !          2397:                RADDR (scratcha),
        !          2398:        SCR_RETURN,
        !          2399:                0,
        !          2400: 
        !          2401:        SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)),
        !          2402:                PADDR (msg_out),
        !          2403:        SCR_JUMP ^ IFTRUE (IF (SCR_MSG_IN)),
        !          2404:                PADDR (msg_in),
        !          2405:        SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)),
        !          2406:                PADDR (command),
        !          2407:        SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)),
        !          2408:                PADDR (status),
        !          2409:        /*
        !          2410:        **      Discard one illegal phase byte, if required.
        !          2411:        */
        !          2412:        SCR_LOAD_REG (scratcha, XE_BAD_PHASE),
        !          2413:                0,
        !          2414:        SCR_COPY (1),
        !          2415:                RADDR (scratcha),
        !          2416:                NADDR (xerr_st),
        !          2417:        SCR_JUMPR ^ IFFALSE (IF (SCR_ILG_OUT)),
        !          2418:                8,
        !          2419:        SCR_MOVE_ABS (1) ^ SCR_ILG_OUT,
        !          2420:                NADDR (scratch),
        !          2421:        SCR_JUMPR ^ IFFALSE (IF (SCR_ILG_IN)),
        !          2422:                8,
        !          2423:        SCR_MOVE_ABS (1) ^ SCR_ILG_IN,
        !          2424:                NADDR (scratch),
        !          2425:        SCR_JUMP,
        !          2426:                PADDR (dispatch),
        !          2427: 
        !          2428: }/*-------------------------< NO_DATA >--------------------*/,{
        !          2429:        /*
        !          2430:        **      The target wants to tranfer too much data
        !          2431:        **      or in the wrong direction.
        !          2432:        **      Remember that in extended error.
        !          2433:        */
        !          2434:        SCR_LOAD_REG (scratcha, XE_EXTRA_DATA),
        !          2435:                0,
        !          2436:        SCR_COPY (1),
        !          2437:                RADDR (scratcha),
        !          2438:                NADDR (xerr_st),
        !          2439:        /*
        !          2440:        **      Discard one data byte, if required.
        !          2441:        */
        !          2442:        SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_OUT)),
        !          2443:                8,
        !          2444:        SCR_MOVE_ABS (1) ^ SCR_DATA_OUT,
        !          2445:                NADDR (scratch),
        !          2446:        SCR_JUMPR ^ IFFALSE (IF (SCR_DATA_IN)),
        !          2447:                8,
        !          2448:        SCR_MOVE_ABS (1) ^ SCR_DATA_IN,
        !          2449:                NADDR (scratch),
        !          2450:        /*
        !          2451:        **      .. and repeat as required.
        !          2452:        */
        !          2453:        SCR_CALL,
        !          2454:                PADDR (dispatch),
        !          2455:        SCR_JUMP,
        !          2456:                PADDR (no_data),
        !          2457: }/*-------------------------< CHECKATN >--------------------*/,{
        !          2458:        /*
        !          2459:        **      If AAP (bit 1 of scntl0 register) is set
        !          2460:        **      and a parity error is detected,
        !          2461:        **      the script processor asserts ATN.
        !          2462:        **
        !          2463:        **      The target should switch to a MSG_OUT phase
        !          2464:        **      to get the message.
        !          2465:        */
        !          2466:        SCR_FROM_REG (socl),
        !          2467:                0,
        !          2468:        SCR_JUMP ^ IFFALSE (MASK (CATN, CATN)),
        !          2469:                PADDR (dispatch),
        !          2470:        /*
        !          2471:        **      count it
        !          2472:        */
        !          2473:        SCR_REG_REG (PS_REG, SCR_ADD, 1),
        !          2474:                0,
        !          2475:        /*
        !          2476:        **      Prepare a M_ID_ERROR message
        !          2477:        **      (initiator detected error).
        !          2478:        **      The target should retry the transfer.
        !          2479:        */
        !          2480:        SCR_LOAD_REG (scratcha, M_ID_ERROR),
        !          2481:                0,
        !          2482:        SCR_JUMP,
        !          2483:                PADDR (setmsg),
        !          2484: 
        !          2485: }/*-------------------------< COMMAND >--------------------*/,{
        !          2486:        /*
        !          2487:        **      If this is not a GETCC transfer ...
        !          2488:        */
        !          2489:        SCR_FROM_REG (SS_REG),
        !          2490:                0,
        !          2491: /*<<<*/        SCR_JUMPR ^ IFTRUE (DATA (S_CHECK_COND)),
        !          2492:                28,
        !          2493:        /*
        !          2494:        **      ... set a timestamp ...
        !          2495:        */
        !          2496:        SCR_COPY (sizeof (u_long)),
        !          2497:                KVAR(SCRIPT_KVAR_JIFFIES),
        !          2498:                NADDR (header.stamp.command),
        !          2499:        /*
        !          2500:        **      ... and send the command
        !          2501:        */
        !          2502:        SCR_MOVE_TBL ^ SCR_COMMAND,
        !          2503:                offsetof (struct dsb, cmd),
        !          2504:        SCR_JUMP,
        !          2505:                PADDR (dispatch),
        !          2506:        /*
        !          2507:        **      Send the GETCC command
        !          2508:        */
        !          2509: /*>>>*/        SCR_MOVE_TBL ^ SCR_COMMAND,
        !          2510:                offsetof (struct dsb, scmd),
        !          2511:        SCR_JUMP,
        !          2512:                PADDR (dispatch),
        !          2513: 
        !          2514: }/*-------------------------< STATUS >--------------------*/,{
        !          2515:        /*
        !          2516:        **      set the timestamp.
        !          2517:        */
        !          2518:        SCR_COPY (sizeof (u_long)),
        !          2519:                KVAR(SCRIPT_KVAR_JIFFIES),
        !          2520:                NADDR (header.stamp.status),
        !          2521:        /*
        !          2522:        **      If this is a GETCC transfer,
        !          2523:        */
        !          2524:        SCR_FROM_REG (SS_REG),
        !          2525:                0,
        !          2526: /*<<<*/        SCR_JUMPR ^ IFFALSE (DATA (S_CHECK_COND)),
        !          2527:                40,
        !          2528:        /*
        !          2529:        **      get the status
        !          2530:        */
        !          2531:        SCR_MOVE_ABS (1) ^ SCR_STATUS,
        !          2532:                NADDR (scratch),
        !          2533:        /*
        !          2534:        **      Save status to scsi_status.
        !          2535:        **      Mark as complete.
        !          2536:        **      And wait for disconnect.
        !          2537:        */
        !          2538:        SCR_TO_REG (SS_REG),
        !          2539:                0,
        !          2540:        SCR_REG_REG (SS_REG, SCR_OR, S_SENSE),
        !          2541:                0,
        !          2542:        SCR_LOAD_REG (HS_REG, HS_COMPLETE),
        !          2543:                0,
        !          2544:        SCR_JUMP,
        !          2545:                PADDR (checkatn),
        !          2546:        /*
        !          2547:        **      If it was no GETCC transfer,
        !          2548:        **      save the status to scsi_status.
        !          2549:        */
        !          2550: /*>>>*/        SCR_MOVE_ABS (1) ^ SCR_STATUS,
        !          2551:                NADDR (scratch),
        !          2552:        SCR_TO_REG (SS_REG),
        !          2553:                0,
        !          2554:        /*
        !          2555:        **      if it was no check condition ...
        !          2556:        */
        !          2557:        SCR_JUMP ^ IFTRUE (DATA (S_CHECK_COND)),
        !          2558:                PADDR (checkatn),
        !          2559:        /*
        !          2560:        **      ... mark as complete.
        !          2561:        */
        !          2562:        SCR_LOAD_REG (HS_REG, HS_COMPLETE),
        !          2563:                0,
        !          2564:        SCR_JUMP,
        !          2565:                PADDR (checkatn),
        !          2566: 
        !          2567: }/*-------------------------< MSG_IN >--------------------*/,{
        !          2568:        /*
        !          2569:        **      Get the first byte of the message
        !          2570:        **      and save it to SCRATCHA.
        !          2571:        **
        !          2572:        **      The script processor doesn't negate the
        !          2573:        **      ACK signal after this transfer.
        !          2574:        */
        !          2575:        SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
        !          2576:                NADDR (msgin[0]),
        !          2577:        /*
        !          2578:        **      Check for message parity error.
        !          2579:        */
        !          2580:        SCR_TO_REG (scratcha),
        !          2581:                0,
        !          2582:        SCR_FROM_REG (socl),
        !          2583:                0,
        !          2584:        SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
        !          2585:                PADDRH (msg_parity),
        !          2586:        SCR_FROM_REG (scratcha),
        !          2587:                0,
        !          2588:        /*
        !          2589:        **      Parity was ok, handle this message.
        !          2590:        */
        !          2591:        SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)),
        !          2592:                PADDR (complete),
        !          2593:        SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)),
        !          2594:                PADDR (save_dp),
        !          2595:        SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)),
        !          2596:                PADDR (restore_dp),
        !          2597:        SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)),
        !          2598:                PADDR (disconnect),
        !          2599:        SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)),
        !          2600:                PADDRH (msg_extended),
        !          2601:        SCR_JUMP ^ IFTRUE (DATA (M_NOOP)),
        !          2602:                PADDR (clrack),
        !          2603:        SCR_JUMP ^ IFTRUE (DATA (M_REJECT)),
        !          2604:                PADDRH (msg_reject),
        !          2605:        SCR_JUMP ^ IFTRUE (DATA (M_IGN_RESIDUE)),
        !          2606:                PADDRH (msg_ign_residue),
        !          2607:        /*
        !          2608:        **      Rest of the messages left as
        !          2609:        **      an exercise ...
        !          2610:        **
        !          2611:        **      Unimplemented messages:
        !          2612:        **      fall through to MSG_BAD.
        !          2613:        */
        !          2614: }/*-------------------------< MSG_BAD >------------------*/,{
        !          2615:        /*
        !          2616:        **      unimplemented message - reject it.
        !          2617:        */
        !          2618:        SCR_INT,
        !          2619:                SIR_REJECT_SENT,
        !          2620:        SCR_LOAD_REG (scratcha, M_REJECT),
        !          2621:                0,
        !          2622:        SCR_JUMP,
        !          2623:                PADDR (setmsg),
        !          2624: 
        !          2625: }/*-------------------------< COMPLETE >-----------------*/,{
        !          2626:        /*
        !          2627:        **      Complete message.
        !          2628:        **
        !          2629:        **      If it's not the get condition code,
        !          2630:        **      copy TEMP register to LASTP in header.
        !          2631:        */
        !          2632:        SCR_FROM_REG (SS_REG),
        !          2633:                0,
        !          2634: /*<<<*/        SCR_JUMPR ^ IFTRUE (MASK (S_SENSE, S_SENSE)),
        !          2635:                12,
        !          2636:        SCR_COPY (4),
        !          2637:                RADDR (temp),
        !          2638:                NADDR (header.lastp),
        !          2639: /*>>>*/        /*
        !          2640:        **      When we terminate the cycle by clearing ACK,
        !          2641:        **      the target may disconnect immediately.
        !          2642:        **
        !          2643:        **      We don't want to be told of an
        !          2644:        **      "unexpected disconnect",
        !          2645:        **      so we disable this feature.
        !          2646:        */
        !          2647:        SCR_REG_REG (scntl2, SCR_AND, 0x7f),
        !          2648:                0,
        !          2649:        /*
        !          2650:        **      Terminate cycle ...
        !          2651:        */
        !          2652:        SCR_CLR (SCR_ACK|SCR_ATN),
        !          2653:                0,
        !          2654:        /*
        !          2655:        **      ... and wait for the disconnect.
        !          2656:        */
        !          2657:        SCR_WAIT_DISC,
        !          2658:                0,
        !          2659: }/*-------------------------< CLEANUP >-------------------*/,{
        !          2660:        /*
        !          2661:        **      dsa:    Pointer to ccb
        !          2662:        **            or xxxxxxFF (no ccb)
        !          2663:        **
        !          2664:        **      HS_REG:   Host-Status (<>0!)
        !          2665:        */
        !          2666:        SCR_FROM_REG (dsa),
        !          2667:                0,
        !          2668:        SCR_JUMP ^ IFTRUE (DATA (0xff)),
        !          2669:                PADDR (signal),
        !          2670:        /*
        !          2671:        **      dsa is valid.
        !          2672:        **      save the status registers
        !          2673:        */
        !          2674:        SCR_COPY (4),
        !          2675:                RADDR (scr0),
        !          2676:                NADDR (header.status),
        !          2677:        /*
        !          2678:        **      and copy back the header to the ccb.
        !          2679:        */
        !          2680:        SCR_COPY_F (4),
        !          2681:                RADDR (dsa),
        !          2682:                PADDR (cleanup0),
        !          2683:        SCR_COPY (sizeof (struct head)),
        !          2684:                NADDR (header),
        !          2685: }/*-------------------------< CLEANUP0 >--------------------*/,{
        !          2686:                0,
        !          2687: 
        !          2688:        /*
        !          2689:        **      If command resulted in "check condition"
        !          2690:        **      status and is not yet completed,
        !          2691:        **      try to get the condition code.
        !          2692:        */
        !          2693:        SCR_FROM_REG (HS_REG),
        !          2694:                0,
        !          2695: /*<<<*/        SCR_JUMPR ^ IFFALSE (MASK (0, HS_DONEMASK)),
        !          2696:                16,
        !          2697:        SCR_FROM_REG (SS_REG),
        !          2698:                0,
        !          2699:        SCR_JUMP ^ IFTRUE (DATA (S_CHECK_COND)),
        !          2700:                PADDRH(getcc2),
        !          2701:        /*
        !          2702:        **      And make the DSA register invalid.
        !          2703:        */
        !          2704: /*>>>*/        SCR_LOAD_REG (dsa, 0xff), /* invalid */
        !          2705:                0,
        !          2706: }/*-------------------------< SIGNAL >----------------------*/,{
        !          2707:        /*
        !          2708:        **      if status = queue full,
        !          2709:        **      reinsert in startqueue and stall queue.
        !          2710:        */
        !          2711:        SCR_FROM_REG (SS_REG),
        !          2712:                0,
        !          2713:        SCR_INT ^ IFTRUE (DATA (S_QUEUE_FULL)),
        !          2714:                SIR_STALL_QUEUE,
        !          2715:        /*
        !          2716:        **      if job completed ...
        !          2717:        */
        !          2718:        SCR_FROM_REG (HS_REG),
        !          2719:                0,
        !          2720:        /*
        !          2721:        **      ... signal completion to the host
        !          2722:        */
        !          2723:        SCR_INT_FLY ^ IFFALSE (MASK (0, HS_DONEMASK)),
        !          2724:                0,
        !          2725:        /*
        !          2726:        **      Auf zu neuen Schandtaten!
        !          2727:        */
        !          2728:        SCR_JUMP,
        !          2729:                PADDR(start),
        !          2730: 
        !          2731: }/*-------------------------< SAVE_DP >------------------*/,{
        !          2732:        /*
        !          2733:        **      SAVE_DP message:
        !          2734:        **      Copy TEMP register to SAVEP in header.
        !          2735:        */
        !          2736:        SCR_COPY (4),
        !          2737:                RADDR (temp),
        !          2738:                NADDR (header.savep),
        !          2739:        SCR_JUMP,
        !          2740:                PADDR (clrack),
        !          2741: }/*-------------------------< RESTORE_DP >---------------*/,{
        !          2742:        /*
        !          2743:        **      RESTORE_DP message:
        !          2744:        **      Copy SAVEP in header to TEMP register.
        !          2745:        */
        !          2746:        SCR_COPY (4),
        !          2747:                NADDR (header.savep),
        !          2748:                RADDR (temp),
        !          2749:        SCR_JUMP,
        !          2750:                PADDR (clrack),
        !          2751: 
        !          2752: }/*-------------------------< DISCONNECT >---------------*/,{
        !          2753:        /*
        !          2754:        **      If QUIRK_AUTOSAVE is set,
        !          2755:        **      do an "save pointer" operation.
        !          2756:        */
        !          2757:        SCR_FROM_REG (QU_REG),
        !          2758:                0,
        !          2759: /*<<<*/        SCR_JUMPR ^ IFFALSE (MASK (QUIRK_AUTOSAVE, QUIRK_AUTOSAVE)),
        !          2760:                12,
        !          2761:        /*
        !          2762:        **      like SAVE_DP message:
        !          2763:        **      Copy TEMP register to SAVEP in header.
        !          2764:        */
        !          2765:        SCR_COPY (4),
        !          2766:                RADDR (temp),
        !          2767:                NADDR (header.savep),
        !          2768: /*>>>*/        /*
        !          2769:        **      Check if temp==savep or temp==goalp:
        !          2770:        **      if not, log a missing save pointer message.
        !          2771:        **      In fact, it's a comparison mod 256.
        !          2772:        **
        !          2773:        **      Hmmm, I hadn't thought that I would be urged to
        !          2774:        **      write this kind of ugly self modifying code.
        !          2775:        **
        !          2776:        **      It's unbelievable, but the ncr53c8xx isn't able
        !          2777:        **      to subtract one register from another.
        !          2778:        */
        !          2779:        SCR_FROM_REG (temp),
        !          2780:                0,
        !          2781:        /*
        !          2782:        **      You are not expected to understand this ..
        !          2783:        **
        !          2784:        **      CAUTION: only little endian architectures supported! XXX
        !          2785:        */
        !          2786:        SCR_COPY_F (1),
        !          2787:                NADDR (header.savep),
        !          2788:                PADDR (disconnect0),
        !          2789: }/*-------------------------< DISCONNECT0 >--------------*/,{
        !          2790: /*<<<*/        SCR_JUMPR ^ IFTRUE (DATA (1)),
        !          2791:                20,
        !          2792:        /*
        !          2793:        **      neither this
        !          2794:        */
        !          2795:        SCR_COPY_F (1),
        !          2796:                NADDR (header.goalp),
        !          2797:                PADDR (disconnect1),
        !          2798: }/*-------------------------< DISCONNECT1 >--------------*/,{
        !          2799:        SCR_INT ^ IFFALSE (DATA (1)),
        !          2800:                SIR_MISSING_SAVE,
        !          2801: /*>>>*/
        !          2802: 
        !          2803:        /*
        !          2804:        **      DISCONNECTing  ...
        !          2805:        **
        !          2806:        **      disable the "unexpected disconnect" feature,
        !          2807:        **      and remove the ACK signal.
        !          2808:        */
        !          2809:        SCR_REG_REG (scntl2, SCR_AND, 0x7f),
        !          2810:                0,
        !          2811:        SCR_CLR (SCR_ACK|SCR_ATN),
        !          2812:                0,
        !          2813:        /*
        !          2814:        **      Wait for the disconnect.
        !          2815:        */
        !          2816:        SCR_WAIT_DISC,
        !          2817:                0,
        !          2818:        /*
        !          2819:        **      Profiling:
        !          2820:        **      Set a time stamp,
        !          2821:        **      and count the disconnects.
        !          2822:        */
        !          2823:        SCR_COPY (sizeof (u_long)),
        !          2824:                KVAR(SCRIPT_KVAR_JIFFIES),
        !          2825:                NADDR (header.stamp.disconnect),
        !          2826:        SCR_COPY (4),
        !          2827:                NADDR (disc_phys),
        !          2828:                RADDR (temp),
        !          2829:        SCR_REG_REG (temp, SCR_ADD, 0x01),
        !          2830:                0,
        !          2831:        SCR_COPY (4),
        !          2832:                RADDR (temp),
        !          2833:                NADDR (disc_phys),
        !          2834:        /*
        !          2835:        **      Status is: DISCONNECTED.
        !          2836:        */
        !          2837:        SCR_LOAD_REG (HS_REG, HS_DISCONNECT),
        !          2838:                0,
        !          2839:        SCR_JUMP,
        !          2840:                PADDR (cleanup),
        !          2841: 
        !          2842: }/*-------------------------< MSG_OUT >-------------------*/,{
        !          2843:        /*
        !          2844:        **      The target requests a message.
        !          2845:        */
        !          2846:        SCR_MOVE_ABS (1) ^ SCR_MSG_OUT,
        !          2847:                NADDR (msgout),
        !          2848:        SCR_COPY (1),
        !          2849:                RADDR (sfbr),
        !          2850:                NADDR (lastmsg),
        !          2851:        /*
        !          2852:        **      If it was no ABORT message ...
        !          2853:        */
        !          2854:        SCR_JUMP ^ IFTRUE (DATA (M_ABORT)),
        !          2855:                PADDRH (msg_out_abort),
        !          2856:        /*
        !          2857:        **      ... wait for the next phase
        !          2858:        **      if it's a message out, send it again, ...
        !          2859:        */
        !          2860:        SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)),
        !          2861:                PADDR (msg_out),
        !          2862: }/*-------------------------< MSG_OUT_DONE >--------------*/,{
        !          2863:        /*
        !          2864:        **      ... else clear the message ...
        !          2865:        */
        !          2866:        SCR_LOAD_REG (scratcha, M_NOOP),
        !          2867:                0,
        !          2868:        SCR_COPY (4),
        !          2869:                RADDR (scratcha),
        !          2870:                NADDR (msgout),
        !          2871:        /*
        !          2872:        **      ... and process the next phase
        !          2873:        */
        !          2874:        SCR_JUMP,
        !          2875:                PADDR (dispatch),
        !          2876: }/*------------------------< BADGETCC >---------------------*/,{
        !          2877:        /*
        !          2878:        **      If SIGP was set, clear it and try again.
        !          2879:        */
        !          2880:        SCR_FROM_REG (ctest2),
        !          2881:                0,
        !          2882:        SCR_JUMP ^ IFTRUE (MASK (CSIGP,CSIGP)),
        !          2883:                PADDRH (getcc2),
        !          2884:        SCR_INT,
        !          2885:                SIR_SENSE_FAILED,
        !          2886: }/*-------------------------< RESELECT >--------------------*/,{
        !          2887:        /*
        !          2888:        **      This NOP will be patched with LED OFF
        !          2889:        **      SCR_REG_REG (gpreg, SCR_OR, 0x01)
        !          2890:        */
        !          2891:        SCR_NO_OP,
        !          2892:                0,
        !          2893:        /*
        !          2894:        **      make the DSA invalid.
        !          2895:        */
        !          2896:        SCR_LOAD_REG (dsa, 0xff),
        !          2897:                0,
        !          2898:        SCR_CLR (SCR_TRG),
        !          2899:                0,
        !          2900:        /*
        !          2901:        **      Sleep waiting for a reselection.
        !          2902:        **      If SIGP is set, special treatment.
        !          2903:        **
        !          2904:        **      Zu allem bereit ..
        !          2905:        */
        !          2906:        SCR_WAIT_RESEL,
        !          2907:                PADDR(reselect2),
        !          2908: }/*-------------------------< RESELECT1 >--------------------*/,{
        !          2909:        /*
        !          2910:        **      This NOP will be patched with LED ON
        !          2911:        **      SCR_REG_REG (gpreg, SCR_AND, 0xfe)
        !          2912:        */
        !          2913:        SCR_NO_OP,
        !          2914:                0,
        !          2915:        /*
        !          2916:        **      ... zu nichts zu gebrauchen ?
        !          2917:        **
        !          2918:        **      load the target id into the SFBR
        !          2919:        **      and jump to the control block.
        !          2920:        **
        !          2921:        **      Look at the declarations of
        !          2922:        **      - struct ncb
        !          2923:        **      - struct tcb
        !          2924:        **      - struct lcb
        !          2925:        **      - struct ccb
        !          2926:        **      to understand what's going on.
        !          2927:        */
        !          2928:        SCR_REG_SFBR (ssid, SCR_AND, 0x8F),
        !          2929:                0,
        !          2930:        SCR_TO_REG (ctest0),
        !          2931:                0,
        !          2932:        SCR_JUMP,
        !          2933:                NADDR (jump_tcb),
        !          2934: }/*-------------------------< RESELECT2 >-------------------*/,{
        !          2935:        /*
        !          2936:        **      This NOP will be patched with LED ON
        !          2937:        **      SCR_REG_REG (gpreg, SCR_AND, 0xfe)
        !          2938:        */
        !          2939:        SCR_NO_OP,
        !          2940:                0,
        !          2941:        /*
        !          2942:        **      If it's not connected :(
        !          2943:        **      -> interrupted by SIGP bit.
        !          2944:        **      Jump to start.
        !          2945:        */
        !          2946:        SCR_FROM_REG (ctest2),
        !          2947:                0,
        !          2948:        SCR_JUMP ^ IFTRUE (MASK (CSIGP,CSIGP)),
        !          2949:                PADDR (start),
        !          2950:        SCR_JUMP,
        !          2951:                PADDR (reselect),
        !          2952: 
        !          2953: }/*-------------------------< RESEL_TMP >-------------------*/,{
        !          2954:        /*
        !          2955:        **      The return address in TEMP
        !          2956:        **      is in fact the data structure address,
        !          2957:        **      so copy it to the DSA register.
        !          2958:        */
        !          2959:        SCR_COPY (4),
        !          2960:                RADDR (temp),
        !          2961:                RADDR (dsa),
        !          2962:        SCR_JUMP,
        !          2963:                PADDR (prepare),
        !          2964: 
        !          2965: }/*-------------------------< RESEL_LUN >-------------------*/,{
        !          2966:        /*
        !          2967:        **      come back to this point
        !          2968:        **      to get an IDENTIFY message
        !          2969:        **      Wait for a msg_in phase.
        !          2970:        */
        !          2971: /*<<<*/        SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)),
        !          2972:                48,
        !          2973:        /*
        !          2974:        **      message phase
        !          2975:        **      It's not a sony, it's a trick:
        !          2976:        **      read the data without acknowledging it.
        !          2977:        */
        !          2978:        SCR_FROM_REG (sbdl),
        !          2979:                0,
        !          2980: /*<<<*/        SCR_JUMPR ^ IFFALSE (MASK (M_IDENTIFY, 0x98)),
        !          2981:                32,
        !          2982:        /*
        !          2983:        **      It WAS an Identify message.
        !          2984:        **      get it and ack it!
        !          2985:        */
        !          2986:        SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
        !          2987:                NADDR (msgin),
        !          2988:        SCR_CLR (SCR_ACK),
        !          2989:                0,
        !          2990:        /*
        !          2991:        **      Mask out the lun.
        !          2992:        */
        !          2993:        SCR_REG_REG (sfbr, SCR_AND, 0x07),
        !          2994:                0,
        !          2995:        SCR_RETURN,
        !          2996:                0,
        !          2997:        /*
        !          2998:        **      No message phase or no IDENTIFY message:
        !          2999:        **      return 0.
        !          3000:        */
        !          3001: /*>>>*/        SCR_LOAD_SFBR (0),
        !          3002:                0,
        !          3003:        SCR_RETURN,
        !          3004:                0,
        !          3005: 
        !          3006: }/*-------------------------< RESEL_TAG >-------------------*/,{
        !          3007:        /*
        !          3008:        **      come back to this point
        !          3009:        **      to get a SIMPLE_TAG message
        !          3010:        **      Wait for a MSG_IN phase.
        !          3011:        */
        !          3012: /*<<<*/        SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)),
        !          3013:                64,
        !          3014:        /*
        !          3015:        **      message phase
        !          3016:        **      It's a trick - read the data
        !          3017:        **      without acknowledging it.
        !          3018:        */
        !          3019:        SCR_FROM_REG (sbdl),
        !          3020:                0,
        !          3021: /*<<<*/        SCR_JUMPR ^ IFFALSE (DATA (M_SIMPLE_TAG)),
        !          3022:                48,
        !          3023:        /*
        !          3024:        **      It WAS a SIMPLE_TAG message.
        !          3025:        **      get it and ack it!
        !          3026:        */
        !          3027:        SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
        !          3028:                NADDR (msgin),
        !          3029:        SCR_CLR (SCR_ACK),
        !          3030:                0,
        !          3031:        /*
        !          3032:        **      Wait for the second byte (the tag)
        !          3033:        */
        !          3034: /*<<<*/        SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)),
        !          3035:                24,
        !          3036:        /*
        !          3037:        **      Get it and ack it!
        !          3038:        */
        !          3039:        SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
        !          3040:                NADDR (msgin),
        !          3041:        SCR_CLR (SCR_ACK|SCR_CARRY),
        !          3042:                0,
        !          3043:        SCR_RETURN,
        !          3044:                0,
        !          3045:        /*
        !          3046:        **      No message phase or no SIMPLE_TAG message
        !          3047:        **      or no second byte: return 0.
        !          3048:        */
        !          3049: /*>>>*/        SCR_LOAD_SFBR (0),
        !          3050:                0,
        !          3051:        SCR_SET (SCR_CARRY),
        !          3052:                0,
        !          3053:        SCR_RETURN,
        !          3054:                0,
        !          3055: 
        !          3056: }/*-------------------------< DATA_IO >--------------------*/,{
        !          3057: /*
        !          3058: **     Because Linux does not provide xfer data direction 
        !          3059: **     to low-level scsi drivers, we must trust the target 
        !          3060: **     for actual data direction when we cannot guess it.
        !          3061: **     The programmed interrupt patches savep, lastp, goalp,
        !          3062: **     etc.., and restarts the scsi script at data_out/in.
        !          3063: */
        !          3064:        SCR_INT ^ IFTRUE (WHEN (SCR_DATA_OUT)),
        !          3065:                SIR_DATA_IO_IS_OUT,
        !          3066:        SCR_INT ^ IFTRUE (WHEN (SCR_DATA_IN)),
        !          3067:                SIR_DATA_IO_IS_IN,
        !          3068:        SCR_JUMP,
        !          3069:                PADDR (no_data),
        !          3070: 
        !          3071: }/*-------------------------< DATA_IN >--------------------*/,{
        !          3072: /*
        !          3073: **     Because the size depends on the
        !          3074: **     #define MAX_SCATTER parameter,
        !          3075: **     it is filled in at runtime.
        !          3076: **
        !          3077: **  ##===========< i=0; i<MAX_SCATTER >=========
        !          3078: **  || SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_IN)),
        !          3079: **  ||         PADDR (checkatn),
        !          3080: **  || SCR_MOVE_TBL ^ SCR_DATA_IN,
        !          3081: **  ||         offsetof (struct dsb, data[ i]),
        !          3082: **  ##==========================================
        !          3083: **
        !          3084: **     SCR_CALL,
        !          3085: **             PADDR (checkatn),
        !          3086: **     SCR_JUMP,
        !          3087: **             PADDR (no_data),
        !          3088: */
        !          3089: 0
        !          3090: }/*--------------------------------------------------------*/
        !          3091: };
        !          3092: 
        !          3093: static struct scripth scripth0 __initdata = {
        !          3094: /*-------------------------< TRYLOOP >---------------------*/{
        !          3095: /*
        !          3096: **     Load an entry of the start queue into dsa
        !          3097: **     and try to start it by jumping to TRYSEL.
        !          3098: **
        !          3099: **     Because the size depends on the
        !          3100: **     #define MAX_START parameter, it is filled
        !          3101: **     in at runtime.
        !          3102: **
        !          3103: **-----------------------------------------------------------
        !          3104: **
        !          3105: **  ##===========< I=0; i<MAX_START >===========
        !          3106: **  || SCR_COPY (4),
        !          3107: **  ||         NADDR (squeue[i]),
        !          3108: **  ||         RADDR (dsa),
        !          3109: **  || SCR_CALL,
        !          3110: **  ||         PADDR (trysel),
        !          3111: **  ##==========================================
        !          3112: **
        !          3113: **     SCR_JUMP,
        !          3114: **             PADDRH(tryloop),
        !          3115: **
        !          3116: **-----------------------------------------------------------
        !          3117: */
        !          3118: 0
        !          3119: },/*-------------------------< MSG_PARITY >---------------*/{
        !          3120:        /*
        !          3121:        **      count it
        !          3122:        */
        !          3123:        SCR_REG_REG (PS_REG, SCR_ADD, 0x01),
        !          3124:                0,
        !          3125:        /*
        !          3126:        **      send a "message parity error" message.
        !          3127:        */
        !          3128:        SCR_LOAD_REG (scratcha, M_PARITY),
        !          3129:                0,
        !          3130:        SCR_JUMP,
        !          3131:                PADDR (setmsg),
        !          3132: }/*-------------------------< MSG_REJECT >---------------*/,{
        !          3133:        /*
        !          3134:        **      If a negotiation was in progress,
        !          3135:        **      negotiation failed.
        !          3136:        */
        !          3137:        SCR_FROM_REG (HS_REG),
        !          3138:                0,
        !          3139:        SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)),
        !          3140:                SIR_NEGO_FAILED,
        !          3141:        /*
        !          3142:        **      else make host log this message
        !          3143:        */
        !          3144:        SCR_INT ^ IFFALSE (DATA (HS_NEGOTIATE)),
        !          3145:                SIR_REJECT_RECEIVED,
        !          3146:        SCR_JUMP,
        !          3147:                PADDR (clrack),
        !          3148: 
        !          3149: }/*-------------------------< MSG_IGN_RESIDUE >----------*/,{
        !          3150:        /*
        !          3151:        **      Terminate cycle
        !          3152:        */
        !          3153:        SCR_CLR (SCR_ACK),
        !          3154:                0,
        !          3155:        SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
        !          3156:                PADDR (dispatch),
        !          3157:        /*
        !          3158:        **      get residue size.
        !          3159:        */
        !          3160:        SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
        !          3161:                NADDR (msgin[1]),
        !          3162:        /*
        !          3163:        **      Check for message parity error.
        !          3164:        */
        !          3165:        SCR_TO_REG (scratcha),
        !          3166:                0,
        !          3167:        SCR_FROM_REG (socl),
        !          3168:                0,
        !          3169:        SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
        !          3170:                PADDRH (msg_parity),
        !          3171:        SCR_FROM_REG (scratcha),
        !          3172:                0,
        !          3173:        /*
        !          3174:        **      Size is 0 .. ignore message.
        !          3175:        */
        !          3176:        SCR_JUMP ^ IFTRUE (DATA (0)),
        !          3177:                PADDR (clrack),
        !          3178:        /*
        !          3179:        **      Size is not 1 .. have to interrupt.
        !          3180:        */
        !          3181: /*<<<*/        SCR_JUMPR ^ IFFALSE (DATA (1)),
        !          3182:                40,
        !          3183:        /*
        !          3184:        **      Check for residue byte in swide register
        !          3185:        */
        !          3186:        SCR_FROM_REG (scntl2),
        !          3187:                0,
        !          3188: /*<<<*/        SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)),
        !          3189:                16,
        !          3190:        /*
        !          3191:        **      There IS data in the swide register.
        !          3192:        **      Discard it.
        !          3193:        */
        !          3194:        SCR_REG_REG (scntl2, SCR_OR, WSR),
        !          3195:                0,
        !          3196:        SCR_JUMP,
        !          3197:                PADDR (clrack),
        !          3198:        /*
        !          3199:        **      Load again the size to the sfbr register.
        !          3200:        */
        !          3201: /*>>>*/        SCR_FROM_REG (scratcha),
        !          3202:                0,
        !          3203: /*>>>*/        SCR_INT,
        !          3204:                SIR_IGN_RESIDUE,
        !          3205:        SCR_JUMP,
        !          3206:                PADDR (clrack),
        !          3207: 
        !          3208: }/*-------------------------< MSG_EXTENDED >-------------*/,{
        !          3209:        /*
        !          3210:        **      Terminate cycle
        !          3211:        */
        !          3212:        SCR_CLR (SCR_ACK),
        !          3213:                0,
        !          3214:        SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
        !          3215:                PADDR (dispatch),
        !          3216:        /*
        !          3217:        **      get length.
        !          3218:        */
        !          3219:        SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
        !          3220:                NADDR (msgin[1]),
        !          3221:        /*
        !          3222:        **      Check for message parity error.
        !          3223:        */
        !          3224:        SCR_TO_REG (scratcha),
        !          3225:                0,
        !          3226:        SCR_FROM_REG (socl),
        !          3227:                0,
        !          3228:        SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
        !          3229:                PADDRH (msg_parity),
        !          3230:        SCR_FROM_REG (scratcha),
        !          3231:                0,
        !          3232:        /*
        !          3233:        */
        !          3234:        SCR_JUMP ^ IFTRUE (DATA (3)),
        !          3235:                PADDRH (msg_ext_3),
        !          3236:        SCR_JUMP ^ IFFALSE (DATA (2)),
        !          3237:                PADDR (msg_bad),
        !          3238: }/*-------------------------< MSG_EXT_2 >----------------*/,{
        !          3239:        SCR_CLR (SCR_ACK),
        !          3240:                0,
        !          3241:        SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
        !          3242:                PADDR (dispatch),
        !          3243:        /*
        !          3244:        **      get extended message code.
        !          3245:        */
        !          3246:        SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
        !          3247:                NADDR (msgin[2]),
        !          3248:        /*
        !          3249:        **      Check for message parity error.
        !          3250:        */
        !          3251:        SCR_TO_REG (scratcha),
        !          3252:                0,
        !          3253:        SCR_FROM_REG (socl),
        !          3254:                0,
        !          3255:        SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
        !          3256:                PADDRH (msg_parity),
        !          3257:        SCR_FROM_REG (scratcha),
        !          3258:                0,
        !          3259:        SCR_JUMP ^ IFTRUE (DATA (M_X_WIDE_REQ)),
        !          3260:                PADDRH (msg_wdtr),
        !          3261:        /*
        !          3262:        **      unknown extended message
        !          3263:        */
        !          3264:        SCR_JUMP,
        !          3265:                PADDR (msg_bad)
        !          3266: }/*-------------------------< MSG_WDTR >-----------------*/,{
        !          3267:        SCR_CLR (SCR_ACK),
        !          3268:                0,
        !          3269:        SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
        !          3270:                PADDR (dispatch),
        !          3271:        /*
        !          3272:        **      get data bus width
        !          3273:        */
        !          3274:        SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
        !          3275:                NADDR (msgin[3]),
        !          3276:        SCR_FROM_REG (socl),
        !          3277:                0,
        !          3278:        SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
        !          3279:                PADDRH (msg_parity),
        !          3280:        /*
        !          3281:        **      let the host do the real work.
        !          3282:        */
        !          3283:        SCR_INT,
        !          3284:                SIR_NEGO_WIDE,
        !          3285:        /*
        !          3286:        **      let the target fetch our answer.
        !          3287:        */
        !          3288:        SCR_SET (SCR_ATN),
        !          3289:                0,
        !          3290:        SCR_CLR (SCR_ACK),
        !          3291:                0,
        !          3292: 
        !          3293:        SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)),
        !          3294:                SIR_NEGO_PROTO,
        !          3295:        /*
        !          3296:        **      Send the M_X_WIDE_REQ
        !          3297:        */
        !          3298:        SCR_MOVE_ABS (4) ^ SCR_MSG_OUT,
        !          3299:                NADDR (msgout),
        !          3300:        SCR_CLR (SCR_ATN),
        !          3301:                0,
        !          3302:        SCR_COPY (1),
        !          3303:                RADDR (sfbr),
        !          3304:                NADDR (lastmsg),
        !          3305:        SCR_JUMP,
        !          3306:                PADDR (msg_out_done),
        !          3307: 
        !          3308: }/*-------------------------< MSG_EXT_3 >----------------*/,{
        !          3309:        SCR_CLR (SCR_ACK),
        !          3310:                0,
        !          3311:        SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
        !          3312:                PADDR (dispatch),
        !          3313:        /*
        !          3314:        **      get extended message code.
        !          3315:        */
        !          3316:        SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
        !          3317:                NADDR (msgin[2]),
        !          3318:        /*
        !          3319:        **      Check for message parity error.
        !          3320:        */
        !          3321:        SCR_TO_REG (scratcha),
        !          3322:                0,
        !          3323:        SCR_FROM_REG (socl),
        !          3324:                0,
        !          3325:        SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
        !          3326:                PADDRH (msg_parity),
        !          3327:        SCR_FROM_REG (scratcha),
        !          3328:                0,
        !          3329:        SCR_JUMP ^ IFTRUE (DATA (M_X_SYNC_REQ)),
        !          3330:                PADDRH (msg_sdtr),
        !          3331:        /*
        !          3332:        **      unknown extended message
        !          3333:        */
        !          3334:        SCR_JUMP,
        !          3335:                PADDR (msg_bad)
        !          3336: 
        !          3337: }/*-------------------------< MSG_SDTR >-----------------*/,{
        !          3338:        SCR_CLR (SCR_ACK),
        !          3339:                0,
        !          3340:        SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
        !          3341:                PADDR (dispatch),
        !          3342:        /*
        !          3343:        **      get period and offset
        !          3344:        */
        !          3345:        SCR_MOVE_ABS (2) ^ SCR_MSG_IN,
        !          3346:                NADDR (msgin[3]),
        !          3347:        SCR_FROM_REG (socl),
        !          3348:                0,
        !          3349:        SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)),
        !          3350:                PADDRH (msg_parity),
        !          3351:        /*
        !          3352:        **      let the host do the real work.
        !          3353:        */
        !          3354:        SCR_INT,
        !          3355:                SIR_NEGO_SYNC,
        !          3356:        /*
        !          3357:        **      let the target fetch our answer.
        !          3358:        */
        !          3359:        SCR_SET (SCR_ATN),
        !          3360:                0,
        !          3361:        SCR_CLR (SCR_ACK),
        !          3362:                0,
        !          3363: 
        !          3364:        SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)),
        !          3365:                SIR_NEGO_PROTO,
        !          3366:        /*
        !          3367:        **      Send the M_X_SYNC_REQ
        !          3368:        */
        !          3369:        SCR_MOVE_ABS (5) ^ SCR_MSG_OUT,
        !          3370:                NADDR (msgout),
        !          3371:        SCR_CLR (SCR_ATN),
        !          3372:                0,
        !          3373:        SCR_COPY (1),
        !          3374:                RADDR (sfbr),
        !          3375:                NADDR (lastmsg),
        !          3376:        SCR_JUMP,
        !          3377:                PADDR (msg_out_done),
        !          3378: 
        !          3379: }/*-------------------------< MSG_OUT_ABORT >-------------*/,{
        !          3380:        /*
        !          3381:        **      After ABORT message,
        !          3382:        **
        !          3383:        **      expect an immediate disconnect, ...
        !          3384:        */
        !          3385:        SCR_REG_REG (scntl2, SCR_AND, 0x7f),
        !          3386:                0,
        !          3387:        SCR_CLR (SCR_ACK|SCR_ATN),
        !          3388:                0,
        !          3389:        SCR_WAIT_DISC,
        !          3390:                0,
        !          3391:        /*
        !          3392:        **      ... and set the status to "ABORTED"
        !          3393:        */
        !          3394:        SCR_LOAD_REG (HS_REG, HS_ABORTED),
        !          3395:                0,
        !          3396:        SCR_JUMP,
        !          3397:                PADDR (cleanup),
        !          3398: 
        !          3399: }/*-------------------------< GETCC >-----------------------*/,{
        !          3400:        /*
        !          3401:        **      The ncr doesn't have an indirect load
        !          3402:        **      or store command. So we have to
        !          3403:        **      copy part of the control block to a
        !          3404:        **      fixed place, where we can modify it.
        !          3405:        **
        !          3406:        **      We patch the address part of a COPY command
        !          3407:        **      with the address of the dsa register ...
        !          3408:        */
        !          3409:        SCR_COPY_F (4),
        !          3410:                RADDR (dsa),
        !          3411:                PADDRH (getcc1),
        !          3412:        /*
        !          3413:        **      ... then we do the actual copy.
        !          3414:        */
        !          3415:        SCR_COPY (sizeof (struct head)),
        !          3416: }/*-------------------------< GETCC1 >----------------------*/,{
        !          3417:                0,
        !          3418:                NADDR (header),
        !          3419:        /*
        !          3420:        **      Initialize the status registers
        !          3421:        */
        !          3422:        SCR_COPY (4),
        !          3423:                NADDR (header.status),
        !          3424:                RADDR (scr0),
        !          3425: }/*-------------------------< GETCC2 >----------------------*/,{
        !          3426:        /*
        !          3427:        **      Get the condition code from a target.
        !          3428:        **
        !          3429:        **      DSA points to a data structure.
        !          3430:        **      Set TEMP to the script location
        !          3431:        **      that receives the condition code.
        !          3432:        **
        !          3433:        **      Because there is no script command
        !          3434:        **      to load a longword into a register,
        !          3435:        **      we use a CALL command.
        !          3436:        */
        !          3437: /*<<<*/        SCR_CALLR,
        !          3438:                24,
        !          3439:        /*
        !          3440:        **      Get the condition code.
        !          3441:        */
        !          3442:        SCR_MOVE_TBL ^ SCR_DATA_IN,
        !          3443:                offsetof (struct dsb, sense),
        !          3444:        /*
        !          3445:        **      No data phase may follow!
        !          3446:        */
        !          3447:        SCR_CALL,
        !          3448:                PADDR (checkatn),
        !          3449:        SCR_JUMP,
        !          3450:                PADDR (no_data),
        !          3451: /*>>>*/
        !          3452: 
        !          3453:        /*
        !          3454:        **      The CALL jumps to this point.
        !          3455:        **      Prepare for a RESTORE_POINTER message.
        !          3456:        **      Save the TEMP register into the saved pointer.
        !          3457:        */
        !          3458:        SCR_COPY (4),
        !          3459:                RADDR (temp),
        !          3460:                NADDR (header.savep),
        !          3461:        /*
        !          3462:        **      Load scratcha, because in case of a selection timeout,
        !          3463:        **      the host will expect a new value for startpos in
        !          3464:        **      the scratcha register.
        !          3465:        */
        !          3466:        SCR_COPY (4),
        !          3467:                PADDR (startpos),
        !          3468:                RADDR (scratcha),
        !          3469: #ifdef NCR_GETCC_WITHMSG
        !          3470:        /*
        !          3471:        **      If QUIRK_NOMSG is set, select without ATN.
        !          3472:        **      and don't send a message.
        !          3473:        */
        !          3474:        SCR_FROM_REG (QU_REG),
        !          3475:                0,
        !          3476:        SCR_JUMP ^ IFTRUE (MASK (QUIRK_NOMSG, QUIRK_NOMSG)),
        !          3477:                PADDRH(getcc3),
        !          3478:        /*
        !          3479:        **      Then try to connect to the target.
        !          3480:        **      If we are reselected, special treatment
        !          3481:        **      of the current job is required before
        !          3482:        **      accepting the reselection.
        !          3483:        */
        !          3484:        SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select),
        !          3485:                PADDR(badgetcc),
        !          3486:        /*
        !          3487:        **      save target id.
        !          3488:        */
        !          3489:        SCR_FROM_REG (sdid),
        !          3490:                0,
        !          3491:        SCR_TO_REG (ctest0),
        !          3492:                0,
        !          3493:        /*
        !          3494:        **      Send the IDENTIFY message.
        !          3495:        **      In case of short transfer, remove ATN.
        !          3496:        */
        !          3497:        SCR_MOVE_TBL ^ SCR_MSG_OUT,
        !          3498:                offsetof (struct dsb, smsg2),
        !          3499:        SCR_CLR (SCR_ATN),
        !          3500:                0,
        !          3501:        /*
        !          3502:        **      save the first byte of the message.
        !          3503:        */
        !          3504:        SCR_COPY (1),
        !          3505:                RADDR (sfbr),
        !          3506:                NADDR (lastmsg),
        !          3507:        SCR_JUMP,
        !          3508:                PADDR (prepare2),
        !          3509: 
        !          3510: #endif
        !          3511: }/*-------------------------< GETCC3 >----------------------*/,{
        !          3512:        /*
        !          3513:        **      Try to connect to the target.
        !          3514:        **      If we are reselected, special treatment
        !          3515:        **      of the current job is required before
        !          3516:        **      accepting the reselection.
        !          3517:        **
        !          3518:        **      Silly target won't accept a message.
        !          3519:        **      Select without ATN.
        !          3520:        */
        !          3521:        SCR_SEL_TBL ^ offsetof (struct dsb, select),
        !          3522:                PADDR(badgetcc),
        !          3523:        /*
        !          3524:        **      save target id.
        !          3525:        */
        !          3526:        SCR_FROM_REG (sdid),
        !          3527:                0,
        !          3528:        SCR_TO_REG (ctest0),
        !          3529:                0,
        !          3530:        /*
        !          3531:        **      Force error if selection timeout
        !          3532:        */
        !          3533:        SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_IN)),
        !          3534:                0,
        !          3535:        /*
        !          3536:        **      don't negotiate.
        !          3537:        */
        !          3538:        SCR_JUMP,
        !          3539:                PADDR (prepare2),
        !          3540: 
        !          3541: }/*-------------------------< DATA_OUT >-------------------*/,{
        !          3542: /*
        !          3543: **     Because the size depends on the
        !          3544: **     #define MAX_SCATTER parameter,
        !          3545: **     it is filled in at runtime.
        !          3546: **
        !          3547: **  ##===========< i=0; i<MAX_SCATTER >=========
        !          3548: **  || SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_OUT)),
        !          3549: **  ||         PADDR (dispatch),
        !          3550: **  || SCR_MOVE_TBL ^ SCR_DATA_OUT,
        !          3551: **  ||         offsetof (struct dsb, data[ i]),
        !          3552: **  ##==========================================
        !          3553: **
        !          3554: **     SCR_CALL,
        !          3555: **             PADDR (dispatch),
        !          3556: **     SCR_JUMP,
        !          3557: **             PADDR (no_data),
        !          3558: **
        !          3559: **---------------------------------------------------------
        !          3560: */
        !          3561: 0
        !          3562: }/*-------------------------< ABORTTAG >-------------------*/,{
        !          3563:        /*
        !          3564:        **      Abort a bad reselection.
        !          3565:        **      Set the message to ABORT vs. ABORT_TAG
        !          3566:        */
        !          3567:        SCR_LOAD_REG (scratcha, M_ABORT_TAG),
        !          3568:                0,
        !          3569:        SCR_JUMPR ^ IFFALSE (CARRYSET),
        !          3570:                8,
        !          3571: }/*-------------------------< ABORT >----------------------*/,{
        !          3572:        SCR_LOAD_REG (scratcha, M_ABORT),
        !          3573:                0,
        !          3574:        SCR_COPY (1),
        !          3575:                RADDR (scratcha),
        !          3576:                NADDR (msgout),
        !          3577:        SCR_SET (SCR_ATN),
        !          3578:                0,
        !          3579:        SCR_CLR (SCR_ACK),
        !          3580:                0,
        !          3581:        /*
        !          3582:        **      and send it.
        !          3583:        **      we expect an immediate disconnect
        !          3584:        */
        !          3585:        SCR_REG_REG (scntl2, SCR_AND, 0x7f),
        !          3586:                0,
        !          3587:        SCR_MOVE_ABS (1) ^ SCR_MSG_OUT,
        !          3588:                NADDR (msgout),
        !          3589:        SCR_COPY (1),
        !          3590:                RADDR (sfbr),
        !          3591:                NADDR (lastmsg),
        !          3592:        SCR_CLR (SCR_ACK|SCR_ATN),
        !          3593:                0,
        !          3594:        SCR_WAIT_DISC,
        !          3595:                0,
        !          3596:        SCR_JUMP,
        !          3597:                PADDR (start),
        !          3598: }/*-------------------------< SNOOPTEST >-------------------*/,{
        !          3599:        /*
        !          3600:        **      Read the variable.
        !          3601:        */
        !          3602:        SCR_COPY (4),
        !          3603:                NADDR(ncr_cache),
        !          3604:                RADDR (scratcha),
        !          3605:        /*
        !          3606:        **      Write the variable.
        !          3607:        */
        !          3608:        SCR_COPY (4),
        !          3609:                RADDR (temp),
        !          3610:                NADDR(ncr_cache),
        !          3611:        /*
        !          3612:        **      Read back the variable.
        !          3613:        */
        !          3614:        SCR_COPY (4),
        !          3615:                NADDR(ncr_cache),
        !          3616:                RADDR (temp),
        !          3617: }/*-------------------------< SNOOPEND >-------------------*/,{
        !          3618:        /*
        !          3619:        **      And stop.
        !          3620:        */
        !          3621:        SCR_INT,
        !          3622:                99,
        !          3623: }/*--------------------------------------------------------*/
        !          3624: };
        !          3625: 
        !          3626: /*==========================================================
        !          3627: **
        !          3628: **
        !          3629: **     Fill in #define dependent parts of the script
        !          3630: **
        !          3631: **
        !          3632: **==========================================================
        !          3633: */
        !          3634: 
        !          3635: __initfunc(
        !          3636: void ncr_script_fill (struct script * scr, struct scripth * scrh)
        !          3637: )
        !          3638: {
        !          3639:        int     i;
        !          3640:        ncrcmd  *p;
        !          3641: 
        !          3642:        p = scrh->tryloop;
        !          3643:        for (i=0; i<MAX_START; i++) {
        !          3644:                *p++ =SCR_COPY (4);
        !          3645:                *p++ =NADDR (squeue[i]);
        !          3646:                *p++ =RADDR (dsa);
        !          3647:                *p++ =SCR_CALL;
        !          3648:                *p++ =PADDR (trysel);
        !          3649:        };
        !          3650:        *p++ =SCR_JUMP;
        !          3651:        *p++ =PADDRH(tryloop);
        !          3652: 
        !          3653:        assert ((u_long)p == (u_long)&scrh->tryloop + sizeof (scrh->tryloop));
        !          3654: 
        !          3655:        p = scr->data_in;
        !          3656: 
        !          3657:        for (i=0; i<MAX_SCATTER; i++) {
        !          3658:                *p++ =SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_IN));
        !          3659:                *p++ =PADDR (checkatn);
        !          3660:                *p++ =SCR_MOVE_TBL ^ SCR_DATA_IN;
        !          3661:                *p++ =offsetof (struct dsb, data[i]);
        !          3662:        };
        !          3663: 
        !          3664:        *p++ =SCR_CALL;
        !          3665:        *p++ =PADDR (checkatn);
        !          3666:        *p++ =SCR_JUMP;
        !          3667:        *p++ =PADDR (no_data);
        !          3668: 
        !          3669:        assert ((u_long)p == (u_long)&scr->data_in + sizeof (scr->data_in));
        !          3670: 
        !          3671:        p = scrh->data_out;
        !          3672: 
        !          3673:        for (i=0; i<MAX_SCATTER; i++) {
        !          3674:                *p++ =SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_OUT));
        !          3675:                *p++ =PADDR (dispatch);
        !          3676:                *p++ =SCR_MOVE_TBL ^ SCR_DATA_OUT;
        !          3677:                *p++ =offsetof (struct dsb, data[i]);
        !          3678:        };
        !          3679: 
        !          3680:        *p++ =SCR_CALL;
        !          3681:        *p++ =PADDR (dispatch);
        !          3682:        *p++ =SCR_JUMP;
        !          3683:        *p++ =PADDR (no_data);
        !          3684: 
        !          3685:        assert ((u_long)p == (u_long)&scrh->data_out + sizeof (scrh->data_out));
        !          3686: }
        !          3687: 
        !          3688: /*==========================================================
        !          3689: **
        !          3690: **
        !          3691: **     Copy and rebind a script.
        !          3692: **
        !          3693: **
        !          3694: **==========================================================
        !          3695: */
        !          3696: 
        !          3697: __initfunc(
        !          3698: static void ncr_script_copy_and_bind (ncb_p np, ncrcmd *src, ncrcmd *dst, int len)
        !          3699: )
        !          3700: {
        !          3701:        ncrcmd  opcode, new, old, tmp1, tmp2;
        !          3702:        ncrcmd  *start, *end;
        !          3703:        int relocs;
        !          3704:        int opchanged = 0;
        !          3705: 
        !          3706:        start = src;
        !          3707:        end = src + len/4;
        !          3708: 
        !          3709:        while (src < end) {
        !          3710: 
        !          3711:                opcode = *src++;
        !          3712:                *dst++ = cpu_to_scr(opcode);
        !          3713: 
        !          3714:                /*
        !          3715:                **      If we forget to change the length
        !          3716:                **      in struct script, a field will be
        !          3717:                **      padded with 0. This is an illegal
        !          3718:                **      command.
        !          3719:                */
        !          3720: 
        !          3721:                if (opcode == 0) {
        !          3722:                        printf ("%s: ERROR0 IN SCRIPT at %d.\n",
        !          3723:                                ncr_name(np), (int) (src-start-1));
        !          3724:                        DELAY (1000000);
        !          3725:                };
        !          3726: 
        !          3727:                if (DEBUG_FLAGS & DEBUG_SCRIPT)
        !          3728:                        printf ("%p:  <%x>\n",
        !          3729:                                (src-1), (unsigned)opcode);
        !          3730: 
        !          3731:                /*
        !          3732:                **      We don't have to decode ALL commands
        !          3733:                */
        !          3734:                switch (opcode >> 28) {
        !          3735: 
        !          3736:                case 0xc:
        !          3737:                        /*
        !          3738:                        **      COPY has TWO arguments.
        !          3739:                        */
        !          3740:                        relocs = 2;
        !          3741:                        tmp1 = src[0];
        !          3742:                        if ((tmp1 & RELOC_MASK) == RELOC_KVAR)
        !          3743:                                tmp1 = 0;
        !          3744:                        tmp2 = src[1];
        !          3745:                        if ((tmp2 & RELOC_MASK) == RELOC_KVAR)
        !          3746:                                tmp2 = 0;
        !          3747:                        if ((tmp1 ^ tmp2) & 3) {
        !          3748:                                printf ("%s: ERROR1 IN SCRIPT at %d.\n",
        !          3749:                                        ncr_name(np), (int) (src-start-1));
        !          3750:                                DELAY (1000000);
        !          3751:                        }
        !          3752:                        /*
        !          3753:                        **      If PREFETCH feature not enabled, remove 
        !          3754:                        **      the NO FLUSH bit if present.
        !          3755:                        */
        !          3756:                        if ((opcode & SCR_NO_FLUSH) && !(np->features & FE_PFEN)) {
        !          3757:                                dst[-1] = cpu_to_scr(opcode & ~SCR_NO_FLUSH);
        !          3758:                                ++opchanged;
        !          3759:                        }
        !          3760:                        break;
        !          3761: 
        !          3762:                case 0x0:
        !          3763:                        /*
        !          3764:                        **      MOVE (absolute address)
        !          3765:                        */
        !          3766:                        relocs = 1;
        !          3767:                        break;
        !          3768: 
        !          3769:                case 0x8:
        !          3770:                        /*
        !          3771:                        **      JUMP / CALL
        !          3772:                        **      don't relocate if relative :-)
        !          3773:                        */
        !          3774:                        if (opcode & 0x00800000)
        !          3775:                                relocs = 0;
        !          3776:                        else
        !          3777:                                relocs = 1;
        !          3778:                        break;
        !          3779: 
        !          3780:                case 0x4:
        !          3781:                case 0x5:
        !          3782:                case 0x6:
        !          3783:                case 0x7:
        !          3784:                        relocs = 1;
        !          3785:                        break;
        !          3786: 
        !          3787:                default:
        !          3788:                        relocs = 0;
        !          3789:                        break;
        !          3790:                };
        !          3791: 
        !          3792:                if (relocs) {
        !          3793:                        while (relocs--) {
        !          3794:                                old = *src++;
        !          3795: 
        !          3796:                                switch (old & RELOC_MASK) {
        !          3797:                                case RELOC_REGISTER:
        !          3798:                                        new = (old & ~RELOC_MASK) + np->paddr;
        !          3799:                                        break;
        !          3800:                                case RELOC_LABEL:
        !          3801:                                        new = (old & ~RELOC_MASK) + np->p_script;
        !          3802:                                        break;
        !          3803:                                case RELOC_LABELH:
        !          3804:                                        new = (old & ~RELOC_MASK) + np->p_scripth;
        !          3805:                                        break;
        !          3806:                                case RELOC_SOFTC:
        !          3807:                                        new = (old & ~RELOC_MASK) + vtophys(np);
        !          3808:                                        break;
        !          3809:                                case RELOC_KVAR:
        !          3810:                                        if (((old & ~RELOC_MASK) <
        !          3811:                                             SCRIPT_KVAR_FIRST) ||
        !          3812:                                            ((old & ~RELOC_MASK) >
        !          3813:                                             SCRIPT_KVAR_LAST))
        !          3814:                                                panic("ncr KVAR out of range");
        !          3815:                                        new = vtophys(script_kvars[old &
        !          3816:                                            ~RELOC_MASK]);
        !          3817:                                        break;
        !          3818:                                case 0:
        !          3819:                                        /* Don't relocate a 0 address. */
        !          3820:                                        if (old == 0) {
        !          3821:                                                new = old;
        !          3822:                                                break;
        !          3823:                                        }
        !          3824:                                        /* fall through */
        !          3825:                                default:
        !          3826:                                        panic("ncr_script_copy_and_bind: weird relocation %x\n", old);
        !          3827:                                        break;
        !          3828:                                }
        !          3829: 
        !          3830:                                *dst++ = cpu_to_scr(new);
        !          3831:                        }
        !          3832:                } else
        !          3833:                        *dst++ = cpu_to_scr(*src++);
        !          3834: 
        !          3835:        };
        !          3836:        if (bootverbose > 1 && opchanged)
        !          3837:                printf("%s: NO FLUSH bit removed from %d script instructions\n",
        !          3838:                        ncr_name(np), opchanged); 
        !          3839: }
        !          3840: 
        !          3841: /*==========================================================
        !          3842: **
        !          3843: **
        !          3844: **      Auto configuration:  attach and init a host adapter.
        !          3845: **
        !          3846: **
        !          3847: **==========================================================
        !          3848: */
        !          3849: 
        !          3850: /*
        !          3851: **     Linux host data structure
        !          3852: **
        !          3853: **     The script area is allocated in the host data structure
        !          3854: **     because kmalloc() returns NULL during scsi initialisations
        !          3855: **     with Linux 1.2.X
        !          3856: */
        !          3857: 
        !          3858: struct host_data {
        !          3859:      struct ncb *ncb;
        !          3860: 
        !          3861:      char ncb_align[NCB_ALIGN_SIZE-1]; /* Filler for alignment */
        !          3862:      struct ncb _ncb_data;
        !          3863: 
        !          3864:      char ccb_align[CCB_ALIGN_SIZE-1]; /* Filler for alignment */
        !          3865:      struct ccb _ccb_data;
        !          3866: 
        !          3867:      char scr_align[SCR_ALIGN_SIZE-1]; /* Filler for alignment */
        !          3868:      struct script script_data;
        !          3869: 
        !          3870:      struct scripth scripth_data;
        !          3871: };
        !          3872: 
        !          3873: /*
        !          3874: **     Print something which allow to retrieve the controler type, unit,
        !          3875: **     target, lun concerned by a kernel message.
        !          3876: */
        !          3877: 
        !          3878: #define PRINT_LUN(np, target, lun) \
        !          3879: printf(KERN_INFO "%s-<%d,%d>: ", ncr_name(np), (int) (target), (int) (lun))
        !          3880: 
        !          3881: static void PRINT_ADDR(Scsi_Cmnd *cmd)
        !          3882: {
        !          3883:        struct host_data *host_data = (struct host_data *) cmd->host->hostdata;
        !          3884:        ncb_p np                    = host_data->ncb;
        !          3885:        if (np) PRINT_LUN(np, cmd->target, cmd->lun);
        !          3886: }
        !          3887: 
        !          3888: /*==========================================================
        !          3889: **
        !          3890: **     NCR chip clock divisor table.
        !          3891: **     Divisors are multiplied by 10,000,000 in order to make 
        !          3892: **     calculations more simple.
        !          3893: **
        !          3894: **==========================================================
        !          3895: */
        !          3896: 
        !          3897: #define _5M 5000000
        !          3898: static u_long div_10M[] =
        !          3899:        {2*_5M, 3*_5M, 4*_5M, 6*_5M, 8*_5M, 12*_5M, 16*_5M};
        !          3900: 
        !          3901: 
        !          3902: /*===============================================================
        !          3903: **
        !          3904: **     Prepare io register values used by ncr_init() according 
        !          3905: **     to selected and supported features.
        !          3906: **
        !          3907: **     NCR chips allow burst lengths of 2, 4, 8, 16, 32, 64, 128 
        !          3908: **     transfers. 32,64,128 are only supported by 875 and 895 chips.
        !          3909: **     We use log base 2 (burst length) as internal code, with 
        !          3910: **     value 0 meaning "burst disabled".
        !          3911: **
        !          3912: **===============================================================
        !          3913: */
        !          3914: 
        !          3915: /*
        !          3916:  *     Burst length from burst code.
        !          3917:  */
        !          3918: #define burst_length(bc) (!(bc))? 0 : 1 << (bc)
        !          3919: 
        !          3920: /*
        !          3921:  *     Burst code from io register bits.
        !          3922:  */
        !          3923: #define burst_code(dmode, ctest4, ctest5) \
        !          3924:        (ctest4) & 0x80? 0 : (((dmode) & 0xc0) >> 6) + ((ctest5) & 0x04) + 1
        !          3925: 
        !          3926: /*
        !          3927:  *     Set initial io register bits from burst code.
        !          3928:  */
        !          3929: static inline void ncr_init_burst(ncb_p np, u_char bc)
        !          3930: {
        !          3931:        np->rv_ctest4   &= ~0x80;
        !          3932:        np->rv_dmode    &= ~(0x3 << 6);
        !          3933:        np->rv_ctest5   &= ~0x4;
        !          3934: 
        !          3935:        if (!bc) {
        !          3936:                np->rv_ctest4   |= 0x80;
        !          3937:        }
        !          3938:        else {
        !          3939:                --bc;
        !          3940:                np->rv_dmode    |= ((bc & 0x3) << 6);
        !          3941:                np->rv_ctest5   |= (bc & 0x4);
        !          3942:        }
        !          3943: }
        !          3944: 
        !          3945: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          3946: 
        !          3947: /*
        !          3948: **     Get target set-up from Symbios format NVRAM.
        !          3949: */
        !          3950: 
        !          3951: __initfunc(
        !          3952: static void
        !          3953:        ncr_Symbios_setup_target(ncb_p np, int target, Symbios_nvram *nvram)
        !          3954: )
        !          3955: {
        !          3956:        tcb_p tp = &np->target[target];
        !          3957:        Symbios_target *tn = &nvram->target[target];
        !          3958: 
        !          3959:        tp->usrsync = tn->sync_period ? (tn->sync_period + 3) / 4 : 255;
        !          3960:        tp->usrwide = tn->bus_width == 0x10 ? 1 : 0;
        !          3961:        tp->usrtags =
        !          3962:                (tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED)? SCSI_NCR_MAX_TAGS : 0;
        !          3963: 
        !          3964:        if (!(tn->flags & SYMBIOS_DISCONNECT_ENABLE))
        !          3965:                tp->usrflag |= UF_NODISC;
        !          3966:        if (!(tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME))
        !          3967:                tp->usrflag |= UF_NOSCAN;
        !          3968: }
        !          3969: 
        !          3970: /*
        !          3971: **     Get target set-up from Tekram format NVRAM.
        !          3972: */
        !          3973: 
        !          3974: __initfunc(
        !          3975: static void
        !          3976:        ncr_Tekram_setup_target(ncb_p np, int target, Tekram_nvram *nvram)
        !          3977: )
        !          3978: {
        !          3979:        tcb_p tp = &np->target[target];
        !          3980:        struct Tekram_target *tn = &nvram->target[target];
        !          3981:        int i;
        !          3982: 
        !          3983:        if (tn->flags & TEKRAM_SYNC_NEGO) {
        !          3984:                i = tn->sync_index & 0xf;
        !          3985:                tp->usrsync = i < 12 ? Tekram_sync[i] : 255;
        !          3986:        }
        !          3987: 
        !          3988:        tp->usrwide = (tn->flags & TEKRAM_WIDE_NEGO) ? 1 : 0;
        !          3989: 
        !          3990:        if (tn->flags & TEKRAM_TAGGED_COMMANDS) {
        !          3991:                tp->usrtags = 2 << nvram->max_tags_index;
        !          3992:                if (tp->usrtags > SCSI_NCR_MAX_TAGS)
        !          3993:                        tp->usrtags = SCSI_NCR_MAX_TAGS;
        !          3994:        }
        !          3995: 
        !          3996:        if (!(tn->flags & TEKRAM_DISCONNECT_ENABLE))
        !          3997:                tp->usrflag = UF_NODISC;
        !          3998:  
        !          3999:        /* If any device does not support parity, we will not use this option */
        !          4000:        if (!(tn->flags & TEKRAM_PARITY_CHECK))
        !          4001:                np->rv_scntl0  &= ~0x0a; /* SCSI parity checking disabled */
        !          4002: }
        !          4003: #endif /* SCSI_NCR_NVRAM_SUPPORT */
        !          4004: 
        !          4005: __initfunc(
        !          4006: static int ncr_prepare_setting(ncb_p np, ncr_nvram *nvram)
        !          4007: )
        !          4008: {
        !          4009:        u_char  burst_max;
        !          4010:        u_long  period;
        !          4011:        int i;
        !          4012: 
        !          4013:        /*
        !          4014:        **      Save assumed BIOS setting
        !          4015:        */
        !          4016: 
        !          4017:        np->sv_scntl0   = INB(nc_scntl0) & 0x0a;
        !          4018:        np->sv_scntl3   = INB(nc_scntl3) & 0x07;
        !          4019:        np->sv_dmode    = INB(nc_dmode)  & 0xce;
        !          4020:        np->sv_dcntl    = INB(nc_dcntl)  & 0xa8;
        !          4021:        np->sv_ctest3   = INB(nc_ctest3) & 0x01;
        !          4022:        np->sv_ctest4   = INB(nc_ctest4) & 0x80;
        !          4023:        np->sv_ctest5   = INB(nc_ctest5) & 0x24;
        !          4024:        np->sv_gpcntl   = INB(nc_gpcntl);
        !          4025:        np->sv_stest2   = INB(nc_stest2) & 0x20;
        !          4026:        np->sv_stest4   = INB(nc_stest4);
        !          4027: 
        !          4028:        /*
        !          4029:        **      Wide ?
        !          4030:        */
        !          4031: 
        !          4032:        np->maxwide     = (np->features & FE_WIDE)? 1 : 0;
        !          4033: 
        !          4034:        /*
        !          4035:        **      Get the frequency of the chip's clock.
        !          4036:        **      Find the right value for scntl3.
        !          4037:        */
        !          4038: 
        !          4039:        if      (np->features & FE_QUAD)
        !          4040:                np->multiplier  = 4;
        !          4041:        else if (np->features & FE_DBLR)
        !          4042:                np->multiplier  = 2;
        !          4043:        else
        !          4044:                np->multiplier  = 1;
        !          4045: 
        !          4046:        np->clock_khz   = (np->features & FE_CLK80)? 80000 : 40000;
        !          4047:        np->clock_khz   *= np->multiplier;
        !          4048: 
        !          4049:        if (np->clock_khz != 40000)
        !          4050:                ncr_getclock(np, np->multiplier);
        !          4051: 
        !          4052:        /*
        !          4053:         * Divisor to be used for async (timer pre-scaler).
        !          4054:         */
        !          4055:        i = np->clock_divn - 1;
        !          4056:        while (i >= 0) {
        !          4057:                --i;
        !          4058:                if (10ul * SCSI_NCR_MIN_ASYNC * np->clock_khz > div_10M[i]) {
        !          4059:                        ++i;
        !          4060:                        break;
        !          4061:                }
        !          4062:        }
        !          4063:        np->rv_scntl3 = i+1;
        !          4064: 
        !          4065:        /*
        !          4066:         * Minimum synchronous period factor supported by the chip.
        !          4067:         * Btw, 'period' is in tenths of nanoseconds.
        !          4068:         */
        !          4069: 
        !          4070:        period = (4 * div_10M[0] + np->clock_khz - 1) / np->clock_khz;
        !          4071:        if      (period <= 250)         np->minsync = 10;
        !          4072:        else if (period <= 303)         np->minsync = 11;
        !          4073:        else if (period <= 500)         np->minsync = 12;
        !          4074:        else                            np->minsync = (period + 40 - 1) / 40;
        !          4075: 
        !          4076:        /*
        !          4077:         * Check against chip SCSI standard support (SCSI-2,ULTRA,ULTRA2).
        !          4078:         */
        !          4079: 
        !          4080:        if      (np->minsync < 25 && !(np->features & (FE_ULTRA|FE_ULTRA2)))
        !          4081:                np->minsync = 25;
        !          4082:        else if (np->minsync < 12 && !(np->features & FE_ULTRA2))
        !          4083:                np->minsync = 12;
        !          4084: 
        !          4085:        /*
        !          4086:         * Maximum synchronous period factor supported by the chip.
        !          4087:         */
        !          4088: 
        !          4089:        period = (11 * div_10M[np->clock_divn - 1]) / (4 * np->clock_khz);
        !          4090:        np->maxsync = period > 2540 ? 254 : period / 10;
        !          4091: 
        !          4092:        /*
        !          4093:        **      Prepare initial value of other IO registers
        !          4094:        */
        !          4095: #if defined SCSI_NCR_TRUST_BIOS_SETTING
        !          4096:        np->rv_scntl0   = np->sv_scntl0;
        !          4097:        np->rv_dmode    = np->sv_dmode;
        !          4098:        np->rv_dcntl    = np->sv_dcntl;
        !          4099:        np->rv_ctest3   = np->sv_ctest3;
        !          4100:        np->rv_ctest4   = np->sv_ctest4;
        !          4101:        np->rv_ctest5   = np->sv_ctest5;
        !          4102:        burst_max       = burst_code(np->sv_dmode, np->sv_ctest4, np->sv_ctest5);
        !          4103: #else
        !          4104: 
        !          4105:        /*
        !          4106:        **      Select burst length (dwords)
        !          4107:        */
        !          4108:        burst_max       = driver_setup.burst_max;
        !          4109:        if (burst_max == 255)
        !          4110:                burst_max = burst_code(np->sv_dmode, np->sv_ctest4, np->sv_ctest5);
        !          4111:        if (burst_max > 7)
        !          4112:                burst_max = 7;
        !          4113:        if (burst_max > np->maxburst)
        !          4114:                burst_max = np->maxburst;
        !          4115: 
        !          4116:        /*
        !          4117:        **      Select all supported special features
        !          4118:        */
        !          4119:        if (np->features & FE_ERL)
        !          4120:                np->rv_dmode    |= ERL;         /* Enable Read Line */
        !          4121:        if (np->features & FE_BOF)
        !          4122:                np->rv_dmode    |= BOF;         /* Burst Opcode Fetch */
        !          4123:        if (np->features & FE_ERMP)
        !          4124:                np->rv_dmode    |= ERMP;        /* Enable Read Multiple */
        !          4125:        if (np->features & FE_PFEN)
        !          4126:                np->rv_dcntl    |= PFEN;        /* Prefetch Enable */
        !          4127:        if (np->features & FE_CLSE)
        !          4128:                np->rv_dcntl    |= CLSE;        /* Cache Line Size Enable */
        !          4129:        if (np->features & FE_WRIE)
        !          4130:                np->rv_ctest3   |= WRIE;        /* Write and Invalidate */
        !          4131:        if (np->features & FE_DFS)
        !          4132:                np->rv_ctest5   |= DFS;         /* Dma Fifo Size */
        !          4133: 
        !          4134:        /*
        !          4135:        **      Select some other
        !          4136:        */
        !          4137:        if (driver_setup.master_parity)
        !          4138:                np->rv_ctest4   |= MPEE;        /* Master parity checking */
        !          4139:        if (driver_setup.scsi_parity)
        !          4140:                np->rv_scntl0   |= 0x0a;        /*  full arb., ena parity, par->ATN  */
        !          4141: 
        !          4142: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          4143:        /*
        !          4144:        **      Get parity checking, host ID and verbose mode from NVRAM
        !          4145:        **/
        !          4146:        if (nvram) {
        !          4147:                switch(nvram->type) {
        !          4148:                case SCSI_NCR_TEKRAM_NVRAM:
        !          4149:                        np->myaddr = nvram->data.Tekram.host_id & 0x0f;
        !          4150:                        break;
        !          4151:                case SCSI_NCR_SYMBIOS_NVRAM:
        !          4152:                        if (!(nvram->data.Symbios.flags & SYMBIOS_PARITY_ENABLE))
        !          4153:                                np->rv_scntl0  &= ~0x0a;
        !          4154:                        np->myaddr = nvram->data.Symbios.host_id & 0x0f;
        !          4155:                        if (nvram->data.Symbios.flags & SYMBIOS_VERBOSE_MSGS)
        !          4156:                                np->verbose += 1;
        !          4157:                        break;
        !          4158:                }
        !          4159:        }
        !          4160: #endif
        !          4161:        /*
        !          4162:        **  Get SCSI addr of host adapter (set by bios?).
        !          4163:        */
        !          4164:        if (!np->myaddr) np->myaddr = INB(nc_scid) & 0x07;
        !          4165:        if (!np->myaddr) np->myaddr = SCSI_NCR_MYADDR;
        !          4166: 
        !          4167: 
        !          4168: #endif /* SCSI_NCR_TRUST_BIOS_SETTING */
        !          4169: 
        !          4170:        /*
        !          4171:         *      Prepare initial io register bits for burst length
        !          4172:         */
        !          4173:        ncr_init_burst(np, burst_max);
        !          4174: 
        !          4175:        /*
        !          4176:        **      Set differential mode and LED support.
        !          4177:        **      Ignore these features for boards known to use a 
        !          4178:        **      specific GPIO wiring (Tekram only for now).
        !          4179:        **      Probe initial setting of GPREG and GPCNTL for 
        !          4180:        **      other ones.
        !          4181:        */
        !          4182:        if (!nvram || nvram->type != SCSI_NCR_TEKRAM_NVRAM) {
        !          4183:                switch(driver_setup.diff_support) {
        !          4184:                case 3:
        !          4185:                        if (INB(nc_gpreg) & 0x08)
        !          4186:                        break;
        !          4187:                case 2:
        !          4188:                        np->rv_stest2   |= 0x20;
        !          4189:                        break;
        !          4190:                case 1:
        !          4191:                        np->rv_stest2   |= (np->sv_stest2 & 0x20);
        !          4192:                        break;
        !          4193:                default:
        !          4194:                        break;
        !          4195:                }
        !          4196:        }
        !          4197:        if ((driver_setup.led_pin ||
        !          4198:             (nvram && nvram->type == SCSI_NCR_SYMBIOS_NVRAM)) &&
        !          4199:            !(np->sv_gpcntl & 0x01))
        !          4200:                np->features |= FE_LED0;
        !          4201: 
        !          4202:        /*
        !          4203:        **      Set irq mode.
        !          4204:        */
        !          4205:        switch(driver_setup.irqm) {
        !          4206:        case 2:
        !          4207:                np->rv_dcntl    |= IRQM;
        !          4208:                break;
        !          4209:        case 1:
        !          4210:                np->rv_dcntl    |= (np->sv_dcntl & IRQM);
        !          4211:                break;
        !          4212:        default:
        !          4213:                break;
        !          4214:        }
        !          4215: 
        !          4216:        /*
        !          4217:        **      Configure targets according to driver setup.
        !          4218:        **      If NVRAM present get targets setup from NVRAM.
        !          4219:        **      Allow to override sync, wide and NOSCAN from 
        !          4220:        **      boot command line.
        !          4221:        */
        !          4222:        for (i = 0 ; i < MAX_TARGET ; i++) {
        !          4223:                tcb_p tp = &np->target[i];
        !          4224: 
        !          4225:                tp->usrsync = 255;
        !          4226: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          4227:                if (nvram) {
        !          4228:                        switch(nvram->type) {
        !          4229:                        case SCSI_NCR_TEKRAM_NVRAM:
        !          4230:                                ncr_Tekram_setup_target(np, i, &nvram->data.Tekram);
        !          4231:                                break;
        !          4232:                        case SCSI_NCR_SYMBIOS_NVRAM:
        !          4233:                                ncr_Symbios_setup_target(np, i, &nvram->data.Symbios);
        !          4234:                                break;
        !          4235:                        }
        !          4236:                        if (driver_setup.use_nvram & 0x2)
        !          4237:                                tp->usrsync = driver_setup.default_sync;
        !          4238:                        if (driver_setup.use_nvram & 0x4)
        !          4239:                                tp->usrwide = driver_setup.max_wide;
        !          4240:                        if (driver_setup.use_nvram & 0x8)
        !          4241:                                tp->usrflag &= ~UF_NOSCAN;
        !          4242:                }
        !          4243:                else {
        !          4244: #else
        !          4245:                if (1) {
        !          4246: #endif
        !          4247:                        tp->usrsync = driver_setup.default_sync;
        !          4248:                        tp->usrwide = driver_setup.max_wide;
        !          4249:                        tp->usrtags = driver_setup.default_tags;
        !          4250:                        if (!driver_setup.disconnection)
        !          4251:                                np->target[i].usrflag = UF_NODISC;
        !          4252:                }
        !          4253:        }
        !          4254: 
        !          4255:        /*
        !          4256:        **      Announce all that stuff to user.
        !          4257:        */
        !          4258: 
        !          4259:        i = nvram ? nvram->type : 0;
        !          4260:        printf(KERN_INFO "%s: %sID %d, Fast-%d%s%s\n", ncr_name(np),
        !          4261:                i  == SCSI_NCR_SYMBIOS_NVRAM ? "Symbios format NVRAM, " :
        !          4262:                (i == SCSI_NCR_TEKRAM_NVRAM  ? "Tekram format NVRAM, " : ""),
        !          4263:                np->myaddr,
        !          4264:                np->minsync < 12 ? 40 : (np->minsync < 25 ? 20 : 10),
        !          4265:                (np->rv_scntl0 & 0xa)   ? ", Parity Checking"   : ", NO Parity",
        !          4266:                (np->rv_stest2 & 0x20)  ? ", Differential"      : "");
        !          4267: 
        !          4268:        if (bootverbose > 1) {
        !          4269:                printf ("%s: initial SCNTL3/DMODE/DCNTL/CTEST3/4/5 = "
        !          4270:                        "(hex) %02x/%02x/%02x/%02x/%02x/%02x\n",
        !          4271:                        ncr_name(np), np->sv_scntl3, np->sv_dmode, np->sv_dcntl,
        !          4272:                        np->sv_ctest3, np->sv_ctest4, np->sv_ctest5);
        !          4273: 
        !          4274:                printf ("%s: final   SCNTL3/DMODE/DCNTL/CTEST3/4/5 = "
        !          4275:                        "(hex) %02x/%02x/%02x/%02x/%02x/%02x\n",
        !          4276:                        ncr_name(np), np->rv_scntl3, np->rv_dmode, np->rv_dcntl,
        !          4277:                        np->rv_ctest3, np->rv_ctest4, np->rv_ctest5);
        !          4278:        }
        !          4279: 
        !          4280:        if (bootverbose && np->paddr2)
        !          4281:                printf (KERN_INFO "%s: on-board RAM at 0x%lx\n",
        !          4282:                        ncr_name(np), np->paddr2);
        !          4283: 
        !          4284:        return 0;
        !          4285: }
        !          4286: 
        !          4287: 
        !          4288: #ifdef SCSI_NCR_DEBUG_NVRAM
        !          4289: 
        !          4290: __initfunc(
        !          4291: void ncr_display_Symbios_nvram(ncb_p np, Symbios_nvram *nvram)
        !          4292: )
        !          4293: {
        !          4294:        int i;
        !          4295: 
        !          4296:        /* display Symbios nvram host data */
        !          4297:        printf("%s: HOST ID=%d%s%s%s%s\n",
        !          4298:                ncr_name(np), nvram->host_id & 0x0f,
        !          4299:                (nvram->flags  & SYMBIOS_SCAM_ENABLE)   ? " SCAM"       :"",
        !          4300:                (nvram->flags  & SYMBIOS_PARITY_ENABLE) ? " PARITY"     :"",
        !          4301:                (nvram->flags  & SYMBIOS_VERBOSE_MSGS)  ? " VERSBOSE"   :"", 
        !          4302:                (nvram->flags1 & SYMBIOS_SCAN_HI_LO)    ? " HI_LO"      :"");
        !          4303: 
        !          4304:        /* display Symbios nvram drive data */
        !          4305:        for (i = 0 ; i < 15 ; i++) {
        !          4306:                struct Symbios_target *tn = &nvram->target[i];
        !          4307:                printf("%s-%d:%s%s%s%s WIDTH=%d SYNC=%d TMO=%d\n",
        !          4308:                ncr_name(np), i,
        !          4309:                (tn->flags & SYMBIOS_DISCONNECT_ENABLE) ? " DISC"       : "",
        !          4310:                (tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME) ? " SCAN_BOOT"  : "",
        !          4311:                (tn->flags & SYMBIOS_SCAN_LUNS)         ? " SCAN_LUNS"  : "",
        !          4312:                (tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED)? " TCQ"        : "",
        !          4313:                tn->bus_width,
        !          4314:                tn->sync_period / 4,
        !          4315:                tn->timeout);
        !          4316:        }
        !          4317: }
        !          4318: 
        !          4319: static u_char Tekram_boot_delay[7] __initdata = {3, 5, 10, 20, 30, 60, 120};
        !          4320: 
        !          4321: __initfunc(
        !          4322: void ncr_display_Tekram_nvram(ncb_p np, Tekram_nvram *nvram)
        !          4323: )
        !          4324: {
        !          4325:        int i, tags, boot_delay;
        !          4326:        char *rem;
        !          4327: 
        !          4328:        /* display Tekram nvram host data */
        !          4329:        tags = 2 << nvram->max_tags_index;
        !          4330:        boot_delay = 0;
        !          4331:        if (nvram->boot_delay_index < 6)
        !          4332:                boot_delay = Tekram_boot_delay[nvram->boot_delay_index];
        !          4333:        switch((nvram->flags & TEKRAM_REMOVABLE_FLAGS) >> 6) {
        !          4334:        default:
        !          4335:        case 0: rem = "";                       break;
        !          4336:        case 1: rem = " REMOVABLE=boot device"; break;
        !          4337:        case 2: rem = " REMOVABLE=all";         break;
        !          4338:        }
        !          4339: 
        !          4340:        printf("%s: HOST ID=%d%s%s%s%s%s%s%s%s%s BOOT DELAY=%d tags=%d\n",
        !          4341:                ncr_name(np), nvram->host_id & 0x0f,
        !          4342:                (nvram->flags1 & SYMBIOS_SCAM_ENABLE)   ? " SCAM"       :"",
        !          4343:                (nvram->flags & TEKRAM_MORE_THAN_2_DRIVES) ? " >2DRIVES"        :"",
        !          4344:                (nvram->flags & TEKRAM_DRIVES_SUP_1GB)  ? " >1GB"       :"",
        !          4345:                (nvram->flags & TEKRAM_RESET_ON_POWER_ON) ? " RESET"    :"",
        !          4346:                (nvram->flags & TEKRAM_ACTIVE_NEGATION) ? " ACT_NEG"    :"",
        !          4347:                (nvram->flags & TEKRAM_IMMEDIATE_SEEK)  ? " IMM_SEEK"   :"",
        !          4348:                (nvram->flags & TEKRAM_SCAN_LUNS)       ? " SCAN_LUNS"  :"",
        !          4349:                (nvram->flags1 & TEKRAM_F2_F6_ENABLED)  ? " F2_F6"      :"",
        !          4350:                rem, boot_delay, tags);
        !          4351: 
        !          4352:        /* display Tekram nvram drive data */
        !          4353:        for (i = 0; i <= 15; i++) {
        !          4354:                int sync, j;
        !          4355:                struct Tekram_target *tn = &nvram->target[i];
        !          4356:                j = tn->sync_index & 0xf;
        !          4357:                sync = j < 12 ? Tekram_sync[j] : 255;
        !          4358:                printf("%s-%d:%s%s%s%s%s%s PERIOD=%d\n",
        !          4359:                ncr_name(np), i,
        !          4360:                (tn->flags & TEKRAM_PARITY_CHECK)       ? " PARITY"     : "",
        !          4361:                (tn->flags & TEKRAM_SYNC_NEGO)          ? " SYNC"       : "",
        !          4362:                (tn->flags & TEKRAM_DISCONNECT_ENABLE)  ? " DISC"       : "",
        !          4363:                (tn->flags & TEKRAM_START_CMD)          ? " START"      : "",
        !          4364:                (tn->flags & TEKRAM_TAGGED_COMMANDS)    ? " TCQ"        : "",
        !          4365:                (tn->flags & TEKRAM_WIDE_NEGO)          ? " WIDE"       : "",
        !          4366:                sync);
        !          4367:        }
        !          4368: }
        !          4369: #endif /* SCSI_NCR_DEBUG_NVRAM */
        !          4370: 
        !          4371: /*
        !          4372: **     Host attach and initialisations.
        !          4373: **
        !          4374: **     Allocate host data and ncb structure.
        !          4375: **     Request IO region and remap MMIO region.
        !          4376: **     Do chip initialization.
        !          4377: **     If all is OK, install interrupt handling and
        !          4378: **     start the timer daemon.
        !          4379: */
        !          4380: 
        !          4381: __initfunc(
        !          4382: static int ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
        !          4383: )
        !          4384: {
        !          4385:         struct host_data *host_data;
        !          4386:        ncb_p np;
        !          4387:         struct Scsi_Host *instance = 0;
        !          4388:        u_long flags = 0;
        !          4389:        ncr_nvram *nvram = device->nvram;
        !          4390: 
        !          4391: printf(KERN_INFO "ncr53c%s-%d: rev=0x%02x, base=0x%x, io_port=0x%x, irq=%d\n",
        !          4392:        device->chip.name, unit, device->chip.revision_id, device->slot.base,
        !          4393:        device->slot.io_port, device->slot.irq);
        !          4394: 
        !          4395:        /*
        !          4396:        **      Allocate host_data structure
        !          4397:        */
        !          4398:         if (!(instance = scsi_register(tpnt, sizeof(*host_data))))
        !          4399:                goto attach_error;
        !          4400: 
        !          4401:        /*
        !          4402:        **      Initialize structure.
        !          4403:        */
        !          4404:        host_data = (struct host_data *) instance->hostdata;
        !          4405: 
        !          4406:        /*
        !          4407:        **      Align np and first ccb to 32 boundary for cache line 
        !          4408:        **      bursting when copying the global header.
        !          4409:        */
        !          4410:        np        = (ncb_p) (((u_long) &host_data->_ncb_data) & NCB_ALIGN_MASK);
        !          4411:        host_data->ncb = np;
        !          4412:        bzero (np, sizeof (*np));
        !          4413: 
        !          4414:        np->ccb   = (ccb_p) (((u_long) &host_data->_ccb_data) & CCB_ALIGN_MASK);
        !          4415:        bzero (np->ccb, sizeof (*np->ccb));
        !          4416: 
        !          4417:        /*
        !          4418:        **      Store input informations in the host data structure.
        !          4419:        */
        !          4420:        strncpy(np->chip_name, device->chip.name, sizeof(np->chip_name) - 1);
        !          4421:        np->unit        = unit;
        !          4422:        np->verbose     = driver_setup.verbose;
        !          4423:        sprintf(np->inst_name, "ncr53c%s-%d", np->chip_name, np->unit);
        !          4424:        np->device_id   = device->chip.device_id;
        !          4425:        np->revision_id = device->chip.revision_id;
        !          4426:        np->features    = device->chip.features;
        !          4427:        np->clock_divn  = device->chip.nr_divisor;
        !          4428:        np->maxoffs     = device->chip.offset_max;
        !          4429:        np->maxburst    = device->chip.burst_max;
        !          4430: 
        !          4431:        np->script0  =
        !          4432:        (struct script *) (((u_long) &host_data->script_data) & SCR_ALIGN_MASK);
        !          4433:        np->scripth0 = &host_data->scripth_data;
        !          4434: 
        !          4435:        /*
        !          4436:        **    Initialize timer structure
        !          4437:         **
        !          4438:         */
        !          4439:        init_timer(&np->timer);
        !          4440:        np->timer.data     = (unsigned long) np;
        !          4441:        np->timer.function = ncr53c8xx_timeout;
        !          4442: 
        !          4443:        /*
        !          4444:        **      Try to map the controller chip to
        !          4445:        **      virtual and physical memory.
        !          4446:        */
        !          4447: 
        !          4448:        np->paddr       = device->slot.base;
        !          4449:        np->paddr2      = (np->features & FE_RAM)? device->slot.base_2 : 0;
        !          4450: 
        !          4451: #ifndef NCR_IOMAPPED
        !          4452:        np->vaddr = remap_pci_mem((u_long) np->paddr, (u_long) 128);
        !          4453:        if (!np->vaddr) {
        !          4454:                printf("%s: can't map memory mapped IO region\n", ncr_name(np));
        !          4455:                goto attach_error;
        !          4456:        }
        !          4457:        else
        !          4458:                if (bootverbose > 1)
        !          4459:                        printf("%s: using memory mapped IO at virtual address 0x%lx\n", ncr_name(np), (u_long) np->vaddr);
        !          4460: 
        !          4461:        /*
        !          4462:        **      Make the controller's registers available.
        !          4463:        **      Now the INB INW INL OUTB OUTW OUTL macros
        !          4464:        **      can be used safely.
        !          4465:        */
        !          4466: 
        !          4467:        np->reg = (struct ncr_reg*) np->vaddr;
        !          4468: 
        !          4469: #endif /* !defined NCR_IOMAPPED */
        !          4470: 
        !          4471:        /*
        !          4472:        **      Try to map the controller chip into iospace.
        !          4473:        */
        !          4474: 
        !          4475:        request_region(device->slot.io_port, 128, "ncr53c8xx");
        !          4476:        np->port = device->slot.io_port;
        !          4477: 
        !          4478: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          4479:        if (nvram) {
        !          4480:                switch(nvram->type) {
        !          4481:                case SCSI_NCR_SYMBIOS_NVRAM:
        !          4482: #ifdef SCSI_NCR_DEBUG_NVRAM
        !          4483:                        ncr_display_Symbios_nvram(np, &nvram->data.Symbios);
        !          4484: #endif
        !          4485:                        break;
        !          4486:                case SCSI_NCR_TEKRAM_NVRAM:
        !          4487: #ifdef SCSI_NCR_DEBUG_NVRAM
        !          4488:                        ncr_display_Tekram_nvram(np, &nvram->data.Tekram);
        !          4489: #endif
        !          4490:                        break;
        !          4491:                default:
        !          4492:                        nvram = 0;
        !          4493: #ifdef SCSI_NCR_DEBUG_NVRAM
        !          4494:                        printf("%s: NVRAM: None or invalid data.\n", ncr_name(np));
        !          4495: #endif
        !          4496:                }
        !          4497:        }
        !          4498: #endif
        !          4499: 
        !          4500:        /*
        !          4501:        **      Do chip dependent initialization.
        !          4502:        */
        !          4503:        (void)ncr_prepare_setting(np, nvram);
        !          4504: 
        !          4505: #ifndef NCR_IOMAPPED
        !          4506:        if (np->paddr2 && sizeof(struct script) <= 4096) {
        !          4507:                np->vaddr2 = remap_pci_mem((u_long) np->paddr2, (u_long) 4096);
        !          4508:                if (!np->vaddr2) {
        !          4509:                        printf("%s: can't map memory mapped IO region\n", ncr_name(np));
        !          4510:                        goto attach_error;
        !          4511:                }
        !          4512:                else
        !          4513:                        if (bootverbose > 1)
        !          4514:                                printf("%s: on-board ram mapped at virtual address 0x%lx\n", ncr_name(np), (u_long) np->vaddr2);
        !          4515:        }
        !          4516: #endif /* !defined NCR_IOMAPPED */
        !          4517: 
        !          4518:        /*
        !          4519:        **      Fill Linux host instance structure
        !          4520:        */
        !          4521: #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,0)
        !          4522:        instance->max_channel   = 0;
        !          4523:        instance->max_id        = np->maxwide ? 16 : 8;
        !          4524:        instance->max_lun       = SCSI_NCR_MAX_LUN;
        !          4525: #endif
        !          4526: #ifndef NCR_IOMAPPED
        !          4527:        instance->base          = (char *) np->reg;
        !          4528: #endif
        !          4529:        instance->irq           = device->slot.irq;
        !          4530:        instance->io_port       = device->slot.io_port;
        !          4531:        instance->n_io_port     = 128;
        !          4532:        instance->dma_channel   = 0;
        !          4533: #if LINUX_VERSION_CODE >= LinuxVersionCode(2,0,0)
        !          4534:        instance->select_queue_depths = ncr53c8xx_select_queue_depths;
        !          4535: #endif
        !          4536: 
        !          4537:        /*
        !          4538:        **      Patch script to physical addresses
        !          4539:        */
        !          4540:        ncr_script_fill (&script0, &scripth0);
        !          4541: 
        !          4542:        np->scripth     = np->scripth0;
        !          4543:        np->p_scripth   = vtophys(np->scripth);
        !          4544: 
        !          4545:        np->script      = (np->vaddr2) ? (struct script *) np->vaddr2 : np->script0;
        !          4546:        np->p_script    = (np->vaddr2) ? np->paddr2 : vtophys(np->script0);
        !          4547: 
        !          4548:        ncr_script_copy_and_bind (np, (ncrcmd *) &script0, (ncrcmd *) np->script0, sizeof(struct script));
        !          4549:        ncr_script_copy_and_bind (np, (ncrcmd *) &scripth0, (ncrcmd *) np->scripth0, sizeof(struct scripth));
        !          4550:        np->ccb->p_ccb          = vtophys (np->ccb);
        !          4551: 
        !          4552:        /*
        !          4553:        **    Patch the script for LED support.
        !          4554:        */
        !          4555: 
        !          4556:        if (np->features & FE_LED0) {
        !          4557:                np->script0->reselect[0]  =
        !          4558:                                cpu_to_scr(SCR_REG_REG(gpreg, SCR_OR,  0x01));
        !          4559:                np->script0->reselect1[0] =
        !          4560:                                cpu_to_scr(SCR_REG_REG(gpreg, SCR_AND, 0xfe));
        !          4561:                np->script0->reselect2[0] =
        !          4562:                                cpu_to_scr(SCR_REG_REG(gpreg, SCR_AND, 0xfe));
        !          4563:        }
        !          4564: 
        !          4565:        /*
        !          4566:        **      init data structure
        !          4567:        */
        !          4568: 
        !          4569:        np->jump_tcb.l_cmd      = cpu_to_scr(SCR_JUMP);
        !          4570:        np->jump_tcb.l_paddr    = cpu_to_scr(NCB_SCRIPTH_PHYS (np, abort));
        !          4571: 
        !          4572:        /*
        !          4573:        **      Reset chip.
        !          4574:        */
        !          4575: 
        !          4576:        OUTB (nc_istat,  SRST);
        !          4577:        DELAY (1000);
        !          4578:        OUTB (nc_istat,  0   );
        !          4579: 
        !          4580:        /*
        !          4581:        **      Now check the cache handling of the pci chipset.
        !          4582:        */
        !          4583: 
        !          4584:        if (ncr_snooptest (np)) {
        !          4585:                printf ("CACHE INCORRECTLY CONFIGURED.\n");
        !          4586:                goto attach_error;
        !          4587:        };
        !          4588: 
        !          4589:        /*
        !          4590:        **      Install the interrupt handler.
        !          4591:        */
        !          4592: #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,70)
        !          4593: #ifdef SCSI_NCR_SHARE_IRQ
        !          4594:        if (bootverbose > 1)
        !          4595:                printf("%s: requesting shared irq %d (dev_id=0x%lx)\n",
        !          4596:                        ncr_name(np), device->slot.irq, (u_long) np);
        !          4597:        if (request_irq(device->slot.irq, ncr53c8xx_intr,
        !          4598:                        SA_INTERRUPT|SA_SHIRQ, "ncr53c8xx", np)) {
        !          4599: #else
        !          4600:        if (request_irq(device->slot.irq, ncr53c8xx_intr,
        !          4601:                        SA_INTERRUPT, "ncr53c8xx", np)) {
        !          4602: #endif
        !          4603: #else
        !          4604:        if (request_irq(device->slot.irq, ncr53c8xx_intr,
        !          4605:                        SA_INTERRUPT, "ncr53c8xx")) {
        !          4606: #endif
        !          4607:                printf("%s: request irq %d failure\n", ncr_name(np), device->slot.irq);
        !          4608:                goto attach_error;
        !          4609:        }
        !          4610:        np->irq = device->slot.irq;
        !          4611: 
        !          4612:        /*
        !          4613:        **      After SCSI devices have been opened, we cannot
        !          4614:        **      reset the bus safely, so we do it here.
        !          4615:        **      Interrupt handler does the real work.
        !          4616:        **      Process the reset exception,
        !          4617:        **      if interrupts are not enabled yet.
        !          4618:        **      Then enable disconnects.
        !          4619:        */
        !          4620:        save_flags(flags); cli();
        !          4621:        if (ncr_reset_scsi_bus(np, 0, driver_setup.settle_delay) != 0) {
        !          4622:                printf("%s: FATAL ERROR: CHECK SCSI BUS - CABLES, TERMINATION, DEVICE POWER etc.!\n", ncr_name(np));
        !          4623:                restore_flags(flags);
        !          4624:                goto attach_error;
        !          4625:        }
        !          4626:        ncr_exception (np);
        !          4627:        restore_flags(flags);
        !          4628: 
        !          4629:        np->disc = 1;
        !          4630: 
        !          4631:        /*
        !          4632:        **      The middle-level SCSI driver does not
        !          4633:        **      wait devices to settle.
        !          4634:        **      Wait synchronously if more than 2 seconds.
        !          4635:        */
        !          4636:        if (driver_setup.settle_delay > 2) {
        !          4637:                printf("%s: waiting %d seconds for scsi devices to settle...\n",
        !          4638:                        ncr_name(np), driver_setup.settle_delay);
        !          4639:                DELAY(1000000UL * driver_setup.settle_delay);
        !          4640:        }
        !          4641: 
        !          4642:        /*
        !          4643:        **      Now let the generic SCSI driver
        !          4644:        **      look for the SCSI devices on the bus ..
        !          4645:        */
        !          4646: 
        !          4647:        /*
        !          4648:        **      start the timeout daemon
        !          4649:        */
        !          4650:        np->lasttime=0;
        !          4651:        ncr_timeout (np);
        !          4652: 
        !          4653:        /*
        !          4654:        **  use SIMPLE TAG messages by default
        !          4655:        */
        !          4656: #ifdef SCSI_NCR_ALWAYS_SIMPLE_TAG
        !          4657:        np->order = M_SIMPLE_TAG;
        !          4658: #endif
        !          4659: 
        !          4660:        /*
        !          4661:        **  Done.
        !          4662:        */
        !          4663:         if (!the_template) {
        !          4664:                the_template = instance->hostt;
        !          4665:                first_host = instance;
        !          4666:        }
        !          4667: 
        !          4668:        return 0;
        !          4669: 
        !          4670: attach_error:
        !          4671:        if (!instance) return -1;
        !          4672:        printf("%s: detaching...\n", ncr_name(np));
        !          4673: #ifndef NCR_IOMAPPED
        !          4674:        if (np->vaddr) {
        !          4675: #ifdef DEBUG_NCR53C8XX
        !          4676:                printf("%s: releasing memory mapped IO region %lx[%d]\n", ncr_name(np), (u_long) np->vaddr, 128);
        !          4677: #endif
        !          4678:                unmap_pci_mem((vm_offset_t) np->vaddr, (u_long) 128);
        !          4679:        }
        !          4680:        if (np->vaddr2) {
        !          4681: #ifdef DEBUG_NCR53C8XX
        !          4682:                printf("%s: releasing memory mapped IO region %lx[%d]\n", ncr_name(np), (u_long) np->vaddr2, 4096);
        !          4683: #endif
        !          4684:                unmap_pci_mem((vm_offset_t) np->vaddr2, (u_long) 4096);
        !          4685:        }
        !          4686: #endif
        !          4687:        if (np->port) {
        !          4688: #ifdef DEBUG_NCR53C8XX
        !          4689:                printf("%s: releasing IO region %x[%d]\n", ncr_name(np), np->port, 128);
        !          4690: #endif
        !          4691:                release_region(np->port, 128);
        !          4692:        }
        !          4693:        if (np->irq) {
        !          4694: #ifdef DEBUG_NCR53C8XX
        !          4695:                printf("%s: freeing irq %d\n", ncr_name(np), np->irq);
        !          4696: #endif
        !          4697: #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,70)
        !          4698:                free_irq(np->irq, np);
        !          4699: #else
        !          4700:                free_irq(np->irq);
        !          4701: #endif
        !          4702:        }
        !          4703:        scsi_unregister(instance);
        !          4704: 
        !          4705:         return -1;
        !          4706:  }
        !          4707: 
        !          4708: /*==========================================================
        !          4709: **
        !          4710: **
        !          4711: **     Start execution of a SCSI command.
        !          4712: **     This is called from the generic SCSI driver.
        !          4713: **
        !          4714: **
        !          4715: **==========================================================
        !          4716: */
        !          4717: int ncr_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
        !          4718: {
        !          4719:         struct Scsi_Host   *host      = cmd->host;
        !          4720: /*     Scsi_Device        *device    = cmd->device; */
        !          4721:        struct host_data   *host_data = (struct host_data *) host->hostdata;
        !          4722:        ncb_p np                      = host_data->ncb;
        !          4723:        tcb_p tp                      = &np->target[cmd->target];
        !          4724: 
        !          4725:        ccb_p cp;
        !          4726:        lcb_p lp;
        !          4727: 
        !          4728:        int     segments;
        !          4729:        u_char  qidx, nego, idmsg, *msgptr;
        !          4730:        u_int  msglen, msglen2;
        !          4731:        u_long  flags;
        !          4732:        int     xfer_direction;
        !          4733: 
        !          4734:        cmd->scsi_done     = done;
        !          4735:        cmd->host_scribble = NULL;
        !          4736:        cmd->SCp.ptr       = NULL;
        !          4737:        cmd->SCp.buffer    = NULL;
        !          4738: 
        !          4739:        /*---------------------------------------------
        !          4740:        **
        !          4741:        **      Some shortcuts ...
        !          4742:        **
        !          4743:        **---------------------------------------------
        !          4744:        */
        !          4745:        if ((cmd->target == np->myaddr    ) ||
        !          4746:                (cmd->target >= MAX_TARGET) ||
        !          4747:                (cmd->lun    >= MAX_LUN   )) {
        !          4748:                return(DID_BAD_TARGET);
        !          4749:         }
        !          4750: 
        !          4751:        /*---------------------------------------------
        !          4752:        **
        !          4753:        **      Complete the 1st TEST UNIT READY command
        !          4754:        **      with error condition if the device is 
        !          4755:        **      flagged NOSCAN, in order to speed up 
        !          4756:        **      the boot.
        !          4757:        **
        !          4758:        **---------------------------------------------
        !          4759:        */
        !          4760:        if (cmd->cmnd[0] == 0 && (tp->usrflag & UF_NOSCAN)) {
        !          4761:                tp->usrflag &= ~UF_NOSCAN;
        !          4762:                return DID_BAD_TARGET;
        !          4763:        }
        !          4764: 
        !          4765:        if (DEBUG_FLAGS & DEBUG_TINY) {
        !          4766:                PRINT_ADDR(cmd);
        !          4767:                printf ("CMD=%x ", cmd->cmnd[0]);
        !          4768:        }
        !          4769: 
        !          4770:        /*---------------------------------------------------
        !          4771:        **
        !          4772:        **      Assign a ccb / bind cmd.
        !          4773:        **      If resetting, shorten settle_time if necessary
        !          4774:        **      in order to avoid spurious timeouts.
        !          4775:        **      If resetting or no free ccb,
        !          4776:        **      insert cmd into the waiting list.
        !          4777:        **
        !          4778:        **----------------------------------------------------
        !          4779:        */
        !          4780:        save_flags(flags); cli();
        !          4781: 
        !          4782:        if (np->settle_time && cmd->timeout_per_command >= HZ &&
        !          4783:                np->settle_time > jiffies + cmd->timeout_per_command - HZ) {
        !          4784:                np->settle_time = jiffies + cmd->timeout_per_command - HZ;
        !          4785:        }
        !          4786: 
        !          4787:         if (np->settle_time || !(cp=ncr_get_ccb (np, cmd->target, cmd->lun))) {
        !          4788:                insert_into_waiting_list(np, cmd);
        !          4789:                restore_flags(flags);
        !          4790:                return(DID_OK);
        !          4791:        }
        !          4792:        cp->cmd = cmd;
        !          4793: 
        !          4794:        /*---------------------------------------------------
        !          4795:        **
        !          4796:        **      Enable tagged queue if asked by scsi ioctl
        !          4797:        **
        !          4798:        **----------------------------------------------------
        !          4799:        */
        !          4800:        if (!tp->usrtags && cmd->device && cmd->device->tagged_queue) {
        !          4801:                tp->usrtags = SCSI_NCR_MAX_TAGS;
        !          4802:                ncr_setmaxtags (np, tp, SCSI_NCR_MAX_TAGS);
        !          4803:        }
        !          4804: 
        !          4805:        /*---------------------------------------------------
        !          4806:        **
        !          4807:        **      timestamp
        !          4808:        **
        !          4809:        **----------------------------------------------------
        !          4810:        */
        !          4811: #ifdef SCSI_NCR_PROFILE_SUPPORT
        !          4812:        bzero (&cp->phys.header.stamp, sizeof (struct tstamp));
        !          4813:        cp->phys.header.stamp.start = jiffies;
        !          4814: #endif
        !          4815: 
        !          4816:        /*----------------------------------------------------
        !          4817:        **
        !          4818:        **      Get device quirks from a speciality table.
        !          4819:        **
        !          4820:        **      @GENSCSI@
        !          4821:        **      This should be a part of the device table
        !          4822:        **      in "scsi_conf.c".
        !          4823:        **
        !          4824:        **----------------------------------------------------
        !          4825:        */
        !          4826:        if (tp->quirks & QUIRK_UPDATE) {
        !          4827:                tp->quirks = ncr_lookup ((char*) &tp->inqdata[0]);
        !          4828: #ifndef NCR_GETCC_WITHMSG
        !          4829:                if (tp->quirks) {
        !          4830:                        PRINT_ADDR(cmd);
        !          4831:                        printf ("quirks=%x.\n", tp->quirks);
        !          4832:                }
        !          4833: #endif
        !          4834:        }
        !          4835: 
        !          4836:        /*---------------------------------------------------
        !          4837:        **
        !          4838:        **      negotiation required?
        !          4839:        **
        !          4840:        **      Only SCSI-II devices.
        !          4841:        **      To negotiate with SCSI-I devices is dangerous, since
        !          4842:        **      Synchronous Negotiation protocol is optional, and
        !          4843:        **      INQUIRY data do not contains capabilities in byte 7.
        !          4844:        **----------------------------------------------------
        !          4845:        */
        !          4846: 
        !          4847:        nego = 0;
        !          4848: 
        !          4849:        if (cmd->lun == 0 && !tp->nego_cp && 
        !          4850:            (tp->inqdata[2] & 0x7) >= 2 && tp->inqdata[7]) {
        !          4851:                /*
        !          4852:                **      negotiate wide transfers ?
        !          4853:                */
        !          4854: 
        !          4855:                if (!tp->widedone) {
        !          4856:                        if (tp->inqdata[7] & INQ7_WIDE16) {
        !          4857:                                nego = NS_WIDE;
        !          4858:                        } else
        !          4859:                                tp->widedone=1;
        !          4860:                };
        !          4861: 
        !          4862:                /*
        !          4863:                **      negotiate synchronous transfers?
        !          4864:                */
        !          4865: 
        !          4866:                if (!nego && !tp->period) {
        !          4867:                        if ( 1
        !          4868: #if defined (CDROM_ASYNC)
        !          4869:                            && ((tp->inqdata[0] & 0x1f) != 5)
        !          4870: #endif
        !          4871:                            && (tp->inqdata[7] & INQ7_SYNC)) {
        !          4872:                                nego = NS_SYNC;
        !          4873:                        } else {
        !          4874:                                tp->period  =0xffff;
        !          4875:                                tp->sval = 0xe0;
        !          4876:                                PRINT_ADDR(cmd);
        !          4877:                                printf ("asynchronous.\n");
        !          4878:                        };
        !          4879:                };
        !          4880: 
        !          4881:                /*
        !          4882:                **      remember nego is pending for the target.
        !          4883:                **      Avoid to start a nego for all queued commands 
        !          4884:                **      when tagged command queuing is enabled.
        !          4885:                */
        !          4886: 
        !          4887:                if (nego)
        !          4888:                        tp->nego_cp = cp;
        !          4889:        };
        !          4890: 
        !          4891:        /*---------------------------------------------------
        !          4892:        **
        !          4893:        **      choose a new tag ...
        !          4894:        **
        !          4895:        **----------------------------------------------------
        !          4896:        */
        !          4897: 
        !          4898:        if ((lp = tp->lp[cmd->lun]) && (lp->usetags)) {
        !          4899:                /*
        !          4900:                **      assign a tag to this ccb!
        !          4901:                */
        !          4902:                while (!cp->tag) {
        !          4903:                        ccb_p cp2 = lp->next_ccb;
        !          4904:                        lp->lasttag = lp->lasttag % 255 + 1;
        !          4905:                        while (cp2 && cp2->tag != lp->lasttag)
        !          4906:                                cp2 = cp2->next_ccb;
        !          4907:                        if (cp2) continue;
        !          4908:                        cp->tag=lp->lasttag;
        !          4909:                        if (DEBUG_FLAGS & DEBUG_TAGS) {
        !          4910:                                PRINT_ADDR(cmd);
        !          4911:                                printf ("using tag #%d.\n", cp->tag);
        !          4912:                        }
        !          4913:                }
        !          4914:        } else {
        !          4915:                cp->tag=0;
        !          4916:        }
        !          4917: 
        !          4918:        /*----------------------------------------------------
        !          4919:        **
        !          4920:        **      Build the identify / tag / sdtr message
        !          4921:        **
        !          4922:        **----------------------------------------------------
        !          4923:        */
        !          4924: 
        !          4925:        idmsg = M_IDENTIFY | cmd->lun;
        !          4926: 
        !          4927:        if (cp != np->ccb && ((np->disc && !(tp->usrflag & UF_NODISC)) || cp->tag))
        !          4928:                idmsg |= 0x40;
        !          4929: 
        !          4930:        msgptr = cp->scsi_smsg;
        !          4931:        msglen = 0;
        !          4932:        msgptr[msglen++] = idmsg;
        !          4933: 
        !          4934:        if (cp->tag) {
        !          4935:            char tag;
        !          4936: 
        !          4937:            tag = np->order;
        !          4938:            if (tag == 0) {
        !          4939:                /*
        !          4940:                **      Ordered write ops, unordered read ops.
        !          4941:                */
        !          4942:                switch (cmd->cmnd[0]) {
        !          4943:                case 0x08:  /* READ_SMALL (6) */
        !          4944:                case 0x28:  /* READ_BIG  (10) */
        !          4945:                case 0xa8:  /* READ_HUGE (12) */
        !          4946:                    tag = M_SIMPLE_TAG;
        !          4947:                    break;
        !          4948:                default:
        !          4949:                    tag = M_ORDERED_TAG;
        !          4950:                }
        !          4951:            }
        !          4952:            /*
        !          4953:            **  Have to force ordered tag to avoid timeouts
        !          4954:            */
        !          4955:            if ((lp = tp->lp[cmd->lun]) && (lp->force_ordered_tag)) {
        !          4956:                tag = M_ORDERED_TAG;
        !          4957:                lp->force_ordered_tag = 0;
        !          4958:                if (DEBUG_FLAGS & DEBUG_TAGS) {
        !          4959:                        PRINT_ADDR(cmd);
        !          4960:                        printf ("Ordered Queue Tag forced\n");
        !          4961:                }
        !          4962:            }
        !          4963:            msgptr[msglen++] = tag;
        !          4964:            msgptr[msglen++] = cp -> tag;
        !          4965:        }
        !          4966: 
        !          4967:        switch (nego) {
        !          4968:        case NS_SYNC:
        !          4969:                msgptr[msglen++] = M_EXTENDED;
        !          4970:                msgptr[msglen++] = 3;
        !          4971:                msgptr[msglen++] = M_X_SYNC_REQ;
        !          4972:                msgptr[msglen++] = tp->maxoffs ? tp->minsync : 0;
        !          4973:                msgptr[msglen++] = tp->maxoffs;
        !          4974:                if (DEBUG_FLAGS & DEBUG_NEGO) {
        !          4975:                        PRINT_ADDR(cp->cmd);
        !          4976:                        printf ("sync msgout: ");
        !          4977:                        ncr_show_msg (&cp->scsi_smsg [msglen-5]);
        !          4978:                        printf (".\n");
        !          4979:                };
        !          4980:                break;
        !          4981:        case NS_WIDE:
        !          4982:                msgptr[msglen++] = M_EXTENDED;
        !          4983:                msgptr[msglen++] = 2;
        !          4984:                msgptr[msglen++] = M_X_WIDE_REQ;
        !          4985:                msgptr[msglen++] = tp->usrwide;
        !          4986:                if (DEBUG_FLAGS & DEBUG_NEGO) {
        !          4987:                        PRINT_ADDR(cp->cmd);
        !          4988:                        printf ("wide msgout: ");
        !          4989:                        ncr_show_msg (&cp->scsi_smsg [msglen-4]);
        !          4990:                        printf (".\n");
        !          4991:                };
        !          4992:                break;
        !          4993:        };
        !          4994: 
        !          4995:        /*----------------------------------------------------
        !          4996:        **
        !          4997:        **      Build the identify message for getcc.
        !          4998:        **
        !          4999:        **----------------------------------------------------
        !          5000:        */
        !          5001: 
        !          5002:        cp -> scsi_smsg2 [0] = idmsg;
        !          5003:        msglen2 = 1;
        !          5004: 
        !          5005:        /*----------------------------------------------------
        !          5006:        **
        !          5007:        **      Build the data descriptors
        !          5008:        **
        !          5009:        **----------------------------------------------------
        !          5010:        */
        !          5011: 
        !          5012:        segments = ncr_scatter (cp, cp->cmd);
        !          5013: 
        !          5014:        if (segments < 0) {
        !          5015:                ncr_free_ccb(np, cp, cmd->target, cmd->lun);
        !          5016:                restore_flags(flags);
        !          5017:                return(DID_ERROR);
        !          5018:        }
        !          5019: 
        !          5020:        /*----------------------------------------------------
        !          5021:        **
        !          5022:        **      Guess xfer direction.
        !          5023:        **      Spare some CPU by testing here frequently opcode.
        !          5024:        **
        !          5025:        **----------------------------------------------------
        !          5026:        */
        !          5027:        switch((int) cmd->cmnd[0]) {
        !          5028:        case 0x08:  /*  READ(6)                         08 */
        !          5029:        case 0x28:  /*  READ(10)                        28 */
        !          5030:        case 0xA8:  /*  READ(12)                        A8 */
        !          5031:                xfer_direction = XferIn;
        !          5032:                break;
        !          5033:        case 0x0A:  /*  WRITE(6)                        0A */
        !          5034:        case 0x2A:  /*  WRITE(10)                       2A */
        !          5035:        case 0xAA:  /*  WRITE(12)                       AA */
        !          5036:                xfer_direction = XferOut;
        !          5037:                break;
        !          5038:        default:
        !          5039:                xfer_direction = guess_xfer_direction((int) cmd->cmnd[0]);
        !          5040:                break;
        !          5041:        }
        !          5042: 
        !          5043:        /*----------------------------------------------------
        !          5044:        **
        !          5045:        **      Set the SAVED_POINTER.
        !          5046:        **
        !          5047:        **----------------------------------------------------
        !          5048:        */
        !          5049: 
        !          5050:        cp->segments = segments;
        !          5051:        if (!cp->data_len)
        !          5052:                xfer_direction = XferNone;
        !          5053: 
        !          5054:        switch (xfer_direction) {
        !          5055:                u_long endp;
        !          5056:        default:
        !          5057:        case XferBoth:
        !          5058:                cp->phys.header.savep =
        !          5059:                        cpu_to_scr(NCB_SCRIPT_PHYS (np, data_io));
        !          5060:                cp->phys.header.goalp = cp->phys.header.savep;
        !          5061:                break;
        !          5062:        case XferIn:
        !          5063:                endp = NCB_SCRIPT_PHYS (np, data_in) + MAX_SCATTER*16;
        !          5064:                cp->phys.header.goalp = cpu_to_scr(endp + 8);
        !          5065:                cp->phys.header.savep = cpu_to_scr(endp - segments*16);
        !          5066:                break;
        !          5067:        case XferOut:
        !          5068:                endp = NCB_SCRIPTH_PHYS (np, data_out) + MAX_SCATTER*16;
        !          5069:                cp->phys.header.goalp = cpu_to_scr(endp + 8);
        !          5070:                cp->phys.header.savep = cpu_to_scr(endp - segments*16);
        !          5071:                break;
        !          5072:        case XferNone:
        !          5073:                cp->phys.header.savep =
        !          5074:                        cpu_to_scr(NCB_SCRIPT_PHYS (np, no_data));
        !          5075:                cp->phys.header.goalp = cp->phys.header.savep;
        !          5076:                break;
        !          5077:        }
        !          5078: 
        !          5079:        cp->phys.header.lastp = cp->phys.header.savep;
        !          5080: 
        !          5081:        /*----------------------------------------------------
        !          5082:        **
        !          5083:        **      fill in ccb
        !          5084:        **
        !          5085:        **----------------------------------------------------
        !          5086:        **
        !          5087:        **
        !          5088:        **      physical -> virtual backlink
        !          5089:        **      Generic SCSI command
        !          5090:        */
        !          5091:        cp->phys.header.cp              = cp;
        !          5092:        /*
        !          5093:        **      Startqueue
        !          5094:        */
        !          5095:        cp->phys.header.launch.l_paddr  =
        !          5096:                        cpu_to_scr(NCB_SCRIPT_PHYS (np, select));
        !          5097:        cp->phys.header.launch.l_cmd    = cpu_to_scr(SCR_JUMP);
        !          5098:        /*
        !          5099:        **      select
        !          5100:        */
        !          5101:        cp->phys.select.sel_id          = cmd->target;
        !          5102:        cp->phys.select.sel_scntl3      = tp->wval;
        !          5103:        cp->phys.select.sel_sxfer       = tp->sval;
        !          5104:        /*
        !          5105:        **      message
        !          5106:        */
        !          5107:        cp->phys.smsg.addr              = cpu_to_scr(CCB_PHYS (cp, scsi_smsg));
        !          5108:        cp->phys.smsg.size              = cpu_to_scr(msglen);
        !          5109: 
        !          5110:        cp->phys.smsg2.addr             = cpu_to_scr(CCB_PHYS (cp, scsi_smsg2));
        !          5111:        cp->phys.smsg2.size             = cpu_to_scr(msglen2);
        !          5112:        /*
        !          5113:        **      command
        !          5114:        */
        !          5115:        cp->phys.cmd.addr               = cpu_to_scr(vtophys (&cmd->cmnd[0]));
        !          5116:        cp->phys.cmd.size               = cpu_to_scr(cmd->cmd_len);
        !          5117:        /*
        !          5118:        **      sense command
        !          5119:        */
        !          5120:        cp->phys.scmd.addr              = cpu_to_scr(CCB_PHYS (cp, sensecmd));
        !          5121:        cp->phys.scmd.size              = cpu_to_scr(6);
        !          5122:        /*
        !          5123:        **      patch requested size into sense command
        !          5124:        */
        !          5125:        cp->sensecmd[0]                 = 0x03;
        !          5126:        cp->sensecmd[1]                 = cmd->lun << 5;
        !          5127:        cp->sensecmd[4]                 = sizeof(cmd->sense_buffer);
        !          5128:        /*
        !          5129:        **      sense data
        !          5130:        */
        !          5131:        cp->phys.sense.addr             =
        !          5132:                        cpu_to_scr(vtophys (&cmd->sense_buffer[0]));
        !          5133:        cp->phys.sense.size             = cpu_to_scr(sizeof(cmd->sense_buffer));
        !          5134:        /*
        !          5135:        **      status
        !          5136:        */
        !          5137:        cp->actualquirks                = tp->quirks;
        !          5138:        cp->host_status                 = nego ? HS_NEGOTIATE : HS_BUSY;
        !          5139:        cp->scsi_status                 = S_ILLEGAL;
        !          5140:        cp->parity_status               = 0;
        !          5141: 
        !          5142:        cp->xerr_status                 = XE_OK;
        !          5143:        cp->sync_status                 = tp->sval;
        !          5144:        cp->nego_status                 = nego;
        !          5145:        cp->wide_status                 = tp->wval;
        !          5146: 
        !          5147:        /*----------------------------------------------------
        !          5148:        **
        !          5149:        **      Critical region: start this job.
        !          5150:        **
        !          5151:        **----------------------------------------------------
        !          5152:        */
        !          5153: 
        !          5154:        /*
        !          5155:        **      reselect pattern and activate this job.
        !          5156:        */
        !          5157: 
        !          5158:        cp->jump_ccb.l_cmd      =
        !          5159:                cpu_to_scr((SCR_JUMP ^ IFFALSE (DATA (cp->tag))));
        !          5160: 
        !          5161:        /* Compute a time limit greater than the middle-level driver one */
        !          5162:        if (cmd->timeout_per_command > 0)
        !          5163:                cp->tlimit      = jiffies + cmd->timeout_per_command + NCR_TIMEOUT_INCREASE;
        !          5164:        else
        !          5165:                cp->tlimit      = jiffies + 3600 * HZ; /* No timeout=one hour */
        !          5166:        cp->magic               = CCB_MAGIC;
        !          5167: 
        !          5168:        /*
        !          5169:        **      insert into start queue.
        !          5170:        */
        !          5171: 
        !          5172:        qidx = np->squeueput + 1;
        !          5173:        if (qidx >= MAX_START) qidx=0;
        !          5174:        np->squeue [qidx         ] = cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
        !          5175:        np->squeue [np->squeueput] = cpu_to_scr(CCB_PHYS (cp, phys));
        !          5176:        np->squeueput = qidx;
        !          5177: 
        !          5178:        if(DEBUG_FLAGS & DEBUG_QUEUE)
        !          5179:                printf ("%s: queuepos=%d tryoffset=%d.\n", ncr_name (np),
        !          5180:                np->squeueput,
        !          5181:                (unsigned)(scr_to_cpu(np->script->startpos[0]) - 
        !          5182:                           (NCB_SCRIPTH_PHYS (np, tryloop))));
        !          5183: 
        !          5184:        /*
        !          5185:        **      Script processor may be waiting for reselect.
        !          5186:        **      Wake it up.
        !          5187:        */
        !          5188: #ifdef SCSI_NCR_DEBUG_ERROR_RECOVERY_SUPPORT
        !          5189:        if (!np->stalling)
        !          5190: #endif
        !          5191:        OUTB (nc_istat, SIGP);
        !          5192: 
        !          5193:        /*
        !          5194:        **      and reenable interrupts
        !          5195:        */
        !          5196:        restore_flags(flags);
        !          5197: 
        !          5198:        /*
        !          5199:        **      Command is successfully queued.
        !          5200:        */
        !          5201: 
        !          5202:        return(DID_OK);
        !          5203: }
        !          5204: 
        !          5205: /*==========================================================
        !          5206: **
        !          5207: **
        !          5208: **     Start reset process.
        !          5209: **     If reset in progress do nothing.
        !          5210: **     The interrupt handler will reinitialize the chip.
        !          5211: **     The timeout handler will wait for settle_time before 
        !          5212: **     clearing it and so resuming command processing.
        !          5213: **
        !          5214: **
        !          5215: **==========================================================
        !          5216: */
        !          5217: static void ncr_start_reset(ncb_p np, int settle_delay)
        !          5218: {
        !          5219:        u_long flags;
        !          5220: 
        !          5221:        save_flags(flags); cli();
        !          5222: 
        !          5223:        if (!np->settle_time) {
        !          5224:                (void) ncr_reset_scsi_bus(np, 1, settle_delay);
        !          5225:        }
        !          5226:        restore_flags(flags);
        !          5227: }
        !          5228: 
        !          5229: static int ncr_reset_scsi_bus(ncb_p np, int enab_int, int settle_delay)
        !          5230: {
        !          5231:        u_int32 term;
        !          5232:        int retv = 0;
        !          5233: 
        !          5234:        np->settle_time = jiffies + settle_delay * HZ;
        !          5235: 
        !          5236:        if (bootverbose > 1)
        !          5237:                printf("%s: resetting, "
        !          5238:                        "command processing suspended for %d seconds\n",
        !          5239:                        ncr_name(np), settle_delay);
        !          5240: 
        !          5241:        OUTB (nc_istat, SRST);
        !          5242:        DELAY (1000);
        !          5243:        OUTB (nc_istat, 0);
        !          5244:        if (enab_int)
        !          5245:                OUTW (nc_sien, RST);
        !          5246:        /*
        !          5247:        **      Enable Tolerant, reset IRQD if present and 
        !          5248:        **      properly set IRQ mode, prior to resetting the bus.
        !          5249:        */
        !          5250:        OUTB (nc_stest3, TE);
        !          5251:        OUTB (nc_dcntl, (np->rv_dcntl & IRQM));
        !          5252:        OUTB (nc_scntl1, CRST);
        !          5253:        DELAY (100);
        !          5254: 
        !          5255:        if (!driver_setup.bus_check)
        !          5256:                goto out;
        !          5257:        /*
        !          5258:        **      Check for no terminators or SCSI bus shorts to ground.
        !          5259:        **      Read SCSI data bus, data parity bits and control signals.
        !          5260:        **      We are expecting RESET to be TRUE and other signals to be 
        !          5261:        **      FALSE.
        !          5262:        */
        !          5263:        term =  INB(nc_sstat0);                         /* rst, sdp0 */
        !          5264:        term =  ((term & 2) << 7) + ((term & 1) << 16);
        !          5265:        term |= ((INB(nc_sstat2) & 0x01) << 25) |       /* sdp1 */
        !          5266:                (INW(nc_sbdl) << 9) |                   /* d15-0 */
        !          5267:                INB(nc_sbcl);   /* req, ack, bsy, sel, atn, msg, cd, io */
        !          5268: 
        !          5269:        if (!(np->features & FE_WIDE))
        !          5270:                term &= 0x3ffff;
        !          5271: 
        !          5272:        if (term != (2<<7)) {
        !          5273:                printf("%s: suspicious SCSI data while resetting the BUS.\n",
        !          5274:                        ncr_name(np));
        !          5275:                printf("%s: %sdp0,d7-0,rst,req,ack,bsy,sel,atn,msg,c/d,i/o = "
        !          5276:                        "0x%lx, expecting 0x%lx\n",
        !          5277:                        ncr_name(np),
        !          5278:                        (np->features & FE_WIDE) ? "dp1,d15-8," : "",
        !          5279:                        (u_long)term, (u_long)(2<<7));
        !          5280:                if (driver_setup.bus_check == 1)
        !          5281:                        retv = 1;
        !          5282:        }
        !          5283: out:
        !          5284:        OUTB (nc_scntl1, 0);
        !          5285:        return retv;
        !          5286: }
        !          5287: 
        !          5288: /*==========================================================
        !          5289: **
        !          5290: **
        !          5291: **     Reset the SCSI BUS.
        !          5292: **     This is called from the generic SCSI driver.
        !          5293: **
        !          5294: **
        !          5295: **==========================================================
        !          5296: */
        !          5297: int ncr_reset_bus (Scsi_Cmnd *cmd, int sync_reset)
        !          5298: {
        !          5299:         struct Scsi_Host   *host      = cmd->host;
        !          5300: /*     Scsi_Device        *device    = cmd->device; */
        !          5301:        struct host_data   *host_data = (struct host_data *) host->hostdata;
        !          5302:        ncb_p np                      = host_data->ncb;
        !          5303:        ccb_p cp;
        !          5304:        u_long flags;
        !          5305:        int found;
        !          5306: 
        !          5307: #ifdef SCSI_NCR_DEBUG_ERROR_RECOVERY_SUPPORT
        !          5308:        if (np->stalling)
        !          5309:                np->stalling = 0;
        !          5310: #endif
        !          5311: 
        !          5312:        save_flags(flags); cli();
        !          5313: /*
        !          5314:  * Return immediately if reset is in progress.
        !          5315:  */
        !          5316:        if (np->settle_time) {
        !          5317:                restore_flags(flags);
        !          5318:                return SCSI_RESET_PUNT;
        !          5319:        }
        !          5320: /*
        !          5321:  * Start the reset process.
        !          5322:  * The script processor is then assumed to be stopped.
        !          5323:  * Commands will now be queued in the waiting list until a settle 
        !          5324:  * delay of 2 seconds will be completed.
        !          5325:  */
        !          5326:        ncr_start_reset(np, driver_setup.settle_delay);
        !          5327: /*
        !          5328:  * First, look in the wakeup list
        !          5329:  */
        !          5330:        for (found=0, cp=np->ccb; cp; cp=cp->link_ccb) {
        !          5331:                /*
        !          5332:                **      look for the ccb of this command.
        !          5333:                */
        !          5334:                if (cp->host_status == HS_IDLE) continue;
        !          5335:                if (cp->cmd == cmd) {
        !          5336:                        found = 1;
        !          5337:                        break;
        !          5338:                }
        !          5339:        }
        !          5340: /*
        !          5341:  * Then, look in the waiting list
        !          5342:  */
        !          5343:        if (!found && retrieve_from_waiting_list(0, np, cmd))
        !          5344:                found = 1;
        !          5345: /*
        !          5346:  * Wake-up all awaiting commands with DID_RESET.
        !          5347:  */
        !          5348:        reset_waiting_list(np);
        !          5349: /*
        !          5350:  * Wake-up all pending commands with HS_RESET -> DID_RESET.
        !          5351:  */
        !          5352:        ncr_wakeup(np, HS_RESET);
        !          5353: /*
        !          5354:  * If the involved command was not in a driver queue, and the 
        !          5355:  * scsi driver told us reset is synchronous, and the command is not 
        !          5356:  * currently in the waiting list, complete it with DID_RESET status,
        !          5357:  * in order to keep it alive.
        !          5358:  */
        !          5359:        if (!found && sync_reset && !retrieve_from_waiting_list(0, np, cmd)) {
        !          5360:                cmd->result = ScsiResult(DID_RESET, 0);
        !          5361:                cmd->scsi_done(cmd);
        !          5362:        }
        !          5363: 
        !          5364:        restore_flags(flags);
        !          5365: 
        !          5366:        return SCSI_RESET_SUCCESS;
        !          5367: }
        !          5368: 
        !          5369: /*==========================================================
        !          5370: **
        !          5371: **
        !          5372: **     Abort an SCSI command.
        !          5373: **     This is called from the generic SCSI driver.
        !          5374: **
        !          5375: **
        !          5376: **==========================================================
        !          5377: */
        !          5378: static int ncr_abort_command (Scsi_Cmnd *cmd)
        !          5379: {
        !          5380:         struct Scsi_Host   *host      = cmd->host;
        !          5381: /*     Scsi_Device        *device    = cmd->device; */
        !          5382:        struct host_data   *host_data = (struct host_data *) host->hostdata;
        !          5383:        ncb_p np                      = host_data->ncb;
        !          5384:        ccb_p cp;
        !          5385:        u_long flags;
        !          5386:        int found;
        !          5387:        int retv;
        !          5388: 
        !          5389: #ifdef SCSI_NCR_DEBUG_ERROR_RECOVERY_SUPPORT
        !          5390:        if (np->stalling == 2)
        !          5391:                np->stalling = 0;
        !          5392: #endif
        !          5393: 
        !          5394:        save_flags(flags); cli();
        !          5395: /*
        !          5396:  * First, look for the scsi command in the waiting list
        !          5397:  */
        !          5398:        if (remove_from_waiting_list(np, cmd)) {
        !          5399:                cmd->result = ScsiResult(DID_ABORT, 0);
        !          5400:                cmd->scsi_done(cmd);
        !          5401:                restore_flags(flags);
        !          5402:                return SCSI_ABORT_SUCCESS;
        !          5403:        }
        !          5404: 
        !          5405: /*
        !          5406:  * Then, look in the wakeup list
        !          5407:  */
        !          5408:        for (found=0, cp=np->ccb; cp; cp=cp->link_ccb) {
        !          5409:                /*
        !          5410:                **      look for the ccb of this command.
        !          5411:                */
        !          5412:                if (cp->host_status == HS_IDLE) continue;
        !          5413:                if (cp->cmd == cmd) {
        !          5414:                        found = 1;
        !          5415:                        break;
        !          5416:                }
        !          5417:        }
        !          5418: 
        !          5419:        if (!found) {
        !          5420:                restore_flags(flags);
        !          5421:                return SCSI_ABORT_NOT_RUNNING;
        !          5422:        }
        !          5423: 
        !          5424:        if (np->settle_time) {
        !          5425:                restore_flags(flags);
        !          5426:                return SCSI_ABORT_SNOOZE;
        !          5427:        }
        !          5428: 
        !          5429:        /*
        !          5430:        **      Disable reselect.
        !          5431:        **      Remove it from startqueue.
        !          5432:        **      Set cp->tlimit to 0. The ncr_timeout() handler will use 
        !          5433:        **      this condition in order to complete the canceled command 
        !          5434:        **      after the script skipped the ccb, if necessary.
        !          5435:        */
        !          5436:        cp->jump_ccb.l_cmd = cpu_to_scr(SCR_JUMP);
        !          5437:        if (cp->phys.header.launch.l_paddr ==
        !          5438:                cpu_to_scr(NCB_SCRIPT_PHYS (np, select))) {
        !          5439:                printf ("%s: abort ccb=%p (skip)\n", ncr_name (np), cp);
        !          5440:                cp->phys.header.launch.l_paddr =
        !          5441:                        cpu_to_scr(NCB_SCRIPT_PHYS (np, skip));
        !          5442:        }
        !          5443: 
        !          5444:        cp->tlimit = 0;
        !          5445:        retv = SCSI_ABORT_PENDING;
        !          5446: 
        !          5447:        /*
        !          5448:        **      If there are no requests, the script
        !          5449:        **      processor will sleep on SEL_WAIT_RESEL.
        !          5450:        **      Let's wake it up, since it may have to work.
        !          5451:        */
        !          5452: #ifdef SCSI_NCR_DEBUG_ERROR_RECOVERY_SUPPORT
        !          5453:        if (!np->stalling)
        !          5454: #endif
        !          5455:        OUTB (nc_istat, SIGP);
        !          5456: 
        !          5457:        restore_flags(flags);
        !          5458: 
        !          5459:        return retv;
        !          5460: }
        !          5461: 
        !          5462: /*==========================================================
        !          5463: **
        !          5464: **     Linux release module stuff.
        !          5465: **
        !          5466: **     Called before unloading the module
        !          5467: **     Detach the host.
        !          5468: **     We have to free resources and halt the NCR chip
        !          5469: **
        !          5470: **==========================================================
        !          5471: */
        !          5472: 
        !          5473: #ifdef MODULE
        !          5474: static int ncr_detach(ncb_p np)
        !          5475: {
        !          5476:        ccb_p cp;
        !          5477:        tcb_p tp;
        !          5478:        lcb_p lp;
        !          5479:        int target, lun;
        !          5480:        int i;
        !          5481: 
        !          5482:        printf("%s: releasing host resources\n", ncr_name(np));
        !          5483: 
        !          5484: /*
        !          5485: **     Stop the ncr_timeout process
        !          5486: **     Set release_stage to 1 and wait that ncr_timeout() set it to 2.
        !          5487: */
        !          5488: 
        !          5489: #ifdef DEBUG_NCR53C8XX
        !          5490:        printf("%s: stopping the timer\n", ncr_name(np));
        !          5491: #endif
        !          5492:        np->release_stage = 1;
        !          5493:        for (i = 50 ; i && np->release_stage != 2 ; i--) DELAY(100000);
        !          5494:        if (np->release_stage != 2)
        !          5495:                printf("%s: the timer seems to be already stopped\n", ncr_name(np));
        !          5496:        else np->release_stage = 2;
        !          5497: 
        !          5498: /*
        !          5499: **     Disable chip interrupts
        !          5500: */
        !          5501: 
        !          5502: #ifdef DEBUG_NCR53C8XX
        !          5503:        printf("%s: disabling chip interrupts\n", ncr_name(np));
        !          5504: #endif
        !          5505:        OUTW (nc_sien , 0);
        !          5506:        OUTB (nc_dien , 0);
        !          5507: 
        !          5508: /*
        !          5509: **     Free irq
        !          5510: */
        !          5511: 
        !          5512: #ifdef DEBUG_NCR53C8XX
        !          5513:        printf("%s: freeing irq %d\n", ncr_name(np), np->irq);
        !          5514: #endif
        !          5515: #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,70)
        !          5516:        free_irq(np->irq, np);
        !          5517: #else
        !          5518:        free_irq(np->irq);
        !          5519: #endif
        !          5520: 
        !          5521:        /*
        !          5522:        **      Reset NCR chip
        !          5523:        **      Restore bios setting for automatic clock detection.
        !          5524:        */
        !          5525: 
        !          5526:        printf("%s: resetting chip\n", ncr_name(np));
        !          5527:        OUTB (nc_istat,  SRST);
        !          5528:        DELAY (1000);
        !          5529:        OUTB (nc_istat,  0   );
        !          5530: 
        !          5531:        OUTB(nc_dmode,  np->sv_dmode);
        !          5532:        OUTB(nc_dcntl,  np->sv_dcntl);
        !          5533:        OUTB(nc_ctest3, np->sv_ctest3);
        !          5534:        OUTB(nc_ctest4, np->sv_ctest4);
        !          5535:        OUTB(nc_ctest5, np->sv_ctest5);
        !          5536:        OUTB(nc_gpcntl, np->sv_gpcntl);
        !          5537:        OUTB(nc_stest2, np->sv_stest2);
        !          5538: 
        !          5539:        ncr_selectclock(np, np->sv_scntl3);
        !          5540: 
        !          5541:        /*
        !          5542:        **      Release Memory mapped IO region and IO mapped region
        !          5543:        */
        !          5544: 
        !          5545: #ifndef NCR_IOMAPPED
        !          5546: #ifdef DEBUG_NCR53C8XX
        !          5547:        printf("%s: releasing memory mapped IO region %lx[%d]\n", ncr_name(np), (u_long) np->vaddr, 128);
        !          5548: #endif
        !          5549:        unmap_pci_mem((vm_offset_t) np->vaddr, (u_long) 128);
        !          5550: #ifdef DEBUG_NCR53C8XX
        !          5551:        printf("%s: releasing memory mapped IO region %lx[%d]\n", ncr_name(np), (u_long) np->vaddr2, 4096);
        !          5552: #endif
        !          5553:        unmap_pci_mem((vm_offset_t) np->vaddr2, (u_long) 4096);
        !          5554: #endif
        !          5555: 
        !          5556: #ifdef DEBUG_NCR53C8XX
        !          5557:        printf("%s: releasing IO region %x[%d]\n", ncr_name(np), np->port, 128);
        !          5558: #endif
        !          5559:        release_region(np->port, 128);
        !          5560: 
        !          5561:        /*
        !          5562:        **      Free allocated ccb(s)
        !          5563:        */
        !          5564: 
        !          5565:        while ((cp=np->ccb->link_ccb) != NULL) {
        !          5566:                np->ccb->link_ccb = cp->link_ccb;
        !          5567:                if (cp->host_status) {
        !          5568:                printf("%s: shall free an active ccb (host_status=%d)\n",
        !          5569:                        ncr_name(np), cp->host_status);
        !          5570:                }
        !          5571: #ifdef DEBUG_NCR53C8XX
        !          5572:        printf("%s: freeing ccb (%lx)\n", ncr_name(np), (u_long) cp);
        !          5573: #endif
        !          5574:                m_free(cp, sizeof(*cp));
        !          5575:        }
        !          5576: 
        !          5577:        /*
        !          5578:        **      Free allocated tp(s)
        !          5579:        */
        !          5580: 
        !          5581:        for (target = 0; target < MAX_TARGET ; target++) {
        !          5582:                tp=&np->target[target];
        !          5583:                for (lun = 0 ; lun < MAX_LUN ; lun++) {
        !          5584:                        lp = tp->lp[lun];
        !          5585:                        if (lp) {
        !          5586: #ifdef DEBUG_NCR53C8XX
        !          5587:        printf("%s: freeing lp (%lx)\n", ncr_name(np), (u_long) lp);
        !          5588: #endif
        !          5589:                                m_free(lp, sizeof(*lp));
        !          5590:                        }
        !          5591:                }
        !          5592:        }
        !          5593: 
        !          5594:        printf("%s: host resources successfully released\n", ncr_name(np));
        !          5595: 
        !          5596:        return 1;
        !          5597: }
        !          5598: #endif
        !          5599: 
        !          5600: /*==========================================================
        !          5601: **
        !          5602: **
        !          5603: **     Complete execution of a SCSI command.
        !          5604: **     Signal completion to the generic SCSI driver.
        !          5605: **
        !          5606: **
        !          5607: **==========================================================
        !          5608: */
        !          5609: 
        !          5610: void ncr_complete (ncb_p np, ccb_p cp)
        !          5611: {
        !          5612:        Scsi_Cmnd *cmd;
        !          5613:        tcb_p tp;
        !          5614:        lcb_p lp;
        !          5615: 
        !          5616:        /*
        !          5617:        **      Sanity check
        !          5618:        */
        !          5619: 
        !          5620:        if (!cp || (cp->magic!=CCB_MAGIC) || !cp->cmd) return;
        !          5621:        cp->magic = 1;
        !          5622:        cp->tlimit= 0;
        !          5623:        cmd = cp->cmd;
        !          5624: 
        !          5625:        /*
        !          5626:        **      No Reselect anymore.
        !          5627:        */
        !          5628:        cp->jump_ccb.l_cmd = cpu_to_scr(SCR_JUMP);
        !          5629: 
        !          5630:        /*
        !          5631:        **      No starting.
        !          5632:        */
        !          5633:        cp->phys.header.launch.l_paddr = cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
        !          5634: 
        !          5635:        /*
        !          5636:        **      timestamp
        !          5637:        **      Optional, spare some CPU time
        !          5638:        */
        !          5639: #ifdef SCSI_NCR_PROFILE_SUPPORT
        !          5640:        ncb_profile (np, cp);
        !          5641: #endif
        !          5642: 
        !          5643:        if (DEBUG_FLAGS & DEBUG_TINY)
        !          5644:                printf ("CCB=%lx STAT=%x/%x\n", (unsigned long)cp & 0xfff,
        !          5645:                        cp->host_status,cp->scsi_status);
        !          5646: 
        !          5647:        cmd = cp->cmd;
        !          5648:        cp->cmd = NULL;
        !          5649:        tp = &np->target[cmd->target];
        !          5650:        lp = tp->lp[cmd->lun];
        !          5651: 
        !          5652:        /*
        !          5653:        **      We donnot queue more than 1 ccb per target 
        !          5654:        **      with negotiation at any time. If this ccb was 
        !          5655:        **      used for negotiation, clear this info in the tcb.
        !          5656:        */
        !          5657: 
        !          5658:        if (cp == tp->nego_cp)
        !          5659:                tp->nego_cp = 0;
        !          5660: 
        !          5661:        /*
        !          5662:        **      Check for parity errors.
        !          5663:        */
        !          5664: 
        !          5665:        if (cp->parity_status) {
        !          5666:                PRINT_ADDR(cmd);
        !          5667:                printf ("%d parity error(s), fallback.\n", cp->parity_status);
        !          5668:                /*
        !          5669:                **      fallback to asynch transfer.
        !          5670:                */
        !          5671:                tp->usrsync=255;
        !          5672:                tp->period =  0;
        !          5673:        }
        !          5674: 
        !          5675:        /*
        !          5676:        **      Check for extended errors.
        !          5677:        */
        !          5678: 
        !          5679:        if (cp->xerr_status != XE_OK) {
        !          5680:                PRINT_ADDR(cmd);
        !          5681:                switch (cp->xerr_status) {
        !          5682:                case XE_EXTRA_DATA:
        !          5683:                        printf ("extraneous data discarded.\n");
        !          5684:                        break;
        !          5685:                case XE_BAD_PHASE:
        !          5686:                        printf ("illegal scsi phase (4/5).\n");
        !          5687:                        break;
        !          5688:                default:
        !          5689:                        printf ("extended error %d.\n", cp->xerr_status);
        !          5690:                        break;
        !          5691:                }
        !          5692:                if (cp->host_status==HS_COMPLETE)
        !          5693:                        cp->host_status = HS_FAIL;
        !          5694:        }
        !          5695: 
        !          5696:        /*
        !          5697:        **      Check the status.
        !          5698:        */
        !          5699:        if (   (cp->host_status == HS_COMPLETE)
        !          5700:                && (cp->scsi_status == S_GOOD ||
        !          5701:                    cp->scsi_status == S_COND_MET)) {
        !          5702:                /*
        !          5703:                **      All went well (GOOD status).
        !          5704:                **      CONDITION MET status is returned on 
        !          5705:                **      `Pre-Fetch' or `Search data' success.
        !          5706:                */
        !          5707:                cmd->result = ScsiResult(DID_OK, cp->scsi_status);
        !          5708: 
        !          5709:                /*
        !          5710:                ** if (cp->phys.header.lastp != cp->phys.header.goalp)...
        !          5711:                **
        !          5712:                **      @RESID@
        !          5713:                **      Could dig out the correct value for resid,
        !          5714:                **      but it would be quite complicated.
        !          5715:                **
        !          5716:                **      The ah1542.c driver sets it to 0 too ...
        !          5717:                */
        !          5718: 
        !          5719:                /*
        !          5720:                **      Try to assign a ccb to this nexus
        !          5721:                */
        !          5722:                ncr_alloc_ccb (np, cmd->target, cmd->lun);
        !          5723: 
        !          5724:                /*
        !          5725:                **      On inquire cmd (0x12) save some data.
        !          5726:                **      Clear questionnable capacities.
        !          5727:                */
        !          5728:                if (cmd->lun == 0 && cmd->cmnd[0] == 0x12) {
        !          5729:                        if (np->unit < SCSI_NCR_MAX_HOST) {
        !          5730:                                if (driver_setup.force_sync_nego)
        !          5731:                                        ((char *) cmd->request_buffer)[7] |= INQ7_SYNC;
        !          5732:                                else
        !          5733:                                        ((char *) cmd->request_buffer)[7] &=
        !          5734:                                        (target_capabilities[np->unit].and_map[cmd->target]);
        !          5735:                        }
        !          5736:                        bcopy ( cmd->request_buffer,
        !          5737:                                &tp->inqdata,
        !          5738:                                sizeof (tp->inqdata));
        !          5739: 
        !          5740:                        /*
        !          5741:                        **      set number of tags
        !          5742:                        */
        !          5743:                                ncr_setmaxtags (np, tp, driver_setup.default_tags);
        !          5744:                        /*
        !          5745:                        **      prepare negotiation of synch and wide.
        !          5746:                        */
        !          5747:                        ncr_negotiate (np, tp);
        !          5748: 
        !          5749:                        /*
        !          5750:                        **      force quirks update before next command start
        !          5751:                        */
        !          5752:                        tp->quirks |= QUIRK_UPDATE;
        !          5753:                }
        !          5754: 
        !          5755:                /*
        !          5756:                **      Announce changes to the generic driver.
        !          5757:                */
        !          5758:                if (lp) {
        !          5759:                        ncr_settags (tp, lp);
        !          5760:                        if (lp->reqlink != lp->actlink)
        !          5761:                                ncr_opennings (np, lp, cmd);
        !          5762:                };
        !          5763: 
        !          5764:                tp->bytes     += cp->data_len;
        !          5765:                tp->transfers ++;
        !          5766: 
        !          5767:                /*
        !          5768:                **      If tags was reduced due to queue full,
        !          5769:                **      increase tags if 100 good status received.
        !          5770:                */
        !          5771:                if (tp->numtags < tp->maxtags) {
        !          5772:                        ++tp->num_good;
        !          5773:                        if (tp->num_good >= 100) {
        !          5774:                                tp->num_good = 0;
        !          5775:                                ++tp->numtags;
        !          5776:                                if (tp->numtags == 1) {
        !          5777:                                        PRINT_ADDR(cmd);
        !          5778:                                        printf("tagged command queueing resumed\n");
        !          5779:                                }
        !          5780:                        }
        !          5781:                }
        !          5782:        } else if ((cp->host_status == HS_COMPLETE)
        !          5783:                && (cp->scsi_status == (S_SENSE|S_GOOD) ||
        !          5784:                    cp->scsi_status == (S_SENSE|S_CHECK_COND))) {
        !          5785: 
        !          5786:                /*
        !          5787:                **   Check condition code
        !          5788:                */
        !          5789:                cmd->result = ScsiResult(DID_OK, S_CHECK_COND);
        !          5790: 
        !          5791:                if (DEBUG_FLAGS & (DEBUG_RESULT|DEBUG_TINY)) {
        !          5792:                        u_char * p = (u_char*) & cmd->sense_buffer;
        !          5793:                        int i;
        !          5794:                        printf ("\n%s: sense data:", ncr_name (np));
        !          5795:                        for (i=0; i<14; i++) printf (" %x", *p++);
        !          5796:                        printf (".\n");
        !          5797:                }
        !          5798: 
        !          5799:        } else if ((cp->host_status == HS_COMPLETE)
        !          5800:                && (cp->scsi_status == S_BUSY ||
        !          5801:                    cp->scsi_status == S_CONFLICT)) {
        !          5802: 
        !          5803:                /*
        !          5804:                **   Target is busy.
        !          5805:                */
        !          5806:                cmd->result = ScsiResult(DID_OK, cp->scsi_status);
        !          5807: 
        !          5808:        } else if ((cp->host_status == HS_COMPLETE)
        !          5809:                && (cp->scsi_status == S_QUEUE_FULL)) {
        !          5810: 
        !          5811:                /*
        !          5812:                **   Target is stuffed.
        !          5813:                */
        !          5814:                cmd->result = ScsiResult(DID_OK, cp->scsi_status);
        !          5815: 
        !          5816:                /*
        !          5817:                **  Suspend tagged queuing and start good status counter.
        !          5818:                **  Announce changes to the generic driver.
        !          5819:                */
        !          5820:                if (tp->numtags) {
        !          5821:                        PRINT_ADDR(cmd);
        !          5822:                        printf("QUEUE FULL! suspending tagged command queueing\n");
        !          5823:                        tp->numtags     = 0;
        !          5824:                        tp->num_good    = 0;
        !          5825:                        if (lp) {
        !          5826:                                ncr_settags (tp, lp);
        !          5827:                                if (lp->reqlink != lp->actlink)
        !          5828:                                        ncr_opennings (np, lp, cmd);
        !          5829:                        };
        !          5830:                }
        !          5831:        } else if ((cp->host_status == HS_SEL_TIMEOUT)
        !          5832:                || (cp->host_status == HS_TIMEOUT)) {
        !          5833: 
        !          5834:                /*
        !          5835:                **   No response
        !          5836:                */
        !          5837:                cmd->result = ScsiResult(DID_TIME_OUT, cp->scsi_status);
        !          5838: 
        !          5839:        } else if (cp->host_status == HS_RESET) {
        !          5840: 
        !          5841:                /*
        !          5842:                **   SCSI bus reset
        !          5843:                */
        !          5844:                cmd->result = ScsiResult(DID_RESET, cp->scsi_status);
        !          5845: 
        !          5846:        } else if (cp->host_status == HS_ABORTED) {
        !          5847: 
        !          5848:                /*
        !          5849:                **   Transfer aborted
        !          5850:                */
        !          5851:                cmd->result = ScsiResult(DID_ABORT, cp->scsi_status);
        !          5852: 
        !          5853:        } else {
        !          5854: 
        !          5855:                /*
        !          5856:                **  Other protocol messes
        !          5857:                */
        !          5858:                PRINT_ADDR(cmd);
        !          5859:                printf ("COMMAND FAILED (%x %x) @%p.\n",
        !          5860:                        cp->host_status, cp->scsi_status, cp);
        !          5861: 
        !          5862:                cmd->result = ScsiResult(DID_ERROR, cp->scsi_status);
        !          5863:        }
        !          5864: 
        !          5865:        /*
        !          5866:        **      trace output
        !          5867:        */
        !          5868: 
        !          5869:        if (tp->usrflag & UF_TRACE) {
        !          5870:                u_char * p;
        !          5871:                int i;
        !          5872:                PRINT_ADDR(cmd);
        !          5873:                printf (" CMD:");
        !          5874:                p = (u_char*) &cmd->cmnd[0];
        !          5875:                for (i=0; i<cmd->cmd_len; i++) printf (" %x", *p++);
        !          5876: 
        !          5877:                if (cp->host_status==HS_COMPLETE) {
        !          5878:                        switch (cp->scsi_status) {
        !          5879:                        case S_GOOD:
        !          5880:                                printf ("  GOOD");
        !          5881:                                break;
        !          5882:                        case S_CHECK_COND:
        !          5883:                                printf ("  SENSE:");
        !          5884:                                p = (u_char*) &cmd->sense_buffer;
        !          5885:                                for (i=0; i<14; i++)
        !          5886:                                        printf (" %x", *p++);
        !          5887:                                break;
        !          5888:                        default:
        !          5889:                                printf ("  STAT: %x\n", cp->scsi_status);
        !          5890:                                break;
        !          5891:                        }
        !          5892:                } else printf ("  HOSTERROR: %x", cp->host_status);
        !          5893:                printf ("\n");
        !          5894:        }
        !          5895: 
        !          5896:        /*
        !          5897:        **      Free this ccb
        !          5898:        */
        !          5899:        ncr_free_ccb (np, cp, cmd->target, cmd->lun);
        !          5900: 
        !          5901:        /*
        !          5902:        **      requeue awaiting scsi commands
        !          5903:        */
        !          5904:        if (np->waiting_list) requeue_waiting_list(np);
        !          5905: 
        !          5906:        /*
        !          5907:        **      signal completion to generic driver.
        !          5908:        */
        !          5909:        cmd->scsi_done (cmd);
        !          5910: }
        !          5911: 
        !          5912: /*==========================================================
        !          5913: **
        !          5914: **
        !          5915: **     Signal all (or one) control block done.
        !          5916: **
        !          5917: **
        !          5918: **==========================================================
        !          5919: */
        !          5920: 
        !          5921: void ncr_wakeup (ncb_p np, u_long code)
        !          5922: {
        !          5923:        /*
        !          5924:        **      Starting at the default ccb and following
        !          5925:        **      the links, complete all jobs with a
        !          5926:        **      host_status greater than "disconnect".
        !          5927:        **
        !          5928:        **      If the "code" parameter is not zero,
        !          5929:        **      complete all jobs that are not IDLE.
        !          5930:        */
        !          5931: 
        !          5932:        ccb_p cp = np->ccb;
        !          5933:        while (cp) {
        !          5934:                switch (cp->host_status) {
        !          5935: 
        !          5936:                case HS_IDLE:
        !          5937:                        break;
        !          5938: 
        !          5939:                case HS_DISCONNECT:
        !          5940:                        if(DEBUG_FLAGS & DEBUG_TINY) printf ("D");
        !          5941:                        /* fall through */
        !          5942: 
        !          5943:                case HS_BUSY:
        !          5944:                case HS_NEGOTIATE:
        !          5945:                        if (!code) break;
        !          5946:                        cp->host_status = code;
        !          5947: 
        !          5948:                        /* fall through */
        !          5949: 
        !          5950:                default:
        !          5951:                        ncr_complete (np, cp);
        !          5952:                        break;
        !          5953:                };
        !          5954:                cp = cp -> link_ccb;
        !          5955:        };
        !          5956: }
        !          5957: 
        !          5958: /*==========================================================
        !          5959: **
        !          5960: **
        !          5961: **     Start NCR chip.
        !          5962: **
        !          5963: **
        !          5964: **==========================================================
        !          5965: */
        !          5966: 
        !          5967: void ncr_init (ncb_p np, int reset, char * msg, u_long code)
        !          5968: {
        !          5969:        int     i;
        !          5970: 
        !          5971:        /*
        !          5972:        **      Reset chip if asked, otherwise just clear fifos.
        !          5973:        */
        !          5974:        if (reset) {
        !          5975:                OUTB (nc_istat,  SRST);
        !          5976:                DELAY (10000);
        !          5977:        }
        !          5978:        else {
        !          5979:                OUTB (nc_stest3, TE|CSF);
        !          5980:                OUTONB (nc_ctest3, CLF);
        !          5981:        }
        !          5982: 
        !          5983:        /*
        !          5984:        **      Message.
        !          5985:        */
        !          5986: 
        !          5987:        if (msg) printf (KERN_INFO "%s: restart (%s).\n", ncr_name (np), msg);
        !          5988: 
        !          5989:        /*
        !          5990:        **      Clear Start Queue
        !          5991:        */
        !          5992:        for (i=0;i<MAX_START;i++)
        !          5993:                np -> squeue [i] = cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
        !          5994: 
        !          5995:        /*
        !          5996:        **      Start at first entry.
        !          5997:        */
        !          5998:        np->squeueput = 0;
        !          5999:        np->script0->startpos[0] = cpu_to_scr(NCB_SCRIPTH_PHYS (np, tryloop));
        !          6000:        np->script0->start0  [0] = cpu_to_scr(SCR_INT ^ IFFALSE (0));
        !          6001: 
        !          6002:        /*
        !          6003:        **      Wakeup all pending jobs.
        !          6004:        */
        !          6005:        ncr_wakeup (np, code);
        !          6006: 
        !          6007:        /*
        !          6008:        **      Init chip.
        !          6009:        */
        !          6010: 
        !          6011:        OUTB (nc_istat,  0x00   );      /*  Remove Reset, abort */
        !          6012:        OUTB (nc_scntl0, np->rv_scntl0 | 0xc0);
        !          6013:                                        /*  full arb., ena parity, par->ATN  */
        !          6014:        OUTB (nc_scntl1, 0x00);         /*  odd parity, and remove CRST!! */
        !          6015: 
        !          6016:        ncr_selectclock(np, np->rv_scntl3);     /* Select SCSI clock */
        !          6017: 
        !          6018:        OUTB (nc_scid  , RRE|np->myaddr);       /* Adapter SCSI address */
        !          6019:        OUTW (nc_respid, 1ul<<np->myaddr);      /* Id to respond to */
        !          6020:        OUTB (nc_istat , SIGP   );              /*  Signal Process */
        !          6021:        OUTB (nc_dmode , np->rv_dmode);         /* Burst length, dma mode */
        !          6022:        OUTB (nc_ctest5, np->rv_ctest5);        /* Large fifo + large burst */
        !          6023: 
        !          6024:        OUTB (nc_dcntl , NOCOM|np->rv_dcntl);   /* Protect SFBR */
        !          6025:        OUTB (nc_ctest3, np->rv_ctest3);        /* Write and invalidate */
        !          6026:        OUTB (nc_ctest4, np->rv_ctest4);        /* Master parity checking */
        !          6027: 
        !          6028:        OUTB (nc_stest2, EXT|np->rv_stest2);    /* Extended Sreq/Sack filtering */
        !          6029:        OUTB (nc_stest3, TE);                   /* TolerANT enable */
        !          6030:        OUTB (nc_stime0, 0x0d   );              /* HTH disabled  STO 0.4 sec. */
        !          6031: 
        !          6032:        /*
        !          6033:        **      Disable disconnects.
        !          6034:        */
        !          6035: 
        !          6036:        np->disc = 0;
        !          6037: 
        !          6038:        /*
        !          6039:        **    Enable GPIO0 pin for writing if LED support.
        !          6040:        */
        !          6041: 
        !          6042:        if (np->features & FE_LED0) {
        !          6043:                OUTOFFB (nc_gpcntl, 0x01);
        !          6044:        }
        !          6045: 
        !          6046:        /*
        !          6047:        **    Upload the script into on-board RAM
        !          6048:        */
        !          6049:        if (np->vaddr2) {
        !          6050:                if (bootverbose)
        !          6051:                        printf ("%s: copying script fragments into the on-board RAM ...\n", ncr_name(np));
        !          6052: #if LINUX_VERSION_CODE >= LinuxVersionCode(2,0,0)
        !          6053:                memcpy_toio(np->script, np->script0, sizeof(struct script));
        !          6054: #else
        !          6055:                memcpy(np->script, np->script0, sizeof(struct script));
        !          6056: #endif
        !          6057:        }
        !          6058: 
        !          6059:        /*
        !          6060:        **      enable ints
        !          6061:        */
        !          6062: 
        !          6063:        OUTW (nc_sien , STO|HTH|MA|SGE|UDC|RST);
        !          6064:        OUTB (nc_dien , MDPE|BF|ABRT|SSI|SIR|IID);
        !          6065: 
        !          6066:        /*
        !          6067:        **      For 895/6 enable SBMC interrupt and save current SCSI bus mode.
        !          6068:        */
        !          6069:        if (np->features & FE_ULTRA2) {
        !          6070:                OUTONW (nc_sien, SBMC);
        !          6071:                np->scsi_mode = INB (nc_stest4) & SMODE;
        !          6072:        }
        !          6073: 
        !          6074:        /*
        !          6075:        **      Fill in target structure.
        !          6076:        **      Reinitialize usrsync.
        !          6077:        **      Reinitialize usrwide.
        !          6078:        **      Prepare sync negotiation according to actual SCSI bus mode.
        !          6079:        */
        !          6080: 
        !          6081:        for (i=0;i<MAX_TARGET;i++) {
        !          6082:                tcb_p tp = &np->target[i];
        !          6083: 
        !          6084:                tp->sval    = 0;
        !          6085:                tp->wval    = np->rv_scntl3;
        !          6086: 
        !          6087:                if (tp->usrsync != 255) {
        !          6088:                        if (tp->usrsync <= np->maxsync) {
        !          6089:                                if (tp->usrsync < np->minsync) {
        !          6090:                                        tp->usrsync = np->minsync;
        !          6091:                                }
        !          6092:                        }
        !          6093:                        else
        !          6094:                                tp->usrsync = 255;
        !          6095:                };
        !          6096: 
        !          6097:                if (tp->usrwide > np->maxwide)
        !          6098:                        tp->usrwide = np->maxwide;
        !          6099: 
        !          6100:                ncr_negotiate (np, tp);
        !          6101:        }
        !          6102: 
        !          6103:        /*
        !          6104:        **    Start script processor.
        !          6105:        */
        !          6106: 
        !          6107:        OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, start));
        !          6108: }
        !          6109: 
        !          6110: /*==========================================================
        !          6111: **
        !          6112: **     Prepare the negotiation values for wide and
        !          6113: **     synchronous transfers.
        !          6114: **
        !          6115: **==========================================================
        !          6116: */
        !          6117: 
        !          6118: static void ncr_negotiate (struct ncb* np, struct tcb* tp)
        !          6119: {
        !          6120:        /*
        !          6121:        **      minsync unit is 4ns !
        !          6122:        */
        !          6123: 
        !          6124:        u_long minsync = tp->usrsync;
        !          6125: 
        !          6126:        /*
        !          6127:        **      SCSI bus mode limit
        !          6128:        */
        !          6129: 
        !          6130:        if (np->scsi_mode && np->scsi_mode == SMODE_SE) {
        !          6131:                if (minsync < 12) minsync = 12;
        !          6132:        }
        !          6133: 
        !          6134:        /*
        !          6135:        **      if not scsi 2
        !          6136:        **      don't believe FAST!
        !          6137:        */
        !          6138: 
        !          6139:        if ((minsync < 50) && (tp->inqdata[2] & 0x0f) < 2)
        !          6140:                minsync=50;
        !          6141: 
        !          6142:        /*
        !          6143:        **      our limit ..
        !          6144:        */
        !          6145: 
        !          6146:        if (minsync < np->minsync)
        !          6147:                minsync = np->minsync;
        !          6148: 
        !          6149:        /*
        !          6150:        **      divider limit
        !          6151:        */
        !          6152: 
        !          6153:        if (minsync > np->maxsync)
        !          6154:                minsync = 255;
        !          6155: 
        !          6156:        tp->minsync = minsync;
        !          6157:        tp->maxoffs = (minsync<255 ? np->maxoffs : 0);
        !          6158: 
        !          6159:        /*
        !          6160:        **      period=0: has to negotiate sync transfer
        !          6161:        */
        !          6162: 
        !          6163:        tp->period=0;
        !          6164: 
        !          6165:        /*
        !          6166:        **      widedone=0: has to negotiate wide transfer
        !          6167:        */
        !          6168:        tp->widedone=0;
        !          6169: }
        !          6170: 
        !          6171: /*==========================================================
        !          6172: **
        !          6173: **     Get clock factor and sync divisor for a given 
        !          6174: **     synchronous factor period.
        !          6175: **     Returns the clock factor (in sxfer) and scntl3 
        !          6176: **     synchronous divisor field.
        !          6177: **
        !          6178: **==========================================================
        !          6179: */
        !          6180: 
        !          6181: static void ncr_getsync(ncb_p np, u_char sfac, u_char *fakp, u_char *scntl3p)
        !          6182: {
        !          6183:        u_long  clk = np->clock_khz;    /* SCSI clock frequency in kHz  */
        !          6184:        int     div = np->clock_divn;   /* Number of divisors supported */
        !          6185:        u_long  fak;                    /* Sync factor in sxfer         */
        !          6186:        u_long  per;                    /* Period in tenths of ns       */
        !          6187:        u_long  kpc;                    /* (per * clk)                  */
        !          6188: 
        !          6189:        /*
        !          6190:        **      Compute the synchronous period in tenths of nano-seconds
        !          6191:        */
        !          6192:        if      (sfac <= 10)    per = 250;
        !          6193:        else if (sfac == 11)    per = 303;
        !          6194:        else if (sfac == 12)    per = 500;
        !          6195:        else                    per = 40 * sfac;
        !          6196: 
        !          6197:        /*
        !          6198:        **      Look for the greatest clock divisor that allows an 
        !          6199:        **      input speed faster than the period.
        !          6200:        */
        !          6201:        kpc = per * clk;
        !          6202:        while (--div >= 0)
        !          6203:                if (kpc >= (div_10M[div] << 2)) break;
        !          6204: 
        !          6205:        /*
        !          6206:        **      Calculate the lowest clock factor that allows an output 
        !          6207:        **      speed not faster than the period.
        !          6208:        */
        !          6209:        fak = (kpc - 1) / div_10M[div] + 1;
        !          6210: 
        !          6211: #if 0  /* This optimization does not seem very usefull */
        !          6212: 
        !          6213:        per = (fak * div_10M[div]) / clk;
        !          6214: 
        !          6215:        /*
        !          6216:        **      Why not to try the immediate lower divisor and to choose 
        !          6217:        **      the one that allows the fastest output speed ?
        !          6218:        **      We don't want input speed too much greater than output speed.
        !          6219:        */
        !          6220:        if (div >= 1 && fak < 8) {
        !          6221:                u_long fak2, per2;
        !          6222:                fak2 = (kpc - 1) / div_10M[div-1] + 1;
        !          6223:                per2 = (fak2 * div_10M[div-1]) / clk;
        !          6224:                if (per2 < per && fak2 <= 8) {
        !          6225:                        fak = fak2;
        !          6226:                        per = per2;
        !          6227:                        --div;
        !          6228:                }
        !          6229:        }
        !          6230: #endif
        !          6231: 
        !          6232:        if (fak < 4) fak = 4;   /* Should never happen, too bad ... */
        !          6233: 
        !          6234:        /*
        !          6235:        **      Compute and return sync parameters for the ncr
        !          6236:        */
        !          6237:        *fakp           = fak - 4;
        !          6238:        *scntl3p        = ((div+1) << 4) + (sfac < 25 ? 0x80 : 0);
        !          6239: }
        !          6240: 
        !          6241: 
        !          6242: /*==========================================================
        !          6243: **
        !          6244: **     Set actual values, sync status and patch all ccbs of 
        !          6245: **     a target according to new sync/wide agreement.
        !          6246: **
        !          6247: **==========================================================
        !          6248: */
        !          6249: 
        !          6250: static void ncr_set_sync_wide_status (ncb_p np, u_char target)
        !          6251: {
        !          6252:        ccb_p cp;
        !          6253:        tcb_p tp = &np->target[target];
        !          6254: 
        !          6255:        /*
        !          6256:        **      set actual value and sync_status
        !          6257:        */
        !          6258:        OUTB (nc_sxfer, tp->sval);
        !          6259:        np->sync_st = tp->sval;
        !          6260:        OUTB (nc_scntl3, tp->wval);
        !          6261:        np->wide_st = tp->wval;
        !          6262: 
        !          6263:        /*
        !          6264:        **      patch ALL ccbs of this target.
        !          6265:        */
        !          6266:        for (cp = np->ccb; cp; cp = cp->link_ccb) {
        !          6267:                if (!cp->cmd) continue;
        !          6268:                if (cp->cmd->target != target) continue;
        !          6269:                cp->sync_status = tp->sval;
        !          6270:                cp->wide_status = tp->wval;
        !          6271:        };
        !          6272: }
        !          6273: 
        !          6274: /*==========================================================
        !          6275: **
        !          6276: **     Switch sync mode for current job and it's target
        !          6277: **
        !          6278: **==========================================================
        !          6279: */
        !          6280: 
        !          6281: static void ncr_setsync (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer)
        !          6282: {
        !          6283:        Scsi_Cmnd *cmd;
        !          6284:        tcb_p tp;
        !          6285:        u_char target = INB (nc_ctest0) & 0x0f;
        !          6286:        u_char idiv;
        !          6287: 
        !          6288:        assert (cp);
        !          6289:        if (!cp) return;
        !          6290: 
        !          6291:        cmd = cp->cmd;
        !          6292:        assert (cmd);
        !          6293:        if (!cmd) return;
        !          6294:        assert (target == (cmd->target & 0xf));
        !          6295: 
        !          6296:        tp = &np->target[target];
        !          6297: 
        !          6298:        if (!scntl3 || !(sxfer & 0x1f))
        !          6299:                scntl3 = np->rv_scntl3;
        !          6300:        scntl3 = (scntl3 & 0xf0) | (tp->wval & EWS) | (np->rv_scntl3 & 0x07);
        !          6301: 
        !          6302:        /*
        !          6303:        **      Deduce the value of controller sync period from scntl3.
        !          6304:        **      period is in tenths of nano-seconds.
        !          6305:        */
        !          6306: 
        !          6307:        idiv = ((scntl3 >> 4) & 0x7);
        !          6308:        if ((sxfer & 0x1f) && idiv)
        !          6309:                tp->period = (((sxfer>>5)+4)*div_10M[idiv-1])/np->clock_khz;
        !          6310:        else
        !          6311:                tp->period = 0xffff;
        !          6312: 
        !          6313:        /*
        !          6314:        **       Stop there if sync parameters are unchanged
        !          6315:        */
        !          6316:        if (tp->sval == sxfer && tp->wval == scntl3) return;
        !          6317:        tp->sval = sxfer;
        !          6318:        tp->wval = scntl3;
        !          6319: 
        !          6320:        /*
        !          6321:        **      Bells and whistles   ;-)
        !          6322:        */
        !          6323:        PRINT_ADDR(cmd);
        !          6324:        if (sxfer & 0x01f) {
        !          6325:                unsigned f10 = 100000 << (tp->widedone ? tp->widedone -1 : 0);
        !          6326:                unsigned mb10 = (f10 + tp->period/2) / tp->period;
        !          6327:                char *scsi;
        !          6328: 
        !          6329:                /*
        !          6330:                **  Disable extended Sreq/Sack filtering
        !          6331:                */
        !          6332:                if (tp->period <= 2000) OUTOFFB (nc_stest2, EXT);
        !          6333: 
        !          6334:                /*
        !          6335:                **      Bells and whistles   ;-)
        !          6336:                */
        !          6337:                if      (tp->period < 500)      scsi = "FAST-40";
        !          6338:                else if (tp->period < 1000)     scsi = "FAST-20";
        !          6339:                else if (tp->period < 2000)     scsi = "FAST-10";
        !          6340:                else                            scsi = "FAST-5";
        !          6341: 
        !          6342:                printf ("%s %sSCSI %d.%d MB/s (%d ns, offset %d)\n", scsi,
        !          6343:                        tp->widedone > 1 ? "WIDE " : "",
        !          6344:                        mb10 / 10, mb10 % 10, tp->period / 10, sxfer & 0x1f);
        !          6345:        } else
        !          6346:                printf ("%sasynchronous.\n", tp->widedone > 1 ? "wide " : "");
        !          6347: 
        !          6348:        /*
        !          6349:        **      set actual value and sync_status
        !          6350:        **      patch ALL ccbs of this target.
        !          6351:        */
        !          6352:        ncr_set_sync_wide_status(np, target);
        !          6353: }
        !          6354: 
        !          6355: /*==========================================================
        !          6356: **
        !          6357: **     Switch wide mode for current job and it's target
        !          6358: **     SCSI specs say: a SCSI device that accepts a WDTR 
        !          6359: **     message shall reset the synchronous agreement to 
        !          6360: **     asynchronous mode.
        !          6361: **
        !          6362: **==========================================================
        !          6363: */
        !          6364: 
        !          6365: static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide, u_char ack)
        !          6366: {
        !          6367:        Scsi_Cmnd *cmd;
        !          6368:        u_short target = INB (nc_ctest0) & 0x0f;
        !          6369:        tcb_p tp;
        !          6370:        u_char  scntl3;
        !          6371:        u_char  sxfer;
        !          6372: 
        !          6373:        assert (cp);
        !          6374:        if (!cp) return;
        !          6375: 
        !          6376:        cmd = cp->cmd;
        !          6377:        assert (cmd);
        !          6378:        if (!cmd) return;
        !          6379:        assert (target == (cmd->target & 0xf));
        !          6380: 
        !          6381:        tp = &np->target[target];
        !          6382:        tp->widedone  =  wide+1;
        !          6383:        scntl3 = (tp->wval & (~EWS)) | (wide ? EWS : 0);
        !          6384: 
        !          6385:        sxfer = ack ? 0 : tp->sval;
        !          6386: 
        !          6387:        /*
        !          6388:        **       Stop there if sync/wide parameters are unchanged
        !          6389:        */
        !          6390:        if (tp->sval == sxfer && tp->wval == scntl3) return;
        !          6391:        tp->sval = sxfer;
        !          6392:        tp->wval = scntl3;
        !          6393: 
        !          6394:        /*
        !          6395:        **      Bells and whistles   ;-)
        !          6396:        */
        !          6397:        if (bootverbose >= 2) {
        !          6398:                PRINT_ADDR(cmd);
        !          6399:                if (scntl3 & EWS)
        !          6400:                        printf ("WIDE SCSI (16 bit) enabled.\n");
        !          6401:                else
        !          6402:                        printf ("WIDE SCSI disabled.\n");
        !          6403:        }
        !          6404: 
        !          6405:        /*
        !          6406:        **      set actual value and sync_status
        !          6407:        **      patch ALL ccbs of this target.
        !          6408:        */
        !          6409:        ncr_set_sync_wide_status(np, target);
        !          6410: }
        !          6411: 
        !          6412: /*==========================================================
        !          6413: **
        !          6414: **     Switch tagged mode for a target.
        !          6415: **
        !          6416: **==========================================================
        !          6417: */
        !          6418: 
        !          6419: static void ncr_setmaxtags (ncb_p np, tcb_p tp, u_long numtags)
        !          6420: {
        !          6421:        int l;
        !          6422:        if (numtags > tp->usrtags)
        !          6423:                numtags = tp->usrtags;
        !          6424:        tp->numtags = numtags;
        !          6425:        tp->maxtags = numtags;
        !          6426: 
        !          6427:        for (l=0; l<MAX_LUN; l++) {
        !          6428:                lcb_p lp;
        !          6429:                u_char wastags;
        !          6430: 
        !          6431:                if (!tp) break;
        !          6432:                lp=tp->lp[l];
        !          6433:                if (!lp) continue;
        !          6434: 
        !          6435:                wastags = lp->usetags;
        !          6436:                ncr_settags (tp, lp);
        !          6437: 
        !          6438:                if (numtags > 1 && lp->reqccbs > 1) {
        !          6439:                        PRINT_LUN(np, tp - np->target, l);
        !          6440:                        printf("using tagged command queueing, up to %ld cmds/lun\n", numtags);
        !          6441:                }
        !          6442:                else if (numtags <= 1 && wastags) {
        !          6443:                        PRINT_LUN(np, tp - np->target, l);
        !          6444:                        printf("disabling tagged command queueing\n");
        !          6445:                }
        !          6446:        };
        !          6447: }
        !          6448: 
        !          6449: static void ncr_settags (tcb_p tp, lcb_p lp)
        !          6450: {
        !          6451:        u_char reqtags, tmp;
        !          6452: 
        !          6453:        if ((!tp) || (!lp)) return;
        !          6454: 
        !          6455:        /*
        !          6456:        **      only devices conformant to ANSI Version >= 2
        !          6457:        **      only devices capable of tagges commands
        !          6458:        **      only disk devices
        !          6459:        **      only if enabled by user ..
        !          6460:        */
        !          6461:        if ((  tp->inqdata[2] & 0x7) >= 2 &&
        !          6462:            (  tp->inqdata[7] & INQ7_QUEUE) && ((tp->inqdata[0] & 0x1f)==0x00)
        !          6463:                && tp->numtags > 1) {
        !          6464:                reqtags = tp->numtags;
        !          6465:                if (lp->actlink <= 1)
        !          6466:                        lp->usetags=reqtags;
        !          6467:        } else {
        !          6468:                reqtags = 1;
        !          6469:                if (lp->actlink <= 1)
        !          6470:                        lp->usetags=0;
        !          6471:        };
        !          6472: 
        !          6473:        /*
        !          6474:        **      don't announce more than available.
        !          6475:        */
        !          6476:        tmp = lp->actccbs;
        !          6477:        if (tmp > reqtags) tmp = reqtags;
        !          6478:        lp->reqlink = tmp;
        !          6479: 
        !          6480:        /*
        !          6481:        **      don't discard if announced.
        !          6482:        */
        !          6483:        tmp = lp->actlink;
        !          6484:        if (tmp < reqtags) tmp = reqtags;
        !          6485:        lp->reqccbs = tmp;
        !          6486: }
        !          6487: 
        !          6488: /*----------------------------------------------------
        !          6489: **
        !          6490: **     handle user commands
        !          6491: **
        !          6492: **----------------------------------------------------
        !          6493: */
        !          6494: 
        !          6495: #ifdef SCSI_NCR_USER_COMMAND_SUPPORT
        !          6496: 
        !          6497: static void ncr_usercmd (ncb_p np)
        !          6498: {
        !          6499:        u_char t;
        !          6500:        tcb_p tp;
        !          6501: 
        !          6502:        switch (np->user.cmd) {
        !          6503: 
        !          6504:        case 0: return;
        !          6505: 
        !          6506:        case UC_SETSYNC:
        !          6507:                for (t=0; t<MAX_TARGET; t++) {
        !          6508:                        if (!((np->user.target>>t)&1)) continue;
        !          6509:                        tp = &np->target[t];
        !          6510:                        tp->usrsync = np->user.data;
        !          6511:                        ncr_negotiate (np, tp);
        !          6512:                };
        !          6513:                break;
        !          6514: 
        !          6515:        case UC_SETTAGS:
        !          6516:                if (np->user.data > SCSI_NCR_MAX_TAGS)
        !          6517:                        np->user.data = SCSI_NCR_MAX_TAGS;
        !          6518:                for (t=0; t<MAX_TARGET; t++) {
        !          6519:                        if (!((np->user.target>>t)&1)) continue;
        !          6520:                        np->target[t].usrtags = np->user.data;
        !          6521:                        ncr_setmaxtags (np, &np->target[t], np->user.data);
        !          6522:                };
        !          6523:                break;
        !          6524: 
        !          6525:        case UC_SETDEBUG:
        !          6526: #ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
        !          6527:                ncr_debug = np->user.data;
        !          6528: #endif
        !          6529:                break;
        !          6530: 
        !          6531:        case UC_SETORDER:
        !          6532:                np->order = np->user.data;
        !          6533:                break;
        !          6534: 
        !          6535:        case UC_SETWIDE:
        !          6536:                for (t=0; t<MAX_TARGET; t++) {
        !          6537:                        u_long size;
        !          6538:                        if (!((np->user.target>>t)&1)) continue;
        !          6539:                        tp = &np->target[t];
        !          6540:                        size = np->user.data;
        !          6541:                        if (size > np->maxwide) size=np->maxwide;
        !          6542:                        tp->usrwide = size;
        !          6543:                        ncr_negotiate (np, tp);
        !          6544:                };
        !          6545:                break;
        !          6546: 
        !          6547:        case UC_SETFLAG:
        !          6548:                for (t=0; t<MAX_TARGET; t++) {
        !          6549:                        if (!((np->user.target>>t)&1)) continue;
        !          6550:                        tp = &np->target[t];
        !          6551:                        tp->usrflag = np->user.data;
        !          6552:                };
        !          6553:                break;
        !          6554: 
        !          6555:        case UC_CLEARPROF:
        !          6556:                bzero(&np->profile, sizeof(np->profile));
        !          6557:                break;
        !          6558: #ifdef UC_DEBUG_ERROR_RECOVERY
        !          6559:        case UC_DEBUG_ERROR_RECOVERY:
        !          6560:                np->debug_error_recovery = np->user.data;
        !          6561:                break;
        !          6562: #endif
        !          6563:        }
        !          6564:        np->user.cmd=0;
        !          6565: }
        !          6566: #endif
        !          6567: 
        !          6568: 
        !          6569: /*=====================================================================
        !          6570: **
        !          6571: **    Embedded error recovery debugging code.
        !          6572: **
        !          6573: **=====================================================================
        !          6574: **
        !          6575: **    This code is conditionned by SCSI_NCR_DEBUG_ERROR_RECOVERY_SUPPORT.
        !          6576: **    It only can be enabled after boot-up with a control command.
        !          6577: **
        !          6578: **    Every 30 seconds the timer handler of the driver decides to 
        !          6579: **    change the behaviour of the driver in order to trigger errors.
        !          6580: **
        !          6581: **    If last command was "debug_error_recovery sge", the driver 
        !          6582: **    sets sync offset of all targets that use sync transfers to 2, 
        !          6583: **    and so hopes a SCSI gross error at the next read operation.
        !          6584: **
        !          6585: **    If last command was "debug_error_recovery abort", the driver 
        !          6586: **    does not signal new scsi commands to the script processor, until 
        !          6587: **    it is asked to abort or reset a command by the mid-level driver.
        !          6588: **
        !          6589: **    If last command was "debug_error_recovery reset", the driver 
        !          6590: **    does not signal new scsi commands to the script processor, until 
        !          6591: **    it is asked to reset a command by the mid-level driver.
        !          6592: **
        !          6593: **    If last command was "debug_error_recovery parity", the driver 
        !          6594: **    will assert ATN on the next DATA IN phase mismatch, and so will 
        !          6595: **    behave as if a parity error had been detected.
        !          6596: **
        !          6597: **    The command "debug_error_recovery none" makes the driver behave 
        !          6598: **    normaly.
        !          6599: **
        !          6600: **=====================================================================
        !          6601: */
        !          6602: 
        !          6603: #ifdef SCSI_NCR_DEBUG_ERROR_RECOVERY_SUPPORT
        !          6604: static void ncr_trigger_errors (ncb_p np)
        !          6605: {
        !          6606:        /*
        !          6607:        **      If np->debug_error_recovery is not zero, we want to 
        !          6608:        **      simulate common errors in order to test error recovery.
        !          6609:        */
        !          6610:        do {
        !          6611:                static u_long last = 0l;
        !          6612: 
        !          6613:                if (!np->debug_error_recovery)
        !          6614:                        break;
        !          6615:                if (!last)
        !          6616:                        last = jiffies;
        !          6617:                else if (jiffies < last + 30*HZ)
        !          6618:                        break;
        !          6619:                last = jiffies;
        !          6620:                /*
        !          6621:                 * This one triggers SCSI gross errors.
        !          6622:                 */
        !          6623:                if (np->debug_error_recovery == 1) {
        !          6624:                        int i;
        !          6625:                        printf("%s: testing error recovery from SCSI gross error...\n", ncr_name(np));
        !          6626:                        for (i = 0 ; i < MAX_TARGET ; i++) {
        !          6627:                                if (np->target[i].sval & 0x1f) {
        !          6628:                                        np->target[i].sval &= ~0x1f;
        !          6629:                                        np->target[i].sval += 2;
        !          6630:                                }
        !          6631:                        }
        !          6632:                }
        !          6633:                /*
        !          6634:                 * This one triggers abort from the mid-level driver.
        !          6635:                 */
        !          6636:                else if (np->debug_error_recovery == 2) {
        !          6637:                        printf("%s: testing error recovery from mid-level driver abort()...\n", ncr_name(np));
        !          6638:                        np->stalling = 2;
        !          6639:                }
        !          6640:                /*
        !          6641:                 * This one triggers reset from the mid-level driver.
        !          6642:                 */
        !          6643:                else if (np->debug_error_recovery == 3) {
        !          6644:                        printf("%s: testing error recovery from mid-level driver reset()...\n", ncr_name(np));
        !          6645:                        np->stalling = 3;
        !          6646:                }
        !          6647:                /*
        !          6648:                 * This one set ATN on phase mismatch in DATA IN phase and so 
        !          6649:                 * will behave as on scsi parity error detected.
        !          6650:                 */
        !          6651:                else if (np->debug_error_recovery == 4) {
        !          6652:                        printf("%s: testing data in parity error...\n", ncr_name(np));
        !          6653:                        np->assert_atn = 1;
        !          6654:                }
        !          6655:        } while (0);
        !          6656: }
        !          6657: #endif
        !          6658: 
        !          6659: /*==========================================================
        !          6660: **
        !          6661: **
        !          6662: **     ncr timeout handler.
        !          6663: **
        !          6664: **
        !          6665: **==========================================================
        !          6666: **
        !          6667: **     Misused to keep the driver running when
        !          6668: **     interrupts are not configured correctly.
        !          6669: **
        !          6670: **----------------------------------------------------------
        !          6671: */
        !          6672: 
        !          6673: static void ncr_timeout (ncb_p np)
        !          6674: {
        !          6675:        u_long  thistime = jiffies;
        !          6676:        u_long  count = 0;
        !          6677:        ccb_p cp;
        !          6678:        u_long flags;
        !          6679: 
        !          6680:        /*
        !          6681:        **      If release process in progress, let's go
        !          6682:        **      Set the release stage from 1 to 2 to synchronize
        !          6683:        **      with the release process.
        !          6684:        */
        !          6685: 
        !          6686:        if (np->release_stage) {
        !          6687:                if (np->release_stage == 1) np->release_stage = 2;
        !          6688:                return;
        !          6689:        }
        !          6690: 
        !          6691:        np->timer.expires =
        !          6692: #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,0)
        !          6693:                        jiffies +
        !          6694: #endif
        !          6695:                        SCSI_NCR_TIMER_INTERVAL;
        !          6696: 
        !          6697:        add_timer(&np->timer);
        !          6698: 
        !          6699: #ifdef SCSI_NCR_DEBUG_ERROR_RECOVERY_SUPPORT
        !          6700:        ncr_trigger_errors (np);
        !          6701: #endif
        !          6702: 
        !          6703:        /*
        !          6704:        **      If we are resetting the ncr, wait for settle_time before 
        !          6705:        **      clearing it. Then command processing will be resumed.
        !          6706:        */
        !          6707:        if (np->settle_time) {
        !          6708:                if (np->settle_time <= thistime) {
        !          6709:                        if (bootverbose > 1)
        !          6710:                                printf("%s: command processing resumed\n", ncr_name(np));
        !          6711:                        save_flags(flags); cli();
        !          6712:                        np->settle_time = 0;
        !          6713:                        np->disc        = 1;
        !          6714:                        requeue_waiting_list(np);
        !          6715:                        restore_flags(flags);
        !          6716:                }
        !          6717:                return;
        !          6718:        }
        !          6719: 
        !          6720:        /*
        !          6721:        **      Since the generic scsi driver only allows us 0.5 second 
        !          6722:        **      to perform abort of a command, we must look at ccbs about 
        !          6723:        **      every 0.25 second.
        !          6724:        */
        !          6725:        if (np->lasttime + (HZ>>2) <= thistime) {
        !          6726:                /*
        !          6727:                **      block ncr interrupts
        !          6728:                */
        !          6729:                save_flags(flags); cli();
        !          6730: 
        !          6731:                np->lasttime = thistime;
        !          6732: 
        !          6733:                /*
        !          6734:                **      Reset profile data to avoid ugly overflow
        !          6735:                **      (Limited to 1024 GB for 32 bit architecture)
        !          6736:                */
        !          6737:                if (np->profile.num_kbytes > (~0UL >> 2))
        !          6738:                        bzero(&np->profile, sizeof(np->profile));
        !          6739: 
        !          6740:                /*----------------------------------------------------
        !          6741:                **
        !          6742:                **      handle ncr chip timeouts
        !          6743:                **
        !          6744:                **      Assumption:
        !          6745:                **      We have a chance to arbitrate for the
        !          6746:                **      SCSI bus at least every 10 seconds.
        !          6747:                **
        !          6748:                **----------------------------------------------------
        !          6749:                */
        !          6750: #if 0
        !          6751:                if (thistime < np->heartbeat + HZ + HZ)
        !          6752:                        np->latetime = 0;
        !          6753:                else
        !          6754:                        np->latetime++;
        !          6755: #endif
        !          6756: 
        !          6757:                /*----------------------------------------------------
        !          6758:                **
        !          6759:                **      handle ccb timeouts
        !          6760:                **
        !          6761:                **----------------------------------------------------
        !          6762:                */
        !          6763: 
        !          6764:                for (cp=np->ccb; cp; cp=cp->link_ccb) {
        !          6765:                        /*
        !          6766:                        **      look for timed out ccbs.
        !          6767:                        */
        !          6768:                        if (!cp->host_status) continue;
        !          6769:                        count++;
        !          6770:                        /*
        !          6771:                        **      Have to force ordered tag to avoid timeouts
        !          6772:                        */
        !          6773:                        if (cp->cmd && cp->tlimit && cp->tlimit <= 
        !          6774:                                thistime + NCR_TIMEOUT_INCREASE + SCSI_NCR_TIMEOUT_ALERT) {
        !          6775:                                lcb_p lp;
        !          6776:                                lp = np->target[cp->cmd->target].lp[cp->cmd->lun];
        !          6777:                                if (lp && !lp->force_ordered_tag) {
        !          6778:                                        lp->force_ordered_tag = 1;
        !          6779:                                }
        !          6780:                        }
        !          6781:                        /*
        !          6782:                        **      ncr_abort_command() cannot complete canceled 
        !          6783:                        **      commands immediately. It sets tlimit to zero 
        !          6784:                        **      and ask the script to skip the scsi process if 
        !          6785:                        **      necessary. We have to complete this work here.
        !          6786:                        */
        !          6787: 
        !          6788:                        if (cp->tlimit) continue;
        !          6789: 
        !          6790:                        switch (cp->host_status) {
        !          6791: 
        !          6792:                        case HS_BUSY:
        !          6793:                        case HS_NEGOTIATE:
        !          6794:                                /*
        !          6795:                                ** still in start queue ?
        !          6796:                                */
        !          6797:                                if (cp->phys.header.launch.l_paddr ==
        !          6798:                                        cpu_to_scr(NCB_SCRIPT_PHYS (np, skip)))
        !          6799:                                        continue;
        !          6800: 
        !          6801:                                /* fall through */
        !          6802:                        case HS_DISCONNECT:
        !          6803:                                cp->host_status=HS_ABORTED;
        !          6804:                        };
        !          6805:                        cp->tag = 0;
        !          6806: 
        !          6807:                        /*
        !          6808:                        **      wakeup this ccb.
        !          6809:                        */
        !          6810:                        ncr_complete (np, cp);
        !          6811: 
        !          6812: #ifdef SCSI_NCR_DEBUG_ERROR_RECOVERY_SUPPORT
        !          6813:                        if (!np->stalling)
        !          6814: #endif
        !          6815:                        OUTB (nc_istat, SIGP);
        !          6816:                }
        !          6817:                restore_flags(flags);
        !          6818:        }
        !          6819: 
        !          6820: #ifdef SCSI_NCR_BROKEN_INTR
        !          6821:        if (INB(nc_istat) & (INTF|SIP|DIP)) {
        !          6822: 
        !          6823:                /*
        !          6824:                **      Process pending interrupts.
        !          6825:                */
        !          6826:                save_flags(flags); cli();
        !          6827:                if (DEBUG_FLAGS & DEBUG_TINY) printf ("{");
        !          6828:                ncr_exception (np);
        !          6829:                if (DEBUG_FLAGS & DEBUG_TINY) printf ("}");
        !          6830:                restore_flags(flags);
        !          6831:        }
        !          6832: #endif /* SCSI_NCR_BROKEN_INTR */
        !          6833: }
        !          6834: 
        !          6835: /*==========================================================
        !          6836: **
        !          6837: **     log message for real hard errors
        !          6838: **
        !          6839: **     "ncr0 targ 0?: ERROR (ds:si) (so-si-sd) (sxfer/scntl3) @ name (dsp:dbc)."
        !          6840: **     "             reg: r0 r1 r2 r3 r4 r5 r6 ..... rf."
        !          6841: **
        !          6842: **     exception register:
        !          6843: **             ds:     dstat
        !          6844: **             si:     sist
        !          6845: **
        !          6846: **     SCSI bus lines:
        !          6847: **             so:     control lines as driver by NCR.
        !          6848: **             si:     control lines as seen by NCR.
        !          6849: **             sd:     scsi data lines as seen by NCR.
        !          6850: **
        !          6851: **     wide/fastmode:
        !          6852: **             sxfer:  (see the manual)
        !          6853: **             scntl3: (see the manual)
        !          6854: **
        !          6855: **     current script command:
        !          6856: **             dsp:    script adress (relative to start of script).
        !          6857: **             dbc:    first word of script command.
        !          6858: **
        !          6859: **     First 16 register of the chip:
        !          6860: **             r0..rf
        !          6861: **
        !          6862: **==========================================================
        !          6863: */
        !          6864: 
        !          6865: static void ncr_log_hard_error(ncb_p np, u_short sist, u_char dstat)
        !          6866: {
        !          6867:        u_int32 dsp;
        !          6868:        int     script_ofs;
        !          6869:        int     script_size;
        !          6870:        char    *script_name;
        !          6871:        u_char  *script_base;
        !          6872:        int     i;
        !          6873: 
        !          6874:        dsp     = INL (nc_dsp);
        !          6875: 
        !          6876:        if (dsp > np->p_script && dsp <= np->p_script + sizeof(struct script)) {
        !          6877:                script_ofs      = dsp - np->p_script;
        !          6878:                script_size     = sizeof(struct script);
        !          6879:                script_base     = (u_char *) np->script;
        !          6880:                script_name     = "script";
        !          6881:        }
        !          6882:        else if (np->p_scripth < dsp && 
        !          6883:                 dsp <= np->p_scripth + sizeof(struct scripth)) {
        !          6884:                script_ofs      = dsp - np->p_scripth;
        !          6885:                script_size     = sizeof(struct scripth);
        !          6886:                script_base     = (u_char *) np->scripth;
        !          6887:                script_name     = "scripth";
        !          6888:        } else {
        !          6889:                script_ofs      = dsp;
        !          6890:                script_size     = 0;
        !          6891:                script_base     = 0;
        !          6892:                script_name     = "mem";
        !          6893:        }
        !          6894: 
        !          6895:        printf ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x) @ (%s %x:%08x).\n",
        !          6896:                ncr_name (np), (unsigned)INB (nc_ctest0)&0x0f, dstat, sist,
        !          6897:                (unsigned)INB (nc_socl), (unsigned)INB (nc_sbcl), (unsigned)INB (nc_sbdl),
        !          6898:                (unsigned)INB (nc_sxfer),(unsigned)INB (nc_scntl3), script_name, script_ofs,
        !          6899:                (unsigned)INL (nc_dbc));
        !          6900: 
        !          6901:        if (((script_ofs & 3) == 0) &&
        !          6902:            (unsigned)script_ofs < script_size) {
        !          6903:                printf ("%s: script cmd = %08x\n", ncr_name(np),
        !          6904:                        (int) *(ncrcmd *)(script_base + script_ofs));
        !          6905:        }
        !          6906: 
        !          6907:         printf ("%s: regdump:", ncr_name(np));
        !          6908:         for (i=0; i<16;i++)
        !          6909:             printf (" %02x", (unsigned)INB_OFF(i));
        !          6910:         printf (".\n");
        !          6911: }
        !          6912: 
        !          6913: /*============================================================
        !          6914: **
        !          6915: **     ncr chip exception handler.
        !          6916: **
        !          6917: **============================================================
        !          6918: **
        !          6919: **     In normal cases, interrupt conditions occur one at a 
        !          6920: **     time. The ncr is able to stack in some extra registers 
        !          6921: **     other interrupts that will occurs after the first one.
        !          6922: **     But severall interrupts may occur at the same time.
        !          6923: **
        !          6924: **     We probably should only try to deal with the normal 
        !          6925: **     case, but it seems that multiple interrupts occur in 
        !          6926: **     some cases that are not abnormal at all.
        !          6927: **
        !          6928: **     The most frequent interrupt condition is Phase Mismatch.
        !          6929: **     We should want to service this interrupt quickly.
        !          6930: **     A SCSI parity error may be delivered at the same time.
        !          6931: **     The SIR interrupt is not very frequent in this driver, 
        !          6932: **     since the INTFLY is likely used for command completion 
        !          6933: **     signaling.
        !          6934: **     The Selection Timeout interrupt may be triggered with 
        !          6935: **     IID and/or UDC.
        !          6936: **     The SBMC interrupt (SCSI Bus Mode Change) may probably 
        !          6937: **     occur at any time.
        !          6938: **
        !          6939: **     This handler try to deal as cleverly as possible with all
        !          6940: **     the above.
        !          6941: **
        !          6942: **============================================================
        !          6943: */
        !          6944: 
        !          6945: void ncr_exception (ncb_p np)
        !          6946: {
        !          6947:        u_char  istat, dstat;
        !          6948:        u_short sist;
        !          6949:        int     i;
        !          6950: 
        !          6951:        /*
        !          6952:        **      interrupt on the fly ?
        !          6953:        **      Since the global header may be copied back to a CCB 
        !          6954:        **      using a posted PCI memory write, the last operation on 
        !          6955:        **      the istat register is a READ in order to flush posted 
        !          6956:        **      PCI commands (Btw, the 'do' loop is probably useless).
        !          6957:        */
        !          6958:        istat = INB (nc_istat);
        !          6959:        if (istat & INTF) {
        !          6960:                do {
        !          6961:                        OUTB (nc_istat, (istat & SIGP) | INTF);
        !          6962:                        istat = INB (nc_istat);
        !          6963:                } while (istat & INTF);
        !          6964:                if (DEBUG_FLAGS & DEBUG_TINY) printf ("F ");
        !          6965:                np->profile.num_fly++;
        !          6966:                ncr_wakeup (np, 0);
        !          6967:        };
        !          6968: 
        !          6969:        if (!(istat & (SIP|DIP)))
        !          6970:                return;
        !          6971: 
        !          6972:        np->profile.num_int++;
        !          6973: 
        !          6974:        if (istat & CABRT)
        !          6975:                OUTB (nc_istat, CABRT);
        !          6976: 
        !          6977:        /*
        !          6978:        **      Steinbach's Guideline for Systems Programming:
        !          6979:        **      Never test for an error condition you don't know how to handle.
        !          6980:        */
        !          6981: 
        !          6982:        sist  = (istat & SIP) ? INW (nc_sist)  : 0;
        !          6983:        dstat = (istat & DIP) ? INB (nc_dstat) : 0;
        !          6984: 
        !          6985:        if (DEBUG_FLAGS & DEBUG_TINY)
        !          6986:                printf ("<%d|%x:%x|%x:%x>",
        !          6987:                        (int)INB(nc_scr0),
        !          6988:                        dstat,sist,
        !          6989:                        (unsigned)INL(nc_dsp),
        !          6990:                        (unsigned)INL(nc_dbc));
        !          6991: 
        !          6992:        /*========================================================
        !          6993:        **      First, interrupts we want to service cleanly.
        !          6994:        **
        !          6995:        **      Phase mismatch is the most frequent interrupt, and 
        !          6996:        **      so we have to service it as quickly and as cleanly 
        !          6997:        **      as possible.
        !          6998:        **      Programmed interrupts are rarely used in this driver,
        !          6999:        **      but we must handle them cleanly anyway.
        !          7000:        **      We try to deal with PAR and SBMC combined with 
        !          7001:        **      some other interrupt(s).
        !          7002:        **=========================================================
        !          7003:        */
        !          7004: 
        !          7005:        if (!(sist  & (STO|GEN|HTH|SGE|UDC|RST)) &&
        !          7006:            !(dstat & (MDPE|BF|ABRT|IID))) {
        !          7007:                if ((sist & SBMC) && ncr_int_sbmc (np))
        !          7008:                        return;
        !          7009:                if ((sist & PAR)  && ncr_int_par  (np))
        !          7010:                        return;
        !          7011:                if (sist & MA) {
        !          7012:                        ncr_int_ma (np);
        !          7013:                        return;
        !          7014:                }
        !          7015:                if (dstat & SIR) {
        !          7016:                        ncr_int_sir (np);
        !          7017:                        return;
        !          7018:                }
        !          7019:                /*
        !          7020:                **  DEL 397 - 53C875 Rev 3 - Part Number 609-0392410 - ITEM 2.
        !          7021:                */
        !          7022:                if (!(sist & (SBMC|PAR)) && !(dstat & SSI)) {
        !          7023:                        printf( "%s: unknown interrupt(s) ignored, "
        !          7024:                                "ISTAT=%x DSTAT=%x SIST=%x\n",
        !          7025:                                ncr_name(np), istat, dstat, sist);
        !          7026:                        return;
        !          7027:                }
        !          7028: 
        !          7029:                OUTONB (nc_dcntl, (STD|NOCOM));
        !          7030:                return;
        !          7031:        };
        !          7032: 
        !          7033:        /*========================================================
        !          7034:        **      Now, interrupts that need some fixing up.
        !          7035:        **      Order and multiple interrupts is so less important.
        !          7036:        **
        !          7037:        **      If SRST has been asserted, we just reset the chip.
        !          7038:        **
        !          7039:        **      Selection is intirely handled by the chip. If the 
        !          7040:        **      chip says STO, we trust it. Seems some other 
        !          7041:        **      interrupts may occur at the same time (UDC, IID), so 
        !          7042:        **      we ignore them. In any case we do enough fix-up 
        !          7043:        **      in the service routine.
        !          7044:        **      We just exclude some fatal dma errors.
        !          7045:        **=========================================================
        !          7046:        */
        !          7047: 
        !          7048:        if (sist & RST) {
        !          7049:                ncr_init (np, 1, bootverbose ? "scsi reset" : NULL, HS_RESET);
        !          7050:                return;
        !          7051:        };
        !          7052: 
        !          7053:        if ((sist & STO) &&
        !          7054:                !(dstat & (MDPE|BF|ABRT))) {
        !          7055:        /*
        !          7056:        **      DEL 397 - 53C875 Rev 3 - Part Number 609-0392410 - ITEM 1.
        !          7057:        */
        !          7058:                OUTONB (nc_ctest3, CLF);
        !          7059: 
        !          7060:                ncr_int_sto (np);
        !          7061:                return;
        !          7062:        };
        !          7063: 
        !          7064:        /*=========================================================
        !          7065:        **      Now, interrupts we are not able to recover cleanly.
        !          7066:        **      (At least for the moment).
        !          7067:        **
        !          7068:        **      Do the register dump.
        !          7069:        **      Log message for real hard errors.
        !          7070:        **      Clear all fifos.
        !          7071:        **      For MDPE, BF, ABORT, IID, SGE and HTH we reset the 
        !          7072:        **      BUS and the chip.
        !          7073:        **      We are more soft for UDC.
        !          7074:        **=========================================================
        !          7075:        */
        !          7076:        if (jiffies - np->regtime > 10*HZ) {
        !          7077:                np->regtime = jiffies;
        !          7078:                for (i = 0; i<sizeof(np->regdump); i++)
        !          7079:                        ((char*)&np->regdump)[i] = INB_OFF(i);
        !          7080:                np->regdump.nc_dstat = dstat;
        !          7081:                np->regdump.nc_sist  = sist;
        !          7082:        };
        !          7083: 
        !          7084:        ncr_log_hard_error(np, sist, dstat);
        !          7085: 
        !          7086:        printf ("%s: have to clear fifos.\n", ncr_name (np));
        !          7087:        OUTB (nc_stest3, TE|CSF);
        !          7088:        OUTONB (nc_ctest3, CLF);
        !          7089: 
        !          7090:        if ((sist & (SGE)) ||
        !          7091:                (dstat & (MDPE|BF|ABORT|IID))) {
        !          7092:                ncr_start_reset(np, driver_setup.settle_delay);
        !          7093:                return;
        !          7094:        };
        !          7095: 
        !          7096:        if (sist & HTH) {
        !          7097:                printf ("%s: handshake timeout\n", ncr_name(np));
        !          7098:                ncr_start_reset(np, driver_setup.settle_delay);
        !          7099:                return;
        !          7100:        };
        !          7101: 
        !          7102:        if (sist & UDC) {
        !          7103:                printf ("%s: unexpected disconnect\n", ncr_name(np));
        !          7104:                if (INB (nc_scr1) != 0xff) {
        !          7105:                        OUTB (nc_scr1, HS_UNEXPECTED);
        !          7106:                        OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, cleanup));
        !          7107:                };
        !          7108:                ncr_start_reset(np, driver_setup.settle_delay);
        !          7109:                return;
        !          7110:        };
        !          7111: 
        !          7112:        /*=========================================================
        !          7113:        **      We just miss the cause of the interrupt. :(
        !          7114:        **      Print a message. The timeout will do the real work.
        !          7115:        **=========================================================
        !          7116:        */
        !          7117:        printf ("%s: unknown interrupt\n", ncr_name(np));
        !          7118: }
        !          7119: 
        !          7120: /*==========================================================
        !          7121: **
        !          7122: **     ncr chip exception handler for selection timeout
        !          7123: **
        !          7124: **==========================================================
        !          7125: **
        !          7126: **     There seems to be a bug in the 53c810.
        !          7127: **     Although a STO-Interrupt is pending,
        !          7128: **     it continues executing script commands.
        !          7129: **     But it will fail and interrupt (IID) on
        !          7130: **     the next instruction where it's looking
        !          7131: **     for a valid phase.
        !          7132: **
        !          7133: **----------------------------------------------------------
        !          7134: */
        !          7135: 
        !          7136: void ncr_int_sto (ncb_p np)
        !          7137: {
        !          7138:        u_long dsa, scratcha, diff;
        !          7139:        ccb_p cp;
        !          7140:        if (DEBUG_FLAGS & DEBUG_TINY) printf ("T");
        !          7141: 
        !          7142:        /*
        !          7143:        **      look for ccb and set the status.
        !          7144:        */
        !          7145: 
        !          7146:        dsa = INL (nc_dsa);
        !          7147:        cp = np->ccb;
        !          7148:        while (cp && (CCB_PHYS (cp, phys) != dsa))
        !          7149:                cp = cp->link_ccb;
        !          7150: 
        !          7151:        if (cp) {
        !          7152:                cp-> host_status = HS_SEL_TIMEOUT;
        !          7153:                ncr_complete (np, cp);
        !          7154:        };
        !          7155: 
        !          7156:        /*
        !          7157:        **      repair start queue
        !          7158:        */
        !          7159: 
        !          7160:        scratcha = INL (nc_scratcha);
        !          7161:        diff = scratcha - NCB_SCRIPTH_PHYS (np, tryloop);
        !          7162: 
        !          7163: /*     assert ((diff <= MAX_START * 20) && !(diff % 20));*/
        !          7164: 
        !          7165:        if ((diff <= MAX_START * 20) && !(diff % 20)) {
        !          7166:                np->script->startpos[0] = cpu_to_scr(scratcha);
        !          7167:                OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, start));
        !          7168:                return;
        !          7169:        };
        !          7170:        ncr_init (np, 1, "selection timeout", HS_FAIL);
        !          7171:        np->disc = 1;
        !          7172: }
        !          7173: 
        !          7174: /*==========================================================
        !          7175: **
        !          7176: **     ncr chip exception handler for SCSI bus mode change
        !          7177: **
        !          7178: **==========================================================
        !          7179: **
        !          7180: **     spi2-r12 11.2.3 says a transceiver mode change must 
        !          7181: **     generate a reset event and a device that detects a reset 
        !          7182: **     event shall initiate a hard reset. It says also that a
        !          7183: **     device that detects a mode change shall set data transfer 
        !          7184: **     mode to eight bit asynchronous, etc...
        !          7185: **     So, just resetting should be enough.
        !          7186: **      
        !          7187: **
        !          7188: **----------------------------------------------------------
        !          7189: */
        !          7190: 
        !          7191: static int ncr_int_sbmc (ncb_p np)
        !          7192: {
        !          7193:        u_char scsi_mode = INB (nc_stest4) & SMODE;
        !          7194: 
        !          7195:        printf("%s: SCSI bus mode change from %x to %x.\n",
        !          7196:                ncr_name(np), np->scsi_mode, scsi_mode);
        !          7197: 
        !          7198:        np->scsi_mode = scsi_mode;
        !          7199: 
        !          7200:        /*
        !          7201:        **      Suspend command processing for 1 second and 
        !          7202:        **      reinitialize all except the chip.
        !          7203:        */
        !          7204:        np->settle_time = jiffies + HZ;
        !          7205:        ncr_init (np, 0, bootverbose ? "scsi mode change" : NULL, HS_RESET);
        !          7206: 
        !          7207:        return 1;
        !          7208: }
        !          7209: 
        !          7210: /*==========================================================
        !          7211: **
        !          7212: **     ncr chip exception handler for SCSI parity error.
        !          7213: **
        !          7214: **==========================================================
        !          7215: **
        !          7216: **     SCSI parity errors are handled by the SCSI script.
        !          7217: **     So, we just print some message.
        !          7218: **
        !          7219: **----------------------------------------------------------
        !          7220: */
        !          7221: 
        !          7222: static int ncr_int_par (ncb_p np)
        !          7223: {
        !          7224:        printf("%s: SCSI parity error detected\n", ncr_name(np));
        !          7225:        return 0;
        !          7226: }
        !          7227: 
        !          7228: /*==========================================================
        !          7229: **
        !          7230: **
        !          7231: **     ncr chip exception handler for phase errors.
        !          7232: **
        !          7233: **
        !          7234: **==========================================================
        !          7235: **
        !          7236: **     We have to construct a new transfer descriptor,
        !          7237: **     to transfer the rest of the current block.
        !          7238: **
        !          7239: **----------------------------------------------------------
        !          7240: */
        !          7241: 
        !          7242: static void ncr_int_ma (ncb_p np)
        !          7243: {
        !          7244:        u_int32 dbc;
        !          7245:        u_int32 rest;
        !          7246:        u_int32 dsp;
        !          7247:        u_int32 dsa;
        !          7248:        u_int32 nxtdsp;
        !          7249:        u_int32 *vdsp;
        !          7250:        u_int32 oadr, olen;
        !          7251:        u_int32 *tblp;
        !          7252:         ncrcmd *newcmd;
        !          7253:        u_char  cmd, sbcl;
        !          7254:        ccb_p   cp;
        !          7255: 
        !          7256:        dsp     = INL (nc_dsp);
        !          7257:        dbc     = INL (nc_dbc);
        !          7258:        sbcl    = INB (nc_sbcl);
        !          7259: 
        !          7260:        cmd     = dbc >> 24;
        !          7261:        rest    = dbc & 0xffffff;
        !          7262: 
        !          7263:        /*
        !          7264:        **      Take into account dma fifo and various buffers and latches,
        !          7265:        **      only if the interrupted phase is an OUTPUT phase.
        !          7266:        */
        !          7267: 
        !          7268:        if ((cmd & 1) == 0) {
        !          7269:                u_char  ctest5, ss0, ss2;
        !          7270:                u_short delta;
        !          7271: 
        !          7272:                ctest5 = (np->rv_ctest5 & DFS) ? INB (nc_ctest5) : 0;
        !          7273:                if (ctest5 & DFS)
        !          7274:                        delta=(((ctest5 << 8) | (INB (nc_dfifo) & 0xff)) - rest) & 0x3ff;
        !          7275:                else
        !          7276:                        delta=(INB (nc_dfifo) - rest) & 0x7f;
        !          7277: 
        !          7278:                /*
        !          7279:                **      The data in the dma fifo has not been transfered to
        !          7280:                **      the target -> add the amount to the rest
        !          7281:                **      and clear the data.
        !          7282:                **      Check the sstat2 register in case of wide transfer.
        !          7283:                */
        !          7284: 
        !          7285:                rest += delta;
        !          7286:                ss0  = INB (nc_sstat0);
        !          7287:                if (ss0 & OLF) rest++;
        !          7288:                if (ss0 & ORF) rest++;
        !          7289:                if (INB(nc_scntl3) & EWS) {
        !          7290:                        ss2 = INB (nc_sstat2);
        !          7291:                        if (ss2 & OLF1) rest++;
        !          7292:                        if (ss2 & ORF1) rest++;
        !          7293:                };
        !          7294: 
        !          7295:                OUTONB (nc_ctest3, CLF );       /* clear dma fifo  */
        !          7296:                OUTB (nc_stest3, TE|CSF);       /* clear scsi fifo */
        !          7297: 
        !          7298:                if (DEBUG_FLAGS & (DEBUG_TINY|DEBUG_PHASE))
        !          7299:                        printf ("P%x%x RL=%d D=%d SS0=%x ", cmd&7, sbcl&7,
        !          7300:                                (unsigned) rest, (unsigned) delta, ss0);
        !          7301: 
        !          7302:        } else  {
        !          7303:                if (DEBUG_FLAGS & (DEBUG_TINY|DEBUG_PHASE))
        !          7304:                        printf ("P%x%x RL=%d ", cmd&7, sbcl&7, rest);
        !          7305:                if ((cmd & 7) != 1) {
        !          7306:                        OUTONB (nc_ctest3, CLF );
        !          7307:                        OUTB (nc_stest3, TE|CSF);
        !          7308:                }
        !          7309:        }
        !          7310: 
        !          7311:        /*
        !          7312:        **      locate matching cp
        !          7313:        */
        !          7314:        dsa = INL (nc_dsa);
        !          7315:        cp  = np->ccb;
        !          7316:        while (cp && (CCB_PHYS (cp, phys) != dsa))
        !          7317:                cp = cp->link_ccb;
        !          7318: 
        !          7319:        if (!cp) {
        !          7320:            printf ("%s: SCSI phase error fixup: CCB already dequeued (0x%08lx)\n", 
        !          7321:                    ncr_name (np), (u_long) np->header.cp);
        !          7322:            return;
        !          7323:        }
        !          7324:        if (cp != np->header.cp) {
        !          7325:            printf ("%s: SCSI phase error fixup: CCB address mismatch (0x%08lx != 0x%08lx)\n", 
        !          7326:                    ncr_name (np), (u_long) cp, (u_long) np->header.cp);
        !          7327: /*         return;*/
        !          7328:        }
        !          7329: 
        !          7330:        /*
        !          7331:        **      find the interrupted script command,
        !          7332:        **      and the address at which to continue.
        !          7333:        */
        !          7334: 
        !          7335:        if (dsp == vtophys (&cp->patch[2])) {
        !          7336:                vdsp = &cp->patch[0];
        !          7337:                nxtdsp = vdsp[3];
        !          7338:        } else if (dsp == vtophys (&cp->patch[6])) {
        !          7339:                vdsp = &cp->patch[4];
        !          7340:                nxtdsp = vdsp[3];
        !          7341:        } else if (dsp > np->p_script && dsp <= np->p_script + sizeof(struct script)) {
        !          7342:                vdsp = (u_int32 *) ((char*)np->script - np->p_script + dsp -8);
        !          7343:                nxtdsp = dsp;
        !          7344:        } else {
        !          7345:                vdsp = (u_int32 *) ((char*)np->scripth - np->p_scripth + dsp -8);
        !          7346:                nxtdsp = dsp;
        !          7347:        };
        !          7348: 
        !          7349:        /*
        !          7350:        **      log the information
        !          7351:        */
        !          7352: 
        !          7353:        if (DEBUG_FLAGS & DEBUG_PHASE) {
        !          7354:                printf ("\nCP=%p CP2=%p DSP=%x NXT=%x VDSP=%p CMD=%x ",
        !          7355:                        cp, np->header.cp,
        !          7356:                        (unsigned)dsp,
        !          7357:                        (unsigned)nxtdsp, vdsp, cmd);
        !          7358:        };
        !          7359: 
        !          7360:        /*
        !          7361:        **      get old startaddress and old length.
        !          7362:        */
        !          7363: 
        !          7364:        oadr = scr_to_cpu(vdsp[1]);
        !          7365: 
        !          7366:        if (cmd & 0x10) {       /* Table indirect */
        !          7367:                tblp = (u_int32 *) ((char*) &cp->phys + oadr);
        !          7368:                olen = scr_to_cpu(tblp[0]);
        !          7369:                oadr = scr_to_cpu(tblp[1]);
        !          7370:        } else {
        !          7371:                tblp = (u_int32 *) 0;
        !          7372:                olen = scr_to_cpu(vdsp[0]) & 0xffffff;
        !          7373:        };
        !          7374: 
        !          7375:        if (DEBUG_FLAGS & DEBUG_PHASE) {
        !          7376:                printf ("OCMD=%x\nTBLP=%p OLEN=%x OADR=%x\n",
        !          7377:                        (unsigned) (scr_to_cpu(vdsp[0]) >> 24),
        !          7378:                        tblp,
        !          7379:                        (unsigned) olen,
        !          7380:                        (unsigned) oadr);
        !          7381:        };
        !          7382: 
        !          7383:        /*
        !          7384:        **      check cmd against assumed interrupted script command.
        !          7385:        */
        !          7386: 
        !          7387:        if (cmd != (scr_to_cpu(vdsp[0]) >> 24)) {
        !          7388:                PRINT_ADDR(cp->cmd);
        !          7389:                printf ("internal error: cmd=%02x != %02x=(vdsp[0] >> 24)\n",
        !          7390:                        (unsigned)cmd, (unsigned)scr_to_cpu(vdsp[0]) >> 24);
        !          7391:                
        !          7392:                return;
        !          7393:        }
        !          7394: 
        !          7395: #ifdef SCSI_NCR_DEBUG_ERROR_RECOVERY_SUPPORT
        !          7396:        if ((cmd & 7) == 1 && np->assert_atn) {
        !          7397:                np->assert_atn = 0;
        !          7398:                OUTONB(nc_socl, CATN);
        !          7399:        }
        !          7400: #endif
        !          7401: 
        !          7402:        /*
        !          7403:        **      if old phase not dataphase, leave here.
        !          7404:        */
        !          7405: 
        !          7406:        if (cmd & 0x06) {
        !          7407:                PRINT_ADDR(cp->cmd);
        !          7408:                printf ("phase change %x-%x %d@%08x resid=%d.\n",
        !          7409:                        cmd&7, sbcl&7, (unsigned)olen,
        !          7410:                        (unsigned)oadr, (unsigned)rest);
        !          7411: 
        !          7412:                OUTONB (nc_dcntl, (STD|NOCOM));
        !          7413:                return;
        !          7414:        };
        !          7415: 
        !          7416:        /*
        !          7417:        **      choose the correct patch area.
        !          7418:        **      if savep points to one, choose the other.
        !          7419:        */
        !          7420: 
        !          7421:        newcmd = cp->patch;
        !          7422:        if (cp->phys.header.savep == cpu_to_scr(vtophys (newcmd))) newcmd+=4;
        !          7423: 
        !          7424:        /*
        !          7425:        **      fillin the commands
        !          7426:        */
        !          7427: 
        !          7428:        newcmd[0] = cpu_to_scr(((cmd & 0x0f) << 24) | rest);
        !          7429:        newcmd[1] = cpu_to_scr(oadr + olen - rest);
        !          7430:        newcmd[2] = cpu_to_scr(SCR_JUMP);
        !          7431:        newcmd[3] = cpu_to_scr(nxtdsp);
        !          7432: 
        !          7433:        if (DEBUG_FLAGS & DEBUG_PHASE) {
        !          7434:                PRINT_ADDR(cp->cmd);
        !          7435:                printf ("newcmd[%d] %x %x %x %x.\n",
        !          7436:                        (int) (newcmd - cp->patch),
        !          7437:                        (unsigned)scr_to_cpu(newcmd[0]),
        !          7438:                        (unsigned)scr_to_cpu(newcmd[1]),
        !          7439:                        (unsigned)scr_to_cpu(newcmd[2]),
        !          7440:                        (unsigned)scr_to_cpu(newcmd[3]));
        !          7441:        }
        !          7442:        /*
        !          7443:        **      fake the return address (to the patch).
        !          7444:        **      and restart script processor at dispatcher.
        !          7445:        */
        !          7446:        np->profile.num_break++;
        !          7447:        OUTL (nc_temp, vtophys (newcmd));
        !          7448:        if ((cmd & 7) == 0)
        !          7449:                OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, dispatch));
        !          7450:        else
        !          7451:                OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, checkatn));
        !          7452: }
        !          7453: 
        !          7454: /*==========================================================
        !          7455: **
        !          7456: **
        !          7457: **      ncr chip exception handler for programmed interrupts.
        !          7458: **
        !          7459: **
        !          7460: **==========================================================
        !          7461: */
        !          7462: 
        !          7463: static int ncr_show_msg (u_char * msg)
        !          7464: {
        !          7465:        u_char i;
        !          7466:        printf ("%x",*msg);
        !          7467:        if (*msg==M_EXTENDED) {
        !          7468:                for (i=1;i<8;i++) {
        !          7469:                        if (i-1>msg[1]) break;
        !          7470:                        printf ("-%x",msg[i]);
        !          7471:                };
        !          7472:                return (i+1);
        !          7473:        } else if ((*msg & 0xf0) == 0x20) {
        !          7474:                printf ("-%x",msg[1]);
        !          7475:                return (2);
        !          7476:        };
        !          7477:        return (1);
        !          7478: }
        !          7479: 
        !          7480: void ncr_int_sir (ncb_p np)
        !          7481: {
        !          7482:        u_char scntl3;
        !          7483:        u_char chg, ofs, per, fak, wide;
        !          7484:        u_char num = INB (nc_dsps);
        !          7485:        ccb_p   cp=0;
        !          7486:        u_long  dsa;
        !          7487:        u_char  target = INB (nc_ctest0) & 0x0f;
        !          7488:        tcb_p   tp     = &np->target[target];
        !          7489:        int     i;
        !          7490:        if (DEBUG_FLAGS & DEBUG_TINY) printf ("I#%d", num);
        !          7491: 
        !          7492:        switch (num) {
        !          7493:        case SIR_SENSE_RESTART:
        !          7494:        case SIR_STALL_RESTART:
        !          7495:                break;
        !          7496:        case SIR_STALL_QUEUE:   /* Ignore, just restart the script */
        !          7497:                goto out;
        !          7498: 
        !          7499:        default:
        !          7500:                /*
        !          7501:                **      lookup the ccb
        !          7502:                */
        !          7503:                dsa = INL (nc_dsa);
        !          7504:                cp = np->ccb;
        !          7505:                while (cp && (CCB_PHYS (cp, phys) != dsa))
        !          7506:                        cp = cp->link_ccb;
        !          7507: 
        !          7508:                assert (cp);
        !          7509:                if (!cp)
        !          7510:                        goto out;
        !          7511:                assert (cp == np->header.cp);
        !          7512:                if (cp != np->header.cp)
        !          7513:                        goto out;
        !          7514:        }
        !          7515: 
        !          7516:        switch (num) {
        !          7517:                u_long endp;
        !          7518:        case SIR_DATA_IO_IS_OUT:
        !          7519:        case SIR_DATA_IO_IS_IN:
        !          7520: /*
        !          7521: **     We did not guess the direction of transfer. We have to wait for 
        !          7522: **     actual data direction driven by the target before setting 
        !          7523: **     pointers. We must patch the global header too.
        !          7524: */
        !          7525:                if (num == SIR_DATA_IO_IS_OUT) {
        !          7526:                        endp = NCB_SCRIPTH_PHYS (np, data_out) + MAX_SCATTER*16;
        !          7527:                        cp->phys.header.goalp = cpu_to_scr(endp + 8);
        !          7528:                        cp->phys.header.savep =
        !          7529:                                cpu_to_scr(endp - cp->segments*16);
        !          7530:                } else {
        !          7531:                        endp = NCB_SCRIPT_PHYS (np, data_in)  + MAX_SCATTER*16;
        !          7532:                        cp->phys.header.goalp = cpu_to_scr(endp + 8);
        !          7533:                        cp->phys.header.savep =
        !          7534:                                cpu_to_scr(endp - cp->segments*16);
        !          7535:                }
        !          7536: 
        !          7537:                cp->phys.header.lastp   = cp->phys.header.savep;
        !          7538:                np->header.savep        = cp->phys.header.savep;
        !          7539:                np->header.goalp        = cp->phys.header.goalp;
        !          7540:                np->header.lastp        = cp->phys.header.lastp;
        !          7541: 
        !          7542:                OUTL (nc_temp,  scr_to_cpu(np->header.savep));
        !          7543:                OUTL (nc_dsp,   scr_to_cpu(np->header.savep));
        !          7544:                return;
        !          7545:                /* break; */
        !          7546: 
        !          7547: /*--------------------------------------------------------------------
        !          7548: **
        !          7549: **     Processing of interrupted getcc selects
        !          7550: **
        !          7551: **--------------------------------------------------------------------
        !          7552: */
        !          7553: 
        !          7554:        case SIR_SENSE_RESTART:
        !          7555:                /*------------------------------------------
        !          7556:                **      Script processor is idle.
        !          7557:                **      Look for interrupted "check cond"
        !          7558:                **------------------------------------------
        !          7559:                */
        !          7560: 
        !          7561:                if (DEBUG_FLAGS & DEBUG_RESTART)
        !          7562:                        printf ("%s: int#%d",ncr_name (np),num);
        !          7563:                cp = (ccb_p) 0;
        !          7564:                for (i=0; i<MAX_TARGET; i++) {
        !          7565:                        if (DEBUG_FLAGS & DEBUG_RESTART) printf (" t%d", i);
        !          7566:                        tp = &np->target[i];
        !          7567:                        if (DEBUG_FLAGS & DEBUG_RESTART) printf ("+");
        !          7568:                        cp = tp->hold_cp;
        !          7569:                        if (!cp) continue;
        !          7570:                        if (DEBUG_FLAGS & DEBUG_RESTART) printf ("+");
        !          7571:                        if ((cp->host_status==HS_BUSY) &&
        !          7572:                                (cp->scsi_status==S_CHECK_COND))
        !          7573:                                break;
        !          7574:                        if (DEBUG_FLAGS & DEBUG_RESTART) printf ("- (remove)");
        !          7575:                        tp->hold_cp = cp = (ccb_p) 0;
        !          7576:                };
        !          7577: 
        !          7578:                if (cp) {
        !          7579:                        if (DEBUG_FLAGS & DEBUG_RESTART)
        !          7580:                                printf ("+ restart job ..\n");
        !          7581:                        OUTL (nc_dsa, CCB_PHYS (cp, phys));
        !          7582:                        OUTL (nc_dsp, NCB_SCRIPTH_PHYS (np, getcc));
        !          7583:                        return;
        !          7584:                };
        !          7585: 
        !          7586:                /*
        !          7587:                **      no job, resume normal processing
        !          7588:                */
        !          7589:                if (DEBUG_FLAGS & DEBUG_RESTART) printf (" -- remove trap\n");
        !          7590:                np->script->start0[0] =  cpu_to_scr(SCR_INT ^ IFFALSE (0));
        !          7591:                break;
        !          7592: 
        !          7593:        case SIR_SENSE_FAILED:
        !          7594:                /*-------------------------------------------
        !          7595:                **      While trying to select for
        !          7596:                **      getting the condition code,
        !          7597:                **      a target reselected us.
        !          7598:                **-------------------------------------------
        !          7599:                */
        !          7600:                if (DEBUG_FLAGS & DEBUG_RESTART) {
        !          7601:                        PRINT_ADDR(cp->cmd);
        !          7602:                        printf ("in getcc reselect by t%d.\n",
        !          7603:                                (int)INB(nc_ssid) & 0x0f);
        !          7604:                }
        !          7605: 
        !          7606:                /*
        !          7607:                **      Mark this job
        !          7608:                */
        !          7609:                cp->host_status = HS_BUSY;
        !          7610:                cp->scsi_status = S_CHECK_COND;
        !          7611:                np->target[cp->cmd->target].hold_cp = cp;
        !          7612: 
        !          7613:                /*
        !          7614:                **      And patch code to restart it.
        !          7615:                */
        !          7616:                np->script->start0[0] =  cpu_to_scr(SCR_INT);
        !          7617:                break;
        !          7618: 
        !          7619: /*-----------------------------------------------------------------------------
        !          7620: **
        !          7621: **     Was Sie schon immer ueber transfermode negotiation wissen wollten ...
        !          7622: **
        !          7623: **     We try to negotiate sync and wide transfer only after
        !          7624: **     a successfull inquire command. We look at byte 7 of the
        !          7625: **     inquire data to determine the capabilities of the target.
        !          7626: **
        !          7627: **     When we try to negotiate, we append the negotiation message
        !          7628: **     to the identify and (maybe) simple tag message.
        !          7629: **     The host status field is set to HS_NEGOTIATE to mark this
        !          7630: **     situation.
        !          7631: **
        !          7632: **     If the target doesn't answer this message immidiately
        !          7633: **     (as required by the standard), the SIR_NEGO_FAIL interrupt
        !          7634: **     will be raised eventually.
        !          7635: **     The handler removes the HS_NEGOTIATE status, and sets the
        !          7636: **     negotiated value to the default (async / nowide).
        !          7637: **
        !          7638: **     If we receive a matching answer immediately, we check it
        !          7639: **     for validity, and set the values.
        !          7640: **
        !          7641: **     If we receive a Reject message immediately, we assume the
        !          7642: **     negotiation has failed, and fall back to standard values.
        !          7643: **
        !          7644: **     If we receive a negotiation message while not in HS_NEGOTIATE
        !          7645: **     state, it's a target initiated negotiation. We prepare a
        !          7646: **     (hopefully) valid answer, set our parameters, and send back 
        !          7647: **     this answer to the target.
        !          7648: **
        !          7649: **     If the target doesn't fetch the answer (no message out phase),
        !          7650: **     we assume the negotiation has failed, and fall back to default
        !          7651: **     settings.
        !          7652: **
        !          7653: **     When we set the values, we adjust them in all ccbs belonging 
        !          7654: **     to this target, in the controller's register, and in the "phys"
        !          7655: **     field of the controller's struct ncb.
        !          7656: **
        !          7657: **     Possible cases:            hs  sir   msg_in value  send   goto
        !          7658: **     We try to negotiate:
        !          7659: **     -> target doesnt't msgin   NEG FAIL  noop   defa.  -      dispatch
        !          7660: **     -> target rejected our msg NEG FAIL  reject defa.  -      dispatch
        !          7661: **     -> target answered  (ok)   NEG SYNC  sdtr   set    -      clrack
        !          7662: **     -> target answered (!ok)   NEG SYNC  sdtr   defa.  REJ--->msg_bad
        !          7663: **     -> target answered  (ok)   NEG WIDE  wdtr   set    -      clrack
        !          7664: **     -> target answered (!ok)   NEG WIDE  wdtr   defa.  REJ--->msg_bad
        !          7665: **     -> any other msgin         NEG FAIL  noop   defa.  -      dispatch
        !          7666: **
        !          7667: **     Target tries to negotiate:
        !          7668: **     -> incoming message        --- SYNC  sdtr   set    SDTR   -
        !          7669: **     -> incoming message        --- WIDE  wdtr   set    WDTR   -
        !          7670: **      We sent our answer:
        !          7671: **     -> target doesn't msgout   --- PROTO ?      defa.  -      dispatch
        !          7672: **
        !          7673: **-----------------------------------------------------------------------------
        !          7674: */
        !          7675: 
        !          7676:        case SIR_NEGO_FAILED:
        !          7677:                /*-------------------------------------------------------
        !          7678:                **
        !          7679:                **      Negotiation failed.
        !          7680:                **      Target doesn't send an answer message,
        !          7681:                **      or target rejected our message.
        !          7682:                **
        !          7683:                **      Remove negotiation request.
        !          7684:                **
        !          7685:                **-------------------------------------------------------
        !          7686:                */
        !          7687:                OUTB (HS_PRT, HS_BUSY);
        !          7688: 
        !          7689:                /* fall through */
        !          7690: 
        !          7691:        case SIR_NEGO_PROTO:
        !          7692:                /*-------------------------------------------------------
        !          7693:                **
        !          7694:                **      Negotiation failed.
        !          7695:                **      Target doesn't fetch the answer message.
        !          7696:                **
        !          7697:                **-------------------------------------------------------
        !          7698:                */
        !          7699: 
        !          7700:                if (DEBUG_FLAGS & DEBUG_NEGO) {
        !          7701:                        PRINT_ADDR(cp->cmd);
        !          7702:                        printf ("negotiation failed sir=%x status=%x.\n",
        !          7703:                                num, cp->nego_status);
        !          7704:                };
        !          7705: 
        !          7706:                /*
        !          7707:                **      any error in negotiation:
        !          7708:                **      fall back to default mode.
        !          7709:                */
        !          7710:                switch (cp->nego_status) {
        !          7711: 
        !          7712:                case NS_SYNC:
        !          7713:                        ncr_setsync (np, cp, 0, 0xe0);
        !          7714:                        break;
        !          7715: 
        !          7716:                case NS_WIDE:
        !          7717:                        ncr_setwide (np, cp, 0, 0);
        !          7718:                        break;
        !          7719: 
        !          7720:                };
        !          7721:                np->msgin [0] = M_NOOP;
        !          7722:                np->msgout[0] = M_NOOP;
        !          7723:                cp->nego_status = 0;
        !          7724:                OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, dispatch));
        !          7725:                break;
        !          7726: 
        !          7727:        case SIR_NEGO_SYNC:
        !          7728:                /*
        !          7729:                **      Synchronous request message received.
        !          7730:                */
        !          7731: 
        !          7732:                if (DEBUG_FLAGS & DEBUG_NEGO) {
        !          7733:                        PRINT_ADDR(cp->cmd);
        !          7734:                        printf ("sync msgin: ");
        !          7735:                        (void) ncr_show_msg (np->msgin);
        !          7736:                        printf (".\n");
        !          7737:                };
        !          7738: 
        !          7739:                /*
        !          7740:                **      get requested values.
        !          7741:                */
        !          7742: 
        !          7743:                chg = 0;
        !          7744:                per = np->msgin[3];
        !          7745:                ofs = np->msgin[4];
        !          7746:                if (ofs==0) per=255;
        !          7747: 
        !          7748:                /*
        !          7749:                **      if target sends SDTR message,
        !          7750:                **            it CAN transfer synch.
        !          7751:                */
        !          7752: 
        !          7753:                if (ofs)
        !          7754:                        tp->inqdata[7] |= INQ7_SYNC;
        !          7755: 
        !          7756:                /*
        !          7757:                **      check values against driver limits.
        !          7758:                */
        !          7759: 
        !          7760:                if (per < np->minsync)
        !          7761:                        {chg = 1; per = np->minsync;}
        !          7762:                if (per < tp->minsync)
        !          7763:                        {chg = 1; per = tp->minsync;}
        !          7764:                if (ofs > tp->maxoffs)
        !          7765:                        {chg = 1; ofs = tp->maxoffs;}
        !          7766: 
        !          7767:                /*
        !          7768:                **      Check against controller limits.
        !          7769:                */
        !          7770:                fak     = 7;
        !          7771:                scntl3  = 0;
        !          7772:                if (ofs != 0) {
        !          7773:                        ncr_getsync(np, per, &fak, &scntl3);
        !          7774:                        if (fak > 7) {
        !          7775:                                chg = 1;
        !          7776:                                ofs = 0;
        !          7777:                        }
        !          7778:                }
        !          7779:                if (ofs == 0) {
        !          7780:                        fak     = 7;
        !          7781:                        per     = 0;
        !          7782:                        scntl3  = 0;
        !          7783:                        tp->minsync = 0;
        !          7784:                }
        !          7785: 
        !          7786:                if (DEBUG_FLAGS & DEBUG_NEGO) {
        !          7787:                        PRINT_ADDR(cp->cmd);
        !          7788:                        printf ("sync: per=%d scntl3=0x%x ofs=%d fak=%d chg=%d.\n",
        !          7789:                                per, scntl3, ofs, fak, chg);
        !          7790:                }
        !          7791: 
        !          7792:                if (INB (HS_PRT) == HS_NEGOTIATE) {
        !          7793:                        OUTB (HS_PRT, HS_BUSY);
        !          7794:                        switch (cp->nego_status) {
        !          7795: 
        !          7796:                        case NS_SYNC:
        !          7797:                                /*
        !          7798:                                **      This was an answer message
        !          7799:                                */
        !          7800:                                if (chg) {
        !          7801:                                        /*
        !          7802:                                        **      Answer wasn't acceptable.
        !          7803:                                        */
        !          7804:                                        ncr_setsync (np, cp, 0, 0xe0);
        !          7805:                                        OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, msg_bad));
        !          7806:                                } else {
        !          7807:                                        /*
        !          7808:                                        **      Answer is ok.
        !          7809:                                        */
        !          7810:                                        ncr_setsync (np, cp, scntl3, (fak<<5)|ofs);
        !          7811:                                        OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack));
        !          7812:                                };
        !          7813:                                return;
        !          7814: 
        !          7815:                        case NS_WIDE:
        !          7816:                                ncr_setwide (np, cp, 0, 0);
        !          7817:                                break;
        !          7818:                        };
        !          7819:                };
        !          7820: 
        !          7821:                /*
        !          7822:                **      It was a request.
        !          7823:                **      Check against the table of target capabilities.
        !          7824:                **      If target not capable force M_REJECT and asynchronous.
        !          7825:                */
        !          7826:                if (np->unit < SCSI_NCR_MAX_HOST) {
        !          7827:                        tp->inqdata[7] &=
        !          7828:                                (target_capabilities[np->unit].and_map[target]);
        !          7829:                        if (!(tp->inqdata[7] & INQ7_SYNC)) {
        !          7830:                                ofs = 0;
        !          7831:                                fak = 7;
        !          7832:                        }
        !          7833:                }
        !          7834: 
        !          7835:                /*
        !          7836:                **      It was a request. Set value and
        !          7837:                **      prepare an answer message
        !          7838:                */
        !          7839: 
        !          7840:                ncr_setsync (np, cp, scntl3, (fak<<5)|ofs);
        !          7841: 
        !          7842:                np->msgout[0] = M_EXTENDED;
        !          7843:                np->msgout[1] = 3;
        !          7844:                np->msgout[2] = M_X_SYNC_REQ;
        !          7845:                np->msgout[3] = per;
        !          7846:                np->msgout[4] = ofs;
        !          7847: 
        !          7848:                cp->nego_status = NS_SYNC;
        !          7849: 
        !          7850:                if (DEBUG_FLAGS & DEBUG_NEGO) {
        !          7851:                        PRINT_ADDR(cp->cmd);
        !          7852:                        printf ("sync msgout: ");
        !          7853:                        (void) ncr_show_msg (np->msgout);
        !          7854:                        printf (".\n");
        !          7855:                }
        !          7856: 
        !          7857:                if (!ofs) {
        !          7858:                        OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, msg_bad));
        !          7859:                        return;
        !          7860:                }
        !          7861:                np->msgin [0] = M_NOOP;
        !          7862: 
        !          7863:                break;
        !          7864: 
        !          7865:        case SIR_NEGO_WIDE:
        !          7866:                /*
        !          7867:                **      Wide request message received.
        !          7868:                */
        !          7869:                if (DEBUG_FLAGS & DEBUG_NEGO) {
        !          7870:                        PRINT_ADDR(cp->cmd);
        !          7871:                        printf ("wide msgin: ");
        !          7872:                        (void) ncr_show_msg (np->msgin);
        !          7873:                        printf (".\n");
        !          7874:                };
        !          7875: 
        !          7876:                /*
        !          7877:                **      get requested values.
        !          7878:                */
        !          7879: 
        !          7880:                chg  = 0;
        !          7881:                wide = np->msgin[3];
        !          7882: 
        !          7883:                /*
        !          7884:                **      if target sends WDTR message,
        !          7885:                **            it CAN transfer wide.
        !          7886:                */
        !          7887: 
        !          7888:                if (wide)
        !          7889:                        tp->inqdata[7] |= INQ7_WIDE16;
        !          7890: 
        !          7891:                /*
        !          7892:                **      check values against driver limits.
        !          7893:                */
        !          7894: 
        !          7895:                if (wide > tp->usrwide)
        !          7896:                        {chg = 1; wide = tp->usrwide;}
        !          7897: 
        !          7898:                if (DEBUG_FLAGS & DEBUG_NEGO) {
        !          7899:                        PRINT_ADDR(cp->cmd);
        !          7900:                        printf ("wide: wide=%d chg=%d.\n", wide, chg);
        !          7901:                }
        !          7902: 
        !          7903:                if (INB (HS_PRT) == HS_NEGOTIATE) {
        !          7904:                        OUTB (HS_PRT, HS_BUSY);
        !          7905:                        switch (cp->nego_status) {
        !          7906: 
        !          7907:                        case NS_WIDE:
        !          7908:                                /*
        !          7909:                                **      This was an answer message
        !          7910:                                */
        !          7911:                                if (chg) {
        !          7912:                                        /*
        !          7913:                                        **      Answer wasn't acceptable.
        !          7914:                                        */
        !          7915:                                        ncr_setwide (np, cp, 0, 1);
        !          7916:                                        OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, msg_bad));
        !          7917:                                } else {
        !          7918:                                        /*
        !          7919:                                        **      Answer is ok.
        !          7920:                                        */
        !          7921:                                        ncr_setwide (np, cp, wide, 1);
        !          7922:                                        OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack));
        !          7923:                                };
        !          7924:                                return;
        !          7925: 
        !          7926:                        case NS_SYNC:
        !          7927:                                ncr_setsync (np, cp, 0, 0xe0);
        !          7928:                                break;
        !          7929:                        };
        !          7930:                };
        !          7931: 
        !          7932:                /*
        !          7933:                **      It was a request, set value and
        !          7934:                **      prepare an answer message
        !          7935:                */
        !          7936: 
        !          7937:                ncr_setwide (np, cp, wide, 1);
        !          7938: 
        !          7939:                np->msgout[0] = M_EXTENDED;
        !          7940:                np->msgout[1] = 2;
        !          7941:                np->msgout[2] = M_X_WIDE_REQ;
        !          7942:                np->msgout[3] = wide;
        !          7943: 
        !          7944:                np->msgin [0] = M_NOOP;
        !          7945: 
        !          7946:                cp->nego_status = NS_WIDE;
        !          7947: 
        !          7948:                if (DEBUG_FLAGS & DEBUG_NEGO) {
        !          7949:                        PRINT_ADDR(cp->cmd);
        !          7950:                        printf ("wide msgout: ");
        !          7951:                        (void) ncr_show_msg (np->msgin);
        !          7952:                        printf (".\n");
        !          7953:                }
        !          7954:                break;
        !          7955: 
        !          7956: /*--------------------------------------------------------------------
        !          7957: **
        !          7958: **     Processing of special messages
        !          7959: **
        !          7960: **--------------------------------------------------------------------
        !          7961: */
        !          7962: 
        !          7963:        case SIR_REJECT_RECEIVED:
        !          7964:                /*-----------------------------------------------
        !          7965:                **
        !          7966:                **      We received a M_REJECT message.
        !          7967:                **
        !          7968:                **-----------------------------------------------
        !          7969:                */
        !          7970: 
        !          7971:                PRINT_ADDR(cp->cmd);
        !          7972:                printf ("M_REJECT received (%x:%x).\n",
        !          7973:                        (unsigned)scr_to_cpu(np->lastmsg), np->msgout[0]);
        !          7974:                break;
        !          7975: 
        !          7976:        case SIR_REJECT_SENT:
        !          7977:                /*-----------------------------------------------
        !          7978:                **
        !          7979:                **      We received an unknown message
        !          7980:                **
        !          7981:                **-----------------------------------------------
        !          7982:                */
        !          7983: 
        !          7984:                PRINT_ADDR(cp->cmd);
        !          7985:                printf ("M_REJECT sent for ");
        !          7986:                (void) ncr_show_msg (np->msgin);
        !          7987:                printf (".\n");
        !          7988:                break;
        !          7989: 
        !          7990: /*--------------------------------------------------------------------
        !          7991: **
        !          7992: **     Processing of special messages
        !          7993: **
        !          7994: **--------------------------------------------------------------------
        !          7995: */
        !          7996: 
        !          7997:        case SIR_IGN_RESIDUE:
        !          7998:                /*-----------------------------------------------
        !          7999:                **
        !          8000:                **      We received an IGNORE RESIDUE message,
        !          8001:                **      which couldn't be handled by the script.
        !          8002:                **
        !          8003:                **-----------------------------------------------
        !          8004:                */
        !          8005: 
        !          8006:                PRINT_ADDR(cp->cmd);
        !          8007:                printf ("M_IGN_RESIDUE received, but not yet implemented.\n");
        !          8008:                break;
        !          8009: 
        !          8010:        case SIR_MISSING_SAVE:
        !          8011:                /*-----------------------------------------------
        !          8012:                **
        !          8013:                **      We received an DISCONNECT message,
        !          8014:                **      but the datapointer wasn't saved before.
        !          8015:                **
        !          8016:                **-----------------------------------------------
        !          8017:                */
        !          8018: 
        !          8019:                PRINT_ADDR(cp->cmd);
        !          8020:                printf ("M_DISCONNECT received, but datapointer not saved: "
        !          8021:                        "data=%x save=%x goal=%x.\n",
        !          8022:                        (unsigned) INL (nc_temp),
        !          8023:                        (unsigned) scr_to_cpu(np->header.savep),
        !          8024:                        (unsigned) scr_to_cpu(np->header.goalp));
        !          8025:                break;
        !          8026: 
        !          8027: #if 0   /* This stuff does not work */
        !          8028: /*--------------------------------------------------------------------
        !          8029: **
        !          8030: **     Processing of a "S_QUEUE_FULL" status.
        !          8031: **
        !          8032: **     The current command has been rejected,
        !          8033: **     because there are too many in the command queue.
        !          8034: **     We have started too many commands for that target.
        !          8035: **
        !          8036: **     If possible, reinsert at head of queue.
        !          8037: **     Stall queue until there are no disconnected jobs
        !          8038: **     (ncr is REALLY idle). Then restart processing.
        !          8039: **
        !          8040: **     We should restart the current job after the controller
        !          8041: **     has become idle. But this is not yet implemented.
        !          8042: **
        !          8043: **--------------------------------------------------------------------
        !          8044: */
        !          8045:        case SIR_STALL_QUEUE:
        !          8046:                /*-----------------------------------------------
        !          8047:                **
        !          8048:                **      Stall the start queue.
        !          8049:                **
        !          8050:                **-----------------------------------------------
        !          8051:                */
        !          8052:                PRINT_ADDR(cp->cmd);
        !          8053:                printf ("queue full.\n");
        !          8054: 
        !          8055:                np->script->start1[0] =  cpu_to_scr(SCR_INT);
        !          8056: 
        !          8057:                /*
        !          8058:                **      Try to disable tagged transfers.
        !          8059:                */
        !          8060:                ncr_setmaxtags (np, &np->target[target], 0);
        !          8061: 
        !          8062:                /*
        !          8063:                ** @QUEUE@
        !          8064:                **
        !          8065:                **      Should update the launch field of the
        !          8066:                **      current job to be able to restart it.
        !          8067:                **      Then prepend it to the start queue.
        !          8068:                */
        !          8069: 
        !          8070:                /* fall through */
        !          8071: 
        !          8072:        case SIR_STALL_RESTART:
        !          8073:                /*-----------------------------------------------
        !          8074:                **
        !          8075:                **      Enable selecting again,
        !          8076:                **      if NO disconnected jobs.
        !          8077:                **
        !          8078:                **-----------------------------------------------
        !          8079:                */
        !          8080:                /*
        !          8081:                **      Look for a disconnected job.
        !          8082:                */
        !          8083:                cp = np->ccb;
        !          8084:                while (cp && cp->host_status != HS_DISCONNECT)
        !          8085:                        cp = cp->link_ccb;
        !          8086: 
        !          8087:                /*
        !          8088:                **      if there is one, ...
        !          8089:                */
        !          8090:                if (cp) {
        !          8091:                        /*
        !          8092:                        **      wait for reselection
        !          8093:                        */
        !          8094:                        OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, reselect));
        !          8095:                        return;
        !          8096:                };
        !          8097: 
        !          8098:                /*
        !          8099:                **      else remove the interrupt.
        !          8100:                */
        !          8101: 
        !          8102:                printf ("%s: queue empty.\n", ncr_name (np));
        !          8103:                np->script->start1[0] =  cpu_to_scr(SCR_INT ^ IFFALSE (0));
        !          8104:                break;
        !          8105: #endif   /* This stuff does not work */
        !          8106:        };
        !          8107: 
        !          8108: out:
        !          8109:        OUTONB (nc_dcntl, (STD|NOCOM));
        !          8110: }
        !          8111: 
        !          8112: /*==========================================================
        !          8113: **
        !          8114: **
        !          8115: **     Aquire a control block
        !          8116: **
        !          8117: **
        !          8118: **==========================================================
        !          8119: */
        !          8120: 
        !          8121: static ccb_p ncr_get_ccb
        !          8122:        (ncb_p np, u_long target, u_long lun)
        !          8123: {
        !          8124:        lcb_p lp;
        !          8125:        ccb_p cp = (ccb_p) 0;
        !          8126: 
        !          8127:        /*
        !          8128:        **      Lun structure available ?
        !          8129:        */
        !          8130: 
        !          8131:        lp = np->target[target].lp[lun];
        !          8132: 
        !          8133:        if (lp && lp->opennings && (!lp->active || lp->active < lp->reqlink)) {
        !          8134: 
        !          8135:                cp = lp->next_ccb;
        !          8136: 
        !          8137:                /*
        !          8138:                **      Look for free CCB
        !          8139:                */
        !          8140: 
        !          8141:                while (cp && cp->magic) cp = cp->next_ccb;
        !          8142: 
        !          8143:                /*
        !          8144:                **      Increment active commands and decrement credit.
        !          8145:                */
        !          8146: 
        !          8147:                if (cp) {
        !          8148:                        ++lp->active;
        !          8149:                        --lp->opennings;
        !          8150:                }
        !          8151:        }
        !          8152: 
        !          8153:        /*
        !          8154:        **      if nothing available, take the default.
        !          8155:        **      DANGEROUS, because this ccb is not suitable for
        !          8156:        **      reselection.
        !          8157:        **      If lp->actccbs > 0 wait for a suitable ccb to be free.
        !          8158:        */
        !          8159:        if ((!cp) && lp && lp->actccbs > 0)
        !          8160:                return ((ccb_p) 0);
        !          8161: 
        !          8162:        if (!cp) cp = np->ccb;
        !          8163: 
        !          8164:        /*
        !          8165:        **      Wait until available.
        !          8166:        */
        !          8167: #if 0
        !          8168:        while (cp->magic) {
        !          8169:                if (flags & SCSI_NOSLEEP) break;
        !          8170:                if (tsleep ((caddr_t)cp, PRIBIO|PCATCH, "ncr", 0))
        !          8171:                        break;
        !          8172:        };
        !          8173: #endif
        !          8174: 
        !          8175:        if (cp->magic)
        !          8176:                return ((ccb_p) 0);
        !          8177: 
        !          8178:        cp->magic = 1;
        !          8179:        return (cp);
        !          8180: }
        !          8181: 
        !          8182: /*==========================================================
        !          8183: **
        !          8184: **
        !          8185: **     Release one control block
        !          8186: **
        !          8187: **
        !          8188: **==========================================================
        !          8189: */
        !          8190: 
        !          8191: void ncr_free_ccb (ncb_p np, ccb_p cp, u_long target, u_long lun)
        !          8192: {
        !          8193:        lcb_p lp;
        !          8194: 
        !          8195:        /*
        !          8196:        **    sanity
        !          8197:        */
        !          8198: 
        !          8199:        assert (cp != NULL);
        !          8200: 
        !          8201:        /*
        !          8202:        **      Decrement active commands and increment credit.
        !          8203:        */
        !          8204: 
        !          8205:        lp = np->target[target].lp[lun];
        !          8206:        if (lp) {
        !          8207:                        --lp->active;
        !          8208:                        ++lp->opennings;
        !          8209:        }
        !          8210: 
        !          8211:        cp -> host_status = HS_IDLE;
        !          8212:        cp -> magic = 0;
        !          8213: #if 0
        !          8214:        if (cp == np->ccb)
        !          8215:                wakeup ((caddr_t) cp);
        !          8216: #endif
        !          8217: }
        !          8218: 
        !          8219: /*==========================================================
        !          8220: **
        !          8221: **
        !          8222: **      Allocation of resources for Targets/Luns/Tags.
        !          8223: **
        !          8224: **
        !          8225: **==========================================================
        !          8226: */
        !          8227: 
        !          8228: static void ncr_alloc_ccb (ncb_p np, u_long target, u_long lun)
        !          8229: {
        !          8230:        tcb_p tp;
        !          8231:        lcb_p lp;
        !          8232:        ccb_p cp;
        !          8233: 
        !          8234:        assert (np != NULL);
        !          8235: 
        !          8236:        if (target>=MAX_TARGET) return;
        !          8237:        if (lun   >=MAX_LUN   ) return;
        !          8238: 
        !          8239:        tp=&np->target[target];
        !          8240: 
        !          8241:        if (!tp->jump_tcb.l_cmd) {
        !          8242:                /*
        !          8243:                **      initialize it.
        !          8244:                */
        !          8245:                tp->jump_tcb.l_cmd   =
        !          8246:                        cpu_to_scr((SCR_JUMP^IFFALSE (DATA (0x80 + target))));
        !          8247:                tp->jump_tcb.l_paddr = np->jump_tcb.l_paddr;
        !          8248: 
        !          8249:                tp->getscr[0] = (np->features & FE_PFEN) ?
        !          8250:                        cpu_to_scr(SCR_COPY(1)):cpu_to_scr(SCR_COPY_F(1));
        !          8251:                tp->getscr[1] = cpu_to_scr(vtophys (&tp->sval));
        !          8252:                tp->getscr[2] =
        !          8253:                cpu_to_scr(np->paddr + offsetof (struct ncr_reg, nc_sxfer));
        !          8254: 
        !          8255:                tp->getscr[3] = (np->features & FE_PFEN) ?
        !          8256:                        cpu_to_scr(SCR_COPY(1)):cpu_to_scr(SCR_COPY_F(1));
        !          8257:                tp->getscr[4] = cpu_to_scr(vtophys (&tp->wval));
        !          8258:                tp->getscr[5] =
        !          8259:                cpu_to_scr(np->paddr + offsetof (struct ncr_reg, nc_scntl3));
        !          8260: 
        !          8261:                assert (( (offsetof(struct ncr_reg, nc_sxfer) ^
        !          8262:                        offsetof(struct tcb    , sval    )) &3) == 0);
        !          8263:                assert (( (offsetof(struct ncr_reg, nc_scntl3) ^
        !          8264:                        offsetof(struct tcb    , wval    )) &3) == 0);
        !          8265: 
        !          8266:                tp->call_lun.l_cmd   = cpu_to_scr(SCR_CALL);
        !          8267:                tp->call_lun.l_paddr =
        !          8268:                        cpu_to_scr(NCB_SCRIPT_PHYS (np, resel_lun));
        !          8269: 
        !          8270:                tp->jump_lcb.l_cmd   = cpu_to_scr(SCR_JUMP);
        !          8271:                tp->jump_lcb.l_paddr = cpu_to_scr(NCB_SCRIPTH_PHYS (np, abort));
        !          8272:                np->jump_tcb.l_paddr = cpu_to_scr(vtophys (&tp->jump_tcb));
        !          8273:        }
        !          8274: 
        !          8275:        /*
        !          8276:        **      Logic unit control block
        !          8277:        */
        !          8278:        lp = tp->lp[lun];
        !          8279:        if (!lp) {
        !          8280:                /*
        !          8281:                **      Allocate a lcb
        !          8282:                */
        !          8283:                lp = (lcb_p) m_alloc (sizeof (struct lcb), LCB_ALIGN_SHIFT);
        !          8284:                if (!lp) return;
        !          8285: 
        !          8286:                if (DEBUG_FLAGS & DEBUG_ALLOC) {
        !          8287:                        PRINT_LUN(np, target, lun);
        !          8288:                        printf ("new lcb @%p.\n", lp);
        !          8289:                }
        !          8290: 
        !          8291:                /*
        !          8292:                **      Initialize it
        !          8293:                */
        !          8294:                bzero (lp, sizeof (*lp));
        !          8295:                lp->jump_lcb.l_cmd   =
        !          8296:                        cpu_to_scr(SCR_JUMP ^ IFFALSE (DATA (lun)));
        !          8297:                lp->jump_lcb.l_paddr = tp->jump_lcb.l_paddr;
        !          8298: 
        !          8299:                lp->call_tag.l_cmd   = cpu_to_scr(SCR_CALL);
        !          8300:                lp->call_tag.l_paddr =
        !          8301:                        cpu_to_scr(NCB_SCRIPT_PHYS (np, resel_tag));
        !          8302: 
        !          8303:                lp->jump_ccb.l_cmd   = cpu_to_scr(SCR_JUMP);
        !          8304:                lp->jump_ccb.l_paddr =
        !          8305:                        cpu_to_scr(NCB_SCRIPTH_PHYS (np, aborttag));
        !          8306: 
        !          8307:                lp->actlink = 1;
        !          8308: 
        !          8309:                lp->active  = 1;
        !          8310: 
        !          8311:                /*
        !          8312:                **   Chain into LUN list
        !          8313:                */
        !          8314:                tp->jump_lcb.l_paddr = cpu_to_scr(vtophys (&lp->jump_lcb));
        !          8315:                tp->lp[lun] = lp;
        !          8316: 
        !          8317:                ncr_setmaxtags (np, tp, driver_setup.default_tags);
        !          8318:        }
        !          8319: 
        !          8320:        /*
        !          8321:        **      Allocate ccbs up to lp->reqccbs.
        !          8322:        */
        !          8323: 
        !          8324:        /*
        !          8325:        **      Limit possible number of ccbs.
        !          8326:        **
        !          8327:        **      If tagged command queueing is enabled,
        !          8328:        **      can use more than one ccb.
        !          8329:        */
        !          8330:        if (np->actccbs >= MAX_START-2) return;
        !          8331:        if (lp->actccbs && (lp->actccbs >= lp->reqccbs))
        !          8332:                return;
        !          8333: 
        !          8334:        /*
        !          8335:        **      Allocate a ccb
        !          8336:        */
        !          8337:        cp = (ccb_p) m_alloc (sizeof (struct ccb), CCB_ALIGN_SHIFT);
        !          8338:        if (!cp)
        !          8339:                return;
        !          8340: 
        !          8341:        if (DEBUG_FLAGS & DEBUG_ALLOC) {
        !          8342:                PRINT_LUN(np, target, lun);
        !          8343:                printf ("new ccb @%p.\n", cp);
        !          8344:        }
        !          8345: 
        !          8346:        /*
        !          8347:        **      Count it
        !          8348:        */
        !          8349:        lp->actccbs++;
        !          8350:        np->actccbs++;
        !          8351: 
        !          8352:        /*
        !          8353:        **      Initialize it
        !          8354:        */
        !          8355:        bzero (cp, sizeof (*cp));
        !          8356: 
        !          8357:        /*
        !          8358:        **      Fill in physical addresses
        !          8359:        */
        !          8360: 
        !          8361:        cp->p_ccb            = vtophys (cp);
        !          8362: 
        !          8363:        /*
        !          8364:        **      Chain into reselect list
        !          8365:        */
        !          8366:        cp->jump_ccb.l_cmd   = cpu_to_scr(SCR_JUMP);
        !          8367:        cp->jump_ccb.l_paddr = lp->jump_ccb.l_paddr;
        !          8368:        lp->jump_ccb.l_paddr = cpu_to_scr(CCB_PHYS (cp, jump_ccb));
        !          8369:        cp->call_tmp.l_cmd   = cpu_to_scr(SCR_CALL);
        !          8370:        cp->call_tmp.l_paddr = cpu_to_scr(NCB_SCRIPT_PHYS (np, resel_tmp));
        !          8371: 
        !          8372:        /*
        !          8373:        **      Chain into wakeup list
        !          8374:        */
        !          8375:        cp->link_ccb      = np->ccb->link_ccb;
        !          8376:        np->ccb->link_ccb = cp;
        !          8377: 
        !          8378:        /*
        !          8379:        **      Chain into CCB list
        !          8380:        */
        !          8381:        cp->next_ccb    = lp->next_ccb;
        !          8382:        lp->next_ccb    = cp;
        !          8383: }
        !          8384: 
        !          8385: /*==========================================================
        !          8386: **
        !          8387: **
        !          8388: **     Announce the number of ccbs/tags to the scsi driver.
        !          8389: **
        !          8390: **
        !          8391: **==========================================================
        !          8392: */
        !          8393: 
        !          8394: static void ncr_opennings (ncb_p np, lcb_p lp, Scsi_Cmnd * cmd)
        !          8395: {
        !          8396:        /*
        !          8397:        **      want to reduce the number ...
        !          8398:        */
        !          8399:        if (lp->actlink > lp->reqlink) {
        !          8400: 
        !          8401:                /*
        !          8402:                **      Try to  reduce the count.
        !          8403:                **      We assume to run at splbio ..
        !          8404:                */
        !          8405:                u_char diff = lp->actlink - lp->reqlink;
        !          8406: 
        !          8407:                if (!diff) return;
        !          8408: 
        !          8409:                if (diff > lp->opennings)
        !          8410:                        diff = lp->opennings;
        !          8411: 
        !          8412:                lp->opennings   -= diff;
        !          8413: 
        !          8414:                lp->actlink     -= diff;
        !          8415:                if (DEBUG_FLAGS & DEBUG_TAGS)
        !          8416:                        printf ("%s: actlink: diff=%d, new=%d, req=%d\n",
        !          8417:                                ncr_name(np), diff, lp->actlink, lp->reqlink);
        !          8418:                return;
        !          8419:        };
        !          8420: 
        !          8421:        /*
        !          8422:        **      want to increase the number ?
        !          8423:        */
        !          8424:        if (lp->reqlink > lp->actlink) {
        !          8425:                u_char diff = lp->reqlink - lp->actlink;
        !          8426: 
        !          8427:                lp->opennings   += diff;
        !          8428: 
        !          8429:                lp->actlink     += diff;
        !          8430: #if 0
        !          8431:                wakeup ((caddr_t) xp->sc_link);
        !          8432: #endif
        !          8433:                if (DEBUG_FLAGS & DEBUG_TAGS)
        !          8434:                        printf ("%s: actlink: diff=%d, new=%d, req=%d\n",
        !          8435:                                ncr_name(np), diff, lp->actlink, lp->reqlink);
        !          8436:        };
        !          8437: }
        !          8438: 
        !          8439: /*==========================================================
        !          8440: **
        !          8441: **
        !          8442: **     Build Scatter Gather Block
        !          8443: **
        !          8444: **
        !          8445: **==========================================================
        !          8446: **
        !          8447: **     The transfer area may be scattered among
        !          8448: **     several non adjacent physical pages.
        !          8449: **
        !          8450: **     We may use MAX_SCATTER blocks.
        !          8451: **
        !          8452: **----------------------------------------------------------
        !          8453: */
        !          8454: 
        !          8455: /*
        !          8456: **     We try to reduce the number of interrupts caused
        !          8457: **     by unexpected phase changes due to disconnects.
        !          8458: **     A typical harddisk may disconnect before ANY block.
        !          8459: **     If we wanted to avoid unexpected phase changes at all
        !          8460: **     we had to use a break point every 512 bytes.
        !          8461: **     Of course the number of scatter/gather blocks is
        !          8462: **     limited.
        !          8463: **     Under Linux, the scatter/gatter blocks are provided by 
        !          8464: **     the generic driver. We just have to copy addresses and 
        !          8465: **     sizes to the data segment array.
        !          8466: */
        !          8467: 
        !          8468: static int     ncr_scatter(ccb_p cp, Scsi_Cmnd *cmd)
        !          8469: {
        !          8470:        struct scr_tblmove *data;
        !          8471:        int segment     = 0;
        !          8472:        int use_sg      = (int) cmd->use_sg;
        !          8473: 
        !          8474: #if 0
        !          8475:        bzero (cp->phys.data, sizeof (cp->phys.data));
        !          8476: #endif
        !          8477:        data            = cp->phys.data;
        !          8478:        cp->data_len    = 0;
        !          8479: 
        !          8480:        if (!use_sg) {
        !          8481:                if (cmd->request_bufflen) {
        !          8482:                        data = &data[MAX_SCATTER - 1];
        !          8483:                        data[0].addr = cpu_to_scr(vtophys(cmd->request_buffer));
        !          8484:                        data[0].size = cpu_to_scr(cmd->request_bufflen);
        !          8485:                        cp->data_len = cmd->request_bufflen;
        !          8486:                        segment = 1;
        !          8487:                }
        !          8488:        }
        !          8489:        else if (use_sg <= MAX_SCATTER) {
        !          8490:                struct scatterlist *scatter = (struct scatterlist *)cmd->buffer;
        !          8491: 
        !          8492:                data = &data[MAX_SCATTER - use_sg];
        !          8493:                while (segment < use_sg) {
        !          8494:                        data[segment].addr =
        !          8495:                                cpu_to_scr(vtophys(scatter[segment].address));
        !          8496:                        data[segment].size =
        !          8497:                                cpu_to_scr(scatter[segment].length);
        !          8498:                        cp->data_len       += scatter[segment].length;
        !          8499:                        ++segment;
        !          8500:                }
        !          8501:        }
        !          8502:        else {
        !          8503:                return -1;
        !          8504:        }
        !          8505: 
        !          8506:        return segment;
        !          8507: }
        !          8508: 
        !          8509: /*==========================================================
        !          8510: **
        !          8511: **
        !          8512: **     Test the pci bus snoop logic :-(
        !          8513: **
        !          8514: **     Has to be called with interrupts disabled.
        !          8515: **
        !          8516: **
        !          8517: **==========================================================
        !          8518: */
        !          8519: 
        !          8520: #ifndef NCR_IOMAPPED
        !          8521: __initfunc(
        !          8522: static int ncr_regtest (struct ncb* np)
        !          8523: )
        !          8524: {
        !          8525:        register volatile u_long data;
        !          8526:        /*
        !          8527:        **      ncr registers may NOT be cached.
        !          8528:        **      write 0xffffffff to a read only register area,
        !          8529:        **      and try to read it back.
        !          8530:        */
        !          8531:        data = 0xffffffff;
        !          8532:        OUTL_OFF(offsetof(struct ncr_reg, nc_dstat), data);
        !          8533:        data = INL_OFF(offsetof(struct ncr_reg, nc_dstat));
        !          8534: #if 1
        !          8535:        if (data == 0xffffffff) {
        !          8536: #else
        !          8537:        if ((data & 0xe2f0fffd) != 0x02000080) {
        !          8538: #endif
        !          8539:                printf ("CACHE TEST FAILED: reg dstat-sstat2 readback %x.\n",
        !          8540:                        (unsigned) data);
        !          8541:                return (0x10);
        !          8542:        };
        !          8543:        return (0);
        !          8544: }
        !          8545: #endif
        !          8546: 
        !          8547: __initfunc(
        !          8548: static int ncr_snooptest (struct ncb* np)
        !          8549: )
        !          8550: {
        !          8551:        u_long  ncr_rd, ncr_wr, ncr_bk, host_rd, host_wr, pc, err=0;
        !          8552:        int     i;
        !          8553: #ifndef NCR_IOMAPPED
        !          8554:        if (np->reg) {
        !          8555:             err |= ncr_regtest (np);
        !          8556:             if (err) return (err);
        !          8557:        }
        !          8558: #endif
        !          8559:        /*
        !          8560:        **      init
        !          8561:        */
        !          8562:        pc  = NCB_SCRIPTH_PHYS (np, snooptest);
        !          8563:        host_wr = 1;
        !          8564:        ncr_wr  = 2;
        !          8565:        /*
        !          8566:        **      Set memory and register.
        !          8567:        */
        !          8568:        np->ncr_cache = cpu_to_scr(host_wr);
        !          8569:        OUTL (nc_temp, ncr_wr);
        !          8570:        /*
        !          8571:        **      Start script (exchange values)
        !          8572:        */
        !          8573:        OUTL (nc_dsp, pc);
        !          8574:        /*
        !          8575:        **      Wait 'til done (with timeout)
        !          8576:        */
        !          8577:        for (i=0; i<NCR_SNOOP_TIMEOUT; i++)
        !          8578:                if (INB(nc_istat) & (INTF|SIP|DIP))
        !          8579:                        break;
        !          8580:        /*
        !          8581:        **      Save termination position.
        !          8582:        */
        !          8583:        pc = INL (nc_dsp);
        !          8584:        /*
        !          8585:        **      Read memory and register.
        !          8586:        */
        !          8587:        host_rd = scr_to_cpu(np->ncr_cache);
        !          8588:        ncr_rd  = INL (nc_scratcha);
        !          8589:        ncr_bk  = INL (nc_temp);
        !          8590:        /*
        !          8591:        **      Reset ncr chip
        !          8592:        */
        !          8593:        OUTB (nc_istat,  SRST);
        !          8594:        DELAY (1000);
        !          8595:        OUTB (nc_istat,  0   );
        !          8596:        /*
        !          8597:        **      check for timeout
        !          8598:        */
        !          8599:        if (i>=NCR_SNOOP_TIMEOUT) {
        !          8600:                printf ("CACHE TEST FAILED: timeout.\n");
        !          8601:                return (0x20);
        !          8602:        };
        !          8603:        /*
        !          8604:        **      Check termination position.
        !          8605:        */
        !          8606:        if (pc != NCB_SCRIPTH_PHYS (np, snoopend)+8) {
        !          8607:                printf ("CACHE TEST FAILED: script execution failed.\n");
        !          8608:                printf ("start=%08lx, pc=%08lx, end=%08lx\n", 
        !          8609:                        (u_long) NCB_SCRIPTH_PHYS (np, snooptest), pc,
        !          8610:                        (u_long) NCB_SCRIPTH_PHYS (np, snoopend) +8);
        !          8611:                return (0x40);
        !          8612:        };
        !          8613:        /*
        !          8614:        **      Show results.
        !          8615:        */
        !          8616:        if (host_wr != ncr_rd) {
        !          8617:                printf ("CACHE TEST FAILED: host wrote %d, ncr read %d.\n",
        !          8618:                        (int) host_wr, (int) ncr_rd);
        !          8619:                err |= 1;
        !          8620:        };
        !          8621:        if (host_rd != ncr_wr) {
        !          8622:                printf ("CACHE TEST FAILED: ncr wrote %d, host read %d.\n",
        !          8623:                        (int) ncr_wr, (int) host_rd);
        !          8624:                err |= 2;
        !          8625:        };
        !          8626:        if (ncr_bk != ncr_wr) {
        !          8627:                printf ("CACHE TEST FAILED: ncr wrote %d, read back %d.\n",
        !          8628:                        (int) ncr_wr, (int) ncr_bk);
        !          8629:                err |= 4;
        !          8630:        };
        !          8631:        return (err);
        !          8632: }
        !          8633: 
        !          8634: /*==========================================================
        !          8635: **
        !          8636: **
        !          8637: **     Profiling the drivers and targets performance.
        !          8638: **
        !          8639: **
        !          8640: **==========================================================
        !          8641: */
        !          8642: 
        !          8643: #ifdef SCSI_NCR_PROFILE_SUPPORT
        !          8644: 
        !          8645: /*
        !          8646: **     Compute the difference in jiffies ticks.
        !          8647: */
        !          8648: 
        !          8649: #define ncr_delta(from, to) \
        !          8650:        ( ((to) && (from))? (to) - (from) : -1 )
        !          8651: 
        !          8652: #define PROFILE  cp->phys.header.stamp
        !          8653: static void ncb_profile (ncb_p np, ccb_p cp)
        !          8654: {
        !          8655:        int co, st, en, di, se, post,work,disc;
        !          8656:        u_long diff;
        !          8657: 
        !          8658:        PROFILE.end = jiffies;
        !          8659: 
        !          8660:        st = ncr_delta (PROFILE.start,PROFILE.status);
        !          8661:        if (st<0) return;       /* status  not reached  */
        !          8662: 
        !          8663:        co = ncr_delta (PROFILE.start,PROFILE.command);
        !          8664:        if (co<0) return;       /* command not executed */
        !          8665: 
        !          8666:        en = ncr_delta (PROFILE.start,PROFILE.end),
        !          8667:        di = ncr_delta (PROFILE.start,PROFILE.disconnect),
        !          8668:        se = ncr_delta (PROFILE.start,PROFILE.select);
        !          8669:        post = en - st;
        !          8670: 
        !          8671:        /*
        !          8672:        **      @PROFILE@  Disconnect time invalid if multiple disconnects
        !          8673:        */
        !          8674: 
        !          8675:        if (di>=0) disc = se-di; else  disc = 0;
        !          8676: 
        !          8677:        work = (st - co) - disc;
        !          8678: 
        !          8679:        diff = (np->disc_phys - np->disc_ref) & 0xff;
        !          8680:        np->disc_ref += diff;
        !          8681: 
        !          8682:        np->profile.num_trans   += 1;
        !          8683:        if (cp->cmd) {
        !          8684:                np->profile.num_kbytes  += (cp->cmd->request_bufflen >> 10);
        !          8685:                np->profile.rest_bytes  += (cp->cmd->request_bufflen & (0x400-1));
        !          8686:                if (np->profile.rest_bytes >= 0x400) {
        !          8687:                        ++np->profile.num_kbytes;
        !          8688:                        np->profile.rest_bytes  -= 0x400;
        !          8689:                }
        !          8690:        }
        !          8691:        np->profile.num_disc    += diff;
        !          8692:        np->profile.ms_setup    += co;
        !          8693:        np->profile.ms_data     += work;
        !          8694:        np->profile.ms_disc     += disc;
        !          8695:        np->profile.ms_post     += post;
        !          8696: }
        !          8697: #undef PROFILE
        !          8698: 
        !          8699: #endif /* SCSI_NCR_PROFILE_SUPPORT */
        !          8700: 
        !          8701: /*==========================================================
        !          8702: **
        !          8703: **
        !          8704: **     Device lookup.
        !          8705: **
        !          8706: **     @GENSCSI@ should be integrated to scsiconf.c
        !          8707: **
        !          8708: **
        !          8709: **==========================================================
        !          8710: */
        !          8711: 
        !          8712: struct table_entry {
        !          8713:        char *  manufacturer;
        !          8714:        char *  model;
        !          8715:        char *  version;
        !          8716:        u_long  info;
        !          8717: };
        !          8718: 
        !          8719: static struct table_entry device_tab[] =
        !          8720: {
        !          8721: #ifdef NCR_GETCC_WITHMSG
        !          8722:        {"", "", "", QUIRK_NOMSG},
        !          8723:        {"SONY", "SDT-5000", "3.17", QUIRK_NOMSG},
        !          8724:        {"WangDAT", "Model 2600", "01.7", QUIRK_NOMSG},
        !          8725:        {"WangDAT", "Model 3200", "02.2", QUIRK_NOMSG},
        !          8726:        {"WangDAT", "Model 1300", "02.4", QUIRK_NOMSG},
        !          8727: #endif
        !          8728:        {"", "", "", 0} /* catch all: must be last entry. */
        !          8729: };
        !          8730: 
        !          8731: static u_long ncr_lookup(char * id)
        !          8732: {
        !          8733:        struct table_entry * p = device_tab;
        !          8734:        char *d, *r, c;
        !          8735: 
        !          8736:        for (;;p++) {
        !          8737: 
        !          8738:                d = id+8;
        !          8739:                r = p->manufacturer;
        !          8740:                while ((c=*r++)) if (c!=*d++) break;
        !          8741:                if (c) continue;
        !          8742: 
        !          8743:                d = id+16;
        !          8744:                r = p->model;
        !          8745:                while ((c=*r++)) if (c!=*d++) break;
        !          8746:                if (c) continue;
        !          8747: 
        !          8748:                d = id+32;
        !          8749:                r = p->version;
        !          8750:                while ((c=*r++)) if (c!=*d++) break;
        !          8751:                if (c) continue;
        !          8752: 
        !          8753:                return (p->info);
        !          8754:        }
        !          8755: }
        !          8756: 
        !          8757: /*==========================================================
        !          8758: **
        !          8759: **     Determine the ncr's clock frequency.
        !          8760: **     This is essential for the negotiation
        !          8761: **     of the synchronous transfer rate.
        !          8762: **
        !          8763: **==========================================================
        !          8764: **
        !          8765: **     Note: we have to return the correct value.
        !          8766: **     THERE IS NO SAVE DEFAULT VALUE.
        !          8767: **
        !          8768: **     Most NCR/SYMBIOS boards are delivered with a 40 Mhz clock.
        !          8769: **     53C860 and 53C875 rev. 1 support fast20 transfers but 
        !          8770: **     do not have a clock doubler and so are provided with a 
        !          8771: **     80 MHz clock. All other fast20 boards incorporate a doubler 
        !          8772: **     and so should be delivered with a 40 MHz clock.
        !          8773: **     The future fast40 chips (895/895) use a 40 Mhz base clock 
        !          8774: **     and provide a clock quadrupler (160 Mhz). The code below 
        !          8775: **     tries to deal as cleverly as possible with all this stuff.
        !          8776: **
        !          8777: **----------------------------------------------------------
        !          8778: */
        !          8779: 
        !          8780: /*
        !          8781:  *     Select NCR SCSI clock frequency
        !          8782:  */
        !          8783: static void ncr_selectclock(ncb_p np, u_char scntl3)
        !          8784: {
        !          8785:        if (np->multiplier < 2) {
        !          8786:                OUTB(nc_scntl3, scntl3);
        !          8787:                return;
        !          8788:        }
        !          8789: 
        !          8790:        if (bootverbose >= 2)
        !          8791:                printf ("%s: enabling clock multiplier\n", ncr_name(np));
        !          8792: 
        !          8793:        OUTB(nc_stest1, DBLEN);    /* Enable clock multiplier             */
        !          8794:        if (np->multiplier > 2) {  /* Poll bit 5 of stest4 for quadrupler */
        !          8795:                int i = 20;
        !          8796:                while (!(INB(nc_stest4) & LCKFRQ) && --i > 0)
        !          8797:                        DELAY(20);
        !          8798:                if (!i)
        !          8799:                        printf("%s: the chip cannot lock the frequency\n", ncr_name(np));
        !          8800:        } else                  /* Wait 20 micro-seconds for doubler    */
        !          8801:                DELAY(20);
        !          8802:        OUTB(nc_stest3, HSC);           /* Halt the scsi clock          */
        !          8803:        OUTB(nc_scntl3, scntl3);
        !          8804:        OUTB(nc_stest1, (DBLEN|DBLSEL));/* Select clock multiplier      */
        !          8805:        OUTB(nc_stest3, 0x00|TE);               /* Restart scsi clock           */
        !          8806: }
        !          8807: 
        !          8808: 
        !          8809: /*
        !          8810:  *     calculate NCR SCSI clock frequency (in KHz)
        !          8811:  */
        !          8812: __initfunc(
        !          8813: static unsigned ncrgetfreq (ncb_p np, int gen)
        !          8814: )
        !          8815: {
        !          8816:        unsigned ms = 0;
        !          8817: 
        !          8818:        /*
        !          8819:         * Measure GEN timer delay in order 
        !          8820:         * to calculate SCSI clock frequency
        !          8821:         *
        !          8822:         * This code will never execute too
        !          8823:         * many loop iterations (if DELAY is 
        !          8824:         * reasonably correct). It could get
        !          8825:         * too low a delay (too high a freq.)
        !          8826:         * if the CPU is slow executing the 
        !          8827:         * loop for some reason (an NMI, for
        !          8828:         * example). For this reason we will
        !          8829:         * if multiple measurements are to be 
        !          8830:         * performed trust the higher delay 
        !          8831:         * (lower frequency returned).
        !          8832:         */
        !          8833:        OUTB (nc_stest1, 0);    /* make sure clock doubler is OFF */
        !          8834:        OUTW (nc_sien , 0);     /* mask all scsi interrupts */
        !          8835:        (void) INW (nc_sist);   /* clear pending scsi interrupt */
        !          8836:        OUTB (nc_dien , 0);     /* mask all dma interrupts */
        !          8837:        (void) INW (nc_sist);   /* another one, just to be sure :) */
        !          8838:        OUTB (nc_scntl3, 4);    /* set pre-scaler to divide by 3 */
        !          8839:        OUTB (nc_stime1, 0);    /* disable general purpose timer */
        !          8840:        OUTB (nc_stime1, gen);  /* set to nominal delay of 1<<gen * 125us */
        !          8841:        while (!(INW(nc_sist) & GEN) && ms++ < 100000)
        !          8842:                DELAY(1000);    /* count ms */
        !          8843:        OUTB (nc_stime1, 0);    /* disable general purpose timer */
        !          8844:        /*
        !          8845:         * set prescaler to divide by whatever 0 means
        !          8846:         * 0 ought to choose divide by 2, but appears
        !          8847:         * to set divide by 3.5 mode in my 53c810 ...
        !          8848:         */
        !          8849:        OUTB (nc_scntl3, 0);
        !          8850: 
        !          8851:        if (bootverbose >= 2)
        !          8852:                printf ("%s: Delay (GEN=%d): %u msec\n", ncr_name(np), gen, ms);
        !          8853:        /*
        !          8854:         * adjust for prescaler, and convert into KHz 
        !          8855:         */
        !          8856:        return ms ? ((1 << gen) * 4340) / ms : 0;
        !          8857: }
        !          8858: 
        !          8859: /*
        !          8860:  *     Get/probe NCR SCSI clock frequency
        !          8861:  */
        !          8862: __initfunc(
        !          8863: static void ncr_getclock (ncb_p np, int mult)
        !          8864: )
        !          8865: {
        !          8866:        unsigned char scntl3 = INB(nc_scntl3);
        !          8867:        unsigned char stest1 = INB(nc_stest1);
        !          8868:        unsigned f1;
        !          8869: 
        !          8870:        np->multiplier = 1;
        !          8871:        f1 = 40000;
        !          8872: 
        !          8873:        /*
        !          8874:        **      True with 875 or 895 with clock multiplier selected
        !          8875:        */
        !          8876:        if (mult > 1 && (stest1 & (DBLEN+DBLSEL)) == DBLEN+DBLSEL) {
        !          8877:                if (bootverbose >= 2)
        !          8878:                        printf ("%s: clock multiplier found\n", ncr_name(np));
        !          8879:                np->multiplier = mult;
        !          8880:        }
        !          8881: 
        !          8882:        /*
        !          8883:        **      If multiplier not found or scntl3 not 7,5,3,
        !          8884:        **      reset chip and get frequency from general purpose timer.
        !          8885:        **      Otherwise trust scntl3 BIOS setting.
        !          8886:        */
        !          8887:        if (np->multiplier != mult || (scntl3 & 7) < 3 || !(scntl3 & 1)) {
        !          8888:                unsigned f2;
        !          8889: 
        !          8890:                OUTB(nc_istat, SRST); DELAY(5); OUTB(nc_istat, 0);
        !          8891: 
        !          8892:                (void) ncrgetfreq (np, 11);     /* throw away first result */
        !          8893:                f1 = ncrgetfreq (np, 11);
        !          8894:                f2 = ncrgetfreq (np, 11);
        !          8895: 
        !          8896:                if (bootverbose)
        !          8897:                        printf ("%s: NCR clock is %uKHz, %uKHz\n", ncr_name(np), f1, f2);
        !          8898: 
        !          8899:                if (f1 > f2) f1 = f2;           /* trust lower result   */
        !          8900: 
        !          8901:                if      (f1 <   45000)          f1 =  40000;
        !          8902:                else if (f1 <   55000)          f1 =  50000;
        !          8903:                else                            f1 =  80000;
        !          8904: 
        !          8905:                if (f1 < 80000 && mult > 1) {
        !          8906:                        if (bootverbose >= 2)
        !          8907:                                printf ("%s: clock multiplier assumed\n", ncr_name(np));
        !          8908:                        np->multiplier  = mult;
        !          8909:                }
        !          8910:        } else {
        !          8911:                if      ((scntl3 & 7) == 3)     f1 =  40000;
        !          8912:                else if ((scntl3 & 7) == 5)     f1 =  80000;
        !          8913:                else                            f1 = 160000;
        !          8914: 
        !          8915:                f1 /= np->multiplier;
        !          8916:        }
        !          8917: 
        !          8918:        /*
        !          8919:        **      Compute controller synchronous parameters.
        !          8920:        */
        !          8921:        f1              *= np->multiplier;
        !          8922:        np->clock_khz   = f1;
        !          8923: }
        !          8924: 
        !          8925: /*===================== LINUX ENTRY POINTS SECTION ==========================*/
        !          8926: 
        !          8927: #ifndef uchar
        !          8928: #define uchar unsigned char
        !          8929: #endif
        !          8930: 
        !          8931: #ifndef ushort
        !          8932: #define ushort unsigned short
        !          8933: #endif
        !          8934: 
        !          8935: #ifndef ulong
        !          8936: #define ulong unsigned long
        !          8937: #endif
        !          8938: 
        !          8939: /* ---------------------------------------------------------------------
        !          8940: **
        !          8941: **     Driver setup from the boot command line
        !          8942: **
        !          8943: ** ---------------------------------------------------------------------
        !          8944: */
        !          8945: 
        !          8946: __initfunc(
        !          8947: void ncr53c8xx_setup(char *str, int *ints)
        !          8948: )
        !          8949: {
        !          8950: #ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
        !          8951:        char *cur = str;
        !          8952:        char *pc, *pv;
        !          8953:        int val;
        !          8954:        int base;
        !          8955:        int c;
        !          8956: 
        !          8957:        while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
        !          8958:                val = 0;
        !          8959:                pv = pc;
        !          8960:                c = *++pv;
        !          8961:                if      (c == 'n')
        !          8962:                        val = 0;
        !          8963:                else if (c == 'y')
        !          8964:                        val = 1;
        !          8965:                else {
        !          8966:                        base = 0;
        !          8967: #if 0
        !          8968:                        if      (c == '0') {
        !          8969:                                c = *pv++;
        !          8970:                                base = 8;
        !          8971:                        }
        !          8972:                        if      (c == 'x') {
        !          8973:                                ++pv;
        !          8974:                                base = 16;
        !          8975:                        }
        !          8976:                        else if (c >= '0' && c <= '9')
        !          8977:                                base = 10;
        !          8978:                        else
        !          8979:                                break;
        !          8980: #endif
        !          8981:                        val = (int) simple_strtoul(pv, NULL, base);
        !          8982:                }
        !          8983: 
        !          8984:                if      (!strncmp(cur, "mpar:", 5))
        !          8985:                        driver_setup.master_parity      = val;
        !          8986:                else if (!strncmp(cur, "spar:", 5))
        !          8987:                        driver_setup.scsi_parity        = val;
        !          8988:                else if (!strncmp(cur, "disc:", 5))
        !          8989:                        driver_setup.disconnection      = val;
        !          8990:                else if (!strncmp(cur, "specf:", 6))
        !          8991:                        driver_setup.special_features = val;
        !          8992:                else if (!strncmp(cur, "ultra:", 6))
        !          8993:                        driver_setup.ultra_scsi = val;
        !          8994:                else if (!strncmp(cur, "fsn:", 4))
        !          8995:                        driver_setup.force_sync_nego    = val;
        !          8996:                else if (!strncmp(cur, "revprob:", 8))
        !          8997:                        driver_setup.reverse_probe      = val;
        !          8998:                else if (!strncmp(cur, "tags:", 5)) {
        !          8999:                        if (val > SCSI_NCR_MAX_TAGS)
        !          9000:                                val = SCSI_NCR_MAX_TAGS;
        !          9001:                        driver_setup.default_tags       = val;
        !          9002:                        }
        !          9003:                else if (!strncmp(cur, "sync:", 5))
        !          9004:                        driver_setup.default_sync       = val;
        !          9005:                else if (!strncmp(cur, "verb:", 5))
        !          9006:                        driver_setup.verbose    = val;
        !          9007:                else if (!strncmp(cur, "debug:", 6))
        !          9008:                        driver_setup.debug      = val;
        !          9009:                else if (!strncmp(cur, "burst:", 6))
        !          9010:                        driver_setup.burst_max  = val;
        !          9011:                else if (!strncmp(cur, "led:", 4))
        !          9012:                        driver_setup.led_pin    = val;
        !          9013:                else if (!strncmp(cur, "wide:", 5))
        !          9014:                        driver_setup.max_wide   = val? 1:0;
        !          9015:                else if (!strncmp(cur, "settle:", 7))
        !          9016:                        driver_setup.settle_delay= val;
        !          9017:                else if (!strncmp(cur, "diff:", 5))
        !          9018:                        driver_setup.diff_support= val;
        !          9019:                else if (!strncmp(cur, "irqm:", 5))
        !          9020:                        driver_setup.irqm       = val;
        !          9021:                else if (!strncmp(cur, "pcifix:", 7))
        !          9022:                        driver_setup.pci_fix_up = val;
        !          9023:                else if (!strncmp(cur, "buschk:", 7))
        !          9024:                        driver_setup.bus_check  = val;
        !          9025: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          9026:                else if (!strncmp(cur, "nvram:", 6))
        !          9027:                        driver_setup.use_nvram  = val;
        !          9028: #endif
        !          9029: 
        !          9030:                else if (!strncmp(cur, "safe:", 5) && val)
        !          9031:                        memcpy(&driver_setup, &driver_safe_setup, sizeof(driver_setup));
        !          9032:                else
        !          9033:                        printf("ncr53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
        !          9034: 
        !          9035: #ifdef MODULE
        !          9036:                if ((cur = strchr(cur, ' ')) != NULL)
        !          9037: #else
        !          9038:                if ((cur = strchr(cur, ',')) != NULL)
        !          9039: #endif
        !          9040:                        ++cur;
        !          9041:        }
        !          9042: #endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */
        !          9043: }
        !          9044: 
        !          9045: static int ncr53c8xx_pci_init(Scsi_Host_Template *tpnt,
        !          9046:             uchar bus, uchar device_fn, ncr_device *device);
        !          9047: 
        !          9048: /*
        !          9049: **   Linux entry point for NCR53C8XX devices detection routine.
        !          9050: **
        !          9051: **   Called by the middle-level scsi drivers at initialization time,
        !          9052: **   or at module installation.
        !          9053: **
        !          9054: **   Read the PCI configuration and try to attach each
        !          9055: **   detected NCR board.
        !          9056: **
        !          9057: **   If NVRAM is present, try to attach boards according to 
        !          9058: **   the used defined boot order.
        !          9059: **
        !          9060: **   Returns the number of boards successfully attached.
        !          9061: */
        !          9062: 
        !          9063: __initfunc(
        !          9064: static void ncr_print_driver_setup(void)
        !          9065: )
        !          9066: {
        !          9067: #define YesNo(y)       y ? 'y' : 'n'
        !          9068:        printk("ncr53c8xx: setup=disc:%c,specf:%d,ultra:%c,tags:%d,sync:%d,burst:%d,wide:%c,diff:%d\n",
        !          9069:                        YesNo(driver_setup.disconnection),
        !          9070:                        driver_setup.special_features,
        !          9071:                        YesNo(driver_setup.ultra_scsi),
        !          9072:                        driver_setup.default_tags,
        !          9073:                        driver_setup.default_sync,
        !          9074:                        driver_setup.burst_max,
        !          9075:                        YesNo(driver_setup.max_wide),
        !          9076:                        driver_setup.diff_support);
        !          9077:        printk("ncr53c8xx: setup=mpar:%c,spar:%c,fsn=%c,verb:%d,debug:0x%x,led:%c,settle:%d,irqm:%d\n",
        !          9078:                        YesNo(driver_setup.master_parity),
        !          9079:                        YesNo(driver_setup.scsi_parity),
        !          9080:                        YesNo(driver_setup.force_sync_nego),
        !          9081:                        driver_setup.verbose,
        !          9082:                        driver_setup.debug,
        !          9083:                        YesNo(driver_setup.led_pin),
        !          9084:                        driver_setup.settle_delay,
        !          9085:                        driver_setup.irqm);
        !          9086: #undef YesNo
        !          9087: }
        !          9088: 
        !          9089: /*
        !          9090: **   NCR53C8XX devices description table and chip ids list.
        !          9091: */
        !          9092: 
        !          9093: static ncr_chip        ncr_chip_table[] __initdata     = SCSI_NCR_CHIP_TABLE;
        !          9094: static ushort  ncr_chip_ids[]   __initdata     = SCSI_NCR_CHIP_IDS;
        !          9095: 
        !          9096: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          9097: __initfunc(
        !          9098: static int
        !          9099: ncr_attach_using_nvram(Scsi_Host_Template *tpnt, int nvram_index, int count, ncr_device device[])
        !          9100: )
        !          9101: {
        !          9102:        int i, j;
        !          9103:        int attach_count = 0;
        !          9104:        ncr_nvram  *nvram;
        !          9105:        ncr_device *devp;
        !          9106: 
        !          9107:        if (!nvram_index)
        !          9108:                return 0;
        !          9109: 
        !          9110:        /* find first Symbios NVRAM if there is one as we need to check it for host boot order */
        !          9111:        for (i = 0, nvram_index = -1; i < count; i++) {
        !          9112:                devp  = &device[i];
        !          9113:                nvram = devp->nvram;
        !          9114:                if (!nvram)
        !          9115:                        continue;
        !          9116:                if (nvram->type == SCSI_NCR_SYMBIOS_NVRAM) {
        !          9117:                        if (nvram_index == -1)
        !          9118:                                nvram_index = i;
        !          9119: #ifdef SCSI_NCR_DEBUG_NVRAM
        !          9120:                        printf("ncr53c8xx: NVRAM: Symbios format Boot Block, 53c%s, PCI bus %d, device %d, function %d\n",
        !          9121:                                devp->chip.name, devp->slot.bus, 
        !          9122:                                (int) (devp->slot.device_fn & 0xf8) >> 3, 
        !          9123:                                (int) devp->slot.device_fn & 7);
        !          9124:                        for (j = 0 ; j < 4 ; j++) {
        !          9125:                                Symbios_host *h = &nvram->data.Symbios.host[j];
        !          9126:                        printf("ncr53c8xx: BOOT[%d] device_id=%04x vendor_id=%04x device_fn=%02x io_port=%04x %s\n",
        !          9127:                                j,              h->device_id,   h->vendor_id,
        !          9128:                                h->device_fn,   h->io_port,
        !          9129:                                (h->flags & SYMBIOS_INIT_SCAN_AT_BOOT) ? "SCAN AT BOOT" : "");
        !          9130:                        }
        !          9131:                }
        !          9132:                else if (nvram->type == SCSI_NCR_TEKRAM_NVRAM) {
        !          9133:                        /* display Tekram nvram data */
        !          9134:                        printf("ncr53c8xx: NVRAM: Tekram format data, 53c%s, PCI bus %d, device %d, function %d\n",
        !          9135:                                devp->chip.name, devp->slot.bus, 
        !          9136:                                (int) (devp->slot.device_fn & 0xf8) >> 3, 
        !          9137:                                (int) devp->slot.device_fn & 7);
        !          9138: #endif
        !          9139:                }
        !          9140:        }
        !          9141: 
        !          9142:        if (nvram_index >= 0 && nvram_index < count)
        !          9143:                nvram = device[nvram_index].nvram;
        !          9144:        else
        !          9145:                nvram = 0;
        !          9146: 
        !          9147:        if (!nvram)
        !          9148:                goto out;
        !          9149: 
        !          9150:        /* 
        !          9151:        ** check devices in the boot record against devices detected. 
        !          9152:        ** attach devices if we find a match. boot table records that 
        !          9153:        ** do not match any detected devices will be ignored. 
        !          9154:        ** devices that do not match any boot table will not be attached
        !          9155:        ** here but will attempt to be attached during the device table 
        !          9156:        ** rescan.
        !          9157:        */
        !          9158:        for (i = 0; i < 4; i++) {
        !          9159:                Symbios_host *h = &nvram->data.Symbios.host[i];
        !          9160:                for (j = 0 ; j < count ; j++) {
        !          9161:                        devp = &device[j];
        !          9162:                        if (h->device_fn == devp->slot.device_fn &&
        !          9163: #if 0  /* bus number location in nvram ? */
        !          9164:                            h->bus       == devp->slot.bus       &&
        !          9165: #endif
        !          9166:                            h->device_id == devp->chip.device_id)
        !          9167:                                break;
        !          9168:                }
        !          9169:                if (j < count && !devp->attach_done) {
        !          9170:                        if (!ncr_attach (tpnt, attach_count, devp))
        !          9171:                                attach_count++;
        !          9172:                        devp->attach_done = 1;
        !          9173:                }
        !          9174:        }
        !          9175: 
        !          9176: out:
        !          9177:        return attach_count;
        !          9178: }
        !          9179: #endif /* SCSI_NCR_NVRAM_SUPPORT */
        !          9180: 
        !          9181: __initfunc(
        !          9182: int ncr53c8xx_detect(Scsi_Host_Template *tpnt)
        !          9183: )
        !          9184: {
        !          9185:        int i, j;
        !          9186:        int chips;
        !          9187:        int count = 0;
        !          9188:        uchar bus, device_fn;
        !          9189:        short index;
        !          9190:        int attach_count = 0;
        !          9191:        ncr_device device[8];
        !          9192: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          9193:        ncr_nvram  nvram[4];
        !          9194:        int k, nvrams;
        !          9195: #endif
        !          9196:        int hosts;
        !          9197: 
        !          9198: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          9199:        int nvram_index = 0;
        !          9200: #endif
        !          9201:        if (initverbose >= 2)
        !          9202:                ncr_print_driver_setup();
        !          9203: 
        !          9204: #ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
        !          9205:        ncr_debug = driver_setup.debug;
        !          9206: #endif
        !          9207: 
        !          9208: #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,0)
        !          9209:      tpnt->proc_dir = &proc_scsi_ncr53c8xx;
        !          9210: # ifdef SCSI_NCR_PROC_INFO_SUPPORT
        !          9211:      tpnt->proc_info = ncr53c8xx_proc_info;
        !          9212: # endif
        !          9213: #endif
        !          9214: 
        !          9215: #if    defined(SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT) && defined(MODULE)
        !          9216: if (ncr53c8xx)
        !          9217:        ncr53c8xx_setup(ncr53c8xx, (int *) 0);
        !          9218: #endif
        !          9219: 
        !          9220:        /* 
        !          9221:        ** Detect all 53c8xx hosts and then attach them.
        !          9222:        **
        !          9223:        ** If we are using NVRAM, once all hosts are detected, we need to check
        !          9224:        ** any NVRAM for boot order in case detect and boot order differ and
        !          9225:        ** attach them using the order in the NVRAM.
        !          9226:        **
        !          9227:        ** If no NVRAM is found or data appears invalid attach boards in the 
        !          9228:        ** the order they are detected.
        !          9229:        */
        !          9230: 
        !          9231:        if (!pcibios_present())
        !          9232:                return 0;
        !          9233: 
        !          9234:        chips   = sizeof(ncr_chip_ids)  / sizeof(ncr_chip_ids[0]);
        !          9235:        hosts   = sizeof(device)        / sizeof(device[0]);
        !          9236: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          9237:        k = 0;
        !          9238:        if (driver_setup.use_nvram & 0x1)
        !          9239:                nvrams  = sizeof(nvram) / sizeof(nvram[0]);
        !          9240:        else
        !          9241:                nvrams  = 0;
        !          9242: #endif
        !          9243: 
        !          9244:        for (j = 0; j < chips ; ++j) {
        !          9245:                i = driver_setup.reverse_probe ? chips-1 - j : j;
        !          9246:                for (index = 0; ; index++) {
        !          9247:                        char *msg = "";
        !          9248:                        if ((pcibios_find_device(PCI_VENDOR_ID_NCR, ncr_chip_ids[i],
        !          9249:                                                index, &bus, &device_fn)) ||
        !          9250:                            (count == hosts))
        !          9251:                                break;
        !          9252: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          9253:                        device[count].nvram = k < nvrams ? &nvram[k] : 0;
        !          9254: #else
        !          9255:                        device[count].nvram = 0;
        !          9256: #endif
        !          9257:                        if (ncr53c8xx_pci_init(tpnt, bus, device_fn, &device[count])) {
        !          9258:                                device[count].nvram = 0;
        !          9259:                                continue;
        !          9260:                        }
        !          9261: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          9262:                        if (device[count].nvram) {
        !          9263:                                ++k;
        !          9264:                                nvram_index |= device[count].nvram->type;
        !          9265:                                switch (device[count].nvram->type) {
        !          9266:                                case SCSI_NCR_TEKRAM_NVRAM:
        !          9267:                                        msg = "with Tekram NVRAM";
        !          9268:                                        break;
        !          9269:                                case SCSI_NCR_SYMBIOS_NVRAM:
        !          9270:                                        msg = "with Symbios NVRAM";
        !          9271:                                        break;
        !          9272:                                default:
        !          9273:                                        msg = "";
        !          9274:                                        device[count].nvram = 0;
        !          9275:                                        --k;
        !          9276:                                }
        !          9277:                        }
        !          9278: #endif
        !          9279:                        printf(KERN_INFO "ncr53c8xx: 53c%s detected %s\n",
        !          9280:                                device[count].chip.name, msg);
        !          9281:                        ++count;
        !          9282:                }
        !          9283:        }
        !          9284: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          9285:        attach_count = ncr_attach_using_nvram(tpnt, nvram_index, count, device);
        !          9286: #endif
        !          9287:        /* 
        !          9288:        ** rescan device list to make sure all boards attached.
        !          9289:        ** devices without boot records will not be attached yet
        !          9290:        ** so try to attach them here.
        !          9291:        */
        !          9292:        for (i= 0; i < count; i++) {
        !          9293:                if (!device[i].attach_done && 
        !          9294:                    !ncr_attach (tpnt, attach_count, &device[i])) {
        !          9295:                        attach_count++;
        !          9296:                }
        !          9297:        }
        !          9298: 
        !          9299:        return attach_count;
        !          9300: }
        !          9301: 
        !          9302: /*
        !          9303: **   Read and check the PCI configuration for any detected NCR 
        !          9304: **   boards and save data for attaching after all boards have 
        !          9305: **   been detected.
        !          9306: */
        !          9307: 
        !          9308: __initfunc(
        !          9309: static int ncr53c8xx_pci_init(Scsi_Host_Template *tpnt,
        !          9310:                              uchar bus, uchar device_fn, ncr_device *device)
        !          9311: )
        !          9312: {
        !          9313:        ushort vendor_id, device_id, command;
        !          9314:        uchar cache_line_size, latency_timer;
        !          9315:        uchar irq, revision;
        !          9316: #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,0)
        !          9317:        uint base, base_2, io_port; 
        !          9318: #else
        !          9319:        ulong base, base_2; 
        !          9320: #endif
        !          9321:        int i;
        !          9322: 
        !          9323: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          9324:        ncr_nvram *nvram = device->nvram;
        !          9325: #endif
        !          9326:        ncr_chip *chip;
        !          9327: 
        !          9328:        printk(KERN_INFO "ncr53c8xx: at PCI bus %d, device %d, function %d\n",
        !          9329:                bus, (int) (device_fn & 0xf8) >> 3, (int) device_fn & 7);
        !          9330:        /*
        !          9331:         * Read info from the PCI config space.
        !          9332:         * pcibios_read_config_xxx() functions are assumed to be used for 
        !          9333:         * successfully detected PCI devices.
        !          9334:         * Expecting error conditions from them is just paranoia,
        !          9335:         * thus void cast.
        !          9336:         */
        !          9337:        (void) pcibios_read_config_word(bus, device_fn,
        !          9338:                                        PCI_VENDOR_ID, &vendor_id);
        !          9339:        (void) pcibios_read_config_word(bus, device_fn,
        !          9340:                                        PCI_DEVICE_ID, &device_id);
        !          9341:        (void) pcibios_read_config_word(bus, device_fn,
        !          9342:                                        PCI_COMMAND, &command);
        !          9343:        (void) pcibios_read_config_dword(bus, device_fn,
        !          9344:                                        PCI_BASE_ADDRESS_0, &io_port);  
        !          9345:        (void) pcibios_read_config_dword(bus, device_fn,
        !          9346:                                        PCI_BASE_ADDRESS_1, &base);
        !          9347:        (void) pcibios_read_config_dword(bus, device_fn,
        !          9348:                                        PCI_BASE_ADDRESS_2, &base_2);
        !          9349:        (void) pcibios_read_config_byte(bus, device_fn,
        !          9350:                                        PCI_CLASS_REVISION,&revision);  
        !          9351:        (void) pcibios_read_config_byte(bus, device_fn,
        !          9352:                                        PCI_INTERRUPT_LINE, &irq);
        !          9353:        (void) pcibios_read_config_byte(bus, device_fn,
        !          9354:                                        PCI_CACHE_LINE_SIZE, &cache_line_size);
        !          9355:        (void) pcibios_read_config_byte(bus, device_fn,
        !          9356:                                        PCI_LATENCY_TIMER, &latency_timer);
        !          9357: 
        !          9358:        /*
        !          9359:         *      Check if the chip is supported
        !          9360:         */
        !          9361:        chip = 0;
        !          9362:        for (i = 0; i < sizeof(ncr_chip_table)/sizeof(ncr_chip_table[0]); i++) {
        !          9363:                if (device_id != ncr_chip_table[i].device_id)
        !          9364:                        continue;
        !          9365:                if (revision > ncr_chip_table[i].revision_id)
        !          9366:                        continue;
        !          9367:                chip = &device->chip;
        !          9368:                memcpy(chip, &ncr_chip_table[i], sizeof(*chip));
        !          9369:                chip->revision_id = revision;
        !          9370:                break;
        !          9371:        }
        !          9372:        if (!chip) {
        !          9373:                printk("ncr53c8xx: not initializing, device not supported\n");
        !          9374:                return -1;
        !          9375:        }
        !          9376: 
        !          9377: #ifdef __powerpc__
        !          9378:        /*
        !          9379:         *      Severall fix-up for power/pc.
        !          9380:         *      Should not be performed by the driver.
        !          9381:         */
        !          9382:        if ((command &
        !          9383:                (PCI_COMMAND_MASTER|PCI_COMMAND_IO|PCI_COMMAND_MEMORY)) !=
        !          9384:                (PCI_COMMAND_MASTER|PCI_COMMAND_IO|PCI_COMMAND_MEMORY)) {
        !          9385:                printk("ncr53c8xx : setting PCI master/io/command bit\n");
        !          9386:                command |= PCI_COMMAND_MASTER|PCI_COMMAND_IO|PCI_COMMAND_MEMORY;
        !          9387:                pcibios_write_config_word(bus, device_fn, PCI_COMMAND, command);
        !          9388:        }
        !          9389:        if (io_port >= 0x10000000) {
        !          9390:                io_port = (io_port & 0x00FFFFFF) | 0x01000000;
        !          9391:                pcibios_write_config_dword(bus, device_fn, PCI_BASE_ADDRESS_0, io_port);
        !          9392:        }
        !          9393:        if (base >= 0x10000000) {
        !          9394:                base = (base & 0x00FFFFFF) | 0x01000000;
        !          9395:                pcibios_write_config_dword(bus, device_fn, PCI_BASE_ADDRESS_1, base);
        !          9396:        }
        !          9397: #endif
        !          9398: 
        !          9399:        /*
        !          9400:         * Check availability of IO space, memory space and master capability.
        !          9401:         */
        !          9402:        if (command & PCI_COMMAND_IO) { 
        !          9403:                if ((io_port & 3) != 1) {
        !          9404:                        printk("ncr53c8xx: disabling I/O mapping since base address 0 (0x%x)\n"
        !          9405:                                "           bits 0..1 indicate a non-IO mapping\n", (int) io_port);
        !          9406:                        io_port = 0;
        !          9407:                }
        !          9408:                else
        !          9409:                        io_port &= PCI_BASE_ADDRESS_IO_MASK;
        !          9410:        }
        !          9411:        else
        !          9412:                io_port = 0;
        !          9413: 
        !          9414:        if (command & PCI_COMMAND_MEMORY) {
        !          9415:                if ((base & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) {
        !          9416:                        printk("ncr53c8xx: disabling memory mapping since base address 1\n"
        !          9417:                                "            contains a non-memory mapping\n");
        !          9418:                        base = 0;
        !          9419:                }
        !          9420:                else 
        !          9421:                        base &= PCI_BASE_ADDRESS_MEM_MASK;
        !          9422:        }
        !          9423:        else
        !          9424:                base = 0;
        !          9425:        
        !          9426:        if (!io_port && !base) {
        !          9427:                printk("ncr53c8xx: not initializing, both I/O and memory mappings disabled\n");
        !          9428:                return -1;
        !          9429:        }
        !          9430: 
        !          9431:        base_2 &= PCI_BASE_ADDRESS_MEM_MASK;
        !          9432: 
        !          9433:        if (io_port && check_region (io_port, 128)) {
        !          9434:                printk("ncr53c8xx: IO region 0x%x to 0x%x is in use\n",
        !          9435:                        (int) io_port, (int) (io_port + 127));
        !          9436:                return -1;
        !          9437:        }
        !          9438:        
        !          9439:        if (!(command & PCI_COMMAND_MASTER)) {
        !          9440:                printk("ncr53c8xx: not initializing, BUS MASTERING was disabled\n");
        !          9441:                return -1;
        !          9442:        }
        !          9443: 
        !          9444:        /*
        !          9445:         * Fix some features according to driver setup.
        !          9446:         */
        !          9447:        if (!(driver_setup.special_features & 1))
        !          9448:                chip->features &= ~FE_SPECIAL_SET;
        !          9449:        else {
        !          9450:                if (driver_setup.special_features & 2)
        !          9451:                        chip->features &= ~FE_WRIE;
        !          9452:        }
        !          9453:        if (driver_setup.ultra_scsi < 2 && (chip->features & FE_ULTRA2)) {
        !          9454:                chip->features |=  FE_ULTRA;
        !          9455:                chip->features &= ~FE_ULTRA2;
        !          9456:        }
        !          9457:        if (driver_setup.ultra_scsi < 1)
        !          9458:                chip->features &= ~FE_ULTRA;
        !          9459:        if (!driver_setup.max_wide)
        !          9460:                chip->features &= ~FE_WIDE;
        !          9461: 
        !          9462: 
        !          9463: #ifdef SCSI_NCR_PCI_FIX_UP_SUPPORT
        !          9464: 
        !          9465:        /*
        !          9466:         * Try to fix up PCI config according to wished features.
        !          9467:         */
        !          9468: #if defined(__i386) && !defined(MODULE)
        !          9469:        if ((driver_setup.pci_fix_up & 1) &&
        !          9470:            (chip->features & FE_CLSE) && cache_line_size == 0) {
        !          9471: #if LINUX_VERSION_CODE < LinuxVersionCode(2,1,75)
        !          9472:                extern char x86;
        !          9473:                switch(x86) {
        !          9474: #else
        !          9475:                switch(boot_cpu_data.x86) {
        !          9476: #endif
        !          9477:                case 4: cache_line_size = 4; break;
        !          9478:                case 5: cache_line_size = 8; break;
        !          9479:                }
        !          9480:                if (cache_line_size)
        !          9481:                        (void) pcibios_write_config_byte(bus, device_fn,
        !          9482:                                        PCI_CACHE_LINE_SIZE, cache_line_size);
        !          9483:                if (initverbose)
        !          9484:                        printk("ncr53c8xx: setting PCI_CACHE_LINE_SIZE to %d (fix-up).\n", cache_line_size);
        !          9485:        }
        !          9486: 
        !          9487:        if ((driver_setup.pci_fix_up & 2) && cache_line_size &&
        !          9488:            (chip->features & FE_WRIE) && !(command & PCI_COMMAND_INVALIDATE)) {
        !          9489:                command |= PCI_COMMAND_INVALIDATE;
        !          9490:                (void) pcibios_write_config_word(bus, device_fn,
        !          9491:                                                PCI_COMMAND, command);
        !          9492:                if (initverbose)
        !          9493:                        printk("ncr53c8xx: setting PCI_COMMAND_INVALIDATE bit (fix-up).\n");
        !          9494:        }
        !          9495: #endif
        !          9496:        /*
        !          9497:         * Fix up for old chips that support READ LINE but not CACHE LINE SIZE.
        !          9498:         * - If CACHE LINE SIZE is unknown, set burst max to 32 bytes = 8 dwords
        !          9499:         *   and donnot enable READ LINE.
        !          9500:         * - Otherwise set it to the CACHE LINE SIZE (power of 2 assumed). 
        !          9501:         */
        !          9502: 
        !          9503:        if (!(chip->features & FE_CLSE)) {
        !          9504:                int burst_max = chip->burst_max;
        !          9505:                if (cache_line_size == 0) {
        !          9506:                        chip->features  &= ~FE_ERL;
        !          9507:                        if (burst_max > 3)
        !          9508:                                burst_max = 3;
        !          9509:                }
        !          9510:                else {
        !          9511:                        while (cache_line_size < (1 << burst_max))
        !          9512:                                --burst_max;
        !          9513:                }
        !          9514:                chip->burst_max = burst_max;
        !          9515:        }
        !          9516: 
        !          9517:        /*
        !          9518:         * Tune PCI LATENCY TIMER according to burst max length transfer.
        !          9519:         * (latency timer >= burst length + 6, we add 10 to be quite sure)
        !          9520:         * If current value is zero, the device has probably been configured 
        !          9521:         * for no bursting due to some broken hardware.
        !          9522:         */
        !          9523: 
        !          9524:        if (latency_timer == 0 && chip->burst_max)
        !          9525:                printk("ncr53c8xx: PCI_LATENCY_TIMER=0, bursting should'nt be allowed.\n");
        !          9526: 
        !          9527:        if ((driver_setup.pci_fix_up & 4) && chip->burst_max) {
        !          9528:                uchar lt = (1 << chip->burst_max) + 6 + 10;
        !          9529:                if (latency_timer < lt) {
        !          9530:                        latency_timer = lt;
        !          9531:                        if (initverbose)
        !          9532:                                printk("ncr53c8xx: setting PCI_LATENCY_TIMER to %d bus clocks (fix-up).\n", latency_timer);
        !          9533:                         (void) pcibios_write_config_byte(bus, device_fn,
        !          9534:                                        PCI_LATENCY_TIMER, latency_timer);
        !          9535:                }
        !          9536:        }
        !          9537: 
        !          9538:        /*
        !          9539:         * Fix up for recent chips that support CACHE LINE SIZE.
        !          9540:         * If PCI config space is not OK, remove features that shall not be 
        !          9541:         * used by the chip. No need to trigger possible chip bugs.
        !          9542:         */
        !          9543: 
        !          9544:        if ((chip->features & FE_CLSE) && cache_line_size == 0) {
        !          9545:                chip->features &= ~FE_CACHE_SET;
        !          9546:                printk("ncr53c8xx: PCI_CACHE_LINE_SIZE not set, features based on CACHE LINE SIZE not used.\n");
        !          9547:        }
        !          9548: 
        !          9549:        if ((chip->features & FE_WRIE) && !(command & PCI_COMMAND_INVALIDATE)) {
        !          9550:                chip->features &= ~FE_WRIE;
        !          9551:                printk("ncr53c8xx: PCI_COMMAND_INVALIDATE not set, WRITE AND INVALIDATE not used\n");
        !          9552:        }
        !          9553: 
        !          9554: #endif /* SCSI_NCR_PCI_FIX_UP_SUPPORT */
        !          9555: 
        !          9556:        /* initialise ncr_device structure with items required by ncr_attach */
        !          9557:        device->slot.bus        = bus;
        !          9558:        device->slot.device_fn  = device_fn;
        !          9559:        device->slot.base       = base;
        !          9560:        device->slot.base_2     = base_2;
        !          9561:        device->slot.io_port    = io_port;
        !          9562:        device->slot.irq        = irq;
        !          9563:        device->attach_done     = 0;
        !          9564: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          9565:        if (!nvram)
        !          9566:                goto out;
        !          9567: 
        !          9568:        /*
        !          9569:        ** Get access to chip IO registers
        !          9570:        */
        !          9571: #ifdef NCR_IOMAPPED
        !          9572:        request_region(io_port, 128, "ncr53c8xx");
        !          9573:        device->slot.port = io_port;
        !          9574: #else
        !          9575:        device->slot.reg = (struct ncr_reg *) remap_pci_mem((ulong) base, 128);
        !          9576:        if (!device->slot.reg)
        !          9577:                goto out;
        !          9578: #endif
        !          9579: 
        !          9580:        /*
        !          9581:        ** Try to read SYMBIOS nvram.
        !          9582:        ** Data can be used to order booting of boards.
        !          9583:        **
        !          9584:        ** Data is saved in ncr_device structure if NVRAM found. This
        !          9585:        ** is then used to find drive boot order for ncr_attach().
        !          9586:        **
        !          9587:        ** NVRAM data is passed to Scsi_Host_Template later during ncr_attach()
        !          9588:        ** for any device set up.
        !          9589:        **
        !          9590:        ** Try to read TEKRAM nvram if Symbios nvram not found.
        !          9591:        */
        !          9592: 
        !          9593:        if      (!ncr_get_Symbios_nvram(&device->slot, &nvram->data.Symbios))
        !          9594:                nvram->type = SCSI_NCR_SYMBIOS_NVRAM;
        !          9595:        else if (!ncr_get_Tekram_nvram(&device->slot, &nvram->data.Tekram))
        !          9596:                nvram->type = SCSI_NCR_TEKRAM_NVRAM;
        !          9597:        else
        !          9598:                nvram->type = 0;
        !          9599: out:
        !          9600:        /*
        !          9601:        ** Release access to chip IO registers
        !          9602:        */
        !          9603: #ifdef NCR_IOMAPPED
        !          9604:        release_region(device->slot.port, 128);
        !          9605: #else
        !          9606:        unmap_pci_mem((vm_offset_t) device->slot.reg, (u_long) 128);
        !          9607: #endif
        !          9608: 
        !          9609: #endif /* SCSI_NCR_NVRAM_SUPPORT */
        !          9610:        return 0;     
        !          9611: }
        !          9612: 
        !          9613: #if LINUX_VERSION_CODE >= LinuxVersionCode(2,0,0)
        !          9614: /*
        !          9615: **   Linux select queue depths function
        !          9616: */
        !          9617: static void ncr53c8xx_select_queue_depths(struct Scsi_Host *host, struct scsi_device *devlist)
        !          9618: {
        !          9619:        struct scsi_device *device;
        !          9620: 
        !          9621:        for (device = devlist; device; device = device->next) {
        !          9622:                if (device->host == host) {
        !          9623: #if SCSI_NCR_MAX_TAGS > 1
        !          9624:                        if (device->tagged_supported) {
        !          9625:                                device->queue_depth = SCSI_NCR_MAX_TAGS;
        !          9626:                        }
        !          9627:                        else {
        !          9628:                                device->queue_depth = 2;
        !          9629:                        }
        !          9630: #else
        !          9631:                        device->queue_depth = 1;
        !          9632: #endif
        !          9633: 
        !          9634: #ifdef DEBUG_NCR53C8XX
        !          9635: printk("ncr53c8xx_select_queue_depth: id=%d, lun=%d, queue_depth=%d\n",
        !          9636:        device->id, device->lun, device->queue_depth);
        !          9637: #endif
        !          9638:                }
        !          9639:        }
        !          9640: }
        !          9641: #endif
        !          9642: 
        !          9643: /*
        !          9644: **   Linux entry point of queuecommand() function
        !          9645: */
        !          9646: 
        !          9647: int ncr53c8xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
        !          9648: {
        !          9649:      int sts;
        !          9650: #ifdef DEBUG_NCR53C8XX
        !          9651: printk("ncr53c8xx_queue_command\n");
        !          9652: #endif
        !          9653: 
        !          9654:      if ((sts = ncr_queue_command(cmd, done)) != DID_OK) {
        !          9655:          cmd->result = ScsiResult(sts, 0);
        !          9656:          done(cmd);
        !          9657: #ifdef DEBUG_NCR53C8XX
        !          9658: printk("ncr53c8xx : command not queued - result=%d\n", sts);
        !          9659: #endif
        !          9660:           return sts;
        !          9661:      }
        !          9662: #ifdef DEBUG_NCR53C8XX
        !          9663: printk("ncr53c8xx : command successfully queued\n");
        !          9664: #endif
        !          9665:      return sts;
        !          9666: }
        !          9667: 
        !          9668: /*
        !          9669: **   Linux entry point of the interrupt handler.
        !          9670: **   Fort linux versions > 1.3.70, we trust the kernel for 
        !          9671: **   passing the internal host descriptor as 'dev_id'.
        !          9672: **   Otherwise, we scan the host list and call the interrupt 
        !          9673: **   routine for each host that uses this IRQ.
        !          9674: */
        !          9675: 
        !          9676: #if LINUX_VERSION_CODE >= LinuxVersionCode(1,3,70)
        !          9677: static void ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs)
        !          9678: {
        !          9679: #ifdef DEBUG_NCR53C8XX
        !          9680:      printk("ncr53c8xx : interrupt received\n");
        !          9681: #endif
        !          9682: 
        !          9683:      if (DEBUG_FLAGS & DEBUG_TINY) printf ("[");
        !          9684:      ncr_exception((ncb_p) dev_id);
        !          9685:      if (DEBUG_FLAGS & DEBUG_TINY) printf ("]\n");
        !          9686: }
        !          9687: 
        !          9688: #else
        !          9689: static void ncr53c8xx_intr(int irq, struct pt_regs * regs)
        !          9690: {
        !          9691:      struct Scsi_Host *host;
        !          9692:      struct host_data *host_data;
        !          9693: 
        !          9694:      for (host = first_host; host; host = host->next) {
        !          9695:          if (host->hostt == the_template && host->irq == irq) {
        !          9696:               host_data = (struct host_data *) host->hostdata;
        !          9697:                if (DEBUG_FLAGS & DEBUG_TINY) printf ("[");
        !          9698:                ncr_exception(host_data->ncb);
        !          9699:                if (DEBUG_FLAGS & DEBUG_TINY) printf ("]\n");
        !          9700:          }
        !          9701:      }
        !          9702: }
        !          9703: #endif
        !          9704: 
        !          9705: /*
        !          9706: **   Linux entry point of the timer handler
        !          9707: */
        !          9708: 
        !          9709: static void ncr53c8xx_timeout(unsigned long np)
        !          9710: {
        !          9711:      ncr_timeout((ncb_p) np);
        !          9712: }
        !          9713: 
        !          9714: /*
        !          9715: **   Linux entry point of reset() function
        !          9716: */
        !          9717: 
        !          9718: #if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
        !          9719: 
        !          9720: int ncr53c8xx_reset(Scsi_Cmnd *cmd, unsigned int reset_flags)
        !          9721: {
        !          9722:        int sts;
        !          9723:        unsigned long flags;
        !          9724: 
        !          9725:        printk("ncr53c8xx_reset: pid=%lu reset_flags=%x serial_number=%ld serial_number_at_timeout=%ld\n",
        !          9726:                cmd->pid, reset_flags, cmd->serial_number, cmd->serial_number_at_timeout);
        !          9727: 
        !          9728:        save_flags(flags); cli();
        !          9729: 
        !          9730:        /*
        !          9731:         * We have to just ignore reset requests in some situations.
        !          9732:         */
        !          9733: #if defined SCSI_RESET_NOT_RUNNING
        !          9734:        if (cmd->serial_number != cmd->serial_number_at_timeout) {
        !          9735:                sts = SCSI_RESET_NOT_RUNNING;
        !          9736:                goto out;
        !          9737:        }
        !          9738: #endif
        !          9739:        /*
        !          9740:         * If the mid-level driver told us reset is synchronous, it seems 
        !          9741:         * that we must call the done() callback for the involved command, 
        !          9742:         * even if this command was not queued to the low-level driver, 
        !          9743:         * before returning SCSI_RESET_SUCCESS.
        !          9744:         */
        !          9745: 
        !          9746:        sts = ncr_reset_bus(cmd,
        !          9747:        (reset_flags & (SCSI_RESET_SYNCHRONOUS | SCSI_RESET_ASYNCHRONOUS)) == SCSI_RESET_SYNCHRONOUS);
        !          9748:        /*
        !          9749:         * Since we always reset the controller, when we return success, 
        !          9750:         * we add this information to the return code.
        !          9751:         */
        !          9752: #if defined SCSI_RESET_HOST_RESET
        !          9753:        if (sts == SCSI_RESET_SUCCESS)
        !          9754:                sts |= SCSI_RESET_HOST_RESET;
        !          9755: #endif
        !          9756: 
        !          9757: out:
        !          9758:        restore_flags(flags);
        !          9759:        return sts;
        !          9760: }
        !          9761: #else
        !          9762: int ncr53c8xx_reset(Scsi_Cmnd *cmd)
        !          9763: {
        !          9764:        printk("ncr53c8xx_reset: command pid %lu\n", cmd->pid);
        !          9765:        return ncr_reset_bus(cmd, 1);
        !          9766: }
        !          9767: #endif
        !          9768: 
        !          9769: /*
        !          9770: **   Linux entry point of abort() function
        !          9771: */
        !          9772: 
        !          9773: #if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
        !          9774: 
        !          9775: int ncr53c8xx_abort(Scsi_Cmnd *cmd)
        !          9776: {
        !          9777:        int sts;
        !          9778:        unsigned long flags;
        !          9779: 
        !          9780:        printk("ncr53c8xx_abort: pid=%lu serial_number=%ld serial_number_at_timeout=%ld\n",
        !          9781:                cmd->pid, cmd->serial_number, cmd->serial_number_at_timeout);
        !          9782: 
        !          9783:        save_flags(flags); cli();
        !          9784: 
        !          9785:        /*
        !          9786:         * We have to just ignore abort requests in some situations.
        !          9787:         */
        !          9788:        if (cmd->serial_number != cmd->serial_number_at_timeout) {
        !          9789:                sts = SCSI_ABORT_NOT_RUNNING;
        !          9790:                goto out;
        !          9791:        }
        !          9792: 
        !          9793:        sts = ncr_abort_command(cmd);
        !          9794: out:
        !          9795:        restore_flags(flags);
        !          9796:        return sts;
        !          9797: }
        !          9798: #else
        !          9799: int ncr53c8xx_abort(Scsi_Cmnd *cmd)
        !          9800: {
        !          9801:        printk("ncr53c8xx_abort: command pid %lu\n", cmd->pid);
        !          9802:        return ncr_abort_command(cmd);
        !          9803: }
        !          9804: #endif
        !          9805: 
        !          9806: #ifdef MODULE
        !          9807: int ncr53c8xx_release(struct Scsi_Host *host)
        !          9808: {
        !          9809: #ifdef DEBUG_NCR53C8XX
        !          9810: printk("ncr53c8xx : release\n");
        !          9811: #endif
        !          9812:      ncr_detach(((struct host_data *) host->hostdata)->ncb);
        !          9813: 
        !          9814:      return 1;
        !          9815: }
        !          9816: #endif
        !          9817: 
        !          9818: 
        !          9819: /*
        !          9820: **     Scsi command waiting list management.
        !          9821: **
        !          9822: **     It may happen that we cannot insert a scsi command into the start queue,
        !          9823: **     in the following circumstances.
        !          9824: **             Too few preallocated ccb(s), 
        !          9825: **             maxtags < cmd_per_lun of the Linux host control block,
        !          9826: **             etc...
        !          9827: **     Such scsi commands are inserted into a waiting list.
        !          9828: **     When a scsi command complete, we try to requeue the commands of the
        !          9829: **     waiting list.
        !          9830: */
        !          9831: 
        !          9832: #define next_wcmd host_scribble
        !          9833: 
        !          9834: static void insert_into_waiting_list(ncb_p np, Scsi_Cmnd *cmd)
        !          9835: {
        !          9836:        Scsi_Cmnd *wcmd;
        !          9837: 
        !          9838: #ifdef DEBUG_WAITING_LIST
        !          9839:        printf("%s: cmd %lx inserted into waiting list\n", ncr_name(np), (u_long) cmd);
        !          9840: #endif
        !          9841:        cmd->next_wcmd = 0;
        !          9842:        if (!(wcmd = np->waiting_list)) np->waiting_list = cmd;
        !          9843:        else {
        !          9844:                while ((wcmd->next_wcmd) != 0)
        !          9845:                        wcmd = (Scsi_Cmnd *) wcmd->next_wcmd;
        !          9846:                wcmd->next_wcmd = (char *) cmd;
        !          9847:        }
        !          9848: }
        !          9849: 
        !          9850: static Scsi_Cmnd *retrieve_from_waiting_list(int to_remove, ncb_p np, Scsi_Cmnd *cmd)
        !          9851: {
        !          9852:        Scsi_Cmnd *wcmd;
        !          9853: 
        !          9854:        if (!(wcmd = np->waiting_list)) return 0;
        !          9855:        while (wcmd->next_wcmd) {
        !          9856:                if (cmd == (Scsi_Cmnd *) wcmd->next_wcmd) {
        !          9857:                        if (to_remove) {
        !          9858:                                wcmd->next_wcmd = cmd->next_wcmd;
        !          9859:                                cmd->next_wcmd = 0;
        !          9860:                        }
        !          9861: #ifdef DEBUG_WAITING_LIST
        !          9862:        printf("%s: cmd %lx retrieved from waiting list\n", ncr_name(np), (u_long) cmd);
        !          9863: #endif
        !          9864:                        return cmd;
        !          9865:                }
        !          9866:        }
        !          9867:        return 0;
        !          9868: }
        !          9869: 
        !          9870: static void process_waiting_list(ncb_p np, int sts)
        !          9871: {
        !          9872:        Scsi_Cmnd *waiting_list, *wcmd;
        !          9873: 
        !          9874:        waiting_list = np->waiting_list;
        !          9875:        np->waiting_list = 0;
        !          9876: 
        !          9877: #ifdef DEBUG_WAITING_LIST
        !          9878:        if (waiting_list) printf("%s: waiting_list=%lx processing sts=%d\n", ncr_name(np), (u_long) waiting_list, sts);
        !          9879: #endif
        !          9880:        while ((wcmd = waiting_list) != 0) {
        !          9881:                waiting_list = (Scsi_Cmnd *) wcmd->next_wcmd;
        !          9882:                wcmd->next_wcmd = 0;
        !          9883:                if (sts == DID_OK) {
        !          9884: #ifdef DEBUG_WAITING_LIST
        !          9885:        printf("%s: cmd %lx trying to requeue\n", ncr_name(np), (u_long) wcmd);
        !          9886: #endif
        !          9887:                        sts = ncr_queue_command(wcmd, wcmd->scsi_done);
        !          9888:                }
        !          9889:                if (sts != DID_OK) {
        !          9890: #ifdef DEBUG_WAITING_LIST
        !          9891:        printf("%s: cmd %lx done forced sts=%d\n", ncr_name(np), (u_long) wcmd, sts);
        !          9892: #endif
        !          9893:                        wcmd->result = ScsiResult(sts, 0);
        !          9894:                        wcmd->scsi_done(wcmd);
        !          9895:                }
        !          9896:        }
        !          9897: }
        !          9898: 
        !          9899: #undef next_wcmd
        !          9900: 
        !          9901: /*
        !          9902: **     Returns data transfer direction for common op-codes.
        !          9903: */
        !          9904: 
        !          9905: static int guess_xfer_direction(int opcode)
        !          9906: {
        !          9907:        int d;
        !          9908: 
        !          9909:        switch(opcode) {
        !          9910:        case 0x12:  /*  INQUIRY                         12 */
        !          9911:        case 0x4D:  /*  LOG SENSE                       4D */
        !          9912:        case 0x5A:  /*  MODE SENSE(10)                  5A */
        !          9913:        case 0x1A:  /*  MODE SENSE(6)                   1A */
        !          9914:        case 0x3C:  /*  READ BUFFER                     3C */
        !          9915:        case 0x1C:  /*  RECEIVE DIAGNOSTIC RESULTS      1C */
        !          9916:        case 0x03:  /*  REQUEST SENSE                   03 */
        !          9917:                d = XferIn;
        !          9918:                break;
        !          9919:        case 0x39:  /*  COMPARE                         39 */
        !          9920:        case 0x3A:  /*  COPY AND VERIFY                 3A */
        !          9921:        case 0x18:  /*  COPY                            18 */
        !          9922:        case 0x4C:  /*  LOG SELECT                      4C */
        !          9923:        case 0x55:  /*  MODE SELECT(10)                 55 */
        !          9924:        case 0x3B:  /*  WRITE BUFFER                    3B */
        !          9925:        case 0x1D:  /*  SEND DIAGNOSTIC                 1D */
        !          9926:        case 0x40:  /*  CHANGE DEFINITION               40 */
        !          9927:        case 0x15:  /*  MODE SELECT(6)                  15 */
        !          9928:                d = XferOut;
        !          9929:                break;
        !          9930:        case 0x00:  /*  TEST UNIT READY                 00 */
        !          9931:                d = XferNone;
        !          9932:                break;
        !          9933:        default:
        !          9934:                d = XferBoth;
        !          9935:                break;
        !          9936:        }
        !          9937: 
        !          9938:        return d;
        !          9939: }
        !          9940: 
        !          9941: 
        !          9942: #ifdef SCSI_NCR_PROC_INFO_SUPPORT
        !          9943: 
        !          9944: /*=========================================================================
        !          9945: **     Proc file system stuff
        !          9946: **
        !          9947: **     A read operation returns profile information.
        !          9948: **     A write operation is a control command.
        !          9949: **     The string is parsed in the driver code and the command is passed 
        !          9950: **     to the ncr_usercmd() function.
        !          9951: **=========================================================================
        !          9952: */
        !          9953: 
        !          9954: #ifdef SCSI_NCR_USER_COMMAND_SUPPORT
        !          9955: 
        !          9956: #define is_digit(c)    ((c) >= '0' && (c) <= '9')
        !          9957: #define digit_to_bin(c)        ((c) - '0')
        !          9958: #define is_space(c)    ((c) == ' ' || (c) == '\t')
        !          9959: 
        !          9960: static int skip_spaces(char *ptr, int len)
        !          9961: {
        !          9962:        int cnt, c;
        !          9963: 
        !          9964:        for (cnt = len; cnt > 0 && (c = *ptr++) && is_space(c); cnt--);
        !          9965: 
        !          9966:        return (len - cnt);
        !          9967: }
        !          9968: 
        !          9969: static int get_int_arg(char *ptr, int len, u_long *pv)
        !          9970: {
        !          9971:        int     cnt, c;
        !          9972:        u_long  v;
        !          9973: 
        !          9974:        for (v = 0, cnt = len; cnt > 0 && (c = *ptr++) && is_digit(c); cnt--) {
        !          9975:                v = (v * 10) + digit_to_bin(c);
        !          9976:        }
        !          9977: 
        !          9978:        if (pv)
        !          9979:                *pv = v;
        !          9980: 
        !          9981:        return (len - cnt);
        !          9982: }
        !          9983: 
        !          9984: static int is_keyword(char *ptr, int len, char *verb)
        !          9985: {
        !          9986:        int verb_len = strlen(verb);
        !          9987: 
        !          9988:        if (len >= strlen(verb) && !memcmp(verb, ptr, verb_len))
        !          9989:                return verb_len;
        !          9990:        else
        !          9991:                return 0;
        !          9992: 
        !          9993: }
        !          9994: 
        !          9995: #define SKIP_SPACES(min_spaces)                                                \
        !          9996:        if ((arg_len = skip_spaces(ptr, len)) < (min_spaces))           \
        !          9997:                return -EINVAL;                                         \
        !          9998:        ptr += arg_len; len -= arg_len;
        !          9999: 
        !          10000: #define GET_INT_ARG(v)                                                 \
        !          10001:        if (!(arg_len = get_int_arg(ptr, len, &(v))))                   \
        !          10002:                return -EINVAL;                                         \
        !          10003:        ptr += arg_len; len -= arg_len;
        !          10004: 
        !          10005: 
        !          10006: /*
        !          10007: **     Parse a control command
        !          10008: */
        !          10009: 
        !          10010: static int ncr_user_command(ncb_p np, char *buffer, int length)
        !          10011: {
        !          10012:        char *ptr       = buffer;
        !          10013:        int len         = length;
        !          10014:        struct usrcmd    *uc = &np->user;
        !          10015:        int             arg_len;
        !          10016:        u_long          target;
        !          10017: 
        !          10018:        bzero(uc, sizeof(*uc));
        !          10019: 
        !          10020:        if (len > 0 && ptr[len-1] == '\n')
        !          10021:                --len;
        !          10022: 
        !          10023:        if      ((arg_len = is_keyword(ptr, len, "setsync")) != 0)
        !          10024:                uc->cmd = UC_SETSYNC;
        !          10025:        else if ((arg_len = is_keyword(ptr, len, "settags")) != 0)
        !          10026:                uc->cmd = UC_SETTAGS;
        !          10027:        else if ((arg_len = is_keyword(ptr, len, "setorder")) != 0)
        !          10028:                uc->cmd = UC_SETORDER;
        !          10029:        else if ((arg_len = is_keyword(ptr, len, "setwide")) != 0)
        !          10030:                uc->cmd = UC_SETWIDE;
        !          10031:        else if ((arg_len = is_keyword(ptr, len, "setdebug")) != 0)
        !          10032:                uc->cmd = UC_SETDEBUG;
        !          10033:        else if ((arg_len = is_keyword(ptr, len, "setflag")) != 0)
        !          10034:                uc->cmd = UC_SETFLAG;
        !          10035:        else if ((arg_len = is_keyword(ptr, len, "clearprof")) != 0)
        !          10036:                uc->cmd = UC_CLEARPROF;
        !          10037: #ifdef UC_DEBUG_ERROR_RECOVERY
        !          10038:        else if ((arg_len = is_keyword(ptr, len, "debug_error_recovery")) != 0)
        !          10039:                uc->cmd = UC_DEBUG_ERROR_RECOVERY;
        !          10040: #endif
        !          10041:        else
        !          10042:                arg_len = 0;
        !          10043: 
        !          10044: #ifdef DEBUG_PROC_INFO
        !          10045: printf("ncr_user_command: arg_len=%d, cmd=%ld\n", arg_len, uc->cmd);
        !          10046: #endif
        !          10047: 
        !          10048:        if (!arg_len)
        !          10049:                return -EINVAL;
        !          10050:        ptr += arg_len; len -= arg_len;
        !          10051: 
        !          10052:        switch(uc->cmd) {
        !          10053:        case UC_SETSYNC:
        !          10054:        case UC_SETTAGS:
        !          10055:        case UC_SETWIDE:
        !          10056:        case UC_SETFLAG:
        !          10057:                SKIP_SPACES(1);
        !          10058:                if ((arg_len = is_keyword(ptr, len, "all")) != 0) {
        !          10059:                        ptr += arg_len; len -= arg_len;
        !          10060:                        uc->target = ~0;
        !          10061:                } else {
        !          10062:                        GET_INT_ARG(target);
        !          10063:                        uc->target = (1<<target);
        !          10064: #ifdef DEBUG_PROC_INFO
        !          10065: printf("ncr_user_command: target=%ld\n", target);
        !          10066: #endif
        !          10067:                }
        !          10068:                break;
        !          10069:        }
        !          10070: 
        !          10071:        switch(uc->cmd) {
        !          10072:        case UC_SETSYNC:
        !          10073:        case UC_SETTAGS:
        !          10074:        case UC_SETWIDE:
        !          10075:                SKIP_SPACES(1);
        !          10076:                GET_INT_ARG(uc->data);
        !          10077: #ifdef DEBUG_PROC_INFO
        !          10078: printf("ncr_user_command: data=%ld\n", uc->data);
        !          10079: #endif
        !          10080:                break;
        !          10081:        case UC_SETORDER:
        !          10082:                SKIP_SPACES(1);
        !          10083:                if      ((arg_len = is_keyword(ptr, len, "simple")))
        !          10084:                        uc->data = M_SIMPLE_TAG;
        !          10085:                else if ((arg_len = is_keyword(ptr, len, "ordered")))
        !          10086:                        uc->data = M_ORDERED_TAG;
        !          10087:                else if ((arg_len = is_keyword(ptr, len, "default")))
        !          10088:                        uc->data = 0;
        !          10089:                else
        !          10090:                        return -EINVAL;
        !          10091:                break;
        !          10092:        case UC_SETDEBUG:
        !          10093:                while (len > 0) {
        !          10094:                        SKIP_SPACES(1);
        !          10095:                        if      ((arg_len = is_keyword(ptr, len, "alloc")))
        !          10096:                                uc->data |= DEBUG_ALLOC;
        !          10097:                        else if ((arg_len = is_keyword(ptr, len, "phase")))
        !          10098:                                uc->data |= DEBUG_PHASE;
        !          10099:                        else if ((arg_len = is_keyword(ptr, len, "poll")))
        !          10100:                                uc->data |= DEBUG_POLL;
        !          10101:                        else if ((arg_len = is_keyword(ptr, len, "queue")))
        !          10102:                                uc->data |= DEBUG_QUEUE;
        !          10103:                        else if ((arg_len = is_keyword(ptr, len, "result")))
        !          10104:                                uc->data |= DEBUG_RESULT;
        !          10105:                        else if ((arg_len = is_keyword(ptr, len, "scatter")))
        !          10106:                                uc->data |= DEBUG_SCATTER;
        !          10107:                        else if ((arg_len = is_keyword(ptr, len, "script")))
        !          10108:                                uc->data |= DEBUG_SCRIPT;
        !          10109:                        else if ((arg_len = is_keyword(ptr, len, "tiny")))
        !          10110:                                uc->data |= DEBUG_TINY;
        !          10111:                        else if ((arg_len = is_keyword(ptr, len, "timing")))
        !          10112:                                uc->data |= DEBUG_TIMING;
        !          10113:                        else if ((arg_len = is_keyword(ptr, len, "nego")))
        !          10114:                                uc->data |= DEBUG_NEGO;
        !          10115:                        else if ((arg_len = is_keyword(ptr, len, "tags")))
        !          10116:                                uc->data |= DEBUG_TAGS;
        !          10117:                        else if ((arg_len = is_keyword(ptr, len, "freeze")))
        !          10118:                                uc->data |= DEBUG_FREEZE;
        !          10119:                        else if ((arg_len = is_keyword(ptr, len, "restart")))
        !          10120:                                uc->data |= DEBUG_RESTART;
        !          10121:                        else
        !          10122:                                return -EINVAL;
        !          10123:                        ptr += arg_len; len -= arg_len;
        !          10124:                }
        !          10125: #ifdef DEBUG_PROC_INFO
        !          10126: printf("ncr_user_command: data=%ld\n", uc->data);
        !          10127: #endif
        !          10128:                break;
        !          10129:        case UC_SETFLAG:
        !          10130:                while (len > 0) {
        !          10131:                        SKIP_SPACES(1);
        !          10132:                        if      ((arg_len = is_keyword(ptr, len, "trace")))
        !          10133:                                uc->data |= UF_TRACE;
        !          10134:                        else if ((arg_len = is_keyword(ptr, len, "no_disc")))
        !          10135:                                uc->data |= UF_NODISC;
        !          10136:                        else
        !          10137:                                return -EINVAL;
        !          10138:                        ptr += arg_len; len -= arg_len;
        !          10139:                }
        !          10140:                break;
        !          10141: #ifdef UC_DEBUG_ERROR_RECOVERY
        !          10142:        case UC_DEBUG_ERROR_RECOVERY:
        !          10143:                SKIP_SPACES(1);
        !          10144:                if      ((arg_len = is_keyword(ptr, len, "sge")))
        !          10145:                        uc->data = 1;
        !          10146:                else if ((arg_len = is_keyword(ptr, len, "abort")))
        !          10147:                        uc->data = 2;
        !          10148:                else if ((arg_len = is_keyword(ptr, len, "reset")))
        !          10149:                        uc->data = 3;
        !          10150:                else if ((arg_len = is_keyword(ptr, len, "parity")))
        !          10151:                        uc->data = 4;
        !          10152:                else if ((arg_len = is_keyword(ptr, len, "none")))
        !          10153:                        uc->data = 0;
        !          10154:                else
        !          10155:                        return -EINVAL;
        !          10156:                ptr += arg_len; len -= arg_len;
        !          10157:                break;
        !          10158: #endif
        !          10159:        default:
        !          10160:                break;
        !          10161:        }
        !          10162: 
        !          10163:        if (len)
        !          10164:                return -EINVAL;
        !          10165:        else {
        !          10166:                long flags;
        !          10167: 
        !          10168:                save_flags(flags); cli();
        !          10169:                ncr_usercmd (np);
        !          10170:                restore_flags(flags);
        !          10171:        }
        !          10172:        return length;
        !          10173: }
        !          10174: 
        !          10175: #endif /* SCSI_NCR_USER_COMMAND_SUPPORT */
        !          10176: 
        !          10177: #ifdef SCSI_NCR_USER_INFO_SUPPORT
        !          10178: 
        !          10179: struct info_str
        !          10180: {
        !          10181:        char *buffer;
        !          10182:        int length;
        !          10183:        int offset;
        !          10184:        int pos;
        !          10185: };
        !          10186: 
        !          10187: static void copy_mem_info(struct info_str *info, char *data, int len)
        !          10188: {
        !          10189:        if (info->pos + len > info->length)
        !          10190:                len = info->length - info->pos;
        !          10191: 
        !          10192:        if (info->pos + len < info->offset) {
        !          10193:                info->pos += len;
        !          10194:                return;
        !          10195:        }
        !          10196:        if (info->pos < info->offset) {
        !          10197:                data += (info->offset - info->pos);
        !          10198:                len  -= (info->offset - info->pos);
        !          10199:        }
        !          10200: 
        !          10201:        if (len > 0) {
        !          10202:                memcpy(info->buffer + info->pos, data, len);
        !          10203:                info->pos += len;
        !          10204:        }
        !          10205: }
        !          10206: 
        !          10207: static int copy_info(struct info_str *info, char *fmt, ...)
        !          10208: {
        !          10209:        va_list args;
        !          10210:        char buf[81];
        !          10211:        int len;
        !          10212: 
        !          10213:        va_start(args, fmt);
        !          10214:        len = vsprintf(buf, fmt, args);
        !          10215:        va_end(args);
        !          10216: 
        !          10217:        copy_mem_info(info, buf, len);
        !          10218:        return len;
        !          10219: }
        !          10220: 
        !          10221: /*
        !          10222: **     Copy formatted profile information into the input buffer.
        !          10223: */
        !          10224: 
        !          10225: #define to_ms(t) ((t) * 1000 / HZ)
        !          10226: 
        !          10227: static int ncr_host_info(ncb_p np, char *ptr, off_t offset, int len)
        !          10228: {
        !          10229:        struct info_str info;
        !          10230: 
        !          10231:        info.buffer     = ptr;
        !          10232:        info.length     = len;
        !          10233:        info.offset     = offset;
        !          10234:        info.pos        = 0;
        !          10235: 
        !          10236:        copy_info(&info, "General information:\n");
        !          10237:        copy_info(&info, "  Chip NCR53C%s, ",   np->chip_name);
        !          10238:        copy_info(&info, "device id 0x%x, ",    np->device_id);
        !          10239:        copy_info(&info, "revision id 0x%x\n",  np->revision_id);
        !          10240: 
        !          10241:        copy_info(&info, "  IO port address 0x%lx, ", (u_long) np->port);
        !          10242:        copy_info(&info, "IRQ number %d\n", (int) np->irq);
        !          10243: 
        !          10244: #ifndef NCR_IOMAPPED
        !          10245:        if (np->reg)
        !          10246:                copy_info(&info, "  Using memory mapped IO at virtual address 0x%lx\n",
        !          10247:                                  (u_long) np->reg);
        !          10248: #endif
        !          10249:        copy_info(&info, "  Synchronous period factor %d, ", (int) np->minsync);
        !          10250:        copy_info(&info, "max commands per lun %d\n", SCSI_NCR_MAX_TAGS);
        !          10251: 
        !          10252:        if (driver_setup.debug || driver_setup.verbose > 1) {
        !          10253:                copy_info(&info, "  Debug flags 0x%x, ", driver_setup.debug);
        !          10254:                copy_info(&info, "verbosity level %d\n", driver_setup.verbose);
        !          10255:        }
        !          10256: 
        !          10257: #ifdef SCSI_NCR_PROFILE_SUPPORT
        !          10258:        copy_info(&info, "Profiling information:\n");
        !          10259:        copy_info(&info, "  %-12s = %lu\n", "num_trans",np->profile.num_trans);
        !          10260:        copy_info(&info, "  %-12s = %lu\n", "num_kbytes",np->profile.num_kbytes);
        !          10261:        copy_info(&info, "  %-12s = %lu\n", "num_disc", np->profile.num_disc);
        !          10262:        copy_info(&info, "  %-12s = %lu\n", "num_break",np->profile.num_break);
        !          10263:        copy_info(&info, "  %-12s = %lu\n", "num_int",  np->profile.num_int);
        !          10264:        copy_info(&info, "  %-12s = %lu\n", "num_fly",  np->profile.num_fly);
        !          10265:        copy_info(&info, "  %-12s = %lu\n", "ms_setup", to_ms(np->profile.ms_setup));
        !          10266:        copy_info(&info, "  %-12s = %lu\n", "ms_data",  to_ms(np->profile.ms_data));
        !          10267:        copy_info(&info, "  %-12s = %lu\n", "ms_disc",  to_ms(np->profile.ms_disc));
        !          10268:        copy_info(&info, "  %-12s = %lu\n", "ms_post",  to_ms(np->profile.ms_post));
        !          10269: #endif
        !          10270:        
        !          10271:        return info.pos > info.offset? info.pos - info.offset : 0;
        !          10272: }
        !          10273: 
        !          10274: #endif /* SCSI_NCR_USER_INFO_SUPPORT */
        !          10275: 
        !          10276: /*
        !          10277: **     Entry point of the scsi proc fs of the driver.
        !          10278: **     - func = 0 means read  (returns profile data)
        !          10279: **     - func = 1 means write (parse user control command)
        !          10280: */
        !          10281: 
        !          10282: int ncr53c8xx_proc_info(char *buffer, char **start, off_t offset,
        !          10283:                        int length, int hostno, int func)
        !          10284: {
        !          10285:        struct Scsi_Host *host;
        !          10286:        struct host_data *host_data;
        !          10287:        ncb_p ncb = 0;
        !          10288:        int retv;
        !          10289: 
        !          10290: #ifdef DEBUG_PROC_INFO
        !          10291: printf("ncr53c8xx_proc_info: hostno=%d, func=%d\n", hostno, func);
        !          10292: #endif
        !          10293: 
        !          10294:        for (host = first_host; host; host = host->next) {
        !          10295:                if (host->hostt == the_template && host->host_no == hostno) {
        !          10296:                        host_data = (struct host_data *) host->hostdata;
        !          10297:                        ncb = host_data->ncb;
        !          10298:                        break;
        !          10299:                }
        !          10300:        }
        !          10301: 
        !          10302:        if (!ncb)
        !          10303:                return -EINVAL;
        !          10304: 
        !          10305:        if (func) {
        !          10306: #ifdef SCSI_NCR_USER_COMMAND_SUPPORT
        !          10307:                retv = ncr_user_command(ncb, buffer, length);
        !          10308: #else
        !          10309:                retv = -EINVAL;
        !          10310: #endif
        !          10311:        }
        !          10312:        else {
        !          10313:                if (start)
        !          10314:                        *start = buffer;
        !          10315: #ifdef SCSI_NCR_USER_INFO_SUPPORT
        !          10316:                retv = ncr_host_info(ncb, buffer, offset, length);
        !          10317: #else
        !          10318:                retv = -EINVAL;
        !          10319: #endif
        !          10320:        }
        !          10321: 
        !          10322:        return retv;
        !          10323: }
        !          10324: 
        !          10325: 
        !          10326: /*=========================================================================
        !          10327: **     End of proc file system stuff
        !          10328: **=========================================================================
        !          10329: */
        !          10330: #endif
        !          10331: 
        !          10332: 
        !          10333: #ifdef SCSI_NCR_NVRAM_SUPPORT
        !          10334: 
        !          10335: /* ---------------------------------------------------------------------
        !          10336: **
        !          10337: **     Try reading Symbios format nvram
        !          10338: **
        !          10339: ** ---------------------------------------------------------------------
        !          10340: **
        !          10341: ** GPOI0 - data in/data out
        !          10342: ** GPIO1 - clock
        !          10343: **
        !          10344: **     return 0 if NVRAM data OK, 1 if NVRAM data not OK
        !          10345: ** ---------------------------------------------------------------------
        !          10346: */
        !          10347: 
        !          10348: #define SET_BIT 0
        !          10349: #define CLR_BIT 1
        !          10350: #define SET_CLK 2
        !          10351: #define CLR_CLK 3
        !          10352: 
        !          10353: static u_short nvram_read_data(ncr_slot *np, u_char *data, int len, u_char *gpreg, u_char *gpcntl);
        !          10354: static void nvram_start(ncr_slot *np, u_char *gpreg);
        !          10355: static void nvram_write_byte(ncr_slot *np, u_char *ack_data, u_char write_data, u_char *gpreg, u_char *gpcntl);
        !          10356: static void nvram_read_byte(ncr_slot *np, u_char *read_data, u_char ack_data, u_char *gpreg, u_char *gpcntl);
        !          10357: static void nvram_readAck(ncr_slot *np, u_char *read_bit, u_char *gpreg, u_char *gpcntl);
        !          10358: static void nvram_writeAck(ncr_slot *np, u_char write_bit, u_char *gpreg, u_char *gpcntl);
        !          10359: static void nvram_doBit(ncr_slot *np, u_char *read_bit, u_char write_bit, u_char *gpreg);
        !          10360: static void nvram_stop(ncr_slot *np, u_char *gpreg);
        !          10361: static void nvram_setBit(ncr_slot *np, u_char write_bit, u_char *gpreg, int bit_mode);
        !          10362: 
        !          10363: __initfunc(
        !          10364: static int ncr_get_Symbios_nvram (ncr_slot *np, Symbios_nvram *nvram)
        !          10365: )
        !          10366: {
        !          10367:        static u_char Symbios_trailer[6] = {0xfe, 0xfe, 0, 0, 0, 0};
        !          10368:        u_char  gpcntl, gpreg;
        !          10369:        u_char  old_gpcntl, old_gpreg;
        !          10370:        u_short csum;
        !          10371:        u_char  ack_data;
        !          10372:        int     retv = 1;
        !          10373: 
        !          10374:        /* save current state of GPCNTL and GPREG */
        !          10375:        old_gpreg       = INB (nc_gpreg);
        !          10376:        old_gpcntl      = INB (nc_gpcntl);
        !          10377:        gpcntl          = old_gpcntl & 0xfc;
        !          10378: 
        !          10379:        /* set up GPREG & GPCNTL to set GPIO0 and GPIO1 in to known state */
        !          10380:        OUTB (nc_gpreg,  old_gpreg);
        !          10381:        OUTB (nc_gpcntl, gpcntl);
        !          10382: 
        !          10383:        /* this is to set NVRAM into a known state with GPIO0/1 both low */
        !          10384:        gpreg = old_gpreg;
        !          10385:        nvram_setBit(np, 0, &gpreg, CLR_CLK);
        !          10386:        nvram_setBit(np, 0, &gpreg, CLR_BIT);
        !          10387:                
        !          10388:        /* now set NVRAM inactive with GPIO0/1 both high */
        !          10389:        nvram_stop(np, &gpreg);
        !          10390:        
        !          10391:        /* activate NVRAM */
        !          10392:        nvram_start(np, &gpreg);
        !          10393: 
        !          10394:        /* write device code and random address MSB */
        !          10395:        nvram_write_byte(np, &ack_data,
        !          10396:                0xa0 | ((SYMBIOS_NVRAM_ADDRESS >> 7) & 0x0e), &gpreg, &gpcntl);
        !          10397:        if (ack_data & 0x01)
        !          10398:                goto out;
        !          10399: 
        !          10400:        /* write random address LSB */
        !          10401:        nvram_write_byte(np, &ack_data,
        !          10402:                (SYMBIOS_NVRAM_ADDRESS & 0x7f) << 1, &gpreg, &gpcntl);
        !          10403:        if (ack_data & 0x01)
        !          10404:                goto out;
        !          10405: 
        !          10406:        /* regenerate START state to set up for reading */
        !          10407:        nvram_start(np, &gpreg);
        !          10408:        
        !          10409:        /* rewrite device code and address MSB with read bit set (lsb = 0x01) */
        !          10410:        nvram_write_byte(np, &ack_data,
        !          10411:                0xa1 | ((SYMBIOS_NVRAM_ADDRESS >> 7) & 0x0e), &gpreg, &gpcntl);
        !          10412:        if (ack_data & 0x01)
        !          10413:                goto out;
        !          10414: 
        !          10415:        /* now set up GPIO0 for inputting data */
        !          10416:        gpcntl |= 0x01;
        !          10417:        OUTB (nc_gpcntl, gpcntl);
        !          10418:                
        !          10419:        /* input all active data - only part of total NVRAM */
        !          10420:        csum = nvram_read_data(np,
        !          10421:                        (u_char *) nvram, sizeof(*nvram), &gpreg, &gpcntl);
        !          10422: 
        !          10423:        /* finally put NVRAM back in inactive mode */
        !          10424:        gpcntl &= 0xfe;
        !          10425:        OUTB (nc_gpcntl, gpcntl);
        !          10426:        nvram_stop(np, &gpreg);
        !          10427:        
        !          10428: #ifdef SCSI_NCR_DEBUG_NVRAM
        !          10429: printf("ncr53c8xx: NvRAM marker=%x trailer=%x %x %x %x %x %x byte_count=%d/%d checksum=%x/%x\n",
        !          10430:        nvram->start_marker,
        !          10431:        nvram->trailer[0], nvram->trailer[1], nvram->trailer[2],
        !          10432:        nvram->trailer[3], nvram->trailer[4], nvram->trailer[5],
        !          10433:        nvram->byte_count, sizeof(*nvram) - 12,
        !          10434:        nvram->checksum, csum);
        !          10435: #endif
        !          10436: 
        !          10437:        /* check valid NVRAM signature, verify byte count and checksum */
        !          10438:        if (nvram->start_marker == 0 &&
        !          10439:            !memcmp(nvram->trailer, Symbios_trailer, 6) &&
        !          10440:            nvram->byte_count == sizeof(*nvram) - 12 &&
        !          10441:            csum == nvram->checksum)
        !          10442:                retv = 0;
        !          10443: out:
        !          10444:        /* return GPIO0/1 to original states after having accessed NVRAM */
        !          10445:        OUTB (nc_gpcntl, old_gpcntl);
        !          10446:        OUTB (nc_gpreg,  old_gpreg);
        !          10447: 
        !          10448:        return retv;
        !          10449: }
        !          10450: 
        !          10451: /*
        !          10452:  * Read Symbios NvRAM data and compute checksum.
        !          10453:  */
        !          10454: __initfunc(
        !          10455: static u_short nvram_read_data(ncr_slot *np, u_char *data, int len, u_char *gpreg, u_char *gpcntl)
        !          10456: )
        !          10457: {
        !          10458:        int     x;
        !          10459:        u_short csum;
        !          10460: 
        !          10461:        for (x = 0; x < len; x++) 
        !          10462:                nvram_read_byte(np, &data[x], (x == (len - 1)), gpreg, gpcntl);
        !          10463: 
        !          10464:        for (x = 6, csum = 0; x < len - 6; x++)
        !          10465:                csum += data[x];
        !          10466: 
        !          10467:        return csum;
        !          10468: }
        !          10469: 
        !          10470: /*
        !          10471:  * Send START condition to NVRAM to wake it up.
        !          10472:  */
        !          10473: __initfunc(
        !          10474: static void nvram_start(ncr_slot *np, u_char *gpreg)
        !          10475: )
        !          10476: {
        !          10477:        nvram_setBit(np, 1, gpreg, SET_BIT);
        !          10478:        nvram_setBit(np, 0, gpreg, SET_CLK);
        !          10479:        nvram_setBit(np, 0, gpreg, CLR_BIT);
        !          10480:        nvram_setBit(np, 0, gpreg, CLR_CLK);
        !          10481: }
        !          10482: 
        !          10483: /*
        !          10484:  * WRITE a byte to the NVRAM and then get an ACK to see it was accepted OK,
        !          10485:  * GPIO0 must already be set as an output
        !          10486:  */
        !          10487: __initfunc(
        !          10488: static void nvram_write_byte(ncr_slot *np, u_char *ack_data, u_char write_data, u_char *gpreg, u_char *gpcntl)
        !          10489: )
        !          10490: {
        !          10491:        int x;
        !          10492:        
        !          10493:        for (x = 0; x < 8; x++)
        !          10494:                nvram_doBit(np, 0, (write_data >> (7 - x)) & 0x01, gpreg);
        !          10495:                
        !          10496:        nvram_readAck(np, ack_data, gpreg, gpcntl);
        !          10497: }
        !          10498: 
        !          10499: /*
        !          10500:  * READ a byte from the NVRAM and then send an ACK to say we have got it,
        !          10501:  * GPIO0 must already be set as an input
        !          10502:  */
        !          10503: __initfunc(
        !          10504: static void nvram_read_byte(ncr_slot *np, u_char *read_data, u_char ack_data, u_char *gpreg, u_char *gpcntl)
        !          10505: )
        !          10506: {
        !          10507:        int x;
        !          10508:        u_char read_bit;
        !          10509: 
        !          10510:        *read_data = 0;
        !          10511:        for (x = 0; x < 8; x++) {
        !          10512:                nvram_doBit(np, &read_bit, 1, gpreg);
        !          10513:                *read_data |= ((read_bit & 0x01) << (7 - x));
        !          10514:        }
        !          10515: 
        !          10516:        nvram_writeAck(np, ack_data, gpreg, gpcntl);
        !          10517: }
        !          10518: 
        !          10519: /*
        !          10520:  * Output an ACK to the NVRAM after reading,
        !          10521:  * change GPIO0 to output and when done back to an input
        !          10522:  */
        !          10523: __initfunc(
        !          10524: static void nvram_writeAck(ncr_slot *np, u_char write_bit, u_char *gpreg, u_char *gpcntl)
        !          10525: )
        !          10526: {
        !          10527:        OUTB (nc_gpcntl, *gpcntl & 0xfe);
        !          10528:        nvram_doBit(np, 0, write_bit, gpreg);
        !          10529:        OUTB (nc_gpcntl, *gpcntl);
        !          10530: }
        !          10531: 
        !          10532: /*
        !          10533:  * Input an ACK from NVRAM after writing,
        !          10534:  * change GPIO0 to input and when done back to an output
        !          10535:  */
        !          10536: __initfunc(
        !          10537: static void nvram_readAck(ncr_slot *np, u_char *read_bit, u_char *gpreg, u_char *gpcntl)
        !          10538: )
        !          10539: {
        !          10540:        OUTB (nc_gpcntl, *gpcntl | 0x01);
        !          10541:        nvram_doBit(np, read_bit, 1, gpreg);
        !          10542:        OUTB (nc_gpcntl, *gpcntl);
        !          10543: }
        !          10544: 
        !          10545: /*
        !          10546:  * Read or write a bit to the NVRAM,
        !          10547:  * read if GPIO0 input else write if GPIO0 output
        !          10548:  */
        !          10549: __initfunc(
        !          10550: static void nvram_doBit(ncr_slot *np, u_char *read_bit, u_char write_bit, u_char *gpreg)
        !          10551: )
        !          10552: {
        !          10553:        nvram_setBit(np, write_bit, gpreg, SET_BIT);
        !          10554:        nvram_setBit(np, 0, gpreg, SET_CLK);
        !          10555:        if (read_bit)
        !          10556:                *read_bit = INB (nc_gpreg);
        !          10557:        nvram_setBit(np, 0, gpreg, CLR_CLK);
        !          10558:        nvram_setBit(np, 0, gpreg, CLR_BIT);
        !          10559: }
        !          10560: 
        !          10561: /*
        !          10562:  * Send STOP condition to NVRAM - puts NVRAM to sleep... ZZzzzz!!
        !          10563:  */
        !          10564: __initfunc(
        !          10565: static void nvram_stop(ncr_slot *np, u_char *gpreg)
        !          10566: )
        !          10567: {
        !          10568:        nvram_setBit(np, 0, gpreg, SET_CLK);
        !          10569:        nvram_setBit(np, 1, gpreg, SET_BIT);
        !          10570: }
        !          10571: 
        !          10572: /*
        !          10573:  * Set/clear data/clock bit in GPIO0
        !          10574:  */
        !          10575: __initfunc(
        !          10576: static void nvram_setBit(ncr_slot *np, u_char write_bit, u_char *gpreg, int bit_mode)
        !          10577: )
        !          10578: {
        !          10579:        DELAY(5);
        !          10580:        switch (bit_mode){
        !          10581:        case SET_BIT:
        !          10582:                *gpreg |= write_bit;
        !          10583:                break;
        !          10584:        case CLR_BIT:
        !          10585:                *gpreg &= 0xfe;
        !          10586:                break;
        !          10587:        case SET_CLK:
        !          10588:                *gpreg |= 0x02;
        !          10589:                break;
        !          10590:        case CLR_CLK:
        !          10591:                *gpreg &= 0xfd;
        !          10592:                break;
        !          10593: 
        !          10594:        }
        !          10595:        OUTB (nc_gpreg, *gpreg);
        !          10596:        DELAY(5);
        !          10597: }
        !          10598: 
        !          10599: #undef SET_BIT 0
        !          10600: #undef CLR_BIT 1
        !          10601: #undef SET_CLK 2
        !          10602: #undef CLR_CLK 3
        !          10603: 
        !          10604: 
        !          10605: /* ---------------------------------------------------------------------
        !          10606: **
        !          10607: **     Try reading Tekram format nvram
        !          10608: **
        !          10609: ** ---------------------------------------------------------------------
        !          10610: **
        !          10611: ** GPOI0 - data in
        !          10612: ** GPIO1 - data out
        !          10613: ** GPIO2 - clock
        !          10614: ** GPIO4 - chip select
        !          10615: **
        !          10616: **     return 0 if NVRAM data OK, 1 if NVRAM data not OK
        !          10617: ** ---------------------------------------------------------------------
        !          10618: */
        !          10619: 
        !          10620: static u_short Tnvram_read_data(ncr_slot *np, u_short *data, int len, u_char *gpreg);
        !          10621: static void Tnvram_Send_Command(ncr_slot *np, u_short write_data, u_char *read_bit, u_char *gpreg);
        !          10622: static void Tnvram_Read_Word(ncr_slot *np, u_short *nvram_data, u_char *gpreg);
        !          10623: static void Tnvram_Read_Bit(ncr_slot *np, u_char *read_bit, u_char *gpreg);
        !          10624: static void Tnvram_Write_Bit(ncr_slot *np, u_char write_bit, u_char *gpreg);
        !          10625: static void Tnvram_Stop(ncr_slot *np, u_char *gpreg);
        !          10626: static void Tnvram_Clk(ncr_slot *np, u_char *gpreg);
        !          10627: 
        !          10628: __initfunc(
        !          10629: static int ncr_get_Tekram_nvram (ncr_slot *np, Tekram_nvram *nvram)
        !          10630: )
        !          10631: {
        !          10632:        u_char gpcntl, gpreg;
        !          10633:        u_char old_gpcntl, old_gpreg;
        !          10634:        u_short csum;
        !          10635: 
        !          10636:        /* save current state of GPCNTL and GPREG */
        !          10637:        old_gpreg       = INB (nc_gpreg);
        !          10638:        old_gpcntl      = INB (nc_gpcntl);
        !          10639: 
        !          10640:        /* set up GPREG & GPCNTL to set GPIO0/1/2/4 in to known state, 0 in,
        !          10641:           1/2/4 out */
        !          10642:        gpreg = old_gpreg & 0xe9;
        !          10643:        OUTB (nc_gpreg, gpreg);
        !          10644:        gpcntl = (old_gpcntl & 0xe9) | 0x09;
        !          10645:        OUTB (nc_gpcntl, gpcntl);
        !          10646: 
        !          10647:        /* input all of NVRAM, 64 words */
        !          10648:        csum = Tnvram_read_data(np, (u_short *) nvram,
        !          10649:                        sizeof(*nvram) / sizeof(short), &gpreg);
        !          10650:        
        !          10651:        /* return GPIO0/1/2/4 to original states after having accessed NVRAM */
        !          10652:        OUTB (nc_gpcntl, old_gpcntl);
        !          10653:        OUTB (nc_gpreg,  old_gpreg);
        !          10654: 
        !          10655:        /* check data valid */
        !          10656:        if (csum != 0x1234)
        !          10657:                return 1;
        !          10658: 
        !          10659:        return 0;
        !          10660: }
        !          10661: 
        !          10662: /*
        !          10663:  * Read Tekram NvRAM data and compute checksum.
        !          10664:  */
        !          10665: __initfunc(
        !          10666: static u_short Tnvram_read_data(ncr_slot *np, u_short *data, int len, u_char *gpreg)
        !          10667: )
        !          10668: {
        !          10669:        u_char  read_bit;
        !          10670:        u_short csum;
        !          10671:        int     x;
        !          10672: 
        !          10673:        for (x = 0, csum = 0; x < len; x++)  {
        !          10674: 
        !          10675:                /* output read command and address */
        !          10676:                Tnvram_Send_Command(np, 0x180 | x, &read_bit, gpreg);
        !          10677:                if (read_bit & 0x01)
        !          10678:                        return 0; /* Force bad checksum */
        !          10679: 
        !          10680:                Tnvram_Read_Word(np, &data[x], gpreg);
        !          10681:                csum += data[x];
        !          10682: 
        !          10683:                Tnvram_Stop(np, gpreg);
        !          10684:        }
        !          10685: 
        !          10686:        return csum;
        !          10687: }
        !          10688: 
        !          10689: /*
        !          10690:  * Send read command and address to NVRAM
        !          10691:  */
        !          10692: __initfunc(
        !          10693: static void Tnvram_Send_Command(ncr_slot *np, u_short write_data, u_char *read_bit, u_char *gpreg)
        !          10694: )
        !          10695: {
        !          10696:        int x;
        !          10697: 
        !          10698:        /* send 9 bits, start bit (1), command (2), address (6)  */
        !          10699:        for (x = 0; x < 9; x++)
        !          10700:                Tnvram_Write_Bit(np, (u_char) (write_data >> (8 - x)), gpreg);
        !          10701: 
        !          10702:        *read_bit = INB (nc_gpreg);
        !          10703: }
        !          10704: 
        !          10705: /*
        !          10706:  * READ a byte from the NVRAM
        !          10707:  */
        !          10708: __initfunc(
        !          10709: static void Tnvram_Read_Word(ncr_slot *np, u_short *nvram_data, u_char *gpreg)
        !          10710: )
        !          10711: {
        !          10712:        int x;
        !          10713:        u_char read_bit;
        !          10714: 
        !          10715:        *nvram_data = 0;
        !          10716:        for (x = 0; x < 16; x++) {
        !          10717:                Tnvram_Read_Bit(np, &read_bit, gpreg);
        !          10718: 
        !          10719:                if (read_bit & 0x01)
        !          10720:                        *nvram_data |=  (0x01 << (15 - x));
        !          10721:                else
        !          10722:                        *nvram_data &= ~(0x01 << (15 - x));
        !          10723:        }
        !          10724: }
        !          10725: 
        !          10726: /* 
        !          10727:  * Read bit from NVRAM
        !          10728:  */
        !          10729: __initfunc(
        !          10730: static void Tnvram_Read_Bit(ncr_slot *np, u_char *read_bit, u_char *gpreg)
        !          10731: )
        !          10732: {
        !          10733:        DELAY(2);
        !          10734:        Tnvram_Clk(np, gpreg);
        !          10735:        *read_bit = INB (nc_gpreg);
        !          10736: }
        !          10737: 
        !          10738: /*
        !          10739:  * Write bit to GPIO0
        !          10740:  */
        !          10741: __initfunc(
        !          10742: static void Tnvram_Write_Bit(ncr_slot *np, u_char write_bit, u_char *gpreg)
        !          10743: )
        !          10744: {
        !          10745:        if (write_bit & 0x01)
        !          10746:                *gpreg |= 0x02;
        !          10747:        else
        !          10748:                *gpreg &= 0xfd;
        !          10749:                
        !          10750:        *gpreg |= 0x10;
        !          10751:                
        !          10752:        OUTB (nc_gpreg, *gpreg);
        !          10753:        DELAY(2);
        !          10754: 
        !          10755:        Tnvram_Clk(np, gpreg);
        !          10756: }
        !          10757: 
        !          10758: /*
        !          10759:  * Send STOP condition to NVRAM - puts NVRAM to sleep... ZZZzzz!!
        !          10760:  */
        !          10761: __initfunc(
        !          10762: static void Tnvram_Stop(ncr_slot *np, u_char *gpreg)
        !          10763: )
        !          10764: {
        !          10765:        *gpreg &= 0xef;
        !          10766:        OUTB (nc_gpreg, *gpreg);
        !          10767:        DELAY(2);
        !          10768: 
        !          10769:        Tnvram_Clk(np, gpreg);
        !          10770: }
        !          10771: 
        !          10772: /*
        !          10773:  * Pulse clock bit in GPIO0
        !          10774:  */
        !          10775: __initfunc(
        !          10776: static void Tnvram_Clk(ncr_slot *np, u_char *gpreg)
        !          10777: )
        !          10778: {
        !          10779:        OUTB (nc_gpreg, *gpreg | 0x04);
        !          10780:        DELAY(2);
        !          10781:        OUTB (nc_gpreg, *gpreg);
        !          10782: }
        !          10783: 
        !          10784: #endif /* SCSI_NCR_NVRAM_SUPPORT */
        !          10785: 
        !          10786: /*
        !          10787: **     Module stuff
        !          10788: */
        !          10789: 
        !          10790: #ifdef MODULE
        !          10791: Scsi_Host_Template driver_template = NCR53C8XX;
        !          10792: #include "scsi_module.c"
        !          10793: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.