1 /*	$MirOS: src/sys/dev/i2o/ioprbs.c,v 1.2 2013/10/31 20:06:51 tg Exp $ */
2 /*	$OpenBSD: ioprbs.c,v 1.5 2004/04/12 22:12:32 jmc Exp $	*/
3 
4 /*
5  * Copyright © 2013
6  *	Thorsten “mirabilos” Glaser <tg@mirbsd.org>
7  * Copyright (c) 2001 Niklas Hallqvist
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 /*-
33  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
34  * All rights reserved.
35  *
36  * This code is derived from software contributed to The NetBSD Foundation
37  * by Andrew Doran.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions
41  * are met:
42  * 1. Redistributions of source code must retain the above copyright
43  *    notice, this list of conditions and the following disclaimer.
44  * 2. Redistributions in binary form must reproduce the above copyright
45  *    notice, this list of conditions and the following disclaimer in the
46  *    documentation and/or other materials provided with the distribution.
47  * 3. All advertising materials mentioning features or use of this software
48  *    must display the following acknowledgement:
49  *        This product includes software developed by the NetBSD
50  *        Foundation, Inc. and its contributors.
51  * 4. Neither the name of The NetBSD Foundation nor the names of its
52  *    contributors may be used to endorse or promote products derived
53  *    from this software without specific prior written permission.
54  *
55  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
56  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
57  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
58  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
59  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
60  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
61  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
62  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
63  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
64  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
65  * POSSIBILITY OF SUCH DAMAGE.
66  */
67 
68 /*
69  * A driver for I2O "Random block storage" devices, like RAID.
70  */
71 
72 /*
73  * This driver would not have been written if it was not for the hardware
74  * donation from pi.se.  I want to thank them for their support.  It also
75  * had been much harder without Andrew Doran's work in NetBSD's ld_iop.c
76  * driver, from which I have both gotten inspiration and actual code.
77  * - Niklas Hallqvist
78  */
79 
80 #include <sys/param.h>
81 #include <sys/buf.h>
82 #include <sys/device.h>
83 #include <sys/kernel.h>
84 #include <sys/proc.h>
85 #include <sys/systm.h>
86 
87 #include <machine/bus.h>
88 
89 #include <scsi/scsi_all.h>
90 #include <scsi/scsi_disk.h>
91 #include <scsi/scsiconf.h>
92 
93 #include <dev/i2o/i2o.h>
94 #include <dev/i2o/iopio.h>
95 #include <dev/i2o/iopvar.h>
96 #include <dev/i2o/ioprbsvar.h>
97 
98 #ifdef I2ODEBUG
99 #define DPRINTF(x)	printf x
100 #else
101 #define	DPRINTF(x)
102 #endif
103 
104 void	ioprbsminphys(struct buf *);
105 void	ioprbs_adjqparam(struct device *, int);
106 void	ioprbs_attach(struct device *, struct device *, void *);
107 void	ioprbs_copy_internal_data(struct scsi_xfer *, u_int8_t *,
108 	    size_t);
109 struct scsi_xfer *ioprbs_dequeue(struct ioprbs_softc *);
110 void	ioprbs_enqueue(struct ioprbs_softc *, struct scsi_xfer *, int);
111 void	ioprbs_enqueue_ccb(struct ioprbs_softc *, struct ioprbs_ccb *);
112 int	ioprbs_exec_ccb(struct ioprbs_ccb *);
113 void	ioprbs_free_ccb(struct ioprbs_softc *, struct ioprbs_ccb *);
114 struct ioprbs_ccb *ioprbs_get_ccb(struct ioprbs_softc *, int);
115 int	ioprbs_internal_cache_cmd(struct scsi_xfer *);
116 void	ioprbs_intr(struct device *, struct iop_msg *, void *);
117 void	ioprbs_intr_event(struct device *, struct iop_msg *, void *);
118 int	ioprbs_match(struct device *, void *, void *);
119 int	ioprbs_scsi_cmd(struct scsi_xfer *);
120 int	ioprbs_start(struct ioprbs_ccb *);
121 void	ioprbs_start_ccbs(struct ioprbs_softc *);
122 void	ioprbs_timeout(void *);
123 void	ioprbs_unconfig(struct ioprbs_softc *, int);
124 void	ioprbs_watchdog(void *);
125 
126 struct cfdriver ioprbs_cd = {
127 	NULL, "ioprbs", DV_DULL
128 };
129 
130 struct cfattach ioprbs_ca = {
131 	sizeof(struct ioprbs_softc), ioprbs_match, ioprbs_attach
132 };
133 
134 struct scsi_adapter ioprbs_switch = {
135 	ioprbs_scsi_cmd, ioprbsminphys, 0, 0,
136 };
137 
138 struct scsi_device ioprbs_dev = {
139 	NULL, NULL, NULL, NULL
140 };
141 
142 #ifdef I2OVERBOSE
143 static const char *const ioprbs_errors[] = {
144 	"success",
145 	"media error",
146 	"access error",
147 	"device failure",
148 	"device not ready",
149 	"media not present",
150 	"media locked",
151 	"media failure",
152 	"protocol failure",
153 	"bus failure",
154 	"access violation",
155 	"media write protected",
156 	"device reset",
157 	"volume changed, waiting for acknowledgement",
158 	"timeout",
159 };
160 #endif
161 
162 /*
163  * Match a supported device.
164  */
165 int
ioprbs_match(parent,match,aux)166 ioprbs_match(parent, match, aux)
167 	struct device *parent;
168 	void *match;
169 	void *aux;
170 {
171 	struct iop_attach_args *ia = aux;
172 
173 	return (ia->ia_class == I2O_CLASS_RANDOM_BLOCK_STORAGE);
174 }
175 
176 /*
177  * Attach a supported device.
178  */
179 void
ioprbs_attach(struct device * parent,struct device * self,void * aux)180 ioprbs_attach(struct device *parent, struct device *self, void *aux)
181 {
182 	struct iop_attach_args *ia = aux;
183 	struct ioprbs_softc *sc = (struct ioprbs_softc *)self;
184 	struct iop_softc *iop = (struct iop_softc *)parent;
185 	int rv, state = 0;
186 	int enable;
187 	u_int32_t cachesz;
188 	char *typestr, *fixedstr;
189 	struct {
190 		struct	i2o_param_op_results pr;
191 		struct	i2o_param_read_results prr;
192 		union {
193 			struct	i2o_param_rbs_cache_control cc;
194 			struct	i2o_param_rbs_device_info bdi;
195 			struct	i2o_param_rbs_operation op;
196 		} p;
197 	} param /* XXX gcc __attribute__((__packed__)) */;
198 	int i;
199 
200 	TAILQ_INIT(&sc->sc_free_ccb);
201 	TAILQ_INIT(&sc->sc_ccbq);
202 	LIST_INIT(&sc->sc_queue);
203 
204 	/* Initialize the ccbs */
205 	for (i = 0; i < IOPRBS_MAX_CCBS; i++)
206 		TAILQ_INSERT_TAIL(&sc->sc_free_ccb, &sc->sc_ccbs[i],
207 		    ic_chain);
208 
209 	/* Register us as an initiator. */
210 	sc->sc_ii.ii_dv = self;
211 	sc->sc_ii.ii_intr = ioprbs_intr;
212 	sc->sc_ii.ii_adjqparam = ioprbs_adjqparam;
213 	sc->sc_ii.ii_flags = 0;
214 	sc->sc_ii.ii_tid = ia->ia_tid;
215 	iop_initiator_register(iop, &sc->sc_ii);
216 
217 	/* Register another initiator to handle events from the device. */
218 	sc->sc_eventii.ii_dv = self;
219 	sc->sc_eventii.ii_intr = ioprbs_intr_event;
220 	sc->sc_eventii.ii_flags = II_DISCARD | II_UTILITY;
221 	sc->sc_eventii.ii_tid = ia->ia_tid;
222 	iop_initiator_register(iop, &sc->sc_eventii);
223 
224 	rv = iop_util_eventreg(iop, &sc->sc_eventii,
225 	    I2O_EVENT_GEN_EVENT_MASK_MODIFIED | I2O_EVENT_GEN_DEVICE_RESET |
226 	    I2O_EVENT_GEN_STATE_CHANGE | I2O_EVENT_GEN_GENERAL_WARNING);
227 	if (rv != 0) {
228 		printf("%s: unable to register for events", self->dv_xname);
229 		goto bad;
230 	}
231 	state++;
232 
233 	/*
234 	 * Start out with one queued command.  The `iop' driver will adjust
235 	 * the queue parameters once we're up and running.
236 	 */
237 	sc->sc_maxqueuecnt = 1;
238 
239 	sc->sc_maxxfer = IOP_MAX_XFER;
240 
241 	/* Say what the device is. */
242 	printf(":");
243 	iop_print_ident(iop, ia->ia_tid);
244 
245 	/*
246 	 * Claim the device so that we don't get any nasty surprises.  Allow
247 	 * failure.
248 	 */
249 	rv = iop_util_claim(iop, &sc->sc_ii, 0,
250 	    I2O_UTIL_CLAIM_CAPACITY_SENSITIVE |
251 	    I2O_UTIL_CLAIM_NO_PEER_SERVICE |
252 	    I2O_UTIL_CLAIM_NO_MANAGEMENT_SERVICE |
253 	    I2O_UTIL_CLAIM_PRIMARY_USER);
254 	sc->sc_flags = rv ? 0 : IOPRBS_CLAIMED;
255 
256 	rv = iop_param_op(iop, ia->ia_tid, NULL, 0, I2O_PARAM_RBS_DEVICE_INFO,
257 	    &param, sizeof param);
258 	if (rv != 0) {
259 		printf("%s: unable to get parameters (0x%04x; %d)\n",
260 		   sc->sc_dv.dv_xname, I2O_PARAM_RBS_DEVICE_INFO, rv);
261 		goto bad;
262 	}
263 
264 	sc->sc_secsize = letoh32(param.p.bdi.blocksize);
265 	sc->sc_secperunit = (int)
266 	    (letoh64(param.p.bdi.capacity) / sc->sc_secsize);
267 
268 	/* Build synthetic geometry. */
269 	if (sc->sc_secperunit <= 528 * 2048)		/* 528MB */
270 		sc->sc_nheads = 16;
271 	else if (sc->sc_secperunit <= 1024 * 2048)	/* 1GB */
272 		sc->sc_nheads = 32;
273 	else if (sc->sc_secperunit <= 21504 * 2048)	/* 21GB */
274 		sc->sc_nheads = 64;
275 	else if (sc->sc_secperunit <= 43008 * 2048)	/* 42GB */
276 		sc->sc_nheads = 128;
277 	else
278 		sc->sc_nheads = 255;
279 
280 	sc->sc_nsectors = 63;
281 	sc->sc_ncylinders = sc->sc_secperunit /
282 	    (sc->sc_nheads * sc->sc_nsectors);
283 
284 	switch (param.p.bdi.type) {
285 	case I2O_RBS_TYPE_DIRECT:
286 		typestr = "direct access";
287 		enable = 1;
288 		break;
289 	case I2O_RBS_TYPE_WORM:
290 		typestr = "WORM";
291 		enable = 0;
292 		break;
293 	case I2O_RBS_TYPE_CDROM:
294 		typestr = "CD-ROM";
295 		enable = 0;
296 		break;
297 	case I2O_RBS_TYPE_OPTICAL:
298 		typestr = "optical";
299 		enable = 0;
300 		break;
301 	default:
302 		typestr = "unknown";
303 		enable = 0;
304 		break;
305 	}
306 
307 	if ((letoh32(param.p.bdi.capabilities) & I2O_RBS_CAP_REMOVABLE_MEDIA)
308 	    != 0) {
309 		/* sc->sc_flags = IOPRBS_REMOVABLE; */
310 		fixedstr = "removable";
311 		enable = 0;
312 	} else
313 		fixedstr = "fixed";
314 
315 	printf(" %s, %s", typestr, fixedstr);
316 
317 	/*
318 	 * Determine if the device has an private cache.  If so, print the
319 	 * cache size.  Even if the device doesn't appear to have a cache,
320 	 * we perform a flush at shutdown.
321 	 */
322 	rv = iop_param_op(iop, ia->ia_tid, NULL, 0,
323 	    I2O_PARAM_RBS_CACHE_CONTROL, &param, sizeof(param));
324 	if (rv != 0) {
325 		printf("%s: unable to get parameters (0x%04x; %d)\n",
326 		   sc->sc_dv.dv_xname, I2O_PARAM_RBS_CACHE_CONTROL, rv);
327 		goto bad;
328 	}
329 
330 	if ((cachesz = letoh32(param.p.cc.totalcachesize)) != 0)
331 		printf(", %dkB cache", cachesz >> 10);
332 
333 	printf("\n");
334 
335 	/*
336 	 * Configure the DDM's timeout functions to time out all commands
337 	 * after 30 seconds.
338 	 */
339 	rv = iop_param_op(iop, ia->ia_tid, NULL, 0, I2O_PARAM_RBS_OPERATION,
340 	    &param, sizeof(param));
341 	if (rv != 0) {
342 		printf("%s: unable to get parameters (0x%04x; %d)\n",
343 		   sc->sc_dv.dv_xname, I2O_PARAM_RBS_OPERATION, rv);
344 		goto bad;
345 	}
346 
347 	param.p.op.timeoutbase = htole32(IOPRBS_TIMEOUT * 1000);
348 	param.p.op.rwvtimeoutbase = htole32(IOPRBS_TIMEOUT * 1000);
349 	param.p.op.rwvtimeout = 0;
350 
351 	rv = iop_param_op(iop, ia->ia_tid, NULL, 1, I2O_PARAM_RBS_OPERATION,
352 	    &param, sizeof(param));
353 #ifdef notdef
354 	/*
355 	 * Intel RAID adapters don't like the above, but do post a
356 	 * `parameter changed' event.  Perhaps we're doing something
357 	 * wrong...
358 	 */
359 	if (rv != 0) {
360 		printf("%s: unable to set parameters (0x%04x; %d)\n",
361 		   sc->sc_dv.dv_xname, I2O_PARAM_RBS_OPERATION, rv);
362 		goto bad;
363 	}
364 #endif
365 
366 	if (enable)
367 		sc->sc_flags |= IOPRBS_ENABLED;
368 	else
369 		printf("%s: device not yet supported\n", self->dv_xname);
370 
371 	/* Fill in the prototype scsi_link. */
372 	sc->sc_link.adapter_softc = sc;
373 	sc->sc_link.adapter = &ioprbs_switch;
374 	sc->sc_link.device = &ioprbs_dev;
375 	sc->sc_link.openings = 1;
376 	sc->sc_link.adapter_buswidth = 1;
377 	sc->sc_link.adapter_target = 1;
378 
379 	config_found(&sc->sc_dv, &sc->sc_link, scsiprint);
380 
381 	return;
382 
383  bad:
384 	ioprbs_unconfig(sc, state > 0);
385 }
386 
387 void
ioprbs_unconfig(struct ioprbs_softc * sc,int evreg)388 ioprbs_unconfig(struct ioprbs_softc *sc, int evreg)
389 {
390 	struct iop_softc *iop;
391 	int s;
392 
393 	iop = (struct iop_softc *)sc->sc_dv.dv_parent;
394 
395 	if ((sc->sc_flags & IOPRBS_CLAIMED) != 0)
396 		iop_util_claim(iop, &sc->sc_ii, 1,
397 		    I2O_UTIL_CLAIM_PRIMARY_USER);
398 
399 	if (evreg) {
400 		/*
401 		 * Mask off events, and wait up to 5 seconds for a reply.
402 		 * Note that some adapters won't reply to this (XXX We
403 		 * should check the event capabilities).
404 		 */
405 		sc->sc_flags &= ~IOPRBS_NEW_EVTMASK;
406 		iop_util_eventreg(iop, &sc->sc_eventii,
407 		    I2O_EVENT_GEN_EVENT_MASK_MODIFIED);
408 		s = splbio();
409 		if ((sc->sc_flags & IOPRBS_NEW_EVTMASK) == 0)
410 			tsleep(&sc->sc_eventii, PRIBIO, "ioprbsevt", hz * 5);
411 		splx(s);
412 #ifdef I2ODEBUG
413 		if ((sc->sc_flags & IOPRBS_NEW_EVTMASK) == 0)
414 			printf("%s: didn't reply to event unregister",
415 			    sc->sc_dv.dv_xname);
416 #endif
417 	}
418 
419 	iop_initiator_unregister(iop, &sc->sc_eventii);
420 	iop_initiator_unregister(iop, &sc->sc_ii);
421 }
422 
423 int
ioprbs_scsi_cmd(xs)424 ioprbs_scsi_cmd(xs)
425 	struct scsi_xfer *xs;
426 {
427 	struct scsi_link *link = xs->sc_link;
428 	struct ioprbs_softc *sc = link->adapter_softc;
429 	struct ioprbs_ccb *ccb;
430 	u_int32_t blockno, blockcnt;
431 	struct scsi_rw *rw;
432 	struct scsi_rw_big *rwb;
433 	ioprbs_lock_t lock;
434 	int retval = SUCCESSFULLY_QUEUED;
435 
436 	lock = IOPRBS_LOCK(sc);
437 
438 	/* Don't double enqueue if we came from ioprbs_chain. */
439 	if (xs != LIST_FIRST(&sc->sc_queue))
440 		ioprbs_enqueue(sc, xs, 0);
441 
442 	while ((xs = ioprbs_dequeue(sc))) {
443 		xs->error = XS_NOERROR;
444 
445 		ccb = NULL;
446 
447 		switch (xs->cmd->opcode) {
448 		case TEST_UNIT_READY:
449 		case REQUEST_SENSE:
450 		case INQUIRY:
451 		case MODE_SENSE:
452 		case START_STOP:
453 		case READ_CAPACITY:
454 #if 0
455 		case VERIFY:
456 #endif
457 			if (!ioprbs_internal_cache_cmd(xs)) {
458 				IOPRBS_UNLOCK(sc, lock);
459 				return (TRY_AGAIN_LATER);
460 			}
461 			xs->flags |= ITSDONE;
462 			scsi_done(xs);
463 			goto ready;
464 
465 		case PREVENT_ALLOW:
466 			DPRINTF(("PREVENT/ALLOW "));
467 			/* XXX Not yet implemented */
468 			xs->error = XS_NOERROR;
469 			xs->flags |= ITSDONE;
470 			scsi_done(xs);
471 			goto ready;
472 
473 		case SYNCHRONIZE_CACHE:
474 			DPRINTF(("SYNCHRONIZE_CACHE "));
475 			/* XXX Not yet implemented */
476 			xs->error = XS_NOERROR;
477 			xs->flags |= ITSDONE;
478 			scsi_done(xs);
479 			goto ready;
480 
481 		default:
482 			DPRINTF(("unknown opc %d ", xs->cmd->opcode));
483 			/* XXX Not yet implemented */
484 			xs->error = XS_DRIVER_STUFFUP;
485 			xs->flags |= ITSDONE;
486 			scsi_done(xs);
487 			goto ready;
488 
489 		case READ_COMMAND:
490 		case READ_BIG:
491 		case WRITE_COMMAND:
492 		case WRITE_BIG:
493 			DPRINTF(("rw opc %d ", xs->cmd->opcode));
494 
495 			if (xs->cmd->opcode != SYNCHRONIZE_CACHE) {
496 				/* A read or write operation. */
497 				if (xs->cmdlen == 6) {
498 					rw = (struct scsi_rw *)xs->cmd;
499 					blockno = _3btol(rw->addr) &
500 					    (SRW_TOPADDR << 16 | 0xffff);
501 					blockcnt =
502 					    rw->length ? rw->length : 0x100;
503 				} else {
504 					rwb = (struct scsi_rw_big *)xs->cmd;
505 					blockno = _4btol(rwb->addr);
506 					blockcnt = _2btol(rwb->length);
507 				}
508 				if (blockno >= sc->sc_secperunit ||
509 				    blockno + blockcnt > sc->sc_secperunit) {
510 					printf(
511 					    "%s: out of bounds %u-%u >= %u\n",
512 					    sc->sc_dv.dv_xname, blockno,
513 					    blockcnt, sc->sc_secperunit);
514 					/*
515 					 * XXX Should be XS_SENSE but that
516 					 * would require setting up a faked
517 					 * sense too.
518 					 */
519 					xs->error = XS_DRIVER_STUFFUP;
520 					xs->flags |= ITSDONE;
521 					scsi_done(xs);
522 					goto ready;
523 				}
524 			}
525 
526 			ccb = ioprbs_get_ccb(sc, xs->flags);
527 
528 			/*
529 			 * We are out of commands, try again in a little while.
530 			 */
531 			if (ccb == NULL) {
532 				xs->error = XS_DRIVER_STUFFUP;
533 				IOPRBS_UNLOCK(sc, lock);
534 				return (TRY_AGAIN_LATER);
535 			}
536 
537 			ccb->ic_blockno = blockno;
538 			ccb->ic_blockcnt = blockcnt;
539 			ccb->ic_xs = xs;
540 			ccb->ic_timeout = xs->timeout;
541 
542 			ioprbs_enqueue_ccb(sc, ccb);
543 
544 			/* XXX what if enqueue did not start a transfer? */
545 			if (xs->flags & SCSI_POLL) {
546 #if 0
547 				if (!ioprbs_wait(sc, ccb, ccb->ic_timeout)) {
548 					IOPRBS_UNLOCK(sc, lock);
549 					printf("%s: command timed out\n",
550 					    sc->sc_dv.dv_xname);
551 					xs->error = XS_TIMEOUT;
552 					return (TRY_AGAIN_LATER);
553 				}
554 				xs->flags |= ITSDONE;
555 				scsi_done(xs);
556 #endif
557 			}
558 		}
559 
560 	ready:
561 		/*
562 		 * Don't process the queue if we are polling.
563 		 */
564 		if (xs->flags & SCSI_POLL) {
565 			retval = COMPLETE;
566 			break;
567 		}
568 	}
569 
570 	IOPRBS_UNLOCK(sc, lock);
571 	return (retval);
572 }
573 
574 void
ioprbsminphys(bp)575 ioprbsminphys(bp)
576 	struct buf *bp;
577 {
578 	minphys(bp);
579 }
580 
581 void
ioprbs_intr(struct device * dv,struct iop_msg * im,void * reply)582 ioprbs_intr(struct device *dv, struct iop_msg *im, void *reply)
583 {
584 	struct i2o_rbs_reply *rb = reply;
585 	struct ioprbs_ccb *ccb = im->im_dvcontext;
586 	struct buf *bp = ccb->ic_xs->bp;
587 	struct ioprbs_softc *sc = (struct ioprbs_softc *)dv;
588 	struct iop_softc *iop = (struct iop_softc *)dv->dv_parent;
589 	int err, detail;
590 #ifdef I2OVERBOSE
591 	const char *errstr;
592 #endif
593 
594 	DPRINTF(("ioprbs_intr(%p, %p, %p) ", dv, im, reply));
595 
596 	timeout_del(&ccb->ic_xs->stimeout);
597 
598 	err = ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0);
599 
600 	if (!err && rb->reqstatus != I2O_STATUS_SUCCESS) {
601 		detail = letoh16(rb->detail);
602 #ifdef I2OVERBOSE
603 		if (detail > sizeof(ioprbs_errors) / sizeof(ioprbs_errors[0]))
604 			errstr = "<unknown>";
605 		else
606 			errstr = ioprbs_errors[detail];
607 		printf("%s: error 0x%04x: %s\n", dv->dv_xname, detail, errstr);
608 #else
609 		printf("%s: error 0x%04x\n", dv->dv_xname, detail);
610 #endif
611 		err = 1;
612 	}
613 
614 	if (err) {
615 		bp->b_flags |= B_ERROR;
616 		bp->b_error = EIO;
617 		bp->b_resid = bp->b_bcount;
618 	} else
619 		bp->b_resid = bp->b_bcount - letoh32(rb->transfercount);
620 
621 	iop_msg_unmap(iop, im);
622 	iop_msg_free(iop, im);
623 	scsi_done(ccb->ic_xs);
624 	ioprbs_free_ccb(sc, ccb);
625 }
626 
627 void
ioprbs_intr_event(struct device * dv,struct iop_msg * im,void * reply)628 ioprbs_intr_event(struct device *dv, struct iop_msg *im, void *reply)
629 {
630 	struct i2o_util_event_register_reply *rb;
631 	struct ioprbs_softc *sc;
632 	u_int event;
633 
634 	rb = reply;
635 
636 	if ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0)
637 		return;
638 
639 	event = letoh32(rb->event);
640 	sc = (struct ioprbs_softc *)dv;
641 
642 	if (event == I2O_EVENT_GEN_EVENT_MASK_MODIFIED) {
643 		sc->sc_flags |= IOPRBS_NEW_EVTMASK;
644 		wakeup(&sc->sc_eventii);
645 #ifndef I2ODEBUG
646 		return;
647 #endif
648 	}
649 
650 	printf("%s: event 0x%08x received\n", dv->dv_xname, event);
651 }
652 
653 void
ioprbs_adjqparam(struct device * dv,int mpi)654 ioprbs_adjqparam(struct device *dv, int mpi)
655 {
656 #if 0
657 	struct iop_softc *iop;
658 
659 	/*
660 	 * AMI controllers seem to loose the plot if you hand off lots of
661 	 * queued commands.
662 	 */
663 	iop = (struct iop_softc *)dv->dv_parent;
664 	if (letoh16(I2O_ORG_AMI) == iop->sc_status.orgid && mpi > 64)
665 		mpi = 64;
666 
667 	ldadjqparam((struct ld_softc *)dv, mpi);
668 #endif
669 }
670 
671 /*
672  * Insert a command into the driver queue, either at the front or at the tail.
673  * It's ok to overload the freelist link as these structures are never on
674  * the freelist at this time.
675  */
676 void
ioprbs_enqueue(sc,xs,infront)677 ioprbs_enqueue(sc, xs, infront)
678 	struct ioprbs_softc *sc;
679 	struct scsi_xfer *xs;
680 	int infront;
681 {
682 	if (infront || LIST_FIRST(&sc->sc_queue) == NULL) {
683 		if (LIST_FIRST(&sc->sc_queue) == NULL)
684 			sc->sc_queuelast = xs;
685 		LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
686 		return;
687 	}
688 	LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
689 	sc->sc_queuelast = xs;
690 }
691 
692 /*
693  * Pull a command off the front of the driver queue.
694  */
695 struct scsi_xfer *
ioprbs_dequeue(sc)696 ioprbs_dequeue(sc)
697 	struct ioprbs_softc *sc;
698 {
699 	struct scsi_xfer *xs;
700 
701 	xs = LIST_FIRST(&sc->sc_queue);
702 	if (xs == NULL)
703 		return (NULL);
704 	LIST_REMOVE(xs, free_list);
705 
706 	if (LIST_FIRST(&sc->sc_queue) == NULL)
707 		sc->sc_queuelast = NULL;
708 
709 	return (xs);
710 }
711 
712 void
ioprbs_copy_internal_data(xs,data,size)713 ioprbs_copy_internal_data(xs, data, size)
714 	struct scsi_xfer *xs;
715 	u_int8_t *data;
716 	size_t size;
717 {
718 	size_t copy_cnt;
719 
720 	DPRINTF(("ioprbs_copy_internal_data "));
721 
722 	if (!xs->datalen)
723 		printf("uio move not yet supported\n");
724 	else {
725 		copy_cnt = MIN(size, xs->datalen);
726 		bcopy(data, xs->data, copy_cnt);
727 	}
728 }
729 
730 /* Emulated SCSI operation on cache device */
731 int
ioprbs_internal_cache_cmd(xs)732 ioprbs_internal_cache_cmd(xs)
733 	struct scsi_xfer *xs;
734 {
735 	struct scsi_link *link = xs->sc_link;
736 	struct ioprbs_softc *sc = link->adapter_softc;
737 	u_int8_t target = link->target;
738 	struct scsi_inquiry_data inq;
739 	struct scsi_sense_data sd;
740 	struct {
741 		struct scsi_mode_header hd;
742 		struct scsi_blk_desc bd;
743 		union scsi_disk_pages dp;
744 	} mpd;
745 	struct scsi_read_cap_data rcd;
746 
747 	DPRINTF(("ioprbs_internal_cache_cmd "));
748 
749 	xs->error = XS_NOERROR;
750 
751 	if (target > 0 || link->lun != 0) {
752 		/*
753 		 * XXX Should be XS_SENSE but that would require setting up a
754 		 * faked sense too.
755 		 */
756 		xs->error = XS_DRIVER_STUFFUP;
757 		xs->flags |= ITSDONE;
758 		scsi_done(xs);
759 		return (COMPLETE);
760 	}
761 
762 	switch (xs->cmd->opcode) {
763 	case TEST_UNIT_READY:
764 	case START_STOP:
765 #if 0
766 	case VERIFY:
767 #endif
768 		DPRINTF(("opc %d tgt %d ", xs->cmd->opcode, target));
769 		break;
770 
771 	case REQUEST_SENSE:
772 		DPRINTF(("REQUEST SENSE tgt %d ", target));
773 		bzero(&sd, sizeof sd);
774 		sd.error_code = 0x70;
775 		sd.segment = 0;
776 		sd.flags = SKEY_NO_SENSE;
777 		bzero(sd.info, sizeof sd.info);
778 		sd.extra_len = 0;
779 		ioprbs_copy_internal_data(xs, (u_int8_t *)&sd, sizeof sd);
780 		break;
781 
782 	case INQUIRY:
783 		DPRINTF(("INQUIRY tgt %d", target));
784 		bzero(&inq, sizeof inq);
785 		/* XXX How do we detect removable/CD-ROM devices?  */
786 		inq.device = T_DIRECT;
787 		inq.dev_qual2 = 0;
788 		inq.version = 2;
789 		inq.response_format = 2;
790 		inq.additional_length = 32;
791 		strlcpy(inq.vendor, "I2O", sizeof inq.vendor);
792 		snprintf(inq.product, sizeof inq.product, "Container #%02d",
793 		    target);
794 		strlcpy(inq.revision, "   ", sizeof inq.revision);
795 		ioprbs_copy_internal_data(xs, (u_int8_t *)&inq, sizeof inq);
796 		break;
797 
798 	case MODE_SENSE:
799 		DPRINTF(("MODE SENSE tgt %d ", target));
800 
801 		bzero(&mpd, sizeof mpd);
802 		switch (((struct scsi_mode_sense *)xs->cmd)->page) {
803 		case 4:
804 			/* scsi_disk.h says this should be 0x16 */
805 			mpd.dp.rigid_geometry.pg_length = 0x16;
806 			mpd.hd.data_length = sizeof mpd.hd + sizeof mpd.bd +
807 			    mpd.dp.rigid_geometry.pg_length;
808 			mpd.hd.blk_desc_len = sizeof mpd.bd;
809 
810 			/* XXX */
811 			mpd.hd.dev_spec = 0;
812 			_lto3b(IOPRBS_BLOCK_SIZE, mpd.bd.blklen);
813 			mpd.dp.rigid_geometry.pg_code = 4;
814 			_lto3b(sc->sc_ncylinders, mpd.dp.rigid_geometry.ncyl);
815 			mpd.dp.rigid_geometry.nheads = sc->sc_nheads;
816 			ioprbs_copy_internal_data(xs, (u_int8_t *)&mpd,
817 			    sizeof mpd);
818 			break;
819 
820 		default:
821 			printf("%s: mode sense page %d not simulated\n",
822 			    sc->sc_dv.dv_xname,
823 			    ((struct scsi_mode_sense *)xs->cmd)->page);
824 			xs->error = XS_DRIVER_STUFFUP;
825 			return (0);
826 		}
827 		break;
828 
829 	case READ_CAPACITY:
830 		DPRINTF(("READ CAPACITY tgt %d ", target));
831 		bzero(&rcd, sizeof rcd);
832 		_lto4b(sc->sc_secperunit - 1, rcd.addr);
833 		_lto4b(IOPRBS_BLOCK_SIZE, rcd.length);
834 		ioprbs_copy_internal_data(xs, (u_int8_t *)&rcd, sizeof rcd);
835 		break;
836 
837 	default:
838 		printf("ioprbs_internal_cache_cmd got bad opcode: %d\n",
839 		    xs->cmd->opcode);
840 		xs->error = XS_DRIVER_STUFFUP;
841 		return (0);
842 	}
843 
844 	xs->error = XS_NOERROR;
845 	return (1);
846 }
847 
848 struct ioprbs_ccb *
ioprbs_get_ccb(sc,flags)849 ioprbs_get_ccb(sc, flags)
850 	struct ioprbs_softc *sc;
851 	int flags;
852 {
853 	struct ioprbs_ccb *ccb;
854 	ioprbs_lock_t lock;
855 
856 	DPRINTF(("ioprbs_get_ccb(%p, 0x%x) ", sc, flags));
857 
858 	lock = IOPRBS_LOCK(sc);
859 
860 	for (;;) {
861 		ccb = TAILQ_FIRST(&sc->sc_free_ccb);
862 		if (ccb != NULL)
863 			break;
864 		if (flags & SCSI_NOSLEEP)
865 			goto bail_out;
866 		tsleep(&sc->sc_free_ccb, PRIBIO, "ioprbs_ccb", 0);
867 	}
868 
869 	TAILQ_REMOVE(&sc->sc_free_ccb, ccb, ic_chain);
870 
871 	/* initialise the command */
872 	ccb->ic_flags = 0;
873 
874  bail_out:
875 	IOPRBS_UNLOCK(sc, lock);
876 	return (ccb);
877 }
878 
879 void
ioprbs_free_ccb(sc,ccb)880 ioprbs_free_ccb(sc, ccb)
881 	struct ioprbs_softc *sc;
882 	struct ioprbs_ccb *ccb;
883 {
884 	ioprbs_lock_t lock;
885 
886 	DPRINTF(("ioprbs_free_ccb(%p, %p) ", sc, ccb));
887 
888 	lock = IOPRBS_LOCK(sc);
889 
890 	TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, ic_chain);
891 
892 	/* If the free list was empty, wake up potential waiters. */
893 	if (TAILQ_NEXT(ccb, ic_chain) == NULL)
894 		wakeup(&sc->sc_free_ccb);
895 
896 	IOPRBS_UNLOCK(sc, lock);
897 }
898 
899 void
ioprbs_enqueue_ccb(sc,ccb)900 ioprbs_enqueue_ccb(sc, ccb)
901 	struct ioprbs_softc *sc;
902 	struct ioprbs_ccb *ccb;
903 {
904 	DPRINTF(("ioprbs_enqueue_ccb(%p, %p) ", sc, ccb));
905 
906 	timeout_set(&ccb->ic_xs->stimeout, ioprbs_timeout, ccb);
907 	TAILQ_INSERT_TAIL(&sc->sc_ccbq, ccb, ic_chain);
908 	ioprbs_start_ccbs(sc);
909 }
910 
911 void
ioprbs_start_ccbs(sc)912 ioprbs_start_ccbs(sc)
913 	struct ioprbs_softc *sc;
914 {
915 	struct ioprbs_ccb *ccb;
916 	struct scsi_xfer *xs;
917 
918 	DPRINTF(("ioprbs_start_ccbs(%p) ", sc));
919 
920 	while ((ccb = TAILQ_FIRST(&sc->sc_ccbq)) != NULL) {
921 
922 		xs = ccb->ic_xs;
923 		if (ccb->ic_flags & IOPRBS_ICF_WATCHDOG)
924 			timeout_del(&xs->stimeout);
925 
926 		if (ioprbs_exec_ccb(ccb) == 0) {
927 			ccb->ic_flags |= IOPRBS_ICF_WATCHDOG;
928 			timeout_set(&ccb->ic_xs->stimeout, ioprbs_watchdog,
929 			    ccb);
930 			timeout_add(&xs->stimeout,
931 			    (IOPRBS_WATCH_TIMEOUT * hz) / 1000);
932 			break;
933 		}
934 		TAILQ_REMOVE(&sc->sc_ccbq, ccb, ic_chain);
935 
936 		if ((xs->flags & SCSI_POLL) == 0) {
937 			timeout_set(&ccb->ic_xs->stimeout, ioprbs_timeout,
938 			    ccb);
939 			timeout_add(&xs->stimeout,
940 			    (ccb->ic_timeout * hz) / 1000);
941 		}
942 	}
943 }
944 
945 int
ioprbs_exec_ccb(ccb)946 ioprbs_exec_ccb(ccb)
947 	struct ioprbs_ccb *ccb;
948 {
949 	struct scsi_xfer *xs = ccb->ic_xs;
950 
951 	DPRINTF(("ioprbs_exec_ccb(%p, %p) ", xs, ccb));
952 
953 	ioprbs_start(ccb);
954 
955 	xs->error = XS_NOERROR;
956 	xs->resid = 0;
957 	return (1);
958 }
959 
960 /*
961  * Deliver a command to the controller; allocate controller resources at the
962  * last moment when possible.
963  */
964 int
ioprbs_start(struct ioprbs_ccb * ccb)965 ioprbs_start(struct ioprbs_ccb *ccb)
966 {
967 	struct scsi_xfer *xs = ccb->ic_xs;
968 	struct scsi_link *link = xs->sc_link;
969 	struct ioprbs_softc *sc = link->adapter_softc;
970 #ifdef I2ODEBUG
971 	u_int8_t target = link->target;
972 #endif
973 	struct iop_msg *im;
974 	struct iop_softc *iop = (struct iop_softc *)sc->sc_dv.dv_parent;
975 	struct i2o_rbs_block_read *mf;
976 	u_int rv, flags = 0, mode = I2O_RBS_BLOCK_READ;
977 	u_int64_t ba;
978 	u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
979 
980 	im = iop_msg_alloc(iop, &sc->sc_ii, 0);
981 	im->im_dvcontext = ccb;
982 
983 	switch (xs->cmd->opcode) {
984 	case PREVENT_ALLOW:
985 	case SYNCHRONIZE_CACHE:
986 		if (xs->cmd->opcode == PREVENT_ALLOW) {
987 			/* XXX PREVENT_ALLOW support goes here */
988 		} else {
989 			DPRINTF(("SYNCHRONIZE CACHE tgt %d ", target));
990 		}
991 		break;
992 
993 	case WRITE_COMMAND:
994 	case WRITE_BIG:
995 		flags = I2O_RBS_BLOCK_WRITE_CACHE_WB;
996 		mode = I2O_RBS_BLOCK_WRITE;
997 		/* FALLTHROUGH */
998 
999 	case READ_COMMAND:
1000 	case READ_BIG:
1001 		ba = (u_int64_t)ccb->ic_blockno * DEV_BSIZE;
1002 
1003 		/*
1004 		 * Fill the message frame.  We can use the block_read
1005 		 * structure for both reads and writes, as it's almost
1006 		 * identical to the * block_write structure.
1007 		 */
1008 		mf = (struct i2o_rbs_block_read *)mb;
1009 		mf->msgflags = I2O_MSGFLAGS(i2o_rbs_block_read);
1010 		mf->msgfunc = I2O_MSGFUNC(sc->sc_ii.ii_tid, mode);
1011 		mf->msgictx = sc->sc_ii.ii_ictx;
1012 		mf->msgtctx = im->im_tctx;
1013 		mf->flags = flags | (1 << 16);	/* flags & time multiplier */
1014 		mf->datasize = ccb->ic_blockcnt * DEV_BSIZE;
1015 		mf->lowoffset = (u_int32_t)ba;
1016 		mf->highoffset = (u_int32_t)(ba >> 32);
1017 
1018 		/* Map the data transfer and enqueue the command. */
1019 		rv = iop_msg_map_bio(iop, im, mb, xs->data,
1020 		    ccb->ic_blockcnt * DEV_BSIZE, mode == I2O_RBS_BLOCK_WRITE);
1021 		if (rv == 0) {
1022 			if ((rv = iop_msg_post(iop, im, mb, 0)) != 0) {
1023 				iop_msg_unmap(iop, im);
1024 				iop_msg_free(iop, im);
1025 			}
1026 		}
1027 		break;
1028 	}
1029 	return (0);
1030 }
1031 
1032 void
ioprbs_timeout(arg)1033 ioprbs_timeout(arg)
1034 	void *arg;
1035 {
1036 	struct ioprbs_ccb *ccb = arg;
1037 	struct scsi_link *link = ccb->ic_xs->sc_link;
1038 	struct ioprbs_softc *sc = link->adapter_softc;
1039 	ioprbs_lock_t lock;
1040 
1041 	sc_print_addr(link);
1042 	printf("timed out\n");
1043 
1044 	/* XXX Test for multiple timeouts */
1045 
1046 	ccb->ic_xs->error = XS_TIMEOUT;
1047 	lock = IOPRBS_LOCK(sc);
1048 	ioprbs_enqueue_ccb(sc, ccb);
1049 	IOPRBS_UNLOCK(sc, lock);
1050 }
1051 
1052 void
ioprbs_watchdog(arg)1053 ioprbs_watchdog(arg)
1054 	void *arg;
1055 {
1056 	struct ioprbs_ccb *ccb = arg;
1057 	struct scsi_link *link = ccb->ic_xs->sc_link;
1058 	struct ioprbs_softc *sc = link->adapter_softc;
1059 	ioprbs_lock_t lock;
1060 
1061 	lock = IOPRBS_LOCK(sc);
1062 	ccb->ic_flags &= ~IOPRBS_ICF_WATCHDOG;
1063 	ioprbs_start_ccbs(sc);
1064 	IOPRBS_UNLOCK(sc, lock);
1065 }
1066