OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [scsi/] [fdomain.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* fdomain.c -- Future Domain TMC-16x0 SCSI driver
2
 * Created: Sun May  3 18:53:19 1992 by faith@cs.unc.edu
3
 * Revised: Sat Nov  2 09:27:47 1996 by root@cs.unc.edu
4
 * Author: Rickard E. Faith, faith@cs.unc.edu
5
 * Copyright 1992, 1993, 1994, 1995, 1996 Rickard E. Faith
6
 *
7
 * $Id: fdomain.c,v 1.1 2005-12-20 10:17:45 jcastillo Exp $
8
 
9
 * This program is free software; you can redistribute it and/or modify it
10
 * under the terms of the GNU General Public License as published by the
11
 * Free Software Foundation; either version 2, or (at your option) any
12
 * later version.
13
 
14
 * This program is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * General Public License for more details.
18
 
19
 * You should have received a copy of the GNU General Public License along
20
 * with this program; if not, write to the Free Software Foundation, Inc.,
21
 * 675 Mass Ave, Cambridge, MA 02139, USA.
22
 
23
 **************************************************************************
24
 
25
 SUMMARY:
26
 
27
 Future Domain BIOS versions supported for autodetect:
28
    2.0, 3.0, 3.2, 3.4 (1.0), 3.5 (2.0), 3.6, 3.61
29
 Chips are supported:
30
    TMC-1800, TMC-18C50, TMC-18C30, TMC-36C70
31
 Boards supported:
32
    Future Domain TMC-1650, TMC-1660, TMC-1670, TMC-1680, TMC-1610M/MER/MEX
33
    Future Domain TMC-3260 (PCI)
34
    Quantum ISA-200S, ISA-250MG
35
    Adaptec AHA-2920 (PCI)
36
    IBM ?
37
 LILO command-line options:
38
    fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]
39
 
40
 
41
 
42
 DESCRIPTION:
43
 
44
 This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
45
 TMC-1650/1670, and TMC-3260 SCSI host adapters.  The 1650 and 1670 have a
46
 25-pin external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin
47
 high-density external connector.  The 1670 and 1680 have floppy disk
48
 controllers built in.  The TMC-3260 is a PCI bus card.
49
 
50
 Future Domain's older boards are based on the TMC-1800 chip, and this
51
 driver was originally written for a TMC-1680 board with the TMC-1800 chip.
52
 More recently, boards are being produced with the TMC-18C50 and TMC-18C30
53
 chips.  The latest and greatest board may not work with this driver.  If
54
 you have to patch this driver so that it will recognize your board's BIOS
55
 signature, then the driver may fail to function after the board is
56
 detected.
57
 
58
 Please note that the drive ordering that Future Domain implemented in BIOS
59
 versions 3.4 and 3.5 is the opposite of the order (currently) used by the
60
 rest of the SCSI industry.  If you have BIOS version 3.4 or 3.5, and have
61
 more then one drive, then the drive ordering will be the reverse of that
62
 which you see under DOS.  For example, under DOS SCSI ID 0 will be D: and
63
 SCSI ID 1 will be C: (the boot device).  Under Linux, SCSI ID 0 will be
64
 /dev/sda and SCSI ID 1 will be /dev/sdb.  The Linux ordering is consistent
65
 with that provided by all the other SCSI drivers for Linux.  If you want
66
 this changed, you will probably have to patch the higher level SCSI code.
67
 If you do so, please send me patches that are protected by #ifdefs.
68
 
69
 If you have a TMC-8xx or TMC-9xx board, then this is not the driver for
70
 your board.  Please refer to the Seagate driver for more information and
71
 possible support.
72
 
73
 
74
 
75
 HISTORY:
76
 
77
 Linux       Driver      Driver
78
 Version     Version     Date         Support/Notes
79
 
80
             0.0          3 May 1992  V2.0 BIOS; 1800 chip
81
 0.97        1.9         28 Jul 1992
82
 0.98.6      3.1         27 Nov 1992
83
 0.99        3.2          9 Dec 1992
84
 
85
 0.99.3      3.3         10 Jan 1993  V3.0 BIOS
86
 0.99.5      3.5         18 Feb 1993
87
 0.99.10     3.6         15 May 1993  V3.2 BIOS; 18C50 chip
88
 0.99.11     3.17         3 Jul 1993  (now under RCS)
89
 0.99.12     3.18        13 Aug 1993
90
 0.99.14     5.6         31 Oct 1993  (reselection code removed)
91
 
92
 0.99.15     5.9         23 Jan 1994  V3.4 BIOS (preliminary)
93
 1.0.8/1.1.1 5.15         1 Apr 1994  V3.4 BIOS; 18C30 chip (preliminary)
94
 1.0.9/1.1.3 5.16         7 Apr 1994  V3.4 BIOS; 18C30 chip
95
 1.1.38      5.18        30 Jul 1994  36C70 chip (PCI version of 18C30)
96
 1.1.62      5.20         2 Nov 1994  V3.5 BIOS
97
 1.1.73      5.22         7 Dec 1994  Quantum ISA-200S board; V2.0 BIOS
98
 
99
 1.1.82      5.26        14 Jan 1995  V3.5 BIOS; TMC-1610M/MER/MEX board
100
 1.2.10      5.28         5 Jun 1995  Quantum ISA-250MG board; V2.0, V2.01 BIOS
101
 1.3.4       5.31        23 Jun 1995  PCI BIOS-32 detection (preliminary)
102
 1.3.7       5.33         4 Jul 1995  PCI BIOS-32 detection
103
 1.3.28      5.36        17 Sep 1995  V3.61 BIOS; LILO command-line support
104
 1.3.34      5.39        12 Oct 1995  V3.60 BIOS; /proc
105
 1.3.72      5.39         8 Feb 1996  Adaptec AHA-2920 board
106
 1.3.85      5.41         4 Apr 1996
107
 2.0.12      5.44         8 Aug 1996  Use ID 7 for all PCI cards
108
 
109
 
110
 
111
 REFERENCES USED:
112
 
113
 "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation,
114
 1990.
115
 
116
 "Technical Reference Manual: 18C50 SCSI Host Adapter Chip", Future Domain
117
 Corporation, January 1992.
118
 
119
 "LXT SCSI Products: Specifications and OEM Technical Manual (Revision
120
 B/September 1991)", Maxtor Corporation, 1991.
121
 
122
 "7213S product Manual (Revision P3)", Maxtor Corporation, 1992.
123
 
124
 "Draft Proposed American National Standard: Small Computer System
125
 Interface - 2 (SCSI-2)", Global Engineering Documents. (X3T9.2/86-109,
126
 revision 10h, October 17, 1991)
127
 
128
 Private communications, Drew Eckhardt (drew@cs.colorado.edu) and Eric
129
 Youngdale (ericy@cais.com), 1992.
130
 
131
 Private communication, Tuong Le (Future Domain Engineering department),
132
 1994. (Disk geometry computations for Future Domain BIOS version 3.4, and
133
 TMC-18C30 detection.)
134
 
135
 Hogan, Thom. The Programmer's PC Sourcebook. Microsoft Press, 1988. Page
136
 60 (2.39: Disk Partition Table Layout).
137
 
138
 "18C30 Technical Reference Manual", Future Domain Corporation, 1993, page
139
 6-1.
140
 
141
 
142
 
143
 NOTES ON REFERENCES:
144
 
145
 The Maxtor manuals were free.  Maxtor telephone technical support is
146
 great!
147
 
148
 The Future Domain manuals were $25 and $35.  They document the chip, not
149
 the TMC-16x0 boards, so some information I had to guess at.  In 1992,
150
 Future Domain sold DOS BIOS source for $250 and the UN*X driver source was
151
 $750, but these required a non-disclosure agreement, so even if I could
152
 have afforded them, they would *not* have been useful for writing this
153
 publically distributable driver.  Future Domain technical support has
154
 provided some information on the phone and have sent a few useful FAXs.
155
 They have been much more helpful since they started to recognize that the
156
 word "Linux" refers to an operating system :-).
157
 
158
 
159
 
160
 ALPHA TESTERS:
161
 
162
 There are many other alpha testers that come and go as the driver
163
 develops.  The people listed here were most helpful in times of greatest
164
 need (mostly early on -- I've probably left out a few worthy people in
165
 more recent times):
166
 
167
 Todd Carrico (todd@wutc.wustl.edu), Dan Poirier (poirier@cs.unc.edu ), Ken
168
 Corey (kenc@sol.acs.unt.edu), C. de Bruin (bruin@bruin@sterbbs.nl), Sakari
169
 Aaltonen (sakaria@vipunen.hit.fi), John Rice (rice@xanth.cs.odu.edu), Brad
170
 Yearwood (brad@optilink.com), and Ray Toy (toy@soho.crd.ge.com).
171
 
172
 Special thanks to Tien-Wan Yang (twyang@cs.uh.edu), who graciously lent me
173
 his 18C50-based card for debugging.  He is the sole reason that this
174
 driver works with the 18C50 chip.
175
 
176
 Thanks to Dave Newman (dnewman@crl.com) for providing initial patches for
177
 the version 3.4 BIOS.
178
 
179
 Thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for providing
180
 patches that support the TMC-3260, a PCI bus card with the 36C70 chip.
181
 The 36C70 chip appears to be "completely compatible" with the 18C30 chip.
182
 
183
 Thanks to Eric Kasten (tigger@petroglyph.cl.msu.edu) for providing the
184
 patch for the version 3.5 BIOS.
185
 
186
 Thanks for Stephen Henson (shenson@nyx10.cs.du.edu) for providing the
187
 patch for the Quantum ISA-200S SCSI adapter.
188
 
189
 Thanks to Adam Bowen for the signature to the 1610M/MER/MEX scsi cards, to
190
 Martin Andrews (andrewm@ccfadm.eeg.ccf.org) for the signature to some
191
 random TMC-1680 repackaged by IBM; and to Mintak Ng (mintak@panix.com) for
192
 the version 3.61 BIOS signature.
193
 
194
 Thanks for Mark Singer (elf@netcom.com) and Richard Simpson
195
 (rsimpson@ewrcsdra.demon.co.uk) for more Quantum signatures and detective
196
 work on the Quantum RAM layout.
197
 
198
 Special thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for
199
 providing patches for proper PCI BIOS32-mediated detection of the TMC-3260
200
 card (a PCI bus card with the 36C70 chip).  Please send James PCI-related
201
 bug reports.
202
 
203
 Thanks to Tom Cavin (tec@usa1.com) for preliminary command-line option
204
 patches.
205
 
206
 All of the alpha testers deserve much thanks.
207
 
208
 
209
 
210
 NOTES ON USER DEFINABLE OPTIONS:
211
 
212
 DEBUG: This turns on the printing of various debug information.
213
 
214
 ENABLE_PARITY: This turns on SCSI parity checking.  With the current
215
 driver, all attached devices must support SCSI parity.  If none of your
