firewire.c revision 1.26.2.1 1 1.26.2.1 rmind /* $NetBSD: firewire.c,v 1.26.2.1 2010/05/30 05:17:27 rmind 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.26.2.1 rmind *
35 1.26.2.1 rmind * $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.26.2.1 rmind __KERNEL_RCSID(0, "$NetBSD: firewire.c,v 1.26.2.1 2010/05/30 05:17:27 rmind Exp $");
41 1.18 lukem
42 1.1 kiyohara #include <sys/param.h>
43 1.15 ad #include <sys/bus.h>
44 1.26.2.1 rmind #include <sys/callout.h>
45 1.26.2.1 rmind #include <sys/condvar.h>
46 1.26.2.1 rmind #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.26.2.1 rmind 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.22 ad * 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.26.2.1 rmind 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.26.2.1 rmind #define FW_GENERATION_CHANGEABLE 2
136 1.26.2.1 rmind
137 1.26.2.1 rmind static int firewirematch (device_t, cfdata_t, void *);
138 1.26.2.1 rmind static void firewireattach (device_t, device_t, void *);
139 1.26.2.1 rmind static int firewiredetach (device_t, int);
140 1.26.2.1 rmind static int firewire_print (void *, const char *);
141 1.1 kiyohara
142 1.20 kiyohara int firewire_resume (struct firewire_comm *);
143 1.26.2.1 rmind
144 1.26.2.1 rmind static void fw_asystart(struct fw_xfer *);
145 1.26.2.1 rmind static void firewire_xfer_timeout(struct firewire_comm *);
146 1.26.2.1 rmind static void firewire_watchdog(void *);
147 1.26.2.1 rmind static void fw_xferq_drain(struct fw_xferq *);
148 1.26.2.1 rmind static void fw_reset_csr(struct firewire_comm *);
149 1.26.2.1 rmind static void fw_init_crom(struct firewire_comm *);
150 1.26.2.1 rmind static void fw_reset_crom(struct firewire_comm *);
151 1.16 kiyohara static void fw_dump_hdr(struct fw_pkt *, const char *);
152 1.26.2.1 rmind static void fw_tl_free(struct firewire_comm *, struct fw_xfer *);
153 1.26.2.1 rmind static struct fw_xfer *fw_tl2xfer(struct firewire_comm *, int, int, int);
154 1.26.2.1 rmind static void fw_phy_config(struct firewire_comm *, int, int);
155 1.26.2.1 rmind static void fw_print_sid(uint32_t);
156 1.26.2.1 rmind static void fw_bus_probe(struct firewire_comm *);
157 1.26.2.1 rmind static int fw_explore_read_quads(struct fw_device *, int, uint32_t *, int);
158 1.26.2.1 rmind static int fw_explore_csrblock(struct fw_device *, int, int);
159 1.26.2.1 rmind static int fw_explore_node(struct fw_device *);
160 1.26.2.1 rmind static union fw_self_id *fw_find_self_id(struct firewire_comm *, int);
161 1.26.2.1 rmind static void fw_explore(struct firewire_comm *);
162 1.26.2.1 rmind static void fw_bus_probe_thread(void *);
163 1.26.2.1 rmind static void fw_attach_dev(struct firewire_comm *);
164 1.26.2.1 rmind static int fw_get_tlabel(struct firewire_comm *, struct fw_xfer *);
165 1.26.2.1 rmind static void fw_rcv_copy(struct fw_rcv_buf *);
166 1.26.2.1 rmind static void fw_try_bmr_callback(struct fw_xfer *);
167 1.26.2.1 rmind static void fw_try_bmr(void *);
168 1.26.2.1 rmind 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.26.2.1 rmind
174 1.26.2.1 rmind
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.26.2.1 rmind
193 1.26.2.1 rmind static int
194 1.26.2.1 rmind firewirematch(device_t parent, cfdata_t cf, void *aux)
195 1.26.2.1 rmind {
196 1.26.2.1 rmind
197 1.26.2.1 rmind return 1; /* always match */
198 1.26.2.1 rmind }
199 1.26.2.1 rmind
200 1.26.2.1 rmind static void
201 1.26.2.1 rmind firewireattach(device_t parent, device_t self, void *aux)
202 1.26.2.1 rmind {
203 1.26.2.1 rmind struct firewire_softc *sc = device_private(self);
204 1.26.2.1 rmind struct firewire_comm *fc = device_private(parent);
205 1.26.2.1 rmind struct fw_attach_args faa;
206 1.26.2.1 rmind struct firewire_dev_list *devlist;
207 1.26.2.1 rmind
208 1.26.2.1 rmind aprint_naive("\n");
209 1.26.2.1 rmind aprint_normal(": IEEE1394 bus\n");
210 1.26.2.1 rmind
211 1.26.2.1 rmind fc->bdev = sc->dev = self;
212 1.26.2.1 rmind sc->fc = fc;
213 1.26.2.1 rmind SLIST_INIT(&sc->devlist);
214 1.26.2.1 rmind
215 1.26.2.1 rmind fc->status = FWBUSNOTREADY;
216 1.26.2.1 rmind
217 1.26.2.1 rmind if (fc->nisodma > FWMAXNDMA)
218 1.26.2.1 rmind fc->nisodma = FWMAXNDMA;
219 1.26.2.1 rmind
220 1.26.2.1 rmind fc->crom_src_buf =
221 1.26.2.1 rmind (struct crom_src_buf *)malloc(sizeof(struct crom_src_buf),
222 1.26.2.1 rmind M_FW, M_NOWAIT | M_ZERO);
223 1.26.2.1 rmind if (fc->crom_src_buf == NULL) {
224 1.26.2.1 rmind aprint_error_dev(fc->bdev, "Malloc Failure crom src buff\n");
225 1.26.2.1 rmind return;
226 1.26.2.1 rmind }
227 1.26.2.1 rmind fc->topology_map =
228 1.26.2.1 rmind (struct fw_topology_map *)malloc(sizeof(struct fw_topology_map),
229 1.26.2.1 rmind M_FW, M_NOWAIT | M_ZERO);
230 1.26.2.1 rmind if (fc->topology_map == NULL) {
231 1.26.2.1 rmind aprint_error_dev(fc->dev, "Malloc Failure topology map\n");
232 1.26.2.1 rmind free(fc->crom_src_buf, M_FW);
233 1.26.2.1 rmind return;
234 1.26.2.1 rmind }
235 1.26.2.1 rmind fc->speed_map =
236 1.26.2.1 rmind (struct fw_speed_map *)malloc(sizeof(struct fw_speed_map),
237 1.26.2.1 rmind M_FW, M_NOWAIT | M_ZERO);
238 1.26.2.1 rmind if (fc->speed_map == NULL) {
239 1.26.2.1 rmind aprint_error_dev(fc->dev, "Malloc Failure speed map\n");
240 1.26.2.1 rmind free(fc->crom_src_buf, M_FW);
241 1.26.2.1 rmind free(fc->topology_map, M_FW);
242 1.26.2.1 rmind return;
243 1.26.2.1 rmind }
244 1.26.2.1 rmind
245 1.26.2.1 rmind mutex_init(&fc->tlabel_lock, MUTEX_DEFAULT, IPL_VM);
246 1.26.2.1 rmind mutex_init(&fc->fc_mtx, MUTEX_DEFAULT, IPL_VM);
247 1.26.2.1 rmind mutex_init(&fc->wait_lock, MUTEX_DEFAULT, IPL_VM);
248 1.26.2.1 rmind cv_init(&fc->fc_cv, "ieee1394");
249 1.26.2.1 rmind
250 1.26.2.1 rmind callout_init(&fc->timeout_callout, CALLOUT_MPSAFE);
251 1.26.2.1 rmind callout_setfunc(&fc->timeout_callout, firewire_watchdog, fc);
252 1.26.2.1 rmind callout_init(&fc->bmr_callout, CALLOUT_MPSAFE);
253 1.26.2.1 rmind callout_setfunc(&fc->bmr_callout, fw_try_bmr, fc);
254 1.26.2.1 rmind callout_init(&fc->busprobe_callout, CALLOUT_MPSAFE);
255 1.26.2.1 rmind callout_setfunc(&fc->busprobe_callout, (void *)fw_bus_probe, fc);
256 1.26.2.1 rmind
257 1.26.2.1 rmind callout_schedule(&fc->timeout_callout, hz);
258 1.26.2.1 rmind
259 1.26.2.1 rmind /* create thread */
260 1.26.2.1 rmind if (kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, fw_bus_probe_thread,
261 1.26.2.1 rmind fc, &fc->probe_thread, "fw%dprobe", device_unit(fc->bdev)))
262 1.26.2.1 rmind aprint_error_dev(self, "kthread_create failed\n");
263 1.26.2.1 rmind config_pending_incr();
264 1.26.2.1 rmind
265 1.26.2.1 rmind devlist = malloc(sizeof(struct firewire_dev_list), M_DEVBUF, M_NOWAIT);
266 1.26.2.1 rmind if (devlist == NULL) {
267 1.26.2.1 rmind aprint_error_dev(self, "device list allocation failed\n");
268 1.26.2.1 rmind return;
269 1.26.2.1 rmind }
270 1.26.2.1 rmind
271 1.26.2.1 rmind faa.name = "fwip";
272 1.26.2.1 rmind faa.fc = fc;
273 1.26.2.1 rmind faa.fwdev = NULL;
274 1.26.2.1 rmind devlist->dev = config_found(sc->dev, &faa, firewire_print);
275 1.26.2.1 rmind if (devlist->dev == NULL)
276 1.26.2.1 rmind free(devlist, M_DEVBUF);
277 1.26.2.1 rmind else
278 1.26.2.1 rmind SLIST_INSERT_HEAD(&sc->devlist, devlist, link);
279 1.26.2.1 rmind
280 1.26.2.1 rmind /* bus_reset */
281 1.26.2.1 rmind fw_busreset(fc, FWBUSNOTREADY);
282 1.26.2.1 rmind fc->ibr(fc);
283 1.26.2.1 rmind
284 1.26.2.1 rmind if (!pmf_device_register(self, NULL, NULL))
285 1.26.2.1 rmind aprint_error_dev(self, "couldn't establish power handler\n");
286 1.26.2.1 rmind
287 1.26.2.1 rmind return;
288 1.26.2.1 rmind }
289 1.26.2.1 rmind
290 1.26.2.1 rmind static int
291 1.26.2.1 rmind firewiredetach(device_t self, int flags)
292 1.26.2.1 rmind {
293 1.26.2.1 rmind struct firewire_softc *sc = device_private(self);
294 1.26.2.1 rmind struct firewire_comm *fc;
295 1.26.2.1 rmind struct fw_device *fwdev, *fwdev_next;
296 1.26.2.1 rmind struct firewire_dev_list *devlist;
297 1.26.2.1 rmind int err;
298 1.26.2.1 rmind
299 1.26.2.1 rmind fc = sc->fc;
300 1.26.2.1 rmind mutex_enter(&fc->wait_lock);
301 1.26.2.1 rmind fc->status = FWBUSDETACH;
302 1.26.2.1 rmind cv_signal(&fc->fc_cv);
303 1.26.2.1 rmind while (fc->status != FWBUSDETACHOK) {
304 1.26.2.1 rmind err = cv_timedwait_sig(&fc->fc_cv, &fc->wait_lock, hz * 60);
305 1.26.2.1 rmind if (err == EWOULDBLOCK) {
306 1.26.2.1 rmind aprint_error_dev(self,
307 1.26.2.1 rmind "firewire probe thread didn't die\n");
308 1.26.2.1 rmind break;
309 1.26.2.1 rmind }
310 1.26.2.1 rmind }
311 1.26.2.1 rmind mutex_exit(&fc->wait_lock);
312 1.26.2.1 rmind
313 1.26.2.1 rmind
314 1.26.2.1 rmind while ((devlist = SLIST_FIRST(&sc->devlist)) != NULL) {
315 1.26.2.1 rmind if ((err = config_detach(devlist->dev, flags)) != 0)
316 1.26.2.1 rmind return err;
317 1.26.2.1 rmind SLIST_REMOVE(&sc->devlist, devlist, firewire_dev_list, link);
318 1.26.2.1 rmind free(devlist, M_DEVBUF);
319 1.26.2.1 rmind }
320 1.26.2.1 rmind
321 1.26.2.1 rmind callout_stop(&fc->timeout_callout);
322 1.26.2.1 rmind callout_stop(&fc->bmr_callout);
323 1.26.2.1 rmind callout_stop(&fc->busprobe_callout);
324 1.26.2.1 rmind
325 1.26.2.1 rmind /* XXX xfer_free and untimeout on all xfers */
326 1.26.2.1 rmind for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL;
327 1.26.2.1 rmind fwdev = fwdev_next) {
328 1.26.2.1 rmind fwdev_next = STAILQ_NEXT(fwdev, link);
329 1.26.2.1 rmind free(fwdev, M_FW);
330 1.26.2.1 rmind }
331 1.26.2.1 rmind free(fc->topology_map, M_FW);
332 1.26.2.1 rmind free(fc->speed_map, M_FW);
333 1.26.2.1 rmind free(fc->crom_src_buf, M_FW);
334 1.26.2.1 rmind
335 1.26.2.1 rmind cv_destroy(&fc->fc_cv);
336 1.26.2.1 rmind mutex_destroy(&fc->wait_lock);
337 1.26.2.1 rmind mutex_destroy(&fc->fc_mtx);
338 1.26.2.1 rmind mutex_destroy(&fc->tlabel_lock);
339 1.26.2.1 rmind return 0;
340 1.26.2.1 rmind }
341 1.26.2.1 rmind
342 1.26.2.1 rmind static int
343 1.26.2.1 rmind firewire_print(void *aux, const char *pnp)
344 1.26.2.1 rmind {
345 1.26.2.1 rmind struct fw_attach_args *fwa = (struct fw_attach_args *)aux;
346 1.26.2.1 rmind
347 1.26.2.1 rmind if (pnp)
348 1.26.2.1 rmind aprint_normal("%s at %s", fwa->name, pnp);
349 1.26.2.1 rmind
350 1.26.2.1 rmind return UNCONF;
351 1.26.2.1 rmind }
352 1.26.2.1 rmind
353 1.26.2.1 rmind int
354 1.26.2.1 rmind firewire_resume(struct firewire_comm *fc)
355 1.26.2.1 rmind {
356 1.26.2.1 rmind
357 1.26.2.1 rmind fc->status = FWBUSNOTREADY;
358 1.26.2.1 rmind return 0;
359 1.26.2.1 rmind }
360 1.26.2.1 rmind
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.26.2.1 rmind 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.26.2.1 rmind 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.26.2.1 rmind 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.26.2.1 rmind mutex_exit(&fc->fc_mtx);
392 1.1 kiyohara
393 1.26.2.1 rmind if (fwdev == NULL)
394 1.26.2.1 rmind return NULL;
395 1.26.2.1 rmind if (fwdev->status == FWDEVINVAL)
396 1.26.2.1 rmind 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.26.2.1 rmind if (xfer == NULL)
413 1.26.2.1 rmind return EINVAL;
414 1.26.2.1 rmind if (xfer->hand == NULL) {
415 1.26.2.1 rmind 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.26.2.1 rmind 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.26.2.1 rmind (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.26.2.1 rmind 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.26.2.1 rmind 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.26.2.1 rmind if (len != xfer->send.pay_len) {
453 1.26.2.1 rmind aprint_error_dev(fc->bdev,
454 1.26.2.1 rmind "len(%d) != send.pay_len(%d) %s(%x)\n",
455 1.1 kiyohara len, xfer->send.pay_len, tcode_str[tcode], tcode);
456 1.26.2.1 rmind return EINVAL;
457 1.1 kiyohara }
458 1.1 kiyohara
459 1.26.2.1 rmind if (xferq->start == NULL) {
460 1.26.2.1 rmind aprint_error_dev(fc->bdev, "xferq->start == NULL\n");
461 1.1 kiyohara return EINVAL;
462 1.1 kiyohara }
463 1.26.2.1 rmind if (!(xferq->queued < xferq->maxq)) {
464 1.26.2.1 rmind 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.26.2.1 rmind 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.26.2.1 rmind return 0;
480 1.1 kiyohara }
481 1.26.2.1 rmind
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.26.2.1 rmind mutex_enter(&xfer->fc->wait_lock);
490 1.16 kiyohara xfer->flag |= FWXF_WAKE;
491 1.26.2.1 rmind cv_signal(&xfer->cv);
492 1.26.2.1 rmind 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.26.2.1 rmind int err = 0;
502 1.1 kiyohara
503 1.26.2.1 rmind mutex_enter(&fc->wait_lock);
504 1.26.2.1 rmind while (!(xfer->flag & FWXF_WAKE))
505 1.26.2.1 rmind err = cv_wait_sig(&xfer->cv, &fc->wait_lock);
506 1.26.2.1 rmind mutex_exit(&fc->wait_lock);
507 1.1 kiyohara
508 1.26.2.1 rmind return err;
509 1.1 kiyohara }
510 1.1 kiyohara
511 1.26.2.1 rmind void
512 1.26.2.1 rmind fw_drain_txq(struct firewire_comm *fc)
513 1.1 kiyohara {
514 1.26.2.1 rmind struct fw_xfer *xfer;
515 1.26.2.1 rmind STAILQ_HEAD(, fw_xfer) xfer_drain;
516 1.26.2.1 rmind int i;
517 1.1 kiyohara
518 1.26.2.1 rmind STAILQ_INIT(&xfer_drain);
519 1.1 kiyohara
520 1.26.2.1 rmind mutex_enter(&fc->atq->q_mtx);
521 1.26.2.1 rmind fw_xferq_drain(fc->atq);
522 1.26.2.1 rmind mutex_exit(&fc->atq->q_mtx);
523 1.26.2.1 rmind mutex_enter(&fc->ats->q_mtx);
524 1.26.2.1 rmind fw_xferq_drain(fc->ats);
525 1.26.2.1 rmind mutex_exit(&fc->ats->q_mtx);
526 1.26.2.1 rmind for (i = 0; i < fc->nisodma; i++)
527 1.26.2.1 rmind fw_xferq_drain(fc->it[i]);
528 1.1 kiyohara
529 1.26.2.1 rmind mutex_enter(&fc->tlabel_lock);
530 1.26.2.1 rmind for (i = 0; i < 0x40; i++)
531 1.1 kiyohara while ((xfer = STAILQ_FIRST(&fc->tlabels[i])) != NULL) {
532 1.26.2.1 rmind if (firewire_debug)
533 1.26.2.1 rmind printf("tl=%d flag=%d\n", i, xfer->flag);
534 1.26.2.1 rmind xfer->resp = EAGAIN;
535 1.16 kiyohara STAILQ_REMOVE_HEAD(&fc->tlabels[i], tlabel);
536 1.26.2.1 rmind STAILQ_INSERT_TAIL(&xfer_drain, xfer, tlabel);
537 1.1 kiyohara }
538 1.26.2.1 rmind mutex_exit(&fc->tlabel_lock);
539 1.16 kiyohara
540 1.26.2.1 rmind STAILQ_FOREACH(xfer, &xfer_drain, tlabel)
541 1.26.2.1 rmind xfer->hand(xfer);
542 1.1 kiyohara }
543 1.1 kiyohara
544 1.26.2.1 rmind /*
545 1.26.2.1 rmind * Called after bus reset.
546 1.26.2.1 rmind */
547 1.26.2.1 rmind void
548 1.26.2.1 rmind fw_busreset(struct firewire_comm *fc, uint32_t new_status)
549 1.1 kiyohara {
550 1.26.2.1 rmind struct firewire_softc *sc = device_private(fc->bdev);
551 1.26.2.1 rmind struct firewire_dev_list *devlist;
552 1.26.2.1 rmind struct firewire_dev_comm *fdc;
553 1.26.2.1 rmind struct crom_src *src;
554 1.26.2.1 rmind uint32_t *newrom;
555 1.1 kiyohara
556 1.26.2.1 rmind if (fc->status == FWBUSMGRELECT)
557 1.26.2.1 rmind callout_stop(&fc->bmr_callout);
558 1.26.2.1 rmind
559 1.26.2.1 rmind fc->status = new_status;
560 1.26.2.1 rmind fw_reset_csr(fc);
561 1.26.2.1 rmind
562 1.26.2.1 rmind if (fc->status == FWBUSNOTREADY)
563 1.26.2.1 rmind fw_init_crom(fc);
564 1.26.2.1 rmind
565 1.26.2.1 rmind fw_reset_crom(fc);
566 1.26.2.1 rmind
567 1.26.2.1 rmind /* How many safe this access? */
568 1.26.2.1 rmind SLIST_FOREACH(devlist, &sc->devlist, link) {
569 1.26.2.1 rmind fdc = device_private(devlist->dev);
570 1.26.2.1 rmind if (fdc->post_busreset != NULL)
571 1.26.2.1 rmind fdc->post_busreset(fdc);
572 1.26.2.1 rmind }
573 1.1 kiyohara
574 1.1 kiyohara /*
575 1.26.2.1 rmind * If the old config rom needs to be overwritten,
576 1.26.2.1 rmind * bump the businfo.generation indicator to
577 1.26.2.1 rmind * indicate that we need to be reprobed
578 1.26.2.1 rmind * See 1394a-2000 8.3.2.5.4 for more details.
579 1.26.2.1 rmind * generation starts at 2 and rolls over at 0xF
580 1.26.2.1 rmind * back to 2.
581 1.26.2.1 rmind *
582 1.26.2.1 rmind * A generation of 0 indicates a device
583 1.26.2.1 rmind * that is not 1394a-2000 compliant.
584 1.26.2.1 rmind * A generation of 1 indicates a device that
585 1.26.2.1 rmind * does not change it's Bus Info Block or
586 1.26.2.1 rmind * Configuration ROM.
587 1.1 kiyohara */
588 1.26.2.1 rmind #define FW_MAX_GENERATION 0xF
589 1.26.2.1 rmind newrom = malloc(CROMSIZE, M_FW, M_NOWAIT | M_ZERO);
590 1.26.2.1 rmind src = &fc->crom_src_buf->src;
591 1.26.2.1 rmind crom_load(src, newrom, CROMSIZE);
592 1.26.2.1 rmind if (memcmp(newrom, fc->config_rom, CROMSIZE) != 0) {
593 1.26.2.1 rmind if (src->businfo.generation++ > FW_MAX_GENERATION)
594 1.26.2.1 rmind src->businfo.generation = FW_GENERATION_CHANGEABLE;
595 1.26.2.1 rmind memcpy((void *)fc->config_rom, newrom, CROMSIZE);
596 1.26.2.1 rmind }
597 1.26.2.1 rmind free(newrom, M_FW);
598 1.1 kiyohara }
599 1.1 kiyohara
600 1.26.2.1 rmind /* Call once after reboot */
601 1.26.2.1 rmind void
602 1.26.2.1 rmind fw_init(struct firewire_comm *fc)
603 1.1 kiyohara {
604 1.26.2.1 rmind int i;
605 1.1 kiyohara
606 1.26.2.1 rmind fc->arq->queued = 0;
607 1.26.2.1 rmind fc->ars->queued = 0;
608 1.26.2.1 rmind fc->atq->queued = 0;
609 1.26.2.1 rmind fc->ats->queued = 0;
610 1.26 mrg
611 1.26.2.1 rmind fc->arq->buf = NULL;
612 1.26.2.1 rmind fc->ars->buf = NULL;
613 1.26.2.1 rmind fc->atq->buf = NULL;
614 1.26.2.1 rmind fc->ats->buf = NULL;
615 1.1 kiyohara
616 1.26.2.1 rmind fc->arq->flag = 0;
617 1.26.2.1 rmind fc->ars->flag = 0;
618 1.26.2.1 rmind fc->atq->flag = 0;
619 1.26.2.1 rmind fc->ats->flag = 0;
620 1.1 kiyohara
621 1.26.2.1 rmind STAILQ_INIT(&fc->atq->q);
622 1.26.2.1 rmind STAILQ_INIT(&fc->ats->q);
623 1.26.2.1 rmind mutex_init(&fc->arq->q_mtx, MUTEX_DEFAULT, IPL_VM);
624 1.26.2.1 rmind mutex_init(&fc->ars->q_mtx, MUTEX_DEFAULT, IPL_VM);
625 1.26.2.1 rmind mutex_init(&fc->atq->q_mtx, MUTEX_DEFAULT, IPL_VM);
626 1.26.2.1 rmind mutex_init(&fc->ats->q_mtx, MUTEX_DEFAULT, IPL_VM);
627 1.1 kiyohara
628 1.26.2.1 rmind for (i = 0; i < fc->nisodma; i++) {
629 1.26.2.1 rmind fc->it[i]->queued = 0;
630 1.26.2.1 rmind fc->ir[i]->queued = 0;
631 1.1 kiyohara
632 1.26.2.1 rmind fc->it[i]->start = NULL;
633 1.26.2.1 rmind fc->ir[i]->start = NULL;
634 1.1 kiyohara
635 1.26.2.1 rmind fc->it[i]->buf = NULL;
636 1.26.2.1 rmind fc->ir[i]->buf = NULL;
637 1.1 kiyohara
638 1.26.2.1 rmind fc->it[i]->flag = FWXFERQ_STREAM;
639 1.26.2.1 rmind fc->ir[i]->flag = FWXFERQ_STREAM;
640 1.1 kiyohara
641 1.26.2.1 rmind STAILQ_INIT(&fc->it[i]->q);
642 1.26.2.1 rmind STAILQ_INIT(&fc->ir[i]->q);
643 1.26.2.1 rmind }
644 1.1 kiyohara
645 1.26.2.1 rmind fc->arq->maxq = FWMAXQUEUE;
646 1.26.2.1 rmind fc->ars->maxq = FWMAXQUEUE;
647 1.26.2.1 rmind fc->atq->maxq = FWMAXQUEUE;
648 1.26.2.1 rmind fc->ats->maxq = FWMAXQUEUE;
649 1.26.2.1 rmind
650 1.26.2.1 rmind for (i = 0; i < fc->nisodma; i++) {
651 1.26.2.1 rmind fc->ir[i]->maxq = FWMAXQUEUE;
652 1.26.2.1 rmind fc->it[i]->maxq = FWMAXQUEUE;
653 1.26.2.1 rmind }
654 1.26.2.1 rmind
655 1.26.2.1 rmind CSRARC(fc, TOPO_MAP) = 0x3f1 << 16;
656 1.26.2.1 rmind CSRARC(fc, TOPO_MAP + 4) = 1;
657 1.26.2.1 rmind CSRARC(fc, SPED_MAP) = 0x3f1 << 16;
658 1.26.2.1 rmind CSRARC(fc, SPED_MAP + 4) = 1;
659 1.26.2.1 rmind
660 1.26.2.1 rmind STAILQ_INIT(&fc->devices);
661 1.26.2.1 rmind
662 1.26.2.1 rmind /* Initialize Async handlers */
663 1.26.2.1 rmind STAILQ_INIT(&fc->binds);
664 1.26.2.1 rmind for (i = 0; i < 0x40; i++)
665 1.26.2.1 rmind STAILQ_INIT(&fc->tlabels[i]);
666 1.26.2.1 rmind
667 1.26.2.1 rmind /* DV depend CSRs see blue book */
668 1.26.2.1 rmind #if 0
669 1.26.2.1 rmind CSRARC(fc, oMPR) = 0x3fff0001; /* # output channel = 1 */
670 1.26.2.1 rmind CSRARC(fc, oPCR) = 0x8000007a;
671 1.26.2.1 rmind for (i = 4; i < 0x7c/4; i+=4)
672 1.26.2.1 rmind CSRARC(fc, i + oPCR) = 0x8000007a;
673 1.26.2.1 rmind
674 1.26.2.1 rmind CSRARC(fc, iMPR) = 0x00ff0001; /* # input channel = 1 */
675 1.26.2.1 rmind CSRARC(fc, iPCR) = 0x803f0000;
676 1.26.2.1 rmind for (i = 4; i < 0x7c/4; i+=4)
677 1.26.2.1 rmind CSRARC(fc, i + iPCR) = 0x0;
678 1.17 jmcneill #endif
679 1.17 jmcneill
680 1.26.2.1 rmind fc->crom_src_buf = NULL;
681 1.1 kiyohara }
682 1.1 kiyohara
683 1.26.2.1 rmind #define BIND_CMP(addr, fwb) \
684 1.26.2.1 rmind (((addr) < (fwb)->start) ? -1 : ((fwb)->end < (addr)) ? 1 : 0)
685 1.26.2.1 rmind
686 1.1 kiyohara /*
687 1.26.2.1 rmind * To lookup bound process from IEEE1394 address.
688 1.1 kiyohara */
689 1.26.2.1 rmind struct fw_bind *
690 1.26.2.1 rmind fw_bindlookup(struct firewire_comm *fc, uint16_t dest_hi, uint32_t dest_lo)
691 1.1 kiyohara {
692 1.26.2.1 rmind u_int64_t addr;
693 1.26.2.1 rmind struct fw_bind *tfw, *r = NULL;
694 1.26.2.1 rmind
695 1.26.2.1 rmind addr = ((u_int64_t)dest_hi << 32) | dest_lo;
696 1.26.2.1 rmind mutex_enter(&fc->fc_mtx);
697 1.26.2.1 rmind STAILQ_FOREACH(tfw, &fc->binds, fclist)
698 1.26.2.1 rmind if (BIND_CMP(addr, tfw) == 0) {
699 1.26.2.1 rmind r = tfw;
700 1.26.2.1 rmind break;
701 1.26.2.1 rmind }
702 1.26.2.1 rmind mutex_exit(&fc->fc_mtx);
703 1.26.2.1 rmind return r;
704 1.26.2.1 rmind }
705 1.26.2.1 rmind
706 1.26.2.1 rmind /*
707 1.26.2.1 rmind * To bind IEEE1394 address block to process.
708 1.26.2.1 rmind */
709 1.26.2.1 rmind int
710 1.26.2.1 rmind fw_bindadd(struct firewire_comm *fc, struct fw_bind *fwb)
711 1.26.2.1 rmind {
712 1.26.2.1 rmind struct fw_bind *tfw, *prev = NULL;
713 1.26.2.1 rmind int r = 0;
714 1.1 kiyohara
715 1.26.2.1 rmind if (fwb->start > fwb->end) {
716 1.26.2.1 rmind aprint_error_dev(fc->bdev, "invalid range\n");
717 1.26.2.1 rmind return EINVAL;
718 1.1 kiyohara }
719 1.1 kiyohara
720 1.26.2.1 rmind mutex_enter(&fc->fc_mtx);
721 1.26.2.1 rmind STAILQ_FOREACH(tfw, &fc->binds, fclist) {
722 1.26.2.1 rmind if (fwb->end < tfw->start)
723 1.26.2.1 rmind break;
724 1.26.2.1 rmind prev = tfw;
725 1.26.2.1 rmind }
726 1.26.2.1 rmind if (prev == NULL)
727 1.26.2.1 rmind STAILQ_INSERT_HEAD(&fc->binds, fwb, fclist);
728 1.26.2.1 rmind else if (prev->end < fwb->start)
729 1.26.2.1 rmind STAILQ_INSERT_AFTER(&fc->binds, prev, fwb, fclist);
730 1.26.2.1 rmind else {
731 1.26.2.1 rmind aprint_error_dev(fc->bdev, "bind failed\n");
732 1.26.2.1 rmind r = EBUSY;
733 1.26.2.1 rmind }
734 1.26.2.1 rmind mutex_exit(&fc->fc_mtx);
735 1.26.2.1 rmind return r;
736 1.1 kiyohara }
737 1.1 kiyohara
738 1.26.2.1 rmind /*
739 1.26.2.1 rmind * To free IEEE1394 address block.
740 1.26.2.1 rmind */
741 1.26.2.1 rmind int
742 1.26.2.1 rmind fw_bindremove(struct firewire_comm *fc, struct fw_bind *fwb)
743 1.1 kiyohara {
744 1.26.2.1 rmind #if 0
745 1.26.2.1 rmind struct fw_xfer *xfer, *next;
746 1.26.2.1 rmind #endif
747 1.26.2.1 rmind struct fw_bind *tfw;
748 1.26.2.1 rmind
749 1.26.2.1 rmind mutex_enter(&fc->fc_mtx);
750 1.26.2.1 rmind STAILQ_FOREACH(tfw, &fc->binds, fclist)
751 1.26.2.1 rmind if (tfw == fwb) {
752 1.26.2.1 rmind STAILQ_REMOVE(&fc->binds, fwb, fw_bind, fclist);
753 1.26.2.1 rmind mutex_exit(&fc->fc_mtx);
754 1.26.2.1 rmind goto found;
755 1.26.2.1 rmind }
756 1.1 kiyohara
757 1.26.2.1 rmind mutex_exit(&fc->fc_mtx);
758 1.26.2.1 rmind aprint_error_dev(fc->bdev, "no such binding\n");
759 1.26.2.1 rmind return 1;
760 1.26.2.1 rmind found:
761 1.26.2.1 rmind #if 0
762 1.26.2.1 rmind /* shall we do this? */
763 1.26.2.1 rmind for (xfer = STAILQ_FIRST(&fwb->xferlist); xfer != NULL; xfer = next) {
764 1.26.2.1 rmind next = STAILQ_NEXT(xfer, link);
765 1.26.2.1 rmind fw_xfer_free(xfer);
766 1.26.2.1 rmind }
767 1.26.2.1 rmind STAILQ_INIT(&fwb->xferlist);
768 1.26.2.1 rmind #endif
769 1.1 kiyohara
770 1.26.2.1 rmind return 0;
771 1.26.2.1 rmind }
772 1.26.2.1 rmind
773 1.26.2.1 rmind int
774 1.26.2.1 rmind fw_xferlist_add(struct fw_xferlist *q, struct malloc_type *type, int slen,
775 1.26.2.1 rmind int rlen, int n, struct firewire_comm *fc, void *sc,
776 1.26.2.1 rmind void (*hand)(struct fw_xfer *))
777 1.26.2.1 rmind {
778 1.26.2.1 rmind struct fw_xfer *xfer;
779 1.26.2.1 rmind int i;
780 1.26.2.1 rmind
781 1.26.2.1 rmind for (i = 0; i < n; i++) {
782 1.26.2.1 rmind xfer = fw_xfer_alloc_buf(type, slen, rlen);
783 1.26.2.1 rmind if (xfer == NULL)
784 1.26.2.1 rmind return n;
785 1.26.2.1 rmind xfer->fc = fc;
786 1.26.2.1 rmind xfer->sc = sc;
787 1.26.2.1 rmind xfer->hand = hand;
788 1.26.2.1 rmind STAILQ_INSERT_TAIL(q, xfer, link);
789 1.26.2.1 rmind }
790 1.26.2.1 rmind return n;
791 1.26.2.1 rmind }
792 1.26.2.1 rmind
793 1.26.2.1 rmind void
794 1.26.2.1 rmind fw_xferlist_remove(struct fw_xferlist *q)
795 1.26.2.1 rmind {
796 1.26.2.1 rmind struct fw_xfer *xfer, *next;
797 1.26.2.1 rmind
798 1.26.2.1 rmind for (xfer = STAILQ_FIRST(q); xfer != NULL; xfer = next) {
799 1.26.2.1 rmind next = STAILQ_NEXT(xfer, link);
800 1.26.2.1 rmind fw_xfer_free_buf(xfer);
801 1.26.2.1 rmind }
802 1.26.2.1 rmind STAILQ_INIT(q);
803 1.1 kiyohara }
804 1.1 kiyohara
805 1.1 kiyohara /*
806 1.26.2.1 rmind * To allocate IEEE1394 XFER structure.
807 1.1 kiyohara */
808 1.26.2.1 rmind struct fw_xfer *
809 1.26.2.1 rmind fw_xfer_alloc(struct malloc_type *type)
810 1.1 kiyohara {
811 1.26.2.1 rmind struct fw_xfer *xfer;
812 1.1 kiyohara
813 1.26.2.1 rmind xfer = malloc(sizeof(struct fw_xfer), type, M_NOWAIT | M_ZERO);
814 1.26.2.1 rmind if (xfer == NULL)
815 1.26.2.1 rmind return xfer;
816 1.1 kiyohara
817 1.26.2.1 rmind xfer->malloc = type;
818 1.26.2.1 rmind cv_init(&xfer->cv, "fwxfer");
819 1.26.2.1 rmind
820 1.26.2.1 rmind return xfer;
821 1.26.2.1 rmind }
822 1.26.2.1 rmind
823 1.26.2.1 rmind struct fw_xfer *
824 1.26.2.1 rmind fw_xfer_alloc_buf(struct malloc_type *type, int send_len, int recv_len)
825 1.26.2.1 rmind {
826 1.26.2.1 rmind struct fw_xfer *xfer;
827 1.26.2.1 rmind
828 1.26.2.1 rmind xfer = fw_xfer_alloc(type);
829 1.26.2.1 rmind if (xfer == NULL)
830 1.26.2.1 rmind return NULL;
831 1.26.2.1 rmind xfer->send.pay_len = send_len;
832 1.26.2.1 rmind xfer->recv.pay_len = recv_len;
833 1.26.2.1 rmind if (send_len > 0) {
834 1.26.2.1 rmind xfer->send.payload = malloc(send_len, type, M_NOWAIT | M_ZERO);
835 1.26.2.1 rmind if (xfer->send.payload == NULL) {
836 1.26.2.1 rmind fw_xfer_free(xfer);
837 1.26.2.1 rmind return NULL;
838 1.26.2.1 rmind }
839 1.1 kiyohara }
840 1.26.2.1 rmind if (recv_len > 0) {
841 1.26.2.1 rmind xfer->recv.payload = malloc(recv_len, type, M_NOWAIT);
842 1.26.2.1 rmind if (xfer->recv.payload == NULL) {
843 1.26.2.1 rmind if (xfer->send.payload != NULL)
844 1.26.2.1 rmind free(xfer->send.payload, type);
845 1.26.2.1 rmind fw_xfer_free(xfer);
846 1.26.2.1 rmind return NULL;
847 1.26.2.1 rmind }
848 1.26.2.1 rmind }
849 1.26.2.1 rmind return xfer;
850 1.26.2.1 rmind }
851 1.26.2.1 rmind
852 1.26.2.1 rmind /*
853 1.26.2.1 rmind * IEEE1394 XFER post process.
854 1.26.2.1 rmind */
855 1.26.2.1 rmind void
856 1.26.2.1 rmind fw_xfer_done(struct fw_xfer *xfer)
857 1.26.2.1 rmind {
858 1.26.2.1 rmind
859 1.26.2.1 rmind if (xfer->hand == NULL) {
860 1.26.2.1 rmind aprint_error_dev(xfer->fc->bdev, "hand == NULL\n");
861 1.26.2.1 rmind return;
862 1.26.2.1 rmind }
863 1.26.2.1 rmind
864 1.26.2.1 rmind if (xfer->fc == NULL)
865 1.26.2.1 rmind panic("fw_xfer_done: why xfer->fc is NULL?");
866 1.1 kiyohara
867 1.26.2.1 rmind fw_tl_free(xfer->fc, xfer);
868 1.26.2.1 rmind xfer->hand(xfer);
869 1.1 kiyohara }
870 1.26.2.1 rmind
871 1.26.2.1 rmind void
872 1.26.2.1 rmind fw_xfer_unload(struct fw_xfer* xfer)
873 1.26.2.1 rmind {
874 1.26.2.1 rmind
875 1.26.2.1 rmind if (xfer == NULL)
876 1.26.2.1 rmind return;
877 1.26.2.1 rmind if (xfer->flag & FWXF_INQ) {
878 1.26.2.1 rmind aprint_error_dev(xfer->fc->bdev, "fw_xfer_free FWXF_INQ\n");
879 1.26.2.1 rmind mutex_enter(&xfer->q->q_mtx);
880 1.26.2.1 rmind STAILQ_REMOVE(&xfer->q->q, xfer, fw_xfer, link);
881 1.1 kiyohara #if 0
882 1.26.2.1 rmind xfer->q->queued--;
883 1.26.2.1 rmind #endif
884 1.26.2.1 rmind mutex_exit(&xfer->q->q_mtx);
885 1.26.2.1 rmind }
886 1.26.2.1 rmind if (xfer->fc != NULL) {
887 1.26.2.1 rmind #if 1
888 1.26.2.1 rmind if (xfer->flag == FWXF_START)
889 1.26.2.1 rmind /*
890 1.26.2.1 rmind * This could happen if:
891 1.26.2.1 rmind * 1. We call fwohci_arcv() before fwohci_txd().
892 1.26.2.1 rmind * 2. firewire_watch() is called.
893 1.26.2.1 rmind */
894 1.26.2.1 rmind aprint_error_dev(xfer->fc->bdev,
895 1.26.2.1 rmind "fw_xfer_free FWXF_START\n");
896 1.26.2.1 rmind #endif
897 1.26.2.1 rmind }
898 1.26.2.1 rmind xfer->flag = FWXF_INIT;
899 1.26.2.1 rmind xfer->resp = 0;
900 1.26.2.1 rmind }
901 1.26.2.1 rmind
902 1.26.2.1 rmind /*
903 1.26.2.1 rmind * To free IEEE1394 XFER structure.
904 1.26.2.1 rmind */
905 1.26.2.1 rmind void
906 1.26.2.1 rmind fw_xfer_free(struct fw_xfer* xfer)
907 1.1 kiyohara {
908 1.26.2.1 rmind
909 1.26.2.1 rmind if (xfer == NULL) {
910 1.26.2.1 rmind aprint_error_dev(xfer->fc->bdev, "xfer == NULL\n");
911 1.26.2.1 rmind return;
912 1.26.2.1 rmind }
913 1.26.2.1 rmind fw_xfer_unload(xfer);
914 1.26.2.1 rmind cv_destroy(&xfer->cv);
915 1.26.2.1 rmind free(xfer, xfer->malloc);
916 1.1 kiyohara }
917 1.26.2.1 rmind
918 1.26.2.1 rmind void
919 1.26.2.1 rmind fw_xfer_free_buf(struct fw_xfer* xfer)
920 1.1 kiyohara {
921 1.1 kiyohara
922 1.26.2.1 rmind if (xfer == NULL) {
923 1.26.2.1 rmind aprint_error_dev(xfer->fc->bdev, "xfer == NULL\n");
924 1.26.2.1 rmind return;
925 1.26.2.1 rmind }
926 1.26.2.1 rmind fw_xfer_unload(xfer);
927 1.26.2.1 rmind if (xfer->send.payload != NULL) {
928 1.26.2.1 rmind free(xfer->send.payload, xfer->malloc);
929 1.26.2.1 rmind }
930 1.26.2.1 rmind if (xfer->recv.payload != NULL) {
931 1.26.2.1 rmind free(xfer->recv.payload, xfer->malloc);
932 1.26.2.1 rmind }
933 1.26.2.1 rmind cv_destroy(&xfer->cv);
934 1.26.2.1 rmind free(xfer, xfer->malloc);
935 1.26.2.1 rmind }
936 1.26.2.1 rmind
937 1.26.2.1 rmind void
938 1.26.2.1 rmind fw_asy_callback_free(struct fw_xfer *xfer)
939 1.26.2.1 rmind {
940 1.26.2.1 rmind
941 1.26.2.1 rmind #if 0
942 1.26.2.1 rmind printf("asyreq done flag=%d resp=%d\n", xfer->flag, xfer->resp);
943 1.26.2.1 rmind #endif
944 1.26.2.1 rmind fw_xfer_free(xfer);
945 1.26.2.1 rmind }
946 1.26.2.1 rmind
947 1.26.2.1 rmind /*
948 1.26.2.1 rmind * To receive self ID.
949 1.26.2.1 rmind */
950 1.26.2.1 rmind void
951 1.26.2.1 rmind fw_sidrcv(struct firewire_comm* fc, uint32_t *sid, u_int len)
952 1.26.2.1 rmind {
953 1.26.2.1 rmind uint32_t *p;
954 1.26.2.1 rmind union fw_self_id *self_id;
955 1.26.2.1 rmind u_int i, j, node, c_port = 0, i_branch = 0;
956 1.26.2.1 rmind
957 1.26.2.1 rmind fc->sid_cnt = len / (sizeof(uint32_t) * 2);
958 1.26.2.1 rmind fc->max_node = fc->nodeid & 0x3f;
959 1.26.2.1 rmind CSRARC(fc, NODE_IDS) = ((uint32_t)fc->nodeid) << 16;
960 1.26.2.1 rmind fc->status = FWBUSCYMELECT;
961 1.26.2.1 rmind fc->topology_map->crc_len = 2;
962 1.26.2.1 rmind fc->topology_map->generation++;
963 1.26.2.1 rmind fc->topology_map->self_id_count = 0;
964 1.26.2.1 rmind fc->topology_map->node_count = 0;
965 1.26.2.1 rmind fc->speed_map->generation++;
966 1.26.2.1 rmind fc->speed_map->crc_len = 1 + (64*64 + 3) / 4;
967 1.26.2.1 rmind self_id = fc->topology_map->self_id;
968 1.26.2.1 rmind for (i = 0; i < fc->sid_cnt; i++) {
969 1.26.2.1 rmind if (sid[1] != ~sid[0]) {
970 1.26.2.1 rmind aprint_error_dev(fc->bdev,
971 1.26.2.1 rmind "ERROR invalid self-id packet\n");
972 1.26.2.1 rmind sid += 2;
973 1.26.2.1 rmind continue;
974 1.26.2.1 rmind }
975 1.26.2.1 rmind *self_id = *((union fw_self_id *)sid);
976 1.26.2.1 rmind fc->topology_map->crc_len++;
977 1.26.2.1 rmind if (self_id->p0.sequel == 0) {
978 1.26.2.1 rmind fc->topology_map->node_count++;
979 1.26.2.1 rmind c_port = 0;
980 1.26.2.1 rmind if (firewire_debug)
981 1.26.2.1 rmind fw_print_sid(sid[0]);
982 1.26.2.1 rmind node = self_id->p0.phy_id;
983 1.26.2.1 rmind if (fc->max_node < node)
984 1.26.2.1 rmind fc->max_node = self_id->p0.phy_id;
985 1.26.2.1 rmind /* XXX I'm not sure this is the right speed_map */
986 1.26.2.1 rmind fc->speed_map->speed[node][node] =
987 1.26.2.1 rmind self_id->p0.phy_speed;
988 1.26.2.1 rmind for (j = 0; j < node; j++)
989 1.26.2.1 rmind fc->speed_map->speed[j][node] =
990 1.26.2.1 rmind fc->speed_map->speed[node][j] =
991 1.26.2.1 rmind min(fc->speed_map->speed[j][j],
992 1.26.2.1 rmind self_id->p0.phy_speed);
993 1.26.2.1 rmind if ((fc->irm == -1 || self_id->p0.phy_id > fc->irm) &&
994 1.26.2.1 rmind (self_id->p0.link_active && self_id->p0.contender))
995 1.26.2.1 rmind fc->irm = self_id->p0.phy_id;
996 1.26.2.1 rmind if (self_id->p0.port0 >= 0x2)
997 1.26.2.1 rmind c_port++;
998 1.26.2.1 rmind if (self_id->p0.port1 >= 0x2)
999 1.26.2.1 rmind c_port++;
1000 1.26.2.1 rmind if (self_id->p0.port2 >= 0x2)
1001 1.26.2.1 rmind c_port++;
1002 1.26.2.1 rmind }
1003 1.26.2.1 rmind if (c_port > 2)
1004 1.26.2.1 rmind i_branch += (c_port - 2);
1005 1.26.2.1 rmind sid += 2;
1006 1.26.2.1 rmind self_id++;
1007 1.26.2.1 rmind fc->topology_map->self_id_count++;
1008 1.26.2.1 rmind }
1009 1.26.2.1 rmind /* CRC */
1010 1.26.2.1 rmind fc->topology_map->crc =
1011 1.26.2.1 rmind fw_crc16((uint32_t *)&fc->topology_map->generation,
1012 1.26.2.1 rmind fc->topology_map->crc_len * 4);
1013 1.26.2.1 rmind fc->speed_map->crc = fw_crc16((uint32_t *)&fc->speed_map->generation,
1014 1.26.2.1 rmind fc->speed_map->crc_len * 4);
1015 1.26.2.1 rmind /* byteswap and copy to CSR */
1016 1.26.2.1 rmind p = (uint32_t *)fc->topology_map;
1017 1.26.2.1 rmind for (i = 0; i <= fc->topology_map->crc_len; i++)
1018 1.26.2.1 rmind CSRARC(fc, TOPO_MAP + i * 4) = htonl(*p++);
1019 1.26.2.1 rmind p = (uint32_t *)fc->speed_map;
1020 1.26.2.1 rmind CSRARC(fc, SPED_MAP) = htonl(*p++);
1021 1.26.2.1 rmind CSRARC(fc, SPED_MAP + 4) = htonl(*p++);
1022 1.26.2.1 rmind /* don't byte-swap uint8_t array */
1023 1.26.2.1 rmind memcpy(&CSRARC(fc, SPED_MAP + 8), p, (fc->speed_map->crc_len - 1) * 4);
1024 1.26.2.1 rmind
1025 1.26.2.1 rmind fc->max_hop = fc->max_node - i_branch;
1026 1.26.2.1 rmind aprint_normal_dev(fc->bdev, "%d nodes, maxhop <= %d %s irm(%d)%s\n",
1027 1.26.2.1 rmind fc->max_node + 1, fc->max_hop,
1028 1.26.2.1 rmind (fc->irm == -1) ? "Not IRM capable" : "cable IRM",
1029 1.26.2.1 rmind fc->irm,
1030 1.26.2.1 rmind (fc->irm == fc->nodeid) ? " (me)" : "");
1031 1.26.2.1 rmind
1032 1.26.2.1 rmind if (try_bmr && (fc->irm != -1) && (CSRARC(fc, BUS_MGR_ID) == 0x3f)) {
1033 1.26.2.1 rmind if (fc->irm == fc->nodeid) {
1034 1.26.2.1 rmind fc->status = FWBUSMGRDONE;
1035 1.26.2.1 rmind CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, fc->irm);
1036 1.26.2.1 rmind fw_bmr(fc);
1037 1.26.2.1 rmind } else {
1038 1.26.2.1 rmind fc->status = FWBUSMGRELECT;
1039 1.26.2.1 rmind callout_schedule(&fc->bmr_callout, hz/8);
1040 1.26.2.1 rmind }
1041 1.26.2.1 rmind } else
1042 1.26.2.1 rmind fc->status = FWBUSMGRDONE;
1043 1.26.2.1 rmind
1044 1.26.2.1 rmind callout_schedule(&fc->busprobe_callout, hz/4);
1045 1.26.2.1 rmind }
1046 1.26.2.1 rmind
1047 1.26.2.1 rmind /*
1048 1.26.2.1 rmind * Generic packet receiving process.
1049 1.26.2.1 rmind */
1050 1.26.2.1 rmind void
1051 1.26.2.1 rmind fw_rcv(struct fw_rcv_buf *rb)
1052 1.26.2.1 rmind {
1053 1.26.2.1 rmind struct fw_pkt *fp, *resfp;
1054 1.26.2.1 rmind struct fw_bind *bind;
1055 1.26.2.1 rmind int tcode;
1056 1.26.2.1 rmind int i, len, oldstate;
1057 1.26.2.1 rmind #if 0
1058 1.26.2.1 rmind {
1059 1.26.2.1 rmind uint32_t *qld;
1060 1.26.2.1 rmind int i;
1061 1.26.2.1 rmind qld = (uint32_t *)buf;
1062 1.26.2.1 rmind printf("spd %d len:%d\n", spd, len);
1063 1.26.2.1 rmind for (i = 0; i <= len && i < 32; i+= 4) {
1064 1.26.2.1 rmind printf("0x%08x ", ntohl(qld[i/4]));
1065 1.26.2.1 rmind if ((i % 16) == 15) printf("\n");
1066 1.26.2.1 rmind }
1067 1.26.2.1 rmind if ((i % 16) != 15) printf("\n");
1068 1.26.2.1 rmind }
1069 1.26.2.1 rmind #endif
1070 1.26.2.1 rmind fp = (struct fw_pkt *)rb->vec[0].iov_base;
1071 1.26.2.1 rmind tcode = fp->mode.common.tcode;
1072 1.26.2.1 rmind switch (tcode) {
1073 1.26.2.1 rmind case FWTCODE_WRES:
1074 1.26.2.1 rmind case FWTCODE_RRESQ:
1075 1.26.2.1 rmind case FWTCODE_RRESB:
1076 1.26.2.1 rmind case FWTCODE_LRES:
1077 1.26.2.1 rmind rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src,
1078 1.26.2.1 rmind fp->mode.hdr.tlrt >> 2, tcode);
1079 1.26.2.1 rmind if (rb->xfer == NULL) {
1080 1.26.2.1 rmind aprint_error_dev(rb->fc->bdev, "unknown response"
1081 1.26.2.1 rmind " %s(%x) src=0x%x tl=0x%x rt=%d data=0x%x\n",
1082 1.26.2.1 rmind tcode_str[tcode], tcode,
1083 1.26.2.1 rmind fp->mode.hdr.src,
1084 1.26.2.1 rmind fp->mode.hdr.tlrt >> 2,
1085 1.26.2.1 rmind fp->mode.hdr.tlrt & 3,
1086 1.26.2.1 rmind fp->mode.rresq.data);
1087 1.26.2.1 rmind #if 0
1088 1.26.2.1 rmind printf("try ad-hoc work around!!\n");
1089 1.26.2.1 rmind rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src,
1090 1.26.2.1 rmind (fp->mode.hdr.tlrt >> 2) ^ 3);
1091 1.26.2.1 rmind if (rb->xfer == NULL) {
1092 1.26.2.1 rmind printf("no use...\n");
1093 1.26.2.1 rmind return;
1094 1.26.2.1 rmind }
1095 1.26.2.1 rmind #else
1096 1.26.2.1 rmind return;
1097 1.26.2.1 rmind #endif
1098 1.26.2.1 rmind }
1099 1.26.2.1 rmind fw_rcv_copy(rb);
1100 1.26.2.1 rmind if (rb->xfer->recv.hdr.mode.wres.rtcode != RESP_CMP)
1101 1.26.2.1 rmind rb->xfer->resp = EIO;
1102 1.26.2.1 rmind else
1103 1.26.2.1 rmind rb->xfer->resp = 0;
1104 1.26.2.1 rmind /* make sure the packet is drained in AT queue */
1105 1.26.2.1 rmind oldstate = rb->xfer->flag;
1106 1.26.2.1 rmind rb->xfer->flag = FWXF_RCVD;
1107 1.26.2.1 rmind switch (oldstate) {
1108 1.26.2.1 rmind case FWXF_SENT:
1109 1.26.2.1 rmind fw_xfer_done(rb->xfer);
1110 1.26.2.1 rmind break;
1111 1.26.2.1 rmind case FWXF_START:
1112 1.26.2.1 rmind #if 0
1113 1.26.2.1 rmind if (firewire_debug)
1114 1.26.2.1 rmind printf("not sent yet tl=%x\n", rb->xfer->tl);
1115 1.26.2.1 rmind #endif
1116 1.26.2.1 rmind break;
1117 1.26.2.1 rmind default:
1118 1.26.2.1 rmind aprint_error_dev(rb->fc->bdev,
1119 1.26.2.1 rmind "unexpected flag 0x%02x\n", rb->xfer->flag);
1120 1.26.2.1 rmind }
1121 1.26.2.1 rmind return;
1122 1.26.2.1 rmind case FWTCODE_WREQQ:
1123 1.26.2.1 rmind case FWTCODE_WREQB:
1124 1.26.2.1 rmind case FWTCODE_RREQQ:
1125 1.26.2.1 rmind case FWTCODE_RREQB:
1126 1.26.2.1 rmind case FWTCODE_LREQ:
1127 1.26.2.1 rmind bind = fw_bindlookup(rb->fc, fp->mode.rreqq.dest_hi,
1128 1.26.2.1 rmind fp->mode.rreqq.dest_lo);
1129 1.26.2.1 rmind if (bind == NULL) {
1130 1.26.2.1 rmind #if 1
1131 1.26.2.1 rmind aprint_error_dev(rb->fc->bdev, "Unknown service addr"
1132 1.26.2.1 rmind " 0x%04x:0x%08x %s(%x) src=0x%x data=%x\n",
1133 1.26.2.1 rmind fp->mode.wreqq.dest_hi, fp->mode.wreqq.dest_lo,
1134 1.26.2.1 rmind tcode_str[tcode], tcode,
1135 1.26.2.1 rmind fp->mode.hdr.src, ntohl(fp->mode.wreqq.data));
1136 1.26.2.1 rmind #endif
1137 1.26.2.1 rmind if (rb->fc->status == FWBUSINIT) {
1138 1.26.2.1 rmind aprint_error_dev(rb->fc->bdev,
1139 1.26.2.1 rmind "cannot respond(bus reset)!\n");
1140 1.26.2.1 rmind return;
1141 1.26.2.1 rmind }
1142 1.26.2.1 rmind rb->xfer = fw_xfer_alloc(M_FWXFER);
1143 1.26.2.1 rmind if (rb->xfer == NULL)
1144 1.26.2.1 rmind return;
1145 1.26.2.1 rmind rb->xfer->send.spd = rb->spd;
1146 1.26.2.1 rmind rb->xfer->send.pay_len = 0;
1147 1.26.2.1 rmind resfp = &rb->xfer->send.hdr;
1148 1.26.2.1 rmind switch (tcode) {
1149 1.26.2.1 rmind case FWTCODE_WREQQ:
1150 1.26.2.1 rmind case FWTCODE_WREQB:
1151 1.26.2.1 rmind resfp->mode.hdr.tcode = FWTCODE_WRES;
1152 1.26.2.1 rmind break;
1153 1.26.2.1 rmind case FWTCODE_RREQQ:
1154 1.26.2.1 rmind resfp->mode.hdr.tcode = FWTCODE_RRESQ;
1155 1.26.2.1 rmind break;
1156 1.26.2.1 rmind case FWTCODE_RREQB:
1157 1.26.2.1 rmind resfp->mode.hdr.tcode = FWTCODE_RRESB;
1158 1.26.2.1 rmind break;
1159 1.26.2.1 rmind case FWTCODE_LREQ:
1160 1.26.2.1 rmind resfp->mode.hdr.tcode = FWTCODE_LRES;
1161 1.26.2.1 rmind break;
1162 1.26.2.1 rmind }
1163 1.26.2.1 rmind resfp->mode.hdr.dst = fp->mode.hdr.src;
1164 1.26.2.1 rmind resfp->mode.hdr.tlrt = fp->mode.hdr.tlrt;
1165 1.26.2.1 rmind resfp->mode.hdr.pri = fp->mode.hdr.pri;
1166 1.26.2.1 rmind resfp->mode.rresb.rtcode = RESP_ADDRESS_ERROR;
1167 1.26.2.1 rmind resfp->mode.rresb.extcode = 0;
1168 1.26.2.1 rmind resfp->mode.rresb.len = 0;
1169 1.26.2.1 rmind /*
1170 1.26.2.1 rmind rb->xfer->hand = fw_xferwake;
1171 1.26.2.1 rmind */
1172 1.26.2.1 rmind rb->xfer->hand = fw_xfer_free;
1173 1.26.2.1 rmind if (fw_asyreq(rb->fc, -1, rb->xfer)) {
1174 1.26.2.1 rmind fw_xfer_free(rb->xfer);
1175 1.26.2.1 rmind return;
1176 1.26.2.1 rmind }
1177 1.26.2.1 rmind return;
1178 1.26.2.1 rmind }
1179 1.26.2.1 rmind len = 0;
1180 1.26.2.1 rmind for (i = 0; i < rb->nvec; i++)
1181 1.26.2.1 rmind len += rb->vec[i].iov_len;
1182 1.26.2.1 rmind mutex_enter(&bind->fwb_mtx);
1183 1.26.2.1 rmind rb->xfer = STAILQ_FIRST(&bind->xferlist);
1184 1.26.2.1 rmind if (rb->xfer == NULL) {
1185 1.26.2.1 rmind mutex_exit(&bind->fwb_mtx);
1186 1.26.2.1 rmind #if 1
1187 1.26.2.1 rmind aprint_error_dev(rb->fc->bdev,
1188 1.26.2.1 rmind "Discard a packet for this bind.\n");
1189 1.26.2.1 rmind #endif
1190 1.26.2.1 rmind return;
1191 1.26.2.1 rmind }
1192 1.26.2.1 rmind STAILQ_REMOVE_HEAD(&bind->xferlist, link);
1193 1.26.2.1 rmind mutex_exit(&bind->fwb_mtx);
1194 1.26.2.1 rmind fw_rcv_copy(rb);
1195 1.26.2.1 rmind rb->xfer->hand(rb->xfer);
1196 1.26.2.1 rmind return;
1197 1.26.2.1 rmind
1198 1.26.2.1 rmind default:
1199 1.26.2.1 rmind aprint_error_dev(rb->fc->bdev, "unknow tcode %d\n", tcode);
1200 1.26.2.1 rmind break;
1201 1.26.2.1 rmind }
1202 1.26.2.1 rmind }
1203 1.26.2.1 rmind
1204 1.26.2.1 rmind /*
1205 1.26.2.1 rmind * CRC16 check-sum for IEEE1394 register blocks.
1206 1.26.2.1 rmind */
1207 1.26.2.1 rmind uint16_t
1208 1.26.2.1 rmind fw_crc16(uint32_t *ptr, uint32_t len)
1209 1.26.2.1 rmind {
1210 1.26.2.1 rmind uint32_t i, sum, crc = 0;
1211 1.26.2.1 rmind int shift;
1212 1.26.2.1 rmind
1213 1.26.2.1 rmind len = (len + 3) & ~3;
1214 1.26.2.1 rmind for (i = 0; i < len; i+= 4) {
1215 1.26.2.1 rmind for (shift = 28; shift >= 0; shift -= 4) {
1216 1.26.2.1 rmind sum = ((crc >> 12) ^ (ptr[i/4] >> shift)) & 0xf;
1217 1.26.2.1 rmind crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ sum;
1218 1.26.2.1 rmind }
1219 1.26.2.1 rmind crc &= 0xffff;
1220 1.26.2.1 rmind }
1221 1.26.2.1 rmind return (uint16_t)crc;
1222 1.26.2.1 rmind }
1223 1.26.2.1 rmind
1224 1.26.2.1 rmind int
1225 1.26.2.1 rmind fw_open_isodma(struct firewire_comm *fc, int tx)
1226 1.26.2.1 rmind {
1227 1.26.2.1 rmind struct fw_xferq **xferqa;
1228 1.26.2.1 rmind struct fw_xferq *xferq;
1229 1.26.2.1 rmind int i;
1230 1.26.2.1 rmind
1231 1.26.2.1 rmind if (tx)
1232 1.26.2.1 rmind xferqa = fc->it;
1233 1.26.2.1 rmind else
1234 1.26.2.1 rmind xferqa = fc->ir;
1235 1.26.2.1 rmind
1236 1.26.2.1 rmind mutex_enter(&fc->fc_mtx);
1237 1.26.2.1 rmind for (i = 0; i < fc->nisodma; i++) {
1238 1.26.2.1 rmind xferq = xferqa[i];
1239 1.26.2.1 rmind if (!(xferq->flag & FWXFERQ_OPEN)) {
1240 1.26.2.1 rmind xferq->flag |= FWXFERQ_OPEN;
1241 1.26.2.1 rmind break;
1242 1.26.2.1 rmind }
1243 1.26.2.1 rmind }
1244 1.26.2.1 rmind if (i == fc->nisodma) {
1245 1.26.2.1 rmind aprint_error_dev(fc->bdev, "no free dma channel (tx=%d)\n", tx);
1246 1.26.2.1 rmind i = -1;
1247 1.26.2.1 rmind }
1248 1.26.2.1 rmind mutex_exit(&fc->fc_mtx);
1249 1.26.2.1 rmind return i;
1250 1.26.2.1 rmind }
1251 1.26.2.1 rmind
1252 1.26.2.1 rmind /*
1253 1.26.2.1 rmind * Async. request with given xfer structure.
1254 1.26.2.1 rmind */
1255 1.26.2.1 rmind static void
1256 1.26.2.1 rmind fw_asystart(struct fw_xfer *xfer)
1257 1.26.2.1 rmind {
1258 1.26.2.1 rmind struct firewire_comm *fc = xfer->fc;
1259 1.26.2.1 rmind
1260 1.26.2.1 rmind /* Protect from interrupt/timeout */
1261 1.26.2.1 rmind mutex_enter(&xfer->q->q_mtx);
1262 1.26.2.1 rmind xfer->flag = FWXF_INQ;
1263 1.26.2.1 rmind STAILQ_INSERT_TAIL(&xfer->q->q, xfer, link);
1264 1.26.2.1 rmind #if 0
1265 1.26.2.1 rmind xfer->q->queued++;
1266 1.26.2.1 rmind #endif
1267 1.26.2.1 rmind mutex_exit(&xfer->q->q_mtx);
1268 1.26.2.1 rmind /* XXX just queue for mbuf */
1269 1.26.2.1 rmind if (xfer->mbuf == NULL)
1270 1.26.2.1 rmind xfer->q->start(fc);
1271 1.26.2.1 rmind return;
1272 1.26.2.1 rmind }
1273 1.26.2.1 rmind
1274 1.26.2.1 rmind static void
1275 1.26.2.1 rmind firewire_xfer_timeout(struct firewire_comm *fc)
1276 1.26.2.1 rmind {
1277 1.26.2.1 rmind struct fw_xfer *xfer;
1278 1.26.2.1 rmind struct timeval tv;
1279 1.26.2.1 rmind struct timeval split_timeout;
1280 1.26.2.1 rmind STAILQ_HEAD(, fw_xfer) xfer_timeout;
1281 1.26.2.1 rmind int i;
1282 1.26.2.1 rmind
1283 1.26.2.1 rmind split_timeout.tv_sec = 0;
1284 1.26.2.1 rmind split_timeout.tv_usec = 200 * 1000; /* 200 msec */
1285 1.26.2.1 rmind
1286 1.26.2.1 rmind microtime(&tv);
1287 1.26.2.1 rmind timersub(&tv, &split_timeout, &tv);
1288 1.26.2.1 rmind STAILQ_INIT(&xfer_timeout);
1289 1.26.2.1 rmind
1290 1.26.2.1 rmind mutex_enter(&fc->tlabel_lock);
1291 1.26.2.1 rmind for (i = 0; i < 0x40; i++) {
1292 1.26.2.1 rmind while ((xfer = STAILQ_FIRST(&fc->tlabels[i])) != NULL) {
1293 1.26.2.1 rmind if ((xfer->flag & FWXF_SENT) == 0)
1294 1.26.2.1 rmind /* not sent yet */
1295 1.26.2.1 rmind break;
1296 1.26.2.1 rmind if (timercmp(&xfer->tv, &tv, >))
1297 1.26.2.1 rmind /* the rests are newer than this */
1298 1.26.2.1 rmind break;
1299 1.26.2.1 rmind aprint_error_dev(fc->bdev,
1300 1.26.2.1 rmind "split transaction timeout: tl=0x%x flag=0x%02x\n",
1301 1.26.2.1 rmind i, xfer->flag);
1302 1.26.2.1 rmind fw_dump_hdr(&xfer->send.hdr, "send");
1303 1.26.2.1 rmind xfer->resp = ETIMEDOUT;
1304 1.26.2.1 rmind STAILQ_REMOVE_HEAD(&fc->tlabels[i], tlabel);
1305 1.26.2.1 rmind STAILQ_INSERT_TAIL(&xfer_timeout, xfer, tlabel);
1306 1.26.2.1 rmind }
1307 1.26.2.1 rmind }
1308 1.26.2.1 rmind mutex_exit(&fc->tlabel_lock);
1309 1.26.2.1 rmind fc->timeout(fc);
1310 1.1 kiyohara
1311 1.26.2.1 rmind STAILQ_FOREACH(xfer, &xfer_timeout, tlabel)
1312 1.26.2.1 rmind xfer->hand(xfer);
1313 1.13 kiyohara }
1314 1.16 kiyohara
1315 1.26.2.1 rmind #define WATCHDOG_HZ 10
1316 1.26.2.1 rmind static void
1317 1.26.2.1 rmind firewire_watchdog(void *arg)
1318 1.16 kiyohara {
1319 1.26.2.1 rmind struct firewire_comm *fc;
1320 1.26.2.1 rmind static int watchdog_clock = 0;
1321 1.16 kiyohara
1322 1.26.2.1 rmind fc = (struct firewire_comm *)arg;
1323 1.26.2.1 rmind
1324 1.26.2.1 rmind /*
1325 1.26.2.1 rmind * At boot stage, the device interrupt is disabled and
1326 1.26.2.1 rmind * We encounter a timeout easily. To avoid this,
1327 1.26.2.1 rmind * ignore clock interrupt for a while.
1328 1.26.2.1 rmind */
1329 1.26.2.1 rmind if (watchdog_clock > WATCHDOG_HZ * 15)
1330 1.26.2.1 rmind firewire_xfer_timeout(fc);
1331 1.26.2.1 rmind else
1332 1.26.2.1 rmind watchdog_clock++;
1333 1.26.2.1 rmind
1334 1.26.2.1 rmind 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.26.2.1 rmind 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.26.2.1 rmind CSRARC(fc, STATE_CLEAR) =
1359 1.26.2.1 rmind 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.26.2.1 rmind for (i = 2; i < 0x100/4 - 2; i++)
1369 1.1 kiyohara CSRARC(fc, SPED_MAP + i * 4) = 0;
1370 1.26.2.1 rmind CSRARC(fc, STATE_CLEAR) =
1371 1.26.2.1 rmind 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.26.2.1 rmind CSRARC(fc, CONF_ROM + 8) =
1387 1.26.2.1 rmind 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.26.2.1 rmind CSRARC(fc, oPCR) &= ~DV_BROADCAST_ON;
1392 1.26.2.1 rmind CSRARC(fc, iPCR) &= ~DV_BROADCAST_ON;
1393 1.1 kiyohara
1394 1.26.2.1 rmind 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.24 cegger 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.26.2.1 rmind src->businfo.generation = FW_GENERATION_CHANGEABLE;
1420 1.26.2.1 rmind src->businfo.link_spd = fc->speed;
1421 1.1 kiyohara
1422 1.26.2.1 rmind src->businfo.eui64.hi = fc->eui.hi;
1423 1.26.2.1 rmind src->businfo.eui64.lo = fc->eui.lo;
1424 1.1 kiyohara
1425 1.26.2.1 rmind STAILQ_INIT(&src->chunk_list);
1426 1.26.2.1 rmind
1427 1.26.2.1 rmind fc->crom_src = src;
1428 1.26.2.1 rmind fc->crom_root = &fc->crom_src_buf->root;
1429 1.1 kiyohara }
1430 1.1 kiyohara
1431 1.26.2.1 rmind static void
1432 1.26.2.1 rmind fw_reset_crom(struct firewire_comm *fc)
1433 1.1 kiyohara {
1434 1.26.2.1 rmind struct crom_src_buf *buf;
1435 1.26.2.1 rmind struct crom_src *src;
1436 1.26.2.1 rmind struct crom_chunk *root;
1437 1.1 kiyohara
1438 1.26.2.1 rmind buf = fc->crom_src_buf;
1439 1.26.2.1 rmind src = fc->crom_src;
1440 1.26.2.1 rmind root = fc->crom_root;
1441 1.1 kiyohara
1442 1.26.2.1 rmind STAILQ_INIT(&src->chunk_list);
1443 1.1 kiyohara
1444 1.26.2.1 rmind memset(root, 0, sizeof(struct crom_chunk));
1445 1.26.2.1 rmind crom_add_chunk(src, NULL, root, 0);
1446 1.26.2.1 rmind crom_add_entry(root, CSRKEY_NCAP, 0x0083c0); /* XXX */
1447 1.26.2.1 rmind /* private company_id */
1448 1.26.2.1 rmind crom_add_entry(root, CSRKEY_VENDOR, CSRVAL_VENDOR_PRIVATE);
1449 1.26.2.1 rmind crom_add_simple_text(src, root, &buf->vendor, PROJECT_STR);
1450 1.26.2.1 rmind crom_add_entry(root, CSRKEY_HW, __NetBSD_Version__);
1451 1.26.2.1 rmind 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.26.2.1 rmind
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.26.2.1 rmind 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.26.2.1 rmind if (txfer == xfer)
1484 1.1 kiyohara break;
1485 1.1 kiyohara if (txfer == NULL) {
1486 1.26.2.1 rmind mutex_exit(&fc->tlabel_lock);
1487 1.26.2.1 rmind aprint_error_dev(fc->bdev,
1488 1.26.2.1 rmind "the xfer is not in the queue (tlabel=%d, flag=0x%x)\n",
1489 1.26.2.1 rmind 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.26.2.1 rmind 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.26.2.1 rmind 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.26.2.1 rmind mutex_enter(&fc->tlabel_lock);
1512 1.1 kiyohara STAILQ_FOREACH(xfer, &fc->tlabels[tlabel], tlabel)
1513 1.26.2.1 rmind if (xfer->send.hdr.mode.hdr.dst == node) {
1514 1.26.2.1 rmind mutex_exit(&fc->tlabel_lock);
1515 1.26.2.1 rmind 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.26.2.1 rmind aprint_error_dev(fc->bdev,
1520 1.26.2.1 rmind "invalid response tcode (0x%x for 0x%x)\n",
1521 1.16 kiyohara tcode, req);
1522 1.26.2.1 rmind 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.26.2.1 rmind return xfer;
1528 1.1 kiyohara }
1529 1.26.2.1 rmind 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.26.2.1 rmind return NULL;
1533 1.1 kiyohara }
1534 1.1 kiyohara
1535 1.1 kiyohara /*
1536 1.26.2.1 rmind * 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.26.2.1 rmind 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.26.2.1 rmind * 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.26.2.1 rmind s = (union fw_self_id *) &sid;
1576 1.26.2.1 rmind if (s->p0.sequel) {
1577 1.26.2.1 rmind if (s->p1.sequence_num == FW_SELF_ID_PAGE0)
1578 1.26.2.1 rmind printf("node:%d p3:%d p4:%d p5:%d p6:%d p7:%d"
1579 1.26.2.1 rmind "p8:%d p9:%d p10:%d\n",
1580 1.26.2.1 rmind s->p1.phy_id, s->p1.port3, s->p1.port4,
1581 1.26.2.1 rmind s->p1.port5, s->p1.port6, s->p1.port7,
1582 1.26.2.1 rmind s->p1.port8, s->p1.port9, s->p1.port10);
1583 1.26.2.1 rmind else if (s->p2.sequence_num == FW_SELF_ID_PAGE1)
1584 1.26.2.1 rmind printf("node:%d p11:%d p12:%d p13:%d p14:%d p15:%d\n",
1585 1.26.2.1 rmind s->p2.phy_id, s->p2.port11, s->p2.port12,
1586 1.26.2.1 rmind s->p2.port13, s->p2.port14, s->p2.port15);
1587 1.26.2.1 rmind else
1588 1.26.2.1 rmind printf("node:%d Unknown Self ID Page number %d\n",
1589 1.26.2.1 rmind s->p1.phy_id, s->p1.sequence_num);
1590 1.1 kiyohara } else
1591 1.26.2.1 rmind printf("node:%d link:%d gap:%d spd:%d con:%d pwr:%d"
1592 1.26.2.1 rmind " p0:%d p1:%d p2:%d i:%d m:%d\n",
1593 1.26.2.1 rmind s->p0.phy_id, s->p0.link_active, s->p0.gap_count,
1594 1.26.2.1 rmind s->p0.phy_speed, s->p0.contender,
1595 1.26.2.1 rmind s->p0.power_class, s->p0.port0, s->p0.port1,
1596 1.26.2.1 rmind 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.26.2.1 rmind * 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.26.2.1 rmind 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.26.2.1 rmind if (firewire_debug)
1612 1.26.2.1 rmind printf("iterate and invalidate all nodes\n");
1613 1.26.2.1 rmind 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.26.2.1 rmind if (firewire_debug)
1619 1.26.2.1 rmind printf("Invalidate Dev ID: %08x%08x\n",
1620 1.26.2.1 rmind fwdev->eui.hi, fwdev->eui.lo);
1621 1.26.2.1 rmind } else
1622 1.26.2.1 rmind if (firewire_debug)
1623 1.26.2.1 rmind printf("Dev ID: %08x%08x already invalid\n",
1624 1.26.2.1 rmind fwdev->eui.hi, fwdev->eui.lo);
1625 1.26.2.1 rmind mutex_exit(&fc->fc_mtx);
1626 1.1 kiyohara
1627 1.26.2.1 rmind cv_signal(&fc->fc_cv);
1628 1.26.2.1 rmind mutex_exit(&fc->wait_lock);
1629 1.1 kiyohara }
1630 1.1 kiyohara
1631 1.1 kiyohara static int
1632 1.26.2.1 rmind fw_explore_read_quads(struct fw_device *fwdev, int offset, uint32_t *quad,
1633 1.26.2.1 rmind 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.26.2.1 rmind for (i = 0; i < length; i++, offset += sizeof(uint32_t)) {
1640 1.26.2.1 rmind xfer = fwmem_read_quad(fwdev, NULL, -1, 0xffff,
1641 1.26.2.1 rmind 0xf0000000 | offset, (void *)&tmp, fw_xferwake);
1642 1.1 kiyohara if (xfer == NULL)
1643 1.26.2.1 rmind 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.26.2.1 rmind return error;
1653 1.1 kiyohara }
1654 1.26.2.1 rmind 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.26.2.1 rmind err = fw_explore_read_quads(fwdev, CSRROMOFF + offset, (uint32_t *)dir,
1668 1.26.2.1 rmind 1);
1669 1.1 kiyohara if (err)
1670 1.26.2.1 rmind return -1;
1671 1.1 kiyohara
1672 1.1 kiyohara offset += sizeof(uint32_t);
1673 1.26.2.1 rmind reg = (struct csrreg *)&fwdev->csrrom[offset / sizeof(uint32_t)];
1674 1.26.2.1 rmind err = fw_explore_read_quads(fwdev, CSRROMOFF + offset, (uint32_t *)reg,
1675 1.26.2.1 rmind dir->crc_len);
1676 1.1 kiyohara if (err)
1677 1.26.2.1 rmind 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.26.2.1 rmind return 0;
1687 1.1 kiyohara
1688 1.26.2.1 rmind 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.26.2.1 rmind aprint_error_dev(fwdev->fc->bdev, "invalid offset %d\n",
1699 1.26.2.1 rmind off);
1700 1.26.2.1 rmind 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.26.2.1 rmind return -1;
1705 1.1 kiyohara }
1706 1.26.2.1 rmind 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.26.2.1 rmind uint32_t *csr, speed_test = 0;
1717 1.26.2.1 rmind 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.26.2.1 rmind err = fw_explore_read_quads(dfwdev, CSRROMOFF, csr, 1);
1725 1.26.2.1 rmind if (err) {
1726 1.26.2.1 rmind aprint_error_dev(fc->bdev,
1727 1.26.2.1 rmind "node%d: explore_read_quads failure\n", node);
1728 1.26.2.1 rmind dfwdev->status = FWDEVINVAL;
1729 1.26.2.1 rmind return -1;
1730 1.26.2.1 rmind }
1731 1.26.2.1 rmind 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.26.2.1 rmind dfwdev->status = FWDEVINVAL;
1737 1.26.2.1 rmind 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.26.2.1 rmind if (err) {
1743 1.26.2.1 rmind aprint_error_dev(fc->bdev, "node%d: error reading 0x04\n",
1744 1.26.2.1 rmind node);
1745 1.26.2.1 rmind dfwdev->status = FWDEVINVAL;
1746 1.26.2.1 rmind return -1;
1747 1.26.2.1 rmind }
1748 1.1 kiyohara binfo = (struct bus_info *)&csr[1];
1749 1.1 kiyohara if (binfo->bus_name != CSR_BUS_NAME_IEEE1394) {
1750 1.26.2.1 rmind aprint_error_dev(fc->bdev, "node%d: invalid bus name 0x%08x\n",
1751 1.26.2.1 rmind node, binfo->bus_name);
1752 1.26.2.1 rmind dfwdev->status = FWDEVINVAL;
1753 1.26.2.1 rmind return -1;
1754 1.1 kiyohara }
1755 1.26.2.1 rmind if (firewire_debug)
1756 1.26.2.1 rmind printf("node(%d) BUS INFO BLOCK:\n"
1757 1.26.2.1 rmind "irmc(%d) cmc(%d) isc(%d) bmc(%d) pmc(%d) "
1758 1.26.2.1 rmind "cyc_clk_acc(%d) max_rec(%d) max_rom(%d) "
1759 1.26.2.1 rmind "generation(%d) link_spd(%d)\n",
1760 1.26.2.1 rmind node, binfo->irmc, binfo->cmc, binfo->isc,
1761 1.26.2.1 rmind binfo->bmc, binfo->pmc, binfo->cyc_clk_acc,
1762 1.26.2.1 rmind binfo->max_rec, binfo->max_rom,
1763 1.26.2.1 rmind binfo->generation, binfo->link_spd);
1764 1.26.2.1 rmind
1765 1.26.2.1 rmind 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.26.2.1 rmind mutex_exit(&fc->fc_mtx);
1770 1.1 kiyohara if (fwdev == NULL) {
1771 1.1 kiyohara /* new device */
1772 1.26.2.1 rmind fwdev =
1773 1.26.2.1 rmind 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.26.2.1 rmind return -1;
1778 1.1 kiyohara }
1779 1.1 kiyohara fwdev->fc = fc;
1780 1.1 kiyohara fwdev->eui = binfo->eui64;
1781 1.26.2.1 rmind fwdev->dst = dfwdev->dst;
1782 1.26.2.1 rmind fwdev->maxrec = dfwdev->maxrec;
1783 1.1 kiyohara fwdev->status = FWDEVNEW;
1784 1.26.2.1 rmind /*
1785 1.26.2.1 rmind * Pre-1394a-2000 didn't have link_spd in
1786 1.26.2.1 rmind * the Bus Info block, so try and use the
1787 1.26.2.1 rmind * speed map value.
1788 1.26.2.1 rmind * 1394a-2000 compliant devices only use
1789 1.26.2.1 rmind * the Bus Info Block link spd value, so
1790 1.26.2.1 rmind * ignore the speed map alltogether. SWB
1791 1.26.2.1 rmind */
1792 1.26.2.1 rmind if (binfo->link_spd == FWSPD_S100 /* 0 */) {
1793 1.26.2.1 rmind aprint_normal_dev(fc->bdev,
1794 1.26.2.1 rmind "Pre 1394a-2000 detected\n");
1795 1.26.2.1 rmind fwdev->speed = fc->speed_map->speed[fc->nodeid][node];
1796 1.26.2.1 rmind } else
1797 1.26.2.1 rmind fwdev->speed = binfo->link_spd;
1798 1.26.2.1 rmind /*
1799 1.26.2.1 rmind * Test this speed with a read to the CSRROM.
1800 1.26.2.1 rmind * If it fails, slow down the speed and retry.
1801 1.26.2.1 rmind */
1802 1.26.2.1 rmind while (fwdev->speed > FWSPD_S100 /* 0 */) {
1803 1.26.2.1 rmind err = fw_explore_read_quads(fwdev, CSRROMOFF,
1804 1.26.2.1 rmind &speed_test, 1);
1805 1.26.2.1 rmind if (err) {
1806 1.26.2.1 rmind aprint_error_dev(fc->bdev, "fwdev->speed(%s)"
1807 1.26.2.1 rmind " decremented due to negotiation\n",
1808 1.26.2.1 rmind fw_linkspeed[fwdev->speed]);
1809 1.26.2.1 rmind fwdev->speed--;
1810 1.26.2.1 rmind } else
1811 1.26.2.1 rmind break;
1812 1.26.2.1 rmind }
1813 1.26.2.1 rmind /*
1814 1.26.2.1 rmind * If the fwdev is not found in the
1815 1.26.2.1 rmind * fc->devices TAILQ, then we will add it.
1816 1.26.2.1 rmind */
1817 1.1 kiyohara pfwdev = NULL;
1818 1.26.2.1 rmind 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.26.2.1 rmind (tfwdev->eui.hi == fwdev->eui.hi &&
1822 1.26.2.1 rmind 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.26.2.1 rmind mutex_exit(&fc->fc_mtx);
1831 1.1 kiyohara
1832 1.26.2.1 rmind aprint_normal_dev(fc->bdev, "New %s device ID:%08x%08x\n",
1833 1.26.2.1 rmind fw_linkspeed[fwdev->speed], fwdev->eui.hi, fwdev->eui.lo);
1834 1.26.2.1 rmind } else {
1835 1.26.2.1 rmind fwdev->dst = node;
1836 1.1 kiyohara fwdev->status = FWDEVINIT;
1837 1.26.2.1 rmind /* unchanged ? */
1838 1.26.2.1 rmind if (memcmp(csr, fwdev->csrrom, sizeof(uint32_t) * 5) == 0) {
1839 1.26.2.1 rmind if (firewire_debug)
1840 1.26.2.1 rmind printf("node%d: crom unchanged\n", node);
1841 1.26.2.1 rmind return 0;
1842 1.26.2.1 rmind }
1843 1.1 kiyohara }
1844 1.1 kiyohara
1845 1.26.2.1 rmind memset(fwdev->csrrom, 0, CROMSIZE);
1846 1.1 kiyohara
1847 1.1 kiyohara /* copy first quad and bus info block */
1848 1.26.2.1 rmind 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.26.2.1 rmind if (firewire_debug)
1855 1.26.2.1 rmind 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.26.2.1 rmind 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.26.2.1 rmind
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.26.2.1 rmind int node, err, i, todo, todo2, trys;
1887 1.26.2.1 rmind 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.26.2.1 rmind for (node = 0; node <= fc->max_node; node++) {
1900 1.1 kiyohara /* We don't probe myself and linkdown nodes */
1901 1.26.2.1 rmind if (node == fc->nodeid) {
1902 1.26.2.1 rmind if (firewire_debug)
1903 1.26.2.1 rmind printf("found myself node(%d) fc->nodeid(%d)"
1904 1.26.2.1 rmind " fc->max_node(%d)\n",
1905 1.26.2.1 rmind node, fc->nodeid, fc->max_node);
1906 1.1 kiyohara continue;
1907 1.26.2.1 rmind } else if (firewire_debug)
1908 1.26.2.1 rmind printf("node(%d) fc->max_node(%d) found\n",
1909 1.26.2.1 rmind 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.26.2.1 rmind for (trys = 0; todo > 0 && trys < 3; trys++) {
1920 1.1 kiyohara todo2 = 0;
1921 1.26.2.1 rmind 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.26.2.1 rmind 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.26.2.1 rmind struct firewire_comm *fc = (struct firewire_comm *)arg;
1938 1.1 kiyohara
1939 1.26.2.1 rmind config_pending_decr();
1940 1.1 kiyohara
1941 1.26.2.1 rmind mutex_enter(&fc->wait_lock);
1942 1.16 kiyohara while (fc->status != FWBUSDETACH) {
1943 1.1 kiyohara if (fc->status == FWBUSEXPLORE) {
1944 1.26.2.1 rmind 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.26.2.1 rmind mutex_enter(&fc->wait_lock);
1951 1.16 kiyohara }
1952 1.26.2.1 rmind cv_wait_sig(&fc->fc_cv, &fc->wait_lock);
1953 1.1 kiyohara }
1954 1.26.2.1 rmind fc->status = FWBUSDETACHOK;
1955 1.26.2.1 rmind cv_signal(&fc->fc_cv);
1956 1.26.2.1 rmind mutex_exit(&fc->wait_lock);
1957 1.26.2.1 rmind kthread_exit(0);
1958 1.26.2.1 rmind
1959 1.26.2.1 rmind /* NOTREACHED */
1960 1.1 kiyohara }
1961 1.1 kiyohara
1962 1.1 kiyohara
1963 1.1 kiyohara /*
1964 1.1 kiyohara * To attach sub-devices layer onto IEEE1394 bus.
1965 1.1 kiyohara */
1966 1.1 kiyohara static void
1967 1.1 kiyohara fw_attach_dev(struct firewire_comm *fc)
1968 1.1 kiyohara {
1969 1.26.2.1 rmind struct firewire_softc *sc = device_private(fc->bdev);
1970 1.26.2.1 rmind struct firewire_dev_list *devlist, *elm;
1971 1.1 kiyohara struct fw_device *fwdev, *next;
1972 1.1 kiyohara struct firewire_dev_comm *fdc;
1973 1.1 kiyohara struct fw_attach_args fwa;
1974 1.26.2.1 rmind int locs[IEEE1394IFCF_NLOCS];
1975 1.1 kiyohara
1976 1.1 kiyohara fwa.name = "sbp";
1977 1.1 kiyohara fwa.fc = fc;
1978 1.1 kiyohara
1979 1.26.2.1 rmind mutex_enter(&fc->fc_mtx);
1980 1.1 kiyohara for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL; fwdev = next) {
1981 1.1 kiyohara next = STAILQ_NEXT(fwdev, link);
1982 1.26.2.1 rmind mutex_exit(&fc->fc_mtx);
1983 1.1 kiyohara switch (fwdev->status) {
1984 1.1 kiyohara case FWDEVNEW:
1985 1.26.2.1 rmind devlist = malloc(sizeof(struct firewire_dev_list),
1986 1.26.2.1 rmind M_DEVBUF, M_NOWAIT);
1987 1.26.2.1 rmind if (devlist == NULL) {
1988 1.26.2.1 rmind aprint_error_dev(fc->bdev,
1989 1.26.2.1 rmind "memory allocation failed\n");
1990 1.26.2.1 rmind break;
1991 1.26.2.1 rmind }
1992 1.26.2.1 rmind
1993 1.26.2.1 rmind locs[IEEE1394IFCF_EUIHI] = fwdev->eui.hi;
1994 1.26.2.1 rmind locs[IEEE1394IFCF_EUILO] = fwdev->eui.lo;
1995 1.26.2.1 rmind
1996 1.26.2.1 rmind fwa.fwdev = fwdev;
1997 1.26.2.1 rmind fwdev->sbp = config_found_sm_loc(sc->dev, "ieee1394if",
1998 1.26.2.1 rmind locs, &fwa, firewire_print, config_stdsubmatch);
1999 1.26.2.1 rmind if (fwdev->sbp == NULL) {
2000 1.26.2.1 rmind free(devlist, M_DEVBUF);
2001 1.26.2.1 rmind break;
2002 1.26.2.1 rmind }
2003 1.26.2.1 rmind
2004 1.26.2.1 rmind devlist->fwdev = fwdev;
2005 1.26.2.1 rmind devlist->dev = fwdev->sbp;
2006 1.26.2.1 rmind
2007 1.26.2.1 rmind mutex_enter(&fc->fc_mtx);
2008 1.26.2.1 rmind if (SLIST_EMPTY(&sc->devlist))
2009 1.26.2.1 rmind SLIST_INSERT_HEAD(&sc->devlist, devlist, link);
2010 1.26.2.1 rmind else {
2011 1.26.2.1 rmind for (elm = SLIST_FIRST(&sc->devlist);
2012 1.26.2.1 rmind SLIST_NEXT(elm, link) != NULL;
2013 1.26.2.1 rmind elm = SLIST_NEXT(elm, link));
2014 1.26.2.1 rmind SLIST_INSERT_AFTER(elm, devlist, link);
2015 1.26.2.1 rmind }
2016 1.26.2.1 rmind mutex_exit(&fc->fc_mtx);
2017 1.26.2.1 rmind
2018 1.26.2.1 rmind /* FALLTHROUGH */
2019 1.1 kiyohara
2020 1.1 kiyohara case FWDEVINIT:
2021 1.1 kiyohara case FWDEVATTACHED:
2022 1.1 kiyohara fwdev->status = FWDEVATTACHED;
2023 1.1 kiyohara break;
2024 1.1 kiyohara
2025 1.1 kiyohara case FWDEVINVAL:
2026 1.26.2.1 rmind fwdev->rcnt++;
2027 1.26.2.1 rmind if (firewire_debug)
2028 1.26.2.1 rmind printf("fwdev->rcnt(%d), hold_count(%d)\n",
2029 1.26.2.1 rmind fwdev->rcnt, hold_count);
2030 1.1 kiyohara break;
2031 1.1 kiyohara
2032 1.1 kiyohara default:
2033 1.1 kiyohara /* XXX */
2034 1.1 kiyohara break;
2035 1.1 kiyohara }
2036 1.26.2.1 rmind mutex_enter(&fc->fc_mtx);
2037 1.1 kiyohara }
2038 1.26.2.1 rmind mutex_exit(&fc->fc_mtx);
2039 1.1 kiyohara
2040 1.26.2.1 rmind SLIST_FOREACH(devlist, &sc->devlist, link) {
2041 1.26.2.1 rmind fdc = device_private(devlist->dev);
2042 1.26.2.1 rmind if (fdc->post_explore != NULL)
2043 1.26.2.1 rmind fdc->post_explore(fdc);
2044 1.26.2.1 rmind }
2045 1.1 kiyohara
2046 1.1 kiyohara for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL; fwdev = next) {
2047 1.1 kiyohara next = STAILQ_NEXT(fwdev, link);
2048 1.1 kiyohara if (fwdev->rcnt > 0 && fwdev->rcnt > hold_count) {
2049 1.1 kiyohara /*
2050 1.1 kiyohara * Remove devices which have not been seen
2051 1.1 kiyohara * for a while.
2052 1.1 kiyohara */
2053 1.26.2.1 rmind SLIST_FOREACH(devlist, &sc->devlist, link)
2054 1.26.2.1 rmind if (devlist->fwdev == fwdev)
2055 1.26.2.1 rmind break;
2056 1.26.2.1 rmind if (devlist->fwdev != fwdev)
2057 1.26.2.1 rmind panic("already detached");
2058 1.26.2.1 rmind
2059 1.26.2.1 rmind SLIST_REMOVE(&sc->devlist, devlist, firewire_dev_list,
2060 1.26.2.1 rmind link);
2061 1.26.2.1 rmind free(devlist, M_DEVBUF);
2062 1.26.2.1 rmind
2063 1.26.2.1 rmind if (config_detach(fwdev->sbp, DETACH_FORCE) != 0)
2064 1.26.2.1 rmind return;
2065 1.26.2.1 rmind
2066 1.1 kiyohara STAILQ_REMOVE(&fc->devices, fwdev, fw_device, link);
2067 1.1 kiyohara free(fwdev, M_FW);
2068 1.1 kiyohara }
2069 1.1 kiyohara }
2070 1.1 kiyohara
2071 1.1 kiyohara return;
2072 1.1 kiyohara }
2073 1.1 kiyohara
2074 1.1 kiyohara /*
2075 1.1 kiyohara * To allocate unique transaction label.
2076 1.1 kiyohara */
2077 1.1 kiyohara static int
2078 1.1 kiyohara fw_get_tlabel(struct firewire_comm *fc, struct fw_xfer *xfer)
2079 1.1 kiyohara {
2080 1.16 kiyohara u_int dst, new_tlabel;
2081 1.1 kiyohara struct fw_xfer *txfer;
2082 1.1 kiyohara
2083 1.16 kiyohara dst = xfer->send.hdr.mode.hdr.dst & 0x3f;
2084 1.26.2.1 rmind mutex_enter(&fc->tlabel_lock);
2085 1.16 kiyohara new_tlabel = (fc->last_tlabel[dst] + 1) & 0x3f;
2086 1.16 kiyohara STAILQ_FOREACH(txfer, &fc->tlabels[new_tlabel], tlabel)
2087 1.16 kiyohara if ((txfer->send.hdr.mode.hdr.dst & 0x3f) == dst)
2088 1.16 kiyohara break;
2089 1.26.2.1 rmind if (txfer == NULL) {
2090 1.16 kiyohara fc->last_tlabel[dst] = new_tlabel;
2091 1.16 kiyohara STAILQ_INSERT_TAIL(&fc->tlabels[new_tlabel], xfer, tlabel);
2092 1.26.2.1 rmind mutex_exit(&fc->tlabel_lock);
2093 1.16 kiyohara xfer->tl = new_tlabel;
2094 1.16 kiyohara xfer->send.hdr.mode.hdr.tlrt = new_tlabel << 2;
2095 1.16 kiyohara if (firewire_debug > 1)
2096 1.26.2.1 rmind printf("fw_get_tlabel: dst=%d tl=%d\n",
2097 1.26.2.1 rmind dst, new_tlabel);
2098 1.26.2.1 rmind return new_tlabel;
2099 1.1 kiyohara }
2100 1.26.2.1 rmind mutex_exit(&fc->tlabel_lock);
2101 1.1 kiyohara
2102 1.1 kiyohara if (firewire_debug > 1)
2103 1.1 kiyohara printf("fw_get_tlabel: no free tlabel\n");
2104 1.26.2.1 rmind return -1;
2105 1.1 kiyohara }
2106 1.1 kiyohara
2107 1.1 kiyohara static void
2108 1.1 kiyohara fw_rcv_copy(struct fw_rcv_buf *rb)
2109 1.1 kiyohara {
2110 1.1 kiyohara struct fw_pkt *pkt;
2111 1.1 kiyohara u_char *p;
2112 1.2 drochner const struct tcode_info *tinfo;
2113 1.1 kiyohara u_int res, i, len, plen;
2114 1.1 kiyohara
2115 1.1 kiyohara rb->xfer->recv.spd = rb->spd;
2116 1.1 kiyohara
2117 1.1 kiyohara pkt = (struct fw_pkt *)rb->vec->iov_base;
2118 1.1 kiyohara tinfo = &rb->fc->tcode[pkt->mode.hdr.tcode];
2119 1.1 kiyohara
2120 1.26.2.1 rmind /* Copy header */
2121 1.1 kiyohara p = (u_char *)&rb->xfer->recv.hdr;
2122 1.26.2.1 rmind memcpy(p, rb->vec->iov_base, tinfo->hdr_len);
2123 1.1 kiyohara rb->vec->iov_base = (u_char *)rb->vec->iov_base + tinfo->hdr_len;
2124 1.1 kiyohara rb->vec->iov_len -= tinfo->hdr_len;
2125 1.1 kiyohara
2126 1.1 kiyohara /* Copy payload */
2127 1.1 kiyohara p = (u_char *)rb->xfer->recv.payload;
2128 1.1 kiyohara res = rb->xfer->recv.pay_len;
2129 1.1 kiyohara
2130 1.1 kiyohara /* special handling for RRESQ */
2131 1.1 kiyohara if (pkt->mode.hdr.tcode == FWTCODE_RRESQ &&
2132 1.1 kiyohara p != NULL && res >= sizeof(uint32_t)) {
2133 1.1 kiyohara *(uint32_t *)p = pkt->mode.rresq.data;
2134 1.1 kiyohara rb->xfer->recv.pay_len = sizeof(uint32_t);
2135 1.1 kiyohara return;
2136 1.1 kiyohara }
2137 1.1 kiyohara
2138 1.1 kiyohara if ((tinfo->flag & FWTI_BLOCK_ASY) == 0)
2139 1.1 kiyohara return;
2140 1.1 kiyohara
2141 1.1 kiyohara plen = pkt->mode.rresb.len;
2142 1.1 kiyohara
2143 1.1 kiyohara for (i = 0; i < rb->nvec; i++, rb->vec++) {
2144 1.1 kiyohara len = MIN(rb->vec->iov_len, plen);
2145 1.1 kiyohara if (res < len) {
2146 1.26.2.1 rmind aprint_error_dev(rb->fc->bdev,
2147 1.26.2.1 rmind "rcv buffer(%d) is %d bytes short.\n",
2148 1.1 kiyohara rb->xfer->recv.pay_len, len - res);
2149 1.1 kiyohara len = res;
2150 1.1 kiyohara }
2151 1.7 christos if (p) {
2152 1.26.2.1 rmind memcpy(p, rb->vec->iov_base, len);
2153 1.7 christos p += len;
2154 1.7 christos }
2155 1.1 kiyohara res -= len;
2156 1.1 kiyohara plen -= len;
2157 1.1 kiyohara if (res == 0 || plen == 0)
2158 1.1 kiyohara break;
2159 1.1 kiyohara }
2160 1.1 kiyohara rb->xfer->recv.pay_len -= res;
2161 1.1 kiyohara
2162 1.1 kiyohara }
2163 1.1 kiyohara
2164 1.1 kiyohara /*
2165 1.1 kiyohara * Post process for Bus Manager election process.
2166 1.1 kiyohara */
2167 1.1 kiyohara static void
2168 1.1 kiyohara fw_try_bmr_callback(struct fw_xfer *xfer)
2169 1.1 kiyohara {
2170 1.1 kiyohara struct firewire_comm *fc;
2171 1.1 kiyohara int bmr;
2172 1.1 kiyohara
2173 1.1 kiyohara if (xfer == NULL)
2174 1.1 kiyohara return;
2175 1.1 kiyohara fc = xfer->fc;
2176 1.1 kiyohara if (xfer->resp != 0)
2177 1.1 kiyohara goto error;
2178 1.1 kiyohara if (xfer->recv.payload == NULL)
2179 1.1 kiyohara goto error;
2180 1.1 kiyohara if (xfer->recv.hdr.mode.lres.rtcode != FWRCODE_COMPLETE)
2181 1.1 kiyohara goto error;
2182 1.1 kiyohara
2183 1.1 kiyohara bmr = ntohl(xfer->recv.payload[0]);
2184 1.1 kiyohara if (bmr == 0x3f)
2185 1.1 kiyohara bmr = fc->nodeid;
2186 1.1 kiyohara
2187 1.1 kiyohara CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, bmr & 0x3f);
2188 1.1 kiyohara fw_xfer_free_buf(xfer);
2189 1.1 kiyohara fw_bmr(fc);
2190 1.1 kiyohara return;
2191 1.1 kiyohara
2192 1.1 kiyohara error:
2193 1.26.2.1 rmind aprint_error_dev(fc->bdev, "bus manager election failed\n");
2194 1.1 kiyohara fw_xfer_free_buf(xfer);
2195 1.1 kiyohara }
2196 1.1 kiyohara
2197 1.1 kiyohara
2198 1.1 kiyohara /*
2199 1.1 kiyohara * To candidate Bus Manager election process.
2200 1.1 kiyohara */
2201 1.1 kiyohara static void
2202 1.1 kiyohara fw_try_bmr(void *arg)
2203 1.1 kiyohara {
2204 1.1 kiyohara struct fw_xfer *xfer;
2205 1.1 kiyohara struct firewire_comm *fc = (struct firewire_comm *)arg;
2206 1.1 kiyohara struct fw_pkt *fp;
2207 1.1 kiyohara int err = 0;
2208 1.1 kiyohara
2209 1.1 kiyohara xfer = fw_xfer_alloc_buf(M_FWXFER, 8, 4);
2210 1.26.2.1 rmind if (xfer == NULL)
2211 1.1 kiyohara return;
2212 1.1 kiyohara xfer->send.spd = 0;
2213 1.1 kiyohara fc->status = FWBUSMGRELECT;
2214 1.1 kiyohara
2215 1.1 kiyohara fp = &xfer->send.hdr;
2216 1.1 kiyohara fp->mode.lreq.dest_hi = 0xffff;
2217 1.1 kiyohara fp->mode.lreq.tlrt = 0;
2218 1.1 kiyohara fp->mode.lreq.tcode = FWTCODE_LREQ;
2219 1.1 kiyohara fp->mode.lreq.pri = 0;
2220 1.1 kiyohara fp->mode.lreq.src = 0;
2221 1.1 kiyohara fp->mode.lreq.len = 8;
2222 1.1 kiyohara fp->mode.lreq.extcode = EXTCODE_CMP_SWAP;
2223 1.1 kiyohara fp->mode.lreq.dst = FWLOCALBUS | fc->irm;
2224 1.1 kiyohara fp->mode.lreq.dest_lo = 0xf0000000 | BUS_MGR_ID;
2225 1.1 kiyohara xfer->send.payload[0] = htonl(0x3f);
2226 1.1 kiyohara xfer->send.payload[1] = htonl(fc->nodeid);
2227 1.1 kiyohara xfer->hand = fw_try_bmr_callback;
2228 1.1 kiyohara
2229 1.1 kiyohara err = fw_asyreq(fc, -1, xfer);
2230 1.26.2.1 rmind if (err) {
2231 1.1 kiyohara fw_xfer_free_buf(xfer);
2232 1.1 kiyohara return;
2233 1.1 kiyohara }
2234 1.1 kiyohara return;
2235 1.1 kiyohara }
2236 1.1 kiyohara
2237 1.1 kiyohara /*
2238 1.26.2.1 rmind * Find the root node, if it is not
2239 1.26.2.1 rmind * Cycle Master Capable, then we should
2240 1.26.2.1 rmind * override this and become the Cycle
2241 1.26.2.1 rmind * Master
2242 1.1 kiyohara */
2243 1.1 kiyohara static int
2244 1.1 kiyohara fw_bmr(struct firewire_comm *fc)
2245 1.1 kiyohara {
2246 1.1 kiyohara struct fw_device fwdev;
2247 1.1 kiyohara union fw_self_id *self_id;
2248 1.1 kiyohara int cmstr;
2249 1.1 kiyohara uint32_t quad;
2250 1.1 kiyohara
2251 1.1 kiyohara /* Check to see if the current root node is cycle master capable */
2252 1.1 kiyohara self_id = fw_find_self_id(fc, fc->max_node);
2253 1.1 kiyohara if (fc->max_node > 0) {
2254 1.1 kiyohara /* XXX check cmc bit of businfo block rather than contender */
2255 1.1 kiyohara if (self_id->p0.link_active && self_id->p0.contender)
2256 1.1 kiyohara cmstr = fc->max_node;
2257 1.1 kiyohara else {
2258 1.26.2.1 rmind aprint_normal_dev(fc->bdev,
2259 1.1 kiyohara "root node is not cycle master capable\n");
2260 1.1 kiyohara /* XXX shall we be the cycle master? */
2261 1.1 kiyohara cmstr = fc->nodeid;
2262 1.1 kiyohara /* XXX need bus reset */
2263 1.1 kiyohara }
2264 1.1 kiyohara } else
2265 1.1 kiyohara cmstr = -1;
2266 1.1 kiyohara
2267 1.26.2.1 rmind aprint_normal_dev(fc->bdev, "bus manager %d%s\n",
2268 1.26.2.1 rmind CSRARC(fc, BUS_MGR_ID),
2269 1.26.2.1 rmind (CSRARC(fc, BUS_MGR_ID) != fc->nodeid) ? " (me)" : "");
2270 1.26.2.1 rmind if (CSRARC(fc, BUS_MGR_ID) != fc->nodeid)
2271 1.1 kiyohara /* We are not the bus manager */
2272 1.26.2.1 rmind return 0;
2273 1.1 kiyohara
2274 1.1 kiyohara /* Optimize gapcount */
2275 1.26.2.1 rmind if (fc->max_hop <= MAX_GAPHOP)
2276 1.1 kiyohara fw_phy_config(fc, cmstr, gap_cnt[fc->max_hop]);
2277 1.1 kiyohara /* If we are the cycle master, nothing to do */
2278 1.1 kiyohara if (cmstr == fc->nodeid || cmstr == -1)
2279 1.1 kiyohara return 0;
2280 1.1 kiyohara /* Bus probe has not finished, make dummy fwdev for cmstr */
2281 1.24 cegger memset(&fwdev, 0, sizeof(fwdev));
2282 1.1 kiyohara fwdev.fc = fc;
2283 1.1 kiyohara fwdev.dst = cmstr;
2284 1.1 kiyohara fwdev.speed = 0;
2285 1.1 kiyohara fwdev.maxrec = 8; /* 512 */
2286 1.1 kiyohara fwdev.status = FWDEVINIT;
2287 1.1 kiyohara /* Set cmstr bit on the cycle master */
2288 1.1 kiyohara quad = htonl(1 << 8);
2289 1.26.2.1 rmind fwmem_write_quad(&fwdev, NULL, 0/*spd*/, 0xffff, 0xf0000000 | STATE_SET,
2290 1.26.2.1 rmind &quad, fw_asy_callback_free);
2291 1.1 kiyohara
2292 1.1 kiyohara return 0;
2293 1.1 kiyohara }
2294