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