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 informaiton. 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 toruble 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 SIGANTURE 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 structsigactionsa;
492 intretcode;
493 #ifDO_DETECT 494 constintbuflen = 255;
495 Scsi_CmndSCinit;
496 unsignedchardo_inquiry[] = {INQUIRY, 0, 0, 0, buflen, 0 };
497 unsignedchardo_request_sense[] = {REQUEST_SENSE, 0, 0, 0, buflen, 0 };
498 unsignedchardo_read_capacity[] = {READ_CAPACITY,
499 0, 0, 0, 0, 0, 0, 0, 0, 0 };
500 unsignedcharbuf[buflen];
501 #endif 502
503 #ifDEBUG_DETECT 504 printk( "fdomain_16x0_detect()," );
505 #endif 506
507 for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) { 508 #ifDEBUG_DETECT 509 printk( " %x(%x),", (unsigned)addresses[i], (unsigned)bios_base );
510 #endif 511 for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) { 512 if (!memcmp( ((char *)addresses[i] + signatures[j].sig_offset),
513 signatures[j].signature, signatures[j].sig_length )) { 514 bios_major = signatures[j].major_bios_version;
515 bios_minor = signatures[j].minor_bios_version;
516 PCI_bus = signatures[j].PCI_bus;
517 bios_base = addresses[i];
518 } 519 } 520 } 521
522 if (!bios_base) { 523 #ifDEBUG_DETECT 524 printk( " FAILED: NO BIOS\n" );
525 #endif 526 return 0;
527 } 528
529 if (bios_major == 2) { 530 /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM. 531 Assuming the ROM is enabled (otherwise we wouldn't have been 532 able to read the ROM signature :-), then the ROM sets up the 533 RAM area with some magic numbers, such as a list of port 534 base addresses and a list of the disk "geometry" reported to 535 DOS (this geometry has nothing to do with physical geometry). 536 */ 537
538 port_base = *((char *)bios_base + 0x1fcc)
539 + (*((char *)bios_base + 0x1fcd) << 8);
540
541 #ifDEBUG_DETECT 542 printk( " %x,", port_base );
543 #endif 544
545 for (flag = 0, i = 0; !flag && i < PORT_COUNT; i++) { 546 if (port_base == ports[i])
547 ++flag;
548 } 549
550 if (flag)
551 flag = fdomain_is_valid_port( port_base );
552 } 553
554 if (!flag) {/* Cannot get port base from BIOS RAM */ 555
556 /* This is a bad sign. It usually means that someone patched the 557 BIOS signature list (the signatures variable) to contain a BIOS 558 signature for a board *OTHER THAN* the TMC-1660/TMC-1680. It 559 also means that we don't have a Version 2.0 BIOS :-) 560 */ 561
562 #ifDEBUG_DETECT 563 if (bios_major != 2) printk( " RAM FAILED, " );
564 #endif 565
566 /* Anyway, the alternative to finding the address in the RAM is to 567 just search through every possible port address for one that is 568 attached to the Future Domain card. Don't panic, though, about 569 reading all these random port addresses -- there are rumors that 570 the Future Domain BIOS does something very similar. 571
572 Do not, however, check ports which the kernel knows are being used 573 by another driver. */ 574
575 if (!PCI_bus) { 576 for (i = 0; !flag && i < PORT_COUNT; i++) { 577 port_base = ports[i];
578 if (check_region( port_base, 0x10 )) { 579 #ifDEBUG_DETECT 580 printk( " (%x inuse),", port_base );
581 #endif 582 continue;
583 } 584 #ifDEBUG_DETECT 585 printk( " %x,", port_base );
586 #endif 587 flag = fdomain_is_valid_port( port_base );
588 } 589 }else{ 590
591 /* The proper way of doing this is to use the PCI BIOS call 592 (interrupt 0x1a) to determine the device IRQ and interrupt 593 level. Then the port_base will be in configuration register 594 0x10 (and configuration register 0x30 will contain the value of 595 bios_base). 596
597 Until the Linux kernel supports this sort of PCI bus query, we 598 scan down a bunch of addresses (Future Domain folks say we 599 should find the address before we get to 0xf800). This works 600 fine on some systems -- other systems may have to scan more 601 addresses. If you have to modify this section for your 602 installation, please send mail to faith@cs.unc.edu. */ 603
604 for (i = 0xff00; !flag && i > 0xf000; i -= 8) { 605 port_base = i;
606 if (check_region( port_base, 0x10 )) { 607 #ifDEBUG_DETECT 608 printk( " (%x inuse)," , port_base );
609 #endif 610 continue;
611 } 612 flag = fdomain_is_valid_port( port_base );
613 } 614 } 615 } 616
617 if (!flag) { 618 #ifDEBUG_DETECT 619 printk( " FAILED: NO PORT\n" );
620 #endif 621 return 0; /* Cannot find valid set of ports */ 622 } 623
624 print_banner();
625
626 SCSI_Mode_Cntl_port = port_base + SCSI_Mode_Cntl;
627 FIFO_Data_Count_port = port_base + FIFO_Data_Count;
628 Interrupt_Cntl_port = port_base + Interrupt_Cntl;
629 Interrupt_Status_port = port_base + Interrupt_Status;
630 Read_FIFO_port = port_base + Read_FIFO;
631 Read_SCSI_Data_port = port_base + Read_SCSI_Data;
632 SCSI_Cntl_port = port_base + SCSI_Cntl;
633 SCSI_Data_NoACK_port = port_base + SCSI_Data_NoACK;
634 SCSI_Status_port = port_base + SCSI_Status;
635 TMC_Cntl_port = port_base + TMC_Cntl;
636 TMC_Status_port = port_base + TMC_Status;
637 Write_FIFO_port = port_base + Write_FIFO;
638 Write_SCSI_Data_port = port_base + Write_SCSI_Data;
639
640 fdomain_16x0_reset( NULL );
641
642 if (fdomain_test_loopback()) { 643 #ifDEBUG_DETECT 644 printk( "Future Domain: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
645 #endif 646 return 0;
647 }/* Log IRQ with kernel */ 648
649 if (!interrupt_level) { 650 panic( "Future Domain: *NO* interrupt level selected!\n" );
651 }else{ 652 /* Register the IRQ with the kernel */ 653
654 sa.sa_handler = fdomain_16x0_intr;
655 sa.sa_flags = SA_INTERRUPT;
656 sa.sa_mask = 0;
657 sa.sa_restorer = NULL;
658
659 retcode = irqaction( interrupt_level, &sa );
660
661 if (retcode < 0) { 662 if (retcode == -EINVAL) { 663 printk( "Future Domain: IRQ %d is bad!\n", interrupt_level );
664 printk( " This shouldn't happen!\n" );
665 printk( " Send mail to faith@cs.unc.edu\n" );
666 }elseif (retcode == -EBUSY) { 667 printk( "Future Domain: IRQ %d is already in use!\n",
668 interrupt_level );
669 printk( " Please use another IRQ!\n" );
670 }else{ 671 printk( "Future Domain: Error getting IRQ %d\n", interrupt_level );
672 printk( " This shouldn't happen!\n" );
673 printk( " Send mail to faith@cs.unc.edu\n" );
674 } 675 panic( "Future Domain: Driver requires interruptions\n" );
676 }else{ 677 printk( "Future Domain: IRQ %d requested from kernel\n",
678 interrupt_level );
679 } 680 } 681
682 /* Log I/O ports with kernel */ 683
684 snarf_region( port_base, 0x10 );
685
686 if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) { 687 adapter_mask = 0x80;
688 tpnt->this_id = 7;
689 } 690
691 #ifDO_DETECT 692
693 /* These routines are here because of the way the SCSI bus behaves after 694 a reset. This appropriate behavior was not handled correctly by the 695 higher level SCSI routines when I first wrote this driver. Now, 696 however, correct scan routines are part of scsi.c and these routines 697 are no longer needed. However, this code is still good for 698 debugging. */ 699
700 SCinit.request_buffer = SCinit.buffer = buf;
701 SCinit.request_bufflen = SCinit.bufflen = sizeof(buf)-1;
702 SCinit.use_sg = 0;
703 SCinit.lun = 0;
704
705 printk( "Future Domain detection routine scanning for devices:\n" );
706 for (i = 0; i < 8; i++) { 707 SCinit.target = i;
708 if (i == tpnt->this_id) /* Skip host adapter */ 709 continue;
710 memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
711 retcode = fdomain_16x0_command(&SCinit);
712 if (!retcode) { 713 memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
714 retcode = fdomain_16x0_command(&SCinit);
715 if (!retcode) { 716 printk( " SCSI ID %d: ", i );
717 for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
718 printk( "%c", buf[j] >= 20 ? buf[j] : ' ' );
719 memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
720 retcode = fdomain_16x0_command(&SCinit);
721 if (!retcode) { 722 unsignedlongblocks, size, capacity;
723
724 blocks = (buf[0] << 24) | (buf[1] << 16)
725 | (buf[2] << 8) | buf[3];
726 size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
727 capacity = +( +(blocks / 1024L) * +(size * 10L)) / 1024L;
728
729 printk( "%lu MB (%lu byte blocks)",
730 ((capacity + 5L) / 10L), size );
731 }else{ 732 memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
733 retcode = fdomain_16x0_command(&SCinit);
734 } 735 printk ("\n" );
736 }else{ 737 memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
738 retcode = fdomain_16x0_command(&SCinit);
739 } 740 } 741 } 742 #endif 743
744 return 1;
745 } 746
747 constchar *fdomain_16x0_info(void)
/* */ 748 { 749 staticcharbuffer[80];
750 char *pt;
751
752 strcpy( buffer, "Future Domain: TMC-16x0 SCSI driver, version" );
753 if (strchr( VERSION, ':')) {/* Assume VERSION is an RCS Revision string */ 754 strcat( buffer, strchr( VERSION, ':' ) + 1 );
755 pt = strrchr( buffer, '$') - 1;
756 if (!pt) /* Stripped RCS Revision string? */ 757 pt = buffer + strlen( buffer ) - 1;
758 if (*pt != ' ')
759 ++pt;
760 *pt++ = '\n';
761 *pt = '\0';
762 }else{/* Assume VERSION is a number */ 763 strcat( buffer, " " VERSION "\n" );
764 } 765
766 returnbuffer;
767 } 768
769 #if 0
770 staticint fdomain_arbitrate( void )
/* */ 771 { 772 intstatus = 0;
773 unsignedlongtimeout;
774
775 #ifEVERY_ACCESS 776 printk( "fdomain_arbitrate()\n" );
777 #endif 778
779 outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */ 780 outb( adapter_mask, port_base + SCSI_Data_NoACK ); /* Set our id bit */ 781 outb( 0x04 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */ 782
783 timeout = jiffies + 50; /* 500 mS */ 784 while (jiffies < timeout) { 785 status = inb( TMC_Status_port ); /* Read adapter status */ 786 if (status & 0x02) /* Arbitration complete */ 787 return 0;
788 } 789
790 /* Make bus idle */ 791 fdomain_make_bus_idle();
792
793 #ifEVERY_ACCESS 794 printk( "Arbitration failed, status = %x\n", status );
795 #endif 796 #ifERRORS_ONLY 797 printk( "Future Domain: Arbitration failed, status = %x\n", status );
798 #endif 799 return 1;
800 } 801 #endif 802
803 staticintfdomain_select( inttarget )
/* */ 804 { 805 intstatus;
806 unsignedlongtimeout;
807
808
809 outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */ 810 outb( adapter_mask | (1 << target), SCSI_Data_NoACK_port );
811
812 /* Stop arbitration and enable parity */ 813 outb( PARITY_MASK, TMC_Cntl_port );
814
815 #if 0
816 timeout = jiffies + 25; /* 250mS */ 817 #else 818 timeout = jiffies + 35; /* 350mS -- because of timeouts */ 819 #endif 820 while (jiffies < timeout) { 821 status = inb( SCSI_Status_port ); /* Read adapter status */ 822 if (status & 1) {/* Busy asserted */ 823 /* Enable SCSI Bus (on error, should make bus idle with 0) */ 824 outb( 0x80, SCSI_Cntl_port );
825 return 0;
826 } 827 } 828 /* Make bus idle */ 829 fdomain_make_bus_idle();
830 #ifEVERY_ACCESS 831 if (!target) printk( "Selection failed\n" );
832 #endif 833 #ifERRORS_ONLY 834 if (!target) printk( "Future Domain: Selection failed\n" );
835 #endif 836 return 1;
837 } 838
839 voidmy_done( interror )
/* */ 840 { 841 if (in_command) { 842 in_command = 0;
843 outb( 0x00, Interrupt_Cntl_port );
844 fdomain_make_bus_idle();
845 current_SC->result = error;
846 if (current_SC->scsi_done)
847 current_SC->scsi_done( current_SC );
848 elsepanic( "Future Domain: current_SC->scsi_done() == NULL" );
849 }else{ 850 panic( "Future Domain: my_done() called outside of command\n" );
851 } 852 #ifDEBUG_RACE 853 in_interrupt_flag = 0;
854 #endif 855 } 856
857 voidfdomain_16x0_intr( intunused )
/* */ 858 { 859 intstatus;
860 intdone = 0;
861 unsigneddata_count;
862
863 sti();
864
865 outb( 0x00, Interrupt_Cntl_port );
866
867 /* We usually have one spurious interrupt after each command. Ignore it. */ 868 if (!in_command || !current_SC) {/* Spurious interrupt */ 869 #ifEVERY_ACCESS 870 printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
871 in_command, current_SC );
872 #endif 873 return;
874 } 875
876 /* Abort calls my_done, so we do nothing here. */ 877 if (current_SC->SCp.phase & aborted) { 878 #ifDEBUG_ABORT 879 printk( "Interrupt after abort, ignoring\n" );
880 #endif 881 /* 882 return; */ 883 } 884
885 #ifDEBUG_RACE 886 ++in_interrupt_flag;
887 #endif 888
889 if (current_SC->SCp.phase & in_arbitration) { 890 status = inb( TMC_Status_port ); /* Read adapter status */ 891 if (!(status & 0x02)) { 892 #ifEVERY_ACCESS 893 printk( " AFAIL " );
894 #endif 895 my_done( DID_BUS_BUSY << 16 );
896 return;
897 } 898 current_SC->SCp.phase = in_selection;
899
900 outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );
901
902 outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */ 903 outb( adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port );
904
905 /* Stop arbitration and enable parity */ 906 outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
907 #ifDEBUG_RACE 908 in_interrupt_flag = 0;
909 #endif 910 return;
911 }elseif (current_SC->SCp.phase & in_selection) { 912 status = inb( SCSI_Status_port );
913 if (!(status & 0x01)) { 914 /* Try again, for slow devices */ 915 if (fdomain_select( current_SC->target )) { 916 #ifEVERY_ACCESS 917 printk( " SFAIL " );
918 #endif 919 my_done( DID_NO_CONNECT << 16 );
920 return;
921 }else{ 922 #ifEVERY_ACCESS 923 printk( " AltSel " );
924 #endif 925 /* Stop arbitration and enable parity */ 926 outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
927 } 928 } 929 current_SC->SCp.phase = in_other;
930 outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
931 outb( 0x80, SCSI_Cntl_port );
932 #ifDEBUG_RACE 933 in_interrupt_flag = 0;
934 #endif 935 return;
936 } 937
938 /* current_SC->SCp.phase == in_other: this is the body of the routine */ 939
940 status = inb( SCSI_Status_port );
941
942 if (status & 0x10) {/* REQ */ 943
944 switch (status & 0x0e) { 945
946 case 0x08: /* COMMAND OUT */ 947 outb( current_SC->cmnd[current_SC->SCp.sent_command++],
948 Write_SCSI_Data_port );
949 #ifEVERY_ACCESS 950 printk( "CMD = %x,",
951 current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
952 #endif 953 break;
954 case 0x00: /* DATA OUT -- tmc18c50/tmc18c30 only */ 955 if (chip != tmc1800 && !current_SC->SCp.have_data_in) { 956 current_SC->SCp.have_data_in = -1;
957 outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
958 } 959 break;
960 case 0x04: /* DATA IN -- tmc18c50/tmc18c30 only */ 961 if (chip != tmc1800 && !current_SC->SCp.have_data_in) { 962 current_SC->SCp.have_data_in = 1;
963 outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
964 } 965 break;
966 case 0x0c: /* STATUS IN */ 967 current_SC->SCp.Status = inb( Read_SCSI_Data_port );
968 #ifEVERY_ACCESS 969 printk( "Status = %x, ", current_SC->SCp.Status );
970 #endif 971 #ifERRORS_ONLY 972 if (current_SC->SCp.Status && current_SC->SCp.Status != 2) { 973 printk( "Future Domain: target = %d, command = %x, "
974 "Status = %x\n",
975 current_SC->target, current_SC->cmnd[0],
976 current_SC->SCp.Status );
977 } 978 #endif 979 break;
980 case 0x0a: /* MESSAGE OUT */ 981 outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */ 982 break;
983 case 0x0e: /* MESSAGE IN */ 984 current_SC->SCp.Message = inb( Read_SCSI_Data_port );
985 #ifEVERY_ACCESS 986 printk( "Message = %x, ", current_SC->SCp.Message );
987 #endif 988 if (!current_SC->SCp.Message) ++done;
989 #ifDEBUG_MESSAGES || EVERY_ACCESS 990 if (current_SC->SCp.Message) { 991 printk( "Future Domain: Message = %x\n",
992 current_SC->SCp.Message );
993 } 994 #endif 995 break;
996 } 997 } 998
999 if (chip == tmc18001000 && !current_SC->SCp.have_data_in1001 && (current_SC->SCp.sent_command1002 >= COMMAND_SIZE( current_SC->cmnd[ 0 ] ))) {1003 /* We have to get the FIFO direction1004 correct, so I've made a table based1005 on the SCSI Standard of which commands1006 appear to require a DATA OUT phase.1007 */1008 /*1009 p. 94: Command for all device types1010 CHANGE DEFINITION 40 DATA OUT1011 COMPARE 39 DATA OUT1012 COPY 18 DATA OUT1013 COPY AND VERIFY 3a DATA OUT1014 INQUIRY 12 1015 LOG SELECT 4c DATA OUT1016 LOG SENSE 4d1017 MODE SELECT (6) 15 DATA OUT1018 MODE SELECT (10) 55 DATA OUT1019 MODE SENSE (6) 1a1020 MODE SENSE (10) 5a1021 READ BUFFER 3c1022 RECEIVE DIAGNOSTIC RESULTS 1c1023 REQUEST SENSE 031024 SEND DIAGNOSTIC 1d DATA OUT1025 TEST UNIT READY 001026 WRITE BUFFER 3b DATA OUT1027
1028 p.178: Commands for direct-access devices (not listed on p. 94)1029 FORMAT UNIT 04 DATA OUT1030 LOCK-UNLOCK CACHE 361031 PRE-FETCH 341032 PREVENT-ALLOW MEDIUM REMOVAL 1e1033 READ (6)/RECEIVE 081034 READ (10) 3c1035 READ CAPACITY 251036 READ DEFECT DATA (10) 371037 READ LONG 3e1038 REASSIGN BLOCKS 07 DATA OUT1039 RELEASE 171040 RESERVE 16 DATA OUT1041 REZERO UNIT/REWIND 011042 SEARCH DATA EQUAL (10) 31 DATA OUT1043 SEARCH DATA HIGH (10) 30 DATA OUT1044 SEARCH DATA LOW (10) 32 DATA OUT1045 SEEK (6) 0b1046 SEEK (10) 2b1047 SET LIMITS (10) 331048 START STOP UNIT 1b1049 SYNCHRONIZE CACHE 351050 VERIFY (10) 2f1051 WRITE (6)/PRINT/SEND 0a DATA OUT1052 WRITE (10)/SEND 2a DATA OUT1053 WRITE AND VERIFY (10) 2e DATA OUT1054 WRITE LONG 3f DATA OUT1055 WRITE SAME 41 DATA OUT ?1056
1057 p. 261: Commands for sequential-access devices (not previously listed)1058 ERASE 191059 LOAD UNLOAD 1b1060 LOCATE 2b1061 READ BLOCK LIMITS 051062 READ POSITION 341063 READ REVERSE 0f1064 RECOVER BUFFERED DATA 141065 SPACE 111066 WRITE FILEMARKS 10 ?1067
1068 p. 298: Commands for printer devices (not previously listed)1069 ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****1070 SLEW AND PRINT 0b DATA OUT -- same as seek1071 STOP PRINT 1b1072 SYNCHRONIZE BUFFER 101073
1074 p. 315: Commands for processor devices (not previously listed)1075 1076 p. 321: Commands for write-once devices (not previously listed)1077 MEDIUM SCAN 381078 READ (12) a81079 SEARCH DATA EQUAL (12) b1 DATA OUT1080 SEARCH DATA HIGH (12) b0 DATA OUT1081 SEARCH DATA LOW (12) b2 DATA OUT1082 SET LIMITS (12) b31083 VERIFY (12) af1084 WRITE (12) aa DATA OUT1085 WRITE AND VERIFY (12) ae DATA OUT1086
1087 p. 332: Commands for CD-ROM devices (not previously listed)1088 PAUSE/RESUME 4b1089 PLAY AUDIO (10) 451090 PLAY AUDIO (12) a51091 PLAY AUDIO MSF 471092 PLAY TRACK RELATIVE (10) 491093 PLAY TRACK RELATIVE (12) a91094 READ HEADER 441095 READ SUB-CHANNEL 421096 READ TOC 431097
1098 p. 370: Commands for scanner devices (not previously listed)1099 GET DATA BUFFER STATUS 341100 GET WINDOW 251101 OBJECT POSITION 311102 SCAN 1b1103 SET WINDOW 24 DATA OUT1104
1105 p. 391: Commands for optical memory devices (not listed)1106 ERASE (10) 2c1107 ERASE (12) ac1108 MEDIUM SCAN 38 DATA OUT1109 READ DEFECT DATA (12) b71110 READ GENERATION 291111 READ UPDATED BLOCK 2d1112 UPDATE BLOCK 3d DATA OUT1113
1114 p. 419: Commands for medium changer devices (not listed)1115 EXCHANGE MEDIUM 461116 INITIALIZE ELEMENT STATUS 071117 MOVE MEDIUM a51118 POSITION TO ELEMENT 2b1119 READ ELEMENT STATUS b81120 REQUEST VOL. ELEMENT ADDRESS b51121 SEND VOLUME TAG b6 DATA OUT1122
1123 p. 454: Commands for communications devices (not listed previously)1124 GET MESSAGE (6) 081125 GET MESSAGE (10) 281126 GET MESSAGE (12) a81127 */1128
1129 switch (current_SC->cmnd[0]) {1130 caseCHANGE_DEFINITION: caseCOMPARE: caseCOPY:
1131 caseCOPY_VERIFY: caseLOG_SELECT: caseMODE_SELECT:
1132 caseMODE_SELECT_10: caseSEND_DIAGNOSTIC: caseWRITE_BUFFER:
1133
1134 caseFORMAT_UNIT: caseREASSIGN_BLOCKS: caseRESERVE:
1135 caseSEARCH_EQUAL: caseSEARCH_HIGH: caseSEARCH_LOW:
1136 caseWRITE_6: caseWRITE_10: caseWRITE_VERIFY:
1137 case 0x3f: case 0x41:
1138
1139 case 0xb1: case 0xb0: case 0xb2:
1140 case 0xaa: case 0xae:
1141
1142 case 0x24:
1143
1144 case 0x38: case 0x3d:
1145
1146 case 0xb6:
1147
1148 case 0xea: /* alternate number for WRITE LONG */1149
1150 current_SC->SCp.have_data_in = -1;
1151 outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1152 break;
1153
1154 case 0x00:
1155 default:
1156
1157 current_SC->SCp.have_data_in = 1;
1158 outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1159 break;
1160 }1161 }1162
1163 if (current_SC->SCp.have_data_in == -1) {/* DATA OUT */1164 while ( (data_count = FIFO_Size - inw( FIFO_Data_Count_port )) > 512 ) {1165 #ifEVERY_ACCESS1166 printk( "DC=%d, ", data_count ) ;
1167 #endif1168 if (data_count > current_SC->SCp.this_residual)
1169 data_count = current_SC->SCp.this_residual;
1170 if (data_count > 0) {1171 #ifEVERY_ACCESS1172 printk( "%d OUT, ", data_count );
1173 #endif1174 if (data_count == 1) {1175 outb( *current_SC->SCp.ptr++, Write_FIFO_port );
1176 --current_SC->SCp.this_residual;
1177 }else{1178 data_count >>= 1;
1179 outsw( Write_FIFO_port, current_SC->SCp.ptr, data_count );
1180 current_SC->SCp.ptr += 2 * data_count;
1181 current_SC->SCp.this_residual -= 2 * data_count;
1182 }1183 }1184 if (!current_SC->SCp.this_residual) {1185 if (current_SC->SCp.buffers_residual) {1186 --current_SC->SCp.buffers_residual;
1187 ++current_SC->SCp.buffer;
1188 current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1189 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1190 }else1191 break;
1192 }1193 }1194 }1195
1196 if (current_SC->SCp.have_data_in == 1) {/* DATA IN */1197 while ((data_count = inw( FIFO_Data_Count_port )) > 0) {1198 #ifEVERY_ACCESS1199 printk( "DC=%d, ", data_count );
1200 #endif1201 if (data_count > current_SC->SCp.this_residual)
1202 data_count = current_SC->SCp.this_residual;
1203 if (data_count) {1204 #ifEVERY_ACCESS1205 printk( "%d IN, ", data_count );
1206 #endif1207 if (data_count == 1) {1208 *current_SC->SCp.ptr++ = inb( Read_FIFO_port );
1209 --current_SC->SCp.this_residual;
1210 }else{1211 data_count >>= 1; /* Number of words */1212 insw( Read_FIFO_port, current_SC->SCp.ptr, data_count );
1213 current_SC->SCp.ptr += 2 * data_count;
1214 current_SC->SCp.this_residual -= 2 * data_count;
1215 }1216 }1217 if (!current_SC->SCp.this_residual1218 && current_SC->SCp.buffers_residual) {1219 --current_SC->SCp.buffers_residual;
1220 ++current_SC->SCp.buffer;
1221 current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1222 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1223 }1224 }1225 }1226
1227 if (done) {1228 #ifEVERY_ACCESS1229 printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
1230 #endif1231
1232 #ifERRORS_ONLY1233 if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {1234 if ((unsignedchar)(*((char *)current_SC->request_buffer+2)) & 0x0f) {1235 unsignedcharkey;
1236 unsignedcharcode;
1237 unsignedcharqualifier;
1238
1239 key = (unsignedchar)(*((char *)current_SC->request_buffer + 2))
1240 & 0x0f;
1241 code = (unsignedchar)(*((char *)current_SC->request_buffer + 12));
1242 qualifier = (unsignedchar)(*((char *)current_SC->request_buffer1243 + 13));
1244
1245 if (!(key == UNIT_ATTENTION && (code == 0x29 || !code))
1246 && !(key == NOT_READY1247 && code == 0x04
1248 && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1249 && !(key == ILLEGAL_REQUEST && (code == 0x25
1250 || code == 0x24
1251 || !code)))
1252
1253 printk( "Future Domain: REQUEST SENSE "
1254 "Key = %x, Code = %x, Qualifier = %x\n",
1255 key, code, qualifier );
1256 }1257 }1258 #endif1259 #ifEVERY_ACCESS1260 printk( "BEFORE MY_DONE. . ." );
1261 #endif1262 my_done( (current_SC->SCp.Status & 0xff)
1263 | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
1264 #ifEVERY_ACCESS1265 printk( "RETURNING.\n" );
1266 #endif1267
1268 }else{1269 if (current_SC->SCp.phase & disconnect) {1270 outb( 0xd0 | FIFO_COUNT, Interrupt_Cntl_port );
1271 outb( 0x00, SCSI_Cntl_port );
1272 }else{1273 outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
1274 }1275 }1276 #ifDEBUG_RACE1277 in_interrupt_flag = 0;
1278 #endif1279 return;
1280 }1281
1282 intfdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
/* */1283 {1284 if (in_command) {1285 panic( "Future Domain: fdomain_16x0_queue() NOT REENTRANT!\n" );
1286 }1287 #ifEVERY_ACCESS1288 printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1289 SCpnt->target,
1290 *(unsignedchar *)SCpnt->cmnd,
1291 SCpnt->use_sg,
1292 SCpnt->request_bufflen );
1293 #endif1294
1295 fdomain_make_bus_idle();
1296
1297 current_SC = SCpnt; /* Save this for the done function */1298 current_SC->scsi_done = done;
1299
1300 /* Initialize static data */1301
1302 if (current_SC->use_sg) {1303 current_SC->SCp.buffer =
1304 (structscatterlist *)current_SC->request_buffer;
1305 current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1306 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1307 current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
1308 }else{1309 current_SC->SCp.ptr = (char *)current_SC->request_buffer;
1310 current_SC->SCp.this_residual = current_SC->request_bufflen;
1311 current_SC->SCp.buffer = NULL;
1312 current_SC->SCp.buffers_residual = 0;
1313 }1314
1315
1316 current_SC->SCp.Status = 0;
1317 current_SC->SCp.Message = 0;
1318 current_SC->SCp.have_data_in = 0;
1319 current_SC->SCp.sent_command = 0;
1320 current_SC->SCp.phase = in_arbitration;
1321
1322 /* Start arbitration */1323 outb( 0x00, Interrupt_Cntl_port );
1324 outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */1325 outb( adapter_mask, SCSI_Data_NoACK_port ); /* Set our id bit */1326 ++in_command;
1327 outb( 0x20, Interrupt_Cntl_port );
1328 outb( 0x14 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */1329
1330 return 0;
1331 }1332
1333 /* The following code, which simulates the old-style command function, was1334 taken from Tommy Thorn's aha1542.c file. This code is Copyright (C)1335 1992 Tommy Thorn. */1336
1337 staticvolatileintinternal_done_flag = 0;
1338 staticvolatileintinternal_done_errcode = 0;
1339
1340 staticvoidinternal_done( Scsi_Cmnd *SCpnt )
/* */1341 {1342 internal_done_errcode = SCpnt->result;
1343 ++internal_done_flag;
1344 }1345
1346 intfdomain_16x0_command( Scsi_Cmnd *SCpnt )
/* */1347 {1348 fdomain_16x0_queue( SCpnt, internal_done );
1349
1350 while (!internal_done_flag)
1351 ;
1352 internal_done_flag = 0;
1353 returninternal_done_errcode;
1354 }1355
1356 /* End of code derived from Tommy Thorn's work. */1357
1358 voidprint_info( Scsi_Cmnd *SCpnt )
/* */1359 {1360 unsignedintimr;
1361 unsignedintirr;
1362 unsignedintisr;
1363
1364 print_banner();
1365 switch (SCpnt->SCp.phase) {1366 casein_arbitration: printk( "arbitration " ); break;
1367 casein_selection: printk( "selection " ); break;
1368 casein_other: printk( "other " ); break;
1369 default: printk( "unknown " ); break;
1370 }1371
1372 printk( "(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1373 SCpnt->SCp.phase,
1374 SCpnt->target,
1375 *(unsignedchar *)SCpnt->cmnd,
1376 SCpnt->use_sg,
1377 SCpnt->request_bufflen );
1378 printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
1379 SCpnt->SCp.sent_command,
1380 SCpnt->SCp.have_data_in,
1381 SCpnt->timeout );
1382 #ifDEBUG_RACE1383 printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
1384 #endif1385
1386 imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
1387 outb( 0x0a, 0xa0 );
1388 irr = inb( 0xa0 ) << 8;
1389 outb( 0x0a, 0x20 );
1390 irr += inb( 0x20 );
1391 outb( 0x0b, 0xa0 );
1392 isr = inb( 0xa0 ) << 8;
1393 outb( 0x0b, 0x20 );
1394 isr += inb( 0x20 );
1395
1396 /* Print out interesting information */1397 printk( "IMR = 0x%04x", imr );
1398 if (imr & (1 << interrupt_level))
1399 printk( " (masked)" );
1400 printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
1401
1402 printk( "SCSI Status = 0x%02x\n", inb( SCSI_Status_port ) );
1403 printk( "TMC Status = 0x%02x", inb( TMC_Status_port ) );
1404 if (inb( TMC_Status_port & 1))
1405 printk( " (interrupt)" );
1406 printk( "\n" );
1407 printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port ) );
1408 if (inb( Interrupt_Status_port ) & 0x08)
1409 printk( " (enabled)" );
1410 printk( "\n" );
1411 if (chip == tmc18c50 || chip == tmc18c30) {1412 printk( "FIFO Status = 0x%02x\n", inb( port_base + FIFO_Status ) );
1413 printk( "Int. Condition = 0x%02x\n",
1414 inb( port_base + Interrupt_Cond ) );
1415 }1416 printk( "Configuration 1 = 0x%02x\n", inb( port_base + Configuration1 ) );
1417 if (chip == tmc18c50 || chip == tmc18c30)
1418 printk( "Configuration 2 = 0x%02x\n",
1419 inb( port_base + Configuration2 ) );
1420 }1421
1422 intfdomain_16x0_abort( Scsi_Cmnd *SCpnt)
/* */1423 {1424 #ifEVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT1425 printk( "Future Domain: Abort " );
1426 #endif1427
1428 cli();
1429 if (!in_command) {1430 #ifEVERY_ACCESS || ERRORS_ONLY1431 printk( " (not in command)\n" );
1432 #endif1433 sti();
1434 returnSCSI_ABORT_NOT_RUNNING;
1435 }1436
1437 #ifDEBUG_ABORT1438 print_info( SCpnt );
1439 #endif1440
1441 fdomain_make_bus_idle();
1442
1443 current_SC->SCp.phase |= aborted;
1444
1445 current_SC->result = DID_ABORT << 16;
1446
1447 sti();
1448
1449 /* Aborts are not done well. . . */1450 my_done( DID_ABORT << 16 );
1451
1452 returnSCSI_ABORT_SUCCESS;
1453 }1454
1455 intfdomain_16x0_reset( Scsi_Cmnd *SCpnt )
/* */1456 {1457 #ifDEBUG_RESET1458 staticintcalled_once = 0;
1459 #endif1460
1461 #ifERRORS_ONLY1462 printk( "Future Domain: SCSI Bus Reset\n" );
1463 #endif1464
1465 #ifDEBUG_RESET1466 if (called_once) print_info( current_SC );
1467 called_once = 1;
1468 #endif1469
1470 outb( 1, SCSI_Cntl_port );
1471 do_pause( 2 );
1472 outb( 0, SCSI_Cntl_port );
1473 do_pause( 115 );
1474 outb( 0, SCSI_Mode_Cntl_port );
1475 outb( PARITY_MASK, TMC_Cntl_port );
1476
1477 /* Unless this is the very first call (i.e., SCPnt == NULL), everything1478 is probably hosed at this point. We will, however, try to keep1479 things going by informing the high-level code that we need help. */1480
1481 returnSCSI_RESET_WAKEUP;
1482 }1483
1484 #include "sd.h"
1485 #include "scsi_ioctl.h"
1486
1487 intfdomain_16x0_biosparam( Scsi_Disk *disk, intdev, int *info_array )
/* */1488 {1489 intdrive;
1490 unsignedcharbuf[512 + sizeof( int ) * 2];
1491 intsize = disk->capacity;
1492 int *sizes = (int *)buf;
1493 unsignedchar *data = (unsignedchar *)(sizes + 2);
1494 unsignedchardo_read[] = {READ_6, 0, 0, 0, 1, 0 };
1495 intretcode;
1496 structdrive_info{1497 unsignedshortcylinders;
1498 unsignedcharheads;
1499 unsignedcharsectors;
1500 } *i;
1501
1502 /* NOTES:1503 The RAM area starts at 0x1f00 from the bios_base address.1504
1505 For BIOS Version 2.0:1506 1507 The drive parameter table seems to start at 0x1f30.1508 The first byte's purpose is not known.1509 Next is the cylinder, head, and sector information.1510 The last 4 bytes appear to be the drive's size in sectors.1511 The other bytes in the drive parameter table are unknown.1512 If anyone figures them out, please send me mail, and I will1513 update these notes.1514
1515 Tape drives do not get placed in this table.1516
1517 There is another table at 0x1fea:1518 If the byte is 0x01, then the SCSI ID is not in use.1519 If the byte is 0x18 or 0x48, then the SCSI ID is in use,1520 although tapes don't seem to be in this table. I haven't1521 seen any other numbers (in a limited sample).1522
1523 0x1f2d is a drive count (i.e., not including tapes)1524
1525 The table at 0x1fcc are I/O ports addresses for the various1526 operations. I calculate these by hand in this driver code.1527
1528 For BIOS Version 3.2:1529
1530 The drive parameter table starts at 0x1f70. Each entry is1531 0x0a bytes long. Heads are one less than we need to report.1532 */1533
1534 drive = MINOR(dev) / 16;
1535
1536 if (bios_major == 2) {1537 i = (structdrive_info *)( (char *)bios_base + 0x1f31 + drive * 25 );
1538 info_array[0] = i->heads;
1539 info_array[1] = i->sectors;
1540 info_array[2] = i->cylinders;
1541 }elseif (bios_major == 3 && bios_minor < 4) {/* 3.0 and 3.2 BIOS */1542 i = (structdrive_info *)( (char *)bios_base + 0x1f71 + drive * 10 );
1543 info_array[0] = i->heads + 1;
1544 info_array[1] = i->sectors;
1545 info_array[2] = i->cylinders;
1546 }else{/* 3.4 BIOS (and up?) */1547 /* This algorithm was provided by Future Domain (much thanks!). */1548
1549 sizes[0] = 0; /* zero bytes out */1550 sizes[1] = 512; /* one sector in */1551 memcpy( data, do_read, sizeof( do_read ) );
1552 retcode = kernel_scsi_ioctl( disk->device,
1553 SCSI_IOCTL_SEND_COMMAND,
1554 (void *)buf );
1555 if (!retcode/* SCSI command ok */1556 && data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */1557 && data[0x1c2]) {/* Partition type */1558
1559 /* The partition table layout is as follows:1560
1561 Start: 0x1b3h1562 Offset: 0 = partition status1563 1 = starting head1564 2 = starting sector and cylinder (word, encoded)1565 4 = partition type1566 5 = ending head1567 6 = ending sector and cylinder (word, encoded)1568 8 = starting absolute sector (double word)1569 c = number of sectors (double word)1570 Signature: 0x1fe = 0x55aa1571
1572 So, this algorithm assumes:1573 1) the first partition table is in use,1574 2) the data in the first entry is correct, and1575 3) partitions never divide cylinders1576
1577 Note that (1) may be FALSE for NetBSD (and other BSD flavors),1578 as well as for Linux. Note also, that Linux doesn't pay any1579 attention to the fields that are used by this algorithm -- it1580 only uses the absolute sector data. Recent versions of Linux's1581 fdisk(1) will fill this data in correctly, and forthcoming1582 versions will check for consistency.1583
1584 Checking for a non-zero partition type is not part of the1585 Future Domain algorithm, but it seemed to be a reasonable thing1586 to do, especially in the Linux and BSD worlds. */1587
1588 info_array[0] = data[0x1c3] + 1; /* heads */1589 info_array[1] = data[0x1c4] & 0x3f; /* sectors */1590 }else{1591
1592 /* Note that this new method guarantees that there will always be1593 less than 1024 cylinders on a platter. This is good for drives1594 up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */1595
1596 if ((unsignedint)size >= 0x7e0000U) {1597 info_array[0] = 0xff; /* heads = 255 */1598 info_array[1] = 0x3f; /* sectors = 63 */1599 }elseif ((unsignedint)size >= 0x200000U) {1600 info_array[0] = 0x80; /* heads = 128 */1601 info_array[1] = 0x3f; /* sectors = 63 */1602 }else{1603 info_array[0] = 0x40; /* heads = 64 */1604 info_array[1] = 0x20; /* sectors = 32 */1605 }1606 }1607 /* For both methods, compute the cylinders */1608 info_array[2] = (unsignedint)size / (info_array[0] * info_array[1] );
1609 }1610
1611 return 0;
1612 }