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 ¶m, 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, ¶m, 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 ¶m, 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 ¶m, 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