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: Sun Jan 23 08:59:04 1994 by faith@cs.unc.edu
4 * Author: Rickard E. Faith, faith@cs.unc.edu
5 * Copyright 1992, 1993, 1994 Rickard E. Faith
7 * $Id: fdomain.c,v 5.9 1994/01/23 13:59:14 root Exp $
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
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.
19 **************************************************************************
23 This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
24 and TMC-1650/1670 SCSI host adapters. The 1650 and 1670 have a 25-pin
25 external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin
26 high-density external connector. The 1670 and 1680 have floppy disk
29 Future Domain's older boards are based on the TMC-1800 chip, and the
30 driver was originally written for a TMC-1680 board with the TMC-1800
31 chip. More recently, boards are being produced with the TMC-18C50 chip.
32 The latest and greatest board may not work with this driver. If you have
33 to patch this driver so that it will recognize your board's BIOS
34 signature, then the driver may fail to function after the board is
37 If you have a TMC-8xx or TMC-9xx board, then this is not the driver for
38 your board. Please refer to the Seagate driver for more information and
45 "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation,
48 "Technical Reference Manual: 18C50 SCSI Host Adapter Chip", Future Domain
49 Corporation, January 1992.
51 "LXT SCSI Products: Specifications and OEM Technical Manual (Revision
52 B/September 1991)", Maxtor Corporation, 1991.
54 "7213S product Manual (Revision P3)", Maxtor Corporation, 1992.
56 "Draft Proposed American National Standard: Small Computer System
57 Interface - 2 (SCSI-2)", Global Engineering Documents. (X3T9.2/86-109,
58 revision 10h, October 17, 1991)
60 Private communications, Drew Eckhardt (drew@cs.colorado.edu) and Eric
61 Youngdale (eric@tantalus.nrl.navy.mil), 1992.
67 The Maxtor manuals were free. Maxtor telephone technical support is
70 The Future Domain manuals were $25 and $35. They document the chip, not
71 the TMC-16x0 boards, so some information I had to guess at. In 1992,
72 Future Domain sold DOS BIOS source for $250 and the UN*X driver source was
73 $750, but these required a non-disclosure agreement, so even if I could
74 have afforded them, they would *not* have been useful for writing this
75 publically distributable driver. Future Domain technical support has
76 provided some information on the phone and have sent a few useful FAXs.
77 They have been much more helpful since they started to recognize that the
78 word "Linux" refers to an operating system :-).
84 There are many other alpha testers that come and go as the driver
85 develops. The people listed here were most helpful in times of greatest
86 need (mostly early on -- I've probably left out a few worthy people in
89 Todd Carrico (todd@wutc.wustl.edu), Dan Poirier (poirier@cs.unc.edu ), Ken
90 Corey (kenc@sol.acs.unt.edu), C. de Bruin (bruin@bruin@sterbbs.nl), Sakari
91 Aaltonen (sakaria@vipunen.hit.fi), John Rice (rice@xanth.cs.odu.edu), Brad
92 Yearwood (brad@optilink.com), and Ray Toy (toy@soho.crd.ge.com).
94 Special thanks to Tien-Wan Yang (twyang@cs.uh.edu), who graciously lent me
95 his 18C50-based card for debugging. He is the sole reason that this
96 driver works with the 18C50 chip.
98 All of the alpha testers deserve much thanks.
102 NOTES ON USER DEFINABLE OPTIONS:
104 DEBUG: This turns on the printing of various debug informaiton.
106 ENABLE_PARITY: This turns on SCSI parity checking. With the current
107 driver, all attached devices must support SCSI parity. If none of your
108 devices support parity, then you can probably get the driver to work by
109 turning this option off. I have no way of testing this, however.
111 FIFO_COUNT: The host adapter has an 8K cache. When this many 512 byte
112 blocks are filled by the SCSI device, an interrupt will be raised.
113 Therefore, this could be as low as 0, or as high as 16. Note, however,
114 that values which are too high or too low seem to prevent any interrupts
115 from occuring, and thereby lock up the machine. I have found that 2 is a
116 good number, but throughput may be increased by changing this value to
117 values which are close to 2. Please let me know if you try any different
120 DO_DETECT: This activates some old scan code which was needed before the
121 high level drivers got fixed. If you are having toruble with the driver,
122 turning this on should not hurt, and might help. Please let me know if
123 this is the case, since this code will be removed from future drivers.
125 RESELECTION: This is no longer an option, since I gave up trying to
126 implement it in version 4.x of this driver. It did not improve
127 performance at all and made the driver unstable (because I never found one
128 of the two race conditions which were introduced by multiple outstanding
129 commands). The instability seems a very high price to pay just so that
130 you don't have to wait for the tape to rewind. When I have time, I will
131 work on this again. In the interim, if anyone want to work on the code, I
132 can give them my latest version.
134 **************************************************************************/
136 #include <linux/sched.h>
138 #include "../block/blk.h"
142 #include <asm/system.h>
143 #include <linux/errno.h>
144 #include <linux/string.h>
145 #include <linux/ioport.h>
147 #define VERSION "$Revision: 5.9 $"
149 /* START OF USER DEFINABLE OPTIONS */
151 #define DEBUG 1 /* Enable debugging output */
152 #define ENABLE_PARITY 1 /* Enable SCSI Parity */
153 #define FIFO_COUNT 2 /* Number of 512 byte blocks before INTR */
154 #define DO_DETECT 0 /* Do device detection here (see scsi.c) */
156 /* END OF USER DEFINABLE OPTIONS */
159 #define EVERY_ACCESS 0 /* Write a line on every scsi access */
160 #define ERRORS_ONLY 1 /* Only write a line if there is an error */
161 #define DEBUG_DETECT 0 /* Debug fdomain_16x0_detect() */
162 #define DEBUG_MESSAGES 1 /* Debug MESSAGE IN phase */
163 #define DEBUG_ABORT 1 /* Debug abort() routine */
164 #define DEBUG_RESET 1 /* Debug reset() routine */
165 #define DEBUG_RACE 1 /* Debug interrupt-driven race condition */
167 #define EVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
168 #define ERRORS_ONLY 0
169 #define DEBUG_DETECT 0
170 #define DEBUG_MESSAGES 0
171 #define DEBUG_ABORT 0
172 #define DEBUG_RESET 0
176 /* Errors are reported on the line, so we don't need to report them again */
179 #define ERRORS_ONLY 0
183 #define PARITY_MASK 0x08
185 #define PARITY_MASK 0x00
195 in_arbitration
= 0x02,
207 FIFO_Status
= 3, /* tmc18c50 only */
208 Interrupt_Cond
= 4, /* tmc18c50 only */
213 Interrupt_Status
= 9,
215 Configuration2
= 11, /* tmc18c50 only */
226 Memory_Cntl
= 5, /* tmc18c50 only */
231 static int port_base
= 0;
232 static void *bios_base
= NULL
;
233 static int bios_major
= 0;
234 static int bios_minor
= 0;
235 static int interrupt_level
= 0;
236 static int this_host
= 0;
237 static volatile int in_command
= 0;
238 static Scsi_Cmnd
*current_SC
= NULL
;
239 static enum chip_type chip
= unknown
;
240 static int adapter_mask
= 0x40;
242 static volatile int in_interrupt_flag
= 0;
245 static int SCSI_Mode_Cntl_port
;
246 static int FIFO_Data_Count_port
;
247 static int Interrupt_Cntl_port
;
248 static int Interrupt_Status_port
;
249 static int Read_FIFO_port
;
250 static int Read_SCSI_Data_port
;
251 static int SCSI_Cntl_port
;
252 static int SCSI_Data_NoACK_port
;
253 static int SCSI_Status_port
;
254 static int TMC_Cntl_port
;
255 static int TMC_Status_port
;
256 static int Write_FIFO_port
;
257 static int Write_SCSI_Data_port
;
259 extern void fdomain_16x0_intr( int unused
);
261 static void *addresses
[] = {
266 #define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
268 static unsigned short ports
[] = { 0x140, 0x150, 0x160, 0x170 };
269 #define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short ))
271 static unsigned short ints
[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
275 READ THIS BEFORE YOU ADD A SIGNATURE!
277 READING THIS SHORT NOTE CAN SAVE YOU LOTS OF TIME!
279 READ EVERY WORD, ESPECIALLY THE WORD *NOT*
281 This driver works *ONLY* for Future Domain cards using the TMC-1800 or
282 the TMC-18C50 chip. This includes models TMC-1650, 1660, 1670, and 1680.
284 The following BIOS signature signatures are for boards which do *NOT*
285 work with this driver (these TMC-8xx and TMC-9xx boards may work with the
288 FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88
289 FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89
290 FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89
291 FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90
292 FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90
293 FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90
294 FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92
302 int major_bios_version
;
303 int minor_bios_version
;
306 /* 123456789012345678901234567890123456789012345678901234567890 */
307 { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 5, 50, 2, 0 },
308 { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89", 5, 50, 2, 0 },
309 { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92", 5, 44, 3, 0 },
310 { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93", 5, 44, 3, 2 },
311 { "FUTURE DOMAIN TMC-18XX", 5, 22, -1, -1 },
313 /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGANTURE
314 Also, fix the disk geometry code for your signature and send your
315 changes for faith@cs.unc.edu. Above all, do *NOT* change any old
318 Note that the last line will match a "generic" 18XX bios. Because
319 Future Domain has changed the host SCSI ID and/or the location of the
320 geometry information in the on-board RAM area for each of the first
321 three BIOS's, it is still important to enter a fully qualified
322 signature in the table for any new BIOS's (after the host SCSI ID and
323 geometry location are verified.) */
326 #define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
328 static void print_banner( void )
330 printk( "%s", fdomain_16x0_info() );
331 printk( "Future Domain: BIOS version %d.%d, %s\n",
332 bios_major
, bios_minor
,
333 chip
== tmc1800
? "TMC-1800"
334 : (chip
== tmc18c50
? "TMC-18C50" : "Unknown") );
336 if (interrupt_level
) {
337 printk( "Future Domain: BIOS at %x; port base at %x; using IRQ %d\n",
338 (unsigned)bios_base
, port_base
, interrupt_level
);
340 printk( "Future Domain: BIOS at %x; port base at %x; *NO* IRQ\n",
341 (unsigned)bios_base
, port_base
);
345 static void do_pause( unsigned amount
) /* Pause for amount*10 milliseconds */
347 unsigned long the_time
= jiffies
+ amount
; /* 0.01 seconds per jiffy */
349 while (jiffies
< the_time
);
352 inline static void fdomain_make_bus_idle( void )
354 outb( 0, SCSI_Cntl_port
);
355 outb( 0, SCSI_Mode_Cntl_port
);
356 if (chip
== tmc18c50
)
357 outb( 0x21 | PARITY_MASK
, TMC_Cntl_port
); /* Clear forced intr. */
359 outb( 0x01 | PARITY_MASK
, TMC_Cntl_port
);
362 static int fdomain_is_valid_port( int port
)
368 inb( port
+ MSB_ID_Code
), inb( port
+ LSB_ID_Code
) );
371 /* The MCA ID is a unique id for each MCA compatible board. We
372 are using ISA boards, but Future Domain provides the MCA ID
373 anyway. We can use this ID to ensure that this is a Future
374 Domain TMC-1660/TMC-1680.
377 if (inb( port
+ LSB_ID_Code
) != 0xe9) { /* test for 0x6127 id */
378 if (inb( port
+ LSB_ID_Code
) != 0x27) return 0;
379 if (inb( port
+ MSB_ID_Code
) != 0x61) return 0;
381 } else { /* test for 0xe960 id */
382 if (inb( port
+ MSB_ID_Code
) != 0x60) return 0;
386 /* We have a valid MCA ID for a TMC-1660/TMC-1680 Future Domain board.
387 Now, check to be sure the bios_base matches these ports. If someone
388 was unlucky enough to have purchased more than one Future Domain
389 board, then they will have to modify this code, as we only detect one
390 board here. [The one with the lowest bios_base.] */
392 options
= inb( port
+ Configuration1
);
395 printk( " Options = %x\n", options
);
398 /* Check for board with lowest bios_base. */
399 if (addresses
[ (options
& 0xc0) >> 6 ] != bios_base
)
401 interrupt_level
= ints
[ (options
& 0x0e) >> 1 ];
406 static int fdomain_test_loopback( void )
411 for (i
= 0; i
< 255; i
++) {
412 outb( i
, port_base
+ Write_Loopback
);
413 result
= inb( port_base
+ Read_Loopback
);
420 int fdomain_16x0_detect( int hostnum
)
427 const int buflen
= 255;
429 unsigned char do_inquiry
[] = { INQUIRY
, 0, 0, 0, buflen
, 0 };
430 unsigned char do_request_sense
[] = { REQUEST_SENSE
, 0, 0, 0, buflen
, 0 };
431 unsigned char do_read_capacity
[] = { READ_CAPACITY
,
432 0, 0, 0, 0, 0, 0, 0, 0, 0 };
433 unsigned char buf
[buflen
];
437 printk( "fdomain_16x0_detect()," );
440 for (i
= 0; !bios_base
&& i
< ADDRESS_COUNT
; i
++) {
442 printk( " %x(%x),", (unsigned)addresses
[i
], (unsigned)bios_base
);
444 for (j
= 0; !bios_base
&& j
< SIGNATURE_COUNT
; j
++) {
445 if (!memcmp( ((char *)addresses
[i
] + signatures
[j
].sig_offset
),
446 signatures
[j
].signature
, signatures
[j
].sig_length
)) {
447 bios_major
= signatures
[j
].major_bios_version
;
448 bios_minor
= signatures
[j
].minor_bios_version
;
449 bios_base
= addresses
[i
];
456 printk( " FAILED: NO BIOS\n" );
461 if (bios_major
== 2) {
462 /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM.
463 Assuming the ROM is enabled (otherwise we wouldn't have been
464 able to read the ROM signature :-), then the ROM sets up the
465 RAM area with some magic numbers, such as a list of port
466 base addresses and a list of the disk "geometry" reported to
467 DOS (this geometry has nothing to do with physical geometry).
470 port_base
= *((char *)bios_base
+ 0x1fcc)
471 + (*((char *)bios_base
+ 0x1fcd) << 8);
474 printk( " %x,", port_base
);
477 for (flag
= 0, i
= 0; !flag
&& i
< PORT_COUNT
; i
++) {
478 if (port_base
== ports
[i
])
483 flag
= fdomain_is_valid_port( port_base
);
486 if (!flag
) { /* Cannot get port base from BIOS RAM */
488 /* This is a bad sign. It usually means that someone patched the
489 BIOS signature list (the signatures variable) to contain a BIOS
490 signature for a board *OTHER THAN* the TMC-1660/TMC-1680. It
491 also means that we don't have a Version 2.0 BIOS :-)
495 if (bios_major
!= 2) printk( " RAM FAILED, " );
498 /* Anyway, the alternative to finding the address in the RAM is
499 to just search through every possible port address for one
500 that is attached to the Future Domain card. Don't panic,
501 though, about reading all these random port addresses--there
502 are rumors that the Future Domain BIOS does something very
505 Do not, however, check ports which the kernel knows are being used
509 for (i
= 0; !flag
&& i
< PORT_COUNT
; i
++) {
510 port_base
= ports
[i
];
511 if (check_region( port_base
, 0x10 )) {
513 printf( " (%x inuse),", port_base
);
518 printk( " %x,", port_base
);
520 flag
= fdomain_is_valid_port( port_base
);
526 printk( " FAILED: NO PORT\n" );
528 return 0; /* Cannot find valid set of ports */
533 SCSI_Mode_Cntl_port
= port_base
+ SCSI_Mode_Cntl
;
534 FIFO_Data_Count_port
= port_base
+ FIFO_Data_Count
;
535 Interrupt_Cntl_port
= port_base
+ Interrupt_Cntl
;
536 Interrupt_Status_port
= port_base
+ Interrupt_Status
;
537 Read_FIFO_port
= port_base
+ Read_FIFO
;
538 Read_SCSI_Data_port
= port_base
+ Read_SCSI_Data
;
539 SCSI_Cntl_port
= port_base
+ SCSI_Cntl
;
540 SCSI_Data_NoACK_port
= port_base
+ SCSI_Data_NoACK
;
541 SCSI_Status_port
= port_base
+ SCSI_Status
;
542 TMC_Cntl_port
= port_base
+ TMC_Cntl
;
543 TMC_Status_port
= port_base
+ TMC_Status
;
544 Write_FIFO_port
= port_base
+ Write_FIFO
;
545 Write_SCSI_Data_port
= port_base
+ Write_SCSI_Data
;
547 fdomain_16x0_reset( NULL
);
549 if (fdomain_test_loopback()) {
551 printk( "Future Domain: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
558 /* Log IRQ with kernel */
560 if (!interrupt_level
) {
561 panic( "Future Domain: *NO* interrupt level selected!\n" );
563 /* Register the IRQ with the kernel */
565 sa
.sa_handler
= fdomain_16x0_intr
;
566 sa
.sa_flags
= SA_INTERRUPT
;
568 sa
.sa_restorer
= NULL
;
570 retcode
= irqaction( interrupt_level
, &sa
);
573 if (retcode
== -EINVAL
) {
574 printk( "Future Domain: IRQ %d is bad!\n", interrupt_level
);
575 printk( " This shouldn't happen!\n" );
576 printk( " Send mail to faith@cs.unc.edu\n" );
577 } else if (retcode
== -EBUSY
) {
578 printk( "Future Domain: IRQ %d is already in use!\n",
580 printk( " Please use another IRQ!\n" );
582 printk( "Future Domain: Error getting IRQ %d\n", interrupt_level
);
583 printk( " This shouldn't happen!\n" );
584 printk( " Send mail to faith@cs.unc.edu\n" );
586 panic( "Future Domain: Driver requires interruptions\n" );
588 printk( "Future Domain: IRQ %d requested from kernel\n",
593 /* Log I/O ports with kernel */
595 snarf_region( port_base
, 0x10 );
597 if ((bios_major
== 3 && bios_minor
>= 2) || bios_major
< 0) {
599 scsi_hosts
[this_host
].this_id
= 7;
604 /* These routines are here because of the way the SCSI bus behaves after
605 a reset. This appropriate behavior was not handled correctly by the
606 higher level SCSI routines when I first wrote this driver. Now,
607 however, correct scan routines are part of scsi.c and these routines
608 are no longer needed. However, this code is still good for
611 SCinit
.request_buffer
= SCinit
.buffer
= buf
;
612 SCinit
.request_bufflen
= SCinit
.bufflen
= sizeof(buf
)-1;
616 printk( "Future Domain detection routine scanning for devices:\n" );
617 for (i
= 0; i
< 8; i
++) {
619 if (i
== scsi_hosts
[this_host
].this_id
) /* Skip host adapter */
621 memcpy(SCinit
.cmnd
, do_request_sense
, sizeof(do_request_sense
));
622 retcode
= fdomain_16x0_command(&SCinit
);
624 memcpy(SCinit
.cmnd
, do_inquiry
, sizeof(do_inquiry
));
625 retcode
= fdomain_16x0_command(&SCinit
);
627 printk( " SCSI ID %d: ", i
);
628 for (j
= 8; j
< (buf
[4] < 32 ? buf
[4] : 32); j
++)
629 printk( "%c", buf
[j
] >= 20 ? buf
[j
] : ' ' );
630 memcpy(SCinit
.cmnd
, do_read_capacity
, sizeof(do_read_capacity
));
631 retcode
= fdomain_16x0_command(&SCinit
);
633 unsigned long blocks
, size
, capacity
;
635 blocks
= (buf
[0] << 24) | (buf
[1] << 16)
636 | (buf
[2] << 8) | buf
[3];
637 size
= (buf
[4] << 24) | (buf
[5] << 16) | (buf
[6] << 8) | buf
[7];
638 capacity
= +( +(blocks
/ 1024L) * +(size
* 10L)) / 1024L;
640 printk( "%lu MB (%lu byte blocks)",
641 ((capacity
+ 5L) / 10L), size
);
643 memcpy(SCinit
.cmnd
, do_request_sense
, sizeof(do_request_sense
));
644 retcode
= fdomain_16x0_command(&SCinit
);
648 memcpy(SCinit
.cmnd
, do_request_sense
, sizeof(do_request_sense
));
649 retcode
= fdomain_16x0_command(&SCinit
);
658 const char *fdomain_16x0_info(void)
660 static char buffer
[80];
663 strcpy( buffer
, "Future Domain: TMC-16x0 SCSI driver, version" );
664 if (strchr( VERSION
, ':')) { /* Assume VERSION is an RCS Revision string */
665 strcat( buffer
, strchr( VERSION
, ':' ) + 1 );
666 pt
= strrchr( buffer
, '$') - 1;
667 if (!pt
) /* Stripped RCS Revision string? */
668 pt
= buffer
+ strlen( buffer
) - 1;
673 } else { /* Assume VERSION is a number */
674 strcat( buffer
, " " VERSION
"\n" );
681 static int fdomain_arbitrate( void )
684 unsigned long timeout
;
687 printk( "fdomain_arbitrate()\n" );
690 outb( 0x00, SCSI_Cntl_port
); /* Disable data drivers */
691 outb( adapter_mask
, port_base
+ SCSI_Data_NoACK
); /* Set our id bit */
692 outb( 0x04 | PARITY_MASK
, TMC_Cntl_port
); /* Start arbitration */
694 timeout
= jiffies
+ 50; /* 500 mS */
695 while (jiffies
< timeout
) {
696 status
= inb( TMC_Status_port
); /* Read adapter status */
697 if (status
& 0x02) /* Arbitration complete */
702 fdomain_make_bus_idle();
705 printk( "Arbitration failed, status = %x\n", status
);
708 printk( "Future Domain: Arbitration failed, status = %x", status
);
714 static int fdomain_select( int target
)
717 unsigned long timeout
;
720 outb( 0x82, SCSI_Cntl_port
); /* Bus Enable + Select */
721 outb( adapter_mask
| (1 << target
), SCSI_Data_NoACK_port
);
723 /* Stop arbitration and enable parity */
724 outb( PARITY_MASK
, TMC_Cntl_port
);
726 timeout
= jiffies
+ 25; /* 250mS */
727 while (jiffies
< timeout
) {
728 status
= inb( SCSI_Status_port
); /* Read adapter status */
729 if (status
& 1) { /* Busy asserted */
730 /* Enable SCSI Bus (on error, should make bus idle with 0) */
731 outb( 0x80, SCSI_Cntl_port
);
736 fdomain_make_bus_idle();
738 if (!target
) printk( "Selection failed\n" );
741 if (!target
) printk( "Future Domain: Selection failed" );
746 void my_done( int error
)
750 outb( 0x00, Interrupt_Cntl_port
);
751 fdomain_make_bus_idle();
752 current_SC
->result
= error
;
753 if (current_SC
->scsi_done
)
754 current_SC
->scsi_done( current_SC
);
755 else panic( "Future Domain: current_SC->scsi_done() == NULL" );
757 panic( "Future Domain: my_done() called outside of command\n" );
760 in_interrupt_flag
= 0;
764 void fdomain_16x0_intr( int unused
)
772 outb( 0x00, Interrupt_Cntl_port
);
774 /* We usually have one spurious interrupt after each command. Ignore it. */
775 if (!in_command
|| !current_SC
) { /* Spurious interrupt */
777 printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
778 in_command
, current_SC
);
783 /* Abort calls my_done, so we do nothing here. */
784 if (current_SC
->SCp
.phase
& aborted
) {
786 printk( "Interrupt after abort, ignoring\n" );
796 if (current_SC
->SCp
.phase
& in_arbitration
) {
797 status
= inb( TMC_Status_port
); /* Read adapter status */
798 if (!(status
& 0x02)) {
802 my_done( DID_BUS_BUSY
<< 16 );
805 current_SC
->SCp
.phase
= in_selection
;
807 outb( 0x40 | FIFO_COUNT
, Interrupt_Cntl_port
);
809 outb( 0x82, SCSI_Cntl_port
); /* Bus Enable + Select */
810 outb( adapter_mask
| (1 << current_SC
->target
), SCSI_Data_NoACK_port
);
812 /* Stop arbitration and enable parity */
813 outb( 0x10 | PARITY_MASK
, TMC_Cntl_port
);
815 in_interrupt_flag
= 0;
818 } else if (current_SC
->SCp
.phase
& in_selection
) {
819 status
= inb( SCSI_Status_port
);
820 if (!(status
& 0x01)) {
821 /* Try again, for slow devices */
822 if (fdomain_select( current_SC
->target
)) {
826 my_done( DID_NO_CONNECT
<< 16 );
830 printk( " AltSel " );
832 /* Stop arbitration and enable parity */
833 outb( 0x10 | PARITY_MASK
, TMC_Cntl_port
);
836 current_SC
->SCp
.phase
= in_other
;
837 outb( 0x90 | FIFO_COUNT
, Interrupt_Cntl_port
);
838 outb( 0x80, SCSI_Cntl_port
);
840 in_interrupt_flag
= 0;
845 /* current_SC->SCp.phase == in_other: this is the body of the routine */
847 status
= inb( SCSI_Status_port
);
849 if (status
& 0x10) { /* REQ */
851 switch (status
& 0x0e) {
853 case 0x08: /* COMMAND OUT */
854 outb( current_SC
->cmnd
[current_SC
->SCp
.sent_command
++],
855 Write_SCSI_Data_port
);
858 current_SC
->cmnd
[ current_SC
->SCp
.sent_command
- 1] );
861 case 0x00: /* DATA OUT -- tmc18c50 only */
862 if (chip
!= tmc1800
&& !current_SC
->SCp
.have_data_in
) {
863 current_SC
->SCp
.have_data_in
= -1;
864 outb( 0xd0 | PARITY_MASK
, TMC_Cntl_port
);
867 case 0x04: /* DATA IN -- tmc18c50 only */
868 if (chip
!= tmc1800
&& !current_SC
->SCp
.have_data_in
) {
869 current_SC
->SCp
.have_data_in
= 1;
870 outb( 0x90 | PARITY_MASK
, TMC_Cntl_port
);
873 case 0x0c: /* STATUS IN */
874 current_SC
->SCp
.Status
= inb( Read_SCSI_Data_port
);
876 printk( "Status = %x, ", current_SC
->SCp
.Status
);
879 if (current_SC
->SCp
.Status
&& current_SC
->SCp
.Status
!= 2) {
880 printk( "Future Domain: target = %d, command = %x, "
882 current_SC
->target
, current_SC
->cmnd
[0],
883 current_SC
->SCp
.Status
);
887 case 0x0a: /* MESSAGE OUT */
888 outb( MESSAGE_REJECT
, Write_SCSI_Data_port
); /* Reject */
890 case 0x0e: /* MESSAGE IN */
891 current_SC
->SCp
.Message
= inb( Read_SCSI_Data_port
);
893 printk( "Message = %x, ", current_SC
->SCp
.Message
);
895 if (!current_SC
->SCp
.Message
) ++done
;
896 #if DEBUG_MESSAGES || EVERY_ACCESS
897 if (current_SC
->SCp
.Message
) {
898 printk( "Future Domain: Message = %x\n",
899 current_SC
->SCp
.Message
);
907 && !current_SC
->SCp
.have_data_in
908 && (current_SC
->SCp
.sent_command
909 >= COMMAND_SIZE( current_SC
->cmnd
[ 0 ] ))) {
910 /* We have to get the FIFO direction
911 correct, so I've made a table based
912 on the SCSI Standard of which commands
913 appear to require a DATA OUT phase.
916 p. 94: Command for all device types
917 CHANGE DEFINITION 40 DATA OUT
920 COPY AND VERIFY 3a DATA OUT
922 LOG SELECT 4c DATA OUT
924 MODE SELECT (6) 15 DATA OUT
925 MODE SELECT (10) 55 DATA OUT
929 RECEIVE DIAGNOSTIC RESULTS 1c
931 SEND DIAGNOSTIC 1d DATA OUT
933 WRITE BUFFER 3b DATA OUT
935 p.178: Commands for direct-access devices (not listed on p. 94)
936 FORMAT UNIT 04 DATA OUT
939 PREVENT-ALLOW MEDIUM REMOVAL 1e
943 READ DEFECT DATA (10) 37
945 REASSIGN BLOCKS 07 DATA OUT
948 REZERO UNIT/REWIND 01
949 SEARCH DATA EQUAL (10) 31 DATA OUT
950 SEARCH DATA HIGH (10) 30 DATA OUT
951 SEARCH DATA LOW (10) 32 DATA OUT
958 WRITE (6)/PRINT/SEND 0a DATA OUT
959 WRITE (10)/SEND 2a DATA OUT
960 WRITE AND VERIFY (10) 2e DATA OUT
961 WRITE LONG 3f DATA OUT
962 WRITE SAME 41 DATA OUT ?
964 p. 261: Commands for sequential-access devices (not previously listed)
971 RECOVER BUFFERED DATA 14
975 p. 298: Commands for printer devices (not previously listed)
976 ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****
977 SLEW AND PRINT 0b DATA OUT -- same as seek
979 SYNCHRONIZE BUFFER 10
981 p. 315: Commands for processor devices (not previously listed)
983 p. 321: Commands for write-once devices (not previously listed)
986 SEARCH DATA EQUAL (12) b1 DATA OUT
987 SEARCH DATA HIGH (12) b0 DATA OUT
988 SEARCH DATA LOW (12) b2 DATA OUT
991 WRITE (12) aa DATA OUT
992 WRITE AND VERIFY (12) ae DATA OUT
994 p. 332: Commands for CD-ROM devices (not previously listed)
999 PLAY TRACK RELATIVE (10) 49
1000 PLAY TRACK RELATIVE (12) a9
1005 p. 370: Commands for scanner devices (not previously listed)
1006 GET DATA BUFFER STATUS 34
1010 SET WINDOW 24 DATA OUT
1012 p. 391: Commands for optical memory devices (not listed)
1015 MEDIUM SCAN 38 DATA OUT
1016 READ DEFECT DATA (12) b7
1018 READ UPDATED BLOCK 2d
1019 UPDATE BLOCK 3d DATA OUT
1021 p. 419: Commands for medium changer devices (not listed)
1023 INITIALIZE ELEMENT STATUS 07
1025 POSITION TO ELEMENT 2b
1026 READ ELEMENT STATUS b8
1027 REQUEST VOL. ELEMENT ADDRESS b5
1028 SEND VOLUME TAG b6 DATA OUT
1030 p. 454: Commands for communications devices (not listed previously)
1036 switch (current_SC
->cmnd
[0]) {
1037 case CHANGE_DEFINITION
: case COMPARE
: case COPY
:
1038 case COPY_VERIFY
: case LOG_SELECT
: case MODE_SELECT
:
1039 case MODE_SELECT_10
: case SEND_DIAGNOSTIC
: case WRITE_BUFFER
:
1041 case FORMAT_UNIT
: case REASSIGN_BLOCKS
: case RESERVE
:
1042 case SEARCH_EQUAL
: case SEARCH_HIGH
: case SEARCH_LOW
:
1043 case WRITE_6
: case WRITE_10
: case WRITE_VERIFY
:
1044 case 0x3f: case 0x41:
1046 case 0xb1: case 0xb0: case 0xb2:
1047 case 0xaa: case 0xae:
1051 case 0x38: case 0x3d:
1055 case 0xea: /* alternate number for WRITE LONG */
1057 current_SC
->SCp
.have_data_in
= -1;
1058 outb( 0xd0 | PARITY_MASK
, TMC_Cntl_port
);
1064 current_SC
->SCp
.have_data_in
= 1;
1065 outb( 0x90 | PARITY_MASK
, TMC_Cntl_port
);
1070 if (current_SC
->SCp
.have_data_in
== -1) { /* DATA OUT */
1071 while ( (data_count
= 0x2000 - inw( FIFO_Data_Count_port
)) > 512 ) {
1073 printk( "DC=%d, ", data_count
) ;
1075 if (data_count
> current_SC
->SCp
.this_residual
)
1076 data_count
= current_SC
->SCp
.this_residual
;
1077 if (data_count
> 0) {
1079 printk( "%d OUT, ", data_count
);
1081 if (data_count
== 1) {
1082 outb( *current_SC
->SCp
.ptr
++, Write_FIFO_port
);
1083 --current_SC
->SCp
.this_residual
;
1086 outsw( Write_FIFO_port
, current_SC
->SCp
.ptr
, data_count
);
1087 current_SC
->SCp
.ptr
+= 2 * data_count
;
1088 current_SC
->SCp
.this_residual
-= 2 * data_count
;
1091 if (!current_SC
->SCp
.this_residual
) {
1092 if (current_SC
->SCp
.buffers_residual
) {
1093 --current_SC
->SCp
.buffers_residual
;
1094 ++current_SC
->SCp
.buffer
;
1095 current_SC
->SCp
.ptr
= current_SC
->SCp
.buffer
->address
;
1096 current_SC
->SCp
.this_residual
= current_SC
->SCp
.buffer
->length
;
1103 if (current_SC
->SCp
.have_data_in
== 1) { /* DATA IN */
1104 while ((data_count
= inw( FIFO_Data_Count_port
)) > 0) {
1106 printk( "DC=%d, ", data_count
);
1108 if (data_count
> current_SC
->SCp
.this_residual
)
1109 data_count
= current_SC
->SCp
.this_residual
;
1112 printk( "%d IN, ", data_count
);
1114 if (data_count
== 1) {
1115 *current_SC
->SCp
.ptr
++ = inb( Read_FIFO_port
);
1116 --current_SC
->SCp
.this_residual
;
1118 data_count
>>= 1; /* Number of words */
1119 insw( Read_FIFO_port
, current_SC
->SCp
.ptr
, data_count
);
1120 current_SC
->SCp
.ptr
+= 2 * data_count
;
1121 current_SC
->SCp
.this_residual
-= 2 * data_count
;
1124 if (!current_SC
->SCp
.this_residual
1125 && current_SC
->SCp
.buffers_residual
) {
1126 --current_SC
->SCp
.buffers_residual
;
1127 ++current_SC
->SCp
.buffer
;
1128 current_SC
->SCp
.ptr
= current_SC
->SCp
.buffer
->address
;
1129 current_SC
->SCp
.this_residual
= current_SC
->SCp
.buffer
->length
;
1136 printk( " ** IN DONE %d ** ", current_SC
->SCp
.have_data_in
);
1140 if (current_SC
->cmnd
[0] == REQUEST_SENSE
&& !current_SC
->SCp
.Status
) {
1141 if ((unsigned char)(*((char *)current_SC
->request_buffer
+2)) & 0x0f) {
1144 unsigned char qualifier
;
1146 key
= (unsigned char)(*((char *)current_SC
->request_buffer
+ 2))
1148 code
= (unsigned char)(*((char *)current_SC
->request_buffer
+ 12));
1149 qualifier
= (unsigned char)(*((char *)current_SC
->request_buffer
1152 if (!(key
== UNIT_ATTENTION
&& (code
== 0x29 || !code
))
1153 && !(key
== NOT_READY
1155 && (!qualifier
|| qualifier
== 0x02 || qualifier
== 0x01))
1156 && !(key
== ILLEGAL_REQUEST
&& (code
== 0x25
1160 printk( "Future Domain: REQUEST SENSE "
1161 "Key = %x, Code = %x, Qualifier = %x\n",
1162 key
, code
, qualifier
);
1167 printk( "BEFORE MY_DONE. . ." );
1169 my_done( (current_SC
->SCp
.Status
& 0xff)
1170 | ((current_SC
->SCp
.Message
& 0xff) << 8) | (DID_OK
<< 16) );
1172 printk( "RETURNING.\n" );
1176 if (current_SC
->SCp
.phase
& disconnect
) {
1177 outb( 0xd0 | FIFO_COUNT
, Interrupt_Cntl_port
);
1178 outb( 0x00, SCSI_Cntl_port
);
1180 outb( 0x90 | FIFO_COUNT
, Interrupt_Cntl_port
);
1184 in_interrupt_flag
= 0;
1189 int fdomain_16x0_queue( Scsi_Cmnd
* SCpnt
, void (*done
)(Scsi_Cmnd
*))
1192 panic( "Future Domain: fdomain_16x0_queue() NOT REENTRANT!\n" );
1195 printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1197 *(unsigned char *)SCpnt
->cmnd
,
1199 SCpnt
->request_bufflen
);
1202 fdomain_make_bus_idle();
1204 current_SC
= SCpnt
; /* Save this for the done function */
1205 current_SC
->scsi_done
= done
;
1207 /* Initialize static data */
1209 if (current_SC
->use_sg
) {
1210 current_SC
->SCp
.buffer
=
1211 (struct scatterlist
*)current_SC
->request_buffer
;
1212 current_SC
->SCp
.ptr
= current_SC
->SCp
.buffer
->address
;
1213 current_SC
->SCp
.this_residual
= current_SC
->SCp
.buffer
->length
;
1214 current_SC
->SCp
.buffers_residual
= current_SC
->use_sg
- 1;
1216 current_SC
->SCp
.ptr
= (char *)current_SC
->request_buffer
;
1217 current_SC
->SCp
.this_residual
= current_SC
->request_bufflen
;
1218 current_SC
->SCp
.buffer
= NULL
;
1219 current_SC
->SCp
.buffers_residual
= 0;
1223 current_SC
->SCp
.Status
= 0;
1224 current_SC
->SCp
.Message
= 0;
1225 current_SC
->SCp
.have_data_in
= 0;
1226 current_SC
->SCp
.sent_command
= 0;
1227 current_SC
->SCp
.phase
= in_arbitration
;
1229 /* Start arbitration */
1230 outb( 0x00, Interrupt_Cntl_port
);
1231 outb( 0x00, SCSI_Cntl_port
); /* Disable data drivers */
1232 outb( adapter_mask
, SCSI_Data_NoACK_port
); /* Set our id bit */
1234 outb( 0x20, Interrupt_Cntl_port
);
1235 outb( 0x14 | PARITY_MASK
, TMC_Cntl_port
); /* Start arbitration */
1240 /* The following code, which simulates the old-style command function, was
1241 taken from Tommy Thorn's aha1542.c file. This code is Copyright (C)
1242 1992 Tommy Thorn. */
1244 static volatile int internal_done_flag
= 0;
1245 static volatile int internal_done_errcode
= 0;
1247 static void internal_done( Scsi_Cmnd
*SCpnt
)
1249 internal_done_errcode
= SCpnt
->result
;
1250 ++internal_done_flag
;
1253 int fdomain_16x0_command( Scsi_Cmnd
*SCpnt
)
1255 fdomain_16x0_queue( SCpnt
, internal_done
);
1257 while (!internal_done_flag
)
1259 internal_done_flag
= 0;
1260 return internal_done_errcode
;
1263 /* End of code derived from Tommy Thorn's work. */
1265 void print_info( Scsi_Cmnd
*SCpnt
)
1272 switch (SCpnt
->SCp
.phase
) {
1273 case in_arbitration
: printk( "arbitration " ); break;
1274 case in_selection
: printk( "selection " ); break;
1275 case in_other
: printk( "other " ); break;
1276 default: printk( "unknown " ); break;
1279 printk( "(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1282 *(unsigned char *)SCpnt
->cmnd
,
1284 SCpnt
->request_bufflen
);
1285 printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
1286 SCpnt
->SCp
.sent_command
,
1287 SCpnt
->SCp
.have_data_in
,
1290 printk( "in_interrupt_flag = %d\n", in_interrupt_flag
);
1293 imr
= (inb( 0x0a1 ) << 8) + inb( 0x21 );
1295 irr
= inb( 0xa0 ) << 8;
1299 isr
= inb( 0xa0 ) << 8;
1303 /* Print out interesting information */
1304 printk( "IMR = 0x%04x", imr
);
1305 if (imr
& (1 << interrupt_level
))
1306 printk( " (masked)" );
1307 printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr
, isr
);
1309 printk( "SCSI Status = 0x%02x\n", inb( SCSI_Status_port
) );
1310 printk( "TMC Status = 0x%02x", inb( TMC_Status_port
) );
1311 if (inb( TMC_Status_port
& 1))
1312 printk( " (interrupt)" );
1314 printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port
) );
1315 if (inb( Interrupt_Status_port
) & 0x08)
1316 printk( " (enabled)" );
1318 if (chip
== tmc18c50
) {
1319 printk( "FIFO Status = 0x%02x\n", inb( port_base
+ FIFO_Status
) );
1320 printk( "Int. Condition = 0x%02x\n",
1321 inb( port_base
+ Interrupt_Cond
) );
1323 printk( "Configuration 1 = 0x%02x\n", inb( port_base
+ Configuration1
) );
1324 if (chip
== tmc18c50
)
1325 printk( "Configuration 2 = 0x%02x\n",
1326 inb( port_base
+ Configuration2
) );
1329 int fdomain_16x0_abort( Scsi_Cmnd
*SCpnt
, int code
)
1332 #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1333 printk( "Future Domain: Abort " );
1338 #if EVERY_ACCESS || ERRORS_ONLY
1339 printk( " (not in command)\n" );
1344 #if EVERY_ACCESS || ERRORS_ONLY
1345 printk( " code = %d\n", code
);
1350 print_info( SCpnt
);
1353 fdomain_make_bus_idle();
1355 current_SC
->SCp
.phase
|= aborted
;
1357 current_SC
->result
= code
? code
: DID_ABORT
;
1361 /* Aborts are not done well. . . */
1362 my_done( code
<< 16 );
1367 int fdomain_16x0_reset( Scsi_Cmnd
*SCpnt
)
1370 static int called_once
= 0;
1374 printk( "Future Domain: SCSI Bus Reset\n" );
1378 if (called_once
) print_info( current_SC
);
1382 outb( 1, SCSI_Cntl_port
);
1384 outb( 0, SCSI_Cntl_port
);
1386 outb( 0, SCSI_Mode_Cntl_port
);
1387 outb( PARITY_MASK
, TMC_Cntl_port
);
1389 /* Unless this is the very first call (i.e., SCPnt == NULL), everything
1390 is probably hosed at this point. We will, however, try to keep
1391 things going by informing the high-level code that we need help. */
1394 SCpnt
->flags
|= NEEDS_JUMPSTART
;
1399 int fdomain_16x0_biosparam( int size
, int dev
, int *info_array
)
1403 unsigned short cylinders
;
1404 unsigned char heads
;
1405 unsigned char sectors
;
1409 The RAM area starts at 0x1f00 from the bios_base address.
1411 For BIOS Version 2.0:
1413 The drive parameter table seems to start at 0x1f30.
1414 The first byte's purpose is not known.
1415 Next is the cylinder, head, and sector information.
1416 The last 4 bytes appear to be the drive's size in sectors.
1417 The other bytes in the drive parameter table are unknown.
1418 If anyone figures them out, please send me mail, and I will
1421 Tape drives do not get placed in this table.
1423 There is another table at 0x1fea:
1424 If the byte is 0x01, then the SCSI ID is not in use.
1425 If the byte is 0x18 or 0x48, then the SCSI ID is in use,
1426 although tapes don't seem to be in this table. I haven't
1427 seen any other numbers (in a limited sample).
1429 0x1f2d is a drive count (i.e., not including tapes)
1431 The table at 0x1fcc are I/O ports addresses for the various
1432 operations. I calculate these by hand in this driver code.
1434 For BIOS Version 3.2:
1436 The drive parameter table starts at 0x1f70. Each entry is
1437 0x0a bytes long. Heads are one less than we need to report.
1440 drive
= MINOR(dev
) / 16;
1442 if (bios_major
== 2) {
1443 i
= (struct drive_info
*)( (char *)bios_base
+ 0x1f31 + drive
* 25 );
1444 info_array
[0] = i
->heads
;
1445 info_array
[1] = i
->sectors
;
1446 info_array
[2] = i
->cylinders
;
1447 } else if (bios_major
== 3) { /* Appears to be the same for 3.0 and 3.2 */
1448 i
= (struct drive_info
*)( (char *)bios_base
+ 0x1f71 + drive
* 10 );
1449 info_array
[0] = i
->heads
+ 1;
1450 info_array
[1] = i
->sectors
;
1451 info_array
[2] = i
->cylinders
;
1453 /* How the data is stored in the RAM area is very BIOS-dependent.
1454 Therefore, assume a version 3 layout, and check for validity. */
1456 i
= (struct drive_info
*)( (char *)bios_base
+ 0x1f71 + drive
* 10 );
1457 info_array
[0] = i
->heads
+ 1;
1458 info_array
[1] = i
->sectors
;
1459 info_array
[2] = i
->cylinders
;
1464 || info_array
[2] > 1024 /* DOS uses only 10 bits.
1465 Should this be changed
1466 to support larger drives?
1467 I.e., will the controller
1468 "do the right thing"?