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 <linux/slab.h>
92 #include <scsi/scsicam.h>
93 #include <linux/mca-legacy.h>
96 #include <asm/system.h>
99 #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 */
108 /* END OF USER DEFINABLE OPTIONS */
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 */
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
126 /* Errors are reported on the line, so we don't need to report them again */
129 #define ERRORS_ONLY 0
133 #define PARITY_MASK 0x08
135 #define PARITY_MASK 0x00
146 in_arbitration
= 0x02,
158 FIFO_Status
= 3, /* tmc18c50/tmc18c30 only */
159 Interrupt_Cond
= 4, /* tmc18c50/tmc18c30 only */
164 Interrupt_Status
= 9,
166 Configuration2
= 11, /* tmc18c50/tmc18c30 only */
177 Memory_Cntl
= 5, /* tmc18c50/tmc18c30 only */
179 IO_Control
= 11, /* tmc18c30 only */
184 unsigned long _bios_base
;
187 volatile int _in_command
;
188 Scsi_Cmnd
*_current_SC
;
189 enum chip_type _chip
;
191 int _fifo_count
; /* Number of 512 byte blocks before INTR */
193 char _adapter_name
[64];
195 volatile int _in_interrupt_flag
;
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
;
204 int _Read_SCSI_Data_port
;
206 int _SCSI_Data_NoACK_port
;
207 int _SCSI_Status_port
;
209 int _TMC_Status_port
;
210 int _Write_FIFO_port
;
211 int _Write_SCSI_Data_port
;
213 int _FIFO_Size
; /* = 0x2000; 8k FIFO for
214 pre-tmc18c30 chips */
221 #define FD_MAX_HOSTS 3 /* enough? */
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)
234 #define in_interrupt_flag (HOSTDATA(shpnt)->_in_interrupt_flag)
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)
255 struct fd_mcs_adapters_struct
{
258 enum chip_type fd_chip
;
263 #define REPLY_ID 0x5137
265 static struct fd_mcs_adapters_struct fd_mcs_adapters
[] = {
266 {"Future Domain SCSI Adapter MCS-700(18C50)",
271 {"Future Domain SCSI Adapter MCS-600/700(TMC-1800)",
276 {"Reply Sound Blaster/SCSI Adapter",
283 #define FD_BRDS ARRAY_SIZE(fd_mcs_adapters)
285 static irqreturn_t
fd_mcs_intr(int irq
, void *dev_id
);
287 static unsigned long addresses
[] = { 0xc8000, 0xca000, 0xce000, 0xde000 };
288 static unsigned short ports
[] = { 0x140, 0x150, 0x160, 0x170 };
289 static unsigned short interrupts
[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
291 /* host information */
292 static int found
= 0;
293 static struct Scsi_Host
*hosts
[FD_MAX_HOSTS
+ 1] = { NULL
};
295 static int user_fifo_count
= 0;
296 static int user_fifo_size
= 0;
299 static int __init
fd_mcs_setup(char *str
)
301 static int done_setup
= 0;
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");
310 user_fifo_count
= ints
[0] >= 1 ? ints
[1] : 0;
311 user_fifo_size
= ints
[0] >= 2 ? ints
[2] : 0;
315 __setup("fd_mcs=", fd_mcs_setup
);
318 static void print_banner(struct Scsi_Host
*shpnt
)
320 printk("scsi%d <fd_mcs>: ", shpnt
->host_no
);
323 printk("BIOS at 0x%lX", bios_base
);
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
);
332 static void do_pause(unsigned amount
)
333 { /* Pause for amount*10 milliseconds */
339 static void fd_mcs_make_bus_idle(struct Scsi_Host
*shpnt
)
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. */
346 outb(0x01 | PARITY_MASK
, TMC_Cntl_port
);
349 static int fd_mcs_detect(struct scsi_host_template
* tpnt
)
352 struct Scsi_Host
*shpnt
;
354 /* get id, port, bios, irq */
356 u_char pos2
, pos3
, pos4
;
360 /* if not MCA machine, return */
367 for (loop
= 0; loop
< FD_BRDS
; loop
++) {
369 while (MCA_NOTFOUND
!= (slot
= mca_find_adapter(fd_mcs_adapters
[loop
].id
, slot
))) {
371 /* if we get this far, an adapter has been detected and is
374 printk(KERN_INFO
"scsi <fd_mcs>: %s at slot %d\n", fd_mcs_adapters
[loop
].name
, slot
+ 1);
376 pos2
= mca_read_stored_pos(slot
, 2);
377 pos3
= mca_read_stored_pos(slot
, 3);
378 pos4
= mca_read_stored_pos(slot
, 4);
380 /* ready for next probe */
383 if (fd_mcs_adapters
[loop
].id
== REPLY_ID
) { /* reply card */
384 static int reply_irq
[] = { 10, 11, 14, 15 };
386 bios
= 0; /* no bios */
389 port
= ports
[pos4
& 0x3];
393 /* can't really disable it, same as irq=10 */
394 irq
= reply_irq
[((pos4
>> 2) & 0x1) + 2 * ((pos4
>> 4) & 0x1)];
396 bios
= addresses
[pos2
>> 6];
397 port
= ports
[(pos2
>> 4) & 0x03];
398 irq
= interrupts
[(pos2
>> 1) & 0x07];
403 mca_set_adapter_name(slot
- 1, fd_mcs_adapters
[loop
].name
);
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");
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");
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
);
426 strcpy(adapter_name
, fd_mcs_adapters
[loop
].name
);
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
;
434 /* FIXME: Do we need to keep this bit of code inside NOT_USED around at all? */
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
);
516 if (found
== FD_MAX_HOSTS
) {
517 printk("fd_mcs: detecting reached max=%d host adapters.\n", FD_MAX_HOSTS
);
525 static const char *fd_mcs_info(struct Scsi_Host
*shpnt
)
530 static int TOTAL_INTR
= 0;
533 * inout : decides on the direction of the dataflow and the meaning of the
535 * buffer: If inout==FALSE data is being written to it else read from it
536 * *start: If inout==FALSE start of the valid data in the buffer
537 * offset: If inout==FALSE offset from the beginning of the imaginary file
538 * from which we start writing into the buffer
539 * length: If inout==FALSE max number of bytes to be written into the buffer
540 * else number of bytes in the buffer
542 static int fd_mcs_proc_info(struct Scsi_Host
*shpnt
, char *buffer
, char **start
, off_t offset
, int length
, int inout
)
549 *start
= buffer
+ offset
;
551 len
+= sprintf(buffer
+ len
, "Future Domain MCS-600/700 Driver %s\n", DRIVER_VERSION
);
552 len
+= sprintf(buffer
+ len
, "HOST #%d: %s\n", shpnt
->host_no
, adapter_name
);
553 len
+= sprintf(buffer
+ len
, "FIFO Size=0x%x, FIFO Count=%d\n", FIFO_Size
, FIFO_COUNT
);
554 len
+= sprintf(buffer
+ len
, "DriverCalls=%d, Interrupts=%d, BytesRead=%d, BytesWrite=%d\n\n", TOTAL_INTR
, INTR_Processed
, Bytes_Read
, Bytes_Written
);
556 if ((len
-= offset
) <= 0)
563 static int fd_mcs_select(struct Scsi_Host
*shpnt
, int target
)
566 unsigned long timeout
;
568 outb(0x82, SCSI_Cntl_port
); /* Bus Enable + Select */
569 outb(adapter_mask
| (1 << target
), SCSI_Data_NoACK_port
);
571 /* Stop arbitration and enable parity */
572 outb(PARITY_MASK
, TMC_Cntl_port
);
574 timeout
= 350; /* 350mS -- because of timeouts
578 status
= inb(SCSI_Status_port
); /* Read adapter status */
579 if (status
& 1) { /* Busy asserted */
580 /* Enable SCSI Bus (on error, should make bus idle with 0) */
581 outb(0x80, SCSI_Cntl_port
);
584 udelay(1000); /* wait one msec */
588 fd_mcs_make_bus_idle(shpnt
);
591 printk("Selection failed\n");
597 if (!flag
) /* Skip first failure for all chips. */
600 printk("fd_mcs: Selection failed\n");
606 static void my_done(struct Scsi_Host
*shpnt
, int error
)
610 outb(0x00, Interrupt_Cntl_port
);
611 fd_mcs_make_bus_idle(shpnt
);
612 current_SC
->result
= error
;
613 current_SC
->scsi_done(current_SC
);
615 panic("fd_mcs: my_done() called outside of command\n");
618 in_interrupt_flag
= 0;
622 /* only my_done needs to be protected */
623 static irqreturn_t
fd_mcs_intr(int irq
, void *dev_id
)
628 unsigned data_count
, tmp_count
;
631 struct Scsi_Host
*shpnt
;
635 /* search for one adapter-response on shared interrupt */
636 while ((shpnt
= hosts
[i
++])) {
637 if ((inb(TMC_Status_port
)) & 1)
641 /* return if some other device on this IRQ caused the interrupt */
648 outb(0x00, Interrupt_Cntl_port
);
650 /* Abort calls my_done, so we do nothing here. */
651 if (current_SC
->SCp
.phase
& aborted
) {
653 printk("Interrupt after abort, ignoring\n");
655 /* return IRQ_HANDLED; */
661 if (current_SC
->SCp
.phase
& in_arbitration
) {
662 status
= inb(TMC_Status_port
); /* Read adapter status */
663 if (!(status
& 0x02)) {
667 spin_lock_irqsave(shpnt
->host_lock
, flags
);
668 my_done(shpnt
, DID_BUS_BUSY
<< 16);
669 spin_unlock_irqrestore(shpnt
->host_lock
, flags
);
672 current_SC
->SCp
.phase
= in_selection
;
674 outb(0x40 | FIFO_COUNT
, Interrupt_Cntl_port
);
676 outb(0x82, SCSI_Cntl_port
); /* Bus Enable + Select */
677 outb(adapter_mask
| (1 << scmd_id(current_SC
)), SCSI_Data_NoACK_port
);
679 /* Stop arbitration and enable parity */
680 outb(0x10 | PARITY_MASK
, TMC_Cntl_port
);
682 in_interrupt_flag
= 0;
685 } else if (current_SC
->SCp
.phase
& in_selection
) {
686 status
= inb(SCSI_Status_port
);
687 if (!(status
& 0x01)) {
688 /* Try again, for slow devices */
689 if (fd_mcs_select(shpnt
, scmd_id(current_SC
))) {
693 spin_lock_irqsave(shpnt
->host_lock
, flags
);
694 my_done(shpnt
, DID_NO_CONNECT
<< 16);
695 spin_unlock_irqrestore(shpnt
->host_lock
, flags
);
701 /* Stop arbitration and enable parity */
702 outb(0x10 | PARITY_MASK
, TMC_Cntl_port
);
705 current_SC
->SCp
.phase
= in_other
;
706 outb(0x90 | FIFO_COUNT
, Interrupt_Cntl_port
);
707 outb(0x80, SCSI_Cntl_port
);
709 in_interrupt_flag
= 0;
714 /* current_SC->SCp.phase == in_other: this is the body of the routine */
716 status
= inb(SCSI_Status_port
);
718 if (status
& 0x10) { /* REQ */
720 switch (status
& 0x0e) {
722 case 0x08: /* COMMAND OUT */
723 outb(current_SC
->cmnd
[current_SC
->SCp
.sent_command
++], Write_SCSI_Data_port
);
725 printk("CMD = %x,", current_SC
->cmnd
[current_SC
->SCp
.sent_command
- 1]);
728 case 0x00: /* DATA OUT -- tmc18c50/tmc18c30 only */
729 if (chip
!= tmc1800
&& !current_SC
->SCp
.have_data_in
) {
730 current_SC
->SCp
.have_data_in
= -1;
731 outb(0xd0 | PARITY_MASK
, TMC_Cntl_port
);
734 case 0x04: /* DATA IN -- tmc18c50/tmc18c30 only */
735 if (chip
!= tmc1800
&& !current_SC
->SCp
.have_data_in
) {
736 current_SC
->SCp
.have_data_in
= 1;
737 outb(0x90 | PARITY_MASK
, TMC_Cntl_port
);
740 case 0x0c: /* STATUS IN */
741 current_SC
->SCp
.Status
= inb(Read_SCSI_Data_port
);
743 printk("Status = %x, ", current_SC
->SCp
.Status
);
746 if (current_SC
->SCp
.Status
&& current_SC
->SCp
.Status
!= 2 && current_SC
->SCp
.Status
!= 8) {
747 printk("ERROR fd_mcs: target = %d, command = %x, status = %x\n", current_SC
->device
->id
, current_SC
->cmnd
[0], current_SC
->SCp
.Status
);
751 case 0x0a: /* MESSAGE OUT */
752 outb(MESSAGE_REJECT
, Write_SCSI_Data_port
); /* Reject */
754 case 0x0e: /* MESSAGE IN */
755 current_SC
->SCp
.Message
= inb(Read_SCSI_Data_port
);
757 printk("Message = %x, ", current_SC
->SCp
.Message
);
759 if (!current_SC
->SCp
.Message
)
761 #if DEBUG_MESSAGES || EVERY_ACCESS
762 if (current_SC
->SCp
.Message
) {
763 printk("fd_mcs: message = %x\n", current_SC
->SCp
.Message
);
770 if (chip
== tmc1800
&& !current_SC
->SCp
.have_data_in
&& (current_SC
->SCp
.sent_command
>= current_SC
->cmd_len
)) {
771 /* We have to get the FIFO direction
772 correct, so I've made a table based
773 on the SCSI Standard of which commands
774 appear to require a DATA OUT phase.
777 p. 94: Command for all device types
778 CHANGE DEFINITION 40 DATA OUT
781 COPY AND VERIFY 3a DATA OUT
783 LOG SELECT 4c DATA OUT
785 MODE SELECT (6) 15 DATA OUT
786 MODE SELECT (10) 55 DATA OUT
790 RECEIVE DIAGNOSTIC RESULTS 1c
792 SEND DIAGNOSTIC 1d DATA OUT
794 WRITE BUFFER 3b DATA OUT
796 p.178: Commands for direct-access devices (not listed on p. 94)
797 FORMAT UNIT 04 DATA OUT
800 PREVENT-ALLOW MEDIUM REMOVAL 1e
804 READ DEFECT DATA (10) 37
806 REASSIGN BLOCKS 07 DATA OUT
809 REZERO UNIT/REWIND 01
810 SEARCH DATA EQUAL (10) 31 DATA OUT
811 SEARCH DATA HIGH (10) 30 DATA OUT
812 SEARCH DATA LOW (10) 32 DATA OUT
819 WRITE (6)/PRINT/SEND 0a DATA OUT
820 WRITE (10)/SEND 2a DATA OUT
821 WRITE AND VERIFY (10) 2e DATA OUT
822 WRITE LONG 3f DATA OUT
823 WRITE SAME 41 DATA OUT ?
825 p. 261: Commands for sequential-access devices (not previously listed)
832 RECOVER BUFFERED DATA 14
836 p. 298: Commands for printer devices (not previously listed)
837 ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****
838 SLEW AND PRINT 0b DATA OUT -- same as seek
840 SYNCHRONIZE BUFFER 10
842 p. 315: Commands for processor devices (not previously listed)
844 p. 321: Commands for write-once devices (not previously listed)
847 SEARCH DATA EQUAL (12) b1 DATA OUT
848 SEARCH DATA HIGH (12) b0 DATA OUT
849 SEARCH DATA LOW (12) b2 DATA OUT
852 WRITE (12) aa DATA OUT
853 WRITE AND VERIFY (12) ae DATA OUT
855 p. 332: Commands for CD-ROM devices (not previously listed)
860 PLAY TRACK RELATIVE (10) 49
861 PLAY TRACK RELATIVE (12) a9
866 p. 370: Commands for scanner devices (not previously listed)
867 GET DATA BUFFER STATUS 34
871 SET WINDOW 24 DATA OUT
873 p. 391: Commands for optical memory devices (not listed)
876 MEDIUM SCAN 38 DATA OUT
877 READ DEFECT DATA (12) b7
879 READ UPDATED BLOCK 2d
880 UPDATE BLOCK 3d DATA OUT
882 p. 419: Commands for medium changer devices (not listed)
884 INITIALIZE ELEMENT STATUS 07
886 POSITION TO ELEMENT 2b
887 READ ELEMENT STATUS b8
888 REQUEST VOL. ELEMENT ADDRESS b5
889 SEND VOLUME TAG b6 DATA OUT
891 p. 454: Commands for communications devices (not listed previously)
897 switch (current_SC
->cmnd
[0]) {
898 case CHANGE_DEFINITION
:
905 case SEND_DIAGNOSTIC
:
909 case REASSIGN_BLOCKS
:
933 case 0xea: /* alternate number for WRITE LONG */
935 current_SC
->SCp
.have_data_in
= -1;
936 outb(0xd0 | PARITY_MASK
, TMC_Cntl_port
);
942 current_SC
->SCp
.have_data_in
= 1;
943 outb(0x90 | PARITY_MASK
, TMC_Cntl_port
);
948 if (current_SC
->SCp
.have_data_in
== -1) { /* DATA OUT */
949 while ((data_count
= FIFO_Size
- inw(FIFO_Data_Count_port
)) > 512) {
951 printk("DC=%d, ", data_count
);
953 if (data_count
> current_SC
->SCp
.this_residual
)
954 data_count
= current_SC
->SCp
.this_residual
;
955 if (data_count
> 0) {
957 printk("%d OUT, ", data_count
);
959 if (data_count
== 1) {
962 outb(*current_SC
->SCp
.ptr
++, Write_FIFO_port
);
963 --current_SC
->SCp
.this_residual
;
966 tmp_count
= data_count
<< 1;
967 outsw(Write_FIFO_port
, current_SC
->SCp
.ptr
, data_count
);
968 current_SC
->SCp
.ptr
+= tmp_count
;
969 Bytes_Written
+= tmp_count
;
970 current_SC
->SCp
.this_residual
-= tmp_count
;
973 if (!current_SC
->SCp
.this_residual
) {
974 if (current_SC
->SCp
.buffers_residual
) {
975 --current_SC
->SCp
.buffers_residual
;
976 ++current_SC
->SCp
.buffer
;
977 current_SC
->SCp
.ptr
= sg_virt(current_SC
->SCp
.buffer
);
978 current_SC
->SCp
.this_residual
= current_SC
->SCp
.buffer
->length
;
983 } else if (current_SC
->SCp
.have_data_in
== 1) { /* DATA IN */
984 while ((data_count
= inw(FIFO_Data_Count_port
)) > 0) {
986 printk("DC=%d, ", data_count
);
988 if (data_count
> current_SC
->SCp
.this_residual
)
989 data_count
= current_SC
->SCp
.this_residual
;
992 printk("%d IN, ", data_count
);
994 if (data_count
== 1) {
996 *current_SC
->SCp
.ptr
++ = inb(Read_FIFO_port
);
997 --current_SC
->SCp
.this_residual
;
999 data_count
>>= 1; /* Number of words */
1000 tmp_count
= data_count
<< 1;
1001 insw(Read_FIFO_port
, current_SC
->SCp
.ptr
, data_count
);
1002 current_SC
->SCp
.ptr
+= tmp_count
;
1003 Bytes_Read
+= tmp_count
;
1004 current_SC
->SCp
.this_residual
-= tmp_count
;
1007 if (!current_SC
->SCp
.this_residual
&& current_SC
->SCp
.buffers_residual
) {
1008 --current_SC
->SCp
.buffers_residual
;
1009 ++current_SC
->SCp
.buffer
;
1010 current_SC
->SCp
.ptr
= sg_virt(current_SC
->SCp
.buffer
);
1011 current_SC
->SCp
.this_residual
= current_SC
->SCp
.buffer
->length
;
1018 printk(" ** IN DONE %d ** ", current_SC
->SCp
.have_data_in
);
1022 printk("BEFORE MY_DONE. . .");
1024 spin_lock_irqsave(shpnt
->host_lock
, flags
);
1025 my_done(shpnt
, (current_SC
->SCp
.Status
& 0xff)
1026 | ((current_SC
->SCp
.Message
& 0xff) << 8) | (DID_OK
<< 16));
1027 spin_unlock_irqrestore(shpnt
->host_lock
, flags
);
1029 printk("RETURNING.\n");
1033 if (current_SC
->SCp
.phase
& disconnect
) {
1034 outb(0xd0 | FIFO_COUNT
, Interrupt_Cntl_port
);
1035 outb(0x00, SCSI_Cntl_port
);
1037 outb(0x90 | FIFO_COUNT
, Interrupt_Cntl_port
);
1041 in_interrupt_flag
= 0;
1046 static int fd_mcs_release(struct Scsi_Host
*shpnt
)
1048 int i
, this_host
, irq_usage
;
1050 release_region(shpnt
->io_port
, shpnt
->n_io_port
);
1054 for (i
= 0; i
< found
; i
++) {
1055 if (shpnt
== hosts
[i
])
1057 if (shpnt
->irq
== hosts
[i
]->irq
)
1061 /* only for the last one */
1063 free_irq(shpnt
->irq
, hosts
);
1067 for (i
= this_host
; i
< found
; i
++)
1068 hosts
[i
] = hosts
[i
+ 1];
1070 hosts
[found
] = NULL
;
1075 static int fd_mcs_queue(Scsi_Cmnd
* SCpnt
, void (*done
) (Scsi_Cmnd
*))
1077 struct Scsi_Host
*shpnt
= SCpnt
->device
->host
;
1080 panic("fd_mcs: fd_mcs_queue() NOT REENTRANT!\n");
1083 printk("queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1084 SCpnt
->target
, *(unsigned char *) SCpnt
->cmnd
,
1085 scsi_sg_count(SCpnt
), scsi_bufflen(SCpnt
));
1088 fd_mcs_make_bus_idle(shpnt
);
1090 SCpnt
->scsi_done
= done
; /* Save this for the done function */
1093 /* Initialize static data */
1095 if (scsi_bufflen(current_SC
)) {
1096 current_SC
->SCp
.buffer
= scsi_sglist(current_SC
);
1097 current_SC
->SCp
.ptr
= sg_virt(current_SC
->SCp
.buffer
);
1098 current_SC
->SCp
.this_residual
= current_SC
->SCp
.buffer
->length
;
1099 current_SC
->SCp
.buffers_residual
= scsi_sg_count(current_SC
) - 1;
1101 current_SC
->SCp
.ptr
= NULL
;
1102 current_SC
->SCp
.this_residual
= 0;
1103 current_SC
->SCp
.buffer
= NULL
;
1104 current_SC
->SCp
.buffers_residual
= 0;
1108 current_SC
->SCp
.Status
= 0;
1109 current_SC
->SCp
.Message
= 0;
1110 current_SC
->SCp
.have_data_in
= 0;
1111 current_SC
->SCp
.sent_command
= 0;
1112 current_SC
->SCp
.phase
= in_arbitration
;
1114 /* Start arbitration */
1115 outb(0x00, Interrupt_Cntl_port
);
1116 outb(0x00, SCSI_Cntl_port
); /* Disable data drivers */
1117 outb(adapter_mask
, SCSI_Data_NoACK_port
); /* Set our id bit */
1119 outb(0x20, Interrupt_Cntl_port
);
1120 outb(0x14 | PARITY_MASK
, TMC_Cntl_port
); /* Start arbitration */
1125 #if DEBUG_ABORT || DEBUG_RESET
1126 static void fd_mcs_print_info(Scsi_Cmnd
* SCpnt
)
1131 struct Scsi_Host
*shpnt
= SCpnt
->host
;
1133 if (!SCpnt
|| !SCpnt
->host
) {
1134 printk("fd_mcs: cannot provide detailed information\n");
1137 printk("%s\n", fd_mcs_info(SCpnt
->host
));
1138 print_banner(SCpnt
->host
);
1139 switch (SCpnt
->SCp
.phase
) {
1140 case in_arbitration
:
1141 printk("arbitration ");
1144 printk("selection ");
1154 printk("(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1155 SCpnt
->SCp
.phase
, SCpnt
->device
->id
, *(unsigned char *) SCpnt
->cmnd
,
1156 scsi_sg_count(SCpnt
), scsi_bufflen(SCpnt
));
1157 printk("sent_command = %d, have_data_in = %d, timeout = %d\n", SCpnt
->SCp
.sent_command
, SCpnt
->SCp
.have_data_in
, SCpnt
->timeout
);
1159 printk("in_interrupt_flag = %d\n", in_interrupt_flag
);
1162 imr
= (inb(0x0a1) << 8) + inb(0x21);
1164 irr
= inb(0xa0) << 8;
1168 isr
= inb(0xa0) << 8;
1172 /* Print out interesting information */
1173 printk("IMR = 0x%04x", imr
);
1174 if (imr
& (1 << shpnt
->irq
))
1175 printk(" (masked)");
1176 printk(", IRR = 0x%04x, ISR = 0x%04x\n", irr
, isr
);
1178 printk("SCSI Status = 0x%02x\n", inb(SCSI_Status_port
));
1179 printk("TMC Status = 0x%02x", inb(TMC_Status_port
));
1180 if (inb(TMC_Status_port
) & 1)
1181 printk(" (interrupt)");
1183 printk("Interrupt Status = 0x%02x", inb(Interrupt_Status_port
));
1184 if (inb(Interrupt_Status_port
) & 0x08)
1185 printk(" (enabled)");
1187 if (chip
== tmc18c50
|| chip
== tmc18c30
) {
1188 printk("FIFO Status = 0x%02x\n", inb(shpnt
->io_port
+ FIFO_Status
));
1189 printk("Int. Condition = 0x%02x\n", inb(shpnt
->io_port
+ Interrupt_Cond
));
1191 printk("Configuration 1 = 0x%02x\n", inb(shpnt
->io_port
+ Configuration1
));
1192 if (chip
== tmc18c50
|| chip
== tmc18c30
)
1193 printk("Configuration 2 = 0x%02x\n", inb(shpnt
->io_port
+ Configuration2
));
1197 static int fd_mcs_abort(Scsi_Cmnd
* SCpnt
)
1199 struct Scsi_Host
*shpnt
= SCpnt
->device
->host
;
1201 unsigned long flags
;
1202 #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1203 printk("fd_mcs: abort ");
1206 spin_lock_irqsave(shpnt
->host_lock
, flags
);
1208 #if EVERY_ACCESS || ERRORS_ONLY
1209 printk(" (not in command)\n");
1211 spin_unlock_irqrestore(shpnt
->host_lock
, flags
);
1217 fd_mcs_print_info(SCpnt
);
1220 fd_mcs_make_bus_idle(shpnt
);
1222 current_SC
->SCp
.phase
|= aborted
;
1224 current_SC
->result
= DID_ABORT
<< 16;
1226 /* Aborts are not done well. . . */
1227 my_done(shpnt
, DID_ABORT
<< 16);
1229 spin_unlock_irqrestore(shpnt
->host_lock
, flags
);
1233 static int fd_mcs_bus_reset(Scsi_Cmnd
* SCpnt
) {
1234 struct Scsi_Host
*shpnt
= SCpnt
->device
->host
;
1235 unsigned long flags
;
1238 static int called_once
= 0;
1243 printk("fd_mcs: SCSI Bus Reset\n");
1248 fd_mcs_print_info(current_SC
);
1252 spin_lock_irqsave(shpnt
->host_lock
, flags
);
1254 outb(1, SCSI_Cntl_port
);
1256 outb(0, SCSI_Cntl_port
);
1258 outb(0, SCSI_Mode_Cntl_port
);
1259 outb(PARITY_MASK
, TMC_Cntl_port
);
1261 spin_unlock_irqrestore(shpnt
->host_lock
, flags
);
1263 /* Unless this is the very first call (i.e., SCPnt == NULL), everything
1264 is probably hosed at this point. We will, however, try to keep
1265 things going by informing the high-level code that we need help. */
1269 #include <scsi/scsi_ioctl.h>
1271 static int fd_mcs_biosparam(struct scsi_device
* disk
, struct block_device
*bdev
,
1272 sector_t capacity
, int *info_array
)
1274 unsigned char *p
= scsi_bios_ptable(bdev
);
1275 int size
= capacity
;
1277 /* BIOS >= 3.4 for MCA cards */
1278 /* This algorithm was provided by Future Domain (much thanks!). */
1280 if (p
&& p
[65] == 0xaa && p
[64] == 0x55 /* Partition table valid */
1281 && p
[4]) { /* Partition type */
1282 /* The partition table layout is as follows:
1285 Offset: 0 = partition status
1287 2 = starting sector and cylinder (word, encoded)
1290 6 = ending sector and cylinder (word, encoded)
1291 8 = starting absolute sector (double word)
1292 c = number of sectors (double word)
1293 Signature: 0x1fe = 0x55aa
1295 So, this algorithm assumes:
1296 1) the first partition table is in use,
1297 2) the data in the first entry is correct, and
1298 3) partitions never divide cylinders
1300 Note that (1) may be FALSE for NetBSD (and other BSD flavors),
1301 as well as for Linux. Note also, that Linux doesn't pay any
1302 attention to the fields that are used by this algorithm -- it
1303 only uses the absolute sector data. Recent versions of Linux's
1304 fdisk(1) will fill this data in correctly, and forthcoming
1305 versions will check for consistency.
1307 Checking for a non-zero partition type is not part of the
1308 Future Domain algorithm, but it seemed to be a reasonable thing
1309 to do, especially in the Linux and BSD worlds. */
1311 info_array
[0] = p
[5] + 1; /* heads */
1312 info_array
[1] = p
[6] & 0x3f; /* sectors */
1314 /* Note that this new method guarantees that there will always be
1315 less than 1024 cylinders on a platter. This is good for drives
1316 up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
1317 if ((unsigned int) size
>= 0x7e0000U
)
1319 info_array
[0] = 0xff; /* heads = 255 */
1320 info_array
[1] = 0x3f; /* sectors = 63 */
1321 } else if ((unsigned int) size
>= 0x200000U
) {
1322 info_array
[0] = 0x80; /* heads = 128 */
1323 info_array
[1] = 0x3f; /* sectors = 63 */
1325 info_array
[0] = 0x40; /* heads = 64 */
1326 info_array
[1] = 0x20; /* sectors = 32 */
1329 /* For both methods, compute the cylinders */
1330 info_array
[2] = (unsigned int) size
/ (info_array
[0] * info_array
[1]);
1335 static struct scsi_host_template driver_template
= {
1336 .proc_name
= "fd_mcs",
1337 .proc_info
= fd_mcs_proc_info
,
1338 .detect
= fd_mcs_detect
,
1339 .release
= fd_mcs_release
,
1340 .info
= fd_mcs_info
,
1341 .queuecommand
= fd_mcs_queue
,
1342 .eh_abort_handler
= fd_mcs_abort
,
1343 .eh_bus_reset_handler
= fd_mcs_bus_reset
,
1344 .bios_param
= fd_mcs_biosparam
,
1349 .use_clustering
= DISABLE_CLUSTERING
,
1351 #include "scsi_module.c"
1353 MODULE_LICENSE("GPL");