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