This source file includes following definitions.
- ahc_attach
- ahc_platform_intr
- ahc_done
- ahc_minphys
- ahc_action
- ahc_execute_scb
- ahc_poll
- ahc_setup_data
- ahc_timeout
- ahc_platform_set_tags
- ahc_platform_alloc
- ahc_platform_free
- ahc_softc_comp
- ahc_send_async
- ahc_adapter_req_set_xfer_mode
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 #include <sys/cdefs.h>
44
45
46 #include <dev/ic/aic7xxx_openbsd.h>
47 #include <dev/ic/aic7xxx_inline.h>
48
49 #ifndef AHC_TMODE_ENABLE
50 #define AHC_TMODE_ENABLE 0
51 #endif
52
53
54 int ahc_action(struct scsi_xfer *);
55 int ahc_execute_scb(void *, bus_dma_segment_t *, int);
56 int ahc_poll(struct ahc_softc *, int);
57 int ahc_setup_data(struct ahc_softc *, struct scsi_xfer *, struct scb *);
58
59 void ahc_minphys(struct buf *);
60 void ahc_adapter_req_set_xfer_mode(struct ahc_softc *, struct scb *);
61
62
63 struct cfdriver ahc_cd = {
64 NULL, "ahc", DV_DULL
65 };
66
67 static struct scsi_adapter ahc_switch =
68 {
69 ahc_action,
70 ahc_minphys,
71 0,
72 0,
73 };
74
75
76 static struct scsi_device ahc_dev =
77 {
78 NULL,
79 NULL,
80 NULL,
81 NULL,
82 };
83
84
85
86
87 int
88 ahc_attach(struct ahc_softc *ahc)
89 {
90 struct scsibus_attach_args saa;
91 int s;
92
93 s = splbio();
94
95
96
97
98 ahc->sc_channel.adapter_target = ahc->our_id;
99 if (ahc->features & AHC_WIDE)
100 ahc->sc_channel.adapter_buswidth = 16;
101 ahc->sc_channel.adapter_softc = ahc;
102 ahc->sc_channel.adapter = &ahc_switch;
103 ahc->sc_channel.openings = 16;
104 ahc->sc_channel.device = &ahc_dev;
105
106 if (ahc->features & AHC_TWIN) {
107
108 ahc->sc_channel_b = ahc->sc_channel;
109 ahc->sc_channel_b.adapter_target = ahc->our_id_b;
110 }
111
112 #ifndef DEBUG
113 if (bootverbose) {
114 char ahc_info[256];
115 ahc_controller_info(ahc, ahc_info, sizeof ahc_info);
116 printf("%s: %s\n", ahc->sc_dev.dv_xname, ahc_info);
117 }
118 #endif
119
120 ahc_intr_enable(ahc, TRUE);
121
122 if (ahc->flags & AHC_RESET_BUS_A)
123 ahc_reset_channel(ahc, 'A', TRUE);
124 if ((ahc->features & AHC_TWIN) && ahc->flags & AHC_RESET_BUS_B)
125 ahc_reset_channel(ahc, 'B', TRUE);
126
127 bzero(&saa, sizeof(saa));
128 if ((ahc->flags & AHC_PRIMARY_CHANNEL) == 0) {
129 saa.saa_sc_link = &ahc->sc_channel;
130 ahc->sc_child = config_found((void *)&ahc->sc_dev,
131 &saa, scsiprint);
132 if (ahc->features & AHC_TWIN) {
133 saa.saa_sc_link = &ahc->sc_channel_b;
134 ahc->sc_child_b = config_found((void *)&ahc->sc_dev,
135 &saa, scsiprint);
136 }
137 } else {
138 if (ahc->features & AHC_TWIN) {
139 saa.saa_sc_link = &ahc->sc_channel_b;
140 ahc->sc_child = config_found((void *)&ahc->sc_dev,
141 &saa, scsiprint);
142 }
143 saa.saa_sc_link = &ahc->sc_channel;
144 ahc->sc_child_b = config_found((void *)&ahc->sc_dev,
145 &saa, scsiprint);
146 }
147
148 splx(s);
149 return (1);
150 }
151
152
153
154
155 int
156 ahc_platform_intr(void *arg)
157 {
158 struct ahc_softc *ahc = (struct ahc_softc *)arg;
159
160 bus_dmamap_sync(ahc->parent_dmat, ahc->scb_data->hscb_dmamap,
161 0, ahc->scb_data->hscb_dmamap->dm_mapsize,
162 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
163
164 return ahc_intr(ahc);
165 }
166
167
168
169
170
171
172 void
173 ahc_done(struct ahc_softc *ahc, struct scb *scb)
174 {
175 struct scsi_xfer *xs = scb->xs;
176 int s;
177
178 bus_dmamap_sync(ahc->parent_dmat, ahc->scb_data->hscb_dmamap,
179 0, ahc->scb_data->hscb_dmamap->dm_mapsize,
180 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
181
182 LIST_REMOVE(scb, pending_links);
183 if ((scb->flags & SCB_UNTAGGEDQ) != 0) {
184 struct scb_tailq *untagged_q;
185 int target_offset;
186
187 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
188 untagged_q = &ahc->untagged_queues[target_offset];
189 TAILQ_REMOVE(untagged_q, scb, links.tqe);
190 scb->flags &= ~SCB_UNTAGGEDQ;
191 ahc_run_untagged_queue(ahc, untagged_q);
192 }
193
194 timeout_del(&xs->stimeout);
195
196 if (xs->datalen) {
197 int op;
198
199 if ((xs->flags & SCSI_DATA_IN) != 0)
200 op = BUS_DMASYNC_POSTREAD;
201 else
202 op = BUS_DMASYNC_POSTWRITE;
203 bus_dmamap_sync(ahc->parent_dmat, scb->dmamap, 0,
204 scb->dmamap->dm_mapsize, op);
205 bus_dmamap_unload(ahc->parent_dmat, scb->dmamap);
206 }
207
208
209 switch (xs->error) {
210 case CAM_SCSI_STATUS_ERROR:
211 case CAM_REQ_INPROG:
212 case CAM_REQ_CMP:
213 switch (xs->status) {
214 case SCSI_TASKSET_FULL:
215
216
217
218
219
220
221 xs->error = XS_TIMEOUT;
222 xs->retries++;
223 break;
224 case SCSI_BUSY:
225 xs->error = XS_BUSY;
226 break;
227 case SCSI_CHECK:
228 case SCSI_TERMINATED:
229 if ((scb->flags & SCB_SENSE) == 0) {
230
231 xs->error = XS_DRIVER_STUFFUP;
232 } else
233 xs->error = XS_NOERROR;
234 break;
235 default:
236 xs->error = XS_NOERROR;
237 break;
238 }
239 break;
240 case CAM_BUSY:
241 xs->error = XS_BUSY;
242 break;
243 case CAM_CMD_TIMEOUT:
244 xs->error = XS_TIMEOUT;
245 break;
246 case CAM_BDR_SENT:
247 case CAM_SCSI_BUS_RESET:
248 xs->error = XS_RESET;
249 break;
250 case CAM_REQUEUE_REQ:
251 xs->error = XS_TIMEOUT;
252 xs->retries++;
253 break;
254 case CAM_SEL_TIMEOUT:
255 xs->error = XS_SELTIMEOUT;
256 break;
257 default:
258 xs->error = XS_DRIVER_STUFFUP;
259 break;
260 }
261
262
263 if (xs->error != XS_NOERROR) {
264
265 } else if ((scb->flags & SCB_SENSE) != 0) {
266
267
268
269
270
271
272
273
274
275
276 memset(&xs->sense, 0, sizeof(struct scsi_sense_data));
277 memcpy(&xs->sense, ahc_get_sense_buf(ahc, scb),
278 aic_le32toh(scb->sg_list->len) & AHC_SG_LEN_MASK);
279 xs->error = XS_SENSE;
280 }
281
282 s = splbio();
283 ahc_free_scb(ahc, scb);
284 splx(s);
285
286 xs->flags |= ITSDONE;
287 scsi_done(xs);
288 }
289
290 void
291 ahc_minphys(bp)
292 struct buf *bp;
293 {
294
295
296
297
298
299
300
301 if (bp->b_bcount > ((AHC_NSEG - 1) * PAGE_SIZE)) {
302 bp->b_bcount = ((AHC_NSEG - 1) * PAGE_SIZE);
303 }
304 minphys(bp);
305 }
306
307 int32_t
308 ahc_action(struct scsi_xfer *xs)
309 {
310 struct ahc_softc *ahc;
311 struct scb *scb;
312 struct hardware_scb *hscb;
313 u_int target_id;
314 u_int our_id;
315 int s;
316 int dontqueue = 0;
317
318 SC_DEBUG(xs->sc_link, SDEV_DB3, ("ahc_action\n"));
319 ahc = (struct ahc_softc *)xs->sc_link->adapter_softc;
320
321
322 dontqueue = xs->flags & SCSI_POLL;
323
324 target_id = xs->sc_link->target;
325 our_id = SCSI_SCSI_ID(ahc, xs->sc_link);
326
327
328
329
330 s = splbio();
331 if ((scb = ahc_get_scb(ahc)) == NULL) {
332 splx(s);
333 return (TRY_AGAIN_LATER);
334 }
335 splx(s);
336
337 hscb = scb->hscb;
338
339 SC_DEBUG(xs->sc_link, SDEV_DB3, ("start scb(%p)\n", scb));
340 scb->xs = xs;
341 timeout_set(&xs->stimeout, ahc_timeout, scb);
342
343
344
345
346 hscb->control = 0;
347 hscb->scsiid = BUILD_SCSIID(ahc, xs->sc_link, target_id, our_id);
348 hscb->lun = xs->sc_link->lun;
349 if (xs->xs_control & XS_CTL_RESET) {
350 hscb->cdb_len = 0;
351 scb->flags |= SCB_DEVICE_RESET;
352 hscb->control |= MK_MESSAGE;
353 return (ahc_execute_scb(scb, NULL, 0));
354 }
355
356 return (ahc_setup_data(ahc, xs, scb));
357 }
358
359 int
360 ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments)
361 {
362 struct scb *scb;
363 struct scsi_xfer *xs;
364 struct ahc_softc *ahc;
365 struct ahc_initiator_tinfo *tinfo;
366 struct ahc_tmode_tstate *tstate;
367
368 u_int mask;
369 int s;
370
371 scb = (struct scb *)arg;
372 xs = scb->xs;
373 xs->error = CAM_REQ_INPROG;
374 xs->status = 0;
375 ahc = (struct ahc_softc *)xs->sc_link->adapter_softc;
376
377 if (nsegments != 0) {
378 struct ahc_dma_seg *sg;
379 bus_dma_segment_t *end_seg;
380 int op;
381
382 end_seg = dm_segs + nsegments;
383
384
385 sg = scb->sg_list;
386 while (dm_segs < end_seg) {
387 uint32_t len;
388
389 sg->addr = aic_htole32(dm_segs->ds_addr);
390 len = dm_segs->ds_len
391 | ((dm_segs->ds_addr >> 8) & 0x7F000000);
392 sg->len = aic_htole32(len);
393 sg++;
394 dm_segs++;
395 }
396
397
398
399
400
401
402
403 scb->hscb->sgptr = aic_htole32(scb->sg_list_phys|SG_FULL_RESID);
404
405 if ((xs->flags & SCSI_DATA_IN) != 0)
406 op = BUS_DMASYNC_PREREAD;
407 else
408 op = BUS_DMASYNC_PREWRITE;
409
410 bus_dmamap_sync(ahc->parent_dmat, scb->dmamap, 0,
411 scb->dmamap->dm_mapsize, op);
412
413 sg--;
414 sg->len |= aic_htole32(AHC_DMA_LAST_SEG);
415
416 bus_dmamap_sync(ahc->parent_dmat, scb->sg_map->sg_dmamap,
417 0, scb->sg_map->sg_dmamap->dm_mapsize,
418 BUS_DMASYNC_PREWRITE);
419
420
421 scb->hscb->dataptr = scb->sg_list->addr;
422 scb->hscb->datacnt = scb->sg_list->len;
423 } else {
424 scb->hscb->sgptr = aic_htole32(SG_LIST_NULL);
425 scb->hscb->dataptr = 0;
426 scb->hscb->datacnt = 0;
427 }
428
429 scb->sg_count = nsegments;
430
431 s = splbio();
432
433
434
435
436
437 if (xs->flags & ITSDONE) {
438 if (nsegments != 0)
439 bus_dmamap_unload(ahc->parent_dmat, scb->dmamap);
440
441 ahc_free_scb(ahc, scb);
442 splx(s);
443 return (COMPLETE);
444 }
445
446 tinfo = ahc_fetch_transinfo(ahc, SCSIID_CHANNEL(ahc, scb->hscb->scsiid),
447 SCSIID_OUR_ID(scb->hscb->scsiid),
448 SCSIID_TARGET(ahc, scb->hscb->scsiid),
449 &tstate);
450
451 mask = SCB_GET_TARGET_MASK(ahc, scb);
452 scb->hscb->scsirate = tinfo->scsirate;
453 scb->hscb->scsioffset = tinfo->curr.offset;
454
455 if ((tstate->ultraenb & mask) != 0)
456 scb->hscb->control |= ULTRAENB;
457
458 if ((tstate->discenable & mask) != 0)
459 scb->hscb->control |= DISCENB;
460
461 if ((tstate->auto_negotiate & mask) != 0) {
462 scb->flags |= SCB_AUTO_NEGOTIATE;
463 scb->hscb->control |= MK_MESSAGE;
464 }
465
466 if ((tstate->tagenable & mask) != 0)
467 scb->hscb->control |= TAG_ENB;
468
469 bus_dmamap_sync(ahc->parent_dmat, ahc->scb_data->hscb_dmamap,
470 0, ahc->scb_data->hscb_dmamap->dm_mapsize,
471 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
472
473 LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links);
474
475 if (!(xs->flags & SCSI_POLL))
476 timeout_add(&xs->stimeout, (xs->timeout * hz) / 1000);
477
478
479
480
481
482
483
484
485
486
487
488 if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0
489 && (ahc->flags & AHC_SCB_BTT) == 0) {
490 struct scb_tailq *untagged_q;
491 int target_offset;
492
493 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
494 untagged_q = &(ahc->untagged_queues[target_offset]);
495 TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
496 scb->flags |= SCB_UNTAGGEDQ;
497 if (TAILQ_FIRST(untagged_q) != scb) {
498 if (xs->flags & SCSI_POLL)
499 goto poll;
500 else {
501 splx(s);
502 return (SUCCESSFULLY_QUEUED);
503 }
504 }
505 }
506 scb->flags |= SCB_ACTIVE;
507
508 if ((scb->flags & SCB_TARGET_IMMEDIATE) != 0) {
509
510 ahc->scb_data->scbindex[scb->hscb->tag] = scb;
511 ahc_pause(ahc);
512 if ((ahc->flags & AHC_PAGESCBS) == 0)
513 ahc_outb(ahc, SCBPTR, scb->hscb->tag);
514 ahc_outb(ahc, TARG_IMMEDIATE_SCB, scb->hscb->tag);
515 ahc_unpause(ahc);
516 } else {
517 ahc_queue_scb(ahc, scb);
518 }
519
520 if (!(xs->flags & SCSI_POLL)) {
521 if (ahc->inited_target[xs->sc_link->target] == 0) {
522 struct ahc_devinfo devinfo;
523
524 ahc_adapter_req_set_xfer_mode(ahc, scb);
525 ahc_scb_devinfo(ahc, &devinfo, scb);
526 ahc_update_neg_request(ahc, &devinfo, tstate, tinfo,
527 AHC_NEG_IF_NON_ASYNC);
528
529 ahc->inited_target[xs->sc_link->target] = 1;
530 }
531 splx(s);
532 return (SUCCESSFULLY_QUEUED);
533 }
534
535
536
537
538 poll:
539 SC_DEBUG(xs->sc_link, SDEV_DB3, ("cmd_poll\n"));
540
541 do {
542 if (ahc_poll(ahc, xs->timeout)) {
543 if (!(xs->flags & SCSI_SILENT))
544 printf("cmd fail\n");
545 ahc_timeout(scb);
546 break;
547 }
548 } while (!(xs->flags & ITSDONE));
549
550 splx(s);
551 return (COMPLETE);
552 }
553
554 int
555 ahc_poll(struct ahc_softc *ahc, int wait)
556 {
557 while (--wait) {
558 DELAY(1000);
559 if (ahc_inb(ahc, INTSTAT) & INT_PEND)
560 break;
561 }
562
563 if (wait == 0) {
564 printf("%s: board is not responding\n", ahc_name(ahc));
565 return (EIO);
566 }
567
568 ahc_intr((void *)ahc);
569 return (0);
570 }
571
572 int
573 ahc_setup_data(struct ahc_softc *ahc, struct scsi_xfer *xs,
574 struct scb *scb)
575 {
576 struct hardware_scb *hscb;
577 int s;
578
579 hscb = scb->hscb;
580 xs->resid = xs->status = 0;
581 xs->error = CAM_REQ_INPROG;
582
583 hscb->cdb_len = xs->cmdlen;
584 if (hscb->cdb_len > sizeof(hscb->cdb32)) {
585 s = splbio();
586 ahc_free_scb(ahc, scb);
587 splx(s);
588 xs->error = XS_DRIVER_STUFFUP;
589 xs->flags |= ITSDONE;
590 scsi_done(xs);
591 return (COMPLETE);
592 }
593
594 if (hscb->cdb_len > 12) {
595 memcpy(hscb->cdb32, xs->cmd, hscb->cdb_len);
596 scb->flags |= SCB_CDB32_PTR;
597 } else {
598 memcpy(hscb->shared_data.cdb, xs->cmd, hscb->cdb_len);
599 }
600
601
602 if (xs->datalen) {
603 int error;
604
605 error = bus_dmamap_load(ahc->parent_dmat,
606 scb->dmamap, xs->data,
607 xs->datalen, NULL,
608 (xs->flags & SCSI_NOSLEEP) ?
609 BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
610 if (error) {
611 #ifdef AHC_DEBUG
612 printf("%s: in ahc_setup_data(): bus_dmamap_load() "
613 "= %d\n",
614 ahc_name(ahc), error);
615 #endif
616 s = splbio();
617 ahc_free_scb(ahc, scb);
618 splx(s);
619 return (TRY_AGAIN_LATER);
620 }
621 error = ahc_execute_scb(scb,
622 scb->dmamap->dm_segs,
623 scb->dmamap->dm_nsegs);
624 return error;
625 } else {
626 return ahc_execute_scb(scb, NULL, 0);
627 }
628 }
629
630 void
631 ahc_timeout(void *arg)
632 {
633 struct scb *scb, *list_scb;
634 struct ahc_softc *ahc;
635 int s;
636 int found;
637 char channel;
638
639 scb = (struct scb *)arg;
640 ahc = (struct ahc_softc *)scb->xs->sc_link->adapter_softc;
641
642 s = splbio();
643
644 #ifdef AHC_DEBUG
645 printf("%s: SCB %d timed out\n", ahc_name(ahc), scb->hscb->tag);
646 ahc_dump_card_state(ahc);
647 #endif
648
649 ahc_pause(ahc);
650
651 if (scb->flags & SCB_ACTIVE) {
652 channel = SCB_GET_CHANNEL(ahc, scb);
653 ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
654
655
656
657
658
659 LIST_FOREACH(list_scb, &ahc->pending_scbs, pending_links) {
660 if (list_scb->xs)
661 timeout_del(&list_scb->xs->stimeout);
662 }
663 found = ahc_reset_channel(ahc, channel, TRUE);
664 #ifdef AHC_DEBUG
665 printf("%s: Issued Channel %c Bus Reset %d SCBs aborted\n",
666 ahc_name(ahc), channel, found);
667 #endif
668 }
669
670 ahc_unpause(ahc);
671 splx(s);
672 }
673
674
675 void
676 ahc_platform_set_tags(struct ahc_softc *ahc,
677 struct ahc_devinfo *devinfo, int alg)
678 {
679 struct ahc_tmode_tstate *tstate;
680
681 ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
682 devinfo->target, &tstate);
683
684
685
686 switch (alg) {
687 case AHC_QUEUE_BASIC:
688 case AHC_QUEUE_TAGGED:
689 tstate->tagenable |= devinfo->target_mask;
690 break;
691 case AHC_QUEUE_NONE:
692 tstate->tagenable &= ~devinfo->target_mask;
693 break;
694 }
695 }
696
697 int
698 ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
699 {
700 if (sizeof(struct ahc_platform_data) > 0) {
701 ahc->platform_data = malloc(sizeof(struct ahc_platform_data),
702 M_DEVBUF, M_NOWAIT);
703 if (ahc->platform_data == NULL)
704 return (ENOMEM);
705 bzero(ahc->platform_data, sizeof(struct ahc_platform_data));
706 }
707
708 return (0);
709 }
710
711 void
712 ahc_platform_free(struct ahc_softc *ahc)
713 {
714 if (sizeof(struct ahc_platform_data) > 0)
715 free(ahc->platform_data, M_DEVBUF);
716 }
717
718 int
719 ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc)
720 {
721 return (0);
722 }
723
724 void
725 ahc_send_async(struct ahc_softc *ahc, char channel, u_int target, u_int lun,
726 ac_code code, void *opt_arg)
727 {
728
729 }
730
731 void
732 ahc_adapter_req_set_xfer_mode(struct ahc_softc *ahc, struct scb *scb)
733 {
734 struct ahc_initiator_tinfo *tinfo;
735 struct ahc_tmode_tstate *tstate;
736 struct ahc_syncrate *syncrate;
737 struct ahc_devinfo devinfo;
738 u_int16_t quirks;
739 u_int width, ppr_options, period, offset;
740 int s;
741
742 s = splbio();
743
744 ahc_scb_devinfo(ahc, &devinfo, scb);
745 quirks = scb->xs->sc_link->quirks;
746 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
747 devinfo.our_scsiid, devinfo.target, &tstate);
748
749 tstate->discenable |= (ahc->user_discenable & devinfo.target_mask);
750
751 if (quirks & SDEV_NOTAGS)
752 tstate->tagenable &= ~devinfo.target_mask;
753 else if (ahc->user_tagenable & devinfo.target_mask)
754 tstate->tagenable |= devinfo.target_mask;
755
756 if (quirks & SDEV_NOWIDE)
757 width = MSG_EXT_WDTR_BUS_8_BIT;
758 else
759 width = MSG_EXT_WDTR_BUS_16_BIT;
760
761 ahc_validate_width(ahc, NULL, &width, ROLE_UNKNOWN);
762 if (width > tinfo->user.width)
763 width = tinfo->user.width;
764 ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE);
765
766 if (quirks & SDEV_NOSYNC) {
767 period = 0;
768 offset = 0;
769 } else {
770 period = tinfo->user.period;
771 offset = tinfo->user.offset;
772 }
773
774
775 ppr_options = tinfo->user.ppr_options;
776
777 if (width < MSG_EXT_WDTR_BUS_16_BIT)
778 ppr_options = 0;
779
780 if ((tstate->discenable & devinfo.target_mask) == 0 ||
781 (tstate->tagenable & devinfo.target_mask) == 0)
782 ppr_options &= ~MSG_EXT_PPR_PROT_IUS;
783
784 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
785 AHC_SYNCRATE_MAX);
786 ahc_validate_offset(ahc, NULL, syncrate, &offset, width,
787 ROLE_UNKNOWN);
788
789 if (offset == 0) {
790 period = 0;
791 ppr_options = 0;
792 }
793
794 if (ppr_options != 0 && tinfo->user.transport_version >= 3) {
795 tinfo->goal.transport_version = tinfo->user.transport_version;
796 tinfo->curr.transport_version = tinfo->user.transport_version;
797 }
798
799 ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset, ppr_options,
800 AHC_TRANS_GOAL, FALSE);
801
802 splx(s);
803 }