xref: /csrg-svn/sys/luna68k/stand/sc.c (revision 57096)
1*57096Sakito /*
2*57096Sakito  * Copyright (c) 1992 OMRON Corporation.
3*57096Sakito  * Copyright (c) 1992 The Regents of the University of California.
4*57096Sakito  * All rights reserved.
5*57096Sakito  *
6*57096Sakito  * This code is derived from software contributed to Berkeley by
7*57096Sakito  * OMRON Corporation.
8*57096Sakito  *
9*57096Sakito  * %sccs.include.redist.c%
10*57096Sakito  *
11*57096Sakito  *	@(#)sc.c	7.1 (Berkeley) 12/13/92
12*57096Sakito  */
13*57096Sakito 
14*57096Sakito /*
15*57096Sakito  * sc.c -- SCSI Protocole Controller (SPC)  driver
16*57096Sakito  * remaked by A.Fujita, MAR-11-199
17*57096Sakito  */
18*57096Sakito 
19*57096Sakito 
20*57096Sakito #define NSC	1
21*57096Sakito 
22*57096Sakito #include <sys/param.h>
23*57096Sakito #include <luna68k/dev/scsireg.h>
24*57096Sakito #include <luna68k/stand/device.h>
25*57096Sakito #include <luna68k/stand/scsivar.h>
26*57096Sakito 
27*57096Sakito #define SCSI_IPL	2
28*57096Sakito #define SCSI_ID		7
29*57096Sakito 
30*57096Sakito int	scinit(), scstart(), scgo(), scintr(), scdone();
31*57096Sakito void	screset();
32*57096Sakito struct	driver scdriver = {
33*57096Sakito 	scinit, "sc", scstart, scgo, scintr, scdone
34*57096Sakito };
35*57096Sakito 
36*57096Sakito struct	scsi_softc scsi_softc[NSC];
37*57096Sakito 
38*57096Sakito /*
39*57096Sakito  * Initialize SPC & Data Structure
40*57096Sakito  */
41*57096Sakito 
42*57096Sakito int
43*57096Sakito scinit(hc)
44*57096Sakito 	register struct hp_ctlr *hc;
45*57096Sakito {
46*57096Sakito 	register struct scsi_softc *hs = &scsi_softc[hc->hp_unit];
47*57096Sakito 	register int i;
48*57096Sakito 
49*57096Sakito 	hc->hp_ipl    = SCSI_IPL;
50*57096Sakito 	hs->sc_hc     = hc;
51*57096Sakito 
52*57096Sakito 	hs->sc_flags  = 0;
53*57096Sakito 	hs->sc_phase  = BUS_FREE_PHASE;
54*57096Sakito 	hs->sc_target = SCSI_ID;
55*57096Sakito 
56*57096Sakito 	hs->sc_cdb    = NULL;
57*57096Sakito 	hs->sc_cdblen = 0;
58*57096Sakito 	hs->sc_buf    = NULL;
59*57096Sakito 	hs->sc_len    = 0;
60*57096Sakito 	hs->sc_lock   = NULL;
61*57096Sakito 
62*57096Sakito 	hs->sc_stat   = 0;
63*57096Sakito 	hs->sc_msg[0] = 0;
64*57096Sakito 
65*57096Sakito 	screset(hc->hp_unit);
66*57096Sakito 	return(1);
67*57096Sakito }
68*57096Sakito 
69*57096Sakito void
70*57096Sakito screset(unit)
71*57096Sakito 	register int unit;
72*57096Sakito {
73*57096Sakito 	register struct scsi_softc *hs = &scsi_softc[unit];
74*57096Sakito 	volatile register struct scsidevice *hd =
75*57096Sakito 				(struct scsidevice *)hs->sc_hc->hp_addr;
76*57096Sakito 
77*57096Sakito 	printf("sc%d: ", unit);
78*57096Sakito 
79*57096Sakito 	/*
80*57096Sakito 	 * Disable interrupts then reset the FUJI chip.
81*57096Sakito 	 */
82*57096Sakito 
83*57096Sakito 	hd->scsi_sctl = SCTL_DISABLE | SCTL_CTRLRST;
84*57096Sakito 	hd->scsi_scmd = 0;
85*57096Sakito 	hd->scsi_pctl = 0;
86*57096Sakito 	hd->scsi_temp = 0;
87*57096Sakito 	hd->scsi_tch  = 0;
88*57096Sakito 	hd->scsi_tcm  = 0;
89*57096Sakito 	hd->scsi_tcl  = 0;
90*57096Sakito 	hd->scsi_ints = 0;
91*57096Sakito 
92*57096Sakito 	/* We can use Asynchronous Transfer only */
93*57096Sakito 	printf("async");
94*57096Sakito 
95*57096Sakito 	/*
96*57096Sakito 	 * Configure MB89352 with its SCSI address, all
97*57096Sakito 	 * interrupts enabled & appropriate parity.
98*57096Sakito 	 */
99*57096Sakito 	hd->scsi_bdid = SCSI_ID;
100*57096Sakito 	hd->scsi_sctl = SCTL_DISABLE | SCTL_ABRT_ENAB|
101*57096Sakito 			SCTL_PARITY_ENAB | SCTL_RESEL_ENAB |
102*57096Sakito 			SCTL_INTR_ENAB;
103*57096Sakito 	printf(", parity");
104*57096Sakito 
105*57096Sakito 	DELAY(400);
106*57096Sakito 	hd->scsi_sctl &= ~SCTL_DISABLE;
107*57096Sakito 
108*57096Sakito 	printf(", scsi id %d\n", SCSI_ID);
109*57096Sakito }
110*57096Sakito 
111*57096Sakito 
112*57096Sakito /*
113*57096Sakito  * SPC Arbitration/Selection routine
114*57096Sakito  */
115*57096Sakito 
116*57096Sakito int
117*57096Sakito issue_select(hd, target)
118*57096Sakito 	volatile register struct scsidevice *hd;
119*57096Sakito 	u_char target;
120*57096Sakito {
121*57096Sakito 	hd->scsi_pctl = 0;
122*57096Sakito 	hd->scsi_temp = (1 << SCSI_ID) | (1 << target);
123*57096Sakito 
124*57096Sakito 	/* select timeout is hardcoded to 2ms */
125*57096Sakito 	hd->scsi_tch = 0;
126*57096Sakito 	hd->scsi_tcm = 32;
127*57096Sakito 	hd->scsi_tcl = 4;
128*57096Sakito 
129*57096Sakito 	hd->scsi_scmd = SCMD_SELECT;
130*57096Sakito 
131*57096Sakito 	return (1);
132*57096Sakito }
133*57096Sakito 
134*57096Sakito 
135*57096Sakito /*
136*57096Sakito  * SPC Manual Transfer routines
137*57096Sakito  */
138*57096Sakito 
139*57096Sakito /* not yet */
140*57096Sakito 
141*57096Sakito 
142*57096Sakito /*
143*57096Sakito  * SPC Program Transfer routines
144*57096Sakito  */
145*57096Sakito 
146*57096Sakito int
147*57096Sakito ixfer_start(hd, len, phase, wait)
148*57096Sakito 	volatile register struct scsidevice *hd;
149*57096Sakito 	int len;
150*57096Sakito 	u_char phase;
151*57096Sakito 	register int wait;
152*57096Sakito {
153*57096Sakito 	hd->scsi_tch  = ((len & 0xff0000) >> 16);
154*57096Sakito 	hd->scsi_tcm  = ((len & 0x00ff00) >>  8);
155*57096Sakito 	hd->scsi_tcl  =  (len & 0x0000ff);
156*57096Sakito 	hd->scsi_pctl = phase;
157*57096Sakito 	hd->scsi_scmd = SCMD_XFR | SCMD_PROG_XFR;
158*57096Sakito }
159*57096Sakito 
160*57096Sakito int
161*57096Sakito ixfer_out(hd, len, buf)
162*57096Sakito 	volatile register struct scsidevice *hd;
163*57096Sakito 	int len;
164*57096Sakito 	register u_char *buf;
165*57096Sakito {
166*57096Sakito 	for(; len > 0; len--) {
167*57096Sakito 		while (hd->scsi_ssts & SSTS_DREG_FULL) {
168*57096Sakito 			DELAY(5);
169*57096Sakito 		}
170*57096Sakito 		hd->scsi_dreg = *buf++;
171*57096Sakito 	}
172*57096Sakito }
173*57096Sakito 
174*57096Sakito int
175*57096Sakito ixfer_in(hd, len, buf)
176*57096Sakito 	volatile register struct scsidevice *hd;
177*57096Sakito 	int len;
178*57096Sakito 	register u_char *buf;
179*57096Sakito {
180*57096Sakito 	for (; len > 0; len--) {
181*57096Sakito 		int i;
182*57096Sakito 		while (hd->scsi_ssts & SSTS_DREG_EMPTY) {
183*57096Sakito 			DELAY(5);
184*57096Sakito 		}
185*57096Sakito 		*buf++ = hd->scsi_dreg;
186*57096Sakito 	}
187*57096Sakito }
188*57096Sakito 
189*57096Sakito 
190*57096Sakito /*
191*57096Sakito  * SPC drive routines
192*57096Sakito  */
193*57096Sakito 
194*57096Sakito int
195*57096Sakito scrun(ctlr, slave, cdb, cdblen, buf, len, lock)
196*57096Sakito 	int ctlr, slave;
197*57096Sakito 	u_char *cdb;
198*57096Sakito 	int cdblen;
199*57096Sakito 	u_char *buf;
200*57096Sakito 	int len;
201*57096Sakito 	int *lock;
202*57096Sakito {
203*57096Sakito 	register struct scsi_softc *hs = &scsi_softc[ctlr];
204*57096Sakito 	volatile register struct scsidevice *hd =
205*57096Sakito 		(struct scsidevice *) hs->sc_hc->hp_addr;
206*57096Sakito 
207*57096Sakito 	if (hd->scsi_ssts & (SSTS_INITIATOR|SSTS_TARGET|SSTS_BUSY))
208*57096Sakito 		return(0);
209*57096Sakito 
210*57096Sakito 	hs->sc_flags  = 0;
211*57096Sakito 	hs->sc_phase  = ARB_SEL_PHASE;
212*57096Sakito 	hs->sc_target = slave;
213*57096Sakito 
214*57096Sakito 	hs->sc_cdb    = cdb;
215*57096Sakito 	hs->sc_cdblen = cdblen;
216*57096Sakito 	hs->sc_buf    = buf;
217*57096Sakito 	hs->sc_len    = len;
218*57096Sakito 	hs->sc_lock   = lock;
219*57096Sakito 
220*57096Sakito 	hs->sc_stat   = 0;
221*57096Sakito 	hs->sc_msg[0] = 0;
222*57096Sakito 
223*57096Sakito 	*(hs->sc_lock) = SC_IN_PROGRESS;
224*57096Sakito 	issue_select(hd, hs->sc_target);
225*57096Sakito 
226*57096Sakito 	return(1);
227*57096Sakito }
228*57096Sakito 
229*57096Sakito int
230*57096Sakito scfinish(ctlr)
231*57096Sakito 	int ctlr;
232*57096Sakito {
233*57096Sakito 	register struct scsi_softc *hs = &scsi_softc[ctlr];
234*57096Sakito 	int status = hs->sc_stat;
235*57096Sakito 
236*57096Sakito 	hs->sc_flags  = 0;
237*57096Sakito 	hs->sc_phase  = BUS_FREE_PHASE;
238*57096Sakito 	hs->sc_target = SCSI_ID;
239*57096Sakito 
240*57096Sakito 	hs->sc_cdb    = NULL;
241*57096Sakito 	hs->sc_cdblen = 0;
242*57096Sakito 	hs->sc_buf    = NULL;
243*57096Sakito 	hs->sc_len    = 0;
244*57096Sakito 	hs->sc_lock   = NULL;
245*57096Sakito 
246*57096Sakito 	hs->sc_stat   = 0;
247*57096Sakito 	hs->sc_msg[0] = 0;
248*57096Sakito 
249*57096Sakito 	return(status);
250*57096Sakito }
251*57096Sakito 
252*57096Sakito int
253*57096Sakito scabort(hs, hd)
254*57096Sakito 	register struct scsi_softc *hs;
255*57096Sakito 	volatile register struct scsidevice *hd;
256*57096Sakito {
257*57096Sakito 	int len;
258*57096Sakito 	u_char junk;
259*57096Sakito 
260*57096Sakito 	printf("sc%d: abort  phase=0x%x, ssts=0x%x, ints=0x%x\n",
261*57096Sakito 		hs->sc_hc->hp_unit, hd->scsi_psns, hd->scsi_ssts,
262*57096Sakito 		hd->scsi_ints);
263*57096Sakito 
264*57096Sakito 	if (hd->scsi_ints != 0)
265*57096Sakito 		hd->scsi_ints = hd->scsi_ints;
266*57096Sakito 
267*57096Sakito 	if (hd->scsi_psns == 0 || (hd->scsi_ssts & SSTS_INITIATOR) == 0)
268*57096Sakito 		/* no longer connected to scsi target */
269*57096Sakito 		return;
270*57096Sakito 
271*57096Sakito 	/* get the number of bytes remaining in current xfer + fudge */
272*57096Sakito 	len = (hd->scsi_tch << 16) | (hd->scsi_tcm << 8) | hd->scsi_tcl;
273*57096Sakito 
274*57096Sakito 	/* for that many bus cycles, try to send an abort msg */
275*57096Sakito 	for (len += 1024; (hd->scsi_ssts & SSTS_INITIATOR) && --len >= 0; ) {
276*57096Sakito 		hd->scsi_scmd = SCMD_SET_ATN;
277*57096Sakito 
278*57096Sakito 		while ((hd->scsi_psns & PSNS_REQ) == 0) {
279*57096Sakito 			if (! (hd->scsi_ssts & SSTS_INITIATOR))
280*57096Sakito 				goto out;
281*57096Sakito 			DELAY(1);
282*57096Sakito 		}
283*57096Sakito 
284*57096Sakito 		if ((hd->scsi_psns & PHASE) == MESG_OUT_PHASE)
285*57096Sakito 			hd->scsi_scmd = SCMD_RST_ATN;
286*57096Sakito 		hd->scsi_pctl = hs->sc_phase = hd->scsi_psns & PHASE;
287*57096Sakito 
288*57096Sakito 		if (hd->scsi_psns & PHASE_IO) {
289*57096Sakito 			/* one of the input phases - read & discard a byte */
290*57096Sakito 			hd->scsi_scmd = SCMD_SET_ACK;
291*57096Sakito 			while (hd->scsi_psns & PSNS_REQ)
292*57096Sakito 				DELAY(1);
293*57096Sakito 			junk = hd->scsi_temp;
294*57096Sakito 		} else {
295*57096Sakito 			/* one of the output phases - send an abort msg */
296*57096Sakito 			hd->scsi_temp = MSG_ABORT;
297*57096Sakito 			hd->scsi_scmd = SCMD_SET_ACK;
298*57096Sakito 			while (hd->scsi_psns & PSNS_REQ)
299*57096Sakito 				DELAY(1);
300*57096Sakito 		}
301*57096Sakito 
302*57096Sakito 		hd->scsi_scmd = SCMD_RST_ACK;
303*57096Sakito 	}
304*57096Sakito out:
305*57096Sakito 	/*
306*57096Sakito 	 * Either the abort was successful & the bus is disconnected or
307*57096Sakito 	 * the device didn't listen.  If the latter, announce the problem.
308*57096Sakito 	 * Either way, reset the card & the SPC.
309*57096Sakito 	 */
310*57096Sakito 	if (len < 0 && hs)
311*57096Sakito 		printf("sc%d: abort failed.  phase=0x%x, ssts=0x%x\n",
312*57096Sakito 			hs->sc_hc->hp_unit, hd->scsi_psns, hd->scsi_ssts);
313*57096Sakito }
314*57096Sakito 
315*57096Sakito 
316*57096Sakito /*
317*57096Sakito  * SCSI Command Handler
318*57096Sakito  */
319*57096Sakito 
320*57096Sakito int
321*57096Sakito scsi_test_unit_rdy(ctlr, slave, unit)
322*57096Sakito 	int ctlr, slave, unit;
323*57096Sakito {
324*57096Sakito 	static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY };
325*57096Sakito 	int status, lock;
326*57096Sakito 
327*57096Sakito #ifdef DEBUG
328*57096Sakito 	printf("scsi_test_unit_rdy( %d, %d, %d): Start\n", ctlr, slave, unit);
329*57096Sakito #endif
330*57096Sakito 
331*57096Sakito 	cdb.lun = unit;
332*57096Sakito 
333*57096Sakito 	if (!(scrun(ctlr, slave, &cdb, 6, (u_char *) 0, 0, &lock))) {
334*57096Sakito #ifdef DEBUG
335*57096Sakito 		printf("scsi_test_unit_rdy: Command Transfer Failed.\n");
336*57096Sakito #endif
337*57096Sakito 		return(-1);
338*57096Sakito 	}
339*57096Sakito 
340*57096Sakito 	while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED))
341*57096Sakito 		DELAY(10);
342*57096Sakito 
343*57096Sakito 	status = scfinish(ctlr);
344*57096Sakito 
345*57096Sakito 	if (lock == SC_IO_COMPLETE) {
346*57096Sakito #ifdef DEBUG
347*57096Sakito 		printf("scsi_test_unit_rdy: Status -- 0x%x\n", status);
348*57096Sakito #endif
349*57096Sakito 		return(status);
350*57096Sakito 	} else {
351*57096Sakito 		return(lock);
352*57096Sakito 	}
353*57096Sakito }
354*57096Sakito 
355*57096Sakito int
356*57096Sakito scsi_request_sense(ctlr, slave, unit, buf, len)
357*57096Sakito 	int ctlr, slave, unit;
358*57096Sakito 	u_char *buf;
359*57096Sakito 	unsigned len;
360*57096Sakito {
361*57096Sakito 	static struct scsi_cdb6 cdb = {	CMD_REQUEST_SENSE };
362*57096Sakito 	int status, lock;
363*57096Sakito 
364*57096Sakito #ifdef DEBUG
365*57096Sakito 	printf("scsi_request_sense: Start\n");
366*57096Sakito #endif
367*57096Sakito 
368*57096Sakito 	/* Request Sense$N>l9g!"E>Aw$5$l$k%G!<%?D9$O%?!<%2368H$K0MB8$7!"        */
369*57096Sakito 	/* %;%s%9%G!<%?$N#8/usr/home/csrg/sccs/sys/luna68k/stand/SCCS/s.sc.c$%HL\$NAddtional Sens Length$K$h$jF0E*$K7hDj$9$k!#*/
370*57096Sakito 	/* $3$3$G$O%G!<%?!<E>Aw?t$rcdb$NAllocation Length$K:GDcD9$G$"$k#8/usr/home/csrg/sccs/sys/luna68k/stand/SCCS/s.sc.c$%H */
371*57096Sakito 	/* $r8GDj$7$F!"#S#P#C$N=hM}%7!<%1%s%9$rJx$5$J$$$h$&$K$7$F$$$k!#         */
372*57096Sakito 
373*57096Sakito 	/* %F!<@(#)sc.c	7.1f%K373H$N>uBV$rD4$Y$k$?$a!"Addtional Sens Field$r%"%/%;%9$9$k */
374*57096Sakito 	/* I,MW$,$"$k$N$G12/13/92P%$%97.1i%$%PB&$Glen$r7hDj$9$k$3$H$K$9$k            */
375*57096Sakito 
376*57096Sakito 	cdb.lun = unit;
377*57096Sakito 	cdb.len = len;
378*57096Sakito 
379*57096Sakito 	if (!(scrun(ctlr, slave, &cdb, 6, buf, len, &lock))) {
380*57096Sakito #ifdef DEBUG
381*57096Sakito 		printf("scsi_request_sense: Command Transfer Failed.\n");
382*57096Sakito #endif
383*57096Sakito 		return(-1);
384*57096Sakito 	}
385*57096Sakito 
386*57096Sakito 	while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED))
387*57096Sakito 		DELAY(10);
388*57096Sakito 
389*57096Sakito 	status = scfinish(ctlr);
390*57096Sakito 
391*57096Sakito 	if (lock == SC_IO_COMPLETE) {
392*57096Sakito #ifdef DEBUG
393*57096Sakito 		printf("scsi_request_sense: Status -- 0x%x\n", status);
394*57096Sakito #endif
395*57096Sakito 		return(status);
396*57096Sakito 	} else {
397*57096Sakito 		return(lock);
398*57096Sakito 	}
399*57096Sakito }
400*57096Sakito 
401*57096Sakito int
402*57096Sakito scsi_immed_command(ctlr, slave, unit, cdb, buf, len)
403*57096Sakito 	int ctlr, slave, unit;
404*57096Sakito 	struct scsi_fmt_cdb *cdb;
405*57096Sakito 	u_char *buf;
406*57096Sakito 	unsigned len;
407*57096Sakito {
408*57096Sakito 	int lock, status;
409*57096Sakito 
410*57096Sakito #ifdef DEBUG
411*57096Sakito 	printf("scsi_immed_command( %d, %d, %d, cdb(%d), buf, %d): Start\n",
412*57096Sakito 	       ctlr, slave, unit, cdb->len, len);
413*57096Sakito #endif
414*57096Sakito 
415*57096Sakito 	cdb->cdb[1] |= unit << 5;
416*57096Sakito 
417*57096Sakito 	if (!(scrun(ctlr, slave, &cdb->cdb[0], cdb->len, buf, len, &lock))) {
418*57096Sakito #ifdef DEBUG
419*57096Sakito 		printf("scsi_immed_command: Command Transfer Failed.\n");
420*57096Sakito #endif
421*57096Sakito 		return(-1);
422*57096Sakito 	}
423*57096Sakito 
424*57096Sakito 	while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED))
425*57096Sakito 		DELAY(10);
426*57096Sakito 
427*57096Sakito 	status = scfinish(ctlr);
428*57096Sakito 
429*57096Sakito 	if (lock == SC_IO_COMPLETE) {
430*57096Sakito #ifdef DEBUG
431*57096Sakito 		printf("scsi_immed_command: Status -- 0x%x\n", status);
432*57096Sakito #endif
433*57096Sakito 		return(status);
434*57096Sakito 	} else {
435*57096Sakito 		return(lock);
436*57096Sakito 	}
437*57096Sakito }
438*57096Sakito 
439*57096Sakito int
440*57096Sakito scsi_format_unit(ctlr, slave, unit)
441*57096Sakito 	int ctlr, slave, unit;
442*57096Sakito {
443*57096Sakito 	static struct scsi_cdb6 cdb = { CMD_FORMAT_UNIT, 0, 0, 0, 0, 0 };
444*57096Sakito 	int status, lock, count = 0;
445*57096Sakito 
446*57096Sakito #ifdef DEBUG
447*57096Sakito 	printf("scsi_format_unit( %d, %d, %d): Start\n", ctlr, slave, unit);
448*57096Sakito #endif
449*57096Sakito 
450*57096Sakito 	cdb.lun = unit;
451*57096Sakito 
452*57096Sakito 	if (!(scrun(ctlr, slave, &cdb, 6, (u_char *) 0, 0, &lock))) {
453*57096Sakito #ifdef DEBUG
454*57096Sakito 		printf("scsi_format_unit: Command Transfer Failed.\n");
455*57096Sakito #endif
456*57096Sakito 		return(-1);
457*57096Sakito 	}
458*57096Sakito 
459*57096Sakito 	while ((lock == SC_IN_PROGRESS) || (lock == SC_DISCONNECTED)) {
460*57096Sakito 		DELAY(1000000);
461*57096Sakito #ifdef DEBUG
462*57096Sakito 		if ((count % 60) == 0)
463*57096Sakito 			printf("scsi_format_unit: %d\n");
464*57096Sakito #endif
465*57096Sakito 	}
466*57096Sakito 
467*57096Sakito 	status = scfinish(ctlr);
468*57096Sakito 
469*57096Sakito 	if (lock == SC_IO_COMPLETE) {
470*57096Sakito #ifdef DEBUG
471*57096Sakito 		printf("scsi_format_unit: Status -- 0x%x\n", status);
472*57096Sakito #endif
473*57096Sakito 		return(status);
474*57096Sakito 	} else {
475*57096Sakito 		return(lock);
476*57096Sakito 	}
477*57096Sakito }
478*57096Sakito 
479*57096Sakito 
480*57096Sakito /*
481*57096Sakito  * ????
482*57096Sakito  */
483*57096Sakito 
484*57096Sakito int
485*57096Sakito scstart()
486*57096Sakito {
487*57096Sakito }
488*57096Sakito 
489*57096Sakito int
490*57096Sakito scgo()
491*57096Sakito {
492*57096Sakito }
493*57096Sakito 
494*57096Sakito int
495*57096Sakito scdone()
496*57096Sakito {
497*57096Sakito }
498*57096Sakito 
499*57096Sakito 
500*57096Sakito /*
501*57096Sakito  * Interrupt Routine
502*57096Sakito  */
503*57096Sakito 
504*57096Sakito int
505*57096Sakito scintr()
506*57096Sakito {
507*57096Sakito 	register struct scsi_softc *hs;
508*57096Sakito 	volatile register struct scsidevice *hd;
509*57096Sakito 	register u_char ints, temp;
510*57096Sakito 	register int i;
511*57096Sakito 	u_char *buf;
512*57096Sakito 	int len;
513*57096Sakito 
514*57096Sakito 	for (i = 0; i < NSC; i++) {
515*57096Sakito 		hs = &scsi_softc[i];
516*57096Sakito 		hd = (struct scsidevice *) hs->sc_hc->hp_addr;
517*57096Sakito 		if ((ints = hd->scsi_ints) != 0)
518*57096Sakito 			goto get_intr;
519*57096Sakito 	}
520*57096Sakito 
521*57096Sakito 	/* Unknown Interrupt occured */
522*57096Sakito 	return;
523*57096Sakito 
524*57096Sakito 
525*57096Sakito 	/*
526*57096Sakito 	 * Interrupt
527*57096Sakito 	 */
528*57096Sakito 
529*57096Sakito  get_intr:
530*57096Sakito #ifdef DEBUG
531*57096Sakito 	printf("scintr: INTS 0x%x, SSTS 0x%x,  PCTL 0x%x,  PSNS 0x%x    0x%x\n",
532*57096Sakito 	        ints, hd->scsi_ssts, hd->scsi_pctl, hd->scsi_psns,
533*57096Sakito 	        hs->sc_phase);
534*57096Sakito #endif
535*57096Sakito 	if (ints & INTS_RESEL) {
536*57096Sakito 		if (hs->sc_phase == BUS_FREE_PHASE) {
537*57096Sakito 			temp = hd->scsi_temp & ~(1 << SCSI_ID);
538*57096Sakito 			for (i = 0; temp != 1; i++) {
539*57096Sakito 				temp >>= 1;
540*57096Sakito 			}
541*57096Sakito 			hs->sc_target = i;
542*57096Sakito 			*(hs->sc_lock) = SC_IN_PROGRESS;
543*57096Sakito 		} else
544*57096Sakito 			goto abort;
545*57096Sakito 	} else if (ints & INTS_DISCON) {
546*57096Sakito 		if ((hs->sc_msg[0] == MSG_CMD_COMPLETE) || (hs->sc_msg[0] == MSG_DISCONNECT)) {
547*57096Sakito 			hs->sc_phase  = BUS_FREE_PHASE;
548*57096Sakito 			hs->sc_target = SCSI_ID;
549*57096Sakito 			if (hs->sc_msg[0] == MSG_CMD_COMPLETE)
550*57096Sakito 				/* SCSI IO complete */
551*57096Sakito 				*(hs->sc_lock) = SC_IO_COMPLETE;
552*57096Sakito 			else
553*57096Sakito 				/* Cisconnected from Target */
554*57096Sakito 				*(hs->sc_lock) = SC_DISCONNECTED;
555*57096Sakito 			hd->scsi_ints = ints;
556*57096Sakito 			return;
557*57096Sakito 		} else
558*57096Sakito 			goto abort;
559*57096Sakito 	} else if (ints & INTS_CMD_DONE) {
560*57096Sakito 		if (hs->sc_phase == BUS_FREE_PHASE)
561*57096Sakito 			goto abort;
562*57096Sakito 		else if (hs->sc_phase == MESG_IN_PHASE) {
563*57096Sakito 			hd->scsi_scmd = SCMD_RST_ACK;
564*57096Sakito 			hd->scsi_ints = ints;
565*57096Sakito 			hs->sc_phase  = hd->scsi_psns & PHASE;
566*57096Sakito 			return;
567*57096Sakito 		}
568*57096Sakito 		if (hs->sc_flags & SC_SEL_TIMEOUT)
569*57096Sakito 			hs->sc_flags &= ~SC_SEL_TIMEOUT;
570*57096Sakito 	} else if (ints & INTS_SRV_REQ) {
571*57096Sakito 		if (hs->sc_phase != MESG_IN_PHASE)
572*57096Sakito 			goto abort;
573*57096Sakito 	} else if (ints & INTS_TIMEOUT) {
574*57096Sakito 		if (hs->sc_phase == ARB_SEL_PHASE) {
575*57096Sakito 			if (hs->sc_flags & SC_SEL_TIMEOUT) {
576*57096Sakito 				hs->sc_flags &= ~SC_SEL_TIMEOUT;
577*57096Sakito 				hs->sc_phase  = BUS_FREE_PHASE;
578*57096Sakito 				hs->sc_target = SCSI_ID;
579*57096Sakito 				/* Such SCSI Device is not conected. */
580*57096Sakito 				*(hs->sc_lock) = SC_DEV_NOT_FOUND;
581*57096Sakito 				hd->scsi_ints = ints;
582*57096Sakito 				return;
583*57096Sakito 			} else {
584*57096Sakito 				/* wait more 250 usec */
585*57096Sakito 				hs->sc_flags |= SC_SEL_TIMEOUT;
586*57096Sakito 				hd->scsi_temp = 0;
587*57096Sakito 				hd->scsi_tch  = 0;
588*57096Sakito 				hd->scsi_tcm  = 0x06;
589*57096Sakito 				hd->scsi_tcl  = 0x40;
590*57096Sakito 				hd->scsi_ints = ints;
591*57096Sakito 				return;
592*57096Sakito 			}
593*57096Sakito 		} else
594*57096Sakito 			goto abort;
595*57096Sakito 	} else
596*57096Sakito 		goto abort;
597*57096Sakito 
598*57096Sakito 	hd->scsi_ints = ints;
599*57096Sakito 
600*57096Sakito 	/*
601*57096Sakito 	 * Next SCSI Transfer
602*57096Sakito 	 */
603*57096Sakito 
604*57096Sakito 	while ((hd->scsi_psns & PSNS_REQ) == 0) {
605*57096Sakito 		DELAY(1);
606*57096Sakito 	}
607*57096Sakito 
608*57096Sakito 	hs->sc_phase = hd->scsi_psns & PHASE;
609*57096Sakito 
610*57096Sakito 	if ((hs->sc_phase == DATA_OUT_PHASE) || (hs->sc_phase == DATA_IN_PHASE)) {
611*57096Sakito 		len = hs->sc_len;
612*57096Sakito 		buf = hs->sc_buf;
613*57096Sakito 	} else if (hs->sc_phase == CMD_PHASE) {
614*57096Sakito 		len = hs->sc_cdblen;
615*57096Sakito 		buf = hs->sc_cdb;
616*57096Sakito 	} else if (hs->sc_phase == STATUS_PHASE) {
617*57096Sakito 		len = 1;
618*57096Sakito 		buf = &hs->sc_stat;
619*57096Sakito 	} else {
620*57096Sakito 		len = 1;
621*57096Sakito 		buf = hs->sc_msg;
622*57096Sakito 	}
623*57096Sakito 
624*57096Sakito 	ixfer_start(hd, len, hs->sc_phase, 0);
625*57096Sakito 	if (hs->sc_phase & PHASE_IO)
626*57096Sakito 		ixfer_in(hd, len, buf);
627*57096Sakito 	else
628*57096Sakito 		ixfer_out(hd, len, buf);
629*57096Sakito 
630*57096Sakito 	return;
631*57096Sakito 
632*57096Sakito 	/*
633*57096Sakito 	 * SCSI Abort
634*57096Sakito 	 */
635*57096Sakito  abort:
636*57096Sakito 	/* SCSI IO failed */
637*57096Sakito 	scabort(hs, hd);
638*57096Sakito 	hd->scsi_ints = ints;
639*57096Sakito 	*(hs->sc_lock) = SC_IO_FAILED;
640*57096Sakito 	return;
641*57096Sakito }
642