fd_mcs.c revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac
1/* fd_mcs.c -- Future Domain MCS 600/700 (or IBM OEM) driver 2 * 3 * FutureDomain MCS-600/700 v0.2 03/11/1998 by ZP Gu (zpg@castle.net) 4 * 5 * This driver is cloned from fdomain.* to specifically support 6 * the Future Domain MCS 600/700 MCA SCSI adapters. Some PS/2s 7 * also equipped with IBM Fast SCSI Adapter/A which is an OEM 8 * of MCS 700. 9 * 10 * This driver also supports Reply SB16/SCSI card (the SCSI part). 11 * 12 * What makes this driver different is that this driver is MCA only 13 * and it supports multiple adapters in the same system, IRQ 14 * sharing, some driver statistics, and maps highest SCSI id to sda. 15 * All cards are auto-detected. 16 * 17 * Assumptions: TMC-1800/18C50/18C30, BIOS >= 3.4 18 * 19 * LILO command-line options: 20 * fd_mcs=<FIFO_COUNT>[,<FIFO_SIZE>] 21 * 22 * ******************************************************** 23 * Please see Copyrights/Comments in fdomain.* for credits. 24 * Following is from fdomain.c for acknowledgement: 25 * 26 * Created: Sun May 3 18:53:19 1992 by faith@cs.unc.edu 27 * Revised: Wed Oct 2 11:10:55 1996 by r.faith@ieee.org 28 * Author: Rickard E. Faith, faith@cs.unc.edu 29 * Copyright 1992, 1993, 1994, 1995, 1996 Rickard E. Faith 30 * 31 * $Id: fdomain.c,v 5.45 1996/10/02 15:13:06 root Exp $ 32 33 * This program is free software; you can redistribute it and/or modify it 34 * under the terms of the GNU General Public License as published by the 35 * Free Software Foundation; either version 2, or (at your option) any 36 * later version. 37 38 * This program is distributed in the hope that it will be useful, but 39 * WITHOUT ANY WARRANTY; without even the implied warranty of 40 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 41 * General Public License for more details. 42 43 * You should have received a copy of the GNU General Public License along 44 * with this program; if not, write to the Free Software Foundation, Inc., 45 * 675 Mass Ave, Cambridge, MA 02139, USA. 46 47 ************************************************************************** 48 49 NOTES ON USER DEFINABLE OPTIONS: 50 51 DEBUG: This turns on the printing of various debug information. 52 53 ENABLE_PARITY: This turns on SCSI parity checking. With the current 54 driver, all attached devices must support SCSI parity. If none of your 55 devices support parity, then you can probably get the driver to work by 56 turning this option off. I have no way of testing this, however, and it 57 would appear that no one ever uses this option. 58 59 FIFO_COUNT: The host adapter has an 8K cache (host adapters based on the 60 18C30 chip have a 2k cache). When this many 512 byte blocks are filled by 61 the SCSI device, an interrupt will be raised. Therefore, this could be as 62 low as 0, or as high as 16. Note, however, that values which are too high 63 or too low seem to prevent any interrupts from occurring, and thereby lock 64 up the machine. I have found that 2 is a good number, but throughput may 65 be increased by changing this value to values which are close to 2. 66 Please let me know if you try any different values. 67 [*****Now a runtime option*****] 68 69 RESELECTION: This is no longer an option, since I gave up trying to 70 implement it in version 4.x of this driver. It did not improve 71 performance at all and made the driver unstable (because I never found one 72 of the two race conditions which were introduced by the multiple 73 outstanding command code). The instability seems a very high price to pay 74 just so that you don't have to wait for the tape to rewind. If you want 75 this feature implemented, send me patches. I'll be happy to send a copy 76 of my (broken) driver to anyone who would like to see a copy. 77 78 **************************************************************************/ 79 80#include <linux/module.h> 81#include <linux/init.h> 82#include <linux/interrupt.h> 83#include <linux/blkdev.h> 84#include <linux/errno.h> 85#include <linux/string.h> 86#include <linux/ioport.h> 87#include <linux/proc_fs.h> 88#include <linux/delay.h> 89#include <linux/mca.h> 90#include <linux/spinlock.h> 91#include <scsi/scsicam.h> 92#include <linux/mca-legacy.h> 93 94#include <asm/io.h> 95#include <asm/system.h> 96 97#include "scsi.h" 98#include <scsi/scsi_host.h> 99 100#define DRIVER_VERSION "v0.2 by ZP Gu<zpg@castle.net>" 101 102/* START OF USER DEFINABLE OPTIONS */ 103 104#define DEBUG 0 /* Enable debugging output */ 105#define ENABLE_PARITY 1 /* Enable SCSI Parity */ 106 107/* END OF USER DEFINABLE OPTIONS */ 108 109#if DEBUG 110#define EVERY_ACCESS 0 /* Write a line on every scsi access */ 111#define ERRORS_ONLY 1 /* Only write a line if there is an error */ 112#define DEBUG_MESSAGES 1 /* Debug MESSAGE IN phase */ 113#define DEBUG_ABORT 1 /* Debug abort() routine */ 114#define DEBUG_RESET 1 /* Debug reset() routine */ 115#define DEBUG_RACE 1 /* Debug interrupt-driven race condition */ 116#else 117#define EVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */ 118#define ERRORS_ONLY 0 119#define DEBUG_MESSAGES 0 120#define DEBUG_ABORT 0 121#define DEBUG_RESET 0 122#define DEBUG_RACE 0 123#endif 124 125/* Errors are reported on the line, so we don't need to report them again */ 126#if EVERY_ACCESS 127#undef ERRORS_ONLY 128#define ERRORS_ONLY 0 129#endif 130 131#if ENABLE_PARITY 132#define PARITY_MASK 0x08 133#else 134#define PARITY_MASK 0x00 135#endif 136 137enum chip_type { 138 unknown = 0x00, 139 tmc1800 = 0x01, 140 tmc18c50 = 0x02, 141 tmc18c30 = 0x03, 142}; 143 144enum { 145 in_arbitration = 0x02, 146 in_selection = 0x04, 147 in_other = 0x08, 148 disconnect = 0x10, 149 aborted = 0x20, 150 sent_ident = 0x40, 151}; 152 153enum in_port_type { 154 Read_SCSI_Data = 0, 155 SCSI_Status = 1, 156 TMC_Status = 2, 157 FIFO_Status = 3, /* tmc18c50/tmc18c30 only */ 158 Interrupt_Cond = 4, /* tmc18c50/tmc18c30 only */ 159 LSB_ID_Code = 5, 160 MSB_ID_Code = 6, 161 Read_Loopback = 7, 162 SCSI_Data_NoACK = 8, 163 Interrupt_Status = 9, 164 Configuration1 = 10, 165 Configuration2 = 11, /* tmc18c50/tmc18c30 only */ 166 Read_FIFO = 12, 167 FIFO_Data_Count = 14 168}; 169 170enum out_port_type { 171 Write_SCSI_Data = 0, 172 SCSI_Cntl = 1, 173 Interrupt_Cntl = 2, 174 SCSI_Mode_Cntl = 3, 175 TMC_Cntl = 4, 176 Memory_Cntl = 5, /* tmc18c50/tmc18c30 only */ 177 Write_Loopback = 7, 178 IO_Control = 11, /* tmc18c30 only */ 179 Write_FIFO = 12 180}; 181 182struct fd_hostdata { 183 unsigned long _bios_base; 184 int _bios_major; 185 int _bios_minor; 186 volatile int _in_command; 187 Scsi_Cmnd *_current_SC; 188 enum chip_type _chip; 189 int _adapter_mask; 190 int _fifo_count; /* Number of 512 byte blocks before INTR */ 191 192 char _adapter_name[64]; 193#if DEBUG_RACE 194 volatile int _in_interrupt_flag; 195#endif 196 197 int _SCSI_Mode_Cntl_port; 198 int _FIFO_Data_Count_port; 199 int _Interrupt_Cntl_port; 200 int _Interrupt_Status_port; 201 int _Interrupt_Cond_port; 202 int _Read_FIFO_port; 203 int _Read_SCSI_Data_port; 204 int _SCSI_Cntl_port; 205 int _SCSI_Data_NoACK_port; 206 int _SCSI_Status_port; 207 int _TMC_Cntl_port; 208 int _TMC_Status_port; 209 int _Write_FIFO_port; 210 int _Write_SCSI_Data_port; 211 212 int _FIFO_Size; /* = 0x2000; 8k FIFO for 213 pre-tmc18c30 chips */ 214 /* simple stats */ 215 int _Bytes_Read; 216 int _Bytes_Written; 217 int _INTR_Processed; 218}; 219 220#define FD_MAX_HOSTS 3 /* enough? */ 221 222#define HOSTDATA(shpnt) ((struct fd_hostdata *) shpnt->hostdata) 223#define bios_base (HOSTDATA(shpnt)->_bios_base) 224#define bios_major (HOSTDATA(shpnt)->_bios_major) 225#define bios_minor (HOSTDATA(shpnt)->_bios_minor) 226#define in_command (HOSTDATA(shpnt)->_in_command) 227#define current_SC (HOSTDATA(shpnt)->_current_SC) 228#define chip (HOSTDATA(shpnt)->_chip) 229#define adapter_mask (HOSTDATA(shpnt)->_adapter_mask) 230#define FIFO_COUNT (HOSTDATA(shpnt)->_fifo_count) 231#define adapter_name (HOSTDATA(shpnt)->_adapter_name) 232#if DEBUG_RACE 233#define in_interrupt_flag (HOSTDATA(shpnt)->_in_interrupt_flag) 234#endif 235#define SCSI_Mode_Cntl_port (HOSTDATA(shpnt)->_SCSI_Mode_Cntl_port) 236#define FIFO_Data_Count_port (HOSTDATA(shpnt)->_FIFO_Data_Count_port) 237#define Interrupt_Cntl_port (HOSTDATA(shpnt)->_Interrupt_Cntl_port) 238#define Interrupt_Status_port (HOSTDATA(shpnt)->_Interrupt_Status_port) 239#define Interrupt_Cond_port (HOSTDATA(shpnt)->_Interrupt_Cond_port) 240#define Read_FIFO_port (HOSTDATA(shpnt)->_Read_FIFO_port) 241#define Read_SCSI_Data_port (HOSTDATA(shpnt)->_Read_SCSI_Data_port) 242#define SCSI_Cntl_port (HOSTDATA(shpnt)->_SCSI_Cntl_port) 243#define SCSI_Data_NoACK_port (HOSTDATA(shpnt)->_SCSI_Data_NoACK_port) 244#define SCSI_Status_port (HOSTDATA(shpnt)->_SCSI_Status_port) 245#define TMC_Cntl_port (HOSTDATA(shpnt)->_TMC_Cntl_port) 246#define TMC_Status_port (HOSTDATA(shpnt)->_TMC_Status_port) 247#define Write_FIFO_port (HOSTDATA(shpnt)->_Write_FIFO_port) 248#define Write_SCSI_Data_port (HOSTDATA(shpnt)->_Write_SCSI_Data_port) 249#define FIFO_Size (HOSTDATA(shpnt)->_FIFO_Size) 250#define Bytes_Read (HOSTDATA(shpnt)->_Bytes_Read) 251#define Bytes_Written (HOSTDATA(shpnt)->_Bytes_Written) 252#define INTR_Processed (HOSTDATA(shpnt)->_INTR_Processed) 253 254struct fd_mcs_adapters_struct { 255 char *name; 256 int id; 257 enum chip_type fd_chip; 258 int fifo_size; 259 int fifo_count; 260}; 261 262#define REPLY_ID 0x5137 263 264static struct fd_mcs_adapters_struct fd_mcs_adapters[] = { 265 {"Future Domain SCSI Adapter MCS-700(18C50)", 266 0x60e9, 267 tmc18c50, 268 0x2000, 269 4}, 270 {"Future Domain SCSI Adapter MCS-600/700(TMC-1800)", 271 0x6127, 272 tmc1800, 273 0x2000, 274 4}, 275 {"Reply Sound Blaster/SCSI Adapter", 276 REPLY_ID, 277 tmc18c30, 278 0x800, 279 2}, 280}; 281 282#define FD_BRDS sizeof(fd_mcs_adapters)/sizeof(struct fd_mcs_adapters_struct) 283 284static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs); 285 286static unsigned long addresses[] = { 0xc8000, 0xca000, 0xce000, 0xde000 }; 287static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 }; 288static unsigned short interrupts[] = { 3, 5, 10, 11, 12, 14, 15, 0 }; 289 290/* host information */ 291static int found = 0; 292static struct Scsi_Host *hosts[FD_MAX_HOSTS + 1] = { NULL }; 293 294static int user_fifo_count = 0; 295static int user_fifo_size = 0; 296 297static int __init fd_mcs_setup(char *str) 298{ 299 static int done_setup = 0; 300 int ints[3]; 301 302 get_options(str, 3, ints); 303 if (done_setup++ || ints[0] < 1 || ints[0] > 2 || ints[1] < 1 || ints[1] > 16) { 304 printk("fd_mcs: usage: fd_mcs=FIFO_COUNT, FIFO_SIZE\n"); 305 return 0; 306 } 307 308 user_fifo_count = ints[0] >= 1 ? ints[1] : 0; 309 user_fifo_size = ints[0] >= 2 ? ints[2] : 0; 310 return 1; 311} 312 313__setup("fd_mcs=", fd_mcs_setup); 314 315static void print_banner(struct Scsi_Host *shpnt) 316{ 317 printk("scsi%d <fd_mcs>: ", shpnt->host_no); 318 319 if (bios_base) { 320 printk("BIOS at 0x%lX", bios_base); 321 } else { 322 printk("No BIOS"); 323 } 324 325 printk(", HostID %d, %s Chip, IRQ %d, IO 0x%lX\n", shpnt->this_id, chip == tmc18c50 ? "TMC-18C50" : (chip == tmc18c30 ? "TMC-18C30" : (chip == tmc1800 ? "TMC-1800" : "Unknown")), shpnt->irq, shpnt->io_port); 326} 327 328 329static void do_pause(unsigned amount) 330{ /* Pause for amount*10 milliseconds */ 331 do { 332 mdelay(10); 333 } while (--amount); 334} 335 336static void fd_mcs_make_bus_idle(struct Scsi_Host *shpnt) 337{ 338 outb(0, SCSI_Cntl_port); 339 outb(0, SCSI_Mode_Cntl_port); 340 if (chip == tmc18c50 || chip == tmc18c30) 341 outb(0x21 | PARITY_MASK, TMC_Cntl_port); /* Clear forced intr. */ 342 else 343 outb(0x01 | PARITY_MASK, TMC_Cntl_port); 344} 345 346static int fd_mcs_detect(Scsi_Host_Template * tpnt) 347{ 348 int loop; 349 struct Scsi_Host *shpnt; 350 351 /* get id, port, bios, irq */ 352 int slot; 353 u_char pos2, pos3, pos4; 354 int id, port, irq; 355 unsigned long bios; 356 357 /* if not MCA machine, return */ 358 if (!MCA_bus) 359 return 0; 360 361 /* changeable? */ 362 id = 7; 363 364 for (loop = 0; loop < FD_BRDS; loop++) { 365 slot = 0; 366 while (MCA_NOTFOUND != (slot = mca_find_adapter(fd_mcs_adapters[loop].id, slot))) { 367 368 /* if we get this far, an adapter has been detected and is 369 enabled */ 370 371 printk(KERN_INFO "scsi <fd_mcs>: %s at slot %d\n", fd_mcs_adapters[loop].name, slot + 1); 372 373 pos2 = mca_read_stored_pos(slot, 2); 374 pos3 = mca_read_stored_pos(slot, 3); 375 pos4 = mca_read_stored_pos(slot, 4); 376 377 /* ready for next probe */ 378 slot++; 379 380 if (fd_mcs_adapters[loop].id == REPLY_ID) { /* reply card */ 381 static int reply_irq[] = { 10, 11, 14, 15 }; 382 383 bios = 0; /* no bios */ 384 385 if (pos2 & 0x2) 386 port = ports[pos4 & 0x3]; 387 else 388 continue; 389 390 /* can't really disable it, same as irq=10 */ 391 irq = reply_irq[((pos4 >> 2) & 0x1) + 2 * ((pos4 >> 4) & 0x1)]; 392 } else { 393 bios = addresses[pos2 >> 6]; 394 port = ports[(pos2 >> 4) & 0x03]; 395 irq = interrupts[(pos2 >> 1) & 0x07]; 396 } 397 398 if (irq) { 399 /* claim the slot */ 400 mca_set_adapter_name(slot - 1, fd_mcs_adapters[loop].name); 401 402 /* check irq/region */ 403 if (request_irq(irq, fd_mcs_intr, SA_SHIRQ, "fd_mcs", hosts)) { 404 printk(KERN_ERR "fd_mcs: interrupt is not available, skipping...\n"); 405 continue; 406 } 407 408 /* request I/O region */ 409 if (request_region(port, 0x10, "fd_mcs")) { 410 printk(KERN_ERR "fd_mcs: I/O region is already in use, skipping...\n"); 411 continue; 412 } 413 /* register */ 414 if (!(shpnt = scsi_register(tpnt, sizeof(struct fd_hostdata)))) { 415 printk(KERN_ERR "fd_mcs: scsi_register() failed\n"); 416 release_region(port, 0x10); 417 free_irq(irq, hosts); 418 continue; 419 } 420 421 422 /* save name */ 423 strcpy(adapter_name, fd_mcs_adapters[loop].name); 424 425 /* chip/fifo */ 426 chip = fd_mcs_adapters[loop].fd_chip; 427 /* use boot time value if available */ 428 FIFO_COUNT = user_fifo_count ? user_fifo_count : fd_mcs_adapters[loop].fifo_count; 429 FIFO_Size = user_fifo_size ? user_fifo_size : fd_mcs_adapters[loop].fifo_size; 430 431/* FIXME: Do we need to keep this bit of code inside NOT_USED around at all? */ 432#ifdef NOT_USED 433 /* *************************************************** */ 434 /* Try to toggle 32-bit mode. This only 435 works on an 18c30 chip. (User reports 436 say this works, so we should switch to 437 it in the near future.) */ 438 outb(0x80, port + IO_Control); 439 if ((inb(port + Configuration2) & 0x80) == 0x80) { 440 outb(0x00, port + IO_Control); 441 if ((inb(port + Configuration2) & 0x80) == 0x00) { 442 chip = tmc18c30; 443 FIFO_Size = 0x800; /* 2k FIFO */ 444 445 printk("FIRST: chip=%s, fifo_size=0x%x\n", (chip == tmc18c30) ? "tmc18c30" : "tmc18c50", FIFO_Size); 446 } 447 } 448 449 /* That should have worked, but appears to 450 have problems. Let's assume it is an 451 18c30 if the RAM is disabled. */ 452 453 if (inb(port + Configuration2) & 0x02) { 454 chip = tmc18c30; 455 FIFO_Size = 0x800; /* 2k FIFO */ 456 457 printk("SECOND: chip=%s, fifo_size=0x%x\n", (chip == tmc18c30) ? "tmc18c30" : "tmc18c50", FIFO_Size); 458 } 459 /* *************************************************** */ 460#endif 461 462 /* IBM/ANSI scsi scan ordering */ 463 /* Stick this back in when the scsi.c changes are there */ 464 shpnt->reverse_ordering = 1; 465 466 467 /* saving info */ 468 hosts[found++] = shpnt; 469 470 shpnt->this_id = id; 471 shpnt->irq = irq; 472 shpnt->io_port = port; 473 shpnt->n_io_port = 0x10; 474 475 /* save */ 476 bios_base = bios; 477 adapter_mask = (1 << id); 478 479 /* save more */ 480 SCSI_Mode_Cntl_port = port + SCSI_Mode_Cntl; 481 FIFO_Data_Count_port = port + FIFO_Data_Count; 482 Interrupt_Cntl_port = port + Interrupt_Cntl; 483 Interrupt_Status_port = port + Interrupt_Status; 484 Interrupt_Cond_port = port + Interrupt_Cond; 485 Read_FIFO_port = port + Read_FIFO; 486 Read_SCSI_Data_port = port + Read_SCSI_Data; 487 SCSI_Cntl_port = port + SCSI_Cntl; 488 SCSI_Data_NoACK_port = port + SCSI_Data_NoACK; 489 SCSI_Status_port = port + SCSI_Status; 490 TMC_Cntl_port = port + TMC_Cntl; 491 TMC_Status_port = port + TMC_Status; 492 Write_FIFO_port = port + Write_FIFO; 493 Write_SCSI_Data_port = port + Write_SCSI_Data; 494 495 Bytes_Read = 0; 496 Bytes_Written = 0; 497 INTR_Processed = 0; 498 499 /* say something */ 500 print_banner(shpnt); 501 502 /* reset */ 503 outb(1, SCSI_Cntl_port); 504 do_pause(2); 505 outb(0, SCSI_Cntl_port); 506 do_pause(115); 507 outb(0, SCSI_Mode_Cntl_port); 508 outb(PARITY_MASK, TMC_Cntl_port); 509 /* done reset */ 510 } 511 } 512 513 if (found == FD_MAX_HOSTS) { 514 printk("fd_mcs: detecting reached max=%d host adapters.\n", FD_MAX_HOSTS); 515 break; 516 } 517 } 518 519 return found; 520} 521 522static const char *fd_mcs_info(struct Scsi_Host *shpnt) 523{ 524 return adapter_name; 525} 526 527static int TOTAL_INTR = 0; 528 529/* 530 * inout : decides on the direction of the dataflow and the meaning of the 531 * variables 532 * buffer: If inout==FALSE data is being written to it else read from it 533 * *start: If inout==FALSE start of the valid data in the buffer 534 * offset: If inout==FALSE offset from the beginning of the imaginary file 535 * from which we start writing into the buffer 536 * length: If inout==FALSE max number of bytes to be written into the buffer 537 * else number of bytes in the buffer 538 */ 539static int fd_mcs_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, int inout) 540{ 541 int len = 0; 542 543 if (inout) 544 return (-ENOSYS); 545 546 *start = buffer + offset; 547 548 len += sprintf(buffer + len, "Future Domain MCS-600/700 Driver %s\n", DRIVER_VERSION); 549 len += sprintf(buffer + len, "HOST #%d: %s\n", shpnt->host_no, adapter_name); 550 len += sprintf(buffer + len, "FIFO Size=0x%x, FIFO Count=%d\n", FIFO_Size, FIFO_COUNT); 551 len += sprintf(buffer + len, "DriverCalls=%d, Interrupts=%d, BytesRead=%d, BytesWrite=%d\n\n", TOTAL_INTR, INTR_Processed, Bytes_Read, Bytes_Written); 552 553 if ((len -= offset) <= 0) 554 return 0; 555 if (len > length) 556 len = length; 557 return len; 558} 559 560static int fd_mcs_select(struct Scsi_Host *shpnt, int target) 561{ 562 int status; 563 unsigned long timeout; 564 565 outb(0x82, SCSI_Cntl_port); /* Bus Enable + Select */ 566 outb(adapter_mask | (1 << target), SCSI_Data_NoACK_port); 567 568 /* Stop arbitration and enable parity */ 569 outb(PARITY_MASK, TMC_Cntl_port); 570 571 timeout = 350; /* 350mS -- because of timeouts 572 (was 250mS) */ 573 574 do { 575 status = inb(SCSI_Status_port); /* Read adapter status */ 576 if (status & 1) { /* Busy asserted */ 577 /* Enable SCSI Bus (on error, should make bus idle with 0) */ 578 outb(0x80, SCSI_Cntl_port); 579 return 0; 580 } 581 udelay(1000); /* wait one msec */ 582 } while (--timeout); 583 584 /* Make bus idle */ 585 fd_mcs_make_bus_idle(shpnt); 586#if EVERY_ACCESS 587 if (!target) 588 printk("Selection failed\n"); 589#endif 590#if ERRORS_ONLY 591 if (!target) { 592 static int flag = 0; 593 594 if (!flag) /* Skip first failure for all chips. */ 595 ++flag; 596 else 597 printk("fd_mcs: Selection failed\n"); 598 } 599#endif 600 return 1; 601} 602 603static void my_done(struct Scsi_Host *shpnt, int error) 604{ 605 if (in_command) { 606 in_command = 0; 607 outb(0x00, Interrupt_Cntl_port); 608 fd_mcs_make_bus_idle(shpnt); 609 current_SC->result = error; 610 current_SC->scsi_done(current_SC); 611 } else { 612 panic("fd_mcs: my_done() called outside of command\n"); 613 } 614#if DEBUG_RACE 615 in_interrupt_flag = 0; 616#endif 617} 618 619/* only my_done needs to be protected */ 620static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs) 621{ 622 unsigned long flags; 623 int status; 624 int done = 0; 625 unsigned data_count, tmp_count; 626 627 int i = 0; 628 struct Scsi_Host *shpnt; 629 630 TOTAL_INTR++; 631 632 /* search for one adapter-response on shared interrupt */ 633 while ((shpnt = hosts[i++])) { 634 if ((inb(TMC_Status_port)) & 1) 635 break; 636 } 637 638 /* return if some other device on this IRQ caused the interrupt */ 639 if (!shpnt) { 640 return IRQ_NONE; 641 } 642 643 INTR_Processed++; 644 645 outb(0x00, Interrupt_Cntl_port); 646 647 /* Abort calls my_done, so we do nothing here. */ 648 if (current_SC->SCp.phase & aborted) { 649#if DEBUG_ABORT 650 printk("Interrupt after abort, ignoring\n"); 651#endif 652 /* return IRQ_HANDLED; */ 653 } 654#if DEBUG_RACE 655 ++in_interrupt_flag; 656#endif 657 658 if (current_SC->SCp.phase & in_arbitration) { 659 status = inb(TMC_Status_port); /* Read adapter status */ 660 if (!(status & 0x02)) { 661#if EVERY_ACCESS 662 printk(" AFAIL "); 663#endif 664 spin_lock_irqsave(shpnt->host_lock, flags); 665 my_done(shpnt, DID_BUS_BUSY << 16); 666 spin_unlock_irqrestore(shpnt->host_lock, flags); 667 return IRQ_HANDLED; 668 } 669 current_SC->SCp.phase = in_selection; 670 671 outb(0x40 | FIFO_COUNT, Interrupt_Cntl_port); 672 673 outb(0x82, SCSI_Cntl_port); /* Bus Enable + Select */ 674 outb(adapter_mask | (1 << current_SC->device->id), SCSI_Data_NoACK_port); 675 676 /* Stop arbitration and enable parity */ 677 outb(0x10 | PARITY_MASK, TMC_Cntl_port); 678#if DEBUG_RACE 679 in_interrupt_flag = 0; 680#endif 681 return IRQ_HANDLED; 682 } else if (current_SC->SCp.phase & in_selection) { 683 status = inb(SCSI_Status_port); 684 if (!(status & 0x01)) { 685 /* Try again, for slow devices */ 686 if (fd_mcs_select(shpnt, current_SC->device->id)) { 687#if EVERY_ACCESS 688 printk(" SFAIL "); 689#endif 690 spin_lock_irqsave(shpnt->host_lock, flags); 691 my_done(shpnt, DID_NO_CONNECT << 16); 692 spin_unlock_irqrestore(shpnt->host_lock, flags); 693 return IRQ_HANDLED; 694 } else { 695#if EVERY_ACCESS 696 printk(" AltSel "); 697#endif 698 /* Stop arbitration and enable parity */ 699 outb(0x10 | PARITY_MASK, TMC_Cntl_port); 700 } 701 } 702 current_SC->SCp.phase = in_other; 703 outb(0x90 | FIFO_COUNT, Interrupt_Cntl_port); 704 outb(0x80, SCSI_Cntl_port); 705#if DEBUG_RACE 706 in_interrupt_flag = 0; 707#endif 708 return IRQ_HANDLED; 709 } 710 711 /* current_SC->SCp.phase == in_other: this is the body of the routine */ 712 713 status = inb(SCSI_Status_port); 714 715 if (status & 0x10) { /* REQ */ 716 717 switch (status & 0x0e) { 718 719 case 0x08: /* COMMAND OUT */ 720 outb(current_SC->cmnd[current_SC->SCp.sent_command++], Write_SCSI_Data_port); 721#if EVERY_ACCESS 722 printk("CMD = %x,", current_SC->cmnd[current_SC->SCp.sent_command - 1]); 723#endif 724 break; 725 case 0x00: /* DATA OUT -- tmc18c50/tmc18c30 only */ 726 if (chip != tmc1800 && !current_SC->SCp.have_data_in) { 727 current_SC->SCp.have_data_in = -1; 728 outb(0xd0 | PARITY_MASK, TMC_Cntl_port); 729 } 730 break; 731 case 0x04: /* DATA IN -- tmc18c50/tmc18c30 only */ 732 if (chip != tmc1800 && !current_SC->SCp.have_data_in) { 733 current_SC->SCp.have_data_in = 1; 734 outb(0x90 | PARITY_MASK, TMC_Cntl_port); 735 } 736 break; 737 case 0x0c: /* STATUS IN */ 738 current_SC->SCp.Status = inb(Read_SCSI_Data_port); 739#if EVERY_ACCESS 740 printk("Status = %x, ", current_SC->SCp.Status); 741#endif 742#if ERRORS_ONLY 743 if (current_SC->SCp.Status && current_SC->SCp.Status != 2 && current_SC->SCp.Status != 8) { 744 printk("ERROR fd_mcs: target = %d, command = %x, status = %x\n", current_SC->device->id, current_SC->cmnd[0], current_SC->SCp.Status); 745 } 746#endif 747 break; 748 case 0x0a: /* MESSAGE OUT */ 749 outb(MESSAGE_REJECT, Write_SCSI_Data_port); /* Reject */ 750 break; 751 case 0x0e: /* MESSAGE IN */ 752 current_SC->SCp.Message = inb(Read_SCSI_Data_port); 753#if EVERY_ACCESS 754 printk("Message = %x, ", current_SC->SCp.Message); 755#endif 756 if (!current_SC->SCp.Message) 757 ++done; 758#if DEBUG_MESSAGES || EVERY_ACCESS 759 if (current_SC->SCp.Message) { 760 printk("fd_mcs: message = %x\n", current_SC->SCp.Message); 761 } 762#endif 763 break; 764 } 765 } 766 767 if (chip == tmc1800 && !current_SC->SCp.have_data_in && (current_SC->SCp.sent_command >= current_SC->cmd_len)) { 768 /* We have to get the FIFO direction 769 correct, so I've made a table based 770 on the SCSI Standard of which commands 771 appear to require a DATA OUT phase. 772 */ 773 /* 774 p. 94: Command for all device types 775 CHANGE DEFINITION 40 DATA OUT 776 COMPARE 39 DATA OUT 777 COPY 18 DATA OUT 778 COPY AND VERIFY 3a DATA OUT 779 INQUIRY 12 780 LOG SELECT 4c DATA OUT 781 LOG SENSE 4d 782 MODE SELECT (6) 15 DATA OUT 783 MODE SELECT (10) 55 DATA OUT 784 MODE SENSE (6) 1a 785 MODE SENSE (10) 5a 786 READ BUFFER 3c 787 RECEIVE DIAGNOSTIC RESULTS 1c 788 REQUEST SENSE 03 789 SEND DIAGNOSTIC 1d DATA OUT 790 TEST UNIT READY 00 791 WRITE BUFFER 3b DATA OUT 792 793 p.178: Commands for direct-access devices (not listed on p. 94) 794 FORMAT UNIT 04 DATA OUT 795 LOCK-UNLOCK CACHE 36 796 PRE-FETCH 34 797 PREVENT-ALLOW MEDIUM REMOVAL 1e 798 READ (6)/RECEIVE 08 799 READ (10) 3c 800 READ CAPACITY 25 801 READ DEFECT DATA (10) 37 802 READ LONG 3e 803 REASSIGN BLOCKS 07 DATA OUT 804 RELEASE 17 805 RESERVE 16 DATA OUT 806 REZERO UNIT/REWIND 01 807 SEARCH DATA EQUAL (10) 31 DATA OUT 808 SEARCH DATA HIGH (10) 30 DATA OUT 809 SEARCH DATA LOW (10) 32 DATA OUT 810 SEEK (6) 0b 811 SEEK (10) 2b 812 SET LIMITS (10) 33 813 START STOP UNIT 1b 814 SYNCHRONIZE CACHE 35 815 VERIFY (10) 2f 816 WRITE (6)/PRINT/SEND 0a DATA OUT 817 WRITE (10)/SEND 2a DATA OUT 818 WRITE AND VERIFY (10) 2e DATA OUT 819 WRITE LONG 3f DATA OUT 820 WRITE SAME 41 DATA OUT ? 821 822 p. 261: Commands for sequential-access devices (not previously listed) 823 ERASE 19 824 LOAD UNLOAD 1b 825 LOCATE 2b 826 READ BLOCK LIMITS 05 827 READ POSITION 34 828 READ REVERSE 0f 829 RECOVER BUFFERED DATA 14 830 SPACE 11 831 WRITE FILEMARKS 10 ? 832 833 p. 298: Commands for printer devices (not previously listed) 834 ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) ***** 835 SLEW AND PRINT 0b DATA OUT -- same as seek 836 STOP PRINT 1b 837 SYNCHRONIZE BUFFER 10 838 839 p. 315: Commands for processor devices (not previously listed) 840 841 p. 321: Commands for write-once devices (not previously listed) 842 MEDIUM SCAN 38 843 READ (12) a8 844 SEARCH DATA EQUAL (12) b1 DATA OUT 845 SEARCH DATA HIGH (12) b0 DATA OUT 846 SEARCH DATA LOW (12) b2 DATA OUT 847 SET LIMITS (12) b3 848 VERIFY (12) af 849 WRITE (12) aa DATA OUT 850 WRITE AND VERIFY (12) ae DATA OUT 851 852 p. 332: Commands for CD-ROM devices (not previously listed) 853 PAUSE/RESUME 4b 854 PLAY AUDIO (10) 45 855 PLAY AUDIO (12) a5 856 PLAY AUDIO MSF 47 857 PLAY TRACK RELATIVE (10) 49 858 PLAY TRACK RELATIVE (12) a9 859 READ HEADER 44 860 READ SUB-CHANNEL 42 861 READ TOC 43 862 863 p. 370: Commands for scanner devices (not previously listed) 864 GET DATA BUFFER STATUS 34 865 GET WINDOW 25 866 OBJECT POSITION 31 867 SCAN 1b 868 SET WINDOW 24 DATA OUT 869 870 p. 391: Commands for optical memory devices (not listed) 871 ERASE (10) 2c 872 ERASE (12) ac 873 MEDIUM SCAN 38 DATA OUT 874 READ DEFECT DATA (12) b7 875 READ GENERATION 29 876 READ UPDATED BLOCK 2d 877 UPDATE BLOCK 3d DATA OUT 878 879 p. 419: Commands for medium changer devices (not listed) 880 EXCHANGE MEDIUM 46 881 INITIALIZE ELEMENT STATUS 07 882 MOVE MEDIUM a5 883 POSITION TO ELEMENT 2b 884 READ ELEMENT STATUS b8 885 REQUEST VOL. ELEMENT ADDRESS b5 886 SEND VOLUME TAG b6 DATA OUT 887 888 p. 454: Commands for communications devices (not listed previously) 889 GET MESSAGE (6) 08 890 GET MESSAGE (10) 28 891 GET MESSAGE (12) a8 892 */ 893 894 switch (current_SC->cmnd[0]) { 895 case CHANGE_DEFINITION: 896 case COMPARE: 897 case COPY: 898 case COPY_VERIFY: 899 case LOG_SELECT: 900 case MODE_SELECT: 901 case MODE_SELECT_10: 902 case SEND_DIAGNOSTIC: 903 case WRITE_BUFFER: 904 905 case FORMAT_UNIT: 906 case REASSIGN_BLOCKS: 907 case RESERVE: 908 case SEARCH_EQUAL: 909 case SEARCH_HIGH: 910 case SEARCH_LOW: 911 case WRITE_6: 912 case WRITE_10: 913 case WRITE_VERIFY: 914 case 0x3f: 915 case 0x41: 916 917 case 0xb1: 918 case 0xb0: 919 case 0xb2: 920 case 0xaa: 921 case 0xae: 922 923 case 0x24: 924 925 case 0x38: 926 case 0x3d: 927 928 case 0xb6: 929 930 case 0xea: /* alternate number for WRITE LONG */ 931 932 current_SC->SCp.have_data_in = -1; 933 outb(0xd0 | PARITY_MASK, TMC_Cntl_port); 934 break; 935 936 case 0x00: 937 default: 938 939 current_SC->SCp.have_data_in = 1; 940 outb(0x90 | PARITY_MASK, TMC_Cntl_port); 941 break; 942 } 943 } 944 945 if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */ 946 while ((data_count = FIFO_Size - inw(FIFO_Data_Count_port)) > 512) { 947#if EVERY_ACCESS 948 printk("DC=%d, ", data_count); 949#endif 950 if (data_count > current_SC->SCp.this_residual) 951 data_count = current_SC->SCp.this_residual; 952 if (data_count > 0) { 953#if EVERY_ACCESS 954 printk("%d OUT, ", data_count); 955#endif 956 if (data_count == 1) { 957 Bytes_Written++; 958 959 outb(*current_SC->SCp.ptr++, Write_FIFO_port); 960 --current_SC->SCp.this_residual; 961 } else { 962 data_count >>= 1; 963 tmp_count = data_count << 1; 964 outsw(Write_FIFO_port, current_SC->SCp.ptr, data_count); 965 current_SC->SCp.ptr += tmp_count; 966 Bytes_Written += tmp_count; 967 current_SC->SCp.this_residual -= tmp_count; 968 } 969 } 970 if (!current_SC->SCp.this_residual) { 971 if (current_SC->SCp.buffers_residual) { 972 --current_SC->SCp.buffers_residual; 973 ++current_SC->SCp.buffer; 974 current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset; 975 current_SC->SCp.this_residual = current_SC->SCp.buffer->length; 976 } else 977 break; 978 } 979 } 980 } else if (current_SC->SCp.have_data_in == 1) { /* DATA IN */ 981 while ((data_count = inw(FIFO_Data_Count_port)) > 0) { 982#if EVERY_ACCESS 983 printk("DC=%d, ", data_count); 984#endif 985 if (data_count > current_SC->SCp.this_residual) 986 data_count = current_SC->SCp.this_residual; 987 if (data_count) { 988#if EVERY_ACCESS 989 printk("%d IN, ", data_count); 990#endif 991 if (data_count == 1) { 992 Bytes_Read++; 993 *current_SC->SCp.ptr++ = inb(Read_FIFO_port); 994 --current_SC->SCp.this_residual; 995 } else { 996 data_count >>= 1; /* Number of words */ 997 tmp_count = data_count << 1; 998 insw(Read_FIFO_port, current_SC->SCp.ptr, data_count); 999 current_SC->SCp.ptr += tmp_count; 1000 Bytes_Read += tmp_count; 1001 current_SC->SCp.this_residual -= tmp_count; 1002 } 1003 } 1004 if (!current_SC->SCp.this_residual && current_SC->SCp.buffers_residual) { 1005 --current_SC->SCp.buffers_residual; 1006 ++current_SC->SCp.buffer; 1007 current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset; 1008 current_SC->SCp.this_residual = current_SC->SCp.buffer->length; 1009 } 1010 } 1011 } 1012 1013 if (done) { 1014#if EVERY_ACCESS 1015 printk(" ** IN DONE %d ** ", current_SC->SCp.have_data_in); 1016#endif 1017 1018#if ERRORS_ONLY 1019 if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) { 1020 if ((unsigned char) (*((char *) current_SC->request_buffer + 2)) & 0x0f) { 1021 unsigned char key; 1022 unsigned char code; 1023 unsigned char qualifier; 1024 1025 key = (unsigned char) (*((char *) current_SC->request_buffer + 2)) & 0x0f; 1026 code = (unsigned char) (*((char *) current_SC->request_buffer + 12)); 1027 qualifier = (unsigned char) (*((char *) current_SC->request_buffer + 13)); 1028 1029 if (key != UNIT_ATTENTION && !(key == NOT_READY && code == 0x04 && (!qualifier || qualifier == 0x02 || qualifier == 0x01)) 1030 && !(key == ILLEGAL_REQUEST && (code == 0x25 || code == 0x24 || !code))) 1031 1032 printk("fd_mcs: REQUEST SENSE " "Key = %x, Code = %x, Qualifier = %x\n", key, code, qualifier); 1033 } 1034 } 1035#endif 1036#if EVERY_ACCESS 1037 printk("BEFORE MY_DONE. . ."); 1038#endif 1039 spin_lock_irqsave(shpnt->host_lock, flags); 1040 my_done(shpnt, (current_SC->SCp.Status & 0xff) 1041 | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16)); 1042 spin_unlock_irqrestore(shpnt->host_lock, flags); 1043#if EVERY_ACCESS 1044 printk("RETURNING.\n"); 1045#endif 1046 1047 } else { 1048 if (current_SC->SCp.phase & disconnect) { 1049 outb(0xd0 | FIFO_COUNT, Interrupt_Cntl_port); 1050 outb(0x00, SCSI_Cntl_port); 1051 } else { 1052 outb(0x90 | FIFO_COUNT, Interrupt_Cntl_port); 1053 } 1054 } 1055#if DEBUG_RACE 1056 in_interrupt_flag = 0; 1057#endif 1058 return IRQ_HANDLED; 1059} 1060 1061static int fd_mcs_release(struct Scsi_Host *shpnt) 1062{ 1063 int i, this_host, irq_usage; 1064 1065 release_region(shpnt->io_port, shpnt->n_io_port); 1066 1067 this_host = -1; 1068 irq_usage = 0; 1069 for (i = 0; i < found; i++) { 1070 if (shpnt == hosts[i]) 1071 this_host = i; 1072 if (shpnt->irq == hosts[i]->irq) 1073 irq_usage++; 1074 } 1075 1076 /* only for the last one */ 1077 if (1 == irq_usage) 1078 free_irq(shpnt->irq, hosts); 1079 1080 found--; 1081 1082 for (i = this_host; i < found; i++) 1083 hosts[i] = hosts[i + 1]; 1084 1085 hosts[found] = NULL; 1086 1087 return 0; 1088} 1089 1090static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) 1091{ 1092 struct Scsi_Host *shpnt = SCpnt->device->host; 1093 1094 if (in_command) { 1095 panic("fd_mcs: fd_mcs_queue() NOT REENTRANT!\n"); 1096 } 1097#if EVERY_ACCESS 1098 printk("queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n", SCpnt->target, *(unsigned char *) SCpnt->cmnd, SCpnt->use_sg, SCpnt->request_bufflen); 1099#endif 1100 1101 fd_mcs_make_bus_idle(shpnt); 1102 1103 SCpnt->scsi_done = done; /* Save this for the done function */ 1104 current_SC = SCpnt; 1105 1106 /* Initialize static data */ 1107 1108 if (current_SC->use_sg) { 1109 current_SC->SCp.buffer = (struct scatterlist *) current_SC->request_buffer; 1110 current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset; 1111 current_SC->SCp.this_residual = current_SC->SCp.buffer->length; 1112 current_SC->SCp.buffers_residual = current_SC->use_sg - 1; 1113 } else { 1114 current_SC->SCp.ptr = (char *) current_SC->request_buffer; 1115 current_SC->SCp.this_residual = current_SC->request_bufflen; 1116 current_SC->SCp.buffer = NULL; 1117 current_SC->SCp.buffers_residual = 0; 1118 } 1119 1120 1121 current_SC->SCp.Status = 0; 1122 current_SC->SCp.Message = 0; 1123 current_SC->SCp.have_data_in = 0; 1124 current_SC->SCp.sent_command = 0; 1125 current_SC->SCp.phase = in_arbitration; 1126 1127 /* Start arbitration */ 1128 outb(0x00, Interrupt_Cntl_port); 1129 outb(0x00, SCSI_Cntl_port); /* Disable data drivers */ 1130 outb(adapter_mask, SCSI_Data_NoACK_port); /* Set our id bit */ 1131 in_command = 1; 1132 outb(0x20, Interrupt_Cntl_port); 1133 outb(0x14 | PARITY_MASK, TMC_Cntl_port); /* Start arbitration */ 1134 1135 return 0; 1136} 1137 1138#if DEBUG_ABORT || DEBUG_RESET 1139static void fd_mcs_print_info(Scsi_Cmnd * SCpnt) 1140{ 1141 unsigned int imr; 1142 unsigned int irr; 1143 unsigned int isr; 1144 struct Scsi_Host *shpnt = SCpnt->host; 1145 1146 if (!SCpnt || !SCpnt->host) { 1147 printk("fd_mcs: cannot provide detailed information\n"); 1148 } 1149 1150 printk("%s\n", fd_mcs_info(SCpnt->host)); 1151 print_banner(SCpnt->host); 1152 switch (SCpnt->SCp.phase) { 1153 case in_arbitration: 1154 printk("arbitration "); 1155 break; 1156 case in_selection: 1157 printk("selection "); 1158 break; 1159 case in_other: 1160 printk("other "); 1161 break; 1162 default: 1163 printk("unknown "); 1164 break; 1165 } 1166 1167 printk("(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n", SCpnt->SCp.phase, SCpnt->device->id, *(unsigned char *) SCpnt->cmnd, SCpnt->use_sg, SCpnt->request_bufflen); 1168 printk("sent_command = %d, have_data_in = %d, timeout = %d\n", SCpnt->SCp.sent_command, SCpnt->SCp.have_data_in, SCpnt->timeout); 1169#if DEBUG_RACE 1170 printk("in_interrupt_flag = %d\n", in_interrupt_flag); 1171#endif 1172 1173 imr = (inb(0x0a1) << 8) + inb(0x21); 1174 outb(0x0a, 0xa0); 1175 irr = inb(0xa0) << 8; 1176 outb(0x0a, 0x20); 1177 irr += inb(0x20); 1178 outb(0x0b, 0xa0); 1179 isr = inb(0xa0) << 8; 1180 outb(0x0b, 0x20); 1181 isr += inb(0x20); 1182 1183 /* Print out interesting information */ 1184 printk("IMR = 0x%04x", imr); 1185 if (imr & (1 << shpnt->irq)) 1186 printk(" (masked)"); 1187 printk(", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr); 1188 1189 printk("SCSI Status = 0x%02x\n", inb(SCSI_Status_port)); 1190 printk("TMC Status = 0x%02x", inb(TMC_Status_port)); 1191 if (inb(TMC_Status_port) & 1) 1192 printk(" (interrupt)"); 1193 printk("\n"); 1194 printk("Interrupt Status = 0x%02x", inb(Interrupt_Status_port)); 1195 if (inb(Interrupt_Status_port) & 0x08) 1196 printk(" (enabled)"); 1197 printk("\n"); 1198 if (chip == tmc18c50 || chip == tmc18c30) { 1199 printk("FIFO Status = 0x%02x\n", inb(shpnt->io_port + FIFO_Status)); 1200 printk("Int. Condition = 0x%02x\n", inb(shpnt->io_port + Interrupt_Cond)); 1201 } 1202 printk("Configuration 1 = 0x%02x\n", inb(shpnt->io_port + Configuration1)); 1203 if (chip == tmc18c50 || chip == tmc18c30) 1204 printk("Configuration 2 = 0x%02x\n", inb(shpnt->io_port + Configuration2)); 1205} 1206#endif 1207 1208static int fd_mcs_abort(Scsi_Cmnd * SCpnt) 1209{ 1210 struct Scsi_Host *shpnt = SCpnt->device->host; 1211 1212 unsigned long flags; 1213#if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT 1214 printk("fd_mcs: abort "); 1215#endif 1216 1217 spin_lock_irqsave(shpnt->host_lock, flags); 1218 if (!in_command) { 1219#if EVERY_ACCESS || ERRORS_ONLY 1220 printk(" (not in command)\n"); 1221#endif 1222 spin_unlock_irqrestore(shpnt->host_lock, flags); 1223 return FAILED; 1224 } else 1225 printk("\n"); 1226 1227#if DEBUG_ABORT 1228 fd_mcs_print_info(SCpnt); 1229#endif 1230 1231 fd_mcs_make_bus_idle(shpnt); 1232 1233 current_SC->SCp.phase |= aborted; 1234 1235 current_SC->result = DID_ABORT << 16; 1236 1237 /* Aborts are not done well. . . */ 1238 my_done(shpnt, DID_ABORT << 16); 1239 1240 spin_unlock_irqrestore(shpnt->host_lock, flags); 1241 return SUCCESS; 1242} 1243 1244static int fd_mcs_host_reset(Scsi_Cmnd * SCpnt) 1245{ 1246 return FAILED; 1247} 1248 1249static int fd_mcs_device_reset(Scsi_Cmnd * SCpnt) 1250{ 1251 return FAILED; 1252} 1253 1254static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) { 1255 struct Scsi_Host *shpnt = SCpnt->device->host; 1256 1257#if DEBUG_RESET 1258 static int called_once = 0; 1259#endif 1260 1261#if ERRORS_ONLY 1262 if (SCpnt) 1263 printk("fd_mcs: SCSI Bus Reset\n"); 1264#endif 1265 1266#if DEBUG_RESET 1267 if (called_once) 1268 fd_mcs_print_info(current_SC); 1269 called_once = 1; 1270#endif 1271 1272 outb(1, SCSI_Cntl_port); 1273 do_pause(2); 1274 outb(0, SCSI_Cntl_port); 1275 do_pause(115); 1276 outb(0, SCSI_Mode_Cntl_port); 1277 outb(PARITY_MASK, TMC_Cntl_port); 1278 1279 /* Unless this is the very first call (i.e., SCPnt == NULL), everything 1280 is probably hosed at this point. We will, however, try to keep 1281 things going by informing the high-level code that we need help. */ 1282 return SUCCESS; 1283} 1284 1285#include <scsi/scsi_ioctl.h> 1286 1287static int fd_mcs_biosparam(struct scsi_device * disk, struct block_device *bdev, 1288 sector_t capacity, int *info_array) 1289{ 1290 unsigned char *p = scsi_bios_ptable(bdev); 1291 int size = capacity; 1292 1293 /* BIOS >= 3.4 for MCA cards */ 1294 /* This algorithm was provided by Future Domain (much thanks!). */ 1295 1296 if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */ 1297 && p[4]) { /* Partition type */ 1298 /* The partition table layout is as follows: 1299 1300 Start: 0x1b3h 1301 Offset: 0 = partition status 1302 1 = starting head 1303 2 = starting sector and cylinder (word, encoded) 1304 4 = partition type 1305 5 = ending head 1306 6 = ending sector and cylinder (word, encoded) 1307 8 = starting absolute sector (double word) 1308 c = number of sectors (double word) 1309 Signature: 0x1fe = 0x55aa 1310 1311 So, this algorithm assumes: 1312 1) the first partition table is in use, 1313 2) the data in the first entry is correct, and 1314 3) partitions never divide cylinders 1315 1316 Note that (1) may be FALSE for NetBSD (and other BSD flavors), 1317 as well as for Linux. Note also, that Linux doesn't pay any 1318 attention to the fields that are used by this algorithm -- it 1319 only uses the absolute sector data. Recent versions of Linux's 1320 fdisk(1) will fill this data in correctly, and forthcoming 1321 versions will check for consistency. 1322 1323 Checking for a non-zero partition type is not part of the 1324 Future Domain algorithm, but it seemed to be a reasonable thing 1325 to do, especially in the Linux and BSD worlds. */ 1326 1327 info_array[0] = p[5] + 1; /* heads */ 1328 info_array[1] = p[6] & 0x3f; /* sectors */ 1329 } else { 1330 /* Note that this new method guarantees that there will always be 1331 less than 1024 cylinders on a platter. This is good for drives 1332 up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */ 1333 if ((unsigned int) size >= 0x7e0000U) 1334 { 1335 info_array[0] = 0xff; /* heads = 255 */ 1336 info_array[1] = 0x3f; /* sectors = 63 */ 1337 } else if ((unsigned int) size >= 0x200000U) { 1338 info_array[0] = 0x80; /* heads = 128 */ 1339 info_array[1] = 0x3f; /* sectors = 63 */ 1340 } else { 1341 info_array[0] = 0x40; /* heads = 64 */ 1342 info_array[1] = 0x20; /* sectors = 32 */ 1343 } 1344 } 1345 /* For both methods, compute the cylinders */ 1346 info_array[2] = (unsigned int) size / (info_array[0] * info_array[1]); 1347 kfree(p); 1348 return 0; 1349} 1350 1351static Scsi_Host_Template driver_template = { 1352 .proc_name = "fd_mcs", 1353 .proc_info = fd_mcs_proc_info, 1354 .detect = fd_mcs_detect, 1355 .release = fd_mcs_release, 1356 .info = fd_mcs_info, 1357 .queuecommand = fd_mcs_queue, 1358 .eh_abort_handler = fd_mcs_abort, 1359 .eh_bus_reset_handler = fd_mcs_bus_reset, 1360 .eh_host_reset_handler = fd_mcs_host_reset, 1361 .eh_device_reset_handler = fd_mcs_device_reset, 1362 .bios_param = fd_mcs_biosparam, 1363 .can_queue = 1, 1364 .this_id = 7, 1365 .sg_tablesize = 64, 1366 .cmd_per_lun = 1, 1367 .use_clustering = DISABLE_CLUSTERING, 1368}; 1369#include "scsi_module.c" 1370