Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / drivers / scsi / initio.c
1 /**************************************************************************
2  * Initio 9100 device driver for Linux.
3  *
4  * Copyright (c) 1994-1998 Initio Corporation
5  * Copyright (c) 1998 Bas Vermeulen <bvermeul@blackstar.xs4all.nl>
6  * All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; see the file COPYING.  If not, write to
20  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * --------------------------------------------------------------------------
23  *
24  * Redistribution and use in source and binary forms, with or without
25  * modification, are permitted provided that the following conditions
26  * are met:
27  * 1. Redistributions of source code must retain the above copyright
28  *    notice, this list of conditions, and the following disclaimer,
29  *    without modification, immediately at the beginning of the file.
30  * 2. Redistributions in binary form must reproduce the above copyright
31  *    notice, this list of conditions and the following disclaimer in the
32  *    documentation and/or other materials provided with the distribution.
33  * 3. The name of the author may not be used to endorse or promote products
34  *    derived from this software without specific prior written permission.
35  *
36  * Where this Software is combined with software released under the terms of 
37  * the GNU General Public License ("GPL") and the terms of the GPL would require the 
38  * combined work to also be released under the terms of the GPL, the terms
39  * and conditions of this License will apply in addition to those of the
40  * GPL with the exception of any terms or conditions of this License that
41  * conflict with, or are expressly prohibited by, the GPL.
42  *
43  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
44  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
47  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53  * SUCH DAMAGE.
54  *
55  *************************************************************************
56  *
57  * DESCRIPTION:
58  *
59  * This is the Linux low-level SCSI driver for Initio INI-9X00U/UW SCSI host
60  * adapters
61  *
62  * 08/06/97 hc  - v1.01h
63  *              - Support inic-940 and inic-935
64  * 09/26/97 hc  - v1.01i
65  *              - Make correction from J.W. Schultz suggestion
66  * 10/13/97 hc  - Support reset function
67  * 10/21/97 hc  - v1.01j
68  *              - Support 32 LUN (SCSI 3)
69  * 01/14/98 hc  - v1.01k
70  *              - Fix memory allocation problem
71  * 03/04/98 hc  - v1.01l
72  *              - Fix tape rewind which will hang the system problem
73  *              - Set can_queue to tul_num_scb
74  * 06/25/98 hc  - v1.01m
75  *              - Get it work for kernel version >= 2.1.75
76  *              - Dynamic assign SCSI bus reset holding time in init_tulip()
77  * 07/02/98 hc  - v1.01n
78  *              - Support 0002134A
79  * 08/07/98 hc  - v1.01o
80  *              - Change the tul_abort_srb routine to use scsi_done. <01>
81  * 09/07/98 hl  - v1.02
82  *              - Change the INI9100U define and proc_dir_entry to
83  *                reflect the newer Kernel 2.1.118, but the v1.o1o
84  *                should work with Kernel 2.1.118.
85  * 09/20/98 wh  - v1.02a
86  *              - Support Abort command.
87  *              - Handle reset routine.
88  * 09/21/98 hl  - v1.03
89  *              - remove comments.
90  * 12/09/98 bv  - v1.03a
91  *              - Removed unused code
92  * 12/13/98 bv  - v1.03b
93  *              - Remove cli() locking for kernels >= 2.1.95. This uses
94  *                spinlocks to serialize access to the pSRB_head and
95  *                pSRB_tail members of the HCS structure.
96  * 09/01/99 bv  - v1.03d
97  *              - Fixed a deadlock problem in SMP.
98  * 21/01/99 bv  - v1.03e
99  *              - Add support for the Domex 3192U PCI SCSI
100  *                This is a slightly modified patch by
101  *                Brian Macy <bmacy@sunshinecomputing.com>
102  * 22/02/99 bv  - v1.03f
103  *              - Didn't detect the INIC-950 in 2.0.x correctly.
104  *                Now fixed.
105  * 05/07/99 bv  - v1.03g
106  *              - Changed the assumption that HZ = 100
107  * 10/17/03 mc  - v1.04
108  *              - added new DMA API support
109  * 06/01/04 jmd - v1.04a
110  *              - Re-add reset_bus support
111  **************************************************************************/
112
113 #include <linux/module.h>
114 #include <linux/errno.h>
115 #include <linux/delay.h>
116 #include <linux/pci.h>
117 #include <linux/init.h>
118 #include <linux/blkdev.h>
119 #include <linux/spinlock.h>
120 #include <linux/stat.h>
121 #include <linux/kernel.h>
122 #include <linux/proc_fs.h>
123 #include <linux/string.h>
124 #include <linux/interrupt.h>
125 #include <linux/ioport.h>
126 #include <linux/slab.h>
127 #include <linux/jiffies.h>
128 #include <linux/dma-mapping.h>
129 #include <asm/io.h>
130
131 #include <scsi/scsi.h>
132 #include <scsi/scsi_cmnd.h>
133 #include <scsi/scsi_device.h>
134 #include <scsi/scsi_host.h>
135 #include <scsi/scsi_tcq.h>
136
137 #include "initio.h"
138
139 #define SENSE_SIZE              14
140
141 #define i91u_MAXQUEUE           2
142 #define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.04a"
143
144 #define I950_DEVICE_ID  0x9500  /* Initio's inic-950 product ID   */
145 #define I940_DEVICE_ID  0x9400  /* Initio's inic-940 product ID   */
146 #define I935_DEVICE_ID  0x9401  /* Initio's inic-935 product ID   */
147 #define I920_DEVICE_ID  0x0002  /* Initio's other product ID      */
148
149 #ifdef DEBUG_i91u
150 static unsigned int i91u_debug = DEBUG_DEFAULT;
151 #endif
152
153 #define TUL_RDWORD(x,y)         (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) ))
154
155 typedef struct PCI_ID_Struc {
156         unsigned short vendor_id;
157         unsigned short device_id;
158 } PCI_ID;
159
160 static int tul_num_ch = 4;      /* Maximum 4 adapters           */
161 static int tul_num_scb;
162 static int tul_tag_enable = 1;
163 static SCB *tul_scb;
164
165 #ifdef DEBUG_i91u
166 static int setup_debug = 0;
167 #endif
168
169 static void i91uSCBPost(BYTE * pHcb, BYTE * pScb);
170
171 /* PCI Devices supported by this driver */
172 static struct pci_device_id i91u_pci_devices[] = {
173         { PCI_VENDOR_ID_INIT,  I950_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
174         { PCI_VENDOR_ID_INIT,  I940_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
175         { PCI_VENDOR_ID_INIT,  I935_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
176         { PCI_VENDOR_ID_INIT,  I920_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
177         { PCI_VENDOR_ID_DOMEX, I920_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
178         { }
179 };
180 MODULE_DEVICE_TABLE(pci, i91u_pci_devices);
181
182 #define DEBUG_INTERRUPT 0
183 #define DEBUG_QUEUE     0
184 #define DEBUG_STATE     0
185 #define INT_DISC        0
186
187 /*--- external functions --*/
188 static void tul_se2_wait(void);
189
190 /*--- forward refrence ---*/
191 static SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun);
192 static SCB *tul_find_done_scb(HCS * pCurHcb);
193
194 static int tulip_main(HCS * pCurHcb);
195
196 static int tul_next_state(HCS * pCurHcb);
197 static int tul_state_1(HCS * pCurHcb);
198 static int tul_state_2(HCS * pCurHcb);
199 static int tul_state_3(HCS * pCurHcb);
200 static int tul_state_4(HCS * pCurHcb);
201 static int tul_state_5(HCS * pCurHcb);
202 static int tul_state_6(HCS * pCurHcb);
203 static int tul_state_7(HCS * pCurHcb);
204 static int tul_xfer_data_in(HCS * pCurHcb);
205 static int tul_xfer_data_out(HCS * pCurHcb);
206 static int tul_xpad_in(HCS * pCurHcb);
207 static int tul_xpad_out(HCS * pCurHcb);
208 static int tul_status_msg(HCS * pCurHcb);
209
210 static int tul_msgin(HCS * pCurHcb);
211 static int tul_msgin_sync(HCS * pCurHcb);
212 static int tul_msgin_accept(HCS * pCurHcb);
213 static int tul_msgout_reject(HCS * pCurHcb);
214 static int tul_msgin_extend(HCS * pCurHcb);
215
216 static int tul_msgout_ide(HCS * pCurHcb);
217 static int tul_msgout_abort_targ(HCS * pCurHcb);
218 static int tul_msgout_abort_tag(HCS * pCurHcb);
219
220 static int tul_bus_device_reset(HCS * pCurHcb);
221 static void tul_select_atn(HCS * pCurHcb, SCB * pCurScb);
222 static void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb);
223 static void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb);
224 static int int_tul_busfree(HCS * pCurHcb);
225 static int int_tul_scsi_rst(HCS * pCurHcb);
226 static int int_tul_bad_seq(HCS * pCurHcb);
227 static int int_tul_resel(HCS * pCurHcb);
228 static int tul_sync_done(HCS * pCurHcb);
229 static int wdtr_done(HCS * pCurHcb);
230 static int wait_tulip(HCS * pCurHcb);
231 static int tul_wait_done_disc(HCS * pCurHcb);
232 static int tul_wait_disc(HCS * pCurHcb);
233 static void tulip_scsi(HCS * pCurHcb);
234 static int tul_post_scsi_rst(HCS * pCurHcb);
235
236 static void tul_se2_ew_en(WORD CurBase);
237 static void tul_se2_ew_ds(WORD CurBase);
238 static int tul_se2_rd_all(WORD CurBase);
239 static void tul_se2_update_all(WORD CurBase);   /* setup default pattern */
240 static void tul_read_eeprom(WORD CurBase);
241
242                                 /* ---- INTERNAL VARIABLES ---- */
243 static HCS tul_hcs[MAX_SUPPORTED_ADAPTERS];
244 static INI_ADPT_STRUCT i91u_adpt[MAX_SUPPORTED_ADAPTERS];
245
246 /*NVRAM nvram, *nvramp = &nvram; */
247 static NVRAM i91unvram;
248 static NVRAM *i91unvramp;
249
250
251
252 static UCHAR i91udftNvRam[64] =
253 {
254 /*----------- header -----------*/
255         0x25, 0xc9,             /* Signature    */
256         0x40,                   /* Size         */
257         0x01,                   /* Revision     */
258         /* -- Host Adapter Structure -- */
259         0x95,                   /* ModelByte0   */
260         0x00,                   /* ModelByte1   */
261         0x00,                   /* ModelInfo    */
262         0x01,                   /* NumOfCh      */
263         NBC1_DEFAULT,           /* BIOSConfig1  */
264         0,                      /* BIOSConfig2  */
265         0,                      /* HAConfig1    */
266         0,                      /* HAConfig2    */
267         /* SCSI channel 0 and target Structure  */
268         7,                      /* SCSIid       */
269         NCC1_DEFAULT,           /* SCSIconfig1  */
270         0,                      /* SCSIconfig2  */
271         0x10,                   /* NumSCSItarget */
272
273         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
274         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
275         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
276         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
277
278         /* SCSI channel 1 and target Structure  */
279         7,                      /* SCSIid       */
280         NCC1_DEFAULT,           /* SCSIconfig1  */
281         0,                      /* SCSIconfig2  */
282         0x10,                   /* NumSCSItarget */
283
284         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
285         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
286         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
287         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
288         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
289         0, 0};                  /*      - CheckSum -            */
290
291
292 static UCHAR tul_rate_tbl[8] =  /* fast 20      */
293 {
294                                 /* nanosecond devide by 4 */
295         12,                     /* 50ns,  20M   */
296         18,                     /* 75ns,  13.3M */
297         25,                     /* 100ns, 10M   */
298         31,                     /* 125ns, 8M    */
299         37,                     /* 150ns, 6.6M  */
300         43,                     /* 175ns, 5.7M  */
301         50,                     /* 200ns, 5M    */
302         62                      /* 250ns, 4M    */
303 };
304
305 static void tul_do_pause(unsigned amount)
306 {                               /* Pause for amount jiffies */
307         unsigned long the_time = jiffies + amount;
308
309         while (time_before_eq(jiffies, the_time));
310 }
311
312 /*-- forward reference --*/
313
314 /*******************************************************************
315         Use memeory refresh time        ~ 15us * 2
316 ********************************************************************/
317 void tul_se2_wait(void)
318 {
319 #if 1
320         udelay(30);
321 #else
322         UCHAR readByte;
323
324         readByte = TUL_RD(0, 0x61);
325         if ((readByte & 0x10) == 0x10) {
326                 for (;;) {
327                         readByte = TUL_RD(0, 0x61);
328                         if ((readByte & 0x10) == 0x10)
329                                 break;
330                 }
331                 for (;;) {
332                         readByte = TUL_RD(0, 0x61);
333                         if ((readByte & 0x10) != 0x10)
334                                 break;
335                 }
336         } else {
337                 for (;;) {
338                         readByte = TUL_RD(0, 0x61);
339                         if ((readByte & 0x10) == 0x10)
340                                 break;
341                 }
342                 for (;;) {
343                         readByte = TUL_RD(0, 0x61);
344                         if ((readByte & 0x10) != 0x10)
345                                 break;
346                 }
347         }
348 #endif
349 }
350
351
352 /******************************************************************
353  Input: instruction for  Serial E2PROM
354
355  EX: se2_rd(0 call se2_instr() to send address and read command
356
357          StartBit  OP_Code   Address                Data
358          --------- --------  ------------------     -------
359          1         1 , 0     A5,A4,A3,A2,A1,A0      D15-D0
360
361                  +-----------------------------------------------------
362                  |
363  CS -----+
364                         +--+  +--+  +--+  +--+  +--+
365                         ^  |  ^  |  ^  |  ^  |  ^  |
366                         |  |  |  |  |  |  |  |  |  |
367  CLK -------+  +--+  +--+  +--+  +--+  +--
368  (leading edge trigger)
369
370                  +--1-----1--+
371                  | SB    OP  |  OP    A5    A4
372  DI  ----+           +--0------------------
373  (address and cmd sent to nvram)
374
375          -------------------------------------------+
376                                                                                                 |
377  DO                                             +---
378  (data sent from nvram)
379
380
381 ******************************************************************/
382 static void tul_se2_instr(WORD CurBase, UCHAR instr)
383 {
384         int i;
385         UCHAR b;
386
387         TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2DO);     /* cs+start bit */
388         tul_se2_wait();
389         TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK | SE2DO);    /* +CLK */
390         tul_se2_wait();
391
392         for (i = 0; i < 8; i++) {
393                 if (instr & 0x80)
394                         b = SE2CS | SE2DO;      /* -CLK+dataBit */
395                 else
396                         b = SE2CS;      /* -CLK */
397                 TUL_WR(CurBase + TUL_NVRAM, b);
398                 tul_se2_wait();
399                 TUL_WR(CurBase + TUL_NVRAM, b | SE2CLK);        /* +CLK */
400                 tul_se2_wait();
401                 instr <<= 1;
402         }
403         TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK */
404         tul_se2_wait();
405         return;
406 }
407
408
409 /******************************************************************
410  Function name  : tul_se2_ew_en
411  Description    : Enable erase/write state of serial EEPROM
412 ******************************************************************/
413 void tul_se2_ew_en(WORD CurBase)
414 {
415         tul_se2_instr(CurBase, 0x30);   /* EWEN */
416         TUL_WR(CurBase + TUL_NVRAM, 0);         /* -CS  */
417         tul_se2_wait();
418         return;
419 }
420
421
422 /************************************************************************
423  Disable erase/write state of serial EEPROM
424 *************************************************************************/
425 void tul_se2_ew_ds(WORD CurBase)
426 {
427         tul_se2_instr(CurBase, 0);      /* EWDS */
428         TUL_WR(CurBase + TUL_NVRAM, 0);         /* -CS  */
429         tul_se2_wait();
430         return;
431 }
432
433
434 /******************************************************************
435         Input  :address of Serial E2PROM
436         Output :value stored in  Serial E2PROM
437 *******************************************************************/
438 static USHORT tul_se2_rd(WORD CurBase, ULONG adr)
439 {
440         UCHAR instr, readByte;
441         USHORT readWord;
442         int i;
443
444         instr = (UCHAR) (adr | 0x80);
445         tul_se2_instr(CurBase, instr);  /* READ INSTR */
446         readWord = 0;
447
448         for (i = 15; i >= 0; i--) {
449                 TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK);    /* +CLK */
450                 tul_se2_wait();
451                 TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK */
452
453                 /* sample data after the following edge of clock  */
454                 readByte = TUL_RD(CurBase, TUL_NVRAM);
455                 readByte &= SE2DI;
456                 readWord += (readByte << i);
457                 tul_se2_wait(); /* 6/20/95 */
458         }
459
460         TUL_WR(CurBase + TUL_NVRAM, 0);         /* no chip select */
461         tul_se2_wait();
462         return readWord;
463 }
464
465
466 /******************************************************************
467  Input: new value in  Serial E2PROM, address of Serial E2PROM
468 *******************************************************************/
469 static void tul_se2_wr(WORD CurBase, UCHAR adr, USHORT writeWord)
470 {
471         UCHAR readByte;
472         UCHAR instr;
473         int i;
474
475         instr = (UCHAR) (adr | 0x40);
476         tul_se2_instr(CurBase, instr);  /* WRITE INSTR */
477         for (i = 15; i >= 0; i--) {
478                 if (writeWord & 0x8000)
479                         TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2DO);     /* -CLK+dataBit 1 */
480                 else
481                         TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK+dataBit 0 */
482                 tul_se2_wait();
483                 TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK);    /* +CLK */
484                 tul_se2_wait();
485                 writeWord <<= 1;
486         }
487         TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK */
488         tul_se2_wait();
489         TUL_WR(CurBase + TUL_NVRAM, 0);         /* -CS  */
490         tul_se2_wait();
491
492         TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* +CS  */
493         tul_se2_wait();
494
495         for (;;) {
496                 TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK);    /* +CLK */
497                 tul_se2_wait();
498                 TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK */
499                 tul_se2_wait();
500                 if ((readByte = TUL_RD(CurBase, TUL_NVRAM)) & SE2DI)
501                         break;  /* write complete */
502         }
503         TUL_WR(CurBase + TUL_NVRAM, 0);         /* -CS */
504         return;
505 }
506
507
508 /***********************************************************************
509  Read SCSI H/A configuration parameters from serial EEPROM
510 ************************************************************************/
511 int tul_se2_rd_all(WORD CurBase)
512 {
513         int i;
514         ULONG chksum = 0;
515         USHORT *np;
516
517         i91unvramp = &i91unvram;
518         np = (USHORT *) i91unvramp;
519         for (i = 0; i < 32; i++) {
520                 *np++ = tul_se2_rd(CurBase, i);
521         }
522
523 /*--------------------Is signature "ini" ok ? ----------------*/
524         if (i91unvramp->NVM_Signature != INI_SIGNATURE)
525                 return -1;
526 /*---------------------- Is ckecksum ok ? ----------------------*/
527         np = (USHORT *) i91unvramp;
528         for (i = 0; i < 31; i++)
529                 chksum += *np++;
530         if (i91unvramp->NVM_CheckSum != (USHORT) chksum)
531                 return -1;
532         return 1;
533 }
534
535
536 /***********************************************************************
537  Update SCSI H/A configuration parameters from serial EEPROM
538 ************************************************************************/
539 void tul_se2_update_all(WORD CurBase)
540 {                               /* setup default pattern */
541         int i;
542         ULONG chksum = 0;
543         USHORT *np, *np1;
544
545         i91unvramp = &i91unvram;
546         /* Calculate checksum first */
547         np = (USHORT *) i91udftNvRam;
548         for (i = 0; i < 31; i++)
549                 chksum += *np++;
550         *np = (USHORT) chksum;
551         tul_se2_ew_en(CurBase); /* Enable write  */
552
553         np = (USHORT *) i91udftNvRam;
554         np1 = (USHORT *) i91unvramp;
555         for (i = 0; i < 32; i++, np++, np1++) {
556                 if (*np != *np1) {
557                         tul_se2_wr(CurBase, i, *np);
558                 }
559         }
560
561         tul_se2_ew_ds(CurBase); /* Disable write   */
562         return;
563 }
564
565 /*************************************************************************
566  Function name  : read_eeprom
567 **************************************************************************/
568 void tul_read_eeprom(WORD CurBase)
569 {
570         UCHAR gctrl;
571
572         i91unvramp = &i91unvram;
573 /*------Enable EEProm programming ---*/
574         gctrl = TUL_RD(CurBase, TUL_GCTRL);
575         TUL_WR(CurBase + TUL_GCTRL, gctrl | TUL_GCTRL_EEPROM_BIT);
576         if (tul_se2_rd_all(CurBase) != 1) {
577                 tul_se2_update_all(CurBase);    /* setup default pattern */
578                 tul_se2_rd_all(CurBase);        /* load again  */
579         }
580 /*------ Disable EEProm programming ---*/
581         gctrl = TUL_RD(CurBase, TUL_GCTRL);
582         TUL_WR(CurBase + TUL_GCTRL, gctrl & ~TUL_GCTRL_EEPROM_BIT);
583 }                               /* read_eeprom */
584
585 static int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
586                                       BYTE bBus, BYTE bDevice)
587 {
588         int i, j;
589
590         for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) {
591                 if (i91u_adpt[i].ADPT_BIOS < wBIOS)
592                         continue;
593                 if (i91u_adpt[i].ADPT_BIOS == wBIOS) {
594                         if (i91u_adpt[i].ADPT_BASE == wBASE) {
595                                 if (i91u_adpt[i].ADPT_Bus != 0xFF)
596                                         return 1;
597                         } else if (i91u_adpt[i].ADPT_BASE < wBASE)
598                                         continue;
599                 }
600                 for (j = MAX_SUPPORTED_ADAPTERS - 1; j > i; j--) {
601                         i91u_adpt[j].ADPT_BASE = i91u_adpt[j - 1].ADPT_BASE;
602                         i91u_adpt[j].ADPT_INTR = i91u_adpt[j - 1].ADPT_INTR;
603                         i91u_adpt[j].ADPT_BIOS = i91u_adpt[j - 1].ADPT_BIOS;
604                         i91u_adpt[j].ADPT_Bus = i91u_adpt[j - 1].ADPT_Bus;
605                         i91u_adpt[j].ADPT_Device = i91u_adpt[j - 1].ADPT_Device;
606                 }
607                 i91u_adpt[i].ADPT_BASE = wBASE;
608                 i91u_adpt[i].ADPT_INTR = bInterrupt;
609                 i91u_adpt[i].ADPT_BIOS = wBIOS;
610                 i91u_adpt[i].ADPT_Bus = bBus;
611                 i91u_adpt[i].ADPT_Device = bDevice;
612                 return 0;
613         }
614         return 1;
615 }
616
617 static void init_i91uAdapter_table(void)
618 {
619         int i;
620
621         for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) {  /* Initialize adapter structure */
622                 i91u_adpt[i].ADPT_BIOS = 0xffff;
623                 i91u_adpt[i].ADPT_BASE = 0xffff;
624                 i91u_adpt[i].ADPT_INTR = 0xff;
625                 i91u_adpt[i].ADPT_Bus = 0xff;
626                 i91u_adpt[i].ADPT_Device = 0xff;
627         }
628         return;
629 }
630
631 static void tul_stop_bm(HCS * pCurHcb)
632 {
633
634         if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) {   /* if DMA xfer is pending, abort DMA xfer */
635                 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT | TAX_X_CLR_FIFO);
636                 /* wait Abort DMA xfer done */
637                 while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & XABT) == 0);
638         }
639         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
640 }
641
642 /***************************************************************************/
643 static void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx)
644 {
645         pCurHcb->HCS_Base = i91u_adpt[ch_idx].ADPT_BASE;        /* Supply base address  */
646         pCurHcb->HCS_BIOS = i91u_adpt[ch_idx].ADPT_BIOS;        /* Supply BIOS address  */
647         pCurHcb->HCS_Intr = i91u_adpt[ch_idx].ADPT_INTR;        /* Supply interrupt line */
648         return;
649 }
650
651 /***************************************************************************/
652 static int tul_reset_scsi(HCS * pCurHcb, int seconds)
653 {
654         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_BUS);
655
656         while (!((pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt)) & TSS_SCSIRST_INT));
657         /* reset tulip chip */
658
659         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, 0);
660
661         /* Stall for a while, wait for target's firmware ready,make it 2 sec ! */
662         /* SONY 5200 tape drive won't work if only stall for 1 sec */
663         tul_do_pause(seconds * HZ);
664
665         TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
666
667         return (SCSI_RESET_SUCCESS);
668 }
669
670 /***************************************************************************/
671 static int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb,
672                       BYTE * pbBiosAdr, int seconds)
673 {
674         int i;
675         BYTE *pwFlags;
676         BYTE *pbHeads;
677         SCB *pTmpScb, *pPrevScb = NULL;
678
679         pCurHcb->HCS_NumScbs = tul_num_scb;
680         pCurHcb->HCS_Semaph = 1;
681         spin_lock_init(&pCurHcb->HCS_SemaphLock);
682         pCurHcb->HCS_JSStatus0 = 0;
683         pCurHcb->HCS_Scb = scbp;
684         pCurHcb->HCS_NxtPend = scbp;
685         pCurHcb->HCS_NxtAvail = scbp;
686         for (i = 0, pTmpScb = scbp; i < tul_num_scb; i++, pTmpScb++) {
687                 pTmpScb->SCB_TagId = i;
688                 if (i != 0)
689                         pPrevScb->SCB_NxtScb = pTmpScb;
690                 pPrevScb = pTmpScb;
691         }
692         pPrevScb->SCB_NxtScb = NULL;
693         pCurHcb->HCS_ScbEnd = pTmpScb;
694         pCurHcb->HCS_FirstAvail = scbp;
695         pCurHcb->HCS_LastAvail = pPrevScb;
696         spin_lock_init(&pCurHcb->HCS_AvailLock);
697         pCurHcb->HCS_FirstPend = NULL;
698         pCurHcb->HCS_LastPend = NULL;
699         pCurHcb->HCS_FirstBusy = NULL;
700         pCurHcb->HCS_LastBusy = NULL;
701         pCurHcb->HCS_FirstDone = NULL;
702         pCurHcb->HCS_LastDone = NULL;
703         pCurHcb->HCS_ActScb = NULL;
704         pCurHcb->HCS_ActTcs = NULL;
705
706         tul_read_eeprom(pCurHcb->HCS_Base);
707 /*---------- get H/A configuration -------------*/
708         if (i91unvramp->NVM_SCSIInfo[0].NVM_NumOfTarg == 8)
709                 pCurHcb->HCS_MaxTar = 8;
710         else
711                 pCurHcb->HCS_MaxTar = 16;
712
713         pCurHcb->HCS_Config = i91unvramp->NVM_SCSIInfo[0].NVM_ChConfig1;
714
715         pCurHcb->HCS_SCSI_ID = i91unvramp->NVM_SCSIInfo[0].NVM_ChSCSIID;
716         pCurHcb->HCS_IdMask = ~(1 << pCurHcb->HCS_SCSI_ID);
717
718 #ifdef CHK_PARITY
719         /* Enable parity error response */
720         TUL_WR(pCurHcb->HCS_Base + TUL_PCMD, TUL_RD(pCurHcb->HCS_Base, TUL_PCMD) | 0x40);
721 #endif
722
723         /* Mask all the interrupt       */
724         TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
725
726         tul_stop_bm(pCurHcb);
727         /* --- Initialize the tulip --- */
728         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_CHIP);
729
730         /* program HBA's SCSI ID        */
731         TUL_WR(pCurHcb->HCS_Base + TUL_SScsiId, pCurHcb->HCS_SCSI_ID << 4);
732
733         /* Enable Initiator Mode ,phase latch,alternate sync period mode,
734            disable SCSI reset */
735         if (pCurHcb->HCS_Config & HCC_EN_PAR)
736                 pCurHcb->HCS_SConf1 = (TSC_INITDEFAULT | TSC_EN_SCSI_PAR);
737         else
738                 pCurHcb->HCS_SConf1 = (TSC_INITDEFAULT);
739         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_SConf1);
740
741         /* Enable HW reselect           */
742         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);
743
744         TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, 0);
745
746         /* selection time out = 250 ms */
747         TUL_WR(pCurHcb->HCS_Base + TUL_STimeOut, 153);
748
749 /*--------- Enable SCSI terminator -----*/
750         TUL_WR(pCurHcb->HCS_Base + TUL_XCtrl, (pCurHcb->HCS_Config & (HCC_ACT_TERM1 | HCC_ACT_TERM2)));
751         TUL_WR(pCurHcb->HCS_Base + TUL_GCTRL1,
752                ((pCurHcb->HCS_Config & HCC_AUTO_TERM) >> 4) | (TUL_RD(pCurHcb->HCS_Base, TUL_GCTRL1) & 0xFE));
753
754         for (i = 0,
755              pwFlags = & (i91unvramp->NVM_SCSIInfo[0].NVM_Targ0Config),
756              pbHeads = pbBiosAdr + 0x180;
757              i < pCurHcb->HCS_MaxTar;
758              i++, pwFlags++) {
759                 pCurHcb->HCS_Tcs[i].TCS_Flags = *pwFlags & ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
760                 if (pCurHcb->HCS_Tcs[i].TCS_Flags & TCF_EN_255)
761                         pCurHcb->HCS_Tcs[i].TCS_DrvFlags = TCF_DRV_255_63;
762                 else
763                         pCurHcb->HCS_Tcs[i].TCS_DrvFlags = 0;
764                 pCurHcb->HCS_Tcs[i].TCS_JS_Period = 0;
765                 pCurHcb->HCS_Tcs[i].TCS_SConfig0 = pCurHcb->HCS_SConf1;
766                 pCurHcb->HCS_Tcs[i].TCS_DrvHead = *pbHeads++;
767                 if (pCurHcb->HCS_Tcs[i].TCS_DrvHead == 255)
768                         pCurHcb->HCS_Tcs[i].TCS_DrvFlags = TCF_DRV_255_63;
769                 else
770                         pCurHcb->HCS_Tcs[i].TCS_DrvFlags = 0;
771                 pCurHcb->HCS_Tcs[i].TCS_DrvSector = *pbHeads++;
772                 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~TCF_BUSY;
773                 pCurHcb->HCS_ActTags[i] = 0;
774                 pCurHcb->HCS_MaxTags[i] = 0xFF;
775         }                       /* for                          */
776         printk("i91u: PCI Base=0x%04X, IRQ=%d, BIOS=0x%04X0, SCSI ID=%d\n",
777                pCurHcb->HCS_Base, pCurHcb->HCS_Intr,
778                pCurHcb->HCS_BIOS, pCurHcb->HCS_SCSI_ID);
779 /*------------------- reset SCSI Bus ---------------------------*/
780         if (pCurHcb->HCS_Config & HCC_SCSI_RESET) {
781                 printk("i91u: Reset SCSI Bus ... \n");
782                 tul_reset_scsi(pCurHcb, seconds);
783         }
784         TUL_WR(pCurHcb->HCS_Base + TUL_SCFG1, 0x17);
785         TUL_WR(pCurHcb->HCS_Base + TUL_SIntEnable, 0xE9);
786         return (0);
787 }
788
789 /***************************************************************************/
790 static SCB *tul_alloc_scb(HCS * hcsp)
791 {
792         SCB *pTmpScb;
793         ULONG flags;
794         spin_lock_irqsave(&(hcsp->HCS_AvailLock), flags);
795         if ((pTmpScb = hcsp->HCS_FirstAvail) != NULL) {
796 #if DEBUG_QUEUE
797                 printk("find scb at %08lx\n", (ULONG) pTmpScb);
798 #endif
799                 if ((hcsp->HCS_FirstAvail = pTmpScb->SCB_NxtScb) == NULL)
800                         hcsp->HCS_LastAvail = NULL;
801                 pTmpScb->SCB_NxtScb = NULL;
802                 pTmpScb->SCB_Status = SCB_RENT;
803         }
804         spin_unlock_irqrestore(&(hcsp->HCS_AvailLock), flags);
805         return (pTmpScb);
806 }
807
808 /***************************************************************************/
809 static void tul_release_scb(HCS * hcsp, SCB * scbp)
810 {
811         ULONG flags;
812
813 #if DEBUG_QUEUE
814         printk("Release SCB %lx; ", (ULONG) scbp);
815 #endif
816         spin_lock_irqsave(&(hcsp->HCS_AvailLock), flags);
817         scbp->SCB_Srb = NULL;
818         scbp->SCB_Status = 0;
819         scbp->SCB_NxtScb = NULL;
820         if (hcsp->HCS_LastAvail != NULL) {
821                 hcsp->HCS_LastAvail->SCB_NxtScb = scbp;
822                 hcsp->HCS_LastAvail = scbp;
823         } else {
824                 hcsp->HCS_FirstAvail = scbp;
825                 hcsp->HCS_LastAvail = scbp;
826         }
827         spin_unlock_irqrestore(&(hcsp->HCS_AvailLock), flags);
828 }
829
830 /***************************************************************************/
831 static void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp)
832 {
833
834 #if DEBUG_QUEUE
835         printk("Append pend SCB %lx; ", (ULONG) scbp);
836 #endif
837         scbp->SCB_Status = SCB_PEND;
838         scbp->SCB_NxtScb = NULL;
839         if (pCurHcb->HCS_LastPend != NULL) {
840                 pCurHcb->HCS_LastPend->SCB_NxtScb = scbp;
841                 pCurHcb->HCS_LastPend = scbp;
842         } else {
843                 pCurHcb->HCS_FirstPend = scbp;
844                 pCurHcb->HCS_LastPend = scbp;
845         }
846 }
847
848 /***************************************************************************/
849 static void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp)
850 {
851
852 #if DEBUG_QUEUE
853         printk("Push pend SCB %lx; ", (ULONG) scbp);
854 #endif
855         scbp->SCB_Status = SCB_PEND;
856         if ((scbp->SCB_NxtScb = pCurHcb->HCS_FirstPend) != NULL) {
857                 pCurHcb->HCS_FirstPend = scbp;
858         } else {
859                 pCurHcb->HCS_FirstPend = scbp;
860                 pCurHcb->HCS_LastPend = scbp;
861         }
862 }
863
864 /***************************************************************************/
865 static SCB *tul_find_first_pend_scb(HCS * pCurHcb)
866 {
867         SCB *pFirstPend;
868
869
870         pFirstPend = pCurHcb->HCS_FirstPend;
871         while (pFirstPend != NULL) {
872                 if (pFirstPend->SCB_Opcode != ExecSCSI) {
873                         return (pFirstPend);
874                 }
875                 if (pFirstPend->SCB_TagMsg == 0) {
876                         if ((pCurHcb->HCS_ActTags[pFirstPend->SCB_Target] == 0) &&
877                             !(pCurHcb->HCS_Tcs[pFirstPend->SCB_Target].TCS_Flags & TCF_BUSY)) {
878                                 return (pFirstPend);
879                         }
880                 } else {
881                         if ((pCurHcb->HCS_ActTags[pFirstPend->SCB_Target] >=
882                           pCurHcb->HCS_MaxTags[pFirstPend->SCB_Target]) |
883                             (pCurHcb->HCS_Tcs[pFirstPend->SCB_Target].TCS_Flags & TCF_BUSY)) {
884                                 pFirstPend = pFirstPend->SCB_NxtScb;
885                                 continue;
886                         }
887                         return (pFirstPend);
888                 }
889                 pFirstPend = pFirstPend->SCB_NxtScb;
890         }
891
892
893         return (pFirstPend);
894 }
895 /***************************************************************************/
896 static void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb)
897 {
898         SCB *pTmpScb, *pPrevScb;
899
900 #if DEBUG_QUEUE
901         printk("unlink pend SCB %lx; ", (ULONG) pCurScb);
902 #endif
903
904         pPrevScb = pTmpScb = pCurHcb->HCS_FirstPend;
905         while (pTmpScb != NULL) {
906                 if (pCurScb == pTmpScb) {       /* Unlink this SCB              */
907                         if (pTmpScb == pCurHcb->HCS_FirstPend) {
908                                 if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL)
909                                         pCurHcb->HCS_LastPend = NULL;
910                         } else {
911                                 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
912                                 if (pTmpScb == pCurHcb->HCS_LastPend)
913                                         pCurHcb->HCS_LastPend = pPrevScb;
914                         }
915                         pTmpScb->SCB_NxtScb = NULL;
916                         break;
917                 }
918                 pPrevScb = pTmpScb;
919                 pTmpScb = pTmpScb->SCB_NxtScb;
920         }
921         return;
922 }
923 /***************************************************************************/
924 static void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp)
925 {
926
927 #if DEBUG_QUEUE
928         printk("append busy SCB %lx; ", (ULONG) scbp);
929 #endif
930         if (scbp->SCB_TagMsg)
931                 pCurHcb->HCS_ActTags[scbp->SCB_Target]++;
932         else
933                 pCurHcb->HCS_Tcs[scbp->SCB_Target].TCS_Flags |= TCF_BUSY;
934         scbp->SCB_Status = SCB_BUSY;
935         scbp->SCB_NxtScb = NULL;
936         if (pCurHcb->HCS_LastBusy != NULL) {
937                 pCurHcb->HCS_LastBusy->SCB_NxtScb = scbp;
938                 pCurHcb->HCS_LastBusy = scbp;
939         } else {
940                 pCurHcb->HCS_FirstBusy = scbp;
941                 pCurHcb->HCS_LastBusy = scbp;
942         }
943 }
944
945 /***************************************************************************/
946 static SCB *tul_pop_busy_scb(HCS * pCurHcb)
947 {
948         SCB *pTmpScb;
949
950
951         if ((pTmpScb = pCurHcb->HCS_FirstBusy) != NULL) {
952                 if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
953                         pCurHcb->HCS_LastBusy = NULL;
954                 pTmpScb->SCB_NxtScb = NULL;
955                 if (pTmpScb->SCB_TagMsg)
956                         pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--;
957                 else
958                         pCurHcb->HCS_Tcs[pTmpScb->SCB_Target].TCS_Flags &= ~TCF_BUSY;
959         }
960 #if DEBUG_QUEUE
961         printk("Pop busy SCB %lx; ", (ULONG) pTmpScb);
962 #endif
963         return (pTmpScb);
964 }
965
966 /***************************************************************************/
967 static void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb)
968 {
969         SCB *pTmpScb, *pPrevScb;
970
971 #if DEBUG_QUEUE
972         printk("unlink busy SCB %lx; ", (ULONG) pCurScb);
973 #endif
974
975         pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy;
976         while (pTmpScb != NULL) {
977                 if (pCurScb == pTmpScb) {       /* Unlink this SCB              */
978                         if (pTmpScb == pCurHcb->HCS_FirstBusy) {
979                                 if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
980                                         pCurHcb->HCS_LastBusy = NULL;
981                         } else {
982                                 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
983                                 if (pTmpScb == pCurHcb->HCS_LastBusy)
984                                         pCurHcb->HCS_LastBusy = pPrevScb;
985                         }
986                         pTmpScb->SCB_NxtScb = NULL;
987                         if (pTmpScb->SCB_TagMsg)
988                                 pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--;
989                         else
990                                 pCurHcb->HCS_Tcs[pTmpScb->SCB_Target].TCS_Flags &= ~TCF_BUSY;
991                         break;
992                 }
993                 pPrevScb = pTmpScb;
994                 pTmpScb = pTmpScb->SCB_NxtScb;
995         }
996         return;
997 }
998
999 /***************************************************************************/
1000 SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun)
1001 {
1002         SCB *pTmpScb, *pPrevScb;
1003         WORD scbp_tarlun;
1004
1005
1006         pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy;
1007         while (pTmpScb != NULL) {
1008                 scbp_tarlun = (pTmpScb->SCB_Lun << 8) | (pTmpScb->SCB_Target);
1009                 if (scbp_tarlun == tarlun) {    /* Unlink this SCB              */
1010                         break;
1011                 }
1012                 pPrevScb = pTmpScb;
1013                 pTmpScb = pTmpScb->SCB_NxtScb;
1014         }
1015 #if DEBUG_QUEUE
1016         printk("find busy SCB %lx; ", (ULONG) pTmpScb);
1017 #endif
1018         return (pTmpScb);
1019 }
1020
1021 /***************************************************************************/
1022 static void tul_append_done_scb(HCS * pCurHcb, SCB * scbp)
1023 {
1024
1025 #if DEBUG_QUEUE
1026         printk("append done SCB %lx; ", (ULONG) scbp);
1027 #endif
1028
1029         scbp->SCB_Status = SCB_DONE;
1030         scbp->SCB_NxtScb = NULL;
1031         if (pCurHcb->HCS_LastDone != NULL) {
1032                 pCurHcb->HCS_LastDone->SCB_NxtScb = scbp;
1033                 pCurHcb->HCS_LastDone = scbp;
1034         } else {
1035                 pCurHcb->HCS_FirstDone = scbp;
1036                 pCurHcb->HCS_LastDone = scbp;
1037         }
1038 }
1039
1040 /***************************************************************************/
1041 SCB *tul_find_done_scb(HCS * pCurHcb)
1042 {
1043         SCB *pTmpScb;
1044
1045
1046         if ((pTmpScb = pCurHcb->HCS_FirstDone) != NULL) {
1047                 if ((pCurHcb->HCS_FirstDone = pTmpScb->SCB_NxtScb) == NULL)
1048                         pCurHcb->HCS_LastDone = NULL;
1049                 pTmpScb->SCB_NxtScb = NULL;
1050         }
1051 #if DEBUG_QUEUE
1052         printk("find done SCB %lx; ", (ULONG) pTmpScb);
1053 #endif
1054         return (pTmpScb);
1055 }
1056
1057 /***************************************************************************/
1058 static int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp)
1059 {
1060         ULONG flags;
1061         SCB *pTmpScb, *pPrevScb;
1062
1063         spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1064
1065         if ((pCurHcb->HCS_Semaph == 0) && (pCurHcb->HCS_ActScb == NULL)) {
1066                 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
1067                 /* disable Jasmin SCSI Int        */
1068
1069                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1070
1071                 tulip_main(pCurHcb);
1072
1073                 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1074
1075                 pCurHcb->HCS_Semaph = 1;
1076                 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
1077
1078                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1079
1080                 return SCSI_ABORT_SNOOZE;
1081         }
1082         pPrevScb = pTmpScb = pCurHcb->HCS_FirstPend;    /* Check Pend queue */
1083         while (pTmpScb != NULL) {
1084                 /* 07/27/98 */
1085                 if (pTmpScb->SCB_Srb == srbp) {
1086                         if (pTmpScb == pCurHcb->HCS_ActScb) {
1087                                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1088                                 return SCSI_ABORT_BUSY;
1089                         } else if (pTmpScb == pCurHcb->HCS_FirstPend) {
1090                                 if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL)
1091                                         pCurHcb->HCS_LastPend = NULL;
1092                         } else {
1093                                 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
1094                                 if (pTmpScb == pCurHcb->HCS_LastPend)
1095                                         pCurHcb->HCS_LastPend = pPrevScb;
1096                         }
1097                         pTmpScb->SCB_HaStat = HOST_ABORTED;
1098                         pTmpScb->SCB_Flags |= SCF_DONE;
1099                         if (pTmpScb->SCB_Flags & SCF_POST)
1100                                 (*pTmpScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pTmpScb);
1101                         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1102                         return SCSI_ABORT_SUCCESS;
1103                 }
1104                 pPrevScb = pTmpScb;
1105                 pTmpScb = pTmpScb->SCB_NxtScb;
1106         }
1107
1108         pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy;    /* Check Busy queue */
1109         while (pTmpScb != NULL) {
1110
1111                 if (pTmpScb->SCB_Srb == srbp) {
1112
1113                         if (pTmpScb == pCurHcb->HCS_ActScb) {
1114                                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1115                                 return SCSI_ABORT_BUSY;
1116                         } else if (pTmpScb->SCB_TagMsg == 0) {
1117                                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1118                                 return SCSI_ABORT_BUSY;
1119                         } else {
1120                                 pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--;
1121                                 if (pTmpScb == pCurHcb->HCS_FirstBusy) {
1122                                         if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
1123                                                 pCurHcb->HCS_LastBusy = NULL;
1124                                 } else {
1125                                         pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
1126                                         if (pTmpScb == pCurHcb->HCS_LastBusy)
1127                                                 pCurHcb->HCS_LastBusy = pPrevScb;
1128                                 }
1129                                 pTmpScb->SCB_NxtScb = NULL;
1130
1131
1132                                 pTmpScb->SCB_HaStat = HOST_ABORTED;
1133                                 pTmpScb->SCB_Flags |= SCF_DONE;
1134                                 if (pTmpScb->SCB_Flags & SCF_POST)
1135                                         (*pTmpScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pTmpScb);
1136                                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1137                                 return SCSI_ABORT_SUCCESS;
1138                         }
1139                 }
1140                 pPrevScb = pTmpScb;
1141                 pTmpScb = pTmpScb->SCB_NxtScb;
1142         }
1143         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1144         return (SCSI_ABORT_NOT_RUNNING);
1145 }
1146
1147 /***************************************************************************/
1148 static int tul_bad_seq(HCS * pCurHcb)
1149 {
1150         SCB *pCurScb;
1151
1152         printk("tul_bad_seg c=%d\n", pCurHcb->HCS_Index);
1153
1154         if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) {
1155                 tul_unlink_busy_scb(pCurHcb, pCurScb);
1156                 pCurScb->SCB_HaStat = HOST_BAD_PHAS;
1157                 pCurScb->SCB_TaStat = 0;
1158                 tul_append_done_scb(pCurHcb, pCurScb);
1159         }
1160         tul_stop_bm(pCurHcb);
1161
1162         tul_reset_scsi(pCurHcb, 8);     /* 7/29/98 */
1163
1164         return (tul_post_scsi_rst(pCurHcb));
1165 }
1166
1167 #if 0
1168
1169 /************************************************************************/
1170 static int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb,
1171                             unsigned int target, unsigned int ResetFlags)
1172 {
1173         ULONG flags;
1174         SCB *pScb;
1175         spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1176
1177         if (ResetFlags & SCSI_RESET_ASYNCHRONOUS) {
1178
1179                 if ((pCurHcb->HCS_Semaph == 0) && (pCurHcb->HCS_ActScb == NULL)) {
1180                         TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
1181                         /* disable Jasmin SCSI Int        */
1182
1183                         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1184
1185                         tulip_main(pCurHcb);
1186
1187                         spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1188
1189                         pCurHcb->HCS_Semaph = 1;
1190                         TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
1191
1192                         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1193
1194                         return SCSI_RESET_SNOOZE;
1195                 }
1196                 pScb = pCurHcb->HCS_FirstBusy;  /* Check Busy queue */
1197                 while (pScb != NULL) {
1198                         if (pScb->SCB_Srb == pSrb)
1199                                 break;
1200                         pScb = pScb->SCB_NxtScb;
1201                 }
1202                 if (pScb == NULL) {
1203                         printk("Unable to Reset - No SCB Found\n");
1204
1205                         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1206                         return SCSI_RESET_NOT_RUNNING;
1207                 }
1208         }
1209         if ((pScb = tul_alloc_scb(pCurHcb)) == NULL) {
1210                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1211                 return SCSI_RESET_NOT_RUNNING;
1212         }
1213         pScb->SCB_Opcode = BusDevRst;
1214         pScb->SCB_Flags = SCF_POST;
1215         pScb->SCB_Target = target;
1216         pScb->SCB_Mode = 0;
1217
1218         pScb->SCB_Srb = NULL;
1219         if (ResetFlags & SCSI_RESET_SYNCHRONOUS) {
1220                 pScb->SCB_Srb = pSrb;
1221         }
1222         tul_push_pend_scb(pCurHcb, pScb);       /* push this SCB to Pending queue */
1223
1224         if (pCurHcb->HCS_Semaph == 1) {
1225                 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
1226                 /* disable Jasmin SCSI Int        */
1227                 pCurHcb->HCS_Semaph = 0;
1228
1229                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1230
1231                 tulip_main(pCurHcb);
1232
1233                 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1234
1235                 pCurHcb->HCS_Semaph = 1;
1236                 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
1237         }
1238         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1239         return SCSI_RESET_PENDING;
1240 }
1241
1242 static int tul_reset_scsi_bus(HCS * pCurHcb)
1243 {
1244         ULONG flags;
1245
1246         spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1247         TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
1248         pCurHcb->HCS_Semaph = 0;
1249
1250         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1251
1252         tul_stop_bm(pCurHcb);
1253
1254         tul_reset_scsi(pCurHcb, 2);     /* 7/29/98 */
1255
1256         spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1257         tul_post_scsi_rst(pCurHcb);
1258
1259         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1260
1261         tulip_main(pCurHcb);
1262
1263         spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1264
1265         pCurHcb->HCS_Semaph = 1;
1266         TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
1267         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1268         return (SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET);
1269 }
1270
1271 #endif  /*  0  */
1272
1273 /************************************************************************/
1274 static void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb)
1275 {
1276         ULONG flags;
1277
1278         pCurScb->SCB_Mode = 0;
1279
1280         pCurScb->SCB_SGIdx = 0;
1281         pCurScb->SCB_SGMax = pCurScb->SCB_SGLen;
1282
1283         spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1284
1285         tul_append_pend_scb(pCurHcb, pCurScb);  /* Append this SCB to Pending queue */
1286
1287 /* VVVVV 07/21/98 */
1288         if (pCurHcb->HCS_Semaph == 1) {
1289                 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
1290                 /* disable Jasmin SCSI Int        */
1291                 pCurHcb->HCS_Semaph = 0;
1292
1293                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1294
1295                 tulip_main(pCurHcb);
1296
1297                 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1298
1299                 pCurHcb->HCS_Semaph = 1;
1300                 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
1301         }
1302         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1303         return;
1304 }
1305
1306 /***************************************************************************/
1307 static int tul_isr(HCS * pCurHcb)
1308 {
1309         /* Enter critical section       */
1310
1311         if (TUL_RD(pCurHcb->HCS_Base, TUL_Int) & TSS_INT_PENDING) {
1312                 if (pCurHcb->HCS_Semaph == 1) {
1313                         TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
1314                         /* Disable Tulip SCSI Int */
1315                         pCurHcb->HCS_Semaph = 0;
1316
1317                         tulip_main(pCurHcb);
1318
1319                         pCurHcb->HCS_Semaph = 1;
1320                         TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
1321                         return (1);
1322                 }
1323         }
1324         return (0);
1325 }
1326
1327 /***************************************************************************/
1328 int tulip_main(HCS * pCurHcb)
1329 {
1330         SCB *pCurScb;
1331
1332         for (;;) {
1333
1334                 tulip_scsi(pCurHcb);    /* Call tulip_scsi              */
1335
1336                 while ((pCurScb = tul_find_done_scb(pCurHcb)) != NULL) {        /* find done entry */
1337                         if (pCurScb->SCB_TaStat == INI_QUEUE_FULL) {
1338                                 pCurHcb->HCS_MaxTags[pCurScb->SCB_Target] =
1339                                     pCurHcb->HCS_ActTags[pCurScb->SCB_Target] - 1;
1340                                 pCurScb->SCB_TaStat = 0;
1341                                 tul_append_pend_scb(pCurHcb, pCurScb);
1342                                 continue;
1343                         }
1344                         if (!(pCurScb->SCB_Mode & SCM_RSENS)) {         /* not in auto req. sense mode */
1345                                 if (pCurScb->SCB_TaStat == 2) {
1346
1347                                         /* clr sync. nego flag */
1348
1349                                         if (pCurScb->SCB_Flags & SCF_SENSE) {
1350                                                 BYTE len;
1351                                                 len = pCurScb->SCB_SenseLen;
1352                                                 if (len == 0)
1353                                                         len = 1;
1354                                                 pCurScb->SCB_BufLen = pCurScb->SCB_SenseLen;
1355                                                 pCurScb->SCB_BufPtr = pCurScb->SCB_SensePtr;
1356                                                 pCurScb->SCB_Flags &= ~(SCF_SG | SCF_DIR);      /* for xfer_data_in */
1357 /*                      pCurScb->SCB_Flags |= SCF_NO_DCHK;      */
1358                                                 /* so, we won't report worng direction in xfer_data_in,
1359                                                    and won't report HOST_DO_DU in state_6 */
1360                                                 pCurScb->SCB_Mode = SCM_RSENS;
1361                                                 pCurScb->SCB_Ident &= 0xBF;     /* Disable Disconnect */
1362                                                 pCurScb->SCB_TagMsg = 0;
1363                                                 pCurScb->SCB_TaStat = 0;
1364                                                 pCurScb->SCB_CDBLen = 6;
1365                                                 pCurScb->SCB_CDB[0] = SCSICMD_RequestSense;
1366                                                 pCurScb->SCB_CDB[1] = 0;
1367                                                 pCurScb->SCB_CDB[2] = 0;
1368                                                 pCurScb->SCB_CDB[3] = 0;
1369                                                 pCurScb->SCB_CDB[4] = len;
1370                                                 pCurScb->SCB_CDB[5] = 0;
1371                                                 tul_push_pend_scb(pCurHcb, pCurScb);
1372                                                 break;
1373                                         }
1374                                 }
1375                         } else {        /* in request sense mode */
1376
1377                                 if (pCurScb->SCB_TaStat == 2) {         /* check contition status again after sending
1378                                                                            requset sense cmd 0x3 */
1379                                         pCurScb->SCB_HaStat = HOST_BAD_PHAS;
1380                                 }
1381                                 pCurScb->SCB_TaStat = 2;
1382                         }
1383                         pCurScb->SCB_Flags |= SCF_DONE;
1384                         if (pCurScb->SCB_Flags & SCF_POST) {
1385                                 (*pCurScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pCurScb);
1386                         }
1387                 }               /* while */
1388
1389                 /* find_active: */
1390                 if (TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0) & TSS_INT_PENDING)
1391                         continue;
1392
1393                 if (pCurHcb->HCS_ActScb) {      /* return to OS and wait for xfer_done_ISR/Selected_ISR */
1394                         return 1;       /* return to OS, enable interrupt */
1395                 }
1396                 /* Check pending SCB            */
1397                 if (tul_find_first_pend_scb(pCurHcb) == NULL) {
1398                         return 1;       /* return to OS, enable interrupt */
1399                 }
1400         }                       /* End of for loop */
1401         /* statement won't reach here */
1402 }
1403
1404
1405
1406
1407 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
1408 /***************************************************************************/
1409 /***************************************************************************/
1410 /***************************************************************************/
1411 /***************************************************************************/
1412
1413 /***************************************************************************/
1414 void tulip_scsi(HCS * pCurHcb)
1415 {
1416         SCB *pCurScb;
1417         TCS *pCurTcb;
1418
1419         /* make sure to service interrupt asap */
1420
1421         if ((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0)) & TSS_INT_PENDING) {
1422
1423                 pCurHcb->HCS_Phase = pCurHcb->HCS_JSStatus0 & TSS_PH_MASK;
1424                 pCurHcb->HCS_JSStatus1 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1);
1425                 pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
1426                 if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) {     /* SCSI bus reset detected      */
1427                         int_tul_scsi_rst(pCurHcb);
1428                         return;
1429                 }
1430                 if (pCurHcb->HCS_JSInt & TSS_RESEL_INT) {       /* if selected/reselected interrupt */
1431                         if (int_tul_resel(pCurHcb) == 0)
1432                                 tul_next_state(pCurHcb);
1433                         return;
1434                 }
1435                 if (pCurHcb->HCS_JSInt & TSS_SEL_TIMEOUT) {
1436                         int_tul_busfree(pCurHcb);
1437                         return;
1438                 }
1439                 if (pCurHcb->HCS_JSInt & TSS_DISC_INT) {        /* BUS disconnection            */
1440                         int_tul_busfree(pCurHcb);       /* unexpected bus free or sel timeout */
1441                         return;
1442                 }
1443                 if (pCurHcb->HCS_JSInt & (TSS_FUNC_COMP | TSS_BUS_SERV)) {      /* func complete or Bus service */
1444                         if ((pCurScb = pCurHcb->HCS_ActScb) != NULL)
1445                                 tul_next_state(pCurHcb);
1446                         return;
1447                 }
1448         }
1449         if (pCurHcb->HCS_ActScb != NULL)
1450                 return;
1451
1452         if ((pCurScb = tul_find_first_pend_scb(pCurHcb)) == NULL)
1453                 return;
1454
1455         /* program HBA's SCSI ID & target SCSI ID */
1456         TUL_WR(pCurHcb->HCS_Base + TUL_SScsiId,
1457              (pCurHcb->HCS_SCSI_ID << 4) | (pCurScb->SCB_Target & 0x0F));
1458         if (pCurScb->SCB_Opcode == ExecSCSI) {
1459                 pCurTcb = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
1460
1461                 if (pCurScb->SCB_TagMsg)
1462                         pCurTcb->TCS_DrvFlags |= TCF_DRV_EN_TAG;
1463                 else
1464                         pCurTcb->TCS_DrvFlags &= ~TCF_DRV_EN_TAG;
1465
1466                 TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurTcb->TCS_JS_Period);
1467                 if ((pCurTcb->TCS_Flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {        /* do wdtr negotiation          */
1468                         tul_select_atn_stop(pCurHcb, pCurScb);
1469                 } else {
1470                         if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {   /* do sync negotiation          */
1471                                 tul_select_atn_stop(pCurHcb, pCurScb);
1472                         } else {
1473                                 if (pCurScb->SCB_TagMsg)
1474                                         tul_select_atn3(pCurHcb, pCurScb);
1475                                 else
1476                                         tul_select_atn(pCurHcb, pCurScb);
1477                         }
1478                 }
1479                 if (pCurScb->SCB_Flags & SCF_POLL) {
1480                         while (wait_tulip(pCurHcb) != -1) {
1481                                 if (tul_next_state(pCurHcb) == -1)
1482                                         break;
1483                         }
1484                 }
1485         } else if (pCurScb->SCB_Opcode == BusDevRst) {
1486                 tul_select_atn_stop(pCurHcb, pCurScb);
1487                 pCurScb->SCB_NxtStat = 8;
1488                 if (pCurScb->SCB_Flags & SCF_POLL) {
1489                         while (wait_tulip(pCurHcb) != -1) {
1490                                 if (tul_next_state(pCurHcb) == -1)
1491                                         break;
1492                         }
1493                 }
1494         } else if (pCurScb->SCB_Opcode == AbortCmd) {
1495                 if (tul_abort_srb(pCurHcb, pCurScb->SCB_Srb) != 0) {
1496
1497
1498                         tul_unlink_pend_scb(pCurHcb, pCurScb);
1499
1500                         tul_release_scb(pCurHcb, pCurScb);
1501                 } else {
1502                         pCurScb->SCB_Opcode = BusDevRst;
1503                         tul_select_atn_stop(pCurHcb, pCurScb);
1504                         pCurScb->SCB_NxtStat = 8;
1505                 }
1506
1507 /* 08/03/98 */
1508         } else {
1509                 tul_unlink_pend_scb(pCurHcb, pCurScb);
1510                 pCurScb->SCB_HaStat = 0x16;     /* bad command */
1511                 tul_append_done_scb(pCurHcb, pCurScb);
1512         }
1513         return;
1514 }
1515
1516
1517 /***************************************************************************/
1518 int tul_next_state(HCS * pCurHcb)
1519 {
1520         int next;
1521
1522         next = pCurHcb->HCS_ActScb->SCB_NxtStat;
1523         for (;;) {
1524                 switch (next) {
1525                 case 1:
1526                         next = tul_state_1(pCurHcb);
1527                         break;
1528                 case 2:
1529                         next = tul_state_2(pCurHcb);
1530                         break;
1531                 case 3:
1532                         next = tul_state_3(pCurHcb);
1533                         break;
1534                 case 4:
1535                         next = tul_state_4(pCurHcb);
1536                         break;
1537                 case 5:
1538                         next = tul_state_5(pCurHcb);
1539                         break;
1540                 case 6:
1541                         next = tul_state_6(pCurHcb);
1542                         break;
1543                 case 7:
1544                         next = tul_state_7(pCurHcb);
1545                         break;
1546                 case 8:
1547                         return (tul_bus_device_reset(pCurHcb));
1548                 default:
1549                         return (tul_bad_seq(pCurHcb));
1550                 }
1551                 if (next <= 0)
1552                         return next;
1553         }
1554 }
1555
1556
1557 /***************************************************************************/
1558 /* sTate after selection with attention & stop */
1559 int tul_state_1(HCS * pCurHcb)
1560 {
1561         SCB *pCurScb = pCurHcb->HCS_ActScb;
1562         TCS *pCurTcb = pCurHcb->HCS_ActTcs;
1563 #if DEBUG_STATE
1564         printk("-s1-");
1565 #endif
1566
1567         tul_unlink_pend_scb(pCurHcb, pCurScb);
1568         tul_append_busy_scb(pCurHcb, pCurScb);
1569
1570         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0);
1571         /* ATN on */
1572         if (pCurHcb->HCS_Phase == MSG_OUT) {
1573
1574                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, (TSC_EN_BUS_IN | TSC_HW_RESELECT));
1575
1576                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident);
1577
1578                 if (pCurScb->SCB_TagMsg) {
1579                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagMsg);
1580                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagId);
1581                 }
1582                 if ((pCurTcb->TCS_Flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {
1583
1584                         pCurTcb->TCS_Flags |= TCF_WDTR_DONE;
1585
1586                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
1587                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 2);       /* Extended msg length */
1588                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);       /* Sync request */
1589                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1);       /* Start from 16 bits */
1590                 } else if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {
1591
1592                         pCurTcb->TCS_Flags |= TCF_SYNC_DONE;
1593
1594                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
1595                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);       /* extended msg length */
1596                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1);       /* sync request */
1597                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, tul_rate_tbl[pCurTcb->TCS_Flags & TCF_SCSI_RATE]);
1598                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MAX_OFFSET);      /* REQ/ACK offset */
1599                 }
1600                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1601                 if (wait_tulip(pCurHcb) == -1)
1602                         return (-1);
1603         }
1604         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
1605         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)));
1606         return (3);
1607 }
1608
1609
1610 /***************************************************************************/
1611 /* state after selection with attention */
1612 /* state after selection with attention3 */
1613 int tul_state_2(HCS * pCurHcb)
1614 {
1615         SCB *pCurScb = pCurHcb->HCS_ActScb;
1616         TCS *pCurTcb = pCurHcb->HCS_ActTcs;
1617 #if DEBUG_STATE
1618         printk("-s2-");
1619 #endif
1620
1621         tul_unlink_pend_scb(pCurHcb, pCurScb);
1622         tul_append_busy_scb(pCurHcb, pCurScb);
1623
1624         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0);
1625
1626         if (pCurHcb->HCS_JSStatus1 & TSS_CMD_PH_CMP) {
1627                 return (4);
1628         }
1629         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
1630         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)));
1631         return (3);
1632 }
1633
1634 /***************************************************************************/
1635 /* state before CDB xfer is done */
1636 int tul_state_3(HCS * pCurHcb)
1637 {
1638         SCB *pCurScb = pCurHcb->HCS_ActScb;
1639         TCS *pCurTcb = pCurHcb->HCS_ActTcs;
1640         int i;
1641
1642 #if DEBUG_STATE
1643         printk("-s3-");
1644 #endif
1645         for (;;) {
1646                 switch (pCurHcb->HCS_Phase) {
1647                 case CMD_OUT:   /* Command out phase            */
1648                         for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++)
1649                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]);
1650                         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1651                         if (wait_tulip(pCurHcb) == -1)
1652                                 return (-1);
1653                         if (pCurHcb->HCS_Phase == CMD_OUT) {
1654                                 return (tul_bad_seq(pCurHcb));
1655                         }
1656                         return (4);
1657
1658                 case MSG_IN:    /* Message in phase             */
1659                         pCurScb->SCB_NxtStat = 3;
1660                         if (tul_msgin(pCurHcb) == -1)
1661                                 return (-1);
1662                         break;
1663
1664                 case STATUS_IN: /* Status phase                 */
1665                         if (tul_status_msg(pCurHcb) == -1)
1666                                 return (-1);
1667                         break;
1668
1669                 case MSG_OUT:   /* Message out phase            */
1670                         if (pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) {
1671
1672                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP);         /* msg nop */
1673                                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1674                                 if (wait_tulip(pCurHcb) == -1)
1675                                         return (-1);
1676
1677                         } else {
1678                                 pCurTcb->TCS_Flags |= TCF_SYNC_DONE;
1679
1680                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
1681                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);       /* ext. msg len */
1682                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1);       /* sync request */
1683                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, tul_rate_tbl[pCurTcb->TCS_Flags & TCF_SCSI_RATE]);
1684                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MAX_OFFSET);      /* REQ/ACK offset */
1685                                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1686                                 if (wait_tulip(pCurHcb) == -1)
1687                                         return (-1);
1688                                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
1689                                 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7));
1690
1691                         }
1692                         break;
1693
1694                 default:
1695                         return (tul_bad_seq(pCurHcb));
1696                 }
1697         }
1698 }
1699
1700
1701 /***************************************************************************/
1702 int tul_state_4(HCS * pCurHcb)
1703 {
1704         SCB *pCurScb = pCurHcb->HCS_ActScb;
1705
1706 #if DEBUG_STATE
1707         printk("-s4-");
1708 #endif
1709         if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_NO_XF) {
1710                 return (6);     /* Go to state 6                */
1711         }
1712         for (;;) {
1713                 if (pCurScb->SCB_BufLen == 0)
1714                         return (6);     /* Go to state 6                */
1715
1716                 switch (pCurHcb->HCS_Phase) {
1717
1718                 case STATUS_IN: /* Status phase                 */
1719                         if ((pCurScb->SCB_Flags & SCF_DIR) != 0) {      /* if direction bit set then report data underrun */
1720                                 pCurScb->SCB_HaStat = HOST_DO_DU;
1721                         }
1722                         if ((tul_status_msg(pCurHcb)) == -1)
1723                                 return (-1);
1724                         break;
1725
1726                 case MSG_IN:    /* Message in phase             */
1727                         pCurScb->SCB_NxtStat = 0x4;
1728                         if (tul_msgin(pCurHcb) == -1)
1729                                 return (-1);
1730                         break;
1731
1732                 case MSG_OUT:   /* Message out phase            */
1733                         if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {
1734                                 pCurScb->SCB_BufLen = 0;
1735                                 pCurScb->SCB_HaStat = HOST_DO_DU;
1736                                 if (tul_msgout_ide(pCurHcb) == -1)
1737                                         return (-1);
1738                                 return (6);     /* Go to state 6                */
1739                         } else {
1740                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP);         /* msg nop */
1741                                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1742                                 if (wait_tulip(pCurHcb) == -1)
1743                                         return (-1);
1744                         }
1745                         break;
1746
1747                 case DATA_IN:   /* Data in phase                */
1748                         return (tul_xfer_data_in(pCurHcb));
1749
1750                 case DATA_OUT:  /* Data out phase               */
1751                         return (tul_xfer_data_out(pCurHcb));
1752
1753                 default:
1754                         return (tul_bad_seq(pCurHcb));
1755                 }
1756         }
1757 }
1758
1759
1760 /***************************************************************************/
1761 /* state after dma xfer done or phase change before xfer done */
1762 int tul_state_5(HCS * pCurHcb)
1763 {
1764         SCB *pCurScb = pCurHcb->HCS_ActScb;
1765         long cnt, xcnt;         /* cannot use unsigned !! code: if (xcnt < 0) */
1766
1767 #if DEBUG_STATE
1768         printk("-s5-");
1769 #endif
1770 /*------ get remaining count -------*/
1771
1772         cnt = TUL_RDLONG(pCurHcb->HCS_Base, TUL_SCnt0) & 0x0FFFFFF;
1773
1774         if (TUL_RD(pCurHcb->HCS_Base, TUL_XCmd) & 0x20) {
1775                 /* ----------------------- DATA_IN ----------------------------- */
1776                 /* check scsi parity error */
1777                 if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {
1778                         pCurScb->SCB_HaStat = HOST_DO_DU;
1779                 }
1780                 if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) {   /* DMA xfer pending, Send STOP  */
1781                         /* tell Hardware  scsi xfer has been terminated */
1782                         TUL_WR(pCurHcb->HCS_Base + TUL_XCtrl, TUL_RD(pCurHcb->HCS_Base, TUL_XCtrl) | 0x80);
1783                         /* wait until DMA xfer not pending */
1784                         while (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND);
1785                 }
1786         } else {
1787 /*-------- DATA OUT -----------*/
1788                 if ((TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1) & TSS_XFER_CMP) == 0) {
1789                         if (pCurHcb->HCS_ActTcs->TCS_JS_Period & TSC_WIDE_SCSI)
1790                                 cnt += (TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F) << 1;
1791                         else
1792                                 cnt += (TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F);
1793                 }
1794                 if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) {   /* if DMA xfer is pending, abort DMA xfer */
1795                         TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT);
1796                         /* wait Abort DMA xfer done */
1797                         while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & XABT) == 0);
1798                 }
1799                 if ((cnt == 1) && (pCurHcb->HCS_Phase == DATA_OUT)) {
1800                         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1801                         if (wait_tulip(pCurHcb) == -1) {
1802                                 return (-1);
1803                         }
1804                         cnt = 0;
1805                 } else {
1806                         if ((TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1) & TSS_XFER_CMP) == 0)
1807                                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
1808                 }
1809         }
1810
1811         if (cnt == 0) {
1812                 pCurScb->SCB_BufLen = 0;
1813                 return (6);     /* Go to state 6                */
1814         }
1815         /* Update active data pointer */
1816         xcnt = (long) pCurScb->SCB_BufLen - cnt;        /* xcnt== bytes already xferred */
1817         pCurScb->SCB_BufLen = (U32) cnt;        /* cnt == bytes left to be xferred */
1818         if (pCurScb->SCB_Flags & SCF_SG) {
1819                 register SG *sgp;
1820                 ULONG i;
1821
1822                 sgp = &pCurScb->SCB_SGList[pCurScb->SCB_SGIdx];
1823                 for (i = pCurScb->SCB_SGIdx; i < pCurScb->SCB_SGMax; sgp++, i++) {
1824                         xcnt -= (long) sgp->SG_Len;
1825                         if (xcnt < 0) {         /* this sgp xfer half done */
1826                                 xcnt += (long) sgp->SG_Len;     /* xcnt == bytes xferred in this sgp */
1827                                 sgp->SG_Ptr += (U32) xcnt;      /* new ptr to be xfer */
1828                                 sgp->SG_Len -= (U32) xcnt;      /* new len to be xfer */
1829                                 pCurScb->SCB_BufPtr += ((U32) (i - pCurScb->SCB_SGIdx) << 3);
1830                                 /* new SG table ptr */
1831                                 pCurScb->SCB_SGLen = (BYTE) (pCurScb->SCB_SGMax - i);
1832                                 /* new SG table len */
1833                                 pCurScb->SCB_SGIdx = (WORD) i;
1834                                 /* for next disc and come in this loop */
1835                                 return (4);     /* Go to state 4                */
1836                         }
1837                         /* else (xcnt >= 0 , i.e. this sgp already xferred */
1838                 }               /* for */
1839                 return (6);     /* Go to state 6                */
1840         } else {
1841                 pCurScb->SCB_BufPtr += (U32) xcnt;
1842         }
1843         return (4);             /* Go to state 4                */
1844 }
1845
1846 /***************************************************************************/
1847 /* state after Data phase */
1848 int tul_state_6(HCS * pCurHcb)
1849 {
1850         SCB *pCurScb = pCurHcb->HCS_ActScb;
1851
1852 #if DEBUG_STATE
1853         printk("-s6-");
1854 #endif
1855         for (;;) {
1856                 switch (pCurHcb->HCS_Phase) {
1857                 case STATUS_IN: /* Status phase                 */
1858                         if ((tul_status_msg(pCurHcb)) == -1)
1859                                 return (-1);
1860                         break;
1861
1862                 case MSG_IN:    /* Message in phase             */
1863                         pCurScb->SCB_NxtStat = 6;
1864                         if ((tul_msgin(pCurHcb)) == -1)
1865                                 return (-1);
1866                         break;
1867
1868                 case MSG_OUT:   /* Message out phase            */
1869                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP);         /* msg nop */
1870                         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1871                         if (wait_tulip(pCurHcb) == -1)
1872                                 return (-1);
1873                         break;
1874
1875                 case DATA_IN:   /* Data in phase                */
1876                         return (tul_xpad_in(pCurHcb));
1877
1878                 case DATA_OUT:  /* Data out phase               */
1879                         return (tul_xpad_out(pCurHcb));
1880
1881                 default:
1882                         return (tul_bad_seq(pCurHcb));
1883                 }
1884         }
1885 }
1886
1887 /***************************************************************************/
1888 int tul_state_7(HCS * pCurHcb)
1889 {
1890         int cnt, i;
1891
1892 #if DEBUG_STATE
1893         printk("-s7-");
1894 #endif
1895         /* flush SCSI FIFO */
1896         cnt = TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F;
1897         if (cnt) {
1898                 for (i = 0; i < cnt; i++)
1899                         TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
1900         }
1901         switch (pCurHcb->HCS_Phase) {
1902         case DATA_IN:           /* Data in phase                */
1903         case DATA_OUT:          /* Data out phase               */
1904                 return (tul_bad_seq(pCurHcb));
1905         default:
1906                 return (6);     /* Go to state 6                */
1907         }
1908 }
1909
1910 /***************************************************************************/
1911 int tul_xfer_data_in(HCS * pCurHcb)
1912 {
1913         SCB *pCurScb = pCurHcb->HCS_ActScb;
1914
1915         if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_DOUT) {
1916                 return (6);     /* wrong direction */
1917         }
1918         TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, pCurScb->SCB_BufLen);
1919
1920         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_DMA_IN);    /* 7/25/95 */
1921
1922         if (pCurScb->SCB_Flags & SCF_SG) {      /* S/G xfer */
1923                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, ((ULONG) pCurScb->SCB_SGLen) << 3);
1924                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
1925                 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_SG_IN);
1926         } else {
1927                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, pCurScb->SCB_BufLen);
1928                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
1929                 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_IN);
1930         }
1931         pCurScb->SCB_NxtStat = 0x5;
1932         return (0);             /* return to OS, wait xfer done , let jas_isr come in */
1933 }
1934
1935
1936 /***************************************************************************/
1937 int tul_xfer_data_out(HCS * pCurHcb)
1938 {
1939         SCB *pCurScb = pCurHcb->HCS_ActScb;
1940
1941         if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_DIN) {
1942                 return (6);     /* wrong direction */
1943         }
1944         TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, pCurScb->SCB_BufLen);
1945         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_DMA_OUT);
1946
1947         if (pCurScb->SCB_Flags & SCF_SG) {      /* S/G xfer */
1948                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, ((ULONG) pCurScb->SCB_SGLen) << 3);
1949                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
1950                 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_SG_OUT);
1951         } else {
1952                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, pCurScb->SCB_BufLen);
1953                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
1954                 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_OUT);
1955         }
1956
1957         pCurScb->SCB_NxtStat = 0x5;
1958         return (0);             /* return to OS, wait xfer done , let jas_isr come in */
1959 }
1960
1961
1962 /***************************************************************************/
1963 int tul_xpad_in(HCS * pCurHcb)
1964 {
1965         SCB *pCurScb = pCurHcb->HCS_ActScb;
1966         TCS *pCurTcb = pCurHcb->HCS_ActTcs;
1967
1968         if ((pCurScb->SCB_Flags & SCF_DIR) != SCF_NO_DCHK) {
1969                 pCurScb->SCB_HaStat = HOST_DO_DU;       /* over run             */
1970         }
1971         for (;;) {
1972                 if (pCurTcb->TCS_JS_Period & TSC_WIDE_SCSI)
1973                         TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 2);
1974                 else
1975                         TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
1976
1977                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
1978                 if ((wait_tulip(pCurHcb)) == -1) {
1979                         return (-1);
1980                 }
1981                 if (pCurHcb->HCS_Phase != DATA_IN) {
1982                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
1983                         return (6);
1984                 }
1985                 TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
1986         }
1987 }
1988
1989 int tul_xpad_out(HCS * pCurHcb)
1990 {
1991         SCB *pCurScb = pCurHcb->HCS_ActScb;
1992         TCS *pCurTcb = pCurHcb->HCS_ActTcs;
1993
1994         if ((pCurScb->SCB_Flags & SCF_DIR) != SCF_NO_DCHK) {
1995                 pCurScb->SCB_HaStat = HOST_DO_DU;       /* over run             */
1996         }
1997         for (;;) {
1998                 if (pCurTcb->TCS_JS_Period & TSC_WIDE_SCSI)
1999                         TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 2);
2000                 else
2001                         TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
2002
2003                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 0);
2004                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2005                 if ((wait_tulip(pCurHcb)) == -1) {
2006                         return (-1);
2007                 }
2008                 if (pCurHcb->HCS_Phase != DATA_OUT) {   /* Disable wide CPU to allow read 16 bits */
2009                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);
2010                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
2011                         return (6);
2012                 }
2013         }
2014 }
2015
2016
2017 /***************************************************************************/
2018 int tul_status_msg(HCS * pCurHcb)
2019 {                               /* status & MSG_IN */
2020         SCB *pCurScb = pCurHcb->HCS_ActScb;
2021         BYTE msg;
2022
2023         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_CMD_COMP);
2024         if ((wait_tulip(pCurHcb)) == -1) {
2025                 return (-1);
2026         }
2027         /* get status */
2028         pCurScb->SCB_TaStat = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
2029
2030         if (pCurHcb->HCS_Phase == MSG_OUT) {
2031                 if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {
2032                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_PARITY);
2033                 } else {
2034                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP);
2035                 }
2036                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2037                 return (wait_tulip(pCurHcb));
2038         }
2039         if (pCurHcb->HCS_Phase == MSG_IN) {
2040                 msg = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
2041                 if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {   /* Parity error                 */
2042                         if ((tul_msgin_accept(pCurHcb)) == -1)
2043                                 return (-1);
2044                         if (pCurHcb->HCS_Phase != MSG_OUT)
2045                                 return (tul_bad_seq(pCurHcb));
2046                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_PARITY);
2047                         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2048                         return (wait_tulip(pCurHcb));
2049                 }
2050                 if (msg == 0) { /* Command complete             */
2051
2052                         if ((pCurScb->SCB_TaStat & 0x18) == 0x10) {     /* No link support              */
2053                                 return (tul_bad_seq(pCurHcb));
2054                         }
2055                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
2056                         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
2057                         return tul_wait_done_disc(pCurHcb);
2058
2059                 }
2060                 if ((msg == MSG_LINK_COMP) || (msg == MSG_LINK_FLAG)) {
2061                         if ((pCurScb->SCB_TaStat & 0x18) == 0x10)
2062                                 return (tul_msgin_accept(pCurHcb));
2063                 }
2064         }
2065         return (tul_bad_seq(pCurHcb));
2066 }
2067
2068
2069 /***************************************************************************/
2070 /* scsi bus free */
2071 int int_tul_busfree(HCS * pCurHcb)
2072 {
2073         SCB *pCurScb = pCurHcb->HCS_ActScb;
2074
2075         if (pCurScb != NULL) {
2076                 if (pCurScb->SCB_Status & SCB_SELECT) {         /* selection timeout */
2077                         tul_unlink_pend_scb(pCurHcb, pCurScb);
2078                         pCurScb->SCB_HaStat = HOST_SEL_TOUT;
2079                         tul_append_done_scb(pCurHcb, pCurScb);
2080                 } else {        /* Unexpected bus free          */
2081                         tul_unlink_busy_scb(pCurHcb, pCurScb);
2082                         pCurScb->SCB_HaStat = HOST_BUS_FREE;
2083                         tul_append_done_scb(pCurHcb, pCurScb);
2084                 }
2085                 pCurHcb->HCS_ActScb = NULL;
2086                 pCurHcb->HCS_ActTcs = NULL;
2087         }
2088         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
2089         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
2090         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
2091         return (-1);
2092 }
2093
2094
2095 /***************************************************************************/
2096 /* scsi bus reset */
2097 static int int_tul_scsi_rst(HCS * pCurHcb)
2098 {
2099         SCB *pCurScb;
2100         int i;
2101
2102         /* if DMA xfer is pending, abort DMA xfer */
2103         if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & 0x01) {
2104                 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT | TAX_X_CLR_FIFO);
2105                 /* wait Abort DMA xfer done */
2106                 while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & 0x04) == 0);
2107                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
2108         }
2109         /* Abort all active & disconnected scb */
2110         while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) {
2111                 pCurScb->SCB_HaStat = HOST_BAD_PHAS;
2112                 tul_append_done_scb(pCurHcb, pCurScb);
2113         }
2114         pCurHcb->HCS_ActScb = NULL;
2115         pCurHcb->HCS_ActTcs = NULL;
2116
2117         /* clr sync nego. done flag */
2118         for (i = 0; i < pCurHcb->HCS_MaxTar; i++) {
2119                 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
2120         }
2121         return (-1);
2122 }
2123
2124
2125 /***************************************************************************/
2126 /* scsi reselection */
2127 int int_tul_resel(HCS * pCurHcb)
2128 {
2129         SCB *pCurScb;
2130         TCS *pCurTcb;
2131         BYTE tag, msg = 0;
2132         BYTE tar, lun;
2133
2134         if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) {
2135                 if (pCurScb->SCB_Status & SCB_SELECT) {         /* if waiting for selection complete */
2136                         pCurScb->SCB_Status &= ~SCB_SELECT;
2137                 }
2138                 pCurHcb->HCS_ActScb = NULL;
2139         }
2140         /* --------- get target id---------------------- */
2141         tar = TUL_RD(pCurHcb->HCS_Base, TUL_SBusId);
2142         /* ------ get LUN from Identify message----------- */
2143         lun = TUL_RD(pCurHcb->HCS_Base, TUL_SIdent) & 0x0F;
2144         /* 07/22/98 from 0x1F -> 0x0F */
2145         pCurTcb = &pCurHcb->HCS_Tcs[tar];
2146         pCurHcb->HCS_ActTcs = pCurTcb;
2147         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0);
2148         TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurTcb->TCS_JS_Period);
2149
2150
2151         /* ------------- tag queueing ? ------------------- */
2152         if (pCurTcb->TCS_DrvFlags & TCF_DRV_EN_TAG) {
2153                 if ((tul_msgin_accept(pCurHcb)) == -1)
2154                         return (-1);
2155                 if (pCurHcb->HCS_Phase != MSG_IN)
2156                         goto no_tag;
2157                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
2158                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
2159                 if ((wait_tulip(pCurHcb)) == -1)
2160                         return (-1);
2161                 msg = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);     /* Read Tag Message    */
2162
2163                 if ((msg < MSG_STAG) || (msg > MSG_OTAG))       /* Is simple Tag      */
2164                         goto no_tag;
2165
2166                 if ((tul_msgin_accept(pCurHcb)) == -1)
2167                         return (-1);
2168
2169                 if (pCurHcb->HCS_Phase != MSG_IN)
2170                         goto no_tag;
2171
2172                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
2173                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
2174                 if ((wait_tulip(pCurHcb)) == -1)
2175                         return (-1);
2176                 tag = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);     /* Read Tag ID       */
2177                 pCurScb = pCurHcb->HCS_Scb + tag;
2178                 if ((pCurScb->SCB_Target != tar) || (pCurScb->SCB_Lun != lun)) {
2179                         return tul_msgout_abort_tag(pCurHcb);
2180                 }
2181                 if (pCurScb->SCB_Status != SCB_BUSY) {  /* 03/24/95             */
2182                         return tul_msgout_abort_tag(pCurHcb);
2183                 }
2184                 pCurHcb->HCS_ActScb = pCurScb;
2185                 if ((tul_msgin_accept(pCurHcb)) == -1)
2186                         return (-1);
2187         } else {                /* No tag               */
2188               no_tag:
2189                 if ((pCurScb = tul_find_busy_scb(pCurHcb, tar | (lun << 8))) == NULL) {
2190                         return tul_msgout_abort_targ(pCurHcb);
2191                 }
2192                 pCurHcb->HCS_ActScb = pCurScb;
2193                 if (!(pCurTcb->TCS_DrvFlags & TCF_DRV_EN_TAG)) {
2194                         if ((tul_msgin_accept(pCurHcb)) == -1)
2195                                 return (-1);
2196                 }
2197         }
2198         return 0;
2199 }
2200
2201
2202 /***************************************************************************/
2203 static int int_tul_bad_seq(HCS * pCurHcb)
2204 {                               /* target wrong phase           */
2205         SCB *pCurScb;
2206         int i;
2207
2208         tul_reset_scsi(pCurHcb, 10);
2209
2210         while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) {
2211                 pCurScb->SCB_HaStat = HOST_BAD_PHAS;
2212                 tul_append_done_scb(pCurHcb, pCurScb);
2213         }
2214         for (i = 0; i < pCurHcb->HCS_MaxTar; i++) {
2215                 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
2216         }
2217         return (-1);
2218 }
2219
2220
2221 /***************************************************************************/
2222 int tul_msgout_abort_targ(HCS * pCurHcb)
2223 {
2224
2225         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
2226         if (tul_msgin_accept(pCurHcb) == -1)
2227                 return (-1);
2228         if (pCurHcb->HCS_Phase != MSG_OUT)
2229                 return (tul_bad_seq(pCurHcb));
2230
2231         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_ABORT);
2232         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2233
2234         return tul_wait_disc(pCurHcb);
2235 }
2236
2237 /***************************************************************************/
2238 int tul_msgout_abort_tag(HCS * pCurHcb)
2239 {
2240
2241         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
2242         if (tul_msgin_accept(pCurHcb) == -1)
2243                 return (-1);
2244         if (pCurHcb->HCS_Phase != MSG_OUT)
2245                 return (tul_bad_seq(pCurHcb));
2246
2247         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_ABORT_TAG);
2248         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2249
2250         return tul_wait_disc(pCurHcb);
2251
2252 }
2253
2254 /***************************************************************************/
2255 int tul_msgin(HCS * pCurHcb)
2256 {
2257         TCS *pCurTcb;
2258
2259         for (;;) {
2260
2261                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
2262
2263                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
2264                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
2265                 if ((wait_tulip(pCurHcb)) == -1)
2266                         return (-1);
2267
2268                 switch (TUL_RD(pCurHcb->HCS_Base, TUL_SFifo)) {
2269                 case MSG_DISC:  /* Disconnect msg */
2270                         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
2271
2272                         return tul_wait_disc(pCurHcb);
2273
2274                 case MSG_SDP:
2275                 case MSG_RESTORE:
2276                 case MSG_NOP:
2277                         tul_msgin_accept(pCurHcb);
2278                         break;
2279
2280                 case MSG_REJ:   /* Clear ATN first              */
2281                         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal,
2282                                (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)));
2283                         pCurTcb = pCurHcb->HCS_ActTcs;
2284                         if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {   /* do sync nego */
2285                                 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
2286                         }
2287                         tul_msgin_accept(pCurHcb);
2288                         break;
2289
2290                 case MSG_EXTEND:        /* extended msg */
2291                         tul_msgin_extend(pCurHcb);
2292                         break;
2293
2294                 case MSG_IGNOREWIDE:
2295                         tul_msgin_accept(pCurHcb);
2296                         break;
2297
2298                         /* get */
2299                         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
2300                         if (wait_tulip(pCurHcb) == -1)
2301                                 return -1;
2302
2303                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 0);       /* put pad  */
2304                         TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);   /* get IGNORE field */
2305                         TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);   /* get pad */
2306
2307                         tul_msgin_accept(pCurHcb);
2308                         break;
2309
2310                 case MSG_COMP:
2311                         {
2312                                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
2313                                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
2314                                 return tul_wait_done_disc(pCurHcb);
2315                         }
2316                 default:
2317                         tul_msgout_reject(pCurHcb);
2318                         break;
2319                 }
2320                 if (pCurHcb->HCS_Phase != MSG_IN)
2321                         return (pCurHcb->HCS_Phase);
2322         }
2323         /* statement won't reach here */
2324 }
2325
2326
2327
2328
2329 /***************************************************************************/
2330 int tul_msgout_reject(HCS * pCurHcb)
2331 {
2332
2333         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
2334
2335         if ((tul_msgin_accept(pCurHcb)) == -1)
2336                 return (-1);
2337
2338         if (pCurHcb->HCS_Phase == MSG_OUT) {
2339                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_REJ);         /* Msg reject           */
2340                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2341                 return (wait_tulip(pCurHcb));
2342         }
2343         return (pCurHcb->HCS_Phase);
2344 }
2345
2346
2347
2348 /***************************************************************************/
2349 int tul_msgout_ide(HCS * pCurHcb)
2350 {
2351         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_IDE);         /* Initiator Detected Error */
2352         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2353         return (wait_tulip(pCurHcb));
2354 }
2355
2356
2357 /***************************************************************************/
2358 int tul_msgin_extend(HCS * pCurHcb)
2359 {
2360         BYTE len, idx;
2361
2362         if (tul_msgin_accept(pCurHcb) != MSG_IN)
2363                 return (pCurHcb->HCS_Phase);
2364
2365         /* Get extended msg length      */
2366         TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
2367         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
2368         if (wait_tulip(pCurHcb) == -1)
2369                 return (-1);
2370
2371         len = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
2372         pCurHcb->HCS_Msg[0] = len;
2373         for (idx = 1; len != 0; len--) {
2374
2375                 if ((tul_msgin_accept(pCurHcb)) != MSG_IN)
2376                         return (pCurHcb->HCS_Phase);
2377                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
2378                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
2379                 if (wait_tulip(pCurHcb) == -1)
2380                         return (-1);
2381                 pCurHcb->HCS_Msg[idx++] = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
2382         }
2383         if (pCurHcb->HCS_Msg[1] == 1) {         /* if it's synchronous data transfer request */
2384                 if (pCurHcb->HCS_Msg[0] != 3)   /* if length is not right */
2385                         return (tul_msgout_reject(pCurHcb));
2386                 if (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_SYNC_NEGO) {        /* Set OFFSET=0 to do async, nego back */
2387                         pCurHcb->HCS_Msg[3] = 0;
2388                 } else {
2389                         if ((tul_msgin_sync(pCurHcb) == 0) &&
2390                             (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_SYNC_DONE)) {
2391                                 tul_sync_done(pCurHcb);
2392                                 return (tul_msgin_accept(pCurHcb));
2393                         }
2394                 }
2395
2396                 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
2397                 if ((tul_msgin_accept(pCurHcb)) != MSG_OUT)
2398                         return (pCurHcb->HCS_Phase);
2399                 /* sync msg out */
2400                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
2401
2402                 tul_sync_done(pCurHcb);
2403
2404                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
2405                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);
2406                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1);
2407                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[2]);
2408                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[3]);
2409
2410                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2411                 return (wait_tulip(pCurHcb));
2412         }
2413         if ((pCurHcb->HCS_Msg[0] != 2) || (pCurHcb->HCS_Msg[1] != 3))
2414                 return (tul_msgout_reject(pCurHcb));
2415         /* if it's WIDE DATA XFER REQ   */
2416         if (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_WDTR) {
2417                 pCurHcb->HCS_Msg[2] = 0;
2418         } else {
2419                 if (pCurHcb->HCS_Msg[2] > 2)    /* > 32 bits            */
2420                         return (tul_msgout_reject(pCurHcb));
2421                 if (pCurHcb->HCS_Msg[2] == 2) {         /* == 32                */
2422                         pCurHcb->HCS_Msg[2] = 1;
2423                 } else {
2424                         if ((pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_WDTR) == 0) {
2425                                 wdtr_done(pCurHcb);
2426                                 if ((pCurHcb->HCS_ActTcs->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0)
2427                                         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
2428                                 return (tul_msgin_accept(pCurHcb));
2429                         }
2430                 }
2431         }
2432         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
2433
2434         if (tul_msgin_accept(pCurHcb) != MSG_OUT)
2435                 return (pCurHcb->HCS_Phase);
2436         /* WDTR msg out                 */
2437         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
2438         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 2);
2439         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);
2440         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[2]);
2441         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2442         return (wait_tulip(pCurHcb));
2443 }
2444
2445 /***************************************************************************/
2446 int tul_msgin_sync(HCS * pCurHcb)
2447 {
2448         char default_period;
2449
2450         default_period = tul_rate_tbl[pCurHcb->HCS_ActTcs->TCS_Flags & TCF_SCSI_RATE];
2451         if (pCurHcb->HCS_Msg[3] > MAX_OFFSET) {
2452                 pCurHcb->HCS_Msg[3] = MAX_OFFSET;
2453                 if (pCurHcb->HCS_Msg[2] < default_period) {
2454                         pCurHcb->HCS_Msg[2] = default_period;
2455                         return 1;
2456                 }
2457                 if (pCurHcb->HCS_Msg[2] >= 59) {        /* Change to async              */
2458                         pCurHcb->HCS_Msg[3] = 0;
2459                 }
2460                 return 1;
2461         }
2462         /* offset requests asynchronous transfers ? */
2463         if (pCurHcb->HCS_Msg[3] == 0) {
2464                 return 0;
2465         }
2466         if (pCurHcb->HCS_Msg[2] < default_period) {
2467                 pCurHcb->HCS_Msg[2] = default_period;
2468                 return 1;
2469         }
2470         if (pCurHcb->HCS_Msg[2] >= 59) {
2471                 pCurHcb->HCS_Msg[3] = 0;
2472                 return 1;
2473         }
2474         return 0;
2475 }
2476
2477
2478 /***************************************************************************/
2479 int wdtr_done(HCS * pCurHcb)
2480 {
2481         pCurHcb->HCS_ActTcs->TCS_Flags &= ~TCF_SYNC_DONE;
2482         pCurHcb->HCS_ActTcs->TCS_Flags |= TCF_WDTR_DONE;
2483
2484         pCurHcb->HCS_ActTcs->TCS_JS_Period = 0;
2485         if (pCurHcb->HCS_Msg[2]) {      /* if 16 bit */
2486                 pCurHcb->HCS_ActTcs->TCS_JS_Period |= TSC_WIDE_SCSI;
2487         }
2488         pCurHcb->HCS_ActTcs->TCS_SConfig0 &= ~TSC_ALT_PERIOD;
2489         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_ActTcs->TCS_SConfig0);
2490         TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurHcb->HCS_ActTcs->TCS_JS_Period);
2491
2492         return 1;
2493 }
2494
2495 /***************************************************************************/
2496 int tul_sync_done(HCS * pCurHcb)
2497 {
2498         int i;
2499
2500         pCurHcb->HCS_ActTcs->TCS_Flags |= TCF_SYNC_DONE;
2501
2502         if (pCurHcb->HCS_Msg[3]) {
2503                 pCurHcb->HCS_ActTcs->TCS_JS_Period |= pCurHcb->HCS_Msg[3];
2504                 for (i = 0; i < 8; i++) {
2505                         if (tul_rate_tbl[i] >= pCurHcb->HCS_Msg[2])     /* pick the big one */
2506                                 break;
2507                 }
2508                 pCurHcb->HCS_ActTcs->TCS_JS_Period |= (i << 4);
2509                 pCurHcb->HCS_ActTcs->TCS_SConfig0 |= TSC_ALT_PERIOD;
2510         }
2511         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_ActTcs->TCS_SConfig0);
2512         TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurHcb->HCS_ActTcs->TCS_JS_Period);
2513
2514         return (-1);
2515 }
2516
2517
2518 int tul_post_scsi_rst(HCS * pCurHcb)
2519 {
2520         SCB *pCurScb;
2521         TCS *pCurTcb;
2522         int i;
2523
2524         pCurHcb->HCS_ActScb = NULL;
2525         pCurHcb->HCS_ActTcs = NULL;
2526         pCurHcb->HCS_Flags = 0;
2527
2528         while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) {
2529                 pCurScb->SCB_HaStat = HOST_BAD_PHAS;
2530                 tul_append_done_scb(pCurHcb, pCurScb);
2531         }
2532         /* clear sync done flag         */
2533         pCurTcb = &pCurHcb->HCS_Tcs[0];
2534         for (i = 0; i < pCurHcb->HCS_MaxTar; pCurTcb++, i++) {
2535                 pCurTcb->TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
2536                 /* Initialize the sync. xfer register values to an asyn xfer */
2537                 pCurTcb->TCS_JS_Period = 0;
2538                 pCurTcb->TCS_SConfig0 = pCurHcb->HCS_SConf1;
2539                 pCurHcb->HCS_ActTags[0] = 0;    /* 07/22/98 */
2540                 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~TCF_BUSY;     /* 07/22/98 */
2541         }                       /* for */
2542
2543         return (-1);
2544 }
2545
2546 /***************************************************************************/
2547 void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb)
2548 {
2549         pCurScb->SCB_Status |= SCB_SELECT;
2550         pCurScb->SCB_NxtStat = 0x1;
2551         pCurHcb->HCS_ActScb = pCurScb;
2552         pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
2553         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SELATNSTOP);
2554         return;
2555 }
2556
2557
2558 /***************************************************************************/
2559 void tul_select_atn(HCS * pCurHcb, SCB * pCurScb)
2560 {
2561         int i;
2562
2563         pCurScb->SCB_Status |= SCB_SELECT;
2564         pCurScb->SCB_NxtStat = 0x2;
2565
2566         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident);
2567         for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++)
2568                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]);
2569         pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
2570         pCurHcb->HCS_ActScb = pCurScb;
2571         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SEL_ATN);
2572         return;
2573 }
2574
2575 /***************************************************************************/
2576 void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb)
2577 {
2578         int i;
2579
2580         pCurScb->SCB_Status |= SCB_SELECT;
2581         pCurScb->SCB_NxtStat = 0x2;
2582
2583         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident);
2584         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagMsg);
2585         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagId);
2586         for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++)
2587                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]);
2588         pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
2589         pCurHcb->HCS_ActScb = pCurScb;
2590         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SEL_ATN3);
2591         return;
2592 }
2593
2594 /***************************************************************************/
2595 /* SCSI Bus Device Reset */
2596 int tul_bus_device_reset(HCS * pCurHcb)
2597 {
2598         SCB *pCurScb = pCurHcb->HCS_ActScb;
2599         TCS *pCurTcb = pCurHcb->HCS_ActTcs;
2600         SCB *pTmpScb, *pPrevScb;
2601         BYTE tar;
2602
2603         if (pCurHcb->HCS_Phase != MSG_OUT) {
2604                 return (int_tul_bad_seq(pCurHcb));      /* Unexpected phase             */
2605         }
2606         tul_unlink_pend_scb(pCurHcb, pCurScb);
2607         tul_release_scb(pCurHcb, pCurScb);
2608
2609
2610         tar = pCurScb->SCB_Target;      /* target                       */
2611         pCurTcb->TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE | TCF_BUSY);
2612         /* clr sync. nego & WDTR flags  07/22/98 */
2613
2614         /* abort all SCB with same target */
2615         pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy;    /* Check Busy queue */
2616         while (pTmpScb != NULL) {
2617
2618                 if (pTmpScb->SCB_Target == tar) {
2619                         /* unlink it */
2620                         if (pTmpScb == pCurHcb->HCS_FirstBusy) {
2621                                 if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
2622                                         pCurHcb->HCS_LastBusy = NULL;
2623                         } else {
2624                                 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
2625                                 if (pTmpScb == pCurHcb->HCS_LastBusy)
2626                                         pCurHcb->HCS_LastBusy = pPrevScb;
2627                         }
2628                         pTmpScb->SCB_HaStat = HOST_ABORTED;
2629                         tul_append_done_scb(pCurHcb, pTmpScb);
2630                 }
2631                 /* Previous haven't change      */
2632                 else {
2633                         pPrevScb = pTmpScb;
2634                 }
2635                 pTmpScb = pTmpScb->SCB_NxtScb;
2636         }
2637
2638         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_DEVRST);
2639         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2640
2641         return tul_wait_disc(pCurHcb);
2642
2643 }
2644
2645 /***************************************************************************/
2646 int tul_msgin_accept(HCS * pCurHcb)
2647 {
2648         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
2649         return (wait_tulip(pCurHcb));
2650 }
2651
2652 /***************************************************************************/
2653 int wait_tulip(HCS * pCurHcb)
2654 {
2655
2656         while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0))
2657                  & TSS_INT_PENDING));
2658
2659         pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
2660         pCurHcb->HCS_Phase = pCurHcb->HCS_JSStatus0 & TSS_PH_MASK;
2661         pCurHcb->HCS_JSStatus1 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1);
2662
2663         if (pCurHcb->HCS_JSInt & TSS_RESEL_INT) {       /* if SCSI bus reset detected   */
2664                 return (int_tul_resel(pCurHcb));
2665         }
2666         if (pCurHcb->HCS_JSInt & TSS_SEL_TIMEOUT) {     /* if selected/reselected timeout interrupt */
2667                 return (int_tul_busfree(pCurHcb));
2668         }
2669         if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) {     /* if SCSI bus reset detected   */
2670                 return (int_tul_scsi_rst(pCurHcb));
2671         }
2672         if (pCurHcb->HCS_JSInt & TSS_DISC_INT) {        /* BUS disconnection            */
2673                 if (pCurHcb->HCS_Flags & HCF_EXPECT_DONE_DISC) {
2674                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
2675                         tul_unlink_busy_scb(pCurHcb, pCurHcb->HCS_ActScb);
2676                         pCurHcb->HCS_ActScb->SCB_HaStat = 0;
2677                         tul_append_done_scb(pCurHcb, pCurHcb->HCS_ActScb);
2678                         pCurHcb->HCS_ActScb = NULL;
2679                         pCurHcb->HCS_ActTcs = NULL;
2680                         pCurHcb->HCS_Flags &= ~HCF_EXPECT_DONE_DISC;
2681                         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
2682                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
2683                         return (-1);
2684                 }
2685                 if (pCurHcb->HCS_Flags & HCF_EXPECT_DISC) {
2686                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
2687                         pCurHcb->HCS_ActScb = NULL;
2688                         pCurHcb->HCS_ActTcs = NULL;
2689                         pCurHcb->HCS_Flags &= ~HCF_EXPECT_DISC;
2690                         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
2691                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
2692                         return (-1);
2693                 }
2694                 return (int_tul_busfree(pCurHcb));
2695         }
2696         if (pCurHcb->HCS_JSInt & (TSS_FUNC_COMP | TSS_BUS_SERV)) {
2697                 return (pCurHcb->HCS_Phase);
2698         }
2699         return (pCurHcb->HCS_Phase);
2700 }
2701 /***************************************************************************/
2702 int tul_wait_disc(HCS * pCurHcb)
2703 {
2704
2705         while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0))
2706                  & TSS_INT_PENDING));
2707
2708
2709         pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
2710
2711         if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) {     /* if SCSI bus reset detected   */
2712                 return (int_tul_scsi_rst(pCurHcb));
2713         }
2714         if (pCurHcb->HCS_JSInt & TSS_DISC_INT) {        /* BUS disconnection            */
2715                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
2716                 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
2717                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
2718                 pCurHcb->HCS_ActScb = NULL;
2719                 return (-1);
2720         }
2721         return (tul_bad_seq(pCurHcb));
2722 }
2723
2724 /***************************************************************************/
2725 int tul_wait_done_disc(HCS * pCurHcb)
2726 {
2727
2728
2729         while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0))
2730                  & TSS_INT_PENDING));
2731
2732         pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
2733
2734
2735         if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) {     /* if SCSI bus reset detected   */
2736                 return (int_tul_scsi_rst(pCurHcb));
2737         }
2738         if (pCurHcb->HCS_JSInt & TSS_DISC_INT) {        /* BUS disconnection            */
2739                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
2740                 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
2741                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
2742                 tul_unlink_busy_scb(pCurHcb, pCurHcb->HCS_ActScb);
2743
2744                 tul_append_done_scb(pCurHcb, pCurHcb->HCS_ActScb);
2745                 pCurHcb->HCS_ActScb = NULL;
2746                 return (-1);
2747         }
2748         return (tul_bad_seq(pCurHcb));
2749 }
2750
2751 static irqreturn_t i91u_intr(int irqno, void *dev_id)
2752 {
2753         struct Scsi_Host *dev = dev_id;
2754         unsigned long flags;
2755         
2756         spin_lock_irqsave(dev->host_lock, flags);
2757         tul_isr((HCS *)dev->base);
2758         spin_unlock_irqrestore(dev->host_lock, flags);
2759         return IRQ_HANDLED;
2760 }
2761
2762 static int tul_NewReturnNumberOfAdapters(void)
2763 {
2764         struct pci_dev *pDev = NULL;    /* Start from none              */
2765         int iAdapters = 0;
2766         long dRegValue;
2767         WORD wBIOS;
2768         int i = 0;
2769
2770         init_i91uAdapter_table();
2771
2772         for (i = 0; i < ARRAY_SIZE(i91u_pci_devices); i++)
2773         {
2774                 while ((pDev = pci_find_device(i91u_pci_devices[i].vendor, i91u_pci_devices[i].device, pDev)) != NULL) {
2775                         if (pci_enable_device(pDev))
2776                                 continue;
2777                         pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue);
2778                         wBIOS = (UWORD) (dRegValue & 0xFF);
2779                         if (((dRegValue & 0xFF00) >> 8) == 0xFF)
2780                                 dRegValue = 0;
2781                         wBIOS = (wBIOS << 8) + ((UWORD) ((dRegValue & 0xFF00) >> 8));
2782                         if (pci_set_dma_mask(pDev, DMA_32BIT_MASK)) {
2783                                 printk(KERN_WARNING 
2784                                        "i91u: Could not set 32 bit DMA mask\n");
2785                                 continue;
2786                         }
2787
2788                         if (Addi91u_into_Adapter_table(wBIOS,
2789                                                         (pDev->resource[0].start),
2790                                                         pDev->irq,
2791                                                         pDev->bus->number,
2792                                                         (pDev->devfn >> 3)
2793                                 ) == 0)
2794                                 iAdapters++;
2795                 }
2796         }
2797
2798         return (iAdapters);
2799 }
2800
2801 static int i91u_detect(struct scsi_host_template * tpnt)
2802 {
2803         HCS *pHCB;
2804         struct Scsi_Host *hreg;
2805         unsigned long i;        /* 01/14/98                     */
2806         int ok = 0, iAdapters;
2807         ULONG dBiosAdr;
2808         BYTE *pbBiosAdr;
2809
2810         /* Get total number of adapters in the motherboard */
2811         iAdapters = tul_NewReturnNumberOfAdapters();
2812         if (iAdapters == 0)     /* If no tulip founded, return */
2813                 return (0);
2814
2815         tul_num_ch = (iAdapters > tul_num_ch) ? tul_num_ch : iAdapters;
2816         /* Update actually channel number */
2817         if (tul_tag_enable) {   /* 1.01i                  */
2818                 tul_num_scb = MAX_TARGETS * i91u_MAXQUEUE;
2819         } else {
2820                 tul_num_scb = MAX_TARGETS + 3;  /* 1-tape, 1-CD_ROM, 1- extra */
2821         }                       /* Update actually SCBs per adapter */
2822
2823         /* Get total memory needed for HCS */
2824         i = tul_num_ch * sizeof(HCS);
2825         memset((unsigned char *) &tul_hcs[0], 0, i);    /* Initialize tul_hcs 0 */
2826         /* Get total memory needed for SCB */
2827
2828         for (; tul_num_scb >= MAX_TARGETS + 3; tul_num_scb--) {
2829                 i = tul_num_ch * tul_num_scb * sizeof(SCB);
2830                 if ((tul_scb = kmalloc(i, GFP_ATOMIC | GFP_DMA)) != NULL)
2831                         break;
2832         }
2833         if (tul_scb == NULL) {
2834                 printk("i91u: SCB memory allocation error\n");
2835                 return (0);
2836         }
2837         memset((unsigned char *) tul_scb, 0, i);
2838
2839         for (i = 0, pHCB = &tul_hcs[0];         /* Get pointer for control block */
2840              i < tul_num_ch;
2841              i++, pHCB++) {
2842                 get_tulipPCIConfig(pHCB, i);
2843
2844                 dBiosAdr = pHCB->HCS_BIOS;
2845                 dBiosAdr = (dBiosAdr << 4);
2846
2847                 pbBiosAdr = phys_to_virt(dBiosAdr);
2848
2849                 init_tulip(pHCB, tul_scb + (i * tul_num_scb), tul_num_scb, pbBiosAdr, 10);
2850                 request_region(pHCB->HCS_Base, 256, "i91u"); /* Register */ 
2851
2852                 pHCB->HCS_Index = i;    /* 7/29/98 */
2853                 hreg = scsi_register(tpnt, sizeof(HCS));
2854                 if(hreg == NULL) {
2855                         release_region(pHCB->HCS_Base, 256);
2856                         return 0;
2857                 }
2858                 hreg->io_port = pHCB->HCS_Base;
2859                 hreg->n_io_port = 0xff;
2860                 hreg->can_queue = tul_num_scb;  /* 03/05/98                      */
2861                 hreg->unique_id = pHCB->HCS_Base;
2862                 hreg->max_id = pHCB->HCS_MaxTar;
2863                 hreg->max_lun = 32;     /* 10/21/97                     */
2864                 hreg->irq = pHCB->HCS_Intr;
2865                 hreg->this_id = pHCB->HCS_SCSI_ID;      /* Assign HCS index           */
2866                 hreg->base = (unsigned long)pHCB;
2867                 hreg->sg_tablesize = TOTAL_SG_ENTRY;    /* Maximun support is 32 */
2868
2869                 /* Initial tulip chip           */
2870                 ok = request_irq(pHCB->HCS_Intr, i91u_intr, IRQF_DISABLED | IRQF_SHARED, "i91u", hreg);
2871                 if (ok < 0) {
2872                         printk(KERN_WARNING "i91u: unable to request IRQ %d\n\n", pHCB->HCS_Intr);
2873                         return 0;
2874                 }
2875         }
2876
2877         tpnt->this_id = -1;
2878         tpnt->can_queue = 1;
2879
2880         return 1;
2881 }
2882
2883 static void i91uBuildSCB(HCS * pHCB, SCB * pSCB, struct scsi_cmnd * SCpnt)
2884 {                               /* Create corresponding SCB     */
2885         struct scatterlist *pSrbSG;
2886         SG *pSG;                /* Pointer to SG list           */
2887         int i;
2888         long TotalLen;
2889         dma_addr_t dma_addr;
2890
2891         pSCB->SCB_Post = i91uSCBPost;   /* i91u's callback routine      */
2892         pSCB->SCB_Srb = SCpnt;
2893         pSCB->SCB_Opcode = ExecSCSI;
2894         pSCB->SCB_Flags = SCF_POST;     /* After SCSI done, call post routine */
2895         pSCB->SCB_Target = SCpnt->device->id;
2896         pSCB->SCB_Lun = SCpnt->device->lun;
2897         pSCB->SCB_Ident = SCpnt->device->lun | DISC_ALLOW;
2898
2899         pSCB->SCB_Flags |= SCF_SENSE;   /* Turn on auto request sense   */
2900         dma_addr = dma_map_single(&pHCB->pci_dev->dev, SCpnt->sense_buffer,
2901                                   SENSE_SIZE, DMA_FROM_DEVICE);
2902         pSCB->SCB_SensePtr = cpu_to_le32((u32)dma_addr);
2903         pSCB->SCB_SenseLen = cpu_to_le32(SENSE_SIZE);
2904         SCpnt->SCp.ptr = (char *)(unsigned long)dma_addr;
2905
2906         pSCB->SCB_CDBLen = SCpnt->cmd_len;
2907         pSCB->SCB_HaStat = 0;
2908         pSCB->SCB_TaStat = 0;
2909         memcpy(&pSCB->SCB_CDB[0], &SCpnt->cmnd, SCpnt->cmd_len);
2910
2911         if (SCpnt->device->tagged_supported) {  /* Tag Support                  */
2912                 pSCB->SCB_TagMsg = SIMPLE_QUEUE_TAG;    /* Do simple tag only   */
2913         } else {
2914                 pSCB->SCB_TagMsg = 0;   /* No tag support               */
2915         }
2916         /* todo handle map_sg error */
2917         if (SCpnt->use_sg) {
2918                 dma_addr = dma_map_single(&pHCB->pci_dev->dev, &pSCB->SCB_SGList[0],
2919                                           sizeof(struct SG_Struc) * TOTAL_SG_ENTRY,
2920                                           DMA_BIDIRECTIONAL);
2921                 pSCB->SCB_BufPtr = cpu_to_le32((u32)dma_addr);
2922                 SCpnt->SCp.dma_handle = dma_addr;
2923
2924                 pSrbSG = (struct scatterlist *) SCpnt->request_buffer;
2925                 pSCB->SCB_SGLen = dma_map_sg(&pHCB->pci_dev->dev, pSrbSG,
2926                                              SCpnt->use_sg, SCpnt->sc_data_direction);
2927
2928                 pSCB->SCB_Flags |= SCF_SG;      /* Turn on SG list flag       */
2929                 for (i = 0, TotalLen = 0, pSG = &pSCB->SCB_SGList[0];   /* 1.01g */
2930                      i < pSCB->SCB_SGLen; i++, pSG++, pSrbSG++) {
2931                         pSG->SG_Ptr = cpu_to_le32((u32)sg_dma_address(pSrbSG));
2932                         TotalLen += pSG->SG_Len = cpu_to_le32((u32)sg_dma_len(pSrbSG));
2933                 }
2934
2935                 pSCB->SCB_BufLen = (SCpnt->request_bufflen > TotalLen) ?
2936                     TotalLen : SCpnt->request_bufflen;
2937         } else if (SCpnt->request_bufflen) {            /* Non SG */
2938                 dma_addr = dma_map_single(&pHCB->pci_dev->dev, SCpnt->request_buffer,
2939                                           SCpnt->request_bufflen,
2940                                           SCpnt->sc_data_direction);
2941                 SCpnt->SCp.dma_handle = dma_addr;
2942                 pSCB->SCB_BufPtr = cpu_to_le32((u32)dma_addr);
2943                 pSCB->SCB_BufLen = cpu_to_le32((u32)SCpnt->request_bufflen);
2944                 pSCB->SCB_SGLen = 0;
2945         } else {
2946                 pSCB->SCB_BufLen = 0;
2947                 pSCB->SCB_SGLen = 0;
2948         }
2949 }
2950
2951 static int i91u_queuecommand(struct scsi_cmnd *cmd,
2952                 void (*done)(struct scsi_cmnd *))
2953 {
2954         HCS *pHCB = (HCS *) cmd->device->host->base;
2955         register SCB *pSCB;
2956
2957         cmd->scsi_done = done;
2958
2959         pSCB = tul_alloc_scb(pHCB);
2960         if (!pSCB)
2961                 return SCSI_MLQUEUE_HOST_BUSY;
2962
2963         i91uBuildSCB(pHCB, pSCB, cmd);
2964         tul_exec_scb(pHCB, pSCB);
2965         return 0;
2966 }
2967
2968 #if 0 /* no new EH yet */
2969 /*
2970  *  Abort a queued command
2971  *  (commands that are on the bus can't be aborted easily)
2972  */
2973 static int i91u_abort(struct scsi_cmnd * SCpnt)
2974 {
2975         HCS *pHCB;
2976
2977         pHCB = (HCS *) SCpnt->device->host->base;
2978         return tul_abort_srb(pHCB, SCpnt);
2979 }
2980
2981 /*
2982  *  Reset registers, reset a hanging bus and
2983  *  kill active and disconnected commands for target w/o soft reset
2984  */
2985 static int i91u_reset(struct scsi_cmnd * SCpnt, unsigned int reset_flags)
2986 {                               /* I need Host Control Block Information */
2987         HCS *pHCB;
2988
2989         pHCB = (HCS *) SCpnt->device->host->base;
2990
2991         if (reset_flags & (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET))
2992                 return tul_reset_scsi_bus(pHCB);
2993         else
2994                 return tul_device_reset(pHCB, SCpnt, SCpnt->device->id, reset_flags);
2995 }
2996 #endif
2997
2998 static int i91u_bus_reset(struct scsi_cmnd * SCpnt)
2999 {
3000         HCS *pHCB;
3001
3002         pHCB = (HCS *) SCpnt->device->host->base;
3003
3004         spin_lock_irq(SCpnt->device->host->host_lock);
3005         tul_reset_scsi(pHCB, 0);
3006         spin_unlock_irq(SCpnt->device->host->host_lock);
3007
3008         return SUCCESS;
3009 }
3010
3011 /*
3012  * Return the "logical geometry"
3013  */
3014 static int i91u_biosparam(struct scsi_device *sdev, struct block_device *dev,
3015                 sector_t capacity, int *info_array)
3016 {
3017         HCS *pHcb;              /* Point to Host adapter control block */
3018         TCS *pTcb;
3019
3020         pHcb = (HCS *) sdev->host->base;
3021         pTcb = &pHcb->HCS_Tcs[sdev->id];
3022
3023         if (pTcb->TCS_DrvHead) {
3024                 info_array[0] = pTcb->TCS_DrvHead;
3025                 info_array[1] = pTcb->TCS_DrvSector;
3026                 info_array[2] = (unsigned long)capacity / pTcb->TCS_DrvHead / pTcb->TCS_DrvSector;
3027         } else {
3028                 if (pTcb->TCS_DrvFlags & TCF_DRV_255_63) {
3029                         info_array[0] = 255;
3030                         info_array[1] = 63;
3031                         info_array[2] = (unsigned long)capacity / 255 / 63;
3032                 } else {
3033                         info_array[0] = 64;
3034                         info_array[1] = 32;
3035                         info_array[2] = (unsigned long)capacity >> 11;
3036                 }
3037         }
3038
3039 #if defined(DEBUG_BIOSPARAM)
3040         if (i91u_debug & debug_biosparam) {
3041                 printk("bios geometry: head=%d, sec=%d, cyl=%d\n",
3042                        info_array[0], info_array[1], info_array[2]);
3043                 printk("WARNING: check, if the bios geometry is correct.\n");
3044         }
3045 #endif
3046
3047         return 0;
3048 }
3049
3050 static void i91u_unmap_cmnd(struct pci_dev *pci_dev, struct scsi_cmnd *cmnd)
3051 {
3052         /* auto sense buffer */
3053         if (cmnd->SCp.ptr) {
3054                 dma_unmap_single(&pci_dev->dev,
3055                                  (dma_addr_t)((unsigned long)cmnd->SCp.ptr),
3056                                  SENSE_SIZE, DMA_FROM_DEVICE);
3057                 cmnd->SCp.ptr = NULL;
3058         }
3059
3060         /* request buffer */
3061         if (cmnd->use_sg) {
3062                 dma_unmap_single(&pci_dev->dev, cmnd->SCp.dma_handle,
3063                                  sizeof(struct SG_Struc) * TOTAL_SG_ENTRY,
3064                                  DMA_BIDIRECTIONAL);
3065
3066                 dma_unmap_sg(&pci_dev->dev, cmnd->request_buffer,
3067                              cmnd->use_sg,
3068                              cmnd->sc_data_direction);
3069         } else if (cmnd->request_bufflen) {
3070                 dma_unmap_single(&pci_dev->dev, cmnd->SCp.dma_handle,
3071                                  cmnd->request_bufflen,
3072                                  cmnd->sc_data_direction);
3073         }
3074 }
3075
3076 /*****************************************************************************
3077  Function name  : i91uSCBPost
3078  Description    : This is callback routine be called when tulip finish one
3079                         SCSI command.
3080  Input          : pHCB  -       Pointer to host adapter control block.
3081                   pSCB  -       Pointer to SCSI control block.
3082  Output         : None.
3083  Return         : None.
3084 *****************************************************************************/
3085 static void i91uSCBPost(BYTE * pHcb, BYTE * pScb)
3086 {
3087         struct scsi_cmnd *pSRB; /* Pointer to SCSI request block */
3088         HCS *pHCB;
3089         SCB *pSCB;
3090
3091         pHCB = (HCS *) pHcb;
3092         pSCB = (SCB *) pScb;
3093         if ((pSRB = pSCB->SCB_Srb) == 0) {
3094                 printk("i91uSCBPost: SRB pointer is empty\n");
3095
3096                 tul_release_scb(pHCB, pSCB);    /* Release SCB for current channel */
3097                 return;
3098         }
3099         switch (pSCB->SCB_HaStat) {
3100         case 0x0:
3101         case 0xa:               /* Linked command complete without error and linked normally */
3102         case 0xb:               /* Linked command complete without error interrupt generated */
3103                 pSCB->SCB_HaStat = 0;
3104                 break;
3105
3106         case 0x11:              /* Selection time out-The initiator selection or target
3107                                    reselection was not complete within the SCSI Time out period */
3108                 pSCB->SCB_HaStat = DID_TIME_OUT;
3109                 break;
3110
3111         case 0x14:              /* Target bus phase sequence failure-An invalid bus phase or bus
3112                                    phase sequence was requested by the target. The host adapter
3113                                    will generate a SCSI Reset Condition, notifying the host with
3114                                    a SCRD interrupt */
3115                 pSCB->SCB_HaStat = DID_RESET;
3116                 break;
3117
3118         case 0x1a:              /* SCB Aborted. 07/21/98 */
3119                 pSCB->SCB_HaStat = DID_ABORT;
3120                 break;
3121
3122         case 0x12:              /* Data overrun/underrun-The target attempted to transfer more data
3123                                    than was allocated by the Data Length field or the sum of the
3124                                    Scatter / Gather Data Length fields. */
3125         case 0x13:              /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */
3126         case 0x16:              /* Invalid SCB Operation Code. */
3127
3128         default:
3129                 printk("ini9100u: %x %x\n", pSCB->SCB_HaStat, pSCB->SCB_TaStat);
3130                 pSCB->SCB_HaStat = DID_ERROR;   /* Couldn't find any better */
3131                 break;
3132         }
3133
3134         pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16);
3135
3136         if (pSRB == NULL) {
3137                 printk("pSRB is NULL\n");
3138         }
3139
3140         i91u_unmap_cmnd(pHCB->pci_dev, pSRB);
3141         pSRB->scsi_done(pSRB);  /* Notify system DONE           */
3142
3143         tul_release_scb(pHCB, pSCB);    /* Release SCB for current channel */
3144 }
3145
3146 /*
3147  * Release ressources
3148  */
3149 static int i91u_release(struct Scsi_Host *hreg)
3150 {
3151         free_irq(hreg->irq, hreg);
3152         release_region(hreg->io_port, 256);
3153         return 0;
3154 }
3155 MODULE_LICENSE("Dual BSD/GPL");
3156
3157 static struct scsi_host_template driver_template = {
3158         .proc_name      = "INI9100U",
3159         .name           = i91u_REVID,
3160         .detect         = i91u_detect,
3161         .release        = i91u_release,
3162         .queuecommand   = i91u_queuecommand,
3163 //      .abort          = i91u_abort,
3164 //      .reset          = i91u_reset,
3165         .eh_bus_reset_handler = i91u_bus_reset,
3166         .bios_param     = i91u_biosparam,
3167         .can_queue      = 1,
3168         .this_id        = 1,
3169         .sg_tablesize   = SG_ALL,
3170         .cmd_per_lun    = 1,
3171         .use_clustering = ENABLE_CLUSTERING,
3172 };
3173 #include "scsi_module.c"
3174