This source file includes following definitions.
- ioprbs_match
- ioprbs_attach
- ioprbs_unconfig
- ioprbs_scsi_cmd
- ioprbsminphys
- ioprbs_intr
- ioprbs_intr_event
- ioprbs_adjqparam
- ioprbs_enqueue
- ioprbs_dequeue
- ioprbs_copy_internal_data
- ioprbs_internal_cache_cmd
- ioprbs_get_ccb
- ioprbs_free_ccb
- ioprbs_enqueue_ccb
- ioprbs_start_ccbs
- ioprbs_exec_ccb
- ioprbs_start
- ioprbs_timeout
- ioprbs_watchdog
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 #include <sys/param.h>
78 #include <sys/buf.h>
79 #include <sys/device.h>
80 #include <sys/kernel.h>
81 #include <sys/proc.h>
82 #include <sys/systm.h>
83
84 #include <machine/bus.h>
85
86 #include <scsi/scsi_all.h>
87 #include <scsi/scsi_disk.h>
88 #include <scsi/scsiconf.h>
89
90 #include <dev/i2o/i2o.h>
91 #include <dev/i2o/iopio.h>
92 #include <dev/i2o/iopvar.h>
93 #include <dev/i2o/ioprbsvar.h>
94
95 #ifdef I2ODEBUG
96 #define DPRINTF(x) printf x
97 #else
98 #define DPRINTF(x)
99 #endif
100
101 void ioprbsminphys(struct buf *);
102 void ioprbs_adjqparam(struct device *, int);
103 void ioprbs_attach(struct device *, struct device *, void *);
104 void ioprbs_copy_internal_data(struct scsi_xfer *, u_int8_t *,
105 size_t);
106 struct scsi_xfer *ioprbs_dequeue(struct ioprbs_softc *);
107 void ioprbs_enqueue(struct ioprbs_softc *, struct scsi_xfer *, int);
108 void ioprbs_enqueue_ccb(struct ioprbs_softc *, struct ioprbs_ccb *);
109 int ioprbs_exec_ccb(struct ioprbs_ccb *);
110 void ioprbs_free_ccb(struct ioprbs_softc *, struct ioprbs_ccb *);
111 struct ioprbs_ccb *ioprbs_get_ccb(struct ioprbs_softc *, int);
112 void ioprbs_internal_cache_cmd(struct scsi_xfer *);
113 void ioprbs_intr(struct device *, struct iop_msg *, void *);
114 void ioprbs_intr_event(struct device *, struct iop_msg *, void *);
115 int ioprbs_match(struct device *, void *, void *);
116 int ioprbs_scsi_cmd(struct scsi_xfer *);
117 int ioprbs_start(struct ioprbs_ccb *);
118 void ioprbs_start_ccbs(struct ioprbs_softc *);
119 void ioprbs_timeout(void *);
120 void ioprbs_unconfig(struct ioprbs_softc *, int);
121 void ioprbs_watchdog(void *);
122
123 struct cfdriver ioprbs_cd = {
124 NULL, "ioprbs", DV_DULL
125 };
126
127 struct cfattach ioprbs_ca = {
128 sizeof(struct ioprbs_softc), ioprbs_match, ioprbs_attach
129 };
130
131 struct scsi_adapter ioprbs_switch = {
132 ioprbs_scsi_cmd, ioprbsminphys, 0, 0,
133 };
134
135 struct scsi_device ioprbs_dev = {
136 NULL, NULL, NULL, NULL
137 };
138
139 #ifdef I2OVERBOSE
140 static const char *const ioprbs_errors[] = {
141 "success",
142 "media error",
143 "access error",
144 "device failure",
145 "device not ready",
146 "media not present",
147 "media locked",
148 "media failure",
149 "protocol failure",
150 "bus failure",
151 "access violation",
152 "media write protected",
153 "device reset",
154 "volume changed, waiting for acknowledgement",
155 "timeout",
156 };
157 #endif
158
159
160
161
162 int
163 ioprbs_match(parent, match, aux)
164 struct device *parent;
165 void *match;
166 void *aux;
167 {
168 struct iop_attach_args *ia = aux;
169
170 return (ia->ia_class == I2O_CLASS_RANDOM_BLOCK_STORAGE);
171 }
172
173
174
175
176 void
177 ioprbs_attach(struct device *parent, struct device *self, void *aux)
178 {
179 struct iop_attach_args *ia = aux;
180 struct ioprbs_softc *sc = (struct ioprbs_softc *)self;
181 struct iop_softc *iop = (struct iop_softc *)parent;
182 struct scsibus_attach_args saa;
183 int rv, state = 0;
184 int enable;
185 u_int32_t cachesz;
186 char *typestr, *fixedstr;
187 struct {
188 struct i2o_param_op_results pr;
189 struct i2o_param_read_results prr;
190 union {
191 struct i2o_param_rbs_cache_control cc;
192 struct i2o_param_rbs_device_info bdi;
193 struct i2o_param_rbs_operation op;
194 } p;
195 } param ;
196 int i;
197
198 TAILQ_INIT(&sc->sc_free_ccb);
199 TAILQ_INIT(&sc->sc_ccbq);
200 LIST_INIT(&sc->sc_queue);
201
202
203 for (i = 0; i < IOPRBS_MAX_CCBS; i++)
204 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, &sc->sc_ccbs[i],
205 ic_chain);
206
207
208 sc->sc_ii.ii_dv = self;
209 sc->sc_ii.ii_intr = ioprbs_intr;
210 sc->sc_ii.ii_adjqparam = ioprbs_adjqparam;
211 sc->sc_ii.ii_flags = 0;
212 sc->sc_ii.ii_tid = ia->ia_tid;
213 iop_initiator_register(iop, &sc->sc_ii);
214
215
216 sc->sc_eventii.ii_dv = self;
217 sc->sc_eventii.ii_intr = ioprbs_intr_event;
218 sc->sc_eventii.ii_flags = II_DISCARD | II_UTILITY;
219 sc->sc_eventii.ii_tid = ia->ia_tid;
220 iop_initiator_register(iop, &sc->sc_eventii);
221
222 rv = iop_util_eventreg(iop, &sc->sc_eventii,
223 I2O_EVENT_GEN_EVENT_MASK_MODIFIED | I2O_EVENT_GEN_DEVICE_RESET |
224 I2O_EVENT_GEN_STATE_CHANGE | I2O_EVENT_GEN_GENERAL_WARNING);
225 if (rv != 0) {
226 printf("%s: unable to register for events", self->dv_xname);
227 goto bad;
228 }
229 state++;
230
231
232
233
234
235 sc->sc_maxqueuecnt = 1;
236
237 sc->sc_maxxfer = IOP_MAX_XFER;
238
239
240 printf(":");
241 iop_print_ident(iop, ia->ia_tid);
242
243
244
245
246
247 rv = iop_util_claim(iop, &sc->sc_ii, 0,
248 I2O_UTIL_CLAIM_CAPACITY_SENSITIVE |
249 I2O_UTIL_CLAIM_NO_PEER_SERVICE |
250 I2O_UTIL_CLAIM_NO_MANAGEMENT_SERVICE |
251 I2O_UTIL_CLAIM_PRIMARY_USER);
252 sc->sc_flags = rv ? 0 : IOPRBS_CLAIMED;
253
254 rv = iop_param_op(iop, ia->ia_tid, NULL, 0, I2O_PARAM_RBS_DEVICE_INFO,
255 ¶m, sizeof param);
256 if (rv != 0) {
257 printf("%s: unable to get parameters (0x%04x; %d)\n",
258 sc->sc_dv.dv_xname, I2O_PARAM_RBS_DEVICE_INFO, rv);
259 goto bad;
260 }
261
262 sc->sc_secsize = letoh32(param.p.bdi.blocksize);
263 sc->sc_secperunit = (int)
264 (letoh64(param.p.bdi.capacity) / sc->sc_secsize);
265
266 switch (param.p.bdi.type) {
267 case I2O_RBS_TYPE_DIRECT:
268 typestr = "direct access";
269 enable = 1;
270 break;
271 case I2O_RBS_TYPE_WORM:
272 typestr = "WORM";
273 enable = 0;
274 break;
275 case I2O_RBS_TYPE_CDROM:
276 typestr = "CD-ROM";
277 enable = 0;
278 break;
279 case I2O_RBS_TYPE_OPTICAL:
280 typestr = "optical";
281 enable = 0;
282 break;
283 default:
284 typestr = "unknown";
285 enable = 0;
286 break;
287 }
288
289 if ((letoh32(param.p.bdi.capabilities) & I2O_RBS_CAP_REMOVABLE_MEDIA)
290 != 0) {
291
292 fixedstr = "removable";
293 enable = 0;
294 } else
295 fixedstr = "fixed";
296
297 printf(" %s, %s", typestr, fixedstr);
298
299
300
301
302
303
304 rv = iop_param_op(iop, ia->ia_tid, NULL, 0,
305 I2O_PARAM_RBS_CACHE_CONTROL, ¶m, sizeof(param));
306 if (rv != 0) {
307 printf("%s: unable to get parameters (0x%04x; %d)\n",
308 sc->sc_dv.dv_xname, I2O_PARAM_RBS_CACHE_CONTROL, rv);
309 goto bad;
310 }
311
312 if ((cachesz = letoh32(param.p.cc.totalcachesize)) != 0)
313 printf(", %dkB cache", cachesz >> 10);
314
315 printf("\n");
316
317
318
319
320
321 rv = iop_param_op(iop, ia->ia_tid, NULL, 0, I2O_PARAM_RBS_OPERATION,
322 ¶m, sizeof(param));
323 if (rv != 0) {
324 printf("%s: unable to get parameters (0x%04x; %d)\n",
325 sc->sc_dv.dv_xname, I2O_PARAM_RBS_OPERATION, rv);
326 goto bad;
327 }
328
329 param.p.op.timeoutbase = htole32(IOPRBS_TIMEOUT * 1000);
330 param.p.op.rwvtimeoutbase = htole32(IOPRBS_TIMEOUT * 1000);
331 param.p.op.rwvtimeout = 0;
332
333 rv = iop_param_op(iop, ia->ia_tid, NULL, 1, I2O_PARAM_RBS_OPERATION,
334 ¶m, sizeof(param));
335 #ifdef notdef
336
337
338
339
340
341 if (rv != 0) {
342 printf("%s: unable to set parameters (0x%04x; %d)\n",
343 sc->sc_dv.dv_xname, I2O_PARAM_RBS_OPERATION, rv);
344 goto bad;
345 }
346 #endif
347
348 if (enable)
349 sc->sc_flags |= IOPRBS_ENABLED;
350 else
351 printf("%s: device not yet supported\n", self->dv_xname);
352
353
354 sc->sc_link.adapter_softc = sc;
355 sc->sc_link.adapter = &ioprbs_switch;
356 sc->sc_link.device = &ioprbs_dev;
357 sc->sc_link.openings = 1;
358 sc->sc_link.adapter_buswidth = 1;
359 sc->sc_link.adapter_target = 1;
360
361 bzero(&saa, sizeof(saa));
362 saa.saa_sc_link = &sc->sc_link;
363
364 config_found(&sc->sc_dv, &saa, scsiprint);
365
366 return;
367
368 bad:
369 ioprbs_unconfig(sc, state > 0);
370 }
371
372 void
373 ioprbs_unconfig(struct ioprbs_softc *sc, int evreg)
374 {
375 struct iop_softc *iop;
376 int s;
377
378 iop = (struct iop_softc *)sc->sc_dv.dv_parent;
379
380 if ((sc->sc_flags & IOPRBS_CLAIMED) != 0)
381 iop_util_claim(iop, &sc->sc_ii, 1,
382 I2O_UTIL_CLAIM_PRIMARY_USER);
383
384 if (evreg) {
385
386
387
388
389
390 sc->sc_flags &= ~IOPRBS_NEW_EVTMASK;
391 iop_util_eventreg(iop, &sc->sc_eventii,
392 I2O_EVENT_GEN_EVENT_MASK_MODIFIED);
393 s = splbio();
394 if ((sc->sc_flags & IOPRBS_NEW_EVTMASK) == 0)
395 tsleep(&sc->sc_eventii, PRIBIO, "ioprbsevt", hz * 5);
396 splx(s);
397 #ifdef I2ODEBUG
398 if ((sc->sc_flags & IOPRBS_NEW_EVTMASK) == 0)
399 printf("%s: didn't reply to event unregister",
400 sc->sc_dv.dv_xname);
401 #endif
402 }
403
404 iop_initiator_unregister(iop, &sc->sc_eventii);
405 iop_initiator_unregister(iop, &sc->sc_ii);
406 }
407
408 int
409 ioprbs_scsi_cmd(xs)
410 struct scsi_xfer *xs;
411 {
412 struct scsi_link *link = xs->sc_link;
413 struct ioprbs_softc *sc = link->adapter_softc;
414 struct ioprbs_ccb *ccb;
415 u_int32_t blockno, blockcnt;
416 struct scsi_rw *rw;
417 struct scsi_rw_big *rwb;
418 ioprbs_lock_t lock;
419 int retval = SUCCESSFULLY_QUEUED;
420
421 lock = IOPRBS_LOCK(sc);
422
423
424 if (xs != LIST_FIRST(&sc->sc_queue))
425 ioprbs_enqueue(sc, xs, 0);
426
427 while ((xs = ioprbs_dequeue(sc))) {
428 xs->error = XS_NOERROR;
429
430 ccb = NULL;
431
432 switch (xs->cmd->opcode) {
433 case TEST_UNIT_READY:
434 case REQUEST_SENSE:
435 case INQUIRY:
436 case MODE_SENSE:
437 case START_STOP:
438 case READ_CAPACITY:
439 #if 0
440 case VERIFY:
441 #endif
442 ioprbs_internal_cache_cmd(xs);
443 xs->flags |= ITSDONE;
444 scsi_done(xs);
445 goto ready;
446
447 case PREVENT_ALLOW:
448 DPRINTF(("PREVENT/ALLOW "));
449
450 xs->error = XS_NOERROR;
451 xs->flags |= ITSDONE;
452 scsi_done(xs);
453 goto ready;
454
455 case SYNCHRONIZE_CACHE:
456 DPRINTF(("SYNCHRONIZE_CACHE "));
457
458 xs->error = XS_NOERROR;
459 xs->flags |= ITSDONE;
460 scsi_done(xs);
461 goto ready;
462
463 default:
464 DPRINTF(("unknown opc %d ", xs->cmd->opcode));
465
466 xs->error = XS_DRIVER_STUFFUP;
467 xs->flags |= ITSDONE;
468 scsi_done(xs);
469 goto ready;
470
471 case READ_COMMAND:
472 case READ_BIG:
473 case WRITE_COMMAND:
474 case WRITE_BIG:
475 DPRINTF(("rw opc %d ", xs->cmd->opcode));
476
477 if (xs->cmd->opcode != SYNCHRONIZE_CACHE) {
478
479 if (xs->cmdlen == 6) {
480 rw = (struct scsi_rw *)xs->cmd;
481 blockno = _3btol(rw->addr) &
482 (SRW_TOPADDR << 16 | 0xffff);
483 blockcnt =
484 rw->length ? rw->length : 0x100;
485 } else {
486 rwb = (struct scsi_rw_big *)xs->cmd;
487 blockno = _4btol(rwb->addr);
488 blockcnt = _2btol(rwb->length);
489 }
490 if (blockno >= sc->sc_secperunit ||
491 blockno + blockcnt > sc->sc_secperunit) {
492 printf(
493 "%s: out of bounds %u-%u >= %u\n",
494 sc->sc_dv.dv_xname, blockno,
495 blockcnt, sc->sc_secperunit);
496
497
498
499
500
501 xs->error = XS_DRIVER_STUFFUP;
502 xs->flags |= ITSDONE;
503 scsi_done(xs);
504 goto ready;
505 }
506 }
507
508 ccb = ioprbs_get_ccb(sc, xs->flags);
509
510
511
512
513 if (ccb == NULL) {
514 IOPRBS_UNLOCK(sc, lock);
515 return (TRY_AGAIN_LATER);
516 }
517
518 ccb->ic_blockno = blockno;
519 ccb->ic_blockcnt = blockcnt;
520 ccb->ic_xs = xs;
521 ccb->ic_timeout = xs->timeout;
522
523 ioprbs_enqueue_ccb(sc, ccb);
524
525
526 if (xs->flags & SCSI_POLL) {
527 #if 0
528 if (!ioprbs_wait(sc, ccb, ccb->ic_timeout)) {
529 IOPRBS_UNLOCK(sc, lock);
530 printf("%s: command timed out\n",
531 sc->sc_dv.dv_xname);
532 return (TRY_AGAIN_LATER);
533 }
534 xs->flags |= ITSDONE;
535 scsi_done(xs);
536 #endif
537 }
538 }
539
540 ready:
541
542
543
544 if (xs->flags & SCSI_POLL) {
545 retval = COMPLETE;
546 break;
547 }
548 }
549
550 IOPRBS_UNLOCK(sc, lock);
551 return (retval);
552 }
553
554 void
555 ioprbsminphys(bp)
556 struct buf *bp;
557 {
558 minphys(bp);
559 }
560
561 void
562 ioprbs_intr(struct device *dv, struct iop_msg *im, void *reply)
563 {
564 struct i2o_rbs_reply *rb = reply;
565 struct ioprbs_ccb *ccb = im->im_dvcontext;
566 struct buf *bp = ccb->ic_xs->bp;
567 struct ioprbs_softc *sc = (struct ioprbs_softc *)dv;
568 struct iop_softc *iop = (struct iop_softc *)dv->dv_parent;
569 int err, detail;
570 #ifdef I2OVERBOSE
571 const char *errstr;
572 #endif
573
574 DPRINTF(("ioprbs_intr(%p, %p, %p) ", dv, im, reply));
575
576 timeout_del(&ccb->ic_xs->stimeout);
577
578 err = ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0);
579
580 if (!err && rb->reqstatus != I2O_STATUS_SUCCESS) {
581 detail = letoh16(rb->detail);
582 #ifdef I2OVERBOSE
583 if (detail > sizeof(ioprbs_errors) / sizeof(ioprbs_errors[0]))
584 errstr = "<unknown>";
585 else
586 errstr = ioprbs_errors[detail];
587 printf("%s: error 0x%04x: %s\n", dv->dv_xname, detail, errstr);
588 #else
589 printf("%s: error 0x%04x\n", dv->dv_xname, detail);
590 #endif
591 err = 1;
592 }
593
594 if (bp) {
595 if (err) {
596 bp->b_flags |= B_ERROR;
597 bp->b_error = EIO;
598 bp->b_resid = bp->b_bcount;
599 } else
600 bp->b_resid = bp->b_bcount - letoh32(rb->transfercount);
601 }
602
603 iop_msg_unmap(iop, im);
604 iop_msg_free(iop, im);
605 scsi_done(ccb->ic_xs);
606 ioprbs_free_ccb(sc, ccb);
607 }
608
609 void
610 ioprbs_intr_event(struct device *dv, struct iop_msg *im, void *reply)
611 {
612 struct i2o_util_event_register_reply *rb;
613 struct ioprbs_softc *sc;
614 u_int event;
615
616 rb = reply;
617
618 if ((rb->msgflags & I2O_MSGFLAGS_FAIL) != 0)
619 return;
620
621 event = letoh32(rb->event);
622 sc = (struct ioprbs_softc *)dv;
623
624 if (event == I2O_EVENT_GEN_EVENT_MASK_MODIFIED) {
625 sc->sc_flags |= IOPRBS_NEW_EVTMASK;
626 wakeup(&sc->sc_eventii);
627 #ifndef I2ODEBUG
628 return;
629 #endif
630 }
631
632 printf("%s: event 0x%08x received\n", dv->dv_xname, event);
633 }
634
635 void
636 ioprbs_adjqparam(struct device *dv, int mpi)
637 {
638 #if 0
639 struct iop_softc *iop;
640
641
642
643
644
645 iop = (struct iop_softc *)dv->dv_parent;
646 if (letoh16(I2O_ORG_AMI) == iop->sc_status.orgid && mpi > 64)
647 mpi = 64;
648
649 ldadjqparam((struct ld_softc *)dv, mpi);
650 #endif
651 }
652
653
654
655
656
657
658 void
659 ioprbs_enqueue(sc, xs, infront)
660 struct ioprbs_softc *sc;
661 struct scsi_xfer *xs;
662 int infront;
663 {
664 if (infront || LIST_FIRST(&sc->sc_queue) == NULL) {
665 if (LIST_FIRST(&sc->sc_queue) == NULL)
666 sc->sc_queuelast = xs;
667 LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
668 return;
669 }
670 LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
671 sc->sc_queuelast = xs;
672 }
673
674
675
676
677 struct scsi_xfer *
678 ioprbs_dequeue(sc)
679 struct ioprbs_softc *sc;
680 {
681 struct scsi_xfer *xs;
682
683 xs = LIST_FIRST(&sc->sc_queue);
684 if (xs == NULL)
685 return (NULL);
686 LIST_REMOVE(xs, free_list);
687
688 if (LIST_FIRST(&sc->sc_queue) == NULL)
689 sc->sc_queuelast = NULL;
690
691 return (xs);
692 }
693
694 void
695 ioprbs_copy_internal_data(xs, data, size)
696 struct scsi_xfer *xs;
697 u_int8_t *data;
698 size_t size;
699 {
700 size_t copy_cnt;
701
702 DPRINTF(("ioprbs_copy_internal_data "));
703
704 if (!xs->datalen)
705 printf("uio move not yet supported\n");
706 else {
707 copy_cnt = MIN(size, xs->datalen);
708 bcopy(data, xs->data, copy_cnt);
709 }
710 }
711
712
713 void
714 ioprbs_internal_cache_cmd(xs)
715 struct scsi_xfer *xs;
716 {
717 struct scsi_link *link = xs->sc_link;
718 struct ioprbs_softc *sc = link->adapter_softc;
719 u_int8_t target = link->target;
720 struct scsi_inquiry_data inq;
721 struct scsi_sense_data sd;
722 struct scsi_read_cap_data rcd;
723
724 DPRINTF(("ioprbs_internal_cache_cmd "));
725
726 xs->error = XS_NOERROR;
727
728 if (target > 0 || link->lun != 0) {
729 xs->error = XS_DRIVER_STUFFUP;
730 return;
731 }
732
733 switch (xs->cmd->opcode) {
734 case TEST_UNIT_READY:
735 case START_STOP:
736 #if 0
737 case VERIFY:
738 #endif
739 DPRINTF(("opc %d tgt %d ", xs->cmd->opcode, target));
740 break;
741
742 case REQUEST_SENSE:
743 DPRINTF(("REQUEST SENSE tgt %d ", target));
744 bzero(&sd, sizeof sd);
745 sd.error_code = 0x70;
746 sd.segment = 0;
747 sd.flags = SKEY_NO_SENSE;
748 bzero(sd.info, sizeof sd.info);
749 sd.extra_len = 0;
750 ioprbs_copy_internal_data(xs, (u_int8_t *)&sd, sizeof sd);
751 break;
752
753 case INQUIRY:
754 DPRINTF(("INQUIRY tgt %d", target));
755 bzero(&inq, sizeof inq);
756
757 inq.device = T_DIRECT;
758 inq.dev_qual2 = 0;
759 inq.version = 2;
760 inq.response_format = 2;
761 inq.additional_length = 32;
762 strlcpy(inq.vendor, "I2O", sizeof inq.vendor);
763 snprintf(inq.product, sizeof inq.product, "Container #%02d",
764 target);
765 strlcpy(inq.revision, " ", sizeof inq.revision);
766 ioprbs_copy_internal_data(xs, (u_int8_t *)&inq, sizeof inq);
767 break;
768
769 case READ_CAPACITY:
770 DPRINTF(("READ CAPACITY tgt %d ", target));
771 bzero(&rcd, sizeof rcd);
772 _lto4b(sc->sc_secperunit - 1, rcd.addr);
773 _lto4b(IOPRBS_BLOCK_SIZE, rcd.length);
774 ioprbs_copy_internal_data(xs, (u_int8_t *)&rcd, sizeof rcd);
775 break;
776
777 default:
778 DPRINTF(("unsupported scsi command %#x tgt %d ",
779 xs->cmd->opcode, target));
780 xs->error = XS_DRIVER_STUFFUP;
781 return;
782 }
783
784 xs->error = XS_NOERROR;
785 }
786
787 struct ioprbs_ccb *
788 ioprbs_get_ccb(sc, flags)
789 struct ioprbs_softc *sc;
790 int flags;
791 {
792 struct ioprbs_ccb *ccb;
793 ioprbs_lock_t lock;
794
795 DPRINTF(("ioprbs_get_ccb(%p, 0x%x) ", sc, flags));
796
797 lock = IOPRBS_LOCK(sc);
798
799 for (;;) {
800 ccb = TAILQ_FIRST(&sc->sc_free_ccb);
801 if (ccb != NULL)
802 break;
803 if (flags & SCSI_NOSLEEP)
804 goto bail_out;
805 tsleep(&sc->sc_free_ccb, PRIBIO, "ioprbs_ccb", 0);
806 }
807
808 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, ic_chain);
809
810
811 ccb->ic_flags = 0;
812
813 bail_out:
814 IOPRBS_UNLOCK(sc, lock);
815 return (ccb);
816 }
817
818 void
819 ioprbs_free_ccb(sc, ccb)
820 struct ioprbs_softc *sc;
821 struct ioprbs_ccb *ccb;
822 {
823 ioprbs_lock_t lock;
824
825 DPRINTF(("ioprbs_free_ccb(%p, %p) ", sc, ccb));
826
827 lock = IOPRBS_LOCK(sc);
828
829 TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, ic_chain);
830
831
832 if (TAILQ_NEXT(ccb, ic_chain) == NULL)
833 wakeup(&sc->sc_free_ccb);
834
835 IOPRBS_UNLOCK(sc, lock);
836 }
837
838 void
839 ioprbs_enqueue_ccb(sc, ccb)
840 struct ioprbs_softc *sc;
841 struct ioprbs_ccb *ccb;
842 {
843 DPRINTF(("ioprbs_enqueue_ccb(%p, %p) ", sc, ccb));
844
845 timeout_set(&ccb->ic_xs->stimeout, ioprbs_timeout, ccb);
846 TAILQ_INSERT_TAIL(&sc->sc_ccbq, ccb, ic_chain);
847 ioprbs_start_ccbs(sc);
848 }
849
850 void
851 ioprbs_start_ccbs(sc)
852 struct ioprbs_softc *sc;
853 {
854 struct ioprbs_ccb *ccb;
855 struct scsi_xfer *xs;
856
857 DPRINTF(("ioprbs_start_ccbs(%p) ", sc));
858
859 while ((ccb = TAILQ_FIRST(&sc->sc_ccbq)) != NULL) {
860
861 xs = ccb->ic_xs;
862 if (ccb->ic_flags & IOPRBS_ICF_WATCHDOG)
863 timeout_del(&xs->stimeout);
864
865 if (ioprbs_exec_ccb(ccb) == 0) {
866 ccb->ic_flags |= IOPRBS_ICF_WATCHDOG;
867 timeout_set(&ccb->ic_xs->stimeout, ioprbs_watchdog,
868 ccb);
869 timeout_add(&xs->stimeout,
870 (IOPRBS_WATCH_TIMEOUT * hz) / 1000);
871 break;
872 }
873 TAILQ_REMOVE(&sc->sc_ccbq, ccb, ic_chain);
874
875 if ((xs->flags & SCSI_POLL) == 0) {
876 timeout_set(&ccb->ic_xs->stimeout, ioprbs_timeout,
877 ccb);
878 timeout_add(&xs->stimeout,
879 (ccb->ic_timeout * hz) / 1000);
880 }
881 }
882 }
883
884 int
885 ioprbs_exec_ccb(ccb)
886 struct ioprbs_ccb *ccb;
887 {
888 struct scsi_xfer *xs = ccb->ic_xs;
889
890 DPRINTF(("ioprbs_exec_ccb(%p, %p) ", xs, ccb));
891
892 ioprbs_start(ccb);
893
894 xs->error = XS_NOERROR;
895 xs->resid = 0;
896 return (1);
897 }
898
899
900
901
902
903 int
904 ioprbs_start(struct ioprbs_ccb *ccb)
905 {
906 struct scsi_xfer *xs = ccb->ic_xs;
907 struct scsi_link *link = xs->sc_link;
908 struct ioprbs_softc *sc = link->adapter_softc;
909 #ifdef I2ODEBUG
910 u_int8_t target = link->target;
911 #endif
912 struct iop_msg *im;
913 struct iop_softc *iop = (struct iop_softc *)sc->sc_dv.dv_parent;
914 struct i2o_rbs_block_read *mf;
915 u_int rv, flags = 0, mode = I2O_RBS_BLOCK_READ;
916 u_int64_t ba;
917 u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
918
919 im = iop_msg_alloc(iop, &sc->sc_ii, 0);
920 im->im_dvcontext = ccb;
921
922 switch (xs->cmd->opcode) {
923 case PREVENT_ALLOW:
924 case SYNCHRONIZE_CACHE:
925 if (xs->cmd->opcode == PREVENT_ALLOW) {
926
927 } else {
928 DPRINTF(("SYNCHRONIZE CACHE tgt %d ", target));
929 }
930 break;
931
932 case WRITE_COMMAND:
933 case WRITE_BIG:
934 flags = I2O_RBS_BLOCK_WRITE_CACHE_WB;
935 mode = I2O_RBS_BLOCK_WRITE;
936
937
938 case READ_COMMAND:
939 case READ_BIG:
940 ba = (u_int64_t)ccb->ic_blockno * DEV_BSIZE;
941
942
943
944
945
946
947 mf = (struct i2o_rbs_block_read *)mb;
948 mf->msgflags = I2O_MSGFLAGS(i2o_rbs_block_read);
949 mf->msgfunc = I2O_MSGFUNC(sc->sc_ii.ii_tid, mode);
950 mf->msgictx = sc->sc_ii.ii_ictx;
951 mf->msgtctx = im->im_tctx;
952 mf->flags = flags | (1 << 16);
953 mf->datasize = ccb->ic_blockcnt * DEV_BSIZE;
954 mf->lowoffset = (u_int32_t)ba;
955 mf->highoffset = (u_int32_t)(ba >> 32);
956
957
958 rv = iop_msg_map_bio(iop, im, mb, xs->data,
959 ccb->ic_blockcnt * DEV_BSIZE, mode == I2O_RBS_BLOCK_WRITE);
960 if (rv == 0) {
961 if ((rv = iop_msg_post(iop, im, mb, 0)) != 0) {
962 iop_msg_unmap(iop, im);
963 iop_msg_free(iop, im);
964 }
965 }
966 break;
967 }
968 return (0);
969 }
970
971 void
972 ioprbs_timeout(arg)
973 void *arg;
974 {
975 struct ioprbs_ccb *ccb = arg;
976 struct scsi_link *link = ccb->ic_xs->sc_link;
977 struct ioprbs_softc *sc = link->adapter_softc;
978 ioprbs_lock_t lock;
979
980 sc_print_addr(link);
981 printf("timed out\n");
982
983
984
985 ccb->ic_xs->error = XS_TIMEOUT;
986 lock = IOPRBS_LOCK(sc);
987 ioprbs_enqueue_ccb(sc, ccb);
988 IOPRBS_UNLOCK(sc, lock);
989 }
990
991 void
992 ioprbs_watchdog(arg)
993 void *arg;
994 {
995 struct ioprbs_ccb *ccb = arg;
996 struct scsi_link *link = ccb->ic_xs->sc_link;
997 struct ioprbs_softc *sc = link->adapter_softc;
998 ioprbs_lock_t lock;
999
1000 lock = IOPRBS_LOCK(sc);
1001 ccb->ic_flags &= ~IOPRBS_ICF_WATCHDOG;
1002 ioprbs_start_ccbs(sc);
1003 IOPRBS_UNLOCK(sc, lock);
1004 }