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