5 #define UNSAFE                  /* Leave interrupts enabled during pseudo-dma I/O */
 
   6 #define xNDEBUG (NDEBUG_INTR+NDEBUG_RESELECTION+\
 
   7                  NDEBUG_SELECTION+NDEBUG_ARBITRATION)
 
   8 #define DMA_WORKS_RIGHT
 
  12  * DTC 3180/3280 driver, by
 
  13  *      Ray Van Tassle  rayvt@comm.mot.com
 
  16  *      Trantor T128/T128F/T228 driver by...
 
  20  *      (Unix and Linux consulting and custom programming)
 
  24  * DISTRIBUTION RELEASE 1.
 
  26  * For more information, please consult 
 
  29  * SCSI Protocol Controller
 
  35  * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
 
  36  *      for commands that return with a CHECK CONDITION status. 
 
  38  * PSEUDO_DMA - enables PSEUDO-DMA hardware, should give a 3-4X performance
 
  39  * increase compared to polled I/O.
 
  41  * PARITY - enable parity checking.  Not supported.
 
  43  * UNSAFE - leave interrupts enabled during pseudo-DMA transfers. 
 
  44  *              You probably want this.
 
  46  * The card is detected and initialized in one of several ways : 
 
  47  * 1.  Autoprobe (default) - since the board is memory mapped, 
 
  48  *     a BIOS signature is scanned for to locate the registers.
 
  49  *     An interrupt is triggered to autoprobe for the interrupt
 
  52  * 2.  With command line overrides - dtc=address,irq may be 
 
  53  *     used on the LILO command line to override the defaults.
 
  57 /*----------------------------------------------------------------*/
 
  58 /* the following will set the monitor border color (useful to find
 
  59  where something crashed or gets stuck at */
 
  69 #define rtrc(i) {inb(0x3da); outb(0x31, 0x3c0); outb((i), 0x3c0);}
 
  75 #include <asm/system.h>
 
  76 #include <linux/module.h>
 
  77 #include <linux/signal.h>
 
  78 #include <linux/blkdev.h>
 
  79 #include <linux/delay.h>
 
  80 #include <linux/stat.h>
 
  81 #include <linux/string.h>
 
  82 #include <linux/init.h>
 
  83 #include <linux/interrupt.h>
 
  86 #include <scsi/scsi_host.h>
 
  92 #define DTC_PUBLIC_RELEASE 2
 
  95  * The DTC3180 & 3280 boards are memory mapped.
 
 101 /* Offset from DTC_5380_OFFSET */
 
 102 #define DTC_CONTROL_REG         0x100   /* rw */
 
 103 #define D_CR_ACCESS             0x80    /* ro set=can access 3280 registers */
 
 104 #define CSR_DIR_READ            0x40    /* rw direction, 1 = read 0 = write */
 
 106 #define CSR_RESET              0x80     /* wo  Resets 53c400 */
 
 107 #define CSR_5380_REG           0x80     /* ro  5380 registers can be accessed */
 
 108 #define CSR_TRANS_DIR          0x40     /* rw  Data transfer direction */
 
 109 #define CSR_SCSI_BUFF_INTR     0x20     /* rw  Enable int on transfer ready */
 
 110 #define CSR_5380_INTR          0x10     /* rw  Enable 5380 interrupts */
 
 111 #define CSR_SHARED_INTR        0x08     /* rw  Interrupt sharing */
 
 112 #define CSR_HOST_BUF_NOT_RDY   0x04     /* ro  Host buffer not ready */
 
 113 #define CSR_SCSI_BUF_RDY       0x02     /* ro  SCSI buffer ready */
 
 114 #define CSR_GATED_5380_IRQ     0x01     /* ro  Last block xferred */
 
 115 #define CSR_INT_BASE (CSR_SCSI_BUFF_INTR | CSR_5380_INTR)
 
 118 #define DTC_BLK_CNT             0x101   /* rw 
 
 119                                          * # of 128-byte blocks to transfer */
 
 122 #define D_CR_ACCESS             0x80    /* ro set=can access 3280 registers */
 
 124 #define DTC_SWITCH_REG          0x3982  /* ro - DIP switches */
 
 125 #define DTC_RESUME_XFER         0x3982  /* wo - resume data xfer 
 
 126                                          * after disconnect/reconnect*/
 
 128 #define DTC_5380_OFFSET         0x3880  /* 8 registers here, see NCR5380.h */
 
 130 /*!!!! for dtc, it's a 128 byte buffer at 3900 !!! */
 
 131 #define DTC_DATA_BUF            0x3900  /* rw 128 bytes long */
 
 133 static struct override {
 
 134         unsigned int address;
 
 138 [] __initdata = OVERRIDE;
 
 141         { 0, IRQ_AUTO }, { 0, IRQ_AUTO }, { 0, IRQ_AUTO }, { 0, IRQ_AUTO }
 
 145 #define NO_OVERRIDES ARRAY_SIZE(overrides)
 
 148         unsigned long address;
 
 150 } bases[] __initdata = {
 
 157 #define NO_BASES ARRAY_SIZE(bases)
 
 159 static const struct signature {
 
 163         {"DATA TECHNOLOGY CORPORATION BIOS", 0x25},
 
 166 #define NO_SIGNATURES ARRAY_SIZE(signatures)
 
 170  * Function : dtc_setup(char *str, int *ints)
 
 172  * Purpose : LILO command line initialization of the overrides array,
 
 174  * Inputs : str - unused, ints - array of integer parameters with ints[0]
 
 175  *      equal to the number of ints.
 
 179 static void __init dtc_setup(char *str, int *ints)
 
 181         static int commandline_current = 0;
 
 184                 printk("dtc_setup: usage dtc=address,irq\n");
 
 185         else if (commandline_current < NO_OVERRIDES) {
 
 186                 overrides[commandline_current].address = ints[1];
 
 187                 overrides[commandline_current].irq = ints[2];
 
 188                 for (i = 0; i < NO_BASES; ++i)
 
 189                         if (bases[i].address == ints[1]) {
 
 193                 ++commandline_current;
 
 199  * Function : int dtc_detect(struct scsi_host_template * tpnt)
 
 201  * Purpose : detects and initializes DTC 3180/3280 controllers
 
 202  *      that were autoprobed, overridden on the LILO command line, 
 
 203  *      or specified at compile time.
 
 205  * Inputs : tpnt - template for this SCSI adapter.
 
 207  * Returns : 1 if a host adapter was found, 0 if not.
 
 211 static int __init dtc_detect(struct scsi_host_template * tpnt)
 
 213         static int current_override = 0, current_base = 0;
 
 214         struct Scsi_Host *instance;
 
 219         tpnt->proc_name = "dtc3x80";
 
 220         tpnt->proc_info = &dtc_proc_info;
 
 222         for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
 
 226                 if (overrides[current_override].address) {
 
 227                         addr = overrides[current_override].address;
 
 228                         base = ioremap(addr, 0x2000);
 
 232                         for (; !addr && (current_base < NO_BASES); ++current_base) {
 
 233 #if (DTCDEBUG & DTCDEBUG_INIT)
 
 234                                 printk(KERN_DEBUG "scsi-dtc : probing address %08x\n", bases[current_base].address);
 
 236                                 if (bases[current_base].noauto)
 
 238                                 base = ioremap(bases[current_base].address, 0x2000);
 
 241                                 for (sig = 0; sig < NO_SIGNATURES; ++sig) {
 
 242                                         if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) {
 
 243                                                 addr = bases[current_base].address;
 
 244 #if (DTCDEBUG & DTCDEBUG_INIT)
 
 245                                                 printk(KERN_DEBUG "scsi-dtc : detected board.\n");
 
 253 #if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
 
 254                 printk(KERN_DEBUG "scsi-dtc : base = %08x\n", addr);
 
 261                 instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
 
 262                 if (instance == NULL)
 
 265                 instance->base = addr;
 
 266                 ((struct NCR5380_hostdata *)(instance)->hostdata)->base = base;
 
 268                 NCR5380_init(instance, 0);
 
 270                 NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR);  /* Enable int's */
 
 271                 if (overrides[current_override].irq != IRQ_AUTO)
 
 272                         instance->irq = overrides[current_override].irq;
 
 274                         instance->irq = NCR5380_probe_irq(instance, DTC_IRQS);
 
 276 #ifndef DONT_USE_INTR
 
 277                 /* With interrupts enabled, it will sometimes hang when doing heavy
 
 278                  * reads. So better not enable them until I finger it out. */
 
 279                 if (instance->irq != SCSI_IRQ_NONE)
 
 280                         if (request_irq(instance->irq, dtc_intr, IRQF_DISABLED,
 
 282                                 printk(KERN_ERR "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
 
 283                                 instance->irq = SCSI_IRQ_NONE;
 
 286                 if (instance->irq == SCSI_IRQ_NONE) {
 
 287                         printk(KERN_WARNING "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
 
 288                         printk(KERN_WARNING "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
 
 291                 if (instance->irq != SCSI_IRQ_NONE)
 
 292                         printk(KERN_WARNING "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no);
 
 293                 instance->irq = SCSI_IRQ_NONE;
 
 295 #if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
 
 296                 printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
 
 299                 printk(KERN_INFO "scsi%d : at 0x%05X", instance->host_no, (int) instance->base);
 
 300                 if (instance->irq == SCSI_IRQ_NONE)
 
 301                         printk(" interrupts disabled");
 
 303                         printk(" irq %d", instance->irq);
 
 304                 printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d", CAN_QUEUE, CMD_PER_LUN, DTC_PUBLIC_RELEASE);
 
 305                 NCR5380_print_options(instance);
 
 315  * Function : int dtc_biosparam(Disk * disk, struct block_device *dev, int *ip)
 
 317  * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for 
 
 318  *      the specified device / size.
 
 320  * Inputs : size = size of device in sectors (512 bytes), dev = block device
 
 321  *      major / minor, ip[] = {heads, sectors, cylinders}  
 
 323  * Returns : always 0 (success), initializes ip
 
 328  * XXX Most SCSI boards use this mapping, I could be incorrect.  Some one
 
 329  * using hard disks on a trantor should verify that this mapping corresponds
 
 330  * to that used by the BIOS / ASPI driver by running the linux fdisk program
 
 331  * and matching the H_C_S coordinates to what DOS uses.
 
 334 static int dtc_biosparam(struct scsi_device *sdev, struct block_device *dev,
 
 335                          sector_t capacity, int *ip)
 
 346 /****************************************************************
 
 347  * Function : int NCR5380_pread (struct Scsi_Host *instance, 
 
 348  *      unsigned char *dst, int len)
 
 350  * Purpose : Fast 5380 pseudo-dma read function, reads len bytes to 
 
 353  * Inputs : dst = destination, len = length in bytes
 
 355  * Returns : 0 on success, non zero on a failure such as a watchdog 
 
 359 static int dtc_maxi = 0;
 
 360 static int dtc_wmaxi = 0;
 
 362 static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
 
 364         unsigned char *d = dst;
 
 365         int i;                  /* For counting time spent in the poll-loop */
 
 366         NCR5380_local_declare();
 
 367         NCR5380_setup(instance);
 
 370         NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
 371         NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
 
 372         if (instance->irq == SCSI_IRQ_NONE)
 
 373                 NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ);
 
 375                 NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ | CSR_INT_BASE);
 
 376         NCR5380_write(DTC_BLK_CNT, len >> 7);   /* Block count */
 
 380                 while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
 
 383                 memcpy_fromio(d, base + DTC_DATA_BUF, 128);
 
 387                 /*** with int's on, it sometimes hangs after here.
 
 388                  * Looks like something makes HBNR go away. */
 
 391         while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
 
 393         NCR5380_write(MODE_REG, 0);     /* Clear the operating mode */
 
 395         NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
 401 /****************************************************************
 
 402  * Function : int NCR5380_pwrite (struct Scsi_Host *instance, 
 
 403  *      unsigned char *src, int len)
 
 405  * Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from
 
 408  * Inputs : src = source, len = length in bytes
 
 410  * Returns : 0 on success, non zero on a failure such as a watchdog 
 
 414 static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
 
 417         NCR5380_local_declare();
 
 418         NCR5380_setup(instance);
 
 420         NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
 421         NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
 
 422         /* set direction (write) */
 
 423         if (instance->irq == SCSI_IRQ_NONE)
 
 424                 NCR5380_write(DTC_CONTROL_REG, 0);
 
 426                 NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR);
 
 427         NCR5380_write(DTC_BLK_CNT, len >> 7);   /* Block count */
 
 428         for (i = 0; len > 0; ++i) {
 
 430                 /* Poll until the host buffer can accept data. */
 
 431                 while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
 
 434                 memcpy_toio(base + DTC_DATA_BUF, src, 128);
 
 439         while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
 
 442         /* Wait until the last byte has been sent to the disk */
 
 443         while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
 
 446         /* Check for parity error here. fixme. */
 
 447         NCR5380_write(MODE_REG, 0);     /* Clear the operating mode */
 
 454 MODULE_LICENSE("GPL");
 
 458 static int dtc_release(struct Scsi_Host *shost)
 
 460         NCR5380_local_declare();
 
 461         NCR5380_setup(shost);
 
 463                 free_irq(shost->irq, shost);
 
 465         if (shost->io_port && shost->n_io_port)
 
 466                 release_region(shost->io_port, shost->n_io_port);
 
 467         scsi_unregister(shost);
 
 472 static struct scsi_host_template driver_template = {
 
 473         .name                           = "DTC 3180/3280 ",
 
 474         .detect                         = dtc_detect,
 
 475         .release                        = dtc_release,
 
 476         .queuecommand                   = dtc_queue_command,
 
 477         .eh_abort_handler               = dtc_abort,
 
 478         .eh_bus_reset_handler           = dtc_bus_reset,
 
 479         .bios_param                     = dtc_biosparam,
 
 480         .can_queue                      = CAN_QUEUE,
 
 482         .sg_tablesize                   = SG_ALL,
 
 483         .cmd_per_lun                    = CMD_PER_LUN,
 
 484         .use_clustering                 = DISABLE_CLUSTERING,
 
 486 #include "scsi_module.c"