ct.c revision 78209
1/* $FreeBSD: head/sys/dev/ct/ct.c 78209 2001-06-14 11:05:48Z nyan $ */
2/*	$NecBSD: ct.c,v 1.13 1999/07/23 20:54:00 honda Exp $	*/
3/*	$NetBSD$	*/
4
5#define	CT_DEBUG
6#define	CT_USE_CCSEQ
7
8/*
9 * [NetBSD for NEC PC-98 series]
10 *  Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999
11 *	NetBSD/pc98 porting staff. All rights reserved.
12 *
13 * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999
14 *	Naofumi HONDA.  All rights reserved.
15 *
16 *  Redistribution and use in source and binary forms, with or without
17 *  modification, are permitted provided that the following conditions
18 *  are met:
19 *  1. Redistributions of source code must retain the above copyright
20 *     notice, this list of conditions and the following disclaimer.
21 *  2. Redistributions in binary form must reproduce the above copyright
22 *     notice, this list of conditions and the following disclaimer in the
23 *     documentation and/or other materials provided with the distribution.
24 *  3. The name of the author may not be used to endorse or promote products
25 *     derived from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
28 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
31 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
36 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40#include "opt_ddb.h"
41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/kernel.h>
45#include <sys/disklabel.h>
46#include <sys/bio.h>
47#include <sys/buf.h>
48#include <sys/queue.h>
49#include <sys/malloc.h>
50#include <sys/device_port.h>
51#include <sys/errno.h>
52
53#include <vm/vm.h>
54
55#ifdef __NetBSD__
56#include <machine/bus.h>
57#include <machine/intr.h>
58
59#include <dev/scsipi/scsi_all.h>
60#include <dev/scsipi/scsipi_all.h>
61#include <dev/scsipi/scsiconf.h>
62#include <dev/scsipi/scsi_disk.h>
63
64#include <machine/dvcfg.h>
65#include <machine/physio_proc.h>
66
67#include <i386/Cbus/dev/scsi_low.h>
68
69#include <dev/ic/wd33c93reg.h>
70#include <i386/Cbus/dev/ct/ctvar.h>
71#endif /* __NetBSD__ */
72
73#ifdef __FreeBSD__
74#include <machine/bus.h>
75
76#include <machine/dvcfg.h>
77#include <machine/physio_proc.h>
78
79#include <cam/scsi/scsi_low.h>
80
81#include <dev/ic/wd33c93reg.h>
82#include <dev/ct/ctvar.h>
83#endif /* __FreeBSD__ */
84
85/***************************************************
86 * DEBUG
87 ***************************************************/
88#define	CT_NTARGETS	8
89#define	CT_NLUNS	8
90#define	CT_RESET_DEFAULT	2000
91
92#ifndef DDB
93#define Debugger() panic("should call debugger here (ct.c)")
94#else /* ! DDB */
95#ifdef __FreeBSD__
96#define Debugger() Debugger("ct")
97#endif /* __FreeBSD__ */
98#endif
99
100#ifdef	CT_DEBUG
101int ct_debug;
102#endif	/* CT_DEBUG */
103
104/***************************************************
105 * default data
106 ***************************************************/
107u_int8_t cthw_cmdlevel[256] = {
108/*   0  1   2   3   4   5   6   7   8   9   A   B   C   E   D   F */
109/*0*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,1  ,0  ,1  ,0  ,0  ,0  ,0  ,0  ,
110/*1*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
111/*2*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,1  ,0  ,1  ,0  ,0  ,0  ,0  ,0  ,
112/*3*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
113/*4*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
114/*5*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
115/*6*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
116/*7*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
117/*8*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
118/*9*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
119/*A*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
120/*B*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
121/*C*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
122/*D*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
123/*E*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
124/*F*/0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,
125};
126
127/* default synch data table */
128/*  A  10    6.6   5.0   4.0   3.3   2.8   2.5   2.0  M/s */
129/*  X  100   150   200   250   300   350   400   500  ns  */
130static struct ct_synch_data ct_synch_data_20MHz[] = {
131	{25, 0xa0}, {37, 0xb0}, {50, 0x20}, {62, 0xd0}, {75, 0x30},
132	{87, 0xf0}, {100, 0x40}, {125, 0x50}, {0, 0}
133};
134
135extern unsigned int delaycount;
136
137/*****************************************************************
138 * Interface functions
139 *****************************************************************/
140static int ct_xfer __P((struct ct_softc *, u_int8_t *, int, int));
141static void ct_io_xfer __P((struct ct_softc *));
142static __inline int ct_reselected __P((struct ct_softc *));
143static void ct_phase_error __P((struct ct_softc *, u_int8_t));
144static int ct_start_selection __P((struct ct_softc *, struct slccb *));
145static int ct_msg __P((struct ct_softc *, struct targ_info *, u_int));
146static int ct_world_start __P((struct ct_softc *, int));
147static __inline void cthw_phase_bypass __P((struct ct_softc *, u_int8_t));
148static int cthw_chip_reset __P((bus_space_tag_t, bus_space_handle_t, int, int));
149static void cthw_bus_reset __P((struct ct_softc *));
150static int ct_nexus __P((struct ct_softc *, struct targ_info *));
151static void cthw_attention __P((struct ct_softc *));
152static int ct_targ_init __P((struct ct_softc *, struct targ_info *));
153
154struct scsi_low_funcs ct_funcs = {
155	SC_LOW_INIT_T ct_world_start,
156	SC_LOW_BUSRST_T cthw_bus_reset,
157	SC_LOW_TARG_INIT_T ct_targ_init,
158
159	SC_LOW_SELECT_T ct_start_selection,
160	SC_LOW_NEXUS_T ct_nexus,
161
162	SC_LOW_ATTEN_T cthw_attention,
163	SC_LOW_MSG_T ct_msg,
164
165	SC_LOW_POLL_T ctintr,
166
167	NULL,	/* SC_LOW_POWER_T cthw_power, */
168};
169
170/**************************************************
171 * HW functions
172 **************************************************/
173static __inline void
174cthw_phase_bypass(ct, ph)
175	struct ct_softc *ct;
176	u_int8_t ph;
177{
178	bus_space_tag_t bst = ct->sc_iot;
179	bus_space_handle_t bsh = ct->sc_ioh;
180
181	ct_cr_write_1(bst, bsh, wd3s_cph, ph);
182	ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_SELECT_ATN_TFR);
183	ct->sc_satgo = CT_SAT_GOING;
184}
185
186static void
187cthw_bus_reset(ct)
188	struct ct_softc *ct;
189{
190
191	/*
192	 * wd33c93 does not have bus reset function.
193	 */
194	if (ct->ct_bus_reset != NULL)
195		((*ct->ct_bus_reset) (ct));
196}
197
198static int
199cthw_chip_reset(bst, bsh, chipclk, hostid)
200	bus_space_tag_t bst;
201	bus_space_handle_t bsh;
202	int chipclk, hostid;
203{
204#define	CT_SELTIMEOUT_20MHz_REGV	(0x80)
205	u_int8_t aux, regv;
206	u_int seltout;
207	int wc;
208
209	/* issue abort cmd */
210	ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_ABORT);
211	delay(1000);	/* 1ms wait */
212	(void) ct_stat_read_1(bst, bsh);
213	(void) ct_cr_read_1(bst, bsh, wd3s_stat);
214
215	/* setup chip registers */
216	regv = 0;
217	seltout = CT_SELTIMEOUT_20MHz_REGV;
218	switch (chipclk)
219	{
220	case 10:
221		seltout = (seltout * chipclk) / 20;
222		regv = 0;
223		break;
224
225	case 15:
226		seltout = (seltout * chipclk) / 20;
227		regv = IDR_FS_12_15;
228		break;
229
230	case 20:
231		seltout = (seltout * chipclk) / 20;
232		regv = IDR_FS_15_20;
233		break;
234
235	default:
236		panic("ct: illegal chip clk rate\n");
237		break;
238	}
239	regv |= IDR_EHP | hostid;
240	ct_cr_write_1(bst, bsh, wd3s_oid, regv);
241
242	ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_RESET);
243	for (wc = CT_RESET_DEFAULT; wc > 0; wc --)
244	{
245		aux = ct_stat_read_1(bst, bsh);
246		if (aux != 0xff && (aux & STR_INT))
247		{
248			if (ct_cr_read_1(bst, bsh, wd3s_stat) == 0)
249				break;
250
251			ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_RESET);
252		}
253		delay(1);
254	}
255	if (wc == 0)
256		return ENXIO;
257
258	ct_cr_write_1(bst, bsh, wd3s_tout, seltout);
259	ct_cr_write_1(bst, bsh, wd3s_sid, SIDR_RESEL);
260	ct_cr_write_1(bst, bsh, wd3s_ctrl, CR_DEFAULT);
261	ct_cr_write_1(bst, bsh, wd3s_synch, 0);
262
263	(void) ct_stat_read_1(bst, bsh);
264	(void) ct_cr_read_1(bst, bsh, wd3s_stat);
265	return 0;
266}
267
268/**************************************************
269 * Attach & Probe
270 **************************************************/
271int
272ctprobesubr(bst, bsh, dvcfg, hsid, chipclk)
273	bus_space_tag_t bst;
274	bus_space_handle_t bsh;
275	u_int dvcfg, chipclk;
276	int hsid;
277{
278
279#if	0
280	if ((ct_stat_read_1(bst, bsh) & STR_BUSY) != 0)
281		return 0;
282#endif
283	if (cthw_chip_reset(bst, bsh, chipclk, hsid) != 0)
284		return 0;
285	return 1;
286}
287
288int
289ctprint(aux, name)
290	void *aux;
291	const char *name;
292{
293
294	if (name != NULL)
295		printf("%s: scsibus ", name);
296	return UNCONF;
297}
298
299void
300ctattachsubr(ct)
301	struct ct_softc *ct;
302{
303	struct scsi_low_softc *slp = &ct->sc_sclow;
304
305	ct->sc_wc = delaycount * 2000;	/* 2 sec */
306	slp->sl_funcs = &ct_funcs;
307	(void) scsi_low_attach(slp, 2, CT_NTARGETS, CT_NLUNS,
308			       sizeof(struct ct_targ_info));
309}
310
311/**************************************************
312 * SCSI LOW interface functions
313 **************************************************/
314static void
315cthw_attention(ct)
316	struct ct_softc *ct;
317{
318	bus_space_tag_t bst = ct->sc_iot;
319	bus_space_handle_t bsh = ct->sc_ioh;
320
321	if ((ct_stat_read_1(bst, bsh) & STR_BUSY) != 0)
322	{
323		ct->sc_atten = 1;
324		return;
325	}
326
327	ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_ASSERT_ATN);
328	delay(10);
329	if ((ct_stat_read_1(bst, bsh) & STR_LCI) != 0)
330	{
331		ct->sc_atten = 1;
332		return;
333	}
334	ct->sc_atten = 0;
335}
336
337static int
338ct_targ_init(ct, ti)
339	struct ct_softc *ct;
340	struct targ_info *ti;
341{
342	struct ct_targ_info *cti = (void *) ti;
343
344	if (ct->sc_chiprev == CT_WD33C93_A)
345	{
346		ti->ti_maxsynch.period = 200 / 4;	/* 5MHz */
347		ti->ti_maxsynch.offset = 8;
348	}
349	else
350	{
351		ti->ti_maxsynch.period = 100 / 4;	/* 10MHz */
352		ti->ti_maxsynch.offset = 12;
353	}
354
355	cti->cti_syncreg = 0;
356	return 0;
357}
358
359static int
360ct_world_start(ct, fdone)
361	struct ct_softc *ct;
362	int fdone;
363{
364	struct scsi_low_softc *slp = &ct->sc_sclow;
365	bus_space_tag_t bst = ct->sc_iot;
366	bus_space_handle_t bsh = ct->sc_ioh;
367	intrmask_t s;
368
369	if (ct->sc_sdp == NULL)
370		ct->sc_sdp = &ct_synch_data_20MHz[0];
371
372	slp->sl_cfgflags |= CFG_MSGUNIFY;
373	if (slp->sl_cfgflags & CFG_NOPARITY)
374		ct->sc_creg = CR_DEFAULT;
375	else
376		ct->sc_creg = CR_DEFAULT_HP;
377
378	if (ct->sc_dma & CT_DMA_DMASTART)
379		(*ct->ct_dma_xfer_stop) (ct);
380	if (ct->sc_dma & CT_DMA_PIOSTART)
381		(*ct->ct_pio_xfer_stop) (ct);
382	ct->sc_dma = 0;
383	ct->sc_atten = 0;
384
385	s = splcam();
386	cthw_chip_reset(bst, bsh, ct->sc_chipclk, slp->sl_hostid);
387	scsi_low_bus_reset(slp);
388	cthw_chip_reset(bst, bsh, ct->sc_chipclk, slp->sl_hostid);
389	splx(s);
390
391	SOFT_INTR_REQUIRED(slp);
392	return 0;
393}
394
395static int
396ct_start_selection(ct, cb)
397	struct ct_softc *ct;
398	struct slccb *cb;
399{
400	struct scsi_low_softc *slp = &ct->sc_sclow;
401	bus_space_tag_t bst = ct->sc_iot;
402	bus_space_handle_t bsh = ct->sc_ioh;
403	struct targ_info *ti = slp->sl_nexus;
404	struct lun_info *li = ti->ti_li;
405	int s;
406	u_int8_t cmd;
407
408	ct->sc_atten = 0;
409	if (cthw_cmdlevel[slp->sl_scp.scp_cmd[0]] != 0)
410	{
411		/*
412		 * This completely violates scsi protocols,
413		 * however some old devices do not work
414		 * properly with scsi attentions.
415		 */
416		if ((li->li_flags & SCSI_LOW_DISC) != 0)
417			cmd = WD3S_SELECT_ATN_TFR;
418		else
419			cmd = WD3S_SELECT_NO_ATN_TFR;
420		ct->sc_satgo = CT_SAT_GOING;
421	}
422	else
423	{
424		cmd = WD3S_SELECT_ATN;
425		ct->sc_satgo = 0;
426	}
427
428	if ((ct_stat_read_1(bst, bsh) & STR_BUSY) != 0)
429		return SCSI_LOW_START_FAIL;
430
431	scsi_low_cmd(slp, ti);
432
433	if ((ct->sc_satgo & CT_SAT_GOING) != 0)
434		ct_write_cmds(bst, bsh,
435			      slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen);
436
437	s = splhigh();
438	if ((ct_stat_read_1(bst, bsh) & STR_BUSY) == 0)
439	{
440		/* XXX:
441		 * Reload a lun again here.
442		 */
443		ct_cr_write_1(bst, bsh, wd3s_lun, li->li_lun);
444		ct_cr_write_1(bst, bsh, wd3s_cmd, cmd);
445		if ((ct_stat_read_1(bst, bsh) & STR_LCI) == 0)
446		{
447			splx(s);
448			SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART);
449			return SCSI_LOW_START_OK;
450		}
451	}
452	splx(s);
453	return SCSI_LOW_START_FAIL;
454}
455
456static int
457ct_msg(ct, ti, msg)
458	struct ct_softc *ct;
459	struct targ_info *ti;
460	u_int msg;
461{
462	struct lun_info *li = ti->ti_li;
463	struct ct_targ_info *cti = (void *) ti;
464	struct ct_synch_data *csp = ct->sc_sdp;
465	u_int offset, period;
466
467	if (msg != SCSI_LOW_MSG_SYNCH)
468		return 0;
469
470	offset = ti->ti_maxsynch.offset;
471	period = ti->ti_maxsynch.period;
472	for ( ; csp->cs_period != 0; csp ++)
473	{
474		if (period == csp->cs_period)
475			break;
476	}
477
478	if (ti->ti_maxsynch.period != 0 && csp->cs_period == 0)
479	{
480		ti->ti_maxsynch.period = 0;
481		ti->ti_maxsynch.offset = 0;
482		cti->cti_syncreg = 0;
483		return EINVAL;
484	}
485
486	cti->cti_syncreg = ((offset & 0x0f) | csp->cs_syncr);
487	if (ct->ct_synch_setup != 0)
488		(*ct->ct_synch_setup) (ct, li);
489	return 0;
490}
491
492/*************************************************
493 * <DATA PHASE>
494 *************************************************/
495static int
496ct_xfer(ct, data, len, direction)
497	struct ct_softc *ct;
498	u_int8_t *data;
499	int len, direction;
500{
501	bus_space_tag_t bst = ct->sc_iot;
502	bus_space_handle_t bsh = ct->sc_ioh;
503	int wc;
504	register u_int8_t aux;
505
506	if (len == 1)
507	{
508		ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_SBT | WD3S_TFR_INFO);
509	}
510	else
511	{
512		cthw_set_count(bst, bsh, len);
513		ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_TFR_INFO);
514	}
515
516	aux = ct_stat_read_1(bst, bsh);
517	if ((aux & STR_LCI) != 0)
518	{
519		cthw_set_count(bst, bsh, 0);
520		return len;
521	}
522
523	for (wc = ct->sc_wc ; wc > 0; wc --)
524	{
525		/* check data ready */
526		if ((aux & (STR_BSY | STR_DBR)) == (STR_BSY | STR_DBR))
527		{
528			if (direction == SCSI_LOW_READ)
529				*data = ct_cr_read_1(bst, bsh, wd3s_data);
530			else
531				ct_cr_write_1(bst, bsh, wd3s_data, *data);
532			len --;
533			if (len <= 0)
534				break;
535			data ++;
536		}
537
538		/* check phase miss */
539		aux = ct_stat_read_1(bst, bsh);
540		if ((aux & STR_INT) != 0)
541			break;
542	}
543	return len;
544}
545
546static void
547ct_io_xfer(ct)
548	struct ct_softc *ct;
549{
550	struct scsi_low_softc *slp = &ct->sc_sclow;
551	bus_space_tag_t bst = ct->sc_iot;
552	bus_space_handle_t bsh = ct->sc_ioh;
553	struct sc_p *sp = &slp->sl_scp;
554	u_int dummy;
555	int len;
556
557	/* io polling mode */
558	ct_cr_write_1(bst, bsh, wd3s_ctrl, ct->sc_creg);
559
560	if (sp->scp_datalen <= 0)
561	{
562		slp->sl_error |= PDMAERR;
563		dummy = 0;
564		len = ct_xfer(ct, (u_int8_t *) &dummy, 1, sp->scp_direction);
565	}
566	else
567		len = ct_xfer(ct, sp->scp_data, sp->scp_datalen,
568			      sp->scp_direction);
569
570	sp->scp_data += (sp->scp_datalen - len);
571	sp->scp_datalen = len;
572}
573
574/**************************************************
575 * <PHASE ERROR>
576 **************************************************/
577struct ct_err {
578	u_char	*pe_msg;
579	u_int	pe_err;
580	u_int	pe_errmsg;
581	int	pe_done;
582};
583
584struct ct_err ct_cmderr[] = {
585/*0*/	{ "illegal cmd", FATALIO, SCSI_LOW_MSG_ABORT, 1},
586/*1*/	{ "unexpected bus free", FATALIO, 0, 1},
587/*2*/	{ NULL, SELTIMEOUTIO, 0, 1},
588/*3*/	{ "scsi bus parity error", PARITYERR, SCSI_LOW_MSG_ERROR, 0},
589/*4*/	{ "scsi bus parity error", PARITYERR, SCSI_LOW_MSG_ERROR, 0},
590/*5*/	{ "unknown" , FATALIO, SCSI_LOW_MSG_ABORT, 1},
591/*6*/	{ "miss reselection (target mode)", FATALIO, SCSI_LOW_MSG_ABORT, 0},
592/*7*/	{ "wrong status byte", PARITYERR, SCSI_LOW_MSG_ERROR, 0},
593};
594
595static void
596ct_phase_error(ct, scsi_status)
597	struct ct_softc *ct;
598	u_int8_t scsi_status;
599{
600	struct scsi_low_softc *slp = &ct->sc_sclow;
601	struct targ_info *ti = slp->sl_nexus;
602	struct ct_err *pep;
603	u_int msg = 0;
604
605	if ((scsi_status & BSR_CM) == BSR_CMDERR &&
606	    (scsi_status & BSR_PHVALID) == 0)
607	{
608		pep = &ct_cmderr[scsi_status & BSR_PM];
609		slp->sl_error |= pep->pe_err;
610		if ((pep->pe_err & PARITYERR) != 0)
611		{
612			if (ti->ti_phase == PH_MSGIN)
613				msg = SCSI_LOW_MSG_PARITY;
614			else
615				msg = SCSI_LOW_MSG_ERROR;
616		}
617		else
618			msg = pep->pe_errmsg;
619
620		if (msg != 0)
621			scsi_low_assert_msg(slp, slp->sl_nexus, msg, 1);
622
623		if (pep->pe_msg != NULL)
624		{
625			printf("%s: phase error: %s",
626				slp->sl_xname, pep->pe_msg);
627			scsi_low_print(slp, slp->sl_nexus);
628		}
629
630		if (pep->pe_done != 0)
631			scsi_low_disconnected(slp, ti);
632	}
633	else
634	{
635		slp->sl_error |= FATALIO;
636		scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, "phase error");
637	}
638}
639
640/**************************************************
641 * ### SCSI PHASE SEQUENCER ###
642 **************************************************/
643static __inline int
644ct_reselected(ct)
645	struct ct_softc *ct;
646{
647	struct scsi_low_softc *slp = &ct->sc_sclow;
648	bus_space_tag_t bst = ct->sc_iot;
649	bus_space_handle_t bsh = ct->sc_ioh;
650	struct targ_info *ti;
651	u_int sid;
652
653	ct->sc_atten = 0;
654	sid = (ct_cr_read_1(bst, bsh, wd3s_sid) & SIDR_IDM);
655	if ((ti = scsi_low_reselected(slp, sid)) == NULL)
656		return EJUSTRETURN;
657
658	ct_cr_write_1(bst, bsh, wd3s_did, sid);
659	ct_cr_write_1(bst, bsh, wd3s_lun, 0);	/* temp */
660	ct_cr_write_1(bst, bsh, wd3s_ctrl, ct->sc_creg | CR_DMA);
661	cthw_set_count(bst, bsh, 0);
662	return EJUSTRETURN;
663}
664
665static int
666ct_nexus(ct, ti)
667	struct ct_softc *ct;
668	struct targ_info *ti;
669{
670	bus_space_tag_t bst = ct->sc_iot;
671	bus_space_handle_t bsh = ct->sc_ioh;
672	struct lun_info *li = ti->ti_li;
673	struct ct_targ_info *cti = (void *) ti;
674
675	if ((li->li_flags & SCSI_LOW_NOPARITY) != 0)
676		ct->sc_creg = CR_DEFAULT;
677	else
678		ct->sc_creg = CR_DEFAULT_HP;
679
680	ct_cr_write_1(bst, bsh, wd3s_did, ti->ti_id);
681	ct_cr_write_1(bst, bsh, wd3s_lun, li->li_lun);
682	ct_cr_write_1(bst, bsh, wd3s_ctrl, ct->sc_creg | CR_DMA);
683	ct_cr_write_1(bst, bsh, wd3s_cph, 0);
684	ct_cr_write_1(bst, bsh, wd3s_synch, cti->cti_syncreg);
685	cthw_set_count(bst, bsh, 0);
686	ct_cr_write_1(bst, bsh, wd3s_lun, li->li_lun);	/* XXX */
687	return 0;
688}
689
690int
691ctintr(arg)
692	void *arg;
693{
694	struct ct_softc *ct = arg;
695	struct scsi_low_softc *slp = &ct->sc_sclow;
696	bus_space_tag_t bst = ct->sc_iot;
697	bus_space_handle_t bsh = ct->sc_ioh;
698	struct targ_info *ti;
699	struct physio_proc *pp;
700	struct buf *bp;
701	int len, satgo;
702	u_int8_t scsi_status, regv;
703
704	if (slp->sl_flags & HW_INACTIVE)
705		return 0;
706
707	/**************************************************
708	 * Get status & bus phase
709	 **************************************************/
710	if ((ct_stat_read_1(bst, bsh) & STR_INT) == 0)
711		return 0;
712
713	scsi_status = ct_cr_read_1(bst, bsh, wd3s_stat);
714	if (scsi_status == ((u_int8_t) -1))
715		return 1;
716
717	/**************************************************
718	 * Check reselection, or nexus
719	 **************************************************/
720	if (scsi_status == BSR_RESEL)
721	{
722		if (ct_reselected(ct) == EJUSTRETURN)
723			return 1;
724	}
725
726	if ((ti = slp->sl_nexus) == NULL)
727		return 1;
728
729	/**************************************************
730	 * Debug section
731	 **************************************************/
732#ifdef	CT_DEBUG
733	if (ct_debug > 0)
734	{
735		scsi_low_print(slp, NULL);
736		printf("%s: scsi_status 0x%x\n\n", slp->sl_xname,
737		       (u_int) scsi_status);
738		if (ct_debug > 1)
739			Debugger();
740	}
741#endif	/* CT_DEBUG */
742
743	/**************************************************
744	 * Internal scsi phase
745	 **************************************************/
746	satgo = ct->sc_satgo;
747	ct->sc_satgo = 0;
748
749	switch (ti->ti_phase)
750	{
751	case PH_SELSTART:
752		if ((satgo & CT_SAT_GOING) == 0)
753		{
754			if (scsi_status != BSR_SELECTED)
755			{
756				ct_phase_error(ct, scsi_status);
757				return 1;
758			}
759			scsi_low_arbit_win(slp, ti);
760			SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED);
761			scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
762			return 1;
763		}
764		else
765		{
766			scsi_low_arbit_win(slp, ti);
767			SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED);
768		}
769		break;
770
771	case PH_RESEL:
772	    	if ((scsi_status & BSR_PHVALID) == 0 ||
773		    (scsi_status & BSR_PM) != BSR_MSGIN)
774		{
775			scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
776				 "phase miss after reselect");
777			return 1;
778		}
779		break;
780
781	default:
782		if (slp->sl_flags & HW_PDMASTART)
783		{
784			slp->sl_flags &= ~HW_PDMASTART;
785			if (ct->sc_dma & CT_DMA_DMASTART)
786			{
787				(*ct->ct_dma_xfer_stop) (ct);
788				ct->sc_dma &= ~CT_DMA_DMASTART;
789			}
790			else
791			{
792				(*ct->ct_pio_xfer_stop) (ct);
793				ct->sc_dma &= ~CT_DMA_PIOSTART;
794			}
795		}
796		break;
797	}
798
799	/**************************************************
800	 * parse scsi phase
801	 **************************************************/
802	if (scsi_status & BSR_PHVALID)
803	{
804		/**************************************************
805		 * Normal SCSI phase.
806		 **************************************************/
807		if ((scsi_status & BSR_CM) == BSR_CMDABT)
808		{
809			ct_phase_error(ct, scsi_status);
810			return 1;
811		}
812
813		switch (scsi_status & BSR_PM)
814		{
815		case BSR_DATAOUT:
816			SCSI_LOW_SETUP_PHASE(ti, PH_DATA);
817			if (scsi_low_data(slp, ti, &bp, SCSI_LOW_WRITE) != 0)
818				return 1;
819			goto common_data_phase;
820
821		case BSR_DATAIN:
822			SCSI_LOW_SETUP_PHASE(ti, PH_DATA);
823			if (scsi_low_data(slp, ti, &bp, SCSI_LOW_READ) != 0)
824				return 1;
825
826common_data_phase:
827			if (slp->sl_scp.scp_datalen <= 0)
828			{
829				ct_io_xfer(ct);
830				return 1;
831			}
832
833			slp->sl_flags |= HW_PDMASTART;
834			if ((ct->sc_xmode & CT_XMODE_PIO) != 0 &&
835			    (slp->sl_scp.scp_datalen % DEV_BSIZE) == 0)
836			{
837				pp = physio_proc_enter(bp);
838				ct->sc_dma |= CT_DMA_PIOSTART;
839				(*ct->ct_pio_xfer_start) (ct);
840				physio_proc_leave(pp);
841				return 1;
842			}
843			else
844			{
845				ct->sc_dma |= CT_DMA_DMASTART;
846				(*ct->ct_dma_xfer_start) (ct);
847				ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_TFR_INFO);
848			}
849			return 1;
850
851		case BSR_CMDOUT:
852			SCSI_LOW_SETUP_PHASE(ti, PH_CMD);
853			if (scsi_low_cmd(slp, ti) != 0)
854				break;
855
856			if (ct_xfer(ct,
857				    slp->sl_scp.scp_cmd,
858				    slp->sl_scp.scp_cmdlen,
859				    SCSI_LOW_WRITE) != 0)
860			{
861				printf("%s: scsi cmd xfer short\n",
862					slp->sl_xname);
863			}
864			return 1;
865
866		case BSR_STATIN:
867			SCSI_LOW_SETUP_PHASE(ti, PH_STAT);
868#ifdef CT_USE_CCSEQ
869			if (scsi_low_is_msgout_continue(ti) != 0 ||
870			    ct->sc_atten != 0)
871			{
872				ct_xfer(ct, &ti->ti_status, 1, SCSI_LOW_READ);
873			}
874			else
875			{
876				cthw_set_count(bst, bsh, 0);
877				cthw_phase_bypass(ct, 0x41);
878			}
879#else	/* !CT_USE_CCSEQ */
880			ct_xfer(ct, &ti->ti_status, 1, SCSI_LOW_READ);
881#endif	/* !CT_USE_CCSEQ */
882			return 1;
883
884		case BSR_UNSPINFO0:
885		case BSR_UNSPINFO1:
886			printf("%s: illegal bus phase (0x%x)\n", slp->sl_xname,
887				(u_int) scsi_status);
888			scsi_low_print(slp, ti);
889			return 1;
890
891		case BSR_MSGOUT:
892			SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT);
893			len = scsi_low_msgout(slp, ti);
894			if (ct_xfer(ct, ti->ti_msgoutstr, len, SCSI_LOW_WRITE))
895			{
896				printf("%s: scsi msgout xfer short\n",
897					slp->sl_xname);
898				scsi_low_assert_msg(slp, ti,
899					SCSI_LOW_MSG_ABORT, 1);
900			}
901			return 1;
902
903		case BSR_MSGIN:/* msg in */
904			SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
905			ct_xfer(ct, &regv, 1, SCSI_LOW_READ);
906			scsi_low_msgin(slp, ti, regv);
907			return 1;
908		}
909	}
910	else
911	{
912		/**************************************************
913		 * Special SCSI phase
914		 **************************************************/
915		switch (scsi_status)
916		{
917		case BSR_SATSDP: /* SAT with save data pointer */
918			SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
919			scsi_low_msgin(slp, ti, MSG_SAVESP);
920			cthw_phase_bypass(ct, 0x41);
921			return 1;
922
923		case BSR_SATFIN: /* SAT COMPLETE */
924			/*
925			 * emulate statusin => msgin
926			 */
927			ti->ti_status = ct_cr_read_1(bst, bsh, wd3s_lun);
928			SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
929			SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
930			scsi_low_disconnected(slp, ti);
931			return 1;
932
933		case BSR_ACKREQ: /* negate ACK */
934			if (ct->sc_atten != 0)
935				cthw_attention(ct);
936
937			ct_cr_write_1(bst, bsh, wd3s_cmd, WD3S_NEGATE_ACK);
938			return 1;
939
940		case BSR_DISC: /* disconnect */
941			if (slp->sl_msgphase == MSGPH_NULL &&
942			    (satgo & CT_SAT_GOING) != 0)
943			{
944				/*
945				 * emulate disconnect msg
946				 */
947				SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
948				SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
949			}
950			scsi_low_disconnected(slp, ti);
951			return 1;
952
953		default:
954			break;
955		}
956	}
957
958	ct_phase_error(ct, scsi_status);
959	return 1;
960}
961