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