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