216
 devices support parity, then you can probably get the driver to work by
217
 turning this option off.  I have no way of testing this, however, and it
218
 would appear that no one ever uses this option.
219
 
220
 FIFO_COUNT: The host adapter has an 8K cache (host adapters based on the
221
 18C30 chip have a 2k cache).  When this many 512 byte blocks are filled by
222
 the SCSI device, an interrupt will be raised.  Therefore, this could be as
223
 low as 0, or as high as 16.  Note, however, that values which are too high
224
 or too low seem to prevent any interrupts from occurring, and thereby lock
225
 up the machine.  I have found that 2 is a good number, but throughput may
226
 be increased by changing this value to values which are close to 2.
227
 Please let me know if you try any different values.
228
 
229
 DO_DETECT: This activates some old scan code which was needed before the
230
 high level drivers got fixed.  If you are having trouble with the driver,
231
 turning this on should not hurt, and might help.  Please let me know if
232
 this is the case, since this code will be removed from future drivers.
233
 
234
 RESELECTION: This is no longer an option, since I gave up trying to
235
 implement it in version 4.x of this driver.  It did not improve
236
 performance at all and made the driver unstable (because I never found one
237
 of the two race conditions which were introduced by the multiple
238
 outstanding command code).  The instability seems a very high price to pay
239
 just so that you don't have to wait for the tape to rewind.  If you want
240
 this feature implemented, send me patches.  I'll be happy to send a copy
241
 of my (broken) driver to anyone who would like to see a copy.
242
 
243
 **************************************************************************/
244
 
245
#ifdef PCMCIA
246
#define MODULE
247
#endif
248
 
249
#ifdef MODULE
250
#include <linux/module.h>
251
#endif
252
 
253
#ifdef PCMCIA
254
#undef MODULE
255
#endif
256
 
257
#include <linux/sched.h>
258
#include <asm/io.h>
259
#include <linux/blk.h>
260
#include "scsi.h"
261
#include "hosts.h"
262
#include "fdomain.h"
263
#include <asm/system.h>
264
#include <linux/errno.h>
265
#include <linux/string.h>
266
#include <linux/ioport.h>
267
#include <linux/proc_fs.h>
268
#include <linux/bios32.h>
269
#include <linux/pci.h>
270
#include <linux/stat.h>
271
 
272
#include <linux/config.h>       /* for CONFIG_PCI */
273
 
274
struct proc_dir_entry proc_scsi_fdomain = {
275
    PROC_SCSI_FDOMAIN, 7, "fdomain",
276
    S_IFDIR | S_IRUGO | S_IXUGO, 2
277
};
278
 
279
#define VERSION          "$Revision: 1.1 $"
280
 
281
/* START OF USER DEFINABLE OPTIONS */
282
 
283
#define DEBUG            1      /* Enable debugging output */
284
#define ENABLE_PARITY    1      /* Enable SCSI Parity */
285
#define FIFO_COUNT       2      /* Number of 512 byte blocks before INTR */
286
#define DO_DETECT        0      /* Do device detection here (see scsi.c) */
287
 
288
/* END OF USER DEFINABLE OPTIONS */
289
 
290
#if DEBUG
291
#define EVERY_ACCESS     0      /* Write a line on every scsi access */
292
#define ERRORS_ONLY      1      /* Only write a line if there is an error */
293
#define DEBUG_DETECT     0      /* Debug fdomain_16x0_detect() */
294
#define DEBUG_MESSAGES   1      /* Debug MESSAGE IN phase */
295
#define DEBUG_ABORT      1      /* Debug abort() routine */
296
#define DEBUG_RESET      1      /* Debug reset() routine */
297
#define DEBUG_RACE       1      /* Debug interrupt-driven race condition */
298
#else
299
#define EVERY_ACCESS     0      /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
300
#define ERRORS_ONLY      0
301
#define DEBUG_DETECT     0
302
#define DEBUG_MESSAGES   0
303
#define DEBUG_ABORT      0
304
#define DEBUG_RESET      0
305
#define DEBUG_RACE       0
306
#endif
307
 
308
/* Errors are reported on the line, so we don't need to report them again */
309
#if EVERY_ACCESS
310
#undef ERRORS_ONLY
311
#define ERRORS_ONLY      0
312
#endif
313
 
314
#if ENABLE_PARITY
315
#define PARITY_MASK      0x08
316
#else
317
#define PARITY_MASK      0x00
318
#endif
319
 
320
enum chip_type {
321
   unknown          = 0x00,
322
   tmc1800          = 0x01,
323
   tmc18c50         = 0x02,
324
   tmc18c30         = 0x03,
325
};
326
 
327
enum {
328
   in_arbitration   = 0x02,
329
   in_selection     = 0x04,
330
   in_other         = 0x08,
331
   disconnect       = 0x10,
332
   aborted          = 0x20,
333
   sent_ident       = 0x40,
334
};
335
 
336
enum in_port_type {
337
   Read_SCSI_Data   =  0,
338
   SCSI_Status      =  1,
339
   TMC_Status       =  2,
340
   FIFO_Status      =  3,       /* tmc18c50/tmc18c30 only */
341
   Interrupt_Cond   =  4,       /* tmc18c50/tmc18c30 only */
342
   LSB_ID_Code      =  5,
343
   MSB_ID_Code      =  6,
344
   Read_Loopback    =  7,
345
   SCSI_Data_NoACK  =  8,
346
   Interrupt_Status =  9,
347
   Configuration1   = 10,
348
   Configuration2   = 11,       /* tmc18c50/tmc18c30 only */
349
   Read_FIFO        = 12,
350
   FIFO_Data_Count  = 14
351
};
352
 
353
enum out_port_type {
354
   Write_SCSI_Data  =  0,
355
   SCSI_Cntl        =  1,
356
   Interrupt_Cntl   =  2,
357
   SCSI_Mode_Cntl   =  3,
358
   TMC_Cntl         =  4,
359
   Memory_Cntl      =  5,       /* tmc18c50/tmc18c30 only */
360
   Write_Loopback   =  7,
361
   IO_Control       = 11,       /* tmc18c30 only */
362
   Write_FIFO       = 12
363
};
364
 
365
static int               port_base         = 0;
366
static void              *bios_base        = NULL;
367
static int               bios_major        = 0;
368
static int               bios_minor        = 0;
369
static int               PCI_bus           = 0;
370
static int               Quantum           = 0;  /* Quantum board variant */
371
static int               interrupt_level   = 0;
372
static volatile int      in_command        = 0;
373
static Scsi_Cmnd         *current_SC       = NULL;
374
static enum chip_type    chip              = unknown;
375
static int               adapter_mask      = 0;
376
static int               this_id           = 0;
377
static int               setup_called      = 0;
378
 
379
#if DEBUG_RACE
380
static volatile int      in_interrupt_flag = 0;
381
#endif
382
 
383
static int               SCSI_Mode_Cntl_port;
384
static int               FIFO_Data_Count_port;
385
static int               Interrupt_Cntl_port;
386
static int               Interrupt_Status_port;
387
static int               Read_FIFO_port;
388
static int               Read_SCSI_Data_port;
389
static int               SCSI_Cntl_port;
390
static int               SCSI_Data_NoACK_port;
391
static int               SCSI_Status_port;
392
static int               TMC_Cntl_port;
393
static int               TMC_Status_port;
394
static int               Write_FIFO_port;
395
static int               Write_SCSI_Data_port;
396
 
397
static int               FIFO_Size = 0x2000; /* 8k FIFO for
398
                                                pre-tmc18c30 chips */
399
 
400
extern void              fdomain_16x0_intr( int irq, void *dev_id, struct pt_regs * regs );
401
 
402
static void *addresses[] = {
403
   (void *)0xc8000,
404
   (void *)0xca000,
405
   (void *)0xce000,
406
   (void *)0xde000,
407
   (void *)0xcc000,             /* Extra addresses for PCI boards */
408
   (void *)0xd0000,
409
   (void *)0xe0000,
410
};
411
#define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
412
 
413
static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
414
#define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short ))
415
 
416
static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
417
 
418
/*
419
 
420
  READ THIS BEFORE YOU ADD A SIGNATURE!
421
 
422
  READING THIS SHORT NOTE CAN SAVE YOU LOTS OF TIME!
423
 
424
  READ EVERY WORD, ESPECIALLY THE WORD *NOT*
425
 
426
  This driver works *ONLY* for Future Domain cards using the TMC-1800,
427
  TMC-18C50, or TMC-18C30 chip.  This includes models TMC-1650, 1660, 1670,
428
  and 1680.
429
 
430
  The following BIOS signature signatures are for boards which do *NOT*
431
  work with this driver (these TMC-8xx and TMC-9xx boards may work with the
432
  Seagate driver):
433
 
434
  FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88
435
  FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89
436
  FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89
437
  FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90
438
  FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90
439
  FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90
440
  FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92
441
 
442
*/
443
 
