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