|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.