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