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