1 /* fdomain.c -- Future Domain TMC-16x0 SCSI driver 2 * Created: Sun May 3 18:53:19 1992 by faith@cs.unc.edu 3 * Revised: Sat Jan 14 21:39:15 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.26 1995/01/15 02:39:19 root Exp $ 8
9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by the 11 * Free Software Foundation; either version 2, or (at your option) any 12 * later version. 13
14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18
19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write to the Free Software Foundation, Inc., 21 * 675 Mass Ave, Cambridge, MA 02139, USA. 22
23 ************************************************************************** 24 25 DESCRIPTION: 26
27 This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680 28 TMC-1650/1670, and TMC-3260 SCSI host adapters. The 1650 and 1670 have a 29 25-pin external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin 30 high-density external connector. The 1670 and 1680 have floppy disk 31 controllers built in. The TMC-3260 is a PCI bus card. 32
33 Future Domain's older boards are based on the TMC-1800 chip, and this 34 driver was originally written for a TMC-1680 board with the TMC-1800 chip. 35 More recently, boards are being produced with the TMC-18C50 and TMC-18C30 36 chips. The latest and greatest board may not work with this driver. If 37 you have to patch this driver so that it will recognize your board's BIOS 38 signature, then the driver may fail to function after the board is 39 detected. 40
41 The following BIOS versions are supported: 2.0, 3.0, 3.2, 3.4, and 3.5. 42 The following chips are supported: TMC-1800, TMC-18C50, TMC-18C30. 43 Reports suggest that the driver will also work with the 36C70 chip and 44 with the Quantum ISA-200S SCSI adapter. 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 All of the alpha testers deserve much thanks. 145
146
147
148 NOTES ON USER DEFINABLE OPTIONS: 149
150 DEBUG: This turns on the printing of various debug information. 151
152 ENABLE_PARITY: This turns on SCSI parity checking. With the current 153 driver, all attached devices must support SCSI parity. If none of your 154 devices support parity, then you can probably get the driver to work by 155 turning this option off. I have no way of testing this, however. 156
157 FIFO_COUNT: The host adapter has an 8K cache (host adapters based on the 158 18C30 chip have a 2k cache). When this many 512 byte blocks are filled by 159 the SCSI device, an interrupt will be raised. Therefore, this could be as 160 low as 0, or as high as 16. Note, however, that values which are too high 161 or too low seem to prevent any interrupts from occurring, and thereby lock 162 up the machine. I have found that 2 is a good number, but throughput may 163 be increased by changing this value to values which are close to 2. 164 Please let me know if you try any different values. 165
166 DO_DETECT: This activates some old scan code which was needed before the 167 high level drivers got fixed. If you are having trouble with the driver, 168 turning this on should not hurt, and might help. Please let me know if 169 this is the case, since this code will be removed from future drivers. 170
171 RESELECTION: This is no longer an option, since I gave up trying to 172 implement it in version 4.x of this driver. It did not improve 173 performance at all and made the driver unstable (because I never found one 174 of the two race conditions which were introduced by the multiple 175 outstanding command code). The instability seems a very high price to pay 176 just so that you don't have to wait for the tape to rewind. If you want 177 this feature implemented, send me patches. I'll be happy to send a copy 178 of my (broken) driver to anyone who would like to see a copy. 179
180 **************************************************************************/ 181
182 #include <linux/sched.h>
183 #include <asm/io.h>
184 #include "../block/blk.h"
185 #include "scsi.h"
186 #include "hosts.h"
187 #include "fdomain.h"
188 #include <asm/system.h>
189 #include <linux/errno.h>
190 #include <linux/string.h>
191 #include <linux/ioport.h>
192
193 #defineVERSION "$Revision: 5.26 $"
194
195 /* START OF USER DEFINABLE OPTIONS */ 196
197 #defineDEBUG 1 /* Enable debugging output */ 198 #defineENABLE_PARITY 1 /* Enable SCSI Parity */ 199 #defineFIFO_COUNT 2 /* Number of 512 byte blocks before INTR */ 200 #defineDO_DETECT 0 /* Do device detection here (see scsi.c) */ 201
202 /* END OF USER DEFINABLE OPTIONS */ 203
204 #ifDEBUG 205 #defineEVERY_ACCESS 0 /* Write a line on every scsi access */ 206 #defineERRORS_ONLY 1 /* Only write a line if there is an error */ 207 #defineDEBUG_DETECT 0 /* Debug fdomain_16x0_detect() */ 208 #defineDEBUG_MESSAGES 1 /* Debug MESSAGE IN phase */ 209 #defineDEBUG_ABORT 1 /* Debug abort() routine */ 210 #defineDEBUG_RESET 1 /* Debug reset() routine */ 211 #defineDEBUG_RACE 1 /* Debug interrupt-driven race condition */ 212 #else 213 #defineEVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */ 214 #defineERRORS_ONLY 0
215 #defineDEBUG_DETECT 0
216 #defineDEBUG_MESSAGES 0
217 #defineDEBUG_ABORT 0
218 #defineDEBUG_RESET 0
219 #defineDEBUG_RACE 0
220 #endif 221
222 /* Errors are reported on the line, so we don't need to report them again */ 223 #ifEVERY_ACCESS 224 #undefERRORS_ONLY 225 #defineERRORS_ONLY 0
226 #endif 227
228 #ifENABLE_PARITY 229 #definePARITY_MASK 0x08
230 #else 231 #definePARITY_MASK 0x00
232 #endif 233
234 enumchip_type{ 235 unknown = 0x00,
236 tmc1800 = 0x01,
237 tmc18c50 = 0x02,
238 tmc18c30 = 0x03,
239 };
240
241 enum{ 242 in_arbitration = 0x02,
243 in_selection = 0x04,
244 in_other = 0x08,
245 disconnect = 0x10,
246 aborted = 0x20,
247 sent_ident = 0x40,
248 };
249
250 enum in_port_type { 251 Read_SCSI_Data = 0,
252 SCSI_Status = 1,
253 TMC_Status = 2,
254 FIFO_Status = 3, /* tmc18c50/tmc18c30 only */ 255 Interrupt_Cond = 4, /* tmc18c50/tmc18c30 only */ 256 LSB_ID_Code = 5,
257 MSB_ID_Code = 6,
258 Read_Loopback = 7,
259 SCSI_Data_NoACK = 8,
260 Interrupt_Status = 9,
261 Configuration1 = 10,
262 Configuration2 = 11, /* tmc18c50/tmc18c30 only */ 263 Read_FIFO = 12,
264 FIFO_Data_Count = 14
265 };
266
267 enum out_port_type { 268 Write_SCSI_Data = 0,
269 SCSI_Cntl = 1,
270 Interrupt_Cntl = 2,
271 SCSI_Mode_Cntl = 3,
272 TMC_Cntl = 4,
273 Memory_Cntl = 5, /* tmc18c50/tmc18c30 only */ 274 Write_Loopback = 7,
275 IO_Control = 11, /* tmc18c30 only */ 276 Write_FIFO = 12
277 };
278
279 staticintport_base = 0;
280 staticvoid *bios_base = NULL;
281 staticintbios_major = 0;
282 staticintbios_minor = 0;
283 staticintPCI_bus = 0;
284 staticintISA_200S = 0; /* Quantum ISA-200S */ 285 staticintinterrupt_level = 0;
286 staticvolatileintin_command = 0;
287 staticScsi_Cmnd *current_SC = NULL;
288 staticenumchip_typechip = unknown;
289 staticintadapter_mask = 0x40;
290 #ifDEBUG_RACE 291 staticvolatileintin_interrupt_flag = 0;
292 #endif 293
294 staticintSCSI_Mode_Cntl_port;
295 staticintFIFO_Data_Count_port;
296 staticintInterrupt_Cntl_port;
297 staticintInterrupt_Status_port;
298 staticintRead_FIFO_port;
299 staticintRead_SCSI_Data_port;
300 staticintSCSI_Cntl_port;
301 staticintSCSI_Data_NoACK_port;
302 staticintSCSI_Status_port;
303 staticintTMC_Cntl_port;
304 staticintTMC_Status_port;
305 staticintWrite_FIFO_port;
306 staticintWrite_SCSI_Data_port;
307
308 staticintFIFO_Size = 0x2000; /* 8k FIFO for 309 pre-tmc18c30 chips */ 310
311 externvoidfdomain_16x0_intr( intirq, structpt_regs * regs );
312
313 staticvoid *addresses[] = { 314 (void *)0xc8000,
315 (void *)0xca000,
316 (void *)0xce000,
317 (void *)0xde000,
318 (void *)0xd0000, /* Extra addresses for PCI boards */ 319 (void *)0xe0000,
320 };
321 #defineADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
322
323 staticunsignedshortports[] = { 0x140, 0x150, 0x160, 0x170 };
324 #definePORT_COUNT (sizeof( ports ) / sizeof( unsignedshort ))
325
326 staticunsignedshortints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
327
328 /* 329
330 READ THIS BEFORE YOU ADD A SIGNATURE! 331
332 READING THIS SHORT NOTE CAN SAVE YOU LOTS OF TIME! 333
334 READ EVERY WORD, ESPECIALLY THE WORD *NOT* 335
336 This driver works *ONLY* for Future Domain cards using the TMC-1800, 337 TMC-18C50, or TMC-18C30 chip. This includes models TMC-1650, 1660, 1670, 338 and 1680. 339
340 The following BIOS signature signatures are for boards which do *NOT* 341 work with this driver (these TMC-8xx and TMC-9xx boards may work with the 342 Seagate driver): 343
344 FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88 345 FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89 346 FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89 347 FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90 348 FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90 349 FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90 350 FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92 351
352 */ 353
354 structsignature{ 355 char *signature;
356 intsig_offset;
357 intsig_length;
358 intmajor_bios_version;
359 intminor_bios_version;
360 intflag; /* 1 == PCI_bus, 2 == ISA_200S */ 361 }signatures[] = { 362 /* 1 2 3 4 5 6 */ 363 /* 123456789012345678901234567890123456789012345678901234567890 */ 364 { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 5, 50, 2, 0, 0 },
365 { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89", 5, 50, 2, 0, 0 },
366 { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50, 2, 0, 2 },
367 { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92", 5, 44, 3, 0, 0 },
368 { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93", 5, 44, 3, 2, 0 },
369 { "IBM F1 P2 BIOS v1.0104/29/93", 5, 28, 3, -1, 0 },
370 { "Future Domain Corp. V1.0008/18/93", 5, 33, 3, 4, 0 },
371 { "Future Domain Corp. V1.0008/18/93", 26, 33, 3, 4, 1 },
372 { "FUTURE DOMAIN CORP. V3.5008/18/93", 5, 34, 3, 5, 0 },
373 { "FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5", 5, 44, 3, 5, 0 },
374 { "FUTURE DOMAIN TMC-18XX", 5, 22, -1, -1, 0 },
375
376 /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGNATURE 377 Also, fix the disk geometry code for your signature and send your 378 changes for faith@cs.unc.edu. Above all, do *NOT* change any old 379 signatures! 380
381 Note that the last line will match a "generic" 18XX bios. Because 382 Future Domain has changed the host SCSI ID and/or the location of the 383 geometry information in the on-board RAM area for each of the first 384 three BIOS's, it is still important to enter a fully qualified 385 signature in the table for any new BIOS's (after the host SCSI ID and 386 geometry location are verified). */ 387 };
388
389 #defineSIGNATURE_COUNT (sizeof( signatures ) / sizeof( structsignature ))
390
391 staticvoidprint_banner( structScsi_Host *shpnt )
392 { 393 if (!shpnt) return; /* This won't ever happen */ 394
395 printk( "scsi%d <fdomain>: BIOS version ", shpnt->host_no );
396
397 if (bios_major >= 0) printk( "%d.", bios_major );
398 elseprintk( "?." );
399
400 if (bios_minor >= 0) printk( "%d", bios_minor );
401 elseprintk( "?." );
402
403 printk( " at 0x%x using scsi id %d\n",
404 (unsigned)bios_base, shpnt->this_id );
405
406 printk( "scsi%d <fdomain>: %s chip at 0x%x irq ",
407 shpnt->host_no,
408 chip == tmc1800 ? "TMC-1800"
409 : (chip == tmc18c50 ? "TMC-18C50"
410 : (chip == tmc18c30 ? "TMC-18C30" : "Unknown")),
411 port_base );
412
413 if (interrupt_level) printk( "%d", interrupt_level );
414 elseprintk( "<none>" );
415
416 if (PCI_bus) printk( " (PCI bus)" );
417 printk( "\n" );
418 } 419
420 staticvoiddo_pause( unsignedamount ) /* Pause for amount*10 milliseconds *//* */ 421 { 422 unsignedlongthe_time = jiffies + amount; /* 0.01 seconds per jiffy */ 423
424 while (jiffies < the_time);
425 } 426
427 inlinestaticvoidfdomain_make_bus_idle( void )
/* */ 428 { 429 outb( 0, SCSI_Cntl_port );
430 outb( 0, SCSI_Mode_Cntl_port );
431 if (chip == tmc18c50 || chip == tmc18c30)
432 outb( 0x21 | PARITY_MASK, TMC_Cntl_port ); /* Clear forced intr. */ 433 else 434 outb( 0x01 | PARITY_MASK, TMC_Cntl_port );
435 } 436
437 staticintfdomain_is_valid_port( intport )
/* */ 438 { 439 intoptions;
440
441 #ifDEBUG_DETECT 442 printk( " (%x%x),",
443 inb( port + MSB_ID_Code ), inb( port + LSB_ID_Code ) );
444 #endif 445
446 /* The MCA ID is a unique id for each MCA compatible board. We 447 are using ISA boards, but Future Domain provides the MCA ID 448 anyway. We can use this ID to ensure that this is a Future 449 Domain TMC-1660/TMC-1680. 450 */ 451
452 if (inb( port + LSB_ID_Code ) != 0xe9) {/* test for 0x6127 id */ 453 if (inb( port + LSB_ID_Code ) != 0x27) return 0;
454 if (inb( port + MSB_ID_Code ) != 0x61) return 0;
455 chip = tmc1800;
456 }else{/* test for 0xe960 id */ 457 if (inb( port + MSB_ID_Code ) != 0x60) return 0;
458 chip = tmc18c50;
459
460 #if 0
461
462 /* Try to toggle 32-bit mode. This only 463 works on an 18c30 chip. (User reports 464 say that this doesn't work at all, so 465 we'll use the other method.) */ 466
467 outb( 0x80, port + IO_Control );
468 if (inb( port + Configuration2 ) & 0x80 == 0x80) { 469 outb( 0x00, port + IO_Control );
470 if (inb( port + Configuration2 ) & 0x80 == 0x00) { 471 chip = tmc18c30;
472 FIFO_Size = 0x800; /* 2k FIFO */ 473 } 474 } 475 #else 476
477 /* That should have worked, but appears to 478 have problems. Lets assume it is an 479 18c30 if the RAM is disabled. */ 480
481 if (inb( port + Configuration2 ) & 0x02) { 482 chip = tmc18c30;
483 FIFO_Size = 0x800; /* 2k FIFO */ 484 } 485 #endif 486 /* If that failed, we are an 18c50. */ 487 } 488
489 /* We have a valid MCA ID for a TMC-1660/TMC-1680 Future Domain board. 490 Now, check to be sure the bios_base matches these ports. If someone 491 was unlucky enough to have purchased more than one Future Domain 492 board, then they will have to modify this code, as we only detect one 493 board here. [The one with the lowest bios_base.] */ 494
495 options = inb( port + Configuration1 );
496
497 #ifDEBUG_DETECT 498 printk( " Options = %x\n", options );
499 #endif 500
501 /* Check for board with lowest bios_base -- 502 this isn't valid for the 18c30 or for 503 boards on the PCI bus, so just assume we 504 have the right board. */ 505
506 if (chip != tmc18c30 507 && !PCI_bus 508 && addresses[ (options & 0xc0) >> 6 ] != bios_base) return 0;
509
510 /* Get the IRQ from the options. */ 511
512 interrupt_level = ints[ (options & 0x0e) >> 1 ];
513
514 return 1;
515 } 516
517 staticintfdomain_test_loopback( void )
/* */ 518 { 519 inti;
520 intresult;
521
522 for (i = 0; i < 255; i++) { 523 outb( i, port_base + Write_Loopback );
524 result = inb( port_base + Read_Loopback );
525 if (i != result)
526 return 1;
527 } 528 return 0;
529 } 530
531 intfdomain_16x0_detect( Scsi_Host_Template *tpnt )
/* */ 532 { 533 inti, j;
534 intflag = 0;
535 intretcode;
536 structScsi_Host *shpnt;
537 #ifDO_DETECT 538 constintbuflen = 255;
539 Scsi_CmndSCinit;
540 unsignedchardo_inquiry[] = {INQUIRY, 0, 0, 0, buflen, 0 };
541 unsignedchardo_request_sense[] = {REQUEST_SENSE, 0, 0, 0, buflen, 0 };
542 unsignedchardo_read_capacity[] = {READ_CAPACITY,
543 0, 0, 0, 0, 0, 0, 0, 0, 0 };
544 unsignedcharbuf[buflen];
545 #endif 546
547 #ifDEBUG_DETECT 548 printk( "fdomain_16x0_detect()," );
549 #endif 550
551 for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) { 552 #ifDEBUG_DETECT 553 printk( " %x(%x),", (unsigned)addresses[i], (unsigned)bios_base );
554 #endif 555 for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) { 556 if (!memcmp( ((char *)addresses[i] + signatures[j].sig_offset),
557 signatures[j].signature, signatures[j].sig_length )) { 558 bios_major = signatures[j].major_bios_version;
559 bios_minor = signatures[j].minor_bios_version;
560 PCI_bus = (signatures[j].flag == 1);
561 ISA_200S = (signatures[j].flag == 2);
562 bios_base = addresses[i];
563 } 564 } 565 } 566
567 if (!bios_base) { 568 #ifDEBUG_DETECT 569 printk( " FAILED: NO BIOS\n" );
570 #endif 571 return 0;
572 } 573
574 if (bios_major == 2) { 575 /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM. 576 Assuming the ROM is enabled (otherwise we wouldn't have been 577 able to read the ROM signature :-), then the ROM sets up the 578 RAM area with some magic numbers, such as a list of port 579 base addresses and a list of the disk "geometry" reported to 580 DOS (this geometry has nothing to do with physical geometry). 581 */ 582
583 if (ISA_200S) {/* The Quantum board is slightly different. */ 584 port_base = *((char *)bios_base + 0x1fa2)
585 + (*((char *)bios_base + 0x1fa3) << 8);
586 }else{ 587 port_base = *((char *)bios_base + 0x1fcc)
588 + (*((char *)bios_base + 0x1fcd) << 8);
589 } 590
591 #ifDEBUG_DETECT 592 printk( " %x,", port_base );
593 #endif 594
595 for (flag = 0, i = 0; !flag && i < PORT_COUNT; i++) { 596 if (port_base == ports[i])
597 ++flag;
598 } 599
600 if (flag)
601 flag = fdomain_is_valid_port( port_base );
602 } 603
604 if (!flag) {/* Cannot get port base from BIOS RAM */ 605
606 /* This is a bad sign. It usually means that someone patched the 607 BIOS signature list (the signatures variable) to contain a BIOS 608 signature for a board *OTHER THAN* the TMC-1660/TMC-1680. It 609 also means that we don't have a Version 2.0 BIOS :-) 610 */ 611
612 #ifDEBUG_DETECT 613 if (bios_major != 2) printk( " RAM FAILED, " );
614 #endif 615
616 /* Anyway, the alternative to finding the address in the RAM is to 617 just search through every possible port address for one that is 618 attached to the Future Domain card. Don't panic, though, about 619 reading all these random port addresses -- there are rumors that 620 the Future Domain BIOS does something very similar. 621
622 Do not, however, check ports which the kernel knows are being used 623 by another driver. */ 624
625 if (!PCI_bus) { 626 for (i = 0; !flag && i < PORT_COUNT; i++) { 627 port_base = ports[i];
628 if (check_region( port_base, 0x10 )) { 629 #ifDEBUG_DETECT 630 printk( " (%x inuse),", port_base );
631 #endif 632 continue;
633 } 634 #ifDEBUG_DETECT 635 printk( " %x,", port_base );
636 #endif 637 flag = fdomain_is_valid_port( port_base );
638 } 639 }else{ 640
641 /* The proper way of doing this is to use ask the PCI bus for the 642 device IRQ and interrupt level. 643
644 Until the Linux kernel supports this sort of PCI bus query, we 645 scan down a bunch of addresses (Future Domain tech support says 646 we will probably find the address before we get to 0xf800). 647 This works fine on some systems -- other systems may have to 648 scan more addresses. If you have to modify this section for 649 your installation, please send mail to faith@cs.unc.edu. */ 650
651 for (i = 0xff00; !flag && i > 0xf000; i -= 8) { 652 port_base = i;
653 if (check_region( port_base, 0x10 )) { 654 #ifDEBUG_DETECT 655 printk( " (%x inuse)," , port_base );
656 #endif 657 continue;
658 } 659 flag = fdomain_is_valid_port( port_base );
660 } 661 } 662 } 663
664 if (!flag) { 665 #ifDEBUG_DETECT 666 printk( " FAILED: NO PORT\n" );
667 #endif 668 return 0; /* Cannot find valid set of ports */ 669 } 670
671 SCSI_Mode_Cntl_port = port_base + SCSI_Mode_Cntl;
672 FIFO_Data_Count_port = port_base + FIFO_Data_Count;
673 Interrupt_Cntl_port = port_base + Interrupt_Cntl;
674 Interrupt_Status_port = port_base + Interrupt_Status;
675 Read_FIFO_port = port_base + Read_FIFO;
676 Read_SCSI_Data_port = port_base + Read_SCSI_Data;
677 SCSI_Cntl_port = port_base + SCSI_Cntl;
678 SCSI_Data_NoACK_port = port_base + SCSI_Data_NoACK;
679 SCSI_Status_port = port_base + SCSI_Status;
680 TMC_Cntl_port = port_base + TMC_Cntl;
681 TMC_Status_port = port_base + TMC_Status;
682 Write_FIFO_port = port_base + Write_FIFO;
683 Write_SCSI_Data_port = port_base + Write_SCSI_Data;
684
685 fdomain_16x0_reset( NULL );
686
687 if (fdomain_test_loopback()) { 688 #ifDEBUG_DETECT 689 printk( "fdomain: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
690 #endif 691 return 0;
692 } 693
694 if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) { 695 adapter_mask = 0x80;
696 tpnt->this_id = 7;
697 } 698
699 /* Print out a banner here in case we can't 700 get resources. */ 701
702 shpnt = scsi_register( tpnt, 0 );
703 print_banner( shpnt );
704
705 /* Log IRQ with kernel */ 706 if (!interrupt_level) { 707 panic( "fdomain: *NO* interrupt level selected!\n" );
708 }else{ 709 /* Register the IRQ with the kernel */ 710
711 retcode = request_irq( interrupt_level,
712 fdomain_16x0_intr, SA_INTERRUPT, "fdomain" );
713
714 if (retcode < 0) { 715 if (retcode == -EINVAL) { 716 printk( "fdomain: IRQ %d is bad!\n", interrupt_level );
717 printk( " This shouldn't happen!\n" );
718 printk( " Send mail to faith@cs.unc.edu\n" );
719 }elseif (retcode == -EBUSY) { 720 printk( "fdomain: IRQ %d is already in use!\n", interrupt_level );
721 printk( " Please use another IRQ!\n" );
722 }else{ 723 printk( "fdomain: Error getting IRQ %d\n", interrupt_level );
724 printk( " This shouldn't happen!\n" );
725 printk( " Send mail to faith@cs.unc.edu\n" );
726 } 727 panic( "fdomain: Driver requires interruptions\n" );
728 } 729 } 730
731 /* Log I/O ports with kernel */ 732 request_region( port_base, 0x10, "fdomain" );
733
734 #ifDO_DETECT 735
736 /* These routines are here because of the way the SCSI bus behaves after 737 a reset. This appropriate behavior was not handled correctly by the 738 higher level SCSI routines when I first wrote this driver. Now, 739 however, correct scan routines are part of scsi.c and these routines 740 are no longer needed. However, this code is still good for 741 debugging. */ 742
743 SCinit.request_buffer = SCinit.buffer = buf;
744 SCinit.request_bufflen = SCinit.bufflen = sizeof(buf)-1;
745 SCinit.use_sg = 0;
746 SCinit.lun = 0;
747
748 printk( "fdomain: detection routine scanning for devices:\n" );
749 for (i = 0; i < 8; i++) { 750 SCinit.target = i;
751 if (i == tpnt->this_id) /* Skip host adapter */ 752 continue;
753 memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
754 retcode = fdomain_16x0_command(&SCinit);
755 if (!retcode) { 756 memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
757 retcode = fdomain_16x0_command(&SCinit);
758 if (!retcode) { 759 printk( " SCSI ID %d: ", i );
760 for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
761 printk( "%c", buf[j] >= 20 ? buf[j] : ' ' );
762 memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
763 retcode = fdomain_16x0_command(&SCinit);
764 if (!retcode) { 765 unsignedlongblocks, size, capacity;
766
767 blocks = (buf[0] << 24) | (buf[1] << 16)
768 | (buf[2] << 8) | buf[3];
769 size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
770 capacity = +( +(blocks / 1024L) * +(size * 10L)) / 1024L;
771
772 printk( "%lu MB (%lu byte blocks)",
773 ((capacity + 5L) / 10L), size );
774 }else{ 775 memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
776 retcode = fdomain_16x0_command(&SCinit);
777 } 778 printk ("\n" );
779 }else{ 780 memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
781 retcode = fdomain_16x0_command(&SCinit);
782 } 783 } 784 } 785 #endif 786
787 return 1; /* Maximum of one adapter will be detected. */ 788 } 789
790 constchar *fdomain_16x0_info( structScsi_Host *ignore )
/* */ 791 { 792 staticcharbuffer[80];
793 char *pt;
794
795 strcpy( buffer, "Future Domain TMC-16x0 SCSI driver, version" );
796 if (strchr( VERSION, ':')) {/* Assume VERSION is an RCS Revision string */ 797 strcat( buffer, strchr( VERSION, ':' ) + 1 );
798 pt = strrchr( buffer, '$') - 1;
799 if (!pt) /* Stripped RCS Revision string? */ 800 pt = buffer + strlen( buffer ) - 1;
801 if (*pt != ' ')
802 ++pt;
803 *pt = '\0';
804 }else{/* Assume VERSION is a number */ 805 strcat( buffer, " " VERSION );
806 } 807
808 returnbuffer;
809 } 810
811 #if 0
812 staticint fdomain_arbitrate( void )
/* */ 813 { 814 intstatus = 0;
815 unsignedlongtimeout;
816
817 #ifEVERY_ACCESS 818 printk( "fdomain_arbitrate()\n" );
819 #endif 820
821 outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */ 822 outb( adapter_mask, port_base + SCSI_Data_NoACK ); /* Set our id bit */ 823 outb( 0x04 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */ 824
825 timeout = jiffies + 50; /* 500 mS */ 826 while (jiffies < timeout) { 827 status = inb( TMC_Status_port ); /* Read adapter status */ 828 if (status & 0x02) /* Arbitration complete */ 829 return 0;
830 } 831
832 /* Make bus idle */ 833 fdomain_make_bus_idle();
834
835 #ifEVERY_ACCESS 836 printk( "Arbitration failed, status = %x\n", status );
837 #endif 838 #ifERRORS_ONLY 839 printk( "fdomain: Arbitration failed, status = %x\n", status );
840 #endif 841 return 1;
842 } 843 #endif 844
845 staticintfdomain_select( inttarget )
/* */ 846 { 847 intstatus;
848 unsignedlongtimeout;
849 staticintflag = 0;
850
851
852 outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */ 853 outb( adapter_mask | (1 << target), SCSI_Data_NoACK_port );
854
855 /* Stop arbitration and enable parity */ 856 outb( PARITY_MASK, TMC_Cntl_port );
857
858 timeout = jiffies + 35; /* 350mS -- because of timeouts 859 (was 250mS) */ 860
861 while (jiffies < timeout) { 862 status = inb( SCSI_Status_port ); /* Read adapter status */ 863 if (status & 1) {/* Busy asserted */ 864 /* Enable SCSI Bus (on error, should make bus idle with 0) */ 865 outb( 0x80, SCSI_Cntl_port );
866 return 0;
867 } 868 } 869 /* Make bus idle */ 870 fdomain_make_bus_idle();
871 #ifEVERY_ACCESS 872 if (!target) printk( "Selection failed\n" );
873 #endif 874 #ifERRORS_ONLY 875 if (!target) { 876 if (chip == tmc18c30 && !flag) /* Skip first failure for 18C30 chips. */ 877 ++flag;
878 else 879 printk( "fdomain: Selection failed\n" );
880 } 881 #endif 882 return 1;
883 } 884
885 voidmy_done( interror )
/* */ 886 { 887 if (in_command) { 888 in_command = 0;
889 outb( 0x00, Interrupt_Cntl_port );
890 fdomain_make_bus_idle();
891 current_SC->result = error;
892 if (current_SC->scsi_done)
893 current_SC->scsi_done( current_SC );
894 elsepanic( "fdomain: current_SC->scsi_done() == NULL" );
895 }else{ 896 panic( "fdomain: my_done() called outside of command\n" );
897 } 898 #ifDEBUG_RACE 899 in_interrupt_flag = 0;
900 #endif 901 } 902
903 voidfdomain_16x0_intr( intirq, structpt_regs * regs )
/* */ 904 { 905 intstatus;
906 intdone = 0;
907 unsigneddata_count;
908
909 /* The fdomain_16x0_intr is only called via 910 the interrupt handler. The goal of the 911 sti() here is to allow other 912 interruptions while this routine is 913 running. */ 914
915 sti(); /* Yes, we really want sti() here */ 916
917 outb( 0x00, Interrupt_Cntl_port );
918
919 /* We usually have one spurious interrupt after each command. Ignore it. */ 920 if (!in_command || !current_SC) {/* Spurious interrupt */ 921 #ifEVERY_ACCESS 922 printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
923 in_command, current_SC );
924 #endif 925 return;
926 } 927
928 /* Abort calls my_done, so we do nothing here. */ 929 if (current_SC->SCp.phase & aborted) { 930 #ifDEBUG_ABORT 931 printk( "Interrupt after abort, ignoring\n" );
932 #endif 933 /* 934 return; */ 935 } 936
937 #ifDEBUG_RACE 938 ++in_interrupt_flag;
939 #endif 940
941 if (current_SC->SCp.phase & in_arbitration) { 942 status = inb( TMC_Status_port ); /* Read adapter status */ 943 if (!(status & 0x02)) { 944 #ifEVERY_ACCESS 945 printk( " AFAIL " );
946 #endif 947 my_done( DID_BUS_BUSY << 16 );
948 return;
949 } 950 current_SC->SCp.phase = in_selection;
951
952 outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );
953
954 outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */ 955 outb( adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port );
956
957 /* Stop arbitration and enable parity */ 958 outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
959 #ifDEBUG_RACE 960 in_interrupt_flag = 0;
961 #endif 962 return;
963 }elseif (current_SC->SCp.phase & in_selection) { 964 status = inb( SCSI_Status_port );
965 if (!(status & 0x01)) { 966 /* Try again, for slow devices */ 967 if (fdomain_select( current_SC->target )) { 968 #ifEVERY_ACCESS 969 printk( " SFAIL " );
970 #endif 971 my_done( DID_NO_CONNECT << 16 );
972 return;
973 }else{ 974 #ifEVERY_ACCESS 975 printk( " AltSel " );
976 #endif 977 /* Stop arbitration and enable parity */ 978 outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
979 } 980 } 981 current_SC->SCp.phase = in_other;
982 outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
983 outb( 0x80, SCSI_Cntl_port );
984 #ifDEBUG_RACE 985 in_interrupt_flag = 0;
986 #endif 987 return;
988 } 989
990 /* current_SC->SCp.phase == in_other: this is the body of the routine */ 991
992 status = inb( SCSI_Status_port );
993
994 if (status & 0x10) {/* REQ */ 995
996 switch (status & 0x0e) { 997
998 case 0x08: /* COMMAND OUT */ 999 outb( current_SC->cmnd[current_SC->SCp.sent_command++],
1000 Write_SCSI_Data_port );
1001 #ifEVERY_ACCESS1002 printk( "CMD = %x,",
1003 current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
1004 #endif1005 break;
1006 case 0x00: /* DATA OUT -- tmc18c50/tmc18c30 only */1007 if (chip != tmc1800 && !current_SC->SCp.have_data_in) {1008 current_SC->SCp.have_data_in = -1;
1009 outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1010 }1011 break;
1012 case 0x04: /* DATA IN -- tmc18c50/tmc18c30 only */1013 if (chip != tmc1800 && !current_SC->SCp.have_data_in) {1014 current_SC->SCp.have_data_in = 1;
1015 outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1016 }1017 break;
1018 case 0x0c: /* STATUS IN */1019 current_SC->SCp.Status = inb( Read_SCSI_Data_port );
1020 #ifEVERY_ACCESS1021 printk( "Status = %x, ", current_SC->SCp.Status );
1022 #endif1023 #ifERRORS_ONLY1024 if (current_SC->SCp.Status && current_SC->SCp.Status != 2) {1025 printk( "fdomain: target = %d, command = %x, status = %x\n",
1026 current_SC->target,
1027 current_SC->cmnd[0],
1028 current_SC->SCp.Status );
1029 }1030 #endif1031 break;
1032 case 0x0a: /* MESSAGE OUT */1033 outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */1034 break;
1035 case 0x0e: /* MESSAGE IN */1036 current_SC->SCp.Message = inb( Read_SCSI_Data_port );
1037 #ifEVERY_ACCESS1038 printk( "Message = %x, ", current_SC->SCp.Message );
1039 #endif1040 if (!current_SC->SCp.Message) ++done;
1041 #ifDEBUG_MESSAGES || EVERY_ACCESS1042 if (current_SC->SCp.Message) {1043 printk( "fdomain: message = %x\n", current_SC->SCp.Message );
1044 }1045 #endif1046 break;
1047 }1048 }1049
1050 if (chip == tmc18001051 && !current_SC->SCp.have_data_in1052 && (current_SC->SCp.sent_command1053 >= current_SC->cmd_len)) {1054 /* We have to get the FIFO direction1055 correct, so I've made a table based1056 on the SCSI Standard of which commands1057 appear to require a DATA OUT phase.1058 */1059 /*1060 p. 94: Command for all device types1061 CHANGE DEFINITION 40 DATA OUT1062 COMPARE 39 DATA OUT1063 COPY 18 DATA OUT1064 COPY AND VERIFY 3a DATA OUT1065 INQUIRY 12 1066 LOG SELECT 4c DATA OUT1067 LOG SENSE 4d1068 MODE SELECT (6) 15 DATA OUT1069 MODE SELECT (10) 55 DATA OUT1070 MODE SENSE (6) 1a1071 MODE SENSE (10) 5a1072 READ BUFFER 3c1073 RECEIVE DIAGNOSTIC RESULTS 1c1074 REQUEST SENSE 031075 SEND DIAGNOSTIC 1d DATA OUT1076 TEST UNIT READY 001077 WRITE BUFFER 3b DATA OUT1078
1079 p.178: Commands for direct-access devices (not listed on p. 94)1080 FORMAT UNIT 04 DATA OUT1081 LOCK-UNLOCK CACHE 361082 PRE-FETCH 341083 PREVENT-ALLOW MEDIUM REMOVAL 1e1084 READ (6)/RECEIVE 081085 READ (10) 3c1086 READ CAPACITY 251087 READ DEFECT DATA (10) 371088 READ LONG 3e1089 REASSIGN BLOCKS 07 DATA OUT1090 RELEASE 171091 RESERVE 16 DATA OUT1092 REZERO UNIT/REWIND 011093 SEARCH DATA EQUAL (10) 31 DATA OUT1094 SEARCH DATA HIGH (10) 30 DATA OUT1095 SEARCH DATA LOW (10) 32 DATA OUT1096 SEEK (6) 0b1097 SEEK (10) 2b1098 SET LIMITS (10) 331099 START STOP UNIT 1b1100 SYNCHRONIZE CACHE 351101 VERIFY (10) 2f1102 WRITE (6)/PRINT/SEND 0a DATA OUT1103 WRITE (10)/SEND 2a DATA OUT1104 WRITE AND VERIFY (10) 2e DATA OUT1105 WRITE LONG 3f DATA OUT1106 WRITE SAME 41 DATA OUT ?1107
1108 p. 261: Commands for sequential-access devices (not previously listed)1109 ERASE 191110 LOAD UNLOAD 1b1111 LOCATE 2b1112 READ BLOCK LIMITS 051113 READ POSITION 341114 READ REVERSE 0f1115 RECOVER BUFFERED DATA 141116 SPACE 111117 WRITE FILEMARKS 10 ?1118
1119 p. 298: Commands for printer devices (not previously listed)1120 ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****1121 SLEW AND PRINT 0b DATA OUT -- same as seek1122 STOP PRINT 1b1123 SYNCHRONIZE BUFFER 101124
1125 p. 315: Commands for processor devices (not previously listed)1126 1127 p. 321: Commands for write-once devices (not previously listed)1128 MEDIUM SCAN 381129 READ (12) a81130 SEARCH DATA EQUAL (12) b1 DATA OUT1131 SEARCH DATA HIGH (12) b0 DATA OUT1132 SEARCH DATA LOW (12) b2 DATA OUT1133 SET LIMITS (12) b31134 VERIFY (12) af1135 WRITE (12) aa DATA OUT1136 WRITE AND VERIFY (12) ae DATA OUT1137
1138 p. 332: Commands for CD-ROM devices (not previously listed)1139 PAUSE/RESUME 4b1140 PLAY AUDIO (10) 451141 PLAY AUDIO (12) a51142 PLAY AUDIO MSF 471143 PLAY TRACK RELATIVE (10) 491144 PLAY TRACK RELATIVE (12) a91145 READ HEADER 441146 READ SUB-CHANNEL 421147 READ TOC 431148
1149 p. 370: Commands for scanner devices (not previously listed)1150 GET DATA BUFFER STATUS 341151 GET WINDOW 251152 OBJECT POSITION 311153 SCAN 1b1154 SET WINDOW 24 DATA OUT1155
1156 p. 391: Commands for optical memory devices (not listed)1157 ERASE (10) 2c1158 ERASE (12) ac1159 MEDIUM SCAN 38 DATA OUT1160 READ DEFECT DATA (12) b71161 READ GENERATION 291162 READ UPDATED BLOCK 2d1163 UPDATE BLOCK 3d DATA OUT1164
1165 p. 419: Commands for medium changer devices (not listed)1166 EXCHANGE MEDIUM 461167 INITIALIZE ELEMENT STATUS 071168 MOVE MEDIUM a51169 POSITION TO ELEMENT 2b1170 READ ELEMENT STATUS b81171 REQUEST VOL. ELEMENT ADDRESS b51172 SEND VOLUME TAG b6 DATA OUT1173
1174 p. 454: Commands for communications devices (not listed previously)1175 GET MESSAGE (6) 081176 GET MESSAGE (10) 281177 GET MESSAGE (12) a81178 */1179
1180 switch (current_SC->cmnd[0]) {1181 caseCHANGE_DEFINITION: caseCOMPARE: caseCOPY:
1182 caseCOPY_VERIFY: caseLOG_SELECT: caseMODE_SELECT:
1183 caseMODE_SELECT_10: caseSEND_DIAGNOSTIC: caseWRITE_BUFFER:
1184
1185 caseFORMAT_UNIT: caseREASSIGN_BLOCKS: caseRESERVE:
1186 caseSEARCH_EQUAL: caseSEARCH_HIGH: caseSEARCH_LOW:
1187 caseWRITE_6: caseWRITE_10: caseWRITE_VERIFY:
1188 case 0x3f: case 0x41:
1189
1190 case 0xb1: case 0xb0: case 0xb2:
1191 case 0xaa: case 0xae:
1192
1193 case 0x24:
1194
1195 case 0x38: case 0x3d:
1196
1197 case 0xb6:
1198
1199 case 0xea: /* alternate number for WRITE LONG */1200
1201 current_SC->SCp.have_data_in = -1;
1202 outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1203 break;
1204
1205 case 0x00:
1206 default:
1207
1208 current_SC->SCp.have_data_in = 1;
1209 outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1210 break;
1211 }1212 }1213
1214 if (current_SC->SCp.have_data_in == -1) {/* DATA OUT */1215 while ( (data_count = FIFO_Size - inw( FIFO_Data_Count_port )) > 512 ) {1216 #ifEVERY_ACCESS1217 printk( "DC=%d, ", data_count ) ;
1218 #endif1219 if (data_count > current_SC->SCp.this_residual)
1220 data_count = current_SC->SCp.this_residual;
1221 if (data_count > 0) {1222 #ifEVERY_ACCESS1223 printk( "%d OUT, ", data_count );
1224 #endif1225 if (data_count == 1) {1226 outb( *current_SC->SCp.ptr++, Write_FIFO_port );
1227 --current_SC->SCp.this_residual;
1228 }else{1229 data_count >>= 1;
1230 outsw( Write_FIFO_port, current_SC->SCp.ptr, data_count );
1231 current_SC->SCp.ptr += 2 * data_count;
1232 current_SC->SCp.this_residual -= 2 * data_count;
1233 }1234 }1235 if (!current_SC->SCp.this_residual) {1236 if (current_SC->SCp.buffers_residual) {1237 --current_SC->SCp.buffers_residual;
1238 ++current_SC->SCp.buffer;
1239 current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1240 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1241 }else1242 break;
1243 }1244 }1245 }1246
1247 if (current_SC->SCp.have_data_in == 1) {/* DATA IN */1248 while ((data_count = inw( FIFO_Data_Count_port )) > 0) {1249 #ifEVERY_ACCESS1250 printk( "DC=%d, ", data_count );
1251 #endif1252 if (data_count > current_SC->SCp.this_residual)
1253 data_count = current_SC->SCp.this_residual;
1254 if (data_count) {1255 #ifEVERY_ACCESS1256 printk( "%d IN, ", data_count );
1257 #endif1258 if (data_count == 1) {1259 *current_SC->SCp.ptr++ = inb( Read_FIFO_port );
1260 --current_SC->SCp.this_residual;
1261 }else{1262 data_count >>= 1; /* Number of words */1263 insw( Read_FIFO_port, current_SC->SCp.ptr, data_count );
1264 current_SC->SCp.ptr += 2 * data_count;
1265 current_SC->SCp.this_residual -= 2 * data_count;
1266 }1267 }1268 if (!current_SC->SCp.this_residual1269 && current_SC->SCp.buffers_residual) {1270 --current_SC->SCp.buffers_residual;
1271 ++current_SC->SCp.buffer;
1272 current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1273 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1274 }1275 }1276 }1277
1278 if (done) {1279 #ifEVERY_ACCESS1280 printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
1281 #endif1282
1283 #ifERRORS_ONLY1284 if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {1285 if ((unsignedchar)(*((char *)current_SC->request_buffer+2)) & 0x0f) {1286 unsignedcharkey;
1287 unsignedcharcode;
1288 unsignedcharqualifier;
1289
1290 key = (unsignedchar)(*((char *)current_SC->request_buffer + 2))
1291 & 0x0f;
1292 code = (unsignedchar)(*((char *)current_SC->request_buffer + 12));
1293 qualifier = (unsignedchar)(*((char *)current_SC->request_buffer1294 + 13));
1295
1296 if (!(key == UNIT_ATTENTION && (code == 0x29 || !code))
1297 && !(key == NOT_READY1298 && code == 0x04
1299 && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1300 && !(key == ILLEGAL_REQUEST && (code == 0x25
1301 || code == 0x24
1302 || !code)))
1303
1304 printk( "fdomain: REQUEST SENSE "
1305 "Key = %x, Code = %x, Qualifier = %x\n",
1306 key, code, qualifier );
1307 }1308 }1309 #endif1310 #ifEVERY_ACCESS1311 printk( "BEFORE MY_DONE. . ." );
1312 #endif1313 my_done( (current_SC->SCp.Status & 0xff)
1314 | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
1315 #ifEVERY_ACCESS1316 printk( "RETURNING.\n" );
1317 #endif1318
1319 }else{1320 if (current_SC->SCp.phase & disconnect) {1321 outb( 0xd0 | FIFO_COUNT, Interrupt_Cntl_port );
1322 outb( 0x00, SCSI_Cntl_port );
1323 }else{1324 outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
1325 }1326 }1327 #ifDEBUG_RACE1328 in_interrupt_flag = 0;
1329 #endif1330 return;
1331 }1332
1333 intfdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
/* */1334 {1335 if (in_command) {1336 panic( "fdomain: fdomain_16x0_queue() NOT REENTRANT!\n" );
1337 }1338 #ifEVERY_ACCESS1339 printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1340 SCpnt->target,
1341 *(unsignedchar *)SCpnt->cmnd,
1342 SCpnt->use_sg,
1343 SCpnt->request_bufflen );
1344 #endif1345
1346 fdomain_make_bus_idle();
1347
1348 current_SC = SCpnt; /* Save this for the done function */1349 current_SC->scsi_done = done;
1350
1351 /* Initialize static data */1352
1353 if (current_SC->use_sg) {1354 current_SC->SCp.buffer =
1355 (structscatterlist *)current_SC->request_buffer;
1356 current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1357 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1358 current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
1359 }else{1360 current_SC->SCp.ptr = (char *)current_SC->request_buffer;
1361 current_SC->SCp.this_residual = current_SC->request_bufflen;
1362 current_SC->SCp.buffer = NULL;
1363 current_SC->SCp.buffers_residual = 0;
1364 }1365
1366
1367 current_SC->SCp.Status = 0;
1368 current_SC->SCp.Message = 0;
1369 current_SC->SCp.have_data_in = 0;
1370 current_SC->SCp.sent_command = 0;
1371 current_SC->SCp.phase = in_arbitration;
1372
1373 /* Start arbitration */1374 outb( 0x00, Interrupt_Cntl_port );
1375 outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */1376 outb( adapter_mask, SCSI_Data_NoACK_port ); /* Set our id bit */1377 ++in_command;
1378 outb( 0x20, Interrupt_Cntl_port );
1379 outb( 0x14 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */1380
1381 return 0;
1382 }1383
1384 /* The following code, which simulates the old-style command function, was1385 taken from Tommy Thorn's aha1542.c file. This code is Copyright (C)1386 1992 Tommy Thorn. */1387
1388 staticvolatileintinternal_done_flag = 0;
1389 staticvolatileintinternal_done_errcode = 0;
1390
1391 staticvoidinternal_done( Scsi_Cmnd *SCpnt )
/* */1392 {1393 internal_done_errcode = SCpnt->result;
1394 ++internal_done_flag;
1395 }1396
1397 intfdomain_16x0_command( Scsi_Cmnd *SCpnt )
/* */1398 {1399 fdomain_16x0_queue( SCpnt, internal_done );
1400
1401 while (!internal_done_flag)
1402 ;
1403 internal_done_flag = 0;
1404 returninternal_done_errcode;
1405 }1406
1407 /* End of code derived from Tommy Thorn's work. */1408
1409 voidprint_info( Scsi_Cmnd *SCpnt )
/* */1410 {1411 unsignedintimr;
1412 unsignedintirr;
1413 unsignedintisr;
1414
1415 if (!SCpnt || !SCpnt->host) {1416 printk( "fdomain: cannot provide detailed information\n" );
1417 }1418
1419 printk( "%s\n", fdomain_16x0_info( SCpnt->host ) );
1420 print_banner( SCpnt->host );
1421 switch (SCpnt->SCp.phase) {1422 casein_arbitration: printk( "arbitration " ); break;
1423 casein_selection: printk( "selection " ); break;
1424 casein_other: printk( "other " ); break;
1425 default: printk( "unknown " ); break;
1426 }1427
1428 printk( "(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1429 SCpnt->SCp.phase,
1430 SCpnt->target,
1431 *(unsignedchar *)SCpnt->cmnd,
1432 SCpnt->use_sg,
1433 SCpnt->request_bufflen );
1434 printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
1435 SCpnt->SCp.sent_command,
1436 SCpnt->SCp.have_data_in,
1437 SCpnt->timeout );
1438 #ifDEBUG_RACE1439 printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
1440 #endif1441
1442 imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
1443 outb( 0x0a, 0xa0 );
1444 irr = inb( 0xa0 ) << 8;
1445 outb( 0x0a, 0x20 );
1446 irr += inb( 0x20 );
1447 outb( 0x0b, 0xa0 );
1448 isr = inb( 0xa0 ) << 8;
1449 outb( 0x0b, 0x20 );
1450 isr += inb( 0x20 );
1451
1452 /* Print out interesting information */1453 printk( "IMR = 0x%04x", imr );
1454 if (imr & (1 << interrupt_level))
1455 printk( " (masked)" );
1456 printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
1457
1458 printk( "SCSI Status = 0x%02x\n", inb( SCSI_Status_port ) );
1459 printk( "TMC Status = 0x%02x", inb( TMC_Status_port ) );
1460 if (inb( TMC_Status_port & 1))
1461 printk( " (interrupt)" );
1462 printk( "\n" );
1463 printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port ) );
1464 if (inb( Interrupt_Status_port ) & 0x08)
1465 printk( " (enabled)" );
1466 printk( "\n" );
1467 if (chip == tmc18c50 || chip == tmc18c30) {1468 printk( "FIFO Status = 0x%02x\n", inb( port_base + FIFO_Status ) );
1469 printk( "Int. Condition = 0x%02x\n",
1470 inb( port_base + Interrupt_Cond ) );
1471 }1472 printk( "Configuration 1 = 0x%02x\n", inb( port_base + Configuration1 ) );
1473 if (chip == tmc18c50 || chip == tmc18c30)
1474 printk( "Configuration 2 = 0x%02x\n",
1475 inb( port_base + Configuration2 ) );
1476 }1477
1478 intfdomain_16x0_abort( Scsi_Cmnd *SCpnt)
/* */1479 {1480 unsignedlongflags;
1481 #ifEVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT1482 printk( "fdomain: abort " );
1483 #endif1484
1485 save_flags( flags );
1486 cli();
1487 if (!in_command) {1488 #ifEVERY_ACCESS || ERRORS_ONLY1489 printk( " (not in command)\n" );
1490 #endif1491 restore_flags( flags );
1492 returnSCSI_ABORT_NOT_RUNNING;
1493 }1494
1495 #ifDEBUG_ABORT1496 print_info( SCpnt );
1497 #endif1498
1499 fdomain_make_bus_idle();
1500
1501 current_SC->SCp.phase |= aborted;
1502
1503 current_SC->result = DID_ABORT << 16;
1504
1505 restore_flags( flags );
1506
1507 /* Aborts are not done well. . . */1508 my_done( DID_ABORT << 16 );
1509
1510 returnSCSI_ABORT_SUCCESS;
1511 }1512
1513 intfdomain_16x0_reset( Scsi_Cmnd *SCpnt )
/* */1514 {1515 #ifDEBUG_RESET1516 staticintcalled_once = 0;
1517 #endif1518
1519 #ifERRORS_ONLY1520 if (SCpnt) printk( "fdomain: SCSI Bus Reset\n" );
1521 #endif1522
1523 #ifDEBUG_RESET1524 if (called_once) print_info( current_SC );
1525 called_once = 1;
1526 #endif1527
1528 outb( 1, SCSI_Cntl_port );
1529 do_pause( 2 );
1530 outb( 0, SCSI_Cntl_port );
1531 do_pause( 115 );
1532 outb( 0, SCSI_Mode_Cntl_port );
1533 outb( PARITY_MASK, TMC_Cntl_port );
1534
1535 /* Unless this is the very first call (i.e., SCPnt == NULL), everything1536 is probably hosed at this point. We will, however, try to keep1537 things going by informing the high-level code that we need help. */1538
1539 returnSCSI_RESET_WAKEUP;
1540 }1541
1542 #include "sd.h"
1543 #include "scsi_ioctl.h"
1544
1545 intfdomain_16x0_biosparam( Scsi_Disk *disk, intdev, int *info_array )
/* */1546 {1547 intdrive;
1548 unsignedcharbuf[512 + sizeof( int ) * 2];
1549 intsize = disk->capacity;
1550 int *sizes = (int *)buf;
1551 unsignedchar *data = (unsignedchar *)(sizes + 2);
1552 unsignedchardo_read[] = {READ_6, 0, 0, 0, 1, 0 };
1553 intretcode;
1554 structdrive_info{1555 unsignedshortcylinders;
1556 unsignedcharheads;
1557 unsignedcharsectors;
1558 } *i;
1559
1560 /* NOTES:1561 The RAM area starts at 0x1f00 from the bios_base address.1562
1563 For BIOS Version 2.0:1564 1565 The drive parameter table seems to start at 0x1f30.1566 The first byte's purpose is not known.1567 Next is the cylinder, head, and sector information.1568 The last 4 bytes appear to be the drive's size in sectors.1569 The other bytes in the drive parameter table are unknown.1570 If anyone figures them out, please send me mail, and I will1571 update these notes.1572
1573 Tape drives do not get placed in this table.1574
1575 There is another table at 0x1fea:1576 If the byte is 0x01, then the SCSI ID is not in use.1577 If the byte is 0x18 or 0x48, then the SCSI ID is in use,1578 although tapes don't seem to be in this table. I haven't1579 seen any other numbers (in a limited sample).1580
1581 0x1f2d is a drive count (i.e., not including tapes)1582
1583 The table at 0x1fcc are I/O ports addresses for the various1584 operations. I calculate these by hand in this driver code.1585
1586 1587 1588 For the ISA-200S version of BIOS Version 2.0:1589
1590 The drive parameter table starts at 0x1f33.1591
1592 WARNING: Assume that the table entry is 25 bytes long. Someone needs1593 to check this for the Quantum ISA-200S card.1594
1595 1596 1597 For BIOS Version 3.2:1598
1599 The drive parameter table starts at 0x1f70. Each entry is1600 0x0a bytes long. Heads are one less than we need to report.1601 */1602
1603 drive = MINOR(dev) / 16;
1604
1605 if (bios_major == 2) {1606 if (ISA_200S) {1607 i = (structdrive_info *)( (char *)bios_base + 0x1f33 + drive * 25 );
1608 }else{1609 i = (structdrive_info *)( (char *)bios_base + 0x1f31 + drive * 25 );
1610 }1611 info_array[0] = i->heads;
1612 info_array[1] = i->sectors;
1613 info_array[2] = i->cylinders;
1614 }elseif (bios_major == 3
1615 && bios_minor >= 0
1616 && bios_minor < 4) {/* 3.0 and 3.2 BIOS */1617 i = (structdrive_info *)( (char *)bios_base + 0x1f71 + drive * 10 );
1618 info_array[0] = i->heads + 1;
1619 info_array[1] = i->sectors;
1620 info_array[2] = i->cylinders;
1621 }else{/* 3.4 BIOS (and up?) */1622 /* This algorithm was provided by Future Domain (much thanks!). */1623
1624 sizes[0] = 0; /* zero bytes out */1625 sizes[1] = 512; /* one sector in */1626 memcpy( data, do_read, sizeof( do_read ) );
1627 retcode = kernel_scsi_ioctl( disk->device,
1628 SCSI_IOCTL_SEND_COMMAND,
1629 (void *)buf );
1630 if (!retcode/* SCSI command ok */1631 && data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */1632 && data[0x1c2]) {/* Partition type */1633
1634 /* The partition table layout is as follows:1635
1636 Start: 0x1b3h1637 Offset: 0 = partition status1638 1 = starting head1639 2 = starting sector and cylinder (word, encoded)1640 4 = partition type1641 5 = ending head1642 6 = ending sector and cylinder (word, encoded)1643 8 = starting absolute sector (double word)1644 c = number of sectors (double word)1645 Signature: 0x1fe = 0x55aa1646
1647 So, this algorithm assumes:1648 1) the first partition table is in use,1649 2) the data in the first entry is correct, and1650 3) partitions never divide cylinders1651
1652 Note that (1) may be FALSE for NetBSD (and other BSD flavors),1653 as well as for Linux. Note also, that Linux doesn't pay any1654 attention to the fields that are used by this algorithm -- it1655 only uses the absolute sector data. Recent versions of Linux's1656 fdisk(1) will fill this data in correctly, and forthcoming1657 versions will check for consistency.1658
1659 Checking for a non-zero partition type is not part of the1660 Future Domain algorithm, but it seemed to be a reasonable thing1661 to do, especially in the Linux and BSD worlds. */1662
1663 info_array[0] = data[0x1c3] + 1; /* heads */1664 info_array[1] = data[0x1c4] & 0x3f; /* sectors */1665 }else{1666
1667 /* Note that this new method guarantees that there will always be1668 less than 1024 cylinders on a platter. This is good for drives1669 up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */1670
1671 if ((unsignedint)size >= 0x7e0000U) {1672 info_array[0] = 0xff; /* heads = 255 */1673 info_array[1] = 0x3f; /* sectors = 63 */1674 }elseif ((unsignedint)size >= 0x200000U) {1675 info_array[0] = 0x80; /* heads = 128 */1676 info_array[1] = 0x3f; /* sectors = 63 */1677 }else{1678 info_array[0] = 0x40; /* heads = 64 */1679 info_array[1] = 0x20; /* sectors = 32 */1680 }1681 }1682 /* For both methods, compute the cylinders */1683 info_array[2] = (unsignedint)size / (info_array[0] * info_array[1] );
1684 }1685
1686 return 0;
1687 }