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 **************************************************************************/
81 #include <linux/module.h>
84 #include <linux/sched.h>
85 #include <linux/blk.h>
86 #include <linux/errno.h>
87 #include <linux/string.h>
88 #include <linux/ioport.h>
89 #include <linux/proc_fs.h>
90 #include <linux/delay.h>
91 #include <linux/mca.h>
92 #include <linux/spinlock.h>
94 #include <asm/system.h>
100 #define DRIVER_VERSION "v0.2 by ZP Gu<zpg@castle.net>"
102 /* START OF USER DEFINABLE OPTIONS */
104 #define DEBUG 0 /* Enable debugging output */
105 #define ENABLE_PARITY 1 /* Enable SCSI Parity */
106 #define DO_DETECT 0 /* Do device detection here (see scsi.c) */
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_DETECT 1 /* Debug fd_mcs_detect() */
114 #define DEBUG_MESSAGES 1 /* Debug MESSAGE IN phase */
115 #define DEBUG_ABORT 1 /* Debug abort() routine */
116 #define DEBUG_RESET 1 /* Debug reset() routine */
117 #define DEBUG_RACE 1 /* Debug interrupt-driven race condition */
119 #define EVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
120 #define ERRORS_ONLY 0
121 #define DEBUG_DETECT 0
122 #define DEBUG_MESSAGES 0
123 #define DEBUG_ABORT 0
124 #define DEBUG_RESET 0
128 /* Errors are reported on the line, so we don't need to report them again */
131 #define ERRORS_ONLY 0
135 #define PARITY_MASK 0x08
137 #define PARITY_MASK 0x00
148 in_arbitration
= 0x02,
160 FIFO_Status
= 3, /* tmc18c50/tmc18c30 only */
161 Interrupt_Cond
= 4, /* tmc18c50/tmc18c30 only */
166 Interrupt_Status
= 9,
168 Configuration2
= 11, /* tmc18c50/tmc18c30 only */
179 Memory_Cntl
= 5, /* tmc18c50/tmc18c30 only */
181 IO_Control
= 11, /* tmc18c30 only */
186 unsigned long _bios_base
;
189 volatile int _in_command
;
190 Scsi_Cmnd
*_current_SC
;
191 enum chip_type _chip
;
193 int _fifo_count
; /* Number of 512 byte blocks before INTR */
195 char _adapter_name
[64];
197 volatile int _in_interrupt_flag
;
200 int _SCSI_Mode_Cntl_port
;
201 int _FIFO_Data_Count_port
;
202 int _Interrupt_Cntl_port
;
203 int _Interrupt_Status_port
;
204 int _Interrupt_Cond_port
;
206 int _Read_SCSI_Data_port
;
208 int _SCSI_Data_NoACK_port
;
209 int _SCSI_Status_port
;
211 int _TMC_Status_port
;
212 int _Write_FIFO_port
;
213 int _Write_SCSI_Data_port
;
215 int _FIFO_Size
; /* = 0x2000; 8k FIFO for
216 pre-tmc18c30 chips */
223 #define FD_MAX_HOSTS 3 /* enough? */
225 #define HOSTDATA(shpnt) ((struct fd_hostdata *) shpnt->hostdata)
226 #define bios_base (HOSTDATA(shpnt)->_bios_base)
227 #define bios_major (HOSTDATA(shpnt)->_bios_major)
228 #define bios_minor (HOSTDATA(shpnt)->_bios_minor)
229 #define in_command (HOSTDATA(shpnt)->_in_command)
230 #define current_SC (HOSTDATA(shpnt)->_current_SC)
231 #define chip (HOSTDATA(shpnt)->_chip)
232 #define adapter_mask (HOSTDATA(shpnt)->_adapter_mask)
233 #define FIFO_COUNT (HOSTDATA(shpnt)->_fifo_count)
234 #define adapter_name (HOSTDATA(shpnt)->_adapter_name)
236 #define in_interrupt_flag (HOSTDATA(shpnt)->_in_interrupt_flag)
238 #define SCSI_Mode_Cntl_port (HOSTDATA(shpnt)->_SCSI_Mode_Cntl_port)
239 #define FIFO_Data_Count_port (HOSTDATA(shpnt)->_FIFO_Data_Count_port)
240 #define Interrupt_Cntl_port (HOSTDATA(shpnt)->_Interrupt_Cntl_port)
241 #define Interrupt_Status_port (HOSTDATA(shpnt)->_Interrupt_Status_port)
242 #define Interrupt_Cond_port (HOSTDATA(shpnt)->_Interrupt_Cond_port)
243 #define Read_FIFO_port (HOSTDATA(shpnt)->_Read_FIFO_port)
244 #define Read_SCSI_Data_port (HOSTDATA(shpnt)->_Read_SCSI_Data_port)
245 #define SCSI_Cntl_port (HOSTDATA(shpnt)->_SCSI_Cntl_port)
246 #define SCSI_Data_NoACK_port (HOSTDATA(shpnt)->_SCSI_Data_NoACK_port)
247 #define SCSI_Status_port (HOSTDATA(shpnt)->_SCSI_Status_port)
248 #define TMC_Cntl_port (HOSTDATA(shpnt)->_TMC_Cntl_port)
249 #define TMC_Status_port (HOSTDATA(shpnt)->_TMC_Status_port)
250 #define Write_FIFO_port (HOSTDATA(shpnt)->_Write_FIFO_port)
251 #define Write_SCSI_Data_port (HOSTDATA(shpnt)->_Write_SCSI_Data_port)
252 #define FIFO_Size (HOSTDATA(shpnt)->_FIFO_Size)
253 #define Bytes_Read (HOSTDATA(shpnt)->_Bytes_Read)
254 #define Bytes_Written (HOSTDATA(shpnt)->_Bytes_Written)
255 #define INTR_Processed (HOSTDATA(shpnt)->_INTR_Processed)
257 struct fd_mcs_adapters_struct
{
260 enum chip_type fd_chip
;
265 #define REPLY_ID 0x5137
267 static struct fd_mcs_adapters_struct fd_mcs_adapters
[] = {
268 { "Future Domain SCSI Adapter MCS-700(18C50)",
273 { "Future Domain SCSI Adapter MCS-600/700(TMC-1800)",
278 { "Reply Sound Blaster/SCSI Adapter",
285 #define FD_BRDS sizeof(fd_mcs_adapters)/sizeof(struct fd_mcs_adapters_struct)
287 static void fd_mcs_intr( int irq
, void *dev_id
, struct pt_regs
* regs
);
289 static unsigned long addresses
[] = {0xc8000, 0xca000, 0xce000, 0xde000};
290 static unsigned short ports
[] = { 0x140, 0x150, 0x160, 0x170 };
291 static unsigned short ints
[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
293 /* host information */
294 static int found
= 0;
295 static struct Scsi_Host
*hosts
[FD_MAX_HOSTS
+1] = { NULL
};
297 static int user_fifo_count
= 0;
298 static int user_fifo_size
= 0;
300 void fd_mcs_setup( char *str
, int *ints
)
302 static int done_setup
= 0;
304 if (done_setup
++ || ints
[0] < 1 || ints
[0] > 2 ||
305 ints
[1] < 1 || ints
[1] > 16) {
306 printk( "fd_mcs: usage: fd_mcs=FIFO_COUNT, FIFO_SIZE\n" );
309 user_fifo_count
= ints
[0] >= 1 ? ints
[1] : 0;
310 user_fifo_size
= ints
[0] >= 2 ? ints
[2] : 0;
313 static void print_banner( struct Scsi_Host
*shpnt
)
315 printk( "scsi%d <fd_mcs>: ", shpnt
->host_no
);
318 printk( "BIOS at 0x%lX", bios_base
);
323 printk( ", HostID %d, %s Chip, IRQ %d, IO 0x%lX\n",
325 chip
== tmc18c50
? "TMC-18C50"
326 : (chip
== tmc18c30
? "TMC-18C30" :
327 (chip
== tmc1800
? "TMC-1800" : "Unknown")),
333 static void do_pause( unsigned amount
) /* Pause for amount*10 milliseconds */
340 inline 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 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
!=
371 (slot
= mca_find_adapter(fd_mcs_adapters
[loop
].id
,
374 /* if we get this far, an adapter has been detected and is
377 printk("scsi <fd_mcs>: %s at slot %d\n",
378 fd_mcs_adapters
[loop
].name
, slot
+ 1 );
380 pos2
= mca_read_stored_pos( slot
, 2 );
381 pos3
= mca_read_stored_pos( slot
, 3 );
382 pos4
= mca_read_stored_pos( slot
, 4);
384 /* ready for next probe */
387 if (fd_mcs_adapters
[loop
].id
== REPLY_ID
) { /* reply card */
388 static int reply_irq
[] = {10, 11, 14, 15};
390 bios
= 0; /* no bios */
393 port
= ports
[pos4
& 0x3];
397 /* can't really disable it, same as irq=10 */
398 irq
= reply_irq
[((pos4
>> 2) & 0x1) + 2*((pos4
>> 4) & 0x1)];
400 bios
= addresses
[pos2
>> 6];
401 port
= ports
[(pos2
>> 4) & 0x03];
402 irq
= ints
[(pos2
>> 1) & 0x07];
407 mca_set_adapter_name( slot
-1, fd_mcs_adapters
[loop
].name
);
409 /* check irq/region */
410 if (check_region(port
, 0x10) ||
411 request_irq(irq
, fd_mcs_intr
,
412 SA_SHIRQ
, "fd_mcs", hosts
)) {
413 printk( "fd_mcs: check_region() || request_irq() failed, Skip it\n");
419 if (!(shpnt
= scsi_register(tpnt
, sizeof(struct fd_hostdata
)))) {
420 printk( "fd_mcs: scsi_register() failed\n");
424 /* request I/O region */
425 request_region( port
, 0x10, "fd_mcs" );
428 strcpy(adapter_name
, fd_mcs_adapters
[loop
].name
);
431 chip
= fd_mcs_adapters
[loop
].fd_chip
;
432 /* use boot time value if available */
434 user_fifo_count
?user_fifo_count
:fd_mcs_adapters
[loop
].fifo_count
;
436 user_fifo_size
?user_fifo_size
:fd_mcs_adapters
[loop
].fifo_size
;
439 /* *************************************************** */
440 /* Try to toggle 32-bit mode. This only
441 works on an 18c30 chip. (User reports
442 say this works, so we should switch to
443 it in the near future.) */
444 outb( 0x80, port
+ IO_Control
);
445 if ((inb( port
+ Configuration2
) & 0x80) == 0x80) {
446 outb( 0x00, port
+ IO_Control
);
447 if ((inb( port
+ Configuration2
) & 0x80) == 0x00) {
449 FIFO_Size
= 0x800; /* 2k FIFO */
451 printk("FIRST: chip=%s, fifo_size=0x%x\n",
452 (chip
== tmc18c30
)?"tmc18c30":"tmc18c50", FIFO_Size
);
456 /* That should have worked, but appears to
457 have problems. Let's assume it is an
458 18c30 if the RAM is disabled. */
460 if (inb( port
+ Configuration2
) & 0x02) {
462 FIFO_Size
= 0x800; /* 2k FIFO */
464 printk("SECOND: chip=%s, fifo_size=0x%x\n",
465 (chip
== tmc18c30
)?"tmc18c30":"tmc18c50", FIFO_Size
);
467 /* *************************************************** */
470 /* IBM/ANSI scsi scan ordering */
471 /* Stick this back in when the scsi.c changes are there */
472 shpnt
->reverse_ordering
= 1;
476 hosts
[found
++] = shpnt
;
480 shpnt
->io_port
= port
;
481 shpnt
->n_io_port
= 0x10;
485 adapter_mask
= (1 << id
);
488 SCSI_Mode_Cntl_port
= port
+ SCSI_Mode_Cntl
;
489 FIFO_Data_Count_port
= port
+ FIFO_Data_Count
;
490 Interrupt_Cntl_port
= port
+ Interrupt_Cntl
;
491 Interrupt_Status_port
= port
+ Interrupt_Status
;
492 Interrupt_Cond_port
= port
+ Interrupt_Cond
;
493 Read_FIFO_port
= port
+ Read_FIFO
;
494 Read_SCSI_Data_port
= port
+ Read_SCSI_Data
;
495 SCSI_Cntl_port
= port
+ SCSI_Cntl
;
496 SCSI_Data_NoACK_port
= port
+ SCSI_Data_NoACK
;
497 SCSI_Status_port
= port
+ SCSI_Status
;
498 TMC_Cntl_port
= port
+ TMC_Cntl
;
499 TMC_Status_port
= port
+ TMC_Status
;
500 Write_FIFO_port
= port
+ Write_FIFO
;
501 Write_SCSI_Data_port
= port
+ Write_SCSI_Data
;
508 print_banner( shpnt
);
511 outb( 1, SCSI_Cntl_port
);
513 outb( 0, SCSI_Cntl_port
);
515 outb( 0, SCSI_Mode_Cntl_port
);
516 outb( PARITY_MASK
, TMC_Cntl_port
);
520 /* scan devices attached */
522 const int buflen
= 255;
525 unsigned char do_inquiry
[] = { INQUIRY
, 0, 0, 0, buflen
, 0 };
526 unsigned char do_request_sense
[] = { REQUEST_SENSE
,
527 0, 0, 0, buflen
, 0 };
528 unsigned char do_read_capacity
[] = { READ_CAPACITY
,
529 0, 0, 0, 0, 0, 0, 0, 0, 0 };
530 unsigned char buf
[buflen
];
532 SCinit
.request_buffer
= SCinit
.buffer
= buf
;
533 SCinit
.request_bufflen
= SCinit
.bufflen
= sizeof(buf
)-1;
538 printk( "fd_mcs: detection routine scanning for devices:\n" );
539 for (i
= 0; i
< 8; i
++) {
540 if (i
== shpnt
->this_id
) /* Skip host adapter */
543 memcpy(SCinit
.cmnd
, do_request_sense
,
544 sizeof(do_request_sense
));
545 retcode
= fd_mcs_command(&SCinit
);
547 memcpy(SCinit
.cmnd
, do_inquiry
, sizeof(do_inquiry
));
548 retcode
= fd_mcs_command(&SCinit
);
550 printk( " SCSI ID %d: ", i
);
551 for (j
= 8; j
< (buf
[4] < 32 ? buf
[4] : 32); j
++)
552 printk( "%c", buf
[j
] >= 20 ? buf
[j
] : ' ' );
553 memcpy(SCinit
.cmnd
, do_read_capacity
,
554 sizeof(do_read_capacity
));
555 retcode
= fd_mcs_command(&SCinit
);
557 unsigned long blocks
, size
, capacity
;
559 blocks
= (buf
[0] << 24) | (buf
[1] << 16)
560 | (buf
[2] << 8) | buf
[3];
561 size
= (buf
[4] << 24) | (buf
[5] << 16) |
562 (buf
[6] << 8) | buf
[7];
563 capacity
= +( +(blocks
/ 1024L) * +(size
* 10L)) / 1024L;
565 printk( "%lu MB (%lu byte blocks)\n",
566 ((capacity
+ 5L) / 10L), size
);
576 if (found
== FD_MAX_HOSTS
) {
577 printk( "fd_mcs: detecting reached max=%d host adapters.\n",
586 const char *fd_mcs_info(struct Scsi_Host
*shpnt
)
591 static int TOTAL_INTR
= 0;
594 * inout : decides on the direction of the dataflow and the meaning of the
596 * buffer: If inout==FALSE data is being written to it else read from it
597 * *start: If inout==FALSE start of the valid data in the buffer
598 * offset: If inout==FALSE offset from the beginning of the imaginary file
599 * from which we start writing into the buffer
600 * length: If inout==FALSE max number of bytes to be written into the buffer
601 * else number of bytes in the buffer
603 int fd_mcs_proc_info( char *buffer
, char **start
, off_t offset
,
604 int length
, int hostno
, int inout
)
606 struct Scsi_Host
*shpnt
;
613 *start
= buffer
+ offset
;
615 for (i
= 0; hosts
[i
] && hosts
[i
]->host_no
!= hostno
; i
++);
621 len
+= sprintf(buffer
+len
, "Future Domain MCS-600/700 Driver %s\n",
624 len
+= sprintf(buffer
+len
, "HOST #%d: %s\n",
625 hostno
, adapter_name
);
627 len
+= sprintf(buffer
+len
, "FIFO Size=0x%x, FIFO Count=%d\n",
628 FIFO_Size
, FIFO_COUNT
);
630 len
+= sprintf(buffer
+len
, "DriverCalls=%d, Interrupts=%d, BytesRead=%d, BytesWrite=%d\n\n",
631 TOTAL_INTR
, INTR_Processed
, Bytes_Read
, Bytes_Written
);
634 if ((len
-= offset
) <= 0)
641 static int fd_mcs_select(struct Scsi_Host
*shpnt
, int target
)
644 unsigned long timeout
;
646 outb( 0x82, SCSI_Cntl_port
); /* Bus Enable + Select */
647 outb( adapter_mask
| (1 << target
), SCSI_Data_NoACK_port
);
649 /* Stop arbitration and enable parity */
650 outb( PARITY_MASK
, TMC_Cntl_port
);
652 timeout
= 350; /* 350mS -- because of timeouts
656 status
= inb( SCSI_Status_port
); /* Read adapter status */
657 if (status
& 1) { /* Busy asserted */
658 /* Enable SCSI Bus (on error, should make bus idle with 0) */
659 outb( 0x80, SCSI_Cntl_port
);
662 udelay(1000); /* wait one msec */
666 fd_mcs_make_bus_idle(shpnt
);
668 if (!target
) printk( "Selection failed\n" );
674 if (!flag
) /* Skip first failure for all chips. */
677 printk( "fd_mcs: Selection failed\n" );
683 static void my_done( struct Scsi_Host
*shpnt
, int error
)
687 outb( 0x00, Interrupt_Cntl_port
);
688 fd_mcs_make_bus_idle(shpnt
);
689 current_SC
->result
= error
;
690 current_SC
->scsi_done( current_SC
);
692 panic( "fd_mcs: my_done() called outside of command\n" );
695 in_interrupt_flag
= 0;
699 /* only my_done needs to be protected */
700 static void fd_mcs_intr( int irq
, void *dev_id
, struct pt_regs
* regs
)
705 unsigned data_count
, tmp_count
;
708 struct Scsi_Host
*shpnt
;
712 /* search for one adapter-response on shared interrupt */
713 while ((shpnt
= hosts
[i
++])) {
714 if ((inb(TMC_Status_port
)) & 1)
718 /* return if some other device on this IRQ caused the interrupt */
725 outb( 0x00, Interrupt_Cntl_port
);
727 /* Abort calls my_done, so we do nothing here. */
728 if (current_SC
->SCp
.phase
& aborted
) {
730 printk( "Interrupt after abort, ignoring\n" );
739 if (current_SC
->SCp
.phase
& in_arbitration
) {
740 status
= inb( TMC_Status_port
); /* Read adapter status */
741 if (!(status
& 0x02)) {
745 spin_lock_irqsave(&io_request_lock
, flags
);
746 my_done( shpnt
, DID_BUS_BUSY
<< 16 );
747 spin_unlock_irqrestore(&io_request_lock
, flags
);
750 current_SC
->SCp
.phase
= in_selection
;
752 outb( 0x40 | FIFO_COUNT
, Interrupt_Cntl_port
);
754 outb( 0x82, SCSI_Cntl_port
); /* Bus Enable + Select */
755 outb( adapter_mask
| (1 << current_SC
->target
), SCSI_Data_NoACK_port
);
757 /* Stop arbitration and enable parity */
758 outb( 0x10 | PARITY_MASK
, TMC_Cntl_port
);
760 in_interrupt_flag
= 0;
763 } else if (current_SC
->SCp
.phase
& in_selection
) {
764 status
= inb( SCSI_Status_port
);
765 if (!(status
& 0x01)) {
766 /* Try again, for slow devices */
767 if (fd_mcs_select(shpnt
, current_SC
->target
)) {
771 spin_lock_irqsave(&io_request_lock
, flags
);
772 my_done( shpnt
, DID_NO_CONNECT
<< 16 );
773 spin_unlock_irqrestore(&io_request_lock
, flags
);
777 printk( " AltSel " );
779 /* Stop arbitration and enable parity */
780 outb( 0x10 | PARITY_MASK
, TMC_Cntl_port
);
783 current_SC
->SCp
.phase
= in_other
;
784 outb( 0x90 | FIFO_COUNT
, Interrupt_Cntl_port
);
785 outb( 0x80, SCSI_Cntl_port
);
787 in_interrupt_flag
= 0;
792 /* current_SC->SCp.phase == in_other: this is the body of the routine */
794 status
= inb( SCSI_Status_port
);
796 if (status
& 0x10) { /* REQ */
798 switch (status
& 0x0e) {
800 case 0x08: /* COMMAND OUT */
801 outb( current_SC
->cmnd
[current_SC
->SCp
.sent_command
++],
802 Write_SCSI_Data_port
);
805 current_SC
->cmnd
[ current_SC
->SCp
.sent_command
- 1] );
808 case 0x00: /* DATA OUT -- tmc18c50/tmc18c30 only */
809 if (chip
!= tmc1800
&& !current_SC
->SCp
.have_data_in
) {
810 current_SC
->SCp
.have_data_in
= -1;
811 outb( 0xd0 | PARITY_MASK
, TMC_Cntl_port
);
814 case 0x04: /* DATA IN -- tmc18c50/tmc18c30 only */
815 if (chip
!= tmc1800
&& !current_SC
->SCp
.have_data_in
) {
816 current_SC
->SCp
.have_data_in
= 1;
817 outb( 0x90 | PARITY_MASK
, TMC_Cntl_port
);
820 case 0x0c: /* STATUS IN */
821 current_SC
->SCp
.Status
= inb( Read_SCSI_Data_port
);
823 printk( "Status = %x, ", current_SC
->SCp
.Status
);
826 if (current_SC
->SCp
.Status
827 && current_SC
->SCp
.Status
!= 2
828 && current_SC
->SCp
.Status
!= 8) {
829 printk( "ERROR fd_mcs: target = %d, command = %x, status = %x\n",
832 current_SC
->SCp
.Status
);
836 case 0x0a: /* MESSAGE OUT */
837 outb( MESSAGE_REJECT
, Write_SCSI_Data_port
); /* Reject */
839 case 0x0e: /* MESSAGE IN */
840 current_SC
->SCp
.Message
= inb( Read_SCSI_Data_port
);
842 printk( "Message = %x, ", current_SC
->SCp
.Message
);
844 if (!current_SC
->SCp
.Message
) ++done
;
845 #if DEBUG_MESSAGES || EVERY_ACCESS
846 if (current_SC
->SCp
.Message
) {
847 printk( "fd_mcs: message = %x\n", current_SC
->SCp
.Message
);
855 && !current_SC
->SCp
.have_data_in
856 && (current_SC
->SCp
.sent_command
857 >= current_SC
->cmd_len
)) {
858 /* We have to get the FIFO direction
859 correct, so I've made a table based
860 on the SCSI Standard of which commands
861 appear to require a DATA OUT phase.
864 p. 94: Command for all device types
865 CHANGE DEFINITION 40 DATA OUT
868 COPY AND VERIFY 3a DATA OUT
870 LOG SELECT 4c DATA OUT
872 MODE SELECT (6) 15 DATA OUT
873 MODE SELECT (10) 55 DATA OUT
877 RECEIVE DIAGNOSTIC RESULTS 1c
879 SEND DIAGNOSTIC 1d DATA OUT
881 WRITE BUFFER 3b DATA OUT
883 p.178: Commands for direct-access devices (not listed on p. 94)
884 FORMAT UNIT 04 DATA OUT
887 PREVENT-ALLOW MEDIUM REMOVAL 1e
891 READ DEFECT DATA (10) 37
893 REASSIGN BLOCKS 07 DATA OUT
896 REZERO UNIT/REWIND 01
897 SEARCH DATA EQUAL (10) 31 DATA OUT
898 SEARCH DATA HIGH (10) 30 DATA OUT
899 SEARCH DATA LOW (10) 32 DATA OUT
906 WRITE (6)/PRINT/SEND 0a DATA OUT
907 WRITE (10)/SEND 2a DATA OUT
908 WRITE AND VERIFY (10) 2e DATA OUT
909 WRITE LONG 3f DATA OUT
910 WRITE SAME 41 DATA OUT ?
912 p. 261: Commands for sequential-access devices (not previously listed)
919 RECOVER BUFFERED DATA 14
923 p. 298: Commands for printer devices (not previously listed)
924 ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****
925 SLEW AND PRINT 0b DATA OUT -- same as seek
927 SYNCHRONIZE BUFFER 10
929 p. 315: Commands for processor devices (not previously listed)
931 p. 321: Commands for write-once devices (not previously listed)
934 SEARCH DATA EQUAL (12) b1 DATA OUT
935 SEARCH DATA HIGH (12) b0 DATA OUT
936 SEARCH DATA LOW (12) b2 DATA OUT
939 WRITE (12) aa DATA OUT
940 WRITE AND VERIFY (12) ae DATA OUT
942 p. 332: Commands for CD-ROM devices (not previously listed)
947 PLAY TRACK RELATIVE (10) 49
948 PLAY TRACK RELATIVE (12) a9
953 p. 370: Commands for scanner devices (not previously listed)
954 GET DATA BUFFER STATUS 34
958 SET WINDOW 24 DATA OUT
960 p. 391: Commands for optical memory devices (not listed)
963 MEDIUM SCAN 38 DATA OUT
964 READ DEFECT DATA (12) b7
966 READ UPDATED BLOCK 2d
967 UPDATE BLOCK 3d DATA OUT
969 p. 419: Commands for medium changer devices (not listed)
971 INITIALIZE ELEMENT STATUS 07
973 POSITION TO ELEMENT 2b
974 READ ELEMENT STATUS b8
975 REQUEST VOL. ELEMENT ADDRESS b5
976 SEND VOLUME TAG b6 DATA OUT
978 p. 454: Commands for communications devices (not listed previously)
984 switch (current_SC
->cmnd
[0]) {
985 case CHANGE_DEFINITION
: case COMPARE
: case COPY
:
986 case COPY_VERIFY
: case LOG_SELECT
: case MODE_SELECT
:
987 case MODE_SELECT_10
: case SEND_DIAGNOSTIC
: case WRITE_BUFFER
:
989 case FORMAT_UNIT
: case REASSIGN_BLOCKS
: case RESERVE
:
990 case SEARCH_EQUAL
: case SEARCH_HIGH
: case SEARCH_LOW
:
991 case WRITE_6
: case WRITE_10
: case WRITE_VERIFY
:
992 case 0x3f: case 0x41:
994 case 0xb1: case 0xb0: case 0xb2:
995 case 0xaa: case 0xae:
999 case 0x38: case 0x3d:
1003 case 0xea: /* alternate number for WRITE LONG */
1005 current_SC
->SCp
.have_data_in
= -1;
1006 outb( 0xd0 | PARITY_MASK
, TMC_Cntl_port
);
1012 current_SC
->SCp
.have_data_in
= 1;
1013 outb( 0x90 | PARITY_MASK
, TMC_Cntl_port
);
1018 if (current_SC
->SCp
.have_data_in
== -1) { /* DATA OUT */
1019 while ( (data_count
= FIFO_Size
- inw( FIFO_Data_Count_port
)) > 512 ) {
1021 printk( "DC=%d, ", data_count
) ;
1023 if (data_count
> current_SC
->SCp
.this_residual
)
1024 data_count
= current_SC
->SCp
.this_residual
;
1025 if (data_count
> 0) {
1027 printk( "%d OUT, ", data_count
);
1029 if (data_count
== 1) {
1032 outb( *current_SC
->SCp
.ptr
++, Write_FIFO_port
);
1033 --current_SC
->SCp
.this_residual
;
1036 tmp_count
= data_count
<< 1;
1037 outsw( Write_FIFO_port
, current_SC
->SCp
.ptr
, data_count
);
1038 current_SC
->SCp
.ptr
+= tmp_count
;
1039 Bytes_Written
+= tmp_count
;
1040 current_SC
->SCp
.this_residual
-= tmp_count
;
1043 if (!current_SC
->SCp
.this_residual
) {
1044 if (current_SC
->SCp
.buffers_residual
) {
1045 --current_SC
->SCp
.buffers_residual
;
1046 ++current_SC
->SCp
.buffer
;
1047 current_SC
->SCp
.ptr
= current_SC
->SCp
.buffer
->address
;
1048 current_SC
->SCp
.this_residual
= current_SC
->SCp
.buffer
->length
;
1053 } else if (current_SC
->SCp
.have_data_in
== 1) { /* DATA IN */
1054 while ((data_count
= inw( FIFO_Data_Count_port
)) > 0) {
1056 printk( "DC=%d, ", data_count
);
1058 if (data_count
> current_SC
->SCp
.this_residual
)
1059 data_count
= current_SC
->SCp
.this_residual
;
1062 printk( "%d IN, ", data_count
);
1064 if (data_count
== 1) {
1066 *current_SC
->SCp
.ptr
++ = inb( Read_FIFO_port
);
1067 --current_SC
->SCp
.this_residual
;
1069 data_count
>>= 1; /* Number of words */
1070 tmp_count
= data_count
<< 1;
1071 insw( Read_FIFO_port
, current_SC
->SCp
.ptr
, data_count
);
1072 current_SC
->SCp
.ptr
+= tmp_count
;
1073 Bytes_Read
+= tmp_count
;
1074 current_SC
->SCp
.this_residual
-= tmp_count
;
1077 if (!current_SC
->SCp
.this_residual
1078 && current_SC
->SCp
.buffers_residual
) {
1079 --current_SC
->SCp
.buffers_residual
;
1080 ++current_SC
->SCp
.buffer
;
1081 current_SC
->SCp
.ptr
= current_SC
->SCp
.buffer
->address
;
1082 current_SC
->SCp
.this_residual
= current_SC
->SCp
.buffer
->length
;
1089 printk( " ** IN DONE %d ** ", current_SC
->SCp
.have_data_in
);
1093 if (current_SC
->cmnd
[0] == REQUEST_SENSE
&& !current_SC
->SCp
.Status
) {
1094 if ((unsigned char)(*((char *)current_SC
->request_buffer
+2)) & 0x0f) {
1097 unsigned char qualifier
;
1099 key
= (unsigned char)(*((char *)current_SC
->request_buffer
+ 2))
1101 code
= (unsigned char)(*((char *)current_SC
->request_buffer
+ 12));
1102 qualifier
= (unsigned char)(*((char *)current_SC
->request_buffer
1105 if (key
!= UNIT_ATTENTION
1106 && !(key
== NOT_READY
1108 && (!qualifier
|| qualifier
== 0x02 || qualifier
== 0x01))
1109 && !(key
== ILLEGAL_REQUEST
&& (code
== 0x25
1113 printk( "fd_mcs: REQUEST SENSE "
1114 "Key = %x, Code = %x, Qualifier = %x\n",
1115 key
, code
, qualifier
);
1120 printk( "BEFORE MY_DONE. . ." );
1122 spin_lock_irqsave(&io_request_lock
, flags
);
1124 (current_SC
->SCp
.Status
& 0xff)
1125 | ((current_SC
->SCp
.Message
& 0xff) << 8) | (DID_OK
<< 16) );
1126 spin_unlock_irqrestore(&io_request_lock
, flags
);
1128 printk( "RETURNING.\n" );
1132 if (current_SC
->SCp
.phase
& disconnect
) {
1133 outb( 0xd0 | FIFO_COUNT
, Interrupt_Cntl_port
);
1134 outb( 0x00, SCSI_Cntl_port
);
1136 outb( 0x90 | FIFO_COUNT
, Interrupt_Cntl_port
);
1140 in_interrupt_flag
= 0;
1145 int fd_mcs_release(struct Scsi_Host
*shpnt
)
1147 int i
, this_host
, irq_usage
;
1149 release_region(shpnt
->io_port
, shpnt
->n_io_port
);
1153 for (i
= 0; i
< found
; i
++) {
1154 if (shpnt
== hosts
[i
])
1156 if (shpnt
->irq
== hosts
[i
]->irq
)
1160 /* only for the last one */
1162 free_irq(shpnt
->irq
, hosts
);
1166 for (i
= this_host
; i
< found
; i
++)
1167 hosts
[i
] = hosts
[i
+1];
1169 hosts
[found
] = NULL
;
1174 int fd_mcs_queue( Scsi_Cmnd
* SCpnt
, void (*done
)(Scsi_Cmnd
*))
1176 struct Scsi_Host
*shpnt
= SCpnt
->host
;
1179 panic( "fd_mcs: fd_mcs_queue() NOT REENTRANT!\n" );
1182 printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1184 *(unsigned char *)SCpnt
->cmnd
,
1186 SCpnt
->request_bufflen
);
1189 fd_mcs_make_bus_idle(shpnt
);
1191 SCpnt
->scsi_done
= done
; /* Save this for the done function */
1194 /* Initialize static data */
1196 if (current_SC
->use_sg
) {
1197 current_SC
->SCp
.buffer
=
1198 (struct scatterlist
*)current_SC
->request_buffer
;
1199 current_SC
->SCp
.ptr
= current_SC
->SCp
.buffer
->address
;
1200 current_SC
->SCp
.this_residual
= current_SC
->SCp
.buffer
->length
;
1201 current_SC
->SCp
.buffers_residual
= current_SC
->use_sg
- 1;
1203 current_SC
->SCp
.ptr
= (char *)current_SC
->request_buffer
;
1204 current_SC
->SCp
.this_residual
= current_SC
->request_bufflen
;
1205 current_SC
->SCp
.buffer
= NULL
;
1206 current_SC
->SCp
.buffers_residual
= 0;
1210 current_SC
->SCp
.Status
= 0;
1211 current_SC
->SCp
.Message
= 0;
1212 current_SC
->SCp
.have_data_in
= 0;
1213 current_SC
->SCp
.sent_command
= 0;
1214 current_SC
->SCp
.phase
= in_arbitration
;
1216 /* Start arbitration */
1217 outb( 0x00, Interrupt_Cntl_port
);
1218 outb( 0x00, SCSI_Cntl_port
); /* Disable data drivers */
1219 outb( adapter_mask
, SCSI_Data_NoACK_port
); /* Set our id bit */
1221 outb( 0x20, Interrupt_Cntl_port
);
1222 outb( 0x14 | PARITY_MASK
, TMC_Cntl_port
); /* Start arbitration */
1227 static void internal_done( Scsi_Cmnd
*SCpnt
)
1230 SCpnt
->host_scribble
= (unsigned char *)1;
1233 int fd_mcs_command( Scsi_Cmnd
*SCpnt
)
1235 fd_mcs_queue( SCpnt
, internal_done
);
1236 /* host_scribble is used for status here */
1237 SCpnt
->host_scribble
= NULL
;
1238 while (!SCpnt
->host_scribble
)
1240 return SCpnt
->result
;
1243 #if DEBUG_ABORT || DEBUG_RESET
1244 static void fd_mcs_print_info( Scsi_Cmnd
*SCpnt
)
1249 struct Scsi_Host
*shpnt
= SCpnt
->host
;
1251 if (!SCpnt
|| !SCpnt
->host
) {
1252 printk( "fd_mcs: cannot provide detailed information\n" );
1255 printk( "%s\n", fd_mcs_info( SCpnt
->host
) );
1256 print_banner( SCpnt
->host
);
1257 switch (SCpnt
->SCp
.phase
) {
1258 case in_arbitration
: printk( "arbitration " ); break;
1259 case in_selection
: printk( "selection " ); break;
1260 case in_other
: printk( "other " ); break;
1261 default: printk( "unknown " ); break;
1264 printk( "(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1267 *(unsigned char *)SCpnt
->cmnd
,
1269 SCpnt
->request_bufflen
);
1270 printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
1271 SCpnt
->SCp
.sent_command
,
1272 SCpnt
->SCp
.have_data_in
,
1275 printk( "in_interrupt_flag = %d\n", in_interrupt_flag
);
1278 imr
= (inb( 0x0a1 ) << 8) + inb( 0x21 );
1280 irr
= inb( 0xa0 ) << 8;
1284 isr
= inb( 0xa0 ) << 8;
1288 /* Print out interesting information */
1289 printk( "IMR = 0x%04x", imr
);
1290 if (imr
& (1 << shpnt
->irq
))
1291 printk( " (masked)" );
1292 printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr
, isr
);
1294 printk( "SCSI Status = 0x%02x\n", inb( SCSI_Status_port
) );
1295 printk( "TMC Status = 0x%02x", inb( TMC_Status_port
) );
1296 if (inb( TMC_Status_port
) & 1)
1297 printk( " (interrupt)" );
1299 printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port
) );
1300 if (inb( Interrupt_Status_port
) & 0x08)
1301 printk( " (enabled)" );
1303 if (chip
== tmc18c50
|| chip
== tmc18c30
) {
1304 printk( "FIFO Status = 0x%02x\n", inb( shpnt
->io_port
+ FIFO_Status
) );
1305 printk( "Int. Condition = 0x%02x\n",
1306 inb( shpnt
->io_port
+ Interrupt_Cond
) );
1308 printk( "Configuration 1 = 0x%02x\n", inb( shpnt
->io_port
+ Configuration1
) );
1309 if (chip
== tmc18c50
|| chip
== tmc18c30
)
1310 printk( "Configuration 2 = 0x%02x\n",
1311 inb( shpnt
->io_port
+ Configuration2
) );
1315 int fd_mcs_abort( Scsi_Cmnd
*SCpnt
)
1317 struct Scsi_Host
*shpnt
= SCpnt
->host
;
1319 unsigned long flags
;
1320 #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1321 printk( "fd_mcs: abort " );
1324 save_flags( flags
);
1327 #if EVERY_ACCESS || ERRORS_ONLY
1328 printk( " (not in command)\n" );
1330 restore_flags( flags
);
1331 return SCSI_ABORT_NOT_RUNNING
;
1332 } else printk( "\n" );
1335 fd_mcs_print_info( SCpnt
);
1338 fd_mcs_make_bus_idle(shpnt
);
1340 current_SC
->SCp
.phase
|= aborted
;
1342 current_SC
->result
= DID_ABORT
<< 16;
1344 restore_flags( flags
);
1346 /* Aborts are not done well. . . */
1347 spin_lock_irqsave(&io_request_lock
, flags
);
1348 my_done( shpnt
, DID_ABORT
<< 16 );
1349 spin_unlock_irqrestore(&io_request_lock
, flags
);
1351 return SCSI_ABORT_SUCCESS
;
1354 int fd_mcs_reset( Scsi_Cmnd
*SCpnt
, unsigned int reset_flags
)
1356 struct Scsi_Host
*shpnt
= SCpnt
->host
;
1359 static int called_once
= 0;
1363 if (SCpnt
) printk( "fd_mcs: SCSI Bus Reset\n" );
1367 if (called_once
) fd_mcs_print_info( current_SC
);
1371 outb( 1, SCSI_Cntl_port
);
1373 outb( 0, SCSI_Cntl_port
);
1375 outb( 0, SCSI_Mode_Cntl_port
);
1376 outb( PARITY_MASK
, TMC_Cntl_port
);
1378 /* Unless this is the very first call (i.e., SCPnt == NULL), everything
1379 is probably hosed at this point. We will, however, try to keep
1380 things going by informing the high-level code that we need help. */
1382 return SCSI_RESET_WAKEUP
;
1386 #include <scsi/scsi_ioctl.h>
1388 int fd_mcs_biosparam( Scsi_Disk
*disk
, kdev_t dev
, int *info_array
)
1391 unsigned char buf
[512 + sizeof( int ) * 2];
1392 int size
= disk
->capacity
;
1393 int *sizes
= (int *)buf
;
1394 unsigned char *data
= (unsigned char *)(sizes
+ 2);
1395 unsigned char do_read
[] = { READ_6
, 0, 0, 0, 1, 0 };
1398 /* BIOS >= 3.4 for MCA cards */
1399 drive
= MINOR(dev
) / 16;
1401 /* This algorithm was provided by Future Domain (much thanks!). */
1403 sizes
[0] = 0; /* zero bytes out */
1404 sizes
[1] = 512; /* one sector in */
1405 memcpy( data
, do_read
, sizeof( do_read
) );
1406 retcode
= kernel_scsi_ioctl( disk
->device
,
1407 SCSI_IOCTL_SEND_COMMAND
,
1409 if (!retcode
/* SCSI command ok */
1410 && data
[511] == 0xaa && data
[510] == 0x55 /* Partition table valid */
1411 && data
[0x1c2]) { /* Partition type */
1413 /* The partition table layout is as follows:
1416 Offset: 0 = partition status
1418 2 = starting sector and cylinder (word, encoded)
1421 6 = ending sector and cylinder (word, encoded)
1422 8 = starting absolute sector (double word)
1423 c = number of sectors (double word)
1424 Signature: 0x1fe = 0x55aa
1426 So, this algorithm assumes:
1427 1) the first partition table is in use,
1428 2) the data in the first entry is correct, and
1429 3) partitions never divide cylinders
1431 Note that (1) may be FALSE for NetBSD (and other BSD flavors),
1432 as well as for Linux. Note also, that Linux doesn't pay any
1433 attention to the fields that are used by this algorithm -- it
1434 only uses the absolute sector data. Recent versions of Linux's
1435 fdisk(1) will fill this data in correctly, and forthcoming
1436 versions will check for consistency.
1438 Checking for a non-zero partition type is not part of the
1439 Future Domain algorithm, but it seemed to be a reasonable thing
1440 to do, especially in the Linux and BSD worlds. */
1442 info_array
[0] = data
[0x1c3] + 1; /* heads */
1443 info_array
[1] = data
[0x1c4] & 0x3f; /* sectors */
1446 /* Note that this new method guarantees that there will always be
1447 less than 1024 cylinders on a platter. This is good for drives
1448 up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
1450 if ((unsigned int)size
>= 0x7e0000U
) {
1451 info_array
[0] = 0xff; /* heads = 255 */
1452 info_array
[1] = 0x3f; /* sectors = 63 */
1453 } else if ((unsigned int)size
>= 0x200000U
) {
1454 info_array
[0] = 0x80; /* heads = 128 */
1455 info_array
[1] = 0x3f; /* sectors = 63 */
1457 info_array
[0] = 0x40; /* heads = 64 */
1458 info_array
[1] = 0x20; /* sectors = 32 */
1461 /* For both methods, compute the cylinders */
1462 info_array
[2] = (unsigned int)size
/ (info_array
[0] * info_array
[1] );
1468 /* Eventually this will go into an include file, but this will be later */
1469 static Scsi_Host_Template driver_template
= FD_MCS
;
1471 #include "scsi_module.c"