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