• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/scsi/
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 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#ifdef NOT_USED
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) {
444						chip = tmc18c30;
445						FIFO_Size = 0x800;	/* 2k FIFO */
446
447						printk("FIRST: chip=%s, fifo_size=0x%x\n", (chip == tmc18c30) ? "tmc18c30" : "tmc18c50", FIFO_Size);
448					}
449				}
450
451				/* That should have worked, but appears to
452				   have problems.  Let's assume it is an
453				   18c30 if the RAM is disabled. */
454
455				if (inb(port + Configuration2) & 0x02) {
456					chip = tmc18c30;
457					FIFO_Size = 0x800;	/* 2k FIFO */
458
459					printk("SECOND: chip=%s, fifo_size=0x%x\n", (chip == tmc18c30) ? "tmc18c30" : "tmc18c50", FIFO_Size);
460				}
461				/* *************************************************** */
462#endif
463
464				/* IBM/ANSI scsi scan ordering */
465				/* Stick this back in when the scsi.c changes are there */
466				shpnt->reverse_ordering = 1;
467
468
469				/* saving info */
470				hosts[found++] = shpnt;
471
472				shpnt->this_id = id;
473				shpnt->irq = irq;
474				shpnt->io_port = port;
475				shpnt->n_io_port = 0x10;
476
477				/* save */
478				bios_base = bios;
479				adapter_mask = (1 << id);
480
481				/* save more */
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;
496
497				Bytes_Read = 0;
498				Bytes_Written = 0;
499				INTR_Processed = 0;
500
501				/* say something */
502				print_banner(shpnt);
503
504				/* reset */
505				outb(1, SCSI_Cntl_port);
506				do_pause(2);
507				outb(0, SCSI_Cntl_port);
508				do_pause(115);
509				outb(0, SCSI_Mode_Cntl_port);
510				outb(PARITY_MASK, TMC_Cntl_port);
511				/* done reset */
512			}
513		}
514
515		if (found == FD_MAX_HOSTS) {
516			printk("fd_mcs: detecting reached max=%d host adapters.\n", FD_MAX_HOSTS);
517			break;
518		}
519	}
520
521	return found;
522}
523
524static const char *fd_mcs_info(struct Scsi_Host *shpnt)
525{
526	return adapter_name;
527}
528
529static int TOTAL_INTR = 0;
530
531/*
532 * inout : decides on the direction of the dataflow and the meaning of the
533 *         variables
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
540 */
541static int fd_mcs_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, int inout)
542{
543	int len = 0;
544
545	if (inout)
546		return (-ENOSYS);
547
548	*start = buffer + offset;
549
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);
554
555	if ((len -= offset) <= 0)
556		return 0;
557	if (len > length)
558		len = length;
559	return len;
560}
561
562static int fd_mcs_select(struct Scsi_Host *shpnt, int target)
563{
564	int status;
565	unsigned long timeout;
566
567	outb(0x82, SCSI_Cntl_port);	/* Bus Enable + Select */
568	outb(adapter_mask | (1 << target), SCSI_Data_NoACK_port);
569
570	/* Stop arbitration and enable parity */
571	outb(PARITY_MASK, TMC_Cntl_port);
572
573	timeout = 350;		/* 350mS -- because of timeouts
574				   (was 250mS) */
575
576	do {
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);
581			return 0;
582		}
583		udelay(1000);	/* wait one msec */
584	} while (--timeout);
585
586	/* Make bus idle */
587	fd_mcs_make_bus_idle(shpnt);
588#if EVERY_ACCESS
589	if (!target)
590		printk("Selection failed\n");
591#endif
592#if ERRORS_ONLY
593	if (!target) {
594		static int flag = 0;
595
596		if (!flag)	/* Skip first failure for all chips. */
597			++flag;
598		else
599			printk("fd_mcs: Selection failed\n");
600	}
601#endif
602	return 1;
603}
604
605static void my_done(struct Scsi_Host *shpnt, int error)
606{
607	if (in_command) {
608		in_command = 0;
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);
613	} else {
614		panic("fd_mcs: my_done() called outside of command\n");
615	}
616#if DEBUG_RACE
617	in_interrupt_flag = 0;
618#endif
619}
620
621/* only my_done needs to be protected  */
622static irqreturn_t fd_mcs_intr(int irq, void *dev_id)
623{
624	unsigned long flags;
625	int status;
626	int done = 0;
627	unsigned data_count, tmp_count;
628
629	int i = 0;
630	struct Scsi_Host *shpnt;
631
632	TOTAL_INTR++;
633
634	/* search for one adapter-response on shared interrupt */
635	while ((shpnt = hosts[i++])) {
636		if ((inb(TMC_Status_port)) & 1)
637			break;
638	}
639
640	/* return if some other device on this IRQ caused the interrupt */
641	if (!shpnt) {
642		return IRQ_NONE;
643	}
644
645	INTR_Processed++;
646
647	outb(0x00, Interrupt_Cntl_port);
648
649	/* Abort calls my_done, so we do nothing here. */
650	if (current_SC->SCp.phase & aborted) {
651#if DEBUG_ABORT
652		printk("Interrupt after abort, ignoring\n");
653#endif
654		/* return IRQ_HANDLED; */
655	}
656#if DEBUG_RACE
657	++in_interrupt_flag;
658#endif
659
660	if (current_SC->SCp.phase & in_arbitration) {
661		status = inb(TMC_Status_port);	/* Read adapter status */
662		if (!(status & 0x02)) {
663#if EVERY_ACCESS
664			printk(" AFAIL ");
665#endif
666			spin_lock_irqsave(shpnt->host_lock, flags);
667			my_done(shpnt, DID_BUS_BUSY << 16);
668			spin_unlock_irqrestore(shpnt->host_lock, flags);
669			return IRQ_HANDLED;
670		}
671		current_SC->SCp.phase = in_selection;
672
673		outb(0x40 | FIFO_COUNT, Interrupt_Cntl_port);
674
675		outb(0x82, SCSI_Cntl_port);	/* Bus Enable + Select */
676		outb(adapter_mask | (1 << scmd_id(current_SC)), SCSI_Data_NoACK_port);
677
678		/* Stop arbitration and enable parity */
679		outb(0x10 | PARITY_MASK, TMC_Cntl_port);
680#if DEBUG_RACE
681		in_interrupt_flag = 0;
682#endif
683		return IRQ_HANDLED;
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))) {
689#if EVERY_ACCESS
690				printk(" SFAIL ");
691#endif
692				spin_lock_irqsave(shpnt->host_lock, flags);
693				my_done(shpnt, DID_NO_CONNECT << 16);
694				spin_unlock_irqrestore(shpnt->host_lock, flags);
695				return IRQ_HANDLED;
696			} else {
697#if EVERY_ACCESS
698				printk(" AltSel ");
699#endif
700				/* Stop arbitration and enable parity */
701				outb(0x10 | PARITY_MASK, TMC_Cntl_port);
702			}
703		}
704		current_SC->SCp.phase = in_other;
705		outb(0x90 | FIFO_COUNT, Interrupt_Cntl_port);
706		outb(0x80, SCSI_Cntl_port);
707#if DEBUG_RACE
708		in_interrupt_flag = 0;
709#endif
710		return IRQ_HANDLED;
711	}
712
713	/* current_SC->SCp.phase == in_other: this is the body of the routine */
714
715	status = inb(SCSI_Status_port);
716
717	if (status & 0x10) {	/* REQ */
718
719		switch (status & 0x0e) {
720
721		case 0x08:	/* COMMAND OUT */
722			outb(current_SC->cmnd[current_SC->SCp.sent_command++], Write_SCSI_Data_port);
723#if EVERY_ACCESS
724			printk("CMD = %x,", current_SC->cmnd[current_SC->SCp.sent_command - 1]);
725#endif
726			break;
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);
731			}
732			break;
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);
737			}
738			break;
739		case 0x0c:	/* STATUS IN */
740			current_SC->SCp.Status = inb(Read_SCSI_Data_port);
741#if EVERY_ACCESS
742			printk("Status = %x, ", current_SC->SCp.Status);
743#endif
744#if ERRORS_ONLY
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);
747			}
748#endif
749			break;
750		case 0x0a:	/* MESSAGE OUT */
751			outb(MESSAGE_REJECT, Write_SCSI_Data_port);	/* Reject */
752			break;
753		case 0x0e:	/* MESSAGE IN */
754			current_SC->SCp.Message = inb(Read_SCSI_Data_port);
755#if EVERY_ACCESS
756			printk("Message = %x, ", current_SC->SCp.Message);
757#endif
758			if (!current_SC->SCp.Message)
759				++done;
760#if DEBUG_MESSAGES || EVERY_ACCESS
761			if (current_SC->SCp.Message) {
762				printk("fd_mcs: message = %x\n", current_SC->SCp.Message);
763			}
764#endif
765			break;
766		}
767	}
768
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.
774		 */
775		/*
776		   p. 94: Command for all device types
777		   CHANGE DEFINITION            40 DATA OUT
778		   COMPARE                      39 DATA OUT
779		   COPY                         18 DATA OUT
780		   COPY AND VERIFY              3a DATA OUT
781		   INQUIRY                      12
782		   LOG SELECT                   4c DATA OUT
783		   LOG SENSE                    4d
784		   MODE SELECT (6)              15 DATA OUT
785		   MODE SELECT (10)             55 DATA OUT
786		   MODE SENSE (6)               1a
787		   MODE SENSE (10)              5a
788		   READ BUFFER                  3c
789		   RECEIVE DIAGNOSTIC RESULTS   1c
790		   REQUEST SENSE                03
791		   SEND DIAGNOSTIC              1d DATA OUT
792		   TEST UNIT READY              00
793		   WRITE BUFFER                 3b DATA OUT
794
795		   p.178: Commands for direct-access devices (not listed on p. 94)
796		   FORMAT UNIT                  04 DATA OUT
797		   LOCK-UNLOCK CACHE            36
798		   PRE-FETCH                    34
799		   PREVENT-ALLOW MEDIUM REMOVAL 1e
800		   READ (6)/RECEIVE             08
801		   READ (10)                    3c
802		   READ CAPACITY                25
803		   READ DEFECT DATA (10)        37
804		   READ LONG                    3e
805		   REASSIGN BLOCKS              07 DATA OUT
806		   RELEASE                      17
807		   RESERVE                      16 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
812		   SEEK (6)                     0b
813		   SEEK (10)                    2b
814		   SET LIMITS (10)              33
815		   START STOP UNIT              1b
816		   SYNCHRONIZE CACHE            35
817		   VERIFY (10)                  2f
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 ?
823
824		   p. 261: Commands for sequential-access devices (not previously listed)
825		   ERASE                        19
826		   LOAD UNLOAD                  1b
827		   LOCATE                       2b
828		   READ BLOCK LIMITS            05
829		   READ POSITION                34
830		   READ REVERSE                 0f
831		   RECOVER BUFFERED DATA        14
832		   SPACE                        11
833		   WRITE FILEMARKS              10 ?
834
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
838		   STOP PRINT                   1b
839		   SYNCHRONIZE BUFFER           10
840
841		   p. 315: Commands for processor devices (not previously listed)
842
843		   p. 321: Commands for write-once devices (not previously listed)
844		   MEDIUM SCAN                  38
845		   READ (12)                    a8
846		   SEARCH DATA EQUAL (12)       b1 DATA OUT
847		   SEARCH DATA HIGH (12)        b0 DATA OUT
848		   SEARCH DATA LOW (12)         b2 DATA OUT
849		   SET LIMITS (12)              b3
850		   VERIFY (12)                  af
851		   WRITE (12)                   aa DATA OUT
852		   WRITE AND VERIFY (12)        ae DATA OUT
853
854		   p. 332: Commands for CD-ROM devices (not previously listed)
855		   PAUSE/RESUME                 4b
856		   PLAY AUDIO (10)              45
857		   PLAY AUDIO (12)              a5
858		   PLAY AUDIO MSF               47
859		   PLAY TRACK RELATIVE (10)     49
860		   PLAY TRACK RELATIVE (12)     a9
861		   READ HEADER                  44
862		   READ SUB-CHANNEL             42
863		   READ TOC                     43
864
865		   p. 370: Commands for scanner devices (not previously listed)
866		   GET DATA BUFFER STATUS       34
867		   GET WINDOW                   25
868		   OBJECT POSITION              31
869		   SCAN                         1b
870		   SET WINDOW                   24 DATA OUT
871
872		   p. 391: Commands for optical memory devices (not listed)
873		   ERASE (10)                   2c
874		   ERASE (12)                   ac
875		   MEDIUM SCAN                  38 DATA OUT
876		   READ DEFECT DATA (12)        b7
877		   READ GENERATION              29
878		   READ UPDATED BLOCK           2d
879		   UPDATE BLOCK                 3d DATA OUT
880
881		   p. 419: Commands for medium changer devices (not listed)
882		   EXCHANGE MEDIUM              46
883		   INITIALIZE ELEMENT STATUS    07
884		   MOVE MEDIUM                  a5
885		   POSITION TO ELEMENT          2b
886		   READ ELEMENT STATUS          b8
887		   REQUEST VOL. ELEMENT ADDRESS b5
888		   SEND VOLUME TAG              b6 DATA OUT
889
890		   p. 454: Commands for communications devices (not listed previously)
891		   GET MESSAGE (6)              08
892		   GET MESSAGE (10)             28
893		   GET MESSAGE (12)             a8
894		 */
895
896		switch (current_SC->cmnd[0]) {
897		case CHANGE_DEFINITION:
898		case COMPARE:
899		case COPY:
900		case COPY_VERIFY:
901		case LOG_SELECT:
902		case MODE_SELECT:
903		case MODE_SELECT_10:
904		case SEND_DIAGNOSTIC:
905		case WRITE_BUFFER:
906
907		case FORMAT_UNIT:
908		case REASSIGN_BLOCKS:
909		case RESERVE:
910		case SEARCH_EQUAL:
911		case SEARCH_HIGH:
912		case SEARCH_LOW:
913		case WRITE_6:
914		case WRITE_10:
915		case WRITE_VERIFY:
916		case 0x3f:
917		case 0x41:
918
919		case 0xb1:
920		case 0xb0:
921		case 0xb2:
922		case 0xaa:
923		case 0xae:
924
925		case 0x24:
926
927		case 0x38:
928		case 0x3d:
929
930		case 0xb6:
931
932		case 0xea:	/* alternate number for WRITE LONG */
933
934			current_SC->SCp.have_data_in = -1;
935			outb(0xd0 | PARITY_MASK, TMC_Cntl_port);
936			break;
937
938		case 0x00:
939		default:
940
941			current_SC->SCp.have_data_in = 1;
942			outb(0x90 | PARITY_MASK, TMC_Cntl_port);
943			break;
944		}
945	}
946
947	if (current_SC->SCp.have_data_in == -1) {	/* DATA OUT */
948		while ((data_count = FIFO_Size - inw(FIFO_Data_Count_port)) > 512) {
949#if EVERY_ACCESS
950			printk("DC=%d, ", data_count);
951#endif
952			if (data_count > current_SC->SCp.this_residual)
953				data_count = current_SC->SCp.this_residual;
954			if (data_count > 0) {
955#if EVERY_ACCESS
956				printk("%d OUT, ", data_count);
957#endif
958				if (data_count == 1) {
959					Bytes_Written++;
960
961					outb(*current_SC->SCp.ptr++, Write_FIFO_port);
962					--current_SC->SCp.this_residual;
963				} else {
964					data_count >>= 1;
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;
970				}
971			}
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;
978				} else
979					break;
980			}
981		}
982	} else if (current_SC->SCp.have_data_in == 1) {	/* DATA IN */
983		while ((data_count = inw(FIFO_Data_Count_port)) > 0) {
984#if EVERY_ACCESS
985			printk("DC=%d, ", data_count);
986#endif
987			if (data_count > current_SC->SCp.this_residual)
988				data_count = current_SC->SCp.this_residual;
989			if (data_count) {
990#if EVERY_ACCESS
991				printk("%d IN, ", data_count);
992#endif
993				if (data_count == 1) {
994					Bytes_Read++;
995					*current_SC->SCp.ptr++ = inb(Read_FIFO_port);
996					--current_SC->SCp.this_residual;
997				} else {
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;
1004				}
1005			}
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;
1011			}
1012		}
1013	}
1014
1015	if (done) {
1016#if EVERY_ACCESS
1017		printk(" ** IN DONE %d ** ", current_SC->SCp.have_data_in);
1018#endif
1019
1020#if EVERY_ACCESS
1021		printk("BEFORE MY_DONE. . .");
1022#endif
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);
1027#if EVERY_ACCESS
1028		printk("RETURNING.\n");
1029#endif
1030
1031	} else {
1032		if (current_SC->SCp.phase & disconnect) {
1033			outb(0xd0 | FIFO_COUNT, Interrupt_Cntl_port);
1034			outb(0x00, SCSI_Cntl_port);
1035		} else {
1036			outb(0x90 | FIFO_COUNT, Interrupt_Cntl_port);
1037		}
1038	}
1039#if DEBUG_RACE
1040	in_interrupt_flag = 0;
1041#endif
1042	return IRQ_HANDLED;
1043}
1044
1045static int fd_mcs_release(struct Scsi_Host *shpnt)
1046{
1047	int i, this_host, irq_usage;
1048
1049	release_region(shpnt->io_port, shpnt->n_io_port);
1050
1051	this_host = -1;
1052	irq_usage = 0;
1053	for (i = 0; i < found; i++) {
1054		if (shpnt == hosts[i])
1055			this_host = i;
1056		if (shpnt->irq == hosts[i]->irq)
1057			irq_usage++;
1058	}
1059
1060	/* only for the last one */
1061	if (1 == irq_usage)
1062		free_irq(shpnt->irq, hosts);
1063
1064	found--;
1065
1066	for (i = this_host; i < found; i++)
1067		hosts[i] = hosts[i + 1];
1068
1069	hosts[found] = NULL;
1070
1071	return 0;
1072}
1073
1074static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
1075{
1076	struct Scsi_Host *shpnt = SCpnt->device->host;
1077
1078	if (in_command) {
1079		panic("fd_mcs: fd_mcs_queue() NOT REENTRANT!\n");
1080	}
1081#if EVERY_ACCESS
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));
1085#endif
1086
1087	fd_mcs_make_bus_idle(shpnt);
1088
1089	SCpnt->scsi_done = done;	/* Save this for the done function */
1090	current_SC = SCpnt;
1091
1092	/* Initialize static data */
1093
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;
1099	} else {
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;
1104	}
1105
1106
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;
1112
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 */
1117	in_command = 1;
1118	outb(0x20, Interrupt_Cntl_port);
1119	outb(0x14 | PARITY_MASK, TMC_Cntl_port);	/* Start arbitration */
1120
1121	return 0;
1122}
1123
1124#if DEBUG_ABORT || DEBUG_RESET
1125static void fd_mcs_print_info(Scsi_Cmnd * SCpnt)
1126{
1127	unsigned int imr;
1128	unsigned int irr;
1129	unsigned int isr;
1130	struct Scsi_Host *shpnt = SCpnt->host;
1131
1132	if (!SCpnt || !SCpnt->host) {
1133		printk("fd_mcs: cannot provide detailed information\n");
1134	}
1135
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 ");
1141		break;
1142	case in_selection:
1143		printk("selection ");
1144		break;
1145	case in_other:
1146		printk("other ");
1147		break;
1148	default:
1149		printk("unknown ");
1150		break;
1151	}
1152
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);
1157#if DEBUG_RACE
1158	printk("in_interrupt_flag = %d\n", in_interrupt_flag);
1159#endif
1160
1161	imr = (inb(0x0a1) << 8) + inb(0x21);
1162	outb(0x0a, 0xa0);
1163	irr = inb(0xa0) << 8;
1164	outb(0x0a, 0x20);
1165	irr += inb(0x20);
1166	outb(0x0b, 0xa0);
1167	isr = inb(0xa0) << 8;
1168	outb(0x0b, 0x20);
1169	isr += inb(0x20);
1170
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);
1176
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)");
1181	printk("\n");
1182	printk("Interrupt Status = 0x%02x", inb(Interrupt_Status_port));
1183	if (inb(Interrupt_Status_port) & 0x08)
1184		printk(" (enabled)");
1185	printk("\n");
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));
1189	}
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));
1193}
1194#endif
1195
1196static int fd_mcs_abort(Scsi_Cmnd * SCpnt)
1197{
1198	struct Scsi_Host *shpnt = SCpnt->device->host;
1199
1200	unsigned long flags;
1201#if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1202	printk("fd_mcs: abort ");
1203#endif
1204
1205	spin_lock_irqsave(shpnt->host_lock, flags);
1206	if (!in_command) {
1207#if EVERY_ACCESS || ERRORS_ONLY
1208		printk(" (not in command)\n");
1209#endif
1210		spin_unlock_irqrestore(shpnt->host_lock, flags);
1211		return FAILED;
1212	} else
1213		printk("\n");
1214
1215#if DEBUG_ABORT
1216	fd_mcs_print_info(SCpnt);
1217#endif
1218
1219	fd_mcs_make_bus_idle(shpnt);
1220
1221	current_SC->SCp.phase |= aborted;
1222
1223	current_SC->result = DID_ABORT << 16;
1224
1225	/* Aborts are not done well. . . */
1226	my_done(shpnt, DID_ABORT << 16);
1227
1228	spin_unlock_irqrestore(shpnt->host_lock, flags);
1229	return SUCCESS;
1230}
1231
1232static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
1233	struct Scsi_Host *shpnt = SCpnt->device->host;
1234	unsigned long flags;
1235
1236#if DEBUG_RESET
1237	static int called_once = 0;
1238#endif
1239
1240#if ERRORS_ONLY
1241	if (SCpnt)
1242		printk("fd_mcs: SCSI Bus Reset\n");
1243#endif
1244
1245#if DEBUG_RESET
1246	if (called_once)
1247		fd_mcs_print_info(current_SC);
1248	called_once = 1;
1249#endif
1250
1251	spin_lock_irqsave(shpnt->host_lock, flags);
1252
1253	outb(1, SCSI_Cntl_port);
1254	do_pause(2);
1255	outb(0, SCSI_Cntl_port);
1256	do_pause(115);
1257	outb(0, SCSI_Mode_Cntl_port);
1258	outb(PARITY_MASK, TMC_Cntl_port);
1259
1260	spin_unlock_irqrestore(shpnt->host_lock, flags);
1261
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. */
1265		return SUCCESS;
1266}
1267
1268#include <scsi/scsi_ioctl.h>
1269
1270static int fd_mcs_biosparam(struct scsi_device * disk, struct block_device *bdev,
1271			    sector_t capacity, int *info_array)
1272{
1273	unsigned char *p = scsi_bios_ptable(bdev);
1274	int size = capacity;
1275
1276	/* BIOS >= 3.4 for MCA cards */
1277	/* This algorithm was provided by Future Domain (much thanks!). */
1278
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:
1282
1283		   Start: 0x1b3h
1284		   Offset: 0 = partition status
1285		   1 = starting head
1286		   2 = starting sector and cylinder (word, encoded)
1287		   4 = partition type
1288		   5 = ending head
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
1293
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
1298
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.
1305
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. */
1309
1310		info_array[0] = p[5] + 1;	/* heads */
1311		info_array[1] = p[6] & 0x3f;	/* sectors */
1312	} else {
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)
1317		{
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 */
1323		} else {
1324			info_array[0] = 0x40;	/* heads   =  64 */
1325			info_array[1] = 0x20;	/* sectors =  32 */
1326		}
1327	}
1328	/* For both methods, compute the cylinders */
1329	info_array[2] = (unsigned int) size / (info_array[0] * info_array[1]);
1330	kfree(p);
1331	return 0;
1332}
1333
1334static 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,
1344	.can_queue      		= 1,
1345	.this_id        		= 7,
1346	.sg_tablesize   		= 64,
1347	.cmd_per_lun    		= 1,
1348	.use_clustering 		= DISABLE_CLUSTERING,
1349};
1350#include "scsi_module.c"
1351
1352MODULE_LICENSE("GPL");
1353