Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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