ld_iop.c revision 1.10 1 /* $NetBSD: ld_iop.c,v 1.10 2001/11/13 12:24:59 lukem Exp $ */
2
3 /*-
4 * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran.
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 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 /*
40 * I2O front-end for ld(4) driver, supporting random block storage class
41 * devices. Currently, this doesn't handle anything more complex than
42 * fixed direct-access devices.
43 */
44
45 #include <sys/cdefs.h>
46 __KERNEL_RCSID(0, "$NetBSD: ld_iop.c,v 1.10 2001/11/13 12:24:59 lukem Exp $");
47
48 #include "opt_i2o.h"
49 #include "rnd.h"
50
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/kernel.h>
54 #include <sys/device.h>
55 #include <sys/buf.h>
56 #include <sys/endian.h>
57 #include <sys/dkio.h>
58 #include <sys/disk.h>
59 #include <sys/proc.h>
60 #if NRND > 0
61 #include <sys/rnd.h>
62 #endif
63
64 #include <machine/bus.h>
65
66 #include <dev/ldvar.h>
67
68 #include <dev/i2o/i2o.h>
69 #include <dev/i2o/iopio.h>
70 #include <dev/i2o/iopvar.h>
71
72 #define LD_IOP_TIMEOUT 30*1000
73
74 #define LD_IOP_CLAIMED 0x01
75 #define LD_IOP_NEW_EVTMASK 0x02
76
77 struct ld_iop_softc {
78 struct ld_softc sc_ld;
79 struct iop_initiator sc_ii;
80 struct iop_initiator sc_eventii;
81 int sc_flags;
82 };
83
84 static void ld_iop_adjqparam(struct device *, int);
85 static void ld_iop_attach(struct device *, struct device *, void *);
86 static int ld_iop_detach(struct device *, int);
87 static int ld_iop_dump(struct ld_softc *, void *, int, int);
88 static int ld_iop_flush(struct ld_softc *);
89 static void ld_iop_intr(struct device *, struct iop_msg *, void *);
90 static void ld_iop_intr_event(struct device *, struct iop_msg *, void *);
91 static int ld_iop_match(struct device *, struct cfdata *, void *);
92 static int ld_iop_start(struct ld_softc *, struct buf *);
93 static void ld_iop_unconfig(struct ld_iop_softc *, int);
94
95 struct cfattach ld_iop_ca = {
96 sizeof(struct ld_iop_softc),
97 ld_iop_match,
98 ld_iop_attach,
99 ld_iop_detach
100 };
101
102 #ifdef I2OVERBOSE
103 static const char * const ld_iop_errors[] = {
104 "success",
105 "media error",
106 "access error",
107 "device failure",
108 "device not ready",
109 "media not present",
110 "media locked",
111 "media failure",
112 "protocol failure",
113 "bus failure",
114 "access violation",
115 "media write protected",
116 "device reset",
117 "volume changed, waiting for acknowledgement",
118 "timeout",
119 };
120 #endif
121
122 static int
123 ld_iop_match(struct device *parent, struct cfdata *match, void *aux)
124 {
125 struct iop_attach_args *ia;
126
127 ia = aux;
128
129 return (ia->ia_class == I2O_CLASS_RANDOM_BLOCK_STORAGE);
130 }
131
132 static void
133 ld_iop_attach(struct device *parent, struct device *self, void *aux)
134 {
135 struct iop_attach_args *ia;
136 struct ld_softc *ld;
137 struct ld_iop_softc *sc;
138 struct iop_softc *iop;
139 int rv, evreg, enable;
140 char *typestr, *fixedstr;
141 u_int cachesz;
142 u_int32_t timeoutbase, rwvtimeoutbase, rwvtimeout;
143 struct {
144 struct i2o_param_op_results pr;
145 struct i2o_param_read_results prr;
146 union {
147 struct i2o_param_rbs_cache_control cc;
148 struct i2o_param_rbs_device_info bdi;
149 } p;
150 } __attribute__ ((__packed__)) param;
151
152 sc = (struct ld_iop_softc *)self;
153 ld = &sc->sc_ld;
154 iop = (struct iop_softc *)parent;
155 ia = (struct iop_attach_args *)aux;
156 evreg = 0;
157
158 /* Register us as an initiator. */
159 sc->sc_ii.ii_dv = self;
160 sc->sc_ii.ii_intr = ld_iop_intr;
161 sc->sc_ii.ii_adjqparam = ld_iop_adjqparam;
162 sc->sc_ii.ii_flags = 0;
163 sc->sc_ii.ii_tid = ia->ia_tid;
164 iop_initiator_register(iop, &sc->sc_ii);
165
166 /* Register another initiator to handle events from the device. */
167 sc->sc_eventii.ii_dv = self;
168 sc->sc_eventii.ii_intr = ld_iop_intr_event;
169 sc->sc_eventii.ii_flags = II_NOTCTX | II_UTILITY;
170 sc->sc_eventii.ii_tid = ia->ia_tid;
171 iop_initiator_register(iop, &sc->sc_eventii);
172
173 rv = iop_util_eventreg(iop, &sc->sc_eventii,
174 I2O_EVENT_GEN_EVENT_MASK_MODIFIED |
175 I2O_EVENT_GEN_DEVICE_RESET |
176 I2O_EVENT_GEN_STATE_CHANGE |
177 I2O_EVENT_GEN_GENERAL_WARNING);
178 if (rv != 0) {
179 printf("%s: unable to register for events", self->dv_xname);
180 goto bad;
181 }
182 evreg = 1;
183
184 /*
185 * Start out with one queued command. The `iop' driver will adjust
186 * the queue parameters once we're up and running.
187 */
188 ld->sc_maxqueuecnt = 1;
189
190 ld->sc_maxxfer = IOP_MAX_XFER;
191 ld->sc_dump = ld_iop_dump;
192 ld->sc_flush = ld_iop_flush;
193 ld->sc_start = ld_iop_start;
194
195 /* Say what the device is. */
196 printf(":");
197 iop_print_ident(iop, ia->ia_tid);
198
199 /*
200 * Claim the device so that we don't get any nasty surprises. Allow
201 * failure.
202 */
203 rv = iop_util_claim(iop, &sc->sc_ii, 0,
204 I2O_UTIL_CLAIM_CAPACITY_SENSITIVE |
205 I2O_UTIL_CLAIM_NO_PEER_SERVICE |
206 I2O_UTIL_CLAIM_NO_MANAGEMENT_SERVICE |
207 I2O_UTIL_CLAIM_PRIMARY_USER);
208 sc->sc_flags = rv ? 0 : LD_IOP_CLAIMED;
209
210 rv = iop_field_get_all(iop, ia->ia_tid, I2O_PARAM_RBS_DEVICE_INFO,
211 ¶m, sizeof(param), NULL);
212 if (rv != 0)
213 goto bad;
214
215 ld->sc_secsize = le32toh(param.p.bdi.blocksize);
216 ld->sc_secperunit = (int)
217 (le64toh(param.p.bdi.capacity) / ld->sc_secsize);
218
219 switch (param.p.bdi.type) {
220 case I2O_RBS_TYPE_DIRECT:
221 typestr = "direct access";
222 enable = 1;
223 break;
224 case I2O_RBS_TYPE_WORM:
225 typestr = "WORM";
226 enable = 0;
227 break;
228 case I2O_RBS_TYPE_CDROM:
229 typestr = "CD-ROM";
230 enable = 0;
231 break;
232 case I2O_RBS_TYPE_OPTICAL:
233 typestr = "optical";
234 enable = 0;
235 break;
236 default:
237 typestr = "unknown";
238 enable = 0;
239 break;
240 }
241
242 if ((le32toh(param.p.bdi.capabilities) & I2O_RBS_CAP_REMOVEABLE_MEDIA)
243 != 0) {
244 /* ld->sc_flags = LDF_REMOVEABLE; */
245 fixedstr = "removeable";
246 enable = 0;
247 } else
248 fixedstr = "fixed";
249
250 printf(" %s, %s", typestr, fixedstr);
251
252 /*
253 * Determine if the device has an private cache. If so, print the
254 * cache size. Even if the device doesn't appear to have a cache,
255 * we perform a flush at shutdown.
256 */
257 rv = iop_field_get_all(iop, ia->ia_tid, I2O_PARAM_RBS_CACHE_CONTROL,
258 ¶m, sizeof(param), NULL);
259 if (rv != 0)
260 goto bad;
261
262 if ((cachesz = le32toh(param.p.cc.totalcachesize)) != 0)
263 printf(", %dkB cache", cachesz >> 10);
264
265 printf("\n");
266
267 /*
268 * Configure the DDM's timeout functions to time out all commands
269 * after 30 seconds.
270 */
271 timeoutbase = htole32(LD_IOP_TIMEOUT * 1000);
272 rwvtimeoutbase = htole32(LD_IOP_TIMEOUT * 1000);
273 rwvtimeout = 0;
274
275 iop_field_set(iop, ia->ia_tid, I2O_PARAM_RBS_OPERATION,
276 &timeoutbase, sizeof(timeoutbase),
277 I2O_PARAM_RBS_OPERATION_timeoutbase);
278 iop_field_set(iop, ia->ia_tid, I2O_PARAM_RBS_OPERATION,
279 &rwvtimeoutbase, sizeof(rwvtimeoutbase),
280 I2O_PARAM_RBS_OPERATION_rwvtimeoutbase);
281 iop_field_set(iop, ia->ia_tid, I2O_PARAM_RBS_OPERATION,
282 &rwvtimeout, sizeof(rwvtimeout),
283 I2O_PARAM_RBS_OPERATION_rwvtimeoutbase);
284
285 if (enable)
286 ld->sc_flags |= LDF_ENABLED;
287 else
288 printf("%s: device not yet supported\n", self->dv_xname);
289
290 ldattach(ld);
291 return;
292
293 bad:
294 ld_iop_unconfig(sc, evreg);
295 }
296
297 static void
298 ld_iop_unconfig(struct ld_iop_softc *sc, int evreg)
299 {
300 struct iop_softc *iop;
301 int s;
302
303 iop = (struct iop_softc *)sc->sc_ld.sc_dv.dv_parent;
304
305 if ((sc->sc_flags & LD_IOP_CLAIMED) != 0)
306 iop_util_claim(iop, &sc->sc_ii, 1,
307 I2O_UTIL_CLAIM_PRIMARY_USER);
308
309 if (evreg) {
310 /*
311 * Mask off events, and wait up to 5 seconds for a reply.
312 * Note that some adapters won't reply to this (XXX We
313 * should check the event capabilities).
314 */
315 sc->sc_flags &= ~LD_IOP_NEW_EVTMASK;
316 iop_util_eventreg(iop, &sc->sc_eventii,
317 I2O_EVENT_GEN_EVENT_MASK_MODIFIED);
318 s = splbio();
319 if ((sc->sc_flags & LD_IOP_NEW_EVTMASK) == 0)
320 tsleep(&sc->sc_eventii, PRIBIO, "ld_iopevt", hz * 5);
321 splx(s);
322 #ifdef I2ODEBUG
323 if ((sc->sc_flags & LD_IOP_NEW_EVTMASK) == 0)
324 printf("%s: didn't reply to event unregister",
325 sc->sc_ld.sc_dv.dv_xname);
326 #endif
327 }
328
329 iop_initiator_unregister(iop, &sc->sc_eventii);
330 iop_initiator_unregister(iop, &sc->sc_ii);
331 }
332
333 static int
334 ld_iop_detach(struct device *self, int flags)
335 {
336 struct ld_iop_softc *sc;
337 struct iop_softc *iop;
338 int rv;
339
340 sc = (struct ld_iop_softc *)self;
341 iop = (struct iop_softc *)self->dv_parent;
342
343 if ((rv = ldbegindetach(&sc->sc_ld, flags)) != 0)
344 return (rv);
345
346 /*
347 * Abort any requests queued with the IOP, but allow requests that
348 * are already in progress to complete.
349 */
350 if ((sc->sc_ld.sc_flags & LDF_ENABLED) != 0)
351 iop_util_abort(iop, &sc->sc_ii, 0, 0,
352 I2O_UTIL_ABORT_WILD | I2O_UTIL_ABORT_CLEAN);
353
354 ldenddetach(&sc->sc_ld);
355
356 /* Un-claim the target, and un-register our initiators. */
357 if ((sc->sc_ld.sc_flags & LDF_ENABLED) != 0)
358 ld_iop_unconfig(sc, 1);
359
360 return (0);
361 }
362
363 static int
364 ld_iop_start(struct ld_softc *ld, struct buf *bp)
365 {
366 struct iop_msg *im;
367 struct iop_softc *iop;
368 struct ld_iop_softc *sc;
369 struct i2o_rbs_block_read *mf;
370 u_int rv, flags, write;
371 u_int64_t ba;
372 u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
373
374 sc = (struct ld_iop_softc *)ld;
375 iop = (struct iop_softc *)ld->sc_dv.dv_parent;
376
377 im = iop_msg_alloc(iop, 0);
378 im->im_dvcontext = bp;
379
380 write = ((bp->b_flags & B_READ) == 0);
381 ba = (u_int64_t)bp->b_rawblkno * ld->sc_secsize;
382
383 /*
384 * Write through the cache when performing synchronous writes. When
385 * performing a read, we don't request that the DDM cache the data,
386 * as there's little advantage to it.
387 */
388 if (write) {
389 if ((bp->b_flags & B_ASYNC) == 0)
390 flags = I2O_RBS_BLOCK_WRITE_CACHE_WT;
391 else
392 flags = I2O_RBS_BLOCK_WRITE_CACHE_WB;
393 } else
394 flags = 0;
395
396 /*
397 * Fill the message frame. We can use the block_read structure for
398 * both reads and writes, as it's almost identical to the
399 * block_write structure.
400 */
401 mf = (struct i2o_rbs_block_read *)mb;
402 mf->msgflags = I2O_MSGFLAGS(i2o_rbs_block_read);
403 mf->msgfunc = I2O_MSGFUNC(sc->sc_ii.ii_tid,
404 write ? I2O_RBS_BLOCK_WRITE : I2O_RBS_BLOCK_READ);
405 mf->msgictx = sc->sc_ii.ii_ictx;
406 mf->msgtctx = im->im_tctx;
407 mf->flags = flags | (1 << 16); /* flags & time multiplier */
408 mf->datasize = bp->b_bcount;
409 mf->lowoffset = (u_int32_t)ba;
410 mf->highoffset = (u_int32_t)(ba >> 32);
411
412 /* Map the data transfer and enqueue the command. */
413 rv = iop_msg_map_bio(iop, im, mb, bp->b_data, bp->b_bcount, write);
414 if (rv == 0) {
415 if ((rv = iop_post(iop, mb)) != 0) {
416 iop_msg_unmap(iop, im);
417 iop_msg_free(iop, im);
418 }
419 }
420 return (rv);
421 }
422
423 static int
424 ld_iop_dump(struct ld_softc *ld, void *data, int blkno, int blkcnt)
425 {
426 struct iop_msg *im;
427 struct iop_softc *iop;
428 struct ld_iop_softc *sc;
429 struct i2o_rbs_block_write *mf;
430 int rv, bcount;
431 u_int64_t ba;
432 u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
433
434 sc = (struct ld_iop_softc *)ld;
435 iop = (struct iop_softc *)ld->sc_dv.dv_parent;
436 bcount = blkcnt * ld->sc_secsize;
437 ba = (u_int64_t)blkno * ld->sc_secsize;
438 im = iop_msg_alloc(iop, IM_POLL);
439
440 mf = (struct i2o_rbs_block_write *)mb;
441 mf->msgflags = I2O_MSGFLAGS(i2o_rbs_block_write);
442 mf->msgfunc = I2O_MSGFUNC(sc->sc_ii.ii_tid, I2O_RBS_BLOCK_WRITE);
443 mf->msgictx = sc->sc_ii.ii_ictx;
444 mf->msgtctx = im->im_tctx;
445 mf->flags = I2O_RBS_BLOCK_WRITE_CACHE_WT | (1 << 16);
446 mf->datasize = bcount;
447 mf->lowoffset = (u_int32_t)ba;
448 mf->highoffset = (u_int32_t)(ba >> 32);
449
450 if ((rv = iop_msg_map(iop, im, mb, data, bcount, 1, NULL)) != 0) {
451 iop_msg_free(iop, im);
452 return (rv);
453 }
454
455 rv = iop_msg_post(iop, im, mb, LD_IOP_TIMEOUT * 2);
456 iop_msg_unmap(iop, im);
457 iop_msg_free(iop, im);
458 return (rv);
459 }
460
461 static int
462 ld_iop_flush(struct ld_softc *ld)
463 {
464 struct iop_msg *im;
465 struct iop_softc *iop;
466 struct ld_iop_softc *sc;
467 struct i2o_rbs_cache_flush mf;
468 int rv;
469
470 sc = (struct ld_iop_softc *)ld;
471 iop = (struct iop_softc *)ld->sc_dv.dv_parent;
472 im = iop_msg_alloc(iop, IM_WAIT);
473
474 mf.msgflags = I2O_MSGFLAGS(i2o_rbs_cache_flush);
475 mf.msgfunc = I2O_MSGFUNC(sc->sc_ii.ii_tid, I2O_RBS_CACHE_FLUSH);
476 mf.msgictx = sc->sc_ii.ii_ictx;
477 mf.msgtctx = im->im_tctx;
478 mf.flags = 1 << 16; /* time multiplier */
479
480 /* XXX Aincent disks will return an error here. */
481 rv = iop_msg_post(iop, im, &mf, LD_IOP_TIMEOUT * 2);
482 iop_msg_free(iop, im);
483 return (rv);
484 }
485
486 void
487 ld_iop_intr(struct device *dv, struct iop_msg *im, void *reply)
488 {
489 struct i2o_rbs_reply *rb;
490 struct buf *bp;
491 struct ld_iop_softc *sc;
492 struct iop_softc *iop;
493 int err, detail;
494 #ifdef I2OVERBOSE
495 const char *errstr;
496 #endif
497
498 rb = reply;
499 bp = im->im_dvcontext;
500 sc = (struct ld_iop_softc *)dv;
501 iop = (struct iop_softc *)dv->dv_parent;
502
503 err = ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0);
504
505 if (!err && rb->reqstatus != I2O_STATUS_SUCCESS) {
506 detail = le16toh(rb->detail);
507 #ifdef I2OVERBOSE
508 if (detail > sizeof(ld_iop_errors) / sizeof(ld_iop_errors[0]))
509 errstr = "<unknown>";
510 else
511 errstr = ld_iop_errors[detail];
512 printf("%s: error 0x%04x: %s\n", dv->dv_xname, detail, errstr);
513 #else
514 printf("%s: error 0x%04x\n", dv->dv_xname, detail);
515 #endif
516 err = 1;
517 }
518
519 if (err) {
520 bp->b_flags |= B_ERROR;
521 bp->b_error = EIO;
522 bp->b_resid = bp->b_bcount;
523 } else
524 bp->b_resid = bp->b_bcount - le32toh(rb->transfercount);
525
526 iop_msg_unmap(iop, im);
527 iop_msg_free(iop, im);
528 lddone(&sc->sc_ld, bp);
529 }
530
531 static void
532 ld_iop_intr_event(struct device *dv, struct iop_msg *im, void *reply)
533 {
534 struct i2o_util_event_register_reply *rb;
535 struct ld_iop_softc *sc;
536 u_int event;
537
538 rb = reply;
539
540 if ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0)
541 return;
542
543 event = le32toh(rb->event);
544 sc = (struct ld_iop_softc *)dv;
545
546 if (event == I2O_EVENT_GEN_EVENT_MASK_MODIFIED) {
547 sc->sc_flags |= LD_IOP_NEW_EVTMASK;
548 wakeup(&sc->sc_eventii);
549 #ifndef I2ODEBUG
550 return;
551 #endif
552 }
553
554 printf("%s: event 0x%08x received\n", dv->dv_xname, event);
555 }
556
557 static void
558 ld_iop_adjqparam(struct device *dv, int mpi)
559 {
560 struct iop_softc *iop;
561
562 /*
563 * AMI controllers seem to loose the plot if you hand off lots of
564 * queued commands.
565 */
566 iop = (struct iop_softc *)dv->dv_parent;
567 if (le16toh(I2O_ORG_AMI) == iop->sc_status.orgid && mpi > 64)
568 mpi = 64;
569
570 ldadjqparam((struct ld_softc *)dv, mpi);
571 }
572