Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / drivers / scsi / fd_mcs.c
blob097893204f3cc30bc7234e9cef048f5ac8d7c6a3
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
8 * of MCS 700.
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
36 * later version.
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 #ifdef MODULE
81 #include <linux/module.h>
82 #endif
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>
93 #include <asm/io.h>
94 #include <asm/system.h>
96 #include "scsi.h"
97 #include "hosts.h"
98 #include "fd_mcs.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 */
110 #if DEBUG
111 #define EVERY_ACCESS 0 /* Write a line on every scsi access */
112 #define ERRORS_ONLY 1 /* Only write a line if there is an error */
113 #define DEBUG_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 */
118 #else
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
125 #define DEBUG_RACE 0
126 #endif
128 /* Errors are reported on the line, so we don't need to report them again */
129 #if EVERY_ACCESS
130 #undef ERRORS_ONLY
131 #define ERRORS_ONLY 0
132 #endif
134 #if ENABLE_PARITY
135 #define PARITY_MASK 0x08
136 #else
137 #define PARITY_MASK 0x00
138 #endif
140 enum chip_type {
141 unknown = 0x00,
142 tmc1800 = 0x01,
143 tmc18c50 = 0x02,
144 tmc18c30 = 0x03,
147 enum {
148 in_arbitration = 0x02,
149 in_selection = 0x04,
150 in_other = 0x08,
151 disconnect = 0x10,
152 aborted = 0x20,
153 sent_ident = 0x40,
156 enum in_port_type {
157 Read_SCSI_Data = 0,
158 SCSI_Status = 1,
159 TMC_Status = 2,
160 FIFO_Status = 3, /* tmc18c50/tmc18c30 only */
161 Interrupt_Cond = 4, /* tmc18c50/tmc18c30 only */
162 LSB_ID_Code = 5,
163 MSB_ID_Code = 6,
164 Read_Loopback = 7,
165 SCSI_Data_NoACK = 8,
166 Interrupt_Status = 9,
167 Configuration1 = 10,
168 Configuration2 = 11, /* tmc18c50/tmc18c30 only */
169 Read_FIFO = 12,
170 FIFO_Data_Count = 14
173 enum out_port_type {
174 Write_SCSI_Data = 0,
175 SCSI_Cntl = 1,
176 Interrupt_Cntl = 2,
177 SCSI_Mode_Cntl = 3,
178 TMC_Cntl = 4,
179 Memory_Cntl = 5, /* tmc18c50/tmc18c30 only */
180 Write_Loopback = 7,
181 IO_Control = 11, /* tmc18c30 only */
182 Write_FIFO = 12
185 struct fd_hostdata {
186 unsigned long _bios_base;
187 int _bios_major;
188 int _bios_minor;
189 volatile int _in_command;
190 Scsi_Cmnd *_current_SC;
191 enum chip_type _chip;
192 int _adapter_mask;
193 int _fifo_count; /* Number of 512 byte blocks before INTR */
195 char _adapter_name[64];
196 #if DEBUG_RACE
197 volatile int _in_interrupt_flag;
198 #endif
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;
205 int _Read_FIFO_port;
206 int _Read_SCSI_Data_port;
207 int _SCSI_Cntl_port;
208 int _SCSI_Data_NoACK_port;
209 int _SCSI_Status_port;
210 int _TMC_Cntl_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 */
217 /* simple stats */
218 int _Bytes_Read;
219 int _Bytes_Written;
220 int _INTR_Processed;
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)
235 #if DEBUG_RACE
236 #define in_interrupt_flag (HOSTDATA(shpnt)->_in_interrupt_flag)
237 #endif
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 {
258 char* name;
259 int id;
260 enum chip_type fd_chip;
261 int fifo_size;
262 int fifo_count;
265 #define REPLY_ID 0x5137
267 static struct fd_mcs_adapters_struct fd_mcs_adapters[] = {
268 { "Future Domain SCSI Adapter MCS-700(18C50)",
269 0x60e9,
270 tmc18c50,
271 0x2000,
272 4 },
273 { "Future Domain SCSI Adapter MCS-600/700(TMC-1800)",
274 0x6127,
275 tmc1800,
276 0x2000,
277 4 },
278 { "Reply Sound Blaster/SCSI Adapter",
279 REPLY_ID,
280 tmc18c30,
281 0x800,
282 2 },
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);
317 if (bios_base) {
318 printk( "BIOS at 0x%lX", bios_base);
319 } else {
320 printk( "No BIOS");
323 printk( ", HostID %d, %s Chip, IRQ %d, IO 0x%lX\n",
324 shpnt->this_id,
325 chip == tmc18c50 ? "TMC-18C50"
326 : (chip == tmc18c30 ? "TMC-18C30" :
327 (chip == tmc1800 ? "TMC-1800" : "Unknown")),
328 shpnt->irq,
329 shpnt->io_port );
333 static void do_pause( unsigned amount ) /* Pause for amount*10 milliseconds */
335 do {
336 udelay(10*1000);
337 } while (--amount);
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. */
346 else
347 outb( 0x01 | PARITY_MASK, TMC_Cntl_port );
350 int fd_mcs_detect( Scsi_Host_Template *tpnt )
352 int loop;
353 struct Scsi_Host *shpnt;
355 /* get id, port, bios, irq */
356 int slot;
357 u_char pos2, pos3, pos4;
358 int id, port, irq;
359 unsigned long bios;
361 /* if not MCA machine, return */
362 if (!MCA_bus)
363 return 0;
365 /* changeable? */
366 id = 7;
368 for( loop = 0; loop < FD_BRDS; loop++ ) {
369 slot = 0;
370 while ( MCA_NOTFOUND !=
371 (slot = mca_find_adapter(fd_mcs_adapters[loop].id,
372 slot)) ) {
374 /* if we get this far, an adapter has been detected and is
375 enabled */
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 */
385 slot++;
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 */
392 if (pos2 & 0x2)
393 port = ports[pos4 & 0x3];
394 else
395 continue;
397 /* can't really disable it, same as irq=10 */
398 irq = reply_irq[((pos4 >> 2) & 0x1) + 2*((pos4 >> 4) & 0x1)];
399 } else {
400 bios = addresses[pos2 >> 6];
401 port = ports[(pos2 >> 4) & 0x03];
402 irq = ints[(pos2 >> 1) & 0x07];
405 if (irq) {
406 /* claim the slot */
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");
415 continue;
418 /* register */
419 if (!(shpnt = scsi_register(tpnt, sizeof(struct fd_hostdata)))) {
420 printk( "fd_mcs: scsi_register() failed\n");
421 continue;
424 /* request I/O region */
425 request_region( port, 0x10, "fd_mcs" );
427 /* save name */
428 strcpy(adapter_name, fd_mcs_adapters[loop].name);
430 /* chip/fifo */
431 chip = fd_mcs_adapters[loop].fd_chip;
432 /* use boot time value if available */
433 FIFO_COUNT =
434 user_fifo_count?user_fifo_count:fd_mcs_adapters[loop].fifo_count;
435 FIFO_Size =
436 user_fifo_size?user_fifo_size:fd_mcs_adapters[loop].fifo_size;
438 #ifdef NOT_USED
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) {
448 chip = tmc18c30;
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) {
461 chip = tmc18c30;
462 FIFO_Size = 0x800; /* 2k FIFO */
464 printk("SECOND: chip=%s, fifo_size=0x%x\n",
465 (chip == tmc18c30)?"tmc18c30":"tmc18c50", FIFO_Size);
467 /* *************************************************** */
468 #endif
470 /* IBM/ANSI scsi scan ordering */
471 /* Stick this back in when the scsi.c changes are there */
472 shpnt->reverse_ordering = 1;
475 /* saving info */
476 hosts[found++] = shpnt;
478 shpnt->this_id = id;
479 shpnt->irq = irq;
480 shpnt->io_port = port;
481 shpnt->n_io_port = 0x10;
483 /* save */
484 bios_base = bios;
485 adapter_mask = (1 << id);
487 /* save more */
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;
503 Bytes_Read = 0;
504 Bytes_Written = 0;
505 INTR_Processed = 0;
507 /* say something */
508 print_banner( shpnt );
510 /* reset */
511 outb( 1, SCSI_Cntl_port );
512 do_pause( 2 );
513 outb( 0, SCSI_Cntl_port );
514 do_pause( 115 );
515 outb( 0, SCSI_Mode_Cntl_port );
516 outb( PARITY_MASK, TMC_Cntl_port );
517 /* done reset */
519 #if DO_DETECT
520 /* scan devices attached */
522 const int buflen = 255;
523 int i, j, retcode;
524 Scsi_Cmnd SCinit;
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;
534 SCinit.use_sg = 0;
535 SCinit.lun = 0;
536 SCinit.host = shpnt;
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 */
541 continue;
542 SCinit.target = i;
543 memcpy(SCinit.cmnd, do_request_sense,
544 sizeof(do_request_sense));
545 retcode = fd_mcs_command(&SCinit);
546 if (!retcode) {
547 memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
548 retcode = fd_mcs_command(&SCinit);
549 if (!retcode) {
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);
556 if (!retcode) {
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 );
572 #endif
576 if (found == FD_MAX_HOSTS) {
577 printk( "fd_mcs: detecting reached max=%d host adapters.\n",
578 FD_MAX_HOSTS);
579 break;
583 return found;
586 const char *fd_mcs_info(struct Scsi_Host *shpnt)
588 return adapter_name;
591 static int TOTAL_INTR = 0;
594 * inout : decides on the direction of the dataflow and the meaning of the
595 * variables
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;
607 int len = 0;
608 int i;
610 if (inout)
611 return(-ENOSYS);
613 *start = buffer + offset;
615 for (i = 0; hosts[i] && hosts[i]->host_no != hostno; i++);
616 shpnt = hosts[i];
618 if (!shpnt) {
619 return(-ENOENT);
620 } else {
621 len += sprintf(buffer+len, "Future Domain MCS-600/700 Driver %s\n",
622 DRIVER_VERSION);
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)
635 return 0;
636 if (len > length)
637 len = length;
638 return len;
641 static int fd_mcs_select(struct Scsi_Host *shpnt, int target )
643 int status;
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
653 (was 250mS) */
655 do {
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 );
660 return 0;
662 udelay(1000); /* wait one msec */
663 } while (--timeout);
665 /* Make bus idle */
666 fd_mcs_make_bus_idle(shpnt);
667 #if EVERY_ACCESS
668 if (!target) printk( "Selection failed\n" );
669 #endif
670 #if ERRORS_ONLY
671 if (!target) {
672 static int flag = 0;
674 if (!flag) /* Skip first failure for all chips. */
675 ++flag;
676 else
677 printk( "fd_mcs: Selection failed\n" );
679 #endif
680 return 1;
683 static void my_done( struct Scsi_Host *shpnt, int error )
685 if (in_command) {
686 in_command = 0;
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 );
691 } else {
692 panic( "fd_mcs: my_done() called outside of command\n" );
694 #if DEBUG_RACE
695 in_interrupt_flag = 0;
696 #endif
699 /* only my_done needs to be protected */
700 static void fd_mcs_intr( int irq, void *dev_id, struct pt_regs * regs )
702 unsigned long flags;
703 int status;
704 int done = 0;
705 unsigned data_count, tmp_count;
707 int i = 0;
708 struct Scsi_Host *shpnt;
710 TOTAL_INTR++;
712 /* search for one adapter-response on shared interrupt */
713 while ((shpnt = hosts[i++])) {
714 if ((inb(TMC_Status_port)) & 1)
715 break;
718 /* return if some other device on this IRQ caused the interrupt */
719 if (!shpnt) {
720 return;
723 INTR_Processed++;
725 outb( 0x00, Interrupt_Cntl_port );
727 /* Abort calls my_done, so we do nothing here. */
728 if (current_SC->SCp.phase & aborted) {
729 #if DEBUG_ABORT
730 printk( "Interrupt after abort, ignoring\n" );
731 #endif
732 /* return; */
735 #if DEBUG_RACE
736 ++in_interrupt_flag;
737 #endif
739 if (current_SC->SCp.phase & in_arbitration) {
740 status = inb( TMC_Status_port ); /* Read adapter status */
741 if (!(status & 0x02)) {
742 #if EVERY_ACCESS
743 printk( " AFAIL " );
744 #endif
745 spin_lock_irqsave(&io_request_lock, flags);
746 my_done( shpnt, DID_BUS_BUSY << 16 );
747 spin_unlock_irqrestore(&io_request_lock, flags);
748 return;
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 );
759 #if DEBUG_RACE
760 in_interrupt_flag = 0;
761 #endif
762 return;
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 )) {
768 #if EVERY_ACCESS
769 printk( " SFAIL " );
770 #endif
771 spin_lock_irqsave(&io_request_lock, flags);
772 my_done( shpnt, DID_NO_CONNECT << 16 );
773 spin_unlock_irqrestore(&io_request_lock, flags);
774 return;
775 } else {
776 #if EVERY_ACCESS
777 printk( " AltSel " );
778 #endif
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 );
786 #if DEBUG_RACE
787 in_interrupt_flag = 0;
788 #endif
789 return;
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 );
803 #if EVERY_ACCESS
804 printk( "CMD = %x,",
805 current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
806 #endif
807 break;
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 );
813 break;
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 );
819 break;
820 case 0x0c: /* STATUS IN */
821 current_SC->SCp.Status = inb( Read_SCSI_Data_port );
822 #if EVERY_ACCESS
823 printk( "Status = %x, ", current_SC->SCp.Status );
824 #endif
825 #if ERRORS_ONLY
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",
830 current_SC->target,
831 current_SC->cmnd[0],
832 current_SC->SCp.Status );
834 #endif
835 break;
836 case 0x0a: /* MESSAGE OUT */
837 outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */
838 break;
839 case 0x0e: /* MESSAGE IN */
840 current_SC->SCp.Message = inb( Read_SCSI_Data_port );
841 #if EVERY_ACCESS
842 printk( "Message = %x, ", current_SC->SCp.Message );
843 #endif
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 );
849 #endif
850 break;
854 if (chip == tmc1800
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
866 COMPARE 39 DATA OUT
867 COPY 18 DATA OUT
868 COPY AND VERIFY 3a DATA OUT
869 INQUIRY 12
870 LOG SELECT 4c DATA OUT
871 LOG SENSE 4d
872 MODE SELECT (6) 15 DATA OUT
873 MODE SELECT (10) 55 DATA OUT
874 MODE SENSE (6) 1a
875 MODE SENSE (10) 5a
876 READ BUFFER 3c
877 RECEIVE DIAGNOSTIC RESULTS 1c
878 REQUEST SENSE 03
879 SEND DIAGNOSTIC 1d DATA OUT
880 TEST UNIT READY 00
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
885 LOCK-UNLOCK CACHE 36
886 PRE-FETCH 34
887 PREVENT-ALLOW MEDIUM REMOVAL 1e
888 READ (6)/RECEIVE 08
889 READ (10) 3c
890 READ CAPACITY 25
891 READ DEFECT DATA (10) 37
892 READ LONG 3e
893 REASSIGN BLOCKS 07 DATA OUT
894 RELEASE 17
895 RESERVE 16 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
900 SEEK (6) 0b
901 SEEK (10) 2b
902 SET LIMITS (10) 33
903 START STOP UNIT 1b
904 SYNCHRONIZE CACHE 35
905 VERIFY (10) 2f
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)
913 ERASE 19
914 LOAD UNLOAD 1b
915 LOCATE 2b
916 READ BLOCK LIMITS 05
917 READ POSITION 34
918 READ REVERSE 0f
919 RECOVER BUFFERED DATA 14
920 SPACE 11
921 WRITE FILEMARKS 10 ?
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
926 STOP PRINT 1b
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)
932 MEDIUM SCAN 38
933 READ (12) a8
934 SEARCH DATA EQUAL (12) b1 DATA OUT
935 SEARCH DATA HIGH (12) b0 DATA OUT
936 SEARCH DATA LOW (12) b2 DATA OUT
937 SET LIMITS (12) b3
938 VERIFY (12) af
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)
943 PAUSE/RESUME 4b
944 PLAY AUDIO (10) 45
945 PLAY AUDIO (12) a5
946 PLAY AUDIO MSF 47
947 PLAY TRACK RELATIVE (10) 49
948 PLAY TRACK RELATIVE (12) a9
949 READ HEADER 44
950 READ SUB-CHANNEL 42
951 READ TOC 43
953 p. 370: Commands for scanner devices (not previously listed)
954 GET DATA BUFFER STATUS 34
955 GET WINDOW 25
956 OBJECT POSITION 31
957 SCAN 1b
958 SET WINDOW 24 DATA OUT
960 p. 391: Commands for optical memory devices (not listed)
961 ERASE (10) 2c
962 ERASE (12) ac
963 MEDIUM SCAN 38 DATA OUT
964 READ DEFECT DATA (12) b7
965 READ GENERATION 29
966 READ UPDATED BLOCK 2d
967 UPDATE BLOCK 3d DATA OUT
969 p. 419: Commands for medium changer devices (not listed)
970 EXCHANGE MEDIUM 46
971 INITIALIZE ELEMENT STATUS 07
972 MOVE MEDIUM a5
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)
979 GET MESSAGE (6) 08
980 GET MESSAGE (10) 28
981 GET MESSAGE (12) a8
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:
997 case 0x24:
999 case 0x38: case 0x3d:
1001 case 0xb6:
1003 case 0xea: /* alternate number for WRITE LONG */
1005 current_SC->SCp.have_data_in = -1;
1006 outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1007 break;
1009 case 0x00:
1010 default:
1012 current_SC->SCp.have_data_in = 1;
1013 outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1014 break;
1018 if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */
1019 while ( (data_count = FIFO_Size - inw( FIFO_Data_Count_port )) > 512 ) {
1020 #if EVERY_ACCESS
1021 printk( "DC=%d, ", data_count ) ;
1022 #endif
1023 if (data_count > current_SC->SCp.this_residual)
1024 data_count = current_SC->SCp.this_residual;
1025 if (data_count > 0) {
1026 #if EVERY_ACCESS
1027 printk( "%d OUT, ", data_count );
1028 #endif
1029 if (data_count == 1) {
1030 Bytes_Written++;
1032 outb( *current_SC->SCp.ptr++, Write_FIFO_port );
1033 --current_SC->SCp.this_residual;
1034 } else {
1035 data_count >>= 1;
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;
1049 } else
1050 break;
1053 } else if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
1054 while ((data_count = inw( FIFO_Data_Count_port )) > 0) {
1055 #if EVERY_ACCESS
1056 printk( "DC=%d, ", data_count );
1057 #endif
1058 if (data_count > current_SC->SCp.this_residual)
1059 data_count = current_SC->SCp.this_residual;
1060 if (data_count) {
1061 #if EVERY_ACCESS
1062 printk( "%d IN, ", data_count );
1063 #endif
1064 if (data_count == 1) {
1065 Bytes_Read++;
1066 *current_SC->SCp.ptr++ = inb( Read_FIFO_port );
1067 --current_SC->SCp.this_residual;
1068 } else {
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;
1087 if (done) {
1088 #if EVERY_ACCESS
1089 printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
1090 #endif
1092 #if ERRORS_ONLY
1093 if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
1094 if ((unsigned char)(*((char *)current_SC->request_buffer+2)) & 0x0f) {
1095 unsigned char key;
1096 unsigned char code;
1097 unsigned char qualifier;
1099 key = (unsigned char)(*((char *)current_SC->request_buffer + 2))
1100 & 0x0f;
1101 code = (unsigned char)(*((char *)current_SC->request_buffer + 12));
1102 qualifier = (unsigned char)(*((char *)current_SC->request_buffer
1103 + 13));
1105 if (key != UNIT_ATTENTION
1106 && !(key == NOT_READY
1107 && code == 0x04
1108 && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1109 && !(key == ILLEGAL_REQUEST && (code == 0x25
1110 || code == 0x24
1111 || !code)))
1113 printk( "fd_mcs: REQUEST SENSE "
1114 "Key = %x, Code = %x, Qualifier = %x\n",
1115 key, code, qualifier );
1118 #endif
1119 #if EVERY_ACCESS
1120 printk( "BEFORE MY_DONE. . ." );
1121 #endif
1122 spin_lock_irqsave(&io_request_lock, flags);
1123 my_done( shpnt,
1124 (current_SC->SCp.Status & 0xff)
1125 | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
1126 spin_unlock_irqrestore(&io_request_lock, flags);
1127 #if EVERY_ACCESS
1128 printk( "RETURNING.\n" );
1129 #endif
1131 } else {
1132 if (current_SC->SCp.phase & disconnect) {
1133 outb( 0xd0 | FIFO_COUNT, Interrupt_Cntl_port );
1134 outb( 0x00, SCSI_Cntl_port );
1135 } else {
1136 outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
1139 #if DEBUG_RACE
1140 in_interrupt_flag = 0;
1141 #endif
1142 return;
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);
1151 this_host = -1;
1152 irq_usage = 0;
1153 for (i = 0; i < found; i++) {
1154 if (shpnt == hosts[i])
1155 this_host = i;
1156 if (shpnt->irq == hosts[i]->irq)
1157 irq_usage++;
1160 /* only for the last one */
1161 if (1 == irq_usage)
1162 free_irq(shpnt->irq, hosts);
1164 found--;
1166 for (i = this_host; i < found; i++)
1167 hosts[i] = hosts[i+1];
1169 hosts[found] = NULL;
1171 return 0;
1174 int fd_mcs_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
1176 struct Scsi_Host *shpnt = SCpnt->host;
1178 if (in_command) {
1179 panic( "fd_mcs: fd_mcs_queue() NOT REENTRANT!\n" );
1181 #if EVERY_ACCESS
1182 printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1183 SCpnt->target,
1184 *(unsigned char *)SCpnt->cmnd,
1185 SCpnt->use_sg,
1186 SCpnt->request_bufflen );
1187 #endif
1189 fd_mcs_make_bus_idle(shpnt);
1191 SCpnt->scsi_done = done; /* Save this for the done function */
1192 current_SC = SCpnt;
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;
1202 } else {
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 */
1220 in_command = 1;
1221 outb( 0x20, Interrupt_Cntl_port );
1222 outb( 0x14 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
1224 return 0;
1227 static void internal_done( Scsi_Cmnd *SCpnt )
1229 /* flag it done */
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)
1239 barrier();
1240 return SCpnt->result;
1243 #if DEBUG_ABORT || DEBUG_RESET
1244 static void fd_mcs_print_info( Scsi_Cmnd *SCpnt )
1246 unsigned int imr;
1247 unsigned int irr;
1248 unsigned int isr;
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",
1265 SCpnt->SCp.phase,
1266 SCpnt->target,
1267 *(unsigned char *)SCpnt->cmnd,
1268 SCpnt->use_sg,
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,
1273 SCpnt->timeout );
1274 #if DEBUG_RACE
1275 printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
1276 #endif
1278 imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
1279 outb( 0x0a, 0xa0 );
1280 irr = inb( 0xa0 ) << 8;
1281 outb( 0x0a, 0x20 );
1282 irr += inb( 0x20 );
1283 outb( 0x0b, 0xa0 );
1284 isr = inb( 0xa0 ) << 8;
1285 outb( 0x0b, 0x20 );
1286 isr += inb( 0x20 );
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)" );
1298 printk( "\n" );
1299 printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port ) );
1300 if (inb( Interrupt_Status_port ) & 0x08)
1301 printk( " (enabled)" );
1302 printk( "\n" );
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 ) );
1313 #endif
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 " );
1322 #endif
1324 save_flags( flags );
1325 cli();
1326 if (!in_command) {
1327 #if EVERY_ACCESS || ERRORS_ONLY
1328 printk( " (not in command)\n" );
1329 #endif
1330 restore_flags( flags );
1331 return SCSI_ABORT_NOT_RUNNING;
1332 } else printk( "\n" );
1334 #if DEBUG_ABORT
1335 fd_mcs_print_info( SCpnt );
1336 #endif
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;
1358 #if DEBUG_RESET
1359 static int called_once = 0;
1360 #endif
1362 #if ERRORS_ONLY
1363 if (SCpnt) printk( "fd_mcs: SCSI Bus Reset\n" );
1364 #endif
1366 #if DEBUG_RESET
1367 if (called_once) fd_mcs_print_info( current_SC );
1368 called_once = 1;
1369 #endif
1371 outb( 1, SCSI_Cntl_port );
1372 do_pause( 2 );
1373 outb( 0, SCSI_Cntl_port );
1374 do_pause( 115 );
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;
1385 #include "sd.h"
1386 #include <scsi/scsi_ioctl.h>
1388 int fd_mcs_biosparam( Scsi_Disk *disk, kdev_t dev, int *info_array )
1390 int drive;
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 };
1396 int retcode;
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,
1408 (void *)buf );
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:
1415 Start: 0x1b3h
1416 Offset: 0 = partition status
1417 1 = starting head
1418 2 = starting sector and cylinder (word, encoded)
1419 4 = partition type
1420 5 = ending head
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 */
1444 } else {
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 */
1456 } else {
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] );
1465 return 0;
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"