1 /* fd_mcs.c -- Future Domain MCS 600/700 (or IBM OEM) driver
3 * FutureDomain MCS-600/700 v0.2 03/11/1998 by ZP Gu (zpg@castle.net)
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
10 * This driver also supports Reply SB16/SCSI card (the SCSI part).
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.
17 * Assumptions: TMC-1800/18C50/18C30, BIOS >= 3.4
19 * LILO command-line options:
20 * fd_mcs=<FIFO_COUNT>[,<FIFO_SIZE>]
22 * ********************************************************
23 * Please see Copyrights/Comments in fdomain.* for credits.
24 * Following is from fdomain.c for acknowledgement:
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
31 * $Id: fdomain.c,v 5.45 1996/10/02 15:13:06 root Exp $
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
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.
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.
47 **************************************************************************
49 NOTES ON USER DEFINABLE OPTIONS:
51 DEBUG: This turns on the printing of various debug information.
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.
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*****]
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.
78 **************************************************************************/
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>
95 #include <asm/system.h>
98 #include <scsi/scsi_host.h>
101 #define DRIVER_VERSION "v0.2 by ZP Gu<zpg@castle.net>"
103 /* START OF USER DEFINABLE OPTIONS */
105 #define DEBUG 0 /* Enable debugging output */
106 #define ENABLE_PARITY 1 /* Enable SCSI Parity */
107 #define DO_DETECT 0 /* Do device detection here (see scsi.c) */
109 /* END OF USER DEFINABLE OPTIONS */
112 #define EVERY_ACCESS 0 /* Write a line on every scsi access */
113 #define ERRORS_ONLY 1 /* Only write a line if there is an error */
114 #define DEBUG_DETECT 1 /* Debug fd_mcs_detect() */
115 #define DEBUG_MESSAGES 1 /* Debug MESSAGE IN phase */
116 #define DEBUG_ABORT 1 /* Debug abort() routine */
117 #define DEBUG_RESET 1 /* Debug reset() routine */
118 #define DEBUG_RACE 1 /* Debug interrupt-driven race condition */
120 #define EVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
121 #define ERRORS_ONLY 0
122 #define DEBUG_DETECT 0
123 #define DEBUG_MESSAGES 0
124 #define DEBUG_ABORT 0
125 #define DEBUG_RESET 0
129 /* Errors are reported on the line, so we don't need to report them again */
132 #define ERRORS_ONLY 0
136 #define PARITY_MASK 0x08
138 #define PARITY_MASK 0x00
149 in_arbitration = 0x02,
161 FIFO_Status = 3, /* tmc18c50/tmc18c30 only */
162 Interrupt_Cond = 4, /* tmc18c50/tmc18c30 only */
167 Interrupt_Status = 9,
169 Configuration2 = 11, /* tmc18c50/tmc18c30 only */
180 Memory_Cntl = 5, /* tmc18c50/tmc18c30 only */
182 IO_Control = 11, /* tmc18c30 only */
187 unsigned long _bios_base;
190 volatile int _in_command;
191 Scsi_Cmnd *_current_SC;
192 enum chip_type _chip;
194 int _fifo_count; /* Number of 512 byte blocks before INTR */
196 char _adapter_name[64];
198 volatile int _in_interrupt_flag;
201 int _SCSI_Mode_Cntl_port;
202 int _FIFO_Data_Count_port;
203 int _Interrupt_Cntl_port;
204 int _Interrupt_Status_port;
205 int _Interrupt_Cond_port;
207 int _Read_SCSI_Data_port;
209 int _SCSI_Data_NoACK_port;
210 int _SCSI_Status_port;
212 int _TMC_Status_port;
213 int _Write_FIFO_port;
214 int _Write_SCSI_Data_port;
216 int _FIFO_Size; /* = 0x2000; 8k FIFO for
217 pre-tmc18c30 chips */
224 #define FD_MAX_HOSTS 3 /* enough? */
226 #define HOSTDATA(shpnt) ((struct fd_hostdata *) shpnt->hostdata)
227 #define bios_base (HOSTDATA(shpnt)->_bios_base)
228 #define bios_major (HOSTDATA(shpnt)->_bios_major)
229 #define bios_minor (HOSTDATA(shpnt)->_bios_minor)
230 #define in_command (HOSTDATA(shpnt)->_in_command)
231 #define current_SC (HOSTDATA(shpnt)->_current_SC)
232 #define chip (HOSTDATA(shpnt)->_chip)
233 #define adapter_mask (HOSTDATA(shpnt)->_adapter_mask)
234 #define FIFO_COUNT (HOSTDATA(shpnt)->_fifo_count)
235 #define adapter_name (HOSTDATA(shpnt)->_adapter_name)
237 #define in_interrupt_flag (HOSTDATA(shpnt)->_in_interrupt_flag)
239 #define SCSI_Mode_Cntl_port (HOSTDATA(shpnt)->_SCSI_Mode_Cntl_port)
240 #define FIFO_Data_Count_port (HOSTDATA(shpnt)->_FIFO_Data_Count_port)
241 #define Interrupt_Cntl_port (HOSTDATA(shpnt)->_Interrupt_Cntl_port)
242 #define Interrupt_Status_port (HOSTDATA(shpnt)->_Interrupt_Status_port)
243 #define Interrupt_Cond_port (HOSTDATA(shpnt)->_Interrupt_Cond_port)
244 #define Read_FIFO_port (HOSTDATA(shpnt)->_Read_FIFO_port)
245 #define Read_SCSI_Data_port (HOSTDATA(shpnt)->_Read_SCSI_Data_port)
246 #define SCSI_Cntl_port (HOSTDATA(shpnt)->_SCSI_Cntl_port)
247 #define SCSI_Data_NoACK_port (HOSTDATA(shpnt)->_SCSI_Data_NoACK_port)
248 #define SCSI_Status_port (HOSTDATA(shpnt)->_SCSI_Status_port)
249 #define TMC_Cntl_port (HOSTDATA(shpnt)->_TMC_Cntl_port)
250 #define TMC_Status_port (HOSTDATA(shpnt)->_TMC_Status_port)
251 #define Write_FIFO_port (HOSTDATA(shpnt)->_Write_FIFO_port)
252 #define Write_SCSI_Data_port (HOSTDATA(shpnt)->_Write_SCSI_Data_port)
253 #define FIFO_Size (HOSTDATA(shpnt)->_FIFO_Size)
254 #define Bytes_Read (HOSTDATA(shpnt)->_Bytes_Read)
255 #define Bytes_Written (HOSTDATA(shpnt)->_Bytes_Written)
256 #define INTR_Processed (HOSTDATA(shpnt)->_INTR_Processed)
258 struct fd_mcs_adapters_struct {
261 enum chip_type fd_chip;
266 #define REPLY_ID 0x5137
268 static struct fd_mcs_adapters_struct fd_mcs_adapters[] = {
269 {"Future Domain SCSI Adapter MCS-700(18C50)",
274 {"Future Domain SCSI Adapter MCS-600/700(TMC-1800)",
279 {"Reply Sound Blaster/SCSI Adapter",
286 #define FD_BRDS sizeof(fd_mcs_adapters)/sizeof(struct fd_mcs_adapters_struct)
288 static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs);
290 static unsigned long addresses[] = { 0xc8000, 0xca000, 0xce000, 0xde000 };
291 static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
292 static unsigned short interrupts[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
294 /* host information */
295 static int found = 0;
296 static struct Scsi_Host *hosts[FD_MAX_HOSTS + 1] = { NULL };
298 static int user_fifo_count = 0;
299 static int user_fifo_size = 0;
301 static int __init fd_mcs_setup(char *str)
303 static int done_setup = 0;
306 get_options(str, 3, ints);
307 if (done_setup++ || ints[0] < 1 || ints[0] > 2 || ints[1] < 1 || ints[1] > 16) {
308 printk("fd_mcs: usage: fd_mcs=FIFO_COUNT, FIFO_SIZE\n");
312 user_fifo_count = ints[0] >= 1 ? ints[1] : 0;
313 user_fifo_size = ints[0] >= 2 ? ints[2] : 0;
317 __setup("fd_mcs=", fd_mcs_setup);
319 static void print_banner(struct Scsi_Host *shpnt)
321 printk("scsi%d <fd_mcs>: ", shpnt->host_no);
324 printk("BIOS at 0x%lX", bios_base);
329 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);
333 static void do_pause(unsigned amount)
334 { /* Pause for amount*10 milliseconds */
340 static void fd_mcs_make_bus_idle(struct Scsi_Host *shpnt)
342 outb(0, SCSI_Cntl_port);
343 outb(0, SCSI_Mode_Cntl_port);
344 if (chip == tmc18c50 || chip == tmc18c30)
345 outb(0x21 | PARITY_MASK, TMC_Cntl_port); /* Clear forced intr. */
347 outb(0x01 | PARITY_MASK, TMC_Cntl_port);
350 static int fd_mcs_detect(Scsi_Host_Template * tpnt)
353 struct Scsi_Host *shpnt;
355 /* get id, port, bios, irq */
357 u_char pos2, pos3, pos4;
361 /* if not MCA machine, return */
368 for (loop = 0; loop < FD_BRDS; loop++) {
370 while (MCA_NOTFOUND != (slot = mca_find_adapter(fd_mcs_adapters[loop].id, slot))) {
372 /* if we get this far, an adapter has been detected and is
375 printk(KERN_INFO "scsi <fd_mcs>: %s at slot %d\n", fd_mcs_adapters[loop].name, slot + 1);
377 pos2 = mca_read_stored_pos(slot, 2);
378 pos3 = mca_read_stored_pos(slot, 3);
379 pos4 = mca_read_stored_pos(slot, 4);
381 /* ready for next probe */
384 if (fd_mcs_adapters[loop].id == REPLY_ID) { /* reply card */
385 static int reply_irq[] = { 10, 11, 14, 15 };
387 bios = 0; /* no bios */
390 port = ports[pos4 & 0x3];
394 /* can't really disable it, same as irq=10 */
395 irq = reply_irq[((pos4 >> 2) & 0x1) + 2 * ((pos4 >> 4) & 0x1)];
397 bios = addresses[pos2 >> 6];
398 port = ports[(pos2 >> 4) & 0x03];
399 irq = interrupts[(pos2 >> 1) & 0x07];
404 mca_set_adapter_name(slot - 1, fd_mcs_adapters[loop].name);
406 /* check irq/region */
407 if (request_irq(irq, fd_mcs_intr, SA_SHIRQ, "fd_mcs", hosts)) {
408 printk(KERN_ERR "fd_mcs: interrupt is not available, skipping...\n");
412 /* request I/O region */
413 if (request_region(port, 0x10, "fd_mcs")) {
414 printk(KERN_ERR "fd_mcs: I/O region is already in use, skipping...\n");
418 if (!(shpnt = scsi_register(tpnt, sizeof(struct fd_hostdata)))) {
419 printk(KERN_ERR "fd_mcs: scsi_register() failed\n");
420 release_region(port, 0x10);
421 free_irq(irq, hosts);
427 strcpy(adapter_name, fd_mcs_adapters[loop].name);
430 chip = fd_mcs_adapters[loop].fd_chip;
431 /* use boot time value if available */
432 FIFO_COUNT = user_fifo_count ? user_fifo_count : fd_mcs_adapters[loop].fifo_count;
433 FIFO_Size = user_fifo_size ? user_fifo_size : fd_mcs_adapters[loop].fifo_size;
436 /* *************************************************** */
437 /* Try to toggle 32-bit mode. This only
438 works on an 18c30 chip. (User reports
439 say this works, so we should switch to
440 it in the near future.) */
441 outb(0x80, port + IO_Control);
442 if ((inb(port + Configuration2) & 0x80) == 0x80) {
443 outb(0x00, port + IO_Control);
444 if ((inb(port + Configuration2) & 0x80) == 0x00) {
446 FIFO_Size = 0x800; /* 2k FIFO */
448 printk("FIRST: chip=%s, fifo_size=0x%x\n", (chip == tmc18c30) ? "tmc18c30" : "tmc18c50", FIFO_Size);
452 /* That should have worked, but appears to
453 have problems. Let's assume it is an
454 18c30 if the RAM is disabled. */
456 if (inb(port + Configuration2) & 0x02) {
458 FIFO_Size = 0x800; /* 2k FIFO */
460 printk("SECOND: chip=%s, fifo_size=0x%x\n", (chip == tmc18c30) ? "tmc18c30" : "tmc18c50", FIFO_Size);
462 /* *************************************************** */
465 /* IBM/ANSI scsi scan ordering */
466 /* Stick this back in when the scsi.c changes are there */
467 shpnt->reverse_ordering = 1;
471 hosts[found++] = shpnt;
475 shpnt->io_port = port;
476 shpnt->n_io_port = 0x10;
480 adapter_mask = (1 << id);
483 SCSI_Mode_Cntl_port = port + SCSI_Mode_Cntl;
484 FIFO_Data_Count_port = port + FIFO_Data_Count;
485 Interrupt_Cntl_port = port + Interrupt_Cntl;
486 Interrupt_Status_port = port + Interrupt_Status;
487 Interrupt_Cond_port = port + Interrupt_Cond;
488 Read_FIFO_port = port + Read_FIFO;
489 Read_SCSI_Data_port = port + Read_SCSI_Data;
490 SCSI_Cntl_port = port + SCSI_Cntl;
491 SCSI_Data_NoACK_port = port + SCSI_Data_NoACK;
492 SCSI_Status_port = port + SCSI_Status;
493 TMC_Cntl_port = port + TMC_Cntl;
494 TMC_Status_port = port + TMC_Status;
495 Write_FIFO_port = port + Write_FIFO;
496 Write_SCSI_Data_port = port + Write_SCSI_Data;
506 outb(1, SCSI_Cntl_port);
508 outb(0, SCSI_Cntl_port);
510 outb(0, SCSI_Mode_Cntl_port);
511 outb(PARITY_MASK, TMC_Cntl_port);
515 /* scan devices attached */
517 const int buflen = 255;
520 unsigned char do_inquiry[] = { INQUIRY, 0, 0, 0, buflen, 0 };
521 unsigned char do_request_sense[] = { REQUEST_SENSE,
524 unsigned char do_read_capacity[] = { READ_CAPACITY,
525 0, 0, 0, 0, 0, 0, 0, 0, 0
527 unsigned char buf[buflen];
529 SCinit.request_buffer = SCinit.buffer = buf;
530 SCinit.request_bufflen = SCinit.bufflen = sizeof(buf) - 1;
535 printk("fd_mcs: detection routine scanning for devices:\n");
536 for (i = 0; i < 8; i++) {
537 if (i == shpnt->this_id) /* Skip host adapter */
540 memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
541 retcode = fd_mcs_command(&SCinit);
543 memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
544 retcode = fd_mcs_command(&SCinit);
546 printk(" SCSI ID %d: ", i);
547 for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
548 printk("%c", buf[j] >= 20 ? buf[j] : ' ');
549 memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
550 retcode = fd_mcs_command(&SCinit);
552 unsigned long blocks, size, capacity;
554 blocks = (buf[0] << 24) | (buf[1] << 16)
555 | (buf[2] << 8) | buf[3];
556 size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
557 capacity = +(+(blocks / 1024L) * +(size * 10L)) / 1024L;
559 printk("%lu MB (%lu byte blocks)\n", ((capacity + 5L) / 10L), size);
569 if (found == FD_MAX_HOSTS) {
570 printk("fd_mcs: detecting reached max=%d host adapters.\n", FD_MAX_HOSTS);
578 static const char *fd_mcs_info(struct Scsi_Host *shpnt)
583 static int TOTAL_INTR = 0;
586 * inout : decides on the direction of the dataflow and the meaning of the
588 * buffer: If inout==FALSE data is being written to it else read from it
589 * *start: If inout==FALSE start of the valid data in the buffer
590 * offset: If inout==FALSE offset from the beginning of the imaginary file
591 * from which we start writing into the buffer
592 * length: If inout==FALSE max number of bytes to be written into the buffer
593 * else number of bytes in the buffer
595 static int fd_mcs_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, int inout)
602 *start = buffer + offset;
604 len += sprintf(buffer + len, "Future Domain MCS-600/700 Driver %s\n", DRIVER_VERSION);
605 len += sprintf(buffer + len, "HOST #%d: %s\n", shpnt->host_no, adapter_name);
606 len += sprintf(buffer + len, "FIFO Size=0x%x, FIFO Count=%d\n", FIFO_Size, FIFO_COUNT);
607 len += sprintf(buffer + len, "DriverCalls=%d, Interrupts=%d, BytesRead=%d, BytesWrite=%d\n\n", TOTAL_INTR, INTR_Processed, Bytes_Read, Bytes_Written);
609 if ((len -= offset) <= 0)
616 static int fd_mcs_select(struct Scsi_Host *shpnt, int target)
619 unsigned long timeout;
621 outb(0x82, SCSI_Cntl_port); /* Bus Enable + Select */
622 outb(adapter_mask | (1 << target), SCSI_Data_NoACK_port);
624 /* Stop arbitration and enable parity */
625 outb(PARITY_MASK, TMC_Cntl_port);
627 timeout = 350; /* 350mS -- because of timeouts
631 status = inb(SCSI_Status_port); /* Read adapter status */
632 if (status & 1) { /* Busy asserted */
633 /* Enable SCSI Bus (on error, should make bus idle with 0) */
634 outb(0x80, SCSI_Cntl_port);
637 udelay(1000); /* wait one msec */
641 fd_mcs_make_bus_idle(shpnt);
644 printk("Selection failed\n");
650 if (!flag) /* Skip first failure for all chips. */
653 printk("fd_mcs: Selection failed\n");
659 static void my_done(struct Scsi_Host *shpnt, int error)
663 outb(0x00, Interrupt_Cntl_port);
664 fd_mcs_make_bus_idle(shpnt);
665 current_SC->result = error;
666 current_SC->scsi_done(current_SC);
668 panic("fd_mcs: my_done() called outside of command\n");
671 in_interrupt_flag = 0;
675 /* only my_done needs to be protected */
676 static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs)
681 unsigned data_count, tmp_count;
684 struct Scsi_Host *shpnt;
688 /* search for one adapter-response on shared interrupt */
689 while ((shpnt = hosts[i++])) {
690 if ((inb(TMC_Status_port)) & 1)
694 /* return if some other device on this IRQ caused the interrupt */
701 outb(0x00, Interrupt_Cntl_port);
703 /* Abort calls my_done, so we do nothing here. */
704 if (current_SC->SCp.phase & aborted) {
706 printk("Interrupt after abort, ignoring\n");
708 /* return IRQ_HANDLED; */
714 if (current_SC->SCp.phase & in_arbitration) {
715 status = inb(TMC_Status_port); /* Read adapter status */
716 if (!(status & 0x02)) {
720 spin_lock_irqsave(shpnt->host_lock, flags);
721 my_done(shpnt, DID_BUS_BUSY << 16);
722 spin_unlock_irqrestore(shpnt->host_lock, flags);
725 current_SC->SCp.phase = in_selection;
727 outb(0x40 | FIFO_COUNT, Interrupt_Cntl_port);
729 outb(0x82, SCSI_Cntl_port); /* Bus Enable + Select */
730 outb(adapter_mask | (1 << current_SC->device->id), SCSI_Data_NoACK_port);
732 /* Stop arbitration and enable parity */
733 outb(0x10 | PARITY_MASK, TMC_Cntl_port);
735 in_interrupt_flag = 0;
738 } else if (current_SC->SCp.phase & in_selection) {
739 status = inb(SCSI_Status_port);
740 if (!(status & 0x01)) {
741 /* Try again, for slow devices */
742 if (fd_mcs_select(shpnt, current_SC->device->id)) {
746 spin_lock_irqsave(shpnt->host_lock, flags);
747 my_done(shpnt, DID_NO_CONNECT << 16);
748 spin_unlock_irqrestore(shpnt->host_lock, flags);
754 /* Stop arbitration and enable parity */
755 outb(0x10 | PARITY_MASK, TMC_Cntl_port);
758 current_SC->SCp.phase = in_other;
759 outb(0x90 | FIFO_COUNT, Interrupt_Cntl_port);
760 outb(0x80, SCSI_Cntl_port);
762 in_interrupt_flag = 0;
767 /* current_SC->SCp.phase == in_other: this is the body of the routine */
769 status = inb(SCSI_Status_port);
771 if (status & 0x10) { /* REQ */
773 switch (status & 0x0e) {
775 case 0x08: /* COMMAND OUT */
776 outb(current_SC->cmnd[current_SC->SCp.sent_command++], Write_SCSI_Data_port);
778 printk("CMD = %x,", current_SC->cmnd[current_SC->SCp.sent_command - 1]);
781 case 0x00: /* DATA OUT -- tmc18c50/tmc18c30 only */
782 if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
783 current_SC->SCp.have_data_in = -1;
784 outb(0xd0 | PARITY_MASK, TMC_Cntl_port);
787 case 0x04: /* DATA IN -- tmc18c50/tmc18c30 only */
788 if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
789 current_SC->SCp.have_data_in = 1;
790 outb(0x90 | PARITY_MASK, TMC_Cntl_port);
793 case 0x0c: /* STATUS IN */
794 current_SC->SCp.Status = inb(Read_SCSI_Data_port);
796 printk("Status = %x, ", current_SC->SCp.Status);
799 if (current_SC->SCp.Status && current_SC->SCp.Status != 2 && current_SC->SCp.Status != 8) {
800 printk("ERROR fd_mcs: target = %d, command = %x, status = %x\n", current_SC->device->id, current_SC->cmnd[0], current_SC->SCp.Status);
804 case 0x0a: /* MESSAGE OUT */
805 outb(MESSAGE_REJECT, Write_SCSI_Data_port); /* Reject */
807 case 0x0e: /* MESSAGE IN */
808 current_SC->SCp.Message = inb(Read_SCSI_Data_port);
810 printk("Message = %x, ", current_SC->SCp.Message);
812 if (!current_SC->SCp.Message)
814 #if DEBUG_MESSAGES || EVERY_ACCESS
815 if (current_SC->SCp.Message) {
816 printk("fd_mcs: message = %x\n", current_SC->SCp.Message);
823 if (chip == tmc1800 && !current_SC->SCp.have_data_in && (current_SC->SCp.sent_command >= current_SC->cmd_len)) {
824 /* We have to get the FIFO direction
825 correct, so I've made a table based
826 on the SCSI Standard of which commands
827 appear to require a DATA OUT phase.
830 p. 94: Command for all device types
831 CHANGE DEFINITION 40 DATA OUT
834 COPY AND VERIFY 3a DATA OUT
836 LOG SELECT 4c DATA OUT
838 MODE SELECT (6) 15 DATA OUT
839 MODE SELECT (10) 55 DATA OUT
843 RECEIVE DIAGNOSTIC RESULTS 1c
845 SEND DIAGNOSTIC 1d DATA OUT
847 WRITE BUFFER 3b DATA OUT
849 p.178: Commands for direct-access devices (not listed on p. 94)
850 FORMAT UNIT 04 DATA OUT
853 PREVENT-ALLOW MEDIUM REMOVAL 1e
857 READ DEFECT DATA (10) 37
859 REASSIGN BLOCKS 07 DATA OUT
862 REZERO UNIT/REWIND 01
863 SEARCH DATA EQUAL (10) 31 DATA OUT
864 SEARCH DATA HIGH (10) 30 DATA OUT
865 SEARCH DATA LOW (10) 32 DATA OUT
872 WRITE (6)/PRINT/SEND 0a DATA OUT
873 WRITE (10)/SEND 2a DATA OUT
874 WRITE AND VERIFY (10) 2e DATA OUT
875 WRITE LONG 3f DATA OUT
876 WRITE SAME 41 DATA OUT ?
878 p. 261: Commands for sequential-access devices (not previously listed)
885 RECOVER BUFFERED DATA 14
889 p. 298: Commands for printer devices (not previously listed)
890 ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****
891 SLEW AND PRINT 0b DATA OUT -- same as seek
893 SYNCHRONIZE BUFFER 10
895 p. 315: Commands for processor devices (not previously listed)
897 p. 321: Commands for write-once devices (not previously listed)
900 SEARCH DATA EQUAL (12) b1 DATA OUT
901 SEARCH DATA HIGH (12) b0 DATA OUT
902 SEARCH DATA LOW (12) b2 DATA OUT
905 WRITE (12) aa DATA OUT
906 WRITE AND VERIFY (12) ae DATA OUT
908 p. 332: Commands for CD-ROM devices (not previously listed)
913 PLAY TRACK RELATIVE (10) 49
914 PLAY TRACK RELATIVE (12) a9
919 p. 370: Commands for scanner devices (not previously listed)
920 GET DATA BUFFER STATUS 34
924 SET WINDOW 24 DATA OUT
926 p. 391: Commands for optical memory devices (not listed)
929 MEDIUM SCAN 38 DATA OUT
930 READ DEFECT DATA (12) b7
932 READ UPDATED BLOCK 2d
933 UPDATE BLOCK 3d DATA OUT
935 p. 419: Commands for medium changer devices (not listed)
937 INITIALIZE ELEMENT STATUS 07
939 POSITION TO ELEMENT 2b
940 READ ELEMENT STATUS b8
941 REQUEST VOL. ELEMENT ADDRESS b5
942 SEND VOLUME TAG b6 DATA OUT
944 p. 454: Commands for communications devices (not listed previously)
950 switch (current_SC->cmnd[0]) {
951 case CHANGE_DEFINITION:
958 case SEND_DIAGNOSTIC:
962 case REASSIGN_BLOCKS:
986 case 0xea: /* alternate number for WRITE LONG */
988 current_SC->SCp.have_data_in = -1;
989 outb(0xd0 | PARITY_MASK, TMC_Cntl_port);
995 current_SC->SCp.have_data_in = 1;
996 outb(0x90 | PARITY_MASK, TMC_Cntl_port);
1001 if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */
1002 while ((data_count = FIFO_Size - inw(FIFO_Data_Count_port)) > 512) {
1004 printk("DC=%d, ", data_count);
1006 if (data_count > current_SC->SCp.this_residual)
1007 data_count = current_SC->SCp.this_residual;
1008 if (data_count > 0) {
1010 printk("%d OUT, ", data_count);
1012 if (data_count == 1) {
1015 outb(*current_SC->SCp.ptr++, Write_FIFO_port);
1016 --current_SC->SCp.this_residual;
1019 tmp_count = data_count << 1;
1020 outsw(Write_FIFO_port, current_SC->SCp.ptr, data_count);
1021 current_SC->SCp.ptr += tmp_count;
1022 Bytes_Written += tmp_count;
1023 current_SC->SCp.this_residual -= tmp_count;
1026 if (!current_SC->SCp.this_residual) {
1027 if (current_SC->SCp.buffers_residual) {
1028 --current_SC->SCp.buffers_residual;
1029 ++current_SC->SCp.buffer;
1030 current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
1031 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1036 } else if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
1037 while ((data_count = inw(FIFO_Data_Count_port)) > 0) {
1039 printk("DC=%d, ", data_count);
1041 if (data_count > current_SC->SCp.this_residual)
1042 data_count = current_SC->SCp.this_residual;
1045 printk("%d IN, ", data_count);
1047 if (data_count == 1) {
1049 *current_SC->SCp.ptr++ = inb(Read_FIFO_port);
1050 --current_SC->SCp.this_residual;
1052 data_count >>= 1; /* Number of words */
1053 tmp_count = data_count << 1;
1054 insw(Read_FIFO_port, current_SC->SCp.ptr, data_count);
1055 current_SC->SCp.ptr += tmp_count;
1056 Bytes_Read += tmp_count;
1057 current_SC->SCp.this_residual -= tmp_count;
1060 if (!current_SC->SCp.this_residual && current_SC->SCp.buffers_residual) {
1061 --current_SC->SCp.buffers_residual;
1062 ++current_SC->SCp.buffer;
1063 current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
1064 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1071 printk(" ** IN DONE %d ** ", current_SC->SCp.have_data_in);
1075 if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
1076 if ((unsigned char) (*((char *) current_SC->request_buffer + 2)) & 0x0f) {
1079 unsigned char qualifier;
1081 key = (unsigned char) (*((char *) current_SC->request_buffer + 2)) & 0x0f;
1082 code = (unsigned char) (*((char *) current_SC->request_buffer + 12));
1083 qualifier = (unsigned char) (*((char *) current_SC->request_buffer + 13));
1085 if (key != UNIT_ATTENTION && !(key == NOT_READY && code == 0x04 && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1086 && !(key == ILLEGAL_REQUEST && (code == 0x25 || code == 0x24 || !code)))
1088 printk("fd_mcs: REQUEST SENSE " "Key = %x, Code = %x, Qualifier = %x\n", key, code, qualifier);
1093 printk("BEFORE MY_DONE. . .");
1095 spin_lock_irqsave(shpnt->host_lock, flags);
1096 my_done(shpnt, (current_SC->SCp.Status & 0xff)
1097 | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16));
1098 spin_unlock_irqrestore(shpnt->host_lock, flags);
1100 printk("RETURNING.\n");
1104 if (current_SC->SCp.phase & disconnect) {
1105 outb(0xd0 | FIFO_COUNT, Interrupt_Cntl_port);
1106 outb(0x00, SCSI_Cntl_port);
1108 outb(0x90 | FIFO_COUNT, Interrupt_Cntl_port);
1112 in_interrupt_flag = 0;
1117 static int fd_mcs_release(struct Scsi_Host *shpnt)
1119 int i, this_host, irq_usage;
1121 release_region(shpnt->io_port, shpnt->n_io_port);
1125 for (i = 0; i < found; i++) {
1126 if (shpnt == hosts[i])
1128 if (shpnt->irq == hosts[i]->irq)
1132 /* only for the last one */
1134 free_irq(shpnt->irq, hosts);
1138 for (i = this_host; i < found; i++)
1139 hosts[i] = hosts[i + 1];
1141 hosts[found] = NULL;
1146 static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
1148 struct Scsi_Host *shpnt = SCpnt->device->host;
1151 panic("fd_mcs: fd_mcs_queue() NOT REENTRANT!\n");
1154 printk("queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n", SCpnt->target, *(unsigned char *) SCpnt->cmnd, SCpnt->use_sg, SCpnt->request_bufflen);
1157 fd_mcs_make_bus_idle(shpnt);
1159 SCpnt->scsi_done = done; /* Save this for the done function */
1162 /* Initialize static data */
1164 if (current_SC->use_sg) {
1165 current_SC->SCp.buffer = (struct scatterlist *) current_SC->request_buffer;
1166 current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
1167 current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1168 current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
1170 current_SC->SCp.ptr = (char *) current_SC->request_buffer;
1171 current_SC->SCp.this_residual = current_SC->request_bufflen;
1172 current_SC->SCp.buffer = NULL;
1173 current_SC->SCp.buffers_residual = 0;
1177 current_SC->SCp.Status = 0;
1178 current_SC->SCp.Message = 0;
1179 current_SC->SCp.have_data_in = 0;
1180 current_SC->SCp.sent_command = 0;
1181 current_SC->SCp.phase = in_arbitration;
1183 /* Start arbitration */
1184 outb(0x00, Interrupt_Cntl_port);
1185 outb(0x00, SCSI_Cntl_port); /* Disable data drivers */
1186 outb(adapter_mask, SCSI_Data_NoACK_port); /* Set our id bit */
1188 outb(0x20, Interrupt_Cntl_port);
1189 outb(0x14 | PARITY_MASK, TMC_Cntl_port); /* Start arbitration */
1194 #if DEBUG_ABORT || DEBUG_RESET
1195 static void fd_mcs_print_info(Scsi_Cmnd * SCpnt)
1200 struct Scsi_Host *shpnt = SCpnt->host;
1202 if (!SCpnt || !SCpnt->host) {
1203 printk("fd_mcs: cannot provide detailed information\n");
1206 printk("%s\n", fd_mcs_info(SCpnt->host));
1207 print_banner(SCpnt->host);
1208 switch (SCpnt->SCp.phase) {
1209 case in_arbitration:
1210 printk("arbitration ");
1213 printk("selection ");
1223 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);
1224 printk("sent_command = %d, have_data_in = %d, timeout = %d\n", SCpnt->SCp.sent_command, SCpnt->SCp.have_data_in, SCpnt->timeout);
1226 printk("in_interrupt_flag = %d\n", in_interrupt_flag);
1229 imr = (inb(0x0a1) << 8) + inb(0x21);
1231 irr = inb(0xa0) << 8;
1235 isr = inb(0xa0) << 8;
1239 /* Print out interesting information */
1240 printk("IMR = 0x%04x", imr);
1241 if (imr & (1 << shpnt->irq))
1242 printk(" (masked)");
1243 printk(", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr);
1245 printk("SCSI Status = 0x%02x\n", inb(SCSI_Status_port));
1246 printk("TMC Status = 0x%02x", inb(TMC_Status_port));
1247 if (inb(TMC_Status_port) & 1)
1248 printk(" (interrupt)");
1250 printk("Interrupt Status = 0x%02x", inb(Interrupt_Status_port));
1251 if (inb(Interrupt_Status_port) & 0x08)
1252 printk(" (enabled)");
1254 if (chip == tmc18c50 || chip == tmc18c30) {
1255 printk("FIFO Status = 0x%02x\n", inb(shpnt->io_port + FIFO_Status));
1256 printk("Int. Condition = 0x%02x\n", inb(shpnt->io_port + Interrupt_Cond));
1258 printk("Configuration 1 = 0x%02x\n", inb(shpnt->io_port + Configuration1));
1259 if (chip == tmc18c50 || chip == tmc18c30)
1260 printk("Configuration 2 = 0x%02x\n", inb(shpnt->io_port + Configuration2));
1264 static int fd_mcs_abort(Scsi_Cmnd * SCpnt)
1266 struct Scsi_Host *shpnt = SCpnt->device->host;
1268 unsigned long flags;
1269 #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1270 printk("fd_mcs: abort ");
1273 spin_lock_irqsave(shpnt->host_lock, flags);
1275 #if EVERY_ACCESS || ERRORS_ONLY
1276 printk(" (not in command)\n");
1278 spin_unlock_irqrestore(shpnt->host_lock, flags);
1284 fd_mcs_print_info(SCpnt);
1287 fd_mcs_make_bus_idle(shpnt);
1289 current_SC->SCp.phase |= aborted;
1291 current_SC->result = DID_ABORT << 16;
1293 /* Aborts are not done well. . . */
1294 my_done(shpnt, DID_ABORT << 16);
1296 spin_unlock_irqrestore(shpnt->host_lock, flags);
1300 static int fd_mcs_host_reset(Scsi_Cmnd * SCpnt)
1305 static int fd_mcs_device_reset(Scsi_Cmnd * SCpnt)
1310 static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
1311 struct Scsi_Host *shpnt = SCpnt->device->host;
1314 static int called_once = 0;
1319 printk("fd_mcs: SCSI Bus Reset\n");
1324 fd_mcs_print_info(current_SC);
1328 outb(1, SCSI_Cntl_port);
1330 outb(0, SCSI_Cntl_port);
1332 outb(0, SCSI_Mode_Cntl_port);
1333 outb(PARITY_MASK, TMC_Cntl_port);
1335 /* Unless this is the very first call (i.e., SCPnt == NULL), everything
1336 is probably hosed at this point. We will, however, try to keep
1337 things going by informing the high-level code that we need help. */
1341 #include <scsi/scsi_ioctl.h>
1343 static int fd_mcs_biosparam(struct scsi_device * disk, struct block_device *bdev,
1344 sector_t capacity, int *info_array)
1346 unsigned char *p = scsi_bios_ptable(bdev);
1347 int size = capacity;
1349 /* BIOS >= 3.4 for MCA cards */
1350 /* This algorithm was provided by Future Domain (much thanks!). */
1352 if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */
1353 && p[4]) { /* Partition type */
1354 /* The partition table layout is as follows:
1357 Offset: 0 = partition status
1359 2 = starting sector and cylinder (word, encoded)
1362 6 = ending sector and cylinder (word, encoded)
1363 8 = starting absolute sector (double word)
1364 c = number of sectors (double word)
1365 Signature: 0x1fe = 0x55aa
1367 So, this algorithm assumes:
1368 1) the first partition table is in use,
1369 2) the data in the first entry is correct, and
1370 3) partitions never divide cylinders
1372 Note that (1) may be FALSE for NetBSD (and other BSD flavors),
1373 as well as for Linux. Note also, that Linux doesn't pay any
1374 attention to the fields that are used by this algorithm -- it
1375 only uses the absolute sector data. Recent versions of Linux's
1376 fdisk(1) will fill this data in correctly, and forthcoming
1377 versions will check for consistency.
1379 Checking for a non-zero partition type is not part of the
1380 Future Domain algorithm, but it seemed to be a reasonable thing
1381 to do, especially in the Linux and BSD worlds. */
1383 info_array[0] = p[5] + 1; /* heads */
1384 info_array[1] = p[6] & 0x3f; /* sectors */
1386 /* Note that this new method guarantees that there will always be
1387 less than 1024 cylinders on a platter. This is good for drives
1388 up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
1389 if ((unsigned int) size >= 0x7e0000U)
1391 info_array[0] = 0xff; /* heads = 255 */
1392 info_array[1] = 0x3f; /* sectors = 63 */
1393 } else if ((unsigned int) size >= 0x200000U) {
1394 info_array[0] = 0x80; /* heads = 128 */
1395 info_array[1] = 0x3f; /* sectors = 63 */
1397 info_array[0] = 0x40; /* heads = 64 */
1398 info_array[1] = 0x20; /* sectors = 32 */
1401 /* For both methods, compute the cylinders */
1402 info_array[2] = (unsigned int) size / (info_array[0] * info_array[1]);
1407 static Scsi_Host_Template driver_template = {
1408 .proc_name = "fd_mcs",
1409 .proc_info = fd_mcs_proc_info,
1410 .detect = fd_mcs_detect,
1411 .release = fd_mcs_release,
1412 .info = fd_mcs_info,
1413 .queuecommand = fd_mcs_queue,
1414 .eh_abort_handler = fd_mcs_abort,
1415 .eh_bus_reset_handler = fd_mcs_bus_reset,
1416 .eh_host_reset_handler = fd_mcs_host_reset,
1417 .eh_device_reset_handler = fd_mcs_device_reset,
1418 .bios_param = fd_mcs_biosparam,
1423 .use_clustering = DISABLE_CLUSTERING,
1425 #include "scsi_module.c"