Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.9.
   1/* fd_mcs.c -- Future Domain MCS 600/700 (or IBM OEM) driver
   2 *
   3 * FutureDomain MCS-600/700 v0.2 03/11/1998 by ZP Gu (zpg@castle.net)
   4 *
   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
   8 * of MCS 700.
   9 *
  10 * This driver also supports Reply SB16/SCSI card (the SCSI part).
  11 *
  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.
  16 *
  17 * Assumptions: TMC-1800/18C50/18C30, BIOS >= 3.4
  18 *
  19 * LILO command-line options:
  20 *   fd_mcs=<FIFO_COUNT>[,<FIFO_SIZE>]
  21 *
  22 * ********************************************************
  23 * Please see Copyrights/Comments in fdomain.* for credits.
  24 * Following is from fdomain.c for acknowledgement:
  25 *
  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
  30 *
  31 * $Id: fdomain.c,v 5.45 1996/10/02 15:13:06 root Exp $
  32
  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
  36 * later version.
  37
  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.
  42
  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.
  46
  47 **************************************************************************
  48
  49 NOTES ON USER DEFINABLE OPTIONS:
  50
  51 DEBUG: This turns on the printing of various debug information.
  52
  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.
  58
  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*****]
  68
  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.
  77
  78 **************************************************************************/
  79
  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 <linux/slab.h>
  92#include <scsi/scsicam.h>
  93#include <linux/mca-legacy.h>
  94
  95#include <asm/io.h>
  96#include <asm/system.h>
  97
  98#include "scsi.h"
  99#include <scsi/scsi_host.h>
 100
 101#define DRIVER_VERSION "v0.2 by ZP Gu<zpg@castle.net>"
 102
 103/* START OF USER DEFINABLE OPTIONS */
 104
 105#define DEBUG            0	/* Enable debugging output */
 106#define ENABLE_PARITY    1	/* Enable SCSI Parity */
 107
 108/* END OF USER DEFINABLE OPTIONS */
 109
 110#if DEBUG
 111#define EVERY_ACCESS     0	/* Write a line on every scsi access */
 112#define ERRORS_ONLY      1	/* Only write a line if there is an error */
 113#define DEBUG_MESSAGES   1	/* Debug MESSAGE IN phase */
 114#define DEBUG_ABORT      1	/* Debug abort() routine */
 115#define DEBUG_RESET      1	/* Debug reset() routine */
 116#define DEBUG_RACE       1	/* Debug interrupt-driven race condition */
 117#else
 118#define EVERY_ACCESS     0	/* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
 119#define ERRORS_ONLY      0
 120#define DEBUG_MESSAGES   0
 121#define DEBUG_ABORT      0
 122#define DEBUG_RESET      0
 123#define DEBUG_RACE       0
 124#endif
 125
 126/* Errors are reported on the line, so we don't need to report them again */
 127#if EVERY_ACCESS
 128#undef ERRORS_ONLY
 129#define ERRORS_ONLY      0
 130#endif
 131
 132#if ENABLE_PARITY
 133#define PARITY_MASK      0x08
 134#else
 135#define PARITY_MASK      0x00
 136#endif
 137
 138enum chip_type {
 139	unknown = 0x00,
 140	tmc1800 = 0x01,
 141	tmc18c50 = 0x02,
 142	tmc18c30 = 0x03,
 143};
 144
 145enum {
 146	in_arbitration = 0x02,
 147	in_selection = 0x04,
 148	in_other = 0x08,
 149	disconnect = 0x10,
 150	aborted = 0x20,
 151	sent_ident = 0x40,
 152};
 153
 154enum in_port_type {
 155	Read_SCSI_Data = 0,
 156	SCSI_Status = 1,
 157	TMC_Status = 2,
 158	FIFO_Status = 3,	/* tmc18c50/tmc18c30 only */
 159	Interrupt_Cond = 4,	/* tmc18c50/tmc18c30 only */
 160	LSB_ID_Code = 5,
 161	MSB_ID_Code = 6,
 162	Read_Loopback = 7,
 163	SCSI_Data_NoACK = 8,
 164	Interrupt_Status = 9,
 165	Configuration1 = 10,
 166	Configuration2 = 11,	/* tmc18c50/tmc18c30 only */
 167	Read_FIFO = 12,
 168	FIFO_Data_Count = 14
 169};
 170
 171enum out_port_type {
 172	Write_SCSI_Data = 0,
 173	SCSI_Cntl = 1,
 174	Interrupt_Cntl = 2,
 175	SCSI_Mode_Cntl = 3,
 176	TMC_Cntl = 4,
 177	Memory_Cntl = 5,	/* tmc18c50/tmc18c30 only */
 178	Write_Loopback = 7,
 179	IO_Control = 11,	/* tmc18c30 only */
 180	Write_FIFO = 12
 181};
 182
 183struct fd_hostdata {
 184	unsigned long _bios_base;
 185	int _bios_major;
 186	int _bios_minor;
 187	volatile int _in_command;
 188	Scsi_Cmnd *_current_SC;
 189	enum chip_type _chip;
 190	int _adapter_mask;
 191	int _fifo_count;	/* Number of 512 byte blocks before INTR */
 192
 193	char _adapter_name[64];
 194#if DEBUG_RACE
 195	volatile int _in_interrupt_flag;
 196#endif
 197
 198	int _SCSI_Mode_Cntl_port;
 199	int _FIFO_Data_Count_port;
 200	int _Interrupt_Cntl_port;
 201	int _Interrupt_Status_port;
 202	int _Interrupt_Cond_port;
 203	int _Read_FIFO_port;
 204	int _Read_SCSI_Data_port;
 205	int _SCSI_Cntl_port;
 206	int _SCSI_Data_NoACK_port;
 207	int _SCSI_Status_port;
 208	int _TMC_Cntl_port;
 209	int _TMC_Status_port;
 210	int _Write_FIFO_port;
 211	int _Write_SCSI_Data_port;
 212
 213	int _FIFO_Size;		/* = 0x2000;  8k FIFO for
 214				   pre-tmc18c30 chips */
 215	/* simple stats */
 216	int _Bytes_Read;
 217	int _Bytes_Written;
 218	int _INTR_Processed;
 219};
 220
 221#define FD_MAX_HOSTS 3		/* enough? */
 222
 223#define HOSTDATA(shpnt) ((struct fd_hostdata *) shpnt->hostdata)
 224#define bios_base             (HOSTDATA(shpnt)->_bios_base)
 225#define bios_major            (HOSTDATA(shpnt)->_bios_major)
 226#define bios_minor            (HOSTDATA(shpnt)->_bios_minor)
 227#define in_command            (HOSTDATA(shpnt)->_in_command)
 228#define current_SC            (HOSTDATA(shpnt)->_current_SC)
 229#define chip                  (HOSTDATA(shpnt)->_chip)
 230#define adapter_mask          (HOSTDATA(shpnt)->_adapter_mask)
 231#define FIFO_COUNT            (HOSTDATA(shpnt)->_fifo_count)
 232#define adapter_name          (HOSTDATA(shpnt)->_adapter_name)
 233#if DEBUG_RACE
 234#define in_interrupt_flag     (HOSTDATA(shpnt)->_in_interrupt_flag)
 235#endif
 236#define SCSI_Mode_Cntl_port   (HOSTDATA(shpnt)->_SCSI_Mode_Cntl_port)
 237#define FIFO_Data_Count_port  (HOSTDATA(shpnt)->_FIFO_Data_Count_port)
 238#define Interrupt_Cntl_port   (HOSTDATA(shpnt)->_Interrupt_Cntl_port)
 239#define Interrupt_Status_port (HOSTDATA(shpnt)->_Interrupt_Status_port)
 240#define Interrupt_Cond_port   (HOSTDATA(shpnt)->_Interrupt_Cond_port)
 241#define Read_FIFO_port        (HOSTDATA(shpnt)->_Read_FIFO_port)
 242#define Read_SCSI_Data_port   (HOSTDATA(shpnt)->_Read_SCSI_Data_port)
 243#define SCSI_Cntl_port        (HOSTDATA(shpnt)->_SCSI_Cntl_port)
 244#define SCSI_Data_NoACK_port  (HOSTDATA(shpnt)->_SCSI_Data_NoACK_port)
 245#define SCSI_Status_port      (HOSTDATA(shpnt)->_SCSI_Status_port)
 246#define TMC_Cntl_port         (HOSTDATA(shpnt)->_TMC_Cntl_port)
 247#define TMC_Status_port       (HOSTDATA(shpnt)->_TMC_Status_port)
 248#define Write_FIFO_port       (HOSTDATA(shpnt)->_Write_FIFO_port)
 249#define Write_SCSI_Data_port  (HOSTDATA(shpnt)->_Write_SCSI_Data_port)
 250#define FIFO_Size             (HOSTDATA(shpnt)->_FIFO_Size)
 251#define Bytes_Read            (HOSTDATA(shpnt)->_Bytes_Read)
 252#define Bytes_Written         (HOSTDATA(shpnt)->_Bytes_Written)
 253#define INTR_Processed        (HOSTDATA(shpnt)->_INTR_Processed)
 254
 255struct fd_mcs_adapters_struct {
 256	char *name;
 257	int id;
 258	enum chip_type fd_chip;
 259	int fifo_size;
 260	int fifo_count;
 261};
 262
 263#define REPLY_ID 0x5137
 264
 265static struct fd_mcs_adapters_struct fd_mcs_adapters[] = {
 266	{"Future Domain SCSI Adapter MCS-700(18C50)",
 267	 0x60e9,
 268	 tmc18c50,
 269	 0x2000,
 270	 4},
 271	{"Future Domain SCSI Adapter MCS-600/700(TMC-1800)",
 272	 0x6127,
 273	 tmc1800,
 274	 0x2000,
 275	 4},
 276	{"Reply Sound Blaster/SCSI Adapter",
 277	 REPLY_ID,
 278	 tmc18c30,
 279	 0x800,
 280	 2},
 281};
 282
 283#define FD_BRDS ARRAY_SIZE(fd_mcs_adapters)
 284
 285static irqreturn_t fd_mcs_intr(int irq, void *dev_id);
 286
 287static unsigned long addresses[] = { 0xc8000, 0xca000, 0xce000, 0xde000 };
 288static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
 289static unsigned short interrupts[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
 290
 291/* host information */
 292static int found = 0;
 293static struct Scsi_Host *hosts[FD_MAX_HOSTS + 1] = { NULL };
 294
 295static int user_fifo_count = 0;
 296static int user_fifo_size = 0;
 297
 298#ifndef MODULE
 299static int __init fd_mcs_setup(char *str)
 300{
 301	static int done_setup = 0;
 302	int ints[3];
 303
 304	get_options(str, 3, ints);
 305	if (done_setup++ || ints[0] < 1 || ints[0] > 2 || ints[1] < 1 || ints[1] > 16) {
 306		printk("fd_mcs: usage: fd_mcs=FIFO_COUNT, FIFO_SIZE\n");
 307		return 0;
 308	}
 309
 310	user_fifo_count = ints[0] >= 1 ? ints[1] : 0;
 311	user_fifo_size = ints[0] >= 2 ? ints[2] : 0;
 312	return 1;
 313}
 314
 315__setup("fd_mcs=", fd_mcs_setup);
 316#endif /* !MODULE */
 317
 318static void print_banner(struct Scsi_Host *shpnt)
 319{
 320	printk("scsi%d <fd_mcs>: ", shpnt->host_no);
 321
 322	if (bios_base) {
 323		printk("BIOS at 0x%lX", bios_base);
 324	} else {
 325		printk("No BIOS");
 326	}
 327
 328	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);
 329}
 330
 331
 332static void do_pause(unsigned amount)
 333{				/* Pause for amount*10 milliseconds */
 334	do {
 335		mdelay(10);
 336	} while (--amount);
 337}
 338
 339static void fd_mcs_make_bus_idle(struct Scsi_Host *shpnt)
 340{
 341	outb(0, SCSI_Cntl_port);
 342	outb(0, SCSI_Mode_Cntl_port);
 343	if (chip == tmc18c50 || chip == tmc18c30)
 344		outb(0x21 | PARITY_MASK, TMC_Cntl_port);	/* Clear forced intr. */
 345	else
 346		outb(0x01 | PARITY_MASK, TMC_Cntl_port);
 347}
 348
 349static int fd_mcs_detect(struct scsi_host_template * tpnt)
 350{
 351	int loop;
 352	struct Scsi_Host *shpnt;
 353
 354	/* get id, port, bios, irq */
 355	int slot;
 356	u_char pos2, pos3, pos4;
 357	int id, port, irq;
 358	unsigned long bios;
 359
 360	/* if not MCA machine, return */
 361	if (!MCA_bus)
 362		return 0;
 363
 364	/* changeable? */
 365	id = 7;
 366
 367	for (loop = 0; loop < FD_BRDS; loop++) {
 368		slot = 0;
 369		while (MCA_NOTFOUND != (slot = mca_find_adapter(fd_mcs_adapters[loop].id, slot))) {
 370
 371			/* if we get this far, an adapter has been detected and is
 372			   enabled */
 373
 374			printk(KERN_INFO "scsi  <fd_mcs>: %s at slot %d\n", fd_mcs_adapters[loop].name, slot + 1);
 375
 376			pos2 = mca_read_stored_pos(slot, 2);
 377			pos3 = mca_read_stored_pos(slot, 3);
 378			pos4 = mca_read_stored_pos(slot, 4);
 379
 380			/* ready for next probe */
 381			slot++;
 382
 383			if (fd_mcs_adapters[loop].id == REPLY_ID) {	/* reply card */
 384				static int reply_irq[] = { 10, 11, 14, 15 };
 385
 386				bios = 0;	/* no bios */
 387
 388				if (pos2 & 0x2)
 389					port = ports[pos4 & 0x3];
 390				else
 391					continue;
 392
 393				/* can't really disable it, same as irq=10 */
 394				irq = reply_irq[((pos4 >> 2) & 0x1) + 2 * ((pos4 >> 4) & 0x1)];
 395			} else {
 396				bios = addresses[pos2 >> 6];
 397				port = ports[(pos2 >> 4) & 0x03];
 398				irq = interrupts[(pos2 >> 1) & 0x07];
 399			}
 400
 401			if (irq) {
 402				/* claim the slot */
 403				mca_set_adapter_name(slot - 1, fd_mcs_adapters[loop].name);
 404
 405				/* check irq/region */
 406				if (request_irq(irq, fd_mcs_intr, IRQF_SHARED, "fd_mcs", hosts)) {
 407					printk(KERN_ERR "fd_mcs: interrupt is not available, skipping...\n");
 408					continue;
 409				}
 410
 411				/* request I/O region */
 412				if (request_region(port, 0x10, "fd_mcs")) {
 413					printk(KERN_ERR "fd_mcs: I/O region is already in use, skipping...\n");
 414					continue;
 415				}
 416				/* register */
 417				if (!(shpnt = scsi_register(tpnt, sizeof(struct fd_hostdata)))) {
 418					printk(KERN_ERR "fd_mcs: scsi_register() failed\n");
 419					release_region(port, 0x10);
 420					free_irq(irq, hosts);
 421					continue;
 422				}
 423
 424
 425				/* save name */
 426				strcpy(adapter_name, fd_mcs_adapters[loop].name);
 427
 428				/* chip/fifo */
 429				chip = fd_mcs_adapters[loop].fd_chip;
 430				/* use boot time value if available */
 431				FIFO_COUNT = user_fifo_count ? user_fifo_count : fd_mcs_adapters[loop].fifo_count;
 432				FIFO_Size = user_fifo_size ? user_fifo_size : fd_mcs_adapters[loop].fifo_size;
 433
 434/* FIXME: Do we need to keep this bit of code inside NOT_USED around at all? */
 435#ifdef NOT_USED
 436				/* *************************************************** */
 437				/* Try to toggle 32-bit mode.  This only
 438				   works on an 18c30 chip.  (User reports
 439				   say this works, so we should switch to
 440				   it in the near future.) */
 441				outb(0x80, port + IO_Control);
 442				if ((inb(port + Configuration2) & 0x80) == 0x80) {
 443					outb(0x00, port + IO_Control);
 444					if ((inb(port + Configuration2) & 0x80) == 0x00) {
 445						chip = tmc18c30;
 446						FIFO_Size = 0x800;	/* 2k FIFO */
 447
 448						printk("FIRST: chip=%s, fifo_size=0x%x\n", (chip == tmc18c30) ? "tmc18c30" : "tmc18c50", FIFO_Size);
 449					}
 450				}
 451
 452				/* That should have worked, but appears to
 453				   have problems.  Let's assume it is an
 454				   18c30 if the RAM is disabled. */
 455
 456				if (inb(port + Configuration2) & 0x02) {
 457					chip = tmc18c30;
 458					FIFO_Size = 0x800;	/* 2k FIFO */
 459
 460					printk("SECOND: chip=%s, fifo_size=0x%x\n", (chip == tmc18c30) ? "tmc18c30" : "tmc18c50", FIFO_Size);
 461				}
 462				/* *************************************************** */
 463#endif
 464
 465				/* IBM/ANSI scsi scan ordering */
 466				/* Stick this back in when the scsi.c changes are there */
 467				shpnt->reverse_ordering = 1;
 468
 469
 470				/* saving info */
 471				hosts[found++] = shpnt;
 472
 473				shpnt->this_id = id;
 474				shpnt->irq = irq;
 475				shpnt->io_port = port;
 476				shpnt->n_io_port = 0x10;
 477
 478				/* save */
 479				bios_base = bios;
 480				adapter_mask = (1 << id);
 481
 482				/* save more */
 483				SCSI_Mode_Cntl_port = port + SCSI_Mode_Cntl;
 484				FIFO_Data_Count_port = port + FIFO_Data_Count;
 485				Interrupt_Cntl_port = port + Interrupt_Cntl;
 486				Interrupt_Status_port = port + Interrupt_Status;
 487				Interrupt_Cond_port = port + Interrupt_Cond;
 488				Read_FIFO_port = port + Read_FIFO;
 489				Read_SCSI_Data_port = port + Read_SCSI_Data;
 490				SCSI_Cntl_port = port + SCSI_Cntl;
 491				SCSI_Data_NoACK_port = port + SCSI_Data_NoACK;
 492				SCSI_Status_port = port + SCSI_Status;
 493				TMC_Cntl_port = port + TMC_Cntl;
 494				TMC_Status_port = port + TMC_Status;
 495				Write_FIFO_port = port + Write_FIFO;
 496				Write_SCSI_Data_port = port + Write_SCSI_Data;
 497
 498				Bytes_Read = 0;
 499				Bytes_Written = 0;
 500				INTR_Processed = 0;
 501
 502				/* say something */
 503				print_banner(shpnt);
 504
 505				/* reset */
 506				outb(1, SCSI_Cntl_port);
 507				do_pause(2);
 508				outb(0, SCSI_Cntl_port);
 509				do_pause(115);
 510				outb(0, SCSI_Mode_Cntl_port);
 511				outb(PARITY_MASK, TMC_Cntl_port);
 512				/* done reset */
 513			}
 514		}
 515
 516		if (found == FD_MAX_HOSTS) {
 517			printk("fd_mcs: detecting reached max=%d host adapters.\n", FD_MAX_HOSTS);
 518			break;
 519		}
 520	}
 521
 522	return found;
 523}
 524
 525static const char *fd_mcs_info(struct Scsi_Host *shpnt)
 526{
 527	return adapter_name;
 528}
 529
 530static int TOTAL_INTR = 0;
 531
 532/*
 533 * inout : decides on the direction of the dataflow and the meaning of the 
 534 *         variables
 535 * buffer: If inout==FALSE data is being written to it else read from it
 536 * *start: If inout==FALSE start of the valid data in the buffer
 537 * offset: If inout==FALSE offset from the beginning of the imaginary file 
 538 *         from which we start writing into the buffer
 539 * length: If inout==FALSE max number of bytes to be written into the buffer 
 540 *         else number of bytes in the buffer
 541 */
 542static int fd_mcs_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, int inout)
 543{
 544	int len = 0;
 545
 546	if (inout)
 547		return (-ENOSYS);
 548
 549	*start = buffer + offset;
 550
 551	len += sprintf(buffer + len, "Future Domain MCS-600/700 Driver %s\n", DRIVER_VERSION);
 552	len += sprintf(buffer + len, "HOST #%d: %s\n", shpnt->host_no, adapter_name);
 553	len += sprintf(buffer + len, "FIFO Size=0x%x, FIFO Count=%d\n", FIFO_Size, FIFO_COUNT);
 554	len += sprintf(buffer + len, "DriverCalls=%d, Interrupts=%d, BytesRead=%d, BytesWrite=%d\n\n", TOTAL_INTR, INTR_Processed, Bytes_Read, Bytes_Written);
 555
 556	if ((len -= offset) <= 0)
 557		return 0;
 558	if (len > length)
 559		len = length;
 560	return len;
 561}
 562
 563static int fd_mcs_select(struct Scsi_Host *shpnt, int target)
 564{
 565	int status;
 566	unsigned long timeout;
 567
 568	outb(0x82, SCSI_Cntl_port);	/* Bus Enable + Select */
 569	outb(adapter_mask | (1 << target), SCSI_Data_NoACK_port);
 570
 571	/* Stop arbitration and enable parity */
 572	outb(PARITY_MASK, TMC_Cntl_port);
 573
 574	timeout = 350;		/* 350mS -- because of timeouts
 575				   (was 250mS) */
 576
 577	do {
 578		status = inb(SCSI_Status_port);	/* Read adapter status */
 579		if (status & 1) {	/* Busy asserted */
 580			/* Enable SCSI Bus (on error, should make bus idle with 0) */
 581			outb(0x80, SCSI_Cntl_port);
 582			return 0;
 583		}
 584		udelay(1000);	/* wait one msec */
 585	} while (--timeout);
 586
 587	/* Make bus idle */
 588	fd_mcs_make_bus_idle(shpnt);
 589#if EVERY_ACCESS
 590	if (!target)
 591		printk("Selection failed\n");
 592#endif
 593#if ERRORS_ONLY
 594	if (!target) {
 595		static int flag = 0;
 596
 597		if (!flag)	/* Skip first failure for all chips. */
 598			++flag;
 599		else
 600			printk("fd_mcs: Selection failed\n");
 601	}
 602#endif
 603	return 1;
 604}
 605
 606static void my_done(struct Scsi_Host *shpnt, int error)
 607{
 608	if (in_command) {
 609		in_command = 0;
 610		outb(0x00, Interrupt_Cntl_port);
 611		fd_mcs_make_bus_idle(shpnt);
 612		current_SC->result = error;
 613		current_SC->scsi_done(current_SC);
 614	} else {
 615		panic("fd_mcs: my_done() called outside of command\n");
 616	}
 617#if DEBUG_RACE
 618	in_interrupt_flag = 0;
 619#endif
 620}
 621
 622/* only my_done needs to be protected  */
 623static irqreturn_t fd_mcs_intr(int irq, void *dev_id)
 624{
 625	unsigned long flags;
 626	int status;
 627	int done = 0;
 628	unsigned data_count, tmp_count;
 629
 630	int i = 0;
 631	struct Scsi_Host *shpnt;
 632
 633	TOTAL_INTR++;
 634
 635	/* search for one adapter-response on shared interrupt */
 636	while ((shpnt = hosts[i++])) {
 637		if ((inb(TMC_Status_port)) & 1)
 638			break;
 639	}
 640
 641	/* return if some other device on this IRQ caused the interrupt */
 642	if (!shpnt) {
 643		return IRQ_NONE;
 644	}
 645
 646	INTR_Processed++;
 647
 648	outb(0x00, Interrupt_Cntl_port);
 649
 650	/* Abort calls my_done, so we do nothing here. */
 651	if (current_SC->SCp.phase & aborted) {
 652#if DEBUG_ABORT
 653		printk("Interrupt after abort, ignoring\n");
 654#endif
 655		/* return IRQ_HANDLED; */
 656	}
 657#if DEBUG_RACE
 658	++in_interrupt_flag;
 659#endif
 660
 661	if (current_SC->SCp.phase & in_arbitration) {
 662		status = inb(TMC_Status_port);	/* Read adapter status */
 663		if (!(status & 0x02)) {
 664#if EVERY_ACCESS
 665			printk(" AFAIL ");
 666#endif
 667			spin_lock_irqsave(shpnt->host_lock, flags);
 668			my_done(shpnt, DID_BUS_BUSY << 16);
 669			spin_unlock_irqrestore(shpnt->host_lock, flags);
 670			return IRQ_HANDLED;
 671		}
 672		current_SC->SCp.phase = in_selection;
 673
 674		outb(0x40 | FIFO_COUNT, Interrupt_Cntl_port);
 675
 676		outb(0x82, SCSI_Cntl_port);	/* Bus Enable + Select */
 677		outb(adapter_mask | (1 << scmd_id(current_SC)), SCSI_Data_NoACK_port);
 678
 679		/* Stop arbitration and enable parity */
 680		outb(0x10 | PARITY_MASK, TMC_Cntl_port);
 681#if DEBUG_RACE
 682		in_interrupt_flag = 0;
 683#endif
 684		return IRQ_HANDLED;
 685	} else if (current_SC->SCp.phase & in_selection) {
 686		status = inb(SCSI_Status_port);
 687		if (!(status & 0x01)) {
 688			/* Try again, for slow devices */
 689			if (fd_mcs_select(shpnt, scmd_id(current_SC))) {
 690#if EVERY_ACCESS
 691				printk(" SFAIL ");
 692#endif
 693				spin_lock_irqsave(shpnt->host_lock, flags);
 694				my_done(shpnt, DID_NO_CONNECT << 16);
 695				spin_unlock_irqrestore(shpnt->host_lock, flags);
 696				return IRQ_HANDLED;
 697			} else {
 698#if EVERY_ACCESS
 699				printk(" AltSel ");
 700#endif
 701				/* Stop arbitration and enable parity */
 702				outb(0x10 | PARITY_MASK, TMC_Cntl_port);
 703			}
 704		}
 705		current_SC->SCp.phase = in_other;
 706		outb(0x90 | FIFO_COUNT, Interrupt_Cntl_port);
 707		outb(0x80, SCSI_Cntl_port);
 708#if DEBUG_RACE
 709		in_interrupt_flag = 0;
 710#endif
 711		return IRQ_HANDLED;
 712	}
 713
 714	/* current_SC->SCp.phase == in_other: this is the body of the routine */
 715
 716	status = inb(SCSI_Status_port);
 717
 718	if (status & 0x10) {	/* REQ */
 719
 720		switch (status & 0x0e) {
 721
 722		case 0x08:	/* COMMAND OUT */
 723			outb(current_SC->cmnd[current_SC->SCp.sent_command++], Write_SCSI_Data_port);
 724#if EVERY_ACCESS
 725			printk("CMD = %x,", current_SC->cmnd[current_SC->SCp.sent_command - 1]);
 726#endif
 727			break;
 728		case 0x00:	/* DATA OUT -- tmc18c50/tmc18c30 only */
 729			if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
 730				current_SC->SCp.have_data_in = -1;
 731				outb(0xd0 | PARITY_MASK, TMC_Cntl_port);
 732			}
 733			break;
 734		case 0x04:	/* DATA IN -- tmc18c50/tmc18c30 only */
 735			if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
 736				current_SC->SCp.have_data_in = 1;
 737				outb(0x90 | PARITY_MASK, TMC_Cntl_port);
 738			}
 739			break;
 740		case 0x0c:	/* STATUS IN */
 741			current_SC->SCp.Status = inb(Read_SCSI_Data_port);
 742#if EVERY_ACCESS
 743			printk("Status = %x, ", current_SC->SCp.Status);
 744#endif
 745#if ERRORS_ONLY
 746			if (current_SC->SCp.Status && current_SC->SCp.Status != 2 && current_SC->SCp.Status != 8) {
 747				printk("ERROR fd_mcs: target = %d, command = %x, status = %x\n", current_SC->device->id, current_SC->cmnd[0], current_SC->SCp.Status);
 748			}
 749#endif
 750			break;
 751		case 0x0a:	/* MESSAGE OUT */
 752			outb(MESSAGE_REJECT, Write_SCSI_Data_port);	/* Reject */
 753			break;
 754		case 0x0e:	/* MESSAGE IN */
 755			current_SC->SCp.Message = inb(Read_SCSI_Data_port);
 756#if EVERY_ACCESS
 757			printk("Message = %x, ", current_SC->SCp.Message);
 758#endif
 759			if (!current_SC->SCp.Message)
 760				++done;
 761#if DEBUG_MESSAGES || EVERY_ACCESS
 762			if (current_SC->SCp.Message) {
 763				printk("fd_mcs: message = %x\n", current_SC->SCp.Message);
 764			}
 765#endif
 766			break;
 767		}
 768	}
 769
 770	if (chip == tmc1800 && !current_SC->SCp.have_data_in && (current_SC->SCp.sent_command >= current_SC->cmd_len)) {
 771		/* We have to get the FIFO direction
 772		   correct, so I've made a table based
 773		   on the SCSI Standard of which commands
 774		   appear to require a DATA OUT phase.
 775		 */
 776		/*
 777		   p. 94: Command for all device types
 778		   CHANGE DEFINITION            40 DATA OUT
 779		   COMPARE                      39 DATA OUT
 780		   COPY                         18 DATA OUT
 781		   COPY AND VERIFY              3a DATA OUT
 782		   INQUIRY                      12 
 783		   LOG SELECT                   4c DATA OUT
 784		   LOG SENSE                    4d
 785		   MODE SELECT (6)              15 DATA OUT
 786		   MODE SELECT (10)             55 DATA OUT
 787		   MODE SENSE (6)               1a
 788		   MODE SENSE (10)              5a
 789		   READ BUFFER                  3c
 790		   RECEIVE DIAGNOSTIC RESULTS   1c
 791		   REQUEST SENSE                03
 792		   SEND DIAGNOSTIC              1d DATA OUT
 793		   TEST UNIT READY              00
 794		   WRITE BUFFER                 3b DATA OUT
 795
 796		   p.178: Commands for direct-access devices (not listed on p. 94)
 797		   FORMAT UNIT                  04 DATA OUT
 798		   LOCK-UNLOCK CACHE            36
 799		   PRE-FETCH                    34
 800		   PREVENT-ALLOW MEDIUM REMOVAL 1e
 801		   READ (6)/RECEIVE             08
 802		   READ (10)                    3c
 803		   READ CAPACITY                25
 804		   READ DEFECT DATA (10)        37
 805		   READ LONG                    3e
 806		   REASSIGN BLOCKS              07 DATA OUT
 807		   RELEASE                      17
 808		   RESERVE                      16 DATA OUT
 809		   REZERO UNIT/REWIND           01
 810		   SEARCH DATA EQUAL (10)       31 DATA OUT
 811		   SEARCH DATA HIGH (10)        30 DATA OUT
 812		   SEARCH DATA LOW (10)         32 DATA OUT
 813		   SEEK (6)                     0b
 814		   SEEK (10)                    2b
 815		   SET LIMITS (10)              33
 816		   START STOP UNIT              1b
 817		   SYNCHRONIZE CACHE            35
 818		   VERIFY (10)                  2f
 819		   WRITE (6)/PRINT/SEND         0a DATA OUT
 820		   WRITE (10)/SEND              2a DATA OUT
 821		   WRITE AND VERIFY (10)        2e DATA OUT
 822		   WRITE LONG                   3f DATA OUT
 823		   WRITE SAME                   41 DATA OUT ?
 824
 825		   p. 261: Commands for sequential-access devices (not previously listed)
 826		   ERASE                        19
 827		   LOAD UNLOAD                  1b
 828		   LOCATE                       2b
 829		   READ BLOCK LIMITS            05
 830		   READ POSITION                34
 831		   READ REVERSE                 0f
 832		   RECOVER BUFFERED DATA        14
 833		   SPACE                        11
 834		   WRITE FILEMARKS              10 ?
 835
 836		   p. 298: Commands for printer devices (not previously listed)
 837		   ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****
 838		   SLEW AND PRINT               0b DATA OUT  -- same as seek
 839		   STOP PRINT                   1b
 840		   SYNCHRONIZE BUFFER           10
 841
 842		   p. 315: Commands for processor devices (not previously listed)
 843
 844		   p. 321: Commands for write-once devices (not previously listed)
 845		   MEDIUM SCAN                  38
 846		   READ (12)                    a8
 847		   SEARCH DATA EQUAL (12)       b1 DATA OUT
 848		   SEARCH DATA HIGH (12)        b0 DATA OUT
 849		   SEARCH DATA LOW (12)         b2 DATA OUT
 850		   SET LIMITS (12)              b3
 851		   VERIFY (12)                  af
 852		   WRITE (12)                   aa DATA OUT
 853		   WRITE AND VERIFY (12)        ae DATA OUT
 854
 855		   p. 332: Commands for CD-ROM devices (not previously listed)
 856		   PAUSE/RESUME                 4b
 857		   PLAY AUDIO (10)              45
 858		   PLAY AUDIO (12)              a5
 859		   PLAY AUDIO MSF               47
 860		   PLAY TRACK RELATIVE (10)     49
 861		   PLAY TRACK RELATIVE (12)     a9
 862		   READ HEADER                  44
 863		   READ SUB-CHANNEL             42
 864		   READ TOC                     43
 865
 866		   p. 370: Commands for scanner devices (not previously listed)
 867		   GET DATA BUFFER STATUS       34
 868		   GET WINDOW                   25
 869		   OBJECT POSITION              31
 870		   SCAN                         1b
 871		   SET WINDOW                   24 DATA OUT
 872
 873		   p. 391: Commands for optical memory devices (not listed)
 874		   ERASE (10)                   2c
 875		   ERASE (12)                   ac
 876		   MEDIUM SCAN                  38 DATA OUT
 877		   READ DEFECT DATA (12)        b7
 878		   READ GENERATION              29
 879		   READ UPDATED BLOCK           2d
 880		   UPDATE BLOCK                 3d DATA OUT
 881
 882		   p. 419: Commands for medium changer devices (not listed)
 883		   EXCHANGE MEDIUM              46
 884		   INITIALIZE ELEMENT STATUS    07
 885		   MOVE MEDIUM                  a5
 886		   POSITION TO ELEMENT          2b
 887		   READ ELEMENT STATUS          b8
 888		   REQUEST VOL. ELEMENT ADDRESS b5
 889		   SEND VOLUME TAG              b6 DATA OUT
 890
 891		   p. 454: Commands for communications devices (not listed previously)
 892		   GET MESSAGE (6)              08
 893		   GET MESSAGE (10)             28
 894		   GET MESSAGE (12)             a8
 895		 */
 896
 897		switch (current_SC->cmnd[0]) {
 898		case CHANGE_DEFINITION:
 899		case COMPARE:
 900		case COPY:
 901		case COPY_VERIFY:
 902		case LOG_SELECT:
 903		case MODE_SELECT:
 904		case MODE_SELECT_10:
 905		case SEND_DIAGNOSTIC:
 906		case WRITE_BUFFER:
 907
 908		case FORMAT_UNIT:
 909		case REASSIGN_BLOCKS:
 910		case RESERVE:
 911		case SEARCH_EQUAL:
 912		case SEARCH_HIGH:
 913		case SEARCH_LOW:
 914		case WRITE_6:
 915		case WRITE_10:
 916		case WRITE_VERIFY:
 917		case 0x3f:
 918		case 0x41:
 919
 920		case 0xb1:
 921		case 0xb0:
 922		case 0xb2:
 923		case 0xaa:
 924		case 0xae:
 925
 926		case 0x24:
 927
 928		case 0x38:
 929		case 0x3d:
 930
 931		case 0xb6:
 932
 933		case 0xea:	/* alternate number for WRITE LONG */
 934
 935			current_SC->SCp.have_data_in = -1;
 936			outb(0xd0 | PARITY_MASK, TMC_Cntl_port);
 937			break;
 938
 939		case 0x00:
 940		default:
 941
 942			current_SC->SCp.have_data_in = 1;
 943			outb(0x90 | PARITY_MASK, TMC_Cntl_port);
 944			break;
 945		}
 946	}
 947
 948	if (current_SC->SCp.have_data_in == -1) {	/* DATA OUT */
 949		while ((data_count = FIFO_Size - inw(FIFO_Data_Count_port)) > 512) {
 950#if EVERY_ACCESS
 951			printk("DC=%d, ", data_count);
 952#endif
 953			if (data_count > current_SC->SCp.this_residual)
 954				data_count = current_SC->SCp.this_residual;
 955			if (data_count > 0) {
 956#if EVERY_ACCESS
 957				printk("%d OUT, ", data_count);
 958#endif
 959				if (data_count == 1) {
 960					Bytes_Written++;
 961
 962					outb(*current_SC->SCp.ptr++, Write_FIFO_port);
 963					--current_SC->SCp.this_residual;
 964				} else {
 965					data_count >>= 1;
 966					tmp_count = data_count << 1;
 967					outsw(Write_FIFO_port, current_SC->SCp.ptr, data_count);
 968					current_SC->SCp.ptr += tmp_count;
 969					Bytes_Written += tmp_count;
 970					current_SC->SCp.this_residual -= tmp_count;
 971				}
 972			}
 973			if (!current_SC->SCp.this_residual) {
 974				if (current_SC->SCp.buffers_residual) {
 975					--current_SC->SCp.buffers_residual;
 976					++current_SC->SCp.buffer;
 977					current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
 978					current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 979				} else
 980					break;
 981			}
 982		}
 983	} else if (current_SC->SCp.have_data_in == 1) {	/* DATA IN */
 984		while ((data_count = inw(FIFO_Data_Count_port)) > 0) {
 985#if EVERY_ACCESS
 986			printk("DC=%d, ", data_count);
 987#endif
 988			if (data_count > current_SC->SCp.this_residual)
 989				data_count = current_SC->SCp.this_residual;
 990			if (data_count) {
 991#if EVERY_ACCESS
 992				printk("%d IN, ", data_count);
 993#endif
 994				if (data_count == 1) {
 995					Bytes_Read++;
 996					*current_SC->SCp.ptr++ = inb(Read_FIFO_port);
 997					--current_SC->SCp.this_residual;
 998				} else {
 999					data_count >>= 1;	/* Number of words */
1000					tmp_count = data_count << 1;
1001					insw(Read_FIFO_port, current_SC->SCp.ptr, data_count);
1002					current_SC->SCp.ptr += tmp_count;
1003					Bytes_Read += tmp_count;
1004					current_SC->SCp.this_residual -= tmp_count;
1005				}
1006			}
1007			if (!current_SC->SCp.this_residual && current_SC->SCp.buffers_residual) {
1008				--current_SC->SCp.buffers_residual;
1009				++current_SC->SCp.buffer;
1010				current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
1011				current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1012			}
1013		}
1014	}
1015
1016	if (done) {
1017#if EVERY_ACCESS
1018		printk(" ** IN DONE %d ** ", current_SC->SCp.have_data_in);
1019#endif
1020
1021#if EVERY_ACCESS
1022		printk("BEFORE MY_DONE. . .");
1023#endif
1024		spin_lock_irqsave(shpnt->host_lock, flags);
1025		my_done(shpnt, (current_SC->SCp.Status & 0xff)
1026			| ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16));
1027		spin_unlock_irqrestore(shpnt->host_lock, flags);
1028#if EVERY_ACCESS
1029		printk("RETURNING.\n");
1030#endif
1031
1032	} else {
1033		if (current_SC->SCp.phase & disconnect) {
1034			outb(0xd0 | FIFO_COUNT, Interrupt_Cntl_port);
1035			outb(0x00, SCSI_Cntl_port);
1036		} else {
1037			outb(0x90 | FIFO_COUNT, Interrupt_Cntl_port);
1038		}
1039	}
1040#if DEBUG_RACE
1041	in_interrupt_flag = 0;
1042#endif
1043	return IRQ_HANDLED;
1044}
1045
1046static int fd_mcs_release(struct Scsi_Host *shpnt)
1047{
1048	int i, this_host, irq_usage;
1049
1050	release_region(shpnt->io_port, shpnt->n_io_port);
1051
1052	this_host = -1;
1053	irq_usage = 0;
1054	for (i = 0; i < found; i++) {
1055		if (shpnt == hosts[i])
1056			this_host = i;
1057		if (shpnt->irq == hosts[i]->irq)
1058			irq_usage++;
1059	}
1060
1061	/* only for the last one */
1062	if (1 == irq_usage)
1063		free_irq(shpnt->irq, hosts);
1064
1065	found--;
1066
1067	for (i = this_host; i < found; i++)
1068		hosts[i] = hosts[i + 1];
1069
1070	hosts[found] = NULL;
1071
1072	return 0;
1073}
1074
1075static int fd_mcs_queue_lck(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
1076{
1077	struct Scsi_Host *shpnt = SCpnt->device->host;
1078
1079	if (in_command) {
1080		panic("fd_mcs: fd_mcs_queue() NOT REENTRANT!\n");
1081	}
1082#if EVERY_ACCESS
1083	printk("queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1084		SCpnt->target, *(unsigned char *) SCpnt->cmnd,
1085		scsi_sg_count(SCpnt), scsi_bufflen(SCpnt));
1086#endif
1087
1088	fd_mcs_make_bus_idle(shpnt);
1089
1090	SCpnt->scsi_done = done;	/* Save this for the done function */
1091	current_SC = SCpnt;
1092
1093	/* Initialize static data */
1094
1095	if (scsi_bufflen(current_SC)) {
1096		current_SC->SCp.buffer = scsi_sglist(current_SC);
1097		current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
1098		current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1099		current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
1100	} else {
1101		current_SC->SCp.ptr = NULL;
1102		current_SC->SCp.this_residual = 0;
1103		current_SC->SCp.buffer = NULL;
1104		current_SC->SCp.buffers_residual = 0;
1105	}
1106
1107
1108	current_SC->SCp.Status = 0;
1109	current_SC->SCp.Message = 0;
1110	current_SC->SCp.have_data_in = 0;
1111	current_SC->SCp.sent_command = 0;
1112	current_SC->SCp.phase = in_arbitration;
1113
1114	/* Start arbitration */
1115	outb(0x00, Interrupt_Cntl_port);
1116	outb(0x00, SCSI_Cntl_port);	/* Disable data drivers */
1117	outb(adapter_mask, SCSI_Data_NoACK_port);	/* Set our id bit */
1118	in_command = 1;
1119	outb(0x20, Interrupt_Cntl_port);
1120	outb(0x14 | PARITY_MASK, TMC_Cntl_port);	/* Start arbitration */
1121
1122	return 0;
1123}
1124
1125static DEF_SCSI_QCMD(fd_mcs_queue)
1126
1127#if DEBUG_ABORT || DEBUG_RESET
1128static void fd_mcs_print_info(Scsi_Cmnd * SCpnt)
1129{
1130	unsigned int imr;
1131	unsigned int irr;
1132	unsigned int isr;
1133	struct Scsi_Host *shpnt = SCpnt->host;
1134
1135	if (!SCpnt || !SCpnt->host) {
1136		printk("fd_mcs: cannot provide detailed information\n");
1137	}
1138
1139	printk("%s\n", fd_mcs_info(SCpnt->host));
1140	print_banner(SCpnt->host);
1141	switch (SCpnt->SCp.phase) {
1142	case in_arbitration:
1143		printk("arbitration ");
1144		break;
1145	case in_selection:
1146		printk("selection ");
1147		break;
1148	case in_other:
1149		printk("other ");
1150		break;
1151	default:
1152		printk("unknown ");
1153		break;
1154	}
1155
1156	printk("(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1157		SCpnt->SCp.phase, SCpnt->device->id, *(unsigned char *) SCpnt->cmnd,
1158		scsi_sg_count(SCpnt), scsi_bufflen(SCpnt));
1159	printk("sent_command = %d, have_data_in = %d, timeout = %d\n", SCpnt->SCp.sent_command, SCpnt->SCp.have_data_in, SCpnt->timeout);
1160#if DEBUG_RACE
1161	printk("in_interrupt_flag = %d\n", in_interrupt_flag);
1162#endif
1163
1164	imr = (inb(0x0a1) << 8) + inb(0x21);
1165	outb(0x0a, 0xa0);
1166	irr = inb(0xa0) << 8;
1167	outb(0x0a, 0x20);
1168	irr += inb(0x20);
1169	outb(0x0b, 0xa0);
1170	isr = inb(0xa0) << 8;
1171	outb(0x0b, 0x20);
1172	isr += inb(0x20);
1173
1174	/* Print out interesting information */
1175	printk("IMR = 0x%04x", imr);
1176	if (imr & (1 << shpnt->irq))
1177		printk(" (masked)");
1178	printk(", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr);
1179
1180	printk("SCSI Status      = 0x%02x\n", inb(SCSI_Status_port));
1181	printk("TMC Status       = 0x%02x", inb(TMC_Status_port));
1182	if (inb(TMC_Status_port) & 1)
1183		printk(" (interrupt)");
1184	printk("\n");
1185	printk("Interrupt Status = 0x%02x", inb(Interrupt_Status_port));
1186	if (inb(Interrupt_Status_port) & 0x08)
1187		printk(" (enabled)");
1188	printk("\n");
1189	if (chip == tmc18c50 || chip == tmc18c30) {
1190		printk("FIFO Status      = 0x%02x\n", inb(shpnt->io_port + FIFO_Status));
1191		printk("Int. Condition   = 0x%02x\n", inb(shpnt->io_port + Interrupt_Cond));
1192	}
1193	printk("Configuration 1  = 0x%02x\n", inb(shpnt->io_port + Configuration1));
1194	if (chip == tmc18c50 || chip == tmc18c30)
1195		printk("Configuration 2  = 0x%02x\n", inb(shpnt->io_port + Configuration2));
1196}
1197#endif
1198
1199static int fd_mcs_abort(Scsi_Cmnd * SCpnt)
1200{
1201	struct Scsi_Host *shpnt = SCpnt->device->host;
1202
1203	unsigned long flags;
1204#if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1205	printk("fd_mcs: abort ");
1206#endif
1207
1208	spin_lock_irqsave(shpnt->host_lock, flags);
1209	if (!in_command) {
1210#if EVERY_ACCESS || ERRORS_ONLY
1211		printk(" (not in command)\n");
1212#endif
1213		spin_unlock_irqrestore(shpnt->host_lock, flags);
1214		return FAILED;
1215	} else
1216		printk("\n");
1217
1218#if DEBUG_ABORT
1219	fd_mcs_print_info(SCpnt);
1220#endif
1221
1222	fd_mcs_make_bus_idle(shpnt);
1223
1224	current_SC->SCp.phase |= aborted;
1225
1226	current_SC->result = DID_ABORT << 16;
1227
1228	/* Aborts are not done well. . . */
1229	my_done(shpnt, DID_ABORT << 16);
1230
1231	spin_unlock_irqrestore(shpnt->host_lock, flags);
1232	return SUCCESS;
1233}
1234
1235static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
1236	struct Scsi_Host *shpnt = SCpnt->device->host;
1237	unsigned long flags;
1238
1239#if DEBUG_RESET
1240	static int called_once = 0;
1241#endif
1242
1243#if ERRORS_ONLY
1244	if (SCpnt)
1245		printk("fd_mcs: SCSI Bus Reset\n");
1246#endif
1247
1248#if DEBUG_RESET
1249	if (called_once)
1250		fd_mcs_print_info(current_SC);
1251	called_once = 1;
1252#endif
1253
1254	spin_lock_irqsave(shpnt->host_lock, flags);
1255
1256	outb(1, SCSI_Cntl_port);
1257	do_pause(2);
1258	outb(0, SCSI_Cntl_port);
1259	do_pause(115);
1260	outb(0, SCSI_Mode_Cntl_port);
1261	outb(PARITY_MASK, TMC_Cntl_port);
1262
1263	spin_unlock_irqrestore(shpnt->host_lock, flags);
1264
1265	/* Unless this is the very first call (i.e., SCPnt == NULL), everything
1266	   is probably hosed at this point.  We will, however, try to keep
1267	   things going by informing the high-level code that we need help. */
1268		return SUCCESS;
1269}
1270
1271#include <scsi/scsi_ioctl.h>
1272
1273static int fd_mcs_biosparam(struct scsi_device * disk, struct block_device *bdev,
1274			    sector_t capacity, int *info_array) 
1275{
1276	unsigned char *p = scsi_bios_ptable(bdev);
1277	int size = capacity;
1278
1279	/* BIOS >= 3.4 for MCA cards */
1280	/* This algorithm was provided by Future Domain (much thanks!). */
1281
1282	if (p && p[65] == 0xaa && p[64] == 0x55	/* Partition table valid */
1283	    && p[4]) {	/* Partition type */
1284		/* The partition table layout is as follows:
1285
1286		   Start: 0x1b3h
1287		   Offset: 0 = partition status
1288		   1 = starting head
1289		   2 = starting sector and cylinder (word, encoded)
1290		   4 = partition type
1291		   5 = ending head
1292		   6 = ending sector and cylinder (word, encoded)
1293		   8 = starting absolute sector (double word)
1294		   c = number of sectors (double word)
1295		   Signature: 0x1fe = 0x55aa
1296
1297		   So, this algorithm assumes:
1298		   1) the first partition table is in use,
1299		   2) the data in the first entry is correct, and
1300		   3) partitions never divide cylinders
1301
1302		   Note that (1) may be FALSE for NetBSD (and other BSD flavors),
1303		   as well as for Linux.  Note also, that Linux doesn't pay any
1304		   attention to the fields that are used by this algorithm -- it
1305		   only uses the absolute sector data.  Recent versions of Linux's
1306		   fdisk(1) will fill this data in correctly, and forthcoming
1307		   versions will check for consistency.
1308
1309		   Checking for a non-zero partition type is not part of the
1310		   Future Domain algorithm, but it seemed to be a reasonable thing
1311		   to do, especially in the Linux and BSD worlds. */
1312
1313		info_array[0] = p[5] + 1;	/* heads */
1314		info_array[1] = p[6] & 0x3f;	/* sectors */
1315	} else {
1316		/* Note that this new method guarantees that there will always be
1317		   less than 1024 cylinders on a platter.  This is good for drives
1318		   up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
1319		if ((unsigned int) size >= 0x7e0000U) 
1320		{
1321			info_array[0] = 0xff;	/* heads   = 255 */
1322			info_array[1] = 0x3f;	/* sectors =  63 */
1323		} else if ((unsigned int) size >= 0x200000U) {
1324			info_array[0] = 0x80;	/* heads   = 128 */
1325			info_array[1] = 0x3f;	/* sectors =  63 */
1326		} else {
1327			info_array[0] = 0x40;	/* heads   =  64 */
1328			info_array[1] = 0x20;	/* sectors =  32 */
1329		}
1330	}
1331	/* For both methods, compute the cylinders */
1332	info_array[2] = (unsigned int) size / (info_array[0] * info_array[1]);
1333	kfree(p);
1334	return 0;
1335}
1336
1337static struct scsi_host_template driver_template = {
1338	.proc_name			= "fd_mcs",
1339	.proc_info			= fd_mcs_proc_info,
1340	.detect				= fd_mcs_detect,
1341	.release			= fd_mcs_release,
1342	.info				= fd_mcs_info,
1343	.queuecommand   		= fd_mcs_queue, 
1344	.eh_abort_handler		= fd_mcs_abort,
1345	.eh_bus_reset_handler		= fd_mcs_bus_reset,
1346	.bios_param     		= fd_mcs_biosparam,
1347	.can_queue      		= 1,
1348	.this_id        		= 7,
1349	.sg_tablesize   		= 64,
1350	.cmd_per_lun    		= 1,
1351	.use_clustering 		= DISABLE_CLUSTERING,
1352};
1353#include "scsi_module.c"
1354
1355MODULE_LICENSE("GPL");