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