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