2 * Copyright (c) 2003 Hidetoshi Shimokawa
3 * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the acknowledgement as bellow:
17 * This product includes software developed by K. Kobayashi and H. Shimokawa
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 * $FreeBSD: src/sys/dev/firewire/fwohci.c,v 1.72 2004/01/22 14:41:17 simokawa Exp $
35 * $FreeBSD: src/sys/dev/firewire/fwohci.c,v 1.1.2.19 2003/05/01 06:24:37 simokawa Exp $
36 * $DragonFly: src/sys/bus/firewire/fwohci.c,v 1.16 2008/01/06 16:55:49 swildner Exp $
46 #include <sys/param.h>
47 #include <sys/systm.h>
49 #include <sys/malloc.h>
50 #include <sys/sockio.h>
52 #include <sys/kernel.h>
54 #include <sys/device.h>
55 #include <sys/endian.h>
57 #include <sys/thread2.h>
59 #if defined(__DragonFly__) || __FreeBSD_version < 500000
60 #include <machine/clock.h> /* for DELAY() */
65 #include "firewirereg.h"
67 #include "fwohcireg.h"
68 #include "fwohcivar.h"
69 #include "firewire_phy.h"
71 #include <dev/firewire/firewire.h>
72 #include <dev/firewire/firewirereg.h>
73 #include <dev/firewire/fwdma.h>
74 #include <dev/firewire/fwohcireg.h>
75 #include <dev/firewire/fwohcivar.h>
76 #include <dev/firewire/firewire_phy.h>
81 static char dbcode
[16][0x10]={"OUTM", "OUTL","INPM","INPL",
82 "STOR","LOAD","NOP ","STOP",};
84 static char dbkey
[8][0x10]={"ST0", "ST1","ST2","ST3",
85 "UNDEF","REG","SYS","DEV"};
86 static char dbcond
[4][0x10]={"NEV","C=1", "C=0", "ALL"};
87 char fwohcicode
[32][0x20]={
88 "No stat","Undef","long","miss Ack err",
89 "underrun","overrun","desc err", "data read err",
90 "data write err","bus reset","timeout","tcode err",
91 "Undef","Undef","unknown event","flushed",
92 "Undef","ack complete","ack pend","Undef",
93 "ack busy_X","ack busy_A","ack busy_B","Undef",
94 "Undef","Undef","Undef","ack tardy",
95 "Undef","ack data_err","ack type_err",""};
98 extern char *linkspeed
[];
99 u_int32_t tagbit
[4] = { 1 << 28, 1 << 29, 1 << 30, 1 << 31};
101 static struct tcode_info tinfo
[] = {
102 /* hdr_len block flag*/
103 /* 0 WREQQ */ {16, FWTI_REQ
| FWTI_TLABEL
},
104 /* 1 WREQB */ {16, FWTI_REQ
| FWTI_TLABEL
| FWTI_BLOCK_ASY
},
105 /* 2 WRES */ {12, FWTI_RES
},
107 /* 4 RREQQ */ {12, FWTI_REQ
| FWTI_TLABEL
},
108 /* 5 RREQB */ {16, FWTI_REQ
| FWTI_TLABEL
},
109 /* 6 RRESQ */ {16, FWTI_RES
},
110 /* 7 RRESB */ {16, FWTI_RES
| FWTI_BLOCK_ASY
},
111 /* 8 CYCS */ { 0, 0},
112 /* 9 LREQ */ {16, FWTI_REQ
| FWTI_TLABEL
| FWTI_BLOCK_ASY
},
113 /* a STREAM */ { 4, FWTI_REQ
| FWTI_BLOCK_STR
},
114 /* b LRES */ {16, FWTI_RES
| FWTI_BLOCK_ASY
},
117 /* e PHY */ {12, FWTI_REQ
},
121 #define OHCI_WRITE_SIGMASK 0xffff0000
122 #define OHCI_READ_SIGMASK 0xffff0000
124 #define OWRITE(sc, r, x) bus_space_write_4((sc)->bst, (sc)->bsh, (r), (x))
125 #define OREAD(sc, r) bus_space_read_4((sc)->bst, (sc)->bsh, (r))
127 static void fwohci_ibr (struct firewire_comm
*);
128 static void fwohci_db_init (struct fwohci_softc
*, struct fwohci_dbch
*);
129 static void fwohci_db_free (struct fwohci_dbch
*);
130 static void fwohci_arcv (struct fwohci_softc
*, struct fwohci_dbch
*, int);
131 static void fwohci_txd (struct fwohci_softc
*, struct fwohci_dbch
*);
132 static void fwohci_start_atq (struct firewire_comm
*);
133 static void fwohci_start_ats (struct firewire_comm
*);
134 static void fwohci_start (struct fwohci_softc
*, struct fwohci_dbch
*);
135 static u_int32_t
fwphy_wrdata ( struct fwohci_softc
*, u_int32_t
, u_int32_t
);
136 static u_int32_t
fwphy_rddata ( struct fwohci_softc
*, u_int32_t
);
137 static int fwohci_rx_enable (struct fwohci_softc
*, struct fwohci_dbch
*);
138 static int fwohci_tx_enable (struct fwohci_softc
*, struct fwohci_dbch
*);
139 static int fwohci_irx_enable (struct firewire_comm
*, int);
140 static int fwohci_irx_disable (struct firewire_comm
*, int);
141 #if BYTE_ORDER == BIG_ENDIAN
142 static void fwohci_irx_post (struct firewire_comm
*, u_int32_t
*);
144 static int fwohci_itxbuf_enable (struct firewire_comm
*, int);
145 static int fwohci_itx_disable (struct firewire_comm
*, int);
146 static void fwohci_timeout (void *);
147 static void fwohci_set_intr (struct firewire_comm
*, int);
149 static int fwohci_add_rx_buf (struct fwohci_dbch
*, struct fwohcidb_tr
*, int, struct fwdma_alloc
*);
150 static int fwohci_add_tx_buf (struct fwohci_dbch
*, struct fwohcidb_tr
*, int);
151 static void dump_db (struct fwohci_softc
*, u_int32_t
);
152 static void print_db (struct fwohcidb_tr
*, struct fwohcidb
*, u_int32_t
, u_int32_t
);
153 static void dump_dma (struct fwohci_softc
*, u_int32_t
);
154 static u_int32_t
fwohci_cyctimer (struct firewire_comm
*);
155 static void fwohci_rbuf_update (struct fwohci_softc
*, int);
156 static void fwohci_tbuf_update (struct fwohci_softc
*, int);
157 void fwohci_txbufdb (struct fwohci_softc
*, int , struct fw_bulkxfer
*);
159 static void fwohci_complete(void *, int);
163 * memory allocated for DMA programs
165 #define DMA_PROG_ALLOC (8 * PAGE_SIZE)
167 #define NDB FWMAXQUEUE
169 #define OHCI_VERSION 0x00
170 #define OHCI_ATRETRY 0x08
171 #define OHCI_CROMHDR 0x18
172 #define OHCI_BUS_OPT 0x20
173 #define OHCI_BUSIRMC (1 << 31)
174 #define OHCI_BUSCMC (1 << 30)
175 #define OHCI_BUSISC (1 << 29)
176 #define OHCI_BUSBMC (1 << 28)
177 #define OHCI_BUSPMC (1 << 27)
178 #define OHCI_BUSFNC OHCI_BUSIRMC | OHCI_BUSCMC | OHCI_BUSISC |\
179 OHCI_BUSBMC | OHCI_BUSPMC
181 #define OHCI_EUID_HI 0x24
182 #define OHCI_EUID_LO 0x28
184 #define OHCI_CROMPTR 0x34
185 #define OHCI_HCCCTL 0x50
186 #define OHCI_HCCCTLCLR 0x54
187 #define OHCI_AREQHI 0x100
188 #define OHCI_AREQHICLR 0x104
189 #define OHCI_AREQLO 0x108
190 #define OHCI_AREQLOCLR 0x10c
191 #define OHCI_PREQHI 0x110
192 #define OHCI_PREQHICLR 0x114
193 #define OHCI_PREQLO 0x118
194 #define OHCI_PREQLOCLR 0x11c
195 #define OHCI_PREQUPPER 0x120
197 #define OHCI_SID_BUF 0x64
198 #define OHCI_SID_CNT 0x68
199 #define OHCI_SID_ERR (1 << 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
264 fwphy_wrdata( struct fwohci_softc
*sc
, u_int32_t addr
, u_int32_t data
)
271 fun
= (PHYDEV_WRCMD
| (addr
<< PHYDEV_REGADDR
) | (data
<< PHYDEV_WRDATA
));
272 OWRITE(sc
, OHCI_PHYACCESS
, fun
);
275 return(fwphy_rddata( sc
, addr
));
279 fwohci_set_bus_manager(struct firewire_comm
*fc
, u_int node
)
281 struct fwohci_softc
*sc
= (struct fwohci_softc
*)fc
;
285 #define OHCI_CSR_DATA 0x0c
286 #define OHCI_CSR_COMP 0x10
287 #define OHCI_CSR_CONT 0x14
288 #define OHCI_BUS_MANAGER_ID 0
290 OWRITE(sc
, OHCI_CSR_DATA
, node
);
291 OWRITE(sc
, OHCI_CSR_COMP
, 0x3f);
292 OWRITE(sc
, OHCI_CSR_CONT
, OHCI_BUS_MANAGER_ID
);
293 for (i
= 0; !(OREAD(sc
, OHCI_CSR_CONT
) & (1<<31)) && (i
< 1000); i
++)
295 bm
= OREAD(sc
, OHCI_CSR_DATA
);
296 if((bm
& 0x3f) == 0x3f)
299 device_printf(sc
->fc
.dev
,
300 "fw_set_bus_manager: %d->%d (loop=%d)\n", 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)
325 device_printf(sc
->fc
.dev
, "phy read failed(1).\n");
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
, "phy read failed(2).\n");
337 if (++retry
< MAX_RETRY
) {
342 if (bootverbose
|| retry
>= MAX_RETRY
)
343 device_printf(sc
->fc
.dev
,
344 "fwphy_rddata: 0x%x loop=%d, retry=%d\n", addr
, i
, retry
);
346 return((fun
>> PHYDEV_RDDATA
)& 0xff);
348 /* Device specific ioctl. */
350 fwohci_ioctl (struct dev_ioctl_args
*ap
)
352 cdev_t dev
= ap
->a_head
.a_dev
;
353 struct firewire_softc
*sc
;
354 struct fwohci_softc
*fc
;
355 int unit
= DEV2UNIT(dev
);
357 struct fw_reg_req_t
*reg
= (struct fw_reg_req_t
*) ap
->a_data
;
358 u_int32_t
*dmach
= (u_int32_t
*) ap
->a_data
;
360 sc
= devclass_get_softc(firewire_devclass
, unit
);
364 fc
= (struct fwohci_softc
*)sc
->fc
;
371 #define OHCI_MAX_REG 0x800
372 if(reg
->addr
<= OHCI_MAX_REG
){
373 OWRITE(fc
, reg
->addr
, reg
->data
);
374 reg
->data
= OREAD(fc
, reg
->addr
);
380 if(reg
->addr
<= OHCI_MAX_REG
){
381 reg
->data
= OREAD(fc
, reg
->addr
);
386 /* Read DMA descriptors for debug */
388 if(*dmach
<= OHCI_MAX_DMA_CH
){
389 dump_dma(fc
, *dmach
);
395 /* Read/Write Phy registers */
396 #define OHCI_MAX_PHY_REG 0xf
397 case FWOHCI_RDPHYREG
:
398 if (reg
->addr
<= OHCI_MAX_PHY_REG
)
399 reg
->data
= fwphy_rddata(fc
, reg
->addr
);
403 case FWOHCI_WRPHYREG
:
404 if (reg
->addr
<= OHCI_MAX_PHY_REG
)
405 reg
->data
= fwphy_wrdata(fc
, reg
->addr
, reg
->data
);
417 fwohci_probe_phy(struct fwohci_softc
*sc
, device_t dev
)
422 * probe PHY parameters
423 * 0. to prove PHY version, whether compliance of 1394a.
424 * 1. to probe maximum speed supported by the PHY and
425 * number of port supported by core-logic.
426 * It is not actually available port on your PC .
428 OWRITE(sc
, OHCI_HCCCTL
, OHCI_HCC_LPS
);
429 reg
= fwphy_rddata(sc
, FW_PHY_SPD_REG
);
431 if((reg
>> 5) != 7 ){
432 sc
->fc
.mode
&= ~FWPHYASYST
;
433 sc
->fc
.nport
= reg
& FW_PHY_NP
;
434 sc
->fc
.speed
= reg
& FW_PHY_SPD
>> 6;
435 if (sc
->fc
.speed
> MAX_SPEED
) {
436 device_printf(dev
, "invalid speed %d (fixed to %d).\n",
437 sc
->fc
.speed
, MAX_SPEED
);
438 sc
->fc
.speed
= MAX_SPEED
;
441 "Phy 1394 only %s, %d ports.\n",
442 linkspeed
[sc
->fc
.speed
], sc
->fc
.nport
);
444 reg2
= fwphy_rddata(sc
, FW_PHY_ESPD_REG
);
445 sc
->fc
.mode
|= FWPHYASYST
;
446 sc
->fc
.nport
= reg
& FW_PHY_NP
;
447 sc
->fc
.speed
= (reg2
& FW_PHY_ESPD
) >> 5;
448 if (sc
->fc
.speed
> MAX_SPEED
) {
449 device_printf(dev
, "invalid speed %d (fixed to %d).\n",
450 sc
->fc
.speed
, MAX_SPEED
);
451 sc
->fc
.speed
= MAX_SPEED
;
454 "Phy 1394a available %s, %d ports.\n",
455 linkspeed
[sc
->fc
.speed
], sc
->fc
.nport
);
457 /* check programPhyEnable */
458 reg2
= fwphy_rddata(sc
, 5);
460 if (e1394a
&& (OREAD(sc
, OHCI_HCCCTL
) & OHCI_HCC_PRPHY
)) {
461 #else /* XXX force to enable 1394a */
466 "Enable 1394a Enhancements\n");
469 /* set aPhyEnhanceEnable */
470 OWRITE(sc
, OHCI_HCCCTL
, OHCI_HCC_PHYEN
);
471 OWRITE(sc
, OHCI_HCCCTLCLR
, OHCI_HCC_PRPHY
);
476 reg2
= fwphy_wrdata(sc
, 5, reg2
);
479 reg
= fwphy_rddata(sc
, FW_PHY_SPD_REG
);
480 if((reg
>> 5) == 7 ){
481 reg
= fwphy_rddata(sc
, 4);
483 fwphy_wrdata(sc
, 4, reg
);
484 reg
= fwphy_rddata(sc
, 4);
491 fwohci_reset(struct fwohci_softc
*sc
, device_t dev
)
493 int i
, max_rec
, speed
;
495 struct fwohcidb_tr
*db_tr
;
497 /* Disable interrupt */
498 OWRITE(sc
, FWOHCI_INTMASKCLR
, ~0);
500 /* Now stopping all DMA channel */
501 OWRITE(sc
, OHCI_ARQCTLCLR
, OHCI_CNTL_DMA_RUN
);
502 OWRITE(sc
, OHCI_ARSCTLCLR
, OHCI_CNTL_DMA_RUN
);
503 OWRITE(sc
, OHCI_ATQCTLCLR
, OHCI_CNTL_DMA_RUN
);
504 OWRITE(sc
, OHCI_ATSCTLCLR
, OHCI_CNTL_DMA_RUN
);
506 OWRITE(sc
, OHCI_IR_MASKCLR
, ~0);
507 for( i
= 0 ; i
< sc
->fc
.nisodma
; i
++ ){
508 OWRITE(sc
, OHCI_IRCTLCLR(i
), OHCI_CNTL_DMA_RUN
);
509 OWRITE(sc
, OHCI_ITCTLCLR(i
), OHCI_CNTL_DMA_RUN
);
512 /* FLUSH FIFO and reset Transmitter/Reciever */
513 OWRITE(sc
, OHCI_HCCCTL
, OHCI_HCC_RESET
);
515 device_printf(dev
, "resetting OHCI...");
517 while(OREAD(sc
, OHCI_HCCCTL
) & OHCI_HCC_RESET
) {
518 if (i
++ > 100) break;
522 kprintf("done (loop=%d)\n", i
);
525 fwohci_probe_phy(sc
, dev
);
528 reg
= OREAD(sc
, OHCI_BUS_OPT
);
529 reg2
= reg
| OHCI_BUSFNC
;
530 max_rec
= (reg
& 0x0000f000) >> 12;
531 speed
= (reg
& 0x00000007);
532 device_printf(dev
, "Link %s, max_rec %d bytes.\n",
533 linkspeed
[speed
], MAXREC(max_rec
));
534 /* XXX fix max_rec */
535 sc
->fc
.maxrec
= sc
->fc
.speed
+ 8;
536 if (max_rec
!= sc
->fc
.maxrec
) {
537 reg2
= (reg2
& 0xffff0fff) | (sc
->fc
.maxrec
<< 12);
538 device_printf(dev
, "max_rec %d -> %d\n",
539 MAXREC(max_rec
), MAXREC(sc
->fc
.maxrec
));
542 device_printf(dev
, "BUS_OPT 0x%x -> 0x%x\n", reg
, reg2
);
543 OWRITE(sc
, OHCI_BUS_OPT
, reg2
);
545 /* Initialize registers */
546 OWRITE(sc
, OHCI_CROMHDR
, sc
->fc
.config_rom
[0]);
547 OWRITE(sc
, OHCI_CROMPTR
, sc
->crom_dma
.bus_addr
);
548 OWRITE(sc
, OHCI_HCCCTLCLR
, OHCI_HCC_BIGEND
);
549 OWRITE(sc
, OHCI_HCCCTL
, OHCI_HCC_POSTWR
);
550 OWRITE(sc
, OHCI_SID_BUF
, sc
->sid_dma
.bus_addr
);
551 OWRITE(sc
, OHCI_LNKCTL
, OHCI_CNTL_SID
);
554 OWRITE(sc
, OHCI_HCCCTL
, OHCI_HCC_LINKEN
);
556 /* Force to start async RX DMA */
557 sc
->arrq
.xferq
.flag
&= ~FWXFERQ_RUNNING
;
558 sc
->arrs
.xferq
.flag
&= ~FWXFERQ_RUNNING
;
559 fwohci_rx_enable(sc
, &sc
->arrq
);
560 fwohci_rx_enable(sc
, &sc
->arrs
);
562 /* Initialize async TX */
563 OWRITE(sc
, OHCI_ATQCTLCLR
, OHCI_CNTL_DMA_RUN
| OHCI_CNTL_DMA_DEAD
);
564 OWRITE(sc
, OHCI_ATSCTLCLR
, OHCI_CNTL_DMA_RUN
| OHCI_CNTL_DMA_DEAD
);
567 OWRITE(sc
, FWOHCI_RETRY
,
568 /* CycleLimit PhyRespRetries ATRespRetries ATReqRetries */
569 (0xffff << 16 ) | (0x0f << 8) | (0x0f << 4) | 0x0f) ;
571 sc
->atrq
.top
= STAILQ_FIRST(&sc
->atrq
.db_trq
);
572 sc
->atrs
.top
= STAILQ_FIRST(&sc
->atrs
.db_trq
);
573 sc
->atrq
.bottom
= sc
->atrq
.top
;
574 sc
->atrs
.bottom
= sc
->atrs
.top
;
576 for( i
= 0, db_tr
= sc
->atrq
.top
; i
< sc
->atrq
.ndb
;
577 i
++, db_tr
= STAILQ_NEXT(db_tr
, link
)){
580 for( i
= 0, db_tr
= sc
->atrs
.top
; i
< sc
->atrs
.ndb
;
581 i
++, db_tr
= STAILQ_NEXT(db_tr
, link
)){
586 /* Enable interrupt */
587 OWRITE(sc
, FWOHCI_INTMASK
,
588 OHCI_INT_ERR
| OHCI_INT_PHY_SID
589 | OHCI_INT_DMA_ATRQ
| OHCI_INT_DMA_ATRS
590 | OHCI_INT_DMA_PRRQ
| OHCI_INT_DMA_PRRS
591 | OHCI_INT_PHY_BUS_R
| OHCI_INT_PW_ERR
);
592 fwohci_set_intr(&sc
->fc
, 1);
597 fwohci_init(struct fwohci_softc
*sc
, device_t dev
)
604 TASK_INIT(&sc
->fwohci_task_complete
, 0, fwohci_complete
, sc
);
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 Isochrounous 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 channel 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
);
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);
698 /* SID recieve buffer must allign 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
);
702 if (sc
->sid_buf
== NULL
) {
703 device_printf(dev
, "sid_buf alloc failed.");
707 fwdma_malloc(&sc
->fc
, sizeof(u_int32_t
), sizeof(u_int32_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;
760 fwohci_reset(sc
, dev
);
766 fwohci_timeout(void *arg
)
768 struct fwohci_softc
*sc
;
770 sc
= (struct fwohci_softc
*)arg
;
774 fwohci_cyctimer(struct firewire_comm
*fc
)
776 struct fwohci_softc
*sc
= (struct fwohci_softc
*)fc
;
777 return(OREAD(sc
, OHCI_CYCLETIMER
));
781 fwohci_detach(struct fwohci_softc
*sc
, device_t dev
)
785 if (sc
->sid_buf
!= NULL
)
786 fwdma_free(&sc
->fc
, &sc
->sid_dma
);
787 if (sc
->fc
.config_rom
!= NULL
)
788 fwdma_free(&sc
->fc
, &sc
->crom_dma
);
790 fwohci_db_free(&sc
->arrq
);
791 fwohci_db_free(&sc
->arrs
);
793 fwohci_db_free(&sc
->atrq
);
794 fwohci_db_free(&sc
->atrs
);
796 for( i
= 0 ; i
< sc
->fc
.nisodma
; i
++ ){
797 fwohci_db_free(&sc
->it
[i
]);
798 fwohci_db_free(&sc
->ir
[i
]);
804 #define LAST_DB(dbtr, db) do { \
805 struct fwohcidb_tr *_dbtr = (dbtr); \
806 int _cnt = _dbtr->dbcnt; \
807 db = &_dbtr->db[ (_cnt > 2) ? (_cnt -1) : 0]; \
811 fwohci_execute_db(void *arg
, bus_dma_segment_t
*segs
, int nseg
, int error
)
813 struct fwohcidb_tr
*db_tr
;
815 bus_dma_segment_t
*s
;
818 db_tr
= (struct fwohcidb_tr
*)arg
;
819 db
= &db_tr
->db
[db_tr
->dbcnt
];
821 if (firewire_debug
|| error
!= EFBIG
)
822 kprintf("fwohci_execute_db: error=%d\n", error
);
825 for (i
= 0; i
< nseg
; i
++) {
827 FWOHCI_DMA_WRITE(db
->db
.desc
.addr
, s
->ds_addr
);
828 FWOHCI_DMA_WRITE(db
->db
.desc
.cmd
, s
->ds_len
);
829 FWOHCI_DMA_WRITE(db
->db
.desc
.res
, 0);
836 fwohci_execute_db2(void *arg
, bus_dma_segment_t
*segs
, int nseg
,
837 bus_size_t size
, int error
)
839 fwohci_execute_db(arg
, segs
, nseg
, error
);
843 fwohci_start(struct fwohci_softc
*sc
, struct fwohci_dbch
*dbch
)
846 int tcode
, hdr_len
, pl_off
;
849 struct fw_xfer
*xfer
;
851 struct fwohci_txpkthdr
*ohcifp
;
852 struct fwohcidb_tr
*db_tr
;
855 struct tcode_info
*info
;
856 static int maxdesc
=0;
858 if(&sc
->atrq
== dbch
){
860 }else if(&sc
->atrs
== dbch
){
866 if (dbch
->flags
& FWOHCI_DBCH_FULL
)
872 xfer
= STAILQ_FIRST(&dbch
->xferq
.q
);
876 if(dbch
->xferq
.queued
== 0 ){
877 device_printf(sc
->fc
.dev
, "TX queue empty\n");
879 STAILQ_REMOVE_HEAD(&dbch
->xferq
.q
, link
);
881 xfer
->state
= FWXF_START
;
883 fp
= &xfer
->send
.hdr
;
884 tcode
= fp
->mode
.common
.tcode
;
886 ohcifp
= (struct fwohci_txpkthdr
*) db_tr
->db
[1].db
.immed
;
887 info
= &tinfo
[tcode
];
888 hdr_len
= pl_off
= info
->hdr_len
;
890 ld
= &ohcifp
->mode
.ld
[0];
891 ld
[0] = ld
[1] = ld
[2] = ld
[3] = 0;
892 for( i
= 0 ; i
< pl_off
; i
+= 4)
893 ld
[i
/4] = fp
->mode
.ld
[i
/4];
895 ohcifp
->mode
.common
.spd
= xfer
->send
.spd
& 0x7;
896 if (tcode
== FWTCODE_STREAM
){
898 ohcifp
->mode
.stream
.len
= fp
->mode
.stream
.len
;
899 } else if (tcode
== FWTCODE_PHY
) {
901 ld
[1] = fp
->mode
.ld
[1];
902 ld
[2] = fp
->mode
.ld
[2];
903 ohcifp
->mode
.common
.spd
= 0;
904 ohcifp
->mode
.common
.tcode
= FWOHCITCODE_PHY
;
906 ohcifp
->mode
.asycomm
.dst
= fp
->mode
.hdr
.dst
;
907 ohcifp
->mode
.asycomm
.srcbus
= OHCI_ASYSRCBUS
;
908 ohcifp
->mode
.asycomm
.tlrt
|= FWRETRY_X
;
911 FWOHCI_DMA_WRITE(db
->db
.desc
.cmd
,
912 OHCI_OUTPUT_MORE
| OHCI_KEY_ST2
| hdr_len
);
913 FWOHCI_DMA_WRITE(db
->db
.desc
.addr
, 0);
914 FWOHCI_DMA_WRITE(db
->db
.desc
.res
, 0);
915 /* Specify bound timer of asy. responce */
916 if(&sc
->atrs
== dbch
){
917 FWOHCI_DMA_WRITE(db
->db
.desc
.res
,
918 (OREAD(sc
, OHCI_CYCLETIMER
) >> 12) + (1 << 13));
920 #if BYTE_ORDER == BIG_ENDIAN
921 if (tcode
== FWTCODE_WREQQ
|| tcode
== FWTCODE_RRESQ
)
923 for (i
= 0; i
< hdr_len
/4; i
++)
924 FWOHCI_DMA_WRITE(ld
[i
], ld
[i
]);
929 db
= &db_tr
->db
[db_tr
->dbcnt
];
930 if (xfer
->send
.pay_len
> 0) {
933 if (xfer
->mbuf
== NULL
) {
934 err
= bus_dmamap_load(dbch
->dmat
, db_tr
->dma_map
,
935 &xfer
->send
.payload
[0], xfer
->send
.pay_len
,
936 fwohci_execute_db
, db_tr
,
939 /* XXX we can handle only 6 (=8-2) mbuf chains */
940 err
= bus_dmamap_load_mbuf(dbch
->dmat
, db_tr
->dma_map
,
942 fwohci_execute_db2
, db_tr
,
948 device_printf(sc
->fc
.dev
, "EFBIG.\n");
949 m0
= m_getcl(MB_DONTWAIT
, MT_DATA
, M_PKTHDR
);
951 m_copydata(xfer
->mbuf
, 0,
952 xfer
->mbuf
->m_pkthdr
.len
,
954 m0
->m_len
= m0
->m_pkthdr
.len
=
955 xfer
->mbuf
->m_pkthdr
.len
;
960 device_printf(sc
->fc
.dev
, "m_getcl failed.\n");
964 kprintf("dmamap_load: err=%d\n", err
);
965 bus_dmamap_sync(dbch
->dmat
, db_tr
->dma_map
,
966 BUS_DMASYNC_PREWRITE
);
967 #if 0 /* OHCI_OUTPUT_MODE == 0 */
968 for (i
= 2; i
< db_tr
->dbcnt
; i
++)
969 FWOHCI_DMA_SET(db_tr
->db
[i
].db
.desc
.cmd
,
973 if (maxdesc
< db_tr
->dbcnt
) {
974 maxdesc
= db_tr
->dbcnt
;
976 device_printf(sc
->fc
.dev
, "maxdesc: %d\n", maxdesc
);
980 FWOHCI_DMA_SET(db
->db
.desc
.cmd
,
981 OHCI_OUTPUT_LAST
| OHCI_INTERRUPT_ALWAYS
| OHCI_BRANCH_ALWAYS
);
982 FWOHCI_DMA_WRITE(db
->db
.desc
.depend
,
983 STAILQ_NEXT(db_tr
, link
)->bus_addr
);
986 fsegment
= db_tr
->dbcnt
;
987 if (dbch
->pdb_tr
!= NULL
) {
988 LAST_DB(dbch
->pdb_tr
, db
);
989 FWOHCI_DMA_SET(db
->db
.desc
.depend
, db_tr
->dbcnt
);
991 dbch
->pdb_tr
= db_tr
;
992 db_tr
= STAILQ_NEXT(db_tr
, link
);
993 if(db_tr
!= dbch
->bottom
){
996 device_printf(sc
->fc
.dev
, "fwohci_start: lack of db_trq\n");
997 dbch
->flags
|= FWOHCI_DBCH_FULL
;
1001 fwdma_sync_multiseg_all(dbch
->am
, BUS_DMASYNC_PREREAD
);
1002 fwdma_sync_multiseg_all(dbch
->am
, BUS_DMASYNC_PREWRITE
);
1004 if(dbch
->xferq
.flag
& FWXFERQ_RUNNING
) {
1005 OWRITE(sc
, OHCI_DMACTL(off
), OHCI_CNTL_DMA_WAKE
);
1008 device_printf(sc
->fc
.dev
, "start AT DMA status=%x\n",
1009 OREAD(sc
, OHCI_DMACTL(off
)));
1010 OWRITE(sc
, OHCI_DMACMD(off
), dbch
->top
->bus_addr
| fsegment
);
1011 OWRITE(sc
, OHCI_DMACTL(off
), OHCI_CNTL_DMA_RUN
);
1012 dbch
->xferq
.flag
|= FWXFERQ_RUNNING
;
1021 fwohci_start_atq(struct firewire_comm
*fc
)
1023 struct fwohci_softc
*sc
= (struct fwohci_softc
*)fc
;
1024 fwohci_start( sc
, &(sc
->atrq
));
1029 fwohci_start_ats(struct firewire_comm
*fc
)
1031 struct fwohci_softc
*sc
= (struct fwohci_softc
*)fc
;
1032 fwohci_start( sc
, &(sc
->atrs
));
1037 fwohci_txd(struct fwohci_softc
*sc
, struct fwohci_dbch
*dbch
)
1040 struct fwohcidb_tr
*tr
;
1041 struct fwohcidb
*db
;
1042 struct fw_xfer
*xfer
;
1046 struct firewire_comm
*fc
= (struct firewire_comm
*)sc
;
1048 if(&sc
->atrq
== dbch
){
1051 }else if(&sc
->atrs
== dbch
){
1060 fwdma_sync_multiseg_all(dbch
->am
, BUS_DMASYNC_POSTREAD
);
1061 fwdma_sync_multiseg_all(dbch
->am
, BUS_DMASYNC_POSTWRITE
);
1062 while(dbch
->xferq
.queued
> 0){
1064 status
= FWOHCI_DMA_READ(db
->db
.desc
.res
) >> OHCI_STATUS_SHIFT
;
1065 if(!(status
& OHCI_CNTL_DMA_ACTIVE
)){
1066 if (fc
->status
!= FWBUSRESET
)
1067 /* maybe out of order?? */
1070 bus_dmamap_sync(dbch
->dmat
, tr
->dma_map
,
1071 BUS_DMASYNC_POSTWRITE
);
1072 bus_dmamap_unload(dbch
->dmat
, tr
->dma_map
);
1077 if(status
& OHCI_CNTL_DMA_DEAD
) {
1079 OWRITE(sc
, OHCI_DMACTLCLR(off
), OHCI_CNTL_DMA_RUN
);
1080 device_printf(sc
->fc
.dev
, "force reset AT FIFO\n");
1081 OWRITE(sc
, OHCI_HCCCTLCLR
, OHCI_HCC_LINKEN
);
1082 OWRITE(sc
, OHCI_HCCCTL
, OHCI_HCC_LPS
| OHCI_HCC_LINKEN
);
1083 OWRITE(sc
, OHCI_DMACTLCLR(off
), OHCI_CNTL_DMA_RUN
);
1085 stat
= status
& FWOHCIEV_MASK
;
1087 case FWOHCIEV_ACKPEND
:
1088 case FWOHCIEV_ACKCOMPL
:
1091 case FWOHCIEV_ACKBSA
:
1092 case FWOHCIEV_ACKBSB
:
1093 case FWOHCIEV_ACKBSX
:
1094 device_printf(sc
->fc
.dev
, "txd err=%2x %s\n", stat
, fwohcicode
[stat
]);
1097 case FWOHCIEV_FLUSHED
:
1098 case FWOHCIEV_ACKTARD
:
1099 device_printf(sc
->fc
.dev
, "txd err=%2x %s\n", stat
, fwohcicode
[stat
]);
1102 case FWOHCIEV_MISSACK
:
1103 case FWOHCIEV_UNDRRUN
:
1104 case FWOHCIEV_OVRRUN
:
1105 case FWOHCIEV_DESCERR
:
1106 case FWOHCIEV_DTRDERR
:
1107 case FWOHCIEV_TIMEOUT
:
1108 case FWOHCIEV_TCODERR
:
1109 case FWOHCIEV_UNKNOWN
:
1110 case FWOHCIEV_ACKDERR
:
1111 case FWOHCIEV_ACKTERR
:
1113 device_printf(sc
->fc
.dev
, "txd err=%2x %s\n",
1114 stat
, fwohcicode
[stat
]);
1118 if (tr
->xfer
!= NULL
) {
1120 if (xfer
->state
== FWXF_RCVD
) {
1123 kprintf("already rcvd\n");
1127 xfer
->state
= FWXF_SENT
;
1128 if (err
== EBUSY
&& fc
->status
!= FWBUSRESET
) {
1129 xfer
->state
= FWXF_BUSY
;
1131 if (xfer
->retry_req
!= NULL
)
1132 xfer
->retry_req(xfer
);
1134 xfer
->recv
.pay_len
= 0;
1137 } else if (stat
!= FWOHCIEV_ACKPEND
) {
1138 if (stat
!= FWOHCIEV_ACKCOMPL
)
1139 xfer
->state
= FWXF_SENTERR
;
1141 xfer
->recv
.pay_len
= 0;
1146 * The watchdog timer takes care of split
1147 * transcation timeout for ACKPEND case.
1150 kprintf("this shouldn't happen\n");
1152 dbch
->xferq
.queued
--;
1156 tr
= STAILQ_NEXT(tr
, link
);
1158 if (dbch
->bottom
== dbch
->top
) {
1159 /* we reaches the end of context program */
1160 if (firewire_debug
&& dbch
->xferq
.queued
> 0)
1161 kprintf("queued > 0\n");
1166 if ((dbch
->flags
& FWOHCI_DBCH_FULL
) && packets
> 0) {
1167 kprintf("make free slot\n");
1168 dbch
->flags
&= ~FWOHCI_DBCH_FULL
;
1169 fwohci_start(sc
, dbch
);
1175 fwohci_db_free(struct fwohci_dbch
*dbch
)
1177 struct fwohcidb_tr
*db_tr
;
1180 if ((dbch
->flags
& FWOHCI_DBCH_INIT
) == 0)
1183 for(db_tr
= STAILQ_FIRST(&dbch
->db_trq
), idb
= 0; idb
< dbch
->ndb
;
1184 db_tr
= STAILQ_NEXT(db_tr
, link
), idb
++){
1185 if ((dbch
->xferq
.flag
& FWXFERQ_EXTBUF
) == 0 &&
1186 db_tr
->buf
!= NULL
) {
1187 fwdma_free_size(dbch
->dmat
, db_tr
->dma_map
,
1188 db_tr
->buf
, dbch
->xferq
.psize
);
1190 } else if (db_tr
->dma_map
!= NULL
)
1191 bus_dmamap_destroy(dbch
->dmat
, db_tr
->dma_map
);
1194 db_tr
= STAILQ_FIRST(&dbch
->db_trq
);
1195 fwdma_free_multiseg(dbch
->am
);
1197 STAILQ_INIT(&dbch
->db_trq
);
1198 dbch
->flags
&= ~FWOHCI_DBCH_INIT
;
1202 fwohci_db_init(struct fwohci_softc
*sc
, struct fwohci_dbch
*dbch
)
1205 struct fwohcidb_tr
*db_tr
;
1207 if ((dbch
->flags
& FWOHCI_DBCH_INIT
) != 0)
1210 /* create dma_tag for buffers */
1211 #define MAX_REQCOUNT 0xffff
1212 if (bus_dma_tag_create(/*parent*/ sc
->fc
.dmat
,
1213 /*alignment*/ 1, /*boundary*/ 0,
1214 /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT
,
1215 /*highaddr*/ BUS_SPACE_MAXADDR
,
1216 /*filter*/NULL
, /*filterarg*/NULL
,
1217 /*maxsize*/ dbch
->xferq
.psize
,
1218 /*nsegments*/ dbch
->ndesc
> 3 ? dbch
->ndesc
- 2 : 1,
1219 /*maxsegsz*/ MAX_REQCOUNT
,
1221 #if defined(__FreeBSD__) && __FreeBSD_version >= 501102
1222 /*lockfunc*/busdma_lock_mutex
,
1228 /* allocate DB entries and attach one to each DMA channels */
1229 /* DB entry must start at 16 bytes bounary. */
1230 STAILQ_INIT(&dbch
->db_trq
);
1231 db_tr
= (struct fwohcidb_tr
*)
1232 kmalloc(sizeof(struct fwohcidb_tr
) * dbch
->ndb
,
1233 M_FW
, M_WAITOK
| M_ZERO
);
1235 #define DB_SIZE(x) (sizeof(struct fwohcidb) * (x)->ndesc)
1236 dbch
->am
= fwdma_malloc_multiseg(&sc
->fc
, DB_SIZE(dbch
),
1237 DB_SIZE(dbch
), dbch
->ndb
, BUS_DMA_WAITOK
);
1238 if (dbch
->am
== NULL
) {
1239 kprintf("fwohci_db_init: fwdma_malloc_multiseg failed\n");
1243 /* Attach DB to DMA ch. */
1244 for(idb
= 0 ; idb
< dbch
->ndb
; idb
++){
1246 db_tr
->db
= (struct fwohcidb
*)fwdma_v_addr(dbch
->am
, idb
);
1247 db_tr
->bus_addr
= fwdma_bus_addr(dbch
->am
, idb
);
1248 /* create dmamap for buffers */
1249 /* XXX do we need 4bytes alignment tag? */
1250 /* XXX don't alloc dma_map for AR */
1251 if (bus_dmamap_create(dbch
->dmat
, 0, &db_tr
->dma_map
) != 0) {
1252 kprintf("bus_dmamap_create failed\n");
1253 dbch
->flags
= FWOHCI_DBCH_INIT
; /* XXX fake */
1254 fwohci_db_free(dbch
);
1257 STAILQ_INSERT_TAIL(&dbch
->db_trq
, db_tr
, link
);
1258 if (dbch
->xferq
.flag
& FWXFERQ_EXTBUF
) {
1259 if (idb
% dbch
->xferq
.bnpacket
== 0)
1260 dbch
->xferq
.bulkxfer
[idb
/ dbch
->xferq
.bnpacket
1261 ].start
= (caddr_t
)db_tr
;
1262 if ((idb
+ 1) % dbch
->xferq
.bnpacket
== 0)
1263 dbch
->xferq
.bulkxfer
[idb
/ dbch
->xferq
.bnpacket
1264 ].end
= (caddr_t
)db_tr
;
1268 STAILQ_LAST(&dbch
->db_trq
, fwohcidb_tr
,link
)->link
.stqe_next
1269 = STAILQ_FIRST(&dbch
->db_trq
);
1271 dbch
->xferq
.queued
= 0;
1272 dbch
->pdb_tr
= NULL
;
1273 dbch
->top
= STAILQ_FIRST(&dbch
->db_trq
);
1274 dbch
->bottom
= dbch
->top
;
1275 dbch
->flags
= FWOHCI_DBCH_INIT
;
1279 fwohci_itx_disable(struct firewire_comm
*fc
, int dmach
)
1281 struct fwohci_softc
*sc
= (struct fwohci_softc
*)fc
;
1284 OWRITE(sc
, OHCI_ITCTLCLR(dmach
),
1285 OHCI_CNTL_DMA_RUN
| OHCI_CNTL_CYCMATCH_S
);
1286 OWRITE(sc
, OHCI_IT_MASKCLR
, 1 << dmach
);
1287 OWRITE(sc
, OHCI_IT_STATCLR
, 1 << dmach
);
1288 /* XXX we cannot free buffers until the DMA really stops */
1289 tsleep((void *)&sleepch
, FWPRI
, "fwitxd", hz
);
1290 fwohci_db_free(&sc
->it
[dmach
]);
1291 sc
->it
[dmach
].xferq
.flag
&= ~FWXFERQ_RUNNING
;
1296 fwohci_irx_disable(struct firewire_comm
*fc
, int dmach
)
1298 struct fwohci_softc
*sc
= (struct fwohci_softc
*)fc
;
1301 OWRITE(sc
, OHCI_IRCTLCLR(dmach
), OHCI_CNTL_DMA_RUN
);
1302 OWRITE(sc
, OHCI_IR_MASKCLR
, 1 << dmach
);
1303 OWRITE(sc
, OHCI_IR_STATCLR
, 1 << dmach
);
1304 /* XXX we cannot free buffers until the DMA really stops */
1305 tsleep((void *)&sleepch
, FWPRI
, "fwirxd", hz
);
1306 fwohci_db_free(&sc
->ir
[dmach
]);
1307 sc
->ir
[dmach
].xferq
.flag
&= ~FWXFERQ_RUNNING
;
1311 #if BYTE_ORDER == BIG_ENDIAN
1313 fwohci_irx_post (struct firewire_comm
*fc
, u_int32_t
*qld
)
1315 qld
[0] = FWOHCI_DMA_READ(qld
[0]);
1321 fwohci_tx_enable(struct fwohci_softc
*sc
, struct fwohci_dbch
*dbch
)
1324 int idb
, z
, i
, dmach
= 0, ldesc
;
1326 struct fwohcidb_tr
*db_tr
;
1327 struct fwohcidb
*db
;
1329 if(!(dbch
->xferq
.flag
& FWXFERQ_EXTBUF
)){
1334 for(dmach
= 0 ; dmach
< sc
->fc
.nisodma
; dmach
++){
1335 if( &sc
->it
[dmach
] == dbch
){
1336 off
= OHCI_ITOFF(dmach
);
1344 if(dbch
->xferq
.flag
& FWXFERQ_RUNNING
)
1346 dbch
->xferq
.flag
|= FWXFERQ_RUNNING
;
1347 for( i
= 0, dbch
->bottom
= dbch
->top
; i
< (dbch
->ndb
- 1); i
++){
1348 dbch
->bottom
= STAILQ_NEXT(dbch
->bottom
, link
);
1351 for (idb
= 0; idb
< dbch
->ndb
; idb
++) {
1352 fwohci_add_tx_buf(dbch
, db_tr
, idb
);
1353 if(STAILQ_NEXT(db_tr
, link
) == NULL
){
1357 ldesc
= db_tr
->dbcnt
- 1;
1358 FWOHCI_DMA_WRITE(db
[0].db
.desc
.depend
,
1359 STAILQ_NEXT(db_tr
, link
)->bus_addr
| z
);
1360 db
[ldesc
].db
.desc
.depend
= db
[0].db
.desc
.depend
;
1361 if(dbch
->xferq
.flag
& FWXFERQ_EXTBUF
){
1362 if(((idb
+ 1 ) % dbch
->xferq
.bnpacket
) == 0){
1364 db
[ldesc
].db
.desc
.cmd
,
1365 OHCI_INTERRUPT_ALWAYS
);
1366 /* OHCI 1.1 and above */
1369 OHCI_INTERRUPT_ALWAYS
);
1372 db_tr
= STAILQ_NEXT(db_tr
, link
);
1375 dbch
->bottom
->db
[dbch
->bottom
->dbcnt
- 1].db
.desc
.depend
, 0xf);
1380 fwohci_rx_enable(struct fwohci_softc
*sc
, struct fwohci_dbch
*dbch
)
1383 int idb
, z
, i
, dmach
= 0, ldesc
;
1385 struct fwohcidb_tr
*db_tr
;
1386 struct fwohcidb
*db
;
1389 if(&sc
->arrq
== dbch
){
1391 }else if(&sc
->arrs
== dbch
){
1394 for(dmach
= 0 ; dmach
< sc
->fc
.nisodma
; dmach
++){
1395 if( &sc
->ir
[dmach
] == dbch
){
1396 off
= OHCI_IROFF(dmach
);
1405 if(dbch
->xferq
.flag
& FWXFERQ_STREAM
){
1406 if(dbch
->xferq
.flag
& FWXFERQ_RUNNING
)
1409 if(dbch
->xferq
.flag
& FWXFERQ_RUNNING
){
1414 dbch
->xferq
.flag
|= FWXFERQ_RUNNING
;
1415 dbch
->top
= STAILQ_FIRST(&dbch
->db_trq
);
1416 for( i
= 0, dbch
->bottom
= dbch
->top
; i
< (dbch
->ndb
- 1); i
++){
1417 dbch
->bottom
= STAILQ_NEXT(dbch
->bottom
, link
);
1420 for (idb
= 0; idb
< dbch
->ndb
; idb
++) {
1421 fwohci_add_rx_buf(dbch
, db_tr
, idb
, &sc
->dummy_dma
);
1422 if (STAILQ_NEXT(db_tr
, link
) == NULL
)
1425 ldesc
= db_tr
->dbcnt
- 1;
1426 FWOHCI_DMA_WRITE(db
[ldesc
].db
.desc
.depend
,
1427 STAILQ_NEXT(db_tr
, link
)->bus_addr
| z
);
1428 if(dbch
->xferq
.flag
& FWXFERQ_EXTBUF
){
1429 if(((idb
+ 1 ) % dbch
->xferq
.bnpacket
) == 0){
1431 db
[ldesc
].db
.desc
.cmd
,
1432 OHCI_INTERRUPT_ALWAYS
);
1434 db
[ldesc
].db
.desc
.depend
,
1438 db_tr
= STAILQ_NEXT(db_tr
, link
);
1441 dbch
->bottom
->db
[db_tr
->dbcnt
- 1].db
.desc
.depend
, 0xf);
1442 dbch
->buf_offset
= 0;
1443 fwdma_sync_multiseg_all(dbch
->am
, BUS_DMASYNC_PREREAD
);
1444 fwdma_sync_multiseg_all(dbch
->am
, BUS_DMASYNC_PREWRITE
);
1445 if(dbch
->xferq
.flag
& FWXFERQ_STREAM
){
1448 OWRITE(sc
, OHCI_DMACMD(off
), dbch
->top
->bus_addr
| z
);
1450 OWRITE(sc
, OHCI_DMACTL(off
), OHCI_CNTL_DMA_RUN
);
1455 fwohci_next_cycle(struct firewire_comm
*fc
, int cycle_now
)
1457 int sec
, cycle
, cycle_match
;
1459 cycle
= cycle_now
& 0x1fff;
1460 sec
= cycle_now
>> 13;
1461 #define CYCLE_MOD 0x10
1463 #define CYCLE_DELAY 8 /* min delay to start DMA */
1465 #define CYCLE_DELAY 7000 /* min delay to start DMA */
1467 cycle
= cycle
+ CYCLE_DELAY
;
1468 if (cycle
>= 8000) {
1472 cycle
= roundup2(cycle
, CYCLE_MOD
);
1473 if (cycle
>= 8000) {
1480 cycle_match
= ((sec
<< 13) | cycle
) & 0x7ffff;
1482 return(cycle_match
);
1486 fwohci_itxbuf_enable(struct firewire_comm
*fc
, int dmach
)
1488 struct fwohci_softc
*sc
= (struct fwohci_softc
*)fc
;
1490 unsigned short tag
, ich
;
1491 struct fwohci_dbch
*dbch
;
1492 int cycle_match
, cycle_now
, ldesc
;
1494 struct fw_bulkxfer
*first
, *chunk
, *prev
;
1495 struct fw_xferq
*it
;
1497 dbch
= &sc
->it
[dmach
];
1500 tag
= (it
->flag
>> 6) & 3;
1501 ich
= it
->flag
& 0x3f;
1502 if ((dbch
->flags
& FWOHCI_DBCH_INIT
) == 0) {
1503 dbch
->ndb
= it
->bnpacket
* it
->bnchunk
;
1505 fwohci_db_init(sc
, dbch
);
1506 if ((dbch
->flags
& FWOHCI_DBCH_INIT
) == 0)
1508 err
= fwohci_tx_enable(sc
, dbch
);
1513 ldesc
= dbch
->ndesc
- 1;
1515 prev
= STAILQ_LAST(&it
->stdma
, fw_bulkxfer
, link
);
1516 while ((chunk
= STAILQ_FIRST(&it
->stvalid
)) != NULL
) {
1517 struct fwohcidb
*db
;
1519 fwdma_sync_multiseg(it
->buf
, chunk
->poffset
, it
->bnpacket
,
1520 BUS_DMASYNC_PREWRITE
);
1521 fwohci_txbufdb(sc
, dmach
, chunk
);
1523 db
= ((struct fwohcidb_tr
*)(prev
->end
))->db
;
1524 #if 0 /* XXX necessary? */
1525 FWOHCI_DMA_SET(db
[ldesc
].db
.desc
.cmd
,
1526 OHCI_BRANCH_ALWAYS
);
1528 #if 0 /* if bulkxfer->npacket changes */
1529 db
[ldesc
].db
.desc
.depend
= db
[0].db
.desc
.depend
=
1530 ((struct fwohcidb_tr
*)
1531 (chunk
->start
))->bus_addr
| dbch
->ndesc
;
1533 FWOHCI_DMA_SET(db
[0].db
.desc
.depend
, dbch
->ndesc
);
1534 FWOHCI_DMA_SET(db
[ldesc
].db
.desc
.depend
, dbch
->ndesc
);
1537 STAILQ_REMOVE_HEAD(&it
->stvalid
, link
);
1538 STAILQ_INSERT_TAIL(&it
->stdma
, chunk
, link
);
1541 fwdma_sync_multiseg_all(dbch
->am
, BUS_DMASYNC_PREWRITE
);
1542 fwdma_sync_multiseg_all(dbch
->am
, BUS_DMASYNC_PREREAD
);
1544 stat
= OREAD(sc
, OHCI_ITCTL(dmach
));
1545 if (firewire_debug
&& (stat
& OHCI_CNTL_CYCMATCH_S
))
1546 kprintf("stat 0x%x\n", stat
);
1548 if (stat
& (OHCI_CNTL_DMA_ACTIVE
| OHCI_CNTL_CYCMATCH_S
))
1552 OWRITE(sc
, OHCI_ITCTLCLR(dmach
), OHCI_CNTL_DMA_RUN
);
1554 OWRITE(sc
, OHCI_IT_MASKCLR
, 1 << dmach
);
1555 OWRITE(sc
, OHCI_IT_STATCLR
, 1 << dmach
);
1556 OWRITE(sc
, OHCI_IT_MASK
, 1 << dmach
);
1557 OWRITE(sc
, FWOHCI_INTMASK
, OHCI_INT_DMA_IT
);
1559 first
= STAILQ_FIRST(&it
->stdma
);
1560 OWRITE(sc
, OHCI_ITCMD(dmach
),
1561 ((struct fwohcidb_tr
*)(first
->start
))->bus_addr
| dbch
->ndesc
);
1562 if (firewire_debug
) {
1563 kprintf("fwohci_itxbuf_enable: kick 0x%08x\n", stat
);
1565 dump_dma(sc
, ITX_CH
+ dmach
);
1568 if ((stat
& OHCI_CNTL_DMA_RUN
) == 0) {
1570 /* Don't start until all chunks are buffered */
1571 if (STAILQ_FIRST(&it
->stfree
) != NULL
)
1575 /* Clear cycle match counter bits */
1576 OWRITE(sc
, OHCI_ITCTLCLR(dmach
), 0xffff0000);
1578 /* 2bit second + 13bit cycle */
1579 cycle_now
= (fc
->cyctimer(fc
) >> 12) & 0x7fff;
1580 cycle_match
= fwohci_next_cycle(fc
, cycle_now
);
1582 OWRITE(sc
, OHCI_ITCTL(dmach
),
1583 OHCI_CNTL_CYCMATCH_S
| (cycle_match
<< 16)
1584 | OHCI_CNTL_DMA_RUN
);
1586 OWRITE(sc
, OHCI_ITCTL(dmach
), OHCI_CNTL_DMA_RUN
);
1588 if (firewire_debug
) {
1589 kprintf("cycle_match: 0x%04x->0x%04x\n",
1590 cycle_now
, cycle_match
);
1591 dump_dma(sc
, ITX_CH
+ dmach
);
1592 dump_db(sc
, ITX_CH
+ dmach
);
1594 } else if ((stat
& OHCI_CNTL_CYCMATCH_S
) == 0) {
1595 device_printf(sc
->fc
.dev
,
1596 "IT DMA underrun (0x%08x)\n", stat
);
1597 OWRITE(sc
, OHCI_ITCTL(dmach
), OHCI_CNTL_DMA_WAKE
);
1604 fwohci_irx_enable(struct firewire_comm
*fc
, int dmach
)
1606 struct fwohci_softc
*sc
= (struct fwohci_softc
*)fc
;
1608 unsigned short tag
, ich
;
1610 struct fwohci_dbch
*dbch
;
1611 struct fwohcidb_tr
*db_tr
;
1612 struct fw_bulkxfer
*first
, *prev
, *chunk
;
1613 struct fw_xferq
*ir
;
1615 dbch
= &sc
->ir
[dmach
];
1618 if ((ir
->flag
& FWXFERQ_RUNNING
) == 0) {
1619 tag
= (ir
->flag
>> 6) & 3;
1620 ich
= ir
->flag
& 0x3f;
1621 OWRITE(sc
, OHCI_IRMATCH(dmach
), tagbit
[tag
] | ich
);
1624 dbch
->ndb
= ir
->bnpacket
* ir
->bnchunk
;
1626 fwohci_db_init(sc
, dbch
);
1627 if ((dbch
->flags
& FWOHCI_DBCH_INIT
) == 0)
1629 err
= fwohci_rx_enable(sc
, dbch
);
1634 first
= STAILQ_FIRST(&ir
->stfree
);
1635 if (first
== NULL
) {
1636 device_printf(fc
->dev
, "IR DMA no free chunk\n");
1640 ldesc
= dbch
->ndesc
- 1;
1642 prev
= STAILQ_LAST(&ir
->stdma
, fw_bulkxfer
, link
);
1643 while ((chunk
= STAILQ_FIRST(&ir
->stfree
)) != NULL
) {
1644 struct fwohcidb
*db
;
1646 #if 1 /* XXX for if_fwe */
1647 if (chunk
->mbuf
!= NULL
) {
1648 db_tr
= (struct fwohcidb_tr
*)(chunk
->start
);
1650 err
= bus_dmamap_load_mbuf(dbch
->dmat
, db_tr
->dma_map
,
1651 chunk
->mbuf
, fwohci_execute_db2
, db_tr
,
1653 FWOHCI_DMA_SET(db_tr
->db
[1].db
.desc
.cmd
,
1654 OHCI_UPDATE
| OHCI_INPUT_LAST
|
1655 OHCI_INTERRUPT_ALWAYS
| OHCI_BRANCH_ALWAYS
);
1658 db
= ((struct fwohcidb_tr
*)(chunk
->end
))->db
;
1659 FWOHCI_DMA_WRITE(db
[ldesc
].db
.desc
.res
, 0);
1660 FWOHCI_DMA_CLEAR(db
[ldesc
].db
.desc
.depend
, 0xf);
1662 db
= ((struct fwohcidb_tr
*)(prev
->end
))->db
;
1663 FWOHCI_DMA_SET(db
[ldesc
].db
.desc
.depend
, dbch
->ndesc
);
1665 STAILQ_REMOVE_HEAD(&ir
->stfree
, link
);
1666 STAILQ_INSERT_TAIL(&ir
->stdma
, chunk
, link
);
1669 fwdma_sync_multiseg_all(dbch
->am
, BUS_DMASYNC_PREWRITE
);
1670 fwdma_sync_multiseg_all(dbch
->am
, BUS_DMASYNC_PREREAD
);
1672 stat
= OREAD(sc
, OHCI_IRCTL(dmach
));
1673 if (stat
& OHCI_CNTL_DMA_ACTIVE
)
1675 if (stat
& OHCI_CNTL_DMA_RUN
) {
1676 OWRITE(sc
, OHCI_IRCTLCLR(dmach
), OHCI_CNTL_DMA_RUN
);
1677 device_printf(sc
->fc
.dev
, "IR DMA overrun (0x%08x)\n", stat
);
1681 kprintf("start IR DMA 0x%x\n", stat
);
1682 OWRITE(sc
, OHCI_IR_MASKCLR
, 1 << dmach
);
1683 OWRITE(sc
, OHCI_IR_STATCLR
, 1 << dmach
);
1684 OWRITE(sc
, OHCI_IR_MASK
, 1 << dmach
);
1685 OWRITE(sc
, OHCI_IRCTLCLR(dmach
), 0xf0000000);
1686 OWRITE(sc
, OHCI_IRCTL(dmach
), OHCI_CNTL_ISOHDR
);
1687 OWRITE(sc
, OHCI_IRCMD(dmach
),
1688 ((struct fwohcidb_tr
*)(first
->start
))->bus_addr
1690 OWRITE(sc
, OHCI_IRCTL(dmach
), OHCI_CNTL_DMA_RUN
);
1691 OWRITE(sc
, FWOHCI_INTMASK
, OHCI_INT_DMA_IR
);
1693 dump_db(sc
, IRX_CH
+ dmach
);
1699 fwohci_stop(struct fwohci_softc
*sc
, device_t dev
)
1703 /* Now stopping all DMA channel */
1704 OWRITE(sc
, OHCI_ARQCTLCLR
, OHCI_CNTL_DMA_RUN
);
1705 OWRITE(sc
, OHCI_ARSCTLCLR
, OHCI_CNTL_DMA_RUN
);
1706 OWRITE(sc
, OHCI_ATQCTLCLR
, OHCI_CNTL_DMA_RUN
);
1707 OWRITE(sc
, OHCI_ATSCTLCLR
, OHCI_CNTL_DMA_RUN
);
1709 for( i
= 0 ; i
< sc
->fc
.nisodma
; i
++ ){
1710 OWRITE(sc
, OHCI_IRCTLCLR(i
), OHCI_CNTL_DMA_RUN
);
1711 OWRITE(sc
, OHCI_ITCTLCLR(i
), OHCI_CNTL_DMA_RUN
);
1714 /* FLUSH FIFO and reset Transmitter/Reciever */
1715 OWRITE(sc
, OHCI_HCCCTL
, OHCI_HCC_RESET
);
1717 /* Stop interrupt */
1718 OWRITE(sc
, FWOHCI_INTMASKCLR
,
1719 OHCI_INT_EN
| OHCI_INT_ERR
| OHCI_INT_PHY_SID
1721 | OHCI_INT_DMA_ATRQ
| OHCI_INT_DMA_ATRS
1722 | OHCI_INT_DMA_PRRQ
| OHCI_INT_DMA_PRRS
1723 | OHCI_INT_DMA_ARRQ
| OHCI_INT_DMA_ARRS
1724 | OHCI_INT_PHY_BUS_R
);
1726 if (sc
->fc
.arq
!=0 && sc
->fc
.arq
->maxq
> 0)
1727 fw_drain_txq(&sc
->fc
);
1729 /* XXX Link down? Bus reset? */
1734 fwohci_resume(struct fwohci_softc
*sc
, device_t dev
)
1737 struct fw_xferq
*ir
;
1738 struct fw_bulkxfer
*chunk
;
1740 fwohci_reset(sc
, dev
);
1741 /* XXX resume isochronus receive automatically. (how about TX?) */
1742 for(i
= 0; i
< sc
->fc
.nisodma
; i
++) {
1743 ir
= &sc
->ir
[i
].xferq
;
1744 if((ir
->flag
& FWXFERQ_RUNNING
) != 0) {
1745 device_printf(sc
->fc
.dev
,
1746 "resume iso receive ch: %d\n", i
);
1747 ir
->flag
&= ~FWXFERQ_RUNNING
;
1748 /* requeue stdma to stfree */
1749 while((chunk
= STAILQ_FIRST(&ir
->stdma
)) != NULL
) {
1750 STAILQ_REMOVE_HEAD(&ir
->stdma
, link
);
1751 STAILQ_INSERT_TAIL(&ir
->stfree
, chunk
, link
);
1753 sc
->fc
.irx_enable(&sc
->fc
, i
);
1757 bus_generic_resume(dev
);
1758 sc
->fc
.ibr(&sc
->fc
);
1764 fwohci_intr_body(struct fwohci_softc
*sc
, u_int32_t stat
, int count
)
1766 u_int32_t irstat
, itstat
;
1768 struct firewire_comm
*fc
= (struct firewire_comm
*)sc
;
1771 if(stat
& OREAD(sc
, FWOHCI_INTMASK
))
1772 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",
1773 stat
& OHCI_INT_EN
? "DMA_EN ":"",
1774 stat
& OHCI_INT_PHY_REG
? "PHY_REG ":"",
1775 stat
& OHCI_INT_CYC_LONG
? "CYC_LONG ":"",
1776 stat
& OHCI_INT_ERR
? "INT_ERR ":"",
1777 stat
& OHCI_INT_CYC_ERR
? "CYC_ERR ":"",
1778 stat
& OHCI_INT_CYC_LOST
? "CYC_LOST ":"",
1779 stat
& OHCI_INT_CYC_64SECOND
? "CYC_64SECOND ":"",
1780 stat
& OHCI_INT_CYC_START
? "CYC_START ":"",
1781 stat
& OHCI_INT_PHY_INT
? "PHY_INT ":"",
1782 stat
& OHCI_INT_PHY_BUS_R
? "BUS_RESET ":"",
1783 stat
& OHCI_INT_PHY_SID
? "SID ":"",
1784 stat
& OHCI_INT_LR_ERR
? "DMA_LR_ERR ":"",
1785 stat
& OHCI_INT_PW_ERR
? "DMA_PW_ERR ":"",
1786 stat
& OHCI_INT_DMA_IR
? "DMA_IR ":"",
1787 stat
& OHCI_INT_DMA_IT
? "DMA_IT " :"",
1788 stat
& OHCI_INT_DMA_PRRS
? "DMA_PRRS " :"",
1789 stat
& OHCI_INT_DMA_PRRQ
? "DMA_PRRQ " :"",
1790 stat
& OHCI_INT_DMA_ARRS
? "DMA_ARRS " :"",
1791 stat
& OHCI_INT_DMA_ARRQ
? "DMA_ARRQ " :"",
1792 stat
& OHCI_INT_DMA_ATRS
? "DMA_ATRS " :"",
1793 stat
& OHCI_INT_DMA_ATRQ
? "DMA_ATRQ " :"",
1794 stat
, OREAD(sc
, FWOHCI_INTMASK
)
1798 if(stat
& OHCI_INT_PHY_BUS_R
){
1799 if (fc
->status
== FWBUSRESET
)
1801 /* Disable bus reset interrupt until sid recv. */
1802 OWRITE(sc
, FWOHCI_INTMASKCLR
, OHCI_INT_PHY_BUS_R
);
1804 device_printf(fc
->dev
, "BUS reset\n");
1805 OWRITE(sc
, FWOHCI_INTMASKCLR
, OHCI_INT_CYC_LOST
);
1806 OWRITE(sc
, OHCI_LNKCTLCLR
, OHCI_CNTL_CYCSRC
);
1808 OWRITE(sc
, OHCI_ATQCTLCLR
, OHCI_CNTL_DMA_RUN
);
1809 sc
->atrq
.xferq
.flag
&= ~FWXFERQ_RUNNING
;
1810 OWRITE(sc
, OHCI_ATSCTLCLR
, OHCI_CNTL_DMA_RUN
);
1811 sc
->atrs
.xferq
.flag
&= ~FWXFERQ_RUNNING
;
1814 OWRITE(sc
, FWOHCI_INTSTATCLR
, OHCI_INT_PHY_BUS_R
);
1817 OWRITE(sc
, OHCI_CROMHDR
, ntohl(sc
->fc
.config_rom
[0]));
1818 OWRITE(sc
, OHCI_BUS_OPT
, ntohl(sc
->fc
.config_rom
[2]));
1821 if((stat
& OHCI_INT_DMA_IR
)){
1823 OWRITE(sc
, FWOHCI_INTSTATCLR
, OHCI_INT_DMA_IR
);
1825 #if defined(__DragonFly__) || __FreeBSD_version < 500000
1826 irstat
= sc
->irstat
;
1829 irstat
= atomic_readandclear_int(&sc
->irstat
);
1831 for(i
= 0; i
< fc
->nisodma
; i
++){
1832 struct fwohci_dbch
*dbch
;
1834 if((irstat
& (1 << i
)) != 0){
1836 if ((dbch
->xferq
.flag
& FWXFERQ_OPEN
) == 0) {
1837 device_printf(sc
->fc
.dev
,
1838 "dma(%d) not active\n", i
);
1841 fwohci_rbuf_update(sc
, i
);
1845 if((stat
& OHCI_INT_DMA_IT
)){
1847 OWRITE(sc
, FWOHCI_INTSTATCLR
, OHCI_INT_DMA_IT
);
1849 #if defined(__DragonFly__) || __FreeBSD_version < 500000
1850 itstat
= sc
->itstat
;
1853 itstat
= atomic_readandclear_int(&sc
->itstat
);
1855 for(i
= 0; i
< fc
->nisodma
; i
++){
1856 if((itstat
& (1 << i
)) != 0){
1857 fwohci_tbuf_update(sc
, i
);
1861 if((stat
& OHCI_INT_DMA_PRRS
)){
1863 OWRITE(sc
, FWOHCI_INTSTATCLR
, OHCI_INT_DMA_PRRS
);
1866 dump_dma(sc
, ARRS_CH
);
1867 dump_db(sc
, ARRS_CH
);
1869 fwohci_arcv(sc
, &sc
->arrs
, count
);
1871 if((stat
& OHCI_INT_DMA_PRRQ
)){
1873 OWRITE(sc
, FWOHCI_INTSTATCLR
, OHCI_INT_DMA_PRRQ
);
1876 dump_dma(sc
, ARRQ_CH
);
1877 dump_db(sc
, ARRQ_CH
);
1879 fwohci_arcv(sc
, &sc
->arrq
, count
);
1881 if(stat
& OHCI_INT_PHY_SID
){
1882 u_int32_t
*buf
, node_id
;
1886 OWRITE(sc
, FWOHCI_INTSTATCLR
, OHCI_INT_PHY_SID
);
1888 /* Enable bus reset interrupt */
1889 OWRITE(sc
, FWOHCI_INTMASK
, OHCI_INT_PHY_BUS_R
);
1890 /* Allow async. request to us */
1891 OWRITE(sc
, OHCI_AREQHI
, 1 << 31);
1892 /* XXX insecure ?? */
1893 OWRITE(sc
, OHCI_PREQHI
, 0x7fffffff);
1894 OWRITE(sc
, OHCI_PREQLO
, 0xffffffff);
1895 OWRITE(sc
, OHCI_PREQUPPER
, 0x10000);
1896 /* Set ATRetries register */
1897 OWRITE(sc
, OHCI_ATRETRY
, 1<<(13+16) | 0xfff);
1899 ** Checking whether the node is root or not. If root, turn on
1902 node_id
= OREAD(sc
, FWOHCI_NODEID
);
1903 plen
= OREAD(sc
, OHCI_SID_CNT
);
1905 device_printf(fc
->dev
, "node_id=0x%08x, gen=%d, ",
1906 node_id
, (plen
>> 16) & 0xff);
1907 if (!(node_id
& OHCI_NODE_VALID
)) {
1908 kprintf("Bus reset failure\n");
1911 if (node_id
& OHCI_NODE_ROOT
) {
1912 kprintf("CYCLEMASTER mode\n");
1913 OWRITE(sc
, OHCI_LNKCTL
,
1914 OHCI_CNTL_CYCMTR
| OHCI_CNTL_CYCTIMER
);
1916 kprintf("non CYCLEMASTER mode\n");
1917 OWRITE(sc
, OHCI_LNKCTLCLR
, OHCI_CNTL_CYCMTR
);
1918 OWRITE(sc
, OHCI_LNKCTL
, OHCI_CNTL_CYCTIMER
);
1920 fc
->nodeid
= node_id
& 0x3f;
1922 if (plen
& OHCI_SID_ERR
) {
1923 device_printf(fc
->dev
, "SID Error\n");
1926 plen
&= OHCI_SID_CNT_MASK
;
1927 if (plen
< 4 || plen
> OHCI_SIDSIZE
) {
1928 device_printf(fc
->dev
, "invalid SID len = %d\n", plen
);
1931 plen
-= 4; /* chop control info */
1932 buf
= (u_int32_t
*)kmalloc(OHCI_SIDSIZE
, M_FW
, M_INTWAIT
);
1934 device_printf(fc
->dev
, "malloc failed\n");
1937 for (i
= 0; i
< plen
/ 4; i
++)
1938 buf
[i
] = FWOHCI_DMA_READ(sc
->sid_buf
[i
+1]);
1940 /* pending all pre-bus_reset packets */
1941 fwohci_txd(sc
, &sc
->atrq
);
1942 fwohci_txd(sc
, &sc
->atrs
);
1943 fwohci_arcv(sc
, &sc
->arrs
, -1);
1944 fwohci_arcv(sc
, &sc
->arrq
, -1);
1947 fw_sidrcv(fc
, buf
, plen
);
1951 if((stat
& OHCI_INT_DMA_ATRQ
)){
1953 OWRITE(sc
, FWOHCI_INTSTATCLR
, OHCI_INT_DMA_ATRQ
);
1955 fwohci_txd(sc
, &(sc
->atrq
));
1957 if((stat
& OHCI_INT_DMA_ATRS
)){
1959 OWRITE(sc
, FWOHCI_INTSTATCLR
, OHCI_INT_DMA_ATRS
);
1961 fwohci_txd(sc
, &(sc
->atrs
));
1963 if((stat
& OHCI_INT_PW_ERR
)){
1965 OWRITE(sc
, FWOHCI_INTSTATCLR
, OHCI_INT_PW_ERR
);
1967 device_printf(fc
->dev
, "posted write error\n");
1969 if((stat
& OHCI_INT_ERR
)){
1971 OWRITE(sc
, FWOHCI_INTSTATCLR
, OHCI_INT_ERR
);
1973 device_printf(fc
->dev
, "unrecoverable error\n");
1975 if((stat
& OHCI_INT_PHY_INT
)) {
1977 OWRITE(sc
, FWOHCI_INTSTATCLR
, OHCI_INT_PHY_INT
);
1979 device_printf(fc
->dev
, "phy int\n");
1985 #if FWOHCI_TASKQUEUE
1987 fwohci_complete(void *arg
, int pending
)
1989 struct fwohci_softc
*sc
= (struct fwohci_softc
*)arg
;
1993 stat
= atomic_readandclear_int(&sc
->intstat
);
1995 fwohci_intr_body(sc
, stat
, -1);
2003 fwochi_check_stat(struct fwohci_softc
*sc
)
2005 u_int32_t stat
, irstat
, itstat
;
2007 stat
= OREAD(sc
, FWOHCI_INTSTAT
);
2008 if (stat
== 0xffffffff) {
2009 device_printf(sc
->fc
.dev
,
2010 "device physically ejected?\n");
2015 OWRITE(sc
, FWOHCI_INTSTATCLR
, stat
);
2017 if (stat
& OHCI_INT_DMA_IR
) {
2018 irstat
= OREAD(sc
, OHCI_IR_STAT
);
2019 OWRITE(sc
, OHCI_IR_STATCLR
, irstat
);
2020 atomic_set_int(&sc
->irstat
, irstat
);
2022 if (stat
& OHCI_INT_DMA_IT
) {
2023 itstat
= OREAD(sc
, OHCI_IT_STAT
);
2024 OWRITE(sc
, OHCI_IT_STATCLR
, itstat
);
2025 atomic_set_int(&sc
->itstat
, itstat
);
2031 fwohci_intr(void *arg
)
2033 struct fwohci_softc
*sc
= (struct fwohci_softc
*)arg
;
2035 #if !FWOHCI_TASKQUEUE
2036 u_int32_t bus_reset
= 0;
2039 if (!(sc
->intmask
& OHCI_INT_EN
)) {
2044 #if !FWOHCI_TASKQUEUE
2047 stat
= fwochi_check_stat(sc
);
2048 if (stat
== 0 || stat
== 0xffffffff)
2050 #if FWOHCI_TASKQUEUE
2051 atomic_set_int(&sc
->intstat
, stat
);
2052 /* XXX mask bus reset intr. during bus reset phase */
2054 taskqueue_enqueue(taskqueue_swi_giant
, &sc
->fwohci_task_complete
);
2056 /* We cannot clear bus reset event during bus reset phase */
2057 if ((stat
& ~bus_reset
) == 0)
2059 bus_reset
= stat
& OHCI_INT_PHY_BUS_R
;
2060 fwohci_intr_body(sc
, stat
, -1);
2066 fwohci_poll(struct firewire_comm
*fc
, int quick
, int count
)
2069 struct fwohci_softc
*sc
;
2072 sc
= (struct fwohci_softc
*)fc
;
2073 stat
= OHCI_INT_DMA_IR
| OHCI_INT_DMA_IT
|
2074 OHCI_INT_DMA_PRRS
| OHCI_INT_DMA_PRRQ
|
2075 OHCI_INT_DMA_ATRQ
| OHCI_INT_DMA_ATRS
;
2081 stat
= fwochi_check_stat(sc
);
2082 if (stat
== 0 || stat
== 0xffffffff)
2086 fwohci_intr_body(sc
, stat
, count
);
2091 fwohci_set_intr(struct firewire_comm
*fc
, int enable
)
2093 struct fwohci_softc
*sc
;
2095 sc
= (struct fwohci_softc
*)fc
;
2097 device_printf(sc
->fc
.dev
, "fwohci_set_intr: %d\n", enable
);
2099 sc
->intmask
|= OHCI_INT_EN
;
2100 OWRITE(sc
, FWOHCI_INTMASK
, OHCI_INT_EN
);
2102 sc
->intmask
&= ~OHCI_INT_EN
;
2103 OWRITE(sc
, FWOHCI_INTMASKCLR
, OHCI_INT_EN
);
2108 fwohci_tbuf_update(struct fwohci_softc
*sc
, int dmach
)
2110 struct firewire_comm
*fc
= &sc
->fc
;
2111 struct fwohcidb
*db
;
2112 struct fw_bulkxfer
*chunk
;
2113 struct fw_xferq
*it
;
2114 u_int32_t stat
, count
;
2118 ldesc
= sc
->it
[dmach
].ndesc
- 1;
2119 crit_enter(); /* unnecessary? */
2120 fwdma_sync_multiseg_all(sc
->it
[dmach
].am
, BUS_DMASYNC_POSTREAD
);
2122 dump_db(sc
, ITX_CH
+ dmach
);
2123 while ((chunk
= STAILQ_FIRST(&it
->stdma
)) != NULL
) {
2124 db
= ((struct fwohcidb_tr
*)(chunk
->end
))->db
;
2125 stat
= FWOHCI_DMA_READ(db
[ldesc
].db
.desc
.res
)
2126 >> OHCI_STATUS_SHIFT
;
2127 db
= ((struct fwohcidb_tr
*)(chunk
->start
))->db
;
2129 count
= FWOHCI_DMA_READ(db
[ldesc
].db
.desc
.res
)
2133 STAILQ_REMOVE_HEAD(&it
->stdma
, link
);
2134 switch (stat
& FWOHCIEV_MASK
){
2135 case FWOHCIEV_ACKCOMPL
:
2137 device_printf(fc
->dev
, "0x%08x\n", count
);
2141 device_printf(fc
->dev
,
2142 "Isochronous transmit err %02x(%s)\n",
2143 stat
, fwohcicode
[stat
& 0x1f]);
2145 STAILQ_INSERT_TAIL(&it
->stfree
, chunk
, link
);
2154 fwohci_rbuf_update(struct fwohci_softc
*sc
, int dmach
)
2156 struct firewire_comm
*fc
= &sc
->fc
;
2157 struct fwohcidb_tr
*db_tr
;
2158 struct fw_bulkxfer
*chunk
;
2159 struct fw_xferq
*ir
;
2164 ldesc
= sc
->ir
[dmach
].ndesc
- 1;
2169 fwdma_sync_multiseg_all(sc
->ir
[dmach
].am
, BUS_DMASYNC_POSTREAD
);
2170 while ((chunk
= STAILQ_FIRST(&ir
->stdma
)) != NULL
) {
2171 db_tr
= (struct fwohcidb_tr
*)chunk
->end
;
2172 stat
= FWOHCI_DMA_READ(db_tr
->db
[ldesc
].db
.desc
.res
)
2173 >> OHCI_STATUS_SHIFT
;
2177 if (chunk
->mbuf
!= NULL
) {
2178 bus_dmamap_sync(sc
->ir
[dmach
].dmat
, db_tr
->dma_map
,
2179 BUS_DMASYNC_POSTREAD
);
2180 bus_dmamap_unload(sc
->ir
[dmach
].dmat
, db_tr
->dma_map
);
2181 } else if (ir
->buf
!= NULL
) {
2182 fwdma_sync_multiseg(ir
->buf
, chunk
->poffset
,
2183 ir
->bnpacket
, BUS_DMASYNC_POSTREAD
);
2186 kprintf("fwohci_rbuf_update: this shouldn't happend\n");
2189 STAILQ_REMOVE_HEAD(&ir
->stdma
, link
);
2190 STAILQ_INSERT_TAIL(&ir
->stvalid
, chunk
, link
);
2191 switch (stat
& FWOHCIEV_MASK
) {
2192 case FWOHCIEV_ACKCOMPL
:
2196 chunk
->resp
= EINVAL
;
2197 device_printf(fc
->dev
,
2198 "Isochronous receive err %02x(%s)\n",
2199 stat
, fwohcicode
[stat
& 0x1f]);
2205 if (ir
->flag
& FWXFERQ_HANDLER
)
2213 dump_dma(struct fwohci_softc
*sc
, u_int32_t ch
)
2215 u_int32_t off
, cntl
, stat
, cmd
, match
;
2225 }else if(ch
< IRX_CH
){
2226 off
= OHCI_ITCTL(ch
- ITX_CH
);
2228 off
= OHCI_IRCTL(ch
- IRX_CH
);
2230 cntl
= stat
= OREAD(sc
, off
);
2231 cmd
= OREAD(sc
, off
+ 0xc);
2232 match
= OREAD(sc
, off
+ 0x10);
2234 device_printf(sc
->fc
.dev
, "ch %1x cntl:0x%08x cmd:0x%08x match:0x%08x\n",
2241 device_printf(sc
->fc
.dev
, "dma %d ch:%s%s%s%s%s%s %s(%x)\n",
2243 stat
& OHCI_CNTL_DMA_RUN
? "RUN," : "",
2244 stat
& OHCI_CNTL_DMA_WAKE
? "WAKE," : "",
2245 stat
& OHCI_CNTL_DMA_DEAD
? "DEAD," : "",
2246 stat
& OHCI_CNTL_DMA_ACTIVE
? "ACTIVE," : "",
2247 stat
& OHCI_CNTL_DMA_BT
? "BRANCH," : "",
2248 stat
& OHCI_CNTL_DMA_BAD
? "BADDMA," : "",
2249 fwohcicode
[stat
& 0x1f],
2253 device_printf(sc
->fc
.dev
, "dma %d ch: Nostat\n", ch
);
2258 dump_db(struct fwohci_softc
*sc
, u_int32_t ch
)
2260 struct fwohci_dbch
*dbch
;
2261 struct fwohcidb_tr
*cp
= NULL
, *pp
, *np
= NULL
;
2262 struct fwohcidb
*curr
= NULL
, *prev
, *next
= NULL
;
2277 }else if(ch
< IRX_CH
){
2278 off
= OHCI_ITCTL(ch
- ITX_CH
);
2279 dbch
= &sc
->it
[ch
- ITX_CH
];
2281 off
= OHCI_IRCTL(ch
- IRX_CH
);
2282 dbch
= &sc
->ir
[ch
- IRX_CH
];
2284 cmd
= OREAD(sc
, off
+ 0xc);
2286 if( dbch
->ndb
== 0 ){
2287 device_printf(sc
->fc
.dev
, "No DB is attached ch=%d\n", ch
);
2292 for(idb
= 0 ; idb
< dbch
->ndb
; idb
++ ){
2297 cp
= STAILQ_NEXT(pp
, link
);
2302 np
= STAILQ_NEXT(cp
, link
);
2303 for(jdb
= 0 ; jdb
< dbch
->ndesc
; jdb
++ ){
2304 if ((cmd
& 0xfffffff0) == cp
->bus_addr
) {
2314 pp
= STAILQ_NEXT(pp
, link
);
2320 kprintf("Prev DB %d\n", ch
);
2321 print_db(pp
, prev
, ch
, dbch
->ndesc
);
2323 kprintf("Current DB %d\n", ch
);
2324 print_db(cp
, curr
, ch
, dbch
->ndesc
);
2326 kprintf("Next DB %d\n", ch
);
2327 print_db(np
, next
, ch
, dbch
->ndesc
);
2330 kprintf("dbdump err ch = %d cmd = 0x%08x\n", ch
, cmd
);
2336 print_db(struct fwohcidb_tr
*db_tr
, struct fwohcidb
*db
,
2337 u_int32_t ch
, u_int32_t max
)
2344 kprintf("No Descriptor is found\n");
2348 kprintf("ch = %d\n%8s %s %s %s %s %4s %8s %8s %4s:%4s\n",
2360 for( i
= 0 ; i
<= max
; i
++){
2361 cmd
= FWOHCI_DMA_READ(db
[i
].db
.desc
.cmd
);
2362 res
= FWOHCI_DMA_READ(db
[i
].db
.desc
.res
);
2363 key
= cmd
& OHCI_KEY_MASK
;
2364 stat
= res
>> OHCI_STATUS_SHIFT
;
2365 #if defined(__DragonFly__) || __FreeBSD_version < 500000
2366 kprintf("%08x %s %s %s %s %5d %08x %08x %04x:%04x",
2369 kprintf("%08jx %s %s %s %s %5d %08x %08x %04x:%04x",
2370 (uintmax_t)db_tr
->bus_addr
,
2372 dbcode
[(cmd
>> 28) & 0xf],
2373 dbkey
[(cmd
>> 24) & 0x7],
2374 dbcond
[(cmd
>> 20) & 0x3],
2375 dbcond
[(cmd
>> 18) & 0x3],
2376 cmd
& OHCI_COUNT_MASK
,
2377 FWOHCI_DMA_READ(db
[i
].db
.desc
.addr
),
2378 FWOHCI_DMA_READ(db
[i
].db
.desc
.depend
),
2380 res
& OHCI_COUNT_MASK
);
2382 kprintf(" %s%s%s%s%s%s %s(%x)\n",
2383 stat
& OHCI_CNTL_DMA_RUN
? "RUN," : "",
2384 stat
& OHCI_CNTL_DMA_WAKE
? "WAKE," : "",
2385 stat
& OHCI_CNTL_DMA_DEAD
? "DEAD," : "",
2386 stat
& OHCI_CNTL_DMA_ACTIVE
? "ACTIVE," : "",
2387 stat
& OHCI_CNTL_DMA_BT
? "BRANCH," : "",
2388 stat
& OHCI_CNTL_DMA_BAD
? "BADDMA," : "",
2389 fwohcicode
[stat
& 0x1f],
2393 kprintf(" Nostat\n");
2395 if(key
== OHCI_KEY_ST2
){
2396 kprintf("0x%08x 0x%08x 0x%08x 0x%08x\n",
2397 FWOHCI_DMA_READ(db
[i
+1].db
.immed
[0]),
2398 FWOHCI_DMA_READ(db
[i
+1].db
.immed
[1]),
2399 FWOHCI_DMA_READ(db
[i
+1].db
.immed
[2]),
2400 FWOHCI_DMA_READ(db
[i
+1].db
.immed
[3]));
2402 if(key
== OHCI_KEY_DEVICE
){
2405 if((cmd
& OHCI_BRANCH_MASK
)
2406 == OHCI_BRANCH_ALWAYS
){
2409 if((cmd
& OHCI_CMD_MASK
)
2410 == OHCI_OUTPUT_LAST
){
2413 if((cmd
& OHCI_CMD_MASK
)
2414 == OHCI_INPUT_LAST
){
2417 if(key
== OHCI_KEY_ST2
){
2425 fwohci_ibr(struct firewire_comm
*fc
)
2427 struct fwohci_softc
*sc
;
2430 device_printf(fc
->dev
, "Initiate bus reset\n");
2431 sc
= (struct fwohci_softc
*)fc
;
2434 * Set root hold-off bit so that non cyclemaster capable node
2435 * shouldn't became the root node.
2438 fun
= fwphy_rddata(sc
, FW_PHY_IBR_REG
);
2439 fun
|= FW_PHY_IBR
| FW_PHY_RHB
;
2440 fun
= fwphy_wrdata(sc
, FW_PHY_IBR_REG
, fun
);
2441 #else /* Short bus reset */
2442 fun
= fwphy_rddata(sc
, FW_PHY_ISBR_REG
);
2443 fun
|= FW_PHY_ISBR
| FW_PHY_RHB
;
2444 fun
= fwphy_wrdata(sc
, FW_PHY_ISBR_REG
, fun
);
2449 fwohci_txbufdb(struct fwohci_softc
*sc
, int dmach
, struct fw_bulkxfer
*bulkxfer
)
2451 struct fwohcidb_tr
*db_tr
, *fdb_tr
;
2452 struct fwohci_dbch
*dbch
;
2453 struct fwohcidb
*db
;
2455 struct fwohci_txpkthdr
*ohcifp
;
2456 unsigned short chtag
;
2459 dbch
= &sc
->it
[dmach
];
2460 chtag
= sc
->it
[dmach
].xferq
.flag
& 0xff;
2462 db_tr
= (struct fwohcidb_tr
*)(bulkxfer
->start
);
2463 fdb_tr
= (struct fwohcidb_tr
*)(bulkxfer
->end
);
2465 device_printf(sc->fc.dev, "DB %08x %08x %08x\n", bulkxfer, db_tr->bus_addr, fdb_tr->bus_addr);
2467 for (idb
= 0; idb
< dbch
->xferq
.bnpacket
; idb
++) {
2469 fp
= (struct fw_pkt
*)db_tr
->buf
;
2470 ohcifp
= (struct fwohci_txpkthdr
*) db
[1].db
.immed
;
2471 ohcifp
->mode
.ld
[0] = fp
->mode
.ld
[0];
2472 ohcifp
->mode
.common
.spd
= 0 & 0x7;
2473 ohcifp
->mode
.stream
.len
= fp
->mode
.stream
.len
;
2474 ohcifp
->mode
.stream
.chtag
= chtag
;
2475 ohcifp
->mode
.stream
.tcode
= 0xa;
2476 #if BYTE_ORDER == BIG_ENDIAN
2477 FWOHCI_DMA_WRITE(db
[1].db
.immed
[0], db
[1].db
.immed
[0]);
2478 FWOHCI_DMA_WRITE(db
[1].db
.immed
[1], db
[1].db
.immed
[1]);
2481 FWOHCI_DMA_CLEAR(db
[2].db
.desc
.cmd
, OHCI_COUNT_MASK
);
2482 FWOHCI_DMA_SET(db
[2].db
.desc
.cmd
, fp
->mode
.stream
.len
);
2483 FWOHCI_DMA_WRITE(db
[2].db
.desc
.res
, 0);
2484 #if 0 /* if bulkxfer->npackets changes */
2485 db
[2].db
.desc
.cmd
= OHCI_OUTPUT_LAST
2487 | OHCI_BRANCH_ALWAYS
;
2488 db
[0].db
.desc
.depend
=
2489 = db
[dbch
->ndesc
- 1].db
.desc
.depend
2490 = STAILQ_NEXT(db_tr
, link
)->bus_addr
| dbch
->ndesc
;
2492 FWOHCI_DMA_SET(db
[0].db
.desc
.depend
, dbch
->ndesc
);
2493 FWOHCI_DMA_SET(db
[dbch
->ndesc
- 1].db
.desc
.depend
, dbch
->ndesc
);
2495 bulkxfer
->end
= (caddr_t
)db_tr
;
2496 db_tr
= STAILQ_NEXT(db_tr
, link
);
2498 db
= ((struct fwohcidb_tr
*)bulkxfer
->end
)->db
;
2499 FWOHCI_DMA_CLEAR(db
[0].db
.desc
.depend
, 0xf);
2500 FWOHCI_DMA_CLEAR(db
[dbch
->ndesc
- 1].db
.desc
.depend
, 0xf);
2501 #if 0 /* if bulkxfer->npackets changes */
2502 db
[dbch
->ndesc
- 1].db
.desc
.control
|= OHCI_INTERRUPT_ALWAYS
;
2503 /* OHCI 1.1 and above */
2504 db
[0].db
.desc
.control
|= OHCI_INTERRUPT_ALWAYS
;
2507 db_tr = (struct fwohcidb_tr *)bulkxfer->start;
2508 fdb_tr = (struct fwohcidb_tr *)bulkxfer->end;
2509 device_printf(sc->fc.dev, "DB %08x %3d %08x %08x\n", bulkxfer, bulkxfer->npacket, db_tr->bus_addr, fdb_tr->bus_addr);
2515 fwohci_add_tx_buf(struct fwohci_dbch
*dbch
, struct fwohcidb_tr
*db_tr
,
2518 struct fwohcidb
*db
= db_tr
->db
;
2519 struct fw_xferq
*it
;
2527 db_tr
->buf
= fwdma_v_addr(it
->buf
, poffset
);
2530 FWOHCI_DMA_WRITE(db
[0].db
.desc
.cmd
,
2531 OHCI_OUTPUT_MORE
| OHCI_KEY_ST2
| 8);
2532 FWOHCI_DMA_WRITE(db
[0].db
.desc
.addr
, 0);
2533 bzero((void *)&db
[1].db
.immed
[0], sizeof(db
[1].db
.immed
));
2534 FWOHCI_DMA_WRITE(db
[2].db
.desc
.addr
,
2535 fwdma_bus_addr(it
->buf
, poffset
) + sizeof(u_int32_t
));
2537 FWOHCI_DMA_WRITE(db
[2].db
.desc
.cmd
,
2538 OHCI_OUTPUT_LAST
| OHCI_UPDATE
| OHCI_BRANCH_ALWAYS
);
2540 FWOHCI_DMA_WRITE(db
[0].db
.desc
.res
, 0);
2541 FWOHCI_DMA_WRITE(db
[2].db
.desc
.res
, 0);
2547 fwohci_add_rx_buf(struct fwohci_dbch
*dbch
, struct fwohcidb_tr
*db_tr
,
2548 int poffset
, struct fwdma_alloc
*dummy_dma
)
2550 struct fwohcidb
*db
= db_tr
->db
;
2551 struct fw_xferq
*ir
;
2557 if (ir
->buf
== NULL
&& (dbch
->xferq
.flag
& FWXFERQ_EXTBUF
) == 0) {
2558 db_tr
->buf
= fwdma_malloc_size(dbch
->dmat
, &db_tr
->dma_map
,
2559 ir
->psize
, &dbuf
[0], BUS_DMA_NOWAIT
);
2560 if (db_tr
->buf
== NULL
)
2563 dsiz
[0] = ir
->psize
;
2564 bus_dmamap_sync(dbch
->dmat
, db_tr
->dma_map
,
2565 BUS_DMASYNC_PREREAD
);
2568 if (dummy_dma
!= NULL
) {
2569 dsiz
[db_tr
->dbcnt
] = sizeof(u_int32_t
);
2570 dbuf
[db_tr
->dbcnt
++] = dummy_dma
->bus_addr
;
2572 dsiz
[db_tr
->dbcnt
] = ir
->psize
;
2573 if (ir
->buf
!= NULL
) {
2574 db_tr
->buf
= fwdma_v_addr(ir
->buf
, poffset
);
2575 dbuf
[db_tr
->dbcnt
] = fwdma_bus_addr( ir
->buf
, poffset
);
2579 for(i
= 0 ; i
< db_tr
->dbcnt
; i
++){
2580 FWOHCI_DMA_WRITE(db
[i
].db
.desc
.addr
, dbuf
[i
]);
2581 FWOHCI_DMA_WRITE(db
[i
].db
.desc
.cmd
, OHCI_INPUT_MORE
| dsiz
[i
]);
2582 if (ir
->flag
& FWXFERQ_STREAM
) {
2583 FWOHCI_DMA_SET(db
[i
].db
.desc
.cmd
, OHCI_UPDATE
);
2585 FWOHCI_DMA_WRITE(db
[i
].db
.desc
.res
, dsiz
[i
]);
2587 ldesc
= db_tr
->dbcnt
- 1;
2588 if (ir
->flag
& FWXFERQ_STREAM
) {
2589 FWOHCI_DMA_SET(db
[ldesc
].db
.desc
.cmd
, OHCI_INPUT_LAST
);
2591 FWOHCI_DMA_SET(db
[ldesc
].db
.desc
.cmd
, OHCI_BRANCH_ALWAYS
);
2597 fwohci_arcv_swap(struct fw_pkt
*fp
, int len
)
2602 #if BYTE_ORDER == BIG_ENDIAN
2606 ld0
= FWOHCI_DMA_READ(fp
->mode
.ld
[0]);
2608 kprintf("ld0: x%08x\n", ld0
);
2610 fp0
= (struct fw_pkt
*)&ld0
;
2611 /* determine length to swap */
2612 switch (fp0
->mode
.common
.tcode
) {
2617 case FWOHCITCODE_PHY
:
2628 kprintf("Unknown tcode %d\n", fp0
->mode
.common
.tcode
);
2631 hlen
= tinfo
[fp0
->mode
.common
.tcode
].hdr_len
;
2634 kprintf("splitted header\n");
2637 #if BYTE_ORDER == BIG_ENDIAN
2638 for(i
= 0; i
< slen
/4; i
++)
2639 fp
->mode
.ld
[i
] = FWOHCI_DMA_READ(fp
->mode
.ld
[i
]);
2645 fwohci_get_plen(struct fwohci_softc
*sc
, struct fwohci_dbch
*dbch
, struct fw_pkt
*fp
)
2647 struct tcode_info
*info
;
2650 info
= &tinfo
[fp
->mode
.common
.tcode
];
2651 r
= info
->hdr_len
+ sizeof(u_int32_t
);
2652 if ((info
->flag
& FWTI_BLOCK_ASY
) != 0)
2653 r
+= roundup2(fp
->mode
.wreqb
.len
, sizeof(u_int32_t
));
2655 if (r
== sizeof(u_int32_t
))
2657 device_printf(sc
->fc
.dev
, "Unknown tcode %d\n",
2658 fp
->mode
.common
.tcode
);
2660 if (r
> dbch
->xferq
.psize
) {
2661 device_printf(sc
->fc
.dev
, "Invalid packet length %d\n", r
);
2669 fwohci_arcv_free_buf(struct fwohci_dbch
*dbch
, struct fwohcidb_tr
*db_tr
)
2671 struct fwohcidb
*db
= &db_tr
->db
[0];
2673 FWOHCI_DMA_CLEAR(db
->db
.desc
.depend
, 0xf);
2674 FWOHCI_DMA_WRITE(db
->db
.desc
.res
, dbch
->xferq
.psize
);
2675 FWOHCI_DMA_SET(dbch
->bottom
->db
[0].db
.desc
.depend
, 1);
2676 fwdma_sync_multiseg_all(dbch
->am
, BUS_DMASYNC_PREWRITE
);
2677 dbch
->bottom
= db_tr
;
2681 fwohci_arcv(struct fwohci_softc
*sc
, struct fwohci_dbch
*dbch
, int count
)
2683 struct fwohcidb_tr
*db_tr
;
2684 struct iovec vec
[2];
2685 struct fw_pkt pktbuf
;
2689 u_int32_t stat
, off
, status
;
2691 int len
, plen
, hlen
, pcnt
, offset
;
2695 if(&sc
->arrq
== dbch
){
2697 }else if(&sc
->arrs
== dbch
){
2706 /* XXX we cannot handle a packet which lies in more than two buf */
2707 fwdma_sync_multiseg_all(dbch
->am
, BUS_DMASYNC_POSTREAD
);
2708 fwdma_sync_multiseg_all(dbch
->am
, BUS_DMASYNC_POSTWRITE
);
2709 status
= FWOHCI_DMA_READ(db_tr
->db
[0].db
.desc
.res
) >> OHCI_STATUS_SHIFT
;
2710 resCount
= FWOHCI_DMA_READ(db_tr
->db
[0].db
.desc
.res
) & OHCI_COUNT_MASK
;
2712 kprintf("status 0x%04x, resCount 0x%04x\n", status
, resCount
);
2714 while (status
& OHCI_CNTL_DMA_ACTIVE
) {
2715 len
= dbch
->xferq
.psize
- resCount
;
2716 ld
= (u_int8_t
*)db_tr
->buf
;
2717 if (dbch
->pdb_tr
== NULL
) {
2718 len
-= dbch
->buf_offset
;
2719 ld
+= dbch
->buf_offset
;
2722 bus_dmamap_sync(dbch
->dmat
, db_tr
->dma_map
,
2723 BUS_DMASYNC_POSTREAD
);
2725 if (count
>= 0 && count
-- == 0)
2727 if(dbch
->pdb_tr
!= NULL
){
2728 /* we have a fragment in previous buffer */
2731 offset
= dbch
->buf_offset
;
2734 buf
= dbch
->pdb_tr
->buf
+ offset
;
2735 rlen
= dbch
->xferq
.psize
- offset
;
2737 kprintf("rlen=%d, offset=%d\n",
2738 rlen
, dbch
->buf_offset
);
2739 if (dbch
->buf_offset
< 0) {
2740 /* splitted in header, pull up */
2743 p
= (char *)&pktbuf
;
2744 bcopy(buf
, p
, rlen
);
2746 /* this must be too long but harmless */
2747 rlen
= sizeof(pktbuf
) - rlen
;
2749 kprintf("why rlen < 0\n");
2750 bcopy(db_tr
->buf
, p
, rlen
);
2753 hlen
= fwohci_arcv_swap(&pktbuf
, sizeof(pktbuf
));
2755 kprintf("hlen < 0 shouldn't happen");
2757 offset
= sizeof(pktbuf
);
2758 vec
[0].iov_base
= (char *)&pktbuf
;
2759 vec
[0].iov_len
= offset
;
2761 /* splitted in payload */
2763 vec
[0].iov_base
= buf
;
2764 vec
[0].iov_len
= rlen
;
2766 fp
=(struct fw_pkt
*)vec
[0].iov_base
;
2769 /* no fragment in previous buffer */
2770 fp
=(struct fw_pkt
*)ld
;
2771 hlen
= fwohci_arcv_swap(fp
, len
);
2773 /* XXX need reset */
2776 dbch
->pdb_tr
= db_tr
;
2777 dbch
->buf_offset
= - dbch
->buf_offset
;
2780 kprintf("resCount = %d !?\n",
2782 /* XXX clear pdb_tr */
2788 plen
= fwohci_get_plen(sc
, dbch
, fp
) - offset
;
2790 /* minimum header size + trailer
2791 = sizeof(fw_pkt) so this shouldn't happens */
2792 kprintf("plen(%d) is negative! offset=%d\n",
2794 /* XXX clear pdb_tr */
2800 dbch
->pdb_tr
= db_tr
;
2802 kprintf("splitted payload\n");
2805 kprintf("resCount = %d !?\n",
2807 /* XXX clear pdb_tr */
2810 vec
[nvec
].iov_base
= ld
;
2811 vec
[nvec
].iov_len
= plen
;
2815 dbch
->buf_offset
= ld
- (u_int8_t
*)db_tr
->buf
;
2817 kprintf("nvec == 0\n");
2819 /* DMA result-code will be written at the tail of packet */
2820 #if BYTE_ORDER == BIG_ENDIAN
2821 stat
= FWOHCI_DMA_READ(((struct fwohci_trailer
*)(ld
- sizeof(struct fwohci_trailer
)))->stat
) >> 16;
2823 stat
= ((struct fwohci_trailer
*)(ld
- sizeof(struct fwohci_trailer
)))->stat
;
2826 kprintf("plen: %d, stat %x\n",
2829 spd
= (stat
>> 5) & 0x3;
2832 case FWOHCIEV_ACKPEND
:
2834 kprintf("fwohci_arcv: ack pending tcode=0x%x..\n", fp
->mode
.common
.tcode
);
2837 case FWOHCIEV_ACKCOMPL
:
2839 struct fw_rcv_buf rb
;
2841 if ((vec
[nvec
-1].iov_len
-=
2842 sizeof(struct fwohci_trailer
)) == 0)
2851 case FWOHCIEV_BUSRST
:
2852 if (sc
->fc
.status
!= FWBUSRESET
)
2853 kprintf("got BUSRST packet!?\n");
2856 device_printf(sc
->fc
.dev
, "Async DMA Receive error err = %02x %s\n", stat
, fwohcicode
[stat
]);
2863 if (dbch
->pdb_tr
!= NULL
) {
2864 fwohci_arcv_free_buf(dbch
, dbch
->pdb_tr
);
2865 dbch
->pdb_tr
= NULL
;
2870 if (resCount
== 0) {
2871 /* done on this buffer */
2872 if (dbch
->pdb_tr
== NULL
) {
2873 fwohci_arcv_free_buf(dbch
, db_tr
);
2874 dbch
->buf_offset
= 0;
2876 if (dbch
->pdb_tr
!= db_tr
)
2877 kprintf("pdb_tr != db_tr\n");
2878 db_tr
= STAILQ_NEXT(db_tr
, link
);
2879 status
= FWOHCI_DMA_READ(db_tr
->db
[0].db
.desc
.res
)
2880 >> OHCI_STATUS_SHIFT
;
2881 resCount
= FWOHCI_DMA_READ(db_tr
->db
[0].db
.desc
.res
)
2883 /* XXX check buffer overrun */
2886 dbch
->buf_offset
= dbch
->xferq
.psize
- resCount
;
2889 /* XXX make sure DMA is not dead */
2893 kprintf("fwohci_arcv: no packets\n");