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