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