ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / scsi / i91uscsi.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     Module: i91uscsi.c
57     Description: PCI I/F for INI-910 SCSI Bus Master Controller
58     Revision History:
59         11/09/94 Tim Chen, Initiali Version 0.90A
60         01/17/95 TC, release ver 1.01
61         02/09/95 TC  modify ReadPCIConfig, try both mechanisms;
62         02/15/95 TC  add support for INI-9100W
63         06/04/96 HC, Change to fit LINUX from jaspci.c
64         11/18/96 HC, Port for tulip
65         07/08/98 hc, Support 0002134A
66         07/23/98 wh, Change the abort_srb routine.
67         09/16/98 hl, Support ALPHA, Rewrite the returnNumberAdapters    <01>
68         12/09/98 bv, Removed unused code, changed tul_se2_wait to
69                      use udelay(30) and tul_do_pause to enable 
70                      interrupts for >= 2.1.95
71         12/13/98 bv, Use spinlocks instead of cli() for serialized
72                      access to HCS_Semaph, HCS_FirstAvail and HCS_LastAvail
73                      members of the HCS structure.
74         01/09/98 bv, Fix a deadlock on SMP system.
75 **********************************************************************/
76
77 #define DEBUG_INTERRUPT 0
78 #define DEBUG_QUEUE     0
79 #define DEBUG_STATE     0
80 #define INT_DISC        0
81
82 #include <linux/jiffies.h>
83 #include <linux/delay.h>
84 #include <linux/blkdev.h>
85 #include <asm/io.h>
86
87 #include "i91uscsi.h"
88
89 /*--- external functions --*/
90 static void tul_se2_wait(void);
91
92 /*--- forward refrence ---*/
93 static SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun);
94 static SCB *tul_find_done_scb(HCS * pCurHcb);
95
96 static int tulip_main(HCS * pCurHcb);
97
98 static int tul_next_state(HCS * pCurHcb);
99 static int tul_state_1(HCS * pCurHcb);
100 static int tul_state_2(HCS * pCurHcb);
101 static int tul_state_3(HCS * pCurHcb);
102 static int tul_state_4(HCS * pCurHcb);
103 static int tul_state_5(HCS * pCurHcb);
104 static int tul_state_6(HCS * pCurHcb);
105 static int tul_state_7(HCS * pCurHcb);
106 static int tul_xfer_data_in(HCS * pCurHcb);
107 static int tul_xfer_data_out(HCS * pCurHcb);
108 static int tul_xpad_in(HCS * pCurHcb);
109 static int tul_xpad_out(HCS * pCurHcb);
110 static int tul_status_msg(HCS * pCurHcb);
111
112 static int tul_msgin(HCS * pCurHcb);
113 static int tul_msgin_sync(HCS * pCurHcb);
114 static int tul_msgin_accept(HCS * pCurHcb);
115 static int tul_msgout_reject(HCS * pCurHcb);
116 static int tul_msgin_extend(HCS * pCurHcb);
117
118 static int tul_msgout_ide(HCS * pCurHcb);
119 static int tul_msgout_abort_targ(HCS * pCurHcb);
120 static int tul_msgout_abort_tag(HCS * pCurHcb);
121
122 static int tul_bus_device_reset(HCS * pCurHcb);
123 static void tul_select_atn(HCS * pCurHcb, SCB * pCurScb);
124 static void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb);
125 static void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb);
126 static int int_tul_busfree(HCS * pCurHcb);
127 int int_tul_scsi_rst(HCS * pCurHcb);
128 static int int_tul_bad_seq(HCS * pCurHcb);
129 static int int_tul_resel(HCS * pCurHcb);
130 static int tul_sync_done(HCS * pCurHcb);
131 static int wdtr_done(HCS * pCurHcb);
132 static int wait_tulip(HCS * pCurHcb);
133 static int tul_wait_done_disc(HCS * pCurHcb);
134 static int tul_wait_disc(HCS * pCurHcb);
135 static void tulip_scsi(HCS * pCurHcb);
136 static int tul_post_scsi_rst(HCS * pCurHcb);
137
138 static void tul_se2_ew_en(WORD CurBase);
139 static void tul_se2_ew_ds(WORD CurBase);
140 static int tul_se2_rd_all(WORD CurBase);
141 static void tul_se2_update_all(WORD CurBase);   /* setup default pattern */
142 static void tul_read_eeprom(WORD CurBase);
143
144                                 /* ---- EXTERNAL VARIABLES ---- */
145 HCS tul_hcs[MAX_SUPPORTED_ADAPTERS];
146                                 /* ---- INTERNAL VARIABLES ---- */
147 static INI_ADPT_STRUCT i91u_adpt[MAX_SUPPORTED_ADAPTERS];
148
149 /*NVRAM nvram, *nvramp = &nvram; */
150 static NVRAM i91unvram;
151 static NVRAM *i91unvramp;
152
153
154
155 static UCHAR i91udftNvRam[64] =
156 {
157 /*----------- header -----------*/
158         0x25, 0xc9,             /* Signature    */
159         0x40,                   /* Size         */
160         0x01,                   /* Revision     */
161         /* -- Host Adapter Structure -- */
162         0x95,                   /* ModelByte0   */
163         0x00,                   /* ModelByte1   */
164         0x00,                   /* ModelInfo    */
165         0x01,                   /* NumOfCh      */
166         NBC1_DEFAULT,           /* BIOSConfig1  */
167         0,                      /* BIOSConfig2  */
168         0,                      /* HAConfig1    */
169         0,                      /* HAConfig2    */
170         /* SCSI channel 0 and target Structure  */
171         7,                      /* SCSIid       */
172         NCC1_DEFAULT,           /* SCSIconfig1  */
173         0,                      /* SCSIconfig2  */
174         0x10,                   /* NumSCSItarget */
175
176         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
177         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
178         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
179         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
180
181         /* SCSI channel 1 and target Structure  */
182         7,                      /* SCSIid       */
183         NCC1_DEFAULT,           /* SCSIconfig1  */
184         0,                      /* SCSIconfig2  */
185         0x10,                   /* NumSCSItarget */
186
187         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
188         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
189         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
190         NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
191         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
192         0, 0};                  /*      - CheckSum -            */
193
194
195 static UCHAR tul_rate_tbl[8] =  /* fast 20      */
196 {
197                                 /* nanosecond devide by 4 */
198         12,                     /* 50ns,  20M   */
199         18,                     /* 75ns,  13.3M */
200         25,                     /* 100ns, 10M   */
201         31,                     /* 125ns, 8M    */
202         37,                     /* 150ns, 6.6M  */
203         43,                     /* 175ns, 5.7M  */
204         50,                     /* 200ns, 5M    */
205         62                      /* 250ns, 4M    */
206 };
207
208 extern int tul_num_ch;
209
210
211 static void tul_do_pause(unsigned amount)
212 {                               /* Pause for amount jiffies */
213         unsigned long the_time = jiffies + amount;
214
215         while (time_before_eq(jiffies, the_time));
216 }
217
218 /*-- forward reference --*/
219
220 /*******************************************************************
221         Use memeory refresh time        ~ 15us * 2
222 ********************************************************************/
223 void tul_se2_wait()
224 {
225 #if 1
226         udelay(30);
227 #else
228         UCHAR readByte;
229
230         readByte = TUL_RD(0, 0x61);
231         if ((readByte & 0x10) == 0x10) {
232                 for (;;) {
233                         readByte = TUL_RD(0, 0x61);
234                         if ((readByte & 0x10) == 0x10)
235                                 break;
236                 }
237                 for (;;) {
238                         readByte = TUL_RD(0, 0x61);
239                         if ((readByte & 0x10) != 0x10)
240                                 break;
241                 }
242         } else {
243                 for (;;) {
244                         readByte = TUL_RD(0, 0x61);
245                         if ((readByte & 0x10) == 0x10)
246                                 break;
247                 }
248                 for (;;) {
249                         readByte = TUL_RD(0, 0x61);
250                         if ((readByte & 0x10) != 0x10)
251                                 break;
252                 }
253         }
254 #endif
255 }
256
257
258 /******************************************************************
259  Input: instruction for  Serial E2PROM
260
261  EX: se2_rd(0 call se2_instr() to send address and read command
262
263          StartBit  OP_Code   Address                Data
264          --------- --------  ------------------     -------
265          1         1 , 0     A5,A4,A3,A2,A1,A0      D15-D0
266
267                  +-----------------------------------------------------
268                  |
269  CS -----+
270                         +--+  +--+  +--+  +--+  +--+
271                         ^  |  ^  |  ^  |  ^  |  ^  |
272                         |  |  |  |  |  |  |  |  |  |
273  CLK -------+  +--+  +--+  +--+  +--+  +--
274  (leading edge trigger)
275
276                  +--1-----1--+
277                  | SB    OP  |  OP    A5    A4
278  DI  ----+           +--0------------------
279  (address and cmd sent to nvram)
280
281          -------------------------------------------+
282                                                                                                 |
283  DO                                             +---
284  (data sent from nvram)
285
286
287 ******************************************************************/
288 void tul_se2_instr(WORD CurBase, UCHAR instr)
289 {
290         int i;
291         UCHAR b;
292
293         TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2DO);     /* cs+start bit */
294         tul_se2_wait();
295         TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK | SE2DO);    /* +CLK */
296         tul_se2_wait();
297
298         for (i = 0; i < 8; i++) {
299                 if (instr & 0x80)
300                         b = SE2CS | SE2DO;      /* -CLK+dataBit */
301                 else
302                         b = SE2CS;      /* -CLK */
303                 TUL_WR(CurBase + TUL_NVRAM, b);
304                 tul_se2_wait();
305                 TUL_WR(CurBase + TUL_NVRAM, b | SE2CLK);        /* +CLK */
306                 tul_se2_wait();
307                 instr <<= 1;
308         }
309         TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK */
310         tul_se2_wait();
311         return;
312 }
313
314
315 /******************************************************************
316  Function name  : tul_se2_ew_en
317  Description    : Enable erase/write state of serial EEPROM
318 ******************************************************************/
319 void tul_se2_ew_en(WORD CurBase)
320 {
321         tul_se2_instr(CurBase, 0x30);   /* EWEN */
322         TUL_WR(CurBase + TUL_NVRAM, 0);         /* -CS  */
323         tul_se2_wait();
324         return;
325 }
326
327
328 /************************************************************************
329  Disable erase/write state of serial EEPROM
330 *************************************************************************/
331 void tul_se2_ew_ds(WORD CurBase)
332 {
333         tul_se2_instr(CurBase, 0);      /* EWDS */
334         TUL_WR(CurBase + TUL_NVRAM, 0);         /* -CS  */
335         tul_se2_wait();
336         return;
337 }
338
339
340 /******************************************************************
341         Input  :address of Serial E2PROM
342         Output :value stored in  Serial E2PROM
343 *******************************************************************/
344 USHORT tul_se2_rd(WORD CurBase, ULONG adr)
345 {
346         UCHAR instr, readByte;
347         USHORT readWord;
348         int i;
349
350         instr = (UCHAR) (adr | 0x80);
351         tul_se2_instr(CurBase, instr);  /* READ INSTR */
352         readWord = 0;
353
354         for (i = 15; i >= 0; i--) {
355                 TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK);    /* +CLK */
356                 tul_se2_wait();
357                 TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK */
358
359                 /* sample data after the following edge of clock  */
360                 readByte = TUL_RD(CurBase, TUL_NVRAM);
361                 readByte &= SE2DI;
362                 readWord += (readByte << i);
363                 tul_se2_wait(); /* 6/20/95 */
364         }
365
366         TUL_WR(CurBase + TUL_NVRAM, 0);         /* no chip select */
367         tul_se2_wait();
368         return readWord;
369 }
370
371
372 /******************************************************************
373  Input: new value in  Serial E2PROM, address of Serial E2PROM
374 *******************************************************************/
375 void tul_se2_wr(WORD CurBase, UCHAR adr, USHORT writeWord)
376 {
377         UCHAR readByte;
378         UCHAR instr;
379         int i;
380
381         instr = (UCHAR) (adr | 0x40);
382         tul_se2_instr(CurBase, instr);  /* WRITE INSTR */
383         for (i = 15; i >= 0; i--) {
384                 if (writeWord & 0x8000)
385                         TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2DO);     /* -CLK+dataBit 1 */
386                 else
387                         TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK+dataBit 0 */
388                 tul_se2_wait();
389                 TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK);    /* +CLK */
390                 tul_se2_wait();
391                 writeWord <<= 1;
392         }
393         TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK */
394         tul_se2_wait();
395         TUL_WR(CurBase + TUL_NVRAM, 0);         /* -CS  */
396         tul_se2_wait();
397
398         TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* +CS  */
399         tul_se2_wait();
400
401         for (;;) {
402                 TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK);    /* +CLK */
403                 tul_se2_wait();
404                 TUL_WR(CurBase + TUL_NVRAM, SE2CS);     /* -CLK */
405                 tul_se2_wait();
406                 if ((readByte = TUL_RD(CurBase, TUL_NVRAM)) & SE2DI)
407                         break;  /* write complete */
408         }
409         TUL_WR(CurBase + TUL_NVRAM, 0);         /* -CS */
410         return;
411 }
412
413
414 /***********************************************************************
415  Read SCSI H/A configuration parameters from serial EEPROM
416 ************************************************************************/
417 int tul_se2_rd_all(WORD CurBase)
418 {
419         int i;
420         ULONG chksum = 0;
421         USHORT *np;
422
423         i91unvramp = &i91unvram;
424         np = (USHORT *) i91unvramp;
425         for (i = 0; i < 32; i++) {
426                 *np++ = tul_se2_rd(CurBase, i);
427         }
428
429 /*--------------------Is signature "ini" ok ? ----------------*/
430         if (i91unvramp->NVM_Signature != INI_SIGNATURE)
431                 return -1;
432 /*---------------------- Is ckecksum ok ? ----------------------*/
433         np = (USHORT *) i91unvramp;
434         for (i = 0; i < 31; i++)
435                 chksum += *np++;
436         if (i91unvramp->NVM_CheckSum != (USHORT) chksum)
437                 return -1;
438         return 1;
439 }
440
441
442 /***********************************************************************
443  Update SCSI H/A configuration parameters from serial EEPROM
444 ************************************************************************/
445 void tul_se2_update_all(WORD CurBase)
446 {                               /* setup default pattern */
447         int i;
448         ULONG chksum = 0;
449         USHORT *np, *np1;
450
451         i91unvramp = &i91unvram;
452         /* Calculate checksum first */
453         np = (USHORT *) i91udftNvRam;
454         for (i = 0; i < 31; i++)
455                 chksum += *np++;
456         *np = (USHORT) chksum;
457         tul_se2_ew_en(CurBase); /* Enable write  */
458
459         np = (USHORT *) i91udftNvRam;
460         np1 = (USHORT *) i91unvramp;
461         for (i = 0; i < 32; i++, np++, np1++) {
462                 if (*np != *np1) {
463                         tul_se2_wr(CurBase, i, *np);
464                 }
465         }
466
467         tul_se2_ew_ds(CurBase); /* Disable write   */
468         return;
469 }
470
471 /*************************************************************************
472  Function name  : read_eeprom
473 **************************************************************************/
474 void tul_read_eeprom(WORD CurBase)
475 {
476         UCHAR gctrl;
477
478         i91unvramp = &i91unvram;
479 /*------Enable EEProm programming ---*/
480         gctrl = TUL_RD(CurBase, TUL_GCTRL);
481         TUL_WR(CurBase + TUL_GCTRL, gctrl | TUL_GCTRL_EEPROM_BIT);
482         if (tul_se2_rd_all(CurBase) != 1) {
483                 tul_se2_update_all(CurBase);    /* setup default pattern */
484                 tul_se2_rd_all(CurBase);        /* load again  */
485         }
486 /*------ Disable EEProm programming ---*/
487         gctrl = TUL_RD(CurBase, TUL_GCTRL);
488         TUL_WR(CurBase + TUL_GCTRL, gctrl & ~TUL_GCTRL_EEPROM_BIT);
489 }                               /* read_eeprom */
490
491 int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
492                                BYTE bBus, BYTE bDevice)
493 {
494         int i, j;
495
496         for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) {
497                 if (i91u_adpt[i].ADPT_BIOS < wBIOS)
498                         continue;
499                 if (i91u_adpt[i].ADPT_BIOS == wBIOS) {
500                         if (i91u_adpt[i].ADPT_BASE == wBASE) {
501                                 if (i91u_adpt[i].ADPT_Bus != 0xFF)
502                                         return (FAILURE);
503                         } else if (i91u_adpt[i].ADPT_BASE < wBASE)
504                                         continue;
505                 }
506                 for (j = MAX_SUPPORTED_ADAPTERS - 1; j > i; j--) {
507                         i91u_adpt[j].ADPT_BASE = i91u_adpt[j - 1].ADPT_BASE;
508                         i91u_adpt[j].ADPT_INTR = i91u_adpt[j - 1].ADPT_INTR;
509                         i91u_adpt[j].ADPT_BIOS = i91u_adpt[j - 1].ADPT_BIOS;
510                         i91u_adpt[j].ADPT_Bus = i91u_adpt[j - 1].ADPT_Bus;
511                         i91u_adpt[j].ADPT_Device = i91u_adpt[j - 1].ADPT_Device;
512                 }
513                 i91u_adpt[i].ADPT_BASE = wBASE;
514                 i91u_adpt[i].ADPT_INTR = bInterrupt;
515                 i91u_adpt[i].ADPT_BIOS = wBIOS;
516                 i91u_adpt[i].ADPT_Bus = bBus;
517                 i91u_adpt[i].ADPT_Device = bDevice;
518                 return (SUCCESSFUL);
519         }
520         return (FAILURE);
521 }
522
523 void init_i91uAdapter_table(void)
524 {
525         int i;
526
527         for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) {  /* Initialize adapter structure */
528                 i91u_adpt[i].ADPT_BIOS = 0xffff;
529                 i91u_adpt[i].ADPT_BASE = 0xffff;
530                 i91u_adpt[i].ADPT_INTR = 0xff;
531                 i91u_adpt[i].ADPT_Bus = 0xff;
532                 i91u_adpt[i].ADPT_Device = 0xff;
533         }
534         return;
535 }
536
537 void tul_stop_bm(HCS * pCurHcb)
538 {
539
540         if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) {   /* if DMA xfer is pending, abort DMA xfer */
541                 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT | TAX_X_CLR_FIFO);
542                 /* wait Abort DMA xfer done */
543                 while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & XABT) == 0);
544         }
545         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
546 }
547
548 /***************************************************************************/
549 void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx)
550 {
551         pCurHcb->HCS_Base = i91u_adpt[ch_idx].ADPT_BASE;        /* Supply base address  */
552         pCurHcb->HCS_BIOS = i91u_adpt[ch_idx].ADPT_BIOS;        /* Supply BIOS address  */
553         pCurHcb->HCS_Intr = i91u_adpt[ch_idx].ADPT_INTR;        /* Supply interrupt line */
554         return;
555 }
556
557 /***************************************************************************/
558 int tul_reset_scsi(HCS * pCurHcb, int seconds)
559 {
560         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_BUS);
561
562         while (!((pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt)) & TSS_SCSIRST_INT));
563         /* reset tulip chip */
564
565         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, 0);
566
567         /* Stall for a while, wait for target's firmware ready,make it 2 sec ! */
568         /* SONY 5200 tape drive won't work if only stall for 1 sec */
569         tul_do_pause(seconds * HZ);
570
571         TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
572
573         return (SCSI_RESET_SUCCESS);
574 }
575
576 /***************************************************************************/
577 int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb, BYTE * pbBiosAdr, int seconds)
578 {
579         int i;
580         BYTE *pwFlags;
581         BYTE *pbHeads;
582         SCB *pTmpScb, *pPrevScb = NULL;
583
584         pCurHcb->HCS_NumScbs = tul_num_scb;
585         pCurHcb->HCS_Semaph = 1;
586         pCurHcb->HCS_SemaphLock = SPIN_LOCK_UNLOCKED;
587         pCurHcb->HCS_JSStatus0 = 0;
588         pCurHcb->HCS_Scb = scbp;
589         pCurHcb->HCS_NxtPend = scbp;
590         pCurHcb->HCS_NxtAvail = scbp;
591         for (i = 0, pTmpScb = scbp; i < tul_num_scb; i++, pTmpScb++) {
592                 pTmpScb->SCB_TagId = i;
593                 if (i != 0)
594                         pPrevScb->SCB_NxtScb = pTmpScb;
595                 pPrevScb = pTmpScb;
596         }
597         pPrevScb->SCB_NxtScb = NULL;
598         pCurHcb->HCS_ScbEnd = pTmpScb;
599         pCurHcb->HCS_FirstAvail = scbp;
600         pCurHcb->HCS_LastAvail = pPrevScb;
601         pCurHcb->HCS_AvailLock = SPIN_LOCK_UNLOCKED;
602         pCurHcb->HCS_FirstPend = NULL;
603         pCurHcb->HCS_LastPend = NULL;
604         pCurHcb->HCS_FirstBusy = NULL;
605         pCurHcb->HCS_LastBusy = NULL;
606         pCurHcb->HCS_FirstDone = NULL;
607         pCurHcb->HCS_LastDone = NULL;
608         pCurHcb->HCS_ActScb = NULL;
609         pCurHcb->HCS_ActTcs = NULL;
610
611         tul_read_eeprom(pCurHcb->HCS_Base);
612 /*---------- get H/A configuration -------------*/
613         if (i91unvramp->NVM_SCSIInfo[0].NVM_NumOfTarg == 8)
614                 pCurHcb->HCS_MaxTar = 8;
615         else
616                 pCurHcb->HCS_MaxTar = 16;
617
618         pCurHcb->HCS_Config = i91unvramp->NVM_SCSIInfo[0].NVM_ChConfig1;
619
620         pCurHcb->HCS_SCSI_ID = i91unvramp->NVM_SCSIInfo[0].NVM_ChSCSIID;
621         pCurHcb->HCS_IdMask = ~(1 << pCurHcb->HCS_SCSI_ID);
622
623 #if CHK_PARITY
624         /* Enable parity error response */
625         TUL_WR(pCurHcb->HCS_Base + TUL_PCMD, TUL_RD(pCurHcb->HCS_Base, TUL_PCMD) | 0x40);
626 #endif
627
628         /* Mask all the interrupt       */
629         TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
630
631         tul_stop_bm(pCurHcb);
632         /* --- Initialize the tulip --- */
633         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_CHIP);
634
635         /* program HBA's SCSI ID        */
636         TUL_WR(pCurHcb->HCS_Base + TUL_SScsiId, pCurHcb->HCS_SCSI_ID << 4);
637
638         /* Enable Initiator Mode ,phase latch,alternate sync period mode,
639            disable SCSI reset */
640         if (pCurHcb->HCS_Config & HCC_EN_PAR)
641                 pCurHcb->HCS_SConf1 = (TSC_INITDEFAULT | TSC_EN_SCSI_PAR);
642         else
643                 pCurHcb->HCS_SConf1 = (TSC_INITDEFAULT);
644         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_SConf1);
645
646         /* Enable HW reselect           */
647         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);
648
649         TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, 0);
650
651         /* selection time out = 250 ms */
652         TUL_WR(pCurHcb->HCS_Base + TUL_STimeOut, 153);
653
654 /*--------- Enable SCSI terminator -----*/
655         TUL_WR(pCurHcb->HCS_Base + TUL_XCtrl, (pCurHcb->HCS_Config & (HCC_ACT_TERM1 | HCC_ACT_TERM2)));
656         TUL_WR(pCurHcb->HCS_Base + TUL_GCTRL1,
657                ((pCurHcb->HCS_Config & HCC_AUTO_TERM) >> 4) | (TUL_RD(pCurHcb->HCS_Base, TUL_GCTRL1) & 0xFE));
658
659         for (i = 0,
660              pwFlags = & (i91unvramp->NVM_SCSIInfo[0].NVM_Targ0Config),
661              pbHeads = pbBiosAdr + 0x180;
662              i < pCurHcb->HCS_MaxTar;
663              i++, pwFlags++) {
664                 pCurHcb->HCS_Tcs[i].TCS_Flags = *pwFlags & ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
665                 if (pCurHcb->HCS_Tcs[i].TCS_Flags & TCF_EN_255)
666                         pCurHcb->HCS_Tcs[i].TCS_DrvFlags = TCF_DRV_255_63;
667                 else
668                         pCurHcb->HCS_Tcs[i].TCS_DrvFlags = 0;
669                 pCurHcb->HCS_Tcs[i].TCS_JS_Period = 0;
670                 pCurHcb->HCS_Tcs[i].TCS_SConfig0 = pCurHcb->HCS_SConf1;
671                 pCurHcb->HCS_Tcs[i].TCS_DrvHead = *pbHeads++;
672                 if (pCurHcb->HCS_Tcs[i].TCS_DrvHead == 255)
673                         pCurHcb->HCS_Tcs[i].TCS_DrvFlags = TCF_DRV_255_63;
674                 else
675                         pCurHcb->HCS_Tcs[i].TCS_DrvFlags = 0;
676                 pCurHcb->HCS_Tcs[i].TCS_DrvSector = *pbHeads++;
677                 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~TCF_BUSY;
678                 pCurHcb->HCS_ActTags[i] = 0;
679                 pCurHcb->HCS_MaxTags[i] = 0xFF;
680         }                       /* for                          */
681         printk("i91u: PCI Base=0x%04X, IRQ=%d, BIOS=0x%04X0, SCSI ID=%d\n",
682                pCurHcb->HCS_Base, pCurHcb->HCS_Intr,
683                pCurHcb->HCS_BIOS, pCurHcb->HCS_SCSI_ID);
684 /*------------------- reset SCSI Bus ---------------------------*/
685         if (pCurHcb->HCS_Config & HCC_SCSI_RESET) {
686                 printk("i91u: Reset SCSI Bus ... \n");
687                 tul_reset_scsi(pCurHcb, seconds);
688         }
689         TUL_WR(pCurHcb->HCS_Base + TUL_SCFG1, 0x17);
690         TUL_WR(pCurHcb->HCS_Base + TUL_SIntEnable, 0xE9);
691         return (0);
692 }
693
694 /***************************************************************************/
695 SCB *tul_alloc_scb(HCS * hcsp)
696 {
697         SCB *pTmpScb;
698         ULONG flags;
699         spin_lock_irqsave(&(hcsp->HCS_AvailLock), flags);
700         if ((pTmpScb = hcsp->HCS_FirstAvail) != NULL) {
701 #if DEBUG_QUEUE
702                 printk("find scb at %08lx\n", (ULONG) pTmpScb);
703 #endif
704                 if ((hcsp->HCS_FirstAvail = pTmpScb->SCB_NxtScb) == NULL)
705                         hcsp->HCS_LastAvail = NULL;
706                 pTmpScb->SCB_NxtScb = NULL;
707                 pTmpScb->SCB_Status = SCB_RENT;
708         }
709         spin_unlock_irqrestore(&(hcsp->HCS_AvailLock), flags);
710         return (pTmpScb);
711 }
712
713 /***************************************************************************/
714 void tul_release_scb(HCS * hcsp, SCB * scbp)
715 {
716         ULONG flags;
717
718 #if DEBUG_QUEUE
719         printk("Release SCB %lx; ", (ULONG) scbp);
720 #endif
721         spin_lock_irqsave(&(hcsp->HCS_AvailLock), flags);
722         scbp->SCB_Srb = 0;
723         scbp->SCB_Status = 0;
724         scbp->SCB_NxtScb = NULL;
725         if (hcsp->HCS_LastAvail != NULL) {
726                 hcsp->HCS_LastAvail->SCB_NxtScb = scbp;
727                 hcsp->HCS_LastAvail = scbp;
728         } else {
729                 hcsp->HCS_FirstAvail = scbp;
730                 hcsp->HCS_LastAvail = scbp;
731         }
732         spin_unlock_irqrestore(&(hcsp->HCS_AvailLock), flags);
733 }
734
735 /***************************************************************************/
736 void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp)
737 {
738
739 #if DEBUG_QUEUE
740         printk("Append pend SCB %lx; ", (ULONG) scbp);
741 #endif
742         scbp->SCB_Status = SCB_PEND;
743         scbp->SCB_NxtScb = NULL;
744         if (pCurHcb->HCS_LastPend != NULL) {
745                 pCurHcb->HCS_LastPend->SCB_NxtScb = scbp;
746                 pCurHcb->HCS_LastPend = scbp;
747         } else {
748                 pCurHcb->HCS_FirstPend = scbp;
749                 pCurHcb->HCS_LastPend = scbp;
750         }
751 }
752
753 /***************************************************************************/
754 void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp)
755 {
756
757 #if DEBUG_QUEUE
758         printk("Push pend SCB %lx; ", (ULONG) scbp);
759 #endif
760         scbp->SCB_Status = SCB_PEND;
761         if ((scbp->SCB_NxtScb = pCurHcb->HCS_FirstPend) != NULL) {
762                 pCurHcb->HCS_FirstPend = scbp;
763         } else {
764                 pCurHcb->HCS_FirstPend = scbp;
765                 pCurHcb->HCS_LastPend = scbp;
766         }
767 }
768
769 /***************************************************************************/
770 SCB *tul_find_first_pend_scb(HCS * pCurHcb)
771 {
772         SCB *pFirstPend;
773
774
775         pFirstPend = pCurHcb->HCS_FirstPend;
776         while (pFirstPend != NULL) {
777                 if (pFirstPend->SCB_Opcode != ExecSCSI) {
778                         return (pFirstPend);
779                 }
780                 if (pFirstPend->SCB_TagMsg == 0) {
781                         if ((pCurHcb->HCS_ActTags[pFirstPend->SCB_Target] == 0) &&
782                             !(pCurHcb->HCS_Tcs[pFirstPend->SCB_Target].TCS_Flags & TCF_BUSY)) {
783                                 return (pFirstPend);
784                         }
785                 } else {
786                         if ((pCurHcb->HCS_ActTags[pFirstPend->SCB_Target] >=
787                           pCurHcb->HCS_MaxTags[pFirstPend->SCB_Target]) |
788                             (pCurHcb->HCS_Tcs[pFirstPend->SCB_Target].TCS_Flags & TCF_BUSY)) {
789                                 pFirstPend = pFirstPend->SCB_NxtScb;
790                                 continue;
791                         }
792                         return (pFirstPend);
793                 }
794                 pFirstPend = pFirstPend->SCB_NxtScb;
795         }
796
797
798         return (pFirstPend);
799 }
800 /***************************************************************************/
801 SCB *tul_pop_pend_scb(HCS * pCurHcb)
802 {
803         SCB *pTmpScb;
804
805         if ((pTmpScb = pCurHcb->HCS_FirstPend) != NULL) {
806                 if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL)
807                         pCurHcb->HCS_LastPend = NULL;
808                 pTmpScb->SCB_NxtScb = NULL;
809         }
810 #if DEBUG_QUEUE
811         printk("Pop pend SCB %lx; ", (ULONG) pTmpScb);
812 #endif
813         return (pTmpScb);
814 }
815
816
817 /***************************************************************************/
818 void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb)
819 {
820         SCB *pTmpScb, *pPrevScb;
821
822 #if DEBUG_QUEUE
823         printk("unlink pend SCB %lx; ", (ULONG) pCurScb);
824 #endif
825
826         pPrevScb = pTmpScb = pCurHcb->HCS_FirstPend;
827         while (pTmpScb != NULL) {
828                 if (pCurScb == pTmpScb) {       /* Unlink this SCB              */
829                         if (pTmpScb == pCurHcb->HCS_FirstPend) {
830                                 if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL)
831                                         pCurHcb->HCS_LastPend = NULL;
832                         } else {
833                                 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
834                                 if (pTmpScb == pCurHcb->HCS_LastPend)
835                                         pCurHcb->HCS_LastPend = pPrevScb;
836                         }
837                         pTmpScb->SCB_NxtScb = NULL;
838                         break;
839                 }
840                 pPrevScb = pTmpScb;
841                 pTmpScb = pTmpScb->SCB_NxtScb;
842         }
843         return;
844 }
845 /***************************************************************************/
846 void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp)
847 {
848
849 #if DEBUG_QUEUE
850         printk("append busy SCB %lx; ", (ULONG) scbp);
851 #endif
852         if (scbp->SCB_TagMsg)
853                 pCurHcb->HCS_ActTags[scbp->SCB_Target]++;
854         else
855                 pCurHcb->HCS_Tcs[scbp->SCB_Target].TCS_Flags |= TCF_BUSY;
856         scbp->SCB_Status = SCB_BUSY;
857         scbp->SCB_NxtScb = NULL;
858         if (pCurHcb->HCS_LastBusy != NULL) {
859                 pCurHcb->HCS_LastBusy->SCB_NxtScb = scbp;
860                 pCurHcb->HCS_LastBusy = scbp;
861         } else {
862                 pCurHcb->HCS_FirstBusy = scbp;
863                 pCurHcb->HCS_LastBusy = scbp;
864         }
865 }
866
867 /***************************************************************************/
868 SCB *tul_pop_busy_scb(HCS * pCurHcb)
869 {
870         SCB *pTmpScb;
871
872
873         if ((pTmpScb = pCurHcb->HCS_FirstBusy) != NULL) {
874                 if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
875                         pCurHcb->HCS_LastBusy = NULL;
876                 pTmpScb->SCB_NxtScb = NULL;
877                 if (pTmpScb->SCB_TagMsg)
878                         pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--;
879                 else
880                         pCurHcb->HCS_Tcs[pTmpScb->SCB_Target].TCS_Flags &= ~TCF_BUSY;
881         }
882 #if DEBUG_QUEUE
883         printk("Pop busy SCB %lx; ", (ULONG) pTmpScb);
884 #endif
885         return (pTmpScb);
886 }
887
888 /***************************************************************************/
889 void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb)
890 {
891         SCB *pTmpScb, *pPrevScb;
892
893 #if DEBUG_QUEUE
894         printk("unlink busy SCB %lx; ", (ULONG) pCurScb);
895 #endif
896
897         pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy;
898         while (pTmpScb != NULL) {
899                 if (pCurScb == pTmpScb) {       /* Unlink this SCB              */
900                         if (pTmpScb == pCurHcb->HCS_FirstBusy) {
901                                 if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
902                                         pCurHcb->HCS_LastBusy = NULL;
903                         } else {
904                                 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
905                                 if (pTmpScb == pCurHcb->HCS_LastBusy)
906                                         pCurHcb->HCS_LastBusy = pPrevScb;
907                         }
908                         pTmpScb->SCB_NxtScb = NULL;
909                         if (pTmpScb->SCB_TagMsg)
910                                 pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--;
911                         else
912                                 pCurHcb->HCS_Tcs[pTmpScb->SCB_Target].TCS_Flags &= ~TCF_BUSY;
913                         break;
914                 }
915                 pPrevScb = pTmpScb;
916                 pTmpScb = pTmpScb->SCB_NxtScb;
917         }
918         return;
919 }
920
921 /***************************************************************************/
922 SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun)
923 {
924         SCB *pTmpScb, *pPrevScb;
925         WORD scbp_tarlun;
926
927
928         pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy;
929         while (pTmpScb != NULL) {
930                 scbp_tarlun = (pTmpScb->SCB_Lun << 8) | (pTmpScb->SCB_Target);
931                 if (scbp_tarlun == tarlun) {    /* Unlink this SCB              */
932                         break;
933                 }
934                 pPrevScb = pTmpScb;
935                 pTmpScb = pTmpScb->SCB_NxtScb;
936         }
937 #if DEBUG_QUEUE
938         printk("find busy SCB %lx; ", (ULONG) pTmpScb);
939 #endif
940         return (pTmpScb);
941 }
942
943 /***************************************************************************/
944 void tul_append_done_scb(HCS * pCurHcb, SCB * scbp)
945 {
946
947 #if DEBUG_QUEUE
948         printk("append done SCB %lx; ", (ULONG) scbp);
949 #endif
950
951         scbp->SCB_Status = SCB_DONE;
952         scbp->SCB_NxtScb = NULL;
953         if (pCurHcb->HCS_LastDone != NULL) {
954                 pCurHcb->HCS_LastDone->SCB_NxtScb = scbp;
955                 pCurHcb->HCS_LastDone = scbp;
956         } else {
957                 pCurHcb->HCS_FirstDone = scbp;
958                 pCurHcb->HCS_LastDone = scbp;
959         }
960 }
961
962 /***************************************************************************/
963 SCB *tul_find_done_scb(HCS * pCurHcb)
964 {
965         SCB *pTmpScb;
966
967
968         if ((pTmpScb = pCurHcb->HCS_FirstDone) != NULL) {
969                 if ((pCurHcb->HCS_FirstDone = pTmpScb->SCB_NxtScb) == NULL)
970                         pCurHcb->HCS_LastDone = NULL;
971                 pTmpScb->SCB_NxtScb = NULL;
972         }
973 #if DEBUG_QUEUE
974         printk("find done SCB %lx; ", (ULONG) pTmpScb);
975 #endif
976         return (pTmpScb);
977 }
978
979 /***************************************************************************/
980 int tul_abort_srb(HCS * pCurHcb, ULONG srbp)
981 {
982         ULONG flags;
983         SCB *pTmpScb, *pPrevScb;
984
985         spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
986
987         if ((pCurHcb->HCS_Semaph == 0) && (pCurHcb->HCS_ActScb == NULL)) {
988                 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
989                 /* disable Jasmin SCSI Int        */
990
991                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
992
993                 tulip_main(pCurHcb);
994
995                 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
996
997                 pCurHcb->HCS_Semaph = 1;
998                 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
999
1000                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1001
1002                 return SCSI_ABORT_SNOOZE;
1003         }
1004         pPrevScb = pTmpScb = pCurHcb->HCS_FirstPend;    /* Check Pend queue */
1005         while (pTmpScb != NULL) {
1006                 /* 07/27/98 */
1007                 if (pTmpScb->SCB_Srb == (unsigned char *) srbp) {
1008                         if (pTmpScb == pCurHcb->HCS_ActScb) {
1009                                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1010                                 return SCSI_ABORT_BUSY;
1011                         } else if (pTmpScb == pCurHcb->HCS_FirstPend) {
1012                                 if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL)
1013                                         pCurHcb->HCS_LastPend = NULL;
1014                         } else {
1015                                 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
1016                                 if (pTmpScb == pCurHcb->HCS_LastPend)
1017                                         pCurHcb->HCS_LastPend = pPrevScb;
1018                         }
1019                         pTmpScb->SCB_HaStat = HOST_ABORTED;
1020                         pTmpScb->SCB_Flags |= SCF_DONE;
1021                         if (pTmpScb->SCB_Flags & SCF_POST)
1022                                 (*pTmpScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pTmpScb);
1023                         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1024                         return SCSI_ABORT_SUCCESS;
1025                 }
1026                 pPrevScb = pTmpScb;
1027                 pTmpScb = pTmpScb->SCB_NxtScb;
1028         }
1029
1030         pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy;    /* Check Busy queue */
1031         while (pTmpScb != NULL) {
1032
1033                 if (pTmpScb->SCB_Srb == (unsigned char *) srbp) {
1034
1035                         if (pTmpScb == pCurHcb->HCS_ActScb) {
1036                                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1037                                 return SCSI_ABORT_BUSY;
1038                         } else if (pTmpScb->SCB_TagMsg == 0) {
1039                                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1040                                 return SCSI_ABORT_BUSY;
1041                         } else {
1042                                 pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--;
1043                                 if (pTmpScb == pCurHcb->HCS_FirstBusy) {
1044                                         if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
1045                                                 pCurHcb->HCS_LastBusy = NULL;
1046                                 } else {
1047                                         pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
1048                                         if (pTmpScb == pCurHcb->HCS_LastBusy)
1049                                                 pCurHcb->HCS_LastBusy = pPrevScb;
1050                                 }
1051                                 pTmpScb->SCB_NxtScb = NULL;
1052
1053
1054                                 pTmpScb->SCB_HaStat = HOST_ABORTED;
1055                                 pTmpScb->SCB_Flags |= SCF_DONE;
1056                                 if (pTmpScb->SCB_Flags & SCF_POST)
1057                                         (*pTmpScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pTmpScb);
1058                                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1059                                 return SCSI_ABORT_SUCCESS;
1060                         }
1061                 }
1062                 pPrevScb = pTmpScb;
1063                 pTmpScb = pTmpScb->SCB_NxtScb;
1064         }
1065         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1066         return (SCSI_ABORT_NOT_RUNNING);
1067 }
1068
1069 /***************************************************************************/
1070 int tul_bad_seq(HCS * pCurHcb)
1071 {
1072         SCB *pCurScb;
1073
1074         printk("tul_bad_seg c=%d\n", pCurHcb->HCS_Index);
1075
1076         if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) {
1077                 tul_unlink_busy_scb(pCurHcb, pCurScb);
1078                 pCurScb->SCB_HaStat = HOST_BAD_PHAS;
1079                 pCurScb->SCB_TaStat = 0;
1080                 tul_append_done_scb(pCurHcb, pCurScb);
1081         }
1082         tul_stop_bm(pCurHcb);
1083
1084         tul_reset_scsi(pCurHcb, 8);     /* 7/29/98 */
1085
1086         return (tul_post_scsi_rst(pCurHcb));
1087 }
1088
1089 /************************************************************************/
1090 int tul_device_reset(HCS * pCurHcb, ULONG pSrb, unsigned int target, unsigned int ResetFlags)
1091 {
1092         ULONG flags;
1093         SCB *pScb;
1094         spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1095
1096         if (ResetFlags & SCSI_RESET_ASYNCHRONOUS) {
1097
1098                 if ((pCurHcb->HCS_Semaph == 0) && (pCurHcb->HCS_ActScb == NULL)) {
1099                         TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
1100                         /* disable Jasmin SCSI Int        */
1101
1102                         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1103
1104                         tulip_main(pCurHcb);
1105
1106                         spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1107
1108                         pCurHcb->HCS_Semaph = 1;
1109                         TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
1110
1111                         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1112
1113                         return SCSI_RESET_SNOOZE;
1114                 }
1115                 pScb = pCurHcb->HCS_FirstBusy;  /* Check Busy queue */
1116                 while (pScb != NULL) {
1117                         if (pScb->SCB_Srb == (unsigned char *) pSrb)
1118                                 break;
1119                         pScb = pScb->SCB_NxtScb;
1120                 }
1121                 if (pScb == NULL) {
1122                         printk("Unable to Reset - No SCB Found\n");
1123
1124                         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1125                         return SCSI_RESET_NOT_RUNNING;
1126                 }
1127         }
1128         if ((pScb = tul_alloc_scb(pCurHcb)) == NULL) {
1129                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1130                 return SCSI_RESET_NOT_RUNNING;
1131         }
1132         pScb->SCB_Opcode = BusDevRst;
1133         pScb->SCB_Flags = SCF_POST;
1134         pScb->SCB_Target = target;
1135         pScb->SCB_Mode = 0;
1136
1137         pScb->SCB_Srb = 0;
1138         if (ResetFlags & SCSI_RESET_SYNCHRONOUS) {
1139                 pScb->SCB_Srb = (unsigned char *) pSrb;
1140         }
1141         tul_push_pend_scb(pCurHcb, pScb);       /* push this SCB to Pending queue */
1142
1143         if (pCurHcb->HCS_Semaph == 1) {
1144                 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
1145                 /* disable Jasmin SCSI Int        */
1146                 pCurHcb->HCS_Semaph = 0;
1147
1148                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1149
1150                 tulip_main(pCurHcb);
1151
1152                 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1153
1154                 pCurHcb->HCS_Semaph = 1;
1155                 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
1156         }
1157         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1158         return SCSI_RESET_PENDING;
1159 }
1160
1161 int tul_reset_scsi_bus(HCS * pCurHcb)
1162 {
1163         ULONG flags;
1164
1165         spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1166         TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
1167         pCurHcb->HCS_Semaph = 0;
1168
1169         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1170
1171         tul_stop_bm(pCurHcb);
1172
1173         tul_reset_scsi(pCurHcb, 2);     /* 7/29/98 */
1174
1175         spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1176         tul_post_scsi_rst(pCurHcb);
1177
1178         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1179
1180         tulip_main(pCurHcb);
1181
1182         spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1183
1184         pCurHcb->HCS_Semaph = 1;
1185         TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
1186         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1187         return (SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET);
1188 }
1189
1190 /************************************************************************/
1191 void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb)
1192 {
1193         ULONG flags;
1194
1195         pCurScb->SCB_Mode = 0;
1196
1197         pCurScb->SCB_SGIdx = 0;
1198         pCurScb->SCB_SGMax = pCurScb->SCB_SGLen;
1199
1200         spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1201
1202         tul_append_pend_scb(pCurHcb, pCurScb);  /* Append this SCB to Pending queue */
1203
1204 /* VVVVV 07/21/98 */
1205         if (pCurHcb->HCS_Semaph == 1) {
1206                 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
1207                 /* disable Jasmin SCSI Int        */
1208                 pCurHcb->HCS_Semaph = 0;
1209
1210                 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1211
1212                 tulip_main(pCurHcb);
1213
1214                 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
1215
1216                 pCurHcb->HCS_Semaph = 1;
1217                 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
1218         }
1219         spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
1220         return;
1221 }
1222
1223 /***************************************************************************/
1224 int tul_isr(HCS * pCurHcb)
1225 {
1226         /* Enter critical section       */
1227
1228         if (TUL_RD(pCurHcb->HCS_Base, TUL_Int) & TSS_INT_PENDING) {
1229                 if (pCurHcb->HCS_Semaph == 1) {
1230                         TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
1231                         /* Disable Tulip SCSI Int */
1232                         pCurHcb->HCS_Semaph = 0;
1233
1234                         tulip_main(pCurHcb);
1235
1236                         pCurHcb->HCS_Semaph = 1;
1237                         TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
1238                         return (1);
1239                 }
1240         }
1241         return (0);
1242 }
1243
1244 /***************************************************************************/
1245 int tulip_main(HCS * pCurHcb)
1246 {
1247         SCB *pCurScb;
1248
1249         for (;;) {
1250
1251                 tulip_scsi(pCurHcb);    /* Call tulip_scsi              */
1252
1253                 while ((pCurScb = tul_find_done_scb(pCurHcb)) != NULL) {        /* find done entry */
1254                         if (pCurScb->SCB_TaStat == QUEUE_FULL) {
1255                                 pCurHcb->HCS_MaxTags[pCurScb->SCB_Target] =
1256                                     pCurHcb->HCS_ActTags[pCurScb->SCB_Target] - 1;
1257                                 pCurScb->SCB_TaStat = 0;
1258                                 tul_append_pend_scb(pCurHcb, pCurScb);
1259                                 continue;
1260                         }
1261                         if (!(pCurScb->SCB_Mode & SCM_RSENS)) {         /* not in auto req. sense mode */
1262                                 if (pCurScb->SCB_TaStat == 2) {
1263
1264                                         /* clr sync. nego flag */
1265
1266                                         if (pCurScb->SCB_Flags & SCF_SENSE) {
1267                                                 BYTE len;
1268                                                 len = pCurScb->SCB_SenseLen;
1269                                                 if (len == 0)
1270                                                         len = 1;
1271                                                 pCurScb->SCB_BufLen = pCurScb->SCB_SenseLen;
1272                                                 pCurScb->SCB_BufPtr = pCurScb->SCB_SensePtr;
1273                                                 pCurScb->SCB_Flags &= ~(SCF_SG | SCF_DIR);      /* for xfer_data_in */
1274 /*                      pCurScb->SCB_Flags |= SCF_NO_DCHK;      */
1275                                                 /* so, we won't report worng direction in xfer_data_in,
1276                                                    and won't report HOST_DO_DU in state_6 */
1277                                                 pCurScb->SCB_Mode = SCM_RSENS;
1278                                                 pCurScb->SCB_Ident &= 0xBF;     /* Disable Disconnect */
1279                                                 pCurScb->SCB_TagMsg = 0;
1280                                                 pCurScb->SCB_TaStat = 0;
1281                                                 pCurScb->SCB_CDBLen = 6;
1282                                                 pCurScb->SCB_CDB[0] = SCSICMD_RequestSense;
1283                                                 pCurScb->SCB_CDB[1] = 0;
1284                                                 pCurScb->SCB_CDB[2] = 0;
1285                                                 pCurScb->SCB_CDB[3] = 0;
1286                                                 pCurScb->SCB_CDB[4] = len;
1287                                                 pCurScb->SCB_CDB[5] = 0;
1288                                                 tul_push_pend_scb(pCurHcb, pCurScb);
1289                                                 break;
1290                                         }
1291                                 }
1292                         } else {        /* in request sense mode */
1293
1294                                 if (pCurScb->SCB_TaStat == 2) {         /* check contition status again after sending
1295                                                                            requset sense cmd 0x3 */
1296                                         pCurScb->SCB_HaStat = HOST_BAD_PHAS;
1297                                 }
1298                                 pCurScb->SCB_TaStat = 2;
1299                         }
1300                         pCurScb->SCB_Flags |= SCF_DONE;
1301                         if (pCurScb->SCB_Flags & SCF_POST) {
1302                                 (*pCurScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pCurScb);
1303                         }
1304                 }               /* while */
1305
1306                 /* find_active: */
1307                 if (TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0) & TSS_INT_PENDING)
1308                         continue;
1309
1310                 if (pCurHcb->HCS_ActScb) {      /* return to OS and wait for xfer_done_ISR/Selected_ISR */
1311                         return 1;       /* return to OS, enable interrupt */
1312                 }
1313                 /* Check pending SCB            */
1314                 if (tul_find_first_pend_scb(pCurHcb) == NULL) {
1315                         return 1;       /* return to OS, enable interrupt */
1316                 }
1317         }                       /* End of for loop */
1318         /* statement won't reach here */
1319 }
1320
1321
1322
1323
1324 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
1325 /***************************************************************************/
1326 /***************************************************************************/
1327 /***************************************************************************/
1328 /***************************************************************************/
1329
1330 /***************************************************************************/
1331 void tulip_scsi(HCS * pCurHcb)
1332 {
1333         SCB *pCurScb;
1334         TCS *pCurTcb;
1335
1336         /* make sure to service interrupt asap */
1337
1338         if ((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0)) & TSS_INT_PENDING) {
1339
1340                 pCurHcb->HCS_Phase = pCurHcb->HCS_JSStatus0 & TSS_PH_MASK;
1341                 pCurHcb->HCS_JSStatus1 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1);
1342                 pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
1343                 if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) {     /* SCSI bus reset detected      */
1344                         int_tul_scsi_rst(pCurHcb);
1345                         return;
1346                 }
1347                 if (pCurHcb->HCS_JSInt & TSS_RESEL_INT) {       /* if selected/reselected interrupt */
1348                         if (int_tul_resel(pCurHcb) == 0)
1349                                 tul_next_state(pCurHcb);
1350                         return;
1351                 }
1352                 if (pCurHcb->HCS_JSInt & TSS_SEL_TIMEOUT) {
1353                         int_tul_busfree(pCurHcb);
1354                         return;
1355                 }
1356                 if (pCurHcb->HCS_JSInt & TSS_DISC_INT) {        /* BUS disconnection            */
1357                         int_tul_busfree(pCurHcb);       /* unexpected bus free or sel timeout */
1358                         return;
1359                 }
1360                 if (pCurHcb->HCS_JSInt & (TSS_FUNC_COMP | TSS_BUS_SERV)) {      /* func complete or Bus service */
1361                         if ((pCurScb = pCurHcb->HCS_ActScb) != NULL)
1362                                 tul_next_state(pCurHcb);
1363                         return;
1364                 }
1365         }
1366         if (pCurHcb->HCS_ActScb != NULL)
1367                 return;
1368
1369         if ((pCurScb = tul_find_first_pend_scb(pCurHcb)) == NULL)
1370                 return;
1371
1372         /* program HBA's SCSI ID & target SCSI ID */
1373         TUL_WR(pCurHcb->HCS_Base + TUL_SScsiId,
1374              (pCurHcb->HCS_SCSI_ID << 4) | (pCurScb->SCB_Target & 0x0F));
1375         if (pCurScb->SCB_Opcode == ExecSCSI) {
1376                 pCurTcb = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
1377
1378                 if (pCurScb->SCB_TagMsg)
1379                         pCurTcb->TCS_DrvFlags |= TCF_DRV_EN_TAG;
1380                 else
1381                         pCurTcb->TCS_DrvFlags &= ~TCF_DRV_EN_TAG;
1382
1383                 TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurTcb->TCS_JS_Period);
1384                 if ((pCurTcb->TCS_Flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {        /* do wdtr negotiation          */
1385                         tul_select_atn_stop(pCurHcb, pCurScb);
1386                 } else {
1387                         if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {   /* do sync negotiation          */
1388                                 tul_select_atn_stop(pCurHcb, pCurScb);
1389                         } else {
1390                                 if (pCurScb->SCB_TagMsg)
1391                                         tul_select_atn3(pCurHcb, pCurScb);
1392                                 else
1393                                         tul_select_atn(pCurHcb, pCurScb);
1394                         }
1395                 }
1396                 if (pCurScb->SCB_Flags & SCF_POLL) {
1397                         while (wait_tulip(pCurHcb) != -1) {
1398                                 if (tul_next_state(pCurHcb) == -1)
1399                                         break;
1400                         }
1401                 }
1402         } else if (pCurScb->SCB_Opcode == BusDevRst) {
1403                 tul_select_atn_stop(pCurHcb, pCurScb);
1404                 pCurScb->SCB_NxtStat = 8;
1405                 if (pCurScb->SCB_Flags & SCF_POLL) {
1406                         while (wait_tulip(pCurHcb) != -1) {
1407                                 if (tul_next_state(pCurHcb) == -1)
1408                                         break;
1409                         }
1410                 }
1411         } else if (pCurScb->SCB_Opcode == AbortCmd) {
1412                 ULONG srbp;
1413
1414                 srbp = (ULONG) pCurScb->SCB_Srb;
1415 /* 08/03/98 */
1416                 if (tul_abort_srb(pCurHcb, srbp) != 0) {
1417
1418
1419                         tul_unlink_pend_scb(pCurHcb, pCurScb);
1420
1421                         tul_release_scb(pCurHcb, pCurScb);
1422                 } else {
1423                         pCurScb->SCB_Opcode = BusDevRst;
1424                         tul_select_atn_stop(pCurHcb, pCurScb);
1425                         pCurScb->SCB_NxtStat = 8;
1426                 }
1427
1428 /* 08/03/98 */
1429         } else {
1430                 tul_unlink_pend_scb(pCurHcb, pCurScb);
1431                 pCurScb->SCB_HaStat = 0x16;     /* bad command */
1432                 tul_append_done_scb(pCurHcb, pCurScb);
1433         }
1434         return;
1435 }
1436
1437
1438 /***************************************************************************/
1439 int tul_next_state(HCS * pCurHcb)
1440 {
1441         int next;
1442
1443         next = pCurHcb->HCS_ActScb->SCB_NxtStat;
1444         for (;;) {
1445                 switch (next) {
1446                 case 1:
1447                         next = tul_state_1(pCurHcb);
1448                         break;
1449                 case 2:
1450                         next = tul_state_2(pCurHcb);
1451                         break;
1452                 case 3:
1453                         next = tul_state_3(pCurHcb);
1454                         break;
1455                 case 4:
1456                         next = tul_state_4(pCurHcb);
1457                         break;
1458                 case 5:
1459                         next = tul_state_5(pCurHcb);
1460                         break;
1461                 case 6:
1462                         next = tul_state_6(pCurHcb);
1463                         break;
1464                 case 7:
1465                         next = tul_state_7(pCurHcb);
1466                         break;
1467                 case 8:
1468                         return (tul_bus_device_reset(pCurHcb));
1469                 default:
1470                         return (tul_bad_seq(pCurHcb));
1471                 }
1472                 if (next <= 0)
1473                         return next;
1474         }
1475 }
1476
1477
1478 /***************************************************************************/
1479 /* sTate after selection with attention & stop */
1480 int tul_state_1(HCS * pCurHcb)
1481 {
1482         SCB *pCurScb = pCurHcb->HCS_ActScb;
1483         TCS *pCurTcb = pCurHcb->HCS_ActTcs;
1484 #if DEBUG_STATE
1485         printk("-s1-");
1486 #endif
1487
1488         tul_unlink_pend_scb(pCurHcb, pCurScb);
1489         tul_append_busy_scb(pCurHcb, pCurScb);
1490
1491         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0);
1492         /* ATN on */
1493         if (pCurHcb->HCS_Phase == MSG_OUT) {
1494
1495                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, (TSC_EN_BUS_IN | TSC_HW_RESELECT));
1496
1497                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident);
1498
1499                 if (pCurScb->SCB_TagMsg) {
1500                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagMsg);
1501                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagId);
1502                 }
1503                 if ((pCurTcb->TCS_Flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {
1504
1505                         pCurTcb->TCS_Flags |= TCF_WDTR_DONE;
1506
1507                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
1508                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 2);       /* Extended msg length */
1509                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);       /* Sync request */
1510                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1);       /* Start from 16 bits */
1511                 } else if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {
1512
1513                         pCurTcb->TCS_Flags |= TCF_SYNC_DONE;
1514
1515                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
1516                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);       /* extended msg length */
1517                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1);       /* sync request */
1518                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, tul_rate_tbl[pCurTcb->TCS_Flags & TCF_SCSI_RATE]);
1519                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MAX_OFFSET);      /* REQ/ACK offset */
1520                 }
1521                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1522                 if (wait_tulip(pCurHcb) == -1)
1523                         return (-1);
1524         }
1525         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
1526         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)));
1527         return (3);
1528 }
1529
1530
1531 /***************************************************************************/
1532 /* state after selection with attention */
1533 /* state after selection with attention3 */
1534 int tul_state_2(HCS * pCurHcb)
1535 {
1536         SCB *pCurScb = pCurHcb->HCS_ActScb;
1537         TCS *pCurTcb = pCurHcb->HCS_ActTcs;
1538 #if DEBUG_STATE
1539         printk("-s2-");
1540 #endif
1541
1542         tul_unlink_pend_scb(pCurHcb, pCurScb);
1543         tul_append_busy_scb(pCurHcb, pCurScb);
1544
1545         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0);
1546
1547         if (pCurHcb->HCS_JSStatus1 & TSS_CMD_PH_CMP) {
1548                 return (4);
1549         }
1550         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
1551         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)));
1552         return (3);
1553 }
1554
1555 /***************************************************************************/
1556 /* state before CDB xfer is done */
1557 int tul_state_3(HCS * pCurHcb)
1558 {
1559         SCB *pCurScb = pCurHcb->HCS_ActScb;
1560         TCS *pCurTcb = pCurHcb->HCS_ActTcs;
1561         int i;
1562
1563 #if DEBUG_STATE
1564         printk("-s3-");
1565 #endif
1566         for (;;) {
1567                 switch (pCurHcb->HCS_Phase) {
1568                 case CMD_OUT:   /* Command out phase            */
1569                         for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++)
1570                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]);
1571                         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1572                         if (wait_tulip(pCurHcb) == -1)
1573                                 return (-1);
1574                         if (pCurHcb->HCS_Phase == CMD_OUT) {
1575                                 return (tul_bad_seq(pCurHcb));
1576                         }
1577                         return (4);
1578
1579                 case MSG_IN:    /* Message in phase             */
1580                         pCurScb->SCB_NxtStat = 3;
1581                         if (tul_msgin(pCurHcb) == -1)
1582                                 return (-1);
1583                         break;
1584
1585                 case STATUS_IN: /* Status phase                 */
1586                         if (tul_status_msg(pCurHcb) == -1)
1587                                 return (-1);
1588                         break;
1589
1590                 case MSG_OUT:   /* Message out phase            */
1591                         if (pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) {
1592
1593                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP);         /* msg nop */
1594                                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1595                                 if (wait_tulip(pCurHcb) == -1)
1596                                         return (-1);
1597
1598                         } else {
1599                                 pCurTcb->TCS_Flags |= TCF_SYNC_DONE;
1600
1601                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
1602                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);       /* ext. msg len */
1603                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1);       /* sync request */
1604                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, tul_rate_tbl[pCurTcb->TCS_Flags & TCF_SCSI_RATE]);
1605                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MAX_OFFSET);      /* REQ/ACK offset */
1606                                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1607                                 if (wait_tulip(pCurHcb) == -1)
1608                                         return (-1);
1609                                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
1610                                 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7));
1611
1612                         }
1613                         break;
1614
1615                 default:
1616                         return (tul_bad_seq(pCurHcb));
1617                 }
1618         }
1619 }
1620
1621
1622 /***************************************************************************/
1623 int tul_state_4(HCS * pCurHcb)
1624 {
1625         SCB *pCurScb = pCurHcb->HCS_ActScb;
1626
1627 #if DEBUG_STATE
1628         printk("-s4-");
1629 #endif
1630         if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_NO_XF) {
1631                 return (6);     /* Go to state 6                */
1632         }
1633         for (;;) {
1634                 if (pCurScb->SCB_BufLen == 0)
1635                         return (6);     /* Go to state 6                */
1636
1637                 switch (pCurHcb->HCS_Phase) {
1638
1639                 case STATUS_IN: /* Status phase                 */
1640                         if ((pCurScb->SCB_Flags & SCF_DIR) != 0) {      /* if direction bit set then report data underrun */
1641                                 pCurScb->SCB_HaStat = HOST_DO_DU;
1642                         }
1643                         if ((tul_status_msg(pCurHcb)) == -1)
1644                                 return (-1);
1645                         break;
1646
1647                 case MSG_IN:    /* Message in phase             */
1648                         pCurScb->SCB_NxtStat = 0x4;
1649                         if (tul_msgin(pCurHcb) == -1)
1650                                 return (-1);
1651                         break;
1652
1653                 case MSG_OUT:   /* Message out phase            */
1654                         if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {
1655                                 pCurScb->SCB_BufLen = 0;
1656                                 pCurScb->SCB_HaStat = HOST_DO_DU;
1657                                 if (tul_msgout_ide(pCurHcb) == -1)
1658                                         return (-1);
1659                                 return (6);     /* Go to state 6                */
1660                         } else {
1661                                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP);         /* msg nop */
1662                                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1663                                 if (wait_tulip(pCurHcb) == -1)
1664                                         return (-1);
1665                         }
1666                         break;
1667
1668                 case DATA_IN:   /* Data in phase                */
1669                         return (tul_xfer_data_in(pCurHcb));
1670
1671                 case DATA_OUT:  /* Data out phase               */
1672                         return (tul_xfer_data_out(pCurHcb));
1673
1674                 default:
1675                         return (tul_bad_seq(pCurHcb));
1676                 }
1677         }
1678 }
1679
1680
1681 /***************************************************************************/
1682 /* state after dma xfer done or phase change before xfer done */
1683 int tul_state_5(HCS * pCurHcb)
1684 {
1685         SCB *pCurScb = pCurHcb->HCS_ActScb;
1686         long cnt, xcnt;         /* cannot use unsigned !! code: if (xcnt < 0) */
1687
1688 #if DEBUG_STATE
1689         printk("-s5-");
1690 #endif
1691 /*------ get remaining count -------*/
1692
1693         cnt = TUL_RDLONG(pCurHcb->HCS_Base, TUL_SCnt0) & 0x0FFFFFF;
1694
1695         if (TUL_RD(pCurHcb->HCS_Base, TUL_XCmd) & 0x20) {
1696                 /* ----------------------- DATA_IN ----------------------------- */
1697                 /* check scsi parity error */
1698                 if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {
1699                         pCurScb->SCB_HaStat = HOST_DO_DU;
1700                 }
1701                 if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) {   /* DMA xfer pending, Send STOP  */
1702                         /* tell Hardware  scsi xfer has been terminated */
1703                         TUL_WR(pCurHcb->HCS_Base + TUL_XCtrl, TUL_RD(pCurHcb->HCS_Base, TUL_XCtrl) | 0x80);
1704                         /* wait until DMA xfer not pending */
1705                         while (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND);
1706                 }
1707         } else {
1708 /*-------- DATA OUT -----------*/
1709                 if ((TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1) & TSS_XFER_CMP) == 0) {
1710                         if (pCurHcb->HCS_ActTcs->TCS_JS_Period & TSC_WIDE_SCSI)
1711                                 cnt += (TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F) << 1;
1712                         else
1713                                 cnt += (TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F);
1714                 }
1715                 if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) {   /* if DMA xfer is pending, abort DMA xfer */
1716                         TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT);
1717                         /* wait Abort DMA xfer done */
1718                         while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & XABT) == 0);
1719                 }
1720                 if ((cnt == 1) && (pCurHcb->HCS_Phase == DATA_OUT)) {
1721                         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1722                         if (wait_tulip(pCurHcb) == -1) {
1723                                 return (-1);
1724                         }
1725                         cnt = 0;
1726                 } else {
1727                         if ((TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1) & TSS_XFER_CMP) == 0)
1728                                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
1729                 }
1730         }
1731
1732         if (cnt == 0) {
1733                 pCurScb->SCB_BufLen = 0;
1734                 return (6);     /* Go to state 6                */
1735         }
1736         /* Update active data pointer */
1737         xcnt = (long) pCurScb->SCB_BufLen - cnt;        /* xcnt== bytes already xferred */
1738         pCurScb->SCB_BufLen = (U32) cnt;        /* cnt == bytes left to be xferred */
1739         if (pCurScb->SCB_Flags & SCF_SG) {
1740                 register SG *sgp;
1741                 ULONG i;
1742
1743                 sgp = &pCurScb->SCB_SGList[pCurScb->SCB_SGIdx];
1744                 for (i = pCurScb->SCB_SGIdx; i < pCurScb->SCB_SGMax; sgp++, i++) {
1745                         xcnt -= (long) sgp->SG_Len;
1746                         if (xcnt < 0) {         /* this sgp xfer half done */
1747                                 xcnt += (long) sgp->SG_Len;     /* xcnt == bytes xferred in this sgp */
1748                                 sgp->SG_Ptr += (U32) xcnt;      /* new ptr to be xfer */
1749                                 sgp->SG_Len -= (U32) xcnt;      /* new len to be xfer */
1750                                 pCurScb->SCB_BufPtr += ((U32) (i - pCurScb->SCB_SGIdx) << 3);
1751                                 /* new SG table ptr */
1752                                 pCurScb->SCB_SGLen = (BYTE) (pCurScb->SCB_SGMax - i);
1753                                 /* new SG table len */
1754                                 pCurScb->SCB_SGIdx = (WORD) i;
1755                                 /* for next disc and come in this loop */
1756                                 return (4);     /* Go to state 4                */
1757                         }
1758                         /* else (xcnt >= 0 , i.e. this sgp already xferred */
1759                 }               /* for */
1760                 return (6);     /* Go to state 6                */
1761         } else {
1762                 pCurScb->SCB_BufPtr += (U32) xcnt;
1763         }
1764         return (4);             /* Go to state 4                */
1765 }
1766
1767 /***************************************************************************/
1768 /* state after Data phase */
1769 int tul_state_6(HCS * pCurHcb)
1770 {
1771         SCB *pCurScb = pCurHcb->HCS_ActScb;
1772
1773 #if DEBUG_STATE
1774         printk("-s6-");
1775 #endif
1776         for (;;) {
1777                 switch (pCurHcb->HCS_Phase) {
1778                 case STATUS_IN: /* Status phase                 */
1779                         if ((tul_status_msg(pCurHcb)) == -1)
1780                                 return (-1);
1781                         break;
1782
1783                 case MSG_IN:    /* Message in phase             */
1784                         pCurScb->SCB_NxtStat = 6;
1785                         if ((tul_msgin(pCurHcb)) == -1)
1786                                 return (-1);
1787                         break;
1788
1789                 case MSG_OUT:   /* Message out phase            */
1790                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP);         /* msg nop */
1791                         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1792                         if (wait_tulip(pCurHcb) == -1)
1793                                 return (-1);
1794                         break;
1795
1796                 case DATA_IN:   /* Data in phase                */
1797                         return (tul_xpad_in(pCurHcb));
1798
1799                 case DATA_OUT:  /* Data out phase               */
1800                         return (tul_xpad_out(pCurHcb));
1801
1802                 default:
1803                         return (tul_bad_seq(pCurHcb));
1804                 }
1805         }
1806 }
1807
1808 /***************************************************************************/
1809 int tul_state_7(HCS * pCurHcb)
1810 {
1811         int cnt, i;
1812
1813 #if DEBUG_STATE
1814         printk("-s7-");
1815 #endif
1816         /* flush SCSI FIFO */
1817         cnt = TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F;
1818         if (cnt) {
1819                 for (i = 0; i < cnt; i++)
1820                         TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
1821         }
1822         switch (pCurHcb->HCS_Phase) {
1823         case DATA_IN:           /* Data in phase                */
1824         case DATA_OUT:          /* Data out phase               */
1825                 return (tul_bad_seq(pCurHcb));
1826         default:
1827                 return (6);     /* Go to state 6                */
1828         }
1829 }
1830
1831 /***************************************************************************/
1832 int tul_xfer_data_in(HCS * pCurHcb)
1833 {
1834         SCB *pCurScb = pCurHcb->HCS_ActScb;
1835
1836         if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_DOUT) {
1837                 return (6);     /* wrong direction */
1838         }
1839         TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, pCurScb->SCB_BufLen);
1840
1841         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_DMA_IN);    /* 7/25/95 */
1842
1843         if (pCurScb->SCB_Flags & SCF_SG) {      /* S/G xfer */
1844                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, ((ULONG) pCurScb->SCB_SGLen) << 3);
1845                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
1846                 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_SG_IN);
1847         } else {
1848                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, pCurScb->SCB_BufLen);
1849                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
1850                 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_IN);
1851         }
1852         pCurScb->SCB_NxtStat = 0x5;
1853         return (0);             /* return to OS, wait xfer done , let jas_isr come in */
1854 }
1855
1856
1857 /***************************************************************************/
1858 int tul_xfer_data_out(HCS * pCurHcb)
1859 {
1860         SCB *pCurScb = pCurHcb->HCS_ActScb;
1861
1862         if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_DIN) {
1863                 return (6);     /* wrong direction */
1864         }
1865         TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, pCurScb->SCB_BufLen);
1866         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_DMA_OUT);
1867
1868         if (pCurScb->SCB_Flags & SCF_SG) {      /* S/G xfer */
1869                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, ((ULONG) pCurScb->SCB_SGLen) << 3);
1870                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
1871                 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_SG_OUT);
1872         } else {
1873                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, pCurScb->SCB_BufLen);
1874                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
1875                 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_OUT);
1876         }
1877
1878         pCurScb->SCB_NxtStat = 0x5;
1879         return (0);             /* return to OS, wait xfer done , let jas_isr come in */
1880 }
1881
1882
1883 /***************************************************************************/
1884 int tul_xpad_in(HCS * pCurHcb)
1885 {
1886         SCB *pCurScb = pCurHcb->HCS_ActScb;
1887         TCS *pCurTcb = pCurHcb->HCS_ActTcs;
1888
1889         if ((pCurScb->SCB_Flags & SCF_DIR) != SCF_NO_DCHK) {
1890                 pCurScb->SCB_HaStat = HOST_DO_DU;       /* over run             */
1891         }
1892         for (;;) {
1893                 if (pCurTcb->TCS_JS_Period & TSC_WIDE_SCSI)
1894                         TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 2);
1895                 else
1896                         TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
1897
1898                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
1899                 if ((wait_tulip(pCurHcb)) == -1) {
1900                         return (-1);
1901                 }
1902                 if (pCurHcb->HCS_Phase != DATA_IN) {
1903                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
1904                         return (6);
1905                 }
1906                 TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
1907         }
1908 }
1909
1910 int tul_xpad_out(HCS * pCurHcb)
1911 {
1912         SCB *pCurScb = pCurHcb->HCS_ActScb;
1913         TCS *pCurTcb = pCurHcb->HCS_ActTcs;
1914
1915         if ((pCurScb->SCB_Flags & SCF_DIR) != SCF_NO_DCHK) {
1916                 pCurScb->SCB_HaStat = HOST_DO_DU;       /* over run             */
1917         }
1918         for (;;) {
1919                 if (pCurTcb->TCS_JS_Period & TSC_WIDE_SCSI)
1920                         TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 2);
1921                 else
1922                         TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
1923
1924                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 0);
1925                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1926                 if ((wait_tulip(pCurHcb)) == -1) {
1927                         return (-1);
1928                 }
1929                 if (pCurHcb->HCS_Phase != DATA_OUT) {   /* Disable wide CPU to allow read 16 bits */
1930                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);
1931                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
1932                         return (6);
1933                 }
1934         }
1935 }
1936
1937
1938 /***************************************************************************/
1939 int tul_status_msg(HCS * pCurHcb)
1940 {                               /* status & MSG_IN */
1941         SCB *pCurScb = pCurHcb->HCS_ActScb;
1942         BYTE msg;
1943
1944         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_CMD_COMP);
1945         if ((wait_tulip(pCurHcb)) == -1) {
1946                 return (-1);
1947         }
1948         /* get status */
1949         pCurScb->SCB_TaStat = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
1950
1951         if (pCurHcb->HCS_Phase == MSG_OUT) {
1952                 if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {
1953                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_PARITY);
1954                 } else {
1955                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP);
1956                 }
1957                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1958                 return (wait_tulip(pCurHcb));
1959         }
1960         if (pCurHcb->HCS_Phase == MSG_IN) {
1961                 msg = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
1962                 if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {   /* Parity error                 */
1963                         if ((tul_msgin_accept(pCurHcb)) == -1)
1964                                 return (-1);
1965                         if (pCurHcb->HCS_Phase != MSG_OUT)
1966                                 return (tul_bad_seq(pCurHcb));
1967                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_PARITY);
1968                         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
1969                         return (wait_tulip(pCurHcb));
1970                 }
1971                 if (msg == 0) { /* Command complete             */
1972
1973                         if ((pCurScb->SCB_TaStat & 0x18) == 0x10) {     /* No link support              */
1974                                 return (tul_bad_seq(pCurHcb));
1975                         }
1976                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
1977                         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
1978                         return tul_wait_done_disc(pCurHcb);
1979
1980                 }
1981                 if ((msg == MSG_LINK_COMP) || (msg == MSG_LINK_FLAG)) {
1982                         if ((pCurScb->SCB_TaStat & 0x18) == 0x10)
1983                                 return (tul_msgin_accept(pCurHcb));
1984                 }
1985         }
1986         return (tul_bad_seq(pCurHcb));
1987 }
1988
1989
1990 /***************************************************************************/
1991 /* scsi bus free */
1992 int int_tul_busfree(HCS * pCurHcb)
1993 {
1994         SCB *pCurScb = pCurHcb->HCS_ActScb;
1995
1996         if (pCurScb != NULL) {
1997                 if (pCurScb->SCB_Status & SCB_SELECT) {         /* selection timeout */
1998                         tul_unlink_pend_scb(pCurHcb, pCurScb);
1999                         pCurScb->SCB_HaStat = HOST_SEL_TOUT;
2000                         tul_append_done_scb(pCurHcb, pCurScb);
2001                 } else {        /* Unexpected bus free          */
2002                         tul_unlink_busy_scb(pCurHcb, pCurScb);
2003                         pCurScb->SCB_HaStat = HOST_BUS_FREE;
2004                         tul_append_done_scb(pCurHcb, pCurScb);
2005                 }
2006                 pCurHcb->HCS_ActScb = NULL;
2007                 pCurHcb->HCS_ActTcs = NULL;
2008         }
2009         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
2010         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
2011         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
2012         return (-1);
2013 }
2014
2015
2016 /***************************************************************************/
2017 /* scsi bus reset */
2018 int int_tul_scsi_rst(HCS * pCurHcb)
2019 {
2020         SCB *pCurScb;
2021         int i;
2022
2023         /* if DMA xfer is pending, abort DMA xfer */
2024         if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & 0x01) {
2025                 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT | TAX_X_CLR_FIFO);
2026                 /* wait Abort DMA xfer done */
2027                 while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & 0x04) == 0);
2028                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
2029         }
2030         /* Abort all active & disconnected scb */
2031         while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) {
2032                 pCurScb->SCB_HaStat = HOST_BAD_PHAS;
2033                 tul_append_done_scb(pCurHcb, pCurScb);
2034         }
2035         pCurHcb->HCS_ActScb = NULL;
2036         pCurHcb->HCS_ActTcs = NULL;
2037
2038         /* clr sync nego. done flag */
2039         for (i = 0; i < pCurHcb->HCS_MaxTar; i++) {
2040                 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
2041         }
2042         return (-1);
2043 }
2044
2045
2046 /***************************************************************************/
2047 /* scsi reselection */
2048 int int_tul_resel(HCS * pCurHcb)
2049 {
2050         SCB *pCurScb;
2051         TCS *pCurTcb;
2052         BYTE tag, msg = 0;
2053         BYTE tar, lun;
2054
2055         if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) {
2056                 if (pCurScb->SCB_Status & SCB_SELECT) {         /* if waiting for selection complete */
2057                         pCurScb->SCB_Status &= ~SCB_SELECT;
2058                 }
2059                 pCurHcb->HCS_ActScb = NULL;
2060         }
2061         /* --------- get target id---------------------- */
2062         tar = TUL_RD(pCurHcb->HCS_Base, TUL_SBusId);
2063         /* ------ get LUN from Identify message----------- */
2064         lun = TUL_RD(pCurHcb->HCS_Base, TUL_SIdent) & 0x0F;
2065         /* 07/22/98 from 0x1F -> 0x0F */
2066         pCurTcb = &pCurHcb->HCS_Tcs[tar];
2067         pCurHcb->HCS_ActTcs = pCurTcb;
2068         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0);
2069         TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurTcb->TCS_JS_Period);
2070
2071
2072         /* ------------- tag queueing ? ------------------- */
2073         if (pCurTcb->TCS_DrvFlags & TCF_DRV_EN_TAG) {
2074                 if ((tul_msgin_accept(pCurHcb)) == -1)
2075                         return (-1);
2076                 if (pCurHcb->HCS_Phase != MSG_IN)
2077                         goto no_tag;
2078                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
2079                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
2080                 if ((wait_tulip(pCurHcb)) == -1)
2081                         return (-1);
2082                 msg = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);     /* Read Tag Message    */
2083
2084                 if ((msg < MSG_STAG) || (msg > MSG_OTAG))       /* Is simple Tag      */
2085                         goto no_tag;
2086
2087                 if ((tul_msgin_accept(pCurHcb)) == -1)
2088                         return (-1);
2089
2090                 if (pCurHcb->HCS_Phase != MSG_IN)
2091                         goto no_tag;
2092
2093                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
2094                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
2095                 if ((wait_tulip(pCurHcb)) == -1)
2096                         return (-1);
2097                 tag = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);     /* Read Tag ID       */
2098                 pCurScb = pCurHcb->HCS_Scb + tag;
2099                 if ((pCurScb->SCB_Target != tar) || (pCurScb->SCB_Lun != lun)) {
2100                         return tul_msgout_abort_tag(pCurHcb);
2101                 }
2102                 if (pCurScb->SCB_Status != SCB_BUSY) {  /* 03/24/95             */
2103                         return tul_msgout_abort_tag(pCurHcb);
2104                 }
2105                 pCurHcb->HCS_ActScb = pCurScb;
2106                 if ((tul_msgin_accept(pCurHcb)) == -1)
2107                         return (-1);
2108         } else {                /* No tag               */
2109               no_tag:
2110                 if ((pCurScb = tul_find_busy_scb(pCurHcb, tar | (lun << 8))) == NULL) {
2111                         return tul_msgout_abort_targ(pCurHcb);
2112                 }
2113                 pCurHcb->HCS_ActScb = pCurScb;
2114                 if (!(pCurTcb->TCS_DrvFlags & TCF_DRV_EN_TAG)) {
2115                         if ((tul_msgin_accept(pCurHcb)) == -1)
2116                                 return (-1);
2117                 }
2118         }
2119         return 0;
2120 }
2121
2122
2123 /***************************************************************************/
2124 int int_tul_bad_seq(HCS * pCurHcb)
2125 {                               /* target wrong phase           */
2126         SCB *pCurScb;
2127         int i;
2128
2129         tul_reset_scsi(pCurHcb, 10);
2130
2131         while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) {
2132                 pCurScb->SCB_HaStat = HOST_BAD_PHAS;
2133                 tul_append_done_scb(pCurHcb, pCurScb);
2134         }
2135         for (i = 0; i < pCurHcb->HCS_MaxTar; i++) {
2136                 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
2137         }
2138         return (-1);
2139 }
2140
2141
2142 /***************************************************************************/
2143 int tul_msgout_abort_targ(HCS * pCurHcb)
2144 {
2145
2146         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
2147         if (tul_msgin_accept(pCurHcb) == -1)
2148                 return (-1);
2149         if (pCurHcb->HCS_Phase != MSG_OUT)
2150                 return (tul_bad_seq(pCurHcb));
2151
2152         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_ABORT);
2153         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2154
2155         return tul_wait_disc(pCurHcb);
2156 }
2157
2158 /***************************************************************************/
2159 int tul_msgout_abort_tag(HCS * pCurHcb)
2160 {
2161
2162         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
2163         if (tul_msgin_accept(pCurHcb) == -1)
2164                 return (-1);
2165         if (pCurHcb->HCS_Phase != MSG_OUT)
2166                 return (tul_bad_seq(pCurHcb));
2167
2168         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_ABORT_TAG);
2169         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2170
2171         return tul_wait_disc(pCurHcb);
2172
2173 }
2174
2175 /***************************************************************************/
2176 int tul_msgin(HCS * pCurHcb)
2177 {
2178         TCS *pCurTcb;
2179
2180         for (;;) {
2181
2182                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
2183
2184                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
2185                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
2186                 if ((wait_tulip(pCurHcb)) == -1)
2187                         return (-1);
2188
2189                 switch (TUL_RD(pCurHcb->HCS_Base, TUL_SFifo)) {
2190                 case MSG_DISC:  /* Disconnect msg */
2191                         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
2192
2193                         return tul_wait_disc(pCurHcb);
2194
2195                 case MSG_SDP:
2196                 case MSG_RESTORE:
2197                 case MSG_NOP:
2198                         tul_msgin_accept(pCurHcb);
2199                         break;
2200
2201                 case MSG_REJ:   /* Clear ATN first              */
2202                         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal,
2203                                (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)));
2204                         pCurTcb = pCurHcb->HCS_ActTcs;
2205                         if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {   /* do sync nego */
2206                                 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
2207                         }
2208                         tul_msgin_accept(pCurHcb);
2209                         break;
2210
2211                 case MSG_EXTEND:        /* extended msg */
2212                         tul_msgin_extend(pCurHcb);
2213                         break;
2214
2215                 case MSG_IGNOREWIDE:
2216                         tul_msgin_accept(pCurHcb);
2217                         break;
2218
2219                         /* get */
2220                         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
2221                         if (wait_tulip(pCurHcb) == -1)
2222                                 return -1;
2223
2224                         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 0);       /* put pad  */
2225                         TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);   /* get IGNORE field */
2226                         TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);   /* get pad */
2227
2228                         tul_msgin_accept(pCurHcb);
2229                         break;
2230
2231                 case MSG_COMP:
2232                         {
2233                                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
2234                                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
2235                                 return tul_wait_done_disc(pCurHcb);
2236                         }
2237                 default:
2238                         tul_msgout_reject(pCurHcb);
2239                         break;
2240                 }
2241                 if (pCurHcb->HCS_Phase != MSG_IN)
2242                         return (pCurHcb->HCS_Phase);
2243         }
2244         /* statement won't reach here */
2245 }
2246
2247
2248
2249
2250 /***************************************************************************/
2251 int tul_msgout_reject(HCS * pCurHcb)
2252 {
2253
2254         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
2255
2256         if ((tul_msgin_accept(pCurHcb)) == -1)
2257                 return (-1);
2258
2259         if (pCurHcb->HCS_Phase == MSG_OUT) {
2260                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_REJ);         /* Msg reject           */
2261                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2262                 return (wait_tulip(pCurHcb));
2263         }
2264         return (pCurHcb->HCS_Phase);
2265 }
2266
2267
2268
2269 /***************************************************************************/
2270 int tul_msgout_ide(HCS * pCurHcb)
2271 {
2272         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_IDE);         /* Initiator Detected Error */
2273         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2274         return (wait_tulip(pCurHcb));
2275 }
2276
2277
2278 /***************************************************************************/
2279 int tul_msgin_extend(HCS * pCurHcb)
2280 {
2281         BYTE len, idx;
2282
2283         if (tul_msgin_accept(pCurHcb) != MSG_IN)
2284                 return (pCurHcb->HCS_Phase);
2285
2286         /* Get extended msg length      */
2287         TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
2288         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
2289         if (wait_tulip(pCurHcb) == -1)
2290                 return (-1);
2291
2292         len = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
2293         pCurHcb->HCS_Msg[0] = len;
2294         for (idx = 1; len != 0; len--) {
2295
2296                 if ((tul_msgin_accept(pCurHcb)) != MSG_IN)
2297                         return (pCurHcb->HCS_Phase);
2298                 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
2299                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
2300                 if (wait_tulip(pCurHcb) == -1)
2301                         return (-1);
2302                 pCurHcb->HCS_Msg[idx++] = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
2303         }
2304         if (pCurHcb->HCS_Msg[1] == 1) {         /* if it's synchronous data transfer request */
2305                 if (pCurHcb->HCS_Msg[0] != 3)   /* if length is not right */
2306                         return (tul_msgout_reject(pCurHcb));
2307                 if (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_SYNC_NEGO) {        /* Set OFFSET=0 to do async, nego back */
2308                         pCurHcb->HCS_Msg[3] = 0;
2309                 } else {
2310                         if ((tul_msgin_sync(pCurHcb) == 0) &&
2311                             (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_SYNC_DONE)) {
2312                                 tul_sync_done(pCurHcb);
2313                                 return (tul_msgin_accept(pCurHcb));
2314                         }
2315                 }
2316
2317                 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
2318                 if ((tul_msgin_accept(pCurHcb)) != MSG_OUT)
2319                         return (pCurHcb->HCS_Phase);
2320                 /* sync msg out */
2321                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
2322
2323                 tul_sync_done(pCurHcb);
2324
2325                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
2326                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);
2327                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1);
2328                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[2]);
2329                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[3]);
2330
2331                 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2332                 return (wait_tulip(pCurHcb));
2333         }
2334         if ((pCurHcb->HCS_Msg[0] != 2) || (pCurHcb->HCS_Msg[1] != 3))
2335                 return (tul_msgout_reject(pCurHcb));
2336         /* if it's WIDE DATA XFER REQ   */
2337         if (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_WDTR) {
2338                 pCurHcb->HCS_Msg[2] = 0;
2339         } else {
2340                 if (pCurHcb->HCS_Msg[2] > 2)    /* > 32 bits            */
2341                         return (tul_msgout_reject(pCurHcb));
2342                 if (pCurHcb->HCS_Msg[2] == 2) {         /* == 32                */
2343                         pCurHcb->HCS_Msg[2] = 1;
2344                 } else {
2345                         if ((pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_WDTR) == 0) {
2346                                 wdtr_done(pCurHcb);
2347                                 if ((pCurHcb->HCS_ActTcs->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0)
2348                                         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
2349                                 return (tul_msgin_accept(pCurHcb));
2350                         }
2351                 }
2352         }
2353         TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
2354
2355         if (tul_msgin_accept(pCurHcb) != MSG_OUT)
2356                 return (pCurHcb->HCS_Phase);
2357         /* WDTR msg out                 */
2358         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
2359         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 2);
2360         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);
2361         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[2]);
2362         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2363         return (wait_tulip(pCurHcb));
2364 }
2365
2366 /***************************************************************************/
2367 int tul_msgin_sync(HCS * pCurHcb)
2368 {
2369         char default_period;
2370
2371         default_period = tul_rate_tbl[pCurHcb->HCS_ActTcs->TCS_Flags & TCF_SCSI_RATE];
2372         if (pCurHcb->HCS_Msg[3] > MAX_OFFSET) {
2373                 pCurHcb->HCS_Msg[3] = MAX_OFFSET;
2374                 if (pCurHcb->HCS_Msg[2] < default_period) {
2375                         pCurHcb->HCS_Msg[2] = default_period;
2376                         return 1;
2377                 }
2378                 if (pCurHcb->HCS_Msg[2] >= 59) {        /* Change to async              */
2379                         pCurHcb->HCS_Msg[3] = 0;
2380                 }
2381                 return 1;
2382         }
2383         /* offset requests asynchronous transfers ? */
2384         if (pCurHcb->HCS_Msg[3] == 0) {
2385                 return 0;
2386         }
2387         if (pCurHcb->HCS_Msg[2] < default_period) {
2388                 pCurHcb->HCS_Msg[2] = default_period;
2389                 return 1;
2390         }
2391         if (pCurHcb->HCS_Msg[2] >= 59) {
2392                 pCurHcb->HCS_Msg[3] = 0;
2393                 return 1;
2394         }
2395         return 0;
2396 }
2397
2398
2399 /***************************************************************************/
2400 int wdtr_done(HCS * pCurHcb)
2401 {
2402         pCurHcb->HCS_ActTcs->TCS_Flags &= ~TCF_SYNC_DONE;
2403         pCurHcb->HCS_ActTcs->TCS_Flags |= TCF_WDTR_DONE;
2404
2405         pCurHcb->HCS_ActTcs->TCS_JS_Period = 0;
2406         if (pCurHcb->HCS_Msg[2]) {      /* if 16 bit */
2407                 pCurHcb->HCS_ActTcs->TCS_JS_Period |= TSC_WIDE_SCSI;
2408         }
2409         pCurHcb->HCS_ActTcs->TCS_SConfig0 &= ~TSC_ALT_PERIOD;
2410         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_ActTcs->TCS_SConfig0);
2411         TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurHcb->HCS_ActTcs->TCS_JS_Period);
2412
2413         return 1;
2414 }
2415
2416 /***************************************************************************/
2417 int tul_sync_done(HCS * pCurHcb)
2418 {
2419         int i;
2420
2421         pCurHcb->HCS_ActTcs->TCS_Flags |= TCF_SYNC_DONE;
2422
2423         if (pCurHcb->HCS_Msg[3]) {
2424                 pCurHcb->HCS_ActTcs->TCS_JS_Period |= pCurHcb->HCS_Msg[3];
2425                 for (i = 0; i < 8; i++) {
2426                         if (tul_rate_tbl[i] >= pCurHcb->HCS_Msg[2])     /* pick the big one */
2427                                 break;
2428                 }
2429                 pCurHcb->HCS_ActTcs->TCS_JS_Period |= (i << 4);
2430                 pCurHcb->HCS_ActTcs->TCS_SConfig0 |= TSC_ALT_PERIOD;
2431         }
2432         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_ActTcs->TCS_SConfig0);
2433         TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurHcb->HCS_ActTcs->TCS_JS_Period);
2434
2435         return (-1);
2436 }
2437
2438
2439 int tul_post_scsi_rst(HCS * pCurHcb)
2440 {
2441         SCB *pCurScb;
2442         TCS *pCurTcb;
2443         int i;
2444
2445         pCurHcb->HCS_ActScb = 0;
2446         pCurHcb->HCS_ActTcs = 0;
2447         pCurHcb->HCS_Flags = 0;
2448
2449         while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) {
2450                 pCurScb->SCB_HaStat = HOST_BAD_PHAS;
2451                 tul_append_done_scb(pCurHcb, pCurScb);
2452         }
2453         /* clear sync done flag         */
2454         pCurTcb = &pCurHcb->HCS_Tcs[0];
2455         for (i = 0; i < pCurHcb->HCS_MaxTar; pCurTcb++, i++) {
2456                 pCurTcb->TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
2457                 /* Initialize the sync. xfer register values to an asyn xfer */
2458                 pCurTcb->TCS_JS_Period = 0;
2459                 pCurTcb->TCS_SConfig0 = pCurHcb->HCS_SConf1;
2460                 pCurHcb->HCS_ActTags[0] = 0;    /* 07/22/98 */
2461                 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~TCF_BUSY;     /* 07/22/98 */
2462         }                       /* for */
2463
2464         return (-1);
2465 }
2466
2467 /***************************************************************************/
2468 void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb)
2469 {
2470         pCurScb->SCB_Status |= SCB_SELECT;
2471         pCurScb->SCB_NxtStat = 0x1;
2472         pCurHcb->HCS_ActScb = pCurScb;
2473         pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
2474         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SELATNSTOP);
2475         return;
2476 }
2477
2478
2479 /***************************************************************************/
2480 void tul_select_atn(HCS * pCurHcb, SCB * pCurScb)
2481 {
2482         int i;
2483
2484         pCurScb->SCB_Status |= SCB_SELECT;
2485         pCurScb->SCB_NxtStat = 0x2;
2486
2487         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident);
2488         for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++)
2489                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]);
2490         pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
2491         pCurHcb->HCS_ActScb = pCurScb;
2492         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SEL_ATN);
2493         return;
2494 }
2495
2496 /***************************************************************************/
2497 void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb)
2498 {
2499         int i;
2500
2501         pCurScb->SCB_Status |= SCB_SELECT;
2502         pCurScb->SCB_NxtStat = 0x2;
2503
2504         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident);
2505         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagMsg);
2506         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagId);
2507         for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++)
2508                 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]);
2509         pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
2510         pCurHcb->HCS_ActScb = pCurScb;
2511         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SEL_ATN3);
2512         return;
2513 }
2514
2515 /***************************************************************************/
2516 /* SCSI Bus Device Reset */
2517 int tul_bus_device_reset(HCS * pCurHcb)
2518 {
2519         SCB *pCurScb = pCurHcb->HCS_ActScb;
2520         TCS *pCurTcb = pCurHcb->HCS_ActTcs;
2521         SCB *pTmpScb, *pPrevScb;
2522         BYTE tar;
2523
2524         if (pCurHcb->HCS_Phase != MSG_OUT) {
2525                 return (int_tul_bad_seq(pCurHcb));      /* Unexpected phase             */
2526         }
2527         tul_unlink_pend_scb(pCurHcb, pCurScb);
2528         tul_release_scb(pCurHcb, pCurScb);
2529
2530
2531         tar = pCurScb->SCB_Target;      /* target                       */
2532         pCurTcb->TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE | TCF_BUSY);
2533         /* clr sync. nego & WDTR flags  07/22/98 */
2534
2535         /* abort all SCB with same target */
2536         pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy;    /* Check Busy queue */
2537         while (pTmpScb != NULL) {
2538
2539                 if (pTmpScb->SCB_Target == tar) {
2540                         /* unlink it */
2541                         if (pTmpScb == pCurHcb->HCS_FirstBusy) {
2542                                 if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
2543                                         pCurHcb->HCS_LastBusy = NULL;
2544                         } else {
2545                                 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
2546                                 if (pTmpScb == pCurHcb->HCS_LastBusy)
2547                                         pCurHcb->HCS_LastBusy = pPrevScb;
2548                         }
2549                         pTmpScb->SCB_HaStat = HOST_ABORTED;
2550                         tul_append_done_scb(pCurHcb, pTmpScb);
2551                 }
2552                 /* Previous haven't change      */
2553                 else {
2554                         pPrevScb = pTmpScb;
2555                 }
2556                 pTmpScb = pTmpScb->SCB_NxtScb;
2557         }
2558
2559         TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_DEVRST);
2560         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
2561
2562         return tul_wait_disc(pCurHcb);
2563
2564 }
2565
2566 /***************************************************************************/
2567 int tul_msgin_accept(HCS * pCurHcb)
2568 {
2569         TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
2570         return (wait_tulip(pCurHcb));
2571 }
2572
2573 /***************************************************************************/
2574 int wait_tulip(HCS * pCurHcb)
2575 {
2576
2577         while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0))
2578                  & TSS_INT_PENDING));
2579
2580         pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
2581         pCurHcb->HCS_Phase = pCurHcb->HCS_JSStatus0 & TSS_PH_MASK;
2582         pCurHcb->HCS_JSStatus1 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1);
2583
2584         if (pCurHcb->HCS_JSInt & TSS_RESEL_INT) {       /* if SCSI bus reset detected   */
2585                 return (int_tul_resel(pCurHcb));
2586         }
2587         if (pCurHcb->HCS_JSInt & TSS_SEL_TIMEOUT) {     /* if selected/reselected timeout interrupt */
2588                 return (int_tul_busfree(pCurHcb));
2589         }
2590         if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) {     /* if SCSI bus reset detected   */
2591                 return (int_tul_scsi_rst(pCurHcb));
2592         }
2593         if (pCurHcb->HCS_JSInt & TSS_DISC_INT) {        /* BUS disconnection            */
2594                 if (pCurHcb->HCS_Flags & HCF_EXPECT_DONE_DISC) {
2595                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
2596                         tul_unlink_busy_scb(pCurHcb, pCurHcb->HCS_ActScb);
2597                         pCurHcb->HCS_ActScb->SCB_HaStat = 0;
2598                         tul_append_done_scb(pCurHcb, pCurHcb->HCS_ActScb);
2599                         pCurHcb->HCS_ActScb = NULL;
2600                         pCurHcb->HCS_ActTcs = NULL;
2601                         pCurHcb->HCS_Flags &= ~HCF_EXPECT_DONE_DISC;
2602                         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
2603                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
2604                         return (-1);
2605                 }
2606                 if (pCurHcb->HCS_Flags & HCF_EXPECT_DISC) {
2607                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
2608                         pCurHcb->HCS_ActScb = NULL;
2609                         pCurHcb->HCS_ActTcs = NULL;
2610                         pCurHcb->HCS_Flags &= ~HCF_EXPECT_DISC;
2611                         TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
2612                         TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
2613                         return (-1);
2614                 }
2615                 return (int_tul_busfree(pCurHcb));
2616         }
2617         if (pCurHcb->HCS_JSInt & (TSS_FUNC_COMP | TSS_BUS_SERV)) {
2618                 return (pCurHcb->HCS_Phase);
2619         }
2620         return (pCurHcb->HCS_Phase);
2621 }
2622 /***************************************************************************/
2623 int tul_wait_disc(HCS * pCurHcb)
2624 {
2625
2626         while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0))
2627                  & TSS_INT_PENDING));
2628
2629
2630         pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
2631
2632         if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) {     /* if SCSI bus reset detected   */
2633                 return (int_tul_scsi_rst(pCurHcb));
2634         }
2635         if (pCurHcb->HCS_JSInt & TSS_DISC_INT) {        /* BUS disconnection            */
2636                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
2637                 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
2638                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
2639                 pCurHcb->HCS_ActScb = NULL;
2640                 return (-1);
2641         }
2642         return (tul_bad_seq(pCurHcb));
2643 }
2644
2645 /***************************************************************************/
2646 int tul_wait_done_disc(HCS * pCurHcb)
2647 {
2648
2649
2650         while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0))
2651                  & TSS_INT_PENDING));
2652
2653         pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
2654
2655
2656         if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) {     /* if SCSI bus reset detected   */
2657                 return (int_tul_scsi_rst(pCurHcb));
2658         }
2659         if (pCurHcb->HCS_JSInt & TSS_DISC_INT) {        /* BUS disconnection            */
2660                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);         /* Flush SCSI FIFO  */
2661                 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
2662                 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);        /* Enable HW reselect       */
2663                 tul_unlink_busy_scb(pCurHcb, pCurHcb->HCS_ActScb);
2664
2665                 tul_append_done_scb(pCurHcb, pCurHcb->HCS_ActScb);
2666                 pCurHcb->HCS_ActScb = NULL;
2667                 return (-1);
2668         }
2669         return (tul_bad_seq(pCurHcb));
2670 }
2671
2672 /**************************** EOF *********************************/