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