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