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