This source file includes following definitions.
- iopsp_match
- iopsp_attach
- iopsp_reconfig
- iopsp_rescan
- iopspminphys
- iopsp_scsi_cmd
- iopsp_scsi_abort
- iopsp_intr
- iopsp_adjqparam
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/kernel.h>
48 #include <sys/device.h>
49 #include <sys/queue.h>
50 #include <sys/proc.h>
51 #include <sys/buf.h>
52 #include <sys/endian.h>
53 #include <sys/malloc.h>
54 #include <sys/scsiio.h>
55 #include <sys/lock.h>
56
57 #include <machine/bus.h>
58
59 #include <scsi/scsi_all.h>
60 #include <scsi/scsi_disk.h>
61 #include <scsi/scsi_all.h>
62 #include <scsi/scsiconf.h>
63 #include <scsi/scsi_message.h>
64
65 #include <dev/i2o/i2o.h>
66 #include <dev/i2o/iopio.h>
67 #include <dev/i2o/iopvar.h>
68 #include <dev/i2o/iopspvar.h>
69
70 struct cfdriver iopsp_cd = {
71 NULL, "iopsp", DV_DULL
72 };
73
74 int iopsp_match(struct device *, void *, void *);
75 void iopsp_attach(struct device *, struct device *, void *);
76
77 struct cfattach iopsp_ca = {
78 sizeof(struct iopsp_softc), iopsp_match, iopsp_attach
79 };
80
81 int iopsp_scsi_cmd(struct scsi_xfer *);
82 void iopspminphys(struct buf *bp);
83
84 struct scsi_adapter iopsp_switch = {
85 iopsp_scsi_cmd, iopspminphys, 0, 0,
86 };
87
88 struct scsi_device iopsp_dev = {
89 NULL, NULL, NULL, NULL
90 };
91
92 void iopsp_adjqparam(struct device *, int);
93 void iopsp_intr(struct device *, struct iop_msg *, void *);
94 int iopsp_rescan(struct iopsp_softc *);
95 int iopsp_reconfig(struct device *);
96
97
98
99
100 int
101 iopsp_match(struct device *parent, void *match, void *aux)
102 {
103 struct iop_attach_args *ia = aux;
104 struct {
105 struct i2o_param_op_results pr;
106 struct i2o_param_read_results prr;
107 struct i2o_param_hba_ctlr_info ci;
108 } __attribute__ ((__packed__)) param;
109 int rv;
110
111 if (ia->ia_class != I2O_CLASS_BUS_ADAPTER_PORT)
112 return (0);
113
114 if ((rv = iop_param_op((struct iop_softc *)parent, ia->ia_tid, NULL, 0,
115 I2O_PARAM_HBA_CTLR_INFO, ¶m, sizeof(param)))) {
116 #ifdef I2ODEBUG
117 printf("iopsp_match: iop_param_op failed, status = %d\n", rv);
118 #endif
119 return (0);
120 }
121
122 #ifdef I2ODEBUG
123 printf("iopsp_match: bustype = %d\n", param.ci.bustype);
124 #endif
125
126 return (param.ci.bustype == I2O_HBA_BUS_SCSI ||
127 param.ci.bustype == I2O_HBA_BUS_FCA);
128 }
129
130
131
132
133 void
134 iopsp_attach(struct device *parent, struct device *self, void *aux)
135 {
136 struct iop_softc *iop = (struct iop_softc *)parent;
137 struct iopsp_softc *sc = (struct iopsp_softc *)self;
138 struct iop_attach_args *ia = (struct iop_attach_args *)aux;
139 struct scsibus_attach_args saa;
140 struct {
141 struct i2o_param_op_results pr;
142 struct i2o_param_read_results prr;
143 union {
144 struct i2o_param_hba_ctlr_info ci;
145 struct i2o_param_hba_scsi_ctlr_info sci;
146 struct i2o_param_hba_scsi_port_info spi;
147 } p;
148 } __attribute__ ((__packed__)) param;
149 int fcal, rv;
150 #ifdef I2OVERBOSE
151 int size;
152 #endif
153
154
155 sc->sc_ii.ii_dv = self;
156 sc->sc_ii.ii_intr = iopsp_intr;
157 sc->sc_ii.ii_flags = 0;
158 sc->sc_ii.ii_tid = ia->ia_tid;
159 sc->sc_ii.ii_reconfig = iopsp_reconfig;
160 sc->sc_ii.ii_adjqparam = iopsp_adjqparam;
161 iop_initiator_register(iop, &sc->sc_ii);
162
163 rv = iop_param_op(iop, ia->ia_tid, NULL, 0, I2O_PARAM_HBA_CTLR_INFO,
164 ¶m, sizeof(param));
165 if (rv != 0) {
166 printf("%s: unable to get parameters (0x%04x; %d)\n",
167 sc->sc_dv.dv_xname, I2O_PARAM_HBA_CTLR_INFO, rv);
168 goto bad;
169 }
170
171 fcal = (param.p.ci.bustype == I2O_HBA_BUS_FCA);
172
173
174
175
176
177 printf(": SCSI port");
178 iop_print_ident(iop, ia->ia_tid);
179 printf("\n");
180
181 rv = iop_param_op(iop, ia->ia_tid, NULL, 0,
182 I2O_PARAM_HBA_SCSI_CTLR_INFO, ¶m, sizeof(param));
183 if (rv != 0) {
184 printf("%s: unable to get parameters (0x%04x; %d)\n",
185 sc->sc_dv.dv_xname, I2O_PARAM_HBA_SCSI_CTLR_INFO, rv);
186 goto bad;
187 }
188
189 #ifdef I2OVERBOSE
190 printf("%s: %d-bit, max sync rate %dMHz, initiator ID %d\n",
191 sc->sc_dv.dv_xname, param.p.sci.maxdatawidth,
192 (u_int32_t)letoh64(param.p.sci.maxsyncrate) / 1000,
193 letoh32(param.p.sci.initiatorid));
194 #endif
195
196 sc->sc_link.adapter_softc = sc;
197 sc->sc_link.adapter = &iopsp_switch;
198 sc->sc_link.adapter_target = letoh32(param.p.sci.initiatorid);
199 sc->sc_link.device = &iopsp_dev;
200 sc->sc_link.openings = 1;
201 sc->sc_link.adapter_buswidth = fcal?
202 IOPSP_MAX_FCAL_TARGET : param.p.sci.maxdatawidth;
203 sc->sc_link.luns = IOPSP_MAX_LUN;
204
205 #ifdef I2OVERBOSE
206
207
208
209
210 size = sc->sc_link.adapter_buswidth * sizeof(struct iopsp_target);
211 sc->sc_targetmap = malloc(size, M_DEVBUF, M_NOWAIT);
212 bzero(sc->sc_targetmap, size);
213 #endif
214
215
216 if (iopsp_reconfig(self) != 0) {
217 printf("%s: configure failed\n", sc->sc_dv.dv_xname);
218 goto bad;
219 }
220
221 bzero(&saa, sizeof(saa));
222 saa.saa_sc_link = &sc->sc_link;
223
224 config_found(&sc->sc_dv, &saa, scsiprint);
225 return;
226
227 bad:
228 iop_initiator_unregister(iop, &sc->sc_ii);
229 }
230
231
232
233
234
235 int
236 iopsp_reconfig(struct device *dv)
237 {
238 struct iopsp_softc *sc = (struct iopsp_softc *)dv;
239 struct iop_softc *iop = (struct iop_softc *)sc->sc_dv.dv_parent;
240 struct i2o_lct_entry *le;
241 struct {
242 struct i2o_param_op_results pr;
243 struct i2o_param_read_results prr;
244 struct i2o_param_scsi_device_info sdi;
245 } __attribute__ ((__packed__)) param;
246 u_int tid, nent, i, targ, lun, size, s, rv, bptid;
247 u_short *tidmap;
248 #ifdef I2OVERBOSE
249 struct iopsp_target *it;
250 int syncrate;
251 #endif
252
253
254 if (iop->sc_chgind == sc->sc_chgind)
255 return (0);
256
257
258
259
260
261
262 size = sc->sc_link.adapter_buswidth * IOPSP_MAX_LUN * sizeof(u_short);
263 if (!(tidmap = malloc(size, M_DEVBUF, M_NOWAIT)))
264 return (ENOMEM);
265 bzero(tidmap, size);
266
267 #ifdef I2OVERBOSE
268 for (i = 0; i < sc->sc_link.adapter_buswidth; i++)
269 sc->sc_targetmap[i].it_flags &= ~IT_PRESENT;
270 #endif
271
272
273
274
275 bptid = sc->sc_ii.ii_tid;
276 nent = iop->sc_nlctent;
277 for (le = iop->sc_lct->entry; nent != 0; nent--, le++)
278 if ((letoh16(le->classid) & 4095) ==
279 I2O_CLASS_BUS_ADAPTER_PORT &&
280 (letoh32(le->usertid) & 4095) == bptid) {
281 bptid = letoh16(le->localtid) & 4095;
282 break;
283 }
284
285 nent = iop->sc_nlctent;
286 for (i = 0, le = iop->sc_lct->entry; i < nent; i++, le++) {
287 if ((letoh16(le->classid) & I2O_CLASS_MASK) !=
288 I2O_CLASS_SCSI_PERIPHERAL ||
289 ((letoh32(le->usertid) >> 12) & 4095) != bptid)
290 continue;
291 tid = letoh16(le->localtid) & I2O_LCT_ENTRY_TID_MASK;
292
293 rv = iop_param_op(iop, tid, NULL, 0, I2O_PARAM_SCSI_DEVICE_INFO,
294 ¶m, sizeof(param));
295 if (rv != 0) {
296 printf("%s: unable to get parameters (0x%04x; %d)\n",
297 sc->sc_dv.dv_xname, I2O_PARAM_SCSI_DEVICE_INFO,
298 rv);
299 continue;
300 }
301 targ = letoh32(param.sdi.identifier);
302 lun = param.sdi.luninfo[1];
303 #if defined(DIAGNOSTIC) || defined(I2ODEBUG)
304 if (targ >= sc->sc_link.adapter_buswidth ||
305 lun >= sc->sc_link.adapter_buswidth) {
306 printf("%s: target %d,%d (tid %d): bad target/LUN\n",
307 sc->sc_dv.dv_xname, targ, lun, tid);
308 continue;
309 }
310 #endif
311
312 #ifdef I2OVERBOSE
313
314
315
316
317 it = &sc->sc_targetmap[targ];
318 it->it_flags |= IT_PRESENT;
319 syncrate = (int)((letoh64(param.sdi.negsyncrate) + 500) / 1000);
320 if (it->it_width == param.sdi.negdatawidth &&
321 it->it_offset == param.sdi.negoffset &&
322 it->it_syncrate == syncrate)
323 continue;
324
325 it->it_width = param.sdi.negdatawidth;
326 it->it_offset = param.sdi.negoffset;
327 it->it_syncrate = syncrate;
328
329 printf("%s: target %d (tid %d): %d-bit, ", sc->sc_dv.dv_xname,
330 targ, tid, it->it_width);
331 if (it->it_syncrate == 0)
332 printf("asynchronous\n");
333 else
334 printf("synchronous at %dMHz, offset 0x%x\n",
335 it->it_syncrate, it->it_offset);
336 #endif
337
338
339 if ((letoh32(le->usertid) & 4095) != I2O_TID_NONE) {
340 #ifdef I2OVERBOSE
341 if (sc->sc_tidmap == NULL ||
342 IOPSP_TIDMAP(sc->sc_tidmap, targ, lun) !=
343 IOPSP_TID_INUSE)
344 printf("%s: target %d,%d (tid %d): in use by"
345 " tid %d\n", sc->sc_dv.dv_xname,
346 targ, lun, tid,
347 letoh32(le->usertid) & 4095);
348 #endif
349 IOPSP_TIDMAP(tidmap, targ, lun) = IOPSP_TID_INUSE;
350 } else
351 IOPSP_TIDMAP(tidmap, targ, lun) = (u_short)tid;
352 }
353
354 #ifdef I2OVERBOSE
355 for (i = 0; i < sc->sc_link.adapter_buswidth; i++)
356 if ((sc->sc_targetmap[i].it_flags & IT_PRESENT) == 0)
357 sc->sc_targetmap[i].it_width = 0;
358 #endif
359
360
361 s = splbio();
362 if (sc->sc_tidmap != NULL)
363 free(sc->sc_tidmap, M_DEVBUF);
364 sc->sc_tidmap = tidmap;
365 splx(s);
366 sc->sc_chgind = iop->sc_chgind;
367 return (0);
368 }
369
370
371
372
373 int
374 iopsp_rescan(struct iopsp_softc *sc)
375 {
376 struct iop_softc *iop;
377 struct iop_msg *im;
378 struct i2o_hba_bus_scan mf;
379 int rv;
380
381 iop = (struct iop_softc *)sc->sc_dv.dv_parent;
382
383 rv = lockmgr(&iop->sc_conflock, LK_EXCLUSIVE, NULL);
384 if (rv != 0) {
385 #ifdef I2ODEBUG
386 printf("iopsp_rescan: unable to acquire lock\n");
387 #endif
388 return (rv);
389 }
390
391 im = iop_msg_alloc(iop, &sc->sc_ii, IM_WAIT);
392
393 mf.msgflags = I2O_MSGFLAGS(i2o_hba_bus_scan);
394 mf.msgfunc = I2O_MSGFUNC(sc->sc_ii.ii_tid, I2O_HBA_BUS_SCAN);
395 mf.msgictx = sc->sc_ii.ii_ictx;
396 mf.msgtctx = im->im_tctx;
397
398 rv = iop_msg_post(iop, im, &mf, 5*60*1000);
399 iop_msg_free(iop, im);
400 if (rv != 0)
401 printf("%s: bus rescan failed (error %d)\n",
402 sc->sc_dv.dv_xname, rv);
403
404 if ((rv = iop_lct_get(iop)) == 0)
405 rv = iopsp_reconfig(&sc->sc_dv);
406
407 lockmgr(&iop->sc_conflock, LK_RELEASE, NULL);
408 return (rv);
409 }
410
411 void
412 iopspminphys(bp)
413 struct buf *bp;
414 {
415 if (bp->b_bcount > IOP_MAX_XFER)
416 bp->b_bcount = IOP_MAX_XFER;
417 minphys(bp);
418 }
419
420
421
422
423 int
424 iopsp_scsi_cmd(xs)
425 struct scsi_xfer *xs;
426 {
427 struct scsi_link *link = xs->sc_link;
428 struct iopsp_softc *sc = (struct iopsp_softc *)link->adapter_softc;
429 struct iop_softc *iop = (struct iop_softc *)sc->sc_dv.dv_parent;
430 struct iop_msg *im;
431 struct i2o_scsi_scb_exec *mf;
432 int error, tid, s;
433 u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
434
435 tid = IOPSP_TIDMAP(sc->sc_tidmap, link->target, link->lun);
436 if (tid == IOPSP_TID_ABSENT || tid == IOPSP_TID_INUSE) {
437 xs->error = XS_SELTIMEOUT;
438 scsi_done(xs);
439 return (COMPLETE);
440 }
441
442 SC_DEBUG(xs->sc_link, SDEV_DB2, ("iopsp_scsi_cmd: run_xfer\n"));
443
444
445 if ((xs->flags & XS_RESET) != 0) {
446 if (iop_simple_cmd(iop, tid, I2O_SCSI_DEVICE_RESET,
447 sc->sc_ii.ii_ictx, 1, 30*1000) != 0) {
448 #ifdef I2ODEBUG
449 printf("%s: reset failed\n",
450 sc->sc_dv.dv_xname);
451 #endif
452 xs->error = XS_DRIVER_STUFFUP;
453 } else
454 xs->error = XS_NOERROR;
455
456 scsi_done(xs);
457 return (COMPLETE);
458 }
459
460 #if defined(I2ODEBUG) || defined(SCSIDEBUG)
461 if (xs->cmdlen > sizeof(mf->cdb))
462 panic("%s: CDB too large", sc->sc_dv.dv_xname);
463 #endif
464
465 im = iop_msg_alloc(iop, &sc->sc_ii, IM_POLL_INTR |
466 IM_NOSTATUS | ((xs->flags & SCSI_POLL) != 0 ? IM_POLL : 0));
467 im->im_dvcontext = xs;
468
469 mf = (struct i2o_scsi_scb_exec *)mb;
470 mf->msgflags = I2O_MSGFLAGS(i2o_scsi_scb_exec);
471 mf->msgfunc = I2O_MSGFUNC(tid, I2O_SCSI_SCB_EXEC);
472 mf->msgictx = sc->sc_ii.ii_ictx;
473 mf->msgtctx = im->im_tctx;
474 mf->flags = xs->cmdlen | I2O_SCB_FLAG_ENABLE_DISCONNECT |
475 I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
476 mf->datalen = xs->datalen;
477 memcpy(mf->cdb, xs->cmd, xs->cmdlen);
478
479 #if 0
480 switch (xs->xs_tag_type) {
481 case MSG_ORDERED_Q_TAG:
482 mf->flags |= I2O_SCB_FLAG_ORDERED_QUEUE_TAG;
483 break;
484 case MSG_SIMPLE_Q_TAG:
485 mf->flags |= I2O_SCB_FLAG_SIMPLE_QUEUE_TAG;
486 break;
487 case MSG_HEAD_OF_Q_TAG:
488 mf->flags |= I2O_SCB_FLAG_HEAD_QUEUE_TAG;
489 break;
490 default:
491 break;
492 }
493 #endif
494
495 if (xs->datalen != 0) {
496 error = iop_msg_map_bio(iop, im, mb, xs->data,
497 xs->datalen, (xs->flags & SCSI_DATA_OUT) == 0);
498 if (error) {
499 xs->error = XS_DRIVER_STUFFUP;
500 iop_msg_free(iop, im);
501 scsi_done(xs);
502 return (COMPLETE);
503 }
504 if ((xs->flags & SCSI_DATA_IN) == 0)
505 mf->flags |= I2O_SCB_FLAG_XFER_TO_DEVICE;
506 else
507 mf->flags |= I2O_SCB_FLAG_XFER_FROM_DEVICE;
508 }
509
510 s = splbio();
511 sc->sc_curqd++;
512 splx(s);
513
514 if (iop_msg_post(iop, im, mb, xs->timeout)) {
515 s = splbio();
516 sc->sc_curqd--;
517 splx(s);
518 if (xs->datalen != 0)
519 iop_msg_unmap(iop, im);
520 iop_msg_free(iop, im);
521 xs->error = XS_DRIVER_STUFFUP;
522 scsi_done(xs);
523 return (COMPLETE);
524 }
525
526 return (xs->flags & SCSI_POLL? COMPLETE : SUCCESSFULLY_QUEUED);
527 }
528
529 #ifdef notyet
530
531
532
533 int
534 iopsp_scsi_abort(struct iopsp_softc *sc, int atid, struct iop_msg *aim)
535 {
536 struct iop_msg *im;
537 struct i2o_scsi_scb_abort mf;
538 struct iop_softc *iop;
539 int rv, s;
540
541 iop = (struct iop_softc *)sc->sc_dv.dv_parent;
542 im = iop_msg_alloc(iop, &sc->sc_ii, IM_POLL);
543
544 mf.msgflags = I2O_MSGFLAGS(i2o_scsi_scb_abort);
545 mf.msgfunc = I2O_MSGFUNC(atid, I2O_SCSI_SCB_ABORT);
546 mf.msgictx = sc->sc_ii.ii_ictx;
547 mf.msgtctx = im->im_tctx;
548 mf.tctxabort = aim->im_tctx;
549
550 s = splbio();
551 rv = iop_msg_post(iop, im, &mf, 30000);
552 splx(s);
553 iop_msg_free(iop, im);
554 return (rv);
555 }
556 #endif
557
558
559
560
561
562 void
563 iopsp_intr(struct device *dv, struct iop_msg *im, void *reply)
564 {
565 struct scsi_xfer *xs;
566 struct iopsp_softc *sc;
567 struct i2o_scsi_reply *rb;
568 struct iop_softc *iop;
569 u_int sl;
570
571 sc = (struct iopsp_softc *)dv;
572 xs = (struct scsi_xfer *)im->im_dvcontext;
573 iop = (struct iop_softc *)dv->dv_parent;
574 rb = reply;
575
576 SC_DEBUG(xs->sc_link, SDEV_DB2, ("iopsp_intr\n"));
577
578 if ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0) {
579 xs->error = XS_DRIVER_STUFFUP;
580 xs->resid = xs->datalen;
581 } else {
582 if (rb->hbastatus != I2O_SCSI_DSC_SUCCESS) {
583 switch (rb->hbastatus) {
584 case I2O_SCSI_DSC_ADAPTER_BUSY:
585 case I2O_SCSI_DSC_SCSI_BUS_RESET:
586 case I2O_SCSI_DSC_BUS_BUSY:
587 xs->error = XS_BUSY;
588 break;
589 case I2O_SCSI_DSC_SELECTION_TIMEOUT:
590 xs->error = XS_SELTIMEOUT;
591 break;
592 case I2O_SCSI_DSC_COMMAND_TIMEOUT:
593 case I2O_SCSI_DSC_DEVICE_NOT_PRESENT:
594 case I2O_SCSI_DSC_LUN_INVALID:
595 case I2O_SCSI_DSC_SCSI_TID_INVALID:
596 xs->error = XS_TIMEOUT;
597 break;
598 default:
599 xs->error = XS_DRIVER_STUFFUP;
600 break;
601 }
602 printf("%s: HBA status 0x%02x\n", sc->sc_dv.dv_xname,
603 rb->hbastatus);
604 } else if (rb->scsistatus != SCSI_OK) {
605 switch (rb->scsistatus) {
606 case SCSI_CHECK:
607 xs->error = XS_SENSE;
608 sl = letoh32(rb->senselen);
609 if (sl > sizeof(xs->sense))
610 sl = sizeof(xs->sense);
611 bcopy(rb->sense, &xs->sense, sl);
612 break;
613 case SCSI_QUEUE_FULL:
614 case SCSI_BUSY:
615 xs->error = XS_BUSY;
616 break;
617 default:
618 xs->error = XS_DRIVER_STUFFUP;
619 break;
620 }
621 } else
622 xs->error = XS_NOERROR;
623
624 xs->resid = xs->datalen - letoh32(rb->datalen);
625 xs->status = rb->scsistatus;
626 }
627
628
629 if (xs->datalen != 0)
630 iop_msg_unmap(iop, im);
631 iop_msg_free(iop, im);
632
633 if (--sc->sc_curqd == sc->sc_link.openings)
634 wakeup(&sc->sc_curqd);
635
636 scsi_done(xs);
637 }
638
639
640
641
642 void
643 iopsp_adjqparam(struct device *dv, int mpi)
644 {
645 struct iopsp_softc *sc = (struct iopsp_softc *)dv;
646 int s;
647
648 s = splbio();
649 sc->sc_link.openings = mpi;
650 if (mpi < sc->sc_curqd)
651 tsleep(&sc->sc_curqd, PWAIT, "iopspdrn", 0);
652 splx(s);
653 }