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>
44 #include <sys/malloc.h>
45 #include <sys/sockio.h>
46 #include <sys/sysctl.h>
48 #include <sys/kernel.h>
50 #include <sys/endian.h>
53 #include <machine/bus.h>
54 #include <machine/md_var.h>
56 #include <dev/firewire/firewire.h>
57 #include <dev/firewire/firewirereg.h>
58 #include <dev/firewire/fwdma.h>
59 #include <dev/firewire/fwohcireg.h>
60 #include <dev/firewire/fwohcivar.h>
61 #include <dev/firewire/firewire_phy.h>
65 static int nocyclemaster;
66 int firewire_phydma_enable = 1;
67 SYSCTL_DECL(_hw_firewire);
68 SYSCTL_INT(_hw_firewire, OID_AUTO, nocyclemaster, CTLFLAG_RWTUN,
69 &nocyclemaster, 0, "Do not send cycle start packets");
70 SYSCTL_INT(_hw_firewire, OID_AUTO, phydma_enable, CTLFLAG_RWTUN,
71 &firewire_phydma_enable, 0, "Allow physical request DMA from firewire");
73 static char dbcode[16][0x10] = {"OUTM", "OUTL", "INPM", "INPL",
74 "STOR", "LOAD", "NOP ", "STOP",};
76 static char dbkey[8][0x10] = {"ST0", "ST1", "ST2", "ST3",
77 "UNDEF", "REG", "SYS", "DEV"};
78 static char dbcond[4][0x10] = {"NEV", "C=1", "C=0", "ALL"};
79 char fwohcicode[32][0x20]= {
80 "No stat", "Undef", "long", "miss Ack err",
81 "FIFO underrun", "FIFO overrun", "desc err", "data read err",
82 "data write err", "bus reset", "timeout", "tcode err",
83 "Undef", "Undef", "unknown event", "flushed",
84 "Undef" ,"ack complete", "ack pend", "Undef",
85 "ack busy_X", "ack busy_A", "ack busy_B", "Undef",
86 "Undef", "Undef", "Undef", "ack tardy",
87 "Undef", "ack data_err", "ack type_err", ""};
90 extern char *linkspeed[];
91 uint32_t tagbit[4] = {1 << 28, 1 << 29, 1 << 30, 1 << 31};
93 static struct tcode_info tinfo[] = {
94 /* hdr_len block flag valid_response */
95 /* 0 WREQQ */ {16, FWTI_REQ | FWTI_TLABEL, FWTCODE_WRES},
96 /* 1 WREQB */ {16, FWTI_REQ | FWTI_TLABEL | FWTI_BLOCK_ASY, FWTCODE_WRES},
97 /* 2 WRES */ {12, FWTI_RES, 0xff},
98 /* 3 XXX */ { 0, 0, 0xff},
99 /* 4 RREQQ */ {12, FWTI_REQ | FWTI_TLABEL, FWTCODE_RRESQ},
100 /* 5 RREQB */ {16, FWTI_REQ | FWTI_TLABEL, FWTCODE_RRESB},
101 /* 6 RRESQ */ {16, FWTI_RES, 0xff},
102 /* 7 RRESB */ {16, FWTI_RES | FWTI_BLOCK_ASY, 0xff},
103 /* 8 CYCS */ { 0, 0, 0xff},
104 /* 9 LREQ */ {16, FWTI_REQ | FWTI_TLABEL | FWTI_BLOCK_ASY, FWTCODE_LRES},
105 /* a STREAM */ { 4, FWTI_REQ | FWTI_BLOCK_STR, 0xff},
106 /* b LRES */ {16, FWTI_RES | FWTI_BLOCK_ASY, 0xff},
107 /* c XXX */ { 0, 0, 0xff},
108 /* d XXX */ { 0, 0, 0xff},
109 /* e PHY */ {12, FWTI_REQ, 0xff},
110 /* f XXX */ { 0, 0, 0xff}
120 #define OHCI_WRITE_SIGMASK 0xffff0000
121 #define OHCI_READ_SIGMASK 0xffff0000
123 #define OWRITE(sc, r, x) bus_space_write_4((sc)->bst, (sc)->bsh, (r), (x))
124 #define OREAD(sc, r) bus_space_read_4((sc)->bst, (sc)->bsh, (r))
126 static void fwohci_ibr (struct firewire_comm *);
127 static void fwohci_db_init (struct fwohci_softc *, struct fwohci_dbch *);
128 static void fwohci_db_free (struct fwohci_dbch *);
129 static void fwohci_arcv (struct fwohci_softc *, struct fwohci_dbch *, int);
130 static void fwohci_txd (struct fwohci_softc *, struct fwohci_dbch *);
131 static void fwohci_start_atq (struct firewire_comm *);
132 static void fwohci_start_ats (struct firewire_comm *);
133 static void fwohci_start (struct fwohci_softc *, struct fwohci_dbch *);
134 static uint32_t fwphy_wrdata (struct fwohci_softc *, uint32_t, uint32_t);
135 static uint32_t fwphy_rddata (struct fwohci_softc *, uint32_t);
136 static int fwohci_rx_enable (struct fwohci_softc *, struct fwohci_dbch *);
137 static int fwohci_tx_enable (struct fwohci_softc *, struct fwohci_dbch *);
138 static int fwohci_irx_enable (struct firewire_comm *, int);
139 static int fwohci_irx_disable (struct firewire_comm *, int);
140 #if BYTE_ORDER == BIG_ENDIAN
141 static void fwohci_irx_post (struct firewire_comm *, uint32_t *);
143 static int fwohci_itxbuf_enable (struct firewire_comm *, int);
144 static int fwohci_itx_disable (struct firewire_comm *, int);
145 static void fwohci_timeout (void *);
146 static void fwohci_set_intr (struct firewire_comm *, int);
148 static int fwohci_add_rx_buf (struct fwohci_dbch *, struct fwohcidb_tr *, int, struct fwdma_alloc *);
149 static int fwohci_add_tx_buf (struct fwohci_dbch *, struct fwohcidb_tr *, int);
150 static void dump_db (struct fwohci_softc *, uint32_t);
151 static void print_db (struct fwohcidb_tr *, struct fwohcidb *, uint32_t , uint32_t);
152 static void dump_dma (struct fwohci_softc *, uint32_t);
153 static uint32_t fwohci_cyctimer (struct firewire_comm *);
154 static void fwohci_rbuf_update (struct fwohci_softc *, int);
155 static void fwohci_tbuf_update (struct fwohci_softc *, int);
156 void fwohci_txbufdb (struct fwohci_softc *, int , struct fw_bulkxfer *);
157 static void fwohci_task_busreset(void *, int);
158 static void fwohci_task_sid(void *, int);
159 static void fwohci_task_dma(void *, int);
162 * memory allocated for DMA programs
164 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
166 #define NDB FWMAXQUEUE
168 #define OHCI_VERSION 0x00
169 #define OHCI_ATRETRY 0x08
170 #define OHCI_CROMHDR 0x18
171 #define OHCI_BUS_OPT 0x20
172 #define OHCI_BUSIRMC (1U << 31)
173 #define OHCI_BUSCMC (1 << 30)
174 #define OHCI_BUSISC (1 << 29)
175 #define OHCI_BUSBMC (1 << 28)
176 #define OHCI_BUSPMC (1 << 27)
177 #define OHCI_BUSFNC OHCI_BUSIRMC | OHCI_BUSCMC | OHCI_BUSISC |\
178 OHCI_BUSBMC | OHCI_BUSPMC
180 #define OHCI_EUID_HI 0x24
181 #define OHCI_EUID_LO 0x28
183 #define OHCI_CROMPTR 0x34
184 #define OHCI_HCCCTL 0x50
185 #define OHCI_HCCCTLCLR 0x54
186 #define OHCI_AREQHI 0x100
187 #define OHCI_AREQHICLR 0x104
188 #define OHCI_AREQLO 0x108
189 #define OHCI_AREQLOCLR 0x10c
190 #define OHCI_PREQHI 0x110
191 #define OHCI_PREQHICLR 0x114
192 #define OHCI_PREQLO 0x118
193 #define OHCI_PREQLOCLR 0x11c
194 #define OHCI_PREQUPPER 0x120
195 #define OHCI_PREQUPPER_MAX 0xffff0000
197 #define OHCI_SID_BUF 0x64
198 #define OHCI_SID_CNT 0x68
199 #define OHCI_SID_ERR (1U << 31)
200 #define OHCI_SID_CNT_MASK 0xffc
202 #define OHCI_IT_STAT 0x90
203 #define OHCI_IT_STATCLR 0x94
204 #define OHCI_IT_MASK 0x98
205 #define OHCI_IT_MASKCLR 0x9c
207 #define OHCI_IR_STAT 0xa0
208 #define OHCI_IR_STATCLR 0xa4
209 #define OHCI_IR_MASK 0xa8
210 #define OHCI_IR_MASKCLR 0xac
212 #define OHCI_LNKCTL 0xe0
213 #define OHCI_LNKCTLCLR 0xe4
215 #define OHCI_PHYACCESS 0xec
216 #define OHCI_CYCLETIMER 0xf0
218 #define OHCI_DMACTL(off) (off)
219 #define OHCI_DMACTLCLR(off) (off + 4)
220 #define OHCI_DMACMD(off) (off + 0xc)
221 #define OHCI_DMAMATCH(off) (off + 0x10)
223 #define OHCI_ATQOFF 0x180
224 #define OHCI_ATQCTL OHCI_ATQOFF
225 #define OHCI_ATQCTLCLR (OHCI_ATQOFF + 4)
226 #define OHCI_ATQCMD (OHCI_ATQOFF + 0xc)
227 #define OHCI_ATQMATCH (OHCI_ATQOFF + 0x10)
229 #define OHCI_ATSOFF 0x1a0
230 #define OHCI_ATSCTL OHCI_ATSOFF
231 #define OHCI_ATSCTLCLR (OHCI_ATSOFF + 4)
232 #define OHCI_ATSCMD (OHCI_ATSOFF + 0xc)
233 #define OHCI_ATSMATCH (OHCI_ATSOFF + 0x10)
235 #define OHCI_ARQOFF 0x1c0
236 #define OHCI_ARQCTL OHCI_ARQOFF
237 #define OHCI_ARQCTLCLR (OHCI_ARQOFF + 4)
238 #define OHCI_ARQCMD (OHCI_ARQOFF + 0xc)
239 #define OHCI_ARQMATCH (OHCI_ARQOFF + 0x10)
241 #define OHCI_ARSOFF 0x1e0
242 #define OHCI_ARSCTL OHCI_ARSOFF
243 #define OHCI_ARSCTLCLR (OHCI_ARSOFF + 4)
244 #define OHCI_ARSCMD (OHCI_ARSOFF + 0xc)
245 #define OHCI_ARSMATCH (OHCI_ARSOFF + 0x10)
247 #define OHCI_ITOFF(CH) (0x200 + 0x10 * (CH))
248 #define OHCI_ITCTL(CH) (OHCI_ITOFF(CH))
249 #define OHCI_ITCTLCLR(CH) (OHCI_ITOFF(CH) + 4)
250 #define OHCI_ITCMD(CH) (OHCI_ITOFF(CH) + 0xc)
252 #define OHCI_IROFF(CH) (0x400 + 0x20 * (CH))
253 #define OHCI_IRCTL(CH) (OHCI_IROFF(CH))
254 #define OHCI_IRCTLCLR(CH) (OHCI_IROFF(CH) + 4)
255 #define OHCI_IRCMD(CH) (OHCI_IROFF(CH) + 0xc)
256 #define OHCI_IRMATCH(CH) (OHCI_IROFF(CH) + 0x10)
258 d_ioctl_t fwohci_ioctl;
261 * Communication with PHY device
263 /* XXX need lock for phy access */
265 fwphy_wrdata(struct fwohci_softc *sc, uint32_t addr, uint32_t data)
272 fun = (PHYDEV_WRCMD | (addr << PHYDEV_REGADDR) |
273 (data << PHYDEV_WRDATA));
274 OWRITE(sc, OHCI_PHYACCESS, fun);
277 return (fwphy_rddata(sc, addr));
281 fwohci_set_bus_manager(struct firewire_comm *fc, u_int node)
283 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
287 #define OHCI_CSR_DATA 0x0c
288 #define OHCI_CSR_COMP 0x10
289 #define OHCI_CSR_CONT 0x14
290 #define OHCI_BUS_MANAGER_ID 0
292 OWRITE(sc, OHCI_CSR_DATA, node);
293 OWRITE(sc, OHCI_CSR_COMP, 0x3f);
294 OWRITE(sc, OHCI_CSR_CONT, OHCI_BUS_MANAGER_ID);
295 for (i = 0; !(OREAD(sc, OHCI_CSR_CONT) & (1<<31)) && (i < 1000); i++)
297 bm = OREAD(sc, OHCI_CSR_DATA);
298 if ((bm & 0x3f) == 0x3f)
301 device_printf(sc->fc.dev, "%s: %d->%d (loop=%d)\n",
302 __func__, bm, node, i);
307 fwphy_rddata(struct fwohci_softc *sc, u_int addr)
313 #define MAX_RETRY 100
315 OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_REG_FAIL);
316 fun = PHYDEV_RDCMD | (addr << PHYDEV_REGADDR);
317 OWRITE(sc, OHCI_PHYACCESS, fun);
318 for (i = 0; i < MAX_RETRY; i++) {
319 fun = OREAD(sc, OHCI_PHYACCESS);
320 if ((fun & PHYDEV_RDCMD) == 0 && (fun & PHYDEV_RDDONE) != 0)
324 if (i >= MAX_RETRY) {
326 device_printf(sc->fc.dev, "%s: failed(1).\n", __func__);
327 if (++retry < MAX_RETRY) {
332 /* Make sure that SCLK is started */
333 stat = OREAD(sc, FWOHCI_INTSTAT);
334 if ((stat & OHCI_INT_REG_FAIL) != 0 ||
335 ((fun >> PHYDEV_REGADDR) & 0xf) != addr) {
337 device_printf(sc->fc.dev, "%s: failed(2).\n", __func__);
338 if (++retry < MAX_RETRY) {
343 if (firewire_debug > 1 || retry >= MAX_RETRY)
344 device_printf(sc->fc.dev,
345 "%s:: 0x%x loop=%d, retry=%d\n",
346 __func__, addr, i, retry);
348 return ((fun >> PHYDEV_RDDATA) & 0xff);
351 /* Device specific ioctl. */
353 fwohci_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, fw_proc *td)
355 struct firewire_softc *sc;
356 struct fwohci_softc *fc;
357 int unit = DEV2UNIT(dev);
359 struct fw_reg_req_t *reg = (struct fw_reg_req_t *) data;
360 uint32_t *dmach = (uint32_t *) data;
362 sc = devclass_get_softc(firewire_devclass, unit);
366 fc = (struct fwohci_softc *)sc->fc;
373 #define OHCI_MAX_REG 0x800
374 if (reg->addr <= OHCI_MAX_REG) {
375 OWRITE(fc, reg->addr, reg->data);
376 reg->data = OREAD(fc, reg->addr);
382 if (reg->addr <= OHCI_MAX_REG) {
383 reg->data = OREAD(fc, reg->addr);
388 /* Read DMA descriptors for debug */
390 if (*dmach <= OHCI_MAX_DMA_CH) {
391 dump_dma(fc, *dmach);
397 /* Read/Write Phy registers */
398 #define OHCI_MAX_PHY_REG 0xf
399 case FWOHCI_RDPHYREG:
400 if (reg->addr <= OHCI_MAX_PHY_REG)
401 reg->data = fwphy_rddata(fc, reg->addr);
405 case FWOHCI_WRPHYREG:
406 if (reg->addr <= OHCI_MAX_PHY_REG)
407 reg->data = fwphy_wrdata(fc, reg->addr, reg->data);
419 fwohci_probe_phy(struct fwohci_softc *sc, device_t dev)
425 * probe PHY parameters
426 * 0. to prove PHY version, whether compliance of 1394a.
427 * 1. to probe maximum speed supported by the PHY and
428 * number of port supported by core-logic.
429 * It is not actually available port on your PC .
431 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LPS);
434 reg = fwphy_rddata(sc, FW_PHY_SPD_REG);
436 if ((reg >> 5) != 7) {
437 sc->fc.mode &= ~FWPHYASYST;
438 sc->fc.nport = reg & FW_PHY_NP;
439 sc->fc.speed = reg & FW_PHY_SPD >> 6;
440 if (sc->fc.speed > MAX_SPEED) {
441 device_printf(dev, "invalid speed %d (fixed to %d).\n",
442 sc->fc.speed, MAX_SPEED);
443 sc->fc.speed = MAX_SPEED;
446 "Phy 1394 only %s, %d ports.\n",
447 linkspeed[sc->fc.speed], sc->fc.nport);
449 reg2 = fwphy_rddata(sc, FW_PHY_ESPD_REG);
450 sc->fc.mode |= FWPHYASYST;
451 sc->fc.nport = reg & FW_PHY_NP;
452 sc->fc.speed = (reg2 & FW_PHY_ESPD) >> 5;
453 if (sc->fc.speed > MAX_SPEED) {
454 device_printf(dev, "invalid speed %d (fixed to %d).\n",
455 sc->fc.speed, MAX_SPEED);
456 sc->fc.speed = MAX_SPEED;
459 "Phy 1394a available %s, %d ports.\n",
460 linkspeed[sc->fc.speed], sc->fc.nport);
462 /* check programPhyEnable */
463 reg2 = fwphy_rddata(sc, 5);
465 if (e1394a && (OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_PRPHY)) {
466 #else /* XXX force to enable 1394a */
471 "Enable 1394a Enhancements\n");
474 /* set aPhyEnhanceEnable */
475 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_PHYEN);
476 OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_PRPHY);
481 reg2 = fwphy_wrdata(sc, 5, reg2);
484 reg = fwphy_rddata(sc, FW_PHY_SPD_REG);
485 if ((reg >> 5) == 7) {
486 reg = fwphy_rddata(sc, 4);
488 fwphy_wrdata(sc, 4, reg);
489 reg = fwphy_rddata(sc, 4);
496 fwohci_reset(struct fwohci_softc *sc, device_t dev)
498 int i, max_rec, speed;
500 struct fwohcidb_tr *db_tr;
502 /* Disable interrupts */
503 OWRITE(sc, FWOHCI_INTMASKCLR, ~0);
505 /* Now stopping all DMA channels */
506 OWRITE(sc, OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
507 OWRITE(sc, OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN);
508 OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
509 OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
511 OWRITE(sc, OHCI_IR_MASKCLR, ~0);
512 for (i = 0; i < sc->fc.nisodma; i++) {
513 OWRITE(sc, OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN);
514 OWRITE(sc, OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN);
517 /* FLUSH FIFO and reset Transmitter/Receiver */
518 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_RESET);
520 device_printf(dev, "resetting OHCI...");
522 while (OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_RESET) {
523 if (i++ > 100) break;
527 printf("done (loop=%d)\n", i);
530 fwohci_probe_phy(sc, dev);
533 reg = OREAD(sc, OHCI_BUS_OPT);
534 reg2 = reg | OHCI_BUSFNC;
535 max_rec = (reg & 0x0000f000) >> 12;
536 speed = (reg & 0x00000007);
537 device_printf(dev, "Link %s, max_rec %d bytes.\n",
538 linkspeed[speed], MAXREC(max_rec));
539 /* XXX fix max_rec */
540 sc->fc.maxrec = sc->fc.speed + 8;
541 if (max_rec != sc->fc.maxrec) {
542 reg2 = (reg2 & 0xffff0fff) | (sc->fc.maxrec << 12);
543 device_printf(dev, "max_rec %d -> %d\n",
544 MAXREC(max_rec), MAXREC(sc->fc.maxrec));
547 device_printf(dev, "BUS_OPT 0x%x -> 0x%x\n", reg, reg2);
548 OWRITE(sc, OHCI_BUS_OPT, reg2);
550 /* Initialize registers */
551 OWRITE(sc, OHCI_CROMHDR, sc->fc.config_rom[0]);
552 OWRITE(sc, OHCI_CROMPTR, sc->crom_dma.bus_addr);
553 OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_BIGEND);
554 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_POSTWR);
555 OWRITE(sc, OHCI_SID_BUF, sc->sid_dma.bus_addr);
556 OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_SID);
559 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LINKEN);
561 /* Force to start async RX DMA */
562 sc->arrq.xferq.flag &= ~FWXFERQ_RUNNING;
563 sc->arrs.xferq.flag &= ~FWXFERQ_RUNNING;
564 fwohci_rx_enable(sc, &sc->arrq);
565 fwohci_rx_enable(sc, &sc->arrs);
567 /* Initialize async TX */
568 OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN | OHCI_CNTL_DMA_DEAD);
569 OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN | OHCI_CNTL_DMA_DEAD);
572 OWRITE(sc, FWOHCI_RETRY,
573 /* CycleLimit PhyRespRetries ATRespRetries ATReqRetries */
574 (0xffff << 16) | (0x0f << 8) | (0x0f << 4) | 0x0f);
576 sc->atrq.top = STAILQ_FIRST(&sc->atrq.db_trq);
577 sc->atrs.top = STAILQ_FIRST(&sc->atrs.db_trq);
578 sc->atrq.bottom = sc->atrq.top;
579 sc->atrs.bottom = sc->atrs.top;
581 for (i = 0, db_tr = sc->atrq.top; i < sc->atrq.ndb;
582 i++, db_tr = STAILQ_NEXT(db_tr, link)) {
585 for (i = 0, db_tr = sc->atrs.top; i < sc->atrs.ndb;
586 i++, db_tr = STAILQ_NEXT(db_tr, link)) {
590 /* Enable interrupts */
591 sc->intmask = (OHCI_INT_ERR | OHCI_INT_PHY_SID
592 | OHCI_INT_DMA_ATRQ | OHCI_INT_DMA_ATRS
593 | OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS
594 | OHCI_INT_PHY_BUS_R | OHCI_INT_PW_ERR);
595 sc->intmask |= OHCI_INT_DMA_IR | OHCI_INT_DMA_IT;
596 sc->intmask |= OHCI_INT_CYC_LOST | OHCI_INT_PHY_INT;
597 OWRITE(sc, FWOHCI_INTMASK, sc->intmask);
598 fwohci_set_intr(&sc->fc, 1);
602 fwohci_init(struct fwohci_softc *sc, device_t dev)
609 reg = OREAD(sc, OHCI_VERSION);
610 mver = (reg >> 16) & 0xff;
611 device_printf(dev, "OHCI version %x.%x (ROM=%d)\n",
612 mver, reg & 0xff, (reg >> 24) & 1);
613 if (mver < 1 || mver > 9) {
614 device_printf(dev, "invalid OHCI version\n");
618 /* Available Isochronous DMA channel probe */
619 OWRITE(sc, OHCI_IT_MASK, 0xffffffff);
620 OWRITE(sc, OHCI_IR_MASK, 0xffffffff);
621 reg = OREAD(sc, OHCI_IT_MASK) & OREAD(sc, OHCI_IR_MASK);
622 OWRITE(sc, OHCI_IT_MASKCLR, 0xffffffff);
623 OWRITE(sc, OHCI_IR_MASKCLR, 0xffffffff);
624 for (i = 0; i < 0x20; i++)
625 if ((reg & (1 << i)) == 0)
628 device_printf(dev, "No. of Isochronous channels is %d.\n", i);
632 sc->fc.arq = &sc->arrq.xferq;
633 sc->fc.ars = &sc->arrs.xferq;
634 sc->fc.atq = &sc->atrq.xferq;
635 sc->fc.ats = &sc->atrs.xferq;
637 sc->arrq.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
638 sc->arrs.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
639 sc->atrq.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
640 sc->atrs.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
642 sc->arrq.xferq.start = NULL;
643 sc->arrs.xferq.start = NULL;
644 sc->atrq.xferq.start = fwohci_start_atq;
645 sc->atrs.xferq.start = fwohci_start_ats;
647 sc->arrq.xferq.buf = NULL;
648 sc->arrs.xferq.buf = NULL;
649 sc->atrq.xferq.buf = NULL;
650 sc->atrs.xferq.buf = NULL;
652 sc->arrq.xferq.dmach = -1;
653 sc->arrs.xferq.dmach = -1;
654 sc->atrq.xferq.dmach = -1;
655 sc->atrs.xferq.dmach = -1;
659 sc->atrq.ndesc = 8; /* equal to maximum of mbuf chains */
663 sc->arrs.ndb = NDB / 2;
665 sc->atrs.ndb = NDB / 2;
667 for (i = 0; i < sc->fc.nisodma; i++) {
668 sc->fc.it[i] = &sc->it[i].xferq;
669 sc->fc.ir[i] = &sc->ir[i].xferq;
670 sc->it[i].xferq.dmach = i;
671 sc->ir[i].xferq.dmach = i;
676 sc->fc.tcode = tinfo;
679 sc->fc.config_rom = fwdma_malloc(&sc->fc, CROMSIZE, CROMSIZE,
680 &sc->crom_dma, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
681 if (sc->fc.config_rom == NULL) {
682 device_printf(dev, "config_rom alloc failed.");
687 bzero(&sc->fc.config_rom[0], CROMSIZE);
688 sc->fc.config_rom[1] = 0x31333934;
689 sc->fc.config_rom[2] = 0xf000a002;
690 sc->fc.config_rom[3] = OREAD(sc, OHCI_EUID_HI);
691 sc->fc.config_rom[4] = OREAD(sc, OHCI_EUID_LO);
692 sc->fc.config_rom[5] = 0;
693 sc->fc.config_rom[0] = (4 << 24) | (5 << 16);
695 sc->fc.config_rom[0] |= fw_crc16(&sc->fc.config_rom[1], 5*4);
698 /* SID receive buffer must align 2^11 */
699 #define OHCI_SIDSIZE (1 << 11)
700 sc->sid_buf = fwdma_malloc(&sc->fc, OHCI_SIDSIZE, OHCI_SIDSIZE,
701 &sc->sid_dma, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
702 if (sc->sid_buf == NULL) {
703 device_printf(dev, "sid_buf alloc failed.");
707 fwdma_malloc(&sc->fc, sizeof(uint32_t), sizeof(uint32_t),
708 &sc->dummy_dma, BUS_DMA_WAITOK);
710 if (sc->dummy_dma.v_addr == NULL) {
711 device_printf(dev, "dummy_dma alloc failed.");
715 fwohci_db_init(sc, &sc->arrq);
716 if ((sc->arrq.flags & FWOHCI_DBCH_INIT) == 0)
719 fwohci_db_init(sc, &sc->arrs);
720 if ((sc->arrs.flags & FWOHCI_DBCH_INIT) == 0)
723 fwohci_db_init(sc, &sc->atrq);
724 if ((sc->atrq.flags & FWOHCI_DBCH_INIT) == 0)
727 fwohci_db_init(sc, &sc->atrs);
728 if ((sc->atrs.flags & FWOHCI_DBCH_INIT) == 0)
731 sc->fc.eui.hi = OREAD(sc, FWOHCIGUID_H);
732 sc->fc.eui.lo = OREAD(sc, FWOHCIGUID_L);
733 for (i = 0; i < 8; i++)
734 ui[i] = FW_EUI64_BYTE(&sc->fc.eui,i);
735 device_printf(dev, "EUI64 %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
736 ui[0], ui[1], ui[2], ui[3], ui[4], ui[5], ui[6], ui[7]);
738 sc->fc.ioctl = fwohci_ioctl;
739 sc->fc.cyctimer = fwohci_cyctimer;
740 sc->fc.set_bmr = fwohci_set_bus_manager;
741 sc->fc.ibr = fwohci_ibr;
742 sc->fc.irx_enable = fwohci_irx_enable;
743 sc->fc.irx_disable = fwohci_irx_disable;
745 sc->fc.itx_enable = fwohci_itxbuf_enable;
746 sc->fc.itx_disable = fwohci_itx_disable;
747 #if BYTE_ORDER == BIG_ENDIAN
748 sc->fc.irx_post = fwohci_irx_post;
750 sc->fc.irx_post = NULL;
752 sc->fc.itx_post = NULL;
753 sc->fc.timeout = fwohci_timeout;
754 sc->fc.poll = fwohci_poll;
755 sc->fc.set_intr = fwohci_set_intr;
757 sc->intmask = sc->irstat = sc->itstat = 0;
759 /* Init task queue */
760 sc->fc.taskqueue = taskqueue_create_fast("fw_taskq", M_WAITOK,
761 taskqueue_thread_enqueue, &sc->fc.taskqueue);
762 taskqueue_start_threads(&sc->fc.taskqueue, 1, PI_NET, "fw%d_taskq",
763 device_get_unit(dev));
764 TASK_INIT(&sc->fwohci_task_busreset, 2, fwohci_task_busreset, sc);
765 TASK_INIT(&sc->fwohci_task_sid, 1, fwohci_task_sid, sc);
766 TASK_INIT(&sc->fwohci_task_dma, 0, fwohci_task_dma, sc);
769 fwohci_reset(sc, dev);
775 fwohci_timeout(void *arg)
777 struct fwohci_softc *sc;
779 sc = (struct fwohci_softc *)arg;
783 fwohci_cyctimer(struct firewire_comm *fc)
785 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
786 return (OREAD(sc, OHCI_CYCLETIMER));
790 fwohci_detach(struct fwohci_softc *sc, device_t dev)
794 if (sc->sid_buf != NULL)
795 fwdma_free(&sc->fc, &sc->sid_dma);
796 if (sc->fc.config_rom != NULL)
797 fwdma_free(&sc->fc, &sc->crom_dma);
799 fwohci_db_free(&sc->arrq);
800 fwohci_db_free(&sc->arrs);
802 fwohci_db_free(&sc->atrq);
803 fwohci_db_free(&sc->atrs);
805 for (i = 0; i < sc->fc.nisodma; i++) {
806 fwohci_db_free(&sc->it[i]);
807 fwohci_db_free(&sc->ir[i]);
809 if (sc->fc.taskqueue != NULL) {
810 taskqueue_drain(sc->fc.taskqueue, &sc->fwohci_task_busreset);
811 taskqueue_drain(sc->fc.taskqueue, &sc->fwohci_task_sid);
812 taskqueue_drain(sc->fc.taskqueue, &sc->fwohci_task_dma);
813 taskqueue_drain(sc->fc.taskqueue, &sc->fc.task_timeout);
814 taskqueue_free(sc->fc.taskqueue);
815 sc->fc.taskqueue = NULL;
821 #define LAST_DB(dbtr, db) do { \
822 struct fwohcidb_tr *_dbtr = (dbtr); \
823 int _cnt = _dbtr->dbcnt; \
824 db = &_dbtr->db[ (_cnt > 2) ? (_cnt -1) : 0]; \
828 fwohci_execute_db(void *arg, bus_dma_segment_t *segs, int nseg, int error)
830 struct fwohcidb_tr *db_tr;
832 bus_dma_segment_t *s;
835 db_tr = (struct fwohcidb_tr *)arg;
836 db = &db_tr->db[db_tr->dbcnt];
838 if (firewire_debug || error != EFBIG)
839 printf("fwohci_execute_db: error=%d\n", error);
842 for (i = 0; i < nseg; i++) {
844 FWOHCI_DMA_WRITE(db->db.desc.addr, s->ds_addr);
845 FWOHCI_DMA_WRITE(db->db.desc.cmd, s->ds_len);
846 FWOHCI_DMA_WRITE(db->db.desc.res, 0);
853 fwohci_execute_db2(void *arg, bus_dma_segment_t *segs, int nseg,
854 bus_size_t size, int error)
856 fwohci_execute_db(arg, segs, nseg, error);
860 fwohci_start(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
863 int tcode, hdr_len, pl_off;
866 struct fw_xfer *xfer;
868 struct fwohci_txpkthdr *ohcifp;
869 struct fwohcidb_tr *db_tr;
872 struct tcode_info *info;
873 static int maxdesc=0;
875 FW_GLOCK_ASSERT(&sc->fc);
877 if (&sc->atrq == dbch) {
879 } else if (&sc->atrs == dbch) {
885 if (dbch->flags & FWOHCI_DBCH_FULL)
890 xfer = STAILQ_FIRST(&dbch->xferq.q);
895 if (dbch->xferq.queued == 0) {
896 device_printf(sc->fc.dev, "TX queue empty\n");
899 STAILQ_REMOVE_HEAD(&dbch->xferq.q, link);
901 xfer->flag = FWXF_START;
903 fp = &xfer->send.hdr;
904 tcode = fp->mode.common.tcode;
906 ohcifp = (struct fwohci_txpkthdr *) db_tr->db[1].db.immed;
907 info = &tinfo[tcode];
908 hdr_len = pl_off = info->hdr_len;
910 ld = &ohcifp->mode.ld[0];
911 ld[0] = ld[1] = ld[2] = ld[3] = 0;
912 for (i = 0; i < pl_off; i+= 4)
913 ld[i/4] = fp->mode.ld[i/4];
915 ohcifp->mode.common.spd = xfer->send.spd & 0x7;
916 if (tcode == FWTCODE_STREAM) {
918 ohcifp->mode.stream.len = fp->mode.stream.len;
919 } else if (tcode == FWTCODE_PHY) {
921 ld[1] = fp->mode.ld[1];
922 ld[2] = fp->mode.ld[2];
923 ohcifp->mode.common.spd = 0;
924 ohcifp->mode.common.tcode = FWOHCITCODE_PHY;
926 ohcifp->mode.asycomm.dst = fp->mode.hdr.dst;
927 ohcifp->mode.asycomm.srcbus = OHCI_ASYSRCBUS;
928 ohcifp->mode.asycomm.tlrt |= FWRETRY_X;
931 FWOHCI_DMA_WRITE(db->db.desc.cmd,
932 OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | hdr_len);
933 FWOHCI_DMA_WRITE(db->db.desc.addr, 0);
934 FWOHCI_DMA_WRITE(db->db.desc.res, 0);
935 /* Specify bound timer of asy. response */
936 if (&sc->atrs == dbch) {
937 FWOHCI_DMA_WRITE(db->db.desc.res,
938 (OREAD(sc, OHCI_CYCLETIMER) >> 12) + (1 << 13));
940 #if BYTE_ORDER == BIG_ENDIAN
941 if (tcode == FWTCODE_WREQQ || tcode == FWTCODE_RRESQ)
943 for (i = 0; i < hdr_len/4; i++)
944 FWOHCI_DMA_WRITE(ld[i], ld[i]);
949 db = &db_tr->db[db_tr->dbcnt];
950 if (xfer->send.pay_len > 0) {
953 if (xfer->mbuf == NULL) {
954 err = bus_dmamap_load(dbch->dmat, db_tr->dma_map,
955 &xfer->send.payload[0], xfer->send.pay_len,
956 fwohci_execute_db, db_tr,
959 /* XXX we can handle only 6 (=8-2) mbuf chains */
960 err = bus_dmamap_load_mbuf(dbch->dmat, db_tr->dma_map,
962 fwohci_execute_db2, db_tr,
968 device_printf(sc->fc.dev, "EFBIG.\n");
969 m0 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
971 m_copydata(xfer->mbuf, 0,
972 xfer->mbuf->m_pkthdr.len,
974 m0->m_len = m0->m_pkthdr.len =
975 xfer->mbuf->m_pkthdr.len;
980 device_printf(sc->fc.dev, "m_getcl failed.\n");
984 printf("dmamap_load: err=%d\n", err);
985 bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
986 BUS_DMASYNC_PREWRITE);
987 #if 0 /* OHCI_OUTPUT_MODE == 0 */
988 for (i = 2; i < db_tr->dbcnt; i++)
989 FWOHCI_DMA_SET(db_tr->db[i].db.desc.cmd,
993 if (maxdesc < db_tr->dbcnt) {
994 maxdesc = db_tr->dbcnt;
996 device_printf(sc->fc.dev, "%s: maxdesc %d\n", __func__, maxdesc);
1000 FWOHCI_DMA_SET(db->db.desc.cmd,
1001 OHCI_OUTPUT_LAST | OHCI_INTERRUPT_ALWAYS | OHCI_BRANCH_ALWAYS);
1002 FWOHCI_DMA_WRITE(db->db.desc.depend,
1003 STAILQ_NEXT(db_tr, link)->bus_addr);
1006 fsegment = db_tr->dbcnt;
1007 if (dbch->pdb_tr != NULL) {
1008 LAST_DB(dbch->pdb_tr, db);
1009 FWOHCI_DMA_SET(db->db.desc.depend, db_tr->dbcnt);
1011 dbch->xferq.queued++;
1012 dbch->pdb_tr = db_tr;
1013 db_tr = STAILQ_NEXT(db_tr, link);
1014 if (db_tr != dbch->bottom) {
1017 device_printf(sc->fc.dev, "fwohci_start: lack of db_trq\n");
1018 dbch->flags |= FWOHCI_DBCH_FULL;
1022 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
1023 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
1025 if (dbch->xferq.flag & FWXFERQ_RUNNING) {
1026 OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
1029 device_printf(sc->fc.dev, "start AT DMA status=%x\n",
1030 OREAD(sc, OHCI_DMACTL(off)));
1031 OWRITE(sc, OHCI_DMACMD(off), dbch->top->bus_addr | fsegment);
1032 OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_RUN);
1033 dbch->xferq.flag |= FWXFERQ_RUNNING;
1041 fwohci_start_atq(struct firewire_comm *fc)
1043 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
1045 fwohci_start(sc, &(sc->atrq));
1046 FW_GUNLOCK(&sc->fc);
1051 fwohci_start_ats(struct firewire_comm *fc)
1053 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
1055 fwohci_start(sc, &(sc->atrs));
1056 FW_GUNLOCK(&sc->fc);
1061 fwohci_txd(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
1064 struct fwohcidb_tr *tr;
1065 struct fwohcidb *db;
1066 struct fw_xfer *xfer;
1070 struct firewire_comm *fc = (struct firewire_comm *)sc;
1072 if (&sc->atrq == dbch) {
1075 } else if (&sc->atrs == dbch) {
1084 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTREAD);
1085 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTWRITE);
1086 while (dbch->xferq.queued > 0) {
1088 status = FWOHCI_DMA_READ(db->db.desc.res) >> OHCI_STATUS_SHIFT;
1089 if (!(status & OHCI_CNTL_DMA_ACTIVE)) {
1090 if (fc->status != FWBUSINIT)
1091 /* maybe out of order?? */
1094 bus_dmamap_sync(dbch->dmat, tr->dma_map,
1095 BUS_DMASYNC_POSTWRITE);
1096 bus_dmamap_unload(dbch->dmat, tr->dma_map);
1098 if (firewire_debug > 1)
1101 if (status & OHCI_CNTL_DMA_DEAD) {
1103 OWRITE(sc, OHCI_DMACTLCLR(off), OHCI_CNTL_DMA_RUN);
1104 device_printf(sc->fc.dev, "force reset AT FIFO\n");
1105 OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_LINKEN);
1106 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LPS | OHCI_HCC_LINKEN);
1107 OWRITE(sc, OHCI_DMACTLCLR(off), OHCI_CNTL_DMA_RUN);
1109 stat = status & FWOHCIEV_MASK;
1111 case FWOHCIEV_ACKPEND:
1112 case FWOHCIEV_ACKCOMPL:
1115 case FWOHCIEV_ACKBSA:
1116 case FWOHCIEV_ACKBSB:
1117 case FWOHCIEV_ACKBSX:
1120 case FWOHCIEV_FLUSHED:
1121 case FWOHCIEV_ACKTARD:
1124 case FWOHCIEV_MISSACK:
1125 case FWOHCIEV_UNDRRUN:
1126 case FWOHCIEV_OVRRUN:
1127 case FWOHCIEV_DESCERR:
1128 case FWOHCIEV_DTRDERR:
1129 case FWOHCIEV_TIMEOUT:
1130 case FWOHCIEV_TCODERR:
1131 case FWOHCIEV_UNKNOWN:
1132 case FWOHCIEV_ACKDERR:
1133 case FWOHCIEV_ACKTERR:
1138 if (tr->xfer != NULL) {
1140 if (xfer->flag & FWXF_RCVD) {
1143 printf("already rcvd\n");
1147 microtime(&xfer->tv);
1148 xfer->flag = FWXF_SENT;
1150 xfer->flag = FWXF_BUSY;
1152 xfer->recv.pay_len = 0;
1154 } else if (stat != FWOHCIEV_ACKPEND) {
1155 if (stat != FWOHCIEV_ACKCOMPL)
1156 xfer->flag = FWXF_SENTERR;
1158 xfer->recv.pay_len = 0;
1163 * The watchdog timer takes care of split
1164 * transaction timeout for ACKPEND case.
1167 printf("this shouldn't happen\n");
1170 dbch->xferq.queued--;
1175 tr = STAILQ_NEXT(tr, link);
1177 if (dbch->bottom == dbch->top) {
1178 /* we reaches the end of context program */
1179 if (firewire_debug && dbch->xferq.queued > 0)
1180 printf("queued > 0\n");
1185 if ((dbch->flags & FWOHCI_DBCH_FULL) && packets > 0) {
1186 printf("make free slot\n");
1187 dbch->flags &= ~FWOHCI_DBCH_FULL;
1189 fwohci_start(sc, dbch);
1196 fwohci_db_free(struct fwohci_dbch *dbch)
1198 struct fwohcidb_tr *db_tr;
1201 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
1204 for (db_tr = STAILQ_FIRST(&dbch->db_trq), idb = 0; idb < dbch->ndb;
1205 db_tr = STAILQ_NEXT(db_tr, link), idb++) {
1206 if ((dbch->xferq.flag & FWXFERQ_EXTBUF) == 0 &&
1207 db_tr->buf != NULL) {
1208 fwdma_free_size(dbch->dmat, db_tr->dma_map,
1209 db_tr->buf, dbch->xferq.psize);
1211 } else if (db_tr->dma_map != NULL)
1212 bus_dmamap_destroy(dbch->dmat, db_tr->dma_map);
1215 db_tr = STAILQ_FIRST(&dbch->db_trq);
1216 fwdma_free_multiseg(dbch->am);
1218 STAILQ_INIT(&dbch->db_trq);
1219 dbch->flags &= ~FWOHCI_DBCH_INIT;
1223 fwohci_db_init(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
1226 struct fwohcidb_tr *db_tr;
1228 if ((dbch->flags & FWOHCI_DBCH_INIT) != 0)
1231 /* create dma_tag for buffers */
1232 #define MAX_REQCOUNT 0xffff
1233 if (bus_dma_tag_create(/*parent*/ sc->fc.dmat,
1234 /*alignment*/ 1, /*boundary*/ 0,
1235 /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
1236 /*highaddr*/ BUS_SPACE_MAXADDR,
1237 /*filter*/NULL, /*filterarg*/NULL,
1238 /*maxsize*/ dbch->xferq.psize,
1239 /*nsegments*/ dbch->ndesc > 3 ? dbch->ndesc - 2 : 1,
1240 /*maxsegsz*/ MAX_REQCOUNT,
1242 /*lockfunc*/busdma_lock_mutex,
1243 /*lockarg*/FW_GMTX(&sc->fc),
1247 /* allocate DB entries and attach one to each DMA channels */
1248 /* DB entry must start at 16 bytes bounary. */
1249 STAILQ_INIT(&dbch->db_trq);
1250 db_tr = (struct fwohcidb_tr *)
1251 malloc(sizeof(struct fwohcidb_tr) * dbch->ndb,
1252 M_FW, M_WAITOK | M_ZERO);
1254 #define DB_SIZE(x) (sizeof(struct fwohcidb) * (x)->ndesc)
1255 dbch->am = fwdma_malloc_multiseg(&sc->fc, sizeof(struct fwohcidb),
1256 DB_SIZE(dbch), dbch->ndb, BUS_DMA_WAITOK);
1257 if (dbch->am == NULL) {
1258 printf("fwohci_db_init: fwdma_malloc_multiseg failed\n");
1262 /* Attach DB to DMA ch. */
1263 for (idb = 0; idb < dbch->ndb; idb++) {
1265 db_tr->db = (struct fwohcidb *)fwdma_v_addr(dbch->am, idb);
1266 db_tr->bus_addr = fwdma_bus_addr(dbch->am, idb);
1267 /* create dmamap for buffers */
1268 /* XXX do we need 4bytes alignment tag? */
1269 /* XXX don't alloc dma_map for AR */
1270 if (bus_dmamap_create(dbch->dmat, 0, &db_tr->dma_map) != 0) {
1271 printf("bus_dmamap_create failed\n");
1272 dbch->flags = FWOHCI_DBCH_INIT; /* XXX fake */
1273 fwohci_db_free(dbch);
1276 STAILQ_INSERT_TAIL(&dbch->db_trq, db_tr, link);
1277 if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
1278 if (idb % dbch->xferq.bnpacket == 0)
1279 dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket
1280 ].start = (caddr_t)db_tr;
1281 if ((idb + 1) % dbch->xferq.bnpacket == 0)
1282 dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket
1283 ].end = (caddr_t)db_tr;
1287 STAILQ_LAST(&dbch->db_trq, fwohcidb_tr,link)->link.stqe_next
1288 = STAILQ_FIRST(&dbch->db_trq);
1290 dbch->xferq.queued = 0;
1291 dbch->pdb_tr = NULL;
1292 dbch->top = STAILQ_FIRST(&dbch->db_trq);
1293 dbch->bottom = dbch->top;
1294 dbch->flags = FWOHCI_DBCH_INIT;
1298 fwohci_itx_disable(struct firewire_comm *fc, int dmach)
1300 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
1302 OWRITE(sc, OHCI_ITCTLCLR(dmach),
1303 OHCI_CNTL_DMA_RUN | OHCI_CNTL_CYCMATCH_S);
1304 OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach);
1305 OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach);
1306 /* XXX we cannot free buffers until the DMA really stops */
1307 pause("fwitxd", hz);
1308 fwohci_db_free(&sc->it[dmach]);
1309 sc->it[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
1314 fwohci_irx_disable(struct firewire_comm *fc, int dmach)
1316 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
1318 OWRITE(sc, OHCI_IRCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
1319 OWRITE(sc, OHCI_IR_MASKCLR, 1 << dmach);
1320 OWRITE(sc, OHCI_IR_STATCLR, 1 << dmach);
1321 /* XXX we cannot free buffers until the DMA really stops */
1322 pause("fwirxd", hz);
1323 fwohci_db_free(&sc->ir[dmach]);
1324 sc->ir[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
1328 #if BYTE_ORDER == BIG_ENDIAN
1330 fwohci_irx_post (struct firewire_comm *fc , uint32_t *qld)
1332 qld[0] = FWOHCI_DMA_READ(qld[0]);
1338 fwohci_tx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
1341 int idb, z, i, dmach = 0, ldesc;
1343 struct fwohcidb_tr *db_tr;
1344 struct fwohcidb *db;
1346 if (!(dbch->xferq.flag & FWXFERQ_EXTBUF)) {
1351 for (dmach = 0; dmach < sc->fc.nisodma; dmach++) {
1352 if (&sc->it[dmach] == dbch) {
1353 off = OHCI_ITOFF(dmach);
1361 if (dbch->xferq.flag & FWXFERQ_RUNNING)
1363 dbch->xferq.flag |= FWXFERQ_RUNNING;
1364 for (i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++) {
1365 dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
1368 for (idb = 0; idb < dbch->ndb; idb++) {
1369 fwohci_add_tx_buf(dbch, db_tr, idb);
1370 if (STAILQ_NEXT(db_tr, link) == NULL) {
1374 ldesc = db_tr->dbcnt - 1;
1375 FWOHCI_DMA_WRITE(db[0].db.desc.depend,
1376 STAILQ_NEXT(db_tr, link)->bus_addr | z);
1377 db[ldesc].db.desc.depend = db[0].db.desc.depend;
1378 if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
1379 if (((idb + 1) % dbch->xferq.bnpacket) == 0) {
1381 db[ldesc].db.desc.cmd,
1382 OHCI_INTERRUPT_ALWAYS);
1383 /* OHCI 1.1 and above */
1386 OHCI_INTERRUPT_ALWAYS);
1389 db_tr = STAILQ_NEXT(db_tr, link);
1392 dbch->bottom->db[dbch->bottom->dbcnt - 1].db.desc.depend, 0xf);
1397 fwohci_rx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
1400 int idb, z, i, dmach = 0, ldesc;
1402 struct fwohcidb_tr *db_tr;
1403 struct fwohcidb *db;
1406 if (&sc->arrq == dbch) {
1408 } else if (&sc->arrs == dbch) {
1411 for (dmach = 0; dmach < sc->fc.nisodma; dmach++) {
1412 if (&sc->ir[dmach] == dbch) {
1413 off = OHCI_IROFF(dmach);
1422 if (dbch->xferq.flag & FWXFERQ_STREAM) {
1423 if (dbch->xferq.flag & FWXFERQ_RUNNING)
1426 if (dbch->xferq.flag & FWXFERQ_RUNNING) {
1431 dbch->xferq.flag |= FWXFERQ_RUNNING;
1432 dbch->top = STAILQ_FIRST(&dbch->db_trq);
1433 for (i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++) {
1434 dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
1437 for (idb = 0; idb < dbch->ndb; idb++) {
1438 fwohci_add_rx_buf(dbch, db_tr, idb, &sc->dummy_dma);
1439 if (STAILQ_NEXT(db_tr, link) == NULL)
1442 ldesc = db_tr->dbcnt - 1;
1443 FWOHCI_DMA_WRITE(db[ldesc].db.desc.depend,
1444 STAILQ_NEXT(db_tr, link)->bus_addr | z);
1445 if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
1446 if (((idb + 1) % dbch->xferq.bnpacket) == 0) {
1448 db[ldesc].db.desc.cmd,
1449 OHCI_INTERRUPT_ALWAYS);
1451 db[ldesc].db.desc.depend,
1455 db_tr = STAILQ_NEXT(db_tr, link);
1458 dbch->bottom->db[db_tr->dbcnt - 1].db.desc.depend, 0xf);
1459 dbch->buf_offset = 0;
1460 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
1461 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
1462 if (dbch->xferq.flag & FWXFERQ_STREAM) {
1465 OWRITE(sc, OHCI_DMACMD(off), dbch->top->bus_addr | z);
1467 OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_RUN);
1472 fwohci_next_cycle(struct firewire_comm *fc, int cycle_now)
1474 int sec, cycle, cycle_match;
1476 cycle = cycle_now & 0x1fff;
1477 sec = cycle_now >> 13;
1478 #define CYCLE_MOD 0x10
1480 #define CYCLE_DELAY 8 /* min delay to start DMA */
1482 #define CYCLE_DELAY 7000 /* min delay to start DMA */
1484 cycle = cycle + CYCLE_DELAY;
1485 if (cycle >= 8000) {
1489 cycle = roundup2(cycle, CYCLE_MOD);
1490 if (cycle >= 8000) {
1497 cycle_match = ((sec << 13) | cycle) & 0x7ffff;
1499 return (cycle_match);
1503 fwohci_itxbuf_enable(struct firewire_comm *fc, int dmach)
1505 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
1507 unsigned short tag, ich;
1508 struct fwohci_dbch *dbch;
1509 int cycle_match, cycle_now, s, ldesc;
1511 struct fw_bulkxfer *first, *chunk, *prev;
1512 struct fw_xferq *it;
1514 dbch = &sc->it[dmach];
1517 tag = (it->flag >> 6) & 3;
1518 ich = it->flag & 0x3f;
1519 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0) {
1520 dbch->ndb = it->bnpacket * it->bnchunk;
1522 fwohci_db_init(sc, dbch);
1523 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
1526 err = fwohci_tx_enable(sc, dbch);
1531 ldesc = dbch->ndesc - 1;
1534 prev = STAILQ_LAST(&it->stdma, fw_bulkxfer, link);
1535 while ((chunk = STAILQ_FIRST(&it->stvalid)) != NULL) {
1536 struct fwohcidb *db;
1538 fwdma_sync_multiseg(it->buf, chunk->poffset, it->bnpacket,
1539 BUS_DMASYNC_PREWRITE);
1540 fwohci_txbufdb(sc, dmach, chunk);
1542 db = ((struct fwohcidb_tr *)(prev->end))->db;
1543 #if 0 /* XXX necessary? */
1544 FWOHCI_DMA_SET(db[ldesc].db.desc.cmd,
1545 OHCI_BRANCH_ALWAYS);
1547 #if 0 /* if bulkxfer->npacket changes */
1548 db[ldesc].db.desc.depend = db[0].db.desc.depend =
1549 ((struct fwohcidb_tr *)
1550 (chunk->start))->bus_addr | dbch->ndesc;
1552 FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
1553 FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
1556 STAILQ_REMOVE_HEAD(&it->stvalid, link);
1557 STAILQ_INSERT_TAIL(&it->stdma, chunk, link);
1561 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
1562 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
1564 stat = OREAD(sc, OHCI_ITCTL(dmach));
1565 if (firewire_debug && (stat & OHCI_CNTL_CYCMATCH_S))
1566 printf("stat 0x%x\n", stat);
1568 if (stat & (OHCI_CNTL_DMA_ACTIVE | OHCI_CNTL_CYCMATCH_S))
1572 OWRITE(sc, OHCI_ITCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
1574 OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach);
1575 OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach);
1576 OWRITE(sc, OHCI_IT_MASK, 1 << dmach);
1577 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IT);
1579 first = STAILQ_FIRST(&it->stdma);
1580 OWRITE(sc, OHCI_ITCMD(dmach),
1581 ((struct fwohcidb_tr *)(first->start))->bus_addr | dbch->ndesc);
1582 if (firewire_debug > 1) {
1583 printf("fwohci_itxbuf_enable: kick 0x%08x\n", stat);
1585 dump_dma(sc, ITX_CH + dmach);
1588 if ((stat & OHCI_CNTL_DMA_RUN) == 0) {
1590 /* Don't start until all chunks are buffered */
1591 if (STAILQ_FIRST(&it->stfree) != NULL)
1595 /* Clear cycle match counter bits */
1596 OWRITE(sc, OHCI_ITCTLCLR(dmach), 0xffff0000);
1598 /* 2bit second + 13bit cycle */
1599 cycle_now = (fc->cyctimer(fc) >> 12) & 0x7fff;
1600 cycle_match = fwohci_next_cycle(fc, cycle_now);
1602 OWRITE(sc, OHCI_ITCTL(dmach),
1603 OHCI_CNTL_CYCMATCH_S | (cycle_match << 16)
1604 | OHCI_CNTL_DMA_RUN);
1606 OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_RUN);
1608 if (firewire_debug > 1) {
1609 printf("cycle_match: 0x%04x->0x%04x\n",
1610 cycle_now, cycle_match);
1611 dump_dma(sc, ITX_CH + dmach);
1612 dump_db(sc, ITX_CH + dmach);
1614 } else if ((stat & OHCI_CNTL_CYCMATCH_S) == 0) {
1615 device_printf(sc->fc.dev,
1616 "IT DMA underrun (0x%08x)\n", stat);
1617 OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_WAKE);
1624 fwohci_irx_enable(struct firewire_comm *fc, int dmach)
1626 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
1627 int err = 0, s, ldesc;
1628 unsigned short tag, ich;
1630 struct fwohci_dbch *dbch;
1631 struct fwohcidb_tr *db_tr;
1632 struct fw_bulkxfer *first, *prev, *chunk;
1633 struct fw_xferq *ir;
1635 dbch = &sc->ir[dmach];
1638 if ((ir->flag & FWXFERQ_RUNNING) == 0) {
1639 tag = (ir->flag >> 6) & 3;
1640 ich = ir->flag & 0x3f;
1641 OWRITE(sc, OHCI_IRMATCH(dmach), tagbit[tag] | ich);
1644 dbch->ndb = ir->bnpacket * ir->bnchunk;
1646 fwohci_db_init(sc, dbch);
1647 if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
1649 err = fwohci_rx_enable(sc, dbch);
1654 first = STAILQ_FIRST(&ir->stfree);
1655 if (first == NULL) {
1656 device_printf(fc->dev, "IR DMA no free chunk\n");
1660 ldesc = dbch->ndesc - 1;
1662 if ((ir->flag & FWXFERQ_HANDLER) == 0)
1664 prev = STAILQ_LAST(&ir->stdma, fw_bulkxfer, link);
1665 while ((chunk = STAILQ_FIRST(&ir->stfree)) != NULL) {
1666 struct fwohcidb *db;
1668 #if 1 /* XXX for if_fwe */
1669 if (chunk->mbuf != NULL) {
1670 db_tr = (struct fwohcidb_tr *)(chunk->start);
1672 err = bus_dmamap_load_mbuf(dbch->dmat, db_tr->dma_map,
1673 chunk->mbuf, fwohci_execute_db2, db_tr,
1675 FWOHCI_DMA_SET(db_tr->db[1].db.desc.cmd,
1676 OHCI_UPDATE | OHCI_INPUT_LAST |
1677 OHCI_INTERRUPT_ALWAYS | OHCI_BRANCH_ALWAYS);
1680 db = ((struct fwohcidb_tr *)(chunk->end))->db;
1681 FWOHCI_DMA_WRITE(db[ldesc].db.desc.res, 0);
1682 FWOHCI_DMA_CLEAR(db[ldesc].db.desc.depend, 0xf);
1684 db = ((struct fwohcidb_tr *)(prev->end))->db;
1685 FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
1687 STAILQ_REMOVE_HEAD(&ir->stfree, link);
1688 STAILQ_INSERT_TAIL(&ir->stdma, chunk, link);
1691 if ((ir->flag & FWXFERQ_HANDLER) == 0)
1693 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
1694 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
1696 stat = OREAD(sc, OHCI_IRCTL(dmach));
1697 if (stat & OHCI_CNTL_DMA_ACTIVE)
1699 if (stat & OHCI_CNTL_DMA_RUN) {
1700 OWRITE(sc, OHCI_IRCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
1701 device_printf(sc->fc.dev, "IR DMA overrun (0x%08x)\n", stat);
1705 printf("start IR DMA 0x%x\n", stat);
1706 OWRITE(sc, OHCI_IR_MASKCLR, 1 << dmach);
1707 OWRITE(sc, OHCI_IR_STATCLR, 1 << dmach);
1708 OWRITE(sc, OHCI_IR_MASK, 1 << dmach);
1709 OWRITE(sc, OHCI_IRCTLCLR(dmach), 0xf0000000);
1710 OWRITE(sc, OHCI_IRCTL(dmach), OHCI_CNTL_ISOHDR);
1711 OWRITE(sc, OHCI_IRCMD(dmach),
1712 ((struct fwohcidb_tr *)(first->start))->bus_addr
1714 OWRITE(sc, OHCI_IRCTL(dmach), OHCI_CNTL_DMA_RUN);
1715 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IR);
1717 dump_db(sc, IRX_CH + dmach);
1723 fwohci_stop(struct fwohci_softc *sc, device_t dev)
1727 fwohci_set_intr(&sc->fc, 0);
1729 /* Now stopping all DMA channel */
1730 OWRITE(sc, OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
1731 OWRITE(sc, OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN);
1732 OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
1733 OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
1735 for (i = 0; i < sc->fc.nisodma; i++) {
1736 OWRITE(sc, OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN);
1737 OWRITE(sc, OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN);
1740 #if 0 /* Let dcons(4) be accessed */
1741 /* Stop interrupt */
1742 OWRITE(sc, FWOHCI_INTMASKCLR,
1743 OHCI_INT_EN | OHCI_INT_ERR | OHCI_INT_PHY_SID
1745 | OHCI_INT_DMA_ATRQ | OHCI_INT_DMA_ATRS
1746 | OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS
1747 | OHCI_INT_DMA_ARRQ | OHCI_INT_DMA_ARRS
1748 | OHCI_INT_PHY_BUS_R);
1750 /* FLUSH FIFO and reset Transmitter/Receiver */
1751 OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_RESET);
1754 /* XXX Link down? Bus reset? */
1759 fwohci_resume(struct fwohci_softc *sc, device_t dev)
1762 struct fw_xferq *ir;
1763 struct fw_bulkxfer *chunk;
1765 fwohci_reset(sc, dev);
1766 /* XXX resume isochronous receive automatically. (how about TX?) */
1767 for (i = 0; i < sc->fc.nisodma; i++) {
1768 ir = &sc->ir[i].xferq;
1769 if ((ir->flag & FWXFERQ_RUNNING) != 0) {
1770 device_printf(sc->fc.dev,
1771 "resume iso receive ch: %d\n", i);
1772 ir->flag &= ~FWXFERQ_RUNNING;
1773 /* requeue stdma to stfree */
1774 while ((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
1775 STAILQ_REMOVE_HEAD(&ir->stdma, link);
1776 STAILQ_INSERT_TAIL(&ir->stfree, chunk, link);
1778 sc->fc.irx_enable(&sc->fc, i);
1782 bus_generic_resume(dev);
1783 sc->fc.ibr(&sc->fc);
1789 fwohci_dump_intr(struct fwohci_softc *sc, uint32_t stat)
1791 if (stat & OREAD(sc, FWOHCI_INTMASK))
1792 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",
1793 stat & OHCI_INT_EN ? "DMA_EN ":"",
1794 stat & OHCI_INT_PHY_REG ? "PHY_REG ":"",
1795 stat & OHCI_INT_CYC_LONG ? "CYC_LONG ":"",
1796 stat & OHCI_INT_ERR ? "INT_ERR ":"",
1797 stat & OHCI_INT_CYC_ERR ? "CYC_ERR ":"",
1798 stat & OHCI_INT_CYC_LOST ? "CYC_LOST ":"",
1799 stat & OHCI_INT_CYC_64SECOND ? "CYC_64SECOND ":"",
1800 stat & OHCI_INT_CYC_START ? "CYC_START ":"",
1801 stat & OHCI_INT_PHY_INT ? "PHY_INT ":"",
1802 stat & OHCI_INT_PHY_BUS_R ? "BUS_RESET ":"",
1803 stat & OHCI_INT_PHY_SID ? "SID ":"",
1804 stat & OHCI_INT_LR_ERR ? "DMA_LR_ERR ":"",
1805 stat & OHCI_INT_PW_ERR ? "DMA_PW_ERR ":"",
1806 stat & OHCI_INT_DMA_IR ? "DMA_IR ":"",
1807 stat & OHCI_INT_DMA_IT ? "DMA_IT " :"",
1808 stat & OHCI_INT_DMA_PRRS ? "DMA_PRRS " :"",
1809 stat & OHCI_INT_DMA_PRRQ ? "DMA_PRRQ " :"",
1810 stat & OHCI_INT_DMA_ARRS ? "DMA_ARRS " :"",
1811 stat & OHCI_INT_DMA_ARRQ ? "DMA_ARRQ " :"",
1812 stat & OHCI_INT_DMA_ATRS ? "DMA_ATRS " :"",
1813 stat & OHCI_INT_DMA_ATRQ ? "DMA_ATRQ " :"",
1814 stat, OREAD(sc, FWOHCI_INTMASK)
1820 fwohci_intr_core(struct fwohci_softc *sc, uint32_t stat, int count)
1822 struct firewire_comm *fc = (struct firewire_comm *)sc;
1823 uintmax_t prequpper;
1824 uint32_t node_id, plen;
1826 FW_GLOCK_ASSERT(fc);
1827 if ((stat & OHCI_INT_PHY_BUS_R) && (fc->status != FWBUSRESET)) {
1828 fc->status = FWBUSRESET;
1829 /* Disable bus reset interrupt until sid recv. */
1830 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_PHY_BUS_R);
1832 device_printf(fc->dev, "%s: BUS reset\n", __func__);
1833 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST);
1834 OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCSRC);
1836 OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
1837 sc->atrq.xferq.flag &= ~FWXFERQ_RUNNING;
1838 OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
1839 sc->atrs.xferq.flag &= ~FWXFERQ_RUNNING;
1842 taskqueue_enqueue(sc->fc.taskqueue, &sc->fwohci_task_busreset);
1844 if (stat & OHCI_INT_PHY_SID) {
1845 /* Enable bus reset interrupt */
1846 OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_PHY_BUS_R);
1847 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_PHY_BUS_R);
1849 /* Allow async. request to us */
1850 OWRITE(sc, OHCI_AREQHI, 1 << 31);
1851 if (firewire_phydma_enable) {
1852 /* allow from all nodes */
1853 OWRITE(sc, OHCI_PREQHI, 0x7fffffff);
1854 OWRITE(sc, OHCI_PREQLO, 0xffffffff);
1855 prequpper = ((uintmax_t)Maxmem << PAGE_SHIFT) >> 16;
1856 if (prequpper > OHCI_PREQUPPER_MAX) {
1857 device_printf(fc->dev,
1858 "Physical memory size of 0x%jx exceeds "
1859 "fire wire address space. Limiting dma "
1860 "to memory below 0x%jx\n",
1861 (uintmax_t)Maxmem << PAGE_SHIFT,
1862 (uintmax_t)OHCI_PREQUPPER_MAX << 16);
1863 prequpper = OHCI_PREQUPPER_MAX;
1865 OWRITE(sc, OHCI_PREQUPPER, prequpper & 0xffffffff);
1866 if (OREAD(sc, OHCI_PREQUPPER) !=
1867 (prequpper & 0xffffffff)) {
1868 device_printf(fc->dev,
1869 "PhysicalUpperBound register is not "
1870 "implemented. Physical memory access "
1871 "is limited to the first 4GB\n");
1872 device_printf(fc->dev,
1873 "PhysicalUpperBound = 0x%08x\n",
1874 OREAD(sc, OHCI_PREQUPPER));
1877 /* Set ATRetries register */
1878 OWRITE(sc, OHCI_ATRETRY, 1<<(13 + 16) | 0xfff);
1881 * Checking whether the node is root or not. If root, turn on
1884 node_id = OREAD(sc, FWOHCI_NODEID);
1885 plen = OREAD(sc, OHCI_SID_CNT);
1887 fc->nodeid = node_id & 0x3f;
1888 device_printf(fc->dev, "%s: node_id=0x%08x, SelfID Count=%d, ",
1889 __func__, fc->nodeid, (plen >> 16) & 0xff);
1890 if (!(node_id & OHCI_NODE_VALID)) {
1891 device_printf(fc->dev, "%s: Bus reset failure\n",
1898 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_CYC_LOST);
1899 if ((node_id & OHCI_NODE_ROOT) && !nocyclemaster) {
1900 printf("CYCLEMASTER mode\n");
1901 OWRITE(sc, OHCI_LNKCTL,
1902 OHCI_CNTL_CYCMTR | OHCI_CNTL_CYCTIMER);
1904 printf("non CYCLEMASTER mode\n");
1905 OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCMTR);
1906 OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_CYCTIMER);
1909 fc->status = FWBUSINIT;
1912 taskqueue_enqueue(sc->fc.taskqueue, &sc->fwohci_task_sid);
1915 if ((stat & ~(OHCI_INT_PHY_BUS_R | OHCI_INT_PHY_SID)) && (!kdb_active))
1916 taskqueue_enqueue(sc->fc.taskqueue, &sc->fwohci_task_dma);
1920 fwohci_intr_dma(struct fwohci_softc *sc, uint32_t stat, int count)
1922 uint32_t irstat, itstat;
1924 struct firewire_comm *fc = (struct firewire_comm *)sc;
1926 if (stat & OHCI_INT_DMA_IR) {
1927 irstat = atomic_readandclear_int(&sc->irstat);
1928 for (i = 0; i < fc->nisodma; i++) {
1929 struct fwohci_dbch *dbch;
1931 if ((irstat & (1 << i)) != 0) {
1933 if ((dbch->xferq.flag & FWXFERQ_OPEN) == 0) {
1934 device_printf(sc->fc.dev,
1935 "dma(%d) not active\n", i);
1938 fwohci_rbuf_update(sc, i);
1942 if (stat & OHCI_INT_DMA_IT) {
1943 itstat = atomic_readandclear_int(&sc->itstat);
1944 for (i = 0; i < fc->nisodma; i++) {
1945 if ((itstat & (1 << i)) != 0) {
1946 fwohci_tbuf_update(sc, i);
1950 if (stat & OHCI_INT_DMA_PRRS) {
1952 dump_dma(sc, ARRS_CH);
1953 dump_db(sc, ARRS_CH);
1955 fwohci_arcv(sc, &sc->arrs, count);
1957 if (stat & OHCI_INT_DMA_PRRQ) {
1959 dump_dma(sc, ARRQ_CH);
1960 dump_db(sc, ARRQ_CH);
1962 fwohci_arcv(sc, &sc->arrq, count);
1964 if (stat & OHCI_INT_CYC_LOST) {
1965 if (sc->cycle_lost >= 0)
1967 if (sc->cycle_lost > 10) {
1968 sc->cycle_lost = -1;
1970 OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCTIMER);
1972 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST);
1973 device_printf(fc->dev, "too many cycles lost, "
1974 "no cycle master present?\n");
1977 if (stat & OHCI_INT_DMA_ATRQ) {
1978 fwohci_txd(sc, &(sc->atrq));
1980 if (stat & OHCI_INT_DMA_ATRS) {
1981 fwohci_txd(sc, &(sc->atrs));
1983 if (stat & OHCI_INT_PW_ERR) {
1984 device_printf(fc->dev, "posted write error\n");
1986 if (stat & OHCI_INT_ERR) {
1987 device_printf(fc->dev, "unrecoverable error\n");
1989 if (stat & OHCI_INT_PHY_INT) {
1990 device_printf(fc->dev, "phy int\n");
1995 fwohci_task_busreset(void *arg, int pending)
1997 struct fwohci_softc *sc = (struct fwohci_softc *)arg;
2000 fw_busreset(&sc->fc, FWBUSRESET);
2001 OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
2002 OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
2003 FW_GUNLOCK(&sc->fc);
2007 fwohci_task_sid(void *arg, int pending)
2009 struct fwohci_softc *sc = (struct fwohci_softc *)arg;
2010 struct firewire_comm *fc = &sc->fc;
2016 * We really should have locking
2017 * here. Not sure why it's not
2019 plen = OREAD(sc, OHCI_SID_CNT);
2021 if (plen & OHCI_SID_ERR) {
2022 device_printf(fc->dev, "SID Error\n");
2025 plen &= OHCI_SID_CNT_MASK;
2026 if (plen < 4 || plen > OHCI_SIDSIZE) {
2027 device_printf(fc->dev, "invalid SID len = %d\n", plen);
2030 plen -= 4; /* chop control info */
2031 buf = (uint32_t *)malloc(OHCI_SIDSIZE, M_FW, M_NOWAIT);
2033 device_printf(fc->dev, "malloc failed\n");
2036 for (i = 0; i < plen / 4; i++)
2037 buf[i] = FWOHCI_DMA_READ(sc->sid_buf[i + 1]);
2039 /* pending all pre-bus_reset packets */
2040 fwohci_txd(sc, &sc->atrq);
2041 fwohci_txd(sc, &sc->atrs);
2042 fwohci_arcv(sc, &sc->arrs, -1);
2043 fwohci_arcv(sc, &sc->arrq, -1);
2045 fw_sidrcv(fc, buf, plen);
2050 fwohci_task_dma(void *arg, int pending)
2052 struct fwohci_softc *sc = (struct fwohci_softc *)arg;
2056 stat = atomic_readandclear_int(&sc->intstat);
2058 fwohci_intr_dma(sc, stat, -1);
2065 fwohci_check_stat(struct fwohci_softc *sc)
2067 uint32_t stat, irstat, itstat;
2069 FW_GLOCK_ASSERT(&sc->fc);
2070 stat = OREAD(sc, FWOHCI_INTSTAT);
2071 if (stat == 0xffffffff) {
2072 if (!bus_child_present(sc->fc.dev))
2073 return (FILTER_HANDLED);
2074 device_printf(sc->fc.dev, "device physically ejected?\n");
2075 return (FILTER_STRAY);
2078 OWRITE(sc, FWOHCI_INTSTATCLR, stat & ~OHCI_INT_PHY_BUS_R);
2080 stat &= sc->intmask;
2082 return (FILTER_STRAY);
2084 atomic_set_int(&sc->intstat, stat);
2085 if (stat & OHCI_INT_DMA_IR) {
2086 irstat = OREAD(sc, OHCI_IR_STAT);
2087 OWRITE(sc, OHCI_IR_STATCLR, irstat);
2088 atomic_set_int(&sc->irstat, irstat);
2090 if (stat & OHCI_INT_DMA_IT) {
2091 itstat = OREAD(sc, OHCI_IT_STAT);
2092 OWRITE(sc, OHCI_IT_STATCLR, itstat);
2093 atomic_set_int(&sc->itstat, itstat);
2096 fwohci_intr_core(sc, stat, -1);
2097 return (FILTER_HANDLED);
2101 fwohci_intr(void *arg)
2103 struct fwohci_softc *sc = (struct fwohci_softc *)arg;
2106 fwohci_check_stat(sc);
2107 FW_GUNLOCK(&sc->fc);
2111 fwohci_poll(struct firewire_comm *fc, int quick, int count)
2113 struct fwohci_softc *sc = (struct fwohci_softc *)fc;
2116 fwohci_check_stat(sc);
2121 fwohci_set_intr(struct firewire_comm *fc, int enable)
2123 struct fwohci_softc *sc;
2125 sc = (struct fwohci_softc *)fc;
2127 device_printf(sc->fc.dev, "fwohci_set_intr: %d\n", enable);
2129 sc->intmask |= OHCI_INT_EN;
2130 OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_EN);
2132 sc->intmask &= ~OHCI_INT_EN;
2133 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_EN);
2138 fwohci_tbuf_update(struct fwohci_softc *sc, int dmach)
2140 struct firewire_comm *fc = &sc->fc;
2141 struct fwohcidb *db;
2142 struct fw_bulkxfer *chunk;
2143 struct fw_xferq *it;
2144 uint32_t stat, count;
2148 ldesc = sc->it[dmach].ndesc - 1;
2149 s = splfw(); /* unnecessary ? */
2151 fwdma_sync_multiseg_all(sc->it[dmach].am, BUS_DMASYNC_POSTREAD);
2153 dump_db(sc, ITX_CH + dmach);
2154 while ((chunk = STAILQ_FIRST(&it->stdma)) != NULL) {
2155 db = ((struct fwohcidb_tr *)(chunk->end))->db;
2156 stat = FWOHCI_DMA_READ(db[ldesc].db.desc.res)
2157 >> OHCI_STATUS_SHIFT;
2158 db = ((struct fwohcidb_tr *)(chunk->start))->db;
2160 count = FWOHCI_DMA_READ(db[ldesc].db.desc.res)
2164 STAILQ_REMOVE_HEAD(&it->stdma, link);
2165 switch (stat & FWOHCIEV_MASK) {
2166 case FWOHCIEV_ACKCOMPL:
2168 device_printf(fc->dev, "0x%08x\n", count);
2172 device_printf(fc->dev,
2173 "Isochronous transmit err %02x(%s)\n",
2174 stat, fwohcicode[stat & 0x1f]);
2176 STAILQ_INSERT_TAIL(&it->stfree, chunk, link);
2186 fwohci_rbuf_update(struct fwohci_softc *sc, int dmach)
2188 struct firewire_comm *fc = &sc->fc;
2189 struct fwohcidb_tr *db_tr;
2190 struct fw_bulkxfer *chunk;
2191 struct fw_xferq *ir;
2196 ldesc = sc->ir[dmach].ndesc - 1;
2201 if ((ir->flag & FWXFERQ_HANDLER) == 0)
2203 fwdma_sync_multiseg_all(sc->ir[dmach].am, BUS_DMASYNC_POSTREAD);
2204 while ((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
2205 db_tr = (struct fwohcidb_tr *)chunk->end;
2206 stat = FWOHCI_DMA_READ(db_tr->db[ldesc].db.desc.res)
2207 >> OHCI_STATUS_SHIFT;
2211 if (chunk->mbuf != NULL) {
2212 bus_dmamap_sync(sc->ir[dmach].dmat, db_tr->dma_map,
2213 BUS_DMASYNC_POSTREAD);
2214 bus_dmamap_unload(sc->ir[dmach].dmat, db_tr->dma_map);
2215 } else if (ir->buf != NULL) {
2216 fwdma_sync_multiseg(ir->buf, chunk->poffset,
2217 ir->bnpacket, BUS_DMASYNC_POSTREAD);
2220 printf("fwohci_rbuf_update: this shouldn't happened\n");
2223 STAILQ_REMOVE_HEAD(&ir->stdma, link);
2224 STAILQ_INSERT_TAIL(&ir->stvalid, chunk, link);
2225 switch (stat & FWOHCIEV_MASK) {
2226 case FWOHCIEV_ACKCOMPL:
2230 chunk->resp = EINVAL;
2231 device_printf(fc->dev,
2232 "Isochronous receive err %02x(%s)\n",
2233 stat, fwohcicode[stat & 0x1f]);
2237 if ((ir->flag & FWXFERQ_HANDLER) == 0)
2242 if (ir->flag & FWXFERQ_HANDLER)
2249 dump_dma(struct fwohci_softc *sc, uint32_t ch)
2251 uint32_t off, cntl, stat, cmd, match;
2255 } else if (ch == 1) {
2257 } else if (ch == 2) {
2259 } else if (ch == 3) {
2261 } else if (ch < IRX_CH) {
2262 off = OHCI_ITCTL(ch - ITX_CH);
2264 off = OHCI_IRCTL(ch - IRX_CH);
2266 cntl = stat = OREAD(sc, off);
2267 cmd = OREAD(sc, off + 0xc);
2268 match = OREAD(sc, off + 0x10);
2270 device_printf(sc->fc.dev, "ch %1x cntl:0x%08x cmd:0x%08x match:0x%08x\n",
2277 device_printf(sc->fc.dev, "dma %d ch:%s%s%s%s%s%s %s(%x)\n",
2279 stat & OHCI_CNTL_DMA_RUN ? "RUN," : "",
2280 stat & OHCI_CNTL_DMA_WAKE ? "WAKE," : "",
2281 stat & OHCI_CNTL_DMA_DEAD ? "DEAD," : "",
2282 stat & OHCI_CNTL_DMA_ACTIVE ? "ACTIVE," : "",
2283 stat & OHCI_CNTL_DMA_BT ? "BRANCH," : "",
2284 stat & OHCI_CNTL_DMA_BAD ? "BADDMA," : "",
2285 fwohcicode[stat & 0x1f],
2289 device_printf(sc->fc.dev, "dma %d ch: Nostat\n", ch);
2294 dump_db(struct fwohci_softc *sc, uint32_t ch)
2296 struct fwohci_dbch *dbch;
2297 struct fwohcidb_tr *cp = NULL, *pp, *np = NULL;
2298 struct fwohcidb *curr = NULL, *prev, *next = NULL;
2305 } else if (ch == 1) {
2308 } else if (ch == 2) {
2311 } else if (ch == 3) {
2314 } else if (ch < IRX_CH) {
2315 off = OHCI_ITCTL(ch - ITX_CH);
2316 dbch = &sc->it[ch - ITX_CH];
2318 off = OHCI_IRCTL(ch - IRX_CH);
2319 dbch = &sc->ir[ch - IRX_CH];
2321 cmd = OREAD(sc, off + 0xc);
2323 if (dbch->ndb == 0) {
2324 device_printf(sc->fc.dev, "No DB is attached ch=%d\n", ch);
2329 for (idb = 0; idb < dbch->ndb; idb++) {
2330 cp = STAILQ_NEXT(pp, link);
2335 np = STAILQ_NEXT(cp, link);
2336 for (jdb = 0; jdb < dbch->ndesc; jdb++) {
2337 if ((cmd & 0xfffffff0) == cp->bus_addr) {
2347 pp = STAILQ_NEXT(pp, link);
2357 printf("Prev DB %d\n", ch);
2358 print_db(pp, prev, ch, dbch->ndesc);
2360 printf("Current DB %d\n", ch);
2361 print_db(cp, curr, ch, dbch->ndesc);
2363 printf("Next DB %d\n", ch);
2364 print_db(np, next, ch, dbch->ndesc);
2367 printf("dbdump err ch = %d cmd = 0x%08x\n", ch, cmd);
2373 print_db(struct fwohcidb_tr *db_tr, struct fwohcidb *db,
2374 uint32_t ch, uint32_t max)
2381 printf("No Descriptor is found\n");
2385 printf("ch = %d\n%8s %s %s %s %s %4s %8s %8s %4s:%4s\n",
2397 for (i = 0; i <= max; i++) {
2398 cmd = FWOHCI_DMA_READ(db[i].db.desc.cmd);
2399 res = FWOHCI_DMA_READ(db[i].db.desc.res);
2400 key = cmd & OHCI_KEY_MASK;
2401 stat = res >> OHCI_STATUS_SHIFT;
2402 printf("%08jx %s %s %s %s %5d %08x %08x %04x:%04x",
2403 (uintmax_t)db_tr->bus_addr,
2404 dbcode[(cmd >> 28) & 0xf],
2405 dbkey[(cmd >> 24) & 0x7],
2406 dbcond[(cmd >> 20) & 0x3],
2407 dbcond[(cmd >> 18) & 0x3],
2408 cmd & OHCI_COUNT_MASK,
2409 FWOHCI_DMA_READ(db[i].db.desc.addr),
2410 FWOHCI_DMA_READ(db[i].db.desc.depend),
2412 res & OHCI_COUNT_MASK);
2413 if (stat & 0xff00) {
2414 printf(" %s%s%s%s%s%s %s(%x)\n",
2415 stat & OHCI_CNTL_DMA_RUN ? "RUN," : "",
2416 stat & OHCI_CNTL_DMA_WAKE ? "WAKE," : "",
2417 stat & OHCI_CNTL_DMA_DEAD ? "DEAD," : "",
2418 stat & OHCI_CNTL_DMA_ACTIVE ? "ACTIVE," : "",
2419 stat & OHCI_CNTL_DMA_BT ? "BRANCH," : "",
2420 stat & OHCI_CNTL_DMA_BAD ? "BADDMA," : "",
2421 fwohcicode[stat & 0x1f],
2425 printf(" Nostat\n");
2427 if (key == OHCI_KEY_ST2) {
2428 printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
2429 FWOHCI_DMA_READ(db[i + 1].db.immed[0]),
2430 FWOHCI_DMA_READ(db[i + 1].db.immed[1]),
2431 FWOHCI_DMA_READ(db[i + 1].db.immed[2]),
2432 FWOHCI_DMA_READ(db[i + 1].db.immed[3]));
2434 if (key == OHCI_KEY_DEVICE) {
2437 if ((cmd & OHCI_BRANCH_MASK)
2438 == OHCI_BRANCH_ALWAYS) {
2441 if ((cmd & OHCI_CMD_MASK)
2442 == OHCI_OUTPUT_LAST) {
2445 if ((cmd & OHCI_CMD_MASK)
2446 == OHCI_INPUT_LAST) {
2449 if (key == OHCI_KEY_ST2) {
2457 fwohci_ibr(struct firewire_comm *fc)
2459 struct fwohci_softc *sc;
2462 device_printf(fc->dev, "Initiate bus reset\n");
2463 sc = (struct fwohci_softc *)fc;
2467 * Make sure our cached values from the config rom are
2470 OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
2471 OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
2474 * Set root hold-off bit so that non cyclemaster capable node
2475 * shouldn't became the root node.
2478 fun = fwphy_rddata(sc, FW_PHY_IBR_REG);
2479 fun |= FW_PHY_IBR | FW_PHY_RHB;
2480 fun = fwphy_wrdata(sc, FW_PHY_IBR_REG, fun);
2481 #else /* Short bus reset */
2482 fun = fwphy_rddata(sc, FW_PHY_ISBR_REG);
2483 fun |= FW_PHY_ISBR | FW_PHY_RHB;
2484 fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun);
2490 fwohci_txbufdb(struct fwohci_softc *sc, int dmach, struct fw_bulkxfer *bulkxfer)
2492 struct fwohcidb_tr *db_tr, *fdb_tr;
2493 struct fwohci_dbch *dbch;
2494 struct fwohcidb *db;
2496 struct fwohci_txpkthdr *ohcifp;
2497 unsigned short chtag;
2500 FW_GLOCK_ASSERT(&sc->fc);
2502 dbch = &sc->it[dmach];
2503 chtag = sc->it[dmach].xferq.flag & 0xff;
2505 db_tr = (struct fwohcidb_tr *)(bulkxfer->start);
2506 fdb_tr = (struct fwohcidb_tr *)(bulkxfer->end);
2508 device_printf(sc->fc.dev, "DB %08x %08x %08x\n", bulkxfer, db_tr->bus_addr, fdb_tr->bus_addr);
2510 for (idb = 0; idb < dbch->xferq.bnpacket; idb++) {
2512 fp = (struct fw_pkt *)db_tr->buf;
2513 ohcifp = (struct fwohci_txpkthdr *) db[1].db.immed;
2514 ohcifp->mode.ld[0] = fp->mode.ld[0];
2515 ohcifp->mode.common.spd = 0 & 0x7;
2516 ohcifp->mode.stream.len = fp->mode.stream.len;
2517 ohcifp->mode.stream.chtag = chtag;
2518 ohcifp->mode.stream.tcode = 0xa;
2519 #if BYTE_ORDER == BIG_ENDIAN
2520 FWOHCI_DMA_WRITE(db[1].db.immed[0], db[1].db.immed[0]);
2521 FWOHCI_DMA_WRITE(db[1].db.immed[1], db[1].db.immed[1]);
2524 FWOHCI_DMA_CLEAR(db[2].db.desc.cmd, OHCI_COUNT_MASK);
2525 FWOHCI_DMA_SET(db[2].db.desc.cmd, fp->mode.stream.len);
2526 FWOHCI_DMA_WRITE(db[2].db.desc.res, 0);
2527 #if 0 /* if bulkxfer->npackets changes */
2528 db[2].db.desc.cmd = OHCI_OUTPUT_LAST
2530 | OHCI_BRANCH_ALWAYS;
2531 db[0].db.desc.depend =
2532 = db[dbch->ndesc - 1].db.desc.depend
2533 = STAILQ_NEXT(db_tr, link)->bus_addr | dbch->ndesc;
2535 FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
2536 FWOHCI_DMA_SET(db[dbch->ndesc - 1].db.desc.depend, dbch->ndesc);
2538 bulkxfer->end = (caddr_t)db_tr;
2539 db_tr = STAILQ_NEXT(db_tr, link);
2541 db = ((struct fwohcidb_tr *)bulkxfer->end)->db;
2542 FWOHCI_DMA_CLEAR(db[0].db.desc.depend, 0xf);
2543 FWOHCI_DMA_CLEAR(db[dbch->ndesc - 1].db.desc.depend, 0xf);
2544 #if 0 /* if bulkxfer->npackets changes */
2545 db[dbch->ndesc - 1].db.desc.control |= OHCI_INTERRUPT_ALWAYS;
2546 /* OHCI 1.1 and above */
2547 db[0].db.desc.control |= OHCI_INTERRUPT_ALWAYS;
2550 db_tr = (struct fwohcidb_tr *)bulkxfer->start;
2551 fdb_tr = (struct fwohcidb_tr *)bulkxfer->end;
2552 device_printf(sc->fc.dev, "DB %08x %3d %08x %08x\n", bulkxfer, bulkxfer->npacket, db_tr->bus_addr, fdb_tr->bus_addr);
2558 fwohci_add_tx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
2561 struct fwohcidb *db = db_tr->db;
2562 struct fw_xferq *it;
2570 db_tr->buf = fwdma_v_addr(it->buf, poffset);
2573 FWOHCI_DMA_WRITE(db[0].db.desc.cmd,
2574 OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | 8);
2575 FWOHCI_DMA_WRITE(db[0].db.desc.addr, 0);
2576 bzero((void *)&db[1].db.immed[0], sizeof(db[1].db.immed));
2577 FWOHCI_DMA_WRITE(db[2].db.desc.addr,
2578 fwdma_bus_addr(it->buf, poffset) + sizeof(uint32_t));
2580 FWOHCI_DMA_WRITE(db[2].db.desc.cmd,
2581 OHCI_OUTPUT_LAST | OHCI_UPDATE | OHCI_BRANCH_ALWAYS);
2583 FWOHCI_DMA_WRITE(db[0].db.desc.res, 0);
2584 FWOHCI_DMA_WRITE(db[2].db.desc.res, 0);
2590 fwohci_add_rx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
2591 int poffset, struct fwdma_alloc *dummy_dma)
2593 struct fwohcidb *db = db_tr->db;
2594 struct fw_xferq *ir;
2600 if (ir->buf == NULL && (dbch->xferq.flag & FWXFERQ_EXTBUF) == 0) {
2601 if (db_tr->buf == NULL) {
2602 db_tr->buf = fwdma_malloc_size(dbch->dmat,
2603 &db_tr->dma_map, ir->psize, &dbuf[0],
2605 if (db_tr->buf == NULL)
2609 dsiz[0] = ir->psize;
2610 bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
2611 BUS_DMASYNC_PREREAD);
2614 if (dummy_dma != NULL) {
2615 dsiz[db_tr->dbcnt] = sizeof(uint32_t);
2616 dbuf[db_tr->dbcnt++] = dummy_dma->bus_addr;
2618 dsiz[db_tr->dbcnt] = ir->psize;
2619 if (ir->buf != NULL) {
2620 db_tr->buf = fwdma_v_addr(ir->buf, poffset);
2621 dbuf[db_tr->dbcnt] = fwdma_bus_addr(ir->buf, poffset);
2625 for (i = 0; i < db_tr->dbcnt; i++) {
2626 FWOHCI_DMA_WRITE(db[i].db.desc.addr, dbuf[i]);
2627 FWOHCI_DMA_WRITE(db[i].db.desc.cmd, OHCI_INPUT_MORE | dsiz[i]);
2628 if (ir->flag & FWXFERQ_STREAM) {
2629 FWOHCI_DMA_SET(db[i].db.desc.cmd, OHCI_UPDATE);
2631 FWOHCI_DMA_WRITE(db[i].db.desc.res, dsiz[i]);
2633 ldesc = db_tr->dbcnt - 1;
2634 if (ir->flag & FWXFERQ_STREAM) {
2635 FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_INPUT_LAST);
2637 FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_BRANCH_ALWAYS);
2643 fwohci_arcv_swap(struct fw_pkt *fp, int len)
2648 #if BYTE_ORDER == BIG_ENDIAN
2652 ld0 = FWOHCI_DMA_READ(fp->mode.ld[0]);
2654 printf("ld0: x%08x\n", ld0);
2656 fp0 = (struct fw_pkt *)&ld0;
2657 /* determine length to swap */
2658 switch (fp0->mode.common.tcode) {
2663 case FWOHCITCODE_PHY:
2674 printf("Unknown tcode %d\n", fp0->mode.common.tcode);
2677 hlen = tinfo[fp0->mode.common.tcode].hdr_len;
2680 printf("splitted header\n");
2683 #if BYTE_ORDER == BIG_ENDIAN
2684 for (i = 0; i < slen/4; i++)
2685 fp->mode.ld[i] = FWOHCI_DMA_READ(fp->mode.ld[i]);
2691 fwohci_get_plen(struct fwohci_softc *sc, struct fwohci_dbch *dbch, struct fw_pkt *fp)
2693 struct tcode_info *info;
2696 info = &tinfo[fp->mode.common.tcode];
2697 r = info->hdr_len + sizeof(uint32_t);
2698 if ((info->flag & FWTI_BLOCK_ASY) != 0)
2699 r += roundup2(fp->mode.wreqb.len, sizeof(uint32_t));
2701 if (r == sizeof(uint32_t)) {
2703 device_printf(sc->fc.dev, "Unknown tcode %d\n",
2704 fp->mode.common.tcode);
2708 if (r > dbch->xferq.psize) {
2709 device_printf(sc->fc.dev, "Invalid packet length %d\n", r);
2718 fwohci_arcv_free_buf(struct fwohci_softc *sc, struct fwohci_dbch *dbch,
2719 struct fwohcidb_tr *db_tr, uint32_t off, int wake)
2721 struct fwohcidb *db = &db_tr->db[0];
2723 FWOHCI_DMA_CLEAR(db->db.desc.depend, 0xf);
2724 FWOHCI_DMA_WRITE(db->db.desc.res, dbch->xferq.psize);
2725 FWOHCI_DMA_SET(dbch->bottom->db[0].db.desc.depend, 1);
2726 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREWRITE);
2727 dbch->bottom = db_tr;
2730 OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
2734 fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count)
2736 struct fwohcidb_tr *db_tr;
2737 struct iovec vec[2];
2738 struct fw_pkt pktbuf;
2742 uint32_t stat, off, status, event;
2744 int len, plen, hlen, pcnt, offset;
2749 if (&sc->arrq == dbch) {
2751 } else if (&sc->arrs == dbch) {
2760 /* XXX we cannot handle a packet which lies in more than two buf */
2761 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTREAD);
2762 fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_POSTWRITE);
2763 status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) >> OHCI_STATUS_SHIFT;
2764 resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) & OHCI_COUNT_MASK;
2765 while (status & OHCI_CNTL_DMA_ACTIVE) {
2768 if (off == OHCI_ARQOFF)
2769 printf("buf 0x%08x, status 0x%04x, resCount 0x%04x\n",
2770 db_tr->bus_addr, status, resCount);
2772 len = dbch->xferq.psize - resCount;
2773 ld = (uint8_t *)db_tr->buf;
2774 if (dbch->pdb_tr == NULL) {
2775 len -= dbch->buf_offset;
2776 ld += dbch->buf_offset;
2779 bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
2780 BUS_DMASYNC_POSTREAD);
2782 if (count >= 0 && count-- == 0)
2784 if (dbch->pdb_tr != NULL) {
2785 /* we have a fragment in previous buffer */
2788 offset = dbch->buf_offset;
2791 buf = dbch->pdb_tr->buf + offset;
2792 rlen = dbch->xferq.psize - offset;
2794 printf("rlen=%d, offset=%d\n",
2795 rlen, dbch->buf_offset);
2796 if (dbch->buf_offset < 0) {
2797 /* splitted in header, pull up */
2800 p = (char *)&pktbuf;
2801 bcopy(buf, p, rlen);
2803 /* this must be too long but harmless */
2804 rlen = sizeof(pktbuf) - rlen;
2806 printf("why rlen < 0\n");
2807 bcopy(db_tr->buf, p, rlen);
2810 hlen = fwohci_arcv_swap(&pktbuf, sizeof(pktbuf));
2812 printf("hlen should be positive.");
2815 offset = sizeof(pktbuf);
2816 vec[0].iov_base = (char *)&pktbuf;
2817 vec[0].iov_len = offset;
2819 /* splitted in payload */
2821 vec[0].iov_base = buf;
2822 vec[0].iov_len = rlen;
2824 fp=(struct fw_pkt *)vec[0].iov_base;
2827 /* no fragment in previous buffer */
2828 fp=(struct fw_pkt *)ld;
2829 hlen = fwohci_arcv_swap(fp, len);
2833 dbch->pdb_tr = db_tr;
2834 dbch->buf_offset = - dbch->buf_offset;
2836 if (resCount != 0) {
2837 printf("resCount=%d hlen=%d\n",
2846 plen = fwohci_get_plen(sc, dbch, fp) - offset;
2848 /* minimum header size + trailer
2849 = sizeof(fw_pkt) so this shouldn't happens */
2850 printf("plen(%d) is negative! offset=%d\n",
2857 dbch->pdb_tr = db_tr;
2859 printf("splitted payload\n");
2861 if (resCount != 0) {
2862 printf("resCount=%d plen=%d"
2864 resCount, plen, len);
2869 vec[nvec].iov_base = ld;
2870 vec[nvec].iov_len = plen;
2874 dbch->buf_offset = ld - (uint8_t *)db_tr->buf;
2876 printf("nvec == 0\n");
2878 /* DMA result-code will be written at the tail of packet */
2879 stat = FWOHCI_DMA_READ(*(uint32_t *)(ld - sizeof(struct fwohci_trailer)));
2881 printf("plen: %d, stat %x\n",
2884 spd = (stat >> 21) & 0x3;
2885 event = (stat >> 16) & 0x1f;
2887 case FWOHCIEV_ACKPEND:
2889 printf("fwohci_arcv: ack pending tcode=0x%x..\n", fp->mode.common.tcode);
2892 case FWOHCIEV_ACKCOMPL:
2894 struct fw_rcv_buf rb;
2896 if ((vec[nvec-1].iov_len -=
2897 sizeof(struct fwohci_trailer)) == 0)
2906 case FWOHCIEV_BUSRST:
2907 if ((sc->fc.status != FWBUSRESET) &&
2908 (sc->fc.status != FWBUSINIT))
2909 printf("got BUSRST packet!?\n");
2912 device_printf(sc->fc.dev,
2913 "Async DMA Receive error err=%02x %s"
2914 " plen=%d offset=%d len=%d status=0x%08x"
2915 " tcode=0x%x, stat=0x%08x\n",
2916 event, fwohcicode[event], plen,
2917 dbch->buf_offset, len,
2918 OREAD(sc, OHCI_DMACTL(off)),
2919 fp->mode.common.tcode, stat);
2926 if (dbch->pdb_tr != NULL) {
2927 fwohci_arcv_free_buf(sc, dbch, dbch->pdb_tr,
2929 dbch->pdb_tr = NULL;
2934 if (resCount == 0) {
2935 /* done on this buffer */
2936 if (dbch->pdb_tr == NULL) {
2937 fwohci_arcv_free_buf(sc, dbch, db_tr, off, 1);
2938 dbch->buf_offset = 0;
2940 if (dbch->pdb_tr != db_tr)
2941 printf("pdb_tr != db_tr\n");
2942 db_tr = STAILQ_NEXT(db_tr, link);
2943 status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
2944 >> OHCI_STATUS_SHIFT;
2945 resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
2947 /* XXX check buffer overrun */
2950 dbch->buf_offset = dbch->xferq.psize - resCount;
2953 /* XXX make sure DMA is not dead */
2957 printf("fwohci_arcv: no packets\n");
2963 device_printf(sc->fc.dev, "AR DMA status=%x, ",
2964 OREAD(sc, OHCI_DMACTL(off)));
2965 dbch->pdb_tr = NULL;
2966 /* skip until resCount != 0 */
2967 printf(" skip buffer");
2968 while (resCount == 0) {
2970 fwohci_arcv_free_buf(sc, dbch, db_tr, off, 0);
2971 db_tr = STAILQ_NEXT(db_tr, link);
2972 resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
2977 dbch->buf_offset = dbch->xferq.psize - resCount;
2978 OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);