444
struct signature {
445
   const char *signature;
446
   int  sig_offset;
447
   int  sig_length;
448
   int  major_bios_version;
449
   int  minor_bios_version;
450
   int  flag; /* 1 == PCI_bus, 2 == ISA_200S, 3 == ISA_250MG, 4 == ISA_200S */
451
} signatures[] = {
452
   /*          1         2         3         4         5         6 */
453
   /* 123456789012345678901234567890123456789012345678901234567890 */
454
   { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89",  5, 50,  2,  0, 0 },
455
   { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89",  5, 50,  2,  0, 0 },
456
   { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50,  2,  0, 2 },
457
   { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0",        73, 43,  2,  0, 3 },
458
   { "FUTURE DOMAIN CORP. (C) 1991 1800-V2.0.",            72, 39,  2,  0, 4 },
459
   { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92",        5, 44,  3,  0, 0 },
460
   { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93",        5, 44,  3,  2, 0 },
461
   { "IBM F1 P2 BIOS v1.0104/29/93",                        5, 28,  3, -1, 0 },
462
   { "Future Domain Corp. V1.0008/18/93",                   5, 33,  3,  4, 0 },
463
   { "Future Domain Corp. V1.0008/18/93",                  26, 33,  3,  4, 1 },
464
   { "Adaptec AHA-2920 PCI-SCSI Card",                     42, 31,  3, -1, 1 },
465
   { "IBM F1 P264/32",                                      5, 14,  3, -1, 1 },
466
                                /* This next signature may not be a 3.5 bios */
467
   { "Future Domain Corp. V2.0108/18/93",                   5, 33,  3,  5, 0 },
468
   { "FUTURE DOMAIN CORP.  V3.5008/18/93",                  5, 34,  3,  5, 0 },
469
   { "FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5",        5, 44,  3,  5, 0 },
470
   { "FUTURE DOMAIN CORP.  V3.6008/18/93",                  5, 34,  3,  6, 0 },
471
   { "FUTURE DOMAIN CORP.  V3.6108/18/93",                  5, 34,  3,  6, 0 },
472
   { "FUTURE DOMAIN TMC-18XX",                              5, 22, -1, -1, 0 },
473
 
474
   /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGNATURE
475
    Also, fix the disk geometry code for your signature and send your
476
    changes for faith@cs.unc.edu.  Above all, do *NOT* change any old
477
    signatures!
478
 
479
    Note that the last line will match a "generic" 18XX bios.  Because
480
    Future Domain has changed the host SCSI ID and/or the location of the
481
    geometry information in the on-board RAM area for each of the first
482
    three BIOS's, it is still important to enter a fully qualified
483
    signature in the table for any new BIOS's (after the host SCSI ID and
484
    geometry location are verified). */
485
};
486
 
487
#define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
488
 
489
static void print_banner( struct Scsi_Host *shpnt )
490
{
491
   if (!shpnt) return;          /* This won't ever happen */
492
 
493
   if (bios_major < 0 && bios_minor < 0) {
494
      printk( "scsi%d <fdomain>: No BIOS; using scsi id %d\n",
495
              shpnt->host_no, shpnt->this_id );
496
   } else {
497
      printk( "scsi%d <fdomain>: BIOS version ", shpnt->host_no );
498
 
499
      if (bios_major >= 0) printk( "%d.", bios_major );
500
      else                 printk( "?." );
501
 
502
      if (bios_minor >= 0) printk( "%d", bios_minor );
503
      else                 printk( "?." );
504
 
505
      printk( " at 0x%x using scsi id %d\n",
506
              (unsigned)bios_base, shpnt->this_id );
507
   }
508
 
509
                                /* If this driver works for later FD PCI
510
                                   boards, we will have to modify banner
511
                                   for additional PCI cards, but for now if
512
                                   it's PCI it's a TMC-3260 - JTM */
513
   printk( "scsi%d <fdomain>: %s chip at 0x%x irq ",
514
           shpnt->host_no,
515
           chip == tmc1800 ? "TMC-1800"
516
           : (chip == tmc18c50 ? "TMC-18C50"
517
              : (chip == tmc18c30 ?
518
                 (PCI_bus ? "TMC-36C70 (PCI bus)" : "TMC-18C30")
519
                 : "Unknown")),
520
           port_base );
521
 
522
   if (interrupt_level) printk( "%d", interrupt_level );
523
   else                 printk( "<none>" );
524
 
525
   printk( "\n" );
526
}
527
 
528
void fdomain_setup( char *str, int *ints )
529
{
530
   if (setup_called++ || ints[0] < 2 || ints[0] > 3) {
531
      printk( "fdomain: usage: fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]\n" );
532
      printk( "fdomain: bad LILO parameters?\n" );
533
   }
534
 
535
   port_base       = ints[0] >= 1 ? ints[1] : 0;
536
   interrupt_level = ints[0] >= 2 ? ints[2] : 0;
537
   this_id         = ints[0] >= 3 ? ints[3] : 0;
538
 
539
   bios_major = bios_minor = -1; /* Use geometry for BIOS version >= 3.4 */
540
}
541
 
542
 
543
static void do_pause( unsigned amount ) /* Pause for amount*10 milliseconds */
544
{
545
   unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */
546
 
547
   while (jiffies < the_time);
548
}
549
 
550
inline static void fdomain_make_bus_idle( void )
551
{
552
   outb( 0, SCSI_Cntl_port );
553
   outb( 0, SCSI_Mode_Cntl_port );
554
   if (chip == tmc18c50 || chip == tmc18c30)
555
         outb( 0x21 | PARITY_MASK, TMC_Cntl_port ); /* Clear forced intr. */
556
   else
557
         outb( 0x01 | PARITY_MASK, TMC_Cntl_port );
558
}
559
 
560
static int fdomain_is_valid_port( int port )
561
{
562
#if DEBUG_DETECT 
563
   printk( " (%x%x),",
564
           inb( port + MSB_ID_Code ), inb( port + LSB_ID_Code ) );
565
#endif
566
 
567
   /* The MCA ID is a unique id for each MCA compatible board.  We
568
      are using ISA boards, but Future Domain provides the MCA ID
569
      anyway.  We can use this ID to ensure that this is a Future
570
      Domain TMC-1660/TMC-1680.
571
    */
572
 
573
   if (inb( port + LSB_ID_Code ) != 0xe9) { /* test for 0x6127 id */
574
      if (inb( port + LSB_ID_Code ) != 0x27) return 0;
575
      if (inb( port + MSB_ID_Code ) != 0x61) return 0;
576
      chip = tmc1800;
577
   } else {                                 /* test for 0xe960 id */
578
      if (inb( port + MSB_ID_Code ) != 0x60) return 0;
579
      chip = tmc18c50;
580
 
581
#if 0
582
 
583
                                /* Try to toggle 32-bit mode.  This only
584
                                   works on an 18c30 chip.  (User reports
585
                                   say this works, so we should switch to
586
                                   it in the near future.) */
587
 
588
      outb( 0x80, port + IO_Control );
589
      if ((inb( port + Configuration2 ) & 0x80) == 0x80) {
590
         outb( 0x00, port + IO_Control );
591
         if ((inb( port + Configuration2 ) & 0x80) == 0x00) {
592
            chip = tmc18c30;
593
            FIFO_Size = 0x800;  /* 2k FIFO */
594
         }
595
      }
596
#else
597
 
598
                                /* That should have worked, but appears to
599
                                   have problems.  Let's assume it is an
600
                                   18c30 if the RAM is disabled. */
601
 
602
      if (inb( port + Configuration2 ) & 0x02) {
603
         chip      = tmc18c30;
604
         FIFO_Size = 0x800;     /* 2k FIFO */
605
      }
606
#endif
607
                                /* If that failed, we are an 18c50. */
608
   }
609
 
610
   return 1;
611
}
612
 
613
static int fdomain_test_loopback( void )
614
{
615
   int i;
616
   int result;
617
 
618
   for (i = 0; i < 255; i++) {
619
      outb( i, port_base + Write_Loopback );
620
      result = inb( port_base + Read_Loopback );
621
      if (i != result)
622
            return 1;
623
   }
624
   return 0;
625
}
626
 
627
/* fdomain_get_irq assumes that we have a valid MCA ID for a
628
   TMC-1660/TMC-1680 Future Domain board.  Now, check to be sure the
629
   bios_base matches these ports.  If someone was unlucky enough to have
630
   purchased more than one Future Domain board, then they will have to
631
   modify this code, as we only detect one board here.  [The one with the
632
   lowest bios_base.]
633
 
634
   Note that this routine is only used for systems without a PCI BIOS32
635
   (e.g., ISA bus).  For PCI bus systems, this routine will likely fail
636
   unless one of the IRQs listed in the ints array is used by the board.
637
   Sometimes it is possible to use the computer's BIOS setup screen to
638
   configure a PCI system so that one of these IRQs will be used by the
639
   Future Domain card. */
640
 
641
static int fdomain_get_irq( int base )
642
{
643
   int options = inb( base + Configuration1 );
644
 
645
#if DEBUG_DETECT
646
   printk( " Options = %x\n", options );
647
#endif
648
 
649
                                /* Check for board with lowest bios_base --
650
                                   this isn't valid for the 18c30 or for
651
                                   boards on the PCI bus, so just assume we
652
                                   have the right board. */
653
 
654
   if (chip != tmc18c30
655
       && !PCI_bus
656
       && addresses[ (options & 0xc0) >> 6 ] != bios_base) return 0;
657
 
658
   return ints[ (options & 0x0e) >> 1 ];
659
}
660
 
661
static int fdomain_isa_detect( int *irq, int *iobase )
662
{
663
   int i;
664
   int base;
665
   int flag = 0;
666
 
667
   if (bios_major == 2) {
668
      /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM.
669
         Assuming the ROM is enabled (otherwise we wouldn't have been
670
         able to read the ROM signature :-), then the ROM sets up the
671
         RAM area with some magic numbers, such as a list of port
672
         base addresses and a list of the disk "geometry" reported to
673
         DOS (this geometry has nothing to do with physical geometry).
674
       */
675
 
676
      switch (Quantum) {
677
      case 2:                   /* ISA_200S */
678
      case 3:                   /* ISA_250MG */
679
         base = *((char *)bios_base + 0x1fa2)
680
               + (*((char *)bios_base + 0x1fa3) << 8);
681
         break;
682
      case 4:                   /* ISA_200S (another one) */
683
         base = *((char *)bios_base + 0x1fa3)
684
               + (*((char *)bios_base + 0x1fa4) << 8);
685
         break;
686
      default:
687
         base = *((char *)bios_base + 0x1fcc)
688
               + (*((char *)bios_base + 0x1fcd) << 8);
689
         break;
690
      }
691
 
692
#if DEBUG_DETECT
693
      printk( " %x,", base );
694
#endif
695
 
696
      for (flag = 0, i = 0; !flag && i < PORT_COUNT; i++) {
697
         if (base == ports[i])
698
               ++flag;
699
      }
700
 
701
      if (flag && fdomain_is_valid_port( base )) {
702
         *irq    = fdomain_get_irq( base );
703
         *iobase = base;
704
         return 1;
705
      }
706
 
707
      /* This is a bad sign.  It usually means that someone patched the
708
         BIOS signature list (the signatures variable) to contain a BIOS
709
         signature for a board *OTHER THAN* the TMC-1660/TMC-1680. */
710
 
711
#if DEBUG_DETECT
712
      printk( " RAM FAILED, " );
713
#endif
714
   }
715
 
716
   /* Anyway, the alternative to finding the address in the RAM is to just
717
      search through every possible port address for one that is attached
718
      to the Future Domain card.  Don't panic, though, about reading all
719
      these random port addresses -- there are rumors that the Future
720
      Domain BIOS does something very similar.
721
 
722
      Do not, however, check ports which the kernel knows are being used by
723
      another driver. */
724
 
725
   for (i = 0; i < PORT_COUNT; i++) {
726
      base = ports[i];
727
      if (check_region( base, 0x10 )) {
728
#if DEBUG_DETECT
729
         printk( " (%x inuse),", base );
730
#endif
731
         continue;
732
      }
733
#if DEBUG_DETECT
734
      printk( " %x,", base );
735
#endif
736
      if ((flag = fdomain_is_valid_port( base ))) break;
737
   }
738
 
739
   if (!flag) return 0;          /* iobase not found */
740
 
741
   *irq    = fdomain_get_irq( base );
742
   *iobase = base;
743
 
744
   return 1;                    /* success */
745
}
746
 
747
static int fdomain_pci_nobios_detect( int *irq, int *iobase )
748
{
749
   int i;
750
   int flag = 0;
751
 
752
   /* The proper way of doing this is to use ask the PCI bus for the device
753
      IRQ and interrupt level.  But we can't do that if PCI BIOS32 support
754
      isn't compiled into the kernel, or if a PCI BIOS32 isn't present.
755
 
756
      Instead, we scan down a bunch of addresses (Future Domain tech
757
      support says we will probably find the address before we get to
758
      0xf800).  This works fine on some systems -- other systems may have
759
      to scan more addresses.  If you have to modify this section for your
760
      installation, please send mail to faith@cs.unc.edu. */
761
 
762
   for (i = 0xfff8; i > 0xe000; i -= 8) {
763
      if (check_region( i, 0x10 )) {
764
#if DEBUG_DETECT
765
         printk( " (%x inuse)," , i );
766
#endif
767
         continue;
768
      }
769
      if ((flag = fdomain_is_valid_port( i ))) break;
770
   }
771
 
772
   if (!flag) return 0;          /* iobase not found */
773
 
774
   *irq    = fdomain_get_irq( i );
775
   *iobase = i;
776
 
777
   return 1;                    /* success */
778
}
779
 
780
/* PCI detection function: int fdomain_pci_bios_detect(int* irq, int*
781
   iobase) This function gets the Interrupt Level and I/O base address from
782
   the PCI configuration registers.  The I/O base address is masked with
783
   0xfff8 since on my card the address read from the PCI config registers
784
   is off by one from the actual I/O base address necessary for accessing
785
   the status and control registers on the card (PCI config register gives
786
   0xf801, actual address is 0xf800).  This is likely a bug in the FD
787
   config code that writes to the PCI registers, however using a mask
788
   should be safe since I think the scan done by the card to determine the
789
   I/O base is done in increments of 8 (i.e., 0xf800, 0xf808, ...), at
790
   least the old scan code we used to use to get the I/O base did...  Also,
791
   the device ID from the PCI config registers is 0x0 and should be 0x60e9
792
   as it is in the status registers (offset 5 from I/O base).  If this is
793
   changed in future hardware/BIOS changes it will need to be fixed in this
794
   detection function.  Comments, bug reports, etc... on this function
795
   should be sent to mckinley@msupa.pa.msu.edu - James T. McKinley.  */
796
 
797
#ifdef CONFIG_PCI
798
static int fdomain_pci_bios_detect( int *irq, int *iobase )
799
{
800
   int              error;
801
   unsigned char    pci_bus, pci_dev_fn;    /* PCI bus & device function */
802
   unsigned char    pci_irq;                /* PCI interrupt line */
803
   unsigned int     pci_base;               /* PCI I/O base address */
804
   unsigned short   pci_vendor, pci_device; /* PCI vendor & device IDs */
805
 
806
   /* If the PCI BIOS doesn't exist, use the old-style detection routines.
807
      Otherwise, get the I/O base address and interrupt from the PCI config
808
      registers. */
809
 
810
   if (!pcibios_present()) return fdomain_pci_nobios_detect( irq, iobase );
811
 
812
#if DEBUG_DETECT
813
   /* Tell how to print a list of the known PCI devices from bios32 and
814
      list vendor and device IDs being used if in debug mode.  */
815
 
816
   printk( "\nINFO: cat /proc/pci to see list of PCI devices from bios32\n" );
817
   printk( "\nTMC-3260 detect:"
818
           " Using PCI Vendor ID: 0x%x, PCI Device ID: 0x%x\n",
819
           PCI_VENDOR_ID_FD,
820
           PCI_DEVICE_ID_FD_36C70 );
821
#endif 
822
 
823
   /* We will have to change this if more than 1 PCI bus is present and the
824
      FD scsi host is not on the first bus (i.e., a PCI to PCI bridge,
825
      which is not supported by bios32 right now anyway).  This should
826
      probably be done by a call to pcibios_find_device but I can't get it
827
      to work...  Also the device ID reported from the PCI config registers
828
      does not match the device ID quoted in the tech manual or available
829
      from offset 5 from the I/O base address.  It should be 0x60E9, but it
830
      is 0x0 if read from the PCI config registers.  I guess the FD folks
831
      neglected to write it to the PCI registers...  This loop is necessary
832
      to get the device function (at least until someone can get
833
      pcibios_find_device to work, I cannot but 53c7,8xx.c uses it...). */
834
 
835
   pci_bus = 0;
836
 
837
   for (pci_dev_fn = 0x0; pci_dev_fn < 0xff; pci_dev_fn++) {
838
      pcibios_read_config_word( pci_bus,
839
                                pci_dev_fn,
840
                                PCI_VENDOR_ID,
841
                                &pci_vendor );
842
 
843
      if (pci_vendor == PCI_VENDOR_ID_FD) {
844
         pcibios_read_config_word( pci_bus,
845
                                   pci_dev_fn,
846
                                   PCI_DEVICE_ID,
847
                                   &pci_device );
848
 
849
         if (pci_device == PCI_DEVICE_ID_FD_36C70) {
850
            /* Break out once we have the correct device.  If other FD
851
               PCI devices are added to this driver we will need to add
852
               an or of the other PCI_DEVICE_ID_FD_XXXXX's here. */
853
            break;
854
         } else {
855
            /* If we can't find an FD scsi card we give up. */
856
            return 0;
857
         }
858
      }
859
   }
860
 
861
#if DEBUG_DETECT
862
   printk( "Future Domain 36C70 : at PCI bus %u, device %u, function %u\n",
863
           pci_bus,
864
           (pci_dev_fn & 0xf8) >> 3,
865
           pci_dev_fn & 7 );
866
#endif
867
 
868
   /* We now have the appropriate device function for the FD board so we
869
      just read the PCI config info from the registers.  */
870
 
871
   if ((error = pcibios_read_config_dword( pci_bus,
872
                                           pci_dev_fn,
873
                                           PCI_BASE_ADDRESS_0,
874
                                           &pci_base ))
875
       || (error = pcibios_read_config_byte( pci_bus,
876
                                             pci_dev_fn,
877
                                             PCI_INTERRUPT_LINE,
878
                                             &pci_irq ))) {
879
      printk ( "PCI ERROR: Future Domain 36C70 not initializing"
880
               " due to error reading configuration space\n" );
881
      return 0;
882
   } else {
883
#if DEBUG_DETECT
884
      printk( "TMC-3260 PCI: IRQ = %u, I/O base = 0x%lx\n",
885
              pci_irq, pci_base );
886
#endif
887
 
888
      /* Now we have the I/O base address and interrupt from the PCI
889
         configuration registers.  Unfortunately it seems that the I/O base
890
         address is off by one on my card so I mask it with 0xfff8.  This
891
         must be some kind of goof in the FD code that does the autoconfig
892
         and writes to the PCI registers (or maybe I just don't understand
893
         something).  If they fix it in later versions of the card or BIOS
894
         we may have to adjust the address based on the signature or
895
         something...  */
896
 
897
      *irq    = pci_irq;
898
      *iobase = (pci_base & 0xfff8);
899
 
900
#if DEBUG_DETECT
901
      printk( "TMC-3260 fix: Masking I/O base address with 0xff00.\n" );
902
      printk( "TMC-3260: IRQ = %d, I/O base = 0x%x\n", *irq, *iobase );
903
#endif
904
 
905
      if (!fdomain_is_valid_port( *iobase )) return 0;
906
      return 1;
907
   }
908
   return 0;
909
}
910
#endif
911
 
912
int fdomain_16x0_detect( Scsi_Host_Template *tpnt )
913
{
914
   int              i, j;
915
   int              retcode;
916
   struct Scsi_Host *shpnt;
917
#if DO_DETECT
918
   const int        buflen = 255;
919
   Scsi_Cmnd        SCinit;
920
   unsigned char    do_inquiry[] =       { INQUIRY, 0, 0, 0, buflen, 0 };
921
   unsigned char    do_request_sense[] = { REQUEST_SENSE, 0, 0, 0, buflen, 0 };
922
   unsigned char    do_read_capacity[] = { READ_CAPACITY,
923
                                           0, 0, 0, 0, 0, 0, 0, 0, 0 };
924
   unsigned char    buf[buflen];
925
#endif
926
 
927
#if DEBUG_DETECT
928
   printk( "fdomain_16x0_detect()," );
929
#endif
930
   tpnt->proc_dir = &proc_scsi_fdomain;
931
 
932
   if (setup_called) {
933
#if DEBUG_DETECT
934
      printk( "no BIOS, using port_base = 0x%x, irq = %d\n",
935
              port_base, interrupt_level );
936
#endif
937
      if (!fdomain_is_valid_port( port_base )) {
938
         printk( "fdomain: cannot locate chip at port base 0x%x\n",
939
                 port_base );
940
         printk( "fdomain: bad LILO parameters?\n" );
941
         return 0;
942
      }
943
   } else {
944
      int flag = 0;
945
 
946
      for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) {
947
#if DEBUG_DETECT
948
         printk( " %x(%x),", (unsigned)addresses[i], (unsigned)bios_base );
949
#endif
950
         for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) {
951
            if (!memcmp( ((char *)addresses[i] + signatures[j].sig_offset),
952
                         signatures[j].signature, signatures[j].sig_length )) {
953
               bios_major = signatures[j].major_bios_version;
954
               bios_minor = signatures[j].minor_bios_version;
955
               PCI_bus    = (signatures[j].flag == 1);
956
               Quantum    = (signatures[j].flag > 1) ? signatures[j].flag : 0;
957
               bios_base  = addresses[i];
958
            }
959
         }
960
      }
961
 
962
      if (!bios_base) {
963
#if DEBUG_DETECT
964
         printk( " FAILED: NO BIOS\n" );
965
#endif
966
         return 0;
967
      }
968
 
969
      if (!PCI_bus) {
970
         flag = fdomain_isa_detect( &interrupt_level, &port_base );
971
      } else {
972
#ifdef CONFIG_PCI
973
         flag = fdomain_pci_bios_detect( &interrupt_level, &port_base );
974
#else
975
         flag = fdomain_pci_nobios_detect( &interrupt_level, &port_base );
976
#endif
977
      }
978
 
979
      if (!flag) {
980
#if DEBUG_DETECT
981
         printk( " FAILED: NO PORT\n" );
982
#endif
983
#ifdef CONFIG_PCI
984
         printk( "\nTMC-3260 36C70 PCI scsi chip detection failed.\n" );
985
         printk( "Send mail to mckinley@msupa.pa.msu.edu.\n" );
986
#endif
987
         return 0;               /* Cannot find valid set of ports */
988
      }
989
   }
990
 
991
   SCSI_Mode_Cntl_port   = port_base + SCSI_Mode_Cntl;
992
   FIFO_Data_Count_port  = port_base + FIFO_Data_Count;
993
   Interrupt_Cntl_port   = port_base + Interrupt_Cntl;
994
   Interrupt_Status_port = port_base + Interrupt_Status;
995
   Read_FIFO_port        = port_base + Read_FIFO;
996
   Read_SCSI_Data_port   = port_base + Read_SCSI_Data;
997
   SCSI_Cntl_port        = port_base + SCSI_Cntl;
998
   SCSI_Data_NoACK_port  = port_base + SCSI_Data_NoACK;
999
   SCSI_Status_port      = port_base + SCSI_Status;
1000
   TMC_Cntl_port         = port_base + TMC_Cntl;
1001
   TMC_Status_port       = port_base + TMC_Status;
1002
   Write_FIFO_port       = port_base + Write_FIFO;
1003
   Write_SCSI_Data_port  = port_base + Write_SCSI_Data;
1004
 
1005
   fdomain_16x0_reset( NULL, 0 );
1006
 
1007
   if (fdomain_test_loopback()) {
1008
#if DEBUG_DETECT
1009
      printk( "fdomain: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
1010
#endif
1011
      if (setup_called) {
1012
         printk( "fdomain: loopback test failed at port base 0x%x\n",
1013
                 port_base );
1014
         printk( "fdomain: bad LILO parameters?\n" );
1015
      }
1016
      return 0;
1017
   }
1018
 
1019
   if (this_id) {
1020
      tpnt->this_id = (this_id & 0x07);
1021
      adapter_mask  = (1 << tpnt->this_id);
1022
   } else {
1023
      if (PCI_bus || (bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
1024
         tpnt->this_id = 7;
1025
         adapter_mask  = 0x80;
1026
      } else {
1027
         tpnt->this_id = 6;
1028
         adapter_mask  = 0x40;
1029
      }
1030
   }
1031
 
1032
                                /* Print out a banner here in case we can't
1033
                                   get resources.  */
1034
 
1035
   shpnt = scsi_register( tpnt, 0 );
1036
   shpnt->irq = interrupt_level;
1037
   shpnt->io_port = port_base;
1038
   shpnt->n_io_port = 0x10;
1039
   print_banner( shpnt );
1040
 
1041
                                /* Log IRQ with kernel */
1042
   if (!interrupt_level) {
1043
      panic( "fdomain: *NO* interrupt level selected!\n" );
1044
   } else {
1045
      /* Register the IRQ with the kernel */
1046
 
1047
      retcode = request_irq( interrupt_level,
1048
                             fdomain_16x0_intr, SA_INTERRUPT, "fdomain", NULL);
1049
 
1050
      if (retcode < 0) {
1051
         if (retcode == -EINVAL) {
1052
            printk( "fdomain: IRQ %d is bad!\n", interrupt_level );
1053
            printk( "         This shouldn't happen!\n" );
1054
            printk( "         Send mail to faith@cs.unc.edu\n" );
1055
         } else if (retcode == -EBUSY) {
1056
            printk( "fdomain: IRQ %d is already in use!\n", interrupt_level );
1057
            printk( "         Please use another IRQ!\n" );
1058
         } else {
1059
            printk( "fdomain: Error getting IRQ %d\n", interrupt_level );
1060
            printk( "         This shouldn't happen!\n" );
1061
            printk( "         Send mail to faith@cs.unc.edu\n" );
1062
         }
1063
         panic( "fdomain: Driver requires interruptions\n" );
1064
      }
1065
   }
1066
 
1067
                                /* Log I/O ports with kernel */
1068
   request_region( port_base, 0x10, "fdomain" );
1069
 
1070
#if DO_DETECT
1071
 
1072
   /* These routines are here because of the way the SCSI bus behaves after
1073
      a reset.  This appropriate behavior was not handled correctly by the
1074
      higher level SCSI routines when I first wrote this driver.  Now,
1075
      however, correct scan routines are part of scsi.c and these routines
1076
      are no longer needed.  However, this code is still good for
1077
      debugging.  */
1078
 
1079
   SCinit.request_buffer  = SCinit.buffer = buf;
1080
   SCinit.request_bufflen = SCinit.bufflen = sizeof(buf)-1;
1081
   SCinit.use_sg          = 0;
1082
   SCinit.lun             = 0;
1083
 
1084
   printk( "fdomain: detection routine scanning for devices:\n" );
1085
   for (i = 0; i < 8; i++) {
1086
      SCinit.target = i;
1087
      if (i == tpnt->this_id)   /* Skip host adapter */
1088
            continue;
1089
      memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
1090
      retcode = fdomain_16x0_command(&SCinit);
1091
      if (!retcode) {
1092
         memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
1093
         retcode = fdomain_16x0_command(&SCinit);
1094
         if (!retcode) {
1095
            printk( "     SCSI ID %d: ", i );
1096
            for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
1097
                  printk( "%c", buf[j] >= 20 ? buf[j] : ' ' );
1098
            memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
1099
            retcode = fdomain_16x0_command(&SCinit);
1100
            if (!retcode) {
1101
               unsigned long blocks, size, capacity;
1102
 
1103
               blocks = (buf[0] << 24) | (buf[1] << 16)
1104
                     | (buf[2] << 8) | buf[3];
1105
               size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
1106
               capacity = +( +(blocks / 1024L) * +(size * 10L)) / 1024L;
1107
 
1108
               printk( "%lu MB (%lu byte blocks)",
1109
                       ((capacity + 5L) / 10L), size );
1110
            } else {
1111
               memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
1112
               retcode = fdomain_16x0_command(&SCinit);
1113
            }
1114
            printk ("\n" );
1115
         } else {
1116
            memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
1117
            retcode = fdomain_16x0_command(&SCinit);
1118
         }
1119
      }
1120
   }
1121
#endif
1122
 
1123
   return 1;                    /* Maximum of one adapter will be detected. */
1124
}
1125
 
1126
const char *fdomain_16x0_info( struct Scsi_Host *ignore )
1127
{
1128
   static char buffer[80];
1129
   char        *pt;
1130
 
1131
   strcpy( buffer, "Future Domain TMC-16x0 SCSI driver, version" );
1132
   if (strchr( VERSION, ':')) { /* Assume VERSION is an RCS Revision string */
1133
      strcat( buffer, strchr( VERSION, ':' ) + 1 );
1134
      pt = strrchr( buffer, '$') - 1;
1135
      if (!pt)                  /* Stripped RCS Revision string? */
1136
            pt = buffer + strlen( buffer ) - 1;
1137
      if (*pt != ' ')
1138
            ++pt;
1139
      *pt = '\0';
1140
   } else {                     /* Assume VERSION is a number */
1141
      strcat( buffer, " " VERSION );
1142
   }
1143
 
1144
   return buffer;
1145
}
1146
 
1147
                                /* First pass at /proc information routine. */
1148
/*
1149
 * inout : decides on the direction of the dataflow and the meaning of the
1150
 *         variables
1151
 * buffer: If inout==FALSE data is being written to it else read from it
1152
 * *start: If inout==FALSE start of the valid data in the buffer
1153
 * offset: If inout==FALSE offset from the beginning of the imaginary file
1154
 *         from which we start writing into the buffer
1155
 * length: If inout==FALSE max number of bytes to be written into the buffer
1156
 *         else number of bytes in the buffer
1157
 */
1158
int fdomain_16x0_proc_info( char *buffer, char **start, off_t offset,
1159
                            int length, int hostno, int inout )
1160
{
1161
   const char *info = fdomain_16x0_info( NULL );
1162
   int        len;
1163
   int        pos;
1164
   int        begin;
1165
 
1166
   if (inout) return(-ENOSYS);
1167
 
1168
   begin = 0;
1169
   strcpy( buffer, info );
1170
   strcat( buffer, "\n" );
1171
 
1172
   pos = len = strlen( buffer );
1173
 
1174
   if(pos < offset) {
1175
      len = 0;
1176
      begin = pos;
1177
   }
1178
 
1179
   *start = buffer + (offset - begin);   /* Start of wanted data */
1180
   len -= (offset - begin);
1181
   if(len > length) len = length;
1182
 
1183
   return(len);
1184
}
1185
 
1186
#if 0
1187
static int fdomain_arbitrate( void )
1188
{
1189
   int           status = 0;
1190
   unsigned long timeout;
1191
 
1192
#if EVERY_ACCESS
1193
   printk( "fdomain_arbitrate()\n" );
1194
#endif
1195
 
1196
   outb( 0x00, SCSI_Cntl_port );              /* Disable data drivers */
1197
   outb( adapter_mask, port_base + SCSI_Data_NoACK ); /* Set our id bit */
1198
   outb( 0x04 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
1199
 
1200
   timeout = jiffies + 50;                    /* 500 mS */
1201
   while (jiffies < timeout) {
1202
      status = inb( TMC_Status_port );        /* Read adapter status */
1203
      if (status & 0x02)                      /* Arbitration complete */
1204
            return 0;
1205
   }
1206
 
1207
   /* Make bus idle */
1208
   fdomain_make_bus_idle();
1209
 
1210
#if EVERY_ACCESS
1211
   printk( "Arbitration failed, status = %x\n", status );
1212
#endif
1213
#if ERRORS_ONLY
1214
   printk( "fdomain: Arbitration failed, status = %x\n", status );
1215
#endif
1216
   return 1;
1217
}
1218
#endif
1219
 
1220
static int fdomain_select( int target )
1221
{
1222
   int           status;
1223
   unsigned long timeout;
1224
   static int    flag = 0;
1225
 
1226
 
1227
   outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
1228
   outb( adapter_mask | (1 << target), SCSI_Data_NoACK_port );
1229
 
1230
   /* Stop arbitration and enable parity */
1231
   outb( PARITY_MASK, TMC_Cntl_port );
1232
 
1233
   timeout = jiffies + 35;              /* 350mS -- because of timeouts
1234
                                           (was 250mS) */
1235
 
1236
   while (jiffies < timeout) {
1237
      status = inb( SCSI_Status_port ); /* Read adapter status */
1238
      if (status & 1) {                 /* Busy asserted */
1239
         /* Enable SCSI Bus (on error, should make bus idle with 0) */
1240
         outb( 0x80, SCSI_Cntl_port );
1241
         return 0;
1242
      }
1243
   }
1244
   /* Make bus idle */
1245
   fdomain_make_bus_idle();
1246
#if EVERY_ACCESS
1247
   if (!target) printk( "Selection failed\n" );
1248
#endif
1249
#if ERRORS_ONLY
1250
   if (!target) {
1251
      if (!flag) /* Skip first failure for all chips. */
1252
            ++flag;
1253
      else
1254
            printk( "fdomain: Selection failed\n" );
1255
   }
1256
#endif
1257
   return 1;
1258
}
1259
 
1260
void my_done( int error )
1261
{
1262
   if (in_command) {
1263
      in_command = 0;
1264
      outb( 0x00, Interrupt_Cntl_port );
1265
      fdomain_make_bus_idle();
1266
      current_SC->result = error;
1267
      if (current_SC->scsi_done)
1268
            current_SC->scsi_done( current_SC );
1269
      else panic( "fdomain: current_SC->scsi_done() == NULL" );
1270
   } else {
1271
      panic( "fdomain: my_done() called outside of command\n" );
1272
   }
1273
#if DEBUG_RACE
1274
   in_interrupt_flag = 0;
1275
#endif
1276
}
1277
 
1278
void fdomain_16x0_intr( int irq, void *dev_id, struct pt_regs * regs )
1279
{
1280
   int      status;
1281
   int      done = 0;
1282
   unsigned data_count;
1283
 
1284
                                /* The fdomain_16x0_intr is only called via
1285
                                   the interrupt handler.  The goal of the
1286
                                   sti() here is to allow other
1287
                                   interruptions while this routine is
1288
                                   running. */
1289
 
1290
   sti();                       /* Yes, we really want sti() here */
1291
 
1292
   outb( 0x00, Interrupt_Cntl_port );
1293
 
1294
   /* We usually have one spurious interrupt after each command.  Ignore it. */
1295
   if (!in_command || !current_SC) {    /* Spurious interrupt */
1296
#if EVERY_ACCESS
1297
      printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
1298
              in_command, current_SC );
1299
#endif
1300
      return;
1301
   }
1302
 
1303
   /* Abort calls my_done, so we do nothing here. */
1304
   if (current_SC->SCp.phase & aborted) {
1305
#if DEBUG_ABORT
1306
      printk( "Interrupt after abort, ignoring\n" );
1307
#endif
1308
      /*
1309
      return; */
1310
   }
1311
 
1312
#if DEBUG_RACE
1313
   ++in_interrupt_flag;
1314
#endif
1315
 
1316
   if (current_SC->SCp.phase & in_arbitration) {
1317
      status = inb( TMC_Status_port );        /* Read adapter status */
1318
      if (!(status & 0x02)) {
1319
#if EVERY_ACCESS
1320
         printk( " AFAIL " );
1321
#endif
1322
         my_done( DID_BUS_BUSY << 16 );
1323
         return;
1324
      }
1325
      current_SC->SCp.phase = in_selection;
1326
 
1327
      outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );
1328
 
1329
      outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
1330
      outb( adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port );
1331
 
1332
      /* Stop arbitration and enable parity */
1333
      outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
1334
#if DEBUG_RACE
1335
      in_interrupt_flag = 0;
1336
#endif
1337
      return;
1338
   } else if (current_SC->SCp.phase & in_selection) {
1339
      status = inb( SCSI_Status_port );
1340
      if (!(status & 0x01)) {
1341
         /* Try again, for slow devices */
1342
         if (fdomain_select( current_SC->target )) {
1343
#if EVERY_ACCESS
1344
            printk( " SFAIL " );
1345
#endif
1346
            my_done( DID_NO_CONNECT << 16 );
1347
            return;
1348
         } else {
1349
#if EVERY_ACCESS
1350
            printk( " AltSel " );
1351
#endif
1352
            /* Stop arbitration and enable parity */
1353
            outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
1354
         }
1355
      }
1356
      current_SC->SCp.phase = in_other;
1357
      outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
1358
      outb( 0x80, SCSI_Cntl_port );
1359
#if DEBUG_RACE
1360
      in_interrupt_flag = 0;
1361
#endif
1362
      return;
1363
   }
1364
 
1365
   /* current_SC->SCp.phase == in_other: this is the body of the routine */
1366
 
1367
   status = inb( SCSI_Status_port );
1368
 
1369
   if (status & 0x10) { /* REQ */
1370
 
1371
      switch (status & 0x0e) {
1372
 
1373
      case 0x08:                /* COMMAND OUT */
1374
         outb( current_SC->cmnd[current_SC->SCp.sent_command++],
1375
               Write_SCSI_Data_port );
1376
#if EVERY_ACCESS
1377
         printk( "CMD = %x,",
1378
                 current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
1379
#endif
1380
         break;
1381
      case 0x00:                /* DATA OUT -- tmc18c50/tmc18c30 only */
1382
         if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
1383
            current_SC->SCp.have_data_in = -1;
1384
            outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1385
         }
1386
         break;
1387
      case 0x04:                /* DATA IN -- tmc18c50/tmc18c30 only */
1388
         if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
1389
            current_SC->SCp.have_data_in = 1;
1390
            outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1391
         }
1392
         break;
1393
      case 0x0c:                /* STATUS IN */
1394
         current_SC->SCp.Status = inb( Read_SCSI_Data_port );
1395
#if EVERY_ACCESS
1396
         printk( "Status = %x, ", current_SC->SCp.Status );
1397
#endif
1398
#if ERRORS_ONLY
1399
         if (current_SC->SCp.Status
1400
             && current_SC->SCp.Status != 2
1401
             && current_SC->SCp.Status != 8) {
1402
            printk( "fdomain: target = %d, command = %x, status = %x\n",
1403
                    current_SC->target,
1404
                    current_SC->cmnd[0],
1405
                    current_SC->SCp.Status );
1406
         }
1407
#endif
1408
               break;
1409
      case 0x0a:                /* MESSAGE OUT */
1410
         outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */
1411
         break;
1412
      case 0x0e:                /* MESSAGE IN */
1413
         current_SC->SCp.Message = inb( Read_SCSI_Data_port );
1414
#if EVERY_ACCESS
1415
         printk( "Message = %x, ", current_SC->SCp.Message );
1416
#endif
1417
         if (!current_SC->SCp.Message) ++done;
1418
#if DEBUG_MESSAGES || EVERY_ACCESS
1419
         if (current_SC->SCp.Message) {
1420
            printk( "fdomain: message = %x\n", current_SC->SCp.Message );
1421
         }
1422
#endif
1423
         break;
1424
      }
1425
   }
1426
 
1427
   if (chip == tmc1800
1428
       && !current_SC->SCp.have_data_in
1429
       && (current_SC->SCp.sent_command
1430
           >= current_SC->cmd_len)) {
1431
                                /* We have to get the FIFO direction
1432
                                   correct, so I've made a table based
1433
                                   on the SCSI Standard of which commands
1434
                                   appear to require a DATA OUT phase.
1435
                                 */
1436
      /*
1437
        p. 94: Command for all device types
1438
        CHANGE DEFINITION            40 DATA OUT
1439
        COMPARE                      39 DATA OUT
1440
        COPY                         18 DATA OUT
1441
        COPY AND VERIFY              3a DATA OUT
1442
        INQUIRY                      12
1443
        LOG SELECT                   4c DATA OUT
1444
        LOG SENSE                    4d
1445
        MODE SELECT (6)              15 DATA OUT
1446
        MODE SELECT (10)             55 DATA OUT
1447
        MODE SENSE (6)               1a
1448
        MODE SENSE (10)              5a
1449
        READ BUFFER                  3c
1450
        RECEIVE DIAGNOSTIC RESULTS   1c
1451
        REQUEST SENSE                03
1452
        SEND DIAGNOSTIC              1d DATA OUT
1453
        TEST UNIT READY              00
1454
        WRITE BUFFER                 3b DATA OUT
1455
 
1456
        p.178: Commands for direct-access devices (not listed on p. 94)
1457
        FORMAT UNIT                  04 DATA OUT
1458
        LOCK-UNLOCK CACHE            36
1459
        PRE-FETCH                    34
1460
        PREVENT-ALLOW MEDIUM REMOVAL 1e
1461
        READ (6)/RECEIVE             08
1462
        READ (10)                    3c
1463
        READ CAPACITY                25
1464
        READ DEFECT DATA (10)        37
1465
        READ LONG                    3e
1466
        REASSIGN BLOCKS              07 DATA OUT
1467
        RELEASE                      17
1468
        RESERVE                      16 DATA OUT
1469
        REZERO UNIT/REWIND           01
1470
        SEARCH DATA EQUAL (10)       31 DATA OUT
1471
        SEARCH DATA HIGH (10)        30 DATA OUT
1472
        SEARCH DATA LOW (10)         32 DATA OUT
1473
        SEEK (6)                     0b
1474
        SEEK (10)                    2b
1475
        SET LIMITS (10)              33
1476
        START STOP UNIT              1b
1477
        SYNCHRONIZE CACHE            35
1478
        VERIFY (10)                  2f
1479
        WRITE (6)/PRINT/SEND         0a DATA OUT
1480
        WRITE (10)/SEND              2a DATA OUT
1481
        WRITE AND VERIFY (10)        2e DATA OUT
1482
        WRITE LONG                   3f DATA OUT
1483
        WRITE SAME                   41 DATA OUT ?
1484
 
1485
        p. 261: Commands for sequential-access devices (not previously listed)
1486
        ERASE                        19
1487
        LOAD UNLOAD                  1b
1488
        LOCATE                       2b
1489
        READ BLOCK LIMITS            05
1490
        READ POSITION                34
1491
        READ REVERSE                 0f
1492
        RECOVER BUFFERED DATA        14
1493
        SPACE                        11
1494
        WRITE FILEMARKS              10 ?
1495
 
1496
        p. 298: Commands for printer devices (not previously listed)
1497
        ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****
1498
        SLEW AND PRINT               0b DATA OUT  -- same as seek
1499
        STOP PRINT                   1b
1500
        SYNCHRONIZE BUFFER           10
1501
 
1502
        p. 315: Commands for processor devices (not previously listed)
1503
 
1504
        p. 321: Commands for write-once devices (not previously listed)
1505
        MEDIUM SCAN                  38
1506
        READ (12)                    a8
1507
        SEARCH DATA EQUAL (12)       b1 DATA OUT
1508
        SEARCH DATA HIGH (12)        b0 DATA OUT
1509
        SEARCH DATA LOW (12)         b2 DATA OUT
1510
        SET LIMITS (12)              b3
1511
        VERIFY (12)                  af
1512
        WRITE (12)                   aa DATA OUT
1513
        WRITE AND VERIFY (12)        ae DATA OUT
1514
 
1515
        p. 332: Commands for CD-ROM devices (not previously listed)
1516
        PAUSE/RESUME                 4b
1517
        PLAY AUDIO (10)              45
1518
        PLAY AUDIO (12)              a5
1519
        PLAY AUDIO MSF               47
1520
        PLAY TRACK RELATIVE (10)     49
1521
        PLAY TRACK RELATIVE (12)     a9
1522
        READ HEADER                  44
1523
        READ SUB-CHANNEL             42
1524
        READ TOC                     43
1525
 
1526
        p. 370: Commands for scanner devices (not previously listed)
1527
        GET DATA BUFFER STATUS       34
1528
        GET WINDOW                   25
1529
        OBJECT POSITION              31
1530
        SCAN                         1b
1531
        SET WINDOW                   24 DATA OUT
1532
 
1533
        p. 391: Commands for optical memory devices (not listed)
1534
        ERASE (10)                   2c
1535
        ERASE (12)                   ac
1536
        MEDIUM SCAN                  38 DATA OUT
1537
        READ DEFECT DATA (12)        b7
1538
        READ GENERATION              29
1539
        READ UPDATED BLOCK           2d
1540
        UPDATE BLOCK                 3d DATA OUT
1541
 
1542
        p. 419: Commands for medium changer devices (not listed)
1543
        EXCHANGE MEDIUM              46
1544
        INITIALIZE ELEMENT STATUS    07
1545
        MOVE MEDIUM                  a5
1546
        POSITION TO ELEMENT          2b
1547
        READ ELEMENT STATUS          b8
1548
        REQUEST VOL. ELEMENT ADDRESS b5
1549
        SEND VOLUME TAG              b6 DATA OUT
1550
 
1551
        p. 454: Commands for communications devices (not listed previously)
1552
        GET MESSAGE (6)              08
1553
        GET MESSAGE (10)             28
1554
        GET MESSAGE (12)             a8
1555
      */
1556
 
1557
      switch (current_SC->cmnd[0]) {
1558
      case CHANGE_DEFINITION: case COMPARE:         case COPY:
1559
      case COPY_VERIFY:       case LOG_SELECT:      case MODE_SELECT:
1560
      case MODE_SELECT_10:    case SEND_DIAGNOSTIC: case WRITE_BUFFER:
1561
 
1562
      case FORMAT_UNIT:       case REASSIGN_BLOCKS: case RESERVE:
1563
      case SEARCH_EQUAL:      case SEARCH_HIGH:     case SEARCH_LOW:
1564
      case WRITE_6:           case WRITE_10:        case WRITE_VERIFY:
1565
      case 0x3f:              case 0x41:
1566
 
1567
      case 0xb1:              case 0xb0:            case 0xb2:
1568
      case 0xaa:              case 0xae:
1569
 
1570
      case 0x24:
1571
 
1572
      case 0x38:              case 0x3d:
1573
 
1574
      case 0xb6:
1575
 
1576
      case 0xea:                /* alternate number for WRITE LONG */
1577
 
1578
         current_SC->SCp.have_data_in = -1;
1579
         outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
1580
         break;
1581
 
1582
      case 0x00:
1583
      default:
1584
 
1585
         current_SC->SCp.have_data_in = 1;
1586
         outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
1587
         break;
1588
      }
1589
   }
1590
 
1591
   if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */
1592
      while ( (data_count = FIFO_Size - inw( FIFO_Data_Count_port )) > 512 ) {
1593
#if EVERY_ACCESS
1594
         printk( "DC=%d, ", data_count ) ;
1595
#endif
1596
         if (data_count > current_SC->SCp.this_residual)
1597
               data_count = current_SC->SCp.this_residual;
1598
         if (data_count > 0) {
1599
#if EVERY_ACCESS
1600
            printk( "%d OUT, ", data_count );
1601
#endif
1602
            if (data_count == 1) {
1603
               outb( *current_SC->SCp.ptr++, Write_FIFO_port );
1604
               --current_SC->SCp.this_residual;
1605
            } else {
1606
               data_count >>= 1;
1607
               outsw( Write_FIFO_port, current_SC->SCp.ptr, data_count );
1608
               current_SC->SCp.ptr += 2 * data_count;
1609
               current_SC->SCp.this_residual -= 2 * data_count;
1610
            }
1611
         }
1612
         if (!current_SC->SCp.this_residual) {
1613
            if (current_SC->SCp.buffers_residual) {
1614
               --current_SC->SCp.buffers_residual;
1615
               ++current_SC->SCp.buffer;
1616
               current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1617
               current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1618
            } else
1619
                  break;
1620
         }
1621
      }
1622
   }
1623
 
1624
   if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
1625
      while ((data_count = inw( FIFO_Data_Count_port )) > 0) {
1626
#if EVERY_ACCESS
1627
         printk( "DC=%d, ", data_count );
1628
#endif
1629
         if (data_count > current_SC->SCp.this_residual)
1630
               data_count = current_SC->SCp.this_residual;
1631
         if (data_count) {
1632
#if EVERY_ACCESS
1633
            printk( "%d IN, ", data_count );
1634
#endif
1635
            if (data_count == 1) {
1636
               *current_SC->SCp.ptr++ = inb( Read_FIFO_port );
1637
               --current_SC->SCp.this_residual;
1638
            } else {
1639
               data_count >>= 1; /* Number of words */
1640
               insw( Read_FIFO_port, current_SC->SCp.ptr, data_count );
1641
               current_SC->SCp.ptr += 2 * data_count;
1642
               current_SC->SCp.this_residual -= 2 * data_count;
1643
            }
1644
         }
1645
         if (!current_SC->SCp.this_residual
1646
             && current_SC->SCp.buffers_residual) {
1647
            --current_SC->SCp.buffers_residual;
1648
            ++current_SC->SCp.buffer;
1649
            current_SC->SCp.ptr = current_SC->SCp.buffer->address;
1650
            current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
1651
         }
1652
      }
1653
   }
1654
 
1655
   if (done) {
1656
#if EVERY_ACCESS
1657
      printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
1658
#endif
1659
 
1660
#if ERRORS_ONLY
1661
      if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
1662
         if ((unsigned char)(*((char *)current_SC->request_buffer+2)) & 0x0f) {
1663
            unsigned char key;
1664
            unsigned char code;
1665
            unsigned char qualifier;
1666
 
1667
            key = (unsigned char)(*((char *)current_SC->request_buffer + 2))
1668
                  & 0x0f;
1669
            code = (unsigned char)(*((char *)current_SC->request_buffer + 12));
1670
            qualifier = (unsigned char)(*((char *)current_SC->request_buffer
1671
                                          + 13));
1672
 
1673
            if (key != UNIT_ATTENTION
1674
                && !(key == NOT_READY
1675
                     && code == 0x04
1676
                     && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1677
                && !(key == ILLEGAL_REQUEST && (code == 0x25
1678
                                                || code == 0x24
1679
                                                || !code)))
1680
 
1681
                  printk( "fdomain: REQUEST SENSE "
1682
                          "Key = %x, Code = %x, Qualifier = %x\n",
1683
                          key, code, qualifier );
1684
         }
1685
      }
1686
#endif
1687
#if EVERY_ACCESS
1688
      printk( "BEFORE MY_DONE. . ." );
1689
#endif
1690
      my_done( (current_SC->SCp.Status & 0xff)
1691
               | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
1692
#if EVERY_ACCESS
1693
      printk( "RETURNING.\n" );
1694
#endif
1695
 
1696
   } else {
1697
      if (current_SC->SCp.phase & disconnect) {
1698
         outb( 0xd0 | FIFO_COUNT, Interrupt_Cntl_port );
1699
         outb( 0x00, SCSI_Cntl_port );
1700
      } else {
1701
         outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
1702
      }
1703
   }
1704
#if DEBUG_RACE
1705
   in_interrupt_flag = 0;
1706
#endif
1707
   return;
1708
}
1709
 
1710
int fdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
1711
{
1712
   if (in_command) {
1713
      panic( "fdomain: fdomain_16x0_queue() NOT REENTRANT!\n" );
1714
   }
1715
#if EVERY_ACCESS
1716
   printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1717
           SCpnt->target,
1718
           *(unsigned char *)SCpnt->cmnd,
1719
           SCpnt->use_sg,
1720
           SCpnt->request_bufflen );
1721
#endif
1722
 
1723
   fdomain_make_bus_idle();
1724
 
1725
   current_SC            = SCpnt; /* Save this for the done function */
1726
   current_SC->scsi_done = done;
1727
 
1728
   /* Initialize static data */
1729
 
1730
   if (current_SC->use_sg) {
1731
      current_SC->SCp.buffer =
1732
            (struct scatterlist *)current_SC->request_buffer;
1733
      current_SC->SCp.ptr              = current_SC->SCp.buffer->address;
1734
      current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
1735
      current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
1736
   } else {
1737
      current_SC->SCp.ptr              = (char *)current_SC->request_buffer;
1738
      current_SC->SCp.this_residual    = current_SC->request_bufflen;
1739
      current_SC->SCp.buffer           = NULL;
1740
      current_SC->SCp.buffers_residual = 0;
1741
   }
1742
 
1743
 
1744
   current_SC->SCp.Status              = 0;
1745
   current_SC->SCp.Message             = 0;
1746
   current_SC->SCp.have_data_in        = 0;
1747
   current_SC->SCp.sent_command        = 0;
1748
   current_SC->SCp.phase               = in_arbitration;
1749
 
1750
   /* Start arbitration */
1751
   outb( 0x00, Interrupt_Cntl_port );
1752
   outb( 0x00, SCSI_Cntl_port );              /* Disable data drivers */
1753
   outb( adapter_mask, SCSI_Data_NoACK_port ); /* Set our id bit */
1754
   ++in_command;
1755
   outb( 0x20, Interrupt_Cntl_port );
1756
   outb( 0x14 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
1757
 
1758
   return 0;
1759
}
1760
 
1761
/* The following code, which simulates the old-style command function, was
1762
   taken from Tommy Thorn's aha1542.c file.  This code is Copyright (C)
1763
   1992 Tommy Thorn. */
1764
 
1765
static volatile int internal_done_flag    = 0;
1766
static volatile int internal_done_errcode = 0;
1767
 
1768
static void internal_done( Scsi_Cmnd *SCpnt )
1769
{
1770
    internal_done_errcode = SCpnt->result;
1771
    ++internal_done_flag;
1772
}
1773
 
1774
int fdomain_16x0_command( Scsi_Cmnd *SCpnt )
1775
{
1776
    fdomain_16x0_queue( SCpnt, internal_done );
1777
 
1778
    while (!internal_done_flag)
1779
          ;
1780
    internal_done_flag = 0;
1781
    return internal_done_errcode;
1782
}
1783
 
1784
/* End of code derived from Tommy Thorn's work. */
1785
 
1786
void print_info( Scsi_Cmnd *SCpnt )
1787
{
1788
   unsigned int imr;
1789
   unsigned int irr;
1790
   unsigned int isr;
1791
 
1792
   if (!SCpnt || !SCpnt->host) {
1793
      printk( "fdomain: cannot provide detailed information\n" );
1794
   }
1795
 
1796
   printk( "%s\n", fdomain_16x0_info( SCpnt->host ) );
1797
   print_banner( SCpnt->host );
1798
   switch (SCpnt->SCp.phase) {
1799
   case in_arbitration: printk( "arbitration " ); break;
1800
   case in_selection:   printk( "selection " );   break;
1801
   case in_other:       printk( "other " );       break;
1802
   default:             printk( "unknown " );     break;
1803
   }
1804
 
1805
   printk( "(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1806
           SCpnt->SCp.phase,
1807
           SCpnt->target,
1808
           *(unsigned char *)SCpnt->cmnd,
1809
           SCpnt->use_sg,
1810
           SCpnt->request_bufflen );
1811
   printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
1812
           SCpnt->SCp.sent_command,
1813
           SCpnt->SCp.have_data_in,
1814
           SCpnt->timeout );
1815
#if DEBUG_RACE
1816
   printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
1817
#endif
1818
 
1819
   imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
1820
   outb( 0x0a, 0xa0 );
1821
   irr = inb( 0xa0 ) << 8;
1822
   outb( 0x0a, 0x20 );
1823
   irr += inb( 0x20 );
1824
   outb( 0x0b, 0xa0 );
1825
   isr = inb( 0xa0 ) << 8;
1826
   outb( 0x0b, 0x20 );
1827
   isr += inb( 0x20 );
1828
 
1829
                                /* Print out interesting information */
1830
   printk( "IMR = 0x%04x", imr );
1831
   if (imr & (1 << interrupt_level))
1832
         printk( " (masked)" );
1833
   printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
1834
 
1835
   printk( "SCSI Status      = 0x%02x\n", inb( SCSI_Status_port ) );
1836
   printk( "TMC Status       = 0x%02x", inb( TMC_Status_port ) );
1837
   if (inb( TMC_Status_port & 1))
1838
         printk( " (interrupt)" );
1839
   printk( "\n" );
1840
   printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port ) );
