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