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