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