1 /* $NetBSD: oosiop.c,v 1.11 2007/10/19 11:59:58 ad Exp $ */
4 * Copyright (c) 2001 Shuichiro URATA. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * NCR53C700 SCSI I/O processor (OOSIOP) driver
33 * - More better error handling.
34 * - Implement tagged queuing.
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: oosiop.c,v 1.11 2007/10/19 11:59:58 ad Exp $");
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/callout.h>
43 #include <sys/kernel.h>
44 #include <sys/device.h>
46 #include <sys/malloc.h>
47 #include <sys/queue.h>
49 #include <uvm/uvm_extern.h>
51 #include <dev/scsipi/scsi_all.h>
52 #include <dev/scsipi/scsipi_all.h>
53 #include <dev/scsipi/scsiconf.h>
54 #include <dev/scsipi/scsi_message.h>
59 #include <dev/ic/oosiopreg.h>
60 #include <dev/ic/oosiopvar.h>
61 #include <dev/microcode/siop/oosiop.out>
63 static int oosiop_alloc_cb(struct oosiop_softc
*, int);
65 static inline void oosiop_relocate_io(struct oosiop_softc
*, bus_addr_t
);
66 static inline void oosiop_relocate_tc(struct oosiop_softc
*, bus_addr_t
);
67 static inline void oosiop_fixup_select(struct oosiop_softc
*, bus_addr_t
,
69 static inline void oosiop_fixup_jump(struct oosiop_softc
*, bus_addr_t
,
71 static inline void oosiop_fixup_move(struct oosiop_softc
*, bus_addr_t
,
72 bus_size_t
, bus_addr_t
);
74 static void oosiop_load_script(struct oosiop_softc
*);
75 static void oosiop_setup_sgdma(struct oosiop_softc
*, struct oosiop_cb
*);
76 static void oosiop_setup_dma(struct oosiop_softc
*);
77 static void oosiop_flush_fifo(struct oosiop_softc
*);
78 static void oosiop_clear_fifo(struct oosiop_softc
*);
79 static void oosiop_phasemismatch(struct oosiop_softc
*);
80 static void oosiop_setup_syncxfer(struct oosiop_softc
*);
81 static void oosiop_set_syncparam(struct oosiop_softc
*, int, int, int);
82 static void oosiop_minphys(struct buf
*);
83 static void oosiop_scsipi_request(struct scsipi_channel
*,
84 scsipi_adapter_req_t
, void *);
85 static void oosiop_done(struct oosiop_softc
*, struct oosiop_cb
*);
86 static void oosiop_timeout(void *);
87 static void oosiop_reset(struct oosiop_softc
*);
88 static void oosiop_reset_bus(struct oosiop_softc
*);
89 static void oosiop_scriptintr(struct oosiop_softc
*);
90 static void oosiop_msgin(struct oosiop_softc
*, struct oosiop_cb
*);
92 /* Trap interrupt code for unexpected data I/O */
93 #define DATAIN_TRAP 0xdead0001
94 #define DATAOUT_TRAP 0xdead0002
96 /* Possible TP and SCF conbination */
101 {0, 1}, /* SCLK / 4.0 */
102 {1, 1}, /* SCLK / 5.0 */
103 {2, 1}, /* SCLK / 6.0 */
104 {3, 1}, /* SCLK / 7.0 */
105 {1, 2}, /* SCLK / 7.5 */
106 {4, 1}, /* SCLK / 8.0 */
107 {5, 1}, /* SCLK / 9.0 */
108 {6, 1}, /* SCLK / 10.0 */
109 {3, 2}, /* SCLK / 10.5 */
110 {7, 1}, /* SCLK / 11.0 */
111 {4, 2}, /* SCLK / 12.0 */
112 {5, 2}, /* SCLK / 13.5 */
113 {3, 3}, /* SCLK / 14.0 */
114 {6, 2}, /* SCLK / 15.0 */
115 {4, 3}, /* SCLK / 16.0 */
116 {7, 2}, /* SCLK / 16.5 */
117 {5, 3}, /* SCLK / 18.0 */
118 {6, 3}, /* SCLK / 20.0 */
119 {7, 3} /* SCLK / 22.0 */
121 #define NSYNCTBL (sizeof(synctbl) / sizeof(synctbl[0]))
123 #define oosiop_period(sc, tp, scf) \
124 (((1000000000 / (sc)->sc_freq) * (tp) * (scf)) / 40)
127 oosiop_attach(struct oosiop_softc
*sc
)
130 bus_dma_segment_t seg
;
131 struct oosiop_cb
*cb
;
135 * Allocate DMA-safe memory for the script and map it.
137 scrsize
= sizeof(oosiop_script
);
138 err
= bus_dmamem_alloc(sc
->sc_dmat
, scrsize
, PAGE_SIZE
, 0, &seg
, 1,
139 &nseg
, BUS_DMA_NOWAIT
);
141 aprint_error(": failed to allocate script memory, err=%d\n",
145 err
= bus_dmamem_map(sc
->sc_dmat
, &seg
, nseg
, scrsize
,
146 (void **)&sc
->sc_scr
, BUS_DMA_NOWAIT
| BUS_DMA_COHERENT
);
148 aprint_error(": failed to map script memory, err=%d\n", err
);
151 err
= bus_dmamap_create(sc
->sc_dmat
, scrsize
, 1, scrsize
, 0,
152 BUS_DMA_NOWAIT
, &sc
->sc_scrdma
);
154 aprint_error(": failed to create script map, err=%d\n", err
);
157 err
= bus_dmamap_load(sc
->sc_dmat
, sc
->sc_scrdma
, sc
->sc_scr
, scrsize
,
158 NULL
, BUS_DMA_NOWAIT
| BUS_DMA_WRITE
);
160 aprint_error(": failed to load script map, err=%d\n", err
);
163 sc
->sc_scrbase
= sc
->sc_scrdma
->dm_segs
[0].ds_addr
;
165 /* Initialize command block array */
166 TAILQ_INIT(&sc
->sc_free_cb
);
167 TAILQ_INIT(&sc
->sc_cbq
);
168 if (oosiop_alloc_cb(sc
, OOSIOP_NCB
) != 0)
171 /* Use first cb to reselection msgin buffer */
172 cb
= TAILQ_FIRST(&sc
->sc_free_cb
);
173 sc
->sc_reselbuf
= cb
->xferdma
->dm_segs
[0].ds_addr
+
174 offsetof(struct oosiop_xfer
, msgin
[0]);
176 for (i
= 0; i
< OOSIOP_NTGT
; i
++) {
177 sc
->sc_tgt
[i
].nexus
= NULL
;
178 sc
->sc_tgt
[i
].flags
= 0;
181 /* Setup asynchronous clock divisor parameters */
182 if (sc
->sc_freq
<= 25000000) {
184 sc
->sc_dcntl
= OOSIOP_DCNTL_CF_1
;
185 } else if (sc
->sc_freq
<= 37500000) {
187 sc
->sc_dcntl
= OOSIOP_DCNTL_CF_1_5
;
188 } else if (sc
->sc_freq
<= 50000000) {
190 sc
->sc_dcntl
= OOSIOP_DCNTL_CF_2
;
193 sc
->sc_dcntl
= OOSIOP_DCNTL_CF_3
;
196 if (sc
->sc_chip
== OOSIOP_700
)
197 sc
->sc_minperiod
= oosiop_period(sc
, 4, sc
->sc_ccf
);
199 sc
->sc_minperiod
= oosiop_period(sc
, 4, 10);
201 if (sc
->sc_minperiod
< 25)
202 sc
->sc_minperiod
= 25; /* limit to 10MB/s */
204 aprint_normal(": NCR53C700%s rev %d, %dMHz, SCSI ID %d\n",
205 sc
->sc_chip
== OOSIOP_700_66
? "-66" : "",
206 oosiop_read_1(sc
, OOSIOP_CTEST7
) >> 4,
207 sc
->sc_freq
/ 1000000, sc
->sc_id
);
212 oosiop_reset_bus(sc
);
215 * Start SCRIPTS processor
217 oosiop_load_script(sc
);
219 oosiop_write_4(sc
, OOSIOP_DSP
, sc
->sc_scrbase
+ Ent_wait_reselect
);
222 * Fill in the scsipi_adapter.
224 sc
->sc_adapter
.adapt_dev
= sc
->sc_dev
;
225 sc
->sc_adapter
.adapt_nchannels
= 1;
226 sc
->sc_adapter
.adapt_openings
= OOSIOP_NCB
;
227 sc
->sc_adapter
.adapt_max_periph
= 1;
228 sc
->sc_adapter
.adapt_ioctl
= NULL
;
229 sc
->sc_adapter
.adapt_minphys
= oosiop_minphys
;
230 sc
->sc_adapter
.adapt_request
= oosiop_scsipi_request
;
233 * Fill in the scsipi_channel.
235 sc
->sc_channel
.chan_adapter
= &sc
->sc_adapter
;
236 sc
->sc_channel
.chan_bustype
= &scsi_bustype
;
237 sc
->sc_channel
.chan_channel
= 0;
238 sc
->sc_channel
.chan_ntargets
= OOSIOP_NTGT
;
239 sc
->sc_channel
.chan_nluns
= 8;
240 sc
->sc_channel
.chan_id
= sc
->sc_id
;
243 * Now try to attach all the sub devices.
245 config_found(sc
->sc_dev
, &sc
->sc_channel
, scsiprint
);
249 oosiop_alloc_cb(struct oosiop_softc
*sc
, int ncb
)
251 struct oosiop_cb
*cb
;
252 struct oosiop_xfer
*xfer
;
254 bus_dma_segment_t seg
;
258 * Allocate oosiop_cb.
260 cb
= malloc(sizeof(struct oosiop_cb
) * ncb
, M_DEVBUF
, M_NOWAIT
|M_ZERO
);
262 printf(": failed to allocate cb memory\n");
267 * Allocate DMA-safe memory for the oosiop_xfer and map it.
269 xfersize
= sizeof(struct oosiop_xfer
) * ncb
;
270 err
= bus_dmamem_alloc(sc
->sc_dmat
, xfersize
, PAGE_SIZE
, 0, &seg
, 1,
271 &nseg
, BUS_DMA_NOWAIT
);
273 printf(": failed to allocate xfer block memory, err=%d\n", err
);
276 err
= bus_dmamem_map(sc
->sc_dmat
, &seg
, nseg
, xfersize
,
277 (void **)(void *)&xfer
, BUS_DMA_NOWAIT
| BUS_DMA_COHERENT
);
279 printf(": failed to map xfer block memory, err=%d\n", err
);
283 /* Initialize each command block */
284 for (i
= 0; i
< ncb
; i
++) {
285 err
= bus_dmamap_create(sc
->sc_dmat
, PAGE_SIZE
, 1, PAGE_SIZE
,
286 0, BUS_DMA_NOWAIT
, &cb
->cmddma
);
288 printf(": failed to create cmddma map, err=%d\n", err
);
291 err
= bus_dmamap_create(sc
->sc_dmat
, OOSIOP_MAX_XFER
,
292 OOSIOP_NSG
, OOSIOP_DBC_MAX
, 0, BUS_DMA_NOWAIT
,
295 printf(": failed to create datadma map, err=%d\n", err
);
299 err
= bus_dmamap_create(sc
->sc_dmat
,
300 sizeof(struct oosiop_xfer
), 1, sizeof(struct oosiop_xfer
),
301 0, BUS_DMA_NOWAIT
, &cb
->xferdma
);
303 printf(": failed to create xfer block map, err=%d\n",
307 err
= bus_dmamap_load(sc
->sc_dmat
, cb
->xferdma
, xfer
,
308 sizeof(struct oosiop_xfer
), NULL
, BUS_DMA_NOWAIT
);
310 printf(": failed to load xfer block, err=%d\n", err
);
317 TAILQ_INSERT_TAIL(&sc
->sc_free_cb
, cb
, chain
);
328 oosiop_relocate_io(struct oosiop_softc
*sc
, bus_addr_t addr
)
333 dcmd
= le32toh(sc
->sc_scr
[addr
/ 4 + 0]);
334 dsps
= le32toh(sc
->sc_scr
[addr
/ 4 + 1]);
336 /* convert relative to absolute */
337 if (dcmd
& 0x04000000) {
341 * sign extension isn't needed here because
342 * ncr53cxxx.c generates 32 bit dsps.
347 sc
->sc_scr
[addr
/ 4 + 0] = htole32(dcmd
);
351 sc
->sc_scr
[addr
/ 4 + 1] = htole32(dsps
+ sc
->sc_scrbase
);
355 oosiop_relocate_tc(struct oosiop_softc
*sc
, bus_addr_t addr
)
360 dcmd
= le32toh(sc
->sc_scr
[addr
/ 4 + 0]);
361 dsps
= le32toh(sc
->sc_scr
[addr
/ 4 + 1]);
363 /* convert relative to absolute */
364 if (dcmd
& 0x00800000) {
366 sc
->sc_scr
[addr
/ 4] = htole32(dcmd
);
369 * sign extension isn't needed here because
370 * ncr53cxxx.c generates 32 bit dsps.
378 sc
->sc_scr
[addr
/ 4 + 1] = htole32(dsps
+ sc
->sc_scrbase
);
382 oosiop_fixup_select(struct oosiop_softc
*sc
, bus_addr_t addr
, int id
)
386 dcmd
= le32toh(sc
->sc_scr
[addr
/ 4]);
388 dcmd
|= 0x00010000 << id
;
389 sc
->sc_scr
[addr
/ 4] = htole32(dcmd
);
393 oosiop_fixup_jump(struct oosiop_softc
*sc
, bus_addr_t addr
, bus_addr_t dst
)
396 sc
->sc_scr
[addr
/ 4 + 1] = htole32(dst
);
400 oosiop_fixup_move(struct oosiop_softc
*sc
, bus_addr_t addr
, bus_size_t dbc
,
405 dcmd
= le32toh(sc
->sc_scr
[addr
/ 4]);
407 dcmd
|= dbc
& 0x00ffffff;
408 sc
->sc_scr
[addr
/ 4 + 0] = htole32(dcmd
);
409 sc
->sc_scr
[addr
/ 4 + 1] = htole32(dsps
);
413 oosiop_load_script(struct oosiop_softc
*sc
)
418 for (i
= 0; i
< sizeof(oosiop_script
) / sizeof(oosiop_script
[0]); i
++)
419 sc
->sc_scr
[i
] = htole32(oosiop_script
[i
]);
421 /* relocate script */
422 for (i
= 0; i
< (sizeof(oosiop_script
) / 8); i
++) {
423 switch (oosiop_script
[i
* 2] >> 27) {
424 case 0x08: /* select */
425 case 0x0a: /* wait reselect */
426 oosiop_relocate_io(sc
, i
* 8);
428 case 0x10: /* jump */
429 case 0x11: /* call */
430 oosiop_relocate_tc(sc
, i
* 8);
435 oosiop_fixup_move(sc
, Ent_p_resel_msgin_move
, 1, sc
->sc_reselbuf
);
436 OOSIOP_SCRIPT_SYNC(sc
, BUS_DMASYNC_PREWRITE
);
440 oosiop_setup_sgdma(struct oosiop_softc
*sc
, struct oosiop_cb
*cb
)
442 int i
, n
, off
, control
;
443 struct oosiop_xfer
*xfer
;
445 OOSIOP_XFERSCR_SYNC(sc
, cb
,
446 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
450 control
= cb
->xs
->xs_control
;
452 if (control
& (XS_CTL_DATA_IN
| XS_CTL_DATA_OUT
)) {
453 /* Find start segment */
454 for (i
= 0; i
< cb
->datadma
->dm_nsegs
; i
++) {
455 if (off
< cb
->datadma
->dm_segs
[i
].ds_len
)
457 off
-= cb
->datadma
->dm_segs
[i
].ds_len
;
460 /* build MOVE block */
461 if (control
& XS_CTL_DATA_IN
) {
463 while (i
< cb
->datadma
->dm_nsegs
) {
464 xfer
->datain_scr
[n
* 2 + 0] =
466 (cb
->datadma
->dm_segs
[i
].ds_len
- off
));
467 xfer
->datain_scr
[n
* 2 + 1] =
468 htole32(cb
->datadma
->dm_segs
[i
].ds_addr
+
474 xfer
->datain_scr
[n
* 2 + 0] = htole32(0x80080000);
475 xfer
->datain_scr
[n
* 2 + 1] =
476 htole32(sc
->sc_scrbase
+ Ent_phasedispatch
);
478 if (control
& XS_CTL_DATA_OUT
) {
480 while (i
< cb
->datadma
->dm_nsegs
) {
481 xfer
->dataout_scr
[n
* 2 + 0] =
483 (cb
->datadma
->dm_segs
[i
].ds_len
- off
));
484 xfer
->dataout_scr
[n
* 2 + 1] =
485 htole32(cb
->datadma
->dm_segs
[i
].ds_addr
+
491 xfer
->dataout_scr
[n
* 2 + 0] = htole32(0x80080000);
492 xfer
->dataout_scr
[n
* 2 + 1] =
493 htole32(sc
->sc_scrbase
+ Ent_phasedispatch
);
496 if ((control
& XS_CTL_DATA_IN
) == 0) {
497 xfer
->datain_scr
[0] = htole32(0x98080000);
498 xfer
->datain_scr
[1] = htole32(DATAIN_TRAP
);
500 if ((control
& XS_CTL_DATA_OUT
) == 0) {
501 xfer
->dataout_scr
[0] = htole32(0x98080000);
502 xfer
->dataout_scr
[1] = htole32(DATAOUT_TRAP
);
504 OOSIOP_XFERSCR_SYNC(sc
, cb
,
505 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
509 * Setup DMA pointer into script.
512 oosiop_setup_dma(struct oosiop_softc
*sc
)
514 struct oosiop_cb
*cb
;
518 xferbase
= cb
->xferdma
->dm_segs
[0].ds_addr
;
520 OOSIOP_SCRIPT_SYNC(sc
, BUS_DMASYNC_POSTWRITE
);
522 oosiop_fixup_select(sc
, Ent_p_select
, cb
->id
);
523 oosiop_fixup_jump(sc
, Ent_p_datain_jump
, xferbase
+
524 offsetof(struct oosiop_xfer
, datain_scr
[0]));
525 oosiop_fixup_jump(sc
, Ent_p_dataout_jump
, xferbase
+
526 offsetof(struct oosiop_xfer
, dataout_scr
[0]));
527 oosiop_fixup_move(sc
, Ent_p_msgin_move
, 1, xferbase
+
528 offsetof(struct oosiop_xfer
, msgin
[0]));
529 oosiop_fixup_move(sc
, Ent_p_extmsglen_move
, 1, xferbase
+
530 offsetof(struct oosiop_xfer
, msgin
[1]));
531 oosiop_fixup_move(sc
, Ent_p_msgout_move
, cb
->msgoutlen
, xferbase
+
532 offsetof(struct oosiop_xfer
, msgout
[0]));
533 oosiop_fixup_move(sc
, Ent_p_status_move
, 1, xferbase
+
534 offsetof(struct oosiop_xfer
, status
));
535 oosiop_fixup_move(sc
, Ent_p_cmdout_move
, cb
->xs
->cmdlen
,
536 cb
->cmddma
->dm_segs
[0].ds_addr
);
538 OOSIOP_SCRIPT_SYNC(sc
, BUS_DMASYNC_PREWRITE
);
542 oosiop_flush_fifo(struct oosiop_softc
*sc
)
545 oosiop_write_1(sc
, OOSIOP_DFIFO
, oosiop_read_1(sc
, OOSIOP_DFIFO
) |
547 while ((oosiop_read_1(sc
, OOSIOP_CTEST1
) & OOSIOP_CTEST1_FMT
) !=
550 oosiop_write_1(sc
, OOSIOP_DFIFO
, oosiop_read_1(sc
, OOSIOP_DFIFO
) &
555 oosiop_clear_fifo(struct oosiop_softc
*sc
)
558 oosiop_write_1(sc
, OOSIOP_DFIFO
, oosiop_read_1(sc
, OOSIOP_DFIFO
) |
560 while ((oosiop_read_1(sc
, OOSIOP_CTEST1
) & OOSIOP_CTEST1_FMT
) !=
563 oosiop_write_1(sc
, OOSIOP_DFIFO
, oosiop_read_1(sc
, OOSIOP_DFIFO
) &
568 oosiop_phasemismatch(struct oosiop_softc
*sc
)
570 struct oosiop_cb
*cb
;
571 uint32_t dsp
, dbc
, n
, i
, len
;
572 uint8_t dfifo
, sstat1
;
578 dsp
= oosiop_read_4(sc
, OOSIOP_DSP
);
579 dbc
= oosiop_read_4(sc
, OOSIOP_DBC
) & OOSIOP_DBC_MAX
;
582 n
= dsp
- cb
->xferdma
->dm_segs
[0].ds_addr
- 8;
583 if (n
>= offsetof(struct oosiop_xfer
, datain_scr
[0]) &&
584 n
< offsetof(struct oosiop_xfer
, datain_scr
[OOSIOP_NSG
* 2])) {
585 n
-= offsetof(struct oosiop_xfer
, datain_scr
[0]);
587 OOSIOP_DINSCR_SYNC(sc
, cb
,
588 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
589 for (i
= 0; i
<= n
; i
++)
590 len
+= le32toh(cb
->xfer
->datain_scr
[i
* 2]) &
592 OOSIOP_DINSCR_SYNC(sc
, cb
,
593 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
594 /* All data in the chip are already flushed */
595 } else if (n
>= offsetof(struct oosiop_xfer
, dataout_scr
[0]) &&
596 n
< offsetof(struct oosiop_xfer
, dataout_scr
[OOSIOP_NSG
* 2])) {
597 n
-= offsetof(struct oosiop_xfer
, dataout_scr
[0]);
599 OOSIOP_DOUTSCR_SYNC(sc
, cb
,
600 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
601 for (i
= 0; i
<= n
; i
++)
602 len
+= le32toh(cb
->xfer
->dataout_scr
[i
* 2]) &
604 OOSIOP_DOUTSCR_SYNC(sc
, cb
,
605 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
607 dfifo
= oosiop_read_1(sc
, OOSIOP_DFIFO
);
608 dbc
+= ((dfifo
& OOSIOP_DFIFO_BO
) - (dbc
& OOSIOP_DFIFO_BO
)) &
611 sstat1
= oosiop_read_1(sc
, OOSIOP_SSTAT1
);
612 if (sstat1
& OOSIOP_SSTAT1_OLF
)
614 if ((sc
->sc_tgt
[cb
->id
].sxfer
!= 0) &&
615 (sstat1
& OOSIOP_SSTAT1_ORF
) != 0)
618 oosiop_clear_fifo(sc
);
620 printf("%s: phase mismatch addr=%08x\n",
621 device_xname(sc
->sc_dev
),
622 oosiop_read_4(sc
, OOSIOP_DSP
) - 8);
623 oosiop_clear_fifo(sc
);
630 oosiop_setup_sgdma(sc
, cb
);
635 oosiop_setup_syncxfer(struct oosiop_softc
*sc
)
639 id
= sc
->sc_curcb
->id
;
640 if (sc
->sc_chip
!= OOSIOP_700
)
641 oosiop_write_1(sc
, OOSIOP_SBCL
, sc
->sc_tgt
[id
].scf
);
643 oosiop_write_1(sc
, OOSIOP_SXFER
, sc
->sc_tgt
[id
].sxfer
);
647 oosiop_set_syncparam(struct oosiop_softc
*sc
, int id
, int period
, int offset
)
650 struct scsipi_xfer_mode xm
;
659 sc
->sc_tgt
[id
].scf
= 0;
660 sc
->sc_tgt
[id
].sxfer
= 0;
663 if (sc
->sc_chip
== OOSIOP_700
) {
664 for (i
= 4; i
< 12; i
++) {
665 p
= oosiop_period(sc
, i
, sc
->sc_ccf
);
670 printf("%s: target %d period too large\n",
671 device_xname(sc
->sc_dev
), id
);
674 sc
->sc_tgt
[id
].scf
= 0;
675 sc
->sc_tgt
[id
].sxfer
= ((i
- 4) << 4) | offset
;
677 for (i
= 0; i
< NSYNCTBL
; i
++) {
678 p
= oosiop_period(sc
, synctbl
[i
].tp
+ 4,
679 (synctbl
[i
].scf
+ 1) * 5);
684 printf("%s: target %d period too large\n",
685 device_xname(sc
->sc_dev
), id
);
686 i
= NSYNCTBL
- 1; /* XXX */
688 sc
->sc_tgt
[id
].scf
= synctbl
[i
].scf
;
689 sc
->sc_tgt
[id
].sxfer
= (synctbl
[i
].tp
<< 4) | offset
;
692 xm
.xm_mode
|= PERIPH_CAP_SYNC
;
693 xm
.xm_period
= period
;
694 xm
.xm_offset
= offset
;
697 scsipi_async_event(&sc
->sc_channel
, ASYNC_EVENT_XFER_MODE
, &xm
);
701 oosiop_minphys(struct buf
*bp
)
704 if (bp
->b_bcount
> OOSIOP_MAX_XFER
)
705 bp
->b_bcount
= OOSIOP_MAX_XFER
;
710 oosiop_scsipi_request(struct scsipi_channel
*chan
, scsipi_adapter_req_t req
,
713 struct scsipi_xfer
*xs
;
714 struct oosiop_softc
*sc
;
715 struct oosiop_cb
*cb
;
716 struct oosiop_xfer
*xfer
;
717 struct scsipi_xfer_mode
*xm
;
720 sc
= device_private(chan
->chan_adapter
->adapt_dev
);
723 case ADAPTER_REQ_RUN_XFER
:
727 cb
= TAILQ_FIRST(&sc
->sc_free_cb
);
728 TAILQ_REMOVE(&sc
->sc_free_cb
, cb
, chain
);
733 cb
->id
= xs
->xs_periph
->periph_target
;
734 cb
->lun
= xs
->xs_periph
->periph_lun
;
739 /* Setup SCSI command buffer DMA */
740 err
= bus_dmamap_load(sc
->sc_dmat
, cb
->cmddma
, xs
->cmd
,
741 xs
->cmdlen
, NULL
, ((xs
->xs_control
& XS_CTL_NOSLEEP
) ?
742 BUS_DMA_NOWAIT
: BUS_DMA_WAITOK
) | BUS_DMA_WRITE
);
744 printf("%s: unable to load cmd DMA map: %d",
745 device_xname(sc
->sc_dev
), err
);
746 xs
->error
= XS_RESOURCE_SHORTAGE
;
747 TAILQ_INSERT_TAIL(&sc
->sc_free_cb
, cb
, chain
);
751 bus_dmamap_sync(sc
->sc_dmat
, cb
->cmddma
, 0, xs
->cmdlen
,
752 BUS_DMASYNC_PREWRITE
);
754 /* Setup data buffer DMA */
755 if (xs
->xs_control
& (XS_CTL_DATA_IN
| XS_CTL_DATA_OUT
)) {
756 err
= bus_dmamap_load(sc
->sc_dmat
, cb
->datadma
,
757 xs
->data
, xs
->datalen
, NULL
,
758 ((xs
->xs_control
& XS_CTL_NOSLEEP
) ?
759 BUS_DMA_NOWAIT
: BUS_DMA_WAITOK
) |
761 ((xs
->xs_control
& XS_CTL_DATA_IN
) ? BUS_DMA_READ
:
764 printf("%s: unable to load data DMA map: %d",
765 device_xname(sc
->sc_dev
), err
);
766 xs
->error
= XS_RESOURCE_SHORTAGE
;
767 bus_dmamap_unload(sc
->sc_dmat
, cb
->cmddma
);
768 TAILQ_INSERT_TAIL(&sc
->sc_free_cb
, cb
, chain
);
772 bus_dmamap_sync(sc
->sc_dmat
, cb
->datadma
,
774 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
777 oosiop_setup_sgdma(sc
, cb
);
779 /* Setup msgout buffer */
780 OOSIOP_XFERMSG_SYNC(sc
, cb
,
781 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
782 xfer
->msgout
[0] = MSG_IDENTIFY(cb
->lun
,
783 (xs
->xs_control
& XS_CTL_REQSENSE
) == 0);
786 if (sc
->sc_tgt
[cb
->id
].flags
& TGTF_SYNCNEG
) {
788 xfer
->msgout
[1] = MSG_EXTENDED
;
789 xfer
->msgout
[2] = MSG_EXT_SDTR_LEN
;
790 xfer
->msgout
[3] = MSG_EXT_SDTR
;
791 xfer
->msgout
[4] = sc
->sc_minperiod
;
792 xfer
->msgout
[5] = OOSIOP_MAX_OFFSET
;
794 sc
->sc_tgt
[cb
->id
].flags
&= ~TGTF_SYNCNEG
;
795 sc
->sc_tgt
[cb
->id
].flags
|= TGTF_WAITSDTR
;
798 xfer
->status
= SCSI_OOSIOP_NOSTATUS
;
800 OOSIOP_XFERMSG_SYNC(sc
, cb
,
801 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
805 TAILQ_INSERT_TAIL(&sc
->sc_cbq
, cb
, chain
);
807 if (!sc
->sc_active
) {
808 /* Abort script to start selection */
809 oosiop_write_1(sc
, OOSIOP_ISTAT
, OOSIOP_ISTAT_ABRT
);
811 if (xs
->xs_control
& XS_CTL_POLL
) {
812 /* Poll for command completion */
813 while ((xs
->xs_status
& XS_STS_DONE
) == 0) {
823 case ADAPTER_REQ_GROW_RESOURCES
:
826 case ADAPTER_REQ_SET_XFER_MODE
:
828 if (xm
->xm_mode
& PERIPH_CAP_SYNC
)
829 sc
->sc_tgt
[xm
->xm_target
].flags
|= TGTF_SYNCNEG
;
831 oosiop_set_syncparam(sc
, xm
->xm_target
, 0, 0);
838 oosiop_done(struct oosiop_softc
*sc
, struct oosiop_cb
*cb
)
840 struct scsipi_xfer
*xs
;
843 if (cb
== sc
->sc_curcb
)
845 if (cb
== sc
->sc_lastcb
)
846 sc
->sc_lastcb
= NULL
;
847 sc
->sc_tgt
[cb
->id
].nexus
= NULL
;
849 callout_stop(&xs
->xs_callout
);
851 bus_dmamap_sync(sc
->sc_dmat
, cb
->cmddma
, 0, xs
->cmdlen
,
852 BUS_DMASYNC_POSTWRITE
);
853 bus_dmamap_unload(sc
->sc_dmat
, cb
->cmddma
);
855 if (xs
->datalen
> 0) {
856 bus_dmamap_sync(sc
->sc_dmat
, cb
->datadma
, 0, xs
->datalen
,
857 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
858 bus_dmamap_unload(sc
->sc_dmat
, cb
->datadma
);
861 xs
->status
= cb
->xfer
->status
;
862 xs
->resid
= 0; /* XXX */
864 if (cb
->flags
& CBF_SELTOUT
)
865 xs
->error
= XS_SELTIMEOUT
;
866 else if (cb
->flags
& CBF_TIMEOUT
)
867 xs
->error
= XS_TIMEOUT
;
868 else switch (xs
->status
) {
870 xs
->error
= XS_NOERROR
;
877 case SCSI_OOSIOP_NOSTATUS
:
878 /* the status byte was not updated, cmd was aborted. */
879 xs
->error
= XS_SELTIMEOUT
;
883 xs
->error
= XS_RESET
;
889 /* Put it on the free list. */
890 TAILQ_INSERT_TAIL(&sc
->sc_free_cb
, cb
, chain
);
894 oosiop_timeout(void *arg
)
896 struct oosiop_cb
*cb
;
897 struct scsipi_periph
*periph
;
898 struct oosiop_softc
*sc
;
902 periph
= cb
->xs
->xs_periph
;
903 sc
= device_private(periph
->periph_channel
->chan_adapter
->adapt_dev
);
904 scsipi_printaddr(periph
);
905 printf("timed out\n");
909 cb
->flags
|= CBF_TIMEOUT
;
916 oosiop_reset(struct oosiop_softc
*sc
)
922 /* Stop SCRIPTS processor */
923 oosiop_write_1(sc
, OOSIOP_ISTAT
, OOSIOP_ISTAT_ABRT
);
925 oosiop_write_1(sc
, OOSIOP_ISTAT
, 0);
928 oosiop_write_1(sc
, OOSIOP_DCNTL
, sc
->sc_dcntl
| OOSIOP_DCNTL_RST
);
930 oosiop_write_1(sc
, OOSIOP_DCNTL
, sc
->sc_dcntl
);
933 /* Set up various chip parameters */
934 oosiop_write_1(sc
, OOSIOP_SCNTL0
, OOSIOP_ARB_FULL
| OOSIOP_SCNTL0_EPG
);
935 oosiop_write_1(sc
, OOSIOP_SCNTL1
, OOSIOP_SCNTL1_ESR
);
936 oosiop_write_1(sc
, OOSIOP_DCNTL
, sc
->sc_dcntl
);
937 oosiop_write_1(sc
, OOSIOP_DMODE
, OOSIOP_DMODE_BL_8
);
938 oosiop_write_1(sc
, OOSIOP_SCID
, OOSIOP_SCID_VALUE(sc
->sc_id
));
939 oosiop_write_1(sc
, OOSIOP_DWT
, 0xff); /* Enable DMA timeout */
940 oosiop_write_1(sc
, OOSIOP_CTEST7
, 0);
941 oosiop_write_1(sc
, OOSIOP_SXFER
, 0);
943 /* Clear all interrupts */
944 (void)oosiop_read_1(sc
, OOSIOP_SSTAT0
);
945 (void)oosiop_read_1(sc
, OOSIOP_SSTAT1
);
946 (void)oosiop_read_1(sc
, OOSIOP_DSTAT
);
948 /* Enable interrupts */
949 oosiop_write_1(sc
, OOSIOP_SIEN
,
950 OOSIOP_SIEN_M_A
| OOSIOP_SIEN_STO
| OOSIOP_SIEN_SGE
|
951 OOSIOP_SIEN_UDC
| OOSIOP_SIEN_RST
| OOSIOP_SIEN_PAR
);
952 oosiop_write_1(sc
, OOSIOP_DIEN
,
953 OOSIOP_DIEN_ABRT
| OOSIOP_DIEN_SSI
| OOSIOP_DIEN_SIR
|
954 OOSIOP_DIEN_WTD
| OOSIOP_DIEN_IID
);
956 /* Set target state to asynchronous */
957 for (i
= 0; i
< OOSIOP_NTGT
; i
++) {
958 sc
->sc_tgt
[i
].flags
= 0;
959 sc
->sc_tgt
[i
].scf
= 0;
960 sc
->sc_tgt
[i
].sxfer
= 0;
967 oosiop_reset_bus(struct oosiop_softc
*sc
)
973 /* Assert SCSI RST */
974 oosiop_write_1(sc
, OOSIOP_SCNTL1
, OOSIOP_SCNTL1_RST
);
975 delay(25); /* Reset hold time (25us) */
976 oosiop_write_1(sc
, OOSIOP_SCNTL1
, 0);
978 /* Remove all nexuses */
979 for (i
= 0; i
< OOSIOP_NTGT
; i
++) {
980 if (sc
->sc_tgt
[i
].nexus
) {
981 sc
->sc_tgt
[i
].nexus
->xfer
->status
=
982 SCSI_OOSIOP_NOSTATUS
; /* XXX */
983 oosiop_done(sc
, sc
->sc_tgt
[i
].nexus
);
989 delay(250000); /* Reset to selection (250ms) */
998 oosiop_intr(struct oosiop_softc
*sc
)
1000 struct oosiop_cb
*cb
;
1003 uint8_t istat
, dstat
, sstat0
;
1005 istat
= oosiop_read_1(sc
, OOSIOP_ISTAT
);
1007 if ((istat
& (OOSIOP_ISTAT_SIP
| OOSIOP_ISTAT_DIP
)) == 0)
1010 sc
->sc_nextdsp
= Ent_wait_reselect
;
1012 /* DMA interrupts */
1013 if (istat
& OOSIOP_ISTAT_DIP
) {
1014 oosiop_write_1(sc
, OOSIOP_ISTAT
, 0);
1016 dstat
= oosiop_read_1(sc
, OOSIOP_DSTAT
);
1018 if (dstat
& OOSIOP_DSTAT_ABRT
) {
1019 sc
->sc_nextdsp
= oosiop_read_4(sc
, OOSIOP_DSP
) -
1022 if (sc
->sc_nextdsp
== Ent_p_resel_msgin_move
&&
1023 (oosiop_read_1(sc
, OOSIOP_SBCL
) & OOSIOP_ACK
)) {
1024 if ((dstat
& OOSIOP_DSTAT_DFE
) == 0)
1025 oosiop_flush_fifo(sc
);
1026 sc
->sc_nextdsp
+= 8;
1030 if (dstat
& OOSIOP_DSTAT_SSI
) {
1031 sc
->sc_nextdsp
= oosiop_read_4(sc
, OOSIOP_DSP
) -
1033 printf("%s: single step %08x\n",
1034 device_xname(sc
->sc_dev
), sc
->sc_nextdsp
);
1037 if (dstat
& OOSIOP_DSTAT_SIR
) {
1038 if ((dstat
& OOSIOP_DSTAT_DFE
) == 0)
1039 oosiop_flush_fifo(sc
);
1040 oosiop_scriptintr(sc
);
1043 if (dstat
& OOSIOP_DSTAT_WTD
) {
1044 printf("%s: DMA time out\n", device_xname(sc
->sc_dev
));
1048 if (dstat
& OOSIOP_DSTAT_IID
) {
1049 dcmd
= oosiop_read_4(sc
, OOSIOP_DBC
);
1050 if ((dcmd
& 0xf8000000) == 0x48000000) {
1051 printf("%s: REQ asserted on WAIT DISCONNECT\n",
1052 device_xname(sc
->sc_dev
));
1053 sc
->sc_nextdsp
= Ent_phasedispatch
; /* XXX */
1055 printf("%s: invalid SCRIPTS instruction "
1056 "addr=%08x dcmd=%08x dsps=%08x\n",
1057 device_xname(sc
->sc_dev
),
1058 oosiop_read_4(sc
, OOSIOP_DSP
) - 8, dcmd
,
1059 oosiop_read_4(sc
, OOSIOP_DSPS
));
1061 OOSIOP_SCRIPT_SYNC(sc
, BUS_DMASYNC_POSTWRITE
);
1062 oosiop_load_script(sc
);
1066 if ((dstat
& OOSIOP_DSTAT_DFE
) == 0)
1067 oosiop_clear_fifo(sc
);
1070 /* SCSI interrupts */
1071 if (istat
& OOSIOP_ISTAT_SIP
) {
1072 if (istat
& OOSIOP_ISTAT_DIP
)
1074 sstat0
= oosiop_read_1(sc
, OOSIOP_SSTAT0
);
1076 if (sstat0
& OOSIOP_SSTAT0_M_A
) {
1077 /* SCSI phase mismatch during MOVE operation */
1078 oosiop_phasemismatch(sc
);
1079 sc
->sc_nextdsp
= Ent_phasedispatch
;
1082 if (sstat0
& OOSIOP_SSTAT0_STO
) {
1084 sc
->sc_curcb
->flags
|= CBF_SELTOUT
;
1085 oosiop_done(sc
, sc
->sc_curcb
);
1089 if (sstat0
& OOSIOP_SSTAT0_SGE
) {
1090 printf("%s: SCSI gross error\n",
1091 device_xname(sc
->sc_dev
));
1095 if (sstat0
& OOSIOP_SSTAT0_UDC
) {
1098 printf("%s: unexpected disconnect\n",
1099 device_xname(sc
->sc_dev
));
1100 oosiop_done(sc
, sc
->sc_curcb
);
1104 if (sstat0
& OOSIOP_SSTAT0_RST
)
1107 if (sstat0
& OOSIOP_SSTAT0_PAR
)
1108 printf("%s: parity error\n", device_xname(sc
->sc_dev
));
1111 /* Start next command if available */
1112 if (sc
->sc_nextdsp
== Ent_wait_reselect
&& TAILQ_FIRST(&sc
->sc_cbq
)) {
1113 cb
= sc
->sc_curcb
= TAILQ_FIRST(&sc
->sc_cbq
);
1114 TAILQ_REMOVE(&sc
->sc_cbq
, cb
, chain
);
1115 sc
->sc_tgt
[cb
->id
].nexus
= cb
;
1117 oosiop_setup_dma(sc
);
1118 oosiop_setup_syncxfer(sc
);
1120 sc
->sc_nextdsp
= Ent_start_select
;
1122 /* Schedule timeout */
1123 if ((cb
->xs
->xs_control
& XS_CTL_POLL
) == 0) {
1124 timeout
= mstohz(cb
->xs
->timeout
) + 1;
1125 callout_reset(&cb
->xs
->xs_callout
, timeout
,
1126 oosiop_timeout
, cb
);
1130 sc
->sc_active
= (sc
->sc_nextdsp
!= Ent_wait_reselect
);
1132 /* Restart script */
1133 oosiop_write_4(sc
, OOSIOP_DSP
, sc
->sc_nextdsp
+ sc
->sc_scrbase
);
1139 oosiop_scriptintr(struct oosiop_softc
*sc
)
1141 struct oosiop_cb
*cb
;
1145 uint8_t sfbr
, resid
, resmsg
;
1148 icode
= oosiop_read_4(sc
, OOSIOP_DSPS
);
1153 oosiop_done(sc
, cb
);
1158 oosiop_msgin(sc
, cb
);
1162 /* extended message in DMA setup request */
1163 sfbr
= oosiop_read_1(sc
, OOSIOP_SFBR
);
1164 OOSIOP_SCRIPT_SYNC(sc
, BUS_DMASYNC_POSTWRITE
);
1165 oosiop_fixup_move(sc
, Ent_p_extmsgin_move
, sfbr
,
1166 cb
->xferdma
->dm_segs
[0].ds_addr
+
1167 offsetof(struct oosiop_xfer
, msgin
[2]));
1168 OOSIOP_SCRIPT_SYNC(sc
, BUS_DMASYNC_PREWRITE
);
1169 sc
->sc_nextdsp
= Ent_rcv_extmsg
;
1174 resid
= oosiop_read_1(sc
, OOSIOP_SFBR
);
1175 for (i
= 0; i
< OOSIOP_NTGT
; i
++)
1176 if (resid
& (1 << i
))
1178 if (i
== OOSIOP_NTGT
) {
1179 printf("%s: missing reselection target id\n",
1180 device_xname(sc
->sc_dev
));
1184 sc
->sc_nextdsp
= Ent_wait_resel_identify
;
1187 /* Current command was lost arbitration */
1188 sc
->sc_tgt
[cb
->id
].nexus
= NULL
;
1189 TAILQ_INSERT_HEAD(&sc
->sc_cbq
, cb
, chain
);
1190 sc
->sc_curcb
= NULL
;
1196 cb
= sc
->sc_tgt
[sc
->sc_resid
].nexus
;
1197 resmsg
= oosiop_read_1(sc
, OOSIOP_SFBR
);
1198 if (MSG_ISIDENTIFY(resmsg
) && cb
&&
1199 (resmsg
& MSG_IDENTIFY_LUNMASK
) == cb
->lun
) {
1201 if (cb
!= sc
->sc_lastcb
) {
1202 oosiop_setup_dma(sc
);
1203 oosiop_setup_syncxfer(sc
);
1206 if (cb
->curdp
!= cb
->savedp
) {
1207 cb
->curdp
= cb
->savedp
;
1208 oosiop_setup_sgdma(sc
, cb
);
1210 sc
->sc_nextdsp
= Ent_ack_msgin
;
1212 /* Reselection from invalid target */
1213 oosiop_reset_bus(sc
);
1218 /* reselect failed */
1223 sc
->sc_curcb
= NULL
;
1228 dsp
= oosiop_read_4(sc
, OOSIOP_DSP
);
1229 printf("%s: script error at 0x%08x\n",
1230 device_xname(sc
->sc_dev
), dsp
- 8);
1231 sc
->sc_curcb
= NULL
;
1235 printf("%s: unexpected datain\n", device_xname(sc
->sc_dev
));
1236 /* XXX: need to reset? */
1240 printf("%s: unexpected dataout\n", device_xname(sc
->sc_dev
));
1241 /* XXX: need to reset? */
1245 printf("%s: unknown intr code %08x\n",
1246 device_xname(sc
->sc_dev
), icode
);
1252 oosiop_msgin(struct oosiop_softc
*sc
, struct oosiop_cb
*cb
)
1254 struct oosiop_xfer
*xfer
;
1258 sc
->sc_nextdsp
= Ent_ack_msgin
;
1261 OOSIOP_XFERMSG_SYNC(sc
, cb
,
1262 BUS_DMASYNC_POSTREAD
| BUS_DMASYNC_POSTWRITE
);
1264 switch (xfer
->msgin
[0]) {
1266 switch (xfer
->msgin
[2]) {
1268 if (sc
->sc_tgt
[cb
->id
].flags
& TGTF_WAITSDTR
) {
1269 /* Host initiated SDTR */
1270 sc
->sc_tgt
[cb
->id
].flags
&= ~TGTF_WAITSDTR
;
1272 /* Target initiated SDTR */
1273 if (xfer
->msgin
[3] < sc
->sc_minperiod
)
1274 xfer
->msgin
[3] = sc
->sc_minperiod
;
1275 if (xfer
->msgin
[4] > OOSIOP_MAX_OFFSET
)
1276 xfer
->msgin
[4] = OOSIOP_MAX_OFFSET
;
1277 xfer
->msgout
[0] = MSG_EXTENDED
;
1278 xfer
->msgout
[1] = MSG_EXT_SDTR_LEN
;
1279 xfer
->msgout
[2] = MSG_EXT_SDTR
;
1280 xfer
->msgout
[3] = xfer
->msgin
[3];
1281 xfer
->msgout
[4] = xfer
->msgin
[4];
1285 oosiop_set_syncparam(sc
, cb
->id
, (int)xfer
->msgin
[3],
1286 (int)xfer
->msgin
[4]);
1287 oosiop_setup_syncxfer(sc
);
1291 /* Reject message */
1292 xfer
->msgout
[0] = MSG_MESSAGE_REJECT
;
1299 case MSG_SAVEDATAPOINTER
:
1300 cb
->savedp
= cb
->curdp
;
1303 case MSG_RESTOREPOINTERS
:
1304 if (cb
->curdp
!= cb
->savedp
) {
1305 cb
->curdp
= cb
->savedp
;
1306 oosiop_setup_sgdma(sc
, cb
);
1310 case MSG_MESSAGE_REJECT
:
1311 if (sc
->sc_tgt
[cb
->id
].flags
& TGTF_WAITSDTR
) {
1313 sc
->sc_tgt
[cb
->id
].flags
&= ~TGTF_WAITSDTR
;
1314 oosiop_set_syncparam(sc
, cb
->id
, 0, 0);
1315 oosiop_setup_syncxfer(sc
);
1320 /* Reject message */
1321 xfer
->msgout
[0] = MSG_MESSAGE_REJECT
;
1326 OOSIOP_XFERMSG_SYNC(sc
, cb
,
1327 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
1330 OOSIOP_SCRIPT_SYNC(sc
, BUS_DMASYNC_POSTWRITE
);
1331 oosiop_fixup_move(sc
, Ent_p_msgout_move
, cb
->msgoutlen
,
1332 cb
->xferdma
->dm_segs
[0].ds_addr
+
1333 offsetof(struct oosiop_xfer
, msgout
[0]));
1334 OOSIOP_SCRIPT_SYNC(sc
, BUS_DMASYNC_PREWRITE
);
1335 sc
->sc_nextdsp
= Ent_sendmsg
;