xref: /csrg-svn/sys/dev/scsi/scsi_subr.c (revision 54879)
1*54879Storek /*
2*54879Storek  * Copyright (c) 1992 The Regents of the University of California.
3*54879Storek  * All rights reserved.
4*54879Storek  *
5*54879Storek  * This software was developed by the Computer Systems Engineering group
6*54879Storek  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7*54879Storek  * contributed to Berkeley.
8*54879Storek  *
9*54879Storek  * %sccs.include.redist.c%
10*54879Storek  *
11*54879Storek  *	@(#)scsi_subr.c	5.1 (Berkeley) 07/10/92
12*54879Storek  *
13*54879Storek  * from: $Header: scsi_subr.c,v 1.7 92/06/11 17:55:48 torek Exp $ (LBL)
14*54879Storek  */
15*54879Storek 
16*54879Storek /*
17*54879Storek  * Generic SCSI host adapter driver.
18*54879Storek  * Does almost nothing (most work is relegated to per-hba drivers).
19*54879Storek  */
20*54879Storek 
21*54879Storek #include "sys/param.h"
22*54879Storek #include "sys/buf.h"
23*54879Storek #include "sys/device.h"
24*54879Storek #include "scsi/scsi.h"
25*54879Storek #include "scsi/scsivar.h"
26*54879Storek 
27*54879Storek /*
28*54879Storek  * General subroutines, and scsi data.
29*54879Storek  */
30*54879Storek 
31*54879Storek /* table of lengths of scsi commands */
32*54879Storek const char scsicmdlen[8] = { 6, 10, 0, 0, 0, 12, 0, 0 };
33*54879Storek 
34*54879Storek /* table of lengths of scsi messages */
35*54879Storek const signed char scsimsglen[0x24] = {
36*54879Storek 	SMLEN_DONE,		/* MSG_CMD_COMPLETE */
37*54879Storek 	SMLEN_EXTENDED,		/* MSG_EXT_MESSAGE */
38*54879Storek 	1,			/* MSG_SAVE_DATA_PTR */
39*54879Storek 	1,			/* MSG_RESTORE_PTR */
40*54879Storek 	1,			/* MSG_DISCONNECT */
41*54879Storek 	1,			/* MSG_INIT_DETECT_ERROR */
42*54879Storek 	1,			/* MSG_ABORT */
43*54879Storek 	1,			/* MSG_REJECT */
44*54879Storek 	1,			/* MSG_NOOP */
45*54879Storek 	1,			/* MSG_PARITY_ERROR */
46*54879Storek 	1,			/* MSG_LCC */
47*54879Storek 	1,			/* MSG_LCCF */
48*54879Storek 	1,			/* MSG_BUS_DEVICE_RESET */
49*54879Storek 	1,			/* MSG_ABORT_TAG */
50*54879Storek 	1,			/* MSG_CLEAR_QUEUE */
51*54879Storek 	1,			/* MSG_INITIATE_RECOVERY */
52*54879Storek 	1,			/* MSG_RELEASE_RECOVERY */
53*54879Storek 	1,			/* MSG_TERMINATE_PROCESS */
54*54879Storek 	SMLEN_UNDEF,		/* 0x12 */
55*54879Storek 	SMLEN_UNDEF,		/* 0x13 */
56*54879Storek 	SMLEN_UNDEF,		/* 0x14 */
57*54879Storek 	SMLEN_UNDEF,		/* 0x15 */
58*54879Storek 	SMLEN_UNDEF,		/* 0x16 */
59*54879Storek 	SMLEN_UNDEF,		/* 0x17 */
60*54879Storek 	SMLEN_UNDEF,		/* 0x18 */
61*54879Storek 	SMLEN_UNDEF,		/* 0x19 */
62*54879Storek 	SMLEN_UNDEF,		/* 0x1a */
63*54879Storek 	SMLEN_UNDEF,		/* 0x1b */
64*54879Storek 	SMLEN_UNDEF,		/* 0x1c */
65*54879Storek 	SMLEN_UNDEF,		/* 0x1d */
66*54879Storek 	SMLEN_UNDEF,		/* 0x1e */
67*54879Storek 	SMLEN_UNDEF,		/* 0x1f */
68*54879Storek 	2,			/* MSG_SIMPLE_QTAG */
69*54879Storek 	2,			/* MSG_HEAD_QTAG */
70*54879Storek 	2,			/* MSG_ORDERED_QTAG */
71*54879Storek 	2,			/* MSG_IGNORE_WIDE_RESID */
72*54879Storek };
73*54879Storek 
74*54879Storek /* definition of `tg' target driver for autoconfig */
75*54879Storek static int scsi_targmatch __P((struct device *, struct cfdata *, void *));
76*54879Storek static void scsi_targattach __P((struct device *, struct device *, void *));
77*54879Storek struct cfdriver tgcd =
78*54879Storek     { NULL, "tg", scsi_targmatch, scsi_targattach,
79*54879Storek       DV_DULL, sizeof(struct targ) };
80*54879Storek 
81*54879Storek void	scsi_targstart __P((struct device *, struct sq *, struct buf *,
82*54879Storek 			scdgo_fn, struct device *));
83*54879Storek int	scsi_targgo __P((struct device *, int targ,
84*54879Storek 			scintr_fn, struct device *, struct buf *, int));
85*54879Storek void	scsi_targintr __P((struct device *, int, int));
86*54879Storek void	scsi_targrel __P((struct device *));
87*54879Storek 
88*54879Storek #define	NOBUF	((caddr_t)0)
89*54879Storek 
90*54879Storek /*
91*54879Storek  * Perform a TEST UNIT READY immediate (polled) command
92*54879Storek  * on the given <target,unit> pair.  Return the status byte
93*54879Storek  * returned, or -1 for none.
94*54879Storek  */
95*54879Storek int
96*54879Storek scsi_test_unit_ready(hba, targ, unit)
97*54879Storek 	struct hba_softc *hba;
98*54879Storek 	int targ, unit;
99*54879Storek {
100*54879Storek 	struct scsi_cdb cdb;
101*54879Storek 
102*54879Storek 	CDB6(&cdb)->cdb_cmd = CMD_TEST_UNIT_READY;
103*54879Storek 	CDB6(&cdb)->cdb_lun_lbah = unit << 5;
104*54879Storek 	*(short *)&CDB6(&cdb)->cdb_lbam = 0;
105*54879Storek 	*(short *)&CDB6(&cdb)->cdb_len = 0;
106*54879Storek 	return (hba->hba_driver->hd_icmd(hba, targ, &cdb, NOBUF, 0, 0));
107*54879Storek }
108*54879Storek 
109*54879Storek /*
110*54879Storek  * Request sense.  The sense is to be written into the given buffer.
111*54879Storek  * The given length must be < 256.
112*54879Storek  */
113*54879Storek int
114*54879Storek scsi_request_sense(hba, targ, unit, buf, len)
115*54879Storek 	struct hba_softc *hba;
116*54879Storek 	int targ, unit;
117*54879Storek 	caddr_t buf;
118*54879Storek 	int len;
119*54879Storek {
120*54879Storek 	struct scsi_cdb cdb;
121*54879Storek 
122*54879Storek 	CDB6(&cdb)->cdb_cmd = CMD_REQUEST_SENSE;
123*54879Storek 	CDB6(&cdb)->cdb_lun_lbah = unit << 5;
124*54879Storek 	*(short *)&CDB6(&cdb)->cdb_lbam = 0;
125*54879Storek 	CDB6(&cdb)->cdb_len = len;
126*54879Storek 	CDB6(&cdb)->cdb_ctrl = 0;
127*54879Storek 	return (hba->hba_driver->hd_icmd(hba, targ, &cdb, buf, len, B_READ));
128*54879Storek }
129*54879Storek 
130*54879Storek /*
131*54879Storek  * Called (indirectly, via config_found) from scsi_hbaattach.
132*54879Storek  * Print target number, and if no device was configured there,
133*54879Storek  * the hba as well.
134*54879Storek  */
135*54879Storek int
136*54879Storek scsi_targprint(aux, hba)
137*54879Storek 	void *aux;
138*54879Storek 	char *hba;
139*54879Storek {
140*54879Storek 
141*54879Storek 	if (hba) {
142*54879Storek 		printf("target %d on %s", *(int *)aux, hba);
143*54879Storek 		return (UNCONF);
144*54879Storek 	}
145*54879Storek 	printf(" target %d", *(int *)aux);
146*54879Storek 	return (QUIET);
147*54879Storek }
148*54879Storek 
149*54879Storek /*
150*54879Storek  * Print information about a unit found on some target.
151*54879Storek  * If the unit was not configured, `targ' is the name of the target
152*54879Storek  * on which the unit was found.  If it was, targ is NULL and we
153*54879Storek  * let the unit's attach routine print the INQUIRE result if
154*54879Storek  * appropriate.
155*54879Storek  */
156*54879Storek static int
157*54879Storek scsi_unitprint(aux, targ)
158*54879Storek 	void *aux;
159*54879Storek 	char *targ;
160*54879Storek {
161*54879Storek 	register struct scsi_attach_args *sa = aux;
162*54879Storek 
163*54879Storek 	if (targ) {
164*54879Storek 		printf("unit %d at %s", sa->sa_unit, targ);
165*54879Storek 		if ((sa->sa_inq_status & STS_MASK) == STS_GOOD) {
166*54879Storek 			printf(" (");
167*54879Storek 			scsi_printinq(&sa->sa_si);
168*54879Storek 			printf(")");
169*54879Storek 		}
170*54879Storek 		return (UNCONF);
171*54879Storek 	}
172*54879Storek 	printf(" unit %d", sa->sa_unit);
173*54879Storek 	return (QUIET);
174*54879Storek }
175*54879Storek 
176*54879Storek /*
177*54879Storek  * Generic target-match.
178*54879Storek  */
179*54879Storek static int
180*54879Storek scsi_targmatch(parent, cf, aux)
181*54879Storek 	struct device *parent;
182*54879Storek 	register struct cfdata *cf;
183*54879Storek 	void *aux;
184*54879Storek {
185*54879Storek 	int targ = *(int *)aux;
186*54879Storek 
187*54879Storek 	return (cf->cf_loc[0] == targ || cf->cf_loc[0] == -1);
188*54879Storek }
189*54879Storek 
190*54879Storek /*
191*54879Storek  * And now, a generic `target attach' routine.
192*54879Storek  * We assume that INQUIRY works.
193*54879Storek  */
194*54879Storek static void
195*54879Storek scsi_targattach(parent, self, aux)
196*54879Storek 	struct device *parent, *self;
197*54879Storek 	void *aux;
198*54879Storek {
199*54879Storek 	register struct targ *t = (struct targ *)self;
200*54879Storek 	register struct hba_softc *hba;
201*54879Storek 	register struct hbadriver *hd;
202*54879Storek 	register int targ, unit;
203*54879Storek 	struct scsi_attach_args sa;
204*54879Storek 	struct scsi_cdb si;
205*54879Storek 
206*54879Storek 	printf("\n");
207*54879Storek 	t->t_targ = targ = *(int *)aux;
208*54879Storek 	hba = (struct hba_softc *)parent;
209*54879Storek 	hba->hba_targets[targ] = t;
210*54879Storek 
211*54879Storek 	/*
212*54879Storek 	 * Probe each of the 8 units using the sequence
213*54879Storek 	 *	TEST UNIT READY
214*54879Storek 	 *	REQUEST SENSE
215*54879Storek 	 *	INQUIRY
216*54879Storek 	 * The first should not be necessary, but some SCSI devices
217*54879Storek 	 * refuse to speak until it is done.  The second is only necessary
218*54879Storek 	 * if the first returns a CHECK CONDITION status, but we do it
219*54879Storek 	 * anyway.
220*54879Storek 	 */
221*54879Storek 	hd = hba->hba_driver;
222*54879Storek 	sa.sa_targ = targ;
223*54879Storek 	CDB6(&si)->cdb_cmd = CMD_INQUIRY;
224*54879Storek 	*(short *)&CDB6(&si)->cdb_lbam = 0;
225*54879Storek 	CDB6(&si)->cdb_len = sizeof sa.sa_si;
226*54879Storek 	CDB6(&si)->cdb_ctrl = 0;
227*54879Storek 	for (unit = 0; unit < 8; unit++) {
228*54879Storek 		if (scsi_test_unit_ready(hba, targ, unit) == -1)
229*54879Storek 			continue;
230*54879Storek 		sa.sa_unit = unit;
231*54879Storek 		sa.sa_req_status = scsi_request_sense(hba, targ, unit,
232*54879Storek 		    (caddr_t)&sa.sa_sn, sizeof sa.sa_sn);
233*54879Storek 		CDB6(&si)->cdb_lun_lbah = unit << 5;
234*54879Storek 		sa.sa_inq_status = (*hd->hd_icmd)(hba, targ, &si,
235*54879Storek 		    (caddr_t)&sa.sa_si, sizeof sa.sa_si, B_READ);
236*54879Storek 		if ((sa.sa_inq_status & STS_MASK) == STS_GOOD &&
237*54879Storek #ifdef notdef /* XXX don't know if this is a reasonable test */
238*54879Storek 		    (sa.sa_si.si_type & TYPE_QUAL_MASK) == TYPE_QUAL_NOTCONN &&
239*54879Storek #endif
240*54879Storek 		    (sa.sa_si.si_type & TYPE_TYPE_MASK) == TYPE_NP) {
241*54879Storek 			continue;
242*54879Storek 		}
243*54879Storek 		config_found(&t->t_dev, (void *)&sa, scsi_unitprint);
244*54879Storek 	}
245*54879Storek }
246*54879Storek 
247*54879Storek /*
248*54879Storek  * Each unit calls scsi_establish to tell the hba and target of
249*54879Storek  * its existence.
250*54879Storek  */
251*54879Storek void
252*54879Storek scsi_establish(u, dev, unit)
253*54879Storek 	register struct unit *u;
254*54879Storek 	struct device *dev;
255*54879Storek 	register int unit;
256*54879Storek {
257*54879Storek 	register struct targ *t;
258*54879Storek 	register struct hba_softc *hba;
259*54879Storek 	register struct hbadriver *hbd;
260*54879Storek 
261*54879Storek 	u->u_dev = dev;
262*54879Storek 	t = (struct targ *)dev->dv_parent;
263*54879Storek 	hba = (struct hba_softc *)t->t_dev.dv_parent;
264*54879Storek 	hbd = hba->hba_driver;
265*54879Storek 	t->t_units[unit] = u;
266*54879Storek 	if (t->t_nunits == 0) {
267*54879Storek 		/*
268*54879Storek 		 * This is the first unit on the target.  We can
269*54879Storek 		 * probably just call the hba start code, avoiding
270*54879Storek 		 * one level of calls and queueing.  If we attach
271*54879Storek 		 * another target we will fix this in the code below.
272*54879Storek 		 */
273*54879Storek 		u->u_start = hbd->hd_start;
274*54879Storek 		u->u_go = hbd->hd_go;
275*54879Storek 		u->u_rel = hbd->hd_rel;
276*54879Storek 		u->u_updev = &hba->hba_dev;
277*54879Storek 		t->t_firstunit = unit;
278*54879Storek 	} else {
279*54879Storek 		/*
280*54879Storek 		 * This is not the only unit on the target, so we
281*54879Storek 		 * must call the target start code rather than the
282*54879Storek 		 * hba start code.  Fix the linkage on the first
283*54879Storek 		 * target too (possibly for the 2nd, 3rd, ..., time).
284*54879Storek 		 */
285*54879Storek 		t->t_units[t->t_firstunit]->u_start = scsi_targstart;
286*54879Storek 		t->t_units[t->t_firstunit]->u_updev = &t->t_dev;
287*54879Storek 		u->u_start = scsi_targstart;
288*54879Storek 		u->u_go = scsi_targgo;
289*54879Storek 		u->u_rel = scsi_targrel;
290*54879Storek 		u->u_updev = &t->t_dev;
291*54879Storek 	}
292*54879Storek 	t->t_nunits++;			/* another unit is alive */
293*54879Storek 	u->u_unit = unit;
294*54879Storek 	u->u_targ = t->t_targ;		/* record target number, */
295*54879Storek 	u->u_hba = hba;			/* hba ... */
296*54879Storek 	u->u_hbd = hbd;			/* and driver */
297*54879Storek }
298*54879Storek 
299*54879Storek /* NO DOUBT SOME OF THE STUFF PRINTED HERE IS USELESS */
300*54879Storek void
301*54879Storek scsi_printinq(inq)
302*54879Storek 	register struct scsi_inquiry *inq;
303*54879Storek {
304*54879Storek 	register int iso, ecma, ansi, t;
305*54879Storek 	static char *types[] = { "disk", "tape", "printer", "processor",
306*54879Storek 	    "WORM", "ROM disk", "scanner", "magneto-optical",
307*54879Storek 	    "jukebox", "lan" };
308*54879Storek 
309*54879Storek 	if ((t = (inq->si_type & TYPE_QUAL_MASK)) != 0)
310*54879Storek 		printf("type-qual=0x%x ", t);
311*54879Storek 	t = inq->si_type & TYPE_TYPE_MASK;
312*54879Storek 	if (t < sizeof types / sizeof *types)
313*54879Storek 		printf("%s", types[t]);
314*54879Storek 	else
315*54879Storek 		printf("<type %d>", t);
316*54879Storek 	if (inq->si_qual & QUAL_RMB)
317*54879Storek 		printf(" (removable)");
318*54879Storek 	printf(" qual=0x%x", inq->si_qual & QUAL_MASK);
319*54879Storek 	iso = (inq->si_qual >> VER_ISO_SHIFT) & VER_ISO_MASK;
320*54879Storek 	ecma = (inq->si_qual >> VER_ECMA_SHIFT) & VER_ECMA_MASK;
321*54879Storek 	ansi = (inq->si_qual >> VER_ANSI_SHIFT) & VER_ANSI_MASK;
322*54879Storek 	printf(" version=<iso %d, ecma %d, ansi %d>", iso, ecma, ansi);
323*54879Storek 	if (ansi == 1 || ansi == 2) {
324*54879Storek 		char v[9], p[17], r[5];
325*54879Storek 
326*54879Storek 		scsi_inq_ansi((struct scsi_inq_ansi *)inq, v, p, r);
327*54879Storek 		printf(" vendor %s, product %s, rev %s", v, p, r);
328*54879Storek 	}
329*54879Storek }
330*54879Storek 
331*54879Storek /* copy a counted string but trim trailing blanks; make the dest a C string */
332*54879Storek static void
333*54879Storek scsi_str(src, dst, len)
334*54879Storek 	register char *src, *dst;
335*54879Storek 	register int len;
336*54879Storek {
337*54879Storek 
338*54879Storek 	while (src[len - 1] == ' ') {
339*54879Storek 		if (--len == 0) {
340*54879Storek 			*dst = 0;
341*54879Storek 			return;
342*54879Storek 		}
343*54879Storek 	}
344*54879Storek 	bcopy(src, dst, len);
345*54879Storek 	dst[len] = 0;
346*54879Storek }
347*54879Storek 
348*54879Storek void
349*54879Storek scsi_inq_ansi(si, vendor, product, rev)
350*54879Storek 	register struct scsi_inq_ansi *si;
351*54879Storek 	char *vendor, *product, *rev;
352*54879Storek {
353*54879Storek 	register int i, len;
354*54879Storek 
355*54879Storek 	/* if too short, extend with blanks */
356*54879Storek 	len = si->si_len + 5;	/* 5 fixed; len is `additional' */
357*54879Storek 	if (len < sizeof(*si))
358*54879Storek 		for (i = len; i < sizeof *si; i++)
359*54879Storek 			((char *)si)[i] = ' ';
360*54879Storek 	scsi_str(si->si_vendor, vendor, sizeof si->si_vendor);
361*54879Storek 	scsi_str(si->si_product, product, sizeof si->si_product);
362*54879Storek 	scsi_str(si->si_rev, rev, sizeof si->si_rev);
363*54879Storek }
364*54879Storek 
365*54879Storek /*
366*54879Storek  * Tell all the devices on the given hba that it has been reset.
367*54879Storek  * SHOULD PROBABLY DO MORE HERE
368*54879Storek  */
369*54879Storek void
370*54879Storek scsi_reset_units(hba)
371*54879Storek 	register struct hba_softc *hba;
372*54879Storek {
373*54879Storek 	register int targ, unit;
374*54879Storek 	register struct targ *t;
375*54879Storek 	register struct unit *u;
376*54879Storek 
377*54879Storek 	for (targ = 0; targ < 8; targ++) {
378*54879Storek 		if ((t = hba->hba_targets[targ]) == NULL)
379*54879Storek 			continue;
380*54879Storek 		for (unit = 0; unit < 8; unit++)
381*54879Storek 			if ((u = t->t_units[unit]) != NULL)
382*54879Storek 				(*u->u_driver->ud_reset)(u);
383*54879Storek 	}
384*54879Storek }
385*54879Storek 
386*54879Storek /*
387*54879Storek  * Start a unit on a target.
388*54879Storek  * If the target is busy, just enqueue the unit;
389*54879Storek  * once the target becomes free, we will call the hba start routine.
390*54879Storek  * Otherwise, call the hba start routine now, and then when the hba
391*54879Storek  * becomes free it will call the unit's dgo routine.
392*54879Storek  */
393*54879Storek void
394*54879Storek scsi_targstart(self, sq, bp, dgo, dev)
395*54879Storek 	struct device *self;
396*54879Storek 	register struct sq *sq;
397*54879Storek 	struct buf *bp;
398*54879Storek 	scdgo_fn dgo;
399*54879Storek 	struct device *dev;
400*54879Storek {
401*54879Storek 	register struct targ *t = (struct targ *)self;
402*54879Storek 	register struct hba_softc *hba;
403*54879Storek 
404*54879Storek 	sq->sq_forw = NULL;
405*54879Storek 	if (t->t_head == NULL)
406*54879Storek 		t->t_head = sq;
407*54879Storek 	else
408*54879Storek 		t->t_tail->sq_forw = sq;
409*54879Storek 	t->t_tail = sq;
410*54879Storek 	if (t->t_busy == 0) {
411*54879Storek 		t->t_busy = 1;
412*54879Storek 		hba = (struct hba_softc *)t->t_dev.dv_parent;
413*54879Storek 		(*hba->hba_driver->hd_start)(&hba->hba_dev, &t->t_forw, bp,
414*54879Storek 		    dgo, dev);
415*54879Storek 	} else {
416*54879Storek 		sq->sq_bp = bp;
417*54879Storek 		sq->sq_dgo = dgo;
418*54879Storek 		sq->sq_dev = dev;
419*54879Storek 	}
420*54879Storek }
421*54879Storek 
422*54879Storek /*
423*54879Storek  * The unit got the bus, and wants the hba to go.
424*54879Storek  * Remember its interrupt handler; substitute ours instead.
425*54879Storek  */
426*54879Storek int
427*54879Storek scsi_targgo(self, targ, intr, dev, bp, pad)
428*54879Storek 	struct device *self;
429*54879Storek 	int targ;
430*54879Storek 	scintr_fn intr;
431*54879Storek 	struct device *dev;
432*54879Storek 	struct buf *bp;
433*54879Storek 	int pad;
434*54879Storek {
435*54879Storek 	register struct targ *t = (struct targ *)self;
436*54879Storek 	register struct hba_softc *hba;
437*54879Storek 
438*54879Storek 	t->t_intr = intr;
439*54879Storek 	t->t_intrdev = dev;
440*54879Storek 	hba = (struct hba_softc *)t->t_dev.dv_parent;
441*54879Storek 	return ((*hba->hba_driver->hd_go)(&hba->hba_dev, targ,
442*54879Storek 	    scsi_targintr, &t->t_dev, bp, pad));
443*54879Storek }
444*54879Storek 
445*54879Storek /*
446*54879Storek  * The hba got an interrupt.  Dequeue the unit from the target
447*54879Storek  * (the target is already off the hba queue) and then call the
448*54879Storek  * underlying interrupt handler.
449*54879Storek  */
450*54879Storek void
451*54879Storek scsi_targintr(self, stat, resid)
452*54879Storek 	struct device *self;
453*54879Storek 	int stat, resid;
454*54879Storek {
455*54879Storek 	register struct targ *t = (struct targ *)self;
456*54879Storek 	register struct hba_softc *hba;
457*54879Storek 	register struct sq *sq;
458*54879Storek 
459*54879Storek 	sq = t->t_head;
460*54879Storek if (sq == NULL) panic("scsi_targintr");
461*54879Storek 	t->t_head = sq = sq->sq_forw;
462*54879Storek 	(*t->t_intr)(t->t_intrdev, stat, resid);
463*54879Storek 	if (sq != NULL) {
464*54879Storek 		hba = (struct hba_softc *)t->t_dev.dv_parent;
465*54879Storek 		(*hba->hba_driver->hd_start)(&hba->hba_dev, &t->t_forw,
466*54879Storek 		    sq->sq_bp, sq->sq_dgo, sq->sq_dev);
467*54879Storek 	} else
468*54879Storek 		t->t_busy = 0;
469*54879Storek }
470*54879Storek 
471*54879Storek /*
472*54879Storek  * The unit decided that it needed to `give up' its hold on the bus early.
473*54879Storek  */
474*54879Storek void
475*54879Storek scsi_targrel(self)
476*54879Storek 	struct device *self;
477*54879Storek {
478*54879Storek 	register struct targ *t = (struct targ *)self;
479*54879Storek 	register struct hba_softc *hba;
480*54879Storek 	register struct sq *sq;
481*54879Storek 
482*54879Storek 	hba = (struct hba_softc *)t->t_dev.dv_parent;
483*54879Storek 	sq = t->t_head;
484*54879Storek if (sq == NULL) panic("scsi_targrel");
485*54879Storek 	/*
486*54879Storek 	 * This target is at the head of the hba queue.
487*54879Storek 	 * Remove it by calling hba bus release.  Then, if the
488*54879Storek 	 * target queue is not empty, put it back on the hba queue.
489*54879Storek 	 * (This produces round robin service.)
490*54879Storek 	 */
491*54879Storek 	(*hba->hba_driver->hd_rel)(&hba->hba_dev);
492*54879Storek 	sq = sq->sq_forw;
493*54879Storek 	if ((t->t_head = sq) != NULL)
494*54879Storek 		(*hba->hba_driver->hd_start)(&hba->hba_dev, &t->t_forw,
495*54879Storek 		    sq->sq_bp, sq->sq_dgo, sq->sq_dev);
496*54879Storek 	else
497*54879Storek 		t->t_busy = 0;
498*54879Storek }
499