2 * SPDX-License-Identifier: BSD-4-Clause
4 * Copyright (c) 2003 Hidetoshi Shimokawa
5 * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the acknowledgement as bellow:
19 * This product includes software developed by K. Kobayashi and H. Shimokawa
21 * 4. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
40 #include <sys/param.h>
41 #include <sys/systm.h>
43 #include <sys/malloc.h>
44 #include <sys/sockio.h>
45 #include <sys/sysctl.h>
47 #include <sys/kernel.h>
49 #include <sys/endian.h>
52 #include <machine/bus.h>
53 #include <machine/md_var.h>
55 #include <dev/firewire/firewire.h>
56 #include <dev/firewire/firewirereg.h>
57 #include <dev/firewire/fwdma.h>
58 #include <dev/firewire/fwohcireg.h>
59 #include <dev/firewire/fwohcivar.h>
60 #include <dev/firewire/firewire_phy.h>
64 static int nocyclemaster;
65 int firewire_phydma_enable = 1;
66 SYSCTL_DECL(_hw_firewire);
67 SYSCTL_INT(_hw_firewire, OID_AUTO, nocyclemaster, CTLFLAG_RWTUN,
68 &nocyclemaster, 0, "Do not send cycle start packets");
69 SYSCTL_INT(_hw_firewire, OID_AUTO, phydma_enable, CTLFLAG_RWTUN,
70 &firewire_phydma_enable, 0, "Allow physical request DMA from firewire");
72 static char dbcode[16][0x10] = {"OUTM", "OUTL", "INPM", "INPL",
73 "STOR", "LOAD", "NOP ", "STOP",};
75 static char dbkey[8][0x10] = {"ST0", "ST1", "ST2", "ST3",
76 "UNDEF", "REG", "SYS", "DEV"};
77 static char dbcond[4][0x10] = {"NEV", "C=1", "C=0", "ALL"};
78 char fwohcicode[32][0x20]= {
79 "No stat", "Undef", "long", "miss Ack err",
80 "FIFO underrun", "FIFO overrun", "desc err", "data read err",
81 "data write err", "bus reset", "timeout", "tcode err",
82 "Undef", "Undef", "unknown event", "flushed",
83 "Undef" ,"ack complete", "ack pend", "Undef",
84 "ack busy_X", "ack busy_A", "ack busy_B", "Undef",
85 "Undef", "Undef", "Undef", "ack tardy",
86 "Undef", "ack data_err", "ack type_err", ""};
89 extern char *linkspeed[];
90 uint32_t tagbit[4] = {1 << 28, 1 << 29, 1 << 30, 1 << 31};
92 static struct tcode_info tinfo[] = {
93 /* hdr_len block flag valid_response */
94 /* 0 WREQQ */ {16, FWTI_REQ | FWTI_TLABEL, FWTCODE_WRES},
95 /* 1 WREQB */ {16, FWTI_REQ | FWTI_TLABEL | FWTI_BLOCK_ASY, FWTCODE_WRES},
96 /* 2 WRES */ {12, FWTI_RES, 0xff},
97 /* 3 XXX */ { 0, 0, 0xff},
98 /* 4 RREQQ */ {12, FWTI_REQ | FWTI_TLABEL, FWTCODE_RRESQ},
99 /* 5 RREQB */ {16, FWTI_REQ | FWTI_TLABEL, FWTCODE_RRESB},
100 /* 6 RRESQ */ {16, FWTI_RES, 0xff},
101 /* 7 RRESB */ {16, FWTI_RES | FWTI_BLOCK_ASY, 0xff},
102 /* 8 CYCS */ { 0, 0, 0xff},
103 /* 9 LREQ */ {16, FWTI_REQ | FWTI_TLABEL | FWTI_BLOCK_ASY, FWTCODE_LRES},
104 /* a STREAM */ { 4, FWTI_REQ | FWTI_BLOCK_STR, 0xff},
105 /* b LRES */ {16, FWTI_RES | FWTI_BLOCK_ASY, 0xff},
106 /* c XXX */ { 0, 0, 0xff},
107 /* d XXX */ { 0, 0, 0xff},
108 /* e PHY */ {12, FWTI_REQ, 0xff},
109 /* f XXX */ { 0, 0, 0xff}
119 #define OHCI_WRITE_SIGMASK 0xffff0000
120 #define OHCI_READ_SIGMASK 0xffff0000
122 #define OWRITE(sc, r, x) bus_space_write_4((sc)->bst, (sc)->bsh, (r), (x))
123 #define OREAD(sc, r) bus_space_read_4((sc)->bst, (sc)->bsh, (r))
125 static void fwohci_ibr (struct firewire_comm *);
126 static void fwohci_db_init (struct fwohci_softc *, struct fwohci_dbch *);
127 static void fwohci_db_free (struct fwohci_dbch *);
128 static void fwohci_arcv (struct fwohci_softc *, struct fwohci_dbch *, int);
129 static void fwohci_txd (struct fwohci_softc *, struct fwohci_dbch *);
130 static void fwohci_start_atq (struct firewire_comm *);
131 static void fwohci_start_ats (struct firewire_comm *);
132 static void fwohci_start (struct fwohci_softc *, struct fwohci_dbch *);
133 static uint32_t fwphy_wrdata (struct fwohci_softc *, uint32_t, uint32_t);
134 static uint32_t fwphy_rddata (struct fwohci_softc *, uint32_t);
135 static int fwohci_rx_enable (struct fwohci_softc *, struct fwohci_dbch *);
136 static int fwohci_tx_enable (struct fwohci_softc *, struct fwohci_dbch *);
137 static int fwohci_irx_enable (struct firewire_comm *, int);
138 static int fwohci_irx_disable (struct firewire_comm *, int);
139 #if BYTE_ORDER == BIG_ENDIAN
140 static void fwohci_irx_post (struct firewire_comm *, uint32_t *);
142 static int fwohci_itxbuf_enable (struct firewire_comm *, int);
143 static int fwohci_itx_disable (struct firewire_comm *, int);
144 static void fwohci_timeout (void *);
145 static void fwohci_set_intr (struct firewire_comm *, int);
147 static int fwohci_add_rx_buf (struct fwohci_dbch *, struct fwohcidb_tr *, int, struct fwdma_alloc *);
148 static int fwohci_add_tx_buf (struct fwohci_dbch *, struct fwohcidb_tr *, int);
149 static void dump_db (struct fwohci_softc *, uint32_t);
150 static void print_db (struct fwohcidb_tr *, struct fwohcidb *, uint32_t , uint32_t);
151 static void dump_dma (struct fwohci_softc *, uint32_t);
152 static uint32_t fwohci_cyctimer (struct firewire_comm *);
153 static void fwohci_rbuf_update (struct fwohci_softc *, int);
154 static void fwohci_tbuf_update (struct fwohci_softc *, int);
155 void fwohci_txbufdb (struct fwohci_softc *, int , struct fw_bulkxfer *);
156 static void fwohci_task_busreset(void *, int);
157 static void fwohci_task_sid(void *, int);
158 static void fwohci_task_dma(void *, int);
161 * memory allocated for DMA programs
163 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
165 #define NDB FWMAXQUEUE
167 #define OHCI_VERSION 0x00
168 #define OHCI_ATRETRY 0x08
169 #define OHCI_CROMHDR 0x18
170 #define OHCI_BUS_OPT 0x20
171 #define OHCI_BUSIRMC (1U << 31)
172 #define OHCI_BUSCMC (1 << 30)
173 #define OHCI_BUSISC (1 << 29)
174 #define OHCI_BUSBMC (1 << 28)
175 #define OHCI_BUSPMC (1 << 27)
176 #define OHCI_BUSFNC OHCI_BUSIRMC | OHCI_BUSCMC | OHCI_BUSISC |\
177 OHCI_BUSBMC | OHCI_BUSPMC
179 #define OHCI_EUID_HI 0x24
180 #define OHCI_EUID_LO 0x28
182 #define OHCI_CROMPTR 0x34
183 #define OHCI_HCCCTL 0x50
184 #define OHCI_HCCCTLCLR 0x54
185 #define OHCI_AREQHI 0x100
186 #define OHCI_AREQHICLR 0x104
187 #define OHCI_AREQLO 0x108
188 #define OHCI_AREQLOCLR 0x10c
189 #define OHCI_PREQHI 0x110
190 #define OHCI_PREQHICLR 0x114
191 #define OHCI_PREQLO 0x118
192 #define OHCI_PREQLOCLR 0x11c
193 #define OHCI_PREQUPPER 0x120
194 #define OHCI_PREQUPPER_MAX 0xffff0000
196 #define OHCI_SID_BUF 0x64
197 #define OHCI_SID_CNT 0x68
198 #define OHCI_SID_ERR (1U << 31)
199 #define OHCI_SID_CNT_MASK 0xffc
201 #define OHCI_IT_STAT 0x90
202 #define OHCI_IT_STATCLR 0x94
203 #define OHCI_IT_MASK 0x98
204 #define OHCI_IT_MASKCLR 0x9c
206 #define OHCI_IR_STAT 0xa0
207 #define OHCI_IR_STATCLR 0xa4
208 #define OHCI_IR_MASK 0xa8
209 #define OHCI_IR_MASKCLR 0xac
211 #define OHCI_LNKCTL 0xe0
212 #define OHCI_LNKCTLCLR 0xe4
214 #define OHCI_PHYACCESS 0xec
215 #define OHCI_CYCLETIMER 0xf0
217 #define OHCI_DMACTL(off) (off)
218 #define OHCI_DMACTLCLR(off) (off + 4)
219 #define OHCI_DMACMD(off) (off + 0xc)
220 #define OHCI_DMAMATCH(off) (off + 0x10)
222 #define OHCI_ATQOFF 0x180
223 #define OHCI_ATQCTL OHCI_ATQOFF
224 #define OHCI_ATQCTLCLR (OHCI_ATQOFF + 4)
225 #define OHCI_ATQCMD (OHCI_ATQOFF + 0xc)
226 #define OHCI_ATQMATCH (OHCI_ATQOFF + 0x10)
228 #define OHCI_ATSOFF 0x1a0
229 #define OHCI_ATSCTL OHCI_ATSOFF
230 #define OHCI_ATSCTLCLR (OHCI_ATSOFF + 4)
231 #define OHCI_ATSCMD (OHCI_ATSOFF + 0xc)
232 #define OHCI_ATSMATCH (OHCI_ATSOFF + 0x10)
234 #define OHCI_ARQOFF 0x1c0
235 #define OHCI_ARQCTL OHCI_ARQOFF
236 #define OHCI_ARQCTLCLR (OHCI_ARQOFF + 4)
237 #define OHCI_ARQCMD (OHCI_ARQOFF + 0xc)
238 #define OHCI_ARQMATCH (OHCI_ARQOFF + 0x10)
240 #define OHCI_ARSOFF 0x1e0
241 #define OHCI_ARSCTL OHCI_ARSOFF
242 #define OHCI_ARSCTLCLR (OHCI_ARSOFF + 4)
243 #define OHCI_ARSCMD (OHCI_ARSOFF + 0xc)
244 #define OHCI_ARSMATCH (OHCI_ARSOFF + 0x10)
246 #define OHCI_ITOFF(CH) (0x200 + 0x10 * (CH))
247 #define OHCI_ITCTL(CH) (OHCI_ITOFF(CH))
248 #define OHCI_ITCTLCLR(CH) (OHCI_ITOFF(CH) + 4)
249 #define OHCI_ITCMD(CH) (OHCI_ITOFF(CH) + 0xc)
251 #define OHCI_IROFF(CH) (0x400 + 0x20 * (CH))
252 #define OHCI_IRCTL(CH) (OHCI_IROFF(CH))
253 #define OHCI_IRCTLCLR(CH) (OHCI_IROFF(CH) + 4)
254 #define OHCI_IRCMD(CH) (OHCI_IROFF(CH) + 0xc)
255 #define OHCI_IRMATCH(CH) (OHCI_IROFF(CH) + 0x10)
257 d_ioctl_t fwohci_ioctl;
260 * Communication with PHY device
262 /* XXX need lock for phy access */
264 fwphy_wrdata(struct fwohci_softc *sc, uint32_t addr, uint32_t data)
271 fun = (PHYDEV_WRCMD | (addr << PHYDEV_REGADDR) |
272 (data << PHYDEV_WRDATA));
273 OWRITE(sc, OHCI_PHYACCESS, fun);
276 return (fwphy_rddata(sc, addr));
280 fwohci_set_bus_manager(struct firewire_comm *fc, u_int node)
282 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
286 #define OHCI_CSR_DATA 0x0c
287 #define OHCI_CSR_COMP 0x10
288 #define OHCI_CSR_CONT 0x14
289 #define OHCI_BUS_MANAGER_ID 0
291 OWRITE(sc, OHCI_CSR_DATA, node);
292 OWRITE(sc, OHCI_CSR_COMP, 0x3f);
293 OWRITE(sc, OHCI_CSR_CONT, OHCI_BUS_MANAGER_ID);
294 for (i = 0; !(OREAD(sc, OHCI_CSR_CONT) & (1<<31)) && (i < 1000); i++)
296 bm = OREAD(sc, OHCI_CSR_DATA);
297 if ((bm & 0x3f) == 0x3f)
300 device_printf(sc->fc.dev, "%s: %d->%d (loop=%d)\n",
301 __func__, bm, node, i);
306 fwphy_rddata(struct fwohci_softc *sc, u_int addr)
312 #define MAX_RETRY 100
314 OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_REG_FAIL);
315 fun = PHYDEV_RDCMD | (addr << PHYDEV_REGADDR);
316 OWRITE(sc, OHCI_PHYACCESS, fun);
317 for (i = 0; i < MAX_RETRY; i++) {
318 fun = OREAD(sc, OHCI_PHYACCESS);
319 if ((fun & PHYDEV_RDCMD) == 0 && (fun & PHYDEV_RDDONE) != 0)
323 if (i >= MAX_RETRY) {
325 device_printf(sc->fc.dev, "%s: failed(1).\n", __func__);
326 if (++retry < MAX_RETRY) {
331 /* Make sure that SCLK is started */
332 stat = OREAD(sc, FWOHCI_INTSTAT);
333 if ((stat & OHCI_INT_REG_FAIL) != 0 ||
334 ((fun >> PHYDEV_REGADDR) & 0xf) != addr) {
336 device_printf(sc->fc.dev, "%s: failed(2).\n", __func__);
337 if (++retry < MAX_RETRY) {
342 if (firewire_debug > 1 || retry >= MAX_RETRY)
343 device_printf(sc->fc.dev,
344 "%s:: 0x%x loop=%d, retry=%d\n",
345 __func__, addr, i, retry);
347 return ((fun >> PHYDEV_RDDATA) & 0xff);
350 /* Device specific ioctl. */
352 fwohci_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, fw_proc *td)
354 struct firewire_softc *sc;
355 struct fwohci_softc *fc;
356 int unit = DEV2UNIT(dev);
358 struct fw_reg_req_t *reg = (struct fw_reg_req_t *) data;
359 uint32_t *dmach = (uint32_t *) data;
361 sc = devclass_get_softc(firewire_devclass, unit);
365 fc = (struct fwohci_softc *)sc->fc;
372 #define OHCI_MAX_REG 0x800
373 if (reg->addr <= OHCI_MAX_REG) {
374 OWRITE(fc, reg->addr, reg->data);
375 reg->data = OREAD(fc, reg->addr);
381 if (reg->addr <= OHCI_MAX_REG) {
382 reg->data = OREAD(fc, reg->addr);
387 /* Read DMA descriptors for debug */
389 if (*dmach <= OHCI_MAX_DMA_CH) {
390 dump_dma(fc, *dmach);
396 /* Read/Write Phy registers */
397 #define OHCI_MAX_PHY_REG 0xf
398 case FWOHCI_RDPHYREG:
399 if (reg->addr <= OHCI_MAX_PHY_REG)
400 reg->data = fwphy_rddata(fc, reg->addr);
404 case FWOHCI_WRPHYREG:
405 if (reg->addr <= OHCI_MAX_PHY_REG)
406 reg->data = fwphy_wrdata(fc, reg->addr, reg->data);
418 fwohci_probe_phy(struct fwohci_softc *sc, device_t dev)
424 * probe PHY parameters
425 * 0. to prove PHY version, whether compliance of 1394a.
426 * 1. to probe maximum speed supported by the PHY and
427 * number of port supported by core-logic.
428 * It is not actually available port on your PC .
430 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LPS);
433 reg = fwphy_rddata(sc, FW_PHY_SPD_REG);
435 if ((reg >> 5) != 7) {
436 sc->fc.mode &= ~FWPHYASYST;
437 sc->fc.nport = reg & FW_PHY_NP;
438 sc->fc.speed = reg & FW_PHY_SPD >> 6;
439 if (sc->fc.speed > MAX_SPEED) {
440 device_printf(dev, "invalid speed %d (fixed to %d).\n",
441 sc->fc.speed, MAX_SPEED);
442 sc->fc.speed = MAX_SPEED;
445 "Phy 1394 only %s, %d ports.\n",
446 linkspeed[sc->fc.speed], sc->fc.nport);
448 reg2 = fwphy_rddata(sc, FW_PHY_ESPD_REG);
449 sc->fc.mode |= FWPHYASYST;
450 sc->fc.nport = reg & FW_PHY_NP;
451 sc->fc.speed = (reg2 & FW_PHY_ESPD) >> 5;
452 if (sc->fc.speed > MAX_SPEED) {
453 device_printf(dev, "invalid speed %d (fixed to %d).\n",
454 sc->fc.speed, MAX_SPEED);
455 sc->fc.speed = MAX_SPEED;
458 "Phy 1394a available %s, %d ports.\n",
459 linkspeed[sc->fc.speed], sc->fc.nport);
461 /* check programPhyEnable */
462 reg2 = fwphy_rddata(sc, 5);
464 if (e1394a && (OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_PRPHY)) {
465 #else /* XXX force to enable 1394a */
470 "Enable 1394a Enhancements\n");
473 /* set aPhyEnhanceEnable */
474 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_PHYEN);
475 OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_PRPHY);
480 reg2 = fwphy_wrdata(sc, 5, reg2);
483 reg = fwphy_rddata(sc, FW_PHY_SPD_REG);
484 if ((reg >> 5) == 7) {
485 reg = fwphy_rddata(sc, 4);
487 fwphy_wrdata(sc, 4, reg);
488 reg = fwphy_rddata(sc, 4);
495 fwohci_reset(struct fwohci_softc *sc, device_t dev)
497 int i, max_rec, speed;
499 struct fwohcidb_tr *db_tr;
501 /* Disable interrupts */
502 OWRITE(sc, FWOHCI_INTMASKCLR, ~0);
504 /* Now stopping all DMA channels */
505 OWRITE(sc, OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
506 OWRITE(sc, OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN);
507 OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
508 OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
510 OWRITE(sc, OHCI_IR_MASKCLR, ~0);
511 for (i = 0; i < sc->fc.nisodma; i++) {
512 OWRITE(sc, OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN);
513 OWRITE(sc, OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN);
516 /* FLUSH FIFO and reset Transmitter/Receiver */
517 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_RESET);
519 device_printf(dev, "resetting OHCI...");
521 while (OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_RESET) {
522 if (i++ > 100) break;
526 printf("done (loop=%d)\n", i);
529 fwohci_probe_phy(sc, dev);
532 reg = OREAD(sc, OHCI_BUS_OPT);
533 reg2 = reg | OHCI_BUSFNC;
534 max_rec = (reg & 0x0000f000) >> 12;
535 speed = (reg & 0x00000007);
536 device_printf(dev, "Link %s, max_rec %d bytes.\n",
537 linkspeed[speed], MAXREC(max_rec));
538 /* XXX fix max_rec */
539 sc->fc.maxrec = sc->fc.speed + 8;
540 if (max_rec != sc->fc.maxrec) {
541 reg2 = (reg2 & 0xffff0fff) | (sc->fc.maxrec << 12);
542 device_printf(dev, "max_rec %d -> %d\n",
543 MAXREC(max_rec), MAXREC(sc->fc.maxrec));
546 device_printf(dev, "BUS_OPT 0x%x -> 0x%x\n", reg, reg2);
547 OWRITE(sc, OHCI_BUS_OPT, reg2);
549 /* Initialize registers */
550 OWRITE(sc, OHCI_CROMHDR, sc->fc.config_rom[0]);
551 OWRITE(sc, OHCI_CROMPTR, sc->crom_dma.bus_addr);
552 OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_BIGEND);
553 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_POSTWR);
554 OWRITE(sc, OHCI_SID_BUF, sc->sid_dma.bus_addr);
555 OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_SID);
558 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LINKEN);
560 /* Force to start async RX DMA */
561 sc->arrq.xferq.flag &= ~FWXFERQ_RUNNING;
562 sc->arrs.xferq.flag &= ~FWXFERQ_RUNNING;
563 fwohci_rx_enable(sc, &sc->arrq);
564 fwohci_rx_enable(sc, &sc->arrs);
566 /* Initialize async TX */
567 OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN | OHCI_CNTL_DMA_DEAD);
568 OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN | OHCI_CNTL_DMA_DEAD);
571 OWRITE(sc, FWOHCI_RETRY,
572 /* CycleLimit PhyRespRetries ATRespRetries ATReqRetries */
573 (0xffff << 16) | (0x0f << 8) | (0x0f << 4) | 0x0f);
575 sc->atrq.top = STAILQ_FIRST(&sc->atrq.db_trq);
576 sc->atrs.top = STAILQ_FIRST(&sc->atrs.db_trq);
577 sc->atrq.bottom = sc->atrq.top;
578 sc->atrs.bottom = sc->atrs.top;
580 for (i = 0, db_tr = sc->atrq.top; i < sc->atrq.ndb;
581 i++, db_tr = STAILQ_NEXT(db_tr, link)) {
584 for (i = 0, db_tr = sc->atrs.top; i < sc->atrs.ndb;
585 i++, db_tr = STAILQ_NEXT(db_tr, link)) {
589 /* Enable interrupts */
590 sc->intmask = (OHCI_INT_ERR | OHCI_INT_PHY_SID
591 | OHCI_INT_DMA_ATRQ | OHCI_INT_DMA_ATRS
592 | OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS
593 | OHCI_INT_PHY_BUS_R | OHCI_INT_PW_ERR);
594 sc->intmask |= OHCI_INT_DMA_IR | OHCI_INT_DMA_IT;
595 sc->intmask |= OHCI_INT_CYC_LOST | OHCI_INT_PHY_INT;
596 OWRITE(sc, FWOHCI_INTMASK, sc->intmask);
597 fwohci_set_intr(&sc->fc, 1);
601 fwohci_init(struct fwohci_softc *sc, device_t dev)
608 reg = OREAD(sc, OHCI_VERSION);
609 mver = (reg >> 16) & 0xff;
610 device_printf(dev, "OHCI version %x.%x (ROM=%d)\n",
611 mver, reg & 0xff, (reg >> 24) & 1);
612 if (mver < 1 || mver > 9) {
613 device_printf(dev, "invalid OHCI version\n");
617 /* Available Isochronous DMA channel probe */
618 OWRITE(sc, OHCI_IT_MASK, 0xffffffff);
619 OWRITE(sc, OHCI_IR_MASK, 0xffffffff);
620 reg = OREAD(sc, OHCI_IT_MASK) & OREAD(sc, OHCI_IR_MASK);
621 OWRITE(sc, OHCI_IT_MASKCLR, 0xffffffff);
622 OWRITE(sc, OHCI_IR_MASKCLR, 0xffffffff);
623 for (i = 0; i < 0x20; i++)
624 if ((reg & (1 << i)) == 0)
627 device_printf(dev, "No. of Isochronous channels is %d.\n", i);
631 sc->fc.arq = &sc->arrq.xferq;
632 sc->fc.ars = &sc->arrs.xferq;
633 sc->fc.atq = &sc->atrq.xferq;
634 sc->fc.ats = &sc->atrs.xferq;
636 sc->arrq.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
637 sc->arrs.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
638 sc->atrq.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
639 sc->atrs.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
641 sc->arrq.xferq.start = NULL;
642 sc->arrs.xferq.start = NULL;
643 sc->atrq.xferq.start = fwohci_start_atq;
644 sc->atrs.xferq.start = fwohci_start_ats;
646 sc->arrq.xferq.buf = NULL;
647 sc->arrs.xferq.buf = NULL;
648 sc->atrq.xferq.buf = NULL;
649 sc->atrs.xferq.buf = NULL;
651 sc->arrq.xferq.dmach = -1;
652 sc->arrs.xferq.dmach = -1;
653 sc->atrq.xferq.dmach = -1;
654 sc->atrs.xferq.dmach = -1;
658 sc->atrq.ndesc = 8; /* equal to maximum of mbuf chains */
662 sc->arrs.ndb = NDB / 2;
664 sc->atrs.ndb = NDB / 2;
666 for (i = 0; i < sc->fc.nisodma; i++) {
667 sc->fc.it[i] = &sc->it[i].xferq;
668 sc->fc.ir[i] = &sc->ir[i].xferq;
669 sc->it[i].xferq.dmach = i;
670 sc->ir[i].xferq.dmach = i;
675 sc->fc.tcode = tinfo;
678 sc->fc.config_rom = fwdma_malloc(&sc->fc, CROMSIZE, CROMSIZE,
679 &sc->crom_dma, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
680 if (sc->fc.config_rom == NULL) {
681 device_printf(dev, "config_rom alloc failed.");
686 bzero(&sc->fc.config_rom[0], CROMSIZE);
687 sc->fc.config_rom[1] = 0x31333934;
688 sc->fc.config_rom[2] = 0xf000a002;
689 sc->fc.config_rom[3] = OREAD(sc, OHCI_EUID_HI);
690 sc->fc.config_rom[4] = OREAD(sc, OHCI_EUID_LO);
691 sc->fc.config_rom[5] = 0;
692 sc->fc.config_rom[0] = (4 << 24) | (5 << 16);
694 sc->fc.config_rom[0] |= fw_crc16(&sc->fc.config_rom[1], 5*4);
697 /* SID receive buffer must align 2^11 */
698 #define OHCI_SIDSIZE (1 << 11)
699 sc->sid_buf = fwdma_malloc(&sc->fc, OHCI_SIDSIZE, OHCI_SIDSIZE,
700 &sc->sid_dma, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
701 if (sc->sid_buf == NULL) {
702 device_printf(dev, "sid_buf alloc failed.");
706 fwdma_malloc(&sc->fc, sizeof(uint32_t), sizeof(uint32_t),
707 &sc->dummy_dma, BUS_DMA_WAITOK);
709 if (sc->dummy_dma.v_addr == NULL) {
710 device_printf(dev, "dummy_dma alloc failed.");
714 fwohci_db_init(sc, &sc->arrq);
715 if ((sc->arrq.flags & FWOHCI_DBCH_INIT) == 0)
718 fwohci_db_init(sc, &sc->arrs);
719 if ((sc->arrs.flags & FWOHCI_DBCH_INIT) == 0)
722 fwohci_db_init(sc, &sc->atrq);
723 if ((sc->atrq.flags & FWOHCI_DBCH_INIT) == 0)
726 fwohci_db_init(sc, &sc->atrs);
727 if ((sc->atrs.flags & FWOHCI_DBCH_INIT) == 0)
730 sc->fc.eui.hi = OREAD(sc, FWOHCIGUID_H);
731 sc->fc.eui.lo = OREAD(sc, FWOHCIGUID_L);
732 for (i = 0; i < 8; i++)
733 ui[i] = FW_EUI64_BYTE(&sc->fc.eui,i);
734 device_printf(dev, "EUI64 %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
735 ui[0], ui[1], ui[2], ui[3], ui[4], ui[5], ui[6], ui[7]);
737 sc->fc.ioctl = fwohci_ioctl;
738 sc->fc.cyctimer = fwohci_cyctimer;
739 sc->fc.set_bmr = fwohci_set_bus_manager;
740 sc->fc.ibr = fwohci_ibr;
741 sc->fc.irx_enable = fwohci_irx_enable;
742 sc->fc.irx_disable = fwohci_irx_disable;
744 sc->fc.itx_enable = fwohci_itxbuf_enable;
745 sc->fc.itx_disable = fwohci_itx_disable;
746 #if BYTE_ORDER == BIG_ENDIAN
747 sc->fc.irx_post = fwohci_irx_post;
749 sc->fc.irx_post = NULL;
751 sc->fc.itx_post = NULL;
752 sc->fc.timeout = fwohci_timeout;
753 sc->fc.poll = fwohci_poll;
754 sc->fc.set_intr = fwohci_set_intr;
756 sc->intmask = sc->irstat = sc->itstat = 0;
758 /* Init task queue */
759 sc->fc.taskqueue = taskqueue_create_fast("fw_taskq", M_WAITOK,
760 taskqueue_thread_enqueue, &sc->fc.taskqueue);
761 taskqueue_start_threads(&sc->fc.taskqueue, 1, PI_NET, "fw%d_taskq",
762 device_get_unit(dev));
763 TASK_INIT(&sc->fwohci_task_busreset, 2, fwohci_task_busreset, sc);
764 TASK_INIT(&sc->fwohci_task_sid, 1, fwohci_task_sid, sc);
765 TASK_INIT(&sc->fwohci_task_dma, 0, fwohci_task_dma, sc);
768 fwohci_reset(sc, dev);
774 fwohci_timeout(void *arg)
776 struct fwohci_softc *sc;
778 sc = (struct fwohci_softc *)arg;
782 fwohci_cyctimer(struct firewire_comm *fc)
784 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
785 return (OREAD(sc, OHCI_CYCLETIMER));
789 fwohci_detach(struct fwohci_softc *sc, device_t dev)
793 if (sc->sid_buf != NULL)
794 fwdma_free(&sc->fc, &sc->sid_dma);
795 if (sc->fc.config_rom != NULL)
796 fwdma_free(&sc->fc, &sc->crom_dma);
798 fwohci_db_free(&sc->arrq);
799 fwohci_db_free(&sc->arrs);
801 fwohci_db_free(&sc->atrq);
802 fwohci_db_free(&sc->atrs);
804 for (i = 0; i < sc->fc.nisodma; i++) {
805 fwohci_db_free(&sc->it[i]);
806 fwohci_db_free(&sc->ir[i]);
808 if (sc->fc.taskqueue != NULL) {
809 taskqueue_drain(sc->fc.taskqueue, &sc->fwohci_task_busreset);
810 taskqueue_drain(sc->fc.taskqueue, &sc->fwohci_task_sid);
811 taskqueue_drain(sc->fc.taskqueue, &sc->fwohci_task_dma);
812 taskqueue_drain(sc->fc.taskqueue, &sc->fc.task_timeout);
813 taskqueue_free(sc->fc.taskqueue);
814 sc->fc.taskqueue = NULL;
820 #define LAST_DB(dbtr, db) do { \
821 struct fwohcidb_tr *_dbtr = (dbtr); \
822 int _cnt = _dbtr->dbcnt; \
823 db = &_dbtr->db[ (_cnt > 2) ? (_cnt -1) : 0]; \
827 fwohci_execute_db(void *arg, bus_dma_segment_t *segs, int nseg, int error)
829 struct fwohcidb_tr *db_tr;
831 bus_dma_segment_t *s;
834 db_tr = (struct fwohcidb_tr *)arg;
835 db = &db_tr->db[db_tr->dbcnt];
837 if (firewire_debug || error != EFBIG)
838 printf("fwohci_execute_db: error=%d\n", error);
841 for (i = 0; i < nseg; i++) {
843 FWOHCI_DMA_WRITE(db->db.desc.addr, s->ds_addr);
844 FWOHCI_DMA_WRITE(db->db.desc.cmd, s->ds_len);
845 FWOHCI_DMA_WRITE(db->db.desc.res, 0);
852 fwohci_execute_db2(void *arg, bus_dma_segment_t *segs, int nseg,
853 bus_size_t size, int error)
855 fwohci_execute_db(arg, segs, nseg, error);
859 fwohci_start(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
862 int tcode, hdr_len, pl_off;
865 struct fw_xfer *xfer;
867 struct fwohci_txpkthdr *ohcifp;
868 struct fwohcidb_tr *db_tr;
871 struct tcode_info *info;
872 static int maxdesc=0;
874 FW_GLOCK_ASSERT(&sc->fc);
876 if (&sc->atrq == dbch) {
878 } else if (&sc->atrs == dbch) {
884 if (dbch->flags & FWOHCI_DBCH_FULL)
889 xfer = STAILQ_FIRST(&dbch->xferq.q);
894 if (dbch->xferq.queued == 0) {
895 device_printf(sc->fc.dev, "TX queue empty\n");
898 STAILQ_REMOVE_HEAD(&dbch->xferq.q, link);
900 xfer->flag = FWXF_START;
902 fp = &xfer->send.hdr;
903 tcode = fp->mode.common.tcode;
905 ohcifp = (struct fwohci_txpkthdr *) db_tr->db[1].db.immed;
906 info = &tinfo[tcode];
907 hdr_len = pl_off = info->hdr_len;
909 ld = &ohcifp->mode.ld[0];
910 ld[0] = ld[1] = ld[2] = ld[3] = 0;
911 for (i = 0; i < pl_off; i+= 4)
912 ld[i/4] = fp->mode.ld[i/4];
914 ohcifp->mode.common.spd = xfer->send.spd & 0x7;
915 if (tcode == FWTCODE_STREAM) {
917 ohcifp->mode.stream.len = fp->mode.stream.len;
918 } else if (tcode == FWTCODE_PHY) {
920 ld[1] = fp->mode.ld[1];
921 ld[2] = fp->mode.ld[2];
922 ohcifp->mode.common.spd = 0;
923 ohcifp->mode.common.tcode = FWOHCITCODE_PHY;
925 ohcifp->mode.asycomm.dst = fp->mode.hdr.dst;
926 ohcifp->mode.asycomm.srcbus = OHCI_ASYSRCBUS;
927 ohcifp->mode.asycomm.tlrt |= FWRETRY_X;
930 FWOHCI_DMA_WRITE(db->db.desc.cmd,
931 OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | hdr_len);
932 FWOHCI_DMA_WRITE(db->db.desc.addr, 0);
933 FWOHCI_DMA_WRITE(db->db.desc.res, 0);
934 /* Specify bound timer of asy. response */
935 if (&sc->atrs == dbch) {
936 FWOHCI_DMA_WRITE(db->db.desc.res,
937 (OREAD(sc, OHCI_CYCLETIMER) >> 12) + (1 << 13));
939 #if BYTE_ORDER == BIG_ENDIAN
940 if (tcode == FWTCODE_WREQQ || tcode == FWTCODE_RRESQ)
942 for (i = 0; i < hdr_len/4; i++)
943 FWOHCI_DMA_WRITE(ld[i], ld[i]);
948 db = &db_tr->db[db_tr->dbcnt];
949 if (xfer->send.pay_len > 0) {
952 if (xfer->mbuf == NULL) {
953 err = bus_dmamap_load(dbch->dmat, db_tr->dma_map,
954 &xfer->send.payload[0], xfer->send.pay_len,
955 fwohci_execute_db, db_tr,
958 /* XXX we can handle only 6 (=8-2) mbuf chains */
959 err = bus_dmamap_load_mbuf(dbch->dmat, db_tr->dma_map,
961 fwohci_execute_db2, db_tr,
967 device_printf(sc->fc.dev, "EFBIG.\n");
968 m0 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
970 m_copydata(xfer->mbuf, 0,
971 xfer->mbuf->m_pkthdr.len,
973 m0->m_len = m0->m_pkthdr.len =
974 xfer->mbuf->m_pkthdr.len;
979 device_printf(sc->fc.dev, "m_getcl failed.\n");
983 printf("dmamap_load: err=%d\n", err);
984 bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
985 BUS_DMASYNC_PREWRITE);
986 #if 0 /* OHCI_OUTPUT_MODE == 0 */
987 for (i = 2; i < db_tr->dbcnt; i++)
988 FWOHCI_DMA_SET(db_tr->db[i].db.desc.cmd,
992 if (maxdesc < db_tr->dbcnt) {
993 maxdesc = db_tr->dbcnt;
995 device_printf(sc->fc.dev, "%s: maxdesc %d\n", __func__, maxdesc);
999 FWOHCI_DMA_SET(db->db.desc.cmd,
1000 OHCI_OUTPUT_LAST | OHCI_INTERRUPT_ALWAYS | OHCI_BRANCH_ALWAYS);
1001 FWOHCI_DMA_WRITE(db->db.desc.depend,
1002 STAILQ_NEXT(db_tr, link)->bus_addr);
1005 fsegment = db_tr->dbcnt;
1006 if (dbch->pdb_tr != NULL) {
1007 LAST_DB(dbch->pdb_tr, db);
1008 FWOHCI_DMA_SET(db->db.desc.depend, db_tr->dbcnt);
1010 dbch->xferq.queued++;
1011 dbch->pdb_tr = db_tr;
1012 db_tr = STAILQ_NEXT(db_tr, link);
1013 if (db_tr != dbch->bottom) {
1016 device_printf(sc->fc.dev, "fwohci_start: lack of db_trq\n");
1017 dbch->flags |= FWOHCI_DBCH_FULL;
1021 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
1022 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
1024 if (dbch->xferq.flag & FWXFERQ_RUNNING) {
1025 OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
1028 device_printf(sc->fc.dev, "start AT DMA status=%x\n",
1029 OREAD(sc, OHCI_DMACTL(off)));
1030 OWRITE(sc, OHCI_DMACMD(off), dbch->top->bus_addr | fsegment);
1031 OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_RUN);
1032 dbch->xferq.flag |= FWXFERQ_RUNNING;
1040 fwohci_start_atq(struct firewire_comm *fc)
1042 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
1044 fwohci_start(sc, &(sc->atrq));
1045 FW_GUNLOCK(&sc->fc);
1050 fwohci_start_ats(struct firewire_comm *fc)
1052 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
1054 fwohci_start(sc, &(sc->atrs));
1055 FW_GUNLOCK(&sc->fc);
1060 fwohci_txd(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
1063 struct fwohcidb_tr *tr;
1064 struct fwohcidb *db;
1065 struct fw_xfer *xfer;
1069 struct firewire_comm *fc = (struct firewire_comm *)sc;
1071 if (&sc->atrq == dbch) {
1074 } else if (&sc->atrs == dbch) {
1083 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTREAD);
1084 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTWRITE);
1085 while (dbch->xferq.queued > 0) {
1087 status = FWOHCI_DMA_READ(db->db.desc.res) >> OHCI_STATUS_SHIFT;
1088 if (!(status & OHCI_CNTL_DMA_ACTIVE)) {
1089 if (fc->status != FWBUSINIT)
1090 /* maybe out of order?? */
1093 bus_dmamap_sync(dbch->dmat, tr->dma_map,
1094 BUS_DMASYNC_POSTWRITE);
1095 bus_dmamap_unload(dbch->dmat, tr->dma_map);
1097 if (firewire_debug > 1)
1100 if (status & OHCI_CNTL_DMA_DEAD) {
1102 OWRITE(sc, OHCI_DMACTLCLR(off), OHCI_CNTL_DMA_RUN);
1103 device_printf(sc->fc.dev, "force reset AT FIFO\n");
1104 OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_LINKEN);
1105 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LPS | OHCI_HCC_LINKEN);
1106 OWRITE(sc, OHCI_DMACTLCLR(off), OHCI_CNTL_DMA_RUN);
1108 stat = status & FWOHCIEV_MASK;
1110 case FWOHCIEV_ACKPEND:
1111 case FWOHCIEV_ACKCOMPL:
1114 case FWOHCIEV_ACKBSA:
1115 case FWOHCIEV_ACKBSB:
1116 case FWOHCIEV_ACKBSX:
1119 case FWOHCIEV_FLUSHED:
1120 case FWOHCIEV_ACKTARD:
1123 case FWOHCIEV_MISSACK:
1124 case FWOHCIEV_UNDRRUN:
1125 case FWOHCIEV_OVRRUN:
1126 case FWOHCIEV_DESCERR:
1127 case FWOHCIEV_DTRDERR:
1128 case FWOHCIEV_TIMEOUT:
1129 case FWOHCIEV_TCODERR:
1130 case FWOHCIEV_UNKNOWN:
1131 case FWOHCIEV_ACKDERR:
1132 case FWOHCIEV_ACKTERR:
1137 if (tr->xfer != NULL) {
1139 if (xfer->flag & FWXF_RCVD) {
1142 printf("already rcvd\n");
1146 microtime(&xfer->tv);
1147 xfer->flag = FWXF_SENT;
1149 xfer->flag = FWXF_BUSY;
1151 xfer->recv.pay_len = 0;
1153 } else if (stat != FWOHCIEV_ACKPEND) {
1154 if (stat != FWOHCIEV_ACKCOMPL)
1155 xfer->flag = FWXF_SENTERR;
1157 xfer->recv.pay_len = 0;
1162 * The watchdog timer takes care of split
1163 * transaction timeout for ACKPEND case.
1166 printf("this shouldn't happen\n");
1169 dbch->xferq.queued--;
1174 tr = STAILQ_NEXT(tr, link);
1176 if (dbch->bottom == dbch->top) {
1177 /* we reaches the end of context program */
1178 if (firewire_debug && dbch->xferq.queued > 0)
1179 printf("queued > 0\n");
1184 if ((dbch->flags & FWOHCI_DBCH_FULL) && packets > 0) {
1185 printf("make free slot\n");
1186 dbch->flags &= ~FWOHCI_DBCH_FULL;
1188 fwohci_start(sc, dbch);
1195 fwohci_db_free(struct fwohci_dbch *dbch)
1197 struct fwohcidb_tr *db_tr;
1200 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
1203 for (db_tr = STAILQ_FIRST(&dbch->db_trq), idb = 0; idb < dbch->ndb;
1204 db_tr = STAILQ_NEXT(db_tr, link), idb++) {
1205 if ((dbch->xferq.flag & FWXFERQ_EXTBUF) == 0 &&
1206 db_tr->buf != NULL) {
1207 fwdma_free_size(dbch->dmat, db_tr->dma_map,
1208 db_tr->buf, dbch->xferq.psize);
1210 } else if (db_tr->dma_map != NULL)
1211 bus_dmamap_destroy(dbch->dmat, db_tr->dma_map);
1214 db_tr = STAILQ_FIRST(&dbch->db_trq);
1215 fwdma_free_multiseg(dbch->am);
1217 STAILQ_INIT(&dbch->db_trq);
1218 dbch->flags &= ~FWOHCI_DBCH_INIT;
1222 fwohci_db_init(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
1225 struct fwohcidb_tr *db_tr;
1227 if ((dbch->flags & FWOHCI_DBCH_INIT) != 0)
1230 /* create dma_tag for buffers */
1231 #define MAX_REQCOUNT 0xffff
1232 if (bus_dma_tag_create(/*parent*/ sc->fc.dmat,
1233 /*alignment*/ 1, /*boundary*/ 0,
1234 /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
1235 /*highaddr*/ BUS_SPACE_MAXADDR,
1236 /*filter*/NULL, /*filterarg*/NULL,
1237 /*maxsize*/ dbch->xferq.psize,
1238 /*nsegments*/ dbch->ndesc > 3 ? dbch->ndesc - 2 : 1,
1239 /*maxsegsz*/ MAX_REQCOUNT,
1241 /*lockfunc*/busdma_lock_mutex,
1242 /*lockarg*/FW_GMTX(&sc->fc),
1246 /* allocate DB entries and attach one to each DMA channels */
1247 /* DB entry must start at 16 bytes bounary. */
1248 STAILQ_INIT(&dbch->db_trq);
1249 db_tr = (struct fwohcidb_tr *)
1250 malloc(sizeof(struct fwohcidb_tr) * dbch->ndb,
1251 M_FW, M_WAITOK | M_ZERO);
1253 #define DB_SIZE(x) (sizeof(struct fwohcidb) * (x)->ndesc)
1254 dbch->am = fwdma_malloc_multiseg(&sc->fc, sizeof(struct fwohcidb),
1255 DB_SIZE(dbch), dbch->ndb, BUS_DMA_WAITOK);
1256 if (dbch->am == NULL) {
1257 printf("fwohci_db_init: fwdma_malloc_multiseg failed\n");
1261 /* Attach DB to DMA ch. */
1262 for (idb = 0; idb < dbch->ndb; idb++) {
1264 db_tr->db = (struct fwohcidb *)fwdma_v_addr(dbch->am, idb);
1265 db_tr->bus_addr = fwdma_bus_addr(dbch->am, idb);
1266 /* create dmamap for buffers */
1267 /* XXX do we need 4bytes alignment tag? */
1268 /* XXX don't alloc dma_map for AR */
1269 if (bus_dmamap_create(dbch->dmat, 0, &db_tr->dma_map) != 0) {
1270 printf("bus_dmamap_create failed\n");
1271 dbch->flags = FWOHCI_DBCH_INIT; /* XXX fake */
1272 fwohci_db_free(dbch);
1275 STAILQ_INSERT_TAIL(&dbch->db_trq, db_tr, link);
1276 if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
1277 if (idb % dbch->xferq.bnpacket == 0)
1278 dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket
1279 ].start = (caddr_t)db_tr;
1280 if ((idb + 1) % dbch->xferq.bnpacket == 0)
1281 dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket
1282 ].end = (caddr_t)db_tr;
1286 STAILQ_LAST(&dbch->db_trq, fwohcidb_tr,link)->link.stqe_next
1287 = STAILQ_FIRST(&dbch->db_trq);
1289 dbch->xferq.queued = 0;
1290 dbch->pdb_tr = NULL;
1291 dbch->top = STAILQ_FIRST(&dbch->db_trq);
1292 dbch->bottom = dbch->top;
1293 dbch->flags = FWOHCI_DBCH_INIT;
1297 fwohci_itx_disable(struct firewire_comm *fc, int dmach)
1299 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
1301 OWRITE(sc, OHCI_ITCTLCLR(dmach),
1302 OHCI_CNTL_DMA_RUN | OHCI_CNTL_CYCMATCH_S);
1303 OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach);
1304 OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach);
1305 /* XXX we cannot free buffers until the DMA really stops */
1306 pause("fwitxd", hz);
1307 fwohci_db_free(&sc->it[dmach]);
1308 sc->it[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
1313 fwohci_irx_disable(struct firewire_comm *fc, int dmach)
1315 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
1317 OWRITE(sc, OHCI_IRCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
1318 OWRITE(sc, OHCI_IR_MASKCLR, 1 << dmach);
1319 OWRITE(sc, OHCI_IR_STATCLR, 1 << dmach);
1320 /* XXX we cannot free buffers until the DMA really stops */
1321 pause("fwirxd", hz);
1322 fwohci_db_free(&sc->ir[dmach]);
1323 sc->ir[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
1327 #if BYTE_ORDER == BIG_ENDIAN
1329 fwohci_irx_post (struct firewire_comm *fc , uint32_t *qld)
1331 qld[0] = FWOHCI_DMA_READ(qld[0]);
1337 fwohci_tx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
1340 int idb, z, i, dmach = 0, ldesc;
1342 struct fwohcidb_tr *db_tr;
1343 struct fwohcidb *db;
1345 if (!(dbch->xferq.flag & FWXFERQ_EXTBUF)) {
1350 for (dmach = 0; dmach < sc->fc.nisodma; dmach++) {
1351 if (&sc->it[dmach] == dbch) {
1352 off = OHCI_ITOFF(dmach);
1360 if (dbch->xferq.flag & FWXFERQ_RUNNING)
1362 dbch->xferq.flag |= FWXFERQ_RUNNING;
1363 for (i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++) {
1364 dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
1367 for (idb = 0; idb < dbch->ndb; idb++) {
1368 fwohci_add_tx_buf(dbch, db_tr, idb);
1369 if (STAILQ_NEXT(db_tr, link) == NULL) {
1373 ldesc = db_tr->dbcnt - 1;
1374 FWOHCI_DMA_WRITE(db[0].db.desc.depend,
1375 STAILQ_NEXT(db_tr, link)->bus_addr | z);
1376 db[ldesc].db.desc.depend = db[0].db.desc.depend;
1377 if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
1378 if (((idb + 1) % dbch->xferq.bnpacket) == 0) {
1380 db[ldesc].db.desc.cmd,
1381 OHCI_INTERRUPT_ALWAYS);
1382 /* OHCI 1.1 and above */
1385 OHCI_INTERRUPT_ALWAYS);
1388 db_tr = STAILQ_NEXT(db_tr, link);
1391 dbch->bottom->db[dbch->bottom->dbcnt - 1].db.desc.depend, 0xf);
1396 fwohci_rx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
1399 int idb, z, i, dmach = 0, ldesc;
1401 struct fwohcidb_tr *db_tr;
1402 struct fwohcidb *db;
1405 if (&sc->arrq == dbch) {
1407 } else if (&sc->arrs == dbch) {
1410 for (dmach = 0; dmach < sc->fc.nisodma; dmach++) {
1411 if (&sc->ir[dmach] == dbch) {
1412 off = OHCI_IROFF(dmach);
1421 if (dbch->xferq.flag & FWXFERQ_STREAM) {
1422 if (dbch->xferq.flag & FWXFERQ_RUNNING)
1425 if (dbch->xferq.flag & FWXFERQ_RUNNING) {
1430 dbch->xferq.flag |= FWXFERQ_RUNNING;
1431 dbch->top = STAILQ_FIRST(&dbch->db_trq);
1432 for (i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++) {
1433 dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
1436 for (idb = 0; idb < dbch->ndb; idb++) {
1437 fwohci_add_rx_buf(dbch, db_tr, idb, &sc->dummy_dma);
1438 if (STAILQ_NEXT(db_tr, link) == NULL)
1441 ldesc = db_tr->dbcnt - 1;
1442 FWOHCI_DMA_WRITE(db[ldesc].db.desc.depend,
1443 STAILQ_NEXT(db_tr, link)->bus_addr | z);
1444 if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
1445 if (((idb + 1) % dbch->xferq.bnpacket) == 0) {
1447 db[ldesc].db.desc.cmd,
1448 OHCI_INTERRUPT_ALWAYS);
1450 db[ldesc].db.desc.depend,
1454 db_tr = STAILQ_NEXT(db_tr, link);
1457 dbch->bottom->db[db_tr->dbcnt - 1].db.desc.depend, 0xf);
1458 dbch->buf_offset = 0;
1459 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
1460 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
1461 if (dbch->xferq.flag & FWXFERQ_STREAM) {
1464 OWRITE(sc, OHCI_DMACMD(off), dbch->top->bus_addr | z);
1466 OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_RUN);
1471 fwohci_next_cycle(struct firewire_comm *fc, int cycle_now)
1473 int sec, cycle, cycle_match;
1475 cycle = cycle_now & 0x1fff;
1476 sec = cycle_now >> 13;
1477 #define CYCLE_MOD 0x10
1479 #define CYCLE_DELAY 8 /* min delay to start DMA */
1481 #define CYCLE_DELAY 7000 /* min delay to start DMA */
1483 cycle = cycle + CYCLE_DELAY;
1484 if (cycle >= 8000) {
1488 cycle = roundup2(cycle, CYCLE_MOD);
1489 if (cycle >= 8000) {
1496 cycle_match = ((sec << 13) | cycle) & 0x7ffff;
1498 return (cycle_match);
1502 fwohci_itxbuf_enable(struct firewire_comm *fc, int dmach)
1504 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
1506 unsigned short tag, ich;
1507 struct fwohci_dbch *dbch;
1508 int cycle_match, cycle_now, s, ldesc;
1510 struct fw_bulkxfer *first, *chunk, *prev;
1511 struct fw_xferq *it;
1513 dbch = &sc->it[dmach];
1516 tag = (it->flag >> 6) & 3;
1517 ich = it->flag & 0x3f;
1518 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0) {
1519 dbch->ndb = it->bnpacket * it->bnchunk;
1521 fwohci_db_init(sc, dbch);
1522 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
1525 err = fwohci_tx_enable(sc, dbch);
1530 ldesc = dbch->ndesc - 1;
1533 prev = STAILQ_LAST(&it->stdma, fw_bulkxfer, link);
1534 while ((chunk = STAILQ_FIRST(&it->stvalid)) != NULL) {
1535 struct fwohcidb *db;
1537 fwdma_sync_multiseg(it->buf, chunk->poffset, it->bnpacket,
1538 BUS_DMASYNC_PREWRITE);
1539 fwohci_txbufdb(sc, dmach, chunk);
1541 db = ((struct fwohcidb_tr *)(prev->end))->db;
1542 #if 0 /* XXX necessary? */
1543 FWOHCI_DMA_SET(db[ldesc].db.desc.cmd,
1544 OHCI_BRANCH_ALWAYS);
1546 #if 0 /* if bulkxfer->npacket changes */
1547 db[ldesc].db.desc.depend = db[0].db.desc.depend =
1548 ((struct fwohcidb_tr *)
1549 (chunk->start))->bus_addr | dbch->ndesc;
1551 FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
1552 FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
1555 STAILQ_REMOVE_HEAD(&it->stvalid, link);
1556 STAILQ_INSERT_TAIL(&it->stdma, chunk, link);
1560 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
1561 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
1563 stat = OREAD(sc, OHCI_ITCTL(dmach));
1564 if (firewire_debug && (stat & OHCI_CNTL_CYCMATCH_S))
1565 printf("stat 0x%x\n", stat);
1567 if (stat & (OHCI_CNTL_DMA_ACTIVE | OHCI_CNTL_CYCMATCH_S))
1571 OWRITE(sc, OHCI_ITCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
1573 OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach);
1574 OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach);
1575 OWRITE(sc, OHCI_IT_MASK, 1 << dmach);
1576 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IT);
1578 first = STAILQ_FIRST(&it->stdma);
1579 OWRITE(sc, OHCI_ITCMD(dmach),
1580 ((struct fwohcidb_tr *)(first->start))->bus_addr | dbch->ndesc);
1581 if (firewire_debug > 1) {
1582 printf("fwohci_itxbuf_enable: kick 0x%08x\n", stat);
1584 dump_dma(sc, ITX_CH + dmach);
1587 if ((stat & OHCI_CNTL_DMA_RUN) == 0) {
1589 /* Don't start until all chunks are buffered */
1590 if (STAILQ_FIRST(&it->stfree) != NULL)
1594 /* Clear cycle match counter bits */
1595 OWRITE(sc, OHCI_ITCTLCLR(dmach), 0xffff0000);
1597 /* 2bit second + 13bit cycle */
1598 cycle_now = (fc->cyctimer(fc) >> 12) & 0x7fff;
1599 cycle_match = fwohci_next_cycle(fc, cycle_now);
1601 OWRITE(sc, OHCI_ITCTL(dmach),
1602 OHCI_CNTL_CYCMATCH_S | (cycle_match << 16)
1603 | OHCI_CNTL_DMA_RUN);
1605 OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_RUN);
1607 if (firewire_debug > 1) {
1608 printf("cycle_match: 0x%04x->0x%04x\n",
1609 cycle_now, cycle_match);
1610 dump_dma(sc, ITX_CH + dmach);
1611 dump_db(sc, ITX_CH + dmach);
1613 } else if ((stat & OHCI_CNTL_CYCMATCH_S) == 0) {
1614 device_printf(sc->fc.dev,
1615 "IT DMA underrun (0x%08x)\n", stat);
1616 OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_WAKE);
1623 fwohci_irx_enable(struct firewire_comm *fc, int dmach)
1625 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
1626 int err = 0, s, ldesc;
1627 unsigned short tag, ich;
1629 struct fwohci_dbch *dbch;
1630 struct fwohcidb_tr *db_tr;
1631 struct fw_bulkxfer *first, *prev, *chunk;
1632 struct fw_xferq *ir;
1634 dbch = &sc->ir[dmach];
1637 if ((ir->flag & FWXFERQ_RUNNING) == 0) {
1638 tag = (ir->flag >> 6) & 3;
1639 ich = ir->flag & 0x3f;
1640 OWRITE(sc, OHCI_IRMATCH(dmach), tagbit[tag] | ich);
1643 dbch->ndb = ir->bnpacket * ir->bnchunk;
1645 fwohci_db_init(sc, dbch);
1646 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
1648 err = fwohci_rx_enable(sc, dbch);
1653 first = STAILQ_FIRST(&ir->stfree);
1654 if (first == NULL) {
1655 device_printf(fc->dev, "IR DMA no free chunk\n");
1659 ldesc = dbch->ndesc - 1;
1661 if ((ir->flag & FWXFERQ_HANDLER) == 0)
1663 prev = STAILQ_LAST(&ir->stdma, fw_bulkxfer, link);
1664 while ((chunk = STAILQ_FIRST(&ir->stfree)) != NULL) {
1665 struct fwohcidb *db;
1667 #if 1 /* XXX for if_fwe */
1668 if (chunk->mbuf != NULL) {
1669 db_tr = (struct fwohcidb_tr *)(chunk->start);
1671 err = bus_dmamap_load_mbuf(dbch->dmat, db_tr->dma_map,
1672 chunk->mbuf, fwohci_execute_db2, db_tr,
1674 FWOHCI_DMA_SET(db_tr->db[1].db.desc.cmd,
1675 OHCI_UPDATE | OHCI_INPUT_LAST |
1676 OHCI_INTERRUPT_ALWAYS | OHCI_BRANCH_ALWAYS);
1679 db = ((struct fwohcidb_tr *)(chunk->end))->db;
1680 FWOHCI_DMA_WRITE(db[ldesc].db.desc.res, 0);
1681 FWOHCI_DMA_CLEAR(db[ldesc].db.desc.depend, 0xf);
1683 db = ((struct fwohcidb_tr *)(prev->end))->db;
1684 FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
1686 STAILQ_REMOVE_HEAD(&ir->stfree, link);
1687 STAILQ_INSERT_TAIL(&ir->stdma, chunk, link);
1690 if ((ir->flag & FWXFERQ_HANDLER) == 0)
1692 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
1693 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
1695 stat = OREAD(sc, OHCI_IRCTL(dmach));
1696 if (stat & OHCI_CNTL_DMA_ACTIVE)
1698 if (stat & OHCI_CNTL_DMA_RUN) {
1699 OWRITE(sc, OHCI_IRCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
1700 device_printf(sc->fc.dev, "IR DMA overrun (0x%08x)\n", stat);
1704 printf("start IR DMA 0x%x\n", stat);
1705 OWRITE(sc, OHCI_IR_MASKCLR, 1 << dmach);
1706 OWRITE(sc, OHCI_IR_STATCLR, 1 << dmach);
1707 OWRITE(sc, OHCI_IR_MASK, 1 << dmach);
1708 OWRITE(sc, OHCI_IRCTLCLR(dmach), 0xf0000000);
1709 OWRITE(sc, OHCI_IRCTL(dmach), OHCI_CNTL_ISOHDR);
1710 OWRITE(sc, OHCI_IRCMD(dmach),
1711 ((struct fwohcidb_tr *)(first->start))->bus_addr
1713 OWRITE(sc, OHCI_IRCTL(dmach), OHCI_CNTL_DMA_RUN);
1714 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IR);
1716 dump_db(sc, IRX_CH + dmach);
1722 fwohci_stop(struct fwohci_softc *sc, device_t dev)
1726 fwohci_set_intr(&sc->fc, 0);
1728 /* Now stopping all DMA channel */
1729 OWRITE(sc, OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
1730 OWRITE(sc, OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN);
1731 OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
1732 OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
1734 for (i = 0; i < sc->fc.nisodma; i++) {
1735 OWRITE(sc, OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN);
1736 OWRITE(sc, OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN);
1739 #if 0 /* Let dcons(4) be accessed */
1740 /* Stop interrupt */
1741 OWRITE(sc, FWOHCI_INTMASKCLR,
1742 OHCI_INT_EN | OHCI_INT_ERR | OHCI_INT_PHY_SID
1744 | OHCI_INT_DMA_ATRQ | OHCI_INT_DMA_ATRS
1745 | OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS
1746 | OHCI_INT_DMA_ARRQ | OHCI_INT_DMA_ARRS
1747 | OHCI_INT_PHY_BUS_R);
1749 /* FLUSH FIFO and reset Transmitter/Receiver */
1750 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_RESET);
1753 /* XXX Link down? Bus reset? */
1758 fwohci_resume(struct fwohci_softc *sc, device_t dev)
1761 struct fw_xferq *ir;
1762 struct fw_bulkxfer *chunk;
1764 fwohci_reset(sc, dev);
1765 /* XXX resume isochronous receive automatically. (how about TX?) */
1766 for (i = 0; i < sc->fc.nisodma; i++) {
1767 ir = &sc->ir[i].xferq;
1768 if ((ir->flag & FWXFERQ_RUNNING) != 0) {
1769 device_printf(sc->fc.dev,
1770 "resume iso receive ch: %d\n", i);
1771 ir->flag &= ~FWXFERQ_RUNNING;
1772 /* requeue stdma to stfree */
1773 while ((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
1774 STAILQ_REMOVE_HEAD(&ir->stdma, link);
1775 STAILQ_INSERT_TAIL(&ir->stfree, chunk, link);
1777 sc->fc.irx_enable(&sc->fc, i);
1781 bus_generic_resume(dev);
1782 sc->fc.ibr(&sc->fc);
1788 fwohci_dump_intr(struct fwohci_softc *sc, uint32_t stat)
1790 if (stat & OREAD(sc, FWOHCI_INTMASK))
1791 device_printf(fc->dev, "INTERRUPT < %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s> 0x%08x, 0x%08x\n",
1792 stat & OHCI_INT_EN ? "DMA_EN ":"",
1793 stat & OHCI_INT_PHY_REG ? "PHY_REG ":"",
1794 stat & OHCI_INT_CYC_LONG ? "CYC_LONG ":"",
1795 stat & OHCI_INT_ERR ? "INT_ERR ":"",
1796 stat & OHCI_INT_CYC_ERR ? "CYC_ERR ":"",
1797 stat & OHCI_INT_CYC_LOST ? "CYC_LOST ":"",
1798 stat & OHCI_INT_CYC_64SECOND ? "CYC_64SECOND ":"",
1799 stat & OHCI_INT_CYC_START ? "CYC_START ":"",
1800 stat & OHCI_INT_PHY_INT ? "PHY_INT ":"",
1801 stat & OHCI_INT_PHY_BUS_R ? "BUS_RESET ":"",
1802 stat & OHCI_INT_PHY_SID ? "SID ":"",
1803 stat & OHCI_INT_LR_ERR ? "DMA_LR_ERR ":"",
1804 stat & OHCI_INT_PW_ERR ? "DMA_PW_ERR ":"",
1805 stat & OHCI_INT_DMA_IR ? "DMA_IR ":"",
1806 stat & OHCI_INT_DMA_IT ? "DMA_IT " :"",
1807 stat & OHCI_INT_DMA_PRRS ? "DMA_PRRS " :"",
1808 stat & OHCI_INT_DMA_PRRQ ? "DMA_PRRQ " :"",
1809 stat & OHCI_INT_DMA_ARRS ? "DMA_ARRS " :"",
1810 stat & OHCI_INT_DMA_ARRQ ? "DMA_ARRQ " :"",
1811 stat & OHCI_INT_DMA_ATRS ? "DMA_ATRS " :"",
1812 stat & OHCI_INT_DMA_ATRQ ? "DMA_ATRQ " :"",
1813 stat, OREAD(sc, FWOHCI_INTMASK)
1819 fwohci_intr_core(struct fwohci_softc *sc, uint32_t stat, int count)
1821 struct firewire_comm *fc = (struct firewire_comm *)sc;
1822 uintmax_t prequpper;
1823 uint32_t node_id, plen;
1825 FW_GLOCK_ASSERT(fc);
1826 if ((stat & OHCI_INT_PHY_BUS_R) && (fc->status != FWBUSRESET)) {
1827 fc->status = FWBUSRESET;
1828 /* Disable bus reset interrupt until sid recv. */
1829 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_PHY_BUS_R);
1831 device_printf(fc->dev, "%s: BUS reset\n", __func__);
1832 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST);
1833 OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCSRC);
1835 OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
1836 sc->atrq.xferq.flag &= ~FWXFERQ_RUNNING;
1837 OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
1838 sc->atrs.xferq.flag &= ~FWXFERQ_RUNNING;
1841 taskqueue_enqueue(sc->fc.taskqueue, &sc->fwohci_task_busreset);
1843 if (stat & OHCI_INT_PHY_SID) {
1844 /* Enable bus reset interrupt */
1845 OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_PHY_BUS_R);
1846 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_PHY_BUS_R);
1848 /* Allow async. request to us */
1849 OWRITE(sc, OHCI_AREQHI, 1 << 31);
1850 if (firewire_phydma_enable) {
1851 /* allow from all nodes */
1852 OWRITE(sc, OHCI_PREQHI, 0x7fffffff);
1853 OWRITE(sc, OHCI_PREQLO, 0xffffffff);
1854 prequpper = ((uintmax_t)Maxmem << PAGE_SHIFT) >> 16;
1855 if (prequpper > OHCI_PREQUPPER_MAX) {
1856 device_printf(fc->dev,
1857 "Physical memory size of 0x%jx exceeds "
1858 "fire wire address space. Limiting dma "
1859 "to memory below 0x%jx\n",
1860 (uintmax_t)Maxmem << PAGE_SHIFT,
1861 (uintmax_t)OHCI_PREQUPPER_MAX << 16);
1862 prequpper = OHCI_PREQUPPER_MAX;
1864 OWRITE(sc, OHCI_PREQUPPER, prequpper & 0xffffffff);
1865 if (OREAD(sc, OHCI_PREQUPPER) !=
1866 (prequpper & 0xffffffff)) {
1867 device_printf(fc->dev,
1868 "PhysicalUpperBound register is not "
1869 "implemented. Physical memory access "
1870 "is limited to the first 4GB\n");
1871 device_printf(fc->dev,
1872 "PhysicalUpperBound = 0x%08x\n",
1873 OREAD(sc, OHCI_PREQUPPER));
1876 /* Set ATRetries register */
1877 OWRITE(sc, OHCI_ATRETRY, 1<<(13 + 16) | 0xfff);
1880 * Checking whether the node is root or not. If root, turn on
1883 node_id = OREAD(sc, FWOHCI_NODEID);
1884 plen = OREAD(sc, OHCI_SID_CNT);
1886 fc->nodeid = node_id & 0x3f;
1887 device_printf(fc->dev, "%s: node_id=0x%08x, SelfID Count=%d, ",
1888 __func__, fc->nodeid, (plen >> 16) & 0xff);
1889 if (!(node_id & OHCI_NODE_VALID)) {
1890 device_printf(fc->dev, "%s: Bus reset failure\n",
1897 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_CYC_LOST);
1898 if ((node_id & OHCI_NODE_ROOT) && !nocyclemaster) {
1899 printf("CYCLEMASTER mode\n");
1900 OWRITE(sc, OHCI_LNKCTL,
1901 OHCI_CNTL_CYCMTR | OHCI_CNTL_CYCTIMER);
1903 printf("non CYCLEMASTER mode\n");
1904 OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCMTR);
1905 OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_CYCTIMER);
1908 fc->status = FWBUSINIT;
1911 taskqueue_enqueue(sc->fc.taskqueue, &sc->fwohci_task_sid);
1914 if ((stat & ~(OHCI_INT_PHY_BUS_R | OHCI_INT_PHY_SID)) && (!kdb_active))
1915 taskqueue_enqueue(sc->fc.taskqueue, &sc->fwohci_task_dma);
1919 fwohci_intr_dma(struct fwohci_softc *sc, uint32_t stat, int count)
1921 uint32_t irstat, itstat;
1923 struct firewire_comm *fc = (struct firewire_comm *)sc;
1925 if (stat & OHCI_INT_DMA_IR) {
1926 irstat = atomic_readandclear_int(&sc->irstat);
1927 for (i = 0; i < fc->nisodma; i++) {
1928 struct fwohci_dbch *dbch;
1930 if ((irstat & (1 << i)) != 0) {
1932 if ((dbch->xferq.flag & FWXFERQ_OPEN) == 0) {
1933 device_printf(sc->fc.dev,
1934 "dma(%d) not active\n", i);
1937 fwohci_rbuf_update(sc, i);
1941 if (stat & OHCI_INT_DMA_IT) {
1942 itstat = atomic_readandclear_int(&sc->itstat);
1943 for (i = 0; i < fc->nisodma; i++) {
1944 if ((itstat & (1 << i)) != 0) {
1945 fwohci_tbuf_update(sc, i);
1949 if (stat & OHCI_INT_DMA_PRRS) {
1951 dump_dma(sc, ARRS_CH);
1952 dump_db(sc, ARRS_CH);
1954 fwohci_arcv(sc, &sc->arrs, count);
1956 if (stat & OHCI_INT_DMA_PRRQ) {
1958 dump_dma(sc, ARRQ_CH);
1959 dump_db(sc, ARRQ_CH);
1961 fwohci_arcv(sc, &sc->arrq, count);
1963 if (stat & OHCI_INT_CYC_LOST) {
1964 if (sc->cycle_lost >= 0)
1966 if (sc->cycle_lost > 10) {
1967 sc->cycle_lost = -1;
1969 OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCTIMER);
1971 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST);
1972 device_printf(fc->dev, "too many cycles lost, "
1973 "no cycle master present?\n");
1976 if (stat & OHCI_INT_DMA_ATRQ) {
1977 fwohci_txd(sc, &(sc->atrq));
1979 if (stat & OHCI_INT_DMA_ATRS) {
1980 fwohci_txd(sc, &(sc->atrs));
1982 if (stat & OHCI_INT_PW_ERR) {
1983 device_printf(fc->dev, "posted write error\n");
1985 if (stat & OHCI_INT_ERR) {
1986 device_printf(fc->dev, "unrecoverable error\n");
1988 if (stat & OHCI_INT_PHY_INT) {
1989 device_printf(fc->dev, "phy int\n");
1994 fwohci_task_busreset(void *arg, int pending)
1996 struct fwohci_softc *sc = (struct fwohci_softc *)arg;
1999 fw_busreset(&sc->fc, FWBUSRESET);
2000 OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
2001 OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
2002 FW_GUNLOCK(&sc->fc);
2006 fwohci_task_sid(void *arg, int pending)
2008 struct fwohci_softc *sc = (struct fwohci_softc *)arg;
2009 struct firewire_comm *fc = &sc->fc;
2015 * We really should have locking
2016 * here. Not sure why it's not
2018 plen = OREAD(sc, OHCI_SID_CNT);
2020 if (plen & OHCI_SID_ERR) {
2021 device_printf(fc->dev, "SID Error\n");
2024 plen &= OHCI_SID_CNT_MASK;
2025 if (plen < 4 || plen > OHCI_SIDSIZE) {
2026 device_printf(fc->dev, "invalid SID len = %d\n", plen);
2029 plen -= 4; /* chop control info */
2030 buf = (uint32_t *)malloc(OHCI_SIDSIZE, M_FW, M_NOWAIT);
2032 device_printf(fc->dev, "malloc failed\n");
2035 for (i = 0; i < plen / 4; i++)
2036 buf[i] = FWOHCI_DMA_READ(sc->sid_buf[i + 1]);
2038 /* pending all pre-bus_reset packets */
2039 fwohci_txd(sc, &sc->atrq);
2040 fwohci_txd(sc, &sc->atrs);
2041 fwohci_arcv(sc, &sc->arrs, -1);
2042 fwohci_arcv(sc, &sc->arrq, -1);
2044 fw_sidrcv(fc, buf, plen);
2049 fwohci_task_dma(void *arg, int pending)
2051 struct fwohci_softc *sc = (struct fwohci_softc *)arg;
2055 stat = atomic_readandclear_int(&sc->intstat);
2057 fwohci_intr_dma(sc, stat, -1);
2064 fwohci_check_stat(struct fwohci_softc *sc)
2066 uint32_t stat, irstat, itstat;
2068 FW_GLOCK_ASSERT(&sc->fc);
2069 stat = OREAD(sc, FWOHCI_INTSTAT);
2070 if (stat == 0xffffffff) {
2071 if (!bus_child_present(sc->fc.dev))
2072 return (FILTER_HANDLED);
2073 device_printf(sc->fc.dev, "device physically ejected?\n");
2074 return (FILTER_STRAY);
2077 OWRITE(sc, FWOHCI_INTSTATCLR, stat & ~OHCI_INT_PHY_BUS_R);
2079 stat &= sc->intmask;
2081 return (FILTER_STRAY);
2083 atomic_set_int(&sc->intstat, stat);
2084 if (stat & OHCI_INT_DMA_IR) {
2085 irstat = OREAD(sc, OHCI_IR_STAT);
2086 OWRITE(sc, OHCI_IR_STATCLR, irstat);
2087 atomic_set_int(&sc->irstat, irstat);
2089 if (stat & OHCI_INT_DMA_IT) {
2090 itstat = OREAD(sc, OHCI_IT_STAT);
2091 OWRITE(sc, OHCI_IT_STATCLR, itstat);
2092 atomic_set_int(&sc->itstat, itstat);
2095 fwohci_intr_core(sc, stat, -1);
2096 return (FILTER_HANDLED);
2100 fwohci_intr(void *arg)
2102 struct fwohci_softc *sc = (struct fwohci_softc *)arg;
2105 fwohci_check_stat(sc);
2106 FW_GUNLOCK(&sc->fc);
2110 fwohci_poll(struct firewire_comm *fc, int quick, int count)
2112 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
2115 fwohci_check_stat(sc);
2120 fwohci_set_intr(struct firewire_comm *fc, int enable)
2122 struct fwohci_softc *sc;
2124 sc = (struct fwohci_softc *)fc;
2126 device_printf(sc->fc.dev, "fwohci_set_intr: %d\n", enable);
2128 sc->intmask |= OHCI_INT_EN;
2129 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_EN);
2131 sc->intmask &= ~OHCI_INT_EN;
2132 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_EN);
2137 fwohci_tbuf_update(struct fwohci_softc *sc, int dmach)
2139 struct firewire_comm *fc = &sc->fc;
2140 struct fwohcidb *db;
2141 struct fw_bulkxfer *chunk;
2142 struct fw_xferq *it;
2143 uint32_t stat, count;
2147 ldesc = sc->it[dmach].ndesc - 1;
2148 s = splfw(); /* unnecessary ? */
2150 fwdma_sync_multiseg_all(sc->it[dmach].am, BUS_DMASYNC_POSTREAD);
2152 dump_db(sc, ITX_CH + dmach);
2153 while ((chunk = STAILQ_FIRST(&it->stdma)) != NULL) {
2154 db = ((struct fwohcidb_tr *)(chunk->end))->db;
2155 stat = FWOHCI_DMA_READ(db[ldesc].db.desc.res)
2156 >> OHCI_STATUS_SHIFT;
2157 db = ((struct fwohcidb_tr *)(chunk->start))->db;
2159 count = FWOHCI_DMA_READ(db[ldesc].db.desc.res)
2163 STAILQ_REMOVE_HEAD(&it->stdma, link);
2164 switch (stat & FWOHCIEV_MASK) {
2165 case FWOHCIEV_ACKCOMPL:
2167 device_printf(fc->dev, "0x%08x\n", count);
2171 device_printf(fc->dev,
2172 "Isochronous transmit err %02x(%s)\n",
2173 stat, fwohcicode[stat & 0x1f]);
2175 STAILQ_INSERT_TAIL(&it->stfree, chunk, link);
2185 fwohci_rbuf_update(struct fwohci_softc *sc, int dmach)
2187 struct firewire_comm *fc = &sc->fc;
2188 struct fwohcidb_tr *db_tr;
2189 struct fw_bulkxfer *chunk;
2190 struct fw_xferq *ir;
2195 ldesc = sc->ir[dmach].ndesc - 1;
2200 if ((ir->flag & FWXFERQ_HANDLER) == 0)
2202 fwdma_sync_multiseg_all(sc->ir[dmach].am, BUS_DMASYNC_POSTREAD);
2203 while ((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
2204 db_tr = (struct fwohcidb_tr *)chunk->end;
2205 stat = FWOHCI_DMA_READ(db_tr->db[ldesc].db.desc.res)
2206 >> OHCI_STATUS_SHIFT;
2210 if (chunk->mbuf != NULL) {
2211 bus_dmamap_sync(sc->ir[dmach].dmat, db_tr->dma_map,
2212 BUS_DMASYNC_POSTREAD);
2213 bus_dmamap_unload(sc->ir[dmach].dmat, db_tr->dma_map);
2214 } else if (ir->buf != NULL) {
2215 fwdma_sync_multiseg(ir->buf, chunk->poffset,
2216 ir->bnpacket, BUS_DMASYNC_POSTREAD);
2219 printf("fwohci_rbuf_update: this shouldn't happened\n");
2222 STAILQ_REMOVE_HEAD(&ir->stdma, link);
2223 STAILQ_INSERT_TAIL(&ir->stvalid, chunk, link);
2224 switch (stat & FWOHCIEV_MASK) {
2225 case FWOHCIEV_ACKCOMPL:
2229 chunk->resp = EINVAL;
2230 device_printf(fc->dev,
2231 "Isochronous receive err %02x(%s)\n",
2232 stat, fwohcicode[stat & 0x1f]);
2236 if ((ir->flag & FWXFERQ_HANDLER) == 0)
2241 if (ir->flag & FWXFERQ_HANDLER)
2248 dump_dma(struct fwohci_softc *sc, uint32_t ch)
2250 uint32_t off, cntl, stat, cmd, match;
2254 } else if (ch == 1) {
2256 } else if (ch == 2) {
2258 } else if (ch == 3) {
2260 } else if (ch < IRX_CH) {
2261 off = OHCI_ITCTL(ch - ITX_CH);
2263 off = OHCI_IRCTL(ch - IRX_CH);
2265 cntl = stat = OREAD(sc, off);
2266 cmd = OREAD(sc, off + 0xc);
2267 match = OREAD(sc, off + 0x10);
2269 device_printf(sc->fc.dev, "ch %1x cntl:0x%08x cmd:0x%08x match:0x%08x\n",
2276 device_printf(sc->fc.dev, "dma %d ch:%s%s%s%s%s%s %s(%x)\n",
2278 stat & OHCI_CNTL_DMA_RUN ? "RUN," : "",
2279 stat & OHCI_CNTL_DMA_WAKE ? "WAKE," : "",
2280 stat & OHCI_CNTL_DMA_DEAD ? "DEAD," : "",
2281 stat & OHCI_CNTL_DMA_ACTIVE ? "ACTIVE," : "",
2282 stat & OHCI_CNTL_DMA_BT ? "BRANCH," : "",
2283 stat & OHCI_CNTL_DMA_BAD ? "BADDMA," : "",
2284 fwohcicode[stat & 0x1f],
2288 device_printf(sc->fc.dev, "dma %d ch: Nostat\n", ch);
2293 dump_db(struct fwohci_softc *sc, uint32_t ch)
2295 struct fwohci_dbch *dbch;
2296 struct fwohcidb_tr *cp = NULL, *pp, *np = NULL;
2297 struct fwohcidb *curr = NULL, *prev, *next = NULL;
2304 } else if (ch == 1) {
2307 } else if (ch == 2) {
2310 } else if (ch == 3) {
2313 } else if (ch < IRX_CH) {
2314 off = OHCI_ITCTL(ch - ITX_CH);
2315 dbch = &sc->it[ch - ITX_CH];
2317 off = OHCI_IRCTL(ch - IRX_CH);
2318 dbch = &sc->ir[ch - IRX_CH];
2320 cmd = OREAD(sc, off + 0xc);
2322 if (dbch->ndb == 0) {
2323 device_printf(sc->fc.dev, "No DB is attached ch=%d\n", ch);
2328 for (idb = 0; idb < dbch->ndb; idb++) {
2329 cp = STAILQ_NEXT(pp, link);
2334 np = STAILQ_NEXT(cp, link);
2335 for (jdb = 0; jdb < dbch->ndesc; jdb++) {
2336 if ((cmd & 0xfffffff0) == cp->bus_addr) {
2346 pp = STAILQ_NEXT(pp, link);
2356 printf("Prev DB %d\n", ch);
2357 print_db(pp, prev, ch, dbch->ndesc);
2359 printf("Current DB %d\n", ch);
2360 print_db(cp, curr, ch, dbch->ndesc);
2362 printf("Next DB %d\n", ch);
2363 print_db(np, next, ch, dbch->ndesc);
2366 printf("dbdump err ch = %d cmd = 0x%08x\n", ch, cmd);
2372 print_db(struct fwohcidb_tr *db_tr, struct fwohcidb *db,
2373 uint32_t ch, uint32_t max)
2380 printf("No Descriptor is found\n");
2384 printf("ch = %d\n%8s %s %s %s %s %4s %8s %8s %4s:%4s\n",
2396 for (i = 0; i <= max; i++) {
2397 cmd = FWOHCI_DMA_READ(db[i].db.desc.cmd);
2398 res = FWOHCI_DMA_READ(db[i].db.desc.res);
2399 key = cmd & OHCI_KEY_MASK;
2400 stat = res >> OHCI_STATUS_SHIFT;
2401 printf("%08jx %s %s %s %s %5d %08x %08x %04x:%04x",
2402 (uintmax_t)db_tr->bus_addr,
2403 dbcode[(cmd >> 28) & 0xf],
2404 dbkey[(cmd >> 24) & 0x7],
2405 dbcond[(cmd >> 20) & 0x3],
2406 dbcond[(cmd >> 18) & 0x3],
2407 cmd & OHCI_COUNT_MASK,
2408 FWOHCI_DMA_READ(db[i].db.desc.addr),
2409 FWOHCI_DMA_READ(db[i].db.desc.depend),
2411 res & OHCI_COUNT_MASK);
2412 if (stat & 0xff00) {
2413 printf(" %s%s%s%s%s%s %s(%x)\n",
2414 stat & OHCI_CNTL_DMA_RUN ? "RUN," : "",
2415 stat & OHCI_CNTL_DMA_WAKE ? "WAKE," : "",
2416 stat & OHCI_CNTL_DMA_DEAD ? "DEAD," : "",
2417 stat & OHCI_CNTL_DMA_ACTIVE ? "ACTIVE," : "",
2418 stat & OHCI_CNTL_DMA_BT ? "BRANCH," : "",
2419 stat & OHCI_CNTL_DMA_BAD ? "BADDMA," : "",
2420 fwohcicode[stat & 0x1f],
2424 printf(" Nostat\n");
2426 if (key == OHCI_KEY_ST2) {
2427 printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
2428 FWOHCI_DMA_READ(db[i + 1].db.immed[0]),
2429 FWOHCI_DMA_READ(db[i + 1].db.immed[1]),
2430 FWOHCI_DMA_READ(db[i + 1].db.immed[2]),
2431 FWOHCI_DMA_READ(db[i + 1].db.immed[3]));
2433 if (key == OHCI_KEY_DEVICE) {
2436 if ((cmd & OHCI_BRANCH_MASK)
2437 == OHCI_BRANCH_ALWAYS) {
2440 if ((cmd & OHCI_CMD_MASK)
2441 == OHCI_OUTPUT_LAST) {
2444 if ((cmd & OHCI_CMD_MASK)
2445 == OHCI_INPUT_LAST) {
2448 if (key == OHCI_KEY_ST2) {
2456 fwohci_ibr(struct firewire_comm *fc)
2458 struct fwohci_softc *sc;
2461 device_printf(fc->dev, "Initiate bus reset\n");
2462 sc = (struct fwohci_softc *)fc;
2466 * Make sure our cached values from the config rom are
2469 OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
2470 OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
2473 * Set root hold-off bit so that non cyclemaster capable node
2474 * shouldn't became the root node.
2477 fun = fwphy_rddata(sc, FW_PHY_IBR_REG);
2478 fun |= FW_PHY_IBR | FW_PHY_RHB;
2479 fun = fwphy_wrdata(sc, FW_PHY_IBR_REG, fun);
2480 #else /* Short bus reset */
2481 fun = fwphy_rddata(sc, FW_PHY_ISBR_REG);
2482 fun |= FW_PHY_ISBR | FW_PHY_RHB;
2483 fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun);
2489 fwohci_txbufdb(struct fwohci_softc *sc, int dmach, struct fw_bulkxfer *bulkxfer)
2491 struct fwohcidb_tr *db_tr, *fdb_tr;
2492 struct fwohci_dbch *dbch;
2493 struct fwohcidb *db;
2495 struct fwohci_txpkthdr *ohcifp;
2496 unsigned short chtag;
2499 FW_GLOCK_ASSERT(&sc->fc);
2501 dbch = &sc->it[dmach];
2502 chtag = sc->it[dmach].xferq.flag & 0xff;
2504 db_tr = (struct fwohcidb_tr *)(bulkxfer->start);
2505 fdb_tr = (struct fwohcidb_tr *)(bulkxfer->end);
2507 device_printf(sc->fc.dev, "DB %08x %08x %08x\n", bulkxfer, db_tr->bus_addr, fdb_tr->bus_addr);
2509 for (idb = 0; idb < dbch->xferq.bnpacket; idb++) {
2511 fp = (struct fw_pkt *)db_tr->buf;
2512 ohcifp = (struct fwohci_txpkthdr *) db[1].db.immed;
2513 ohcifp->mode.ld[0] = fp->mode.ld[0];
2514 ohcifp->mode.common.spd = 0 & 0x7;
2515 ohcifp->mode.stream.len = fp->mode.stream.len;
2516 ohcifp->mode.stream.chtag = chtag;
2517 ohcifp->mode.stream.tcode = 0xa;
2518 #if BYTE_ORDER == BIG_ENDIAN
2519 FWOHCI_DMA_WRITE(db[1].db.immed[0], db[1].db.immed[0]);
2520 FWOHCI_DMA_WRITE(db[1].db.immed[1], db[1].db.immed[1]);
2523 FWOHCI_DMA_CLEAR(db[2].db.desc.cmd, OHCI_COUNT_MASK);
2524 FWOHCI_DMA_SET(db[2].db.desc.cmd, fp->mode.stream.len);
2525 FWOHCI_DMA_WRITE(db[2].db.desc.res, 0);
2526 #if 0 /* if bulkxfer->npackets changes */
2527 db[2].db.desc.cmd = OHCI_OUTPUT_LAST
2529 | OHCI_BRANCH_ALWAYS;
2530 db[0].db.desc.depend =
2531 = db[dbch->ndesc - 1].db.desc.depend
2532 = STAILQ_NEXT(db_tr, link)->bus_addr | dbch->ndesc;
2534 FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
2535 FWOHCI_DMA_SET(db[dbch->ndesc - 1].db.desc.depend, dbch->ndesc);
2537 bulkxfer->end = (caddr_t)db_tr;
2538 db_tr = STAILQ_NEXT(db_tr, link);
2540 db = ((struct fwohcidb_tr *)bulkxfer->end)->db;
2541 FWOHCI_DMA_CLEAR(db[0].db.desc.depend, 0xf);
2542 FWOHCI_DMA_CLEAR(db[dbch->ndesc - 1].db.desc.depend, 0xf);
2543 #if 0 /* if bulkxfer->npackets changes */
2544 db[dbch->ndesc - 1].db.desc.control |= OHCI_INTERRUPT_ALWAYS;
2545 /* OHCI 1.1 and above */
2546 db[0].db.desc.control |= OHCI_INTERRUPT_ALWAYS;
2549 db_tr = (struct fwohcidb_tr *)bulkxfer->start;
2550 fdb_tr = (struct fwohcidb_tr *)bulkxfer->end;
2551 device_printf(sc->fc.dev, "DB %08x %3d %08x %08x\n", bulkxfer, bulkxfer->npacket, db_tr->bus_addr, fdb_tr->bus_addr);
2557 fwohci_add_tx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
2560 struct fwohcidb *db = db_tr->db;
2561 struct fw_xferq *it;
2569 db_tr->buf = fwdma_v_addr(it->buf, poffset);
2572 FWOHCI_DMA_WRITE(db[0].db.desc.cmd,
2573 OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | 8);
2574 FWOHCI_DMA_WRITE(db[0].db.desc.addr, 0);
2575 bzero((void *)&db[1].db.immed[0], sizeof(db[1].db.immed));
2576 FWOHCI_DMA_WRITE(db[2].db.desc.addr,
2577 fwdma_bus_addr(it->buf, poffset) + sizeof(uint32_t));
2579 FWOHCI_DMA_WRITE(db[2].db.desc.cmd,
2580 OHCI_OUTPUT_LAST | OHCI_UPDATE | OHCI_BRANCH_ALWAYS);
2582 FWOHCI_DMA_WRITE(db[0].db.desc.res, 0);
2583 FWOHCI_DMA_WRITE(db[2].db.desc.res, 0);
2589 fwohci_add_rx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
2590 int poffset, struct fwdma_alloc *dummy_dma)
2592 struct fwohcidb *db = db_tr->db;
2593 struct fw_xferq *ir;
2599 if (ir->buf == NULL && (dbch->xferq.flag & FWXFERQ_EXTBUF) == 0) {
2600 if (db_tr->buf == NULL) {
2601 db_tr->buf = fwdma_malloc_size(dbch->dmat,
2602 &db_tr->dma_map, ir->psize, &dbuf[0],
2604 if (db_tr->buf == NULL)
2608 dsiz[0] = ir->psize;
2609 bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
2610 BUS_DMASYNC_PREREAD);
2613 if (dummy_dma != NULL) {
2614 dsiz[db_tr->dbcnt] = sizeof(uint32_t);
2615 dbuf[db_tr->dbcnt++] = dummy_dma->bus_addr;
2617 dsiz[db_tr->dbcnt] = ir->psize;
2618 if (ir->buf != NULL) {
2619 db_tr->buf = fwdma_v_addr(ir->buf, poffset);
2620 dbuf[db_tr->dbcnt] = fwdma_bus_addr(ir->buf, poffset);
2624 for (i = 0; i < db_tr->dbcnt; i++) {
2625 FWOHCI_DMA_WRITE(db[i].db.desc.addr, dbuf[i]);
2626 FWOHCI_DMA_WRITE(db[i].db.desc.cmd, OHCI_INPUT_MORE | dsiz[i]);
2627 if (ir->flag & FWXFERQ_STREAM) {
2628 FWOHCI_DMA_SET(db[i].db.desc.cmd, OHCI_UPDATE);
2630 FWOHCI_DMA_WRITE(db[i].db.desc.res, dsiz[i]);
2632 ldesc = db_tr->dbcnt - 1;
2633 if (ir->flag & FWXFERQ_STREAM) {
2634 FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_INPUT_LAST);
2636 FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_BRANCH_ALWAYS);
2642 fwohci_arcv_swap(struct fw_pkt *fp, int len)
2647 #if BYTE_ORDER == BIG_ENDIAN
2651 ld0 = FWOHCI_DMA_READ(fp->mode.ld[0]);
2653 printf("ld0: x%08x\n", ld0);
2655 fp0 = (struct fw_pkt *)&ld0;
2656 /* determine length to swap */
2657 switch (fp0->mode.common.tcode) {
2662 case FWOHCITCODE_PHY:
2673 printf("Unknown tcode %d\n", fp0->mode.common.tcode);
2676 hlen = tinfo[fp0->mode.common.tcode].hdr_len;
2679 printf("splitted header\n");
2682 #if BYTE_ORDER == BIG_ENDIAN
2683 for (i = 0; i < slen/4; i++)
2684 fp->mode.ld[i] = FWOHCI_DMA_READ(fp->mode.ld[i]);
2690 fwohci_get_plen(struct fwohci_softc *sc, struct fwohci_dbch *dbch, struct fw_pkt *fp)
2692 struct tcode_info *info;
2695 info = &tinfo[fp->mode.common.tcode];
2696 r = info->hdr_len + sizeof(uint32_t);
2697 if ((info->flag & FWTI_BLOCK_ASY) != 0)
2698 r += roundup2(fp->mode.wreqb.len, sizeof(uint32_t));
2700 if (r == sizeof(uint32_t)) {
2702 device_printf(sc->fc.dev, "Unknown tcode %d\n",
2703 fp->mode.common.tcode);
2707 if (r > dbch->xferq.psize) {
2708 device_printf(sc->fc.dev, "Invalid packet length %d\n", r);
2717 fwohci_arcv_free_buf(struct fwohci_softc *sc, struct fwohci_dbch *dbch,
2718 struct fwohcidb_tr *db_tr, uint32_t off, int wake)
2720 struct fwohcidb *db = &db_tr->db[0];
2722 FWOHCI_DMA_CLEAR(db->db.desc.depend, 0xf);
2723 FWOHCI_DMA_WRITE(db->db.desc.res, dbch->xferq.psize);
2724 FWOHCI_DMA_SET(dbch->bottom->db[0].db.desc.depend, 1);
2725 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
2726 dbch->bottom = db_tr;
2729 OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
2733 fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count)
2735 struct fwohcidb_tr *db_tr;
2736 struct iovec vec[2];
2737 struct fw_pkt pktbuf;
2741 uint32_t stat, off, status, event;
2743 int len, plen, hlen, pcnt, offset;
2748 if (&sc->arrq == dbch) {
2750 } else if (&sc->arrs == dbch) {
2759 /* XXX we cannot handle a packet which lies in more than two buf */
2760 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTREAD);
2761 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTWRITE);
2762 status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) >> OHCI_STATUS_SHIFT;
2763 resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) & OHCI_COUNT_MASK;
2764 while (status & OHCI_CNTL_DMA_ACTIVE) {
2767 if (off == OHCI_ARQOFF)
2768 printf("buf 0x%08x, status 0x%04x, resCount 0x%04x\n",
2769 db_tr->bus_addr, status, resCount);
2771 len = dbch->xferq.psize - resCount;
2772 ld = (uint8_t *)db_tr->buf;
2773 if (dbch->pdb_tr == NULL) {
2774 len -= dbch->buf_offset;
2775 ld += dbch->buf_offset;
2778 bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
2779 BUS_DMASYNC_POSTREAD);
2781 if (count >= 0 && count-- == 0)
2783 if (dbch->pdb_tr != NULL) {
2784 /* we have a fragment in previous buffer */
2787 offset = dbch->buf_offset;
2790 buf = dbch->pdb_tr->buf + offset;
2791 rlen = dbch->xferq.psize - offset;
2793 printf("rlen=%d, offset=%d\n",
2794 rlen, dbch->buf_offset);
2795 if (dbch->buf_offset < 0) {
2796 /* splitted in header, pull up */
2799 p = (char *)&pktbuf;
2800 bcopy(buf, p, rlen);
2802 /* this must be too long but harmless */
2803 rlen = sizeof(pktbuf) - rlen;
2805 printf("why rlen < 0\n");
2806 bcopy(db_tr->buf, p, rlen);
2809 hlen = fwohci_arcv_swap(&pktbuf, sizeof(pktbuf));
2811 printf("hlen should be positive.");
2814 offset = sizeof(pktbuf);
2815 vec[0].iov_base = (char *)&pktbuf;
2816 vec[0].iov_len = offset;
2818 /* splitted in payload */
2820 vec[0].iov_base = buf;
2821 vec[0].iov_len = rlen;
2823 fp=(struct fw_pkt *)vec[0].iov_base;
2826 /* no fragment in previous buffer */
2827 fp=(struct fw_pkt *)ld;
2828 hlen = fwohci_arcv_swap(fp, len);
2832 dbch->pdb_tr = db_tr;
2833 dbch->buf_offset = - dbch->buf_offset;
2835 if (resCount != 0) {
2836 printf("resCount=%d hlen=%d\n",
2845 plen = fwohci_get_plen(sc, dbch, fp) - offset;
2847 /* minimum header size + trailer
2848 = sizeof(fw_pkt) so this shouldn't happens */
2849 printf("plen(%d) is negative! offset=%d\n",
2856 dbch->pdb_tr = db_tr;
2858 printf("splitted payload\n");
2860 if (resCount != 0) {
2861 printf("resCount=%d plen=%d"
2863 resCount, plen, len);
2868 vec[nvec].iov_base = ld;
2869 vec[nvec].iov_len = plen;
2873 dbch->buf_offset = ld - (uint8_t *)db_tr->buf;
2875 printf("nvec == 0\n");
2877 /* DMA result-code will be written at the tail of packet */
2878 stat = FWOHCI_DMA_READ(*(uint32_t *)(ld - sizeof(struct fwohci_trailer)));
2880 printf("plen: %d, stat %x\n",
2883 spd = (stat >> 21) & 0x3;
2884 event = (stat >> 16) & 0x1f;
2886 case FWOHCIEV_ACKPEND:
2888 printf("fwohci_arcv: ack pending tcode=0x%x..\n", fp->mode.common.tcode);
2891 case FWOHCIEV_ACKCOMPL:
2893 struct fw_rcv_buf rb;
2895 if ((vec[nvec-1].iov_len -=
2896 sizeof(struct fwohci_trailer)) == 0)
2905 case FWOHCIEV_BUSRST:
2906 if ((sc->fc.status != FWBUSRESET) &&
2907 (sc->fc.status != FWBUSINIT))
2908 printf("got BUSRST packet!?\n");
2911 device_printf(sc->fc.dev,
2912 "Async DMA Receive error err=%02x %s"
2913 " plen=%d offset=%d len=%d status=0x%08x"
2914 " tcode=0x%x, stat=0x%08x\n",
2915 event, fwohcicode[event], plen,
2916 dbch->buf_offset, len,
2917 OREAD(sc, OHCI_DMACTL(off)),
2918 fp->mode.common.tcode, stat);
2925 if (dbch->pdb_tr != NULL) {
2926 fwohci_arcv_free_buf(sc, dbch, dbch->pdb_tr,
2928 dbch->pdb_tr = NULL;
2933 if (resCount == 0) {
2934 /* done on this buffer */
2935 if (dbch->pdb_tr == NULL) {
2936 fwohci_arcv_free_buf(sc, dbch, db_tr, off, 1);
2937 dbch->buf_offset = 0;
2939 if (dbch->pdb_tr != db_tr)
2940 printf("pdb_tr != db_tr\n");
2941 db_tr = STAILQ_NEXT(db_tr, link);
2942 status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
2943 >> OHCI_STATUS_SHIFT;
2944 resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
2946 /* XXX check buffer overrun */
2949 dbch->buf_offset = dbch->xferq.psize - resCount;
2952 /* XXX make sure DMA is not dead */
2956 printf("fwohci_arcv: no packets\n");
2962 device_printf(sc->fc.dev, "AR DMA status=%x, ",
2963 OREAD(sc, OHCI_DMACTL(off)));
2964 dbch->pdb_tr = NULL;
2965 /* skip until resCount != 0 */
2966 printf(" skip buffer");
2967 while (resCount == 0) {
2969 fwohci_arcv_free_buf(sc, dbch, db_tr, off, 0);
2970 db_tr = STAILQ_NEXT(db_tr, link);
2971 resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
2976 dbch->buf_offset = dbch->xferq.psize - resCount;
2977 OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);