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