ct.c revision 240172
1/*	$NecBSD: ct.c,v 1.13.12.5 2001/06/26 07:31:53 honda Exp $	*/
2
3#include <sys/cdefs.h>
4__FBSDID("$FreeBSD: head/sys/dev/ct/ct.c 240172 2012-09-06 18:53:33Z jhb $");
5/*	$NetBSD$	*/
6
7#define	CT_DEBUG
8#define	CT_IO_CONTROL_FLAGS	(CT_USE_CCSEQ | CT_FAST_INTR)
9
10/*-
11 * [NetBSD for NEC PC-98 series]
12 *  Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
13 *	NetBSD/pc98 porting staff. All rights reserved.
14 *
15 *  Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
16 *	Naofumi HONDA.  All rights reserved.
17 *
18 *  Redistribution and use in source and binary forms, with or without
19 *  modification, are permitted provided that the following conditions
20 *  are met:
21 *  1. Redistributions of source code must retain the above copyright
22 *     notice, this list of conditions and the following disclaimer.
23 *  2. Redistributions in binary form must reproduce the above copyright
24 *     notice, this list of conditions and the following disclaimer in the
25 *     documentation and/or other materials provided with the distribution.
26 *  3. The name of the author may not be used to endorse or promote products
27 *     derived from this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
30 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
32 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/kernel.h>
45#include <sys/bio.h>
46#include <sys/buf.h>
47#include <sys/queue.h>
48#include <sys/malloc.h>
49#include <sys/errno.h>
50
51#include <machine/bus.h>
52
53#include <compat/netbsd/dvcfg.h>
54#include <compat/netbsd/physio_proc.h>
55
56#include <cam/scsi/scsi_low.h>
57
58#include <dev/ic/wd33c93reg.h>
59#include <dev/ct/ctvar.h>
60#include <dev/ct/ct_machdep.h>
61
62#define	CT_NTARGETS		8
63#define	CT_NLUNS		8
64#define	CT_RESET_DEFAULT	2000
65#define	CT_DELAY_MAX		(2 * 1000 * 1000)
66#define	CT_DELAY_INTERVAL	(1)
67
68/***************************************************
69 * DEBUG
70 ***************************************************/
71#ifdef	CT_DEBUG
72int ct_debug;
73#endif	/* CT_DEBUG */
74
75/***************************************************
76 * IO control
77 ***************************************************/
78#define	CT_USE_CCSEQ	0x0100
79#define	CT_FAST_INTR	0x0200
80
81u_int ct_io_control = CT_IO_CONTROL_FLAGS;
82
83/***************************************************
84 * default data
85 ***************************************************/
86u_int8_t cthw_cmdlevel[256] = {
87/*   0  1   2   3   4   5   6   7   8   9   A   B   C   E   D   F */
88/*0*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,1  ,0  ,1  ,0  ,0  ,0  ,0  ,0  ,
89/*1*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
90/*2*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,1  ,0  ,1  ,0  ,0  ,0  ,0  ,0  ,
91/*3*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
92/*4*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
93/*5*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
94/*6*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
95/*7*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
96/*8*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
97/*9*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
98/*A*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
99/*B*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
100/*C*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
101/*D*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
102/*E*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
103/*F*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
104};
105
106#if	0
107/* default synch data table */
108/*  A  10    6.6   5.0   4.0   3.3   2.8   2.5   2.0  M/s */
109/*  X  100   150   200   250   300   350   400   500  ns  */
110static struct ct_synch_data ct_synch_data_FSCSI[] = {
111	{25, 0xa0}, {37, 0xb0}, {50, 0x20}, {62, 0xd0}, {75, 0x30},
112	{87, 0xf0}, {100, 0x40}, {125, 0x50}, {0, 0}
113};
114
115static struct ct_synch_data ct_synch_data_SCSI[] = {
116	{50, 0x20}, {75, 0x30}, {100, 0x40}, {125, 0x50}, {0, 0}
117};
118#endif
119/***************************************************
120 * DEVICE STRUCTURE
121 ***************************************************/
122extern struct cfdriver ct_cd;
123
124/*****************************************************************
125 * Interface functions
126 *****************************************************************/
127static int ct_xfer(struct ct_softc *, u_int8_t *, int, int, u_int *);
128static void ct_io_xfer(struct ct_softc *);
129static int ct_reselected(struct ct_softc *, u_int8_t);
130static void ct_phase_error(struct ct_softc *, u_int8_t);
131static int ct_start_selection(struct ct_softc *, struct slccb *);
132static int ct_msg(struct ct_softc *, struct targ_info *, u_int);
133static int ct_world_start(struct ct_softc *, int);
134static __inline void cthw_phase_bypass(struct ct_softc *, u_int8_t);
135static int cthw_chip_reset(struct ct_bus_access_handle *, int *, int, int);
136static void cthw_bus_reset(struct ct_softc *);
137static int ct_ccb_nexus_establish(struct ct_softc *);
138static int ct_lun_nexus_establish(struct ct_softc *);
139static int ct_target_nexus_establish(struct ct_softc *, int, int);
140static void cthw_attention(struct ct_softc *);
141static int ct_targ_init(struct ct_softc *, struct targ_info *, int);
142static int ct_unbusy(struct ct_softc *);
143static void ct_attention(struct ct_softc *);
144static struct ct_synch_data *ct_make_synch_table(struct ct_softc *);
145static int ct_catch_intr(struct ct_softc *);
146
147struct scsi_low_funcs ct_funcs = {
148	SC_LOW_INIT_T ct_world_start,
149	SC_LOW_BUSRST_T cthw_bus_reset,
150	SC_LOW_TARG_INIT_T ct_targ_init,
151	SC_LOW_LUN_INIT_T NULL,
152
153	SC_LOW_SELECT_T ct_start_selection,
154	SC_LOW_NEXUS_T ct_lun_nexus_establish,
155	SC_LOW_NEXUS_T ct_ccb_nexus_establish,
156
157	SC_LOW_ATTEN_T cthw_attention,
158	SC_LOW_MSG_T ct_msg,
159
160	SC_LOW_TIMEOUT_T NULL,
161	SC_LOW_POLL_T ctintr,
162
163	NULL,	/* SC_LOW_POWER_T cthw_power, */
164};
165
166/**************************************************
167 * HW functions
168 **************************************************/
169static __inline void
170cthw_phase_bypass(ct, ph)
171	struct ct_softc *ct;
172	u_int8_t ph;
173{
174	struct ct_bus_access_handle *chp = &ct->sc_ch;
175
176	ct_cr_write_1(chp, wd3s_cph, ph);
177	ct_cr_write_1(chp, wd3s_cmd, WD3S_SELECT_ATN_TFR);
178}
179
180static void
181cthw_bus_reset(ct)
182	struct ct_softc *ct;
183{
184
185	/*
186	 * wd33c93 does not have bus reset function.
187	 */
188	if (ct->ct_bus_reset != NULL)
189		((*ct->ct_bus_reset) (ct));
190}
191
192static int
193cthw_chip_reset(chp, chiprevp, chipclk, hostid)
194	struct ct_bus_access_handle *chp;
195	int *chiprevp;
196	int chipclk, hostid;
197{
198#define	CT_SELTIMEOUT_20MHz_REGV	(0x80)
199	u_int8_t aux, regv;
200	u_int seltout;
201	int wc;
202
203	/* issue abort cmd */
204	ct_cr_write_1(chp, wd3s_cmd, WD3S_ABORT);
205	DELAY(1000);	/* 1ms wait */
206	(void) ct_stat_read_1(chp);
207	(void) ct_cr_read_1(chp, wd3s_stat);
208
209	/* setup chip registers */
210	regv = 0;
211	seltout = CT_SELTIMEOUT_20MHz_REGV;
212	switch (chipclk)
213	{
214	case 8:
215	case 10:
216		seltout = (seltout * chipclk) / 20;
217		regv = IDR_FS_8_10;
218		break;
219
220	case 12:
221	case 15:
222		seltout = (seltout * chipclk) / 20;
223		regv = IDR_FS_12_15;
224		break;
225
226	case 16:
227	case 20:
228		seltout = (seltout * chipclk) / 20;
229		regv = IDR_FS_16_20;
230		break;
231
232	default:
233		panic("ct: illegal chip clk rate");
234		break;
235	}
236
237	regv |= IDR_EHP | hostid | IDR_RAF | IDR_EAF;
238	ct_cr_write_1(chp, wd3s_oid, regv);
239
240	ct_cr_write_1(chp, wd3s_cmd, WD3S_RESET);
241	for (wc = CT_RESET_DEFAULT; wc > 0; wc --)
242	{
243		aux = ct_stat_read_1(chp);
244		if (aux != 0xff && (aux & STR_INT))
245		{
246			regv = ct_cr_read_1(chp, wd3s_stat);
247			if (regv == BSR_RESET || regv == BSR_AFM_RESET)
248				break;
249
250			ct_cr_write_1(chp, wd3s_cmd, WD3S_RESET);
251		}
252		DELAY(1);
253	}
254	if (wc == 0)
255		return ENXIO;
256
257	ct_cr_write_1(chp, wd3s_tout, seltout);
258	ct_cr_write_1(chp, wd3s_sid, SIDR_RESEL);
259	ct_cr_write_1(chp, wd3s_ctrl, CR_DEFAULT);
260	ct_cr_write_1(chp, wd3s_synch, 0);
261	if (chiprevp != NULL)
262	{
263		*chiprevp = CT_WD33C93;
264		if (regv == BSR_RESET)
265			goto out;
266
267		*chiprevp = CT_WD33C93_A;
268		ct_cr_write_1(chp, wd3s_qtag, 0xaa);
269		if (ct_cr_read_1(chp, wd3s_qtag) != 0xaa)
270		{
271			ct_cr_write_1(chp, wd3s_qtag, 0x0);
272			goto out;
273		}
274		ct_cr_write_1(chp, wd3s_qtag, 0x55);
275		if (ct_cr_read_1(chp, wd3s_qtag) != 0x55)
276		{
277			ct_cr_write_1(chp, wd3s_qtag, 0x0);
278			goto out;
279		}
280		ct_cr_write_1(chp, wd3s_qtag, 0x0);
281		*chiprevp = CT_WD33C93_B;
282	}
283
284out:
285	(void) ct_stat_read_1(chp);
286	(void) ct_cr_read_1(chp, wd3s_stat);
287	return 0;
288}
289
290static struct ct_synch_data *
291ct_make_synch_table(ct)
292	struct ct_softc *ct;
293{
294	struct ct_synch_data *sdtp, *sdp;
295	u_int base, i, period;
296
297	sdtp = sdp = &ct->sc_default_sdt[0];
298
299	if ((ct->sc_chipclk % 5) == 0)
300		base = 1000 / (5 * 2);	/* 5 MHz type */
301	else
302		base = 1000 / (4 * 2);	/* 4 MHz type */
303
304	if (ct->sc_chiprev >= CT_WD33C93_B)
305	{
306		/* fast scsi */
307		for (i = 2; i < 8; i ++, sdp ++)
308		{
309			period = (base * i) / 2;
310			if (period >= 200)	/* 5 MHz */
311				break;
312			sdp->cs_period = period / 4;
313			sdp->cs_syncr = (i * 0x10) | 0x80;
314		}
315	}
316
317	for (i = 2; i < 8; i ++, sdp ++)
318	{
319		period = (base * i);
320		if (period > 500)		/* 2 MHz */
321			break;
322		sdp->cs_period = period / 4;
323		sdp->cs_syncr = (i * 0x10);
324	}
325
326	sdp->cs_period = 0;
327	sdp->cs_syncr = 0;
328	return sdtp;
329}
330
331/**************************************************
332 * Attach & Probe
333 **************************************************/
334int
335ctprobesubr(chp, dvcfg, hsid, chipclk, chiprevp)
336	struct ct_bus_access_handle *chp;
337	u_int dvcfg, chipclk;
338	int hsid;
339	int *chiprevp;
340{
341
342#if	0
343	if ((ct_stat_read_1(chp) & STR_BSY) != 0)
344		return 0;
345#endif
346	if (cthw_chip_reset(chp, chiprevp, chipclk, hsid) != 0)
347		return 0;
348	return 1;
349}
350
351int
352ctprint(aux, name)
353	void *aux;
354	const char *name;
355{
356
357	if (name != NULL)
358		printf("%s: scsibus ", name);
359	return 1;
360}
361
362void
363ctattachsubr(ct)
364	struct ct_softc *ct;
365{
366	struct scsi_low_softc *slp = &ct->sc_sclow;
367
368	ct->sc_tmaxcnt = SCSI_LOW_MIN_TOUT * 1000 * 1000; /* default */
369	slp->sl_funcs = &ct_funcs;
370	slp->sl_flags |= HW_READ_PADDING;
371	(void) scsi_low_attach(slp, 0, CT_NTARGETS, CT_NLUNS,
372			       sizeof(struct ct_targ_info), 0);
373}
374
375/**************************************************
376 * SCSI LOW interface functions
377 **************************************************/
378static void
379cthw_attention(ct)
380	struct ct_softc *ct;
381{
382	struct ct_bus_access_handle *chp = &ct->sc_ch;
383
384	ct->sc_atten = 1;
385	if ((ct_stat_read_1(chp) & (STR_BSY | STR_CIP)) != 0)
386		return;
387
388	ct_cr_write_1(chp, wd3s_cmd, WD3S_ASSERT_ATN);
389	DELAY(10);
390	if ((ct_stat_read_1(chp) & STR_LCI) == 0)
391		ct->sc_atten = 0;
392	ct_unbusy(ct);
393	return;
394}
395
396static void
397ct_attention(ct)
398	struct ct_softc *ct;
399{
400	struct scsi_low_softc *slp = &ct->sc_sclow;
401
402	if (slp->sl_atten == 0)
403	{
404		ct_unbusy(ct);
405		scsi_low_attention(slp);
406	}
407	else if (ct->sc_atten != 0)
408	{
409		ct_unbusy(ct);
410		cthw_attention(ct);
411	}
412}
413
414static int
415ct_targ_init(ct, ti, action)
416	struct ct_softc *ct;
417	struct targ_info *ti;
418	int action;
419{
420	struct ct_targ_info *cti = (void *) ti;
421
422	if (action == SCSI_LOW_INFO_ALLOC || action == SCSI_LOW_INFO_REVOKE)
423	{
424		if (ct->sc_sdp == NULL)
425		{
426			ct->sc_sdp = ct_make_synch_table(ct);
427		}
428
429		switch (ct->sc_chiprev)
430		{
431		default:
432			ti->ti_maxsynch.offset = 5;
433			break;
434
435		case CT_WD33C93_A:
436		case CT_AM33C93_A:
437			ti->ti_maxsynch.offset = 12;
438			break;
439
440		case CT_WD33C93_B:
441		case CT_WD33C93_C:
442			ti->ti_maxsynch.offset = 12;
443			break;
444		}
445
446		ti->ti_maxsynch.period = ct->sc_sdp[0].cs_period;
447		ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
448		cti->cti_syncreg = 0;
449	}
450
451	return 0;
452}
453
454static int
455ct_world_start(ct, fdone)
456	struct ct_softc *ct;
457	int fdone;
458{
459	struct scsi_low_softc *slp = &ct->sc_sclow;
460	struct ct_bus_access_handle *chp = &ct->sc_ch;
461
462	if (ct->sc_sdp == NULL)
463	{
464		ct->sc_sdp = ct_make_synch_table(ct);
465	}
466
467	if (slp->sl_cfgflags & CFG_NOPARITY)
468		ct->sc_creg = CR_DEFAULT;
469	else
470		ct->sc_creg = CR_DEFAULT_HP;
471
472	if (ct->sc_dma & CT_DMA_DMASTART)
473		(*ct->ct_dma_xfer_stop) (ct);
474	if (ct->sc_dma & CT_DMA_PIOSTART)
475		(*ct->ct_pio_xfer_stop) (ct);
476	ct->sc_dma = 0;
477	ct->sc_atten = 0;
478
479	cthw_chip_reset(chp, NULL, ct->sc_chipclk, slp->sl_hostid);
480	scsi_low_bus_reset(slp);
481	cthw_chip_reset(chp, NULL, ct->sc_chipclk, slp->sl_hostid);
482
483	SOFT_INTR_REQUIRED(slp);
484	return 0;
485}
486
487static int
488ct_start_selection(ct, cb)
489	struct ct_softc *ct;
490	struct slccb *cb;
491{
492	struct scsi_low_softc *slp = &ct->sc_sclow;
493	struct ct_bus_access_handle *chp = &ct->sc_ch;
494
495	struct targ_info *ti = slp->sl_Tnexus;
496	struct lun_info *li = slp->sl_Lnexus;
497	int s, satok;
498	u_int8_t cmd;
499
500	ct->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000;
501	ct->sc_atten = 0;
502	satok = 0;
503
504	if (scsi_low_is_disconnect_ok(cb) != 0)
505	{
506		if (ct->sc_chiprev >= CT_WD33C93_A)
507			satok = 1;
508		else if (cthw_cmdlevel[slp->sl_scp.scp_cmd[0]] != 0)
509			satok = 1;
510	}
511
512	if (satok != 0 &&
513	    scsi_low_is_msgout_continue(ti, SCSI_LOW_MSG_IDENTIFY) == 0)
514	{
515		cmd = WD3S_SELECT_ATN_TFR;
516		ct->sc_satgo = CT_SAT_GOING;
517	}
518	else
519	{
520		cmd = WD3S_SELECT_ATN;
521		ct->sc_satgo = 0;
522	}
523
524	if ((ct_stat_read_1(chp) & (STR_BSY | STR_INT | STR_CIP)) != 0)
525		return SCSI_LOW_START_FAIL;
526
527	if ((ct->sc_satgo & CT_SAT_GOING) != 0)
528	{
529		(void) scsi_low_msgout(slp, ti, SCSI_LOW_MSGOUT_INIT);
530		scsi_low_cmd(slp, ti);
531		ct_cr_write_1(chp, wd3s_oid, slp->sl_scp.scp_cmdlen);
532		ct_write_cmds(chp, slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen);
533	}
534	else
535	{
536		/* anyway attention assert */
537		SCSI_LOW_ASSERT_ATN(slp);
538	}
539
540	ct_target_nexus_establish(ct, li->li_lun, slp->sl_scp.scp_direction);
541
542	s = splhigh();
543	if ((ct_stat_read_1(chp) & (STR_BSY | STR_INT | STR_CIP)) == 0)
544	{
545		/* XXX:
546		 * Reload a lun again here.
547		 */
548		ct_cr_write_1(chp, wd3s_lun, li->li_lun);
549		ct_cr_write_1(chp, wd3s_cmd, cmd);
550		if ((ct_stat_read_1(chp) & STR_LCI) == 0)
551		{
552			splx(s);
553			SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART);
554			return SCSI_LOW_START_OK;
555		}
556	}
557	splx(s);
558	return SCSI_LOW_START_FAIL;
559}
560
561static int
562ct_msg(ct, ti, msg)
563	struct ct_softc *ct;
564	struct targ_info *ti;
565	u_int msg;
566{
567	struct ct_bus_access_handle *chp = &ct->sc_ch;
568	struct ct_targ_info *cti = (void *) ti;
569	struct ct_synch_data *csp = ct->sc_sdp;
570	u_int offset, period;
571	int error;
572
573	if ((msg & SCSI_LOW_MSG_WIDE) != 0)
574	{
575		if (ti->ti_width != SCSI_LOW_BUS_WIDTH_8)
576		{
577			ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
578			return EINVAL;
579		}
580		return 0;
581	}
582
583	if ((msg & SCSI_LOW_MSG_SYNCH) == 0)
584		return 0;
585
586	offset = ti->ti_maxsynch.offset;
587	period = ti->ti_maxsynch.period;
588	for ( ; csp->cs_period != 0; csp ++)
589	{
590		if (period == csp->cs_period)
591			break;
592	}
593
594	if (ti->ti_maxsynch.period != 0 && csp->cs_period == 0)
595	{
596		ti->ti_maxsynch.period = 0;
597		ti->ti_maxsynch.offset = 0;
598		cti->cti_syncreg = 0;
599		error = EINVAL;
600	}
601	else
602	{
603		cti->cti_syncreg = ((offset & 0x0f) | csp->cs_syncr);
604		error = 0;
605	}
606
607	if (ct->ct_synch_setup != 0)
608		(*ct->ct_synch_setup) (ct, ti);
609	ct_cr_write_1(chp, wd3s_synch, cti->cti_syncreg);
610	return error;
611}
612
613/*************************************************
614 * <DATA PHASE>
615 *************************************************/
616static int
617ct_xfer(ct, data, len, direction, statp)
618	struct ct_softc *ct;
619	u_int8_t *data;
620	int len, direction;
621	u_int *statp;
622{
623	struct ct_bus_access_handle *chp = &ct->sc_ch;
624	int wc;
625	register u_int8_t aux;
626
627	*statp = 0;
628	if (len == 1)
629	{
630		ct_cr_write_1(chp, wd3s_cmd, WD3S_SBT | WD3S_TFR_INFO);
631	}
632	else
633	{
634		cthw_set_count(chp, len);
635		ct_cr_write_1(chp, wd3s_cmd, WD3S_TFR_INFO);
636	}
637
638	aux = ct_stat_read_1(chp);
639	if ((aux & STR_LCI) != 0)
640	{
641		cthw_set_count(chp, 0);
642		return len;
643	}
644
645	for (wc = 0; wc < ct->sc_tmaxcnt; wc ++)
646	{
647		/* check data ready */
648		if ((aux & (STR_BSY | STR_DBR)) == (STR_BSY | STR_DBR))
649		{
650			if (direction == SCSI_LOW_READ)
651			{
652				*data = ct_cr_read_1(chp, wd3s_data);
653				if ((aux & STR_PE) != 0)
654					*statp |= SCSI_LOW_DATA_PE;
655			}
656			else
657			{
658				ct_cr_write_1(chp, wd3s_data, *data);
659			}
660			len --;
661			if (len <= 0)
662				break;
663			data ++;
664		}
665		else
666		{
667			DELAY(1);
668		}
669
670		/* check phase miss */
671		aux = ct_stat_read_1(chp);
672		if ((aux & STR_INT) != 0)
673			break;
674	}
675	return len;
676}
677
678#define	CT_PADDING_BUF_SIZE 32
679
680static void
681ct_io_xfer(ct)
682	struct ct_softc *ct;
683{
684	struct scsi_low_softc *slp = &ct->sc_sclow;
685	struct ct_bus_access_handle *chp = &ct->sc_ch;
686	struct sc_p *sp = &slp->sl_scp;
687	u_int stat;
688	int len;
689	u_int8_t pbuf[CT_PADDING_BUF_SIZE];
690
691	/* polling mode */
692	ct_cr_write_1(chp, wd3s_ctrl, ct->sc_creg);
693
694	if (sp->scp_datalen <= 0)
695	{
696		slp->sl_error |= PDMAERR;
697
698		if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE)
699			bzero(pbuf, CT_PADDING_BUF_SIZE);
700		ct_xfer(ct, pbuf, CT_PADDING_BUF_SIZE,
701			sp->scp_direction, &stat);
702	}
703	else
704	{
705		len = ct_xfer(ct, sp->scp_data, sp->scp_datalen,
706			      sp->scp_direction, &stat);
707		sp->scp_data += (sp->scp_datalen - len);
708		sp->scp_datalen = len;
709	}
710}
711
712/**************************************************
713 * <PHASE ERROR>
714 **************************************************/
715struct ct_err {
716	u_char	*pe_msg;
717	u_int	pe_err;
718	u_int	pe_errmsg;
719	int	pe_done;
720};
721
722struct ct_err ct_cmderr[] = {
723/*0*/	{ "illegal cmd", FATALIO, SCSI_LOW_MSG_ABORT, 1},
724/*1*/	{ "unexpected bus free", FATALIO, 0, 1},
725/*2*/	{ NULL, SELTIMEOUTIO, 0, 1},
726/*3*/	{ "scsi bus parity error", PARITYERR, SCSI_LOW_MSG_ERROR, 0},
727/*4*/	{ "scsi bus parity error", PARITYERR, SCSI_LOW_MSG_ERROR, 0},
728/*5*/	{ "unknown" , FATALIO, SCSI_LOW_MSG_ABORT, 1},
729/*6*/	{ "miss reselection (target mode)", FATALIO, SCSI_LOW_MSG_ABORT, 0},
730/*7*/	{ "wrong status byte", PARITYERR, SCSI_LOW_MSG_ERROR, 0},
731};
732
733static void
734ct_phase_error(ct, scsi_status)
735	struct ct_softc *ct;
736	u_int8_t scsi_status;
737{
738	struct scsi_low_softc *slp = &ct->sc_sclow;
739	struct targ_info *ti = slp->sl_Tnexus;
740	struct ct_err *pep;
741	u_int msg = 0;
742
743	if ((scsi_status & BSR_CM) == BSR_CMDERR &&
744	    (scsi_status & BSR_PHVALID) == 0)
745	{
746		pep = &ct_cmderr[scsi_status & BSR_PM];
747		slp->sl_error |= pep->pe_err;
748		if ((pep->pe_err & PARITYERR) != 0)
749		{
750			if (ti->ti_phase == PH_MSGIN)
751				msg = SCSI_LOW_MSG_PARITY;
752			else
753				msg = SCSI_LOW_MSG_ERROR;
754		}
755		else
756			msg = pep->pe_errmsg;
757
758		if (msg != 0)
759			scsi_low_assert_msg(slp, slp->sl_Tnexus, msg, 1);
760
761		if (pep->pe_msg != NULL)
762		{
763			printf("%s: phase error: %s",
764				slp->sl_xname, pep->pe_msg);
765			scsi_low_print(slp, slp->sl_Tnexus);
766		}
767
768		if (pep->pe_done != 0)
769			scsi_low_disconnected(slp, ti);
770	}
771	else
772	{
773		slp->sl_error |= FATALIO;
774		scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, "phase error");
775	}
776}
777
778/**************************************************
779 * ### SCSI PHASE SEQUENCER ###
780 **************************************************/
781static int
782ct_reselected(ct, scsi_status)
783	struct ct_softc *ct;
784	u_int8_t scsi_status;
785{
786	struct scsi_low_softc *slp = &ct->sc_sclow;
787	struct ct_bus_access_handle *chp = &ct->sc_ch;
788	struct targ_info *ti;
789	u_int sid;
790	u_int8_t regv;
791
792	ct->sc_atten = 0;
793	ct->sc_satgo &= ~CT_SAT_GOING;
794	regv = ct_cr_read_1(chp, wd3s_sid);
795	if ((regv & SIDR_VALID) == 0)
796		return EJUSTRETURN;
797
798	sid = regv & SIDR_IDM;
799	if ((ti = scsi_low_reselected(slp, sid)) == NULL)
800		return EJUSTRETURN;
801
802	ct_target_nexus_establish(ct, 0, SCSI_LOW_READ);
803	if (scsi_status != BSR_AFM_RESEL)
804		return EJUSTRETURN;
805
806	SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
807	regv = ct_cr_read_1(chp, wd3s_data);
808	if (scsi_low_msgin(slp, ti, (u_int) regv) == 0)
809	{
810		if (scsi_low_is_msgout_continue(ti, 0) != 0)
811		{
812			/* XXX: scsi_low_attetion */
813			scsi_low_attention(slp);
814		}
815	}
816
817	if (ct->sc_atten != 0)
818	{
819		ct_attention(ct);
820	}
821
822	ct_cr_write_1(chp, wd3s_cmd, WD3S_NEGATE_ACK);
823	return EJUSTRETURN;
824}
825
826static int
827ct_target_nexus_establish(ct, lun, dir)
828	struct ct_softc *ct;
829	int lun, dir;
830{
831	struct scsi_low_softc *slp = &ct->sc_sclow;
832	struct ct_bus_access_handle *chp = &ct->sc_ch;
833	struct targ_info *ti = slp->sl_Tnexus;
834	struct ct_targ_info *cti = (void *) ti;
835
836	if (dir == SCSI_LOW_WRITE)
837		ct_cr_write_1(chp, wd3s_did, ti->ti_id);
838	else
839		ct_cr_write_1(chp, wd3s_did, ti->ti_id | DIDR_DPD);
840	ct_cr_write_1(chp, wd3s_lun, lun);
841	ct_cr_write_1(chp, wd3s_ctrl, ct->sc_creg | CR_DMA);
842	ct_cr_write_1(chp, wd3s_cph, 0);
843	ct_cr_write_1(chp, wd3s_synch, cti->cti_syncreg);
844	cthw_set_count(chp, 0);
845	return 0;
846}
847
848static int
849ct_lun_nexus_establish(ct)
850	struct ct_softc *ct;
851{
852	struct scsi_low_softc *slp = &ct->sc_sclow;
853	struct ct_bus_access_handle *chp = &ct->sc_ch;
854	struct lun_info *li = slp->sl_Lnexus;
855
856	ct_cr_write_1(chp, wd3s_lun, li->li_lun);
857	return 0;
858}
859
860static int
861ct_ccb_nexus_establish(ct)
862	struct ct_softc *ct;
863{
864	struct scsi_low_softc *slp = &ct->sc_sclow;
865	struct ct_bus_access_handle *chp = &ct->sc_ch;
866	struct lun_info *li = slp->sl_Lnexus;
867	struct targ_info *ti = slp->sl_Tnexus;
868	struct ct_targ_info *cti = (void *) ti;
869	struct slccb *cb = slp->sl_Qnexus;
870
871	ct->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000;
872
873	if ((ct->sc_satgo & CT_SAT_GOING) != 0)
874	{
875		ct_cr_write_1(chp, wd3s_oid, slp->sl_scp.scp_cmdlen);
876		ct_write_cmds(chp, slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen);
877	}
878	if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE)
879		ct_cr_write_1(chp, wd3s_did, ti->ti_id);
880	else
881		ct_cr_write_1(chp, wd3s_did, ti->ti_id | DIDR_DPD);
882	ct_cr_write_1(chp, wd3s_lun, li->li_lun);
883	ct_cr_write_1(chp, wd3s_synch, cti->cti_syncreg);
884	return 0;
885}
886
887static int
888ct_unbusy(ct)
889	struct ct_softc *ct;
890{
891	struct scsi_low_softc *slp = &ct->sc_sclow;
892	struct ct_bus_access_handle *chp = &ct->sc_ch;
893	int wc;
894	register u_int8_t regv;
895
896	for (wc = 0; wc < CT_DELAY_MAX / CT_DELAY_INTERVAL; wc ++)
897	{
898		regv = ct_stat_read_1(chp);
899		if ((regv & (STR_BSY | STR_CIP)) == 0)
900			return 0;
901		if (regv == (u_int8_t) -1)
902			return EIO;
903
904		DELAY(CT_DELAY_INTERVAL);
905	}
906
907	printf("%s: unbusy timeout\n", slp->sl_xname);
908	return EBUSY;
909}
910
911static int
912ct_catch_intr(ct)
913	struct ct_softc *ct;
914{
915	struct ct_bus_access_handle *chp = &ct->sc_ch;
916	int wc;
917	register u_int8_t regv;
918
919	for (wc = 0; wc < CT_DELAY_MAX / CT_DELAY_INTERVAL; wc ++)
920	{
921		regv = ct_stat_read_1(chp);
922		if ((regv & (STR_INT | STR_BSY | STR_CIP)) == STR_INT)
923			return 0;
924
925		DELAY(CT_DELAY_INTERVAL);
926	}
927	return EJUSTRETURN;
928}
929
930int
931ctintr(arg)
932	void *arg;
933{
934	struct ct_softc *ct = arg;
935	struct scsi_low_softc *slp = &ct->sc_sclow;
936	struct ct_bus_access_handle *chp = &ct->sc_ch;
937	struct targ_info *ti;
938	struct physio_proc *pp;
939	struct buf *bp;
940	u_int derror, flags;
941	int len, satgo, error;
942	u_int8_t scsi_status, regv;
943
944again:
945	if (slp->sl_flags & HW_INACTIVE)
946		return 0;
947
948	/**************************************************
949	 * Get status & bus phase
950	 **************************************************/
951	if ((ct_stat_read_1(chp) & STR_INT) == 0)
952		return 0;
953
954	scsi_status = ct_cr_read_1(chp, wd3s_stat);
955	if (scsi_status == ((u_int8_t) -1))
956		return 1;
957
958	/**************************************************
959	 * Check reselection, or nexus
960	 **************************************************/
961	if (scsi_status == BSR_RESEL || scsi_status == BSR_AFM_RESEL)
962	{
963		if (ct_reselected(ct, scsi_status) == EJUSTRETURN)
964			return 1;
965	}
966
967	if ((ti = slp->sl_Tnexus) == NULL)
968		return 1;
969
970	/**************************************************
971	 * Debug section
972	 **************************************************/
973#ifdef	CT_DEBUG
974	if (ct_debug > 0)
975	{
976		scsi_low_print(slp, NULL);
977		printf("%s: scsi_status 0x%x\n\n", slp->sl_xname,
978		       (u_int) scsi_status);
979#ifdef	KDB
980		if (ct_debug > 1)
981			kdb_enter(KDB_WHY_CAM, "ct");
982#endif	/* KDB */
983	}
984#endif	/* CT_DEBUG */
985
986	/**************************************************
987	 * Internal scsi phase
988	 **************************************************/
989	satgo = ct->sc_satgo;
990	ct->sc_satgo &= ~CT_SAT_GOING;
991
992	switch (ti->ti_phase)
993	{
994	case PH_SELSTART:
995		if ((satgo & CT_SAT_GOING) == 0)
996		{
997			if (scsi_status != BSR_SELECTED)
998			{
999				ct_phase_error(ct, scsi_status);
1000				return 1;
1001			}
1002			scsi_low_arbit_win(slp);
1003			SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED);
1004			return 1;
1005		}
1006		else
1007		{
1008			scsi_low_arbit_win(slp);
1009			SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT); /* XXX */
1010		}
1011		break;
1012
1013	case PH_RESEL:
1014	    	if ((scsi_status & BSR_PHVALID) == 0 ||
1015		    (scsi_status & BSR_PM) != BSR_MSGIN)
1016		{
1017			scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
1018				 "phase miss after reselect");
1019			return 1;
1020		}
1021		break;
1022
1023	default:
1024		if (slp->sl_flags & HW_PDMASTART)
1025		{
1026			slp->sl_flags &= ~HW_PDMASTART;
1027			if (ct->sc_dma & CT_DMA_DMASTART)
1028			{
1029				(*ct->ct_dma_xfer_stop) (ct);
1030				ct->sc_dma &= ~CT_DMA_DMASTART;
1031			}
1032			else if (ct->sc_dma & CT_DMA_PIOSTART)
1033			{
1034				(*ct->ct_pio_xfer_stop) (ct);
1035				ct->sc_dma &= ~CT_DMA_PIOSTART;
1036			}
1037			else
1038			{
1039				scsi_low_data_finish(slp);
1040			}
1041		}
1042		break;
1043	}
1044
1045	/**************************************************
1046	 * parse scsi phase
1047	 **************************************************/
1048	if (scsi_status & BSR_PHVALID)
1049	{
1050		/**************************************************
1051		 * Normal SCSI phase.
1052		 **************************************************/
1053		if ((scsi_status & BSR_CM) == BSR_CMDABT)
1054		{
1055			ct_phase_error(ct, scsi_status);
1056			return 1;
1057		}
1058
1059		switch (scsi_status & BSR_PM)
1060		{
1061		case BSR_DATAOUT:
1062			SCSI_LOW_SETUP_PHASE(ti, PH_DATA);
1063			if (scsi_low_data(slp, ti, &bp, SCSI_LOW_WRITE) != 0)
1064			{
1065				ct_attention(ct);
1066			}
1067			goto common_data_phase;
1068
1069		case BSR_DATAIN:
1070			SCSI_LOW_SETUP_PHASE(ti, PH_DATA);
1071			if (scsi_low_data(slp, ti, &bp, SCSI_LOW_READ) != 0)
1072			{
1073				ct_attention(ct);
1074			}
1075
1076common_data_phase:
1077			if (slp->sl_scp.scp_datalen > 0)
1078			{
1079				slp->sl_flags |= HW_PDMASTART;
1080				if ((ct->sc_xmode & CT_XMODE_PIO) != 0)
1081				{
1082					pp = physio_proc_enter(bp);
1083					error = (*ct->ct_pio_xfer_start) (ct);
1084					physio_proc_leave(pp);
1085					if (error == 0)
1086					{
1087						ct->sc_dma |= CT_DMA_PIOSTART;
1088						return 1;
1089					}
1090				}
1091
1092				if ((ct->sc_xmode & CT_XMODE_DMA) != 0)
1093				{
1094					error = (*ct->ct_dma_xfer_start) (ct);
1095					if (error == 0)
1096					{
1097						ct->sc_dma |= CT_DMA_DMASTART;
1098						return 1;
1099					}
1100				}
1101			}
1102			else
1103			{
1104				if (slp->sl_scp.scp_direction == SCSI_LOW_READ)
1105				{
1106					if (!(slp->sl_flags & HW_READ_PADDING))
1107					{
1108						printf("%s: read padding required\n", slp->sl_xname);
1109						return 1;
1110					}
1111				}
1112				else
1113				{
1114					if (!(slp->sl_flags & HW_WRITE_PADDING))
1115					{
1116						printf("%s: write padding required\n", slp->sl_xname);
1117						return 1;
1118					}
1119				}
1120				slp->sl_flags |= HW_PDMASTART;
1121			}
1122
1123			ct_io_xfer(ct);
1124			return 1;
1125
1126		case BSR_CMDOUT:
1127			SCSI_LOW_SETUP_PHASE(ti, PH_CMD);
1128			if (scsi_low_cmd(slp, ti) != 0)
1129			{
1130				ct_attention(ct);
1131			}
1132
1133			if (ct_xfer(ct, slp->sl_scp.scp_cmd,
1134				    slp->sl_scp.scp_cmdlen,
1135				    SCSI_LOW_WRITE, &derror) != 0)
1136			{
1137				printf("%s: scsi cmd xfer short\n",
1138					slp->sl_xname);
1139			}
1140			return 1;
1141
1142		case BSR_STATIN:
1143			SCSI_LOW_SETUP_PHASE(ti, PH_STAT);
1144			if ((ct_io_control & CT_USE_CCSEQ) != 0)
1145			{
1146				if (scsi_low_is_msgout_continue(ti, 0) != 0 ||
1147				    ct->sc_atten != 0)
1148				{
1149					ct_xfer(ct, &regv, 1, SCSI_LOW_READ,
1150						&derror);
1151					scsi_low_statusin(slp, ti,
1152						  	  regv | derror);
1153				}
1154				else
1155				{
1156					ct->sc_satgo |= CT_SAT_GOING;
1157					cthw_set_count(chp, 0);
1158					cthw_phase_bypass(ct, 0x41);
1159				}
1160			}
1161			else
1162			{
1163				ct_xfer(ct, &regv, 1, SCSI_LOW_READ, &derror);
1164				scsi_low_statusin(slp, ti, regv | derror);
1165			}
1166			return 1;
1167
1168		case BSR_UNSPINFO0:
1169		case BSR_UNSPINFO1:
1170			printf("%s: illegal bus phase (0x%x)\n", slp->sl_xname,
1171				(u_int) scsi_status);
1172			scsi_low_print(slp, ti);
1173			return 1;
1174
1175		case BSR_MSGOUT:
1176			SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT);
1177			flags = SCSI_LOW_MSGOUT_UNIFY;
1178		        if (ti->ti_ophase != ti->ti_phase)
1179				flags |= SCSI_LOW_MSGOUT_INIT;
1180			len = scsi_low_msgout(slp, ti, flags);
1181
1182			if (len > 1 && slp->sl_atten == 0)
1183			{
1184				ct_attention(ct);
1185			}
1186
1187			if (ct_xfer(ct, ti->ti_msgoutstr, len,
1188				    SCSI_LOW_WRITE, &derror) != 0)
1189			{
1190				printf("%s: scsi msgout xfer short\n",
1191					slp->sl_xname);
1192			}
1193			SCSI_LOW_DEASSERT_ATN(slp);
1194			ct->sc_atten = 0;
1195			return 1;
1196
1197		case BSR_MSGIN:/* msg in */
1198			SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
1199
1200			ct_xfer(ct, &regv, 1, SCSI_LOW_READ, &derror);
1201			if (scsi_low_msgin(slp, ti, regv | derror) == 0)
1202			{
1203				if (scsi_low_is_msgout_continue(ti, 0) != 0)
1204				{
1205					/* XXX: scsi_low_attetion */
1206					scsi_low_attention(slp);
1207				}
1208			}
1209
1210			if ((ct_io_control & CT_FAST_INTR) != 0)
1211			{
1212				if (ct_catch_intr(ct) == 0)
1213					goto again;
1214			}
1215			return 1;
1216		}
1217	}
1218	else
1219	{
1220		/**************************************************
1221		 * Special SCSI phase
1222		 **************************************************/
1223		switch (scsi_status)
1224		{
1225		case BSR_SATSDP: /* SAT with save data pointer */
1226			SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
1227			ct->sc_satgo |= CT_SAT_GOING;
1228			scsi_low_msgin(slp, ti, MSG_SAVESP);
1229			cthw_phase_bypass(ct, 0x41);
1230			return 1;
1231
1232		case BSR_SATFIN: /* SAT COMPLETE */
1233			/*
1234			 * emulate statusin => msgin
1235			 */
1236			SCSI_LOW_SETUP_PHASE(ti, PH_STAT);
1237			scsi_low_statusin(slp, ti, ct_cr_read_1(chp, wd3s_lun));
1238
1239			SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
1240			scsi_low_msgin(slp, ti, MSG_COMP);
1241
1242			scsi_low_disconnected(slp, ti);
1243			return 1;
1244
1245		case BSR_ACKREQ: /* negate ACK */
1246			if (ct->sc_atten != 0)
1247			{
1248				ct_attention(ct);
1249			}
1250
1251			ct_cr_write_1(chp, wd3s_cmd, WD3S_NEGATE_ACK);
1252			if ((ct_io_control & CT_FAST_INTR) != 0)
1253			{
1254				/* XXX:
1255				 * Should clear a pending interrupt and
1256				 * sync with a next interrupt!
1257				 */
1258				ct_catch_intr(ct);
1259			}
1260			return 1;
1261
1262		case BSR_DISC: /* disconnect */
1263			if (slp->sl_msgphase == MSGPH_NULL &&
1264			    (satgo & CT_SAT_GOING) != 0)
1265			{
1266				/*
1267				 * emulate disconnect msg
1268				 */
1269				SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
1270				scsi_low_msgin(slp, ti, MSG_DISCON);
1271			}
1272			scsi_low_disconnected(slp, ti);
1273			return 1;
1274
1275		default:
1276			break;
1277		}
1278	}
1279
1280	ct_phase_error(ct, scsi_status);
1281	return 1;
1282}
1283