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