11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AUTOSENSE 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PSEUDO_DMA 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DONT_USE_INTR 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define UNSAFE /* Leave interrupts enabled during pseudo-dma I/O */ 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define xNDEBUG (NDEBUG_INTR+NDEBUG_RESELECTION+\ 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NDEBUG_SELECTION+NDEBUG_ARBITRATION) 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DMA_WORKS_RIGHT 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DTC 3180/3280 driver, by 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Ray Van Tassle rayvt@comm.mot.com 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * taken from ... 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Trantor T128/T128F/T228 driver by... 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Drew Eckhardt 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Visionary Computing 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (Unix and Linux consulting and custom programming) 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * drew@colorado.edu 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * +1 (303) 440-4894 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DISTRIBUTION RELEASE 1. 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For more information, please consult 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NCR 5380 Family 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SCSI Protocol Controller 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Databook 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Options : 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for commands that return with a CHECK CONDITION status. 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PSEUDO_DMA - enables PSEUDO-DMA hardware, should give a 3-4X performance 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * increase compared to polled I/O. 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARITY - enable parity checking. Not supported. 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * UNSAFE - leave interrupts enabled during pseudo-DMA transfers. 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You probably want this. 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The card is detected and initialized in one of several ways : 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. Autoprobe (default) - since the board is memory mapped, 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * a BIOS signature is scanned for to locate the registers. 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * An interrupt is triggered to autoprobe for the interrupt 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * line. 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. With command line overrides - dtc=address,irq may be 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * used on the LILO command line to override the defaults. 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*----------------------------------------------------------------*/ 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* the following will set the monitor border color (useful to find 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds where something crashed or gets stuck at */ 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1 = blue 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2 = green 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3 = cyan 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4 = red 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5 = magenta 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6 = yellow 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7 = white 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define rtrc(i) {inb(0x3da); outb(0x31, 0x3c0); outb((i), 0x3c0);} 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define rtrc(i) {} 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/signal.h> 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/blkdev.h> 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/stat.h> 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 8353d5ed627df852ba8bab7f70df25290bd733792cMatthew Wilcox#include <linux/io.h> 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "scsi.h" 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_host.h> 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "dtc.h" 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AUTOPROBE_IRQ 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "NCR5380.h" 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DTC_PUBLIC_RELEASE 2 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The DTC3180 & 3280 boards are memory mapped. 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Offset from DTC_5380_OFFSET */ 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DTC_CONTROL_REG 0x100 /* rw */ 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define D_CR_ACCESS 0x80 /* ro set=can access 3280 registers */ 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CSR_DIR_READ 0x40 /* rw direction, 1 = read 0 = write */ 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CSR_RESET 0x80 /* wo Resets 53c400 */ 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CSR_5380_REG 0x80 /* ro 5380 registers can be accessed */ 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CSR_TRANS_DIR 0x40 /* rw Data transfer direction */ 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CSR_SCSI_BUFF_INTR 0x20 /* rw Enable int on transfer ready */ 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CSR_5380_INTR 0x10 /* rw Enable 5380 interrupts */ 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CSR_SHARED_INTR 0x08 /* rw Interrupt sharing */ 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CSR_HOST_BUF_NOT_RDY 0x04 /* ro Host buffer not ready */ 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CSR_SCSI_BUF_RDY 0x02 /* ro SCSI buffer ready */ 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CSR_GATED_5380_IRQ 0x01 /* ro Last block xferred */ 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CSR_INT_BASE (CSR_SCSI_BUFF_INTR | CSR_5380_INTR) 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DTC_BLK_CNT 0x101 /* rw 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * # of 128-byte blocks to transfer */ 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define D_CR_ACCESS 0x80 /* ro set=can access 3280 registers */ 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DTC_SWITCH_REG 0x3982 /* ro - DIP switches */ 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DTC_RESUME_XFER 0x3982 /* wo - resume data xfer 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * after disconnect/reconnect*/ 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DTC_5380_OFFSET 0x3880 /* 8 registers here, see NCR5380.h */ 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*!!!! for dtc, it's a 128 byte buffer at 3900 !!! */ 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DTC_DATA_BUF 0x3900 /* rw 128 bytes long */ 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct override { 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int address; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int irq; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} overrides 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef OVERRIDE 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds[] __initdata = OVERRIDE; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 1391fbe85292f50ce6186619b83ed04d1bb91dda569Alan Cox[4] __initdata = { 1401fbe85292f50ce6186619b83ed04d1bb91dda569Alan Cox { 0, IRQ_AUTO }, { 0, IRQ_AUTO }, { 0, IRQ_AUTO }, { 0, IRQ_AUTO } 1411fbe85292f50ce6186619b83ed04d1bb91dda569Alan Cox}; 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1446391a11375de5e2bb1eb8481e54619761dc65d9fTobias Klauser#define NO_OVERRIDES ARRAY_SIZE(overrides) 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct base { 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long address; 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int noauto; 1496391a11375de5e2bb1eb8481e54619761dc65d9fTobias Klauser} bases[] __initdata = { 1506391a11375de5e2bb1eb8481e54619761dc65d9fTobias Klauser { 0xcc000, 0 }, 1516391a11375de5e2bb1eb8481e54619761dc65d9fTobias Klauser { 0xc8000, 0 }, 1526391a11375de5e2bb1eb8481e54619761dc65d9fTobias Klauser { 0xdc000, 0 }, 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0xd8000, 0 } 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1566391a11375de5e2bb1eb8481e54619761dc65d9fTobias Klauser#define NO_BASES ARRAY_SIZE(bases) 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const struct signature { 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *string; 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int offset; 1616391a11375de5e2bb1eb8481e54619761dc65d9fTobias Klauser} signatures[] = { 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {"DATA TECHNOLOGY CORPORATION BIOS", 0x25}, 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1656391a11375de5e2bb1eb8481e54619761dc65d9fTobias Klauser#define NO_SIGNATURES ARRAY_SIZE(signatures) 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef MODULE 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function : dtc_setup(char *str, int *ints) 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Purpose : LILO command line initialization of the overrides array, 1726391a11375de5e2bb1eb8481e54619761dc65d9fTobias Klauser * 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inputs : str - unused, ints - array of integer parameters with ints[0] 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * equal to the number of ints. 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1761fbe85292f50ce6186619b83ed04d1bb91dda569Alan Cox */ 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __init dtc_setup(char *str, int *ints) 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static int commandline_current = 0; 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ints[0] != 2) 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("dtc_setup: usage dtc=address,irq\n"); 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (commandline_current < NO_OVERRIDES) { 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds overrides[commandline_current].address = ints[1]; 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds overrides[commandline_current].irq = ints[2]; 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < NO_BASES; ++i) 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bases[i].address == ints[1]) { 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bases[i].noauto = 1; 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++commandline_current; 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 198d0be4a7d29ad0bd3ce2209dd9e46d410b632db59Christoph Hellwig * Function : int dtc_detect(struct scsi_host_template * tpnt) 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Purpose : detects and initializes DTC 3180/3280 controllers 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that were autoprobed, overridden on the LILO command line, 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * or specified at compile time. 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inputs : tpnt - template for this SCSI adapter. 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns : 1 if a host adapter was found, 0 if not. 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 210d0be4a7d29ad0bd3ce2209dd9e46d410b632db59Christoph Hellwigstatic int __init dtc_detect(struct scsi_host_template * tpnt) 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static int current_override = 0, current_base = 0; 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Scsi_Host *instance; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int addr; 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *base; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int sig, count; 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tpnt->proc_name = "dtc3x80"; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tpnt->proc_info = &dtc_proc_info; 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (count = 0; current_override < NO_OVERRIDES; ++current_override) { 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr = 0; 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds base = NULL; 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (overrides[current_override].address) { 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr = overrides[current_override].address; 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds base = ioremap(addr, 0x2000); 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!base) 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr = 0; 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (; !addr && (current_base < NO_BASES); ++current_base) { 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if (DTCDEBUG & DTCDEBUG_INIT) 2331fbe85292f50ce6186619b83ed04d1bb91dda569Alan Cox printk(KERN_DEBUG "scsi-dtc : probing address %08x\n", bases[current_base].address); 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (bases[current_base].noauto) 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds base = ioremap(bases[current_base].address, 0x2000); 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!base) 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (sig = 0; sig < NO_SIGNATURES; ++sig) { 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) { 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr = bases[current_base].address; 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if (DTCDEBUG & DTCDEBUG_INIT) 2445307b1e8b050f309901acc9c6121061206a70ba5Alan Cox printk(KERN_DEBUG "scsi-dtc : detected board.\n"); 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto found; 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iounmap(base); 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT) 2531fbe85292f50ce6186619b83ed04d1bb91dda569Alan Cox printk(KERN_DEBUG "scsi-dtc : base = %08x\n", addr); 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!addr) 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsfound: 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata)); 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (instance == NULL) 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance->base = addr; 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((struct NCR5380_hostdata *)(instance)->hostdata)->base = base; 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_init(instance, 0); 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR); /* Enable int's */ 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (overrides[current_override].irq != IRQ_AUTO) 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance->irq = overrides[current_override].irq; 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance->irq = NCR5380_probe_irq(instance, DTC_IRQS); 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef DONT_USE_INTR 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* With interrupts enabled, it will sometimes hang when doing heavy 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * reads. So better not enable them until I finger it out. */ 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (instance->irq != SCSI_IRQ_NONE) 2791e641664301744f0d381de43ae1e12343e60b479Jeff Garzik if (request_irq(instance->irq, dtc_intr, IRQF_DISABLED, 2801e641664301744f0d381de43ae1e12343e60b479Jeff Garzik "dtc", instance)) { 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance->irq = SCSI_IRQ_NONE; 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (instance->irq == SCSI_IRQ_NONE) { 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no); 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no); 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (instance->irq != SCSI_IRQ_NONE) 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no); 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds instance->irq = SCSI_IRQ_NONE; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT) 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("scsi%d : irq = %d\n", instance->host_no, instance->irq); 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "scsi%d : at 0x%05X", instance->host_no, (int) instance->base); 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (instance->irq == SCSI_IRQ_NONE) 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" interrupts disabled"); 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" irq %d", instance->irq); 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", CAN_QUEUE, CMD_PER_LUN, DTC_PUBLIC_RELEASE); 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_print_options(instance); 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("\n"); 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++current_override; 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++count; 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function : int dtc_biosparam(Disk * disk, struct block_device *dev, int *ip) 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the specified device / size. 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inputs : size = size of device in sectors (512 bytes), dev = block device 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * major / minor, ip[] = {heads, sectors, cylinders} 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns : always 0 (success), initializes ip 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * XXX Most SCSI boards use this mapping, I could be incorrect. Some one 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * using hard disks on a trantor should verify that this mapping corresponds 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to that used by the BIOS / ASPI driver by running the linux fdisk program 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and matching the H_C_S coordinates to what DOS uses. 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dtc_biosparam(struct scsi_device *sdev, struct block_device *dev, 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sector_t capacity, int *ip) 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int size = capacity; 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ip[0] = 64; 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ip[1] = 32; 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ip[2] = size >> 11; 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**************************************************************** 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function : int NCR5380_pread (struct Scsi_Host *instance, 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * unsigned char *dst, int len) 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Purpose : Fast 5380 pseudo-dma read function, reads len bytes to 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * dst 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inputs : dst = destination, len = length in bytes 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns : 0 on success, non zero on a failure such as a watchdog 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * timeout. 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dtc_maxi = 0; 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dtc_wmaxi = 0; 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len) 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *d = dst; 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; /* For counting time spent in the poll-loop */ 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_local_declare(); 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_setup(instance); 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = 0; 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_read(RESET_PARITY_INTERRUPT_REG); 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE); 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (instance->irq == SCSI_IRQ_NONE) 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ); 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ | CSR_INT_BASE); 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_write(DTC_BLK_CNT, len >> 7); /* Block count */ 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rtrc(1); 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (len > 0) { 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rtrc(2); 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY) 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++i; 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rtrc(3); 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy_fromio(d, base + DTC_DATA_BUF, 128); 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds d += 128; 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len -= 128; 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rtrc(7); 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /*** with int's on, it sometimes hangs after here. 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Looks like something makes HBNR go away. */ 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rtrc(4); 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS)) 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++i; 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_write(MODE_REG, 0); /* Clear the operating mode */ 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rtrc(0); 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_read(RESET_PARITY_INTERRUPT_REG); 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i > dtc_maxi) 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dtc_maxi = i; 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**************************************************************** 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function : int NCR5380_pwrite (struct Scsi_Host *instance, 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * unsigned char *src, int len) 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * src 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inputs : src = source, len = length in bytes 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns : 0 on success, non zero on a failure such as a watchdog 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * timeout. 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len) 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_local_declare(); 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_setup(instance); 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_read(RESET_PARITY_INTERRUPT_REG); 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE); 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* set direction (write) */ 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (instance->irq == SCSI_IRQ_NONE) 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_write(DTC_CONTROL_REG, 0); 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR); 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_write(DTC_BLK_CNT, len >> 7); /* Block count */ 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; len > 0; ++i) { 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rtrc(5); 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Poll until the host buffer can accept data. */ 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY) 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++i; 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rtrc(3); 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy_toio(base + DTC_DATA_BUF, src, 128); 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds src += 128; 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len -= 128; 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rtrc(4); 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS)) 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++i; 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rtrc(6); 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Wait until the last byte has been sent to the disk */ 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT)) 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++i; 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rtrc(7); 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check for parity error here. fixme. */ 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_write(MODE_REG, 0); /* Clear the operating mode */ 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rtrc(0); 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i > dtc_wmaxi) 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dtc_wmaxi = i; 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "NCR5380.c" 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int dtc_release(struct Scsi_Host *shost) 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_local_declare(); 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_setup(shost); 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (shost->irq) 4621e641664301744f0d381de43ae1e12343e60b479Jeff Garzik free_irq(shost->irq, shost); 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCR5380_exit(shost); 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (shost->io_port && shost->n_io_port) 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_region(shost->io_port, shost->n_io_port); 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds scsi_unregister(shost); 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iounmap(base); 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 471d0be4a7d29ad0bd3ce2209dd9e46d410b632db59Christoph Hellwigstatic struct scsi_host_template driver_template = { 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "DTC 3180/3280 ", 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .detect = dtc_detect, 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = dtc_release, 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .queuecommand = dtc_queue_command, 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .eh_abort_handler = dtc_abort, 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .eh_bus_reset_handler = dtc_bus_reset, 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .bios_param = dtc_biosparam, 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .can_queue = CAN_QUEUE, 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .this_id = 7, 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .sg_tablesize = SG_ALL, 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .cmd_per_lun = CMD_PER_LUN, 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .use_clustering = DISABLE_CLUSTERING, 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "scsi_module.c" 486