firewire.c revision 1.8.4.7 1 1.8.4.7 yamt /* $NetBSD: firewire.c,v 1.8.4.7 2008/01/21 09:43:13 yamt Exp $ */
2 1.8.4.2 yamt /*-
3 1.8.4.2 yamt * Copyright (c) 2003 Hidetoshi Shimokawa
4 1.8.4.2 yamt * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
5 1.8.4.2 yamt * All rights reserved.
6 1.8.4.2 yamt *
7 1.8.4.2 yamt * Redistribution and use in source and binary forms, with or without
8 1.8.4.2 yamt * modification, are permitted provided that the following conditions
9 1.8.4.2 yamt * are met:
10 1.8.4.2 yamt * 1. Redistributions of source code must retain the above copyright
11 1.8.4.2 yamt * notice, this list of conditions and the following disclaimer.
12 1.8.4.2 yamt * 2. Redistributions in binary form must reproduce the above copyright
13 1.8.4.2 yamt * notice, this list of conditions and the following disclaimer in the
14 1.8.4.2 yamt * documentation and/or other materials provided with the distribution.
15 1.8.4.2 yamt * 3. All advertising materials mentioning features or use of this software
16 1.8.4.2 yamt * must display the acknowledgement as bellow:
17 1.8.4.2 yamt *
18 1.8.4.2 yamt * This product includes software developed by K. Kobayashi and H. Shimokawa
19 1.8.4.2 yamt *
20 1.8.4.2 yamt * 4. The name of the author may not be used to endorse or promote products
21 1.8.4.2 yamt * derived from this software without specific prior written permission.
22 1.8.4.2 yamt *
23 1.8.4.2 yamt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 1.8.4.2 yamt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 1.8.4.2 yamt * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 1.8.4.2 yamt * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
27 1.8.4.2 yamt * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 1.8.4.2 yamt * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 1.8.4.2 yamt * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 1.8.4.2 yamt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 1.8.4.2 yamt * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 1.8.4.2 yamt * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 1.8.4.2 yamt * POSSIBILITY OF SUCH DAMAGE.
34 1.8.4.2 yamt *
35 1.8.4.6 yamt * $FreeBSD: src/sys/dev/firewire/firewire.c,v 1.101 2007/10/20 23:23:14 julian Exp $
36 1.8.4.2 yamt *
37 1.8.4.2 yamt */
38 1.8.4.2 yamt
39 1.8.4.7 yamt #include <sys/cdefs.h>
40 1.8.4.7 yamt __KERNEL_RCSID(0, "$NetBSD: firewire.c,v 1.8.4.7 2008/01/21 09:43:13 yamt Exp $");
41 1.8.4.7 yamt
42 1.8.4.2 yamt #if defined(__FreeBSD__)
43 1.8.4.2 yamt #include <sys/param.h>
44 1.8.4.2 yamt #include <sys/systm.h>
45 1.8.4.2 yamt #include <sys/types.h>
46 1.8.4.2 yamt
47 1.8.4.2 yamt #include <sys/kernel.h>
48 1.8.4.2 yamt #include <sys/module.h>
49 1.8.4.2 yamt #include <sys/malloc.h>
50 1.8.4.2 yamt #include <sys/conf.h>
51 1.8.4.2 yamt #include <sys/sysctl.h>
52 1.8.4.2 yamt #include <sys/kthread.h>
53 1.8.4.2 yamt
54 1.8.4.6 yamt #include <sys/kdb.h>
55 1.8.4.6 yamt
56 1.8.4.2 yamt #if defined(__DragonFly__) || __FreeBSD_version < 500000
57 1.8.4.2 yamt #include <machine/clock.h> /* for DELAY() */
58 1.8.4.2 yamt #endif
59 1.8.4.2 yamt
60 1.8.4.2 yamt #include <sys/bus.h> /* used by smbus and newbus */
61 1.8.4.5 yamt #include <sys/bus.h>
62 1.8.4.2 yamt
63 1.8.4.2 yamt #ifdef __DragonFly__
64 1.8.4.2 yamt #include "fw_port.h"
65 1.8.4.2 yamt #include "firewire.h"
66 1.8.4.2 yamt #include "firewirereg.h"
67 1.8.4.2 yamt #include "fwmem.h"
68 1.8.4.2 yamt #include "iec13213.h"
69 1.8.4.2 yamt #include "iec68113.h"
70 1.8.4.2 yamt #else
71 1.8.4.2 yamt #include <dev/firewire/fw_port.h>
72 1.8.4.2 yamt #include <dev/firewire/firewire.h>
73 1.8.4.2 yamt #include <dev/firewire/firewirereg.h>
74 1.8.4.2 yamt #include <dev/firewire/fwmem.h>
75 1.8.4.2 yamt #include <dev/firewire/iec13213.h>
76 1.8.4.2 yamt #include <dev/firewire/iec68113.h>
77 1.8.4.2 yamt #endif
78 1.8.4.2 yamt #elif defined(__NetBSD__)
79 1.8.4.2 yamt #include <sys/param.h>
80 1.8.4.2 yamt #include <sys/device.h>
81 1.8.4.2 yamt #include <sys/errno.h>
82 1.8.4.2 yamt #include <sys/conf.h>
83 1.8.4.2 yamt #include <sys/kernel.h>
84 1.8.4.2 yamt #include <sys/kthread.h>
85 1.8.4.2 yamt #include <sys/malloc.h>
86 1.8.4.2 yamt #include <sys/queue.h>
87 1.8.4.2 yamt #include <sys/sysctl.h>
88 1.8.4.2 yamt #include <sys/systm.h>
89 1.8.4.2 yamt
90 1.8.4.5 yamt #include <sys/bus.h>
91 1.8.4.2 yamt
92 1.8.4.2 yamt #include <dev/ieee1394/fw_port.h>
93 1.8.4.2 yamt #include <dev/ieee1394/firewire.h>
94 1.8.4.2 yamt #include <dev/ieee1394/firewirereg.h>
95 1.8.4.2 yamt #include <dev/ieee1394/fwmem.h>
96 1.8.4.2 yamt #include <dev/ieee1394/iec13213.h>
97 1.8.4.2 yamt #include <dev/ieee1394/iec68113.h>
98 1.8.4.2 yamt
99 1.8.4.2 yamt #include "locators.h"
100 1.8.4.2 yamt #endif
101 1.8.4.2 yamt
102 1.8.4.2 yamt struct crom_src_buf {
103 1.8.4.2 yamt struct crom_src src;
104 1.8.4.2 yamt struct crom_chunk root;
105 1.8.4.2 yamt struct crom_chunk vendor;
106 1.8.4.2 yamt struct crom_chunk hw;
107 1.8.4.2 yamt };
108 1.8.4.2 yamt
109 1.8.4.2 yamt int firewire_debug=0, try_bmr=1, hold_count=3;
110 1.8.4.2 yamt #if defined(__FreeBSD__)
111 1.8.4.2 yamt SYSCTL_INT(_debug, OID_AUTO, firewire_debug, CTLFLAG_RW, &firewire_debug, 0,
112 1.8.4.2 yamt "FireWire driver debug flag");
113 1.8.4.2 yamt SYSCTL_NODE(_hw, OID_AUTO, firewire, CTLFLAG_RD, 0, "FireWire Subsystem");
114 1.8.4.2 yamt SYSCTL_INT(_hw_firewire, OID_AUTO, try_bmr, CTLFLAG_RW, &try_bmr, 0,
115 1.8.4.2 yamt "Try to be a bus manager");
116 1.8.4.2 yamt SYSCTL_INT(_hw_firewire, OID_AUTO, hold_count, CTLFLAG_RW, &hold_count, 0,
117 1.8.4.2 yamt "Number of count of bus resets for removing lost device information");
118 1.8.4.2 yamt
119 1.8.4.2 yamt MALLOC_DEFINE(M_FW, "firewire", "FireWire");
120 1.8.4.2 yamt MALLOC_DEFINE(M_FWXFER, "fw_xfer", "XFER/FireWire");
121 1.8.4.2 yamt #elif defined(__NetBSD__)
122 1.8.4.2 yamt /*
123 1.8.4.2 yamt * Setup sysctl(3) MIB, hw.ieee1394if.*
124 1.8.4.2 yamt *
125 1.8.4.2 yamt * TBD condition CTLFLAG_PERMANENT on being an LKM or not
126 1.8.4.2 yamt */
127 1.8.4.2 yamt SYSCTL_SETUP(sysctl_ieee1394if, "sysctl ieee1394if(4) subtree setup")
128 1.8.4.2 yamt {
129 1.8.4.2 yamt int rc, ieee1394if_node_num;
130 1.8.4.2 yamt const struct sysctlnode *node;
131 1.8.4.2 yamt
132 1.8.4.2 yamt if ((rc = sysctl_createv(clog, 0, NULL, NULL,
133 1.8.4.2 yamt CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
134 1.8.4.2 yamt NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) {
135 1.8.4.2 yamt goto err;
136 1.8.4.2 yamt }
137 1.8.4.2 yamt
138 1.8.4.2 yamt if ((rc = sysctl_createv(clog, 0, NULL, &node,
139 1.8.4.2 yamt CTLFLAG_PERMANENT, CTLTYPE_NODE, "ieee1394if",
140 1.8.4.2 yamt SYSCTL_DESCR("ieee1394if controls"),
141 1.8.4.2 yamt NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {
142 1.8.4.2 yamt goto err;
143 1.8.4.2 yamt }
144 1.8.4.2 yamt ieee1394if_node_num = node->sysctl_num;
145 1.8.4.2 yamt
146 1.8.4.2 yamt /* ieee1394if try bus manager flag */
147 1.8.4.2 yamt if ((rc = sysctl_createv(clog, 0, NULL, &node,
148 1.8.4.2 yamt CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
149 1.8.4.2 yamt "try_bmr", SYSCTL_DESCR("Try to be a bus manager"),
150 1.8.4.2 yamt NULL, 0, &try_bmr,
151 1.8.4.2 yamt 0, CTL_HW, ieee1394if_node_num, CTL_CREATE, CTL_EOL)) != 0) {
152 1.8.4.2 yamt goto err;
153 1.8.4.2 yamt }
154 1.8.4.2 yamt
155 1.8.4.2 yamt /* ieee1394if hold count */
156 1.8.4.2 yamt if ((rc = sysctl_createv(clog, 0, NULL, &node,
157 1.8.4.2 yamt CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
158 1.8.4.2 yamt "hold_count", SYSCTL_DESCR("Number of count of "
159 1.8.4.2 yamt "bus resets for removing lost device information"),
160 1.8.4.2 yamt NULL, 0, &hold_count,
161 1.8.4.2 yamt 0, CTL_HW, ieee1394if_node_num, CTL_CREATE, CTL_EOL)) != 0) {
162 1.8.4.2 yamt goto err;
163 1.8.4.2 yamt }
164 1.8.4.2 yamt
165 1.8.4.2 yamt /* ieee1394if driver debug flag */
166 1.8.4.2 yamt if ((rc = sysctl_createv(clog, 0, NULL, &node,
167 1.8.4.2 yamt CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
168 1.8.4.2 yamt "ieee1394_debug", SYSCTL_DESCR("ieee1394if driver debug flag"),
169 1.8.4.2 yamt NULL, 0, &firewire_debug,
170 1.8.4.2 yamt 0, CTL_HW, ieee1394if_node_num, CTL_CREATE, CTL_EOL)) != 0) {
171 1.8.4.2 yamt goto err;
172 1.8.4.2 yamt }
173 1.8.4.2 yamt
174 1.8.4.2 yamt return;
175 1.8.4.2 yamt
176 1.8.4.2 yamt err:
177 1.8.4.2 yamt printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
178 1.8.4.2 yamt }
179 1.8.4.2 yamt
180 1.8.4.2 yamt MALLOC_DEFINE(M_FW, "ieee1394", "IEEE1394");
181 1.8.4.2 yamt MALLOC_DEFINE(M_FWXFER, "fw_xfer", "XFER/IEEE1394");
182 1.8.4.2 yamt #endif
183 1.8.4.2 yamt
184 1.8.4.2 yamt #define FW_MAXASYRTY 4
185 1.8.4.2 yamt
186 1.8.4.2 yamt #if defined(__FreeBSD__)
187 1.8.4.2 yamt devclass_t firewire_devclass;
188 1.8.4.2 yamt
189 1.8.4.2 yamt static void firewire_identify (driver_t *, device_t);
190 1.8.4.2 yamt static int firewire_probe (device_t);
191 1.8.4.2 yamt static int firewire_attach (device_t);
192 1.8.4.2 yamt static int firewire_detach (device_t);
193 1.8.4.2 yamt static int firewire_resume (device_t);
194 1.8.4.2 yamt #if 0
195 1.8.4.2 yamt static int firewire_shutdown (device_t);
196 1.8.4.2 yamt #endif
197 1.8.4.2 yamt static device_t firewire_add_child (device_t, int, const char *, int);
198 1.8.4.2 yamt #elif defined(__NetBSD__)
199 1.8.4.2 yamt int firewirematch (struct device *, struct cfdata *, void *);
200 1.8.4.2 yamt void firewireattach (struct device *, struct device *, void *);
201 1.8.4.2 yamt int firewiredetach (struct device *, int);
202 1.8.4.2 yamt int firewire_print (void *, const char *);
203 1.8.4.6 yamt int firewire_resume(struct firewire_comm *);
204 1.8.4.2 yamt #endif
205 1.8.4.6 yamt static void firewire_xfer_timeout(void *, int);
206 1.8.4.2 yamt static void fw_try_bmr (void *);
207 1.8.4.2 yamt static void fw_try_bmr_callback (struct fw_xfer *);
208 1.8.4.2 yamt static void fw_asystart (struct fw_xfer *);
209 1.8.4.2 yamt static int fw_get_tlabel (struct firewire_comm *, struct fw_xfer *);
210 1.8.4.2 yamt static void fw_bus_probe (struct firewire_comm *);
211 1.8.4.2 yamt static void fw_attach_dev (struct firewire_comm *);
212 1.8.4.2 yamt static void fw_bus_probe_thread(void *);
213 1.8.4.2 yamt #ifdef FW_VMACCESS
214 1.8.4.2 yamt static void fw_vmaccess (struct fw_xfer *);
215 1.8.4.2 yamt #endif
216 1.8.4.2 yamt static int fw_bmr (struct firewire_comm *);
217 1.8.4.6 yamt static void fw_dump_hdr(struct fw_pkt *, const char *);
218 1.8.4.2 yamt
219 1.8.4.2 yamt #if defined(__FreeBSD__)
220 1.8.4.2 yamt static device_method_t firewire_methods[] = {
221 1.8.4.2 yamt /* Device interface */
222 1.8.4.2 yamt DEVMETHOD(device_identify, firewire_identify),
223 1.8.4.2 yamt DEVMETHOD(device_probe, firewire_probe),
224 1.8.4.2 yamt DEVMETHOD(device_attach, firewire_attach),
225 1.8.4.2 yamt DEVMETHOD(device_detach, firewire_detach),
226 1.8.4.2 yamt DEVMETHOD(device_suspend, bus_generic_suspend),
227 1.8.4.2 yamt DEVMETHOD(device_resume, firewire_resume),
228 1.8.4.2 yamt DEVMETHOD(device_shutdown, bus_generic_shutdown),
229 1.8.4.2 yamt
230 1.8.4.2 yamt /* Bus interface */
231 1.8.4.2 yamt DEVMETHOD(bus_add_child, firewire_add_child),
232 1.8.4.2 yamt DEVMETHOD(bus_print_child, bus_generic_print_child),
233 1.8.4.2 yamt
234 1.8.4.2 yamt { 0, 0 }
235 1.8.4.2 yamt };
236 1.8.4.2 yamt #elif defined(__NetBSD__)
237 1.8.4.2 yamt CFATTACH_DECL(ieee1394if, sizeof (struct firewire_softc),
238 1.8.4.2 yamt firewirematch, firewireattach, firewiredetach, NULL);
239 1.8.4.2 yamt #endif
240 1.8.4.2 yamt const char *fw_linkspeed[] = {
241 1.8.4.2 yamt "S100", "S200", "S400", "S800",
242 1.8.4.2 yamt "S1600", "S3200", "undef", "undef"
243 1.8.4.2 yamt };
244 1.8.4.2 yamt
245 1.8.4.2 yamt static const char *tcode_str[] = {
246 1.8.4.2 yamt "WREQQ", "WREQB", "WRES", "undef",
247 1.8.4.2 yamt "RREQQ", "RREQB", "RRESQ", "RRESB",
248 1.8.4.2 yamt "CYCS", "LREQ", "STREAM", "LRES",
249 1.8.4.2 yamt "undef", "undef", "PHY", "undef"
250 1.8.4.2 yamt };
251 1.8.4.2 yamt
252 1.8.4.2 yamt /* IEEE-1394a Table C-2 Gap count as a function of hops*/
253 1.8.4.2 yamt #define MAX_GAPHOP 15
254 1.8.4.2 yamt u_int gap_cnt[] = { 5, 5, 7, 8, 10, 13, 16, 18,
255 1.8.4.2 yamt 21, 24, 26, 29, 32, 35, 37, 40};
256 1.8.4.2 yamt
257 1.8.4.2 yamt #if defined(__FreeBSD__)
258 1.8.4.2 yamt static driver_t firewire_driver = {
259 1.8.4.2 yamt "firewire",
260 1.8.4.2 yamt firewire_methods,
261 1.8.4.2 yamt sizeof(struct firewire_softc),
262 1.8.4.2 yamt };
263 1.8.4.2 yamt #endif
264 1.8.4.2 yamt
265 1.8.4.2 yamt /*
266 1.8.4.2 yamt * Lookup fwdev by node id.
267 1.8.4.2 yamt */
268 1.8.4.2 yamt struct fw_device *
269 1.8.4.2 yamt fw_noderesolve_nodeid(struct firewire_comm *fc, int dst)
270 1.8.4.2 yamt {
271 1.8.4.2 yamt struct fw_device *fwdev;
272 1.8.4.2 yamt int s;
273 1.8.4.2 yamt
274 1.8.4.2 yamt s = splfw();
275 1.8.4.6 yamt FW_GLOCK(fc);
276 1.8.4.2 yamt STAILQ_FOREACH(fwdev, &fc->devices, link)
277 1.8.4.2 yamt if (fwdev->dst == dst && fwdev->status != FWDEVINVAL)
278 1.8.4.2 yamt break;
279 1.8.4.6 yamt FW_GUNLOCK(fc);
280 1.8.4.2 yamt splx(s);
281 1.8.4.2 yamt
282 1.8.4.2 yamt return fwdev;
283 1.8.4.2 yamt }
284 1.8.4.2 yamt
285 1.8.4.2 yamt /*
286 1.8.4.2 yamt * Lookup fwdev by EUI64.
287 1.8.4.2 yamt */
288 1.8.4.2 yamt struct fw_device *
289 1.8.4.2 yamt fw_noderesolve_eui64(struct firewire_comm *fc, struct fw_eui64 *eui)
290 1.8.4.2 yamt {
291 1.8.4.2 yamt struct fw_device *fwdev;
292 1.8.4.2 yamt int s;
293 1.8.4.2 yamt
294 1.8.4.2 yamt s = splfw();
295 1.8.4.2 yamt STAILQ_FOREACH(fwdev, &fc->devices, link)
296 1.8.4.2 yamt if (FW_EUI64_EQUAL(fwdev->eui, *eui))
297 1.8.4.2 yamt break;
298 1.8.4.2 yamt splx(s);
299 1.8.4.2 yamt
300 1.8.4.2 yamt if(fwdev == NULL) return NULL;
301 1.8.4.2 yamt if(fwdev->status == FWDEVINVAL) return NULL;
302 1.8.4.2 yamt return fwdev;
303 1.8.4.2 yamt }
304 1.8.4.2 yamt
305 1.8.4.2 yamt /*
306 1.8.4.2 yamt * Async. request procedure for userland application.
307 1.8.4.2 yamt */
308 1.8.4.2 yamt int
309 1.8.4.2 yamt fw_asyreq(struct firewire_comm *fc, int sub, struct fw_xfer *xfer)
310 1.8.4.2 yamt {
311 1.8.4.2 yamt int err = 0;
312 1.8.4.2 yamt struct fw_xferq *xferq;
313 1.8.4.6 yamt int len;
314 1.8.4.2 yamt struct fw_pkt *fp;
315 1.8.4.2 yamt int tcode;
316 1.8.4.2 yamt const struct tcode_info *info;
317 1.8.4.2 yamt
318 1.8.4.2 yamt if(xfer == NULL) return EINVAL;
319 1.8.4.2 yamt if(xfer->hand == NULL){
320 1.8.4.2 yamt printf("hand == NULL\n");
321 1.8.4.2 yamt return EINVAL;
322 1.8.4.2 yamt }
323 1.8.4.2 yamt fp = &xfer->send.hdr;
324 1.8.4.2 yamt
325 1.8.4.2 yamt tcode = fp->mode.common.tcode & 0xf;
326 1.8.4.2 yamt info = &fc->tcode[tcode];
327 1.8.4.2 yamt if (info->flag == 0) {
328 1.8.4.2 yamt printf("invalid tcode=%x\n", tcode);
329 1.8.4.2 yamt return EINVAL;
330 1.8.4.2 yamt }
331 1.8.4.6 yamt
332 1.8.4.6 yamt /* XXX allow bus explore packets only after bus rest */
333 1.8.4.6 yamt if ((fc->status < FWBUSEXPLORE) &&
334 1.8.4.6 yamt ((tcode != FWTCODE_RREQQ) || (fp->mode.rreqq.dest_hi != 0xffff) ||
335 1.8.4.6 yamt (fp->mode.rreqq.dest_lo < 0xf0000000) ||
336 1.8.4.6 yamt (fp->mode.rreqq.dest_lo >= 0xf0001000))) {
337 1.8.4.6 yamt xfer->resp = EAGAIN;
338 1.8.4.6 yamt xfer->flag = FWXF_BUSY;
339 1.8.4.6 yamt return (EAGAIN);
340 1.8.4.6 yamt }
341 1.8.4.6 yamt
342 1.8.4.2 yamt if (info->flag & FWTI_REQ)
343 1.8.4.2 yamt xferq = fc->atq;
344 1.8.4.2 yamt else
345 1.8.4.2 yamt xferq = fc->ats;
346 1.8.4.2 yamt len = info->hdr_len;
347 1.8.4.2 yamt if (xfer->send.pay_len > MAXREC(fc->maxrec)) {
348 1.8.4.2 yamt printf("send.pay_len > maxrec\n");
349 1.8.4.2 yamt return EINVAL;
350 1.8.4.2 yamt }
351 1.8.4.2 yamt if (info->flag & FWTI_BLOCK_STR)
352 1.8.4.2 yamt len = fp->mode.stream.len;
353 1.8.4.2 yamt else if (info->flag & FWTI_BLOCK_ASY)
354 1.8.4.2 yamt len = fp->mode.rresb.len;
355 1.8.4.2 yamt else
356 1.8.4.2 yamt len = 0;
357 1.8.4.2 yamt if (len != xfer->send.pay_len){
358 1.8.4.2 yamt printf("len(%d) != send.pay_len(%d) %s(%x)\n",
359 1.8.4.2 yamt len, xfer->send.pay_len, tcode_str[tcode], tcode);
360 1.8.4.2 yamt return EINVAL;
361 1.8.4.2 yamt }
362 1.8.4.2 yamt
363 1.8.4.2 yamt if(xferq->start == NULL){
364 1.8.4.2 yamt printf("xferq->start == NULL\n");
365 1.8.4.2 yamt return EINVAL;
366 1.8.4.2 yamt }
367 1.8.4.2 yamt if(!(xferq->queued < xferq->maxq)){
368 1.8.4.6 yamt fw_printf(fc->bdev, "Discard a packet (queued=%d)\n",
369 1.8.4.2 yamt xferq->queued);
370 1.8.4.6 yamt return EAGAIN;
371 1.8.4.2 yamt }
372 1.8.4.2 yamt
373 1.8.4.6 yamt xfer->tl = -1;
374 1.8.4.2 yamt if (info->flag & FWTI_TLABEL) {
375 1.8.4.6 yamt if (fw_get_tlabel(fc, xfer) < 0)
376 1.8.4.2 yamt return EAGAIN;
377 1.8.4.2 yamt }
378 1.8.4.2 yamt
379 1.8.4.2 yamt xfer->resp = 0;
380 1.8.4.2 yamt xfer->fc = fc;
381 1.8.4.2 yamt xfer->q = xferq;
382 1.8.4.2 yamt
383 1.8.4.2 yamt fw_asystart(xfer);
384 1.8.4.2 yamt return err;
385 1.8.4.2 yamt }
386 1.8.4.2 yamt /*
387 1.8.4.2 yamt * Wakeup blocked process.
388 1.8.4.2 yamt */
389 1.8.4.2 yamt void
390 1.8.4.6 yamt fw_xferwake(struct fw_xfer *xfer)
391 1.8.4.6 yamt {
392 1.8.4.6 yamt fw_mtx_t lock = &xfer->fc->wait_lock;
393 1.8.4.6 yamt
394 1.8.4.6 yamt fw_mtx_lock(lock);
395 1.8.4.6 yamt xfer->flag |= FWXF_WAKE;
396 1.8.4.6 yamt fw_mtx_unlock(lock);
397 1.8.4.6 yamt
398 1.8.4.2 yamt wakeup(xfer);
399 1.8.4.2 yamt return;
400 1.8.4.2 yamt }
401 1.8.4.2 yamt
402 1.8.4.6 yamt int
403 1.8.4.6 yamt fw_xferwait(struct fw_xfer *xfer)
404 1.8.4.6 yamt {
405 1.8.4.6 yamt fw_mtx_t lock = &xfer->fc->wait_lock;
406 1.8.4.6 yamt int err = 0;
407 1.8.4.6 yamt
408 1.8.4.6 yamt fw_mtx_lock(lock);
409 1.8.4.6 yamt if ((xfer->flag & FWXF_WAKE) == 0)
410 1.8.4.6 yamt err = fw_msleep((void *)xfer, lock, PWAIT|PCATCH, "fw_xferwait", 0);
411 1.8.4.6 yamt fw_mtx_unlock(lock);
412 1.8.4.6 yamt
413 1.8.4.6 yamt return (err);
414 1.8.4.6 yamt }
415 1.8.4.6 yamt
416 1.8.4.2 yamt /*
417 1.8.4.2 yamt * Async. request with given xfer structure.
418 1.8.4.2 yamt */
419 1.8.4.2 yamt static void
420 1.8.4.2 yamt fw_asystart(struct fw_xfer *xfer)
421 1.8.4.2 yamt {
422 1.8.4.2 yamt struct firewire_comm *fc = xfer->fc;
423 1.8.4.2 yamt int s;
424 1.8.4.2 yamt s = splfw();
425 1.8.4.6 yamt /* Protect from interrupt/timeout */
426 1.8.4.6 yamt FW_GLOCK(fc);
427 1.8.4.6 yamt xfer->flag = FWXF_INQ;
428 1.8.4.2 yamt STAILQ_INSERT_TAIL(&xfer->q->q, xfer, link);
429 1.8.4.6 yamt #if 0
430 1.8.4.2 yamt xfer->q->queued ++;
431 1.8.4.6 yamt #endif
432 1.8.4.6 yamt FW_GUNLOCK(fc);
433 1.8.4.2 yamt splx(s);
434 1.8.4.2 yamt /* XXX just queue for mbuf */
435 1.8.4.2 yamt if (xfer->mbuf == NULL)
436 1.8.4.2 yamt xfer->q->start(fc);
437 1.8.4.2 yamt return;
438 1.8.4.2 yamt }
439 1.8.4.2 yamt
440 1.8.4.2 yamt #if defined(__FreeBSD__)
441 1.8.4.2 yamt static void
442 1.8.4.2 yamt firewire_identify(driver_t *driver, device_t parent)
443 1.8.4.2 yamt {
444 1.8.4.2 yamt BUS_ADD_CHILD(parent, 0, "firewire", -1);
445 1.8.4.2 yamt }
446 1.8.4.2 yamt
447 1.8.4.2 yamt static int
448 1.8.4.2 yamt firewire_probe(device_t dev)
449 1.8.4.2 yamt {
450 1.8.4.2 yamt device_set_desc(dev, "IEEE1394(FireWire) bus");
451 1.8.4.2 yamt return (0);
452 1.8.4.2 yamt }
453 1.8.4.2 yamt #elif defined(__NetBSD__)
454 1.8.4.2 yamt int
455 1.8.4.3 yamt firewirematch(struct device *parent, struct cfdata *cf,
456 1.8.4.3 yamt void *aux)
457 1.8.4.2 yamt {
458 1.8.4.2 yamt struct fwbus_attach_args *faa = (struct fwbus_attach_args *)aux;
459 1.8.4.2 yamt
460 1.8.4.2 yamt if (strcmp(faa->name, "ieee1394if") == 0)
461 1.8.4.2 yamt return (1);
462 1.8.4.2 yamt return (0);
463 1.8.4.2 yamt }
464 1.8.4.2 yamt #endif
465 1.8.4.2 yamt
466 1.8.4.2 yamt static void
467 1.8.4.6 yamt firewire_xfer_timeout(void *arg, int pending)
468 1.8.4.2 yamt {
469 1.8.4.6 yamt struct firewire_comm *fc = (struct firewire_comm *)arg;
470 1.8.4.6 yamt struct fw_xfer *xfer, *txfer;
471 1.8.4.2 yamt struct timeval tv;
472 1.8.4.2 yamt struct timeval split_timeout;
473 1.8.4.6 yamt STAILQ_HEAD(, fw_xfer) xfer_timeout;
474 1.8.4.2 yamt int i, s;
475 1.8.4.2 yamt
476 1.8.4.2 yamt split_timeout.tv_sec = 0;
477 1.8.4.2 yamt split_timeout.tv_usec = 200 * 1000; /* 200 msec */
478 1.8.4.2 yamt
479 1.8.4.2 yamt microtime(&tv);
480 1.8.4.6 yamt fw_timevalsub(&tv, &split_timeout);
481 1.8.4.6 yamt STAILQ_INIT(&xfer_timeout);
482 1.8.4.2 yamt
483 1.8.4.2 yamt s = splfw();
484 1.8.4.6 yamt fw_mtx_lock(&fc->tlabel_lock);
485 1.8.4.2 yamt for (i = 0; i < 0x40; i ++) {
486 1.8.4.2 yamt while ((xfer = STAILQ_FIRST(&fc->tlabels[i])) != NULL) {
487 1.8.4.6 yamt if ((xfer->flag & FWXF_SENT) == 0)
488 1.8.4.2 yamt /* not sent yet */
489 1.8.4.2 yamt break;
490 1.8.4.6 yamt if (fw_timevalcmp(&xfer->tv, &tv, >))
491 1.8.4.6 yamt /* the rests are newer than this */
492 1.8.4.6 yamt break;
493 1.8.4.6 yamt fw_printf(fc->bdev,
494 1.8.4.6 yamt "split transaction timeout: "
495 1.8.4.6 yamt "tl=0x%x flag=0x%02x\n", i, xfer->flag);
496 1.8.4.6 yamt fw_dump_hdr(&xfer->send.hdr, "send");
497 1.8.4.2 yamt xfer->resp = ETIMEDOUT;
498 1.8.4.6 yamt STAILQ_REMOVE_HEAD(&fc->tlabels[i], tlabel);
499 1.8.4.6 yamt STAILQ_INSERT_TAIL(&xfer_timeout, xfer, tlabel);
500 1.8.4.2 yamt }
501 1.8.4.2 yamt }
502 1.8.4.6 yamt fw_mtx_unlock(&fc->tlabel_lock);
503 1.8.4.2 yamt splx(s);
504 1.8.4.6 yamt fc->timeout(fc);
505 1.8.4.6 yamt
506 1.8.4.6 yamt STAILQ_FOREACH_SAFE(xfer, &xfer_timeout, tlabel, txfer)
507 1.8.4.6 yamt xfer->hand(xfer);
508 1.8.4.2 yamt }
509 1.8.4.2 yamt
510 1.8.4.6 yamt #define WATCHDOG_HZ 10
511 1.8.4.2 yamt static void
512 1.8.4.2 yamt firewire_watchdog(void *arg)
513 1.8.4.2 yamt {
514 1.8.4.2 yamt struct firewire_comm *fc;
515 1.8.4.6 yamt static int watchdog_clock = 0;
516 1.8.4.2 yamt
517 1.8.4.2 yamt fc = (struct firewire_comm *)arg;
518 1.8.4.2 yamt
519 1.8.4.2 yamt /*
520 1.8.4.2 yamt * At boot stage, the device interrupt is disabled and
521 1.8.4.2 yamt * We encounter a timeout easily. To avoid this,
522 1.8.4.2 yamt * ignore clock interrupt for a while.
523 1.8.4.2 yamt */
524 1.8.4.6 yamt if (watchdog_clock > WATCHDOG_HZ * 15)
525 1.8.4.6 yamt fw_taskqueue_enqueue(fc->taskqueue, &fc->task_timeout);
526 1.8.4.6 yamt else
527 1.8.4.6 yamt watchdog_clock ++;
528 1.8.4.2 yamt
529 1.8.4.6 yamt fw_callout_reset(&fc->timeout_callout, hz / WATCHDOG_HZ,
530 1.8.4.2 yamt (void *)firewire_watchdog, (void *)fc);
531 1.8.4.2 yamt }
532 1.8.4.2 yamt
533 1.8.4.2 yamt /*
534 1.8.4.2 yamt * The attach routine.
535 1.8.4.2 yamt */
536 1.8.4.2 yamt FW_ATTACH(firewire)
537 1.8.4.2 yamt {
538 1.8.4.2 yamt FW_ATTACH_START(firewire, sc, fwa);
539 1.8.4.2 yamt FIREWIRE_ATTACH_START;
540 1.8.4.2 yamt
541 1.8.4.2 yamt sc->fc = fc;
542 1.8.4.2 yamt fc->status = FWBUSNOTREADY;
543 1.8.4.2 yamt
544 1.8.4.2 yamt if( fc->nisodma > FWMAXNDMA) fc->nisodma = FWMAXNDMA;
545 1.8.4.2 yamt
546 1.8.4.2 yamt FWDEV_MAKEDEV(sc);
547 1.8.4.2 yamt
548 1.8.4.6 yamt fw_mtx_init(&fc->wait_lock, "fwwait", NULL, MTX_DEF);
549 1.8.4.6 yamt fw_mtx_init(&fc->tlabel_lock, "fwtlabel", NULL, MTX_DEF);
550 1.8.4.6 yamt fw_callout_init(&fc->timeout_callout);
551 1.8.4.6 yamt fw_callout_init(&fc->bmr_callout);
552 1.8.4.6 yamt fw_callout_init(&fc->busprobe_callout);
553 1.8.4.6 yamt FW_TASK_INIT(&fc->task_timeout, 0, firewire_xfer_timeout, (void *)fc);
554 1.8.4.2 yamt
555 1.8.4.6 yamt fw_callout_reset(&sc->fc->timeout_callout, hz,
556 1.8.4.2 yamt (void *)firewire_watchdog, (void *)sc->fc);
557 1.8.4.2 yamt
558 1.8.4.6 yamt /* create thread */
559 1.8.4.6 yamt fw_kthread_create(fw_bus_probe_thread, (void *)fc, &fc->probe_thread,
560 1.8.4.6 yamt "fw%d_probe", fw_get_unit(fc->bdev));
561 1.8.4.6 yamt fw_config_pending_incr();
562 1.8.4.2 yamt
563 1.8.4.2 yamt FIREWIRE_GENERIC_ATTACH;
564 1.8.4.2 yamt
565 1.8.4.2 yamt /* bus_reset */
566 1.8.4.6 yamt fw_busreset(fc, FWBUSNOTREADY);
567 1.8.4.2 yamt fc->ibr(fc);
568 1.8.4.2 yamt
569 1.8.4.7 yamt #ifdef __NetBSD__
570 1.8.4.7 yamt if (!pmf_device_register(self, NULL, NULL))
571 1.8.4.7 yamt aprint_error_dev(self, "couldn't establish power handler\n");
572 1.8.4.7 yamt #endif
573 1.8.4.7 yamt
574 1.8.4.2 yamt FW_ATTACH_RETURN(0);
575 1.8.4.2 yamt }
576 1.8.4.2 yamt
577 1.8.4.2 yamt #if defined(__FreeBSD__)
578 1.8.4.2 yamt /*
579 1.8.4.2 yamt * Attach it as child.
580 1.8.4.2 yamt */
581 1.8.4.2 yamt static device_t
582 1.8.4.2 yamt firewire_add_child(device_t dev, int order, const char *name, int unit)
583 1.8.4.2 yamt {
584 1.8.4.2 yamt device_t child;
585 1.8.4.2 yamt struct firewire_softc *sc;
586 1.8.4.2 yamt struct fw_attach_args fwa;
587 1.8.4.2 yamt
588 1.8.4.2 yamt sc = (struct firewire_softc *)device_get_softc(dev);
589 1.8.4.2 yamt child = device_add_child(dev, name, unit);
590 1.8.4.2 yamt if (child) {
591 1.8.4.2 yamt fwa.name = name;
592 1.8.4.2 yamt fwa.fc = sc->fc;
593 1.8.4.2 yamt fwa.fwdev = NULL;
594 1.8.4.2 yamt device_set_ivars(child, &fwa);
595 1.8.4.2 yamt device_probe_and_attach(child);
596 1.8.4.2 yamt }
597 1.8.4.2 yamt
598 1.8.4.2 yamt return child;
599 1.8.4.2 yamt }
600 1.8.4.2 yamt
601 1.8.4.2 yamt static int
602 1.8.4.2 yamt firewire_resume(device_t dev)
603 1.8.4.2 yamt {
604 1.8.4.2 yamt struct firewire_softc *sc;
605 1.8.4.2 yamt
606 1.8.4.2 yamt sc = (struct firewire_softc *)device_get_softc(dev);
607 1.8.4.2 yamt sc->fc->status = FWBUSNOTREADY;
608 1.8.4.2 yamt
609 1.8.4.2 yamt bus_generic_resume(dev);
610 1.8.4.2 yamt
611 1.8.4.2 yamt return(0);
612 1.8.4.2 yamt }
613 1.8.4.2 yamt #endif
614 1.8.4.2 yamt
615 1.8.4.2 yamt /*
616 1.8.4.2 yamt * Dettach it.
617 1.8.4.2 yamt */
618 1.8.4.2 yamt FW_DETACH(firewire)
619 1.8.4.2 yamt {
620 1.8.4.2 yamt FW_DETACH_START(firewire, sc);
621 1.8.4.2 yamt struct firewire_comm *fc;
622 1.8.4.2 yamt struct fw_device *fwdev, *fwdev_next;
623 1.8.4.2 yamt
624 1.8.4.2 yamt fc = sc->fc;
625 1.8.4.6 yamt fw_mtx_lock(&fc->wait_lock);
626 1.8.4.2 yamt fc->status = FWBUSDETACH;
627 1.8.4.6 yamt wakeup(fc);
628 1.8.4.6 yamt if (fw_msleep(fc->probe_thread,
629 1.8.4.6 yamt &fc->wait_lock, PWAIT, "fwthr", hz * 60))
630 1.8.4.6 yamt printf("firewire probe thread didn't die\n");
631 1.8.4.6 yamt fw_mtx_unlock(&fc->wait_lock);
632 1.8.4.2 yamt
633 1.8.4.2 yamt FWDEV_DESTROYDEV(sc);
634 1.8.4.2 yamt FIREWIRE_GENERIC_DETACH;
635 1.8.4.2 yamt
636 1.8.4.6 yamt fw_callout_stop(&fc->timeout_callout);
637 1.8.4.6 yamt fw_callout_stop(&fc->bmr_callout);
638 1.8.4.6 yamt fw_callout_stop(&fc->busprobe_callout);
639 1.8.4.2 yamt
640 1.8.4.2 yamt /* XXX xfree_free and untimeout on all xfers */
641 1.8.4.2 yamt for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL;
642 1.8.4.2 yamt fwdev = fwdev_next) {
643 1.8.4.2 yamt fwdev_next = STAILQ_NEXT(fwdev, link);
644 1.8.4.2 yamt free(fwdev, M_FW);
645 1.8.4.2 yamt }
646 1.8.4.2 yamt free(fc->topology_map, M_FW);
647 1.8.4.2 yamt free(fc->speed_map, M_FW);
648 1.8.4.2 yamt free(fc->crom_src_buf, M_FW);
649 1.8.4.2 yamt
650 1.8.4.6 yamt fw_mtx_destroy(&fc->wait_lock);
651 1.8.4.6 yamt fw_mtx_destroy(&fc->tlabel_lock);
652 1.8.4.2 yamt return(0);
653 1.8.4.2 yamt }
654 1.8.4.2 yamt #if defined(__FreeBSD__)
655 1.8.4.2 yamt #if 0
656 1.8.4.2 yamt static int
657 1.8.4.2 yamt firewire_shutdown( device_t dev )
658 1.8.4.2 yamt {
659 1.8.4.2 yamt return 0;
660 1.8.4.2 yamt }
661 1.8.4.2 yamt #endif
662 1.8.4.2 yamt #elif defined(__NetBSD__)
663 1.8.4.2 yamt int
664 1.8.4.2 yamt firewire_print(void *aux, const char *pnp)
665 1.8.4.2 yamt {
666 1.8.4.3 yamt struct fw_attach_args *fwa = (struct fw_attach_args *)aux;
667 1.8.4.2 yamt
668 1.8.4.2 yamt if (pnp)
669 1.8.4.3 yamt aprint_normal("%s at %s", fwa->name, pnp);
670 1.8.4.2 yamt
671 1.8.4.2 yamt return UNCONF;
672 1.8.4.4 yamt }
673 1.8.4.6 yamt
674 1.8.4.6 yamt int
675 1.8.4.6 yamt firewire_resume(struct firewire_comm *fc)
676 1.8.4.6 yamt {
677 1.8.4.6 yamt
678 1.8.4.6 yamt fc->status = FWBUSNOTREADY;
679 1.8.4.6 yamt return 0;
680 1.8.4.6 yamt }
681 1.8.4.2 yamt #endif
682 1.8.4.2 yamt
683 1.8.4.2 yamt static void
684 1.8.4.2 yamt fw_xferq_drain(struct fw_xferq *xferq)
685 1.8.4.2 yamt {
686 1.8.4.2 yamt struct fw_xfer *xfer;
687 1.8.4.2 yamt
688 1.8.4.2 yamt while ((xfer = STAILQ_FIRST(&xferq->q)) != NULL) {
689 1.8.4.2 yamt STAILQ_REMOVE_HEAD(&xferq->q, link);
690 1.8.4.6 yamt #if 0
691 1.8.4.2 yamt xferq->queued --;
692 1.8.4.6 yamt #endif
693 1.8.4.2 yamt xfer->resp = EAGAIN;
694 1.8.4.6 yamt xfer->flag = FWXF_SENTERR;
695 1.8.4.2 yamt fw_xfer_done(xfer);
696 1.8.4.2 yamt }
697 1.8.4.2 yamt }
698 1.8.4.2 yamt
699 1.8.4.2 yamt void
700 1.8.4.2 yamt fw_drain_txq(struct firewire_comm *fc)
701 1.8.4.2 yamt {
702 1.8.4.6 yamt struct fw_xfer *xfer, *txfer;
703 1.8.4.6 yamt STAILQ_HEAD(, fw_xfer) xfer_drain;
704 1.8.4.2 yamt int i;
705 1.8.4.2 yamt
706 1.8.4.6 yamt STAILQ_INIT(&xfer_drain);
707 1.8.4.6 yamt
708 1.8.4.6 yamt FW_GLOCK(fc);
709 1.8.4.2 yamt fw_xferq_drain(fc->atq);
710 1.8.4.2 yamt fw_xferq_drain(fc->ats);
711 1.8.4.2 yamt for(i = 0; i < fc->nisodma; i++)
712 1.8.4.2 yamt fw_xferq_drain(fc->it[i]);
713 1.8.4.6 yamt FW_GUNLOCK(fc);
714 1.8.4.6 yamt
715 1.8.4.6 yamt fw_mtx_lock(&fc->tlabel_lock);
716 1.8.4.6 yamt for (i = 0; i < 0x40; i ++)
717 1.8.4.6 yamt while ((xfer = STAILQ_FIRST(&fc->tlabels[i])) != NULL) {
718 1.8.4.6 yamt if (firewire_debug)
719 1.8.4.6 yamt printf("tl=%d flag=%d\n", i, xfer->flag);
720 1.8.4.6 yamt xfer->resp = EAGAIN;
721 1.8.4.6 yamt STAILQ_REMOVE_HEAD(&fc->tlabels[i], tlabel);
722 1.8.4.6 yamt STAILQ_INSERT_TAIL(&xfer_drain, xfer, tlabel);
723 1.8.4.6 yamt }
724 1.8.4.6 yamt fw_mtx_unlock(&fc->tlabel_lock);
725 1.8.4.6 yamt
726 1.8.4.6 yamt STAILQ_FOREACH_SAFE(xfer, &xfer_drain, tlabel, txfer)
727 1.8.4.6 yamt xfer->hand(xfer);
728 1.8.4.2 yamt }
729 1.8.4.2 yamt
730 1.8.4.2 yamt static void
731 1.8.4.2 yamt fw_reset_csr(struct firewire_comm *fc)
732 1.8.4.2 yamt {
733 1.8.4.2 yamt int i;
734 1.8.4.2 yamt
735 1.8.4.2 yamt CSRARC(fc, STATE_CLEAR)
736 1.8.4.2 yamt = 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14 ;
737 1.8.4.2 yamt CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
738 1.8.4.2 yamt CSRARC(fc, NODE_IDS) = 0x3f;
739 1.8.4.2 yamt
740 1.8.4.2 yamt CSRARC(fc, TOPO_MAP + 8) = 0;
741 1.8.4.2 yamt fc->irm = -1;
742 1.8.4.2 yamt
743 1.8.4.2 yamt fc->max_node = -1;
744 1.8.4.2 yamt
745 1.8.4.2 yamt for(i = 2; i < 0x100/4 - 2 ; i++){
746 1.8.4.2 yamt CSRARC(fc, SPED_MAP + i * 4) = 0;
747 1.8.4.2 yamt }
748 1.8.4.2 yamt CSRARC(fc, STATE_CLEAR) = 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14 ;
749 1.8.4.2 yamt CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
750 1.8.4.2 yamt CSRARC(fc, RESET_START) = 0;
751 1.8.4.2 yamt CSRARC(fc, SPLIT_TIMEOUT_HI) = 0;
752 1.8.4.2 yamt CSRARC(fc, SPLIT_TIMEOUT_LO) = 800 << 19;
753 1.8.4.2 yamt CSRARC(fc, CYCLE_TIME) = 0x0;
754 1.8.4.2 yamt CSRARC(fc, BUS_TIME) = 0x0;
755 1.8.4.2 yamt CSRARC(fc, BUS_MGR_ID) = 0x3f;
756 1.8.4.2 yamt CSRARC(fc, BANDWIDTH_AV) = 4915;
757 1.8.4.2 yamt CSRARC(fc, CHANNELS_AV_HI) = 0xffffffff;
758 1.8.4.2 yamt CSRARC(fc, CHANNELS_AV_LO) = 0xffffffff;
759 1.8.4.2 yamt CSRARC(fc, IP_CHANNELS) = (1 << 31);
760 1.8.4.2 yamt
761 1.8.4.2 yamt CSRARC(fc, CONF_ROM) = 0x04 << 24;
762 1.8.4.2 yamt CSRARC(fc, CONF_ROM + 4) = 0x31333934; /* means strings 1394 */
763 1.8.4.2 yamt CSRARC(fc, CONF_ROM + 8) = 1 << 31 | 1 << 30 | 1 << 29 |
764 1.8.4.2 yamt 1 << 28 | 0xff << 16 | 0x09 << 8;
765 1.8.4.2 yamt CSRARC(fc, CONF_ROM + 0xc) = 0;
766 1.8.4.2 yamt
767 1.8.4.2 yamt /* DV depend CSRs see blue book */
768 1.8.4.2 yamt CSRARC(fc, oPCR) &= ~DV_BROADCAST_ON;
769 1.8.4.2 yamt CSRARC(fc, iPCR) &= ~DV_BROADCAST_ON;
770 1.8.4.2 yamt
771 1.8.4.2 yamt CSRARC(fc, STATE_CLEAR) &= ~(1 << 23 | 1 << 15 | 1 << 14 );
772 1.8.4.2 yamt CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
773 1.8.4.2 yamt }
774 1.8.4.2 yamt
775 1.8.4.2 yamt static void
776 1.8.4.2 yamt fw_init_crom(struct firewire_comm *fc)
777 1.8.4.2 yamt {
778 1.8.4.2 yamt struct crom_src *src;
779 1.8.4.2 yamt
780 1.8.4.2 yamt fc->crom_src_buf = (struct crom_src_buf *)
781 1.8.4.2 yamt malloc(sizeof(struct crom_src_buf), M_FW, M_WAITOK | M_ZERO);
782 1.8.4.2 yamt if (fc->crom_src_buf == NULL)
783 1.8.4.2 yamt return;
784 1.8.4.2 yamt
785 1.8.4.2 yamt src = &fc->crom_src_buf->src;
786 1.8.4.2 yamt bzero(src, sizeof(struct crom_src));
787 1.8.4.2 yamt
788 1.8.4.2 yamt /* BUS info sample */
789 1.8.4.2 yamt src->hdr.info_len = 4;
790 1.8.4.2 yamt
791 1.8.4.2 yamt src->businfo.bus_name = CSR_BUS_NAME_IEEE1394;
792 1.8.4.2 yamt
793 1.8.4.2 yamt src->businfo.irmc = 1;
794 1.8.4.2 yamt src->businfo.cmc = 1;
795 1.8.4.2 yamt src->businfo.isc = 1;
796 1.8.4.2 yamt src->businfo.bmc = 1;
797 1.8.4.2 yamt src->businfo.pmc = 0;
798 1.8.4.2 yamt src->businfo.cyc_clk_acc = 100;
799 1.8.4.2 yamt src->businfo.max_rec = fc->maxrec;
800 1.8.4.2 yamt src->businfo.max_rom = MAXROM_4;
801 1.8.4.2 yamt src->businfo.generation = 1;
802 1.8.4.2 yamt src->businfo.link_spd = fc->speed;
803 1.8.4.2 yamt
804 1.8.4.2 yamt src->businfo.eui64.hi = fc->eui.hi;
805 1.8.4.2 yamt src->businfo.eui64.lo = fc->eui.lo;
806 1.8.4.2 yamt
807 1.8.4.2 yamt STAILQ_INIT(&src->chunk_list);
808 1.8.4.2 yamt
809 1.8.4.2 yamt fc->crom_src = src;
810 1.8.4.2 yamt fc->crom_root = &fc->crom_src_buf->root;
811 1.8.4.2 yamt }
812 1.8.4.2 yamt
813 1.8.4.2 yamt static void
814 1.8.4.2 yamt fw_reset_crom(struct firewire_comm *fc)
815 1.8.4.2 yamt {
816 1.8.4.2 yamt struct crom_src_buf *buf;
817 1.8.4.2 yamt struct crom_src *src;
818 1.8.4.2 yamt struct crom_chunk *root;
819 1.8.4.2 yamt
820 1.8.4.2 yamt if (fc->crom_src_buf == NULL)
821 1.8.4.2 yamt fw_init_crom(fc);
822 1.8.4.2 yamt
823 1.8.4.2 yamt buf = fc->crom_src_buf;
824 1.8.4.2 yamt src = fc->crom_src;
825 1.8.4.2 yamt root = fc->crom_root;
826 1.8.4.2 yamt
827 1.8.4.2 yamt STAILQ_INIT(&src->chunk_list);
828 1.8.4.2 yamt
829 1.8.4.2 yamt bzero(root, sizeof(struct crom_chunk));
830 1.8.4.2 yamt crom_add_chunk(src, NULL, root, 0);
831 1.8.4.2 yamt crom_add_entry(root, CSRKEY_NCAP, 0x0083c0); /* XXX */
832 1.8.4.2 yamt /* private company_id */
833 1.8.4.2 yamt crom_add_entry(root, CSRKEY_VENDOR, CSRVAL_VENDOR_PRIVATE);
834 1.8.4.2 yamt crom_add_simple_text(src, root, &buf->vendor, PROJECT_STR);
835 1.8.4.2 yamt crom_add_entry(root, CSRKEY_HW, OS_VER);
836 1.8.4.2 yamt crom_add_simple_text(src, root, &buf->hw, hostname);
837 1.8.4.2 yamt }
838 1.8.4.2 yamt
839 1.8.4.2 yamt /*
840 1.8.4.2 yamt * Called after bus reset.
841 1.8.4.2 yamt */
842 1.8.4.2 yamt void
843 1.8.4.6 yamt fw_busreset(struct firewire_comm *fc, uint32_t new_status)
844 1.8.4.2 yamt {
845 1.8.4.2 yamt struct firewire_dev_comm *fdc;
846 1.8.4.2 yamt struct crom_src *src;
847 1.8.4.2 yamt void *newrom;
848 1.8.4.2 yamt
849 1.8.4.2 yamt switch(fc->status){
850 1.8.4.2 yamt case FWBUSMGRELECT:
851 1.8.4.6 yamt fw_callout_stop(&fc->bmr_callout);
852 1.8.4.2 yamt break;
853 1.8.4.2 yamt default:
854 1.8.4.2 yamt break;
855 1.8.4.2 yamt }
856 1.8.4.6 yamt fc->status = new_status;
857 1.8.4.2 yamt fw_reset_csr(fc);
858 1.8.4.2 yamt fw_reset_crom(fc);
859 1.8.4.2 yamt
860 1.8.4.2 yamt FIREWIRE_CHILDREN_FOREACH_FUNC(post_busreset, fdc);
861 1.8.4.2 yamt
862 1.8.4.2 yamt newrom = malloc(CROMSIZE, M_FW, M_NOWAIT | M_ZERO);
863 1.8.4.2 yamt src = &fc->crom_src_buf->src;
864 1.8.4.2 yamt crom_load(src, (uint32_t *)newrom, CROMSIZE);
865 1.8.4.2 yamt if (bcmp(newrom, fc->config_rom, CROMSIZE) != 0) {
866 1.8.4.2 yamt /* bump generation and reload */
867 1.8.4.2 yamt src->businfo.generation ++;
868 1.8.4.2 yamt /* generation must be between 0x2 and 0xF */
869 1.8.4.2 yamt if (src->businfo.generation < 2)
870 1.8.4.2 yamt src->businfo.generation ++;
871 1.8.4.2 yamt crom_load(src, (uint32_t *)newrom, CROMSIZE);
872 1.8.4.2 yamt bcopy(newrom, (void *)fc->config_rom, CROMSIZE);
873 1.8.4.2 yamt }
874 1.8.4.2 yamt free(newrom, M_FW);
875 1.8.4.2 yamt }
876 1.8.4.2 yamt
877 1.8.4.2 yamt /* Call once after reboot */
878 1.8.4.2 yamt void fw_init(struct firewire_comm *fc)
879 1.8.4.2 yamt {
880 1.8.4.2 yamt int i;
881 1.8.4.2 yamt #ifdef FW_VMACCESS
882 1.8.4.2 yamt struct fw_xfer *xfer;
883 1.8.4.2 yamt struct fw_bind *fwb;
884 1.8.4.2 yamt #endif
885 1.8.4.2 yamt
886 1.8.4.2 yamt fc->arq->queued = 0;
887 1.8.4.2 yamt fc->ars->queued = 0;
888 1.8.4.2 yamt fc->atq->queued = 0;
889 1.8.4.2 yamt fc->ats->queued = 0;
890 1.8.4.2 yamt
891 1.8.4.2 yamt fc->arq->buf = NULL;
892 1.8.4.2 yamt fc->ars->buf = NULL;
893 1.8.4.2 yamt fc->atq->buf = NULL;
894 1.8.4.2 yamt fc->ats->buf = NULL;
895 1.8.4.2 yamt
896 1.8.4.2 yamt fc->arq->flag = 0;
897 1.8.4.2 yamt fc->ars->flag = 0;
898 1.8.4.2 yamt fc->atq->flag = 0;
899 1.8.4.2 yamt fc->ats->flag = 0;
900 1.8.4.2 yamt
901 1.8.4.2 yamt STAILQ_INIT(&fc->atq->q);
902 1.8.4.2 yamt STAILQ_INIT(&fc->ats->q);
903 1.8.4.2 yamt
904 1.8.4.2 yamt for( i = 0 ; i < fc->nisodma ; i ++ ){
905 1.8.4.2 yamt fc->it[i]->queued = 0;
906 1.8.4.2 yamt fc->ir[i]->queued = 0;
907 1.8.4.2 yamt
908 1.8.4.2 yamt fc->it[i]->start = NULL;
909 1.8.4.2 yamt fc->ir[i]->start = NULL;
910 1.8.4.2 yamt
911 1.8.4.2 yamt fc->it[i]->buf = NULL;
912 1.8.4.2 yamt fc->ir[i]->buf = NULL;
913 1.8.4.2 yamt
914 1.8.4.2 yamt fc->it[i]->flag = FWXFERQ_STREAM;
915 1.8.4.2 yamt fc->ir[i]->flag = FWXFERQ_STREAM;
916 1.8.4.2 yamt
917 1.8.4.2 yamt STAILQ_INIT(&fc->it[i]->q);
918 1.8.4.2 yamt STAILQ_INIT(&fc->ir[i]->q);
919 1.8.4.2 yamt }
920 1.8.4.2 yamt
921 1.8.4.2 yamt fc->arq->maxq = FWMAXQUEUE;
922 1.8.4.2 yamt fc->ars->maxq = FWMAXQUEUE;
923 1.8.4.2 yamt fc->atq->maxq = FWMAXQUEUE;
924 1.8.4.2 yamt fc->ats->maxq = FWMAXQUEUE;
925 1.8.4.2 yamt
926 1.8.4.2 yamt for( i = 0 ; i < fc->nisodma ; i++){
927 1.8.4.2 yamt fc->ir[i]->maxq = FWMAXQUEUE;
928 1.8.4.2 yamt fc->it[i]->maxq = FWMAXQUEUE;
929 1.8.4.2 yamt }
930 1.8.4.2 yamt /* Initialize csr registers */
931 1.8.4.2 yamt fc->topology_map = (struct fw_topology_map *)malloc(
932 1.8.4.2 yamt sizeof(struct fw_topology_map),
933 1.8.4.2 yamt M_FW, M_NOWAIT | M_ZERO);
934 1.8.4.2 yamt fc->speed_map = (struct fw_speed_map *)malloc(
935 1.8.4.2 yamt sizeof(struct fw_speed_map),
936 1.8.4.2 yamt M_FW, M_NOWAIT | M_ZERO);
937 1.8.4.2 yamt CSRARC(fc, TOPO_MAP) = 0x3f1 << 16;
938 1.8.4.2 yamt CSRARC(fc, TOPO_MAP + 4) = 1;
939 1.8.4.2 yamt CSRARC(fc, SPED_MAP) = 0x3f1 << 16;
940 1.8.4.2 yamt CSRARC(fc, SPED_MAP + 4) = 1;
941 1.8.4.2 yamt
942 1.8.4.2 yamt STAILQ_INIT(&fc->devices);
943 1.8.4.2 yamt
944 1.8.4.2 yamt /* Initialize Async handlers */
945 1.8.4.2 yamt STAILQ_INIT(&fc->binds);
946 1.8.4.2 yamt for( i = 0 ; i < 0x40 ; i++){
947 1.8.4.2 yamt STAILQ_INIT(&fc->tlabels[i]);
948 1.8.4.2 yamt }
949 1.8.4.2 yamt
950 1.8.4.2 yamt /* DV depend CSRs see blue book */
951 1.8.4.2 yamt #if 0
952 1.8.4.2 yamt CSRARC(fc, oMPR) = 0x3fff0001; /* # output channel = 1 */
953 1.8.4.2 yamt CSRARC(fc, oPCR) = 0x8000007a;
954 1.8.4.2 yamt for(i = 4 ; i < 0x7c/4 ; i+=4){
955 1.8.4.2 yamt CSRARC(fc, i + oPCR) = 0x8000007a;
956 1.8.4.2 yamt }
957 1.8.4.2 yamt
958 1.8.4.2 yamt CSRARC(fc, iMPR) = 0x00ff0001; /* # input channel = 1 */
959 1.8.4.2 yamt CSRARC(fc, iPCR) = 0x803f0000;
960 1.8.4.2 yamt for(i = 4 ; i < 0x7c/4 ; i+=4){
961 1.8.4.2 yamt CSRARC(fc, i + iPCR) = 0x0;
962 1.8.4.2 yamt }
963 1.8.4.2 yamt #endif
964 1.8.4.2 yamt
965 1.8.4.2 yamt fc->crom_src_buf = NULL;
966 1.8.4.2 yamt
967 1.8.4.2 yamt #ifdef FW_VMACCESS
968 1.8.4.2 yamt xfer = fw_xfer_alloc();
969 1.8.4.2 yamt if(xfer == NULL) return;
970 1.8.4.2 yamt
971 1.8.4.2 yamt fwb = (struct fw_bind *)malloc(sizeof (struct fw_bind), M_FW, M_NOWAIT);
972 1.8.4.2 yamt if(fwb == NULL){
973 1.8.4.2 yamt fw_xfer_free(xfer);
974 1.8.4.2 yamt return;
975 1.8.4.2 yamt }
976 1.8.4.2 yamt xfer->hand = fw_vmaccess;
977 1.8.4.2 yamt xfer->fc = fc;
978 1.8.4.2 yamt xfer->sc = NULL;
979 1.8.4.2 yamt
980 1.8.4.2 yamt fwb->start_hi = 0x2;
981 1.8.4.2 yamt fwb->start_lo = 0;
982 1.8.4.2 yamt fwb->addrlen = 0xffffffff;
983 1.8.4.2 yamt fwb->xfer = xfer;
984 1.8.4.2 yamt fw_bindadd(fc, fwb);
985 1.8.4.2 yamt #endif
986 1.8.4.2 yamt }
987 1.8.4.2 yamt
988 1.8.4.2 yamt #define BIND_CMP(addr, fwb) (((addr) < (fwb)->start)?-1:\
989 1.8.4.2 yamt ((fwb)->end < (addr))?1:0)
990 1.8.4.2 yamt
991 1.8.4.2 yamt /*
992 1.8.4.2 yamt * To lookup bound process from IEEE1394 address.
993 1.8.4.2 yamt */
994 1.8.4.2 yamt struct fw_bind *
995 1.8.4.2 yamt fw_bindlookup(struct firewire_comm *fc, uint16_t dest_hi, uint32_t dest_lo)
996 1.8.4.2 yamt {
997 1.8.4.2 yamt u_int64_t addr;
998 1.8.4.6 yamt struct fw_bind *tfw, *r = NULL;
999 1.8.4.2 yamt
1000 1.8.4.2 yamt addr = ((u_int64_t)dest_hi << 32) | dest_lo;
1001 1.8.4.6 yamt FW_GLOCK(fc);
1002 1.8.4.2 yamt STAILQ_FOREACH(tfw, &fc->binds, fclist)
1003 1.8.4.6 yamt if (BIND_CMP(addr, tfw) == 0) {
1004 1.8.4.6 yamt r = tfw;
1005 1.8.4.6 yamt break;
1006 1.8.4.6 yamt }
1007 1.8.4.6 yamt FW_GUNLOCK(fc);
1008 1.8.4.6 yamt return(r);
1009 1.8.4.2 yamt }
1010 1.8.4.2 yamt
1011 1.8.4.2 yamt /*
1012 1.8.4.2 yamt * To bind IEEE1394 address block to process.
1013 1.8.4.2 yamt */
1014 1.8.4.2 yamt int
1015 1.8.4.2 yamt fw_bindadd(struct firewire_comm *fc, struct fw_bind *fwb)
1016 1.8.4.2 yamt {
1017 1.8.4.2 yamt struct fw_bind *tfw, *prev = NULL;
1018 1.8.4.6 yamt int r = 0;
1019 1.8.4.2 yamt
1020 1.8.4.2 yamt if (fwb->start > fwb->end) {
1021 1.8.4.2 yamt printf("%s: invalid range\n", __func__);
1022 1.8.4.2 yamt return EINVAL;
1023 1.8.4.2 yamt }
1024 1.8.4.2 yamt
1025 1.8.4.6 yamt FW_GLOCK(fc);
1026 1.8.4.2 yamt STAILQ_FOREACH(tfw, &fc->binds, fclist) {
1027 1.8.4.2 yamt if (fwb->end < tfw->start)
1028 1.8.4.2 yamt break;
1029 1.8.4.2 yamt prev = tfw;
1030 1.8.4.2 yamt }
1031 1.8.4.6 yamt if (prev == NULL)
1032 1.8.4.2 yamt STAILQ_INSERT_HEAD(&fc->binds, fwb, fclist);
1033 1.8.4.6 yamt else if (prev->end < fwb->start)
1034 1.8.4.2 yamt STAILQ_INSERT_AFTER(&fc->binds, prev, fwb, fclist);
1035 1.8.4.6 yamt else {
1036 1.8.4.6 yamt printf("%s: bind failed\n", __func__);
1037 1.8.4.6 yamt r = EBUSY;
1038 1.8.4.2 yamt }
1039 1.8.4.6 yamt FW_GUNLOCK(fc);
1040 1.8.4.6 yamt return (r);
1041 1.8.4.2 yamt }
1042 1.8.4.2 yamt
1043 1.8.4.2 yamt /*
1044 1.8.4.2 yamt * To free IEEE1394 address block.
1045 1.8.4.2 yamt */
1046 1.8.4.2 yamt int
1047 1.8.4.2 yamt fw_bindremove(struct firewire_comm *fc, struct fw_bind *fwb)
1048 1.8.4.2 yamt {
1049 1.8.4.2 yamt #if 0
1050 1.8.4.2 yamt struct fw_xfer *xfer, *next;
1051 1.8.4.2 yamt #endif
1052 1.8.4.2 yamt struct fw_bind *tfw;
1053 1.8.4.2 yamt int s;
1054 1.8.4.2 yamt
1055 1.8.4.2 yamt s = splfw();
1056 1.8.4.6 yamt FW_GLOCK(fc);
1057 1.8.4.2 yamt STAILQ_FOREACH(tfw, &fc->binds, fclist)
1058 1.8.4.2 yamt if (tfw == fwb) {
1059 1.8.4.2 yamt STAILQ_REMOVE(&fc->binds, fwb, fw_bind, fclist);
1060 1.8.4.2 yamt goto found;
1061 1.8.4.2 yamt }
1062 1.8.4.2 yamt
1063 1.8.4.2 yamt printf("%s: no such binding\n", __func__);
1064 1.8.4.6 yamt FW_GUNLOCK(fc);
1065 1.8.4.2 yamt splx(s);
1066 1.8.4.2 yamt return (1);
1067 1.8.4.2 yamt found:
1068 1.8.4.2 yamt #if 0
1069 1.8.4.2 yamt /* shall we do this? */
1070 1.8.4.2 yamt for (xfer = STAILQ_FIRST(&fwb->xferlist); xfer != NULL; xfer = next) {
1071 1.8.4.2 yamt next = STAILQ_NEXT(xfer, link);
1072 1.8.4.2 yamt fw_xfer_free(xfer);
1073 1.8.4.2 yamt }
1074 1.8.4.2 yamt STAILQ_INIT(&fwb->xferlist);
1075 1.8.4.2 yamt #endif
1076 1.8.4.6 yamt FW_GUNLOCK(fc);
1077 1.8.4.2 yamt
1078 1.8.4.2 yamt splx(s);
1079 1.8.4.2 yamt return 0;
1080 1.8.4.2 yamt }
1081 1.8.4.2 yamt
1082 1.8.4.2 yamt int
1083 1.8.4.2 yamt fw_xferlist_add(struct fw_xferlist *q, struct malloc_type *type,
1084 1.8.4.2 yamt int slen, int rlen, int n,
1085 1.8.4.2 yamt struct firewire_comm *fc, void *sc, void (*hand)(struct fw_xfer *))
1086 1.8.4.2 yamt {
1087 1.8.4.2 yamt int i, s;
1088 1.8.4.2 yamt struct fw_xfer *xfer;
1089 1.8.4.2 yamt
1090 1.8.4.2 yamt for (i = 0; i < n; i++) {
1091 1.8.4.2 yamt xfer = fw_xfer_alloc_buf(type, slen, rlen);
1092 1.8.4.2 yamt if (xfer == NULL)
1093 1.8.4.2 yamt return (n);
1094 1.8.4.2 yamt xfer->fc = fc;
1095 1.8.4.2 yamt xfer->sc = sc;
1096 1.8.4.2 yamt xfer->hand = hand;
1097 1.8.4.2 yamt s = splfw();
1098 1.8.4.2 yamt STAILQ_INSERT_TAIL(q, xfer, link);
1099 1.8.4.2 yamt splx(s);
1100 1.8.4.2 yamt }
1101 1.8.4.2 yamt return (n);
1102 1.8.4.2 yamt }
1103 1.8.4.2 yamt
1104 1.8.4.2 yamt void
1105 1.8.4.2 yamt fw_xferlist_remove(struct fw_xferlist *q)
1106 1.8.4.2 yamt {
1107 1.8.4.2 yamt struct fw_xfer *xfer, *next;
1108 1.8.4.2 yamt
1109 1.8.4.2 yamt for (xfer = STAILQ_FIRST(q); xfer != NULL; xfer = next) {
1110 1.8.4.2 yamt next = STAILQ_NEXT(xfer, link);
1111 1.8.4.2 yamt fw_xfer_free_buf(xfer);
1112 1.8.4.2 yamt }
1113 1.8.4.2 yamt STAILQ_INIT(q);
1114 1.8.4.2 yamt }
1115 1.8.4.2 yamt
1116 1.8.4.2 yamt /*
1117 1.8.4.6 yamt * dump packet header
1118 1.8.4.6 yamt */
1119 1.8.4.6 yamt static void
1120 1.8.4.6 yamt fw_dump_hdr(struct fw_pkt *fp, const char *prefix)
1121 1.8.4.6 yamt {
1122 1.8.4.6 yamt printf("%s: dst=0x%02x tl=0x%02x rt=%d tcode=0x%x pri=0x%x "
1123 1.8.4.6 yamt "src=0x%03x\n", prefix,
1124 1.8.4.6 yamt fp->mode.hdr.dst & 0x3f,
1125 1.8.4.6 yamt fp->mode.hdr.tlrt >> 2, fp->mode.hdr.tlrt & 3,
1126 1.8.4.6 yamt fp->mode.hdr.tcode, fp->mode.hdr.pri,
1127 1.8.4.6 yamt fp->mode.hdr.src);
1128 1.8.4.6 yamt }
1129 1.8.4.6 yamt
1130 1.8.4.6 yamt /*
1131 1.8.4.2 yamt * To free transaction label.
1132 1.8.4.2 yamt */
1133 1.8.4.2 yamt static void
1134 1.8.4.2 yamt fw_tl_free(struct firewire_comm *fc, struct fw_xfer *xfer)
1135 1.8.4.2 yamt {
1136 1.8.4.2 yamt struct fw_xfer *txfer;
1137 1.8.4.2 yamt int s;
1138 1.8.4.2 yamt
1139 1.8.4.2 yamt if (xfer->tl < 0)
1140 1.8.4.2 yamt return;
1141 1.8.4.2 yamt
1142 1.8.4.2 yamt s = splfw();
1143 1.8.4.6 yamt fw_mtx_lock(&fc->tlabel_lock);
1144 1.8.4.2 yamt #if 1 /* make sure the label is allocated */
1145 1.8.4.2 yamt STAILQ_FOREACH(txfer, &fc->tlabels[xfer->tl], tlabel)
1146 1.8.4.2 yamt if(txfer == xfer)
1147 1.8.4.2 yamt break;
1148 1.8.4.2 yamt if (txfer == NULL) {
1149 1.8.4.6 yamt printf("%s: the xfer is not in the queue "
1150 1.8.4.6 yamt "(tlabel=%d, flag=0x%x)\n",
1151 1.8.4.7 yamt __func__, xfer->tl, xfer->flag);
1152 1.8.4.6 yamt fw_dump_hdr(&xfer->send.hdr, "send");
1153 1.8.4.6 yamt fw_dump_hdr(&xfer->recv.hdr, "recv");
1154 1.8.4.6 yamt kdb_backtrace();
1155 1.8.4.6 yamt fw_mtx_unlock(&fc->tlabel_lock);
1156 1.8.4.2 yamt splx(s);
1157 1.8.4.2 yamt return;
1158 1.8.4.2 yamt }
1159 1.8.4.2 yamt #endif
1160 1.8.4.2 yamt
1161 1.8.4.2 yamt STAILQ_REMOVE(&fc->tlabels[xfer->tl], xfer, fw_xfer, tlabel);
1162 1.8.4.6 yamt fw_mtx_unlock(&fc->tlabel_lock);
1163 1.8.4.2 yamt splx(s);
1164 1.8.4.2 yamt return;
1165 1.8.4.2 yamt }
1166 1.8.4.2 yamt
1167 1.8.4.2 yamt /*
1168 1.8.4.2 yamt * To obtain XFER structure by transaction label.
1169 1.8.4.2 yamt */
1170 1.8.4.2 yamt static struct fw_xfer *
1171 1.8.4.6 yamt fw_tl2xfer(struct firewire_comm *fc, int node, int tlabel, int tcode)
1172 1.8.4.2 yamt {
1173 1.8.4.2 yamt struct fw_xfer *xfer;
1174 1.8.4.2 yamt int s = splfw();
1175 1.8.4.6 yamt int req;
1176 1.8.4.2 yamt
1177 1.8.4.6 yamt fw_mtx_lock(&fc->tlabel_lock);
1178 1.8.4.2 yamt STAILQ_FOREACH(xfer, &fc->tlabels[tlabel], tlabel)
1179 1.8.4.2 yamt if(xfer->send.hdr.mode.hdr.dst == node) {
1180 1.8.4.6 yamt fw_mtx_unlock(&fc->tlabel_lock);
1181 1.8.4.2 yamt splx(s);
1182 1.8.4.6 yamt FW_KASSERT(xfer->tl == tlabel,
1183 1.8.4.6 yamt ("xfer->tl 0x%x != 0x%x", xfer->tl, tlabel));
1184 1.8.4.6 yamt /* extra sanity check */
1185 1.8.4.6 yamt req = xfer->send.hdr.mode.hdr.tcode;
1186 1.8.4.6 yamt if (xfer->fc->tcode[req].valid_res != tcode) {
1187 1.8.4.6 yamt printf("%s: invalid response tcode "
1188 1.8.4.7 yamt "(0x%x for 0x%x)\n", __func__,
1189 1.8.4.6 yamt tcode, req);
1190 1.8.4.6 yamt return(NULL);
1191 1.8.4.6 yamt }
1192 1.8.4.6 yamt
1193 1.8.4.2 yamt if (firewire_debug > 2)
1194 1.8.4.2 yamt printf("fw_tl2xfer: found tl=%d\n", tlabel);
1195 1.8.4.2 yamt return(xfer);
1196 1.8.4.2 yamt }
1197 1.8.4.6 yamt fw_mtx_unlock(&fc->tlabel_lock);
1198 1.8.4.2 yamt if (firewire_debug > 1)
1199 1.8.4.2 yamt printf("fw_tl2xfer: not found tl=%d\n", tlabel);
1200 1.8.4.2 yamt splx(s);
1201 1.8.4.2 yamt return(NULL);
1202 1.8.4.2 yamt }
1203 1.8.4.2 yamt
1204 1.8.4.2 yamt /*
1205 1.8.4.2 yamt * To allocate IEEE1394 XFER structure.
1206 1.8.4.2 yamt */
1207 1.8.4.2 yamt struct fw_xfer *
1208 1.8.4.2 yamt fw_xfer_alloc(struct malloc_type *type)
1209 1.8.4.2 yamt {
1210 1.8.4.2 yamt struct fw_xfer *xfer;
1211 1.8.4.2 yamt
1212 1.8.4.2 yamt xfer = malloc(sizeof(struct fw_xfer), type, M_NOWAIT | M_ZERO);
1213 1.8.4.2 yamt if (xfer == NULL)
1214 1.8.4.2 yamt return xfer;
1215 1.8.4.2 yamt
1216 1.8.4.2 yamt xfer->malloc = type;
1217 1.8.4.2 yamt
1218 1.8.4.2 yamt return xfer;
1219 1.8.4.2 yamt }
1220 1.8.4.2 yamt
1221 1.8.4.2 yamt struct fw_xfer *
1222 1.8.4.2 yamt fw_xfer_alloc_buf(struct malloc_type *type, int send_len, int recv_len)
1223 1.8.4.2 yamt {
1224 1.8.4.2 yamt struct fw_xfer *xfer;
1225 1.8.4.2 yamt
1226 1.8.4.2 yamt xfer = fw_xfer_alloc(type);
1227 1.8.4.2 yamt if (xfer == NULL)
1228 1.8.4.2 yamt return(NULL);
1229 1.8.4.2 yamt xfer->send.pay_len = send_len;
1230 1.8.4.2 yamt xfer->recv.pay_len = recv_len;
1231 1.8.4.2 yamt if (send_len > 0) {
1232 1.8.4.2 yamt xfer->send.payload = malloc(send_len, type, M_NOWAIT | M_ZERO);
1233 1.8.4.2 yamt if (xfer->send.payload == NULL) {
1234 1.8.4.2 yamt fw_xfer_free(xfer);
1235 1.8.4.2 yamt return(NULL);
1236 1.8.4.2 yamt }
1237 1.8.4.2 yamt }
1238 1.8.4.2 yamt if (recv_len > 0) {
1239 1.8.4.2 yamt xfer->recv.payload = malloc(recv_len, type, M_NOWAIT);
1240 1.8.4.2 yamt if (xfer->recv.payload == NULL) {
1241 1.8.4.2 yamt if (xfer->send.payload != NULL)
1242 1.8.4.2 yamt free(xfer->send.payload, type);
1243 1.8.4.2 yamt fw_xfer_free(xfer);
1244 1.8.4.2 yamt return(NULL);
1245 1.8.4.2 yamt }
1246 1.8.4.2 yamt }
1247 1.8.4.2 yamt return(xfer);
1248 1.8.4.2 yamt }
1249 1.8.4.2 yamt
1250 1.8.4.2 yamt /*
1251 1.8.4.2 yamt * IEEE1394 XFER post process.
1252 1.8.4.2 yamt */
1253 1.8.4.2 yamt void
1254 1.8.4.2 yamt fw_xfer_done(struct fw_xfer *xfer)
1255 1.8.4.2 yamt {
1256 1.8.4.2 yamt if (xfer->hand == NULL) {
1257 1.8.4.2 yamt printf("hand == NULL\n");
1258 1.8.4.2 yamt return;
1259 1.8.4.2 yamt }
1260 1.8.4.2 yamt
1261 1.8.4.2 yamt if (xfer->fc == NULL)
1262 1.8.4.2 yamt panic("fw_xfer_done: why xfer->fc is NULL?");
1263 1.8.4.2 yamt
1264 1.8.4.2 yamt fw_tl_free(xfer->fc, xfer);
1265 1.8.4.2 yamt xfer->hand(xfer);
1266 1.8.4.2 yamt }
1267 1.8.4.2 yamt
1268 1.8.4.2 yamt void
1269 1.8.4.2 yamt fw_xfer_unload(struct fw_xfer* xfer)
1270 1.8.4.2 yamt {
1271 1.8.4.2 yamt int s;
1272 1.8.4.2 yamt
1273 1.8.4.2 yamt if(xfer == NULL ) return;
1274 1.8.4.6 yamt if(xfer->flag & FWXF_INQ){
1275 1.8.4.2 yamt printf("fw_xfer_free FWXF_INQ\n");
1276 1.8.4.2 yamt s = splfw();
1277 1.8.4.6 yamt FW_GLOCK(xfer->fc);
1278 1.8.4.2 yamt STAILQ_REMOVE(&xfer->q->q, xfer, fw_xfer, link);
1279 1.8.4.6 yamt #if 0
1280 1.8.4.2 yamt xfer->q->queued --;
1281 1.8.4.6 yamt #endif
1282 1.8.4.6 yamt FW_GUNLOCK(xfer->fc);
1283 1.8.4.2 yamt splx(s);
1284 1.8.4.2 yamt }
1285 1.8.4.2 yamt if (xfer->fc != NULL) {
1286 1.8.4.2 yamt #if 1
1287 1.8.4.6 yamt if(xfer->flag == FWXF_START)
1288 1.8.4.2 yamt /*
1289 1.8.4.2 yamt * This could happen if:
1290 1.8.4.2 yamt * 1. We call fwohci_arcv() before fwohci_txd().
1291 1.8.4.2 yamt * 2. firewire_watch() is called.
1292 1.8.4.2 yamt */
1293 1.8.4.2 yamt printf("fw_xfer_free FWXF_START\n");
1294 1.8.4.2 yamt #endif
1295 1.8.4.2 yamt }
1296 1.8.4.6 yamt xfer->flag = FWXF_INIT;
1297 1.8.4.2 yamt xfer->resp = 0;
1298 1.8.4.2 yamt }
1299 1.8.4.2 yamt /*
1300 1.8.4.2 yamt * To free IEEE1394 XFER structure.
1301 1.8.4.2 yamt */
1302 1.8.4.2 yamt void
1303 1.8.4.2 yamt fw_xfer_free_buf( struct fw_xfer* xfer)
1304 1.8.4.2 yamt {
1305 1.8.4.2 yamt if (xfer == NULL) {
1306 1.8.4.2 yamt printf("%s: xfer == NULL\n", __func__);
1307 1.8.4.2 yamt return;
1308 1.8.4.2 yamt }
1309 1.8.4.2 yamt fw_xfer_unload(xfer);
1310 1.8.4.2 yamt if(xfer->send.payload != NULL){
1311 1.8.4.2 yamt free(xfer->send.payload, xfer->malloc);
1312 1.8.4.2 yamt }
1313 1.8.4.2 yamt if(xfer->recv.payload != NULL){
1314 1.8.4.2 yamt free(xfer->recv.payload, xfer->malloc);
1315 1.8.4.2 yamt }
1316 1.8.4.2 yamt free(xfer, xfer->malloc);
1317 1.8.4.2 yamt }
1318 1.8.4.2 yamt
1319 1.8.4.2 yamt void
1320 1.8.4.2 yamt fw_xfer_free( struct fw_xfer* xfer)
1321 1.8.4.2 yamt {
1322 1.8.4.2 yamt if (xfer == NULL) {
1323 1.8.4.2 yamt printf("%s: xfer == NULL\n", __func__);
1324 1.8.4.2 yamt return;
1325 1.8.4.2 yamt }
1326 1.8.4.2 yamt fw_xfer_unload(xfer);
1327 1.8.4.2 yamt free(xfer, xfer->malloc);
1328 1.8.4.2 yamt }
1329 1.8.4.2 yamt
1330 1.8.4.2 yamt void
1331 1.8.4.2 yamt fw_asy_callback_free(struct fw_xfer *xfer)
1332 1.8.4.2 yamt {
1333 1.8.4.2 yamt #if 0
1334 1.8.4.6 yamt printf("asyreq done flag=%d resp=%d\n",
1335 1.8.4.6 yamt xfer->flag, xfer->resp);
1336 1.8.4.2 yamt #endif
1337 1.8.4.2 yamt fw_xfer_free(xfer);
1338 1.8.4.2 yamt }
1339 1.8.4.2 yamt
1340 1.8.4.2 yamt /*
1341 1.8.4.2 yamt * To configure PHY.
1342 1.8.4.2 yamt */
1343 1.8.4.2 yamt static void
1344 1.8.4.2 yamt fw_phy_config(struct firewire_comm *fc, int root_node, int gap_count)
1345 1.8.4.2 yamt {
1346 1.8.4.2 yamt struct fw_xfer *xfer;
1347 1.8.4.2 yamt struct fw_pkt *fp;
1348 1.8.4.2 yamt
1349 1.8.4.2 yamt fc->status = FWBUSPHYCONF;
1350 1.8.4.2 yamt
1351 1.8.4.2 yamt xfer = fw_xfer_alloc(M_FWXFER);
1352 1.8.4.2 yamt if (xfer == NULL)
1353 1.8.4.2 yamt return;
1354 1.8.4.2 yamt xfer->fc = fc;
1355 1.8.4.2 yamt xfer->hand = fw_asy_callback_free;
1356 1.8.4.2 yamt
1357 1.8.4.2 yamt fp = &xfer->send.hdr;
1358 1.8.4.2 yamt fp->mode.ld[1] = 0;
1359 1.8.4.2 yamt if (root_node >= 0)
1360 1.8.4.2 yamt fp->mode.ld[1] |= (root_node & 0x3f) << 24 | 1 << 23;
1361 1.8.4.2 yamt if (gap_count >= 0)
1362 1.8.4.2 yamt fp->mode.ld[1] |= 1 << 22 | (gap_count & 0x3f) << 16;
1363 1.8.4.2 yamt fp->mode.ld[2] = ~fp->mode.ld[1];
1364 1.8.4.2 yamt /* XXX Dangerous, how to pass PHY packet to device driver */
1365 1.8.4.2 yamt fp->mode.common.tcode |= FWTCODE_PHY;
1366 1.8.4.2 yamt
1367 1.8.4.2 yamt if (firewire_debug)
1368 1.8.4.2 yamt printf("send phy_config root_node=%d gap_count=%d\n",
1369 1.8.4.2 yamt root_node, gap_count);
1370 1.8.4.2 yamt fw_asyreq(fc, -1, xfer);
1371 1.8.4.2 yamt }
1372 1.8.4.2 yamt
1373 1.8.4.2 yamt #if 0
1374 1.8.4.2 yamt /*
1375 1.8.4.2 yamt * Dump self ID.
1376 1.8.4.2 yamt */
1377 1.8.4.2 yamt static void
1378 1.8.4.2 yamt fw_print_sid(uint32_t sid)
1379 1.8.4.2 yamt {
1380 1.8.4.2 yamt union fw_self_id *s;
1381 1.8.4.2 yamt s = (union fw_self_id *) &sid;
1382 1.8.4.2 yamt printf("node:%d link:%d gap:%d spd:%d del:%d con:%d pwr:%d"
1383 1.8.4.2 yamt " p0:%d p1:%d p2:%d i:%d m:%d\n",
1384 1.8.4.2 yamt s->p0.phy_id, s->p0.link_active, s->p0.gap_count,
1385 1.8.4.2 yamt s->p0.phy_speed, s->p0.phy_delay, s->p0.contender,
1386 1.8.4.2 yamt s->p0.power_class, s->p0.port0, s->p0.port1,
1387 1.8.4.2 yamt s->p0.port2, s->p0.initiated_reset, s->p0.more_packets);
1388 1.8.4.2 yamt }
1389 1.8.4.2 yamt #endif
1390 1.8.4.2 yamt
1391 1.8.4.2 yamt /*
1392 1.8.4.2 yamt * To receive self ID.
1393 1.8.4.2 yamt */
1394 1.8.4.2 yamt void fw_sidrcv(struct firewire_comm* fc, uint32_t *sid, u_int len)
1395 1.8.4.2 yamt {
1396 1.8.4.2 yamt uint32_t *p;
1397 1.8.4.2 yamt union fw_self_id *self_id;
1398 1.8.4.2 yamt u_int i, j, node, c_port = 0, i_branch = 0;
1399 1.8.4.2 yamt
1400 1.8.4.2 yamt fc->sid_cnt = len /(sizeof(uint32_t) * 2);
1401 1.8.4.2 yamt fc->max_node = fc->nodeid & 0x3f;
1402 1.8.4.2 yamt CSRARC(fc, NODE_IDS) = ((uint32_t)fc->nodeid) << 16;
1403 1.8.4.2 yamt fc->status = FWBUSCYMELECT;
1404 1.8.4.2 yamt fc->topology_map->crc_len = 2;
1405 1.8.4.2 yamt fc->topology_map->generation ++;
1406 1.8.4.2 yamt fc->topology_map->self_id_count = 0;
1407 1.8.4.2 yamt fc->topology_map->node_count = 0;
1408 1.8.4.2 yamt fc->speed_map->generation ++;
1409 1.8.4.2 yamt fc->speed_map->crc_len = 1 + (64*64 + 3) / 4;
1410 1.8.4.2 yamt self_id = &fc->topology_map->self_id[0];
1411 1.8.4.2 yamt for(i = 0; i < fc->sid_cnt; i ++){
1412 1.8.4.2 yamt if (sid[1] != ~sid[0]) {
1413 1.8.4.2 yamt printf("fw_sidrcv: invalid self-id packet\n");
1414 1.8.4.2 yamt sid += 2;
1415 1.8.4.2 yamt continue;
1416 1.8.4.2 yamt }
1417 1.8.4.2 yamt *self_id = *((union fw_self_id *)sid);
1418 1.8.4.2 yamt fc->topology_map->crc_len++;
1419 1.8.4.2 yamt if(self_id->p0.sequel == 0){
1420 1.8.4.2 yamt fc->topology_map->node_count ++;
1421 1.8.4.2 yamt c_port = 0;
1422 1.8.4.2 yamt #if 0
1423 1.8.4.2 yamt fw_print_sid(sid[0]);
1424 1.8.4.2 yamt #endif
1425 1.8.4.2 yamt node = self_id->p0.phy_id;
1426 1.8.4.2 yamt if(fc->max_node < node){
1427 1.8.4.2 yamt fc->max_node = self_id->p0.phy_id;
1428 1.8.4.2 yamt }
1429 1.8.4.2 yamt /* XXX I'm not sure this is the right speed_map */
1430 1.8.4.2 yamt fc->speed_map->speed[node][node]
1431 1.8.4.2 yamt = self_id->p0.phy_speed;
1432 1.8.4.2 yamt for (j = 0; j < node; j ++) {
1433 1.8.4.2 yamt fc->speed_map->speed[j][node]
1434 1.8.4.2 yamt = fc->speed_map->speed[node][j]
1435 1.8.4.2 yamt = min(fc->speed_map->speed[j][j],
1436 1.8.4.2 yamt self_id->p0.phy_speed);
1437 1.8.4.2 yamt }
1438 1.8.4.2 yamt if ((fc->irm == -1 || self_id->p0.phy_id > fc->irm) &&
1439 1.8.4.2 yamt (self_id->p0.link_active && self_id->p0.contender)) {
1440 1.8.4.2 yamt fc->irm = self_id->p0.phy_id;
1441 1.8.4.2 yamt }
1442 1.8.4.2 yamt if(self_id->p0.port0 >= 0x2){
1443 1.8.4.2 yamt c_port++;
1444 1.8.4.2 yamt }
1445 1.8.4.2 yamt if(self_id->p0.port1 >= 0x2){
1446 1.8.4.2 yamt c_port++;
1447 1.8.4.2 yamt }
1448 1.8.4.2 yamt if(self_id->p0.port2 >= 0x2){
1449 1.8.4.2 yamt c_port++;
1450 1.8.4.2 yamt }
1451 1.8.4.2 yamt }
1452 1.8.4.2 yamt if(c_port > 2){
1453 1.8.4.2 yamt i_branch += (c_port - 2);
1454 1.8.4.2 yamt }
1455 1.8.4.2 yamt sid += 2;
1456 1.8.4.2 yamt self_id++;
1457 1.8.4.2 yamt fc->topology_map->self_id_count ++;
1458 1.8.4.2 yamt }
1459 1.8.4.6 yamt fw_printf(fc->bdev, "%d nodes", fc->max_node + 1);
1460 1.8.4.2 yamt /* CRC */
1461 1.8.4.2 yamt fc->topology_map->crc = fw_crc16(
1462 1.8.4.2 yamt (uint32_t *)&fc->topology_map->generation,
1463 1.8.4.2 yamt fc->topology_map->crc_len * 4);
1464 1.8.4.2 yamt fc->speed_map->crc = fw_crc16(
1465 1.8.4.2 yamt (uint32_t *)&fc->speed_map->generation,
1466 1.8.4.2 yamt fc->speed_map->crc_len * 4);
1467 1.8.4.2 yamt /* byteswap and copy to CSR */
1468 1.8.4.2 yamt p = (uint32_t *)fc->topology_map;
1469 1.8.4.2 yamt for (i = 0; i <= fc->topology_map->crc_len; i++)
1470 1.8.4.2 yamt CSRARC(fc, TOPO_MAP + i * 4) = htonl(*p++);
1471 1.8.4.2 yamt p = (uint32_t *)fc->speed_map;
1472 1.8.4.2 yamt CSRARC(fc, SPED_MAP) = htonl(*p++);
1473 1.8.4.2 yamt CSRARC(fc, SPED_MAP + 4) = htonl(*p++);
1474 1.8.4.2 yamt /* don't byte-swap uint8_t array */
1475 1.8.4.2 yamt bcopy(p, &CSRARC(fc, SPED_MAP + 8), (fc->speed_map->crc_len - 1)*4);
1476 1.8.4.2 yamt
1477 1.8.4.2 yamt fc->max_hop = fc->max_node - i_branch;
1478 1.8.4.2 yamt printf(", maxhop <= %d", fc->max_hop);
1479 1.8.4.2 yamt
1480 1.8.4.2 yamt if(fc->irm == -1 ){
1481 1.8.4.2 yamt printf(", Not found IRM capable node");
1482 1.8.4.2 yamt }else{
1483 1.8.4.2 yamt printf(", cable IRM = %d", fc->irm);
1484 1.8.4.2 yamt if (fc->irm == fc->nodeid)
1485 1.8.4.2 yamt printf(" (me)");
1486 1.8.4.2 yamt }
1487 1.8.4.2 yamt printf("\n");
1488 1.8.4.2 yamt
1489 1.8.4.2 yamt if (try_bmr && (fc->irm != -1) && (CSRARC(fc, BUS_MGR_ID) == 0x3f)) {
1490 1.8.4.2 yamt if (fc->irm == fc->nodeid) {
1491 1.8.4.2 yamt fc->status = FWBUSMGRDONE;
1492 1.8.4.2 yamt CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, fc->irm);
1493 1.8.4.2 yamt fw_bmr(fc);
1494 1.8.4.2 yamt } else {
1495 1.8.4.2 yamt fc->status = FWBUSMGRELECT;
1496 1.8.4.6 yamt fw_callout_reset(&fc->bmr_callout, hz/8,
1497 1.8.4.2 yamt (void *)fw_try_bmr, (void *)fc);
1498 1.8.4.2 yamt }
1499 1.8.4.2 yamt } else
1500 1.8.4.2 yamt fc->status = FWBUSMGRDONE;
1501 1.8.4.2 yamt
1502 1.8.4.6 yamt fw_callout_reset(&fc->busprobe_callout, hz/4,
1503 1.8.4.2 yamt (void *)fw_bus_probe, (void *)fc);
1504 1.8.4.2 yamt }
1505 1.8.4.2 yamt
1506 1.8.4.2 yamt /*
1507 1.8.4.2 yamt * To probe devices on the IEEE1394 bus.
1508 1.8.4.2 yamt */
1509 1.8.4.2 yamt static void
1510 1.8.4.2 yamt fw_bus_probe(struct firewire_comm *fc)
1511 1.8.4.2 yamt {
1512 1.8.4.2 yamt int s;
1513 1.8.4.2 yamt struct fw_device *fwdev;
1514 1.8.4.2 yamt
1515 1.8.4.2 yamt s = splfw();
1516 1.8.4.2 yamt fc->status = FWBUSEXPLORE;
1517 1.8.4.2 yamt
1518 1.8.4.2 yamt /* Invalidate all devices, just after bus reset. */
1519 1.8.4.2 yamt STAILQ_FOREACH(fwdev, &fc->devices, link)
1520 1.8.4.2 yamt if (fwdev->status != FWDEVINVAL) {
1521 1.8.4.2 yamt fwdev->status = FWDEVINVAL;
1522 1.8.4.2 yamt fwdev->rcnt = 0;
1523 1.8.4.2 yamt }
1524 1.8.4.2 yamt splx(s);
1525 1.8.4.2 yamt
1526 1.8.4.2 yamt wakeup((void *)fc);
1527 1.8.4.2 yamt }
1528 1.8.4.2 yamt
1529 1.8.4.2 yamt static int
1530 1.8.4.2 yamt fw_explore_read_quads(struct fw_device *fwdev, int offset,
1531 1.8.4.2 yamt uint32_t *quad, int n)
1532 1.8.4.2 yamt {
1533 1.8.4.2 yamt struct fw_xfer *xfer;
1534 1.8.4.2 yamt uint32_t tmp;
1535 1.8.4.2 yamt int i, error;
1536 1.8.4.2 yamt
1537 1.8.4.2 yamt
1538 1.8.4.2 yamt for (i = 0; i < n; i ++, offset += sizeof(uint32_t)) {
1539 1.8.4.2 yamt xfer = fwmem_read_quad(fwdev, NULL, -1,
1540 1.8.4.2 yamt 0xffff, 0xf0000000 | offset, (void *)&tmp,
1541 1.8.4.6 yamt fw_xferwake);
1542 1.8.4.2 yamt if (xfer == NULL)
1543 1.8.4.2 yamt return (-1);
1544 1.8.4.6 yamt fw_xferwait(xfer);
1545 1.8.4.2 yamt
1546 1.8.4.2 yamt if (xfer->resp == 0)
1547 1.8.4.2 yamt quad[i] = ntohl(tmp);
1548 1.8.4.2 yamt
1549 1.8.4.2 yamt error = xfer->resp;
1550 1.8.4.2 yamt fw_xfer_free(xfer);
1551 1.8.4.2 yamt if (error)
1552 1.8.4.2 yamt return (error);
1553 1.8.4.2 yamt }
1554 1.8.4.2 yamt return (0);
1555 1.8.4.2 yamt }
1556 1.8.4.2 yamt
1557 1.8.4.2 yamt
1558 1.8.4.2 yamt static int
1559 1.8.4.2 yamt fw_explore_csrblock(struct fw_device *fwdev, int offset, int recur)
1560 1.8.4.2 yamt {
1561 1.8.4.2 yamt int err, i, off;
1562 1.8.4.2 yamt struct csrdirectory *dir;
1563 1.8.4.2 yamt struct csrreg *reg;
1564 1.8.4.2 yamt
1565 1.8.4.2 yamt
1566 1.8.4.2 yamt dir = (struct csrdirectory *)&fwdev->csrrom[offset/sizeof(uint32_t)];
1567 1.8.4.2 yamt err = fw_explore_read_quads(fwdev, CSRROMOFF + offset,
1568 1.8.4.2 yamt (uint32_t *)dir, 1);
1569 1.8.4.2 yamt if (err)
1570 1.8.4.2 yamt return (-1);
1571 1.8.4.2 yamt
1572 1.8.4.2 yamt offset += sizeof(uint32_t);
1573 1.8.4.2 yamt reg = (struct csrreg *)&fwdev->csrrom[offset/sizeof(uint32_t)];
1574 1.8.4.2 yamt err = fw_explore_read_quads(fwdev, CSRROMOFF + offset,
1575 1.8.4.2 yamt (uint32_t *)reg, dir->crc_len);
1576 1.8.4.2 yamt if (err)
1577 1.8.4.2 yamt return (-1);
1578 1.8.4.2 yamt
1579 1.8.4.2 yamt /* XXX check CRC */
1580 1.8.4.2 yamt
1581 1.8.4.2 yamt off = CSRROMOFF + offset + sizeof(uint32_t) * (dir->crc_len - 1);
1582 1.8.4.2 yamt if (fwdev->rommax < off)
1583 1.8.4.2 yamt fwdev->rommax = off;
1584 1.8.4.2 yamt
1585 1.8.4.2 yamt if (recur == 0)
1586 1.8.4.2 yamt return (0);
1587 1.8.4.2 yamt
1588 1.8.4.2 yamt for (i = 0; i < dir->crc_len; i ++, offset += sizeof(uint32_t)) {
1589 1.8.4.6 yamt if ((reg[i].key & CSRTYPE_MASK) == CSRTYPE_D)
1590 1.8.4.2 yamt recur = 1;
1591 1.8.4.6 yamt else if ((reg[i].key & CSRTYPE_MASK) == CSRTYPE_L)
1592 1.8.4.2 yamt recur = 0;
1593 1.8.4.2 yamt else
1594 1.8.4.2 yamt continue;
1595 1.8.4.2 yamt
1596 1.8.4.2 yamt off = offset + reg[i].val * sizeof(uint32_t);
1597 1.8.4.2 yamt if (off > CROMSIZE) {
1598 1.8.4.7 yamt printf("%s: invalid offset %d\n", __func__, off);
1599 1.8.4.2 yamt return(-1);
1600 1.8.4.2 yamt }
1601 1.8.4.2 yamt err = fw_explore_csrblock(fwdev, off, recur);
1602 1.8.4.2 yamt if (err)
1603 1.8.4.2 yamt return (-1);
1604 1.8.4.2 yamt }
1605 1.8.4.2 yamt return (0);
1606 1.8.4.2 yamt }
1607 1.8.4.2 yamt
1608 1.8.4.2 yamt static int
1609 1.8.4.2 yamt fw_explore_node(struct fw_device *dfwdev)
1610 1.8.4.2 yamt {
1611 1.8.4.2 yamt struct firewire_comm *fc;
1612 1.8.4.2 yamt struct fw_device *fwdev, *pfwdev, *tfwdev;
1613 1.8.4.2 yamt uint32_t *csr;
1614 1.8.4.2 yamt struct csrhdr *hdr;
1615 1.8.4.2 yamt struct bus_info *binfo;
1616 1.8.4.2 yamt int err, node, spd;
1617 1.8.4.2 yamt
1618 1.8.4.2 yamt fc = dfwdev->fc;
1619 1.8.4.2 yamt csr = dfwdev->csrrom;
1620 1.8.4.2 yamt node = dfwdev->dst;
1621 1.8.4.2 yamt
1622 1.8.4.2 yamt /* First quad */
1623 1.8.4.2 yamt err = fw_explore_read_quads(dfwdev, CSRROMOFF, &csr[0], 1);
1624 1.8.4.2 yamt if (err)
1625 1.8.4.2 yamt return (-1);
1626 1.8.4.2 yamt hdr = (struct csrhdr *)&csr[0];
1627 1.8.4.2 yamt if (hdr->info_len != 4) {
1628 1.8.4.2 yamt if (firewire_debug)
1629 1.8.4.2 yamt printf("node%d: wrong bus info len(%d)\n",
1630 1.8.4.2 yamt node, hdr->info_len);
1631 1.8.4.2 yamt return (-1);
1632 1.8.4.2 yamt }
1633 1.8.4.2 yamt
1634 1.8.4.2 yamt /* bus info */
1635 1.8.4.2 yamt err = fw_explore_read_quads(dfwdev, CSRROMOFF + 0x04, &csr[1], 4);
1636 1.8.4.2 yamt if (err)
1637 1.8.4.2 yamt return (-1);
1638 1.8.4.2 yamt binfo = (struct bus_info *)&csr[1];
1639 1.8.4.2 yamt if (binfo->bus_name != CSR_BUS_NAME_IEEE1394) {
1640 1.8.4.2 yamt if (firewire_debug)
1641 1.8.4.2 yamt printf("node%d: invalid bus name 0x%08x\n",
1642 1.8.4.2 yamt node, binfo->bus_name);
1643 1.8.4.2 yamt return (-1);
1644 1.8.4.2 yamt }
1645 1.8.4.2 yamt spd = fc->speed_map->speed[fc->nodeid][node];
1646 1.8.4.2 yamt STAILQ_FOREACH(fwdev, &fc->devices, link)
1647 1.8.4.2 yamt if (FW_EUI64_EQUAL(fwdev->eui, binfo->eui64))
1648 1.8.4.2 yamt break;
1649 1.8.4.2 yamt if (fwdev == NULL) {
1650 1.8.4.2 yamt /* new device */
1651 1.8.4.2 yamt fwdev = malloc(sizeof(struct fw_device), M_FW,
1652 1.8.4.2 yamt M_NOWAIT | M_ZERO);
1653 1.8.4.2 yamt if (fwdev == NULL) {
1654 1.8.4.2 yamt if (firewire_debug)
1655 1.8.4.2 yamt printf("node%d: no memory\n", node);
1656 1.8.4.2 yamt return (-1);
1657 1.8.4.2 yamt }
1658 1.8.4.2 yamt fwdev->fc = fc;
1659 1.8.4.2 yamt fwdev->eui = binfo->eui64;
1660 1.8.4.2 yamt fwdev->status = FWDEVNEW;
1661 1.8.4.2 yamt /* insert into sorted fwdev list */
1662 1.8.4.2 yamt pfwdev = NULL;
1663 1.8.4.2 yamt STAILQ_FOREACH(tfwdev, &fc->devices, link) {
1664 1.8.4.2 yamt if (tfwdev->eui.hi > fwdev->eui.hi ||
1665 1.8.4.2 yamt (tfwdev->eui.hi == fwdev->eui.hi &&
1666 1.8.4.2 yamt tfwdev->eui.lo > fwdev->eui.lo))
1667 1.8.4.2 yamt break;
1668 1.8.4.2 yamt pfwdev = tfwdev;
1669 1.8.4.2 yamt }
1670 1.8.4.2 yamt if (pfwdev == NULL)
1671 1.8.4.2 yamt STAILQ_INSERT_HEAD(&fc->devices, fwdev, link);
1672 1.8.4.2 yamt else
1673 1.8.4.2 yamt STAILQ_INSERT_AFTER(&fc->devices, pfwdev, fwdev, link);
1674 1.8.4.2 yamt
1675 1.8.4.6 yamt fw_printf(fc->bdev, "New %s device ID:%08x%08x\n",
1676 1.8.4.2 yamt fw_linkspeed[spd],
1677 1.8.4.2 yamt fwdev->eui.hi, fwdev->eui.lo);
1678 1.8.4.2 yamt
1679 1.8.4.2 yamt } else
1680 1.8.4.2 yamt fwdev->status = FWDEVINIT;
1681 1.8.4.2 yamt fwdev->dst = node;
1682 1.8.4.2 yamt fwdev->speed = spd;
1683 1.8.4.2 yamt
1684 1.8.4.2 yamt /* unchanged ? */
1685 1.8.4.2 yamt if (bcmp(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5) == 0) {
1686 1.8.4.2 yamt if (firewire_debug)
1687 1.8.4.2 yamt printf("node%d: crom unchanged\n", node);
1688 1.8.4.2 yamt return (0);
1689 1.8.4.2 yamt }
1690 1.8.4.2 yamt
1691 1.8.4.2 yamt bzero(&fwdev->csrrom[0], CROMSIZE);
1692 1.8.4.2 yamt
1693 1.8.4.2 yamt /* copy first quad and bus info block */
1694 1.8.4.2 yamt bcopy(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5);
1695 1.8.4.2 yamt fwdev->rommax = CSRROMOFF + sizeof(uint32_t) * 4;
1696 1.8.4.2 yamt
1697 1.8.4.2 yamt err = fw_explore_csrblock(fwdev, 0x14, 1); /* root directory */
1698 1.8.4.2 yamt
1699 1.8.4.2 yamt if (err) {
1700 1.8.4.2 yamt fwdev->status = FWDEVINVAL;
1701 1.8.4.2 yamt fwdev->csrrom[0] = 0;
1702 1.8.4.2 yamt }
1703 1.8.4.2 yamt return (err);
1704 1.8.4.2 yamt
1705 1.8.4.2 yamt }
1706 1.8.4.2 yamt
1707 1.8.4.2 yamt /*
1708 1.8.4.2 yamt * Find the self_id packet for a node, ignoring sequels.
1709 1.8.4.2 yamt */
1710 1.8.4.2 yamt static union fw_self_id *
1711 1.8.4.2 yamt fw_find_self_id(struct firewire_comm *fc, int node)
1712 1.8.4.2 yamt {
1713 1.8.4.2 yamt uint32_t i;
1714 1.8.4.2 yamt union fw_self_id *s;
1715 1.8.4.2 yamt
1716 1.8.4.2 yamt for (i = 0; i < fc->topology_map->self_id_count; i++) {
1717 1.8.4.2 yamt s = &fc->topology_map->self_id[i];
1718 1.8.4.2 yamt if (s->p0.sequel)
1719 1.8.4.2 yamt continue;
1720 1.8.4.2 yamt if (s->p0.phy_id == node)
1721 1.8.4.2 yamt return s;
1722 1.8.4.2 yamt }
1723 1.8.4.2 yamt return 0;
1724 1.8.4.2 yamt }
1725 1.8.4.2 yamt
1726 1.8.4.2 yamt static void
1727 1.8.4.2 yamt fw_explore(struct firewire_comm *fc)
1728 1.8.4.2 yamt {
1729 1.8.4.2 yamt int node, err, s, i, todo, todo2, trys;
1730 1.8.4.2 yamt char nodes[63];
1731 1.8.4.2 yamt struct fw_device *dfwdev;
1732 1.8.4.6 yamt union fw_self_id *fwsid;
1733 1.8.4.2 yamt
1734 1.8.4.2 yamt todo = 0;
1735 1.8.4.2 yamt dfwdev = malloc(sizeof(*dfwdev), M_TEMP, M_NOWAIT);
1736 1.8.4.2 yamt if (dfwdev == NULL)
1737 1.8.4.2 yamt return;
1738 1.8.4.2 yamt /* setup dummy fwdev */
1739 1.8.4.2 yamt dfwdev->fc = fc;
1740 1.8.4.2 yamt dfwdev->speed = 0;
1741 1.8.4.2 yamt dfwdev->maxrec = 8; /* 512 */
1742 1.8.4.2 yamt dfwdev->status = FWDEVINIT;
1743 1.8.4.2 yamt
1744 1.8.4.2 yamt for (node = 0; node <= fc->max_node; node ++) {
1745 1.8.4.2 yamt /* We don't probe myself and linkdown nodes */
1746 1.8.4.2 yamt if (node == fc->nodeid)
1747 1.8.4.2 yamt continue;
1748 1.8.4.6 yamt fwsid = fw_find_self_id(fc, node);
1749 1.8.4.6 yamt if (!fwsid || !fwsid->p0.link_active) {
1750 1.8.4.2 yamt if (firewire_debug)
1751 1.8.4.2 yamt printf("node%d: link down\n", node);
1752 1.8.4.2 yamt continue;
1753 1.8.4.2 yamt }
1754 1.8.4.2 yamt nodes[todo++] = node;
1755 1.8.4.2 yamt }
1756 1.8.4.2 yamt
1757 1.8.4.2 yamt s = splfw();
1758 1.8.4.2 yamt for (trys = 0; todo > 0 && trys < 3; trys ++) {
1759 1.8.4.2 yamt todo2 = 0;
1760 1.8.4.2 yamt for (i = 0; i < todo; i ++) {
1761 1.8.4.2 yamt dfwdev->dst = nodes[i];
1762 1.8.4.2 yamt err = fw_explore_node(dfwdev);
1763 1.8.4.2 yamt if (err)
1764 1.8.4.2 yamt nodes[todo2++] = nodes[i];
1765 1.8.4.2 yamt if (firewire_debug)
1766 1.8.4.2 yamt printf("%s: node %d, err = %d\n",
1767 1.8.4.7 yamt __func__, node, err);
1768 1.8.4.2 yamt }
1769 1.8.4.2 yamt todo = todo2;
1770 1.8.4.2 yamt }
1771 1.8.4.2 yamt splx(s);
1772 1.8.4.2 yamt free(dfwdev, M_TEMP);
1773 1.8.4.2 yamt }
1774 1.8.4.2 yamt
1775 1.8.4.2 yamt static void
1776 1.8.4.2 yamt fw_bus_probe_thread(void *arg)
1777 1.8.4.2 yamt {
1778 1.8.4.2 yamt struct firewire_comm *fc;
1779 1.8.4.2 yamt
1780 1.8.4.2 yamt fc = (struct firewire_comm *)arg;
1781 1.8.4.2 yamt
1782 1.8.4.6 yamt fw_config_pending_decr();
1783 1.8.4.2 yamt
1784 1.8.4.6 yamt fw_mtx_lock(&fc->wait_lock);
1785 1.8.4.6 yamt while (fc->status != FWBUSDETACH) {
1786 1.8.4.2 yamt if (fc->status == FWBUSEXPLORE) {
1787 1.8.4.6 yamt fw_mtx_unlock(&fc->wait_lock);
1788 1.8.4.2 yamt fw_explore(fc);
1789 1.8.4.2 yamt fc->status = FWBUSEXPDONE;
1790 1.8.4.2 yamt if (firewire_debug)
1791 1.8.4.2 yamt printf("bus_explore done\n");
1792 1.8.4.2 yamt fw_attach_dev(fc);
1793 1.8.4.6 yamt fw_mtx_lock(&fc->wait_lock);
1794 1.8.4.6 yamt }
1795 1.8.4.6 yamt fw_msleep((void *)fc, &fc->wait_lock, PWAIT|PCATCH, "-", 0);
1796 1.8.4.2 yamt }
1797 1.8.4.6 yamt fw_mtx_unlock(&fc->wait_lock);
1798 1.8.4.6 yamt fw_kthread_exit(0);
1799 1.8.4.2 yamt }
1800 1.8.4.2 yamt
1801 1.8.4.2 yamt
1802 1.8.4.2 yamt /*
1803 1.8.4.2 yamt * To attach sub-devices layer onto IEEE1394 bus.
1804 1.8.4.2 yamt */
1805 1.8.4.2 yamt static void
1806 1.8.4.2 yamt fw_attach_dev(struct firewire_comm *fc)
1807 1.8.4.2 yamt {
1808 1.8.4.2 yamt struct fw_device *fwdev, *next;
1809 1.8.4.2 yamt struct firewire_dev_comm *fdc;
1810 1.8.4.2 yamt struct fw_attach_args fwa;
1811 1.8.4.2 yamt
1812 1.8.4.2 yamt fwa.name = "sbp";
1813 1.8.4.2 yamt fwa.fc = fc;
1814 1.8.4.2 yamt
1815 1.8.4.2 yamt for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL; fwdev = next) {
1816 1.8.4.2 yamt next = STAILQ_NEXT(fwdev, link);
1817 1.8.4.2 yamt switch (fwdev->status) {
1818 1.8.4.2 yamt case FWDEVNEW:
1819 1.8.4.2 yamt FIREWIRE_SBP_ATTACH;
1820 1.8.4.2 yamt
1821 1.8.4.2 yamt case FWDEVINIT:
1822 1.8.4.2 yamt case FWDEVATTACHED:
1823 1.8.4.2 yamt fwdev->status = FWDEVATTACHED;
1824 1.8.4.2 yamt break;
1825 1.8.4.2 yamt
1826 1.8.4.2 yamt case FWDEVINVAL:
1827 1.8.4.2 yamt fwdev->rcnt ++;
1828 1.8.4.2 yamt break;
1829 1.8.4.2 yamt
1830 1.8.4.2 yamt default:
1831 1.8.4.2 yamt /* XXX */
1832 1.8.4.2 yamt break;
1833 1.8.4.2 yamt }
1834 1.8.4.2 yamt }
1835 1.8.4.2 yamt
1836 1.8.4.2 yamt FIREWIRE_CHILDREN_FOREACH_FUNC(post_explore, fdc);
1837 1.8.4.2 yamt
1838 1.8.4.2 yamt for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL; fwdev = next) {
1839 1.8.4.2 yamt next = STAILQ_NEXT(fwdev, link);
1840 1.8.4.2 yamt if (fwdev->rcnt > 0 && fwdev->rcnt > hold_count) {
1841 1.8.4.2 yamt /*
1842 1.8.4.2 yamt * Remove devices which have not been seen
1843 1.8.4.2 yamt * for a while.
1844 1.8.4.2 yamt */
1845 1.8.4.2 yamt FIREWIRE_SBP_DETACH;
1846 1.8.4.2 yamt STAILQ_REMOVE(&fc->devices, fwdev, fw_device, link);
1847 1.8.4.2 yamt free(fwdev, M_FW);
1848 1.8.4.2 yamt }
1849 1.8.4.2 yamt }
1850 1.8.4.2 yamt
1851 1.8.4.2 yamt return;
1852 1.8.4.2 yamt }
1853 1.8.4.2 yamt
1854 1.8.4.2 yamt /*
1855 1.8.4.2 yamt * To allocate unique transaction label.
1856 1.8.4.2 yamt */
1857 1.8.4.2 yamt static int
1858 1.8.4.2 yamt fw_get_tlabel(struct firewire_comm *fc, struct fw_xfer *xfer)
1859 1.8.4.2 yamt {
1860 1.8.4.6 yamt u_int dst, new_tlabel;
1861 1.8.4.2 yamt struct fw_xfer *txfer;
1862 1.8.4.2 yamt int s;
1863 1.8.4.2 yamt
1864 1.8.4.6 yamt dst = xfer->send.hdr.mode.hdr.dst & 0x3f;
1865 1.8.4.2 yamt s = splfw();
1866 1.8.4.6 yamt fw_mtx_lock(&fc->tlabel_lock);
1867 1.8.4.6 yamt new_tlabel = (fc->last_tlabel[dst] + 1) & 0x3f;
1868 1.8.4.6 yamt STAILQ_FOREACH(txfer, &fc->tlabels[new_tlabel], tlabel)
1869 1.8.4.6 yamt if ((txfer->send.hdr.mode.hdr.dst & 0x3f) == dst)
1870 1.8.4.6 yamt break;
1871 1.8.4.6 yamt if(txfer == NULL) {
1872 1.8.4.6 yamt fc->last_tlabel[dst] = new_tlabel;
1873 1.8.4.6 yamt STAILQ_INSERT_TAIL(&fc->tlabels[new_tlabel], xfer, tlabel);
1874 1.8.4.6 yamt fw_mtx_unlock(&fc->tlabel_lock);
1875 1.8.4.6 yamt splx(s);
1876 1.8.4.6 yamt xfer->tl = new_tlabel;
1877 1.8.4.6 yamt xfer->send.hdr.mode.hdr.tlrt = new_tlabel << 2;
1878 1.8.4.6 yamt if (firewire_debug > 1)
1879 1.8.4.6 yamt printf("fw_get_tlabel: dst=%d tl=%d\n", dst, new_tlabel);
1880 1.8.4.6 yamt return (new_tlabel);
1881 1.8.4.2 yamt }
1882 1.8.4.6 yamt fw_mtx_unlock(&fc->tlabel_lock);
1883 1.8.4.2 yamt splx(s);
1884 1.8.4.2 yamt
1885 1.8.4.2 yamt if (firewire_debug > 1)
1886 1.8.4.2 yamt printf("fw_get_tlabel: no free tlabel\n");
1887 1.8.4.6 yamt return (-1);
1888 1.8.4.2 yamt }
1889 1.8.4.2 yamt
1890 1.8.4.2 yamt static void
1891 1.8.4.2 yamt fw_rcv_copy(struct fw_rcv_buf *rb)
1892 1.8.4.2 yamt {
1893 1.8.4.2 yamt struct fw_pkt *pkt;
1894 1.8.4.2 yamt u_char *p;
1895 1.8.4.2 yamt const struct tcode_info *tinfo;
1896 1.8.4.2 yamt u_int res, i, len, plen;
1897 1.8.4.2 yamt
1898 1.8.4.2 yamt rb->xfer->recv.spd = rb->spd;
1899 1.8.4.2 yamt
1900 1.8.4.2 yamt pkt = (struct fw_pkt *)rb->vec->iov_base;
1901 1.8.4.2 yamt tinfo = &rb->fc->tcode[pkt->mode.hdr.tcode];
1902 1.8.4.2 yamt
1903 1.8.4.2 yamt /* Copy header */
1904 1.8.4.2 yamt p = (u_char *)&rb->xfer->recv.hdr;
1905 1.8.4.2 yamt bcopy(rb->vec->iov_base, p, tinfo->hdr_len);
1906 1.8.4.2 yamt rb->vec->iov_base = (u_char *)rb->vec->iov_base + tinfo->hdr_len;
1907 1.8.4.2 yamt rb->vec->iov_len -= tinfo->hdr_len;
1908 1.8.4.2 yamt
1909 1.8.4.2 yamt /* Copy payload */
1910 1.8.4.2 yamt p = (u_char *)rb->xfer->recv.payload;
1911 1.8.4.2 yamt res = rb->xfer->recv.pay_len;
1912 1.8.4.2 yamt
1913 1.8.4.2 yamt /* special handling for RRESQ */
1914 1.8.4.2 yamt if (pkt->mode.hdr.tcode == FWTCODE_RRESQ &&
1915 1.8.4.2 yamt p != NULL && res >= sizeof(uint32_t)) {
1916 1.8.4.2 yamt *(uint32_t *)p = pkt->mode.rresq.data;
1917 1.8.4.2 yamt rb->xfer->recv.pay_len = sizeof(uint32_t);
1918 1.8.4.2 yamt return;
1919 1.8.4.2 yamt }
1920 1.8.4.2 yamt
1921 1.8.4.2 yamt if ((tinfo->flag & FWTI_BLOCK_ASY) == 0)
1922 1.8.4.2 yamt return;
1923 1.8.4.2 yamt
1924 1.8.4.2 yamt plen = pkt->mode.rresb.len;
1925 1.8.4.2 yamt
1926 1.8.4.2 yamt for (i = 0; i < rb->nvec; i++, rb->vec++) {
1927 1.8.4.2 yamt len = MIN(rb->vec->iov_len, plen);
1928 1.8.4.2 yamt if (res < len) {
1929 1.8.4.2 yamt printf("rcv buffer(%d) is %d bytes short.\n",
1930 1.8.4.2 yamt rb->xfer->recv.pay_len, len - res);
1931 1.8.4.2 yamt len = res;
1932 1.8.4.2 yamt }
1933 1.8.4.2 yamt if (p) {
1934 1.8.4.2 yamt bcopy(rb->vec->iov_base, p, len);
1935 1.8.4.2 yamt p += len;
1936 1.8.4.2 yamt }
1937 1.8.4.2 yamt res -= len;
1938 1.8.4.2 yamt plen -= len;
1939 1.8.4.2 yamt if (res == 0 || plen == 0)
1940 1.8.4.2 yamt break;
1941 1.8.4.2 yamt }
1942 1.8.4.2 yamt rb->xfer->recv.pay_len -= res;
1943 1.8.4.2 yamt
1944 1.8.4.2 yamt }
1945 1.8.4.2 yamt
1946 1.8.4.2 yamt /*
1947 1.8.4.2 yamt * Generic packet receiving process.
1948 1.8.4.2 yamt */
1949 1.8.4.2 yamt void
1950 1.8.4.2 yamt fw_rcv(struct fw_rcv_buf *rb)
1951 1.8.4.2 yamt {
1952 1.8.4.2 yamt struct fw_pkt *fp, *resfp;
1953 1.8.4.2 yamt struct fw_bind *bind;
1954 1.8.4.2 yamt int tcode;
1955 1.8.4.2 yamt int i, len, oldstate;
1956 1.8.4.2 yamt #if 0
1957 1.8.4.2 yamt {
1958 1.8.4.2 yamt uint32_t *qld;
1959 1.8.4.2 yamt int i;
1960 1.8.4.2 yamt qld = (uint32_t *)buf;
1961 1.8.4.2 yamt printf("spd %d len:%d\n", spd, len);
1962 1.8.4.2 yamt for( i = 0 ; i <= len && i < 32; i+= 4){
1963 1.8.4.2 yamt printf("0x%08x ", ntohl(qld[i/4]));
1964 1.8.4.2 yamt if((i % 16) == 15) printf("\n");
1965 1.8.4.2 yamt }
1966 1.8.4.2 yamt if((i % 16) != 15) printf("\n");
1967 1.8.4.2 yamt }
1968 1.8.4.2 yamt #endif
1969 1.8.4.2 yamt fp = (struct fw_pkt *)rb->vec[0].iov_base;
1970 1.8.4.2 yamt tcode = fp->mode.common.tcode;
1971 1.8.4.2 yamt switch (tcode) {
1972 1.8.4.2 yamt case FWTCODE_WRES:
1973 1.8.4.2 yamt case FWTCODE_RRESQ:
1974 1.8.4.2 yamt case FWTCODE_RRESB:
1975 1.8.4.2 yamt case FWTCODE_LRES:
1976 1.8.4.2 yamt rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src,
1977 1.8.4.6 yamt fp->mode.hdr.tlrt >> 2, fp->mode.hdr.tcode);
1978 1.8.4.2 yamt if(rb->xfer == NULL) {
1979 1.8.4.2 yamt printf("fw_rcv: unknown response "
1980 1.8.4.2 yamt "%s(%x) src=0x%x tl=0x%x rt=%d data=0x%x\n",
1981 1.8.4.2 yamt tcode_str[tcode], tcode,
1982 1.8.4.2 yamt fp->mode.hdr.src,
1983 1.8.4.2 yamt fp->mode.hdr.tlrt >> 2,
1984 1.8.4.2 yamt fp->mode.hdr.tlrt & 3,
1985 1.8.4.2 yamt fp->mode.rresq.data);
1986 1.8.4.6 yamt #if 0
1987 1.8.4.2 yamt printf("try ad-hoc work around!!\n");
1988 1.8.4.2 yamt rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src,
1989 1.8.4.2 yamt (fp->mode.hdr.tlrt >> 2)^3);
1990 1.8.4.2 yamt if (rb->xfer == NULL) {
1991 1.8.4.2 yamt printf("no use...\n");
1992 1.8.4.2 yamt return;
1993 1.8.4.2 yamt }
1994 1.8.4.2 yamt #else
1995 1.8.4.2 yamt return;
1996 1.8.4.2 yamt #endif
1997 1.8.4.2 yamt }
1998 1.8.4.2 yamt fw_rcv_copy(rb);
1999 1.8.4.2 yamt if (rb->xfer->recv.hdr.mode.wres.rtcode != RESP_CMP)
2000 1.8.4.2 yamt rb->xfer->resp = EIO;
2001 1.8.4.2 yamt else
2002 1.8.4.2 yamt rb->xfer->resp = 0;
2003 1.8.4.2 yamt /* make sure the packet is drained in AT queue */
2004 1.8.4.6 yamt oldstate = rb->xfer->flag;
2005 1.8.4.6 yamt rb->xfer->flag = FWXF_RCVD;
2006 1.8.4.2 yamt switch (oldstate) {
2007 1.8.4.2 yamt case FWXF_SENT:
2008 1.8.4.2 yamt fw_xfer_done(rb->xfer);
2009 1.8.4.2 yamt break;
2010 1.8.4.2 yamt case FWXF_START:
2011 1.8.4.2 yamt #if 0
2012 1.8.4.2 yamt if (firewire_debug)
2013 1.8.4.2 yamt printf("not sent yet tl=%x\n", rb->xfer->tl);
2014 1.8.4.2 yamt #endif
2015 1.8.4.2 yamt break;
2016 1.8.4.2 yamt default:
2017 1.8.4.6 yamt printf("unexpected flag 0x%02x\n", rb->xfer->flag);
2018 1.8.4.2 yamt }
2019 1.8.4.2 yamt return;
2020 1.8.4.2 yamt case FWTCODE_WREQQ:
2021 1.8.4.2 yamt case FWTCODE_WREQB:
2022 1.8.4.2 yamt case FWTCODE_RREQQ:
2023 1.8.4.2 yamt case FWTCODE_RREQB:
2024 1.8.4.2 yamt case FWTCODE_LREQ:
2025 1.8.4.2 yamt bind = fw_bindlookup(rb->fc, fp->mode.rreqq.dest_hi,
2026 1.8.4.2 yamt fp->mode.rreqq.dest_lo);
2027 1.8.4.2 yamt if(bind == NULL){
2028 1.8.4.2 yamt #if 1
2029 1.8.4.2 yamt printf("Unknown service addr 0x%04x:0x%08x %s(%x)"
2030 1.8.4.2 yamt #if defined(__DragonFly__) || \
2031 1.8.4.2 yamt (defined(__FreeBSD__) && __FreeBSD_version < 500000)
2032 1.8.4.2 yamt " src=0x%x data=%lx\n",
2033 1.8.4.2 yamt #else
2034 1.8.4.2 yamt " src=0x%x data=%x\n",
2035 1.8.4.2 yamt #endif
2036 1.8.4.2 yamt fp->mode.wreqq.dest_hi, fp->mode.wreqq.dest_lo,
2037 1.8.4.2 yamt tcode_str[tcode], tcode,
2038 1.8.4.2 yamt fp->mode.hdr.src, ntohl(fp->mode.wreqq.data));
2039 1.8.4.2 yamt #endif
2040 1.8.4.6 yamt if (rb->fc->status == FWBUSINIT) {
2041 1.8.4.2 yamt printf("fw_rcv: cannot respond(bus reset)!\n");
2042 1.8.4.2 yamt return;
2043 1.8.4.2 yamt }
2044 1.8.4.2 yamt rb->xfer = fw_xfer_alloc(M_FWXFER);
2045 1.8.4.2 yamt if(rb->xfer == NULL){
2046 1.8.4.2 yamt return;
2047 1.8.4.2 yamt }
2048 1.8.4.2 yamt rb->xfer->send.spd = rb->spd;
2049 1.8.4.2 yamt rb->xfer->send.pay_len = 0;
2050 1.8.4.2 yamt resfp = &rb->xfer->send.hdr;
2051 1.8.4.2 yamt switch (tcode) {
2052 1.8.4.2 yamt case FWTCODE_WREQQ:
2053 1.8.4.2 yamt case FWTCODE_WREQB:
2054 1.8.4.2 yamt resfp->mode.hdr.tcode = FWTCODE_WRES;
2055 1.8.4.2 yamt break;
2056 1.8.4.2 yamt case FWTCODE_RREQQ:
2057 1.8.4.2 yamt resfp->mode.hdr.tcode = FWTCODE_RRESQ;
2058 1.8.4.2 yamt break;
2059 1.8.4.2 yamt case FWTCODE_RREQB:
2060 1.8.4.2 yamt resfp->mode.hdr.tcode = FWTCODE_RRESB;
2061 1.8.4.2 yamt break;
2062 1.8.4.2 yamt case FWTCODE_LREQ:
2063 1.8.4.2 yamt resfp->mode.hdr.tcode = FWTCODE_LRES;
2064 1.8.4.2 yamt break;
2065 1.8.4.2 yamt }
2066 1.8.4.2 yamt resfp->mode.hdr.dst = fp->mode.hdr.src;
2067 1.8.4.2 yamt resfp->mode.hdr.tlrt = fp->mode.hdr.tlrt;
2068 1.8.4.2 yamt resfp->mode.hdr.pri = fp->mode.hdr.pri;
2069 1.8.4.2 yamt resfp->mode.rresb.rtcode = RESP_ADDRESS_ERROR;
2070 1.8.4.2 yamt resfp->mode.rresb.extcode = 0;
2071 1.8.4.2 yamt resfp->mode.rresb.len = 0;
2072 1.8.4.2 yamt /*
2073 1.8.4.6 yamt rb->xfer->hand = fw_xferwake;
2074 1.8.4.2 yamt */
2075 1.8.4.2 yamt rb->xfer->hand = fw_xfer_free;
2076 1.8.4.2 yamt if(fw_asyreq(rb->fc, -1, rb->xfer)){
2077 1.8.4.2 yamt fw_xfer_free(rb->xfer);
2078 1.8.4.2 yamt return;
2079 1.8.4.2 yamt }
2080 1.8.4.2 yamt return;
2081 1.8.4.2 yamt }
2082 1.8.4.2 yamt len = 0;
2083 1.8.4.2 yamt for (i = 0; i < rb->nvec; i ++)
2084 1.8.4.2 yamt len += rb->vec[i].iov_len;
2085 1.8.4.2 yamt rb->xfer = STAILQ_FIRST(&bind->xferlist);
2086 1.8.4.2 yamt if (rb->xfer == NULL) {
2087 1.8.4.2 yamt #if 1
2088 1.8.4.2 yamt printf("Discard a packet for this bind.\n");
2089 1.8.4.2 yamt #endif
2090 1.8.4.2 yamt return;
2091 1.8.4.2 yamt }
2092 1.8.4.2 yamt STAILQ_REMOVE_HEAD(&bind->xferlist, link);
2093 1.8.4.2 yamt fw_rcv_copy(rb);
2094 1.8.4.2 yamt rb->xfer->hand(rb->xfer);
2095 1.8.4.2 yamt return;
2096 1.8.4.2 yamt #if 0 /* shouldn't happen ?? or for GASP */
2097 1.8.4.2 yamt case FWTCODE_STREAM:
2098 1.8.4.2 yamt {
2099 1.8.4.2 yamt struct fw_xferq *xferq;
2100 1.8.4.2 yamt
2101 1.8.4.2 yamt xferq = rb->fc->ir[sub];
2102 1.8.4.2 yamt #if 0
2103 1.8.4.2 yamt printf("stream rcv dma %d len %d off %d spd %d\n",
2104 1.8.4.2 yamt sub, len, off, spd);
2105 1.8.4.2 yamt #endif
2106 1.8.4.2 yamt if(xferq->queued >= xferq->maxq) {
2107 1.8.4.2 yamt printf("receive queue is full\n");
2108 1.8.4.2 yamt return;
2109 1.8.4.2 yamt }
2110 1.8.4.2 yamt /* XXX get xfer from xfer queue, we don't need copy for
2111 1.8.4.2 yamt per packet mode */
2112 1.8.4.2 yamt rb->xfer = fw_xfer_alloc_buf(M_FWXFER, 0, /* XXX */
2113 1.8.4.2 yamt vec[0].iov_len);
2114 1.8.4.2 yamt if (rb->xfer == NULL)
2115 1.8.4.2 yamt return;
2116 1.8.4.2 yamt fw_rcv_copy(rb)
2117 1.8.4.2 yamt s = splfw();
2118 1.8.4.2 yamt xferq->queued++;
2119 1.8.4.2 yamt STAILQ_INSERT_TAIL(&xferq->q, rb->xfer, link);
2120 1.8.4.2 yamt splx(s);
2121 1.8.4.2 yamt sc = device_get_softc(rb->fc->bdev);
2122 1.8.4.2 yamt #if defined(__DragonFly__) || \
2123 1.8.4.2 yamt (defined(__FreeBSD__) && __FreeBSD_version < 500000)
2124 1.8.4.2 yamt if (&xferq->rsel.si_pid != 0)
2125 1.8.4.2 yamt #else
2126 1.8.4.2 yamt if (SEL_WAITING(&xferq->rsel))
2127 1.8.4.2 yamt #endif
2128 1.8.4.2 yamt selwakeuppri(&xferq->rsel, FWPRI);
2129 1.8.4.2 yamt if (xferq->flag & FWXFERQ_WAKEUP) {
2130 1.8.4.2 yamt xferq->flag &= ~FWXFERQ_WAKEUP;
2131 1.8.4.4 yamt wakeup((void *)xferq);
2132 1.8.4.2 yamt }
2133 1.8.4.2 yamt if (xferq->flag & FWXFERQ_HANDLER) {
2134 1.8.4.2 yamt xferq->hand(xferq);
2135 1.8.4.2 yamt }
2136 1.8.4.2 yamt return;
2137 1.8.4.2 yamt break;
2138 1.8.4.2 yamt }
2139 1.8.4.2 yamt #endif
2140 1.8.4.2 yamt default:
2141 1.8.4.2 yamt printf("fw_rcv: unknow tcode %d\n", tcode);
2142 1.8.4.2 yamt break;
2143 1.8.4.2 yamt }
2144 1.8.4.2 yamt }
2145 1.8.4.2 yamt
2146 1.8.4.2 yamt /*
2147 1.8.4.2 yamt * Post process for Bus Manager election process.
2148 1.8.4.2 yamt */
2149 1.8.4.2 yamt static void
2150 1.8.4.2 yamt fw_try_bmr_callback(struct fw_xfer *xfer)
2151 1.8.4.2 yamt {
2152 1.8.4.2 yamt struct firewire_comm *fc;
2153 1.8.4.2 yamt int bmr;
2154 1.8.4.2 yamt
2155 1.8.4.2 yamt if (xfer == NULL)
2156 1.8.4.2 yamt return;
2157 1.8.4.2 yamt fc = xfer->fc;
2158 1.8.4.2 yamt if (xfer->resp != 0)
2159 1.8.4.2 yamt goto error;
2160 1.8.4.2 yamt if (xfer->recv.payload == NULL)
2161 1.8.4.2 yamt goto error;
2162 1.8.4.2 yamt if (xfer->recv.hdr.mode.lres.rtcode != FWRCODE_COMPLETE)
2163 1.8.4.2 yamt goto error;
2164 1.8.4.2 yamt
2165 1.8.4.2 yamt bmr = ntohl(xfer->recv.payload[0]);
2166 1.8.4.2 yamt if (bmr == 0x3f)
2167 1.8.4.2 yamt bmr = fc->nodeid;
2168 1.8.4.2 yamt
2169 1.8.4.2 yamt CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, bmr & 0x3f);
2170 1.8.4.2 yamt fw_xfer_free_buf(xfer);
2171 1.8.4.2 yamt fw_bmr(fc);
2172 1.8.4.2 yamt return;
2173 1.8.4.2 yamt
2174 1.8.4.2 yamt error:
2175 1.8.4.6 yamt fw_printf(fc->bdev, "bus manager election failed\n");
2176 1.8.4.2 yamt fw_xfer_free_buf(xfer);
2177 1.8.4.2 yamt }
2178 1.8.4.2 yamt
2179 1.8.4.2 yamt
2180 1.8.4.2 yamt /*
2181 1.8.4.2 yamt * To candidate Bus Manager election process.
2182 1.8.4.2 yamt */
2183 1.8.4.2 yamt static void
2184 1.8.4.2 yamt fw_try_bmr(void *arg)
2185 1.8.4.2 yamt {
2186 1.8.4.2 yamt struct fw_xfer *xfer;
2187 1.8.4.2 yamt struct firewire_comm *fc = (struct firewire_comm *)arg;
2188 1.8.4.2 yamt struct fw_pkt *fp;
2189 1.8.4.2 yamt int err = 0;
2190 1.8.4.2 yamt
2191 1.8.4.2 yamt xfer = fw_xfer_alloc_buf(M_FWXFER, 8, 4);
2192 1.8.4.2 yamt if(xfer == NULL){
2193 1.8.4.2 yamt return;
2194 1.8.4.2 yamt }
2195 1.8.4.2 yamt xfer->send.spd = 0;
2196 1.8.4.2 yamt fc->status = FWBUSMGRELECT;
2197 1.8.4.2 yamt
2198 1.8.4.2 yamt fp = &xfer->send.hdr;
2199 1.8.4.2 yamt fp->mode.lreq.dest_hi = 0xffff;
2200 1.8.4.2 yamt fp->mode.lreq.tlrt = 0;
2201 1.8.4.2 yamt fp->mode.lreq.tcode = FWTCODE_LREQ;
2202 1.8.4.2 yamt fp->mode.lreq.pri = 0;
2203 1.8.4.2 yamt fp->mode.lreq.src = 0;
2204 1.8.4.2 yamt fp->mode.lreq.len = 8;
2205 1.8.4.2 yamt fp->mode.lreq.extcode = EXTCODE_CMP_SWAP;
2206 1.8.4.2 yamt fp->mode.lreq.dst = FWLOCALBUS | fc->irm;
2207 1.8.4.2 yamt fp->mode.lreq.dest_lo = 0xf0000000 | BUS_MGR_ID;
2208 1.8.4.2 yamt xfer->send.payload[0] = htonl(0x3f);
2209 1.8.4.2 yamt xfer->send.payload[1] = htonl(fc->nodeid);
2210 1.8.4.2 yamt xfer->hand = fw_try_bmr_callback;
2211 1.8.4.2 yamt
2212 1.8.4.2 yamt err = fw_asyreq(fc, -1, xfer);
2213 1.8.4.2 yamt if(err){
2214 1.8.4.2 yamt fw_xfer_free_buf(xfer);
2215 1.8.4.2 yamt return;
2216 1.8.4.2 yamt }
2217 1.8.4.2 yamt return;
2218 1.8.4.2 yamt }
2219 1.8.4.2 yamt
2220 1.8.4.2 yamt #ifdef FW_VMACCESS
2221 1.8.4.2 yamt /*
2222 1.8.4.2 yamt * Software implementation for physical memory block access.
2223 1.8.4.2 yamt * XXX:Too slow, usef for debug purpose only.
2224 1.8.4.2 yamt */
2225 1.8.4.2 yamt static void
2226 1.8.4.2 yamt fw_vmaccess(struct fw_xfer *xfer){
2227 1.8.4.2 yamt struct fw_pkt *rfp, *sfp = NULL;
2228 1.8.4.2 yamt uint32_t *ld = (uint32_t *)xfer->recv.buf;
2229 1.8.4.2 yamt
2230 1.8.4.2 yamt printf("vmaccess spd:%2x len:%03x data:%08x %08x %08x %08x\n",
2231 1.8.4.2 yamt xfer->spd, xfer->recv.len, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3]));
2232 1.8.4.2 yamt printf("vmaccess data:%08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
2233 1.8.4.2 yamt if(xfer->resp != 0){
2234 1.8.4.2 yamt fw_xfer_free( xfer);
2235 1.8.4.2 yamt return;
2236 1.8.4.2 yamt }
2237 1.8.4.2 yamt if(xfer->recv.buf == NULL){
2238 1.8.4.2 yamt fw_xfer_free( xfer);
2239 1.8.4.2 yamt return;
2240 1.8.4.2 yamt }
2241 1.8.4.2 yamt rfp = (struct fw_pkt *)xfer->recv.buf;
2242 1.8.4.2 yamt switch(rfp->mode.hdr.tcode){
2243 1.8.4.2 yamt /* XXX need fix for 64bit arch */
2244 1.8.4.2 yamt case FWTCODE_WREQB:
2245 1.8.4.2 yamt xfer->send.buf = malloc(12, M_FW, M_NOWAIT);
2246 1.8.4.2 yamt xfer->send.len = 12;
2247 1.8.4.2 yamt sfp = (struct fw_pkt *)xfer->send.buf;
2248 1.8.4.2 yamt bcopy(rfp->mode.wreqb.payload,
2249 1.8.4.4 yamt (void *)ntohl(rfp->mode.wreqb.dest_lo), ntohs(rfp->mode.wreqb.len));
2250 1.8.4.2 yamt sfp->mode.wres.tcode = FWTCODE_WRES;
2251 1.8.4.2 yamt sfp->mode.wres.rtcode = 0;
2252 1.8.4.2 yamt break;
2253 1.8.4.2 yamt case FWTCODE_WREQQ:
2254 1.8.4.2 yamt xfer->send.buf = malloc(12, M_FW, M_NOWAIT);
2255 1.8.4.2 yamt xfer->send.len = 12;
2256 1.8.4.2 yamt sfp->mode.wres.tcode = FWTCODE_WRES;
2257 1.8.4.2 yamt *((uint32_t *)(ntohl(rfp->mode.wreqb.dest_lo))) = rfp->mode.wreqq.data;
2258 1.8.4.2 yamt sfp->mode.wres.rtcode = 0;
2259 1.8.4.2 yamt break;
2260 1.8.4.2 yamt case FWTCODE_RREQB:
2261 1.8.4.2 yamt xfer->send.buf = malloc(16 + rfp->mode.rreqb.len, M_FW, M_NOWAIT);
2262 1.8.4.2 yamt xfer->send.len = 16 + ntohs(rfp->mode.rreqb.len);
2263 1.8.4.2 yamt sfp = (struct fw_pkt *)xfer->send.buf;
2264 1.8.4.4 yamt bcopy((void *)ntohl(rfp->mode.rreqb.dest_lo),
2265 1.8.4.2 yamt sfp->mode.rresb.payload, (uint16_t)ntohs(rfp->mode.rreqb.len));
2266 1.8.4.2 yamt sfp->mode.rresb.tcode = FWTCODE_RRESB;
2267 1.8.4.2 yamt sfp->mode.rresb.len = rfp->mode.rreqb.len;
2268 1.8.4.2 yamt sfp->mode.rresb.rtcode = 0;
2269 1.8.4.2 yamt sfp->mode.rresb.extcode = 0;
2270 1.8.4.2 yamt break;
2271 1.8.4.2 yamt case FWTCODE_RREQQ:
2272 1.8.4.2 yamt xfer->send.buf = malloc(16, M_FW, M_NOWAIT);
2273 1.8.4.2 yamt xfer->send.len = 16;
2274 1.8.4.2 yamt sfp = (struct fw_pkt *)xfer->send.buf;
2275 1.8.4.2 yamt sfp->mode.rresq.data = *(uint32_t *)(ntohl(rfp->mode.rreqq.dest_lo));
2276 1.8.4.2 yamt sfp->mode.wres.tcode = FWTCODE_RRESQ;
2277 1.8.4.2 yamt sfp->mode.rresb.rtcode = 0;
2278 1.8.4.2 yamt break;
2279 1.8.4.2 yamt default:
2280 1.8.4.2 yamt fw_xfer_free( xfer);
2281 1.8.4.2 yamt return;
2282 1.8.4.2 yamt }
2283 1.8.4.2 yamt sfp->mode.hdr.dst = rfp->mode.hdr.src;
2284 1.8.4.2 yamt xfer->dst = ntohs(rfp->mode.hdr.src);
2285 1.8.4.2 yamt xfer->hand = fw_xfer_free;
2286 1.8.4.2 yamt
2287 1.8.4.2 yamt sfp->mode.hdr.tlrt = rfp->mode.hdr.tlrt;
2288 1.8.4.2 yamt sfp->mode.hdr.pri = 0;
2289 1.8.4.2 yamt
2290 1.8.4.2 yamt fw_asyreq(xfer->fc, -1, xfer);
2291 1.8.4.2 yamt /**/
2292 1.8.4.2 yamt return;
2293 1.8.4.2 yamt }
2294 1.8.4.2 yamt #endif
2295 1.8.4.2 yamt
2296 1.8.4.2 yamt /*
2297 1.8.4.2 yamt * CRC16 check-sum for IEEE1394 register blocks.
2298 1.8.4.2 yamt */
2299 1.8.4.2 yamt uint16_t
2300 1.8.4.2 yamt fw_crc16(uint32_t *ptr, uint32_t len){
2301 1.8.4.2 yamt uint32_t i, sum, crc = 0;
2302 1.8.4.2 yamt int shift;
2303 1.8.4.2 yamt len = (len + 3) & ~3;
2304 1.8.4.2 yamt for(i = 0 ; i < len ; i+= 4){
2305 1.8.4.2 yamt for( shift = 28 ; shift >= 0 ; shift -= 4){
2306 1.8.4.2 yamt sum = ((crc >> 12) ^ (ptr[i/4] >> shift)) & 0xf;
2307 1.8.4.2 yamt crc = (crc << 4) ^ ( sum << 12 ) ^ ( sum << 5) ^ sum;
2308 1.8.4.2 yamt }
2309 1.8.4.2 yamt crc &= 0xffff;
2310 1.8.4.2 yamt }
2311 1.8.4.2 yamt return((uint16_t) crc);
2312 1.8.4.2 yamt }
2313 1.8.4.2 yamt
2314 1.8.4.2 yamt static int
2315 1.8.4.2 yamt fw_bmr(struct firewire_comm *fc)
2316 1.8.4.2 yamt {
2317 1.8.4.2 yamt struct fw_device fwdev;
2318 1.8.4.2 yamt union fw_self_id *self_id;
2319 1.8.4.2 yamt int cmstr;
2320 1.8.4.2 yamt uint32_t quad;
2321 1.8.4.2 yamt
2322 1.8.4.2 yamt /* Check to see if the current root node is cycle master capable */
2323 1.8.4.2 yamt self_id = fw_find_self_id(fc, fc->max_node);
2324 1.8.4.2 yamt if (fc->max_node > 0) {
2325 1.8.4.2 yamt /* XXX check cmc bit of businfo block rather than contender */
2326 1.8.4.2 yamt if (self_id->p0.link_active && self_id->p0.contender)
2327 1.8.4.2 yamt cmstr = fc->max_node;
2328 1.8.4.2 yamt else {
2329 1.8.4.6 yamt fw_printf(fc->bdev,
2330 1.8.4.2 yamt "root node is not cycle master capable\n");
2331 1.8.4.2 yamt /* XXX shall we be the cycle master? */
2332 1.8.4.2 yamt cmstr = fc->nodeid;
2333 1.8.4.2 yamt /* XXX need bus reset */
2334 1.8.4.2 yamt }
2335 1.8.4.2 yamt } else
2336 1.8.4.2 yamt cmstr = -1;
2337 1.8.4.2 yamt
2338 1.8.4.6 yamt fw_printf(fc->bdev, "bus manager %d ", CSRARC(fc, BUS_MGR_ID));
2339 1.8.4.2 yamt if(CSRARC(fc, BUS_MGR_ID) != fc->nodeid) {
2340 1.8.4.2 yamt /* We are not the bus manager */
2341 1.8.4.2 yamt printf("\n");
2342 1.8.4.2 yamt return(0);
2343 1.8.4.2 yamt }
2344 1.8.4.2 yamt printf("(me)\n");
2345 1.8.4.2 yamt
2346 1.8.4.2 yamt /* Optimize gapcount */
2347 1.8.4.2 yamt if(fc->max_hop <= MAX_GAPHOP )
2348 1.8.4.2 yamt fw_phy_config(fc, cmstr, gap_cnt[fc->max_hop]);
2349 1.8.4.2 yamt /* If we are the cycle master, nothing to do */
2350 1.8.4.2 yamt if (cmstr == fc->nodeid || cmstr == -1)
2351 1.8.4.2 yamt return 0;
2352 1.8.4.2 yamt /* Bus probe has not finished, make dummy fwdev for cmstr */
2353 1.8.4.2 yamt bzero(&fwdev, sizeof(fwdev));
2354 1.8.4.2 yamt fwdev.fc = fc;
2355 1.8.4.2 yamt fwdev.dst = cmstr;
2356 1.8.4.2 yamt fwdev.speed = 0;
2357 1.8.4.2 yamt fwdev.maxrec = 8; /* 512 */
2358 1.8.4.2 yamt fwdev.status = FWDEVINIT;
2359 1.8.4.2 yamt /* Set cmstr bit on the cycle master */
2360 1.8.4.2 yamt quad = htonl(1 << 8);
2361 1.8.4.2 yamt fwmem_write_quad(&fwdev, NULL, 0/*spd*/,
2362 1.8.4.2 yamt 0xffff, 0xf0000000 | STATE_SET, &quad, fw_asy_callback_free);
2363 1.8.4.2 yamt
2364 1.8.4.2 yamt return 0;
2365 1.8.4.2 yamt }
2366 1.8.4.2 yamt
2367 1.8.4.6 yamt int
2368 1.8.4.6 yamt fw_open_isodma(struct firewire_comm *fc, int tx)
2369 1.8.4.6 yamt {
2370 1.8.4.6 yamt struct fw_xferq **xferqa;
2371 1.8.4.6 yamt struct fw_xferq *xferq;
2372 1.8.4.6 yamt int i;
2373 1.8.4.6 yamt
2374 1.8.4.6 yamt if (tx)
2375 1.8.4.6 yamt xferqa = &fc->it[0];
2376 1.8.4.6 yamt else
2377 1.8.4.6 yamt xferqa = &fc->ir[0];
2378 1.8.4.6 yamt
2379 1.8.4.6 yamt FW_GLOCK(fc);
2380 1.8.4.6 yamt for (i = 0; i < fc->nisodma; i ++) {
2381 1.8.4.6 yamt xferq = xferqa[i];
2382 1.8.4.6 yamt if ((xferq->flag & FWXFERQ_OPEN) == 0) {
2383 1.8.4.6 yamt xferq->flag |= FWXFERQ_OPEN;
2384 1.8.4.6 yamt break;
2385 1.8.4.6 yamt }
2386 1.8.4.6 yamt }
2387 1.8.4.6 yamt if (i == fc->nisodma) {
2388 1.8.4.6 yamt printf("no free dma channel (tx=%d)\n", tx);
2389 1.8.4.6 yamt i = -1;
2390 1.8.4.6 yamt }
2391 1.8.4.6 yamt FW_GUNLOCK(fc);
2392 1.8.4.6 yamt return (i);
2393 1.8.4.6 yamt }
2394 1.8.4.6 yamt
2395 1.8.4.2 yamt #if defined(__FreeBSD__)
2396 1.8.4.2 yamt static int
2397 1.8.4.2 yamt fw_modevent(module_t mode, int type, void *data)
2398 1.8.4.2 yamt {
2399 1.8.4.2 yamt int err = 0;
2400 1.8.4.2 yamt #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
2401 1.8.4.2 yamt static eventhandler_tag fwdev_ehtag = NULL;
2402 1.8.4.2 yamt #endif
2403 1.8.4.2 yamt
2404 1.8.4.2 yamt switch (type) {
2405 1.8.4.2 yamt case MOD_LOAD:
2406 1.8.4.2 yamt #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
2407 1.8.4.2 yamt fwdev_ehtag = EVENTHANDLER_REGISTER(dev_clone,
2408 1.8.4.2 yamt fwdev_clone, 0, 1000);
2409 1.8.4.2 yamt #endif
2410 1.8.4.2 yamt break;
2411 1.8.4.2 yamt case MOD_UNLOAD:
2412 1.8.4.2 yamt #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
2413 1.8.4.2 yamt if (fwdev_ehtag != NULL)
2414 1.8.4.2 yamt EVENTHANDLER_DEREGISTER(dev_clone, fwdev_ehtag);
2415 1.8.4.2 yamt #endif
2416 1.8.4.2 yamt break;
2417 1.8.4.2 yamt case MOD_SHUTDOWN:
2418 1.8.4.2 yamt break;
2419 1.8.4.2 yamt default:
2420 1.8.4.2 yamt return (EOPNOTSUPP);
2421 1.8.4.2 yamt }
2422 1.8.4.2 yamt return (err);
2423 1.8.4.2 yamt }
2424 1.8.4.2 yamt
2425 1.8.4.2 yamt
2426 1.8.4.2 yamt #ifdef __DragonFly__
2427 1.8.4.2 yamt DECLARE_DUMMY_MODULE(firewire);
2428 1.8.4.2 yamt #endif
2429 1.8.4.2 yamt DRIVER_MODULE(firewire,fwohci,firewire_driver,firewire_devclass,fw_modevent,0);
2430 1.8.4.2 yamt MODULE_VERSION(firewire, 1);
2431 1.8.4.2 yamt #endif
2432