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: Mon Jun 5 09:21:54 1995 by faith@cs.unc.edu 4 * Author: Rickard E. Faith, faith@cs.unc.edu 5 * Copyright 1992, 1993, 1994, 1995 Rickard E. Faith 6 * 7 * $Id: fdomain.c,v 5.28 1995/06/05 13:21:57 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, 3.4, and 3.5. 42 The following chips are supported: TMC-1800, TMC-18C50, TMC-18C30. 43 Reports suggest that the driver will also work with the 36C70 chip and 44 with the Quantum ISA-200S and ISA-250MG SCSI adapters. 45
46 Please note that the drive ordering that Future Domain implemented in BIOS 47 versions 3.4 and 3.5 is the opposite of the order (currently) used by the 48 rest of the SCSI industry. If you have BIOS version 3.4 or 3.5, and have 49 more then one drive, then the drive ordering will be the reverse of that 50 which you see under DOS. For example, under DOS SCSI ID 0 will be D: and 51 SCSI ID 1 will be C: (the boot device). Under Linux, SCSI ID 0 will be 52 /dev/sda and SCSI ID 1 will be /dev/sdb. The Linux ordering is consistent 53 with that provided by all the other SCSI drivers for Linux. If you want 54 this changed, send me patches that are protected by #ifdefs. 55
56 If you have a TMC-8xx or TMC-9xx board, then this is not the driver for 57 your board. Please refer to the Seagate driver for more information and 58 possible support. 59
60 61
62 REFERENCES USED: 63
64 "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation, 65 1990. 66
67 "Technical Reference Manual: 18C50 SCSI Host Adapter Chip", Future Domain 68 Corporation, January 1992. 69
70 "LXT SCSI Products: Specifications and OEM Technical Manual (Revision 71 B/September 1991)", Maxtor Corporation, 1991. 72
73 "7213S product Manual (Revision P3)", Maxtor Corporation, 1992. 74
75 "Draft Proposed American National Standard: Small Computer System 76 Interface - 2 (SCSI-2)", Global Engineering Documents. (X3T9.2/86-109, 77 revision 10h, October 17, 1991) 78
79 Private communications, Drew Eckhardt (drew@cs.colorado.edu) and Eric 80 Youngdale (ericy@cais.com), 1992. 81
82 Private communication, Tuong Le (Future Domain Engineering department), 83 1994. (Disk geometry computations for Future Domain BIOS version 3.4, and 84 TMC-18C30 detection.) 85
86 Hogan, Thom. The Programmer's PC Sourcebook. Microsoft Press, 1988. Page 87 60 (2.39: Disk Partition Table Layout). 88
89 "18C30 Technical Reference Manual", Future Domain Corporation, 1993, page 90 6-1. 91
92
93 94 NOTES ON REFERENCES: 95
96 The Maxtor manuals were free. Maxtor telephone technical support is 97 great! 98
99 The Future Domain manuals were $25 and $35. They document the chip, not 100 the TMC-16x0 boards, so some information I had to guess at. In 1992, 101 Future Domain sold DOS BIOS source for $250 and the UN*X driver source was 102 $750, but these required a non-disclosure agreement, so even if I could 103 have afforded them, they would *not* have been useful for writing this 104 publically distributable driver. Future Domain technical support has 105 provided some information on the phone and have sent a few useful FAXs. 106 They have been much more helpful since they started to recognize that the 107 word "Linux" refers to an operating system :-). 108
109 110
111 ALPHA TESTERS: 112
113 There are many other alpha testers that come and go as the driver 114 develops. The people listed here were most helpful in times of greatest 115 need (mostly early on -- I've probably left out a few worthy people in 116 more recent times): 117
118 Todd Carrico (todd@wutc.wustl.edu), Dan Poirier (poirier@cs.unc.edu ), Ken 119 Corey (kenc@sol.acs.unt.edu), C. de Bruin (bruin@bruin@sterbbs.nl), Sakari 120 Aaltonen (sakaria@vipunen.hit.fi), John Rice (rice@xanth.cs.odu.edu), Brad 121 Yearwood (brad@optilink.com), and Ray Toy (toy@soho.crd.ge.com). 122
123 Special thanks to Tien-Wan Yang (twyang@cs.uh.edu), who graciously lent me 124 his 18C50-based card for debugging. He is the sole reason that this 125 driver works with the 18C50 chip. 126
127 Thanks to Dave Newman (dnewman@crl.com) for providing initial patches for 128 the version 3.4 BIOS. 129
130 Thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for providing 131 patches that support the TMC-3260, a PCI bus card with the 36C70 chip. 132 The 36C70 chip appears to be "completely compatible" with the 18C30 chip. 133
134 Thanks to Eric Kasten (tigger@petroglyph.cl.msu.edu) for providing the 135 patch for the version 3.5 BIOS. 136
137 Thanks for Stephen Henson (shenson@nyx10.cs.du.edu) for providing the 138 patch for the Quantum ISA-200S SCSI adapter. 139 140 Thanks to Adam Bowen for the signature to the 1610M/MER/MEX scsi cards, 141 and to Martin Andrews (andrewm@ccfadm.eeg.ccf.org) for the signature to 142 some random TMC-1680 repackaged by IBM. 143
144 Thanks for Mark Singer (elf@netcom.com) and Richard Simpson 145 (rsimpson@ewrcsdra.demon.co.uk) for more Quantum signatures and detective 146 work on the Quantum RAM layout. 147
148 All of the alpha testers deserve much thanks. 149
150
151
152 NOTES ON USER DEFINABLE OPTIONS: 153
154 DEBUG: This turns on the printing of various debug information. 155
156 ENABLE_PARITY: This turns on SCSI parity checking. With the current 157 driver, all attached devices must support SCSI parity. If none of your 158 devices support parity, then you can probably get the driver to work by 159 turning this option off. I have no way of testing this, however. 160
161 FIFO_COUNT: The host adapter has an 8K cache (host adapters based on the 162 18C30 chip have a 2k cache). When this many 512 byte blocks are filled by 163 the SCSI device, an interrupt will be raised. Therefore, this could be as 164 low as 0, or as high as 16. Note, however, that values which are too high 165 or too low seem to prevent any interrupts from occurring, and thereby lock 166 up the machine. I have found that 2 is a good number, but throughput may 167 be increased by changing this value to values which are close to 2. 168 Please let me know if you try any different values. 169
170 DO_DETECT: This activates some old scan code which was needed before the 171 high level drivers got fixed. If you are having trouble with the driver, 172 turning this on should not hurt, and might help. Please let me know if 173 this is the case, since this code will be removed from future drivers. 174
175 RESELECTION: This is no longer an option, since I gave up trying to 176 implement it in version 4.x of this driver. It did not improve 177 performance at all and made the driver unstable (because I never found one 178 of the two race conditions which were introduced by the multiple 179 outstanding command code). The instability seems a very high price to pay 180 just so that you don't have to wait for the tape to rewind. If you want 181 this feature implemented, send me patches. I'll be happy to send a copy 182 of my (broken) driver to anyone who would like to see a copy. 183
184 **************************************************************************/ 185
186 #include <linux/sched.h>
187 #include <asm/io.h>
188 #include "../block/blk.h"
189 #include "scsi.h"
190 #include "hosts.h"
191 #include "fdomain.h"
192 #include <asm/system.h>
193 #include <linux/errno.h>
194 #include <linux/string.h>
195 #include <linux/ioport.h>
196
197 #defineVERSION "$Revision: 5.28 $"
198
199 /* START OF USER DEFINABLE OPTIONS */ 200
201 #defineDEBUG 1 /* Enable debugging output */ 202 #defineENABLE_PARITY 1 /* Enable SCSI Parity */ 203 #defineFIFO_COUNT 2 /* Number of 512 byte blocks before INTR */ 204 #defineDO_DETECT 0 /* Do device detection here (see scsi.c) */ 205
206 /* END OF USER DEFINABLE OPTIONS */ 207
208 #ifDEBUG 209 #defineEVERY_ACCESS 0 /* Write a line on every scsi access */ 210 #defineERRORS_ONLY 1 /* Only write a line if there is an error */ 211 #defineDEBUG_DETECT 0 /* Debug fdomain_16x0_detect() */ 212 #defineDEBUG_MESSAGES 1 /* Debug MESSAGE IN phase */ 213 #defineDEBUG_ABORT 1 /* Debug abort() routine */ 214 #defineDEBUG_RESET 1 /* Debug reset() routine */ 215 #defineDEBUG_RACE 1 /* Debug interrupt-driven race condition */ 216 #else 217 #defineEVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */ 218 #defineERRORS_ONLY 0
219 #defineDEBUG_DETECT 0
220 #defineDEBUG_MESSAGES 0
221 #defineDEBUG_ABORT 0
222 #defineDEBUG_RESET 0
223 #defineDEBUG_RACE 0
224 #endif 225
226 /* Errors are reported on the line, so we don't need to report them again */ 227 #ifEVERY_ACCESS 228 #undefERRORS_ONLY 229 #defineERRORS_ONLY 0
230 #endif 231
232 #ifENABLE_PARITY 233 #definePARITY_MASK 0x08
234 #else 235 #definePARITY_MASK 0x00
236 #endif 237
238 enumchip_type{ 239 unknown = 0x00,
240 tmc1800 = 0x01,
241 tmc18c50 = 0x02,
242 tmc18c30 = 0x03,
243 };
244
245 enum{ 246 in_arbitration = 0x02,
247 in_selection = 0x04,
248 in_other = 0x08,
249 disconnect = 0x10,
250 aborted = 0x20,
251 sent_ident = 0x40,
252 };
253
254 enum in_port_type { 255 Read_SCSI_Data = 0,
256 SCSI_Status = 1,
257 TMC_Status = 2,
258 FIFO_Status = 3, /* tmc18c50/tmc18c30 only */ 259 Interrupt_Cond = 4, /* tmc18c50/tmc18c30 only */ 260 LSB_ID_Code = 5,
261 MSB_ID_Code = 6,
262 Read_Loopback = 7,
263 SCSI_Data_NoACK = 8,
264 Interrupt_Status = 9,
265 Configuration1 = 10,
266 Configuration2 = 11, /* tmc18c50/tmc18c30 only */ 267 Read_FIFO = 12,
268 FIFO_Data_Count = 14
269 };
270
271 enum out_port_type { 272 Write_SCSI_Data = 0,
273 SCSI_Cntl = 1,
274 Interrupt_Cntl = 2,
275 SCSI_Mode_Cntl = 3,
276 TMC_Cntl = 4,
277 Memory_Cntl = 5, /* tmc18c50/tmc18c30 only */ 278 Write_Loopback = 7,
279 IO_Control = 11, /* tmc18c30 only */ 280 Write_FIFO = 12
281 };
282
283 staticintport_base = 0;
284 staticvoid *bios_base = NULL;
285 staticintbios_major = 0;
286 staticintbios_minor = 0;
287 staticintPCI_bus = 0;
288 staticintQuantum = 0; /* Quantum board variant */ 289 staticintinterrupt_level = 0;
290 staticvolatileintin_command = 0;
291 staticScsi_Cmnd *current_SC = NULL;
292 staticenumchip_typechip = unknown;
293 staticintadapter_mask = 0x40;
294 #ifDEBUG_RACE 295 staticvolatileintin_interrupt_flag = 0;
296 #endif 297
298 staticintSCSI_Mode_Cntl_port;
299 staticintFIFO_Data_Count_port;
300 staticintInterrupt_Cntl_port;
301 staticintInterrupt_Status_port;
302 staticintRead_FIFO_port;
303 staticintRead_SCSI_Data_port;
304 staticintSCSI_Cntl_port;
305 staticintSCSI_Data_NoACK_port;
306 staticintSCSI_Status_port;
307 staticintTMC_Cntl_port;
308 staticintTMC_Status_port;
309 staticintWrite_FIFO_port;
310 staticintWrite_SCSI_Data_port;
311
312 staticintFIFO_Size = 0x2000; /* 8k FIFO for 313 pre-tmc18c30 chips */ 314
315 externvoidfdomain_16x0_intr( intirq, structpt_regs * regs );
316
317 staticvoid *addresses[] = { 318 (void *)0xc8000,
319 (void *)0xca000,
320 (void *)0xce000,
321 (void *)0xde000,
322 (void *)0xd0000, /* Extra addresses for PCI boards */ 323 (void *)0xe0000,
324 };
325 #defineADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
326
327 staticunsignedshortports[] = { 0x140, 0x150, 0x160, 0x170 };
328 #definePORT_COUNT (sizeof( ports ) / sizeof( unsignedshort ))
329
330 staticunsignedshortints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
331
332 /* 333
334 READ THIS BEFORE YOU ADD A SIGNATURE! 335
336 READING THIS SHORT NOTE CAN SAVE YOU LOTS OF TIME! 337
338 READ EVERY WORD, ESPECIALLY THE WORD *NOT* 339
340 This driver works *ONLY* for Future Domain cards using the TMC-1800, 341 TMC-18C50, or TMC-18C30 chip. This includes models TMC-1650, 1660, 1670, 342 and 1680. 343
344 The following BIOS signature signatures are for boards which do *NOT* 345 work with this driver (these TMC-8xx and TMC-9xx boards may work with the 346 Seagate driver): 347
348 FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88 349 FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89 350 FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89 351 FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90 352 FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90 353 FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90 354 FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92 355
356 */ 357
358 structsignature{ 359 char *signature;
360 intsig_offset;
361 intsig_length;
362 intmajor_bios_version;
363 intminor_bios_version;
364 intflag; /* 1 == PCI_bus, 2 == ISA_200S, 3 == ISA_250MG, 4 == ISA_200S */ 365 }signatures[] = { 366 /* 1 2 3 4 5 6 */ 367 /* 123456789012345678901234567890123456789012345678901234567890 */ 368 { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 5, 50, 2, 0, 0 },
369 { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89", 5, 50, 2, 0, 0 },
370 { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50, 2, 0, 2 },
371 { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0", 73, 43, 2, 0, 3 },
372 { "FUTURE DOMAIN CORP. (C) 1991 1800-V2.0.", 72, 39, 2, 0, 4 },
373 { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92", 5, 44, 3, 0, 0 },
374 { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93", 5, 44, 3, 2, 0 },
375 { "IBM F1 P2 BIOS v1.0104/29/93", 5, 28, 3, -1, 0 },
376 { "Future Domain Corp. V1.0008/18/93", 5, 33, 3, 4, 0 },
377 { "Future Domain Corp. V1.0008/18/93", 26, 33, 3, 4, 1 },
378 /* This next signature may not be a 3.5 bios */ 379 { "Future Domain Corp. V2.0108/18/93", 5, 33, 3, 5, 0 },
380 { "FUTURE DOMAIN CORP. V3.5008/18/93", 5, 34, 3, 5, 0 },
381 { "FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5", 5, 44, 3, 5, 0 },
382 { "FUTURE DOMAIN TMC-18XX", 5, 22, -1, -1, 0 },
383
384 /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGNATURE 385 Also, fix the disk geometry code for your signature and send your 386 changes for faith@cs.unc.edu. Above all, do *NOT* change any old 387 signatures! 388
389 Note that the last line will match a "generic" 18XX bios. Because 390 Future Domain has changed the host SCSI ID and/or the location of the 391 geometry information in the on-board RAM area for each of the first 392 three BIOS's, it is still important to enter a fully qualified 393 signature in the table for any new BIOS's (after the host SCSI ID and 394 geometry location are verified). */ 395 };
396
397 #defineSIGNATURE_COUNT (sizeof( signatures ) / sizeof( structsignature ))
398
399 staticvoidprint_banner( structScsi_Host *shpnt )
400 { 401 if (!shpnt) return; /* This won't ever happen */ 402
403 printk( "scsi%d <fdomain>: BIOS version ", shpnt->host_no );
404
405 if (bios_major >= 0) printk( "%d.", bios_major );
406 elseprintk( "?." );
407
408 if (bios_minor >= 0) printk( "%d", bios_minor );
409 elseprintk( "?." );
410
411 printk( " at 0x%x using scsi id %d\n",
412 (unsigned)bios_base, shpnt->this_id );
413
414 printk( "scsi%d <fdomain>: %s chip at 0x%x irq ",
415 shpnt->host_no,
416 chip == tmc1800 ? "TMC-1800"
417 : (chip == tmc18c50 ? "TMC-18C50"
418 : (chip == tmc18c30 ? "TMC-18C30" : "Unknown")),
419 port_base );
420
421 if (interrupt_level) printk( "%d", interrupt_level );
422 elseprintk( "<none>" );
423
424 if (PCI_bus) printk( " (PCI bus)" );
425 printk( "\n" );
426 } 427
428 staticvoiddo_pause( unsignedamount ) /* Pause for amount*10 milliseconds *//* */ 429 { 430 unsignedlongthe_time = jiffies + amount; /* 0.01 seconds per jiffy */ 431
432 while (jiffies < the_time);
433 } 434
435 inlinestaticvoidfdomain_make_bus_idle( void )
/* */ 436 { 437 outb( 0, SCSI_Cntl_port );
438 outb( 0, SCSI_Mode_Cntl_port );
439 if (chip == tmc18c50 || chip == tmc18c30)
440 outb( 0x21 | PARITY_MASK, TMC_Cntl_port ); /* Clear forced intr. */ 441 else 442 outb( 0x01 | PARITY_MASK, TMC_Cntl_port );
443 } 444
445 staticintfdomain_is_valid_port( intport )
/* */ 446 { 447 intoptions;
448
449 #ifDEBUG_DETECT 450 printk( " (%x%x),",
451 inb( port + MSB_ID_Code ), inb( port + LSB_ID_Code ) );
452 #endif 453
454 /* The MCA ID is a unique id for each MCA compatible board. We 455 are using ISA boards, but Future Domain provides the MCA ID 456 anyway. We can use this ID to ensure that this is a Future 457 Domain TMC-1660/TMC-1680. 458 */ 459
460 if (inb( port + LSB_ID_Code ) != 0xe9) {/* test for 0x6127 id */ 461 if (inb( port + LSB_ID_Code ) != 0x27) return 0;
462 if (inb( port + MSB_ID_Code ) != 0x61) return 0;
463 chip = tmc1800;
464 }else{/* test for 0xe960 id */ 465 if (inb( port + MSB_ID_Code ) != 0x60) return 0;
466 chip = tmc18c50;
467
468 #if 0
469
470 /* Try to toggle 32-bit mode. This only 471 works on an 18c30 chip. (User reports 472 say that this doesn't work at all, so 473 we'll use the other method.) */ 474
475 outb( 0x80, port + IO_Control );
476 if (inb( port + Configuration2 ) & 0x80 == 0x80) { 477 outb( 0x00, port + IO_Control );
478 if (inb( port + Configuration2 ) & 0x80 == 0x00) { 479 chip = tmc18c30;
480 FIFO_Size = 0x800; /* 2k FIFO */ 481 } 482 } 483 #else 484
485 /* That should have worked, but appears to 486 have problems. Lets assume it is an 487 18c30 if the RAM is disabled. */ 488
489 if (inb( port + Configuration2 ) & 0x02) { 490 chip = tmc18c30;
491 FIFO_Size = 0x800; /* 2k FIFO */ 492 } 493 #endif 494 /* If that failed, we are an 18c50. */ 495 } 496
497 /* We have a valid MCA ID for a TMC-1660/TMC-1680 Future Domain board. 498 Now, check to be sure the bios_base matches these ports. If someone 499 was unlucky enough to have purchased more than one Future Domain 500 board, then they will have to modify this code, as we only detect one 501 board here. [The one with the lowest bios_base.] */ 502
503 options = inb( port + Configuration1 );
504
505 #ifDEBUG_DETECT 506 printk( " Options = %x\n", options );
507 #endif 508
509 /* Check for board with lowest bios_base -- 510 this isn't valid for the 18c30 or for 511 boards on the PCI bus, so just assume we 512 have the right board. */ 513
514 if (chip != tmc18c30 515 && !PCI_bus 516 && addresses[ (options & 0xc0) >> 6 ] != bios_base) return 0;
517
518 /* Get the IRQ from the options. */ 519
520 interrupt_level = ints[ (options & 0x0e) >> 1 ];
521
522 return 1;
523 } 524
525 staticintfdomain_test_loopback( void )
/* */ 526 { 527 inti;
528 intresult;
529
530 for (i = 0; i < 255; i++) { 531 outb( i, port_base + Write_Loopback );
532 result = inb( port_base + Read_Loopback );
533 if (i != result)
534 return 1;
535 } 536 return 0;
537 } 538
539 intfdomain_16x0_detect( Scsi_Host_Template *tpnt )
/* */ 540 { 541 inti, j;
542 intflag = 0;
543 intretcode;
544 structScsi_Host *shpnt;
545 #ifDO_DETECT 546 constintbuflen = 255;
547 Scsi_CmndSCinit;
548 unsignedchardo_inquiry[] = {INQUIRY, 0, 0, 0, buflen, 0 };
549 unsignedchardo_request_sense[] = {REQUEST_SENSE, 0, 0, 0, buflen, 0 };
550 unsignedchardo_read_capacity[] = {READ_CAPACITY,
551 0, 0, 0, 0, 0, 0, 0, 0, 0 };
552 unsignedcharbuf[buflen];
553 #endif 554
555 #ifDEBUG_DETECT 556 printk( "fdomain_16x0_detect()," );
557 #endif 558
559 for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) { 560 #ifDEBUG_DETECT 561 printk( " %x(%x),", (unsigned)addresses[i], (unsigned)bios_base );
562 #endif 563 for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) { 564 if (!memcmp( ((char *)addresses[i] + signatures[j].sig_offset),
565 signatures[j].signature, signatures[j].sig_length )) { 566 bios_major = signatures[j].major_bios_version;
567 bios_minor = signatures[j].minor_bios_version;
568 PCI_bus = (signatures[j].flag == 1);
569 Quantum = (signatures[j].flag > 1) ? signatures[j].flag : 0;
570 bios_base = addresses[i];
571 } 572 } 573 } 574
575 if (!bios_base) { 576 #ifDEBUG_DETECT 577 printk( " FAILED: NO BIOS\n" );
578 #endif 579 return 0;
580 } 581
582 if (bios_major == 2) { 583 /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM. 584 Assuming the ROM is enabled (otherwise we wouldn't have been 585 able to read the ROM signature :-), then the ROM sets up the 586 RAM area with some magic numbers, such as a list of port 587 base addresses and a list of the disk "geometry" reported to 588 DOS (this geometry has nothing to do with physical geometry). 589 */ 590
591 switch (Quantum) { 592 case 2: /* ISA_200S */ 593 case 3: /* ISA_250MG */ 594 port_base = *((char *)bios_base + 0x1fa2)
595 + (*((char *)bios_base + 0x1fa3) << 8);
596 break;
597 case 4: /* ISA_200S (another one) */ 598 port_base = *((char *)bios_base + 0x1fa3)
599 + (*((char *)bios_base + 0x1fa4) << 8);
600 break;
601 default:
602 port_base = *((char *)bios_base + 0x1fcc)
603 + (*((char *)bios_base + 0x1fcd) << 8);
604 break;
605 } 606
607 #ifDEBUG_DETECT 608 printk( " %x,", port_base );
609 #endif 610
611 for (flag = 0, i = 0; !flag && i < PORT_COUNT; i++) { 612 if (port_base == ports[i])
613 ++flag;
614 } 615
616 if (flag)
617 flag = fdomain_is_valid_port( port_base );
618 } 619
620 if (!flag) {/* Cannot get port base from BIOS RAM */ 621
622 /* This is a bad sign. It usually means that someone patched the 623 BIOS signature list (the signatures variable) to contain a BIOS 624 signature for a board *OTHER THAN* the TMC-1660/TMC-1680. It 625 also means that we don't have a Version 2.0 BIOS :-) 626 */ 627
628 #ifDEBUG_DETECT 629 if (bios_major != 2) printk( " RAM FAILED, " );
630 #endif 631
632 /* Anyway, the alternative to finding the address in the RAM is to 633 just search through every possible port address for one that is 634 attached to the Future Domain card. Don't panic, though, about 635 reading all these random port addresses -- there are rumors that 636 the Future Domain BIOS does something very similar. 637
638 Do not, however, check ports which the kernel knows are being used 639 by another driver. */ 640
641 if (!PCI_bus) { 642 for (i = 0; !flag && i < PORT_COUNT; i++) { 643 port_base = ports[i];
644 if (check_region( port_base, 0x10 )) { 645 #ifDEBUG_DETECT 646 printk( " (%x inuse),", port_base );
647 #endif 648 continue;
649 } 650 #ifDEBUG_DETECT 651 printk( " %x,", port_base );
652 #endif 653 flag = fdomain_is_valid_port( port_base );
654 } 655 }else{ 656
657 /* The proper way of doing this is to use ask the PCI bus for the 658 device IRQ and interrupt level. 659
660 Until the Linux kernel supports this sort of PCI bus query, we 661 scan down a bunch of addresses (Future Domain tech support says 662 we will probably find the address before we get to 0xf800). 663 This works fine on some systems -- other systems may have to 664 scan more addresses. If you have to modify this section for 665 your installation, please send mail to faith@cs.unc.edu. */ 666
667 for (i = 0xfff8; !flag && i > 0xe000; i -= 8) { 668 port_base = i;
669 if (check_region( port_base, 0x10 )) { 670 #ifDEBUG_DETECT 671 printk( " (%x inuse)," , port_base );
672 #endif 673 continue;
674 } 675 flag = fdomain_is_valid_port( port_base );
676 } 677 } 678 } 679
680 if (!flag) { 681 #ifDEBUG_DETECT 682 printk( " FAILED: NO PORT\n" );
683 #endif 684 return 0; /* Cannot find valid set of ports */ 685 } 686
687 SCSI_Mode_Cntl_port = port_base + SCSI_Mode_Cntl;
688 FIFO_Data_Count_port = port_base + FIFO_Data_Count;
689 Interrupt_Cntl_port = port_base + Interrupt_Cntl;
690 Interrupt_Status_port = port_base + Interrupt_Status;
691 Read_FIFO_port = port_base + Read_FIFO;
692 Read_SCSI_Data_port = port_base + Read_SCSI_Data;
693 SCSI_Cntl_port = port_base + SCSI_Cntl;
694 SCSI_Data_NoACK_port = port_base + SCSI_Data_NoACK;
695 SCSI_Status_port = port_base + SCSI_Status;
696 TMC_Cntl_port = port_base + TMC_Cntl;
697 TMC_Status_port = port_base + TMC_Status;
698 Write_FIFO_port = port_base + Write_FIFO;
699 Write_SCSI_Data_port = port_base + Write_SCSI_Data;
700
701 fdomain_16x0_reset( NULL );
702
703 if (fdomain_test_loopback()) { 704 #ifDEBUG_DETECT 705 printk( "fdomain: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
706 #endif 707 return 0;
708 } 709
710 if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) { 711 adapter_mask = 0x80;
712 tpnt->this_id = 7;
713 } 714
715 /* Print out a banner here in case we can't 716 get resources. */ 717
718 shpnt = scsi_register( tpnt, 0 );
719 print_banner( shpnt );
720
721 /* Log IRQ with kernel */ 722 if (!interrupt_level) { 723 panic( "fdomain: *NO* interrupt level selected!\n" );
724 }else{ 725 /* Register the IRQ with the kernel */ 726
727 retcode = request_irq( interrupt_level,
728 fdomain_16x0_intr, SA_INTERRUPT, "fdomain" );
729
730 if (retcode < 0) { 731 if (retcode == -EINVAL) { 732 printk( "fdomain: IRQ %d is bad!\n", interrupt_level );
733 printk( " This shouldn't happen!\n" );
734 printk( " Send mail to faith@cs.unc.edu\n" );
735 }elseif (retcode == -EBUSY) { 736 printk( "fdomain: IRQ %d is already in use!\n", interrupt_level );
737 printk( " Please use another IRQ!\n" );
738 }else{ 739 printk( "fdomain: Error getting IRQ %d\n", interrupt_level );
740 printk( " This shouldn't happen!\n" );
741 printk( " Send mail to faith@cs.unc.edu\n" );
742 } 743 panic( "fdomain: Driver requires interruptions\n" );
744 } 745 } 746
747 /* Log I/O ports with kernel */ 748 request_region( port_base, 0x10, "fdomain" );
749
750 #ifDO_DETECT 751
752 /* These routines are here because of the way the SCSI bus behaves after 753 a reset. This appropriate behavior was not handled correctly by the 754 higher level SCSI routines when I first wrote this driver. Now, 755 however, correct scan routines are part of scsi.c and these routines 756 are no longer needed. However, this code is still good for 757 debugging. */ 758
759 SCinit.request_buffer = SCinit.buffer = buf;
760 SCinit.request_bufflen = SCinit.bufflen = sizeof(buf)-1;
761 SCinit.use_sg = 0;
762 SCinit.lun = 0;
763
764 printk( "fdomain: detection routine scanning for devices:\n" );
765 for (i = 0; i < 8; i++) { 766 SCinit.target = i;
767 if (i == tpnt->this_id) /* Skip host adapter */ 768 continue;
769 memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
770 retcode = fdomain_16x0_command(&SCinit);
771 if (!retcode) { 772 memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
773 retcode = fdomain_16x0_command(&SCinit);
774 if (!retcode) { 775 printk( " SCSI ID %d: ", i );
776 for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
777 printk( "%c", buf[j] >= 20 ? buf[j] : ' ' );
778 memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
779 retcode = fdomain_16x0_command(&SCinit);
780 if (!retcode) { 781 unsignedlongblocks, size, capacity;
782
783 blocks = (buf[0] << 24) | (buf[1] << 16)
784 | (buf[2] << 8) | buf[3];
785 size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
786 capacity = +( +(blocks / 1024L) * +(size * 10L)) / 1024L;
787
788 printk( "%lu MB (%lu byte blocks)",
789 ((capacity + 5L) / 10L), size );
790 }else{ 791 memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
792 retcode = fdomain_16x0_command(&SCinit);
793 } 794 printk ("\n" );
795 }else{ 796 memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
797 retcode = fdomain_16x0_command(&SCinit);
798 } 799 } 800 } 801 #endif 802
803 return 1; /* Maximum of one adapter will be detected. */ 804 } 805
806 constchar *fdomain_16x0_info( structScsi_Host *ignore )
/* */ 807 { 808 staticcharbuffer[80];
809 char *pt;
810
811 strcpy( buffer, "Future Domain TMC-16x0 SCSI driver, version" );
812 if (strchr( VERSION, ':')) {/* Assume VERSION is an RCS Revision string */ 813 strcat( buffer, strchr( VERSION, ':' ) + 1 );
814 pt = strrchr( buffer, '$') - 1;
815 if (!pt) /* Stripped RCS Revision string? */ 816 pt = buffer + strlen( buffer ) - 1;
817 if (*pt != ' ')
818 ++pt;
819 *pt = '\0';
820 }else{/* Assume VERSION is a number */ 821 strcat( buffer, " " VERSION );
822 } 823
824 returnbuffer;
825 } 826
827 #if 0
828 staticint fdomain_arbitrate( void )
/* */ 829 { 830 intstatus = 0;
831 unsignedlongtimeout;
832
833 #ifEVERY_ACCESS 834 printk( "fdomain_arbitrate()\n" );
835 #endif 836
837 outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */ 838 outb( adapter_mask, port_base + SCSI_Data_NoACK ); /* Set our id bit */ 839 outb( 0x04 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */ 840
841 timeout = jiffies + 50; /* 500 mS */ 842 while (jiffies < timeout) { 843 status = inb( TMC_Status_port ); /* Read adapter status */ 844 if (status & 0x02) /* Arbitration complete */ 845 return 0;
846 } 847
848 /* Make bus idle */ 849 fdomain_make_bus_idle();
850
851 #ifEVERY_ACCESS 852 printk( "Arbitration failed, status = %x\n", status );
853 #endif 854 #ifERRORS_ONLY 855 printk( "fdomain: Arbitration failed, status = %x\n", status );
856 #endif 857 return 1;
858 } 859 #endif 860
861 staticintfdomain_select( inttarget )
/* */ 862 { 863 intstatus;
864 unsignedlongtimeout;
865 staticintflag = 0;
866
867
868 outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */ 869 outb( adapter_mask | (1 << target), SCSI_Data_NoACK_port );
870
871 /* Stop arbitration and enable parity */ 872 outb( PARITY_MASK, TMC_Cntl_port );
873
874 timeout = jiffies + 35; /* 350mS -- because of timeouts 875 (was 250mS) */ 876
877 while (jiffies < timeout) { 878 status = inb( SCSI_Status_port ); /* Read adapter status */ 879 if (status & 1) {/* Busy asserted */ 880 /* Enable SCSI Bus (on error, should make bus idle with 0) */ 881 outb( 0x80, SCSI_Cntl_port );
882 return 0;
883 } 884 } 885 /* Make bus idle */ 886 fdomain_make_bus_idle();
887 #ifEVERY_ACCESS 888 if (!target) printk( "Selection failed\n" );
889 #endif 890 #ifERRORS_ONLY 891 if (!target) { 892 if (chip == tmc18c30 && !flag) /* Skip first failure for 18C30 chips. */ 893 ++flag;
894 else 895 printk( "fdomain: Selection failed\n" );
896 } 897 #endif 898 return 1;
899 } 900
901 voidmy_done( interror )
/* */ 902 { 903 if (in_command) { 904 in_command = 0;
905 outb( 0x00, Interrupt_Cntl_port );
906 fdomain_make_bus_idle();
907 current_SC->result = error;
908 if (current_SC->scsi_done)
909 current_SC->scsi_done( current_SC );
910 elsepanic( "fdomain: current_SC->scsi_done() == NULL" );
911 }else{ 912 panic( "fdomain: my_done() called outside of command\n" );
913 } 914 #ifDEBUG_RACE 915 in_interrupt_flag = 0;
916 #endif 917 } 918
919 voidfdomain_16x0_intr( intirq, structpt_regs * regs )
/* */ 920 { 921 intstatus;
922 intdone = 0;
923 unsigneddata_count;
924
925 /* The fdomain_16x0_intr is only called via 926 the interrupt handler. The goal of the 927 sti() here is to allow other 928 interruptions while this routine is 929 running. */ 930
931 sti(); /* Yes, we really want sti() here */ 932
933 outb( 0x00, Interrupt_Cntl_port );
934
935 /* We usually have one spurious interrupt after each command. Ignore it. */ 936 if (!in_command || !current_SC) {/* Spurious interrupt */ 937 #ifEVERY_ACCESS 938 printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
939 in_command, current_SC );
940 #endif 941 return;
942 } 943
944 /* Abort calls my_done, so we do nothing here. */ 945 if (current_SC->SCp.phase & aborted) { 946 #ifDEBUG_ABORT 947 printk( "Interrupt after abort, ignoring\n" );
948 #endif 949 /* 950 return; */ 951 } 952
953 #ifDEBUG_RACE 954 ++in_interrupt_flag;
955 #endif 956
957 if (current_SC->SCp.phase & in_arbitration) { 958 status = inb( TMC_Status_port ); /* Read adapter status */ 959 if (!(status & 0x02)) { 960 #ifEVERY_ACCESS 961 printk( " AFAIL " );
962 #endif 963 my_done( DID_BUS_BUSY << 16 );
964 return;
965 } 966 current_SC->SCp.phase = in_selection;
967
968 outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );
969
970 outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */ 971 outb( adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port );
972
973 /* Stop arbitration and enable parity */ 974 outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
975 #ifDEBUG_RACE 976 in_interrupt_flag = 0;
977 #endif 978 return;
979 }elseif (current_SC->SCp.phase & in_selection) { 980 status = inb( SCSI_Status_port );
981 if (!(status & 0x01)) { 982 /* Try again, for slow devices */ 983 if (fdomain_select( current_SC->target )) { 984 #ifEVERY_ACCESS 985 printk( " SFAIL " );
986 #endif 987 my_done( DID_NO_CONNECT << 16 );
988 return;
989 }else{ 990 #ifEVERY_ACCESS 991 printk( " AltSel " );
992 #endif 993 /* Stop arbitration and enable parity */ 994 outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
995 } 996 } 997 current_SC->SCp.phase = in_other;
998 outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
999 outb( 0x80, SCSI_Cntl_port );
1000 #ifDEBUG_RACE1001 in_interrupt_flag = 0;
1002 #endif1003 return;
1004 }1005
1006 /* current_SC->SCp.phase == in_other: this is the body of the routine */1007
1008 status = inb( SCSI_Status_port );
1009
1010 if (status & 0x10) {/* REQ */1011
1012 switch (status & 0x0e) {1013
1014 case 0x08: /* COMMAND OUT */1015 outb( current_SC->cmnd[current_SC->SCp.sent_command++],
1016 Write_SCSI_Data_port );
1017 #ifEVERY_ACCESS1018 printk( "CMD = %x,",
1019 current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
1020 #endif1021 break;
1022 case 0x00: /* DATA OUT -- tmc18c50/tmc18c30 only */1023 if (chip != tmc1800 && !current_SC->SCp.have_data_in) {1024 current_SC->SCp.have_data_in = -1;
1025 outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1026 }1027 break;
1028 case 0x04: /* DATA IN -- tmc18c50/tmc18c30 only */1029 if (chip != tmc1800 && !current_SC->SCp.have_data_in) {1030 current_SC->SCp.have_data_in = 1;
1031 outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1032 }1033 break;
1034 case 0x0c: /* STATUS IN */1035 current_SC->SCp.Status = inb( Read_SCSI_Data_port );
1036 #ifEVERY_ACCESS1037 printk( "Status = %x, ", current_SC->SCp.Status );
1038 #endif1039 #ifERRORS_ONLY1040 if (current_SC->SCp.Status && current_SC->SCp.Status != 2) {1041 printk( "fdomain: target = %d, command = %x, status = %x\n",
1042 current_SC->target,
1043 current_SC->cmnd[0],
1044 current_SC->SCp.Status );
1045 }1046 #endif1047 break;
1048 case 0x0a: /* MESSAGE OUT */1049 outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */1050 break;
1051 case 0x0e: /* MESSAGE IN */1052 current_SC->SCp.Message = inb( Read_SCSI_Data_port );
1053 #ifEVERY_ACCESS1054 printk( "Message = %x, ", current_SC->SCp.Message );
1055 #endif1056 if (!current_SC->SCp.Message) ++done;
1057 #ifDEBUG_MESSAGES || EVERY_ACCESS1058 if (current_SC->SCp.Message) {1059 printk( "fdomain: message = %x\n", current_SC->SCp.Message );
1060 }1061 #endif1062 break;
1063 }1064 }1065
1066 if (chip == tmc18001067 && !current_SC->SCp.have_data_in1068 && (current_SC->SCp.sent_command1069 >= current_SC->cmd_len)) {1070 /* We have to get the FIFO direction1071 correct, so I've made a table based1072 on the SCSI Standard of which commands1073 appear to require a DATA OUT phase.1074 */1075 /*1076 p. 94: Command for all device types1077 CHANGE DEFINITION 40 DATA OUT1078 COMPARE 39 DATA OUT1079 COPY 18 DATA OUT1080 COPY AND VERIFY 3a DATA OUT1081 INQUIRY 12 1082 LOG SELECT 4c DATA OUT1083 LOG SENSE 4d1084 MODE SELECT (6) 15 DATA OUT1085 MODE SELECT (10) 55 DATA OUT1086 MODE SENSE (6) 1a1087 MODE SENSE (10) 5a1088 READ BUFFER 3c1089 RECEIVE DIAGNOSTIC RESULTS 1c1090 REQUEST SENSE 031091 SEND DIAGNOSTIC 1d DATA OUT1092 TEST UNIT READY 001093 WRITE BUFFER 3b DATA OUT1094
1095 p.178: Commands for direct-access devices (not listed on p. 94)1096 FORMAT UNIT 04 DATA OUT1097 LOCK-UNLOCK CACHE 361098 PRE-FETCH 341099 PREVENT-ALLOW MEDIUM REMOVAL 1e1100 READ (6)/RECEIVE 081101 READ (10) 3c1102 READ CAPACITY 251103 READ DEFECT DATA (10) 371104 READ LONG 3e1105 REASSIGN BLOCKS 07 DATA OUT1106 RELEASE 171107 RESERVE 16 DATA OUT1108 REZERO UNIT/REWIND 011109 SEARCH DATA EQUAL (10) 31 DATA OUT1110 SEARCH DATA HIGH (10) 30 DATA OUT1111 SEARCH DATA LOW (10) 32 DATA OUT1112 SEEK (6) 0b1113 SEEK (10) 2b1114 SET LIMITS (10) 331115 START STOP UNIT 1b1116 SYNCHRONIZE CACHE 351117 VERIFY (10) 2f1118 WRITE (6)/PRINT/SEND 0a DATA OUT1119 WRITE (10)/SEND 2a DATA OUT1120 WRITE AND VERIFY (10) 2e DATA OUT1121 WRITE LONG 3f DATA OUT1122 WRITE SAME 41 DATA OUT ?1123
1124 p. 261: Commands for sequential-access devices (not previously listed)1125 ERASE 191126 LOAD UNLOAD 1b1127 LOCATE 2b1128 READ BLOCK LIMITS 051129 READ POSITION 341130 READ REVERSE 0f1131 RECOVER BUFFERED DATA 141132 SPACE 111133 WRITE FILEMARKS 10 ?1134
1135 p. 298: Commands for printer devices (not previously listed)1136 ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****1137 SLEW AND PRINT 0b DATA OUT -- same as seek1138 STOP PRINT 1b1139 SYNCHRONIZE BUFFER 101140
1141 p. 315: Commands for processor devices (not previously listed)1142 1143 p. 321: Commands for write-once devices (not previously listed)1144 MEDIUM SCAN 381145 READ (12) a81146 SEARCH DATA EQUAL (12) b1 DATA OUT1147 SEARCH DATA HIGH (12) b0 DATA OUT1148 SEARCH DATA LOW (12) b2 DATA OUT1149 SET LIMITS (12) b31150 VERIFY (12) af1151 WRITE (12) aa DATA OUT1152 WRITE AND VERIFY (12) ae DATA OUT1153
1154 p. 332: Commands for CD-ROM devices (not previously listed)1155 PAUSE/RESUME 4b1156 PLAY AUDIO (10) 451157 PLAY AUDIO (12) a51158 PLAY AUDIO MSF 471159 PLAY TRACK RELATIVE (10) 491160 PLAY TRACK RELATIVE (12) a91161 READ HEADER 441162 READ SUB-CHANNEL 421163 READ TOC 431164
1165 p. 370: Commands for scanner devices (not previously listed)1166 GET DATA BUFFER STATUS 341167 GET WINDOW 251168 OBJECT POSITION 311169 SCAN 1b1170 SET WINDOW 24 DATA OUT1171
1172 p. 391: Commands for optical memory devices (not listed)1173 ERASE (10) 2c1174 ERASE (12) ac1175 MEDIUM SCAN 38 DATA OUT1176 READ DEFECT DATA (12) b71177 READ GENERATION 291178 READ UPDATED BLOCK 2d1179 UPDATE BLOCK 3d DATA OUT1180
1181 p. 419: Commands for medium changer devices (not listed)1182 EXCHANGE MEDIUM 461183 INITIALIZE ELEMENT STATUS 071184 MOVE MEDIUM a51185 POSITION TO ELEMENT 2b1186 READ ELEMENT STATUS b81187 REQUEST VOL. ELEMENT ADDRESS b51188 SEND VOLUME TAG b6 DATA OUT1189
1190 p. 454: Commands for communications devices (not listed previously)1191 GET MESSAGE (6) 081192 GET MESSAGE (10) 281193 GET MESSAGE (12) a81194 */1195
1196 switch (current_SC->cmnd[0]) {1197 caseCHANGE_DEFINITION: caseCOMPARE: caseCOPY:
1198 caseCOPY_VERIFY: caseLOG_SELECT: caseMODE_SELECT:
1199 caseMODE_SELECT_10: caseSEND_DIAGNOSTIC: caseWRITE_BUFFER:
1200
1201 caseFORMAT_UNIT: caseREASSIGN_BLOCKS: caseRESERVE:
1202 caseSEARCH_EQUAL: caseSEARCH_HIGH: caseSEARCH_LOW:
1203 caseWRITE_6: caseWRITE_10: caseWRITE_VERIFY:
1204 case 0x3f: case 0x41:
1205
1206 case 0xb1: case 0xb0: case 0xb2:
1207 case 0xaa: case 0xae:
1208
1209 case 0x24:
1210
1211 case 0x38: case 0x3d:
1212
1213 case 0xb6:
1214
1215 case 0xea: /* alternate number for WRITE LONG */1216
1217 current_SC->SCp.have_data_in = -1;
1218 outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1219 break;
1220
1221 case 0x00:
1222 default:
1223
1224 current_SC->SCp.have_data_in = 1;
1225 outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1226 break;
1227 }1228 }1229
1230 if (current_SC->SCp.have_data_in == -1) {/* DATA OUT */1231 while ( (data_count = FIFO_Size - inw( FIFO_Data_Count_port )) > 512 ) {1232 #ifEVERY_ACCESS1233 printk( "DC=%d, ", data_count ) ;
1234 #endif1235 if (data_count > current_SC->SCp.this_residual)
1236 data_count = current_SC->SCp.this_residual;
1237 if (data_count > 0) {1238 #ifEVERY_ACCESS1239 printk( "%d OUT, ", data_count );
1240 #endif1241 if (data_count == 1) {1242 outb( *current_SC->SCp.ptr++, Write_FIFO_port );
1243 --current_SC->SCp.this_residual;
1244 }else{1245 data_count >>= 1;
1246 outsw( Write_FIFO_port, current_SC->SCp.ptr, data_count );
1247 current_SC->SCp.ptr += 2 * data_count;
1248 current_SC->SCp.this_residual -= 2 * data_count;
1249 }1250 }1251 if (!current_SC->SCp.this_residual) {1252 if (current_SC->SCp.buffers_residual) {1253 --current_SC->SCp.buffers_residual;
1254 ++current_SC->SCp.buffer;
1255 current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1256 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1257 }else1258 break;
1259 }1260 }1261 }1262
1263 if (current_SC->SCp.have_data_in == 1) {/* DATA IN */1264 while ((data_count = inw( FIFO_Data_Count_port )) > 0) {1265 #ifEVERY_ACCESS1266 printk( "DC=%d, ", data_count );
1267 #endif1268 if (data_count > current_SC->SCp.this_residual)
1269 data_count = current_SC->SCp.this_residual;
1270 if (data_count) {1271 #ifEVERY_ACCESS1272 printk( "%d IN, ", data_count );
1273 #endif1274 if (data_count == 1) {1275 *current_SC->SCp.ptr++ = inb( Read_FIFO_port );
1276 --current_SC->SCp.this_residual;
1277 }else{1278 data_count >>= 1; /* Number of words */1279 insw( Read_FIFO_port, current_SC->SCp.ptr, data_count );
1280 current_SC->SCp.ptr += 2 * data_count;
1281 current_SC->SCp.this_residual -= 2 * data_count;
1282 }1283 }1284 if (!current_SC->SCp.this_residual1285 && current_SC->SCp.buffers_residual) {1286 --current_SC->SCp.buffers_residual;
1287 ++current_SC->SCp.buffer;
1288 current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1289 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1290 }1291 }1292 }1293
1294 if (done) {1295 #ifEVERY_ACCESS1296 printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
1297 #endif1298
1299 #ifERRORS_ONLY1300 if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {1301 if ((unsignedchar)(*((char *)current_SC->request_buffer+2)) & 0x0f) {1302 unsignedcharkey;
1303 unsignedcharcode;
1304 unsignedcharqualifier;
1305
1306 key = (unsignedchar)(*((char *)current_SC->request_buffer + 2))
1307 & 0x0f;
1308 code = (unsignedchar)(*((char *)current_SC->request_buffer + 12));
1309 qualifier = (unsignedchar)(*((char *)current_SC->request_buffer1310 + 13));
1311
1312 if (!(key == UNIT_ATTENTION && (code == 0x29 || !code))
1313 && !(key == NOT_READY1314 && code == 0x04
1315 && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1316 && !(key == ILLEGAL_REQUEST && (code == 0x25
1317 || code == 0x24
1318 || !code)))
1319
1320 printk( "fdomain: REQUEST SENSE "
1321 "Key = %x, Code = %x, Qualifier = %x\n",
1322 key, code, qualifier );
1323 }1324 }1325 #endif1326 #ifEVERY_ACCESS1327 printk( "BEFORE MY_DONE. . ." );
1328 #endif1329 my_done( (current_SC->SCp.Status & 0xff)
1330 | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
1331 #ifEVERY_ACCESS1332 printk( "RETURNING.\n" );
1333 #endif1334
1335 }else{1336 if (current_SC->SCp.phase & disconnect) {1337 outb( 0xd0 | FIFO_COUNT, Interrupt_Cntl_port );
1338 outb( 0x00, SCSI_Cntl_port );
1339 }else{1340 outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
1341 }1342 }1343 #ifDEBUG_RACE1344 in_interrupt_flag = 0;
1345 #endif1346 return;
1347 }1348
1349 intfdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
/* */1350 {1351 if (in_command) {1352 panic( "fdomain: fdomain_16x0_queue() NOT REENTRANT!\n" );
1353 }1354 #ifEVERY_ACCESS1355 printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1356 SCpnt->target,
1357 *(unsignedchar *)SCpnt->cmnd,
1358 SCpnt->use_sg,
1359 SCpnt->request_bufflen );
1360 #endif1361
1362 fdomain_make_bus_idle();
1363
1364 current_SC = SCpnt; /* Save this for the done function */1365 current_SC->scsi_done = done;
1366
1367 /* Initialize static data */1368
1369 if (current_SC->use_sg) {1370 current_SC->SCp.buffer =
1371 (structscatterlist *)current_SC->request_buffer;
1372 current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1373 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1374 current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
1375 }else{1376 current_SC->SCp.ptr = (char *)current_SC->request_buffer;
1377 current_SC->SCp.this_residual = current_SC->request_bufflen;
1378 current_SC->SCp.buffer = NULL;
1379 current_SC->SCp.buffers_residual = 0;
1380 }1381
1382
1383 current_SC->SCp.Status = 0;
1384 current_SC->SCp.Message = 0;
1385 current_SC->SCp.have_data_in = 0;
1386 current_SC->SCp.sent_command = 0;
1387 current_SC->SCp.phase = in_arbitration;
1388
1389 /* Start arbitration */1390 outb( 0x00, Interrupt_Cntl_port );
1391 outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */1392 outb( adapter_mask, SCSI_Data_NoACK_port ); /* Set our id bit */1393 ++in_command;
1394 outb( 0x20, Interrupt_Cntl_port );
1395 outb( 0x14 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */1396
1397 return 0;
1398 }1399
1400 /* The following code, which simulates the old-style command function, was1401 taken from Tommy Thorn's aha1542.c file. This code is Copyright (C)1402 1992 Tommy Thorn. */1403
1404 staticvolatileintinternal_done_flag = 0;
1405 staticvolatileintinternal_done_errcode = 0;
1406
1407 staticvoidinternal_done( Scsi_Cmnd *SCpnt )
/* */1408 {1409 internal_done_errcode = SCpnt->result;
1410 ++internal_done_flag;
1411 }1412
1413 intfdomain_16x0_command( Scsi_Cmnd *SCpnt )
/* */1414 {1415 fdomain_16x0_queue( SCpnt, internal_done );
1416
1417 while (!internal_done_flag)
1418 ;
1419 internal_done_flag = 0;
1420 returninternal_done_errcode;
1421 }1422
1423 /* End of code derived from Tommy Thorn's work. */1424
1425 voidprint_info( Scsi_Cmnd *SCpnt )
/* */1426 {1427 unsignedintimr;
1428 unsignedintirr;
1429 unsignedintisr;
1430
1431 if (!SCpnt || !SCpnt->host) {1432 printk( "fdomain: cannot provide detailed information\n" );
1433 }1434
1435 printk( "%s\n", fdomain_16x0_info( SCpnt->host ) );
1436 print_banner( SCpnt->host );
1437 switch (SCpnt->SCp.phase) {1438 casein_arbitration: printk( "arbitration " ); break;
1439 casein_selection: printk( "selection " ); break;
1440 casein_other: printk( "other " ); break;
1441 default: printk( "unknown " ); break;
1442 }1443
1444 printk( "(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1445 SCpnt->SCp.phase,
1446 SCpnt->target,
1447 *(unsignedchar *)SCpnt->cmnd,
1448 SCpnt->use_sg,
1449 SCpnt->request_bufflen );
1450 printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
1451 SCpnt->SCp.sent_command,
1452 SCpnt->SCp.have_data_in,
1453 SCpnt->timeout );
1454 #ifDEBUG_RACE1455 printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
1456 #endif1457
1458 imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
1459 outb( 0x0a, 0xa0 );
1460 irr = inb( 0xa0 ) << 8;
1461 outb( 0x0a, 0x20 );
1462 irr += inb( 0x20 );
1463 outb( 0x0b, 0xa0 );
1464 isr = inb( 0xa0 ) << 8;
1465 outb( 0x0b, 0x20 );
1466 isr += inb( 0x20 );
1467
1468 /* Print out interesting information */1469 printk( "IMR = 0x%04x", imr );
1470 if (imr & (1 << interrupt_level))
1471 printk( " (masked)" );
1472 printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
1473
1474 printk( "SCSI Status = 0x%02x\n", inb( SCSI_Status_port ) );
1475 printk( "TMC Status = 0x%02x", inb( TMC_Status_port ) );
1476 if (inb( TMC_Status_port & 1))
1477 printk( " (interrupt)" );
1478 printk( "\n" );
1479 printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port ) );
1480 if (inb( Interrupt_Status_port ) & 0x08)
1481 printk( " (enabled)" );
1482 printk( "\n" );
1483 if (chip == tmc18c50 || chip == tmc18c30) {1484 printk( "FIFO Status = 0x%02x\n", inb( port_base + FIFO_Status ) );
1485 printk( "Int. Condition = 0x%02x\n",
1486 inb( port_base + Interrupt_Cond ) );
1487 }1488 printk( "Configuration 1 = 0x%02x\n", inb( port_base + Configuration1 ) );
1489 if (chip == tmc18c50 || chip == tmc18c30)
1490 printk( "Configuration 2 = 0x%02x\n",
1491 inb( port_base + Configuration2 ) );
1492 }1493
1494 intfdomain_16x0_abort( Scsi_Cmnd *SCpnt)
/* */1495 {1496 unsignedlongflags;
1497 #ifEVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT1498 printk( "fdomain: abort " );
1499 #endif1500
1501 save_flags( flags );
1502 cli();
1503 if (!in_command) {1504 #ifEVERY_ACCESS || ERRORS_ONLY1505 printk( " (not in command)\n" );
1506 #endif1507 restore_flags( flags );
1508 returnSCSI_ABORT_NOT_RUNNING;
1509 }1510
1511 #ifDEBUG_ABORT1512 print_info( SCpnt );
1513 #endif1514
1515 fdomain_make_bus_idle();
1516
1517 current_SC->SCp.phase |= aborted;
1518
1519 current_SC->result = DID_ABORT << 16;
1520
1521 restore_flags( flags );
1522
1523 /* Aborts are not done well. . . */1524 my_done( DID_ABORT << 16 );
1525
1526 returnSCSI_ABORT_SUCCESS;
1527 }1528
1529 intfdomain_16x0_reset( Scsi_Cmnd *SCpnt )
/* */1530 {1531 #ifDEBUG_RESET1532 staticintcalled_once = 0;
1533 #endif1534
1535 #ifERRORS_ONLY1536 if (SCpnt) printk( "fdomain: SCSI Bus Reset\n" );
1537 #endif1538
1539 #ifDEBUG_RESET1540 if (called_once) print_info( current_SC );
1541 called_once = 1;
1542 #endif1543
1544 outb( 1, SCSI_Cntl_port );
1545 do_pause( 2 );
1546 outb( 0, SCSI_Cntl_port );
1547 do_pause( 115 );
1548 outb( 0, SCSI_Mode_Cntl_port );
1549 outb( PARITY_MASK, TMC_Cntl_port );
1550
1551 /* Unless this is the very first call (i.e., SCPnt == NULL), everything1552 is probably hosed at this point. We will, however, try to keep1553 things going by informing the high-level code that we need help. */1554
1555 returnSCSI_RESET_WAKEUP;
1556 }1557
1558 #include "sd.h"
1559 #include "scsi_ioctl.h"
1560
1561 intfdomain_16x0_biosparam( Scsi_Disk *disk, intdev, int *info_array )
/* */1562 {1563 intdrive;
1564 unsignedcharbuf[512 + sizeof( int ) * 2];
1565 intsize = disk->capacity;
1566 int *sizes = (int *)buf;
1567 unsignedchar *data = (unsignedchar *)(sizes + 2);
1568 unsignedchardo_read[] = {READ_6, 0, 0, 0, 1, 0 };
1569 intretcode;
1570 structdrive_info{1571 unsignedshortcylinders;
1572 unsignedcharheads;
1573 unsignedcharsectors;
1574 } *i;
1575
1576 /* NOTES:1577 The RAM area starts at 0x1f00 from the bios_base address.1578
1579 For BIOS Version 2.0:1580 1581 The drive parameter table seems to start at 0x1f30.1582 The first byte's purpose is not known.1583 Next is the cylinder, head, and sector information.1584 The last 4 bytes appear to be the drive's size in sectors.1585 The other bytes in the drive parameter table are unknown.1586 If anyone figures them out, please send me mail, and I will1587 update these notes.1588
1589 Tape drives do not get placed in this table.1590
1591 There is another table at 0x1fea:1592 If the byte is 0x01, then the SCSI ID is not in use.1593 If the byte is 0x18 or 0x48, then the SCSI ID is in use,1594 although tapes don't seem to be in this table. I haven't1595 seen any other numbers (in a limited sample).1596
1597 0x1f2d is a drive count (i.e., not including tapes)1598
1599 The table at 0x1fcc are I/O ports addresses for the various1600 operations. I calculate these by hand in this driver code.1601
1602 1603 1604 For the ISA-200S version of BIOS Version 2.0:1605
1606 The drive parameter table starts at 0x1f33.1607
1608 WARNING: Assume that the table entry is 25 bytes long. Someone needs1609 to check this for the Quantum ISA-200S card.1610
1611 1612 1613 For BIOS Version 3.2:1614
1615 The drive parameter table starts at 0x1f70. Each entry is1616 0x0a bytes long. Heads are one less than we need to report.1617 */1618
1619 drive = MINOR(dev) / 16;
1620
1621 if (bios_major == 2) {1622 switch (Quantum) {1623 case 2: /* ISA_200S */1624 /* The value of 25 has never been verified.1625 It should probably be 15. */1626 i = (structdrive_info *)( (char *)bios_base + 0x1f33 + drive * 25 );
1627 break;
1628 case 3: /* ISA_250MG */1629 i = (structdrive_info *)( (char *)bios_base + 0x1f36 + drive * 15 );
1630 break;
1631 case 4: /* ISA_200S (another one) */1632 i = (structdrive_info *)( (char *)bios_base + 0x1f34 + drive * 15 );
1633 break;
1634 default:
1635 i = (structdrive_info *)( (char *)bios_base + 0x1f31 + drive * 25 );
1636 break;
1637 }1638 info_array[0] = i->heads;
1639 info_array[1] = i->sectors;
1640 info_array[2] = i->cylinders;
1641 }elseif (bios_major == 3
1642 && bios_minor >= 0
1643 && bios_minor < 4) {/* 3.0 and 3.2 BIOS */1644 i = (structdrive_info *)( (char *)bios_base + 0x1f71 + drive * 10 );
1645 info_array[0] = i->heads + 1;
1646 info_array[1] = i->sectors;
1647 info_array[2] = i->cylinders;
1648 }else{/* 3.4 BIOS (and up?) */1649 /* This algorithm was provided by Future Domain (much thanks!). */1650
1651 sizes[0] = 0; /* zero bytes out */1652 sizes[1] = 512; /* one sector in */1653 memcpy( data, do_read, sizeof( do_read ) );
1654 retcode = kernel_scsi_ioctl( disk->device,
1655 SCSI_IOCTL_SEND_COMMAND,
1656 (void *)buf );
1657 if (!retcode/* SCSI command ok */1658 && data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */1659 && data[0x1c2]) {/* Partition type */1660
1661 /* The partition table layout is as follows:1662
1663 Start: 0x1b3h1664 Offset: 0 = partition status1665 1 = starting head1666 2 = starting sector and cylinder (word, encoded)1667 4 = partition type1668 5 = ending head1669 6 = ending sector and cylinder (word, encoded)1670 8 = starting absolute sector (double word)1671 c = number of sectors (double word)1672 Signature: 0x1fe = 0x55aa1673
1674 So, this algorithm assumes:1675 1) the first partition table is in use,1676 2) the data in the first entry is correct, and1677 3) partitions never divide cylinders1678
1679 Note that (1) may be FALSE for NetBSD (and other BSD flavors),1680 as well as for Linux. Note also, that Linux doesn't pay any1681 attention to the fields that are used by this algorithm -- it1682 only uses the absolute sector data. Recent versions of Linux's1683 fdisk(1) will fill this data in correctly, and forthcoming1684 versions will check for consistency.1685
1686 Checking for a non-zero partition type is not part of the1687 Future Domain algorithm, but it seemed to be a reasonable thing1688 to do, especially in the Linux and BSD worlds. */1689
1690 info_array[0] = data[0x1c3] + 1; /* heads */1691 info_array[1] = data[0x1c4] & 0x3f; /* sectors */1692 }else{1693
1694 /* Note that this new method guarantees that there will always be1695 less than 1024 cylinders on a platter. This is good for drives1696 up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */1697
1698 if ((unsignedint)size >= 0x7e0000U) {1699 info_array[0] = 0xff; /* heads = 255 */1700 info_array[1] = 0x3f; /* sectors = 63 */1701 }elseif ((unsignedint)size >= 0x200000U) {1702 info_array[0] = 0x80; /* heads = 128 */1703 info_array[1] = 0x3f; /* sectors = 63 */1704 }else{1705 info_array[0] = 0x40; /* heads = 64 */1706 info_array[1] = 0x20; /* sectors = 32 */1707 }1708 }1709 /* For both methods, compute the cylinders */1710 info_array[2] = (unsignedint)size / (info_array[0] * info_array[1] );
1711 }1712
1713 return 0;
1714 }