1841
   if (inb( Interrupt_Status_port ) & 0x08)
1842
         printk( " (enabled)" );
1843
   printk( "\n" );
1844
   if (chip == tmc18c50 || chip == tmc18c30) {
1845
      printk( "FIFO Status      = 0x%02x\n", inb( port_base + FIFO_Status ) );
1846
      printk( "Int. Condition   = 0x%02x\n",
1847
              inb( port_base + Interrupt_Cond ) );
1848
   }
1849
   printk( "Configuration 1  = 0x%02x\n", inb( port_base + Configuration1 ) );
1850
   if (chip == tmc18c50 || chip == tmc18c30)
1851
         printk( "Configuration 2  = 0x%02x\n",
1852
                 inb( port_base + Configuration2 ) );
1853
}
1854
 
1855
int fdomain_16x0_abort( Scsi_Cmnd *SCpnt)
1856
{
1857
   unsigned long flags;
1858
#if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1859
   printk( "fdomain: abort " );
1860
#endif
1861
 
1862
   save_flags( flags );
1863
   cli();
1864
   if (!in_command) {
1865
#if EVERY_ACCESS || ERRORS_ONLY
1866
      printk( " (not in command)\n" );
1867
#endif
1868
      restore_flags( flags );
1869
      return SCSI_ABORT_NOT_RUNNING;
1870
   } else printk( "\n" );
1871
 
1872
#if DEBUG_ABORT
1873
   print_info( SCpnt );
1874
#endif
1875
 
1876
   fdomain_make_bus_idle();
1877
 
1878
   current_SC->SCp.phase |= aborted;
1879
 
1880
   current_SC->result = DID_ABORT << 16;
1881
 
1882
   restore_flags( flags );
1883
 
1884
   /* Aborts are not done well. . . */
1885
   my_done( DID_ABORT << 16 );
1886
 
1887
   return SCSI_ABORT_SUCCESS;
1888
}
1889
 
