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