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