1890
int fdomain_16x0_reset( Scsi_Cmnd *SCpnt, unsigned int flags )
1891
{
1892
#if DEBUG_RESET
1893
   static int called_once = 0;
1894
#endif
1895
 
1896
#if ERRORS_ONLY
1897
   if (SCpnt) printk( "fdomain: SCSI Bus Reset\n" );
1898
#endif
1899
 
1900
#if DEBUG_RESET
1901
   if (called_once) print_info( current_SC );
1902
   called_once = 1;
1903
#endif
1904
 
1905
   outb( 1, SCSI_Cntl_port );
1906
   do_pause( 2 );
1907
   outb( 0, SCSI_Cntl_port );
1908
   do_pause( 115 );
1909
   outb( 0, SCSI_Mode_Cntl_port );
1910
   outb( PARITY_MASK, TMC_Cntl_port );
1911
 
1912
   /* Unless this is the very first call (i.e., SCPnt == NULL), everything
1913
      is probably hosed at this point.  We will, however, try to keep
1914
      things going by informing the high-level code that we need help. */
1915
 
1916
   return SCSI_RESET_WAKEUP;
1917
}
1918
 
1919
#include "sd.h"
1920
#include <scsi/scsi_ioctl.h>
1921
 
1922
int fdomain_16x0_biosparam( Scsi_Disk *disk, kdev_t dev, int *info_array )
1923
{
1924
   int              drive;
1925
   unsigned char    buf[512 + sizeof( int ) * 2];
1926
   int              size      = disk->capacity;
1927
   int              *sizes    = (int *)buf;
1928
   unsigned char    *data     = (unsigned char *)(sizes + 2);
1929
   unsigned char    do_read[] = { READ_6, 0, 0, 0, 1, 0 };
1930
   int              retcode;
1931
   struct drive_info {
1932
      unsigned short cylinders;
1933
      unsigned char  heads;
1934
      unsigned char  sectors;
1935
   } *i;
1936
 
1937
   /* NOTES:
1938
      The RAM area starts at 0x1f00 from the bios_base address.
1939
 
1940
      For BIOS Version 2.0:
1941
 
1942
      The drive parameter table seems to start at 0x1f30.
1943
      The first byte's purpose is not known.
1944
      Next is the cylinder, head, and sector information.
1945
      The last 4 bytes appear to be the drive's size in sectors.
1946
      The other bytes in the drive parameter table are unknown.
1947
      If anyone figures them out, please send me mail, and I will
1948
      update these notes.
1949
 
1950
      Tape drives do not get placed in this table.
1951
 
1952
      There is another table at 0x1fea:
1953
      If the byte is 0x01, then the SCSI ID is not in use.
1954
      If the byte is 0x18 or 0x48, then the SCSI ID is in use,
1955
      although tapes don't seem to be in this table.  I haven't
1956
      seen any other numbers (in a limited sample).
1957
 
1958
      0x1f2d is a drive count (i.e., not including tapes)
1959
 
1960
      The table at 0x1fcc are I/O ports addresses for the various
1961
      operations.  I calculate these by hand in this driver code.
1962
 
1963
 
1964
 
1965
      For the ISA-200S version of BIOS Version 2.0:
1966
 
1967
      The drive parameter table starts at 0x1f33.
1968
 
1969
      WARNING: Assume that the table entry is 25 bytes long.  Someone needs
1970
      to check this for the Quantum ISA-200S card.
1971
 
1972
 
1973
 
1974
      For BIOS Version 3.2:
1975
 
1976
      The drive parameter table starts at 0x1f70.  Each entry is
1977
      0x0a bytes long.  Heads are one less than we need to report.
1978
    */
1979
 
1980
   drive = MINOR(dev) / 16;
1981
 
1982
   if (bios_major == 2) {
1983
      switch (Quantum) {
1984
      case 2:                   /* ISA_200S */
1985
                                /* The value of 25 has never been verified.
1986
                                   It should probably be 15. */
1987
         i = (struct drive_info *)( (char *)bios_base + 0x1f33 + drive * 25 );
1988
         break;
1989
      case 3:                   /* ISA_250MG */
1990
         i = (struct drive_info *)( (char *)bios_base + 0x1f36 + drive * 15 );
1991
         break;
1992
      case 4:                   /* ISA_200S (another one) */
1993
         i = (struct drive_info *)( (char *)bios_base + 0x1f34 + drive * 15 );
1994
         break;
1995
      default:
1996
         i = (struct drive_info *)( (char *)bios_base + 0x1f31 + drive * 25 );
1997
         break;
1998
      }
1999
      info_array[0] = i->heads;
2000
      info_array[1] = i->sectors;
2001
      info_array[2] = i->cylinders;
2002
   } else if (bios_major == 3
2003
              && bios_minor >= 0
2004
              && bios_minor < 4) { /* 3.0 and 3.2 BIOS */
2005
      i = (struct drive_info *)( (char *)bios_base + 0x1f71 + drive * 10 );
2006
      info_array[0] = i->heads + 1;
2007
      info_array[1] = i->sectors;
2008
      info_array[2] = i->cylinders;
2009
   } else {                     /* 3.4 BIOS (and up?) */
2010
      /* This algorithm was provided by Future Domain (much thanks!). */
2011
 
2012
      sizes[0] = 0;               /* zero bytes out */
2013
      sizes[1] = 512;           /* one sector in */
2014
      memcpy( data, do_read, sizeof( do_read ) );
2015
      retcode = kernel_scsi_ioctl( disk->device,
2016
                                   SCSI_IOCTL_SEND_COMMAND,
2017
                                   (void *)buf );
2018
      if (!retcode                                  /* SCSI command ok */
2019
          && data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */
2020
          && data[0x1c2]) {                         /* Partition type */
2021
 
2022
         /* The partition table layout is as follows:
2023
 
2024
            Start: 0x1b3h
2025
            Offset: 0 = partition status
2026
                    1 = starting head
2027
                    2 = starting sector and cylinder (word, encoded)
2028
                    4 = partition type
2029
                    5 = ending head
2030
                    6 = ending sector and cylinder (word, encoded)
2031
                    8 = starting absolute sector (double word)
2032
                    c = number of sectors (double word)
2033
            Signature: 0x1fe = 0x55aa
2034
 
2035
            So, this algorithm assumes:
2036
            1) the first partition table is in use,
2037
            2) the data in the first entry is correct, and
2038
            3) partitions never divide cylinders
2039
 
2040
            Note that (1) may be FALSE for NetBSD (and other BSD flavors),
2041
            as well as for Linux.  Note also, that Linux doesn't pay any
2042
            attention to the fields that are used by this algorithm -- it
2043
            only uses the absolute sector data.  Recent versions of Linux's
2044
            fdisk(1) will fill this data in correctly, and forthcoming
2045
            versions will check for consistency.
2046
 
2047
            Checking for a non-zero partition type is not part of the
2048
            Future Domain algorithm, but it seemed to be a reasonable thing
2049
            to do, especially in the Linux and BSD worlds. */
2050
 
2051
         info_array[0] = data[0x1c3] + 1;            /* heads */
2052
         info_array[1] = data[0x1c4] & 0x3f;        /* sectors */
2053
      } else {
2054
 
2055
         /* Note that this new method guarantees that there will always be
2056
            less than 1024 cylinders on a platter.  This is good for drives
2057
            up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
2058
 
2059
         if ((unsigned int)size >= 0x7e0000U) {
2060
            info_array[0] = 0xff; /* heads   = 255 */
2061
            info_array[1] = 0x3f; /* sectors =  63 */
2062
         } else if ((unsigned int)size >= 0x200000U) {
2063
            info_array[0] = 0x80; /* heads   = 128 */
2064
            info_array[1] = 0x3f; /* sectors =  63 */
2065
         } else {
2066
            info_array[0] = 0x40; /* heads   =  64 */
2067
            info_array[1] = 0x20; /* sectors =  32 */
2068
         }
2069
      }
2070
                                /* For both methods, compute the cylinders */
2071
      info_array[2] = (unsigned int)size / (info_array[0] * info_array[1] );
2072
   }
2073
 
2074
   return 0;
2075
}
2076
 
2077
#ifdef MODULE
2078
/* Eventually this will go into an include file, but this will be later */
2079
Scsi_Host_Template driver_template = FDOMAIN_16X0;
2080
 
2081
#include "scsi_module.c"
2082
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.