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