1139747Simp/*======================================================================
24Srgrimes
34Srgrimes    NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI host adapter card driver
44Srgrimes      By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
58876Srgrimes
64Srgrimes    Ver.2.8   Support 32bit MMIO mode
74Srgrimes              Support Synchronous Data Transfer Request (SDTR) mode
84Srgrimes    Ver.2.0   Support 32bit PIO mode
94Srgrimes    Ver.1.1.2 Fix for scatter list buffer exceeds
104Srgrimes    Ver.1.1   Support scatter list
118876Srgrimes    Ver.0.1   Initial version
128876Srgrimes
134Srgrimes    This software may be used and distributed according to the terms of
144Srgrimes    the GNU General Public License.
158876Srgrimes
164Srgrimes======================================================================*/
178876Srgrimes
184Srgrimes/***********************************************************************
194Srgrimes    This driver is for these PCcards.
204Srgrimes
214Srgrimes	I-O DATA PCSC-F	 (Workbit NinjaSCSI-3)
228876Srgrimes			"WBT", "NinjaSCSI-3", "R1.0"
234Srgrimes	I-O DATA CBSC-II (Workbit NinjaSCSI-32Bi in 16bit mode)
244Srgrimes			"IO DATA", "CBSC16	 ", "1"
254Srgrimes
264Srgrimes***********************************************************************/
274Srgrimes
284Srgrimes#include <linux/module.h>
294Srgrimes#include <linux/kernel.h>
304Srgrimes#include <linux/init.h>
314Srgrimes#include <linux/slab.h>
324Srgrimes#include <linux/string.h>
33116176Sobrien#include <linux/timer.h>
34116176Sobrien#include <linux/ioport.h>
35116176Sobrien#include <linux/delay.h>
36116176Sobrien#include <linux/interrupt.h>
372056Swollman#include <linux/major.h>
3842654Sjdp#include <linux/blkdev.h>
3986998Sdd#include <linux/stat.h>
40131952Smarcel
4186998Sdd#include <asm/io.h>
4286998Sdd#include <asm/irq.h>
4317848Spst
4486998Sdd#include <scsi/scsi.h>
452056Swollman#include <scsi/scsi_cmnd.h>
4649558Sphk#include <scsi/scsi_host.h>
47126399Sphk#include <scsi/scsi_ioctl.h>
4812734Sbde
492056Swollman#include <pcmcia/cistpl.h>
5012473Sbde#include <pcmcia/cisreg.h>
514Srgrimes#include <pcmcia/ds.h>
524Srgrimes
534Srgrimes#include "nsp_cs.h"
54118990Smarcel
5579418SjulianMODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
564SrgrimesMODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
574SrgrimesMODULE_LICENSE("GPL");
584Srgrimes
594Srgrimes#include "nsp_io.h"
604Srgrimes
6118296Sbde/*====================================================================*/
624Srgrimes/* Parameters that can be set with 'insmod' */
634Srgrimes
644Srgrimesstatic int       nsp_burst_mode = BURST_MEM32;
654Srgrimesmodule_param(nsp_burst_mode, int, 0);
6678161SpeterMODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
6778161Speter
6878161Speter/* Release IO ports after configuration? */
6912515Sphkstatic bool       free_ports = 0;
70132002Smarcelmodule_param(free_ports, bool, 0);
7186998SddMODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
7285944Speter
73132482Smarcelstatic struct scsi_pointer *nsp_priv(struct scsi_cmnd *cmd)
74150819Srwatson{
75126399Sphk	return scsi_cmd_priv(cmd);
7617848Spst}
77148919Sobrien
78148919Sobrienstatic struct scsi_host_template nsp_driver_template = {
79148919Sobrien	.proc_name	         = "nsp_cs",
8018296Sbde	.show_info		 = nsp_show_info,
81148919Sobrien	.name			 = "WorkBit NinjaSCSI-3/32Bi(16bit)",
82148919Sobrien	.info			 = nsp_info,
83148919Sobrien	.queuecommand		 = nsp_queuecommand,
84148919Sobrien/*	.eh_abort_handler	 = nsp_eh_abort,*/
85148919Sobrien	.eh_bus_reset_handler	 = nsp_eh_bus_reset,
86156412Sjhb	.eh_host_reset_handler	 = nsp_eh_host_reset,
87156412Sjhb	.can_queue		 = 1,
88156412Sjhb	.this_id		 = NSP_INITIATOR_ID,
89156412Sjhb	.sg_tablesize		 = SG_ALL,
90148919Sobrien	.dma_boundary		 = PAGE_SIZE - 1,
91156412Sjhb	.cmd_size		 = sizeof(struct scsi_pointer),
92148919Sobrien};
93148919Sobrien
94148919Sobrienstatic nsp_hw_data nsp_data_base; /* attach <-> detect glue */
95148919Sobrien
96148919Sobrien
97148919Sobrien
98156412Sjhb/*
99156412Sjhb * debug, error print
100156412Sjhb */
101156412Sjhb#ifndef NSP_DEBUG
102156412Sjhb# define NSP_DEBUG_MASK		0x000000
103156412Sjhb# define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
104156412Sjhb# define nsp_dbg(mask, args...) /* */
105148919Sobrien#else
106148919Sobrien# define NSP_DEBUG_MASK		0xffffff
107148919Sobrien# define nsp_msg(type, args...) \
108148919Sobrien	nsp_cs_message (__func__, __LINE__, (type), args)
109148919Sobrien# define nsp_dbg(mask, args...) \
110148919Sobrien	nsp_cs_dmessage(__func__, __LINE__, (mask), args)
111148919Sobrien#endif
112148919Sobrien
113148919Sobrien#define NSP_DEBUG_QUEUECOMMAND		BIT(0)
114148919Sobrien#define NSP_DEBUG_REGISTER		BIT(1)
115148919Sobrien#define NSP_DEBUG_AUTOSCSI		BIT(2)
116163135Sbde#define NSP_DEBUG_INTR			BIT(3)
117148919Sobrien#define NSP_DEBUG_SGLIST		BIT(4)
118148919Sobrien#define NSP_DEBUG_BUSFREE		BIT(5)
119148919Sobrien#define NSP_DEBUG_CDB_CONTENTS		BIT(6)
120148919Sobrien#define NSP_DEBUG_RESELECTION		BIT(7)
121148919Sobrien#define NSP_DEBUG_MSGINOCCUR		BIT(8)
122148919Sobrien#define NSP_DEBUG_EEPROM		BIT(9)
123148919Sobrien#define NSP_DEBUG_MSGOUTOCCUR		BIT(10)
124148919Sobrien#define NSP_DEBUG_BUSRESET		BIT(11)
125148919Sobrien#define NSP_DEBUG_RESTART		BIT(12)
126148919Sobrien#define NSP_DEBUG_SYNC			BIT(13)
127148919Sobrien#define NSP_DEBUG_WAIT			BIT(14)
128148919Sobrien#define NSP_DEBUG_TARGETFLAG		BIT(15)
129163135Sbde#define NSP_DEBUG_PROC			BIT(16)
130151622Sjhb#define NSP_DEBUG_INIT			BIT(17)
131148919Sobrien#define NSP_DEBUG_DATA_IO      		BIT(18)
132151622Sjhb#define NSP_SPECIAL_PRINT_REGISTER	BIT(20)
133148919Sobrien
134156412Sjhb#define NSP_DEBUG_BUF_LEN		150
135148919Sobrien
136148919Sobrienstatic inline void nsp_inc_resid(struct scsi_cmnd *SCpnt, int residInc)
137163135Sbde{
138148919Sobrien	scsi_set_resid(SCpnt, scsi_get_resid(SCpnt) + residInc);
139148919Sobrien}
140148919Sobrien
141148919Sobrien__printf(4, 5)
142148919Sobrienstatic void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
143148919Sobrien{
144148919Sobrien	va_list args;
145156412Sjhb	char buf[NSP_DEBUG_BUF_LEN];
146156412Sjhb
147156412Sjhb	va_start(args, fmt);
148156412Sjhb	vsnprintf(buf, sizeof(buf), fmt, args);
149156412Sjhb	va_end(args);
150156412Sjhb
151148919Sobrien#ifndef NSP_DEBUG
152148919Sobrien	printk("%snsp_cs: %s\n", type, buf);
1534Srgrimes#else
1544Srgrimes	printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
1554Srgrimes#endif
1564Srgrimes}
1574Srgrimes
15812515Sphk#ifdef NSP_DEBUG
1594Srgrimesstatic void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
1604Srgrimes{
1614Srgrimes	va_list args;
1624Srgrimes	char buf[NSP_DEBUG_BUF_LEN];
1634Srgrimes
1644Srgrimes	va_start(args, fmt);
1654Srgrimes	vsnprintf(buf, sizeof(buf), fmt, args);
1664Srgrimes	va_end(args);
1674Srgrimes
1684Srgrimes	if (mask & NSP_DEBUG_MASK) {
1694Srgrimes		printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
1704Srgrimes	}
1714Srgrimes}
1724Srgrimes#endif
1734Srgrimes
1744Srgrimes/***********************************************************/
1754Srgrimes
1764Srgrimes/*====================================================
1774Srgrimes * Clenaup parameters and call done() functions.
1784Srgrimes * You must be set SCpnt->result before call this function.
1794Srgrimes */
1804Srgrimesstatic void nsp_scsi_done(struct scsi_cmnd *SCpnt)
181156412Sjhb{
182156412Sjhb	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
183156412Sjhb
184156412Sjhb	data->CurrentSC = NULL;
185156412Sjhb
18692756Salfred	scsi_done(SCpnt);
187156412Sjhb}
18812473Sbde
1894Srgrimesstatic int nsp_queuecommand_lck(struct scsi_cmnd *const SCpnt)
190156412Sjhb{
1914Srgrimes	struct scsi_pointer *scsi_pointer = nsp_priv(SCpnt);
192156412Sjhb#ifdef NSP_DEBUG
193156412Sjhb	/*unsigned int host_id = SCpnt->device->host->this_id;*/
1944Srgrimes	/*unsigned int base    = SCpnt->device->host->io_port;*/
195156412Sjhb	unsigned char target = scmd_id(SCpnt);
1964Srgrimes#endif
197156412Sjhb	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1984Srgrimes
199156412Sjhb	nsp_dbg(NSP_DEBUG_QUEUECOMMAND,
200156412Sjhb		"SCpnt=0x%p target=%d lun=%llu sglist=0x%p bufflen=%d sg_count=%d",
2014Srgrimes		SCpnt, target, SCpnt->device->lun, scsi_sglist(SCpnt),
202156412Sjhb		scsi_bufflen(SCpnt), scsi_sg_count(SCpnt));
203156412Sjhb	//nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
204156412Sjhb
2054Srgrimes	if (data->CurrentSC != NULL) {
206156412Sjhb		nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
207156412Sjhb		SCpnt->result   = DID_BAD_TARGET << 16;
208156412Sjhb		nsp_scsi_done(SCpnt);
209156412Sjhb		return 0;
2104Srgrimes	}
2114Srgrimes
2124Srgrimes#if 0
213156412Sjhb	/* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
214156412Sjhb	        This makes kernel crash when suspending... */
2154Srgrimes	if (data->ScsiInfo->stop != 0) {
2164Srgrimes		nsp_msg(KERN_INFO, "suspending device. reject command.");
217156412Sjhb		SCpnt->result  = DID_BAD_TARGET << 16;
218156412Sjhb		nsp_scsi_done(SCpnt);
219156412Sjhb		return SCSI_MLQUEUE_HOST_BUSY;
220156412Sjhb	}
221156412Sjhb#endif
222156412Sjhb
223156412Sjhb	show_command(SCpnt);
2244Srgrimes
2254Srgrimes	data->CurrentSC		= SCpnt;
226156412Sjhb
22718296Sbde	scsi_pointer->Status	   = SAM_STAT_CHECK_CONDITION;
228156412Sjhb	scsi_pointer->Message	   = 0;
229156412Sjhb	scsi_pointer->have_data_in = IO_UNKNOWN;
230156412Sjhb	scsi_pointer->sent_command = 0;
231156412Sjhb	scsi_pointer->phase	   = PH_UNDETERMINED;
232156412Sjhb	scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
233156412Sjhb
234156412Sjhb	/* setup scratch area
235156412Sjhb	   SCp.ptr		: buffer pointer
236156412Sjhb	   SCp.this_residual	: buffer length
237156412Sjhb	   SCp.buffer		: next buffer
238156412Sjhb	   SCp.buffers_residual : left buffers in list
239156412Sjhb	   SCp.phase		: current state of the command */
240156412Sjhb	if (scsi_bufflen(SCpnt)) {
241156412Sjhb		scsi_pointer->buffer	       = scsi_sglist(SCpnt);
242156412Sjhb		scsi_pointer->ptr	       = BUFFER_ADDR(SCpnt);
243156412Sjhb		scsi_pointer->this_residual    = scsi_pointer->buffer->length;
24418296Sbde		scsi_pointer->buffers_residual = scsi_sg_count(SCpnt) - 1;
245156412Sjhb	} else {
246156412Sjhb		scsi_pointer->ptr	       = NULL;
247156412Sjhb		scsi_pointer->this_residual    = 0;
248156412Sjhb		scsi_pointer->buffer	       = NULL;
249156412Sjhb		scsi_pointer->buffers_residual = 0;
250156412Sjhb	}
251156412Sjhb
252156412Sjhb	if (!nsphw_start_selection(SCpnt)) {
25318296Sbde		nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
2544Srgrimes		SCpnt->result   = DID_BUS_BUSY << 16;
255156412Sjhb		nsp_scsi_done(SCpnt);
2564Srgrimes		return 0;
2574Srgrimes	}
2584Srgrimes
2594Srgrimes
2604Srgrimes	//nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
2614Srgrimes#ifdef NSP_DEBUG
2624Srgrimes	data->CmdId++;
26312515Sphk#endif
264156412Sjhb	return 0;
265156412Sjhb}
2664Srgrimes
2674Srgrimesstatic DEF_SCSI_QCMD(nsp_queuecommand)
26818296Sbde
2694Srgrimes/*
270156412Sjhb * setup PIO FIFO transfer mode and enable/disable to data out
2714Srgrimes */
272163134Sbdestatic void nsp_setup_fifo(nsp_hw_data *data, bool enabled)
2734Srgrimes{
274156412Sjhb	unsigned int  base = data->BaseAddress;
27518296Sbde	unsigned char transfer_mode_reg;
276156412Sjhb
277156412Sjhb	//nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
27818296Sbde
279163134Sbde	if (enabled) {
28018296Sbde		transfer_mode_reg = TRANSFER_GO | BRAIND;
2814Srgrimes	} else {
2824Srgrimes		transfer_mode_reg = 0;
28312515Sphk	}
284156412Sjhb
2854Srgrimes	transfer_mode_reg |= data->TransferMode;
286156412Sjhb
2874Srgrimes	nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
2884Srgrimes}
2894Srgrimes
2904Srgrimesstatic void nsphw_init_sync(nsp_hw_data *data)
2914Srgrimes{
292798Swollman	sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
2934Srgrimes			       .SyncPeriod      = 0,
2944Srgrimes			       .SyncOffset      = 0
2954Srgrimes	};
2964Srgrimes	int i;
2974Srgrimes
2984Srgrimes	/* setup sync data */
2994Srgrimes	for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
3004Srgrimes		data->Sync[i] = tmp_sync;
3014Srgrimes	}
3024Srgrimes}
3034Srgrimes
3044Srgrimes/*
30510348Sbde * Initialize Ninja hardware
3064Srgrimes */
3074Srgrimesstatic void nsphw_init(nsp_hw_data *data)
3084Srgrimes{
3094Srgrimes	unsigned int base     = data->BaseAddress;
3104Srgrimes
3114Srgrimes	nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
3124Srgrimes
3134Srgrimes	data->ScsiClockDiv = CLOCK_40M | FAST_20;
3144Srgrimes	data->CurrentSC    = NULL;
3154Srgrimes	data->FifoCount    = 0;
3164Srgrimes	data->TransferMode = MODE_IO8;
3174Srgrimes
3184Srgrimes	nsphw_init_sync(data);
3194Srgrimes
3204Srgrimes	/* block all interrupts */
3214Srgrimes	nsp_write(base,	      IRQCONTROL,   IRQCONTROL_ALLMASK);
3224Srgrimes
3234Srgrimes	/* setup SCSI interface */
3244Srgrimes	nsp_write(base,	      IFSELECT,	    IF_IFSEL);
3254Srgrimes
3264Srgrimes	nsp_index_write(base, SCSIIRQMODE,  0);
3274Srgrimes
3284Srgrimes	nsp_index_write(base, TRANSFERMODE, MODE_IO8);
3294Srgrimes	nsp_index_write(base, CLOCKDIV,	    data->ScsiClockDiv);
3304Srgrimes
331156412Sjhb	nsp_index_write(base, PARITYCTRL,   0);
3324Srgrimes	nsp_index_write(base, POINTERCLR,   POINTER_CLEAR     |
3334Srgrimes					    ACK_COUNTER_CLEAR |
3344Srgrimes					    REQ_COUNTER_CLEAR |
3354Srgrimes					    HOST_COUNTER_CLEAR);
3364Srgrimes
337156412Sjhb	/* setup fifo asic */
3384Srgrimes	nsp_write(base,	      IFSELECT,	    IF_REGSEL);
3394Srgrimes	nsp_index_write(base, TERMPWRCTRL,  0);
340156412Sjhb	if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
3414Srgrimes		nsp_msg(KERN_INFO, "terminator power on");
3424Srgrimes		nsp_index_write(base, TERMPWRCTRL, POWER_ON);
3434Srgrimes	}
3444Srgrimes
3454Srgrimes	nsp_index_write(base, TIMERCOUNT,   0);
3464Srgrimes	nsp_index_write(base, TIMERCOUNT,   0); /* requires 2 times!! */
3474Srgrimes
3484Srgrimes	nsp_index_write(base, SYNCREG,	    0);
3494Srgrimes	nsp_index_write(base, ACKWIDTH,	    0);
3504Srgrimes
3514Srgrimes	/* enable interrupts and ack them */
3524Srgrimes	nsp_index_write(base, SCSIIRQMODE,  SCSI_PHASE_CHANGE_EI |
3534Srgrimes					    RESELECT_EI		 |
3544Srgrimes					    SCSI_RESET_IRQ_EI	 );
3554Srgrimes	nsp_write(base,	      IRQCONTROL,   IRQCONTROL_ALLCLEAR);
3564Srgrimes
3574Srgrimes	nsp_setup_fifo(data, false);
3584Srgrimes}
3594Srgrimes
3604Srgrimes/*
3614Srgrimes * Start selection phase
3624Srgrimes */
3634Srgrimesstatic bool nsphw_start_selection(struct scsi_cmnd *const SCpnt)
3644Srgrimes{
3654Srgrimes	struct scsi_pointer *scsi_pointer = nsp_priv(SCpnt);
3664Srgrimes	unsigned int  host_id	 = SCpnt->device->host->this_id;
3674Srgrimes	unsigned int  base	 = SCpnt->device->host->io_port;
3684Srgrimes	unsigned char target	 = scmd_id(SCpnt);
3694Srgrimes	nsp_hw_data  *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
3704Srgrimes	int	      time_out;
3714Srgrimes	unsigned char phase, arbit;
3724Srgrimes
3734Srgrimes	//nsp_dbg(NSP_DEBUG_RESELECTION, "in");
3744Srgrimes
3754Srgrimes	phase = nsp_index_read(base, SCSIBUSMON);
3764Srgrimes	if(phase != BUSMON_BUS_FREE) {
3774Srgrimes		//nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
3784Srgrimes		return false;
3794Srgrimes	}
3804Srgrimes
3814Srgrimes	/* start arbitration */
3824Srgrimes	//nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
3834Srgrimes	scsi_pointer->phase = PH_ARBSTART;
3844Srgrimes	nsp_index_write(base, SETARBIT, ARBIT_GO);
3854Srgrimes
3864Srgrimes	time_out = 1000;
3874Srgrimes	do {
3884Srgrimes		/* XXX: what a stupid chip! */
3894Srgrimes		arbit = nsp_index_read(base, ARBITSTATUS);
3904Srgrimes		//nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
3914Srgrimes		udelay(1); /* hold 1.2us */
3924Srgrimes	} while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
3934Srgrimes		(time_out-- != 0));
3944Srgrimes
3954Srgrimes	if (!(arbit & ARBIT_WIN)) {
3964Srgrimes		//nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
3974Srgrimes		nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
398160312Sjhb		return false;
3994Srgrimes	}
400160312Sjhb
4014Srgrimes	/* assert select line */
4024Srgrimes	//nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
4034Srgrimes	scsi_pointer->phase = PH_SELSTART;
4044Srgrimes	udelay(3); /* wait 2.4us */
4054Srgrimes	nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
4064Srgrimes	nsp_index_write(base, SCSIBUSCTRL,   SCSI_SEL | SCSI_BSY                    | SCSI_ATN);
4074Srgrimes	udelay(2); /* wait >1.2us */
4084Srgrimes	nsp_index_write(base, SCSIBUSCTRL,   SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
4094Srgrimes	nsp_index_write(base, SETARBIT,	     ARBIT_FLAG_CLEAR);
4104Srgrimes	/*udelay(1);*/ /* wait >90ns */
4114Srgrimes	nsp_index_write(base, SCSIBUSCTRL,   SCSI_SEL            | SCSI_DATAOUT_ENB | SCSI_ATN);
4124Srgrimes
4134Srgrimes	/* check selection timeout */
4144Srgrimes	nsp_start_timer(SCpnt, 1000/51);
4154Srgrimes	data->SelectionTimeOut = 1;
4164Srgrimes
4174Srgrimes	return true;
4184Srgrimes}
4194Srgrimes
4204Srgrimesstruct nsp_sync_table {
4214Srgrimes	unsigned int min_period;
4224Srgrimes	unsigned int max_period;
4234Srgrimes	unsigned int chip_period;
4244Srgrimes	unsigned int ack_width;
42533296Sbde};
42633296Sbde
42733296Sbdestatic struct nsp_sync_table nsp_sync_table_40M[] = {
42833296Sbde	{0x0c, 0x0c, 0x1, 0},	/* 20MB	  50ns*/
4296204Sphk	{0x19, 0x19, 0x3, 1},	/* 10MB	 100ns*/
430160505Sjhb	{0x1a, 0x25, 0x5, 2},	/* 7.5MB 150ns*/
4317170Sdg	{0x26, 0x32, 0x7, 3},	/* 5MB	 200ns*/
4326204Sphk	{   0,    0,   0, 0},
4336204Sphk};
4346204Sphk
4354Srgrimesstatic struct nsp_sync_table nsp_sync_table_20M[] = {
4364Srgrimes	{0x19, 0x19, 0x1, 0},	/* 10MB	 100ns*/
4374Srgrimes	{0x1a, 0x25, 0x2, 0},	/* 7.5MB 150ns*/
4384Srgrimes	{0x26, 0x32, 0x3, 1},	/* 5MB	 200ns*/
4394Srgrimes	{   0,    0,   0, 0},
4404Srgrimes};
4414Srgrimes
4424Srgrimes/*
4434Srgrimes * setup synchronous data transfer mode
4444Srgrimes */
4454Srgrimesstatic int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt)
4464Srgrimes{
4474Srgrimes	unsigned char	       target = scmd_id(SCpnt);
4484Srgrimes//	unsigned char	       lun    = SCpnt->device->lun;
4494Srgrimes	nsp_hw_data           *data   = (nsp_hw_data *)SCpnt->device->host->hostdata;
4504Srgrimes	sync_data	      *sync   = &(data->Sync[target]);
451156412Sjhb	struct nsp_sync_table *sync_table;
4524Srgrimes	unsigned int	       period, offset;
4534Srgrimes
4544Srgrimes	nsp_dbg(NSP_DEBUG_SYNC, "in");
4554Srgrimes
4564Srgrimes	period = sync->SyncPeriod;
457103746Smarkm	offset = sync->SyncOffset;
4584Srgrimes
4594Srgrimes	nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
46079884Skris
4614Srgrimes	if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
462131952Smarcel		sync_table = nsp_sync_table_20M;
4634Srgrimes	} else {
4644Srgrimes		sync_table = nsp_sync_table_40M;
4654Srgrimes	}
4664Srgrimes
4674Srgrimes	for (; sync_table->max_period != 0; sync_table++) {
4684Srgrimes		if ( period >= sync_table->min_period &&
4694Srgrimes		     period <= sync_table->max_period	 ) {
470147745Smarcel			break;
471147745Smarcel		}
472147745Smarcel	}
473147745Smarcel
474147745Smarcel	if (period != 0 && sync_table->max_period == 0) {
475147745Smarcel		/*
476147745Smarcel		 * No proper period/offset found
477147745Smarcel		 */
478147745Smarcel		nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
479147745Smarcel
480147745Smarcel		sync->SyncPeriod      = 0;
481147745Smarcel		sync->SyncOffset      = 0;
482147745Smarcel		sync->SyncRegister    = 0;
483147745Smarcel		sync->AckWidth	      = 0;
484147745Smarcel
485147745Smarcel		return false;
486147745Smarcel	}
487147745Smarcel
488147745Smarcel	sync->SyncRegister    = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
48912515Sphk		                (offset & SYNCREG_OFFSET_MASK);
49010348Sbde	sync->AckWidth	      = sync_table->ack_width;
49110348Sbde
49210348Sbde	nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
49310348Sbde
49410348Sbde	return true;
4954Srgrimes}
4964Srgrimes
497147745Smarcel
4984Srgrimes/*
4994Srgrimes * start ninja hardware timer
5004Srgrimes */
5014Srgrimesstatic void nsp_start_timer(struct scsi_cmnd *SCpnt, int time)
5024Srgrimes{
5034Srgrimes	unsigned int base = SCpnt->device->host->io_port;
5044Srgrimes	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
5054Srgrimes
5064Srgrimes	//nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
5074Srgrimes	data->TimerCount = time;
5084Srgrimes	nsp_index_write(base, TIMERCOUNT, time);
5094Srgrimes}
5104Srgrimes
5114Srgrimes/*
5124Srgrimes * wait for bus phase change
513147745Smarcel */
514147745Smarcelstatic int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask,
5154Srgrimes			     char *str)
5164Srgrimes{
5174Srgrimes	unsigned int  base = SCpnt->device->host->io_port;
5184Srgrimes	unsigned char reg;
5194Srgrimes	int	      time_out;
5204Srgrimes
5214Srgrimes	//nsp_dbg(NSP_DEBUG_INTR, "in");
5224Srgrimes
5234Srgrimes	time_out = 100;
5244Srgrimes
5254Srgrimes	do {
5264Srgrimes		reg = nsp_index_read(base, SCSIBUSMON);
5274Srgrimes		if (reg == 0xff) {
5284Srgrimes			break;
5294Srgrimes		}
5304Srgrimes	} while ((--time_out != 0) && (reg & mask) != 0);
5314Srgrimes
5324Srgrimes	if (time_out == 0) {
5334Srgrimes		nsp_msg(KERN_DEBUG, " %s signal off timeout", str);
534160505Sjhb	}
5354Srgrimes
536147745Smarcel	return 0;
537147745Smarcel}
5384Srgrimes
53917848Spst/*
54017848Spst * expect Ninja Irq
54186998Sdd */
54286998Sddstatic int nsp_expect_signal(struct scsi_cmnd *SCpnt,
54386998Sdd			     unsigned char current_phase,
54486998Sdd			     unsigned char mask)
54586998Sdd{
54686998Sdd	unsigned int  base	 = SCpnt->device->host->io_port;
54786998Sdd	int	      time_out;
54886998Sdd	unsigned char phase, i_src;
54986998Sdd
55086998Sdd	//nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
55186998Sdd
55286998Sdd	time_out = 100;
55386998Sdd	do {
55486998Sdd		phase = nsp_index_read(base, SCSIBUSMON);
55586998Sdd		if (phase == 0xff) {
55686998Sdd			//nsp_dbg(NSP_DEBUG_INTR, "ret -1");
55786998Sdd			return -1;
55886998Sdd		}
55986998Sdd		i_src = nsp_read(base, IRQSTATUS);
56086998Sdd		if (i_src & IRQSTATUS_SCSI) {
56186998Sdd			//nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
56286998Sdd			return 0;
56386998Sdd		}
56486998Sdd		if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
56586998Sdd			//nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
56686998Sdd			return 1;
56786998Sdd		}
56886998Sdd	} while(time_out-- != 0);
56986998Sdd
57086998Sdd	//nsp_dbg(NSP_DEBUG_INTR, "timeout");
57186998Sdd	return -1;
57286998Sdd}
57386998Sdd
57486998Sdd/*
57586998Sdd * transfer SCSI message
57686998Sdd */
57786998Sddstatic int nsp_xfer(struct scsi_cmnd *const SCpnt, int phase)
57889442Smjacob{
57986998Sdd	struct scsi_pointer *scsi_pointer = nsp_priv(SCpnt);
58086998Sdd	unsigned int  base = SCpnt->device->host->io_port;
58186998Sdd	nsp_hw_data  *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
58289442Smjacob	char	     *buf  = data->MsgBuffer;
58386998Sdd	int	      len  = min(MSGBUF_SIZE, data->MsgLen);
58486998Sdd	int	      ptr;
58586998Sdd	int	      ret;
58686998Sdd
58786998Sdd	//nsp_dbg(NSP_DEBUG_DATA_IO, "in");
58886998Sdd	for (ptr = 0; len > 0; len--, ptr++) {
58986998Sdd
59086998Sdd		ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
59186998Sdd		if (ret <= 0) {
59286998Sdd			nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
59386998Sdd			return 0;
59485944Speter		}
59585944Speter
59685944Speter		/* if last byte, negate ATN */
59785944Speter		if (len == 1 && scsi_pointer->phase == PH_MSG_OUT) {
59885944Speter			nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
59985944Speter		}
60085944Speter
60185944Speter		/* read & write message */
60285944Speter		if (phase & BUSMON_IO) {
603126399Sphk			nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
604126399Sphk			buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
605126399Sphk		} else {
606126399Sphk			nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
607126399Sphk			nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
608126399Sphk		}
609126399Sphk		nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
610126399Sphk
611126399Sphk	}
612126399Sphk	return len;
613126399Sphk}
614126399Sphk
615126399Sphk/*
616126399Sphk * get extra SCSI data from fifo
617126399Sphk */
618126399Sphkstatic int nsp_dataphase_bypass(struct scsi_cmnd *const SCpnt)
619126399Sphk{
620126399Sphk	struct scsi_pointer *scsi_pointer = nsp_priv(SCpnt);
621132002Smarcel	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
622132002Smarcel	unsigned int count;
623132002Smarcel
624132002Smarcel	//nsp_dbg(NSP_DEBUG_DATA_IO, "in");
625132002Smarcel
626132002Smarcel	if (scsi_pointer->have_data_in != IO_IN) {
627132002Smarcel		return 0;
628132002Smarcel	}
629132002Smarcel
630132002Smarcel	count = nsp_fifo_count(SCpnt);
631132482Smarcel	if (data->FifoCount == count) {
632132482Smarcel		//nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
633132482Smarcel		return 0;
634132482Smarcel	}
635132482Smarcel
636132482Smarcel	/*
637138038Srwatson	 * XXX: NSP_QUIRK
638132482Smarcel	 * data phase skip only occures in case of SCSI_LOW_READ
639132482Smarcel	 */
640132482Smarcel	nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
641132482Smarcel	scsi_pointer->phase = PH_DATA;
642132482Smarcel	nsp_pio_read(SCpnt);
643132482Smarcel	nsp_setup_fifo(data, false);
644132482Smarcel
645132482Smarcel	return 0;
646132482Smarcel}
647132482Smarcel
648132482Smarcel/*
649132482Smarcel * accept reselection
650132482Smarcel */
651132482Smarcelstatic void nsp_reselected(struct scsi_cmnd *SCpnt)
652132482Smarcel{
653132482Smarcel	unsigned int  base    = SCpnt->device->host->io_port;
654132482Smarcel	unsigned int  host_id = SCpnt->device->host->this_id;
655132482Smarcel	//nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
656132482Smarcel	unsigned char bus_reg;
657132482Smarcel	unsigned char id_reg, tmp;
658132482Smarcel	int target;
659132482Smarcel
660132482Smarcel	nsp_dbg(NSP_DEBUG_RESELECTION, "in");
661132482Smarcel
662132482Smarcel	id_reg = nsp_index_read(base, RESELECTID);
663132482Smarcel	tmp    = id_reg & (~BIT(host_id));
664132482Smarcel	target = 0;
665132482Smarcel	while(tmp != 0) {
666132482Smarcel		if (tmp & BIT(0)) {
667132482Smarcel			break;
668132482Smarcel		}
669132482Smarcel		tmp >>= 1;
670138038Srwatson		target++;
671138038Srwatson	}
672138038Srwatson
673138038Srwatson	if (scmd_id(SCpnt) != target) {
674138038Srwatson		nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
675132482Smarcel	}
676132482Smarcel
677150819Srwatson	nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
678150819Srwatson
679150819Srwatson	nsp_nexus(SCpnt);
680150819Srwatson	bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
681150819Srwatson	nsp_index_write(base, SCSIBUSCTRL, bus_reg);
682150819Srwatson	nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
683150819Srwatson}
684150819Srwatson
685157951Sjhb/*
686150819Srwatson * count how many data transferd
687150819Srwatson */
688150819Srwatsonstatic int nsp_fifo_count(struct scsi_cmnd *SCpnt)
689150819Srwatson{
690160312Sjhb	unsigned int base = SCpnt->device->host->io_port;
691150842Scognet	unsigned int count;
692150819Srwatson	unsigned int l, m, h;
693150819Srwatson
694150819Srwatson	nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
695
696	l     = nsp_index_read(base, TRANSFERCOUNT);
697	m     = nsp_index_read(base, TRANSFERCOUNT);
698	h     = nsp_index_read(base, TRANSFERCOUNT);
699	nsp_index_read(base, TRANSFERCOUNT); /* required this! */
700
701	count = (h << 16) | (m << 8) | (l << 0);
702
703	//nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
704
705	return count;
706}
707
708/* fifo size */
709#define RFIFO_CRIT 64
710#define WFIFO_CRIT 64
711
712/*
713 * read data in DATA IN phase
714 */
715static void nsp_pio_read(struct scsi_cmnd *const SCpnt)
716{
717	struct scsi_pointer *scsi_pointer = nsp_priv(SCpnt);
718	unsigned int  base      = SCpnt->device->host->io_port;
719	unsigned long mmio_base = SCpnt->device->host->base;
720	nsp_hw_data  *data      = (nsp_hw_data *)SCpnt->device->host->hostdata;
721	long	      time_out;
722	int	      ocount, res;
723	unsigned char stat, fifo_stat;
724
725	ocount = data->FifoCount;
726
727	nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d",
728		SCpnt, scsi_get_resid(SCpnt), ocount, scsi_pointer->ptr,
729		scsi_pointer->this_residual, scsi_pointer->buffer,
730		scsi_pointer->buffers_residual);
731
732	time_out = 1000;
733
734	while ((time_out-- != 0) &&
735	       (scsi_pointer->this_residual > 0 ||
736		scsi_pointer->buffers_residual > 0)) {
737
738		stat = nsp_index_read(base, SCSIBUSMON);
739		stat &= BUSMON_PHASE_MASK;
740
741
742		res = nsp_fifo_count(SCpnt) - ocount;
743		//nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x ocount=0x%x res=0x%x", scsi_pointer->ptr, scsi_pointer->this_residual, ocount, res);
744		if (res == 0) { /* if some data available ? */
745			if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
746				//nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", scsi_pointer->this_residual);
747				continue;
748			} else {
749				nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
750				break;
751			}
752		}
753
754		fifo_stat = nsp_read(base, FIFOSTATUS);
755		if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
756		    stat                                == BUSPHASE_DATA_IN) {
757			continue;
758		}
759
760		res = min(res, scsi_pointer->this_residual);
761
762		switch (data->TransferMode) {
763		case MODE_IO32:
764			res &= ~(BIT(1)|BIT(0)); /* align 4 */
765			nsp_fifo32_read(base, scsi_pointer->ptr, res >> 2);
766			break;
767		case MODE_IO8:
768			nsp_fifo8_read(base, scsi_pointer->ptr, res);
769			break;
770
771		case MODE_MEM32:
772			res &= ~(BIT(1)|BIT(0)); /* align 4 */
773			nsp_mmio_fifo32_read(mmio_base, scsi_pointer->ptr,
774					     res >> 2);
775			break;
776
777		default:
778			nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
779			return;
780		}
781
782		nsp_inc_resid(SCpnt, -res);
783		scsi_pointer->ptr += res;
784		scsi_pointer->this_residual -= res;
785		ocount			 += res;
786		//nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", scsi_pointer->ptr, scsi_pointer->this_residual, ocount);
787
788		/* go to next scatter list if available */
789		if (scsi_pointer->this_residual	== 0 &&
790		    scsi_pointer->buffers_residual != 0 ) {
791			//nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
792			scsi_pointer->buffers_residual--;
793			scsi_pointer->buffer = sg_next(scsi_pointer->buffer);
794			scsi_pointer->ptr = BUFFER_ADDR(SCpnt);
795			scsi_pointer->this_residual =
796				scsi_pointer->buffer->length;
797			time_out = 1000;
798
799			//nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", scsi_pointer->buffer->page, scsi_pointer->buffer->offset);
800		}
801	}
802
803	data->FifoCount = ocount;
804
805	if (time_out < 0) {
806		nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
807			scsi_get_resid(SCpnt), scsi_pointer->this_residual,
808			scsi_pointer->buffers_residual);
809	}
810	nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
811	nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId,
812	                                                scsi_get_resid(SCpnt));
813}
814
815/*
816 * write data in DATA OUT phase
817 */
818static void nsp_pio_write(struct scsi_cmnd *SCpnt)
819{
820	struct scsi_pointer *scsi_pointer = nsp_priv(SCpnt);
821	unsigned int  base      = SCpnt->device->host->io_port;
822	unsigned long mmio_base = SCpnt->device->host->base;
823	nsp_hw_data  *data      = (nsp_hw_data *)SCpnt->device->host->hostdata;
824	int	      time_out;
825	int           ocount, res;
826	unsigned char stat;
827
828	ocount	 = data->FifoCount;
829
830	nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
831		data->FifoCount, scsi_pointer->ptr, scsi_pointer->this_residual,
832		scsi_pointer->buffer, scsi_pointer->buffers_residual,
833		scsi_get_resid(SCpnt));
834
835	time_out = 1000;
836
837	while ((time_out-- != 0) &&
838	       (scsi_pointer->this_residual > 0 ||
839		scsi_pointer->buffers_residual > 0)) {
840		stat = nsp_index_read(base, SCSIBUSMON);
841		stat &= BUSMON_PHASE_MASK;
842
843		if (stat != BUSPHASE_DATA_OUT) {
844			res = ocount - nsp_fifo_count(SCpnt);
845
846			nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
847			/* Put back pointer */
848			nsp_inc_resid(SCpnt, res);
849			scsi_pointer->ptr -= res;
850			scsi_pointer->this_residual += res;
851			ocount -= res;
852
853			break;
854		}
855
856		res = ocount - nsp_fifo_count(SCpnt);
857		if (res > 0) { /* write all data? */
858			nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
859			continue;
860		}
861
862		res = min(scsi_pointer->this_residual, WFIFO_CRIT);
863
864		//nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", scsi_pointer->ptr, scsi_pointer->this_residual, res);
865		switch (data->TransferMode) {
866		case MODE_IO32:
867			res &= ~(BIT(1)|BIT(0)); /* align 4 */
868			nsp_fifo32_write(base, scsi_pointer->ptr, res >> 2);
869			break;
870		case MODE_IO8:
871			nsp_fifo8_write(base, scsi_pointer->ptr, res);
872			break;
873
874		case MODE_MEM32:
875			res &= ~(BIT(1)|BIT(0)); /* align 4 */
876			nsp_mmio_fifo32_write(mmio_base, scsi_pointer->ptr,
877					      res >> 2);
878			break;
879
880		default:
881			nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
882			break;
883		}
884
885		nsp_inc_resid(SCpnt, -res);
886		scsi_pointer->ptr += res;
887		scsi_pointer->this_residual -= res;
888		ocount += res;
889
890		/* go to next scatter list if available */
891		if (scsi_pointer->this_residual	== 0 &&
892		    scsi_pointer->buffers_residual != 0 ) {
893			//nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
894			scsi_pointer->buffers_residual--;
895			scsi_pointer->buffer = sg_next(scsi_pointer->buffer);
896			scsi_pointer->ptr = BUFFER_ADDR(SCpnt);
897			scsi_pointer->this_residual =
898				scsi_pointer->buffer->length;
899			time_out = 1000;
900		}
901	}
902
903	data->FifoCount = ocount;
904
905	if (time_out < 0) {
906		nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x",
907		                                        scsi_get_resid(SCpnt));
908	}
909	nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
910	nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId,
911	                                                scsi_get_resid(SCpnt));
912}
913#undef RFIFO_CRIT
914#undef WFIFO_CRIT
915
916/*
917 * setup synchronous/asynchronous data transfer mode
918 */
919static int nsp_nexus(struct scsi_cmnd *SCpnt)
920{
921	unsigned int   base   = SCpnt->device->host->io_port;
922	unsigned char  target = scmd_id(SCpnt);
923//	unsigned char  lun    = SCpnt->device->lun;
924	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
925	sync_data     *sync   = &(data->Sync[target]);
926
927	//nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
928
929	/* setup synch transfer registers */
930	nsp_index_write(base, SYNCREG,	sync->SyncRegister);
931	nsp_index_write(base, ACKWIDTH, sync->AckWidth);
932
933	if (scsi_get_resid(SCpnt) % 4 != 0 ||
934	    scsi_get_resid(SCpnt) <= PAGE_SIZE ) {
935		data->TransferMode = MODE_IO8;
936	} else if (nsp_burst_mode == BURST_MEM32) {
937		data->TransferMode = MODE_MEM32;
938	} else if (nsp_burst_mode == BURST_IO32) {
939		data->TransferMode = MODE_IO32;
940	} else {
941		data->TransferMode = MODE_IO8;
942	}
943
944	/* setup pdma fifo */
945	nsp_setup_fifo(data, true);
946
947	/* clear ack counter */
948 	data->FifoCount = 0;
949	nsp_index_write(base, POINTERCLR, POINTER_CLEAR	    |
950					  ACK_COUNTER_CLEAR |
951					  REQ_COUNTER_CLEAR |
952					  HOST_COUNTER_CLEAR);
953
954	return 0;
955}
956
957#include "nsp_message.c"
958/*
959 * interrupt handler
960 */
961static irqreturn_t nspintr(int irq, void *dev_id)
962{
963	unsigned int   base;
964	unsigned char  irq_status, irq_phase, phase;
965	struct scsi_cmnd *tmpSC;
966	struct scsi_pointer *scsi_pointer;
967	unsigned char  target, lun;
968	unsigned int  *sync_neg;
969	int            i, tmp;
970	nsp_hw_data   *data;
971
972
973	//nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
974	//nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
975
976	if (                dev_id        != NULL &&
977	    ((scsi_info_t *)dev_id)->host != NULL  ) {
978		scsi_info_t *info = (scsi_info_t *)dev_id;
979
980		data = (nsp_hw_data *)info->host->hostdata;
981	} else {
982		nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
983		return IRQ_NONE;
984	}
985
986	//nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
987
988	base = data->BaseAddress;
989	//nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
990
991	/*
992	 * interrupt check
993	 */
994	nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
995	irq_status = nsp_read(base, IRQSTATUS);
996	//nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
997	if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
998		nsp_write(base, IRQCONTROL, 0);
999		//nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
1000		return IRQ_NONE;
1001	}
1002
1003	/* XXX: IMPORTANT
1004	 * Do not read an irq_phase register if no scsi phase interrupt.
1005	 * Unless, you should lose a scsi phase interrupt.
1006	 */
1007	phase = nsp_index_read(base, SCSIBUSMON);
1008	if((irq_status & IRQSTATUS_SCSI) != 0) {
1009		irq_phase = nsp_index_read(base, IRQPHASESENCE);
1010	} else {
1011		irq_phase = 0;
1012	}
1013
1014	//nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1015
1016	/*
1017	 * timer interrupt handler (scsi vs timer interrupts)
1018	 */
1019	//nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1020	if (data->TimerCount != 0) {
1021		//nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1022		nsp_index_write(base, TIMERCOUNT, 0);
1023		nsp_index_write(base, TIMERCOUNT, 0);
1024		data->TimerCount = 0;
1025	}
1026
1027	if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1028	    data->SelectionTimeOut == 0) {
1029		//nsp_dbg(NSP_DEBUG_INTR, "timer start");
1030		nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1031		return IRQ_HANDLED;
1032	}
1033
1034	nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1035
1036	if ((irq_status & IRQSTATUS_SCSI) &&
1037	    (irq_phase  & SCSI_RESET_IRQ)) {
1038		nsp_msg(KERN_ERR, "bus reset (power off?)");
1039
1040		nsphw_init(data);
1041		nsp_bus_reset(data);
1042
1043		if(data->CurrentSC != NULL) {
1044			tmpSC = data->CurrentSC;
1045			scsi_pointer = nsp_priv(tmpSC);
1046			tmpSC->result = (DID_RESET              << 16) |
1047				((scsi_pointer->Message & 0xff) <<  8) |
1048				((scsi_pointer->Status  & 0xff) <<  0);
1049			nsp_scsi_done(tmpSC);
1050		}
1051		return IRQ_HANDLED;
1052	}
1053
1054	if (data->CurrentSC == NULL) {
1055		nsp_msg(KERN_ERR, "CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x this can't be happen. reset everything", irq_status, phase, irq_phase);
1056		nsphw_init(data);
1057		nsp_bus_reset(data);
1058		return IRQ_HANDLED;
1059	}
1060
1061	tmpSC    = data->CurrentSC;
1062	scsi_pointer = nsp_priv(tmpSC);
1063	target   = tmpSC->device->id;
1064	lun      = tmpSC->device->lun;
1065	sync_neg = &(data->Sync[target].SyncNegotiation);
1066
1067	/*
1068	 * parse hardware SCSI irq reasons register
1069	 */
1070	if (irq_status & IRQSTATUS_SCSI) {
1071		if (irq_phase & RESELECT_IRQ) {
1072			nsp_dbg(NSP_DEBUG_INTR, "reselect");
1073			nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1074			nsp_reselected(tmpSC);
1075			return IRQ_HANDLED;
1076		}
1077
1078		if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1079			return IRQ_HANDLED;
1080		}
1081	}
1082
1083	//show_phase(tmpSC);
1084
1085	switch (scsi_pointer->phase) {
1086	case PH_SELSTART:
1087		// *sync_neg = SYNC_NOT_YET;
1088		if ((phase & BUSMON_BSY) == 0) {
1089			//nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1090			if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1091				nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1092				data->SelectionTimeOut = 0;
1093				nsp_index_write(base, SCSIBUSCTRL, 0);
1094
1095				tmpSC->result   = DID_TIME_OUT << 16;
1096				nsp_scsi_done(tmpSC);
1097
1098				return IRQ_HANDLED;
1099			}
1100			data->SelectionTimeOut += 1;
1101			nsp_start_timer(tmpSC, 1000/51);
1102			return IRQ_HANDLED;
1103		}
1104
1105		/* attention assert */
1106		//nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1107		data->SelectionTimeOut = 0;
1108		scsi_pointer->phase = PH_SELECTED;
1109		nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
1110		udelay(1);
1111		nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1112		return IRQ_HANDLED;
1113
1114	case PH_RESELECT:
1115		//nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1116		// *sync_neg = SYNC_NOT_YET;
1117		if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1118
1119			tmpSC->result	= DID_ABORT << 16;
1120			nsp_scsi_done(tmpSC);
1121			return IRQ_HANDLED;
1122		}
1123		fallthrough;
1124	default:
1125		if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1126			return IRQ_HANDLED;
1127		}
1128		break;
1129	}
1130
1131	/*
1132	 * SCSI sequencer
1133	 */
1134	//nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1135
1136	/* normal disconnect */
1137	if ((scsi_pointer->phase == PH_MSG_IN ||
1138	     scsi_pointer->phase == PH_MSG_OUT) &&
1139	    (irq_phase & LATCHED_BUS_FREE) != 0) {
1140		nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1141
1142		//*sync_neg       = SYNC_NOT_YET;
1143
1144		/* all command complete and return status */
1145		if (scsi_pointer->Message == COMMAND_COMPLETE) {
1146			tmpSC->result = (DID_OK		        << 16) |
1147				((scsi_pointer->Message & 0xff) <<  8) |
1148				((scsi_pointer->Status  & 0xff) <<  0);
1149			nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1150			nsp_scsi_done(tmpSC);
1151
1152			return IRQ_HANDLED;
1153		}
1154
1155		return IRQ_HANDLED;
1156	}
1157
1158
1159	/* check unexpected bus free state */
1160	if (phase == 0) {
1161		nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1162
1163		*sync_neg       = SYNC_NG;
1164		tmpSC->result   = DID_ERROR << 16;
1165		nsp_scsi_done(tmpSC);
1166		return IRQ_HANDLED;
1167	}
1168
1169	switch (phase & BUSMON_PHASE_MASK) {
1170	case BUSPHASE_COMMAND:
1171		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1172		if ((phase & BUSMON_REQ) == 0) {
1173			nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1174			return IRQ_HANDLED;
1175		}
1176
1177		scsi_pointer->phase = PH_COMMAND;
1178
1179		nsp_nexus(tmpSC);
1180
1181		/* write scsi command */
1182		nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1183		nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1184		for (i = 0; i < tmpSC->cmd_len; i++) {
1185			nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
1186		}
1187		nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1188		break;
1189
1190	case BUSPHASE_DATA_OUT:
1191		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1192
1193		scsi_pointer->phase        = PH_DATA;
1194		scsi_pointer->have_data_in = IO_OUT;
1195
1196		nsp_pio_write(tmpSC);
1197
1198		break;
1199
1200	case BUSPHASE_DATA_IN:
1201		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1202
1203		scsi_pointer->phase        = PH_DATA;
1204		scsi_pointer->have_data_in = IO_IN;
1205
1206		nsp_pio_read(tmpSC);
1207
1208		break;
1209
1210	case BUSPHASE_STATUS:
1211		nsp_dataphase_bypass(tmpSC);
1212		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1213
1214		scsi_pointer->phase = PH_STATUS;
1215
1216		scsi_pointer->Status = nsp_index_read(base, SCSIDATAWITHACK);
1217		nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x",
1218			scsi_pointer->Message, scsi_pointer->Status);
1219
1220		break;
1221
1222	case BUSPHASE_MESSAGE_OUT:
1223		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1224		if ((phase & BUSMON_REQ) == 0) {
1225			goto timer_out;
1226		}
1227
1228		scsi_pointer->phase = PH_MSG_OUT;
1229
1230		//*sync_neg = SYNC_NOT_YET;
1231
1232		data->MsgLen = i = 0;
1233		data->MsgBuffer[i] = IDENTIFY(true, lun); i++;
1234
1235		if (*sync_neg == SYNC_NOT_YET) {
1236			data->Sync[target].SyncPeriod = 0;
1237			data->Sync[target].SyncOffset = 0;
1238
1239			/**/
1240			data->MsgBuffer[i] = EXTENDED_MESSAGE; i++;
1241			data->MsgBuffer[i] = 3;            i++;
1242			data->MsgBuffer[i] = EXTENDED_SDTR; i++;
1243			data->MsgBuffer[i] = 0x0c;         i++;
1244			data->MsgBuffer[i] = 15;           i++;
1245			/**/
1246		}
1247		data->MsgLen = i;
1248
1249		nsp_analyze_sdtr(tmpSC);
1250		show_message(data);
1251		nsp_message_out(tmpSC);
1252		break;
1253
1254	case BUSPHASE_MESSAGE_IN:
1255		nsp_dataphase_bypass(tmpSC);
1256		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1257		if ((phase & BUSMON_REQ) == 0) {
1258			goto timer_out;
1259		}
1260
1261		scsi_pointer->phase = PH_MSG_IN;
1262		nsp_message_in(tmpSC);
1263
1264		/**/
1265		if (*sync_neg == SYNC_NOT_YET) {
1266			//nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1267
1268			if (data->MsgLen       >= 5            &&
1269			    data->MsgBuffer[0] == EXTENDED_MESSAGE &&
1270			    data->MsgBuffer[1] == 3            &&
1271			    data->MsgBuffer[2] == EXTENDED_SDTR ) {
1272				data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1273				data->Sync[target].SyncOffset = data->MsgBuffer[4];
1274				//nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1275				*sync_neg = SYNC_OK;
1276			} else {
1277				data->Sync[target].SyncPeriod = 0;
1278				data->Sync[target].SyncOffset = 0;
1279				*sync_neg = SYNC_NG;
1280			}
1281			nsp_analyze_sdtr(tmpSC);
1282		}
1283		/**/
1284
1285		/* search last messeage byte */
1286		tmp = -1;
1287		for (i = 0; i < data->MsgLen; i++) {
1288			tmp = data->MsgBuffer[i];
1289			if (data->MsgBuffer[i] == EXTENDED_MESSAGE) {
1290				i += (1 + data->MsgBuffer[i+1]);
1291			}
1292		}
1293		scsi_pointer->Message = tmp;
1294
1295		nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d",
1296			scsi_pointer->Message, data->MsgLen);
1297		show_message(data);
1298
1299		break;
1300
1301	case BUSPHASE_SELECT:
1302	default:
1303		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1304
1305		break;
1306	}
1307
1308	//nsp_dbg(NSP_DEBUG_INTR, "out");
1309	return IRQ_HANDLED;
1310
1311timer_out:
1312	nsp_start_timer(tmpSC, 1000/102);
1313	return IRQ_HANDLED;
1314}
1315
1316#ifdef NSP_DEBUG
1317#include "nsp_debug.c"
1318#endif	/* NSP_DEBUG */
1319
1320/*----------------------------------------------------------------*/
1321/* look for ninja3 card and init if found			  */
1322/*----------------------------------------------------------------*/
1323static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht)
1324{
1325	struct Scsi_Host *host;	/* registered host structure */
1326	nsp_hw_data *data_b = &nsp_data_base, *data;
1327
1328	nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1329	host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1330	if (host == NULL) {
1331		nsp_dbg(NSP_DEBUG_INIT, "host failed");
1332		return NULL;
1333	}
1334
1335	memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1336	data = (nsp_hw_data *)host->hostdata;
1337	data->ScsiInfo->host = host;
1338#ifdef NSP_DEBUG
1339	data->CmdId = 0;
1340#endif
1341
1342	nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1343
1344	host->unique_id	  = data->BaseAddress;
1345	host->io_port	  = data->BaseAddress;
1346	host->n_io_port	  = data->NumAddress;
1347	host->irq	  = data->IrqNumber;
1348	host->base        = data->MmioAddress;
1349
1350	spin_lock_init(&(data->Lock));
1351
1352	snprintf(data->nspinfo,
1353		 sizeof(data->nspinfo),
1354		 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1355		 host->io_port, host->io_port + host->n_io_port - 1,
1356		 host->base,
1357		 host->irq);
1358	sht->name	  = data->nspinfo;
1359
1360	nsp_dbg(NSP_DEBUG_INIT, "end");
1361
1362
1363	return host; /* detect done. */
1364}
1365
1366/*----------------------------------------------------------------*/
1367/* return info string						  */
1368/*----------------------------------------------------------------*/
1369static const char *nsp_info(struct Scsi_Host *shpnt)
1370{
1371	nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1372
1373	return data->nspinfo;
1374}
1375
1376static int nsp_show_info(struct seq_file *m, struct Scsi_Host *host)
1377{
1378	int id;
1379	int speed;
1380	unsigned long flags;
1381	nsp_hw_data *data;
1382	int hostno;
1383
1384	hostno = host->host_no;
1385	data = (nsp_hw_data *)host->hostdata;
1386
1387	seq_puts(m, "NinjaSCSI status\n\n"
1388		"Driver version:        $Revision: 1.23 $\n");
1389	seq_printf(m, "SCSI host No.:         %d\n",          hostno);
1390	seq_printf(m, "IRQ:                   %d\n",          host->irq);
1391	seq_printf(m, "IO:                    0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1392	seq_printf(m, "MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1393	seq_printf(m, "sg_tablesize:          %d\n",          host->sg_tablesize);
1394
1395	seq_puts(m, "burst transfer mode:   ");
1396	switch (nsp_burst_mode) {
1397	case BURST_IO8:
1398		seq_puts(m, "io8");
1399		break;
1400	case BURST_IO32:
1401		seq_puts(m, "io32");
1402		break;
1403	case BURST_MEM32:
1404		seq_puts(m, "mem32");
1405		break;
1406	default:
1407		seq_puts(m, "???");
1408		break;
1409	}
1410	seq_putc(m, '\n');
1411
1412
1413	spin_lock_irqsave(&(data->Lock), flags);
1414	seq_printf(m, "CurrentSC:             0x%p\n\n",      data->CurrentSC);
1415	spin_unlock_irqrestore(&(data->Lock), flags);
1416
1417	seq_puts(m, "SDTR status\n");
1418	for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1419
1420		seq_printf(m, "id %d: ", id);
1421
1422		if (id == host->this_id) {
1423			seq_puts(m, "----- NinjaSCSI-3 host adapter\n");
1424			continue;
1425		}
1426
1427		switch(data->Sync[id].SyncNegotiation) {
1428		case SYNC_OK:
1429			seq_puts(m, " sync");
1430			break;
1431		case SYNC_NG:
1432			seq_puts(m, "async");
1433			break;
1434		case SYNC_NOT_YET:
1435			seq_puts(m, " none");
1436			break;
1437		default:
1438			seq_puts(m, "?????");
1439			break;
1440		}
1441
1442		if (data->Sync[id].SyncPeriod != 0) {
1443			speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1444
1445			seq_printf(m, " transfer %d.%dMB/s, offset %d",
1446				speed / 1000,
1447				speed % 1000,
1448				data->Sync[id].SyncOffset
1449				);
1450		}
1451		seq_putc(m, '\n');
1452	}
1453	return 0;
1454}
1455
1456/*---------------------------------------------------------------*/
1457/* error handler                                                 */
1458/*---------------------------------------------------------------*/
1459
1460/*
1461static int nsp_eh_abort(struct scsi_cmnd *SCpnt)
1462{
1463	nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1464
1465	return nsp_eh_bus_reset(SCpnt);
1466}*/
1467
1468static int nsp_bus_reset(nsp_hw_data *data)
1469{
1470	unsigned int base = data->BaseAddress;
1471	int	     i;
1472
1473	nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1474
1475	nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1476	mdelay(100); /* 100ms */
1477	nsp_index_write(base, SCSIBUSCTRL, 0);
1478	for(i = 0; i < 5; i++) {
1479		nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1480	}
1481
1482	nsphw_init_sync(data);
1483
1484	nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1485
1486	return SUCCESS;
1487}
1488
1489static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt)
1490{
1491	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1492
1493	nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1494
1495	return nsp_bus_reset(data);
1496}
1497
1498static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt)
1499{
1500	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1501
1502	nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1503
1504	nsphw_init(data);
1505
1506	return SUCCESS;
1507}
1508
1509
1510/**********************************************************************
1511  PCMCIA functions
1512**********************************************************************/
1513
1514static int nsp_cs_probe(struct pcmcia_device *link)
1515{
1516	scsi_info_t  *info;
1517	nsp_hw_data  *data = &nsp_data_base;
1518	int ret;
1519
1520	nsp_dbg(NSP_DEBUG_INIT, "in");
1521
1522	/* Create new SCSI device */
1523	info = kzalloc(sizeof(*info), GFP_KERNEL);
1524	if (info == NULL) { return -ENOMEM; }
1525	info->p_dev = link;
1526	link->priv = info;
1527	data->ScsiInfo = info;
1528
1529	nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1530
1531	ret = nsp_cs_config(link);
1532
1533	nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1534	return ret;
1535} /* nsp_cs_attach */
1536
1537
1538static void nsp_cs_detach(struct pcmcia_device *link)
1539{
1540	nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1541
1542	((scsi_info_t *)link->priv)->stop = 1;
1543	nsp_cs_release(link);
1544
1545	kfree(link->priv);
1546	link->priv = NULL;
1547} /* nsp_cs_detach */
1548
1549
1550static int nsp_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
1551{
1552	nsp_hw_data		*data = priv_data;
1553
1554	if (p_dev->config_index == 0)
1555		return -ENODEV;
1556
1557	/* This reserves IO space but doesn't actually enable it */
1558	if (pcmcia_request_io(p_dev) != 0)
1559		goto next_entry;
1560
1561	if (resource_size(p_dev->resource[2])) {
1562		p_dev->resource[2]->flags |= (WIN_DATA_WIDTH_16 |
1563					WIN_MEMORY_TYPE_CM |
1564					WIN_ENABLE);
1565		if (p_dev->resource[2]->end < 0x1000)
1566			p_dev->resource[2]->end = 0x1000;
1567		if (pcmcia_request_window(p_dev, p_dev->resource[2], 0) != 0)
1568			goto next_entry;
1569		if (pcmcia_map_mem_page(p_dev, p_dev->resource[2],
1570						p_dev->card_addr) != 0)
1571			goto next_entry;
1572
1573		data->MmioAddress = (unsigned long)
1574			ioremap(p_dev->resource[2]->start,
1575					resource_size(p_dev->resource[2]));
1576		if (!data->MmioAddress)
1577			goto next_entry;
1578
1579		data->MmioLength  = resource_size(p_dev->resource[2]);
1580	}
1581	/* If we got this far, we're cool! */
1582	return 0;
1583
1584next_entry:
1585	nsp_dbg(NSP_DEBUG_INIT, "next");
1586	pcmcia_disable_device(p_dev);
1587	return -ENODEV;
1588}
1589
1590static int nsp_cs_config(struct pcmcia_device *link)
1591{
1592	int		  ret;
1593	scsi_info_t	 *info	 = link->priv;
1594	struct Scsi_Host *host;
1595	nsp_hw_data      *data = &nsp_data_base;
1596
1597	nsp_dbg(NSP_DEBUG_INIT, "in");
1598
1599	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
1600		CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IOMEM |
1601		CONF_AUTO_SET_IO;
1602
1603	ret = pcmcia_loop_config(link, nsp_cs_config_check, data);
1604	if (ret)
1605		goto cs_failed;
1606
1607	if (pcmcia_request_irq(link, nspintr))
1608		goto cs_failed;
1609
1610	ret = pcmcia_enable_device(link);
1611	if (ret)
1612		goto cs_failed;
1613
1614	if (free_ports) {
1615		if (link->resource[0]) {
1616			release_region(link->resource[0]->start,
1617					resource_size(link->resource[0]));
1618		}
1619		if (link->resource[1]) {
1620			release_region(link->resource[1]->start,
1621					resource_size(link->resource[1]));
1622		}
1623	}
1624
1625	/* Set port and IRQ */
1626	data->BaseAddress = link->resource[0]->start;
1627	data->NumAddress  = resource_size(link->resource[0]);
1628	data->IrqNumber   = link->irq;
1629
1630	nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1631		data->BaseAddress, data->NumAddress, data->IrqNumber);
1632
1633	nsphw_init(data);
1634
1635	host = nsp_detect(&nsp_driver_template);
1636
1637	if (host == NULL) {
1638		nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1639		goto cs_failed;
1640	}
1641
1642
1643	ret = scsi_add_host (host, NULL);
1644	if (ret)
1645		goto cs_failed;
1646
1647	scsi_scan_host(host);
1648
1649	info->host = host;
1650
1651	return 0;
1652
1653 cs_failed:
1654	nsp_dbg(NSP_DEBUG_INIT, "config fail");
1655	nsp_cs_release(link);
1656
1657	return -ENODEV;
1658} /* nsp_cs_config */
1659
1660
1661static void nsp_cs_release(struct pcmcia_device *link)
1662{
1663	scsi_info_t *info = link->priv;
1664	nsp_hw_data *data = NULL;
1665
1666	if (info->host == NULL) {
1667		nsp_msg(KERN_DEBUG, "unexpected card release call.");
1668	} else {
1669		data = (nsp_hw_data *)info->host->hostdata;
1670	}
1671
1672	nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1673
1674	/* Unlink the device chain */
1675	if (info->host != NULL) {
1676		scsi_remove_host(info->host);
1677	}
1678
1679	if (resource_size(link->resource[2])) {
1680		if (data != NULL) {
1681			iounmap((void *)(data->MmioAddress));
1682		}
1683	}
1684	pcmcia_disable_device(link);
1685
1686	if (info->host != NULL) {
1687		scsi_host_put(info->host);
1688	}
1689} /* nsp_cs_release */
1690
1691static int nsp_cs_suspend(struct pcmcia_device *link)
1692{
1693	scsi_info_t *info = link->priv;
1694	nsp_hw_data *data;
1695
1696	nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
1697
1698	if (info->host != NULL) {
1699		nsp_msg(KERN_INFO, "clear SDTR status");
1700
1701		data = (nsp_hw_data *)info->host->hostdata;
1702
1703		nsphw_init_sync(data);
1704	}
1705
1706	info->stop = 1;
1707
1708	return 0;
1709}
1710
1711static int nsp_cs_resume(struct pcmcia_device *link)
1712{
1713	scsi_info_t *info = link->priv;
1714	nsp_hw_data *data;
1715
1716	nsp_dbg(NSP_DEBUG_INIT, "event: resume");
1717
1718	info->stop = 0;
1719
1720	if (info->host != NULL) {
1721		nsp_msg(KERN_INFO, "reset host and bus");
1722
1723		data = (nsp_hw_data *)info->host->hostdata;
1724
1725		nsphw_init   (data);
1726		nsp_bus_reset(data);
1727	}
1728
1729	return 0;
1730}
1731
1732/*======================================================================*
1733 *	module entry point
1734 *====================================================================*/
1735static const struct pcmcia_device_id nsp_cs_ids[] = {
1736	PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16       ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
1737	PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
1738	PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
1739	PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
1740	PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
1741	PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
1742	PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
1743	PCMCIA_DEVICE_NULL
1744};
1745MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
1746
1747static struct pcmcia_driver nsp_driver = {
1748	.owner		= THIS_MODULE,
1749	.name		= "nsp_cs",
1750	.probe		= nsp_cs_probe,
1751	.remove		= nsp_cs_detach,
1752	.id_table	= nsp_cs_ids,
1753	.suspend	= nsp_cs_suspend,
1754	.resume		= nsp_cs_resume,
1755};
1756module_pcmcia_driver(nsp_driver);
1757
1758/* end */
1759