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