11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AUTOSENSE 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PSEUDO_DMA 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FOO 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define UNSAFE /* Not unsafe for PAS16 -- use it */ 544456d37b59d8e541936ed26d8b6e08d27e88ac1Olaf Hering#define PDEBUG 0 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This driver adapted from Drew Eckhardt's Trantor T128 driver 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright 1993, Drew Eckhardt 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Visionary Computing 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (Unix and Linux consulting and custom programming) 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * drew@colorado.edu 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * +1 (303) 666-5836 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ( Based on T128 - DISTRIBUTION RELEASE 3. ) 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modified to work with the Pro Audio Spectrum/Studio 16 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * by John Weidman. 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For more information, please consult 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Media Vision 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (510) 770-8600 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (800) 348-7116 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NCR 5380 Family 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SCSI Protocol Controller 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Databook 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NCR Microelectronics 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1635 Aeroplaza Drive 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Colorado Springs, CO 80916 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1+ (719) 578-3400 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1+ (800) 334-5454 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Options : 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for commands that return with a CHECK CONDITION status. 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * LIMIT_TRANSFERSIZE - if defined, limit the pseudo-dma transfers to 512 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bytes at a time. Since interrupts are disabled by default during 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * these transfers, we might need this to give reasonable interrupt 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * service time if the transfer size gets too large. 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PSEUDO_DMA - enables PSEUDO-DMA hardware, should give a 3-4X performance 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * increase compared to polled I/O. 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARITY - enable parity checking. Not supported. 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SCSI2 - enable support for SCSI-II tagged queueing. Untested. 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * UNSAFE - leave interrupts enabled during pseudo-DMA transfers. This 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * parameter comes from the NCR5380 code. It is NOT unsafe with 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the PAS16 and you should use it. If you don't you will have 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a problem with dropped characters during high speed 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * communications during SCSI transfers. If you really don't 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * want to use UNSAFE you can try defining LIMIT_TRANSFERSIZE or 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * twiddle with the transfer size in the high level code. 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * USLEEP - enable support for devices that don't disconnect. Untested. 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The card is detected and initialized in one of several ways : 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. Autoprobe (default) - There are many different models of 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the Pro Audio Spectrum/Studio 16, and I only have one of 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * them, so this may require a little tweaking. An interrupt 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is triggered to autoprobe for the interrupt line. Note: 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * with the newer model boards, the interrupt is set via 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * software after reset using the default_irq for the 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * current board number. 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. With command line overrides - pas16=port,irq may be 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * used on the LILO command line to override the defaults. 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. With the PAS16_OVERRIDE compile time define. This is 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * specified as an array of address, irq tuples. Ie, for 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * one board at the default 0x388 address, IRQ10, I could say 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * -DPAS16_OVERRIDE={{0x388, 10}} 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE: Untested. 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4. When included as a module, with arguments passed on the command line: 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pas16_irq=xx the interrupt 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pas16_addr=xx the port 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * e.g. "modprobe pas16 pas16_addr=0x388 pas16_irq=5" 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note that if the override methods are used, place holders must 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * be specified for other boards in the system. 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Configuration notes : 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The current driver does not support interrupt sharing with the 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * sound portion of the card. If you use the same irq for the 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * scsi port and sound you will have problems. Either use 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a different irq for the scsi port or don't use interrupts 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for the scsi port. 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If you have problems with your card not being recognized, use 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the LILO command line override. Try to get it recognized without 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * interrupts. Ie, for a board at the default 0x388 base port, 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * boot: linux pas16=0x388,255 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SCSI_IRQ_NONE (255) should be specified for no interrupt, 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IRQ_AUTO (254) to autoprobe for an IRQ line if overridden 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * on the command line. 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (IRQ_AUTO == 254, SCSI_IRQ_NONE == 255 in NCR5380.h) 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/system.h> 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/signal.h> 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/proc_fs.h> 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/dma.h> 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/blkdev.h> 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/stat.h> 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "scsi.h" 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_host.h> 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "pas16.h" 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AUTOPROBE_IRQ 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "NCR5380.h" 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int pas_maxi = 0; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int pas_wmaxi = 0; 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned short pas16_addr = 0; 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int pas16_irq = 0; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 140408b664a7d394a5e4315fbd14aca49b042cb2b08Adrian Bunkstatic const int scsi_irq_translate[] = 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 0, 10, 11 }; 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* The default_irqs array contains values used to set the irq into the 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * board via software (as must be done on newer model boards without 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * irq jumpers on the board). The first value in the array will be 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * assigned to logical board 0, the next to board 1, etc. 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 148408b664a7d394a5e4315fbd14aca49b042cb2b08Adrian Bunkstatic int default_irqs[] __initdata = 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { PAS16_DEFAULT_BOARD_1_IRQ, 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PAS16_DEFAULT_BOARD_2_IRQ, 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PAS16_DEFAULT_BOARD_3_IRQ, 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PAS16_DEFAULT_BOARD_4_IRQ 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }; 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct override { 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short io_port; 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int irq; 1586391a11375de5e2bb1eb8481e54619761dc65d9fTobias Klauser} overrides 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef PAS16_OVERRIDE 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds [] __initdata = PAS16_OVERRIDE; 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds [4] __initdata = {{0,IRQ_AUTO}, {0,IRQ_AUTO}, {0,IRQ_AUTO}, 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {0,IRQ_AUTO}}; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1666391a11375de5e2bb1eb8481e54619761dc65d9fTobias Klauser#define NO_OVERRIDES ARRAY_SIZE(overrides) 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct base { 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short io_port; 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int noauto; 1716391a11375de5e2bb1eb8481e54619761dc65d9fTobias Klauser} bases[] __initdata = 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { {PAS16_DEFAULT_BASE_1, 0}, 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PAS16_DEFAULT_BASE_2, 0}, 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PAS16_DEFAULT_BASE_3, 0}, 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {PAS16_DEFAULT_BASE_4, 0} 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }; 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1786391a11375de5e2bb1eb8481e54619761dc65d9fTobias Klauser#define NO_BASES ARRAY_SIZE(bases) 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 180408b664a7d394a5e4315fbd14aca49b042cb2b08Adrian Bunkstatic const unsigned short pas16_offset[ 8 ] = 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1c00, /* OUTPUT_DATA_REG */ 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1c01, /* INITIATOR_COMMAND_REG */ 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1c02, /* MODE_REG */ 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x1c03, /* TARGET_COMMAND_REG */ 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x3c00, /* STATUS_REG ro, SELECT_ENABLE_REG wo */ 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x3c01, /* BUS_AND_STATUS_REG ro, START_DMA_SEND_REG wo */ 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x3c02, /* INPUT_DATA_REGISTER ro, (N/A on PAS16 ?) 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * START_DMA_TARGET_RECEIVE_REG wo 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x3c03, /* RESET_PARITY_INTERRUPT_REG ro, 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * START_DMA_INITIATOR_RECEIVE_REG wo 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }; 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*----------------------------------------------------------------*/ 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* the following will set the monitor border color (useful to find 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds where something crashed or gets stuck at */ 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1 = blue 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2 = green 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3 = cyan 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4 = red 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5 = magenta 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6 = yellow 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7 = white 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 1 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define rtrc(i) {inb(0x3da); outb(0x31, 0x3c0); outb((i), 0x3c0);} 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define rtrc(i) {} 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function : enable_board( int board_num, unsigned short port ) 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Purpose : set address in new model board 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inputs : board_num - logical board number 0-3, port - base address 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __init 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enable_board( int board_num, unsigned short port ) 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( 0xbc + board_num, MASTER_ADDRESS_PTR ); 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( port >> 2, MASTER_ADDRESS_PTR ); 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function : init_board( unsigned short port, int irq ) 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Purpose : Set the board up to handle the SCSI interface 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inputs : port - base address of the board, 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * irq - irq to assign to the SCSI port 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * force_irq - set it even if it conflicts with sound driver 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __init 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_board( unsigned short io_port, int irq, int force_irq ) 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int tmp; 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int pas_irq_code; 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize the SCSI part of the board */ 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( 0x30, io_port + P_TIMEOUT_COUNTER_REG ); /* Timeout counter */ 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( 0x01, io_port + P_TIMEOUT_STATUS_REG_OFFSET ); /* Reset TC */ 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( 0x01, io_port + WAIT_STATE ); /* 1 Wait state */ 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_read( RESET_PARITY_INTERRUPT_REG ); 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set the SCSI interrupt pointer without mucking up the sound 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * interrupt pointer in the same byte. 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pas_irq_code = ( irq < 16 ) ? scsi_irq_translate[irq] : 0; 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = inb( io_port + IO_CONFIG_3 ); 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( (( tmp & 0x0f ) == pas_irq_code) && pas_irq_code > 0 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && !force_irq ) 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk( "pas16: WARNING: Can't use same irq as sound " 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "driver -- interrupts disabled\n" ); 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set up the drive parameters, disable 5380 interrupts */ 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( 0x4d, io_port + SYS_CONFIG_4 ); 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = ( tmp & 0x0f ) | ( pas_irq_code << 4 ); 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( tmp, io_port + IO_CONFIG_3 ); 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set up the drive parameters and enable 5380 interrupts */ 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( 0x6d, io_port + SYS_CONFIG_4 ); 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function : pas16_hw_detect( unsigned short board_num ) 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Purpose : determine if a pas16 board is present 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inputs : board_num - logical board number ( 0 - 3 ) 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns : 0 if board not found, 1 if found. 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pas16_hw_detect( unsigned short board_num ) 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char board_rev, tmp; 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short io_port = bases[ board_num ].io_port; 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* See if we can find a PAS16 board at the address associated 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * with this logical board number. 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* First, attempt to take a newer model board out of reset and 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * give it a base address. This shouldn't affect older boards. 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enable_board( board_num, io_port ); 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Now see if it looks like a PAS16 board */ 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds board_rev = inb( io_port + PCB_CONFIG ); 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( board_rev == 0xff ) 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = board_rev ^ 0xe0; 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( tmp, io_port + PCB_CONFIG ); 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = inb( io_port + PCB_CONFIG ); 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( board_rev, io_port + PCB_CONFIG ); 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( board_rev != tmp ) /* Not a PAS-16 */ 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( ( inb( io_port + OPERATION_MODE_1 ) & 0x03 ) != 0x03 ) 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; /* return if no SCSI interface found */ 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Mediavision has some new model boards that return ID bits 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that indicate a SCSI interface, but they're not (LMS). We'll 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * put in an additional test to try to weed them out. 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( 0x01, io_port + WAIT_STATE ); /* 1 Wait state */ 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_write( MODE_REG, 0x20 ); /* Is it really SCSI? */ 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( NCR5380_read( MODE_REG ) != 0x20 ) /* Write to a reg. */ 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; /* and try to read */ 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_write( MODE_REG, 0x00 ); /* it back. */ 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( NCR5380_read( MODE_REG ) != 0x00 ) 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function : pas16_setup(char *str, int *ints) 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Purpose : LILO command line initialization of the overrides array, 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inputs : str - unused, ints - array of integer parameters with ints[0] 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * equal to the number of ints. 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __init pas16_setup(char *str, int *ints) 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static int commandline_current = 0; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ints[0] != 2) 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("pas16_setup : usage pas16=io_port,irq\n"); 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (commandline_current < NO_OVERRIDES) { 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds overrides[commandline_current].io_port = (unsigned short) ints[1]; 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds overrides[commandline_current].irq = ints[2]; 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < NO_BASES; ++i) 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bases[i].io_port == (unsigned short) ints[1]) { 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bases[i].noauto = 1; 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++commandline_current; 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 371d0be4a7d29ad0bd3ce2209dd9e46d410b632db59Christoph Hellwig * Function : int pas16_detect(struct scsi_host_template * tpnt) 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Purpose : detects and initializes PAS16 controllers 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that were autoprobed, overridden on the LILO command line, 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * or specified at compile time. 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inputs : tpnt - template for this SCSI adapter. 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns : 1 if a host adapter was found, 0 if not. 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 383d0be4a7d29ad0bd3ce2209dd9e46d410b632db59Christoph Hellwigint __init pas16_detect(struct scsi_host_template * tpnt) 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static int current_override = 0; 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static unsigned short current_base = 0; 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Scsi_Host *instance; 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short io_port; 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int count; 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tpnt->proc_name = "pas16"; 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tpnt->proc_info = &pas16_proc_info; 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pas16_addr != 0) { 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds overrides[0].io_port = pas16_addr; 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is how we avoid seeing more than 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * one host adapter at the same I/O port. 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Cribbed shamelessly from pas16_setup(). 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (count = 0; count < NO_BASES; ++count) 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bases[count].io_port == pas16_addr) { 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bases[count].noauto = 1; 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pas16_irq != 0) 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds overrides[0].irq = pas16_irq; 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (count = 0; current_override < NO_OVERRIDES; ++current_override) { 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds io_port = 0; 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (overrides[current_override].io_port) 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds io_port = overrides[current_override].io_port; 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enable_board( current_override, io_port ); 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_board( io_port, overrides[current_override].irq, 1 ); 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (; !io_port && (current_base < NO_BASES); ++current_base) { 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if (PDEBUG & PDEBUG_INIT) 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("scsi-pas16 : probing io_port %04x\n", (unsigned int) bases[current_base].io_port); 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( !bases[current_base].noauto && 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pas16_hw_detect( current_base ) ){ 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds io_port = bases[current_base].io_port; 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_board( io_port, default_irqs[ current_base ], 0 ); 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if (PDEBUG & PDEBUG_INIT) 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("scsi-pas16 : detected board.\n"); 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT) 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("scsi-pas16 : io_port = %04x\n", (unsigned int) io_port); 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!io_port) 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(instance == NULL) 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance->io_port = io_port; 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_init(instance, 0); 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (overrides[current_override].irq != IRQ_AUTO) 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance->irq = overrides[current_override].irq; 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance->irq = NCR5380_probe_irq(instance, PAS16_IRQS); 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (instance->irq != SCSI_IRQ_NONE) 4561e641664301744f0d381de43ae1e12343e60b479Jeff Garzik if (request_irq(instance->irq, pas16_intr, IRQF_DISABLED, 4571e641664301744f0d381de43ae1e12343e60b479Jeff Garzik "pas16", instance)) { 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("scsi%d : IRQ%d not free, interrupts disabled\n", 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance->host_no, instance->irq); 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance->irq = SCSI_IRQ_NONE; 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (instance->irq == SCSI_IRQ_NONE) { 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no); 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no); 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Disable 5380 interrupts, leave drive params the same */ 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( 0x4d, io_port + SYS_CONFIG_4 ); 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( (inb(io_port + IO_CONFIG_3) & 0x0f), io_port + IO_CONFIG_3 ); 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT) 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("scsi%d : irq = %d\n", instance->host_no, instance->irq); 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("scsi%d : at 0x%04x", instance->host_no, (int) 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance->io_port); 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (instance->irq == SCSI_IRQ_NONE) 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk (" interrupts disabled"); 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk (" irq %d", instance->irq); 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds CAN_QUEUE, CMD_PER_LUN, PAS16_PUBLIC_RELEASE); 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_print_options(instance); 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("\n"); 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++current_override; 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++count; 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function : int pas16_biosparam(Disk *disk, struct block_device *dev, int *ip) 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the specified device / size. 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inputs : size = size of device in sectors (512 bytes), dev = block device 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * major / minor, ip[] = {heads, sectors, cylinders} 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns : always 0 (success), initializes ip 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * XXX Most SCSI boards use this mapping, I could be incorrect. Some one 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * using hard disks on a trantor should verify that this mapping corresponds 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to that used by the BIOS / ASPI driver by running the linux fdisk program 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and matching the H_C_S coordinates to what DOS uses. 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint pas16_biosparam(struct scsi_device *sdev, struct block_device *dev, 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sector_t capacity, int * ip) 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int size = capacity; 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ip[0] = 64; 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ip[1] = 32; 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ip[2] = size >> 11; /* I think I have it as /(32*64) */ 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( ip[2] > 1024 ) { /* yes, >, not >= */ 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ip[0]=255; 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ip[1]=63; 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ip[2]=size/(63*255); 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( ip[2] > 1023 ) /* yes >1023... */ 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ip[2] = 1023; 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function : int NCR5380_pread (struct Scsi_Host *instance, 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * unsigned char *dst, int len) 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Purpose : Fast 5380 pseudo-dma read function, transfers len bytes to 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * dst 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inputs : dst = destination, len = length in bytes 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns : 0 on success, non zero on a failure such as a watchdog 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * timeout. 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst, 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len) { 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register unsigned char *d = dst; 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register unsigned short reg = (unsigned short) (instance->io_port + 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds P_DATA_REG_OFFSET); 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register int i = len; 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ii = 0; 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while ( !(inb(instance->io_port + P_STATUS_REG_OFFSET) & P_ST_RDY) ) 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++ii; 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds insb( reg, d, i ); 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( inb(instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET) & P_TS_TIM) { 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( P_TS_CT, instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET); 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("scsi%d : watchdog timer fired in NCR5380_pread()\n", 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance->host_no); 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ii > pas_maxi) 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pas_maxi = ii; 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function : int NCR5380_pwrite (struct Scsi_Host *instance, 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * unsigned char *src, int len) 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * src 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inputs : src = source, len = length in bytes 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns : 0 on success, non zero on a failure such as a watchdog 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * timeout. 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src, 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len) { 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register unsigned char *s = src; 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register unsigned short reg = (instance->io_port + P_DATA_REG_OFFSET); 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register int i = len; 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ii = 0; 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while ( !((inb(instance->io_port + P_STATUS_REG_OFFSET)) & P_ST_RDY) ) 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++ii; 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outsb( reg, s, i ); 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (inb(instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET) & P_TS_TIM) { 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb( P_TS_CT, instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET); 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("scsi%d : watchdog timer fired in NCR5380_pwrite()\n", 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance->host_no); 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ii > pas_maxi) 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pas_wmaxi = ii; 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "NCR5380.c" 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int pas16_release(struct Scsi_Host *shost) 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (shost->irq) 6081e641664301744f0d381de43ae1e12343e60b479Jeff Garzik free_irq(shost->irq, shost); 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_exit(shost); 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (shost->dma_channel != 0xff) 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_dma(shost->dma_channel); 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (shost->io_port && shost->n_io_port) 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_region(shost->io_port, shost->n_io_port); 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scsi_unregister(shost); 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 618d0be4a7d29ad0bd3ce2209dd9e46d410b632db59Christoph Hellwigstatic struct scsi_host_template driver_template = { 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "Pro Audio Spectrum-16 SCSI", 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .detect = pas16_detect, 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = pas16_release, 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .queuecommand = pas16_queue_command, 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .eh_abort_handler = pas16_abort, 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .eh_bus_reset_handler = pas16_bus_reset, 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .bios_param = pas16_biosparam, 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .can_queue = CAN_QUEUE, 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .this_id = 7, 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .sg_tablesize = SG_ALL, 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .cmd_per_lun = CMD_PER_LUN, 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .use_clustering = DISABLE_CLUSTERING, 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "scsi_module.c" 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef MODULE 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(pas16_addr, ushort, 0); 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(pas16_irq, int, 0); 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 639