|
|
1.1 root 1: /* fdomain.c -- Future Domain TMC-16x0 SCSI driver
2: * Created: Sun May 3 18:53:19 1992 by [email protected]
3: * Revised: Sat Nov 2 09:27:47 1996 by [email protected]
4: * Author: Rickard E. Faith, [email protected]
5: * Copyright 1992, 1993, 1994, 1995, 1996 Rickard E. Faith
6: *
7: * $Id: fdomain.c,v 1.1 1999/04/26 05:54:32 tb Exp $
8:
9: * This program is free software; you can redistribute it and/or modify it
10: * under the terms of the GNU General Public License as published by the
11: * Free Software Foundation; either version 2, or (at your option) any
12: * later version.
13:
14: * This program is distributed in the hope that it will be useful, but
15: * WITHOUT ANY WARRANTY; without even the implied warranty of
16: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17: * General Public License for more details.
18:
19: * You should have received a copy of the GNU General Public License along
20: * with this program; if not, write to the Free Software Foundation, Inc.,
21: * 675 Mass Ave, Cambridge, MA 02139, USA.
22:
23: **************************************************************************
24:
25: SUMMARY:
26:
27: Future Domain BIOS versions supported for autodetect:
28: 2.0, 3.0, 3.2, 3.4 (1.0), 3.5 (2.0), 3.6, 3.61
29: Chips are supported:
30: TMC-1800, TMC-18C50, TMC-18C30, TMC-36C70
31: Boards supported:
32: Future Domain TMC-1650, TMC-1660, TMC-1670, TMC-1680, TMC-1610M/MER/MEX
33: Future Domain TMC-3260 (PCI)
34: Quantum ISA-200S, ISA-250MG
35: Adaptec AHA-2920 (PCI)
36: IBM ?
37: LILO command-line options:
38: fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]
39:
40:
41:
42: DESCRIPTION:
43:
44: This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
45: TMC-1650/1670, and TMC-3260 SCSI host adapters. The 1650 and 1670 have a
46: 25-pin external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin
47: high-density external connector. The 1670 and 1680 have floppy disk
48: controllers built in. The TMC-3260 is a PCI bus card.
49:
50: Future Domain's older boards are based on the TMC-1800 chip, and this
51: driver was originally written for a TMC-1680 board with the TMC-1800 chip.
52: More recently, boards are being produced with the TMC-18C50 and TMC-18C30
53: chips. The latest and greatest board may not work with this driver. If
54: you have to patch this driver so that it will recognize your board's BIOS
55: signature, then the driver may fail to function after the board is
56: detected.
57:
58: Please note that the drive ordering that Future Domain implemented in BIOS
59: versions 3.4 and 3.5 is the opposite of the order (currently) used by the
60: rest of the SCSI industry. If you have BIOS version 3.4 or 3.5, and have
61: more then one drive, then the drive ordering will be the reverse of that
62: which you see under DOS. For example, under DOS SCSI ID 0 will be D: and
63: SCSI ID 1 will be C: (the boot device). Under Linux, SCSI ID 0 will be
64: /dev/sda and SCSI ID 1 will be /dev/sdb. The Linux ordering is consistent
65: with that provided by all the other SCSI drivers for Linux. If you want
66: this changed, you will probably have to patch the higher level SCSI code.
67: If you do so, please send me patches that are protected by #ifdefs.
68:
69: If you have a TMC-8xx or TMC-9xx board, then this is not the driver for
70: your board. Please refer to the Seagate driver for more information and
71: possible support.
72:
73:
74:
75: HISTORY:
76:
77: Linux Driver Driver
78: Version Version Date Support/Notes
79:
80: 0.0 3 May 1992 V2.0 BIOS; 1800 chip
81: 0.97 1.9 28 Jul 1992
82: 0.98.6 3.1 27 Nov 1992
83: 0.99 3.2 9 Dec 1992
84:
85: 0.99.3 3.3 10 Jan 1993 V3.0 BIOS
86: 0.99.5 3.5 18 Feb 1993
87: 0.99.10 3.6 15 May 1993 V3.2 BIOS; 18C50 chip
88: 0.99.11 3.17 3 Jul 1993 (now under RCS)
89: 0.99.12 3.18 13 Aug 1993
90: 0.99.14 5.6 31 Oct 1993 (reselection code removed)
91:
92: 0.99.15 5.9 23 Jan 1994 V3.4 BIOS (preliminary)
93: 1.0.8/1.1.1 5.15 1 Apr 1994 V3.4 BIOS; 18C30 chip (preliminary)
94: 1.0.9/1.1.3 5.16 7 Apr 1994 V3.4 BIOS; 18C30 chip
95: 1.1.38 5.18 30 Jul 1994 36C70 chip (PCI version of 18C30)
96: 1.1.62 5.20 2 Nov 1994 V3.5 BIOS
97: 1.1.73 5.22 7 Dec 1994 Quantum ISA-200S board; V2.0 BIOS
98:
99: 1.1.82 5.26 14 Jan 1995 V3.5 BIOS; TMC-1610M/MER/MEX board
100: 1.2.10 5.28 5 Jun 1995 Quantum ISA-250MG board; V2.0, V2.01 BIOS
101: 1.3.4 5.31 23 Jun 1995 PCI BIOS-32 detection (preliminary)
102: 1.3.7 5.33 4 Jul 1995 PCI BIOS-32 detection
103: 1.3.28 5.36 17 Sep 1995 V3.61 BIOS; LILO command-line support
104: 1.3.34 5.39 12 Oct 1995 V3.60 BIOS; /proc
105: 1.3.72 5.39 8 Feb 1996 Adaptec AHA-2920 board
106: 1.3.85 5.41 4 Apr 1996
107: 2.0.12 5.44 8 Aug 1996 Use ID 7 for all PCI cards
108:
109:
110:
111: REFERENCES USED:
112:
113: "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation,
114: 1990.
115:
116: "Technical Reference Manual: 18C50 SCSI Host Adapter Chip", Future Domain
117: Corporation, January 1992.
118:
119: "LXT SCSI Products: Specifications and OEM Technical Manual (Revision
120: B/September 1991)", Maxtor Corporation, 1991.
121:
122: "7213S product Manual (Revision P3)", Maxtor Corporation, 1992.
123:
124: "Draft Proposed American National Standard: Small Computer System
125: Interface - 2 (SCSI-2)", Global Engineering Documents. (X3T9.2/86-109,
126: revision 10h, October 17, 1991)
127:
128: Private communications, Drew Eckhardt ([email protected]) and Eric
129: Youngdale ([email protected]), 1992.
130:
131: Private communication, Tuong Le (Future Domain Engineering department),
132: 1994. (Disk geometry computations for Future Domain BIOS version 3.4, and
133: TMC-18C30 detection.)
134:
135: Hogan, Thom. The Programmer's PC Sourcebook. Microsoft Press, 1988. Page
136: 60 (2.39: Disk Partition Table Layout).
137:
138: "18C30 Technical Reference Manual", Future Domain Corporation, 1993, page
139: 6-1.
140:
141:
142:
143: NOTES ON REFERENCES:
144:
145: The Maxtor manuals were free. Maxtor telephone technical support is
146: great!
147:
148: The Future Domain manuals were $25 and $35. They document the chip, not
149: the TMC-16x0 boards, so some information I had to guess at. In 1992,
150: Future Domain sold DOS BIOS source for $250 and the UN*X driver source was
151: $750, but these required a non-disclosure agreement, so even if I could
152: have afforded them, they would *not* have been useful for writing this
153: publically distributable driver. Future Domain technical support has
154: provided some information on the phone and have sent a few useful FAXs.
155: They have been much more helpful since they started to recognize that the
156: word "Linux" refers to an operating system :-).
157:
158:
159:
160: ALPHA TESTERS:
161:
162: There are many other alpha testers that come and go as the driver
163: develops. The people listed here were most helpful in times of greatest
164: need (mostly early on -- I've probably left out a few worthy people in
165: more recent times):
166:
167: Todd Carrico ([email protected]), Dan Poirier ([email protected] ), Ken
168: Corey ([email protected]), C. de Bruin (bruin@[email protected]), Sakari
169: Aaltonen ([email protected]), John Rice ([email protected]), Brad
170: Yearwood ([email protected]), and Ray Toy ([email protected]).
171:
172: Special thanks to Tien-Wan Yang ([email protected]), who graciously lent me
173: his 18C50-based card for debugging. He is the sole reason that this
174: driver works with the 18C50 chip.
175:
176: Thanks to Dave Newman ([email protected]) for providing initial patches for
177: the version 3.4 BIOS.
178:
179: Thanks to James T. McKinley ([email protected]) for providing
180: patches that support the TMC-3260, a PCI bus card with the 36C70 chip.
181: The 36C70 chip appears to be "completely compatible" with the 18C30 chip.
182:
183: Thanks to Eric Kasten ([email protected]) for providing the
184: patch for the version 3.5 BIOS.
185:
186: Thanks for Stephen Henson ([email protected]) for providing the
187: patch for the Quantum ISA-200S SCSI adapter.
188:
189: Thanks to Adam Bowen for the signature to the 1610M/MER/MEX scsi cards, to
190: Martin Andrews ([email protected]) for the signature to some
191: random TMC-1680 repackaged by IBM; and to Mintak Ng ([email protected]) for
192: the version 3.61 BIOS signature.
193:
194: Thanks for Mark Singer ([email protected]) and Richard Simpson
195: ([email protected]) for more Quantum signatures and detective
196: work on the Quantum RAM layout.
197:
198: Special thanks to James T. McKinley ([email protected]) for
199: providing patches for proper PCI BIOS32-mediated detection of the TMC-3260
200: card (a PCI bus card with the 36C70 chip). Please send James PCI-related
201: bug reports.
202:
203: Thanks to Tom Cavin ([email protected]) for preliminary command-line option
204: patches.
205:
206: All of the alpha testers deserve much thanks.
207:
208:
209:
210: NOTES ON USER DEFINABLE OPTIONS:
211:
212: DEBUG: This turns on the printing of various debug information.
213:
214: ENABLE_PARITY: This turns on SCSI parity checking. With the current
215: driver, all attached devices must support SCSI parity. If none of your
216: devices support parity, then you can probably get the driver to work by
217: turning this option off. I have no way of testing this, however, and it
218: would appear that no one ever uses this option.
219:
220: FIFO_COUNT: The host adapter has an 8K cache (host adapters based on the
221: 18C30 chip have a 2k cache). When this many 512 byte blocks are filled by
222: the SCSI device, an interrupt will be raised. Therefore, this could be as
223: low as 0, or as high as 16. Note, however, that values which are too high
224: or too low seem to prevent any interrupts from occurring, and thereby lock
225: up the machine. I have found that 2 is a good number, but throughput may
226: be increased by changing this value to values which are close to 2.
227: Please let me know if you try any different values.
228:
229: DO_DETECT: This activates some old scan code which was needed before the
230: high level drivers got fixed. If you are having trouble with the driver,
231: turning this on should not hurt, and might help. Please let me know if
232: this is the case, since this code will be removed from future drivers.
233:
234: RESELECTION: This is no longer an option, since I gave up trying to
235: implement it in version 4.x of this driver. It did not improve
236: performance at all and made the driver unstable (because I never found one
237: of the two race conditions which were introduced by the multiple
238: outstanding command code). The instability seems a very high price to pay
239: just so that you don't have to wait for the tape to rewind. If you want
240: this feature implemented, send me patches. I'll be happy to send a copy
241: of my (broken) driver to anyone who would like to see a copy.
242:
243: **************************************************************************/
244:
245: #ifdef PCMCIA
246: #define MODULE
247: #endif
248:
249: #ifdef MODULE
250: #include <linux/module.h>
251: #endif
252:
253: #ifdef PCMCIA
254: #undef MODULE
255: #endif
256:
257: #include <linux/sched.h>
258: #include <asm/io.h>
259: #include <linux/blk.h>
260: #include "scsi.h"
261: #include "hosts.h"
262: #include "fdomain.h"
263: #include <asm/system.h>
264: #include <linux/errno.h>
265: #include <linux/string.h>
266: #include <linux/ioport.h>
267: #include <linux/proc_fs.h>
268: #include <linux/bios32.h>
269: #include <linux/pci.h>
270: #include <linux/stat.h>
271:
272: #include <linux/config.h> /* for CONFIG_PCI */
273:
274: struct proc_dir_entry proc_scsi_fdomain = {
275: PROC_SCSI_FDOMAIN, 7, "fdomain",
276: S_IFDIR | S_IRUGO | S_IXUGO, 2
277: };
278:
279: #define VERSION "$Revision: 1.1 $"
280:
281: /* START OF USER DEFINABLE OPTIONS */
282:
283: #define DEBUG 1 /* Enable debugging output */
284: #define ENABLE_PARITY 1 /* Enable SCSI Parity */
285: #define FIFO_COUNT 2 /* Number of 512 byte blocks before INTR */
286: #define DO_DETECT 0 /* Do device detection here (see scsi.c) */
287:
288: /* END OF USER DEFINABLE OPTIONS */
289:
290: #if DEBUG
291: #define EVERY_ACCESS 0 /* Write a line on every scsi access */
292: #define ERRORS_ONLY 1 /* Only write a line if there is an error */
293: #define DEBUG_DETECT 0 /* Debug fdomain_16x0_detect() */
294: #define DEBUG_MESSAGES 1 /* Debug MESSAGE IN phase */
295: #define DEBUG_ABORT 1 /* Debug abort() routine */
296: #define DEBUG_RESET 1 /* Debug reset() routine */
297: #define DEBUG_RACE 1 /* Debug interrupt-driven race condition */
298: #else
299: #define EVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
300: #define ERRORS_ONLY 0
301: #define DEBUG_DETECT 0
302: #define DEBUG_MESSAGES 0
303: #define DEBUG_ABORT 0
304: #define DEBUG_RESET 0
305: #define DEBUG_RACE 0
306: #endif
307:
308: /* Errors are reported on the line, so we don't need to report them again */
309: #if EVERY_ACCESS
310: #undef ERRORS_ONLY
311: #define ERRORS_ONLY 0
312: #endif
313:
314: #if ENABLE_PARITY
315: #define PARITY_MASK 0x08
316: #else
317: #define PARITY_MASK 0x00
318: #endif
319:
320: enum chip_type {
321: unknown = 0x00,
322: tmc1800 = 0x01,
323: tmc18c50 = 0x02,
324: tmc18c30 = 0x03,
325: };
326:
327: enum {
328: in_arbitration = 0x02,
329: in_selection = 0x04,
330: in_other = 0x08,
331: disconnect = 0x10,
332: aborted = 0x20,
333: sent_ident = 0x40,
334: };
335:
336: enum in_port_type {
337: Read_SCSI_Data = 0,
338: SCSI_Status = 1,
339: TMC_Status = 2,
340: FIFO_Status = 3, /* tmc18c50/tmc18c30 only */
341: Interrupt_Cond = 4, /* tmc18c50/tmc18c30 only */
342: LSB_ID_Code = 5,
343: MSB_ID_Code = 6,
344: Read_Loopback = 7,
345: SCSI_Data_NoACK = 8,
346: Interrupt_Status = 9,
347: Configuration1 = 10,
348: Configuration2 = 11, /* tmc18c50/tmc18c30 only */
349: Read_FIFO = 12,
350: FIFO_Data_Count = 14
351: };
352:
353: enum out_port_type {
354: Write_SCSI_Data = 0,
355: SCSI_Cntl = 1,
356: Interrupt_Cntl = 2,
357: SCSI_Mode_Cntl = 3,
358: TMC_Cntl = 4,
359: Memory_Cntl = 5, /* tmc18c50/tmc18c30 only */
360: Write_Loopback = 7,
361: IO_Control = 11, /* tmc18c30 only */
362: Write_FIFO = 12
363: };
364:
365: static int port_base = 0;
366: static void *bios_base = NULL;
367: static int bios_major = 0;
368: static int bios_minor = 0;
369: static int PCI_bus = 0;
370: static int Quantum = 0; /* Quantum board variant */
371: static int interrupt_level = 0;
372: static volatile int in_command = 0;
373: static Scsi_Cmnd *current_SC = NULL;
374: static enum chip_type chip = unknown;
375: static int adapter_mask = 0;
376: static int this_id = 0;
377: static int setup_called = 0;
378:
379: #if DEBUG_RACE
380: static volatile int in_interrupt_flag = 0;
381: #endif
382:
383: static int SCSI_Mode_Cntl_port;
384: static int FIFO_Data_Count_port;
385: static int Interrupt_Cntl_port;
386: static int Interrupt_Status_port;
387: static int Read_FIFO_port;
388: static int Read_SCSI_Data_port;
389: static int SCSI_Cntl_port;
390: static int SCSI_Data_NoACK_port;
391: static int SCSI_Status_port;
392: static int TMC_Cntl_port;
393: static int TMC_Status_port;
394: static int Write_FIFO_port;
395: static int Write_SCSI_Data_port;
396:
397: static int FIFO_Size = 0x2000; /* 8k FIFO for
398: pre-tmc18c30 chips */
399:
400: extern void fdomain_16x0_intr( int irq, void *dev_id, struct pt_regs * regs );
401:
402: static void *addresses[] = {
403: (void *)0xc8000,
404: (void *)0xca000,
405: (void *)0xce000,
406: (void *)0xde000,
407: (void *)0xcc000, /* Extra addresses for PCI boards */
408: (void *)0xd0000,
409: (void *)0xe0000,
410: };
411: #define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
412:
413: static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
414: #define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short ))
415:
416: static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
417:
418: /*
419:
420: READ THIS BEFORE YOU ADD A SIGNATURE!
421:
422: READING THIS SHORT NOTE CAN SAVE YOU LOTS OF TIME!
423:
424: READ EVERY WORD, ESPECIALLY THE WORD *NOT*
425:
426: This driver works *ONLY* for Future Domain cards using the TMC-1800,
427: TMC-18C50, or TMC-18C30 chip. This includes models TMC-1650, 1660, 1670,
428: and 1680.
429:
430: The following BIOS signature signatures are for boards which do *NOT*
431: work with this driver (these TMC-8xx and TMC-9xx boards may work with the
432: Seagate driver):
433:
434: FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88
435: FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89
436: FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89
437: FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90
438: FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90
439: FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90
440: FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92
441:
442: */
443:
444: struct signature {
445: const char *signature;
446: int sig_offset;
447: int sig_length;
448: int major_bios_version;
449: int minor_bios_version;
450: int flag; /* 1 == PCI_bus, 2 == ISA_200S, 3 == ISA_250MG, 4 == ISA_200S */
451: } signatures[] = {
452: /* 1 2 3 4 5 6 */
453: /* 123456789012345678901234567890123456789012345678901234567890 */
454: { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 5, 50, 2, 0, 0 },
455: { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89", 5, 50, 2, 0, 0 },
456: { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50, 2, 0, 2 },
457: { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0", 73, 43, 2, 0, 3 },
458: { "FUTURE DOMAIN CORP. (C) 1991 1800-V2.0.", 72, 39, 2, 0, 4 },
459: { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92", 5, 44, 3, 0, 0 },
460: { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93", 5, 44, 3, 2, 0 },
461: { "IBM F1 P2 BIOS v1.0104/29/93", 5, 28, 3, -1, 0 },
462: { "Future Domain Corp. V1.0008/18/93", 5, 33, 3, 4, 0 },
463: { "Future Domain Corp. V1.0008/18/93", 26, 33, 3, 4, 1 },
464: { "Adaptec AHA-2920 PCI-SCSI Card", 42, 31, 3, -1, 1 },
465: { "IBM F1 P264/32", 5, 14, 3, -1, 1 },
466: /* This next signature may not be a 3.5 bios */
467: { "Future Domain Corp. V2.0108/18/93", 5, 33, 3, 5, 0 },
468: { "FUTURE DOMAIN CORP. V3.5008/18/93", 5, 34, 3, 5, 0 },
469: { "FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5", 5, 44, 3, 5, 0 },
470: { "FUTURE DOMAIN CORP. V3.6008/18/93", 5, 34, 3, 6, 0 },
471: { "FUTURE DOMAIN CORP. V3.6108/18/93", 5, 34, 3, 6, 0 },
472: { "FUTURE DOMAIN TMC-18XX", 5, 22, -1, -1, 0 },
473:
474: /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGNATURE
475: Also, fix the disk geometry code for your signature and send your
476: changes for [email protected]. Above all, do *NOT* change any old
477: signatures!
478:
479: Note that the last line will match a "generic" 18XX bios. Because
480: Future Domain has changed the host SCSI ID and/or the location of the
481: geometry information in the on-board RAM area for each of the first
482: three BIOS's, it is still important to enter a fully qualified
483: signature in the table for any new BIOS's (after the host SCSI ID and
484: geometry location are verified). */
485: };
486:
487: #define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
488:
489: static void print_banner( struct Scsi_Host *shpnt )
490: {
491: if (!shpnt) return; /* This won't ever happen */
492:
493: if (bios_major < 0 && bios_minor < 0) {
494: printk( "scsi%d <fdomain>: No BIOS; using scsi id %d\n",
495: shpnt->host_no, shpnt->this_id );
496: } else {
497: printk( "scsi%d <fdomain>: BIOS version ", shpnt->host_no );
498:
499: if (bios_major >= 0) printk( "%d.", bios_major );
500: else printk( "?." );
501:
502: if (bios_minor >= 0) printk( "%d", bios_minor );
503: else printk( "?." );
504:
505: printk( " at 0x%x using scsi id %d\n",
506: (unsigned)bios_base, shpnt->this_id );
507: }
508:
509: /* If this driver works for later FD PCI
510: boards, we will have to modify banner
511: for additional PCI cards, but for now if
512: it's PCI it's a TMC-3260 - JTM */
513: printk( "scsi%d <fdomain>: %s chip at 0x%x irq ",
514: shpnt->host_no,
515: chip == tmc1800 ? "TMC-1800"
516: : (chip == tmc18c50 ? "TMC-18C50"
517: : (chip == tmc18c30 ?
518: (PCI_bus ? "TMC-36C70 (PCI bus)" : "TMC-18C30")
519: : "Unknown")),
520: port_base );
521:
522: if (interrupt_level) printk( "%d", interrupt_level );
523: else printk( "<none>" );
524:
525: printk( "\n" );
526: }
527:
528: void fdomain_setup( char *str, int *ints )
529: {
530: if (setup_called++ || ints[0] < 2 || ints[0] > 3) {
531: printk( "fdomain: usage: fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]\n" );
532: printk( "fdomain: bad LILO parameters?\n" );
533: }
534:
535: port_base = ints[0] >= 1 ? ints[1] : 0;
536: interrupt_level = ints[0] >= 2 ? ints[2] : 0;
537: this_id = ints[0] >= 3 ? ints[3] : 0;
538:
539: bios_major = bios_minor = -1; /* Use geometry for BIOS version >= 3.4 */
540: }
541:
542:
543: static void do_pause( unsigned amount ) /* Pause for amount*10 milliseconds */
544: {
545: unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */
546:
547: while (jiffies < the_time);
548: }
549:
550: inline static void fdomain_make_bus_idle( void )
551: {
552: outb( 0, SCSI_Cntl_port );
553: outb( 0, SCSI_Mode_Cntl_port );
554: if (chip == tmc18c50 || chip == tmc18c30)
555: outb( 0x21 | PARITY_MASK, TMC_Cntl_port ); /* Clear forced intr. */
556: else
557: outb( 0x01 | PARITY_MASK, TMC_Cntl_port );
558: }
559:
560: static int fdomain_is_valid_port( int port )
561: {
562: #if DEBUG_DETECT
563: printk( " (%x%x),",
564: inb( port + MSB_ID_Code ), inb( port + LSB_ID_Code ) );
565: #endif
566:
567: /* The MCA ID is a unique id for each MCA compatible board. We
568: are using ISA boards, but Future Domain provides the MCA ID
569: anyway. We can use this ID to ensure that this is a Future
570: Domain TMC-1660/TMC-1680.
571: */
572:
573: if (inb( port + LSB_ID_Code ) != 0xe9) { /* test for 0x6127 id */
574: if (inb( port + LSB_ID_Code ) != 0x27) return 0;
575: if (inb( port + MSB_ID_Code ) != 0x61) return 0;
576: chip = tmc1800;
577: } else { /* test for 0xe960 id */
578: if (inb( port + MSB_ID_Code ) != 0x60) return 0;
579: chip = tmc18c50;
580:
581: #if 0
582:
583: /* Try to toggle 32-bit mode. This only
584: works on an 18c30 chip. (User reports
585: say this works, so we should switch to
586: it in the near future.) */
587:
588: outb( 0x80, port + IO_Control );
589: if ((inb( port + Configuration2 ) & 0x80) == 0x80) {
590: outb( 0x00, port + IO_Control );
591: if ((inb( port + Configuration2 ) & 0x80) == 0x00) {
592: chip = tmc18c30;
593: FIFO_Size = 0x800; /* 2k FIFO */
594: }
595: }
596: #else
597:
598: /* That should have worked, but appears to
599: have problems. Let's assume it is an
600: 18c30 if the RAM is disabled. */
601:
602: if (inb( port + Configuration2 ) & 0x02) {
603: chip = tmc18c30;
604: FIFO_Size = 0x800; /* 2k FIFO */
605: }
606: #endif
607: /* If that failed, we are an 18c50. */
608: }
609:
610: return 1;
611: }
612:
613: static int fdomain_test_loopback( void )
614: {
615: int i;
616: int result;
617:
618: for (i = 0; i < 255; i++) {
619: outb( i, port_base + Write_Loopback );
620: result = inb( port_base + Read_Loopback );
621: if (i != result)
622: return 1;
623: }
624: return 0;
625: }
626:
627: /* fdomain_get_irq assumes that we have a valid MCA ID for a
628: TMC-1660/TMC-1680 Future Domain board. Now, check to be sure the
629: bios_base matches these ports. If someone was unlucky enough to have
630: purchased more than one Future Domain board, then they will have to
631: modify this code, as we only detect one board here. [The one with the
632: lowest bios_base.]
633:
634: Note that this routine is only used for systems without a PCI BIOS32
635: (e.g., ISA bus). For PCI bus systems, this routine will likely fail
636: unless one of the IRQs listed in the ints array is used by the board.
637: Sometimes it is possible to use the computer's BIOS setup screen to
638: configure a PCI system so that one of these IRQs will be used by the
639: Future Domain card. */
640:
641: static int fdomain_get_irq( int base )
642: {
643: int options = inb( base + Configuration1 );
644:
645: #if DEBUG_DETECT
646: printk( " Options = %x\n", options );
647: #endif
648:
649: /* Check for board with lowest bios_base --
650: this isn't valid for the 18c30 or for
651: boards on the PCI bus, so just assume we
652: have the right board. */
653:
654: if (chip != tmc18c30
655: && !PCI_bus
656: && addresses[ (options & 0xc0) >> 6 ] != bios_base) return 0;
657:
658: return ints[ (options & 0x0e) >> 1 ];
659: }
660:
661: static int fdomain_isa_detect( int *irq, int *iobase )
662: {
663: int i;
664: int base;
665: int flag = 0;
666:
667: if (bios_major == 2) {
668: /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM.
669: Assuming the ROM is enabled (otherwise we wouldn't have been
670: able to read the ROM signature :-), then the ROM sets up the
671: RAM area with some magic numbers, such as a list of port
672: base addresses and a list of the disk "geometry" reported to
673: DOS (this geometry has nothing to do with physical geometry).
674: */
675:
676: switch (Quantum) {
677: case 2: /* ISA_200S */
678: case 3: /* ISA_250MG */
679: base = *((char *)bios_base + 0x1fa2)
680: + (*((char *)bios_base + 0x1fa3) << 8);
681: break;
682: case 4: /* ISA_200S (another one) */
683: base = *((char *)bios_base + 0x1fa3)
684: + (*((char *)bios_base + 0x1fa4) << 8);
685: break;
686: default:
687: base = *((char *)bios_base + 0x1fcc)
688: + (*((char *)bios_base + 0x1fcd) << 8);
689: break;
690: }
691:
692: #if DEBUG_DETECT
693: printk( " %x,", base );
694: #endif
695:
696: for (flag = 0, i = 0; !flag && i < PORT_COUNT; i++) {
697: if (base == ports[i])
698: ++flag;
699: }
700:
701: if (flag && fdomain_is_valid_port( base )) {
702: *irq = fdomain_get_irq( base );
703: *iobase = base;
704: return 1;
705: }
706:
707: /* This is a bad sign. It usually means that someone patched the
708: BIOS signature list (the signatures variable) to contain a BIOS
709: signature for a board *OTHER THAN* the TMC-1660/TMC-1680. */
710:
711: #if DEBUG_DETECT
712: printk( " RAM FAILED, " );
713: #endif
714: }
715:
716: /* Anyway, the alternative to finding the address in the RAM is to just
717: search through every possible port address for one that is attached
718: to the Future Domain card. Don't panic, though, about reading all
719: these random port addresses -- there are rumors that the Future
720: Domain BIOS does something very similar.
721:
722: Do not, however, check ports which the kernel knows are being used by
723: another driver. */
724:
725: for (i = 0; i < PORT_COUNT; i++) {
726: base = ports[i];
727: if (check_region( base, 0x10 )) {
728: #if DEBUG_DETECT
729: printk( " (%x inuse),", base );
730: #endif
731: continue;
732: }
733: #if DEBUG_DETECT
734: printk( " %x,", base );
735: #endif
736: if ((flag = fdomain_is_valid_port( base ))) break;
737: }
738:
739: if (!flag) return 0; /* iobase not found */
740:
741: *irq = fdomain_get_irq( base );
742: *iobase = base;
743:
744: return 1; /* success */
745: }
746:
747: static int fdomain_pci_nobios_detect( int *irq, int *iobase )
748: {
749: int i;
750: int flag = 0;
751:
752: /* The proper way of doing this is to use ask the PCI bus for the device
753: IRQ and interrupt level. But we can't do that if PCI BIOS32 support
754: isn't compiled into the kernel, or if a PCI BIOS32 isn't present.
755:
756: Instead, we scan down a bunch of addresses (Future Domain tech
757: support says we will probably find the address before we get to
758: 0xf800). This works fine on some systems -- other systems may have
759: to scan more addresses. If you have to modify this section for your
760: installation, please send mail to [email protected]. */
761:
762: for (i = 0xfff8; i > 0xe000; i -= 8) {
763: if (check_region( i, 0x10 )) {
764: #if DEBUG_DETECT
765: printk( " (%x inuse)," , i );
766: #endif
767: continue;
768: }
769: if ((flag = fdomain_is_valid_port( i ))) break;
770: }
771:
772: if (!flag) return 0; /* iobase not found */
773:
774: *irq = fdomain_get_irq( i );
775: *iobase = i;
776:
777: return 1; /* success */
778: }
779:
780: /* PCI detection function: int fdomain_pci_bios_detect(int* irq, int*
781: iobase) This function gets the Interrupt Level and I/O base address from
782: the PCI configuration registers. The I/O base address is masked with
783: 0xfff8 since on my card the address read from the PCI config registers
784: is off by one from the actual I/O base address necessary for accessing
785: the status and control registers on the card (PCI config register gives
786: 0xf801, actual address is 0xf800). This is likely a bug in the FD
787: config code that writes to the PCI registers, however using a mask
788: should be safe since I think the scan done by the card to determine the
789: I/O base is done in increments of 8 (i.e., 0xf800, 0xf808, ...), at
790: least the old scan code we used to use to get the I/O base did... Also,
791: the device ID from the PCI config registers is 0x0 and should be 0x60e9
792: as it is in the status registers (offset 5 from I/O base). If this is
793: changed in future hardware/BIOS changes it will need to be fixed in this
794: detection function. Comments, bug reports, etc... on this function
795: should be sent to [email protected] - James T. McKinley. */
796:
797: #ifdef CONFIG_PCI
798: static int fdomain_pci_bios_detect( int *irq, int *iobase )
799: {
800: int error;
801: unsigned char pci_bus, pci_dev_fn; /* PCI bus & device function */
802: unsigned char pci_irq; /* PCI interrupt line */
803: unsigned int pci_base; /* PCI I/O base address */
804: unsigned short pci_vendor, pci_device; /* PCI vendor & device IDs */
805:
806: /* If the PCI BIOS doesn't exist, use the old-style detection routines.
807: Otherwise, get the I/O base address and interrupt from the PCI config
808: registers. */
809:
810: if (!pcibios_present()) return fdomain_pci_nobios_detect( irq, iobase );
811:
812: #if DEBUG_DETECT
813: /* Tell how to print a list of the known PCI devices from bios32 and
814: list vendor and device IDs being used if in debug mode. */
815:
816: printk( "\nINFO: cat /proc/pci to see list of PCI devices from bios32\n" );
817: printk( "\nTMC-3260 detect:"
818: " Using PCI Vendor ID: 0x%x, PCI Device ID: 0x%x\n",
819: PCI_VENDOR_ID_FD,
820: PCI_DEVICE_ID_FD_36C70 );
821: #endif
822:
823: /* We will have to change this if more than 1 PCI bus is present and the
824: FD scsi host is not on the first bus (i.e., a PCI to PCI bridge,
825: which is not supported by bios32 right now anyway). This should
826: probably be done by a call to pcibios_find_device but I can't get it
827: to work... Also the device ID reported from the PCI config registers
828: does not match the device ID quoted in the tech manual or available
829: from offset 5 from the I/O base address. It should be 0x60E9, but it
830: is 0x0 if read from the PCI config registers. I guess the FD folks
831: neglected to write it to the PCI registers... This loop is necessary
832: to get the device function (at least until someone can get
833: pcibios_find_device to work, I cannot but 53c7,8xx.c uses it...). */
834:
835: pci_bus = 0;
836:
837: for (pci_dev_fn = 0x0; pci_dev_fn < 0xff; pci_dev_fn++) {
838: pcibios_read_config_word( pci_bus,
839: pci_dev_fn,
840: PCI_VENDOR_ID,
841: &pci_vendor );
842:
843: if (pci_vendor == PCI_VENDOR_ID_FD) {
844: pcibios_read_config_word( pci_bus,
845: pci_dev_fn,
846: PCI_DEVICE_ID,
847: &pci_device );
848:
849: if (pci_device == PCI_DEVICE_ID_FD_36C70) {
850: /* Break out once we have the correct device. If other FD
851: PCI devices are added to this driver we will need to add
852: an or of the other PCI_DEVICE_ID_FD_XXXXX's here. */
853: break;
854: } else {
855: /* If we can't find an FD scsi card we give up. */
856: return 0;
857: }
858: }
859: }
860:
861: #if DEBUG_DETECT
862: printk( "Future Domain 36C70 : at PCI bus %u, device %u, function %u\n",
863: pci_bus,
864: (pci_dev_fn & 0xf8) >> 3,
865: pci_dev_fn & 7 );
866: #endif
867:
868: /* We now have the appropriate device function for the FD board so we
869: just read the PCI config info from the registers. */
870:
871: if ((error = pcibios_read_config_dword( pci_bus,
872: pci_dev_fn,
873: PCI_BASE_ADDRESS_0,
874: &pci_base ))
875: || (error = pcibios_read_config_byte( pci_bus,
876: pci_dev_fn,
877: PCI_INTERRUPT_LINE,
878: &pci_irq ))) {
879: printk ( "PCI ERROR: Future Domain 36C70 not initializing"
880: " due to error reading configuration space\n" );
881: return 0;
882: } else {
883: #if DEBUG_DETECT
884: printk( "TMC-3260 PCI: IRQ = %u, I/O base = 0x%lx\n",
885: pci_irq, pci_base );
886: #endif
887:
888: /* Now we have the I/O base address and interrupt from the PCI
889: configuration registers. Unfortunately it seems that the I/O base
890: address is off by one on my card so I mask it with 0xfff8. This
891: must be some kind of goof in the FD code that does the autoconfig
892: and writes to the PCI registers (or maybe I just don't understand
893: something). If they fix it in later versions of the card or BIOS
894: we may have to adjust the address based on the signature or
895: something... */
896:
897: *irq = pci_irq;
898: *iobase = (pci_base & 0xfff8);
899:
900: #if DEBUG_DETECT
901: printk( "TMC-3260 fix: Masking I/O base address with 0xff00.\n" );
902: printk( "TMC-3260: IRQ = %d, I/O base = 0x%x\n", *irq, *iobase );
903: #endif
904:
905: if (!fdomain_is_valid_port( *iobase )) return 0;
906: return 1;
907: }
908: return 0;
909: }
910: #endif
911:
912: int fdomain_16x0_detect( Scsi_Host_Template *tpnt )
913: {
914: int i, j;
915: int retcode;
916: struct Scsi_Host *shpnt;
917: #if DO_DETECT
918: const int buflen = 255;
919: Scsi_Cmnd SCinit;
920: unsigned char do_inquiry[] = { INQUIRY, 0, 0, 0, buflen, 0 };
921: unsigned char do_request_sense[] = { REQUEST_SENSE, 0, 0, 0, buflen, 0 };
922: unsigned char do_read_capacity[] = { READ_CAPACITY,
923: 0, 0, 0, 0, 0, 0, 0, 0, 0 };
924: unsigned char buf[buflen];
925: #endif
926:
927: #if DEBUG_DETECT
928: printk( "fdomain_16x0_detect()," );
929: #endif
930: tpnt->proc_dir = &proc_scsi_fdomain;
931:
932: if (setup_called) {
933: #if DEBUG_DETECT
934: printk( "no BIOS, using port_base = 0x%x, irq = %d\n",
935: port_base, interrupt_level );
936: #endif
937: if (!fdomain_is_valid_port( port_base )) {
938: printk( "fdomain: cannot locate chip at port base 0x%x\n",
939: port_base );
940: printk( "fdomain: bad LILO parameters?\n" );
941: return 0;
942: }
943: } else {
944: int flag = 0;
945:
946: for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) {
947: #if DEBUG_DETECT
948: printk( " %x(%x),", (unsigned)addresses[i], (unsigned)bios_base );
949: #endif
950: for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) {
951: if (!memcmp( ((char *)addresses[i] + signatures[j].sig_offset),
952: signatures[j].signature, signatures[j].sig_length )) {
953: bios_major = signatures[j].major_bios_version;
954: bios_minor = signatures[j].minor_bios_version;
955: PCI_bus = (signatures[j].flag == 1);
956: Quantum = (signatures[j].flag > 1) ? signatures[j].flag : 0;
957: bios_base = addresses[i];
958: }
959: }
960: }
961:
962: if (!bios_base) {
963: #if DEBUG_DETECT
964: printk( " FAILED: NO BIOS\n" );
965: #endif
966: return 0;
967: }
968:
969: if (!PCI_bus) {
970: flag = fdomain_isa_detect( &interrupt_level, &port_base );
971: } else {
972: #ifdef CONFIG_PCI
973: flag = fdomain_pci_bios_detect( &interrupt_level, &port_base );
974: #else
975: flag = fdomain_pci_nobios_detect( &interrupt_level, &port_base );
976: #endif
977: }
978:
979: if (!flag) {
980: #if DEBUG_DETECT
981: printk( " FAILED: NO PORT\n" );
982: #endif
983: #ifdef CONFIG_PCI
984: printk( "\nTMC-3260 36C70 PCI scsi chip detection failed.\n" );
985: printk( "Send mail to [email protected].\n" );
986: #endif
987: return 0; /* Cannot find valid set of ports */
988: }
989: }
990:
991: SCSI_Mode_Cntl_port = port_base + SCSI_Mode_Cntl;
992: FIFO_Data_Count_port = port_base + FIFO_Data_Count;
993: Interrupt_Cntl_port = port_base + Interrupt_Cntl;
994: Interrupt_Status_port = port_base + Interrupt_Status;
995: Read_FIFO_port = port_base + Read_FIFO;
996: Read_SCSI_Data_port = port_base + Read_SCSI_Data;
997: SCSI_Cntl_port = port_base + SCSI_Cntl;
998: SCSI_Data_NoACK_port = port_base + SCSI_Data_NoACK;
999: SCSI_Status_port = port_base + SCSI_Status;
1000: TMC_Cntl_port = port_base + TMC_Cntl;
1001: TMC_Status_port = port_base + TMC_Status;
1002: Write_FIFO_port = port_base + Write_FIFO;
1003: Write_SCSI_Data_port = port_base + Write_SCSI_Data;
1004:
1005: fdomain_16x0_reset( NULL, 0 );
1006:
1007: if (fdomain_test_loopback()) {
1008: #if DEBUG_DETECT
1009: printk( "fdomain: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
1010: #endif
1011: if (setup_called) {
1012: printk( "fdomain: loopback test failed at port base 0x%x\n",
1013: port_base );
1014: printk( "fdomain: bad LILO parameters?\n" );
1015: }
1016: return 0;
1017: }
1018:
1019: if (this_id) {
1020: tpnt->this_id = (this_id & 0x07);
1021: adapter_mask = (1 << tpnt->this_id);
1022: } else {
1023: if (PCI_bus || (bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
1024: tpnt->this_id = 7;
1025: adapter_mask = 0x80;
1026: } else {
1027: tpnt->this_id = 6;
1028: adapter_mask = 0x40;
1029: }
1030: }
1031:
1032: /* Print out a banner here in case we can't
1033: get resources. */
1034:
1035: shpnt = scsi_register( tpnt, 0 );
1036: shpnt->irq = interrupt_level;
1037: shpnt->io_port = port_base;
1038: shpnt->n_io_port = 0x10;
1039: print_banner( shpnt );
1040:
1041: /* Log IRQ with kernel */
1042: if (!interrupt_level) {
1043: panic( "fdomain: *NO* interrupt level selected!\n" );
1044: } else {
1045: /* Register the IRQ with the kernel */
1046:
1047: retcode = request_irq( interrupt_level,
1048: fdomain_16x0_intr, SA_INTERRUPT, "fdomain", NULL);
1049:
1050: if (retcode < 0) {
1051: if (retcode == -EINVAL) {
1052: printk( "fdomain: IRQ %d is bad!\n", interrupt_level );
1053: printk( " This shouldn't happen!\n" );
1054: printk( " Send mail to [email protected]\n" );
1055: } else if (retcode == -EBUSY) {
1056: printk( "fdomain: IRQ %d is already in use!\n", interrupt_level );
1057: printk( " Please use another IRQ!\n" );
1058: } else {
1059: printk( "fdomain: Error getting IRQ %d\n", interrupt_level );
1060: printk( " This shouldn't happen!\n" );
1061: printk( " Send mail to [email protected]\n" );
1062: }
1063: panic( "fdomain: Driver requires interruptions\n" );
1064: }
1065: }
1066:
1067: /* Log I/O ports with kernel */
1068: request_region( port_base, 0x10, "fdomain" );
1069:
1070: #if DO_DETECT
1071:
1072: /* These routines are here because of the way the SCSI bus behaves after
1073: a reset. This appropriate behavior was not handled correctly by the
1074: higher level SCSI routines when I first wrote this driver. Now,
1075: however, correct scan routines are part of scsi.c and these routines
1076: are no longer needed. However, this code is still good for
1077: debugging. */
1078:
1079: SCinit.request_buffer = SCinit.buffer = buf;
1080: SCinit.request_bufflen = SCinit.bufflen = sizeof(buf)-1;
1081: SCinit.use_sg = 0;
1082: SCinit.lun = 0;
1083:
1084: printk( "fdomain: detection routine scanning for devices:\n" );
1085: for (i = 0; i < 8; i++) {
1086: SCinit.target = i;
1087: if (i == tpnt->this_id) /* Skip host adapter */
1088: continue;
1089: memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
1090: retcode = fdomain_16x0_command(&SCinit);
1091: if (!retcode) {
1092: memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
1093: retcode = fdomain_16x0_command(&SCinit);
1094: if (!retcode) {
1095: printk( " SCSI ID %d: ", i );
1096: for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
1097: printk( "%c", buf[j] >= 20 ? buf[j] : ' ' );
1098: memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
1099: retcode = fdomain_16x0_command(&SCinit);
1100: if (!retcode) {
1101: unsigned long blocks, size, capacity;
1102:
1103: blocks = (buf[0] << 24) | (buf[1] << 16)
1104: | (buf[2] << 8) | buf[3];
1105: size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
1106: capacity = +( +(blocks / 1024L) * +(size * 10L)) / 1024L;
1107:
1108: printk( "%lu MB (%lu byte blocks)",
1109: ((capacity + 5L) / 10L), size );
1110: } else {
1111: memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
1112: retcode = fdomain_16x0_command(&SCinit);
1113: }
1114: printk ("\n" );
1115: } else {
1116: memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
1117: retcode = fdomain_16x0_command(&SCinit);
1118: }
1119: }
1120: }
1121: #endif
1122:
1123: return 1; /* Maximum of one adapter will be detected. */
1124: }
1125:
1126: const char *fdomain_16x0_info( struct Scsi_Host *ignore )
1127: {
1128: static char buffer[80];
1129: char *pt;
1130:
1131: strcpy( buffer, "Future Domain TMC-16x0 SCSI driver, version" );
1132: if (strchr( VERSION, ':')) { /* Assume VERSION is an RCS Revision string */
1133: strcat( buffer, strchr( VERSION, ':' ) + 1 );
1134: pt = strrchr( buffer, '$') - 1;
1135: if (!pt) /* Stripped RCS Revision string? */
1136: pt = buffer + strlen( buffer ) - 1;
1137: if (*pt != ' ')
1138: ++pt;
1139: *pt = '\0';
1140: } else { /* Assume VERSION is a number */
1141: strcat( buffer, " " VERSION );
1142: }
1143:
1144: return buffer;
1145: }
1146:
1147: /* First pass at /proc information routine. */
1148: /*
1149: * inout : decides on the direction of the dataflow and the meaning of the
1150: * variables
1151: * buffer: If inout==FALSE data is being written to it else read from it
1152: * *start: If inout==FALSE start of the valid data in the buffer
1153: * offset: If inout==FALSE offset from the beginning of the imaginary file
1154: * from which we start writing into the buffer
1155: * length: If inout==FALSE max number of bytes to be written into the buffer
1156: * else number of bytes in the buffer
1157: */
1158: int fdomain_16x0_proc_info( char *buffer, char **start, off_t offset,
1159: int length, int hostno, int inout )
1160: {
1161: const char *info = fdomain_16x0_info( NULL );
1162: int len;
1163: int pos;
1164: int begin;
1165:
1166: if (inout) return(-ENOSYS);
1167:
1168: begin = 0;
1169: strcpy( buffer, info );
1170: strcat( buffer, "\n" );
1171:
1172: pos = len = strlen( buffer );
1173:
1174: if(pos < offset) {
1175: len = 0;
1176: begin = pos;
1177: }
1178:
1179: *start = buffer + (offset - begin); /* Start of wanted data */
1180: len -= (offset - begin);
1181: if(len > length) len = length;
1182:
1183: return(len);
1184: }
1185:
1186: #if 0
1187: static int fdomain_arbitrate( void )
1188: {
1189: int status = 0;
1190: unsigned long timeout;
1191:
1192: #if EVERY_ACCESS
1193: printk( "fdomain_arbitrate()\n" );
1194: #endif
1195:
1196: outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */
1197: outb( adapter_mask, port_base + SCSI_Data_NoACK ); /* Set our id bit */
1198: outb( 0x04 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
1199:
1200: timeout = jiffies + 50; /* 500 mS */
1201: while (jiffies < timeout) {
1202: status = inb( TMC_Status_port ); /* Read adapter status */
1203: if (status & 0x02) /* Arbitration complete */
1204: return 0;
1205: }
1206:
1207: /* Make bus idle */
1208: fdomain_make_bus_idle();
1209:
1210: #if EVERY_ACCESS
1211: printk( "Arbitration failed, status = %x\n", status );
1212: #endif
1213: #if ERRORS_ONLY
1214: printk( "fdomain: Arbitration failed, status = %x\n", status );
1215: #endif
1216: return 1;
1217: }
1218: #endif
1219:
1220: static int fdomain_select( int target )
1221: {
1222: int status;
1223: unsigned long timeout;
1224: static int flag = 0;
1225:
1226:
1227: outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
1228: outb( adapter_mask | (1 << target), SCSI_Data_NoACK_port );
1229:
1230: /* Stop arbitration and enable parity */
1231: outb( PARITY_MASK, TMC_Cntl_port );
1232:
1233: timeout = jiffies + 35; /* 350mS -- because of timeouts
1234: (was 250mS) */
1235:
1236: while (jiffies < timeout) {
1237: status = inb( SCSI_Status_port ); /* Read adapter status */
1238: if (status & 1) { /* Busy asserted */
1239: /* Enable SCSI Bus (on error, should make bus idle with 0) */
1240: outb( 0x80, SCSI_Cntl_port );
1241: return 0;
1242: }
1243: }
1244: /* Make bus idle */
1245: fdomain_make_bus_idle();
1246: #if EVERY_ACCESS
1247: if (!target) printk( "Selection failed\n" );
1248: #endif
1249: #if ERRORS_ONLY
1250: if (!target) {
1251: if (!flag) /* Skip first failure for all chips. */
1252: ++flag;
1253: else
1254: printk( "fdomain: Selection failed\n" );
1255: }
1256: #endif
1257: return 1;
1258: }
1259:
1260: void my_done( int error )
1261: {
1262: if (in_command) {
1263: in_command = 0;
1264: outb( 0x00, Interrupt_Cntl_port );
1265: fdomain_make_bus_idle();
1266: current_SC->result = error;
1267: if (current_SC->scsi_done)
1268: current_SC->scsi_done( current_SC );
1269: else panic( "fdomain: current_SC->scsi_done() == NULL" );
1270: } else {
1271: panic( "fdomain: my_done() called outside of command\n" );
1272: }
1273: #if DEBUG_RACE
1274: in_interrupt_flag = 0;
1275: #endif
1276: }
1277:
1278: void fdomain_16x0_intr( int irq, void *dev_id, struct pt_regs * regs )
1279: {
1280: int status;
1281: int done = 0;
1282: unsigned data_count;
1283:
1284: /* The fdomain_16x0_intr is only called via
1285: the interrupt handler. The goal of the
1286: sti() here is to allow other
1287: interruptions while this routine is
1288: running. */
1289:
1290: sti(); /* Yes, we really want sti() here */
1291:
1292: outb( 0x00, Interrupt_Cntl_port );
1293:
1294: /* We usually have one spurious interrupt after each command. Ignore it. */
1295: if (!in_command || !current_SC) { /* Spurious interrupt */
1296: #if EVERY_ACCESS
1297: printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
1298: in_command, current_SC );
1299: #endif
1300: return;
1301: }
1302:
1303: /* Abort calls my_done, so we do nothing here. */
1304: if (current_SC->SCp.phase & aborted) {
1305: #if DEBUG_ABORT
1306: printk( "Interrupt after abort, ignoring\n" );
1307: #endif
1308: /*
1309: return; */
1310: }
1311:
1312: #if DEBUG_RACE
1313: ++in_interrupt_flag;
1314: #endif
1315:
1316: if (current_SC->SCp.phase & in_arbitration) {
1317: status = inb( TMC_Status_port ); /* Read adapter status */
1318: if (!(status & 0x02)) {
1319: #if EVERY_ACCESS
1320: printk( " AFAIL " );
1321: #endif
1322: my_done( DID_BUS_BUSY << 16 );
1323: return;
1324: }
1325: current_SC->SCp.phase = in_selection;
1326:
1327: outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );
1328:
1329: outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
1330: outb( adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port );
1331:
1332: /* Stop arbitration and enable parity */
1333: outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
1334: #if DEBUG_RACE
1335: in_interrupt_flag = 0;
1336: #endif
1337: return;
1338: } else if (current_SC->SCp.phase & in_selection) {
1339: status = inb( SCSI_Status_port );
1340: if (!(status & 0x01)) {
1341: /* Try again, for slow devices */
1342: if (fdomain_select( current_SC->target )) {
1343: #if EVERY_ACCESS
1344: printk( " SFAIL " );
1345: #endif
1346: my_done( DID_NO_CONNECT << 16 );
1347: return;
1348: } else {
1349: #if EVERY_ACCESS
1350: printk( " AltSel " );
1351: #endif
1352: /* Stop arbitration and enable parity */
1353: outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
1354: }
1355: }
1356: current_SC->SCp.phase = in_other;
1357: outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
1358: outb( 0x80, SCSI_Cntl_port );
1359: #if DEBUG_RACE
1360: in_interrupt_flag = 0;
1361: #endif
1362: return;
1363: }
1364:
1365: /* current_SC->SCp.phase == in_other: this is the body of the routine */
1366:
1367: status = inb( SCSI_Status_port );
1368:
1369: if (status & 0x10) { /* REQ */
1370:
1371: switch (status & 0x0e) {
1372:
1373: case 0x08: /* COMMAND OUT */
1374: outb( current_SC->cmnd[current_SC->SCp.sent_command++],
1375: Write_SCSI_Data_port );
1376: #if EVERY_ACCESS
1377: printk( "CMD = %x,",
1378: current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
1379: #endif
1380: break;
1381: case 0x00: /* DATA OUT -- tmc18c50/tmc18c30 only */
1382: if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
1383: current_SC->SCp.have_data_in = -1;
1384: outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1385: }
1386: break;
1387: case 0x04: /* DATA IN -- tmc18c50/tmc18c30 only */
1388: if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
1389: current_SC->SCp.have_data_in = 1;
1390: outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1391: }
1392: break;
1393: case 0x0c: /* STATUS IN */
1394: current_SC->SCp.Status = inb( Read_SCSI_Data_port );
1395: #if EVERY_ACCESS
1396: printk( "Status = %x, ", current_SC->SCp.Status );
1397: #endif
1398: #if ERRORS_ONLY
1399: if (current_SC->SCp.Status
1400: && current_SC->SCp.Status != 2
1401: && current_SC->SCp.Status != 8) {
1402: printk( "fdomain: target = %d, command = %x, status = %x\n",
1403: current_SC->target,
1404: current_SC->cmnd[0],
1405: current_SC->SCp.Status );
1406: }
1407: #endif
1408: break;
1409: case 0x0a: /* MESSAGE OUT */
1410: outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */
1411: break;
1412: case 0x0e: /* MESSAGE IN */
1413: current_SC->SCp.Message = inb( Read_SCSI_Data_port );
1414: #if EVERY_ACCESS
1415: printk( "Message = %x, ", current_SC->SCp.Message );
1416: #endif
1417: if (!current_SC->SCp.Message) ++done;
1418: #if DEBUG_MESSAGES || EVERY_ACCESS
1419: if (current_SC->SCp.Message) {
1420: printk( "fdomain: message = %x\n", current_SC->SCp.Message );
1421: }
1422: #endif
1423: break;
1424: }
1425: }
1426:
1427: if (chip == tmc1800
1428: && !current_SC->SCp.have_data_in
1429: && (current_SC->SCp.sent_command
1430: >= current_SC->cmd_len)) {
1431: /* We have to get the FIFO direction
1432: correct, so I've made a table based
1433: on the SCSI Standard of which commands
1434: appear to require a DATA OUT phase.
1435: */
1436: /*
1437: p. 94: Command for all device types
1438: CHANGE DEFINITION 40 DATA OUT
1439: COMPARE 39 DATA OUT
1440: COPY 18 DATA OUT
1441: COPY AND VERIFY 3a DATA OUT
1442: INQUIRY 12
1443: LOG SELECT 4c DATA OUT
1444: LOG SENSE 4d
1445: MODE SELECT (6) 15 DATA OUT
1446: MODE SELECT (10) 55 DATA OUT
1447: MODE SENSE (6) 1a
1448: MODE SENSE (10) 5a
1449: READ BUFFER 3c
1450: RECEIVE DIAGNOSTIC RESULTS 1c
1451: REQUEST SENSE 03
1452: SEND DIAGNOSTIC 1d DATA OUT
1453: TEST UNIT READY 00
1454: WRITE BUFFER 3b DATA OUT
1455:
1456: p.178: Commands for direct-access devices (not listed on p. 94)
1457: FORMAT UNIT 04 DATA OUT
1458: LOCK-UNLOCK CACHE 36
1459: PRE-FETCH 34
1460: PREVENT-ALLOW MEDIUM REMOVAL 1e
1461: READ (6)/RECEIVE 08
1462: READ (10) 3c
1463: READ CAPACITY 25
1464: READ DEFECT DATA (10) 37
1465: READ LONG 3e
1466: REASSIGN BLOCKS 07 DATA OUT
1467: RELEASE 17
1468: RESERVE 16 DATA OUT
1469: REZERO UNIT/REWIND 01
1470: SEARCH DATA EQUAL (10) 31 DATA OUT
1471: SEARCH DATA HIGH (10) 30 DATA OUT
1472: SEARCH DATA LOW (10) 32 DATA OUT
1473: SEEK (6) 0b
1474: SEEK (10) 2b
1475: SET LIMITS (10) 33
1476: START STOP UNIT 1b
1477: SYNCHRONIZE CACHE 35
1478: VERIFY (10) 2f
1479: WRITE (6)/PRINT/SEND 0a DATA OUT
1480: WRITE (10)/SEND 2a DATA OUT
1481: WRITE AND VERIFY (10) 2e DATA OUT
1482: WRITE LONG 3f DATA OUT
1483: WRITE SAME 41 DATA OUT ?
1484:
1485: p. 261: Commands for sequential-access devices (not previously listed)
1486: ERASE 19
1487: LOAD UNLOAD 1b
1488: LOCATE 2b
1489: READ BLOCK LIMITS 05
1490: READ POSITION 34
1491: READ REVERSE 0f
1492: RECOVER BUFFERED DATA 14
1493: SPACE 11
1494: WRITE FILEMARKS 10 ?
1495:
1496: p. 298: Commands for printer devices (not previously listed)
1497: ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****
1498: SLEW AND PRINT 0b DATA OUT -- same as seek
1499: STOP PRINT 1b
1500: SYNCHRONIZE BUFFER 10
1501:
1502: p. 315: Commands for processor devices (not previously listed)
1503:
1504: p. 321: Commands for write-once devices (not previously listed)
1505: MEDIUM SCAN 38
1506: READ (12) a8
1507: SEARCH DATA EQUAL (12) b1 DATA OUT
1508: SEARCH DATA HIGH (12) b0 DATA OUT
1509: SEARCH DATA LOW (12) b2 DATA OUT
1510: SET LIMITS (12) b3
1511: VERIFY (12) af
1512: WRITE (12) aa DATA OUT
1513: WRITE AND VERIFY (12) ae DATA OUT
1514:
1515: p. 332: Commands for CD-ROM devices (not previously listed)
1516: PAUSE/RESUME 4b
1517: PLAY AUDIO (10) 45
1518: PLAY AUDIO (12) a5
1519: PLAY AUDIO MSF 47
1520: PLAY TRACK RELATIVE (10) 49
1521: PLAY TRACK RELATIVE (12) a9
1522: READ HEADER 44
1523: READ SUB-CHANNEL 42
1524: READ TOC 43
1525:
1526: p. 370: Commands for scanner devices (not previously listed)
1527: GET DATA BUFFER STATUS 34
1528: GET WINDOW 25
1529: OBJECT POSITION 31
1530: SCAN 1b
1531: SET WINDOW 24 DATA OUT
1532:
1533: p. 391: Commands for optical memory devices (not listed)
1534: ERASE (10) 2c
1535: ERASE (12) ac
1536: MEDIUM SCAN 38 DATA OUT
1537: READ DEFECT DATA (12) b7
1538: READ GENERATION 29
1539: READ UPDATED BLOCK 2d
1540: UPDATE BLOCK 3d DATA OUT
1541:
1542: p. 419: Commands for medium changer devices (not listed)
1543: EXCHANGE MEDIUM 46
1544: INITIALIZE ELEMENT STATUS 07
1545: MOVE MEDIUM a5
1546: POSITION TO ELEMENT 2b
1547: READ ELEMENT STATUS b8
1548: REQUEST VOL. ELEMENT ADDRESS b5
1549: SEND VOLUME TAG b6 DATA OUT
1550:
1551: p. 454: Commands for communications devices (not listed previously)
1552: GET MESSAGE (6) 08
1553: GET MESSAGE (10) 28
1554: GET MESSAGE (12) a8
1555: */
1556:
1557: switch (current_SC->cmnd[0]) {
1558: case CHANGE_DEFINITION: case COMPARE: case COPY:
1559: case COPY_VERIFY: case LOG_SELECT: case MODE_SELECT:
1560: case MODE_SELECT_10: case SEND_DIAGNOSTIC: case WRITE_BUFFER:
1561:
1562: case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE:
1563: case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW:
1564: case WRITE_6: case WRITE_10: case WRITE_VERIFY:
1565: case 0x3f: case 0x41:
1566:
1567: case 0xb1: case 0xb0: case 0xb2:
1568: case 0xaa: case 0xae:
1569:
1570: case 0x24:
1571:
1572: case 0x38: case 0x3d:
1573:
1574: case 0xb6:
1575:
1576: case 0xea: /* alternate number for WRITE LONG */
1577:
1578: current_SC->SCp.have_data_in = -1;
1579: outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1580: break;
1581:
1582: case 0x00:
1583: default:
1584:
1585: current_SC->SCp.have_data_in = 1;
1586: outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1587: break;
1588: }
1589: }
1590:
1591: if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */
1592: while ( (data_count = FIFO_Size - inw( FIFO_Data_Count_port )) > 512 ) {
1593: #if EVERY_ACCESS
1594: printk( "DC=%d, ", data_count ) ;
1595: #endif
1596: if (data_count > current_SC->SCp.this_residual)
1597: data_count = current_SC->SCp.this_residual;
1598: if (data_count > 0) {
1599: #if EVERY_ACCESS
1600: printk( "%d OUT, ", data_count );
1601: #endif
1602: if (data_count == 1) {
1603: outb( *current_SC->SCp.ptr++, Write_FIFO_port );
1604: --current_SC->SCp.this_residual;
1605: } else {
1606: data_count >>= 1;
1607: outsw( Write_FIFO_port, current_SC->SCp.ptr, data_count );
1608: current_SC->SCp.ptr += 2 * data_count;
1609: current_SC->SCp.this_residual -= 2 * data_count;
1610: }
1611: }
1612: if (!current_SC->SCp.this_residual) {
1613: if (current_SC->SCp.buffers_residual) {
1614: --current_SC->SCp.buffers_residual;
1615: ++current_SC->SCp.buffer;
1616: current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1617: current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1618: } else
1619: break;
1620: }
1621: }
1622: }
1623:
1624: if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
1625: while ((data_count = inw( FIFO_Data_Count_port )) > 0) {
1626: #if EVERY_ACCESS
1627: printk( "DC=%d, ", data_count );
1628: #endif
1629: if (data_count > current_SC->SCp.this_residual)
1630: data_count = current_SC->SCp.this_residual;
1631: if (data_count) {
1632: #if EVERY_ACCESS
1633: printk( "%d IN, ", data_count );
1634: #endif
1635: if (data_count == 1) {
1636: *current_SC->SCp.ptr++ = inb( Read_FIFO_port );
1637: --current_SC->SCp.this_residual;
1638: } else {
1639: data_count >>= 1; /* Number of words */
1640: insw( Read_FIFO_port, current_SC->SCp.ptr, data_count );
1641: current_SC->SCp.ptr += 2 * data_count;
1642: current_SC->SCp.this_residual -= 2 * data_count;
1643: }
1644: }
1645: if (!current_SC->SCp.this_residual
1646: && current_SC->SCp.buffers_residual) {
1647: --current_SC->SCp.buffers_residual;
1648: ++current_SC->SCp.buffer;
1649: current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1650: current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1651: }
1652: }
1653: }
1654:
1655: if (done) {
1656: #if EVERY_ACCESS
1657: printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
1658: #endif
1659:
1660: #if ERRORS_ONLY
1661: if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
1662: if ((unsigned char)(*((char *)current_SC->request_buffer+2)) & 0x0f) {
1663: unsigned char key;
1664: unsigned char code;
1665: unsigned char qualifier;
1666:
1667: key = (unsigned char)(*((char *)current_SC->request_buffer + 2))
1668: & 0x0f;
1669: code = (unsigned char)(*((char *)current_SC->request_buffer + 12));
1670: qualifier = (unsigned char)(*((char *)current_SC->request_buffer
1671: + 13));
1672:
1673: if (key != UNIT_ATTENTION
1674: && !(key == NOT_READY
1675: && code == 0x04
1676: && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1677: && !(key == ILLEGAL_REQUEST && (code == 0x25
1678: || code == 0x24
1679: || !code)))
1680:
1681: printk( "fdomain: REQUEST SENSE "
1682: "Key = %x, Code = %x, Qualifier = %x\n",
1683: key, code, qualifier );
1684: }
1685: }
1686: #endif
1687: #if EVERY_ACCESS
1688: printk( "BEFORE MY_DONE. . ." );
1689: #endif
1690: my_done( (current_SC->SCp.Status & 0xff)
1691: | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
1692: #if EVERY_ACCESS
1693: printk( "RETURNING.\n" );
1694: #endif
1695:
1696: } else {
1697: if (current_SC->SCp.phase & disconnect) {
1698: outb( 0xd0 | FIFO_COUNT, Interrupt_Cntl_port );
1699: outb( 0x00, SCSI_Cntl_port );
1700: } else {
1701: outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
1702: }
1703: }
1704: #if DEBUG_RACE
1705: in_interrupt_flag = 0;
1706: #endif
1707: return;
1708: }
1709:
1710: int fdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
1711: {
1712: if (in_command) {
1713: panic( "fdomain: fdomain_16x0_queue() NOT REENTRANT!\n" );
1714: }
1715: #if EVERY_ACCESS
1716: printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1717: SCpnt->target,
1718: *(unsigned char *)SCpnt->cmnd,
1719: SCpnt->use_sg,
1720: SCpnt->request_bufflen );
1721: #endif
1722:
1723: fdomain_make_bus_idle();
1724:
1725: current_SC = SCpnt; /* Save this for the done function */
1726: current_SC->scsi_done = done;
1727:
1728: /* Initialize static data */
1729:
1730: if (current_SC->use_sg) {
1731: current_SC->SCp.buffer =
1732: (struct scatterlist *)current_SC->request_buffer;
1733: current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1734: current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1735: current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
1736: } else {
1737: current_SC->SCp.ptr = (char *)current_SC->request_buffer;
1738: current_SC->SCp.this_residual = current_SC->request_bufflen;
1739: current_SC->SCp.buffer = NULL;
1740: current_SC->SCp.buffers_residual = 0;
1741: }
1742:
1743:
1744: current_SC->SCp.Status = 0;
1745: current_SC->SCp.Message = 0;
1746: current_SC->SCp.have_data_in = 0;
1747: current_SC->SCp.sent_command = 0;
1748: current_SC->SCp.phase = in_arbitration;
1749:
1750: /* Start arbitration */
1751: outb( 0x00, Interrupt_Cntl_port );
1752: outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */
1753: outb( adapter_mask, SCSI_Data_NoACK_port ); /* Set our id bit */
1754: ++in_command;
1755: outb( 0x20, Interrupt_Cntl_port );
1756: outb( 0x14 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
1757:
1758: return 0;
1759: }
1760:
1761: /* The following code, which simulates the old-style command function, was
1762: taken from Tommy Thorn's aha1542.c file. This code is Copyright (C)
1763: 1992 Tommy Thorn. */
1764:
1765: static volatile int internal_done_flag = 0;
1766: static volatile int internal_done_errcode = 0;
1767:
1768: static void internal_done( Scsi_Cmnd *SCpnt )
1769: {
1770: internal_done_errcode = SCpnt->result;
1771: ++internal_done_flag;
1772: }
1773:
1774: int fdomain_16x0_command( Scsi_Cmnd *SCpnt )
1775: {
1776: fdomain_16x0_queue( SCpnt, internal_done );
1777:
1778: while (!internal_done_flag)
1779: ;
1780: internal_done_flag = 0;
1781: return internal_done_errcode;
1782: }
1783:
1784: /* End of code derived from Tommy Thorn's work. */
1785:
1786: void print_info( Scsi_Cmnd *SCpnt )
1787: {
1788: unsigned int imr;
1789: unsigned int irr;
1790: unsigned int isr;
1791:
1792: if (!SCpnt || !SCpnt->host) {
1793: printk( "fdomain: cannot provide detailed information\n" );
1794: }
1795:
1796: printk( "%s\n", fdomain_16x0_info( SCpnt->host ) );
1797: print_banner( SCpnt->host );
1798: switch (SCpnt->SCp.phase) {
1799: case in_arbitration: printk( "arbitration " ); break;
1800: case in_selection: printk( "selection " ); break;
1801: case in_other: printk( "other " ); break;
1802: default: printk( "unknown " ); break;
1803: }
1804:
1805: printk( "(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1806: SCpnt->SCp.phase,
1807: SCpnt->target,
1808: *(unsigned char *)SCpnt->cmnd,
1809: SCpnt->use_sg,
1810: SCpnt->request_bufflen );
1811: printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
1812: SCpnt->SCp.sent_command,
1813: SCpnt->SCp.have_data_in,
1814: SCpnt->timeout );
1815: #if DEBUG_RACE
1816: printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
1817: #endif
1818:
1819: imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
1820: outb( 0x0a, 0xa0 );
1821: irr = inb( 0xa0 ) << 8;
1822: outb( 0x0a, 0x20 );
1823: irr += inb( 0x20 );
1824: outb( 0x0b, 0xa0 );
1825: isr = inb( 0xa0 ) << 8;
1826: outb( 0x0b, 0x20 );
1827: isr += inb( 0x20 );
1828:
1829: /* Print out interesting information */
1830: printk( "IMR = 0x%04x", imr );
1831: if (imr & (1 << interrupt_level))
1832: printk( " (masked)" );
1833: printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
1834:
1835: printk( "SCSI Status = 0x%02x\n", inb( SCSI_Status_port ) );
1836: printk( "TMC Status = 0x%02x", inb( TMC_Status_port ) );
1837: if (inb( TMC_Status_port & 1))
1838: printk( " (interrupt)" );
1839: printk( "\n" );
1840: printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port ) );
1841: if (inb( Interrupt_Status_port ) & 0x08)
1842: printk( " (enabled)" );
1843: printk( "\n" );
1844: if (chip == tmc18c50 || chip == tmc18c30) {
1845: printk( "FIFO Status = 0x%02x\n", inb( port_base + FIFO_Status ) );
1846: printk( "Int. Condition = 0x%02x\n",
1847: inb( port_base + Interrupt_Cond ) );
1848: }
1849: printk( "Configuration 1 = 0x%02x\n", inb( port_base + Configuration1 ) );
1850: if (chip == tmc18c50 || chip == tmc18c30)
1851: printk( "Configuration 2 = 0x%02x\n",
1852: inb( port_base + Configuration2 ) );
1853: }
1854:
1855: int fdomain_16x0_abort( Scsi_Cmnd *SCpnt)
1856: {
1857: unsigned long flags;
1858: #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1859: printk( "fdomain: abort " );
1860: #endif
1861:
1862: save_flags( flags );
1863: cli();
1864: if (!in_command) {
1865: #if EVERY_ACCESS || ERRORS_ONLY
1866: printk( " (not in command)\n" );
1867: #endif
1868: restore_flags( flags );
1869: return SCSI_ABORT_NOT_RUNNING;
1870: } else printk( "\n" );
1871:
1872: #if DEBUG_ABORT
1873: print_info( SCpnt );
1874: #endif
1875:
1876: fdomain_make_bus_idle();
1877:
1878: current_SC->SCp.phase |= aborted;
1879:
1880: current_SC->result = DID_ABORT << 16;
1881:
1882: restore_flags( flags );
1883:
1884: /* Aborts are not done well. . . */
1885: my_done( DID_ABORT << 16 );
1886:
1887: return SCSI_ABORT_SUCCESS;
1888: }
1889:
1890: int fdomain_16x0_reset( Scsi_Cmnd *SCpnt, unsigned int flags )
1891: {
1892: #if DEBUG_RESET
1893: static int called_once = 0;
1894: #endif
1895:
1896: #if ERRORS_ONLY
1897: if (SCpnt) printk( "fdomain: SCSI Bus Reset\n" );
1898: #endif
1899:
1900: #if DEBUG_RESET
1901: if (called_once) print_info( current_SC );
1902: called_once = 1;
1903: #endif
1904:
1905: outb( 1, SCSI_Cntl_port );
1906: do_pause( 2 );
1907: outb( 0, SCSI_Cntl_port );
1908: do_pause( 115 );
1909: outb( 0, SCSI_Mode_Cntl_port );
1910: outb( PARITY_MASK, TMC_Cntl_port );
1911:
1912: /* Unless this is the very first call (i.e., SCPnt == NULL), everything
1913: is probably hosed at this point. We will, however, try to keep
1914: things going by informing the high-level code that we need help. */
1915:
1916: return SCSI_RESET_WAKEUP;
1917: }
1918:
1919: #include "sd.h"
1920: #include <scsi/scsi_ioctl.h>
1921:
1922: int fdomain_16x0_biosparam( Scsi_Disk *disk, kdev_t dev, int *info_array )
1923: {
1924: int drive;
1925: unsigned char buf[512 + sizeof( int ) * 2];
1926: int size = disk->capacity;
1927: int *sizes = (int *)buf;
1928: unsigned char *data = (unsigned char *)(sizes + 2);
1929: unsigned char do_read[] = { READ_6, 0, 0, 0, 1, 0 };
1930: int retcode;
1931: struct drive_info {
1932: unsigned short cylinders;
1933: unsigned char heads;
1934: unsigned char sectors;
1935: } *i;
1936:
1937: /* NOTES:
1938: The RAM area starts at 0x1f00 from the bios_base address.
1939:
1940: For BIOS Version 2.0:
1941:
1942: The drive parameter table seems to start at 0x1f30.
1943: The first byte's purpose is not known.
1944: Next is the cylinder, head, and sector information.
1945: The last 4 bytes appear to be the drive's size in sectors.
1946: The other bytes in the drive parameter table are unknown.
1947: If anyone figures them out, please send me mail, and I will
1948: update these notes.
1949:
1950: Tape drives do not get placed in this table.
1951:
1952: There is another table at 0x1fea:
1953: If the byte is 0x01, then the SCSI ID is not in use.
1954: If the byte is 0x18 or 0x48, then the SCSI ID is in use,
1955: although tapes don't seem to be in this table. I haven't
1956: seen any other numbers (in a limited sample).
1957:
1958: 0x1f2d is a drive count (i.e., not including tapes)
1959:
1960: The table at 0x1fcc are I/O ports addresses for the various
1961: operations. I calculate these by hand in this driver code.
1962:
1963:
1964:
1965: For the ISA-200S version of BIOS Version 2.0:
1966:
1967: The drive parameter table starts at 0x1f33.
1968:
1969: WARNING: Assume that the table entry is 25 bytes long. Someone needs
1970: to check this for the Quantum ISA-200S card.
1971:
1972:
1973:
1974: For BIOS Version 3.2:
1975:
1976: The drive parameter table starts at 0x1f70. Each entry is
1977: 0x0a bytes long. Heads are one less than we need to report.
1978: */
1979:
1980: drive = MINOR(dev) / 16;
1981:
1982: if (bios_major == 2) {
1983: switch (Quantum) {
1984: case 2: /* ISA_200S */
1985: /* The value of 25 has never been verified.
1986: It should probably be 15. */
1987: i = (struct drive_info *)( (char *)bios_base + 0x1f33 + drive * 25 );
1988: break;
1989: case 3: /* ISA_250MG */
1990: i = (struct drive_info *)( (char *)bios_base + 0x1f36 + drive * 15 );
1991: break;
1992: case 4: /* ISA_200S (another one) */
1993: i = (struct drive_info *)( (char *)bios_base + 0x1f34 + drive * 15 );
1994: break;
1995: default:
1996: i = (struct drive_info *)( (char *)bios_base + 0x1f31 + drive * 25 );
1997: break;
1998: }
1999: info_array[0] = i->heads;
2000: info_array[1] = i->sectors;
2001: info_array[2] = i->cylinders;
2002: } else if (bios_major == 3
2003: && bios_minor >= 0
2004: && bios_minor < 4) { /* 3.0 and 3.2 BIOS */
2005: i = (struct drive_info *)( (char *)bios_base + 0x1f71 + drive * 10 );
2006: info_array[0] = i->heads + 1;
2007: info_array[1] = i->sectors;
2008: info_array[2] = i->cylinders;
2009: } else { /* 3.4 BIOS (and up?) */
2010: /* This algorithm was provided by Future Domain (much thanks!). */
2011:
2012: sizes[0] = 0; /* zero bytes out */
2013: sizes[1] = 512; /* one sector in */
2014: memcpy( data, do_read, sizeof( do_read ) );
2015: retcode = kernel_scsi_ioctl( disk->device,
2016: SCSI_IOCTL_SEND_COMMAND,
2017: (void *)buf );
2018: if (!retcode /* SCSI command ok */
2019: && data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */
2020: && data[0x1c2]) { /* Partition type */
2021:
2022: /* The partition table layout is as follows:
2023:
2024: Start: 0x1b3h
2025: Offset: 0 = partition status
2026: 1 = starting head
2027: 2 = starting sector and cylinder (word, encoded)
2028: 4 = partition type
2029: 5 = ending head
2030: 6 = ending sector and cylinder (word, encoded)
2031: 8 = starting absolute sector (double word)
2032: c = number of sectors (double word)
2033: Signature: 0x1fe = 0x55aa
2034:
2035: So, this algorithm assumes:
2036: 1) the first partition table is in use,
2037: 2) the data in the first entry is correct, and
2038: 3) partitions never divide cylinders
2039:
2040: Note that (1) may be FALSE for NetBSD (and other BSD flavors),
2041: as well as for Linux. Note also, that Linux doesn't pay any
2042: attention to the fields that are used by this algorithm -- it
2043: only uses the absolute sector data. Recent versions of Linux's
2044: fdisk(1) will fill this data in correctly, and forthcoming
2045: versions will check for consistency.
2046:
2047: Checking for a non-zero partition type is not part of the
2048: Future Domain algorithm, but it seemed to be a reasonable thing
2049: to do, especially in the Linux and BSD worlds. */
2050:
2051: info_array[0] = data[0x1c3] + 1; /* heads */
2052: info_array[1] = data[0x1c4] & 0x3f; /* sectors */
2053: } else {
2054:
2055: /* Note that this new method guarantees that there will always be
2056: less than 1024 cylinders on a platter. This is good for drives
2057: up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
2058:
2059: if ((unsigned int)size >= 0x7e0000U) {
2060: info_array[0] = 0xff; /* heads = 255 */
2061: info_array[1] = 0x3f; /* sectors = 63 */
2062: } else if ((unsigned int)size >= 0x200000U) {
2063: info_array[0] = 0x80; /* heads = 128 */
2064: info_array[1] = 0x3f; /* sectors = 63 */
2065: } else {
2066: info_array[0] = 0x40; /* heads = 64 */
2067: info_array[1] = 0x20; /* sectors = 32 */
2068: }
2069: }
2070: /* For both methods, compute the cylinders */
2071: info_array[2] = (unsigned int)size / (info_array[0] * info_array[1] );
2072: }
2073:
2074: return 0;
2075: }
2076:
2077: #ifdef MODULE
2078: /* Eventually this will go into an include file, but this will be later */
2079: Scsi_Host_Template driver_template = FDOMAIN_16X0;
2080:
2081: #include "scsi_module.c"
2082: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.