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