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 4 20:44:47 1996 by r.faith@ieee.org 4 * Author: Rickard E. Faith, faith@cs.unc.edu 5 * Copyright 1992, 1993, 1994, 1995, 1996 Rickard E. Faith 6 * 7 * $Id: fdomain.c,v 5.41 1996/04/05 04:22:25 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 SUMMARY: 26
27 Future Domain BIOS versions supported for autodetect: 28 2.0, 3.0, 3.2, 3.4 (1.0), 3.5 (2.0), 3.6, 3.61 29 Chips are supported: 30 TMC-1800, TMC-18C50, TMC-18C30, TMC-36C70 31 Boards supported: 32 Future Domain TMC-1650, TMC-1660, TMC-1670, TMC-1680, TMC-1610M/MER/MEX 33 Future Domain TMC-3260 (PCI) 34 Quantum ISA-200S, ISA-250MG 35 Adaptec AHA-2920 (PCI) 36 IBM ? 37 LILO command-line options: 38 fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>] 39
40
41
42 DESCRIPTION: 43 44 This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680 45 TMC-1650/1670, and TMC-3260 SCSI host adapters. The 1650 and 1670 have a 46 25-pin external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin 47 high-density external connector. The 1670 and 1680 have floppy disk 48 controllers built in. The TMC-3260 is a PCI bus card. 49
50 Future Domain's older boards are based on the TMC-1800 chip, and this 51 driver was originally written for a TMC-1680 board with the TMC-1800 chip. 52 More recently, boards are being produced with the TMC-18C50 and TMC-18C30 53 chips. The latest and greatest board may not work with this driver. If 54 you have to patch this driver so that it will recognize your board's BIOS 55 signature, then the driver may fail to function after the board is 56 detected. 57
58 Please note that the drive ordering that Future Domain implemented in BIOS 59 versions 3.4 and 3.5 is the opposite of the order (currently) used by the 60 rest of the SCSI industry. If you have BIOS version 3.4 or 3.5, and have 61 more then one drive, then the drive ordering will be the reverse of that 62 which you see under DOS. For example, under DOS SCSI ID 0 will be D: and 63 SCSI ID 1 will be C: (the boot device). Under Linux, SCSI ID 0 will be 64 /dev/sda and SCSI ID 1 will be /dev/sdb. The Linux ordering is consistent 65 with that provided by all the other SCSI drivers for Linux. If you want 66 this changed, you will probably have to patch the higher level SCSI code. 67 If you do so, please send me patches that are protected by #ifdefs. 68
69 If you have a TMC-8xx or TMC-9xx board, then this is not the driver for 70 your board. Please refer to the Seagate driver for more information and 71 possible support. 72
73
74 75 HISTORY: 76
77 Linux Driver Driver 78 Version Version Date Support/Notes 79
80 0.0 3 May 1992 V2.0 BIOS; 1800 chip 81 0.97 1.9 28 Jul 1992 82 0.98.6 3.1 27 Nov 1992 83 0.99 3.2 9 Dec 1992 84
85 0.99.3 3.3 10 Jan 1993 V3.0 BIOS 86 0.99.5 3.5 18 Feb 1993 87 0.99.10 3.6 15 May 1993 V3.2 BIOS; 18C50 chip 88 0.99.11 3.17 3 Jul 1993 (now under RCS) 89 0.99.12 3.18 13 Aug 1993 90 0.99.14 5.6 31 Oct 1993 (reselection code removed) 91
92 0.99.15 5.9 23 Jan 1994 V3.4 BIOS (preliminary) 93 1.0.8/1.1.1 5.15 1 Apr 1994 V3.4 BIOS; 18C30 chip (preliminary) 94 1.0.9/1.1.3 5.16 7 Apr 1994 V3.4 BIOS; 18C30 chip 95 1.1.38 5.18 30 Jul 1994 36C70 chip (PCI version of 18C30) 96 1.1.62 5.20 2 Nov 1994 V3.5 BIOS 97 1.1.73 5.22 7 Dec 1994 Quantum ISA-200S board; V2.0 BIOS 98
99 1.1.82 5.26 14 Jan 1995 V3.5 BIOS; TMC-1610M/MER/MEX board 100 1.2.10 5.28 5 Jun 1995 Quantum ISA-250MG board; V2.0, V2.01 BIOS 101 1.3.4 5.31 23 Jun 1995 PCI BIOS-32 detection (preliminary) 102 1.3.7 5.33 4 Jul 1995 PCI BIOS-32 detection 103 1.3.28 5.36 17 Sep 1995 V3.61 BIOS; LILO command-line support 104 1.3.34 5.39 12 Oct 1995 V3.60 BIOS; /proc 105 1.3.72 5.39 8 Feb 1996 Adaptec AHA-2920 board 106 1.3.85 5.41 4 Apr 1996 107
108 109
110 REFERENCES USED: 111
112 "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation, 113 1990. 114
115 "Technical Reference Manual: 18C50 SCSI Host Adapter Chip", Future Domain 116 Corporation, January 1992. 117
118 "LXT SCSI Products: Specifications and OEM Technical Manual (Revision 119 B/September 1991)", Maxtor Corporation, 1991. 120
121 "7213S product Manual (Revision P3)", Maxtor Corporation, 1992. 122
123 "Draft Proposed American National Standard: Small Computer System 124 Interface - 2 (SCSI-2)", Global Engineering Documents. (X3T9.2/86-109, 125 revision 10h, October 17, 1991) 126
127 Private communications, Drew Eckhardt (drew@cs.colorado.edu) and Eric 128 Youngdale (ericy@cais.com), 1992. 129
130 Private communication, Tuong Le (Future Domain Engineering department), 131 1994. (Disk geometry computations for Future Domain BIOS version 3.4, and 132 TMC-18C30 detection.) 133
134 Hogan, Thom. The Programmer's PC Sourcebook. Microsoft Press, 1988. Page 135 60 (2.39: Disk Partition Table Layout). 136
137 "18C30 Technical Reference Manual", Future Domain Corporation, 1993, page 138 6-1. 139
140
141 142 NOTES ON REFERENCES: 143
144 The Maxtor manuals were free. Maxtor telephone technical support is 145 great! 146
147 The Future Domain manuals were $25 and $35. They document the chip, not 148 the TMC-16x0 boards, so some information I had to guess at. In 1992, 149 Future Domain sold DOS BIOS source for $250 and the UN*X driver source was 150 $750, but these required a non-disclosure agreement, so even if I could 151 have afforded them, they would *not* have been useful for writing this 152 publically distributable driver. Future Domain technical support has 153 provided some information on the phone and have sent a few useful FAXs. 154 They have been much more helpful since they started to recognize that the 155 word "Linux" refers to an operating system :-). 156
157 158
159 ALPHA TESTERS: 160
161 There are many other alpha testers that come and go as the driver 162 develops. The people listed here were most helpful in times of greatest 163 need (mostly early on -- I've probably left out a few worthy people in 164 more recent times): 165
166 Todd Carrico (todd@wutc.wustl.edu), Dan Poirier (poirier@cs.unc.edu ), Ken 167 Corey (kenc@sol.acs.unt.edu), C. de Bruin (bruin@bruin@sterbbs.nl), Sakari 168 Aaltonen (sakaria@vipunen.hit.fi), John Rice (rice@xanth.cs.odu.edu), Brad 169 Yearwood (brad@optilink.com), and Ray Toy (toy@soho.crd.ge.com). 170
171 Special thanks to Tien-Wan Yang (twyang@cs.uh.edu), who graciously lent me 172 his 18C50-based card for debugging. He is the sole reason that this 173 driver works with the 18C50 chip. 174
175 Thanks to Dave Newman (dnewman@crl.com) for providing initial patches for 176 the version 3.4 BIOS. 177
178 Thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for providing 179 patches that support the TMC-3260, a PCI bus card with the 36C70 chip. 180 The 36C70 chip appears to be "completely compatible" with the 18C30 chip. 181
182 Thanks to Eric Kasten (tigger@petroglyph.cl.msu.edu) for providing the 183 patch for the version 3.5 BIOS. 184
185 Thanks for Stephen Henson (shenson@nyx10.cs.du.edu) for providing the 186 patch for the Quantum ISA-200S SCSI adapter. 187 188 Thanks to Adam Bowen for the signature to the 1610M/MER/MEX scsi cards, to 189 Martin Andrews (andrewm@ccfadm.eeg.ccf.org) for the signature to some 190 random TMC-1680 repackaged by IBM; and to Mintak Ng (mintak@panix.com) for 191 the version 3.61 BIOS signature. 192
193 Thanks for Mark Singer (elf@netcom.com) and Richard Simpson 194 (rsimpson@ewrcsdra.demon.co.uk) for more Quantum signatures and detective 195 work on the Quantum RAM layout. 196
197 Special thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for 198 providing patches for proper PCI BIOS32-mediated detection of the TMC-3260 199 card (a PCI bus card with the 36C70 chip). Please send James PCI-related 200 bug reports. 201
202 Thanks to Tom Cavin (tec@usa1.com) for preliminary command-line option 203 patches. 204 205 All of the alpha testers deserve much thanks. 206
207
208
209 NOTES ON USER DEFINABLE OPTIONS: 210
211 DEBUG: This turns on the printing of various debug information. 212
213 ENABLE_PARITY: This turns on SCSI parity checking. With the current 214 driver, all attached devices must support SCSI parity. If none of your 215 devices support parity, then you can probably get the driver to work by 216 turning this option off. I have no way of testing this, however, and it 217 would appear that no one ever uses this option. 218
219 FIFO_COUNT: The host adapter has an 8K cache (host adapters based on the 220 18C30 chip have a 2k cache). When this many 512 byte blocks are filled by 221 the SCSI device, an interrupt will be raised. Therefore, this could be as 222 low as 0, or as high as 16. Note, however, that values which are too high 223 or too low seem to prevent any interrupts from occurring, and thereby lock 224 up the machine. I have found that 2 is a good number, but throughput may 225 be increased by changing this value to values which are close to 2. 226 Please let me know if you try any different values. 227
228 DO_DETECT: This activates some old scan code which was needed before the 229 high level drivers got fixed. If you are having trouble with the driver, 230 turning this on should not hurt, and might help. Please let me know if 231 this is the case, since this code will be removed from future drivers. 232
233 RESELECTION: This is no longer an option, since I gave up trying to 234 implement it in version 4.x of this driver. It did not improve 235 performance at all and made the driver unstable (because I never found one 236 of the two race conditions which were introduced by the multiple 237 outstanding command code). The instability seems a very high price to pay 238 just so that you don't have to wait for the tape to rewind. If you want 239 this feature implemented, send me patches. I'll be happy to send a copy 240 of my (broken) driver to anyone who would like to see a copy. 241
242 **************************************************************************/ 243
244 #ifdefPCMCIA 245 #defineMODULE 246 #endif 247
248 #ifdefMODULE 249 #include <linux/module.h>
250 #endif 251
252 #ifdefPCMCIA 253 #undefMODULE 254 #endif 255
256 #include <linux/sched.h>
257 #include <asm/io.h>
258 #include <linux/blk.h>
259 #include "scsi.h"
260 #include "hosts.h"
261 #include "fdomain.h"
262 #include <asm/system.h>
263 #include <linux/errno.h>
264 #include <linux/string.h>
265 #include <linux/ioport.h>
266 #include <linux/proc_fs.h>
267 #include <linux/bios32.h>
268 #include <linux/pci.h>
269 #include <linux/stat.h>
270
271 #include <linux/config.h> /* for CONFIG_PCI */ 272
273 structproc_dir_entryproc_scsi_fdomain = { 274 PROC_SCSI_FDOMAIN, 7, "fdomain",
275 S_IFDIR | S_IRUGO | S_IXUGO, 2
276 };
277
278 #defineVERSION "$Revision: 5.41 $"
279
280 /* START OF USER DEFINABLE OPTIONS */ 281
282 #defineDEBUG 1 /* Enable debugging output */ 283 #defineENABLE_PARITY 1 /* Enable SCSI Parity */ 284 #defineFIFO_COUNT 2 /* Number of 512 byte blocks before INTR */ 285 #defineDO_DETECT 0 /* Do device detection here (see scsi.c) */ 286
287 /* END OF USER DEFINABLE OPTIONS */ 288
289 #ifDEBUG 290 #defineEVERY_ACCESS 0 /* Write a line on every scsi access */ 291 #defineERRORS_ONLY 1 /* Only write a line if there is an error */ 292 #defineDEBUG_DETECT 0 /* Debug fdomain_16x0_detect() */ 293 #defineDEBUG_MESSAGES 1 /* Debug MESSAGE IN phase */ 294 #defineDEBUG_ABORT 1 /* Debug abort() routine */ 295 #defineDEBUG_RESET 1 /* Debug reset() routine */ 296 #defineDEBUG_RACE 1 /* Debug interrupt-driven race condition */ 297 #else 298 #defineEVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */ 299 #defineERRORS_ONLY 0
300 #defineDEBUG_DETECT 0
301 #defineDEBUG_MESSAGES 0
302 #defineDEBUG_ABORT 0
303 #defineDEBUG_RESET 0
304 #defineDEBUG_RACE 0
305 #endif 306
307 /* Errors are reported on the line, so we don't need to report them again */ 308 #ifEVERY_ACCESS 309 #undefERRORS_ONLY 310 #defineERRORS_ONLY 0
311 #endif 312
313 #ifENABLE_PARITY 314 #definePARITY_MASK 0x08
315 #else 316 #definePARITY_MASK 0x00
317 #endif 318
319 enumchip_type{ 320 unknown = 0x00,
321 tmc1800 = 0x01,
322 tmc18c50 = 0x02,
323 tmc18c30 = 0x03,
324 };
325
326 enum{ 327 in_arbitration = 0x02,
328 in_selection = 0x04,
329 in_other = 0x08,
330 disconnect = 0x10,
331 aborted = 0x20,
332 sent_ident = 0x40,
333 };
334
335 enum in_port_type { 336 Read_SCSI_Data = 0,
337 SCSI_Status = 1,
338 TMC_Status = 2,
339 FIFO_Status = 3, /* tmc18c50/tmc18c30 only */ 340 Interrupt_Cond = 4, /* tmc18c50/tmc18c30 only */ 341 LSB_ID_Code = 5,
342 MSB_ID_Code = 6,
343 Read_Loopback = 7,
344 SCSI_Data_NoACK = 8,
345 Interrupt_Status = 9,
346 Configuration1 = 10,
347 Configuration2 = 11, /* tmc18c50/tmc18c30 only */ 348 Read_FIFO = 12,
349 FIFO_Data_Count = 14
350 };
351
352 enum out_port_type { 353 Write_SCSI_Data = 0,
354 SCSI_Cntl = 1,
355 Interrupt_Cntl = 2,
356 SCSI_Mode_Cntl = 3,
357 TMC_Cntl = 4,
358 Memory_Cntl = 5, /* tmc18c50/tmc18c30 only */ 359 Write_Loopback = 7,
360 IO_Control = 11, /* tmc18c30 only */ 361 Write_FIFO = 12
362 };
363
364 staticintport_base = 0;
365 staticvoid *bios_base = NULL;
366 staticintbios_major = 0;
367 staticintbios_minor = 0;
368 staticintPCI_bus = 0;
369 staticintQuantum = 0; /* Quantum board variant */ 370 staticintinterrupt_level = 0;
371 staticvolatileintin_command = 0;
372 staticScsi_Cmnd *current_SC = NULL;
373 staticenumchip_typechip = unknown;
374 staticintadapter_mask = 0;
375 staticintthis_id = 0;
376 staticintsetup_called = 0;
377
378 #ifDEBUG_RACE 379 staticvolatileintin_interrupt_flag = 0;
380 #endif 381
382 staticintSCSI_Mode_Cntl_port;
383 staticintFIFO_Data_Count_port;
384 staticintInterrupt_Cntl_port;
385 staticintInterrupt_Status_port;
386 staticintRead_FIFO_port;
387 staticintRead_SCSI_Data_port;
388 staticintSCSI_Cntl_port;
389 staticintSCSI_Data_NoACK_port;
390 staticintSCSI_Status_port;
391 staticintTMC_Cntl_port;
392 staticintTMC_Status_port;
393 staticintWrite_FIFO_port;
394 staticintWrite_SCSI_Data_port;
395
396 staticintFIFO_Size = 0x2000; /* 8k FIFO for 397 pre-tmc18c30 chips */ 398
399 externvoidfdomain_16x0_intr( intirq, void *dev_id, structpt_regs * regs );
400
401 staticvoid *addresses[] = { 402 (void *)0xc8000,
403 (void *)0xca000,
404 (void *)0xce000,
405 (void *)0xde000,
406 (void *)0xcc000, /* Extra addresses for PCI boards */ 407 (void *)0xd0000,
408 (void *)0xe0000,
409 };
410 #defineADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
411
412 staticunsignedshortports[] = { 0x140, 0x150, 0x160, 0x170 };
413 #definePORT_COUNT (sizeof( ports ) / sizeof( unsignedshort ))
414
415 staticunsignedshortints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
416
417 /* 418
419 READ THIS BEFORE YOU ADD A SIGNATURE! 420
421 READING THIS SHORT NOTE CAN SAVE YOU LOTS OF TIME! 422
423 READ EVERY WORD, ESPECIALLY THE WORD *NOT* 424
425 This driver works *ONLY* for Future Domain cards using the TMC-1800, 426 TMC-18C50, or TMC-18C30 chip. This includes models TMC-1650, 1660, 1670, 427 and 1680. 428
429 The following BIOS signature signatures are for boards which do *NOT* 430 work with this driver (these TMC-8xx and TMC-9xx boards may work with the 431 Seagate driver): 432
433 FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88 434 FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89 435 FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89 436 FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90 437 FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90 438 FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90 439 FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92 440
441 */ 442
443 structsignature{ 444 constchar *signature;
445 intsig_offset;
446 intsig_length;
447 intmajor_bios_version;
448 intminor_bios_version;
449 intflag; /* 1 == PCI_bus, 2 == ISA_200S, 3 == ISA_250MG, 4 == ISA_200S */ 450 }signatures[] = { 451 /* 1 2 3 4 5 6 */ 452 /* 123456789012345678901234567890123456789012345678901234567890 */ 453 { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 5, 50, 2, 0, 0 },
454 { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89", 5, 50, 2, 0, 0 },
455 { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50, 2, 0, 2 },
456 { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0", 73, 43, 2, 0, 3 },
457 { "FUTURE DOMAIN CORP. (C) 1991 1800-V2.0.", 72, 39, 2, 0, 4 },
458 { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92", 5, 44, 3, 0, 0 },
459 { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93", 5, 44, 3, 2, 0 },
460 { "IBM F1 P2 BIOS v1.0104/29/93", 5, 28, 3, -1, 0 },
461 { "Future Domain Corp. V1.0008/18/93", 5, 33, 3, 4, 0 },
462 { "Future Domain Corp. V1.0008/18/93", 26, 33, 3, 4, 1 },
463 { "Adaptec AHA-2920 PCI-SCSI Card", 42, 31, 3, 0, 1 },
464 /* This next signature may not be a 3.5 bios */ 465 { "Future Domain Corp. V2.0108/18/93", 5, 33, 3, 5, 0 },
466 { "FUTURE DOMAIN CORP. V3.5008/18/93", 5, 34, 3, 5, 0 },
467 { "FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5", 5, 44, 3, 5, 0 },
468 { "FUTURE DOMAIN CORP. V3.6008/18/93", 5, 34, 3, 6, 0 },
469 { "FUTURE DOMAIN CORP. V3.6108/18/93", 5, 34, 3, 6, 0 },
470 { "FUTURE DOMAIN TMC-18XX", 5, 22, -1, -1, 0 },
471
472 /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGNATURE 473 Also, fix the disk geometry code for your signature and send your 474 changes for faith@cs.unc.edu. Above all, do *NOT* change any old 475 signatures! 476
477 Note that the last line will match a "generic" 18XX bios. Because 478 Future Domain has changed the host SCSI ID and/or the location of the 479 geometry information in the on-board RAM area for each of the first 480 three BIOS's, it is still important to enter a fully qualified 481 signature in the table for any new BIOS's (after the host SCSI ID and 482 geometry location are verified). */ 483 };
484
485 #defineSIGNATURE_COUNT (sizeof( signatures ) / sizeof( structsignature ))
486
487 staticvoidprint_banner( structScsi_Host *shpnt )
488 { 489 if (!shpnt) return; /* This won't ever happen */ 490
491 if (bios_major < 0 && bios_minor < 0) { 492 printk( "scsi%d <fdomain>: No BIOS; using scsi id %d\n",
493 shpnt->host_no, shpnt->this_id );
494 }else{ 495 printk( "scsi%d <fdomain>: BIOS version ", shpnt->host_no );
496
497 if (bios_major >= 0) printk( "%d.", bios_major );
498 elseprintk( "?." );
499
500 if (bios_minor >= 0) printk( "%d", bios_minor );
501 elseprintk( "?." );
502
503 printk( " at 0x%x using scsi id %d\n",
504 (unsigned)bios_base, shpnt->this_id );
505 } 506
507 /* If this driver works for later FD PCI 508 boards, we will have to modify banner 509 for additional PCI cards, but for now if 510 it's PCI it's a TMC-3260 - JTM */ 511 printk( "scsi%d <fdomain>: %s chip at 0x%x irq ",
512 shpnt->host_no,
513 chip == tmc1800 ? "TMC-1800"
514 : (chip == tmc18c50 ? "TMC-18C50"
515 : (chip == tmc18c30 ?
516 (PCI_bus ? "TMC-36C70 (PCI bus)" : "TMC-18C30")
517 : "Unknown")),
518 port_base );
519
520 if (interrupt_level) printk( "%d", interrupt_level );
521 elseprintk( "<none>" );
522
523 printk( "\n" );
524 } 525
526 voidfdomain_setup( char *str, int *ints )
/* */ 527 { 528 if (setup_called++ || ints[0] < 2 || ints[0] > 3) { 529 printk( "fdomain: usage: fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]\n" );
530 printk( "fdomain: bad LILO parameters?\n" );
531 } 532
533 port_base = ints[0] >= 1 ? ints[1] : 0;
534 interrupt_level = ints[0] >= 2 ? ints[2] : 0;
535 this_id = ints[0] >= 3 ? ints[3] : 0;
536
537 bios_major = bios_minor = -1; /* Use geometry for BIOS version >= 3.4 */ 538 } 539
540
541 staticvoiddo_pause( unsignedamount ) /* Pause for amount*10 milliseconds *//* */ 542 { 543 unsignedlongthe_time = jiffies + amount; /* 0.01 seconds per jiffy */ 544
545 while (jiffies < the_time);
546 } 547
548 inlinestaticvoidfdomain_make_bus_idle( void )
/* */ 549 { 550 outb( 0, SCSI_Cntl_port );
551 outb( 0, SCSI_Mode_Cntl_port );
552 if (chip == tmc18c50 || chip == tmc18c30)
553 outb( 0x21 | PARITY_MASK, TMC_Cntl_port ); /* Clear forced intr. */ 554 else 555 outb( 0x01 | PARITY_MASK, TMC_Cntl_port );
556 } 557
558 staticintfdomain_is_valid_port( intport )
/* */ 559 { 560 #ifDEBUG_DETECT 561 printk( " (%x%x),",
562 inb( port + MSB_ID_Code ), inb( port + LSB_ID_Code ) );
563 #endif 564
565 /* The MCA ID is a unique id for each MCA compatible board. We 566 are using ISA boards, but Future Domain provides the MCA ID 567 anyway. We can use this ID to ensure that this is a Future 568 Domain TMC-1660/TMC-1680. 569 */ 570
571 if (inb( port + LSB_ID_Code ) != 0xe9) {/* test for 0x6127 id */ 572 if (inb( port + LSB_ID_Code ) != 0x27) return 0;
573 if (inb( port + MSB_ID_Code ) != 0x61) return 0;
574 chip = tmc1800;
575 }else{/* test for 0xe960 id */ 576 if (inb( port + MSB_ID_Code ) != 0x60) return 0;
577 chip = tmc18c50;
578
579 #if 0
580
581 /* Try to toggle 32-bit mode. This only 582 works on an 18c30 chip. (User reports 583 say that this doesn't work at all, so 584 we'll use the other method.) */ 585
586 outb( 0x80, port + IO_Control );
587 if ((inb( port + Configuration2 ) & 0x80) == 0x80) { 588 outb( 0x00, port + IO_Control );
589 if ((inb( port + Configuration2 ) & 0x80) == 0x00) { 590 chip = tmc18c30;
591 FIFO_Size = 0x800; /* 2k FIFO */ 592 } 593 } 594 #else 595
596 /* That should have worked, but appears to 597 have problems. Lets assume it is an 598 18c30 if the RAM is disabled. */ 599
600 if (inb( port + Configuration2 ) & 0x02) { 601 chip = tmc18c30;
602 FIFO_Size = 0x800; /* 2k FIFO */ 603 } 604 #endif 605 /* If that failed, we are an 18c50. */ 606 } 607
608 return 1;
609 } 610
611 staticintfdomain_test_loopback( void )
/* */ 612 { 613 inti;
614 intresult;
615
616 for (i = 0; i < 255; i++) { 617 outb( i, port_base + Write_Loopback );
618 result = inb( port_base + Read_Loopback );
619 if (i != result)
620 return 1;
621 } 622 return 0;
623 } 624
625 /* fdomain_get_irq assumes that we have a valid MCA ID for a 626 TMC-1660/TMC-1680 Future Domain board. Now, check to be sure the 627 bios_base matches these ports. If someone was unlucky enough to have 628 purchased more than one Future Domain board, then they will have to 629 modify this code, as we only detect one board here. [The one with the 630 lowest bios_base.] 631
632 Note that this routine is only used for systems without a PCI BIOS32 633 (e.g., ISA bus). For PCI bus systems, this routine will likely fail 634 unless one of the IRQs listed in the ints array is used by the board. 635 Sometimes it is possible to use the computer's BIOS setup screen to 636 configure a PCI system so that one of these IRQs will be used by the 637 Future Domain card. */ 638
639 staticintfdomain_get_irq( intbase )
/* */ 640 { 641 intoptions = inb( base + Configuration1 );
642
643 #ifDEBUG_DETECT 644 printk( " Options = %x\n", options );
645 #endif 646
647 /* Check for board with lowest bios_base -- 648 this isn't valid for the 18c30 or for 649 boards on the PCI bus, so just assume we 650 have the right board. */ 651
652 if (chip != tmc18c30 653 && !PCI_bus 654 && addresses[ (options & 0xc0) >> 6 ] != bios_base) return 0;
655
656 returnints[ (options & 0x0e) >> 1 ];
657 } 658
659 staticintfdomain_isa_detect( int *irq, int *iobase )
/* */ 660 { 661 inti;
662 intbase;
663 intflag = 0;
664
665 if (bios_major == 2) { 666 /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM. 667 Assuming the ROM is enabled (otherwise we wouldn't have been 668 able to read the ROM signature :-), then the ROM sets up the 669 RAM area with some magic numbers, such as a list of port 670 base addresses and a list of the disk "geometry" reported to 671 DOS (this geometry has nothing to do with physical geometry). 672 */ 673
674 switch (Quantum) { 675 case 2: /* ISA_200S */ 676 case 3: /* ISA_250MG */ 677 base = *((char *)bios_base + 0x1fa2)
678 + (*((char *)bios_base + 0x1fa3) << 8);
679 break;
680 case 4: /* ISA_200S (another one) */ 681 base = *((char *)bios_base + 0x1fa3)
682 + (*((char *)bios_base + 0x1fa4) << 8);
683 break;
684 default:
685 base = *((char *)bios_base + 0x1fcc)
686 + (*((char *)bios_base + 0x1fcd) << 8);
687 break;
688 } 689
690 #ifDEBUG_DETECT 691 printk( " %x,", base );
692 #endif 693
694 for (flag = 0, i = 0; !flag && i < PORT_COUNT; i++) { 695 if (base == ports[i])
696 ++flag;
697 } 698
699 if (flag && fdomain_is_valid_port( base )) { 700 *irq = fdomain_get_irq( base );
701 *iobase = base;
702 return 1;
703 } 704
705 /* This is a bad sign. It usually means that someone patched the 706 BIOS signature list (the signatures variable) to contain a BIOS 707 signature for a board *OTHER THAN* the TMC-1660/TMC-1680. */ 708
709 #ifDEBUG_DETECT 710 printk( " RAM FAILED, " );
711 #endif 712 } 713
714 /* Anyway, the alternative to finding the address in the RAM is to just 715 search through every possible port address for one that is attached 716 to the Future Domain card. Don't panic, though, about reading all 717 these random port addresses -- there are rumors that the Future 718 Domain BIOS does something very similar. 719
720 Do not, however, check ports which the kernel knows are being used by 721 another driver. */ 722
723 for (i = 0; i < PORT_COUNT; i++) { 724 base = ports[i];
725 if (check_region( base, 0x10 )) { 726 #ifDEBUG_DETECT 727 printk( " (%x inuse),", base );
728 #endif 729 continue;
730 } 731 #ifDEBUG_DETECT 732 printk( " %x,", base );
733 #endif 734 if ((flag = fdomain_is_valid_port( base ))) break;
735 } 736
737 if (!flag) return 0; /* iobase not found */ 738
739 *irq = fdomain_get_irq( base );
740 *iobase = base;
741
742 return 1; /* success */ 743 } 744
745 staticintfdomain_pci_nobios_detect( int *irq, int *iobase )
/* */ 746 { 747 inti;
748 intflag = 0;
749
750 /* The proper way of doing this is to use ask the PCI bus for the device 751 IRQ and interrupt level. But we can't do that if PCI BIOS32 support 752 isn't compiled into the kernel, or if a PCI BIOS32 isn't present. 753
754 Instead, we scan down a bunch of addresses (Future Domain tech 755 support says we will probably find the address before we get to 756 0xf800). This works fine on some systems -- other systems may have 757 to scan more addresses. If you have to modify this section for your 758 installation, please send mail to faith@cs.unc.edu. */ 759
760 for (i = 0xfff8; i > 0xe000; i -= 8) { 761 if (check_region( i, 0x10 )) { 762 #ifDEBUG_DETECT 763 printk( " (%x inuse)," , i );
764 #endif 765 continue;
766 } 767 if ((flag = fdomain_is_valid_port( i ))) break;
768 } 769
770 if (!flag) return 0; /* iobase not found */ 771
772 *irq = fdomain_get_irq( i );
773 *iobase = i;
774
775 return 1; /* success */ 776 } 777
778 /* PCI detection function: int fdomain_pci_bios_detect(int* irq, int* 779 iobase) This function gets the Interrupt Level and I/O base address from 780 the PCI configuration registers. The I/O base address is masked with 781 0xfff8 since on my card the address read from the PCI config registers 782 is off by one from the actual I/O base address necessary for accessing 783 the status and control registers on the card (PCI config register gives 784 0xf801, actual address is 0xf800). This is likely a bug in the FD 785 config code that writes to the PCI registers, however using a mask 786 should be safe since I think the scan done by the card to determine the 787 I/O base is done in increments of 8 (i.e., 0xf800, 0xf808, ...), at 788 least the old scan code we used to use to get the I/O base did... Also, 789 the device ID from the PCI config registers is 0x0 and should be 0x60e9 790 as it is in the status registers (offset 5 from I/O base). If this is 791 changed in future hardware/BIOS changes it will need to be fixed in this 792 detection function. Comments, bug reports, etc... on this function 793 should be sent to mckinley@msupa.pa.msu.edu - James T. McKinley. */ 794
795 #ifdefCONFIG_PCI 796 staticintfdomain_pci_bios_detect( int *irq, int *iobase )
/* */ 797 { 798 interror;
799 unsignedcharpci_bus, pci_dev_fn; /* PCI bus & device function */ 800 unsignedcharpci_irq; /* PCI interrupt line */ 801 unsignedintpci_base; /* PCI I/O base address */ 802 unsignedshortpci_vendor, pci_device; /* PCI vendor & device IDs */ 803
804 /* If the PCI BIOS doesn't exist, use the old-style detection routines. 805 Otherwise, get the I/O base address and interrupt from the PCI config 806 registers. */ 807
808 if (!pcibios_present()) returnfdomain_pci_nobios_detect( irq, iobase );
809
810 #ifDEBUG_DETECT 811 /* Tell how to print a list of the known PCI devices from bios32 and 812 list vendor and device IDs being used if in debug mode. */ 813
814 printk( "\nINFO: cat /proc/pci to see list of PCI devices from bios32\n" );
815 printk( "\nTMC-3260 detect:"
816 " Using PCI Vendor ID: 0x%x, PCI Device ID: 0x%x\n",
817 PCI_VENDOR_ID_FD,
818 PCI_DEVICE_ID_FD_36C70 );
819 #endif 820
821 /* We will have to change this if more than 1 PCI bus is present and the 822 FD scsi host is not on the first bus (i.e., a PCI to PCI bridge, 823 which is not supported by bios32 right now anyway). This should 824 probably be done by a call to pcibios_find_device but I can't get it 825 to work... Also the device ID reported from the PCI config registers 826 does not match the device ID quoted in the tech manual or available 827 from offset 5 from the I/O base address. It should be 0x60E9, but it 828 is 0x0 if read from the PCI config registers. I guess the FD folks 829 neglected to write it to the PCI registers... This loop is necessary 830 to get the device function (at least until someone can get 831 pcibios_find_device to work, I cannot but 53c7,8xx.c uses it...). */ 832
833 pci_bus = 0;
834
835 for (pci_dev_fn = 0x0; pci_dev_fn < 0xff; pci_dev_fn++) { 836 pcibios_read_config_word( pci_bus,
837 pci_dev_fn,
838 PCI_VENDOR_ID,
839 &pci_vendor );
840
841 if (pci_vendor == PCI_VENDOR_ID_FD) { 842 pcibios_read_config_word( pci_bus,
843 pci_dev_fn,
844 PCI_DEVICE_ID,
845 &pci_device );
846
847 if (pci_device == PCI_DEVICE_ID_FD_36C70) { 848 /* Break out once we have the correct device. If other FD 849 PCI devices are added to this driver we will need to add 850 an or of the other PCI_DEVICE_ID_FD_XXXXX's here. */ 851 break;
852 }else{ 853 /* If we can't find an FD scsi card we give up. */ 854 return 0;
855 } 856 } 857 } 858
859 #ifDEBUG_DETECT 860 printk( "Future Domain 36C70 : at PCI bus %u, device %u, function %u\n",
861 pci_bus,
862 (pci_dev_fn & 0xf8) >> 3,
863 pci_dev_fn & 7 );
864 #endif 865
866 /* We now have the appropriate device function for the FD board so we 867 just read the PCI config info from the registers. */ 868
869 if ((error = pcibios_read_config_dword( pci_bus,
870 pci_dev_fn,
871 PCI_BASE_ADDRESS_0,
872 &pci_base ))
873 || (error = pcibios_read_config_byte( pci_bus,
874 pci_dev_fn,
875 PCI_INTERRUPT_LINE,
876 &pci_irq ))) { 877 printk ( "PCI ERROR: Future Domain 36C70 not initializing"
878 " due to error reading configuration space\n" );
879 return 0;
880 }else{ 881 #ifDEBUG_DETECT 882 printk( "TMC-3260 PCI: IRQ = %u, I/O base = 0x%lx\n",
883 pci_irq, pci_base );
884 #endif 885
886 /* Now we have the I/O base address and interrupt from the PCI 887 configuration registers. Unfortunately it seems that the I/O base 888 address is off by one on my card so I mask it with 0xfff8. This 889 must be some kind of goof in the FD code that does the autoconfig 890 and writes to the PCI registers (or maybe I just don't understand 891 something). If they fix it in later versions of the card or BIOS 892 we may have to adjust the address based on the signature or 893 something... */ 894
895 *irq = pci_irq;
896 *iobase = (pci_base & 0xfff8);
897
898 #ifDEBUG_DETECT 899 printk( "TMC-3260 fix: Masking I/O base address with 0xff00.\n" );
900 printk( "TMC-3260: IRQ = %d, I/O base = 0x%x\n", *irq, *iobase );
901 #endif 902
903 if (!fdomain_is_valid_port( *iobase )) return 0;
904 return 1;
905 } 906 return 0;
907 } 908 #endif 909
910 intfdomain_16x0_detect( Scsi_Host_Template *tpnt )
/* */ 911 { 912 inti, j;
913 intretcode;
914 structScsi_Host *shpnt;
915 #ifDO_DETECT 916 constintbuflen = 255;
917 Scsi_CmndSCinit;
918 unsignedchardo_inquiry[] = {INQUIRY, 0, 0, 0, buflen, 0 };
919 unsignedchardo_request_sense[] = {REQUEST_SENSE, 0, 0, 0, buflen, 0 };
920 unsignedchardo_read_capacity[] = {READ_CAPACITY,
921 0, 0, 0, 0, 0, 0, 0, 0, 0 };
922 unsignedcharbuf[buflen];
923 #endif 924
925 #ifDEBUG_DETECT 926 printk( "fdomain_16x0_detect()," );
927 #endif 928 tpnt->proc_dir = &proc_scsi_fdomain;
929
930 if (setup_called) { 931 #ifDEBUG_DETECT 932 printk( "no BIOS, using port_base = 0x%x, irq = %d\n",
933 port_base, interrupt_level );
934 #endif 935 if (!fdomain_is_valid_port( port_base )) { 936 printk( "fdomain: cannot locate chip at port base 0x%x\n",
937 port_base );
938 printk( "fdomain: bad LILO parameters?\n" );
939 return 0;
940 } 941 }else{ 942 intflag = 0;
943
944 for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) { 945 #ifDEBUG_DETECT 946 printk( " %x(%x),", (unsigned)addresses[i], (unsigned)bios_base );
947 #endif 948 for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) { 949 if (!memcmp( ((char *)addresses[i] + signatures[j].sig_offset),
950 signatures[j].signature, signatures[j].sig_length )) { 951 bios_major = signatures[j].major_bios_version;
952 bios_minor = signatures[j].minor_bios_version;
953 PCI_bus = (signatures[j].flag == 1);
954 Quantum = (signatures[j].flag > 1) ? signatures[j].flag : 0;
955 bios_base = addresses[i];
956 } 957 } 958 } 959
960 if (!bios_base) { 961 #ifDEBUG_DETECT 962 printk( " FAILED: NO BIOS\n" );
963 #endif 964 return 0;
965 } 966
967 if (!PCI_bus) { 968 flag = fdomain_isa_detect( &interrupt_level, &port_base );
969 }else{ 970 #ifdefCONFIG_PCI 971 flag = fdomain_pci_bios_detect( &interrupt_level, &port_base );
972 #else 973 flag = fdomain_pci_nobios_detect( &interrupt_level, &port_base );
974 #endif 975 } 976
977 if (!flag) { 978 #ifDEBUG_DETECT 979 printk( " FAILED: NO PORT\n" );
980 #endif 981 #ifdefCONFIG_PCI 982 printk( "\nTMC-3260 36C70 PCI scsi chip detection failed.\n" );
983 printk( "Send mail to mckinley@msupa.pa.msu.edu.\n" );
984 #endif 985 return 0; /* Cannot find valid set of ports */ 986 } 987 } 988
989 SCSI_Mode_Cntl_port = port_base + SCSI_Mode_Cntl;
990 FIFO_Data_Count_port = port_base + FIFO_Data_Count;
991 Interrupt_Cntl_port = port_base + Interrupt_Cntl;
992 Interrupt_Status_port = port_base + Interrupt_Status;
993 Read_FIFO_port = port_base + Read_FIFO;
994 Read_SCSI_Data_port = port_base + Read_SCSI_Data;
995 SCSI_Cntl_port = port_base + SCSI_Cntl;
996 SCSI_Data_NoACK_port = port_base + SCSI_Data_NoACK;
997 SCSI_Status_port = port_base + SCSI_Status;
998 TMC_Cntl_port = port_base + TMC_Cntl;
999 TMC_Status_port = port_base + TMC_Status;
1000 Write_FIFO_port = port_base + Write_FIFO;
1001 Write_SCSI_Data_port = port_base + Write_SCSI_Data;
1002
1003 fdomain_16x0_reset( NULL );
1004
1005 if (fdomain_test_loopback()) {1006 #ifDEBUG_DETECT1007 printk( "fdomain: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
1008 #endif1009 if (setup_called) {1010 printk( "fdomain: loopback test failed at port base 0x%x\n",
1011 port_base );
1012 printk( "fdomain: bad LILO parameters?\n" );
1013 }1014 return 0;
1015 }1016
1017 if (this_id) {1018 tpnt->this_id = (this_id & 0x07);
1019 adapter_mask = (1 << tpnt->this_id);
1020 }else{1021 if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) {1022 tpnt->this_id = 7;
1023 adapter_mask = 0x80;
1024 }else{1025 tpnt->this_id = 6;
1026 adapter_mask = 0x40;
1027 }1028 }1029
1030 /* Print out a banner here in case we can't1031 get resources. */1032
1033 shpnt = scsi_register( tpnt, 0 );
1034 shpnt->irq = interrupt_level;
1035 shpnt->io_port = port_base;
1036 shpnt->n_io_port = 0x10;
1037 print_banner( shpnt );
1038
1039 /* Log IRQ with kernel */1040 if (!interrupt_level) {1041 panic( "fdomain: *NO* interrupt level selected!\n" );
1042 }else{1043 /* Register the IRQ with the kernel */1044
1045 retcode = request_irq( interrupt_level,
1046 fdomain_16x0_intr, SA_INTERRUPT, "fdomain", NULL);
1047
1048 if (retcode < 0) {1049 if (retcode == -EINVAL) {1050 printk( "fdomain: IRQ %d is bad!\n", interrupt_level );
1051 printk( " This shouldn't happen!\n" );
1052 printk( " Send mail to faith@cs.unc.edu\n" );
1053 }elseif (retcode == -EBUSY) {1054 printk( "fdomain: IRQ %d is already in use!\n", interrupt_level );
1055 printk( " Please use another IRQ!\n" );
1056 }else{1057 printk( "fdomain: Error getting IRQ %d\n", interrupt_level );
1058 printk( " This shouldn't happen!\n" );
1059 printk( " Send mail to faith@cs.unc.edu\n" );
1060 }1061 panic( "fdomain: Driver requires interruptions\n" );
1062 }1063 }1064
1065 /* Log I/O ports with kernel */1066 request_region( port_base, 0x10, "fdomain" );
1067
1068 #ifDO_DETECT1069
1070 /* These routines are here because of the way the SCSI bus behaves after1071 a reset. This appropriate behavior was not handled correctly by the1072 higher level SCSI routines when I first wrote this driver. Now,1073 however, correct scan routines are part of scsi.c and these routines1074 are no longer needed. However, this code is still good for1075 debugging. */1076
1077 SCinit.request_buffer = SCinit.buffer = buf;
1078 SCinit.request_bufflen = SCinit.bufflen = sizeof(buf)-1;
1079 SCinit.use_sg = 0;
1080 SCinit.lun = 0;
1081
1082 printk( "fdomain: detection routine scanning for devices:\n" );
1083 for (i = 0; i < 8; i++) {1084 SCinit.target = i;
1085 if (i == tpnt->this_id) /* Skip host adapter */1086 continue;
1087 memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
1088 retcode = fdomain_16x0_command(&SCinit);
1089 if (!retcode) {1090 memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
1091 retcode = fdomain_16x0_command(&SCinit);
1092 if (!retcode) {1093 printk( " SCSI ID %d: ", i );
1094 for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
1095 printk( "%c", buf[j] >= 20 ? buf[j] : ' ' );
1096 memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
1097 retcode = fdomain_16x0_command(&SCinit);
1098 if (!retcode) {1099 unsignedlongblocks, size, capacity;
1100
1101 blocks = (buf[0] << 24) | (buf[1] << 16)
1102 | (buf[2] << 8) | buf[3];
1103 size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
1104 capacity = +( +(blocks / 1024L) * +(size * 10L)) / 1024L;
1105
1106 printk( "%lu MB (%lu byte blocks)",
1107 ((capacity + 5L) / 10L), size );
1108 }else{1109 memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
1110 retcode = fdomain_16x0_command(&SCinit);
1111 }1112 printk ("\n" );
1113 }else{1114 memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
1115 retcode = fdomain_16x0_command(&SCinit);
1116 }1117 }1118 }1119 #endif1120
1121 return 1; /* Maximum of one adapter will be detected. */1122 }1123
1124 constchar *fdomain_16x0_info( structScsi_Host *ignore )
/* */1125 {1126 staticcharbuffer[80];
1127 char *pt;
1128
1129 strcpy( buffer, "Future Domain TMC-16x0 SCSI driver, version" );
1130 if (strchr( VERSION, ':')) {/* Assume VERSION is an RCS Revision string */1131 strcat( buffer, strchr( VERSION, ':' ) + 1 );
1132 pt = strrchr( buffer, '$') - 1;
1133 if (!pt) /* Stripped RCS Revision string? */1134 pt = buffer + strlen( buffer ) - 1;
1135 if (*pt != ' ')
1136 ++pt;
1137 *pt = '\0';
1138 }else{/* Assume VERSION is a number */1139 strcat( buffer, " " VERSION );
1140 }1141
1142 returnbuffer;
1143 }1144
1145 /* First pass at /proc information routine. */1146 /*1147 * inout : decides on the direction of the dataflow and the meaning of the 1148 * variables1149 * buffer: If inout==FALSE data is being written to it else read from it1150 * *start: If inout==FALSE start of the valid data in the buffer1151 * offset: If inout==FALSE offset from the beginning of the imaginary file 1152 * from which we start writing into the buffer1153 * length: If inout==FALSE max number of bytes to be written into the buffer 1154 * else number of bytes in the buffer1155 */1156 intfdomain_16x0_proc_info( char *buffer, char **start, off_toffset,
/* */1157 intlength, inthostno, intinout )
1158 {1159 constchar *info = fdomain_16x0_info( NULL );
1160 intlen;
1161 intpos;
1162 intbegin;
1163
1164 if (inout) return(-ENOSYS);
1165
1166 begin = 0;
1167 strcpy( buffer, info );
1168 strcat( buffer, "\n" );
1169
1170 pos = len = strlen( buffer );
1171
1172 if(pos < offset) {1173 len = 0;
1174 begin = pos;
1175 }1176
1177 *start = buffer + (offset - begin); /* Start of wanted data */1178 len -= (offset - begin);
1179 if(len > length) len = length;
1180
1181 return(len);
1182 }1183
1184 #if 0
1185 staticint fdomain_arbitrate( void )
/* */1186 {1187 intstatus = 0;
1188 unsignedlongtimeout;
1189
1190 #ifEVERY_ACCESS1191 printk( "fdomain_arbitrate()\n" );
1192 #endif1193
1194 outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */1195 outb( adapter_mask, port_base + SCSI_Data_NoACK ); /* Set our id bit */1196 outb( 0x04 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */1197
1198 timeout = jiffies + 50; /* 500 mS */1199 while (jiffies < timeout) {1200 status = inb( TMC_Status_port ); /* Read adapter status */1201 if (status & 0x02) /* Arbitration complete */1202 return 0;
1203 }1204
1205 /* Make bus idle */1206 fdomain_make_bus_idle();
1207
1208 #ifEVERY_ACCESS1209 printk( "Arbitration failed, status = %x\n", status );
1210 #endif1211 #ifERRORS_ONLY1212 printk( "fdomain: Arbitration failed, status = %x\n", status );
1213 #endif1214 return 1;
1215 }1216 #endif1217
1218 staticintfdomain_select( inttarget )
/* */1219 {1220 intstatus;
1221 unsignedlongtimeout;
1222 staticintflag = 0;
1223
1224
1225 outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */1226 outb( adapter_mask | (1 << target), SCSI_Data_NoACK_port );
1227
1228 /* Stop arbitration and enable parity */1229 outb( PARITY_MASK, TMC_Cntl_port );
1230
1231 timeout = jiffies + 35; /* 350mS -- because of timeouts1232 (was 250mS) */1233
1234 while (jiffies < timeout) {1235 status = inb( SCSI_Status_port ); /* Read adapter status */1236 if (status & 1) {/* Busy asserted */1237 /* Enable SCSI Bus (on error, should make bus idle with 0) */1238 outb( 0x80, SCSI_Cntl_port );
1239 return 0;
1240 }1241 }1242 /* Make bus idle */1243 fdomain_make_bus_idle();
1244 #ifEVERY_ACCESS1245 if (!target) printk( "Selection failed\n" );
1246 #endif1247 #ifERRORS_ONLY1248 if (!target) {1249 if (chip == tmc18c30 && !flag) /* Skip first failure for 18C30 chips. */1250 ++flag;
1251 else1252 printk( "fdomain: Selection failed\n" );
1253 }1254 #endif1255 return 1;
1256 }1257
1258 voidmy_done( interror )
/* */1259 {1260 if (in_command) {1261 in_command = 0;
1262 outb( 0x00, Interrupt_Cntl_port );
1263 fdomain_make_bus_idle();
1264 current_SC->result = error;
1265 if (current_SC->scsi_done)
1266 current_SC->scsi_done( current_SC );
1267 elsepanic( "fdomain: current_SC->scsi_done() == NULL" );
1268 }else{1269 panic( "fdomain: my_done() called outside of command\n" );
1270 }1271 #ifDEBUG_RACE1272 in_interrupt_flag = 0;
1273 #endif1274 }1275
1276 voidfdomain_16x0_intr( intirq, void *dev_id, structpt_regs * regs )
/* */1277 {1278 intstatus;
1279 intdone = 0;
1280 unsigneddata_count;
1281
1282 /* The fdomain_16x0_intr is only called via1283 the interrupt handler. The goal of the1284 sti() here is to allow other1285 interruptions while this routine is1286 running. */1287
1288 sti(); /* Yes, we really want sti() here */1289
1290 outb( 0x00, Interrupt_Cntl_port );
1291
1292 /* We usually have one spurious interrupt after each command. Ignore it. */1293 if (!in_command || !current_SC) {/* Spurious interrupt */1294 #ifEVERY_ACCESS1295 printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
1296 in_command, current_SC );
1297 #endif1298 return;
1299 }1300
1301 /* Abort calls my_done, so we do nothing here. */1302 if (current_SC->SCp.phase & aborted) {1303 #ifDEBUG_ABORT1304 printk( "Interrupt after abort, ignoring\n" );
1305 #endif1306 /*1307 return; */1308 }1309
1310 #ifDEBUG_RACE1311 ++in_interrupt_flag;
1312 #endif1313
1314 if (current_SC->SCp.phase & in_arbitration) {1315 status = inb( TMC_Status_port ); /* Read adapter status */1316 if (!(status & 0x02)) {1317 #ifEVERY_ACCESS1318 printk( " AFAIL " );
1319 #endif1320 my_done( DID_BUS_BUSY << 16 );
1321 return;
1322 }1323 current_SC->SCp.phase = in_selection;
1324
1325 outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );
1326
1327 outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */1328 outb( adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port );
1329
1330 /* Stop arbitration and enable parity */1331 outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
1332 #ifDEBUG_RACE1333 in_interrupt_flag = 0;
1334 #endif1335 return;
1336 }elseif (current_SC->SCp.phase & in_selection) {1337 status = inb( SCSI_Status_port );
1338 if (!(status & 0x01)) {1339 /* Try again, for slow devices */1340 if (fdomain_select( current_SC->target )) {1341 #ifEVERY_ACCESS1342 printk( " SFAIL " );
1343 #endif1344 my_done( DID_NO_CONNECT << 16 );
1345 return;
1346 }else{1347 #ifEVERY_ACCESS1348 printk( " AltSel " );
1349 #endif1350 /* Stop arbitration and enable parity */1351 outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
1352 }1353 }1354 current_SC->SCp.phase = in_other;
1355 outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
1356 outb( 0x80, SCSI_Cntl_port );
1357 #ifDEBUG_RACE1358 in_interrupt_flag = 0;
1359 #endif1360 return;
1361 }1362
1363 /* current_SC->SCp.phase == in_other: this is the body of the routine */1364
1365 status = inb( SCSI_Status_port );
1366
1367 if (status & 0x10) {/* REQ */1368
1369 switch (status & 0x0e) {1370
1371 case 0x08: /* COMMAND OUT */1372 outb( current_SC->cmnd[current_SC->SCp.sent_command++],
1373 Write_SCSI_Data_port );
1374 #ifEVERY_ACCESS1375 printk( "CMD = %x,",
1376 current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
1377 #endif1378 break;
1379 case 0x00: /* DATA OUT -- tmc18c50/tmc18c30 only */1380 if (chip != tmc1800 && !current_SC->SCp.have_data_in) {1381 current_SC->SCp.have_data_in = -1;
1382 outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1383 }1384 break;
1385 case 0x04: /* DATA IN -- tmc18c50/tmc18c30 only */1386 if (chip != tmc1800 && !current_SC->SCp.have_data_in) {1387 current_SC->SCp.have_data_in = 1;
1388 outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1389 }1390 break;
1391 case 0x0c: /* STATUS IN */1392 current_SC->SCp.Status = inb( Read_SCSI_Data_port );
1393 #ifEVERY_ACCESS1394 printk( "Status = %x, ", current_SC->SCp.Status );
1395 #endif1396 #ifERRORS_ONLY1397 if (current_SC->SCp.Status && current_SC->SCp.Status != 2) {1398 printk( "fdomain: target = %d, command = %x, status = %x\n",
1399 current_SC->target,
1400 current_SC->cmnd[0],
1401 current_SC->SCp.Status );
1402 }1403 #endif1404 break;
1405 case 0x0a: /* MESSAGE OUT */1406 outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */1407 break;
1408 case 0x0e: /* MESSAGE IN */1409 current_SC->SCp.Message = inb( Read_SCSI_Data_port );
1410 #ifEVERY_ACCESS1411 printk( "Message = %x, ", current_SC->SCp.Message );
1412 #endif1413 if (!current_SC->SCp.Message) ++done;
1414 #ifDEBUG_MESSAGES || EVERY_ACCESS1415 if (current_SC->SCp.Message) {1416 printk( "fdomain: message = %x\n", current_SC->SCp.Message );
1417 }1418 #endif1419 break;
1420 }1421 }1422
1423 if (chip == tmc18001424 && !current_SC->SCp.have_data_in1425 && (current_SC->SCp.sent_command1426 >= current_SC->cmd_len)) {1427 /* We have to get the FIFO direction1428 correct, so I've made a table based1429 on the SCSI Standard of which commands1430 appear to require a DATA OUT phase.1431 */1432 /*1433 p. 94: Command for all device types1434 CHANGE DEFINITION 40 DATA OUT1435 COMPARE 39 DATA OUT1436 COPY 18 DATA OUT1437 COPY AND VERIFY 3a DATA OUT1438 INQUIRY 12 1439 LOG SELECT 4c DATA OUT1440 LOG SENSE 4d1441 MODE SELECT (6) 15 DATA OUT1442 MODE SELECT (10) 55 DATA OUT1443 MODE SENSE (6) 1a1444 MODE SENSE (10) 5a1445 READ BUFFER 3c1446 RECEIVE DIAGNOSTIC RESULTS 1c1447 REQUEST SENSE 031448 SEND DIAGNOSTIC 1d DATA OUT1449 TEST UNIT READY 001450 WRITE BUFFER 3b DATA OUT1451
1452 p.178: Commands for direct-access devices (not listed on p. 94)1453 FORMAT UNIT 04 DATA OUT1454 LOCK-UNLOCK CACHE 361455 PRE-FETCH 341456 PREVENT-ALLOW MEDIUM REMOVAL 1e1457 READ (6)/RECEIVE 081458 READ (10) 3c1459 READ CAPACITY 251460 READ DEFECT DATA (10) 371461 READ LONG 3e1462 REASSIGN BLOCKS 07 DATA OUT1463 RELEASE 171464 RESERVE 16 DATA OUT1465 REZERO UNIT/REWIND 011466 SEARCH DATA EQUAL (10) 31 DATA OUT1467 SEARCH DATA HIGH (10) 30 DATA OUT1468 SEARCH DATA LOW (10) 32 DATA OUT1469 SEEK (6) 0b1470 SEEK (10) 2b1471 SET LIMITS (10) 331472 START STOP UNIT 1b1473 SYNCHRONIZE CACHE 351474 VERIFY (10) 2f1475 WRITE (6)/PRINT/SEND 0a DATA OUT1476 WRITE (10)/SEND 2a DATA OUT1477 WRITE AND VERIFY (10) 2e DATA OUT1478 WRITE LONG 3f DATA OUT1479 WRITE SAME 41 DATA OUT ?1480
1481 p. 261: Commands for sequential-access devices (not previously listed)1482 ERASE 191483 LOAD UNLOAD 1b1484 LOCATE 2b1485 READ BLOCK LIMITS 051486 READ POSITION 341487 READ REVERSE 0f1488 RECOVER BUFFERED DATA 141489 SPACE 111490 WRITE FILEMARKS 10 ?1491
1492 p. 298: Commands for printer devices (not previously listed)1493 ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****1494 SLEW AND PRINT 0b DATA OUT -- same as seek1495 STOP PRINT 1b1496 SYNCHRONIZE BUFFER 101497
1498 p. 315: Commands for processor devices (not previously listed)1499 1500 p. 321: Commands for write-once devices (not previously listed)1501 MEDIUM SCAN 381502 READ (12) a81503 SEARCH DATA EQUAL (12) b1 DATA OUT1504 SEARCH DATA HIGH (12) b0 DATA OUT1505 SEARCH DATA LOW (12) b2 DATA OUT1506 SET LIMITS (12) b31507 VERIFY (12) af1508 WRITE (12) aa DATA OUT1509 WRITE AND VERIFY (12) ae DATA OUT1510
1511 p. 332: Commands for CD-ROM devices (not previously listed)1512 PAUSE/RESUME 4b1513 PLAY AUDIO (10) 451514 PLAY AUDIO (12) a51515 PLAY AUDIO MSF 471516 PLAY TRACK RELATIVE (10) 491517 PLAY TRACK RELATIVE (12) a91518 READ HEADER 441519 READ SUB-CHANNEL 421520 READ TOC 431521
1522 p. 370: Commands for scanner devices (not previously listed)1523 GET DATA BUFFER STATUS 341524 GET WINDOW 251525 OBJECT POSITION 311526 SCAN 1b1527 SET WINDOW 24 DATA OUT1528
1529 p. 391: Commands for optical memory devices (not listed)1530 ERASE (10) 2c1531 ERASE (12) ac1532 MEDIUM SCAN 38 DATA OUT1533 READ DEFECT DATA (12) b71534 READ GENERATION 291535 READ UPDATED BLOCK 2d1536 UPDATE BLOCK 3d DATA OUT1537
1538 p. 419: Commands for medium changer devices (not listed)1539 EXCHANGE MEDIUM 461540 INITIALIZE ELEMENT STATUS 071541 MOVE MEDIUM a51542 POSITION TO ELEMENT 2b1543 READ ELEMENT STATUS b81544 REQUEST VOL. ELEMENT ADDRESS b51545 SEND VOLUME TAG b6 DATA OUT1546
1547 p. 454: Commands for communications devices (not listed previously)1548 GET MESSAGE (6) 081549 GET MESSAGE (10) 281550 GET MESSAGE (12) a81551 */1552
1553 switch (current_SC->cmnd[0]) {1554 caseCHANGE_DEFINITION: caseCOMPARE: caseCOPY:
1555 caseCOPY_VERIFY: caseLOG_SELECT: caseMODE_SELECT:
1556 caseMODE_SELECT_10: caseSEND_DIAGNOSTIC: caseWRITE_BUFFER:
1557
1558 caseFORMAT_UNIT: caseREASSIGN_BLOCKS: caseRESERVE:
1559 caseSEARCH_EQUAL: caseSEARCH_HIGH: caseSEARCH_LOW:
1560 caseWRITE_6: caseWRITE_10: caseWRITE_VERIFY:
1561 case 0x3f: case 0x41:
1562
1563 case 0xb1: case 0xb0: case 0xb2:
1564 case 0xaa: case 0xae:
1565
1566 case 0x24:
1567
1568 case 0x38: case 0x3d:
1569
1570 case 0xb6:
1571
1572 case 0xea: /* alternate number for WRITE LONG */1573
1574 current_SC->SCp.have_data_in = -1;
1575 outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1576 break;
1577
1578 case 0x00:
1579 default:
1580
1581 current_SC->SCp.have_data_in = 1;
1582 outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1583 break;
1584 }1585 }1586
1587 if (current_SC->SCp.have_data_in == -1) {/* DATA OUT */1588 while ( (data_count = FIFO_Size - inw( FIFO_Data_Count_port )) > 512 ) {1589 #ifEVERY_ACCESS1590 printk( "DC=%d, ", data_count ) ;
1591 #endif1592 if (data_count > current_SC->SCp.this_residual)
1593 data_count = current_SC->SCp.this_residual;
1594 if (data_count > 0) {1595 #ifEVERY_ACCESS1596 printk( "%d OUT, ", data_count );
1597 #endif1598 if (data_count == 1) {1599 outb( *current_SC->SCp.ptr++, Write_FIFO_port );
1600 --current_SC->SCp.this_residual;
1601 }else{1602 data_count >>= 1;
1603 outsw( Write_FIFO_port, current_SC->SCp.ptr, data_count );
1604 current_SC->SCp.ptr += 2 * data_count;
1605 current_SC->SCp.this_residual -= 2 * data_count;
1606 }1607 }1608 if (!current_SC->SCp.this_residual) {1609 if (current_SC->SCp.buffers_residual) {1610 --current_SC->SCp.buffers_residual;
1611 ++current_SC->SCp.buffer;
1612 current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1613 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1614 }else1615 break;
1616 }1617 }1618 }1619
1620 if (current_SC->SCp.have_data_in == 1) {/* DATA IN */1621 while ((data_count = inw( FIFO_Data_Count_port )) > 0) {1622 #ifEVERY_ACCESS1623 printk( "DC=%d, ", data_count );
1624 #endif1625 if (data_count > current_SC->SCp.this_residual)
1626 data_count = current_SC->SCp.this_residual;
1627 if (data_count) {1628 #ifEVERY_ACCESS1629 printk( "%d IN, ", data_count );
1630 #endif1631 if (data_count == 1) {1632 *current_SC->SCp.ptr++ = inb( Read_FIFO_port );
1633 --current_SC->SCp.this_residual;
1634 }else{1635 data_count >>= 1; /* Number of words */1636 insw( Read_FIFO_port, current_SC->SCp.ptr, data_count );
1637 current_SC->SCp.ptr += 2 * data_count;
1638 current_SC->SCp.this_residual -= 2 * data_count;
1639 }1640 }1641 if (!current_SC->SCp.this_residual1642 && current_SC->SCp.buffers_residual) {1643 --current_SC->SCp.buffers_residual;
1644 ++current_SC->SCp.buffer;
1645 current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1646 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1647 }1648 }1649 }1650
1651 if (done) {1652 #ifEVERY_ACCESS1653 printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
1654 #endif1655
1656 #ifERRORS_ONLY1657 if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {1658 if ((unsignedchar)(*((char *)current_SC->request_buffer+2)) & 0x0f) {1659 unsignedcharkey;
1660 unsignedcharcode;
1661 unsignedcharqualifier;
1662
1663 key = (unsignedchar)(*((char *)current_SC->request_buffer + 2))
1664 & 0x0f;
1665 code = (unsignedchar)(*((char *)current_SC->request_buffer + 12));
1666 qualifier = (unsignedchar)(*((char *)current_SC->request_buffer1667 + 13));
1668
1669 if (!(key == UNIT_ATTENTION && (code == 0x29 || !code))
1670 && !(key == NOT_READY1671 && code == 0x04
1672 && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1673 && !(key == ILLEGAL_REQUEST && (code == 0x25
1674 || code == 0x24
1675 || !code)))
1676
1677 printk( "fdomain: REQUEST SENSE "
1678 "Key = %x, Code = %x, Qualifier = %x\n",
1679 key, code, qualifier );
1680 }1681 }1682 #endif1683 #ifEVERY_ACCESS1684 printk( "BEFORE MY_DONE. . ." );
1685 #endif1686 my_done( (current_SC->SCp.Status & 0xff)
1687 | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
1688 #ifEVERY_ACCESS1689 printk( "RETURNING.\n" );
1690 #endif1691
1692 }else{1693 if (current_SC->SCp.phase & disconnect) {1694 outb( 0xd0 | FIFO_COUNT, Interrupt_Cntl_port );
1695 outb( 0x00, SCSI_Cntl_port );
1696 }else{1697 outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
1698 }1699 }1700 #ifDEBUG_RACE1701 in_interrupt_flag = 0;
1702 #endif1703 return;
1704 }1705
1706 intfdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
/* */1707 {1708 if (in_command) {1709 panic( "fdomain: fdomain_16x0_queue() NOT REENTRANT!\n" );
1710 }1711 #ifEVERY_ACCESS1712 printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1713 SCpnt->target,
1714 *(unsignedchar *)SCpnt->cmnd,
1715 SCpnt->use_sg,
1716 SCpnt->request_bufflen );
1717 #endif1718
1719 fdomain_make_bus_idle();
1720
1721 current_SC = SCpnt; /* Save this for the done function */1722 current_SC->scsi_done = done;
1723
1724 /* Initialize static data */1725
1726 if (current_SC->use_sg) {1727 current_SC->SCp.buffer =
1728 (structscatterlist *)current_SC->request_buffer;
1729 current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1730 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1731 current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
1732 }else{1733 current_SC->SCp.ptr = (char *)current_SC->request_buffer;
1734 current_SC->SCp.this_residual = current_SC->request_bufflen;
1735 current_SC->SCp.buffer = NULL;
1736 current_SC->SCp.buffers_residual = 0;
1737 }1738
1739
1740 current_SC->SCp.Status = 0;
1741 current_SC->SCp.Message = 0;
1742 current_SC->SCp.have_data_in = 0;
1743 current_SC->SCp.sent_command = 0;
1744 current_SC->SCp.phase = in_arbitration;
1745
1746 /* Start arbitration */1747 outb( 0x00, Interrupt_Cntl_port );
1748 outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */1749 outb( adapter_mask, SCSI_Data_NoACK_port ); /* Set our id bit */1750 ++in_command;
1751 outb( 0x20, Interrupt_Cntl_port );
1752 outb( 0x14 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */1753
1754 return 0;
1755 }1756
1757 /* The following code, which simulates the old-style command function, was1758 taken from Tommy Thorn's aha1542.c file. This code is Copyright (C)1759 1992 Tommy Thorn. */1760
1761 staticvolatileintinternal_done_flag = 0;
1762 staticvolatileintinternal_done_errcode = 0;
1763
1764 staticvoidinternal_done( Scsi_Cmnd *SCpnt )
/* */1765 {1766 internal_done_errcode = SCpnt->result;
1767 ++internal_done_flag;
1768 }1769
1770 intfdomain_16x0_command( Scsi_Cmnd *SCpnt )
/* */1771 {1772 fdomain_16x0_queue( SCpnt, internal_done );
1773
1774 while (!internal_done_flag)
1775 ;
1776 internal_done_flag = 0;
1777 returninternal_done_errcode;
1778 }1779
1780 /* End of code derived from Tommy Thorn's work. */1781
1782 voidprint_info( Scsi_Cmnd *SCpnt )
/* */1783 {1784 unsignedintimr;
1785 unsignedintirr;
1786 unsignedintisr;
1787
1788 if (!SCpnt || !SCpnt->host) {1789 printk( "fdomain: cannot provide detailed information\n" );
1790 }1791
1792 printk( "%s\n", fdomain_16x0_info( SCpnt->host ) );
1793 print_banner( SCpnt->host );
1794 switch (SCpnt->SCp.phase) {1795 casein_arbitration: printk( "arbitration " ); break;
1796 casein_selection: printk( "selection " ); break;
1797 casein_other: printk( "other " ); break;
1798 default: printk( "unknown " ); break;
1799 }1800
1801 printk( "(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1802 SCpnt->SCp.phase,
1803 SCpnt->target,
1804 *(unsignedchar *)SCpnt->cmnd,
1805 SCpnt->use_sg,
1806 SCpnt->request_bufflen );
1807 printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
1808 SCpnt->SCp.sent_command,
1809 SCpnt->SCp.have_data_in,
1810 SCpnt->timeout );
1811 #ifDEBUG_RACE1812 printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
1813 #endif1814
1815 imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
1816 outb( 0x0a, 0xa0 );
1817 irr = inb( 0xa0 ) << 8;
1818 outb( 0x0a, 0x20 );
1819 irr += inb( 0x20 );
1820 outb( 0x0b, 0xa0 );
1821 isr = inb( 0xa0 ) << 8;
1822 outb( 0x0b, 0x20 );
1823 isr += inb( 0x20 );
1824
1825 /* Print out interesting information */1826 printk( "IMR = 0x%04x", imr );
1827 if (imr & (1 << interrupt_level))
1828 printk( " (masked)" );
1829 printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
1830
1831 printk( "SCSI Status = 0x%02x\n", inb( SCSI_Status_port ) );
1832 printk( "TMC Status = 0x%02x", inb( TMC_Status_port ) );
1833 if (inb( TMC_Status_port & 1))
1834 printk( " (interrupt)" );
1835 printk( "\n" );
1836 printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port ) );
1837 if (inb( Interrupt_Status_port ) & 0x08)
1838 printk( " (enabled)" );
1839 printk( "\n" );
1840 if (chip == tmc18c50 || chip == tmc18c30) {1841 printk( "FIFO Status = 0x%02x\n", inb( port_base + FIFO_Status ) );
1842 printk( "Int. Condition = 0x%02x\n",
1843 inb( port_base + Interrupt_Cond ) );
1844 }1845 printk( "Configuration 1 = 0x%02x\n", inb( port_base + Configuration1 ) );
1846 if (chip == tmc18c50 || chip == tmc18c30)
1847 printk( "Configuration 2 = 0x%02x\n",
1848 inb( port_base + Configuration2 ) );
1849 }1850
1851 intfdomain_16x0_abort( Scsi_Cmnd *SCpnt)
/* */1852 {1853 unsignedlongflags;
1854 #ifEVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT1855 printk( "fdomain: abort " );
1856 #endif1857
1858 save_flags( flags );
1859 cli();
1860 if (!in_command) {1861 #ifEVERY_ACCESS || ERRORS_ONLY1862 printk( " (not in command)\n" );
1863 #endif1864 restore_flags( flags );
1865 returnSCSI_ABORT_NOT_RUNNING;
1866 }elseprintk( "\n" );
1867
1868 #ifDEBUG_ABORT1869 print_info( SCpnt );
1870 #endif1871
1872 fdomain_make_bus_idle();
1873
1874 current_SC->SCp.phase |= aborted;
1875
1876 current_SC->result = DID_ABORT << 16;
1877
1878 restore_flags( flags );
1879
1880 /* Aborts are not done well. . . */1881 my_done( DID_ABORT << 16 );
1882
1883 returnSCSI_ABORT_SUCCESS;
1884 }1885
1886 intfdomain_16x0_reset( Scsi_Cmnd *SCpnt )
/* */1887 {1888 #ifDEBUG_RESET1889 staticintcalled_once = 0;
1890 #endif1891
1892 #ifERRORS_ONLY1893 if (SCpnt) printk( "fdomain: SCSI Bus Reset\n" );
1894 #endif1895
1896 #ifDEBUG_RESET1897 if (called_once) print_info( current_SC );
1898 called_once = 1;
1899 #endif1900
1901 outb( 1, SCSI_Cntl_port );
1902 do_pause( 2 );
1903 outb( 0, SCSI_Cntl_port );
1904 do_pause( 115 );
1905 outb( 0, SCSI_Mode_Cntl_port );
1906 outb( PARITY_MASK, TMC_Cntl_port );
1907
1908 /* Unless this is the very first call (i.e., SCPnt == NULL), everything1909 is probably hosed at this point. We will, however, try to keep1910 things going by informing the high-level code that we need help. */1911
1912 returnSCSI_RESET_WAKEUP;
1913 }1914
1915 #include "sd.h"
1916 #include "scsi_ioctl.h"
1917
1918 intfdomain_16x0_biosparam( Scsi_Disk *disk, kdev_tdev, int *info_array )
/* */1919 {1920 intdrive;
1921 unsignedcharbuf[512 + sizeof( int ) * 2];
1922 intsize = disk->capacity;
1923 int *sizes = (int *)buf;
1924 unsignedchar *data = (unsignedchar *)(sizes + 2);
1925 unsignedchardo_read[] = {READ_6, 0, 0, 0, 1, 0 };
1926 intretcode;
1927 structdrive_info{1928 unsignedshortcylinders;
1929 unsignedcharheads;
1930 unsignedcharsectors;
1931 } *i;
1932
1933 /* NOTES:1934 The RAM area starts at 0x1f00 from the bios_base address.1935
1936 For BIOS Version 2.0:1937 1938 The drive parameter table seems to start at 0x1f30.1939 The first byte's purpose is not known.1940 Next is the cylinder, head, and sector information.1941 The last 4 bytes appear to be the drive's size in sectors.1942 The other bytes in the drive parameter table are unknown.1943 If anyone figures them out, please send me mail, and I will1944 update these notes.1945
1946 Tape drives do not get placed in this table.1947
1948 There is another table at 0x1fea:1949 If the byte is 0x01, then the SCSI ID is not in use.1950 If the byte is 0x18 or 0x48, then the SCSI ID is in use,1951 although tapes don't seem to be in this table. I haven't1952 seen any other numbers (in a limited sample).1953
1954 0x1f2d is a drive count (i.e., not including tapes)1955
1956 The table at 0x1fcc are I/O ports addresses for the various1957 operations. I calculate these by hand in this driver code.1958
1959 1960 1961 For the ISA-200S version of BIOS Version 2.0:1962
1963 The drive parameter table starts at 0x1f33.1964
1965 WARNING: Assume that the table entry is 25 bytes long. Someone needs1966 to check this for the Quantum ISA-200S card.1967
1968 1969 1970 For BIOS Version 3.2:1971
1972 The drive parameter table starts at 0x1f70. Each entry is1973 0x0a bytes long. Heads are one less than we need to report.1974 */1975
1976 drive = MINOR(dev) / 16;
1977
1978 if (bios_major == 2) {1979 switch (Quantum) {1980 case 2: /* ISA_200S */1981 /* The value of 25 has never been verified.1982 It should probably be 15. */1983 i = (structdrive_info *)( (char *)bios_base + 0x1f33 + drive * 25 );
1984 break;
1985 case 3: /* ISA_250MG */1986 i = (structdrive_info *)( (char *)bios_base + 0x1f36 + drive * 15 );
1987 break;
1988 case 4: /* ISA_200S (another one) */1989 i = (structdrive_info *)( (char *)bios_base + 0x1f34 + drive * 15 );
1990 break;
1991 default:
1992 i = (structdrive_info *)( (char *)bios_base + 0x1f31 + drive * 25 );
1993 break;
1994 }1995 info_array[0] = i->heads;
1996 info_array[1] = i->sectors;
1997 info_array[2] = i->cylinders;
1998 }elseif (bios_major == 3
1999 && bios_minor >= 0
2000 && bios_minor < 4) {/* 3.0 and 3.2 BIOS */2001 i = (structdrive_info *)( (char *)bios_base + 0x1f71 + drive * 10 );
2002 info_array[0] = i->heads + 1;
2003 info_array[1] = i->sectors;
2004 info_array[2] = i->cylinders;
2005 }else{/* 3.4 BIOS (and up?) */2006 /* This algorithm was provided by Future Domain (much thanks!). */2007
2008 sizes[0] = 0; /* zero bytes out */2009 sizes[1] = 512; /* one sector in */2010 memcpy( data, do_read, sizeof( do_read ) );
2011 retcode = kernel_scsi_ioctl( disk->device,
2012 SCSI_IOCTL_SEND_COMMAND,
2013 (void *)buf );
2014 if (!retcode/* SCSI command ok */2015 && data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */2016 && data[0x1c2]) {/* Partition type */2017
2018 /* The partition table layout is as follows:2019
2020 Start: 0x1b3h2021 Offset: 0 = partition status2022 1 = starting head2023 2 = starting sector and cylinder (word, encoded)2024 4 = partition type2025 5 = ending head2026 6 = ending sector and cylinder (word, encoded)2027 8 = starting absolute sector (double word)2028 c = number of sectors (double word)2029 Signature: 0x1fe = 0x55aa2030
2031 So, this algorithm assumes:2032 1) the first partition table is in use,2033 2) the data in the first entry is correct, and2034 3) partitions never divide cylinders2035
2036 Note that (1) may be FALSE for NetBSD (and other BSD flavors),2037 as well as for Linux. Note also, that Linux doesn't pay any2038 attention to the fields that are used by this algorithm -- it2039 only uses the absolute sector data. Recent versions of Linux's2040 fdisk(1) will fill this data in correctly, and forthcoming2041 versions will check for consistency.2042
2043 Checking for a non-zero partition type is not part of the2044 Future Domain algorithm, but it seemed to be a reasonable thing2045 to do, especially in the Linux and BSD worlds. */2046
2047 info_array[0] = data[0x1c3] + 1; /* heads */2048 info_array[1] = data[0x1c4] & 0x3f; /* sectors */2049 }else{2050
2051 /* Note that this new method guarantees that there will always be2052 less than 1024 cylinders on a platter. This is good for drives2053 up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */2054
2055 if ((unsignedint)size >= 0x7e0000U) {2056 info_array[0] = 0xff; /* heads = 255 */2057 info_array[1] = 0x3f; /* sectors = 63 */2058 }elseif ((unsignedint)size >= 0x200000U) {2059 info_array[0] = 0x80; /* heads = 128 */2060 info_array[1] = 0x3f; /* sectors = 63 */2061 }else{2062 info_array[0] = 0x40; /* heads = 64 */2063 info_array[1] = 0x20; /* sectors = 32 */2064 }2065 }2066 /* For both methods, compute the cylinders */2067 info_array[2] = (unsignedint)size / (info_array[0] * info_array[1] );
2068 }2069
2070 return 0;
2071 }2072
2073 #ifdefMODULE2074 /* Eventually this will go into an include file, but this will be later */2075 Scsi_Host_Templatedriver_template = FDOMAIN_16X0;
2076
2077 #include "scsi_module.c"
2078 #endif