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