1 /* fd_mcs.c -- Future Domain MCS 600/700 (or IBM OEM) driver
 
   3  * FutureDomain MCS-600/700 v0.2 03/11/1998 by ZP Gu (zpg@castle.net)
 
   5  * This driver is cloned from fdomain.* to specifically support
 
   6  * the Future Domain MCS 600/700 MCA SCSI adapters. Some PS/2s
 
   7  * also equipped with IBM Fast SCSI Adapter/A which is an OEM
 
  10  * This driver also supports Reply SB16/SCSI card (the SCSI part).
 
  12  * What makes this driver different is that this driver is MCA only
 
  13  * and it supports multiple adapters in the same system, IRQ 
 
  14  * sharing, some driver statistics, and maps highest SCSI id to sda.
 
  15  * All cards are auto-detected.
 
  17  * Assumptions: TMC-1800/18C50/18C30, BIOS >= 3.4
 
  19  * LILO command-line options:
 
  20  *   fd_mcs=<FIFO_COUNT>[,<FIFO_SIZE>]
 
  22  * ********************************************************
 
  23  * Please see Copyrights/Comments in fdomain.* for credits.
 
  24  * Following is from fdomain.c for acknowledgement:
 
  26  * Created: Sun May  3 18:53:19 1992 by faith@cs.unc.edu
 
  27  * Revised: Wed Oct  2 11:10:55 1996 by r.faith@ieee.org
 
  28  * Author: Rickard E. Faith, faith@cs.unc.edu
 
  29  * Copyright 1992, 1993, 1994, 1995, 1996 Rickard E. Faith
 
  31  * $Id: fdomain.c,v 5.45 1996/10/02 15:13:06 root Exp $
 
  33  * This program is free software; you can redistribute it and/or modify it
 
  34  * under the terms of the GNU General Public License as published by the
 
  35  * Free Software Foundation; either version 2, or (at your option) any
 
  38  * This program is distributed in the hope that it will be useful, but
 
  39  * WITHOUT ANY WARRANTY; without even the implied warranty of
 
  40  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
  41  * General Public License for more details.
 
  43  * You should have received a copy of the GNU General Public License along
 
  44  * with this program; if not, write to the Free Software Foundation, Inc.,
 
  45  * 675 Mass Ave, Cambridge, MA 02139, USA.
 
  47  **************************************************************************
 
  49  NOTES ON USER DEFINABLE OPTIONS:
 
  51  DEBUG: This turns on the printing of various debug information.
 
  53  ENABLE_PARITY: This turns on SCSI parity checking.  With the current
 
  54  driver, all attached devices must support SCSI parity.  If none of your
 
  55  devices support parity, then you can probably get the driver to work by
 
  56  turning this option off.  I have no way of testing this, however, and it
 
  57  would appear that no one ever uses this option.
 
  59  FIFO_COUNT: The host adapter has an 8K cache (host adapters based on the
 
  60  18C30 chip have a 2k cache).  When this many 512 byte blocks are filled by
 
  61  the SCSI device, an interrupt will be raised.  Therefore, this could be as
 
  62  low as 0, or as high as 16.  Note, however, that values which are too high
 
  63  or too low seem to prevent any interrupts from occurring, and thereby lock
 
  64  up the machine.  I have found that 2 is a good number, but throughput may
 
  65  be increased by changing this value to values which are close to 2.
 
  66  Please let me know if you try any different values.
 
  67  [*****Now a runtime option*****]
 
  69  RESELECTION: This is no longer an option, since I gave up trying to
 
  70  implement it in version 4.x of this driver.  It did not improve
 
  71  performance at all and made the driver unstable (because I never found one
 
  72  of the two race conditions which were introduced by the multiple
 
  73  outstanding command code).  The instability seems a very high price to pay
 
  74  just so that you don't have to wait for the tape to rewind.  If you want
 
  75  this feature implemented, send me patches.  I'll be happy to send a copy
 
  76  of my (broken) driver to anyone who would like to see a copy.
 
  78  **************************************************************************/
 
  80 #include <linux/module.h>
 
  81 #include <linux/init.h>
 
  82 #include <linux/interrupt.h>
 
  83 #include <linux/blkdev.h>
 
  84 #include <linux/errno.h>
 
  85 #include <linux/string.h>
 
  86 #include <linux/ioport.h>
 
  87 #include <linux/proc_fs.h>
 
  88 #include <linux/delay.h>
 
  89 #include <linux/mca.h>
 
  90 #include <linux/spinlock.h>
 
  91 #include <scsi/scsicam.h>
 
  92 #include <linux/mca-legacy.h>
 
  95 #include <asm/system.h>
 
  98 #include <scsi/scsi_host.h>
 
 100 #define DRIVER_VERSION "v0.2 by ZP Gu<zpg@castle.net>"
 
 102 /* START OF USER DEFINABLE OPTIONS */
 
 104 #define DEBUG            0      /* Enable debugging output */
 
 105 #define ENABLE_PARITY    1      /* Enable SCSI Parity */
 
 107 /* END OF USER DEFINABLE OPTIONS */
 
 110 #define EVERY_ACCESS     0      /* Write a line on every scsi access */
 
 111 #define ERRORS_ONLY      1      /* Only write a line if there is an error */
 
 112 #define DEBUG_MESSAGES   1      /* Debug MESSAGE IN phase */
 
 113 #define DEBUG_ABORT      1      /* Debug abort() routine */
 
 114 #define DEBUG_RESET      1      /* Debug reset() routine */
 
 115 #define DEBUG_RACE       1      /* Debug interrupt-driven race condition */
 
 117 #define EVERY_ACCESS     0      /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
 
 118 #define ERRORS_ONLY      0
 
 119 #define DEBUG_MESSAGES   0
 
 120 #define DEBUG_ABORT      0
 
 121 #define DEBUG_RESET      0
 
 125 /* Errors are reported on the line, so we don't need to report them again */
 
 128 #define ERRORS_ONLY      0
 
 132 #define PARITY_MASK      0x08
 
 134 #define PARITY_MASK      0x00
 
 145         in_arbitration = 0x02,
 
 157         FIFO_Status = 3,        /* tmc18c50/tmc18c30 only */
 
 158         Interrupt_Cond = 4,     /* tmc18c50/tmc18c30 only */
 
 163         Interrupt_Status = 9,
 
 165         Configuration2 = 11,    /* tmc18c50/tmc18c30 only */
 
 176         Memory_Cntl = 5,        /* tmc18c50/tmc18c30 only */
 
 178         IO_Control = 11,        /* tmc18c30 only */
 
 183         unsigned long _bios_base;
 
 186         volatile int _in_command;
 
 187         Scsi_Cmnd *_current_SC;
 
 188         enum chip_type _chip;
 
 190         int _fifo_count;        /* Number of 512 byte blocks before INTR */
 
 192         char _adapter_name[64];
 
 194         volatile int _in_interrupt_flag;
 
 197         int _SCSI_Mode_Cntl_port;
 
 198         int _FIFO_Data_Count_port;
 
 199         int _Interrupt_Cntl_port;
 
 200         int _Interrupt_Status_port;
 
 201         int _Interrupt_Cond_port;
 
 203         int _Read_SCSI_Data_port;
 
 205         int _SCSI_Data_NoACK_port;
 
 206         int _SCSI_Status_port;
 
 208         int _TMC_Status_port;
 
 209         int _Write_FIFO_port;
 
 210         int _Write_SCSI_Data_port;
 
 212         int _FIFO_Size;         /* = 0x2000;  8k FIFO for
 
 213                                    pre-tmc18c30 chips */
 
 220 #define FD_MAX_HOSTS 3          /* enough? */
 
 222 #define HOSTDATA(shpnt) ((struct fd_hostdata *) shpnt->hostdata)
 
 223 #define bios_base             (HOSTDATA(shpnt)->_bios_base)
 
 224 #define bios_major            (HOSTDATA(shpnt)->_bios_major)
 
 225 #define bios_minor            (HOSTDATA(shpnt)->_bios_minor)
 
 226 #define in_command            (HOSTDATA(shpnt)->_in_command)
 
 227 #define current_SC            (HOSTDATA(shpnt)->_current_SC)
 
 228 #define chip                  (HOSTDATA(shpnt)->_chip)
 
 229 #define adapter_mask          (HOSTDATA(shpnt)->_adapter_mask)
 
 230 #define FIFO_COUNT            (HOSTDATA(shpnt)->_fifo_count)
 
 231 #define adapter_name          (HOSTDATA(shpnt)->_adapter_name)
 
 233 #define in_interrupt_flag     (HOSTDATA(shpnt)->_in_interrupt_flag)
 
 235 #define SCSI_Mode_Cntl_port   (HOSTDATA(shpnt)->_SCSI_Mode_Cntl_port)
 
 236 #define FIFO_Data_Count_port  (HOSTDATA(shpnt)->_FIFO_Data_Count_port)
 
 237 #define Interrupt_Cntl_port   (HOSTDATA(shpnt)->_Interrupt_Cntl_port)
 
 238 #define Interrupt_Status_port (HOSTDATA(shpnt)->_Interrupt_Status_port)
 
 239 #define Interrupt_Cond_port   (HOSTDATA(shpnt)->_Interrupt_Cond_port)
 
 240 #define Read_FIFO_port        (HOSTDATA(shpnt)->_Read_FIFO_port)
 
 241 #define Read_SCSI_Data_port   (HOSTDATA(shpnt)->_Read_SCSI_Data_port)
 
 242 #define SCSI_Cntl_port        (HOSTDATA(shpnt)->_SCSI_Cntl_port)
 
 243 #define SCSI_Data_NoACK_port  (HOSTDATA(shpnt)->_SCSI_Data_NoACK_port)
 
 244 #define SCSI_Status_port      (HOSTDATA(shpnt)->_SCSI_Status_port)
 
 245 #define TMC_Cntl_port         (HOSTDATA(shpnt)->_TMC_Cntl_port)
 
 246 #define TMC_Status_port       (HOSTDATA(shpnt)->_TMC_Status_port)
 
 247 #define Write_FIFO_port       (HOSTDATA(shpnt)->_Write_FIFO_port)
 
 248 #define Write_SCSI_Data_port  (HOSTDATA(shpnt)->_Write_SCSI_Data_port)
 
 249 #define FIFO_Size             (HOSTDATA(shpnt)->_FIFO_Size)
 
 250 #define Bytes_Read            (HOSTDATA(shpnt)->_Bytes_Read)
 
 251 #define Bytes_Written         (HOSTDATA(shpnt)->_Bytes_Written)
 
 252 #define INTR_Processed        (HOSTDATA(shpnt)->_INTR_Processed)
 
 254 struct fd_mcs_adapters_struct {
 
 257         enum chip_type fd_chip;
 
 262 #define REPLY_ID 0x5137
 
 264 static struct fd_mcs_adapters_struct fd_mcs_adapters[] = {
 
 265         {"Future Domain SCSI Adapter MCS-700(18C50)",
 
 270         {"Future Domain SCSI Adapter MCS-600/700(TMC-1800)",
 
 275         {"Reply Sound Blaster/SCSI Adapter",
 
 282 #define FD_BRDS ARRAY_SIZE(fd_mcs_adapters)
 
 284 static irqreturn_t fd_mcs_intr(int irq, void *dev_id);
 
 286 static unsigned long addresses[] = { 0xc8000, 0xca000, 0xce000, 0xde000 };
 
 287 static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
 
 288 static unsigned short interrupts[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
 
 290 /* host information */
 
 291 static int found = 0;
 
 292 static struct Scsi_Host *hosts[FD_MAX_HOSTS + 1] = { NULL };
 
 294 static int user_fifo_count = 0;
 
 295 static int user_fifo_size = 0;
 
 298 static int __init fd_mcs_setup(char *str)
 
 300         static int done_setup = 0;
 
 303         get_options(str, 3, ints);
 
 304         if (done_setup++ || ints[0] < 1 || ints[0] > 2 || ints[1] < 1 || ints[1] > 16) {
 
 305                 printk("fd_mcs: usage: fd_mcs=FIFO_COUNT, FIFO_SIZE\n");
 
 309         user_fifo_count = ints[0] >= 1 ? ints[1] : 0;
 
 310         user_fifo_size = ints[0] >= 2 ? ints[2] : 0;
 
 314 __setup("fd_mcs=", fd_mcs_setup);
 
 317 static void print_banner(struct Scsi_Host *shpnt)
 
 319         printk("scsi%d <fd_mcs>: ", shpnt->host_no);
 
 322                 printk("BIOS at 0x%lX", bios_base);
 
 327         printk(", HostID %d, %s Chip, IRQ %d, IO 0x%lX\n", shpnt->this_id, chip == tmc18c50 ? "TMC-18C50" : (chip == tmc18c30 ? "TMC-18C30" : (chip == tmc1800 ? "TMC-1800" : "Unknown")), shpnt->irq, shpnt->io_port);
 
 331 static void do_pause(unsigned amount)
 
 332 {                               /* Pause for amount*10 milliseconds */
 
 338 static void fd_mcs_make_bus_idle(struct Scsi_Host *shpnt)
 
 340         outb(0, SCSI_Cntl_port);
 
 341         outb(0, SCSI_Mode_Cntl_port);
 
 342         if (chip == tmc18c50 || chip == tmc18c30)
 
 343                 outb(0x21 | PARITY_MASK, TMC_Cntl_port);        /* Clear forced intr. */
 
 345                 outb(0x01 | PARITY_MASK, TMC_Cntl_port);
 
 348 static int fd_mcs_detect(struct scsi_host_template * tpnt)
 
 351         struct Scsi_Host *shpnt;
 
 353         /* get id, port, bios, irq */
 
 355         u_char pos2, pos3, pos4;
 
 359         /* if not MCA machine, return */
 
 366         for (loop = 0; loop < FD_BRDS; loop++) {
 
 368                 while (MCA_NOTFOUND != (slot = mca_find_adapter(fd_mcs_adapters[loop].id, slot))) {
 
 370                         /* if we get this far, an adapter has been detected and is
 
 373                         printk(KERN_INFO "scsi  <fd_mcs>: %s at slot %d\n", fd_mcs_adapters[loop].name, slot + 1);
 
 375                         pos2 = mca_read_stored_pos(slot, 2);
 
 376                         pos3 = mca_read_stored_pos(slot, 3);
 
 377                         pos4 = mca_read_stored_pos(slot, 4);
 
 379                         /* ready for next probe */
 
 382                         if (fd_mcs_adapters[loop].id == REPLY_ID) {     /* reply card */
 
 383                                 static int reply_irq[] = { 10, 11, 14, 15 };
 
 385                                 bios = 0;       /* no bios */
 
 388                                         port = ports[pos4 & 0x3];
 
 392                                 /* can't really disable it, same as irq=10 */
 
 393                                 irq = reply_irq[((pos4 >> 2) & 0x1) + 2 * ((pos4 >> 4) & 0x1)];
 
 395                                 bios = addresses[pos2 >> 6];
 
 396                                 port = ports[(pos2 >> 4) & 0x03];
 
 397                                 irq = interrupts[(pos2 >> 1) & 0x07];
 
 402                                 mca_set_adapter_name(slot - 1, fd_mcs_adapters[loop].name);
 
 404                                 /* check irq/region */
 
 405                                 if (request_irq(irq, fd_mcs_intr, IRQF_SHARED, "fd_mcs", hosts)) {
 
 406                                         printk(KERN_ERR "fd_mcs: interrupt is not available, skipping...\n");
 
 410                                 /* request I/O region */
 
 411                                 if (request_region(port, 0x10, "fd_mcs")) {
 
 412                                         printk(KERN_ERR "fd_mcs: I/O region is already in use, skipping...\n");
 
 416                                 if (!(shpnt = scsi_register(tpnt, sizeof(struct fd_hostdata)))) {
 
 417                                         printk(KERN_ERR "fd_mcs: scsi_register() failed\n");
 
 418                                         release_region(port, 0x10);
 
 419                                         free_irq(irq, hosts);
 
 425                                 strcpy(adapter_name, fd_mcs_adapters[loop].name);
 
 428                                 chip = fd_mcs_adapters[loop].fd_chip;
 
 429                                 /* use boot time value if available */
 
 430                                 FIFO_COUNT = user_fifo_count ? user_fifo_count : fd_mcs_adapters[loop].fifo_count;
 
 431                                 FIFO_Size = user_fifo_size ? user_fifo_size : fd_mcs_adapters[loop].fifo_size;
 
 433 /* FIXME: Do we need to keep this bit of code inside NOT_USED around at all? */
 
 435                                 /* *************************************************** */
 
 436                                 /* Try to toggle 32-bit mode.  This only
 
 437                                    works on an 18c30 chip.  (User reports
 
 438                                    say this works, so we should switch to
 
 439                                    it in the near future.) */
 
 440                                 outb(0x80, port + IO_Control);
 
 441                                 if ((inb(port + Configuration2) & 0x80) == 0x80) {
 
 442                                         outb(0x00, port + IO_Control);
 
 443                                         if ((inb(port + Configuration2) & 0x80) == 0x00) {
 
 445                                                 FIFO_Size = 0x800;      /* 2k FIFO */
 
 447                                                 printk("FIRST: chip=%s, fifo_size=0x%x\n", (chip == tmc18c30) ? "tmc18c30" : "tmc18c50", FIFO_Size);
 
 451                                 /* That should have worked, but appears to
 
 452                                    have problems.  Let's assume it is an
 
 453                                    18c30 if the RAM is disabled. */
 
 455                                 if (inb(port + Configuration2) & 0x02) {
 
 457                                         FIFO_Size = 0x800;      /* 2k FIFO */
 
 459                                         printk("SECOND: chip=%s, fifo_size=0x%x\n", (chip == tmc18c30) ? "tmc18c30" : "tmc18c50", FIFO_Size);
 
 461                                 /* *************************************************** */
 
 464                                 /* IBM/ANSI scsi scan ordering */
 
 465                                 /* Stick this back in when the scsi.c changes are there */
 
 466                                 shpnt->reverse_ordering = 1;
 
 470                                 hosts[found++] = shpnt;
 
 474                                 shpnt->io_port = port;
 
 475                                 shpnt->n_io_port = 0x10;
 
 479                                 adapter_mask = (1 << id);
 
 482                                 SCSI_Mode_Cntl_port = port + SCSI_Mode_Cntl;
 
 483                                 FIFO_Data_Count_port = port + FIFO_Data_Count;
 
 484                                 Interrupt_Cntl_port = port + Interrupt_Cntl;
 
 485                                 Interrupt_Status_port = port + Interrupt_Status;
 
 486                                 Interrupt_Cond_port = port + Interrupt_Cond;
 
 487                                 Read_FIFO_port = port + Read_FIFO;
 
 488                                 Read_SCSI_Data_port = port + Read_SCSI_Data;
 
 489                                 SCSI_Cntl_port = port + SCSI_Cntl;
 
 490                                 SCSI_Data_NoACK_port = port + SCSI_Data_NoACK;
 
 491                                 SCSI_Status_port = port + SCSI_Status;
 
 492                                 TMC_Cntl_port = port + TMC_Cntl;
 
 493                                 TMC_Status_port = port + TMC_Status;
 
 494                                 Write_FIFO_port = port + Write_FIFO;
 
 495                                 Write_SCSI_Data_port = port + Write_SCSI_Data;
 
 505                                 outb(1, SCSI_Cntl_port);
 
 507                                 outb(0, SCSI_Cntl_port);
 
 509                                 outb(0, SCSI_Mode_Cntl_port);
 
 510                                 outb(PARITY_MASK, TMC_Cntl_port);
 
 515                 if (found == FD_MAX_HOSTS) {
 
 516                         printk("fd_mcs: detecting reached max=%d host adapters.\n", FD_MAX_HOSTS);
 
 524 static const char *fd_mcs_info(struct Scsi_Host *shpnt)
 
 529 static int TOTAL_INTR = 0;
 
 532  * inout : decides on the direction of the dataflow and the meaning of the 
 
 534  * buffer: If inout==FALSE data is being written to it else read from it
 
 535  * *start: If inout==FALSE start of the valid data in the buffer
 
 536  * offset: If inout==FALSE offset from the beginning of the imaginary file 
 
 537  *         from which we start writing into the buffer
 
 538  * length: If inout==FALSE max number of bytes to be written into the buffer 
 
 539  *         else number of bytes in the buffer
 
 541 static int fd_mcs_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, int inout)
 
 548         *start = buffer + offset;
 
 550         len += sprintf(buffer + len, "Future Domain MCS-600/700 Driver %s\n", DRIVER_VERSION);
 
 551         len += sprintf(buffer + len, "HOST #%d: %s\n", shpnt->host_no, adapter_name);
 
 552         len += sprintf(buffer + len, "FIFO Size=0x%x, FIFO Count=%d\n", FIFO_Size, FIFO_COUNT);
 
 553         len += sprintf(buffer + len, "DriverCalls=%d, Interrupts=%d, BytesRead=%d, BytesWrite=%d\n\n", TOTAL_INTR, INTR_Processed, Bytes_Read, Bytes_Written);
 
 555         if ((len -= offset) <= 0)
 
 562 static int fd_mcs_select(struct Scsi_Host *shpnt, int target)
 
 565         unsigned long timeout;
 
 567         outb(0x82, SCSI_Cntl_port);     /* Bus Enable + Select */
 
 568         outb(adapter_mask | (1 << target), SCSI_Data_NoACK_port);
 
 570         /* Stop arbitration and enable parity */
 
 571         outb(PARITY_MASK, TMC_Cntl_port);
 
 573         timeout = 350;          /* 350mS -- because of timeouts
 
 577                 status = inb(SCSI_Status_port); /* Read adapter status */
 
 578                 if (status & 1) {       /* Busy asserted */
 
 579                         /* Enable SCSI Bus (on error, should make bus idle with 0) */
 
 580                         outb(0x80, SCSI_Cntl_port);
 
 583                 udelay(1000);   /* wait one msec */
 
 587         fd_mcs_make_bus_idle(shpnt);
 
 590                 printk("Selection failed\n");
 
 596                 if (!flag)      /* Skip first failure for all chips. */
 
 599                         printk("fd_mcs: Selection failed\n");
 
 605 static void my_done(struct Scsi_Host *shpnt, int error)
 
 609                 outb(0x00, Interrupt_Cntl_port);
 
 610                 fd_mcs_make_bus_idle(shpnt);
 
 611                 current_SC->result = error;
 
 612                 current_SC->scsi_done(current_SC);
 
 614                 panic("fd_mcs: my_done() called outside of command\n");
 
 617         in_interrupt_flag = 0;
 
 621 /* only my_done needs to be protected  */
 
 622 static irqreturn_t fd_mcs_intr(int irq, void *dev_id)
 
 627         unsigned data_count, tmp_count;
 
 630         struct Scsi_Host *shpnt;
 
 634         /* search for one adapter-response on shared interrupt */
 
 635         while ((shpnt = hosts[i++])) {
 
 636                 if ((inb(TMC_Status_port)) & 1)
 
 640         /* return if some other device on this IRQ caused the interrupt */
 
 647         outb(0x00, Interrupt_Cntl_port);
 
 649         /* Abort calls my_done, so we do nothing here. */
 
 650         if (current_SC->SCp.phase & aborted) {
 
 652                 printk("Interrupt after abort, ignoring\n");
 
 654                 /* return IRQ_HANDLED; */
 
 660         if (current_SC->SCp.phase & in_arbitration) {
 
 661                 status = inb(TMC_Status_port);  /* Read adapter status */
 
 662                 if (!(status & 0x02)) {
 
 666                         spin_lock_irqsave(shpnt->host_lock, flags);
 
 667                         my_done(shpnt, DID_BUS_BUSY << 16);
 
 668                         spin_unlock_irqrestore(shpnt->host_lock, flags);
 
 671                 current_SC->SCp.phase = in_selection;
 
 673                 outb(0x40 | FIFO_COUNT, Interrupt_Cntl_port);
 
 675                 outb(0x82, SCSI_Cntl_port);     /* Bus Enable + Select */
 
 676                 outb(adapter_mask | (1 << scmd_id(current_SC)), SCSI_Data_NoACK_port);
 
 678                 /* Stop arbitration and enable parity */
 
 679                 outb(0x10 | PARITY_MASK, TMC_Cntl_port);
 
 681                 in_interrupt_flag = 0;
 
 684         } else if (current_SC->SCp.phase & in_selection) {
 
 685                 status = inb(SCSI_Status_port);
 
 686                 if (!(status & 0x01)) {
 
 687                         /* Try again, for slow devices */
 
 688                         if (fd_mcs_select(shpnt, scmd_id(current_SC))) {
 
 692                                 spin_lock_irqsave(shpnt->host_lock, flags);
 
 693                                 my_done(shpnt, DID_NO_CONNECT << 16);
 
 694                                 spin_unlock_irqrestore(shpnt->host_lock, flags);
 
 700                                 /* Stop arbitration and enable parity */
 
 701                                 outb(0x10 | PARITY_MASK, TMC_Cntl_port);
 
 704                 current_SC->SCp.phase = in_other;
 
 705                 outb(0x90 | FIFO_COUNT, Interrupt_Cntl_port);
 
 706                 outb(0x80, SCSI_Cntl_port);
 
 708                 in_interrupt_flag = 0;
 
 713         /* current_SC->SCp.phase == in_other: this is the body of the routine */
 
 715         status = inb(SCSI_Status_port);
 
 717         if (status & 0x10) {    /* REQ */
 
 719                 switch (status & 0x0e) {
 
 721                 case 0x08:      /* COMMAND OUT */
 
 722                         outb(current_SC->cmnd[current_SC->SCp.sent_command++], Write_SCSI_Data_port);
 
 724                         printk("CMD = %x,", current_SC->cmnd[current_SC->SCp.sent_command - 1]);
 
 727                 case 0x00:      /* DATA OUT -- tmc18c50/tmc18c30 only */
 
 728                         if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
 
 729                                 current_SC->SCp.have_data_in = -1;
 
 730                                 outb(0xd0 | PARITY_MASK, TMC_Cntl_port);
 
 733                 case 0x04:      /* DATA IN -- tmc18c50/tmc18c30 only */
 
 734                         if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
 
 735                                 current_SC->SCp.have_data_in = 1;
 
 736                                 outb(0x90 | PARITY_MASK, TMC_Cntl_port);
 
 739                 case 0x0c:      /* STATUS IN */
 
 740                         current_SC->SCp.Status = inb(Read_SCSI_Data_port);
 
 742                         printk("Status = %x, ", current_SC->SCp.Status);
 
 745                         if (current_SC->SCp.Status && current_SC->SCp.Status != 2 && current_SC->SCp.Status != 8) {
 
 746                                 printk("ERROR fd_mcs: target = %d, command = %x, status = %x\n", current_SC->device->id, current_SC->cmnd[0], current_SC->SCp.Status);
 
 750                 case 0x0a:      /* MESSAGE OUT */
 
 751                         outb(MESSAGE_REJECT, Write_SCSI_Data_port);     /* Reject */
 
 753                 case 0x0e:      /* MESSAGE IN */
 
 754                         current_SC->SCp.Message = inb(Read_SCSI_Data_port);
 
 756                         printk("Message = %x, ", current_SC->SCp.Message);
 
 758                         if (!current_SC->SCp.Message)
 
 760 #if DEBUG_MESSAGES || EVERY_ACCESS
 
 761                         if (current_SC->SCp.Message) {
 
 762                                 printk("fd_mcs: message = %x\n", current_SC->SCp.Message);
 
 769         if (chip == tmc1800 && !current_SC->SCp.have_data_in && (current_SC->SCp.sent_command >= current_SC->cmd_len)) {
 
 770                 /* We have to get the FIFO direction
 
 771                    correct, so I've made a table based
 
 772                    on the SCSI Standard of which commands
 
 773                    appear to require a DATA OUT phase.
 
 776                    p. 94: Command for all device types
 
 777                    CHANGE DEFINITION            40 DATA OUT
 
 780                    COPY AND VERIFY              3a DATA OUT
 
 782                    LOG SELECT                   4c DATA OUT
 
 784                    MODE SELECT (6)              15 DATA OUT
 
 785                    MODE SELECT (10)             55 DATA OUT
 
 789                    RECEIVE DIAGNOSTIC RESULTS   1c
 
 791                    SEND DIAGNOSTIC              1d DATA OUT
 
 793                    WRITE BUFFER                 3b DATA OUT
 
 795                    p.178: Commands for direct-access devices (not listed on p. 94)
 
 796                    FORMAT UNIT                  04 DATA OUT
 
 799                    PREVENT-ALLOW MEDIUM REMOVAL 1e
 
 803                    READ DEFECT DATA (10)        37
 
 805                    REASSIGN BLOCKS              07 DATA OUT
 
 808                    REZERO UNIT/REWIND           01
 
 809                    SEARCH DATA EQUAL (10)       31 DATA OUT
 
 810                    SEARCH DATA HIGH (10)        30 DATA OUT
 
 811                    SEARCH DATA LOW (10)         32 DATA OUT
 
 818                    WRITE (6)/PRINT/SEND         0a DATA OUT
 
 819                    WRITE (10)/SEND              2a DATA OUT
 
 820                    WRITE AND VERIFY (10)        2e DATA OUT
 
 821                    WRITE LONG                   3f DATA OUT
 
 822                    WRITE SAME                   41 DATA OUT ?
 
 824                    p. 261: Commands for sequential-access devices (not previously listed)
 
 831                    RECOVER BUFFERED DATA        14
 
 835                    p. 298: Commands for printer devices (not previously listed)
 
 836                    ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****
 
 837                    SLEW AND PRINT               0b DATA OUT  -- same as seek
 
 839                    SYNCHRONIZE BUFFER           10
 
 841                    p. 315: Commands for processor devices (not previously listed)
 
 843                    p. 321: Commands for write-once devices (not previously listed)
 
 846                    SEARCH DATA EQUAL (12)       b1 DATA OUT
 
 847                    SEARCH DATA HIGH (12)        b0 DATA OUT
 
 848                    SEARCH DATA LOW (12)         b2 DATA OUT
 
 851                    WRITE (12)                   aa DATA OUT
 
 852                    WRITE AND VERIFY (12)        ae DATA OUT
 
 854                    p. 332: Commands for CD-ROM devices (not previously listed)
 
 859                    PLAY TRACK RELATIVE (10)     49
 
 860                    PLAY TRACK RELATIVE (12)     a9
 
 865                    p. 370: Commands for scanner devices (not previously listed)
 
 866                    GET DATA BUFFER STATUS       34
 
 870                    SET WINDOW                   24 DATA OUT
 
 872                    p. 391: Commands for optical memory devices (not listed)
 
 875                    MEDIUM SCAN                  38 DATA OUT
 
 876                    READ DEFECT DATA (12)        b7
 
 878                    READ UPDATED BLOCK           2d
 
 879                    UPDATE BLOCK                 3d DATA OUT
 
 881                    p. 419: Commands for medium changer devices (not listed)
 
 883                    INITIALIZE ELEMENT STATUS    07
 
 885                    POSITION TO ELEMENT          2b
 
 886                    READ ELEMENT STATUS          b8
 
 887                    REQUEST VOL. ELEMENT ADDRESS b5
 
 888                    SEND VOLUME TAG              b6 DATA OUT
 
 890                    p. 454: Commands for communications devices (not listed previously)
 
 896                 switch (current_SC->cmnd[0]) {
 
 897                 case CHANGE_DEFINITION:
 
 904                 case SEND_DIAGNOSTIC:
 
 908                 case REASSIGN_BLOCKS:
 
 932                 case 0xea:      /* alternate number for WRITE LONG */
 
 934                         current_SC->SCp.have_data_in = -1;
 
 935                         outb(0xd0 | PARITY_MASK, TMC_Cntl_port);
 
 941                         current_SC->SCp.have_data_in = 1;
 
 942                         outb(0x90 | PARITY_MASK, TMC_Cntl_port);
 
 947         if (current_SC->SCp.have_data_in == -1) {       /* DATA OUT */
 
 948                 while ((data_count = FIFO_Size - inw(FIFO_Data_Count_port)) > 512) {
 
 950                         printk("DC=%d, ", data_count);
 
 952                         if (data_count > current_SC->SCp.this_residual)
 
 953                                 data_count = current_SC->SCp.this_residual;
 
 954                         if (data_count > 0) {
 
 956                                 printk("%d OUT, ", data_count);
 
 958                                 if (data_count == 1) {
 
 961                                         outb(*current_SC->SCp.ptr++, Write_FIFO_port);
 
 962                                         --current_SC->SCp.this_residual;
 
 965                                         tmp_count = data_count << 1;
 
 966                                         outsw(Write_FIFO_port, current_SC->SCp.ptr, data_count);
 
 967                                         current_SC->SCp.ptr += tmp_count;
 
 968                                         Bytes_Written += tmp_count;
 
 969                                         current_SC->SCp.this_residual -= tmp_count;
 
 972                         if (!current_SC->SCp.this_residual) {
 
 973                                 if (current_SC->SCp.buffers_residual) {
 
 974                                         --current_SC->SCp.buffers_residual;
 
 975                                         ++current_SC->SCp.buffer;
 
 976                                         current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
 
 977                                         current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 
 982         } else if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
 
 983                 while ((data_count = inw(FIFO_Data_Count_port)) > 0) {
 
 985                         printk("DC=%d, ", data_count);
 
 987                         if (data_count > current_SC->SCp.this_residual)
 
 988                                 data_count = current_SC->SCp.this_residual;
 
 991                                 printk("%d IN, ", data_count);
 
 993                                 if (data_count == 1) {
 
 995                                         *current_SC->SCp.ptr++ = inb(Read_FIFO_port);
 
 996                                         --current_SC->SCp.this_residual;
 
 998                                         data_count >>= 1;       /* Number of words */
 
 999                                         tmp_count = data_count << 1;
 
1000                                         insw(Read_FIFO_port, current_SC->SCp.ptr, data_count);
 
1001                                         current_SC->SCp.ptr += tmp_count;
 
1002                                         Bytes_Read += tmp_count;
 
1003                                         current_SC->SCp.this_residual -= tmp_count;
 
1006                         if (!current_SC->SCp.this_residual && current_SC->SCp.buffers_residual) {
 
1007                                 --current_SC->SCp.buffers_residual;
 
1008                                 ++current_SC->SCp.buffer;
 
1009                                 current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
 
1010                                 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 
1017                 printk(" ** IN DONE %d ** ", current_SC->SCp.have_data_in);
 
1021                 printk("BEFORE MY_DONE. . .");
 
1023                 spin_lock_irqsave(shpnt->host_lock, flags);
 
1024                 my_done(shpnt, (current_SC->SCp.Status & 0xff)
 
1025                         | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16));
 
1026                 spin_unlock_irqrestore(shpnt->host_lock, flags);
 
1028                 printk("RETURNING.\n");
 
1032                 if (current_SC->SCp.phase & disconnect) {
 
1033                         outb(0xd0 | FIFO_COUNT, Interrupt_Cntl_port);
 
1034                         outb(0x00, SCSI_Cntl_port);
 
1036                         outb(0x90 | FIFO_COUNT, Interrupt_Cntl_port);
 
1040         in_interrupt_flag = 0;
 
1045 static int fd_mcs_release(struct Scsi_Host *shpnt)
 
1047         int i, this_host, irq_usage;
 
1049         release_region(shpnt->io_port, shpnt->n_io_port);
 
1053         for (i = 0; i < found; i++) {
 
1054                 if (shpnt == hosts[i])
 
1056                 if (shpnt->irq == hosts[i]->irq)
 
1060         /* only for the last one */
 
1062                 free_irq(shpnt->irq, hosts);
 
1066         for (i = this_host; i < found; i++)
 
1067                 hosts[i] = hosts[i + 1];
 
1069         hosts[found] = NULL;
 
1074 static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 
1076         struct Scsi_Host *shpnt = SCpnt->device->host;
 
1079                 panic("fd_mcs: fd_mcs_queue() NOT REENTRANT!\n");
 
1082         printk("queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
 
1083                 SCpnt->target, *(unsigned char *) SCpnt->cmnd,
 
1084                 scsi_sg_count(SCpnt), scsi_bufflen(SCpnt));
 
1087         fd_mcs_make_bus_idle(shpnt);
 
1089         SCpnt->scsi_done = done;        /* Save this for the done function */
 
1092         /* Initialize static data */
 
1094         if (scsi_bufflen(current_SC)) {
 
1095                 current_SC->SCp.buffer = scsi_sglist(current_SC);
 
1096                 current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
 
1097                 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 
1098                 current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
 
1100                 current_SC->SCp.ptr = NULL;
 
1101                 current_SC->SCp.this_residual = 0;
 
1102                 current_SC->SCp.buffer = NULL;
 
1103                 current_SC->SCp.buffers_residual = 0;
 
1107         current_SC->SCp.Status = 0;
 
1108         current_SC->SCp.Message = 0;
 
1109         current_SC->SCp.have_data_in = 0;
 
1110         current_SC->SCp.sent_command = 0;
 
1111         current_SC->SCp.phase = in_arbitration;
 
1113         /* Start arbitration */
 
1114         outb(0x00, Interrupt_Cntl_port);
 
1115         outb(0x00, SCSI_Cntl_port);     /* Disable data drivers */
 
1116         outb(adapter_mask, SCSI_Data_NoACK_port);       /* Set our id bit */
 
1118         outb(0x20, Interrupt_Cntl_port);
 
1119         outb(0x14 | PARITY_MASK, TMC_Cntl_port);        /* Start arbitration */
 
1124 #if DEBUG_ABORT || DEBUG_RESET
 
1125 static void fd_mcs_print_info(Scsi_Cmnd * SCpnt)
 
1130         struct Scsi_Host *shpnt = SCpnt->host;
 
1132         if (!SCpnt || !SCpnt->host) {
 
1133                 printk("fd_mcs: cannot provide detailed information\n");
 
1136         printk("%s\n", fd_mcs_info(SCpnt->host));
 
1137         print_banner(SCpnt->host);
 
1138         switch (SCpnt->SCp.phase) {
 
1139         case in_arbitration:
 
1140                 printk("arbitration ");
 
1143                 printk("selection ");
 
1153         printk("(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
 
1154                 SCpnt->SCp.phase, SCpnt->device->id, *(unsigned char *) SCpnt->cmnd,
 
1155                 scsi_sg_count(SCpnt), scsi_bufflen(SCpnt));
 
1156         printk("sent_command = %d, have_data_in = %d, timeout = %d\n", SCpnt->SCp.sent_command, SCpnt->SCp.have_data_in, SCpnt->timeout);
 
1158         printk("in_interrupt_flag = %d\n", in_interrupt_flag);
 
1161         imr = (inb(0x0a1) << 8) + inb(0x21);
 
1163         irr = inb(0xa0) << 8;
 
1167         isr = inb(0xa0) << 8;
 
1171         /* Print out interesting information */
 
1172         printk("IMR = 0x%04x", imr);
 
1173         if (imr & (1 << shpnt->irq))
 
1174                 printk(" (masked)");
 
1175         printk(", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr);
 
1177         printk("SCSI Status      = 0x%02x\n", inb(SCSI_Status_port));
 
1178         printk("TMC Status       = 0x%02x", inb(TMC_Status_port));
 
1179         if (inb(TMC_Status_port) & 1)
 
1180                 printk(" (interrupt)");
 
1182         printk("Interrupt Status = 0x%02x", inb(Interrupt_Status_port));
 
1183         if (inb(Interrupt_Status_port) & 0x08)
 
1184                 printk(" (enabled)");
 
1186         if (chip == tmc18c50 || chip == tmc18c30) {
 
1187                 printk("FIFO Status      = 0x%02x\n", inb(shpnt->io_port + FIFO_Status));
 
1188                 printk("Int. Condition   = 0x%02x\n", inb(shpnt->io_port + Interrupt_Cond));
 
1190         printk("Configuration 1  = 0x%02x\n", inb(shpnt->io_port + Configuration1));
 
1191         if (chip == tmc18c50 || chip == tmc18c30)
 
1192                 printk("Configuration 2  = 0x%02x\n", inb(shpnt->io_port + Configuration2));
 
1196 static int fd_mcs_abort(Scsi_Cmnd * SCpnt)
 
1198         struct Scsi_Host *shpnt = SCpnt->device->host;
 
1200         unsigned long flags;
 
1201 #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
 
1202         printk("fd_mcs: abort ");
 
1205         spin_lock_irqsave(shpnt->host_lock, flags);
 
1207 #if EVERY_ACCESS || ERRORS_ONLY
 
1208                 printk(" (not in command)\n");
 
1210                 spin_unlock_irqrestore(shpnt->host_lock, flags);
 
1216         fd_mcs_print_info(SCpnt);
 
1219         fd_mcs_make_bus_idle(shpnt);
 
1221         current_SC->SCp.phase |= aborted;
 
1223         current_SC->result = DID_ABORT << 16;
 
1225         /* Aborts are not done well. . . */
 
1226         my_done(shpnt, DID_ABORT << 16);
 
1228         spin_unlock_irqrestore(shpnt->host_lock, flags);
 
1232 static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
 
1233         struct Scsi_Host *shpnt = SCpnt->device->host;
 
1234         unsigned long flags;
 
1237         static int called_once = 0;
 
1242                 printk("fd_mcs: SCSI Bus Reset\n");
 
1247                 fd_mcs_print_info(current_SC);
 
1251         spin_lock_irqsave(shpnt->host_lock, flags);
 
1253         outb(1, SCSI_Cntl_port);
 
1255         outb(0, SCSI_Cntl_port);
 
1257         outb(0, SCSI_Mode_Cntl_port);
 
1258         outb(PARITY_MASK, TMC_Cntl_port);
 
1260         spin_unlock_irqrestore(shpnt->host_lock, flags);
 
1262         /* Unless this is the very first call (i.e., SCPnt == NULL), everything
 
1263            is probably hosed at this point.  We will, however, try to keep
 
1264            things going by informing the high-level code that we need help. */
 
1268 #include <scsi/scsi_ioctl.h>
 
1270 static int fd_mcs_biosparam(struct scsi_device * disk, struct block_device *bdev,
 
1271                             sector_t capacity, int *info_array) 
 
1273         unsigned char *p = scsi_bios_ptable(bdev);
 
1274         int size = capacity;
 
1276         /* BIOS >= 3.4 for MCA cards */
 
1277         /* This algorithm was provided by Future Domain (much thanks!). */
 
1279         if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */
 
1280             && p[4]) {  /* Partition type */
 
1281                 /* The partition table layout is as follows:
 
1284                    Offset: 0 = partition status
 
1286                    2 = starting sector and cylinder (word, encoded)
 
1289                    6 = ending sector and cylinder (word, encoded)
 
1290                    8 = starting absolute sector (double word)
 
1291                    c = number of sectors (double word)
 
1292                    Signature: 0x1fe = 0x55aa
 
1294                    So, this algorithm assumes:
 
1295                    1) the first partition table is in use,
 
1296                    2) the data in the first entry is correct, and
 
1297                    3) partitions never divide cylinders
 
1299                    Note that (1) may be FALSE for NetBSD (and other BSD flavors),
 
1300                    as well as for Linux.  Note also, that Linux doesn't pay any
 
1301                    attention to the fields that are used by this algorithm -- it
 
1302                    only uses the absolute sector data.  Recent versions of Linux's
 
1303                    fdisk(1) will fill this data in correctly, and forthcoming
 
1304                    versions will check for consistency.
 
1306                    Checking for a non-zero partition type is not part of the
 
1307                    Future Domain algorithm, but it seemed to be a reasonable thing
 
1308                    to do, especially in the Linux and BSD worlds. */
 
1310                 info_array[0] = p[5] + 1;       /* heads */
 
1311                 info_array[1] = p[6] & 0x3f;    /* sectors */
 
1313                 /* Note that this new method guarantees that there will always be
 
1314                    less than 1024 cylinders on a platter.  This is good for drives
 
1315                    up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
 
1316                 if ((unsigned int) size >= 0x7e0000U) 
 
1318                         info_array[0] = 0xff;   /* heads   = 255 */
 
1319                         info_array[1] = 0x3f;   /* sectors =  63 */
 
1320                 } else if ((unsigned int) size >= 0x200000U) {
 
1321                         info_array[0] = 0x80;   /* heads   = 128 */
 
1322                         info_array[1] = 0x3f;   /* sectors =  63 */
 
1324                         info_array[0] = 0x40;   /* heads   =  64 */
 
1325                         info_array[1] = 0x20;   /* sectors =  32 */
 
1328         /* For both methods, compute the cylinders */
 
1329         info_array[2] = (unsigned int) size / (info_array[0] * info_array[1]);
 
1334 static struct scsi_host_template driver_template = {
 
1335         .proc_name                      = "fd_mcs",
 
1336         .proc_info                      = fd_mcs_proc_info,
 
1337         .detect                         = fd_mcs_detect,
 
1338         .release                        = fd_mcs_release,
 
1339         .info                           = fd_mcs_info,
 
1340         .queuecommand                   = fd_mcs_queue, 
 
1341         .eh_abort_handler               = fd_mcs_abort,
 
1342         .eh_bus_reset_handler           = fd_mcs_bus_reset,
 
1343         .bios_param                     = fd_mcs_biosparam,
 
1348         .use_clustering                 = DISABLE_CLUSTERING,
 
1350 #include "scsi_module.c"
 
1352 MODULE_LICENSE("GPL");