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