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