diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/cardbus/files.cardbus | 8 | ||||
-rw-r--r-- | sys/dev/cardbus/fwohci_cardbus.c | 214 | ||||
-rw-r--r-- | sys/dev/ieee1394/IMPLEMENTATION | 58 | ||||
-rw-r--r-- | sys/dev/ieee1394/TODO | 61 | ||||
-rw-r--r-- | sys/dev/ieee1394/files.ieee1394 | 17 | ||||
-rw-r--r-- | sys/dev/ieee1394/fwnode.c | 497 | ||||
-rw-r--r-- | sys/dev/ieee1394/fwnodereg.h | 59 | ||||
-rw-r--r-- | sys/dev/ieee1394/fwnodevar.h | 54 | ||||
-rw-r--r-- | sys/dev/ieee1394/fwohci.c | 4593 | ||||
-rw-r--r-- | sys/dev/ieee1394/fwohcireg.h | 560 | ||||
-rw-r--r-- | sys/dev/ieee1394/fwohcivar.h | 252 | ||||
-rw-r--r-- | sys/dev/ieee1394/fwscsi.c | 1090 | ||||
-rw-r--r-- | sys/dev/ieee1394/ieee1394reg.h | 294 | ||||
-rw-r--r-- | sys/dev/ieee1394/ieee1394var.h | 124 | ||||
-rw-r--r-- | sys/dev/pci/files.pci | 10 | ||||
-rw-r--r-- | sys/dev/pci/fwlynx_pci.c | 146 | ||||
-rw-r--r-- | sys/dev/pci/fwohci_pci.c | 176 | ||||
-rw-r--r-- | sys/dev/std/SBP2.roadmap | 149 | ||||
-rw-r--r-- | sys/dev/std/ieee1212.c | 1593 | ||||
-rw-r--r-- | sys/dev/std/ieee1212reg.h | 265 | ||||
-rw-r--r-- | sys/dev/std/ieee1212var.h | 107 | ||||
-rw-r--r-- | sys/dev/std/sbp2.c | 1358 | ||||
-rw-r--r-- | sys/dev/std/sbp2reg.h | 115 | ||||
-rw-r--r-- | sys/dev/std/sbp2var.h | 198 |
24 files changed, 2 insertions, 11996 deletions
diff --git a/sys/dev/cardbus/files.cardbus b/sys/dev/cardbus/files.cardbus index 195d0de3e01..74fe04ebd67 100644 --- a/sys/dev/cardbus/files.cardbus +++ b/sys/dev/cardbus/files.cardbus @@ -1,4 +1,4 @@ -# $OpenBSD: files.cardbus,v 1.14 2005/02/15 20:51:18 damien Exp $ +# $OpenBSD: files.cardbus,v 1.15 2005/03/05 23:58:43 tdeval Exp $ # $NetBSD: files.cardbus,v 1.8 2000/01/26 06:37:24 thorpej Exp $ # # files.cardbus @@ -38,12 +38,6 @@ attach fxp at cardbus with fxp_cardbus file dev/cardbus/if_fxp_cardbus.c fxp_cardbus # -# OHCI IEEE 1394 controller -# -attach fwohci at cardbus with fwohci_cardbus -file dev/cardbus/fwohci_cardbus.c fwohci_cardbus - -# # RealTek 8139 based CardBus cards # attach rl at cardbus with rl_cardbus diff --git a/sys/dev/cardbus/fwohci_cardbus.c b/sys/dev/cardbus/fwohci_cardbus.c deleted file mode 100644 index 35584bf1c7f..00000000000 --- a/sys/dev/cardbus/fwohci_cardbus.c +++ /dev/null @@ -1,214 +0,0 @@ -/* $OpenBSD: fwohci_cardbus.c,v 1.6 2004/10/07 21:16:59 brad Exp $ */ -/* $NetBSD: fwohci_cardbus.c,v 1.5 2002/01/26 16:34:28 ichiro Exp $ */ - -/* - * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Matt Thomas of 3am Software Foundry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -#ifdef __KERNEL_RCSID -__KERNEL_RCSID(0, "$NetBSD: fwohci_cardbus.c,v 1.5 2002/01/26 16:34:28 ichiro Exp $"); -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/mbuf.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <sys/errno.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <sys/proc.h> -#include <sys/device.h> - -#include <machine/bus.h> - -#include <dev/pci/pcireg.h> -#include <dev/pci/pcivar.h> -#include <dev/pci/pcidevs.h> - -#include <dev/cardbus/cardbusvar.h> - -#include <dev/ieee1394/ieee1394reg.h> -#include <dev/ieee1394/ieee1394var.h> -#include <dev/ieee1394/fwohcireg.h> -#include <dev/ieee1394/fwohcivar.h> - -struct fwohci_cardbus_softc { - struct fwohci_softc sc_sc; - cardbus_chipset_tag_t sc_cc; - cardbus_function_tag_t sc_cf; - cardbus_devfunc_t sc_ct; - void *sc_ih; -}; - -#ifdef __NetBSD__ -int fwohci_cardbus_match(struct device *, struct cfdata *, void *); -#else -int fwohci_cardbus_match(struct device *, void *, void *); -#endif -void fwohci_cardbus_attach(struct device *, struct device *, void *); -int fwohci_cardbus_detach(struct device *, int); - -struct cfattach fwohci_cardbus_ca = { - sizeof(struct fwohci_cardbus_softc), fwohci_cardbus_match, - fwohci_cardbus_attach, fwohci_cardbus_detach, fwohci_activate -}; - -#define CARDBUS_INTERFACE_OHCI PCI_INTERFACE_OHCI -#define CARDBUS_OHCI_MAP_REGISTER PCI_OHCI_MAP_REGISTER -#define CARDBUS_OHCI_CONTROL_REGISTER PCI_OHCI_CONTROL_REGISTER -#define CARDBUS_GLOBAL_SWAP_BE PCI_GLOBAL_SWAP_BE -#define cardbus_devinfo pci_devinfo - -int -#ifdef __NetBSD__ -fwohci_cardbus_match(struct device *parent, struct cfdata *match, void *aux) -#else -fwohci_cardbus_match(struct device *parent, void *match, void *aux) -#endif -{ - struct cardbus_attach_args *ca = (struct cardbus_attach_args *)aux; - - if (CARDBUS_CLASS(ca->ca_class) == CARDBUS_CLASS_SERIALBUS && - CARDBUS_SUBCLASS(ca->ca_class) == - CARDBUS_SUBCLASS_SERIALBUS_FIREWIRE && - CARDBUS_INTERFACE(ca->ca_class) == CARDBUS_INTERFACE_OHCI) - return (1); - - return (0); -} - -void -fwohci_cardbus_attach(struct device *parent, struct device *self, void *aux) -{ - struct cardbus_attach_args *ca = aux; - struct fwohci_cardbus_softc *sc = (struct fwohci_cardbus_softc *)self; - cardbus_devfunc_t ct = ca->ca_ct; - cardbus_chipset_tag_t cc = ct->ct_cc; - cardbus_function_tag_t cf = ct->ct_cf; - cardbusreg_t csr; - char devinfo[256]; - const char *devname = self->dv_xname; - - cardbus_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof devinfo); - printf(": %s (rev. 0x%02x)\n", devinfo, - CARDBUS_REVISION(ca->ca_class)); - - /* Map I/O registers */ - if (Cardbus_mapreg_map(ct, CARDBUS_OHCI_MAP_REGISTER, - CARDBUS_MAPREG_TYPE_MEM, 0, - &sc->sc_sc.sc_memt, &sc->sc_sc.sc_memh, - NULL, &sc->sc_sc.sc_memsize)) { - printf("%s: can't map OHCI register space\n", devname); - return; - } - - sc->sc_cc = cc; - sc->sc_cf = cf; - sc->sc_ct = ct; - sc->sc_sc.sc_dmat = ca->ca_dmat; - -#if rbus -#else -XXX (ct->ct_cf->cardbus_mem_open)(cc, 0, iob, iob + 0x40); -#endif - (ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE); - (ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE); - - /* Disable interrupts, so we don't get any spurious ones. */ - OHCI_CSR_WRITE(&sc->sc_sc, OHCI_REG_IntMaskClear, - OHCI_Int_MasterEnable); - - /* Enable the device. */ - csr = cardbus_conf_read(cc, cf, ca->ca_tag, CARDBUS_COMMAND_STATUS_REG); - cardbus_conf_write(cc, cf, ca->ca_tag, CARDBUS_COMMAND_STATUS_REG, - csr | CARDBUS_COMMAND_MASTER_ENABLE | CARDBUS_COMMAND_MEM_ENABLE); - -#if BYTE_ORDER == BIG_ENDIAN - csr = cardbus_conf_read(cc, cf, ca->ca_tag, - CARDBUS_OHCI_CONTROL_REGISTER); - cardbus_conf_write(cc, cf, ca->ca_tag, CARDBUS_OHCI_CONTROL_REGISTER, - csr | CARDBUS_GLOBAL_SWAP_BE); -#endif - - sc->sc_ih = cardbus_intr_establish(cc, cf, ca->ca_intrline, - IPL_BIO, fwohci_intr, sc); - if (sc->sc_ih == NULL) { - printf("%s: couldn't establish interrupt\n", devname); - return; - } - printf("%s: interrupting at %d\n", devname, ca->ca_intrline); - - /* XXX NULL should be replaced by some call to Cardbus code. */ - if (fwohci_init(&sc->sc_sc, NULL) != 0) { - cardbus_intr_disestablish(cc, cf, sc->sc_ih); - bus_space_unmap(sc->sc_sc.sc_memt, sc->sc_sc.sc_memh, - sc->sc_sc.sc_memsize); - } -} - -int -fwohci_cardbus_detach(struct device *self, int flags) -{ - struct fwohci_cardbus_softc *sc = (struct fwohci_cardbus_softc *)self; - struct ieee1394_softc *iea; - cardbus_devfunc_t ct = sc->sc_ct; - int rv = 0; - - LIST_FOREACH(iea, &sc->sc_sc.sc_nodelist, sc1394_node) { -#ifdef FWOHCI_DEBUG - printf("%s: detach %s\n", __func__, iea->sc1394_dev.dv_xname); -#endif /* FWOHCI_DEBUG */ - rv |= config_detach(&iea->sc1394_dev, flags); - } - - rv |= fwohci_detach(&sc->sc_sc, flags); - - if (rv) - return (rv); - - if (sc->sc_ih != NULL) { - cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, sc->sc_ih); - sc->sc_ih = NULL; - } - if (sc->sc_sc.sc_memsize) { - Cardbus_mapreg_unmap(ct, CARDBUS_OHCI_MAP_REGISTER, - sc->sc_sc.sc_memt, sc->sc_sc.sc_memh, - sc->sc_sc.sc_memsize); - sc->sc_sc.sc_memsize = 0; - } - return (0); -} diff --git a/sys/dev/ieee1394/IMPLEMENTATION b/sys/dev/ieee1394/IMPLEMENTATION deleted file mode 100644 index 0344ed2e6a8..00000000000 --- a/sys/dev/ieee1394/IMPLEMENTATION +++ /dev/null @@ -1,58 +0,0 @@ -$OpenBSD: IMPLEMENTATION,v 1.2 2002/12/13 02:54:18 tdeval Exp $ -$NetBSD: IMPLEMENTATION,v 1.6 2002/02/03 07:29:14 jmc Exp $ - -At this point in time, there are 3 controller drivers planned: - - fwochi IEEE 1394 OHCI Controller (PCI & CardBus) - fwlynx TI TSB12LV21 (found B&W G3s) - fwsony Sony CXD1947A (found on Sony Vaio laptops) - -(Though as of this time, Sony has declined to release documentation -about the CXD1947A). - -The device hierarchy will look like (using fwohci as the example): - -# -# The controller driver. Handles the device-specific 1394 functions. -# -fwohci* at pci? dev ? function ? -# For each remote 1394 device on the 1394 bus, there will be a corresponding -# fwnode. If a 1394 device offers any supported services, they will be -# a child of corresponding fwnode. A particular fwnode can be tied to a -# specific device by specifing its nodeid as its identifier (XXX this -# is a 64 bit quantity and locators used by config must be 32 bit integers). -# -fwnode0 at fwbus? idhi 0x003065ff idlo 0xfedc46c0 -fwnode1 at fwbus? idhi 0x0060e202 idlo 0x0000157e -fwnode2 at fwbus? idhi 0x00110600 idlo 0x00003169 -fwnode* at fwbus? idhi ? idlo ? -# -# An ip capable interface can be added to the local bus as a service to offer -# on the bus. (the code will only attach to the local bridge so 2 boxes plugged -# into each other would only each have fw0, but would see the other side as -# fwnodeX when it probes for remote devices) -# -fw* at fwbus? -# -# NOTE: All fwbus's, fw's, fwnode's derive their device struct from an -# ieee1394_softc which allows the various layers to have a standard way to -# look at values in their children nodes. (updating nodeid's, etc) -# -# One of the services that a node might offer is access to SCSI devices via -# SBP-2. As described above, this means a scsibus is a child of fwnode at -# some point. (Making it a direct child is bad since that drags in the whole -# scsi code base even if all a person wants is an fwnode and camera support) -# -fwscsi* at fwnode? -scsibus* at fwscsi? - -Note that with the advent of highly mobile storage devices, the need for -signatures or other mechanisms to identify disks independently of their -location in the device hierarchy is sorely needed. - -fwohci0 at pci1 dev 12 function 0: NEC uPD72870 IEEE 1394 OHCI Host Controller (rev. 0x01) -fwohci0: interrupting at isa irq 15 -fwohci0: OHCI 1.0 -fw0 at fwohci0: Id 00:d0:f5:20:00:00:5e:84, 400Mb/s, 1024 byte packets max -fw0: isochronous channels: 16 transmit, 16 receive -fwnode0 at fwohci0: Id xx:xx:xx:xx:xx:xx:xx:xx diff --git a/sys/dev/ieee1394/TODO b/sys/dev/ieee1394/TODO deleted file mode 100644 index 923c9e864a2..00000000000 --- a/sys/dev/ieee1394/TODO +++ /dev/null @@ -1,61 +0,0 @@ -### $OpenBSD: TODO,v 1.4 2002/12/30 12:54:05 tdeval Exp $ ### - -TODO : ------- - -- Move all mbuf code to if_fw.c. Make if_fw use the generic read/write/inreg - and then it can translate the packets into the appropriate mbuf's. - -- Need a tlabel alloc routine within fwohci and a way to use 64 tlabel's per - node (rather than a global set of 64 as it's used now). - -- Flesh out the documentation of the high level API in fwohci.c (fwlynx will - need to implement the same thing so this should be more than just comments - in fwohci.c). - -- Track down issues where multiple hosts plugged into a firewire hub don't - init/see all devices on resets sometimes. - -- Should do topology maps, speed maps, the various bus managers, etc. - -- Implement a real fwscsi scsibus, with each attached device as a new - target/lun. Not a new scsibus per device. - -- Implement proper handlers with either 1 main thread, or timeouts and - callbacks. - -- Move all the SBP2 data manipulation routines to SBP2 codebase. - -============================================================================== - -DONE : ------- - -- Move SBP2 routines into their own file. - -- Rewrite ROM parsing/validation. Unroll all recursion, add ref counting, path - elimination, etc. - -- Move rom routines into their own files to allow easier cross usage. - -- Write sub match setup for fwnode/fwscsi so matching devices listed in the - ROM can be done via autoconf. - -- Remove all of the devcap stuff. - -- SBP2 needs a complete API written up: logins, ORB management/allocation, etc. - (basic routines have been implemented). - -- Add locator detection/usage into fwohci code. - -- Change all FW_DEBUG wrapped printf's to DPRINTF macro's. - -- Ack errors from a TX complete should get passed up to any registered - callbacks. - -- Make fwohci detach correctly (for cardbus/etc type interfaces). - -- Use handler_set (with NULL cb) to create a higher level <bus>_unreg. - -- Rewrite handler_set to allow sub regions, minimums, etc without having to - register 100 callbacks for 100 quad reads. diff --git a/sys/dev/ieee1394/files.ieee1394 b/sys/dev/ieee1394/files.ieee1394 deleted file mode 100644 index b3cd8c6150f..00000000000 --- a/sys/dev/ieee1394/files.ieee1394 +++ /dev/null @@ -1,17 +0,0 @@ -# $OpenBSD: files.ieee1394,v 1.3 2002/12/30 12:54:05 tdeval Exp $ -# $NetBSD: files.ieee1394,v 1.6 2002/02/27 05:02:25 jmc Exp $ - -file dev/ieee1394/fwlynx.c fwlynx -file dev/ieee1394/fwohci.c fwohci - -device fwnode { } -attach fwnode at fwbus: ieee1212 -file dev/ieee1394/fwnode.c fwnode - -device fwscsi: scsi -attach fwscsi at fwnode: sbp2 -file dev/ieee1394/fwscsi.c fwscsi - -#device fw: ieee1394, ifnet -#attach fw at fwbus -#file dev/ieee1394/if_fw.c fw diff --git a/sys/dev/ieee1394/fwnode.c b/sys/dev/ieee1394/fwnode.c deleted file mode 100644 index f90b1246df4..00000000000 --- a/sys/dev/ieee1394/fwnode.c +++ /dev/null @@ -1,497 +0,0 @@ -/* $OpenBSD: fwnode.c,v 1.6 2003/01/12 12:05:53 tdeval Exp $ */ -/* $NetBSD: fwnode.c,v 1.13 2002/04/03 04:15:59 jmc Exp $ */ - -/* - * Copyright (c) 2001,2002 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by James Chacon. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -#ifdef __KERNEL_RCSID -__KERNEL_RCSID(0, "$NetBSD: fwnode.c,v 1.13 2002/04/03 04:15:59 jmc Exp $"); -#endif - -#include <sys/param.h> -#include <sys/kernel.h> -#include <sys/device.h> -#include <sys/systm.h> -#include <sys/malloc.h> - -#include <machine/bus.h> - -#include <dev/std/ieee1212var.h> -#include <dev/std/ieee1212reg.h> - -#include <dev/ieee1394/ieee1394reg.h> -#include <dev/ieee1394/fwnodereg.h> - -#include <dev/ieee1394/ieee1394var.h> -#include <dev/ieee1394/fwnodevar.h> - -#if 0 -const char * const ieee1394_speeds[] = { IEEE1394_SPD_STRINGS }; -#endif - -#ifdef __NetBSD__ -int fwnode_match(struct device *, struct cfdata *, void *); -#else -int fwnode_match(struct device *, void *, void *); -#endif -void fwnode_attach(struct device *, struct device *, void *); -int fwnode_detach(struct device *, int); -void fwnode_configrom_input(struct ieee1394_abuf *, int); -int fwnode_print(void *, const char *); -#ifdef FWNODE_DEBUG -void fwnode_dump_rom(struct fwnode_softc *, u_int32_t *, u_int32_t); -#endif /* FWNODE_DEBUG */ - -#ifdef FWNODE_DEBUG -#include <sys/syslog.h> -extern int log_open; -int fwnode_oldlog; -#define DPRINTF(x) if (fwnodedebug) do { \ - fwnode_oldlog = log_open; log_open = 1; \ - addlog x; log_open = fwnode_oldlog; \ -} while (0) -#define DPRINTFN(n,x) if (fwnodedebug>(n)) do { \ - fwnode_oldlog = log_open; log_open = 1; \ - addlog x; log_open = fwnode_oldlog; \ -} while (0) -#ifdef FW_MALLOC_DEBUG -#define MPRINTF(x,y) DPRINTF(("%s[%d]: %s 0x%08x\n", \ - __func__, __LINE__, (x), (u_int32_t)(y))) -#else /* !FW_MALLOC_DEBUG */ -#define MPRINTF(x,y) -#endif /* FW_MALLOC_DEBUG */ - -int fwnodedebug = 0; -#else /* FWNODE_DEBUG */ -#define DPRINTF(x) -#define DPRINTFN(n,x) -#define MPRINTF(x,y) -#endif /* ! FWNODE_DEBUG */ - -#ifdef __OpenBSD__ -struct cfdriver fwnode_cd = { - NULL, "fwnode", DV_DULL -}; -#endif - -struct cfattach fwnode_ca = { - sizeof(struct fwnode_softc), fwnode_match, fwnode_attach, - fwnode_detach -}; - -#ifdef __NetBSD__ -int -fwnode_match(struct device *parent, struct cfdata *match, void *aux) -#else -int -fwnode_match(struct device *parent, void *match, void *aux) -#endif -{ - struct ieee1394_attach_args *fwa = aux; - - if (strcmp(fwa->name, "fwnode") == 0) - return (1); - return (0); -} - -void -fwnode_attach(struct device *parent, struct device *self, void *aux) -{ - struct fwnode_softc *sc = (struct fwnode_softc *)self; - struct ieee1394_softc *psc = (struct ieee1394_softc *)parent; - struct ieee1394_attach_args *fwa = aux; - struct ieee1394_abuf *ab; - -#ifdef M_ZERO - MALLOC(ab, struct ieee1394_abuf *, sizeof(*ab), - M_1394DATA, M_WAITOK|M_ZERO); - MPRINTF("MALLOC(1394DATA)", ab); -#else - MALLOC(ab, struct ieee1394_abuf *, sizeof(*ab), M_1394DATA, M_WAITOK); - MPRINTF("MALLOC(1394DATA)", ab); - bzero(ab, sizeof(*ab)); -#endif - ab->ab_data = malloc(4, M_1394DATA, M_WAITOK); - MPRINTF("malloc(1394DATA)", ab->ab_data); - ab->ab_data[0] = 0; - - sc->sc_sc1394.sc1394_link_speed = fwa->link_speed; - sc->sc_sc1394.sc1394_node_id = fwa->nodeid; - memcpy(sc->sc_sc1394.sc1394_guid, fwa->uid, 8); - sc->sc1394_read = fwa->read; - sc->sc1394_write = fwa->write; - sc->sc1394_inreg = fwa->inreg; - sc->sc1394_unreg = fwa->unreg; - - /* XXX. Fix the fw code to use the generic routines. */ - sc->sc_sc1394.sc1394_ifinreg = psc->sc1394_ifinreg; - sc->sc_sc1394.sc1394_ifoutput = psc->sc1394_ifoutput; - - printf(" Node %d: UID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - sc->sc_sc1394.sc1394_node_id, - sc->sc_sc1394.sc1394_guid[0], sc->sc_sc1394.sc1394_guid[1], - sc->sc_sc1394.sc1394_guid[2], sc->sc_sc1394.sc1394_guid[3], - sc->sc_sc1394.sc1394_guid[4], sc->sc_sc1394.sc1394_guid[5], - sc->sc_sc1394.sc1394_guid[6], sc->sc_sc1394.sc1394_guid[7]); - ab->ab_req = (struct ieee1394_softc *)sc; - ab->ab_addr = CSR_BASE + CSR_CONFIG_ROM; - ab->ab_length = 4; - ab->ab_retlen = 0; - ab->ab_cbarg = NULL; - ab->ab_cb = fwnode_configrom_input; - sc->sc1394_read(ab); -} - -int -fwnode_detach(struct device *self, int flags) -{ - struct fwnode_softc *sc = (struct fwnode_softc *)self; - struct device **children; - - if (sc->sc_children) { - children = sc->sc_children; - while (*children != NULL) { - config_detach(*children, 0); - children++; - } - free(sc->sc_children, M_DEVBUF); - MPRINTF("free(DEVBUF)", sc->sc_children); - sc->sc_children = NULL; - } - - if (sc->sc_sc1394.sc1394_configrom && - sc->sc_sc1394.sc1394_configrom_len) { - free(sc->sc_sc1394.sc1394_configrom, M_1394DATA); - MPRINTF("free(1394DATA)", sc->sc_sc1394.sc1394_configrom); - sc->sc_sc1394.sc1394_configrom = NULL; - } - - if (sc->sc_configrom) - p1212_free(sc->sc_configrom); - return 0; -} - -/* - * This code is trying to build a complete image of the ROM in memory. - * This is done all here to keep the bus_read logic/callback for the ROM in one - * place since reading the whole ROM may require lots of small reads up front - * and building separate callback handlers for each step would be even worse. - */ - -typedef struct cfgrom_cbarg { - int cc_type; - int cc_retlen; - int cc_num; - uint32_t *cc_buf; -} cfgrom_cbarg; - -void -fwnode_configrom_input(struct ieee1394_abuf *ab, int rcode) -{ - struct fwnode_softc *sc = (struct fwnode_softc *)ab->ab_req; - struct cfgrom_cbarg *cc = NULL; - u_int32_t val, *cbuf; - - if (ab->ab_cbarg != NULL) { - cc = (struct cfgrom_cbarg *) ab->ab_cbarg; - if (cc->cc_type != 0x31333934) - panic("Got an invalid abuf on callback"); - DPRINTF(("(cc_num:%d/0x%02x) ", cc->cc_num, cc->cc_num)); - } - - if (rcode != IEEE1394_RCODE_COMPLETE) { - DPRINTF(("Aborting configrom input, rcode: %d\n", rcode)); -#ifdef FWNODE_DEBUG - fwnode_dump_rom(sc, ab->ab_data, ab->ab_retlen); -#endif /* FWNODE_DEBUG */ - if (cc != NULL) { - FREE(cc, M_1394DATA); - MPRINTF("FREE(1394DATA)", cc); - cc = NULL; /* XXX */ - } - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - return; - } - - if (ab->ab_length != ab->ab_retlen) { - DPRINTF(("%s: config rom short read. Expected :%d, received: " - "%d. Not attaching\n", sc->sc_sc1394.sc1394_dev.dv_xname, - ab->ab_length, ab->ab_retlen)); - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - return; - } - if (ab->ab_retlen % 4) { - DPRINTF(("%s: configrom read of invalid length: %d\n", - sc->sc_sc1394.sc1394_dev.dv_xname, ab->ab_retlen)); - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - return; - } - - ab->ab_retlen = ab->ab_retlen / 4; - - if (cc != NULL) { - cc->cc_buf[cc->cc_num++] = ab->ab_data[0]; - ab->ab_data[0] = 0; - if (cc->cc_num < cc->cc_retlen) { - ab->ab_addr = CSR_BASE + CSR_CONFIG_ROM + - cc->cc_num * 4; - ab->ab_length = 4; - ab->ab_retlen = 0; - ab->ab_cb = fwnode_configrom_input; - ab->ab_cbarg = cc; - sc->sc1394_read(ab); - return; - } else { - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; - ab->ab_data = &cc->cc_buf[0]; - ab->ab_retlen = cc->cc_retlen; - ab->ab_length = cc->cc_retlen * 4; - FREE(cc, M_1394DATA); - MPRINTF("FREE(1394DATA)", cc); - cc = NULL; /* XXX */ - ab->ab_cbarg = NULL; - } - } - - if (p1212_iscomplete(ab->ab_data, &ab->ab_retlen) == -1) { - DPRINTF(("%s: configrom parse error\n", - sc->sc_sc1394.sc1394_dev.dv_xname)); - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; /* XXX */ - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - return; - } - -#ifdef DIAGNOSTIC - if (ab->ab_retlen < (ab->ab_length / 4)) - panic("Configrom shrank during iscomplete check?"); -#endif - - if (ab->ab_retlen > (ab->ab_length / 4)) { - - if (cc != NULL) { /* Should never occur here */ - DPRINTF(("%s: cbarg not NULL\n", - sc->sc_sc1394.sc1394_dev.dv_xname)); - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; /* XXX */ - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - return; - } - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; /* XXX */ - - if (ab->ab_length == 4) { /* reread whole rom */ -#ifdef M_ZERO - ab->ab_data = malloc(ab->ab_retlen * 4, M_1394DATA, - M_WAITOK|M_ZERO); - MPRINTF("malloc(1394DATA)",ab->ab_data); -#else - ab->ab_data = malloc(ab->ab_retlen * 4, - M_1394DATA, M_WAITOK); - MPRINTF("malloc(1394DATA)",ab->ab_data); - bzero(ab->ab_data, ab->ab_retlen * 4); -#endif - - ab->ab_addr = CSR_BASE + CSR_CONFIG_ROM; - ab->ab_length = ab->ab_retlen * 4; - ab->ab_retlen = 0; - ab->ab_cbarg = NULL; - ab->ab_cb = fwnode_configrom_input; - sc->sc1394_read(ab); - } else { /* reread quadlet-wise */ - DPRINTF(("%s: configrom re-read %d(0x%02x) quadlets" - " - 0x%08x\n", sc->sc_sc1394.sc1394_dev.dv_xname, - ab->ab_retlen, ab->ab_retlen, ab->ab_data[0])); - -#ifdef M_ZERO - cbuf = malloc(ab->ab_retlen * 4, M_1394DATA, - M_WAITOK|M_ZERO); - MPRINTF("malloc(1394DATA)", cbuf); - MALLOC(cc, struct cfgrom_cbarg *, sizeof(*cc), - M_1394DATA, M_WAITOK|M_ZERO); - MPRINTF("MALLOC(1394DATA)", cc); -#else - cbuf = malloc(ab->ab_retlen * 4, M_1394DATA, M_WAITOK); - MPRINTF("malloc(1394DATA)", cbuf); - bzero(cbuf, ab->ab_retlen * 4); - MALLOC(cc, struct cfgrom_cbarg *, sizeof(*cc), - M_1394DATA, M_WAITOK); - MPRINTF("MALLOC(1394DATA)", cc); - bzero(cc, sizeof(*cc)); -#endif - cc->cc_type = 0x31333934; - cc->cc_retlen = ab->ab_retlen; - cc->cc_num = 0; - cc->cc_buf = cbuf; - - ab->ab_data = malloc(4, M_1394DATA, M_WAITOK); - MPRINTF("malloc(1394DATA)", ab->ab_data); - ab->ab_data[0] = 0; - ab->ab_addr = CSR_BASE + CSR_CONFIG_ROM; - ab->ab_length = 4; - ab->ab_retlen = 0; - ab->ab_cb = fwnode_configrom_input; - ab->ab_cbarg = cc; - sc->sc1394_read(ab); - } - return; - } else { - DPRINTF(("configrom loaded...\n")); - sc->sc_sc1394.sc1394_configrom_len = ab->ab_retlen; - sc->sc_sc1394.sc1394_configrom = ab->ab_data; - ab->ab_data = NULL; - - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - - /* - * Set P1212_ALLOW_DEPENDENT_INFO_OFFSET_TYPE and - * P1212_ALLOW_DEPENDENT_INFO_IMMED_TYPE as some protocols - * such as SBP2 need it. - */ - - val = P1212_ALLOW_DEPENDENT_INFO_OFFSET_TYPE; - val |= P1212_ALLOW_DEPENDENT_INFO_IMMED_TYPE; - val |= P1212_ALLOW_VENDOR_DIRECTORY_TYPE; - sc->sc_configrom = - p1212_parse(sc->sc_sc1394.sc1394_configrom, - sc->sc_sc1394.sc1394_configrom_len, val); - if ((sc->sc_configrom == NULL) || - (sc->sc_configrom->len != IEEE1394_BUSINFO_LEN)) { -#ifdef FWNODE_DEBUG - DPRINTF(("Parse error with config rom\n")); - fwnode_dump_rom(sc, sc->sc_sc1394.sc1394_configrom, - sc->sc_sc1394.sc1394_configrom_len); -#endif /* FWNODE_DEBUG */ - if (sc->sc_configrom) - p1212_free(sc->sc_configrom); - free(sc->sc_sc1394.sc1394_configrom, M_1394DATA); - MPRINTF("free(1394DATA)", sc->sc_sc1394.sc1394_configrom); - sc->sc_sc1394.sc1394_configrom = NULL; - sc->sc_sc1394.sc1394_configrom_len = 0; - return; - } - - val = htonl(IEEE1394_SIGNATURE); - if (memcmp(sc->sc_configrom->name, &val, 4)) { -#ifdef FWNODE_DEBUG - DPRINTF(("Invalid signature found in bus info block: " - "%s\n", sc->sc_configrom->name)); - fwnode_dump_rom(sc, sc->sc_sc1394.sc1394_configrom, - sc->sc_sc1394.sc1394_configrom_len); -#endif /* FWNODE_DEBUG */ - p1212_free(sc->sc_configrom); - free(sc->sc_sc1394.sc1394_configrom, M_1394DATA); - MPRINTF("free(1394DATA)", sc->sc_sc1394.sc1394_configrom); - sc->sc_sc1394.sc1394_configrom = NULL; - sc->sc_sc1394.sc1394_configrom_len = 0; - return; - } - - sc->sc_sc1394.sc1394_max_receive = - IEEE1394_GET_MAX_REC(ntohl(sc->sc_configrom->data[0])); - val = IEEE1394_GET_LINK_SPD(ntohl(sc->sc_configrom->data[0])); - DPRINTFN(1, ("%s: ConfigRom Link Speed: %s", - sc->sc_sc1394.sc1394_dev.dv_xname, ieee1394_speeds[val])); - printf("%s: Link Speed: %s, max_rec: %d bytes\n", - sc->sc_sc1394.sc1394_dev.dv_xname, - ieee1394_speeds[sc->sc_sc1394.sc1394_link_speed], - IEEE1394_MAX_REC(sc->sc_sc1394.sc1394_max_receive)); -#ifdef FWNODE_DEBUG - if (fwnodedebug) { - fwnode_dump_rom(sc, sc->sc_sc1394.sc1394_configrom, - sc->sc_sc1394.sc1394_configrom_len); - p1212_print(sc->sc_configrom->root); - } -#endif /* FWNODE_DEBUG */ - sc->sc_children = p1212_match_units(&sc->sc_sc1394.sc1394_dev, - sc->sc_configrom->root, fwnode_print); - } -} - -int -fwnode_print(void *aux, const char *pnp) -{ - if (pnp) - printf("Unknown device at %s", pnp); - - return UNCONF; -} - -#ifdef FWNODE_DEBUG -void -fwnode_dump_rom(struct fwnode_softc *sc, u_int32_t *t, u_int32_t len) -{ - int i; - DPRINTF(("%s: Config rom dump:\n", sc->sc_sc1394.sc1394_dev.dv_xname)); - for (i = 0; i < len; i++) { - if ((i % 4) == 0) { - if (i) - DPRINTF(("\n")); - DPRINTF(("%s: 0x%02hx: ", - sc->sc_sc1394.sc1394_dev.dv_xname, (short)(4 * i))); - } - DPRINTF(("0x%08x ", ntohl(t[i]))); - } - DPRINTF(("\n")); -} -#endif /* FWNODE_DEBUG */ diff --git a/sys/dev/ieee1394/fwnodereg.h b/sys/dev/ieee1394/fwnodereg.h deleted file mode 100644 index e2a1026ff1d..00000000000 --- a/sys/dev/ieee1394/fwnodereg.h +++ /dev/null @@ -1,59 +0,0 @@ -/* $OpenBSD: fwnodereg.h,v 1.2 2002/12/13 02:52:04 tdeval Exp $ */ -/* $NetBSD: fwnodereg.h,v 1.1 2001/05/01 04:46:23 jmc Exp $ */ - -/* - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by James Chacon. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_IEEE1394_FWNODEREG_H -#define _DEV_IEEE1394_FWNODEREG_H - -#define DEVTYPE_UNKNOWN 0x0 -#define DEVTYPE_SBP2 0x1 - -#define DEVSPEC_UNKNOWN 0x0 -#define DEVSPEC_SCSI2 0x1 - -#define FWNODE_ENABLED 0x0001 - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#endif /* _DEV_IEEE1394_FWNODEREG_H */ diff --git a/sys/dev/ieee1394/fwnodevar.h b/sys/dev/ieee1394/fwnodevar.h deleted file mode 100644 index 6cf353b11dc..00000000000 --- a/sys/dev/ieee1394/fwnodevar.h +++ /dev/null @@ -1,54 +0,0 @@ -/* $OpenBSD: fwnodevar.h,v 1.2 2002/12/13 02:52:04 tdeval Exp $ */ -/* $NetBSD: fwnodevar.h,v 1.4 2002/02/27 05:02:25 jmc Exp $ */ - -/* - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by James Chacon. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_IEEE1394_FWNODEVAR_H -#define _DEV_IEEE1394_FWNODEVAR_H - -typedef struct fwnode_softc { - struct ieee1394_softc sc_sc1394; - int sc_flags; - int (*sc1394_read) (struct ieee1394_abuf *); - int (*sc1394_write)(struct ieee1394_abuf *); - int (*sc1394_inreg)(struct ieee1394_abuf *, int); - int (*sc1394_unreg)(struct ieee1394_abuf *, int); - struct device **sc_children; - struct p1212_rom *sc_configrom; -} fwnode_softc; - -#endif /* _DEV_IEEE1394_FWNODEVAR_H */ diff --git a/sys/dev/ieee1394/fwohci.c b/sys/dev/ieee1394/fwohci.c deleted file mode 100644 index bd509682bf7..00000000000 --- a/sys/dev/ieee1394/fwohci.c +++ /dev/null @@ -1,4593 +0,0 @@ -/* $OpenBSD: fwohci.c,v 1.14 2003/10/22 09:31:30 jmc Exp $ */ -/* $NetBSD: fwohci.c,v 1.54 2002/03/29 05:06:42 jmc Exp $ */ - -/* - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Matt Thomas of 3am Software Foundry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * IEEE1394 Open Host Controller Interface - * based on OHCI Specification 1.1 (January 6, 2000) - * The first version to support network interface part is wrtten by - * Atsushi Onoe <onoe@netbsd.org>. - */ - -/* - * The first version to support isochronous acquisition part is wrtten - * by HAYAKAWA Koichi <haya@netbsd.org>. - */ - -#include <sys/cdefs.h> -#ifdef __KERNEL_RCSID -__KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.54 2002/03/29 05:06:42 jmc Exp $"); -#endif - -#define DOUBLEBUF 0 -#define NO_THREAD 0 - -#ifdef __NetBSD__ -#include "opt_inet.h" -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kthread.h> -#include <sys/socket.h> -#ifdef __NetBSD__ -#include <sys/callout.h> -#else -#include <sys/timeout.h> -#endif -#include <sys/device.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#ifdef __OpenBSD__ -#include <sys/endian.h> -#endif - -#if __NetBSD_Version__ >= 105010000 || !defined(__NetBSD__) -#include <uvm/uvm_extern.h> -#else -#include <vm/vm.h> -#endif - -#include <machine/bus.h> -#include <machine/intr.h> - -#include <dev/ieee1394/ieee1394reg.h> -#include <dev/ieee1394/fwohcireg.h> - -#include <dev/ieee1394/ieee1394var.h> -#include <dev/ieee1394/fwohcivar.h> - -const char * const ieee1394_speeds[] = { IEEE1394_SPD_STRINGS }; -const char * const ieee1394_power[] = { IEEE1394_POW_STRINGS }; - -#if 0 -int fwohci_dmamem_alloc(struct fwohci_softc *sc, int size, - int alignment, bus_dmamap_t *mapp, caddr_t *kvap, int flags); -#endif -void fwohci_create_event_thread(void *); -void fwohci_thread_init(void *); - -void fwohci_event_thread(struct fwohci_softc *); -void fwohci_event_dispatch(struct fwohci_softc *); -void fwohci_hw_init(struct fwohci_softc *); -void fwohci_power(int, void *); -void fwohci_shutdown(void *); - -int fwohci_desc_alloc(struct fwohci_softc *); -void fwohci_desc_free(struct fwohci_softc *); -struct fwohci_desc *fwohci_desc_get(struct fwohci_softc *, int); -void fwohci_desc_put(struct fwohci_softc *, struct fwohci_desc *, int); - -int fwohci_ctx_alloc(struct fwohci_softc *, struct fwohci_ctx **, - int, int, int); -void fwohci_ctx_free(struct fwohci_softc *, struct fwohci_ctx *); -void fwohci_ctx_init(struct fwohci_softc *, struct fwohci_ctx *); - -int fwohci_buf_alloc(struct fwohci_softc *, struct fwohci_buf *); -void fwohci_buf_free(struct fwohci_softc *, struct fwohci_buf *); -void fwohci_buf_init_rx(struct fwohci_softc *); -void fwohci_buf_start_rx(struct fwohci_softc *); -void fwohci_buf_stop_rx(struct fwohci_softc *); -void fwohci_buf_stop_tx(struct fwohci_softc *); -void fwohci_buf_next(struct fwohci_softc *, struct fwohci_ctx *); -int fwohci_buf_pktget(struct fwohci_softc *, struct fwohci_buf **, - caddr_t *, int); -int fwohci_buf_input(struct fwohci_softc *, struct fwohci_ctx *, - struct fwohci_pkt *); -int fwohci_buf_input_ppb(struct fwohci_softc *, struct fwohci_ctx *, - struct fwohci_pkt *); - -u_int8_t fwohci_phy_read(struct fwohci_softc *, u_int8_t); -void fwohci_phy_write(struct fwohci_softc *, u_int8_t, u_int8_t); -void fwohci_phy_busreset(struct fwohci_softc *); -void fwohci_phy_input(struct fwohci_softc *, struct fwohci_pkt *); - -int fwohci_handler_set(struct fwohci_softc *, int, u_int32_t, u_int32_t, - u_int32_t, int (*)(struct fwohci_softc *, void *, struct fwohci_pkt *), - void *); -int fwohci_block_handler_set(struct fwohci_softc *, int, u_int32_t, u_int32_t, - u_int32_t, int, int (*)(struct fwohci_softc *, void *, struct fwohci_pkt *), - void *); - -void fwohci_arrq_input(struct fwohci_softc *, struct fwohci_ctx *); -void fwohci_arrs_input(struct fwohci_softc *, struct fwohci_ctx *); -void fwohci_ir_input(struct fwohci_softc *, struct fwohci_ctx *); - -int fwohci_at_output(struct fwohci_softc *, struct fwohci_ctx *, - struct fwohci_pkt *); -void fwohci_at_done(struct fwohci_softc *, struct fwohci_ctx *, int); -void fwohci_atrs_output(struct fwohci_softc *, int, struct fwohci_pkt *, - struct fwohci_pkt *); - -int fwohci_guidrom_init(struct fwohci_softc *); -void fwohci_configrom_init(struct fwohci_softc *); -int fwohci_configrom_input(struct fwohci_softc *, void *, - struct fwohci_pkt *); -void fwohci_selfid_init(struct fwohci_softc *); -int fwohci_selfid_input(struct fwohci_softc *); - -void fwohci_csr_init(struct fwohci_softc *); -int fwohci_csr_input(struct fwohci_softc *, void *, - struct fwohci_pkt *); - -void fwohci_uid_collect(struct fwohci_softc *); -void fwohci_uid_req(struct fwohci_softc *, int); -int fwohci_uid_input(struct fwohci_softc *, void *, - struct fwohci_pkt *); -int fwohci_uid_lookup(struct fwohci_softc *, const u_int8_t *); -void fwohci_check_nodes(struct fwohci_softc *); - -int fwohci_if_inreg(struct device *, u_int32_t, u_int32_t, - void (*)(struct device *, struct mbuf *)); -int fwohci_if_input(struct fwohci_softc *, void *, struct fwohci_pkt *); -int fwohci_if_input_iso(struct fwohci_softc *, void *, struct fwohci_pkt *); -int fwohci_if_output(struct device *, struct mbuf *, - void (*)(struct device *, struct mbuf *)); -int fwohci_if_setiso(struct device *, u_int32_t, u_int32_t, u_int32_t, - void (*)(struct device *, struct mbuf *)); -int fwohci_read(struct ieee1394_abuf *); -int fwohci_write(struct ieee1394_abuf *); -int fwohci_read_resp(struct fwohci_softc *, void *, struct fwohci_pkt *); -int fwohci_write_ack(struct fwohci_softc *, void *, struct fwohci_pkt *); -int fwohci_read_multi_resp(struct fwohci_softc *, void *, - struct fwohci_pkt *); -int fwohci_inreg(struct ieee1394_abuf *, int); -int fwohci_unreg(struct ieee1394_abuf *, int); -int fwohci_parse_input(struct fwohci_softc *, void *, - struct fwohci_pkt *); -#ifdef __NetBSD__ -int fwohci_submatch(struct device *, struct cfdata *, void *); -#else -int fwohci_submatch(struct device *, void *, void *); -#endif -u_int16_t fwohci_crc16(u_int32_t *, int); - -#ifdef FWOHCI_DEBUG -void fwohci_show_intr(struct fwohci_softc *, u_int32_t); -void fwohci_show_phypkt(struct fwohci_softc *, u_int32_t); - -/* 1 is normal debug, 2 is verbose debug, 3 is complete (packet dumps). */ - -#include <sys/syslog.h> -extern int log_open; -int fwohci_oldlog; -#define DPRINTF(x) if (fwohcidebug) do { \ - fwohci_oldlog = log_open; log_open = 1; \ - addlog x; log_open = fwohci_oldlog; \ -} while (0) -#define DPRINTFN(n,x) if (fwohcidebug>(n)) do { \ - fwohci_oldlog = log_open; log_open = 1; \ - addlog x; log_open = fwohci_oldlog; \ -} while (0) -#ifdef FW_MALLOC_DEBUG -#define MPRINTF(x,y) DPRINTF(("%s[%d]: %s 0x%08x\n", \ - __func__, __LINE__, (x), (u_int32_t)(y))) -#else /* !FW_MALLOC_DEBUG */ -#define MPRINTF(x,y) -#endif /* FW_MALLOC_DEBUG */ - -int fwohcidebug = 0; -int fwintr = 0; -caddr_t fwptr = 0; -int fwlen = 0; -struct fwohci_buf *fwbuf = NULL; -#else /* FWOHCI_DEBUG */ -#define DPRINTF(x) -#define DPRINTFN(n,x) -#define MPRINTF(x,y) -#endif /* ! FWOHCI_DEBUG */ - -#ifdef __OpenBSD__ -struct cfdriver fwohci_cd = { - NULL, "fwohci", DV_DULL -}; -#endif - -int -fwohci_init(struct fwohci_softc *sc, const struct evcnt *ev) -{ - int i; - u_int32_t val; -#if 0 - int error; -#endif - -#ifdef __NetBSD__ - evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ev, - sc->sc_sc1394.sc1394_dev.dv_xname, "intr"); - - evcnt_attach_dynamic(&sc->sc_isocnt, EVCNT_TYPE_MISC, ev, - sc->sc_sc1394.sc1394_dev.dv_xname, "iso"); - evcnt_attach_dynamic(&sc->sc_isopktcnt, EVCNT_TYPE_MISC, ev, - sc->sc_sc1394.sc1394_dev.dv_xname, "isopackets"); -#endif - - /* - * Wait for reset completion. - */ - for (i = 0; i < OHCI_LOOP; i++) { - val = OHCI_CSR_READ(sc, OHCI_REG_HCControlClear); - if ((val & OHCI_HCControl_SoftReset) == 0) - break; - DELAY(10); - } - - /* - * What dialect of OHCI is this device ? - */ - val = OHCI_CSR_READ(sc, OHCI_REG_Version); - printf("%s: OHCI %u.%u", sc->sc_sc1394.sc1394_dev.dv_xname, - OHCI_Version_GET_Version(val), OHCI_Version_GET_Revision(val)); - - LIST_INIT(&sc->sc_nodelist); - - if (fwohci_guidrom_init(sc) != 0) { - printf("\n%s: fatal: no global UID ROM\n", - sc->sc_sc1394.sc1394_dev.dv_xname); - return -1; - } - - printf(", %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - sc->sc_sc1394.sc1394_guid[0], sc->sc_sc1394.sc1394_guid[1], - sc->sc_sc1394.sc1394_guid[2], sc->sc_sc1394.sc1394_guid[3], - sc->sc_sc1394.sc1394_guid[4], sc->sc_sc1394.sc1394_guid[5], - sc->sc_sc1394.sc1394_guid[6], sc->sc_sc1394.sc1394_guid[7]); - - /* - * Get the maximum link speed and receive size. - */ - val = OHCI_CSR_READ(sc, OHCI_REG_BusOptions); - sc->sc_sc1394.sc1394_link_speed = - OHCI_BITVAL(val, OHCI_BusOptions_LinkSpd); - if (sc->sc_sc1394.sc1394_link_speed < IEEE1394_SPD_MAX) { - printf(", %s", - ieee1394_speeds[sc->sc_sc1394.sc1394_link_speed]); - } else { - printf(", unknown speed %u", sc->sc_sc1394.sc1394_link_speed); - } - - /* - * MaxRec is encoded as log2(max_rec_octets)-1 - */ - sc->sc_sc1394.sc1394_max_receive = - 1 << (OHCI_BITVAL(val, OHCI_BusOptions_MaxRec) + 1); - printf(", %u max_rec", sc->sc_sc1394.sc1394_max_receive); - - /* - * Count how many isochronous ctx we have. - */ - OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntMaskSet, ~0); - val = OHCI_CSR_READ(sc, OHCI_REG_IsoRecvIntMaskClear); - OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntMaskClear, ~0); - for (i = 0; val != 0; val >>= 1) { - if (val & 0x1) - i++; - } - sc->sc_isoctx = i; - printf(", %d iso_ctx", sc->sc_isoctx); - - printf("\n"); - -#if 0 - error = fwohci_dmamem_alloc(sc, OHCI_CONFIG_SIZE, - OHCI_CONFIG_ALIGNMENT, &sc->sc_configrom_map, - (caddr_t *) &sc->sc_configrom, BUS_DMA_WAITOK|BUS_DMA_COHERENT); - return error; -#endif - - MALLOC(sc->sc_dying, int *, sizeof(int), M_DEVBUF, M_WAITOK); - MPRINTF("MALLOC(DEVBUF)", sc->sc_dying); - DPRINTF(("%s: sc_dying 0x%08x\n", __func__, (u_int32_t)sc->sc_dying)); - *sc->sc_dying = 0; - sc->sc_nodeid = 0xFFFF; /* Invalid. */ - -#ifdef __NetBSD__ - kthread_create(fwohci_create_event_thread, sc); -#else - if (initproc == NULL) - kthread_create_deferred(fwohci_create_event_thread, sc); - else - /* Late binding, threads already running. */ - fwohci_create_event_thread(sc); -#endif - - return 0; -} - -int -fwohci_if_setiso(struct device *self, u_int32_t channel, u_int32_t tag, - u_int32_t direction, void (*handler)(struct device *, struct mbuf *)) -{ - struct fwohci_softc *sc = (struct fwohci_softc *)self; - int retval; - int s; - - if (direction == 1) { - return EIO; - } - - s = splnet(); - retval = fwohci_handler_set(sc, IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK, - channel, tag, 0, fwohci_if_input_iso, handler); - splx(s); - - if (!retval) { - printf("%s: dummy iso handler set\n", - sc->sc_sc1394.sc1394_dev.dv_xname); - } else { - printf("%s: dummy iso handler cannot set\n", - sc->sc_sc1394.sc1394_dev.dv_xname); - } - - return retval; -} - -int -fwohci_intr(void *arg) -{ - struct fwohci_softc * const sc = arg; -#if 1 - int progress = 0; -#else - int progress = (sc->sc_intmask != 0); -#endif - u_int32_t intmask, iso; - - splassert(IPL_BIO); - -#ifdef FWOHCI_DEBUG - //DPRINTFN(3,("%s: in(%d)\n", __func__, fwintr)); - fwintr++; -#endif /* FWOHCI_DEBUG */ - -#if 1 - for (;;) { -#endif - intmask = OHCI_CSR_READ(sc, OHCI_REG_IntEventClear); - - /* - * On a bus reset, everything except bus reset gets - * cleared. That can't get cleared until the selfid - * phase completes (which happens outside the - * interrupt routines). So if just a bus reset is left - * in the mask and it's already in the sc_intmask, - * just return. - */ - - if ((intmask == 0xFFFFFFFF) || (intmask == 0) || - (progress && (intmask == OHCI_Int_BusReset) && - (sc->sc_intmask & OHCI_Int_BusReset))) { - - if (intmask == 0xFFFFFFFF) - config_detach(((struct device *)sc) - ->dv_parent, 0); - - if (progress) { -#if NO_THREAD - fwohci_event_dispatch(sc); -#else /* NO_THREAD */ - wakeup(fwohci_event_thread); -#endif /* NO_THREAD */ - } - -#ifdef FWOHCI_DEBUG - --fwintr; - //DPRINTFN(3,("%s: out(%d)\n", __func__, fwintr)); -#endif /* FWOHCI_DEBUG */ - - return (progress); - } -#if 1 - OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear, - intmask & ~OHCI_Int_BusReset); -#else - DPRINTFN(2,("%s: IntEventClear(0x%08x) IntMaskClear(0x%08x)\n", - __func__, - intmask & ~OHCI_Int_BusReset, - intmask & ~OHCI_Int_BusReset & ~OHCI_Int_MasterEnable)); - OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskClear, - intmask & ~OHCI_Int_BusReset & ~OHCI_Int_MasterEnable); - OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear, - intmask & ~OHCI_Int_BusReset); -#endif -#ifdef FWOHCI_DEBUG - if (fwohcidebug > 1) - fwohci_show_intr(sc, intmask); -#endif /* FWOHCI_DEBUG */ - - if (intmask & OHCI_Int_BusReset) { - /* - * According to OHCI spec 6.1.1 "busReset", - * all asynchronous transmit must be stopped before - * clearing BusReset. Moreover, the BusReset - * interrupt bit should not be cleared during the - * SelfID phase. Thus we turned off interrupt mask - * bit of BusReset instead until SelfID completion - * or SelfID timeout. - */ -#if 0 - DPRINTFN(2,("%s: IntMaskSet(0x%08x)" - " IntMaskClear(0x%08x)\n", __func__, - intmask & ~OHCI_Int_BusReset, OHCI_Int_BusReset)); - OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, - intmask & ~OHCI_Int_BusReset); -#endif - intmask &= OHCI_Int_SelfIDComplete; - OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskClear, - OHCI_Int_BusReset); - sc->sc_intmask = OHCI_Int_BusReset; - } - sc->sc_intmask |= intmask; - - if (intmask & OHCI_Int_IsochTx) { - iso = OHCI_CSR_READ(sc, OHCI_REG_IsoXmitIntEventClear); -#if 1 - OHCI_CSR_WRITE(sc, OHCI_REG_IsoXmitIntEventClear, iso); -#else - OHCI_CSR_WRITE(sc, OHCI_REG_IsoXmitIntEventClear, - sc->sc_isotxrst); -#endif - } - if (intmask & OHCI_Int_IsochRx) { -#if NO_THREAD - int i; - int asyncstream = 0; -#endif /* NO_THREAD */ - - iso = OHCI_CSR_READ(sc, OHCI_REG_IsoRecvIntEventClear); -#if 1 - OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntEventClear, iso); -#else - OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntEventClear, - sc->sc_isorxrst); -#endif -#if NO_THREAD - for (i = 0; i < sc->sc_isoctx; i++) { - if ((iso & (1<<i)) && - sc->sc_ctx_ir[i] != NULL) { - if (sc->sc_ctx_ir[i]->fc_type == - FWOHCI_CTX_ISO_SINGLE) { - asyncstream |= (1 << i); - continue; - } - bus_dmamap_sync(sc->sc_dmat, - sc->sc_ddmamap, - 0, sizeof(struct fwohci_desc) * - sc->sc_descsize, - BUS_DMASYNC_PREREAD); - sc->sc_isocnt.ev_count++; - - fwohci_ir_input(sc, sc->sc_ctx_ir[i]); - } - } - if (asyncstream != 0) { - sc->sc_iso |= asyncstream; - } else { - /* All iso intr is pure isochronous. */ - sc->sc_intmask &= ~OHCI_Int_IsochRx; - } -#else /* NO_THREAD */ - sc->sc_iso |= iso; -#endif /* NO_THREAD */ - } - - if (!progress) { - sc->sc_intrcnt.ev_count++; -#if 1 - progress = 1; -#endif - } -#if 1 - } -#else -#ifdef FWOHCI_DEBUG - --fwintr; - //DPRINTF(("%s: out(%d)\n", __func__, fwintr)); -#endif /* FWOHCI_DEBUG */ - - return (progress); -#endif -} - -void -fwohci_create_event_thread(void *arg) -{ - struct fwohci_softc *sc = arg; - -#ifdef __NetBSD__ - if (kthread_create1(fwohci_thread_init, sc, &sc->sc_event_thread, "%s", - sc->sc_sc1394.sc1394_dev.dv_xname)) -#else - if (kthread_create(fwohci_thread_init, sc, &sc->sc_event_thread, "%s", - sc->sc_sc1394.sc1394_dev.dv_xname)) -#endif - { - printf("%s: unable to create event thread\n", - sc->sc_sc1394.sc1394_dev.dv_xname); - panic("fwohci_create_event_thread"); - } -} - -void -fwohci_thread_init(void *arg) -{ - struct fwohci_softc *sc = arg; - int i; - - /* - * Allocate descriptors. - */ - if (fwohci_desc_alloc(sc)) { - printf("%s: not enabling interrupts\n", - sc->sc_sc1394.sc1394_dev.dv_xname); - kthread_exit(1); - } - - /* - * Enable Link Power. - */ - - OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, OHCI_HCControl_LPS); - - /* - * Allocate DMA Context. - */ - fwohci_ctx_alloc(sc, &sc->sc_ctx_arrq, OHCI_BUF_ARRQ_CNT, - OHCI_CTX_ASYNC_RX_REQUEST, FWOHCI_CTX_ASYNC); - fwohci_ctx_alloc(sc, &sc->sc_ctx_arrs, OHCI_BUF_ARRS_CNT, - OHCI_CTX_ASYNC_RX_RESPONSE, FWOHCI_CTX_ASYNC); - fwohci_ctx_alloc(sc, &sc->sc_ctx_atrq, 0, - OHCI_CTX_ASYNC_TX_REQUEST, FWOHCI_CTX_ASYNC); - fwohci_ctx_alloc(sc, &sc->sc_ctx_atrs, 0, - OHCI_CTX_ASYNC_TX_RESPONSE, FWOHCI_CTX_ASYNC); - sc->sc_ctx_ir = malloc(sizeof(sc->sc_ctx_ir[0]) * sc->sc_isoctx, - M_DEVBUF, M_WAITOK); - MPRINTF("malloc(DEVBUF)", sc->sc_ctx_ir); - for (i = 0; i < sc->sc_isoctx; i++) - sc->sc_ctx_ir[i] = NULL; - - /* - * Allocate buffer for configuration ROM and SelfID buffer. - */ - fwohci_buf_alloc(sc, &sc->sc_buf_cnfrom); - fwohci_buf_alloc(sc, &sc->sc_buf_selfid); - -#ifdef __NetBSD__ - callout_init(&sc->sc_selfid_callout); -#else - bzero(&sc->sc_selfid_callout, sizeof(sc->sc_selfid_callout)); -#endif - - sc->sc_sc1394.sc1394_ifinreg = fwohci_if_inreg; - sc->sc_sc1394.sc1394_ifoutput = fwohci_if_output; - sc->sc_sc1394.sc1394_ifsetiso = fwohci_if_setiso; - - /* - * Establish hooks for shutdown and suspend/resume. - */ - sc->sc_shutdownhook = shutdownhook_establish(fwohci_shutdown, sc); - sc->sc_powerhook = powerhook_establish(fwohci_power, sc); - - sc->sc_sc1394.sc1394_if = config_found(&sc->sc_sc1394.sc1394_dev, "fw", - fwohci_print); - - /* Main loop. It's not coming back normally. */ - - fwohci_event_thread(sc); - printf("%s: event thread exited\n", __func__); - - if (sc->sc_uidtbl != NULL) { - free(sc->sc_uidtbl, M_DEVBUF); - MPRINTF("free(DEVBUF)", sc->sc_uidtbl); - sc->sc_uidtbl = NULL; - } - - fwohci_buf_free(sc, &sc->sc_buf_selfid); - fwohci_buf_free(sc, &sc->sc_buf_cnfrom); - - free(sc->sc_ctx_ir, M_DEVBUF); - MPRINTF("free(DEVBUF)", sc->sc_ctx_ir); - sc->sc_ctx_ir = NULL; /* XXX */ - fwohci_ctx_free(sc, sc->sc_ctx_atrs); - fwohci_ctx_free(sc, sc->sc_ctx_atrq); - fwohci_ctx_free(sc, sc->sc_ctx_arrs); - fwohci_ctx_free(sc, sc->sc_ctx_arrq); - - fwohci_desc_free(sc); - - DPRINTF(("%s: waking up... 0x%08x\n", __func__, - (u_int32_t)sc->sc_dying)); - wakeup(sc->sc_dying); - kthread_exit(0); -} - -void -fwohci_event_thread(struct fwohci_softc *sc) -{ - int s; -#if ! NO_THREAD - int i; - uint32_t intmask, iso; -#endif /* NO_THREAD */ - - s = splbio(); - - /* - * Initialize hardware registers. - */ - - fwohci_hw_init(sc); - - /* Initial Bus Reset. */ - fwohci_phy_busreset(sc); - splx(s); - - while (! *sc->sc_dying) { -#if ! NO_THREAD - s = splbio(); - intmask = sc->sc_intmask; - if (intmask == 0) { -#endif /* NO_THREAD */ -#if 1 - tsleep(fwohci_event_thread, PZERO, "fwohciev", 8); -#else - tsleep(fwohci_event_thread, PZERO, "fwohciev", 0); -#endif -#if ! NO_THREAD - splx(s); - continue; - } - sc->sc_intmask = 0; - splx(s); - DPRINTFN(2, ("%s: treating interrupts 0x%08x\n", __func__, - intmask)); - - if (intmask & OHCI_Int_BusReset) { -// s = splbio(); - fwohci_buf_stop_tx(sc); -// splx(s); - if (sc->sc_uidtbl != NULL) { - free(sc->sc_uidtbl, M_DEVBUF); - MPRINTF("free(DEVBUF)", sc->sc_uidtbl); - sc->sc_uidtbl = NULL; - } - -#ifdef __NetBSD__ - callout_reset(&sc->sc_selfid_callout, - OHCI_SELFID_TIMEOUT, - (void (*)(void *))fwohci_phy_busreset, sc); -#else - timeout_set(&sc->sc_selfid_callout, - (void (*)(void *))fwohci_phy_busreset, sc); - timeout_add(&sc->sc_selfid_callout, - OHCI_SELFID_TIMEOUT); -#endif - sc->sc_nodeid = 0xFFFF; /* Indicate invalid. */ - sc->sc_rootid = 0; - sc->sc_irmid = IEEE1394_BCAST_PHY_ID; - } - if (intmask & OHCI_Int_SelfIDComplete) { - s = splbio(); - OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear, - OHCI_Int_BusReset); - OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, - OHCI_Int_BusReset); - splx(s); -#ifdef __NetBSD__ - callout_stop(&sc->sc_selfid_callout); -#else - timeout_del(&sc->sc_selfid_callout); -#endif - if (fwohci_selfid_input(sc) == 0) { -// s = splbio(); - fwohci_buf_start_rx(sc); -// splx(s); - fwohci_uid_collect(sc); - } - } - if (intmask & OHCI_Int_ReqTxComplete) { -// s = splbio(); - fwohci_at_done(sc, sc->sc_ctx_atrq, 0); -// splx(s); - } - if (intmask & OHCI_Int_RespTxComplete) { -// s = splbio(); - fwohci_at_done(sc, sc->sc_ctx_atrs, 0); -// splx(s); - } - if (intmask & OHCI_Int_RQPkt) { - fwohci_arrq_input(sc, sc->sc_ctx_arrq); - } - if (intmask & OHCI_Int_RSPkt) { - fwohci_arrs_input(sc, sc->sc_ctx_arrs); - } - if (intmask & OHCI_Int_IsochRx) { - s = splbio(); - iso = sc->sc_iso; - sc->sc_iso = 0; - splx(s); - for (i = 0; i < sc->sc_isoctx; i++) { - if ((iso & (1 << i)) && - sc->sc_ctx_ir[i] != NULL) { - fwohci_ir_input(sc, sc->sc_ctx_ir[i]); - sc->sc_isocnt.ev_count++; - } - } - } -#if 0 - DPRINTF(("%s: IntMaskSet(0x%08x)\n", - __func__, intmask & ~OHCI_Int_BusReset)); - s = splbio(); -// OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear, -// intmask & ~OHCI_Int_BusReset); - OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, - intmask & ~OHCI_Int_BusReset); - splx(s); -#endif -#endif /* NO_THREAD */ - } -} - -#if NO_THREAD -void -fwohci_event_dispatch(struct fwohci_softc *sc) -{ - int i, s; - u_int32_t intmask, iso; - - splassert(IPL_BIO); - intmask = sc->sc_intmask; - if (intmask == 0) - return; - - sc->sc_intmask = 0; - s = spl0(); - DPRINTFN(2, ("%s: treating interrupts 0x%08x\n", __func__, intmask)); - - if (intmask & OHCI_Int_BusReset) { -// s = splbio(); - fwohci_buf_stop_tx(sc); -// splx(s); - if (sc->sc_uidtbl != NULL) { - free(sc->sc_uidtbl, M_DEVBUF); - MPRINTF("free(DEVBUF)", sc->sc_uidtbl); - sc->sc_uidtbl = NULL; - } - -#ifdef __NetBSD__ - callout_reset(&sc->sc_selfid_callout, - OHCI_SELFID_TIMEOUT, - (void (*)(void *))fwohci_phy_busreset, sc); -#else - timeout_set(&sc->sc_selfid_callout, - (void (*)(void *))fwohci_phy_busreset, sc); - timeout_add(&sc->sc_selfid_callout, - OHCI_SELFID_TIMEOUT); -#endif - sc->sc_nodeid = 0xFFFF; /* Indicate invalid. */ - sc->sc_rootid = 0; - sc->sc_irmid = IEEE1394_BCAST_PHY_ID; - } - if (intmask & OHCI_Int_SelfIDComplete) { - splx(s); - OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear, - OHCI_Int_BusReset); - OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, - OHCI_Int_BusReset); - s = spl0(); -#ifdef __NetBSD__ - callout_stop(&sc->sc_selfid_callout); -#else - timeout_del(&sc->sc_selfid_callout); -#endif - if (fwohci_selfid_input(sc) == 0) { -// s = splbio(); - fwohci_buf_start_rx(sc); -// splx(s); - fwohci_uid_collect(sc); - } - } - if (intmask & OHCI_Int_ReqTxComplete) { -// s = splbio(); - fwohci_at_done(sc, sc->sc_ctx_atrq, 0); -// splx(s); - } - if (intmask & OHCI_Int_RespTxComplete) { -// s = splbio(); - fwohci_at_done(sc, sc->sc_ctx_atrs, 0); -// splx(s); - } - if (intmask & OHCI_Int_RQPkt) { - fwohci_arrq_input(sc, sc->sc_ctx_arrq); - } - if (intmask & OHCI_Int_RSPkt) { - fwohci_arrs_input(sc, sc->sc_ctx_arrs); - } - if (intmask & OHCI_Int_IsochRx) { - splx(s); - iso = sc->sc_iso; - sc->sc_iso = 0; - s = spl0(); - for (i = 0; i < sc->sc_isoctx; i++) { - if ((iso & (1 << i)) && - sc->sc_ctx_ir[i] != NULL) { - fwohci_ir_input(sc, sc->sc_ctx_ir[i]); - sc->sc_isocnt.ev_count++; - } - } - } -#if 0 - DPRINTF(("%s: IntMaskSet(0x%08x)\n", - __func__, intmask & ~OHCI_Int_BusReset)); - s = splbio(); -// OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear, -// intmask & ~OHCI_Int_BusReset); - OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, intmask & ~OHCI_Int_BusReset); - splx(s); -#endif - splx(s); -} -#endif /* NO_THREAD */ - - -#if 0 -int -fwohci_dmamem_alloc(struct fwohci_softc *sc, int size, int alignment, - bus_dmamap_t *mapp, caddr_t *kvap, int flags) -{ - bus_dma_segment_t segs[1]; - int error, nsegs, steps; - - steps = 0; - error = bus_dmamem_alloc(sc->sc_dmat, size, alignment, alignment, - segs, 1, &nsegs, flags); - if (error) - goto cleanup; - MPRINTF("bus_dmamem_alloc", segs->ds_addr); - - steps = 1; - error = bus_dmamem_map(sc->sc_dmat, segs, nsegs, segs[0].ds_len, - kvap, flags); - if (error) - goto cleanup; - - if (error == 0) - error = bus_dmamap_create(sc->sc_dmat, size, 1, alignment, - size, flags, mapp); - if (error) - goto cleanup; - MPRINTF("bus_dmamap_create", mapp); - - if (error == 0) - error = bus_dmamap_load(sc->sc_dmat, *mapp, *kvap, size, NULL, - flags); - if (error) - goto cleanup; - - cleanup: - switch (steps) { - case 1: - bus_dmamem_free(sc->sc_dmat, segs, nsegs); - MPRINTF("bus_dmamem_free", segs->ds_addr); - } - - return error; -} -#endif - -int -fwohci_print(void *aux, const char *pnp) -{ - char *name = aux; - - if (pnp) - printf("%s at %s", name, pnp); - - return UNCONF; -} - -void -fwohci_hw_init(struct fwohci_softc *sc) -{ - int i; - u_int32_t val; - - splassert(IPL_BIO); - - /* - * Software Reset. - */ - OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, OHCI_HCControl_SoftReset); - for (i = 0; i < OHCI_LOOP; i++) { - val = OHCI_CSR_READ(sc, OHCI_REG_HCControlClear); - if ((val & OHCI_HCControl_SoftReset) == 0) - break; - DELAY(10); - } - - OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, OHCI_HCControl_LPS); - DELAY(100000); - - /* - * First, initialize CSRs with undefined value to default settings. - */ - val = OHCI_CSR_READ(sc, OHCI_REG_BusOptions); - val |= OHCI_BusOptions_ISC | OHCI_BusOptions_CMC; -#if 1 - val |= OHCI_BusOptions_BMC | OHCI_BusOptions_IRMC; - val |= OHCI_BusOptions_PMC; -#else - val &= ~(OHCI_BusOptions_BMC | OHCI_BusOptions_IRMC); - val &= ~(OHCI_BusOptions_PMC); -#endif - OHCI_CSR_WRITE(sc, OHCI_REG_BusOptions, val); - for (i = 0; i < sc->sc_isoctx; i++) { - OHCI_SYNC_RX_DMA_WRITE(sc, i, OHCI_SUBREG_ContextControlClear, - ~0); - } - OHCI_CSR_WRITE(sc, OHCI_REG_LinkControlClear, ~0); - - fwohci_configrom_init(sc); - fwohci_selfid_init(sc); - fwohci_buf_init_rx(sc); - fwohci_csr_init(sc); - - /* - * Final CSR settings. - */ - OHCI_CSR_WRITE(sc, OHCI_REG_LinkControlSet, - OHCI_LinkControl_CycleTimerEnable | - OHCI_LinkControl_RcvSelfID | OHCI_LinkControl_RcvPhyPkt); - -#if 0 - OHCI_CSR_WRITE(sc, OHCI_REG_ATRetries, 0x00000888); /*XXX*/ -#else - OHCI_CSR_WRITE(sc, OHCI_REG_ATRetries, 0xFFFF0FFF); /*XXX*/ -#endif - - /* Clear receive filter. */ - OHCI_CSR_WRITE(sc, OHCI_REG_IRMultiChanMaskHiClear, ~0); - OHCI_CSR_WRITE(sc, OHCI_REG_IRMultiChanMaskLoClear, ~0); - OHCI_CSR_WRITE(sc, OHCI_REG_AsynchronousRequestFilterHiSet, 0x80000000); - - OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, - OHCI_HCControl_ProgramPhyEnable); -#if 0 - OHCI_CSR_WRITE(sc, OHCI_REG_HCControlClear, - OHCI_HCControl_APhyEnhanceEnable); -#else - OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, - OHCI_HCControl_APhyEnhanceEnable); -#endif -#if BYTE_ORDER == BIG_ENDIAN - OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, - OHCI_HCControl_NoByteSwapData); -#else - OHCI_CSR_WRITE(sc, OHCI_REG_HCControlClear, - OHCI_HCControl_NoByteSwapData); -#endif - - OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskClear, ~0); - OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, OHCI_Int_BusReset | - OHCI_Int_SelfIDComplete | OHCI_Int_IsochRx | OHCI_Int_IsochTx | - OHCI_Int_RSPkt | OHCI_Int_RQPkt | OHCI_Int_ARRS | OHCI_Int_ARRQ | - OHCI_Int_RespTxComplete | OHCI_Int_ReqTxComplete); - OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, OHCI_Int_CycleTooLong | - OHCI_Int_UnrecoverableError | OHCI_Int_CycleInconsistent | - OHCI_Int_LockRespErr | OHCI_Int_PostedWriteErr); - OHCI_CSR_WRITE(sc, OHCI_REG_IsoXmitIntMaskSet, ~0); - OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntMaskSet, ~0); - OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, OHCI_Int_MasterEnable); - - OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, OHCI_HCControl_LinkEnable); - - /* - * Start the receivers. - */ - fwohci_buf_start_rx(sc); -} - -void -fwohci_power(int why, void *arg) -{ - struct fwohci_softc *sc = arg; - int s; - - s = splbio(); - switch (why) { - case PWR_SUSPEND: - case PWR_STANDBY: - fwohci_shutdown(sc); - break; - case PWR_RESUME: - fwohci_hw_init(sc); - fwohci_phy_busreset(sc); - break; -#ifdef __NetBSD__ - case PWR_SOFTSUSPEND: - case PWR_SOFTSTANDBY: - case PWR_SOFTRESUME: - break; -#endif - } - splx(s); -} - -void -fwohci_shutdown(void *arg) -{ - struct fwohci_softc *sc = arg; - u_int32_t val; - int s; - - //splassert(IPL_BIO); - -#ifdef __NetBSD__ - callout_stop(&sc->sc_selfid_callout); -#else - timeout_del(&sc->sc_selfid_callout); -#endif - /* Disable all interrupt. */ - OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskClear, OHCI_Int_MasterEnable); - fwohci_buf_stop_tx(sc); - fwohci_buf_stop_rx(sc); - s = splbio(); - val = OHCI_CSR_READ(sc, OHCI_REG_BusOptions); - val &= ~(OHCI_BusOptions_BMC | OHCI_BusOptions_ISC | - OHCI_BusOptions_CMC | OHCI_BusOptions_IRMC); - OHCI_CSR_WRITE(sc, OHCI_REG_BusOptions, val); - splx(s); - fwohci_phy_busreset(sc); - OHCI_CSR_WRITE(sc, OHCI_REG_HCControlClear, OHCI_HCControl_LinkEnable); - OHCI_CSR_WRITE(sc, OHCI_REG_HCControlClear, OHCI_HCControl_LPS); - OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, OHCI_HCControl_SoftReset); -} - -/* - * COMMON FUNCTIONS. - */ - -/* - * Read the PHY Register. - */ -u_int8_t -fwohci_phy_read(struct fwohci_softc *sc, u_int8_t reg) -{ - int i; - u_int32_t val; - - //splassert(IPL_BIO); - - OHCI_CSR_WRITE(sc, OHCI_REG_PhyControl, - OHCI_PhyControl_RdReg | - OHCI_BITSET(reg, OHCI_PhyControl_RegAddr)); - for (i = 0; i < OHCI_LOOP; i++) { - val = OHCI_CSR_READ(sc, OHCI_REG_PhyControl); - if (!(val & OHCI_PhyControl_RdReg) && - (val & OHCI_PhyControl_RdDone)) - break; - DELAY(10); - } - return (OHCI_BITVAL(val, OHCI_PhyControl_RdData)); -} - -/* - * Write the PHY Register. - */ -void -fwohci_phy_write(struct fwohci_softc *sc, u_int8_t reg, u_int8_t val) -{ - int i; - - //splassert(IPL_BIO); - - OHCI_CSR_WRITE(sc, OHCI_REG_PhyControl, OHCI_PhyControl_WrReg | - OHCI_BITSET(reg, OHCI_PhyControl_RegAddr) | - OHCI_BITSET(val, OHCI_PhyControl_WrData)); - for (i = 0; i < OHCI_LOOP; i++) { - if (!(OHCI_CSR_READ(sc, OHCI_REG_PhyControl) & - OHCI_PhyControl_WrReg)) - break; - DELAY(10); - } -} - -/* - * Initiate Bus Reset. - */ -void -fwohci_phy_busreset(struct fwohci_softc *sc) -{ - int s; - u_int8_t val; - - //splassert(IPL_BIO); - - s = splbio(); - OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear, - OHCI_Int_BusReset | OHCI_Int_SelfIDComplete); - OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, OHCI_Int_BusReset); -#ifdef __NetBSD__ - callout_stop(&sc->sc_selfid_callout); -#else - timeout_del(&sc->sc_selfid_callout); -#endif - val = fwohci_phy_read(sc, 1); - val = (val & 0x80) | /* Preserve RHB (force root). */ - 0x40 | /* Initiate Bus Reset. */ - 0x3F; /* Default GAP count. */ - fwohci_phy_write(sc, 1, val); - splx(s); -} - -/* - * PHY Packet. - */ -void -fwohci_phy_input(struct fwohci_softc *sc, struct fwohci_pkt *pkt) -{ - u_int32_t val; - - val = pkt->fp_hdr[1]; - if (val != ~pkt->fp_hdr[2]) { - if (val == 0 && ((*pkt->fp_trail & 0x001F0000) >> 16) == - OHCI_CTXCTL_EVENT_BUS_RESET) { - DPRINTFN(1, ("%s: BusReset: 0x%08x\n", __func__, - pkt->fp_hdr[2])); - } else { - printf("%s: phy packet corrupted (0x%08x, 0x%08x)\n", - sc->sc_sc1394.sc1394_dev.dv_xname, val, - pkt->fp_hdr[2]); - } - return; - } -#ifdef FWOHCI_DEBUG - if (fwohcidebug > 1) - fwohci_show_phypkt(sc, val); -#endif /* FWOHCI_DEBUG */ -} - -/* - * Descriptor for context DMA. - */ -int -fwohci_desc_alloc(struct fwohci_softc *sc) -{ - int error, mapsize, dsize; - - /* - * Allocate descriptor buffer. - */ - - sc->sc_descsize = OHCI_BUF_ARRQ_CNT + OHCI_BUF_ARRS_CNT + - OHCI_BUF_ATRQ_CNT + OHCI_BUF_ATRS_CNT + - OHCI_BUF_IR_CNT * sc->sc_isoctx + 2; - dsize = sizeof(struct fwohci_desc) * sc->sc_descsize; - mapsize = howmany(sc->sc_descsize, NBBY); -#ifdef M_ZERO - sc->sc_descmap = malloc(mapsize, M_DEVBUF, M_WAITOK|M_ZERO); - MPRINTF("malloc(DEVBUF)", sc->sc_descmap); -#else - sc->sc_descmap = malloc(mapsize, M_DEVBUF, M_WAITOK); - MPRINTF("malloc(DEVBUF)", sc->sc_descmap); - bzero(sc->sc_descmap, mapsize); -#endif - -#if 1 /* XXX Added when reorganizing dmamap stuff... */ - sc->sc_dnseg = 1; -#endif - - if ((error = bus_dmamap_create(sc->sc_dmat, dsize, sc->sc_dnseg, - dsize, 0, BUS_DMA_WAITOK, &sc->sc_ddmamap)) != 0) { - printf("%s: unable to create descriptor buffer DMA map, " - "error = %d\n", sc->sc_sc1394.sc1394_dev.dv_xname, error); - goto fail_0; - } - MPRINTF("bus_dmamap_create", sc->sc_ddmamap); - - if ((error = bus_dmamem_alloc(sc->sc_dmat, dsize, PAGE_SIZE, 0, - &sc->sc_dseg, 1, &sc->sc_dnseg, BUS_DMA_WAITOK)) != 0) { - printf("%s: unable to allocate descriptor buffer, error = %d\n", - sc->sc_sc1394.sc1394_dev.dv_xname, error); - goto fail_1; - } - MPRINTF("bus_dmamem_alloc", sc->sc_dseg.ds_addr); - - if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dseg, sc->sc_dnseg, - dsize, (caddr_t *)&sc->sc_desc, BUS_DMA_COHERENT | BUS_DMA_WAITOK)) - != 0) { - printf("%s: unable to map descriptor buffer, error = %d\n", - sc->sc_sc1394.sc1394_dev.dv_xname, error); - goto fail_2; - } - -#if 0 - if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_ddmamap, sc->sc_desc, - dsize, NULL, BUS_DMA_WAITOK)) != 0) { -#else - if ((error = bus_dmamap_load_raw(sc->sc_dmat, sc->sc_ddmamap, - &sc->sc_dseg, sc->sc_dnseg, dsize, BUS_DMA_WAITOK)) != 0) { -#endif - printf("%s: unable to load descriptor buffer DMA map, " - "error = %d\n", sc->sc_sc1394.sc1394_dev.dv_xname, error); - goto fail_3; - } - - return 0; - - fail_3: - bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_desc, dsize); - fail_2: - bus_dmamem_free(sc->sc_dmat, &sc->sc_dseg, sc->sc_dnseg); - MPRINTF("bus_dmamem_free", sc->sc_dseg.ds_addr); - fail_1: - bus_dmamap_destroy(sc->sc_dmat, sc->sc_ddmamap); - MPRINTF("bus_dmamap_destroy", sc->sc_ddmamap); - fail_0: - return error; -} - -void -fwohci_desc_free(struct fwohci_softc *sc) -{ - int dsize = sizeof(struct fwohci_desc) * sc->sc_descsize; - - bus_dmamap_unload(sc->sc_dmat, sc->sc_ddmamap); - bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_desc, dsize); - bus_dmamem_free(sc->sc_dmat, &sc->sc_dseg, sc->sc_dnseg); - MPRINTF("bus_dmamem_free", sc->sc_dseg.ds_addr); - bus_dmamap_destroy(sc->sc_dmat, sc->sc_ddmamap); - MPRINTF("bus_dmamap_destroy", sc->sc_ddmamap); - - free(sc->sc_descmap, M_DEVBUF); - MPRINTF("free(DEVBUF)", sc->sc_descmap); - sc->sc_descmap = NULL; /* XXX */ -} - -struct fwohci_desc * -fwohci_desc_get(struct fwohci_softc *sc, int ndesc) -{ - int i, n; - - assert(ndesc > 0); - - for (n = 0; n <= sc->sc_descsize - ndesc; n++) { - for (i = 0; ; i++) { - if (i == ndesc) { - for (i = 0; i < ndesc; i++) - setbit(sc->sc_descmap, n + i); - return sc->sc_desc + n; - } - if (isset(sc->sc_descmap, n + i)) - break; - } - } - return NULL; -} - -void -fwohci_desc_put(struct fwohci_softc *sc, struct fwohci_desc *fd, int ndesc) -{ - int i, n; - - assert(ndesc > 0); - - n = fd - sc->sc_desc; - for (i = 0; i < ndesc; i++, n++) { -#ifdef DIAGNOSTIC - if (isclr(sc->sc_descmap, n)) - panic("fwohci_desc_put: duplicated free"); -#endif - clrbit(sc->sc_descmap, n); - } -} - -/* - * Asynchronous/Isochronous Transmit/Receive Context. - */ -int -fwohci_ctx_alloc(struct fwohci_softc *sc, struct fwohci_ctx **fcp, - int bufcnt, int ctx, int ctxtype) -{ - int i, error; - struct fwohci_ctx *fc; - struct fwohci_buf *fb; - struct fwohci_desc *fd; -#if DOUBLEBUF - int buf2cnt; -#endif - -#ifdef M_ZERO - MALLOC(fc, struct fwohci_ctx *, sizeof(*fc), M_DEVBUF, M_WAITOK|M_ZERO); - MPRINTF("MALLOC(DEVBUF)", fc); -#else - MALLOC(fc, struct fwohci_ctx *, sizeof(*fc), M_DEVBUF, M_WAITOK); - MPRINTF("MALLOC(DEVBUF)", fc); - bzero(fc, sizeof(*fc)); -#endif - LIST_INIT(&fc->fc_handler); - TAILQ_INIT(&fc->fc_buf); - fc->fc_ctx = ctx; -#ifdef M_ZERO - fc->fc_buffers = fb = malloc(sizeof(*fb) * bufcnt, - M_DEVBUF, M_WAITOK|M_ZERO); - MPRINTF("malloc(DEVBUF)", fc->fc_buffers); -#else - fc->fc_buffers = fb = malloc(sizeof(*fb) * bufcnt, M_DEVBUF, M_WAITOK); - MPRINTF("malloc(DEVBUF)", fc->fc_buffers); - bzero(fb, sizeof(*fb) * bufcnt); -#endif - fc->fc_bufcnt = bufcnt; - if (bufcnt == 0) /* Asynchronous transmit... */ - goto ok; - -#if DOUBLEBUF - TAILQ_INIT(&fc->fc_buf2); /* For isochronous. */ - if (ctxtype == FWOHCI_CTX_ISO_MULTI) { - buf2cnt = bufcnt/2; - bufcnt -= buf2cnt; - if (buf2cnt == 0) { - panic("cannot allocate iso buffer"); - } - } -#endif - for (i = 0; i < bufcnt; i++, fb++) { - if ((error = fwohci_buf_alloc(sc, fb)) != 0) - goto fail; - if ((fd = fwohci_desc_get(sc, 1)) == NULL) { - error = ENOBUFS; - goto fail; - } - fb->fb_desc = fd; - fb->fb_daddr = sc->sc_ddmamap->dm_segs[0].ds_addr + - ((caddr_t)fd - (caddr_t)sc->sc_desc); - bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap, - (caddr_t)fd - (caddr_t)sc->sc_desc, - sizeof(struct fwohci_desc), BUS_DMASYNC_PREWRITE); - fd->fd_flags = OHCI_DESC_INPUT | OHCI_DESC_STATUS | - OHCI_DESC_INTR_ALWAYS | OHCI_DESC_BRANCH; - fd->fd_reqcount = fb->fb_dmamap->dm_segs[0].ds_len; - fd->fd_data = fb->fb_dmamap->dm_segs[0].ds_addr; - TAILQ_INSERT_TAIL(&fc->fc_buf, fb, fb_list); - bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap, - (caddr_t)fd - (caddr_t)sc->sc_desc, - sizeof(struct fwohci_desc), BUS_DMASYNC_POSTWRITE); - } -#if DOUBLEBUF - if (ctxtype == FWOHCI_CTX_ISO_MULTI) { - for (i = bufcnt; i < bufcnt + buf2cnt; i++, fb++) { - if ((error = fwohci_buf_alloc(sc, fb)) != 0) - goto fail; - if ((fd = fwohci_desc_get(sc, 1)) == NULL) { - error = ENOBUFS; - goto fail; - } - fb->fb_desc = fd; - fb->fb_daddr = sc->sc_ddmamap->dm_segs[0].ds_addr + - ((caddr_t)fd - (caddr_t)sc->sc_desc); - bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap, - (caddr_t)fd - (caddr_t)sc->sc_desc, - sizeof(struct fwohci_desc), BUS_DMASYNC_PREWRITE); - fd->fd_flags = OHCI_DESC_INPUT | OHCI_DESC_STATUS | - OHCI_DESC_INTR_ALWAYS | OHCI_DESC_BRANCH; - fd->fd_reqcount = fb->fb_dmamap->dm_segs[0].ds_len; - fd->fd_data = fb->fb_dmamap->dm_segs[0].ds_addr; - TAILQ_INSERT_TAIL(&fc->fc_buf2, fb, fb_list); - bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap, - (caddr_t)fd - (caddr_t)sc->sc_desc, - sizeof(struct fwohci_desc), BUS_DMASYNC_POSTWRITE); - } - } -#endif /* DOUBLEBUF */ - ok: - fc->fc_type = ctxtype; - *fcp = fc; - return 0; - - fail: - while (i-- > 0) { - fb--; - if (fb->fb_desc) - fwohci_desc_put(sc, fb->fb_desc, 1); - fwohci_buf_free(sc, fb); - } - FREE(fc, M_DEVBUF); - MPRINTF("FREE(DEVBUF)", fc); - fc = NULL; /* XXX */ - return error; -} - -void -fwohci_ctx_free(struct fwohci_softc *sc, struct fwohci_ctx *fc) -{ - struct fwohci_buf *fb; - struct fwohci_handler *fh; - -#if DOUBLEBUF - if ((fc->fc_type == FWOHCI_CTX_ISO_MULTI) && - (TAILQ_FIRST(&fc->fc_buf) > TAILQ_FIRST(&fc->fc_buf2))) { - struct fwohci_buf_s fctmp; - - fctmp = fc->fc_buf; - fc->fc_buf = fc->fc_buf2; - fc->fc_buf2 = fctmp; - } -#endif - while ((fh = LIST_FIRST(&fc->fc_handler)) != NULL) - fwohci_handler_set(sc, fh->fh_tcode, fh->fh_key1, fh->fh_key2, - fh->fh_key3, NULL, NULL); - while ((fb = TAILQ_FIRST(&fc->fc_buf)) != NULL) { - TAILQ_REMOVE(&fc->fc_buf, fb, fb_list); - if (fb->fb_desc) - fwohci_desc_put(sc, fb->fb_desc, 1); - fwohci_buf_free(sc, fb); - } -#if DOUBLEBUF - while ((fb = TAILQ_FIRST(&fc->fc_buf2)) != NULL) { - TAILQ_REMOVE(&fc->fc_buf2, fb, fb_list); - if (fb->fb_desc) - fwohci_desc_put(sc, fb->fb_desc, 1); - fwohci_buf_free(sc, fb); - } -#endif /* DOUBLEBUF */ - free(fc->fc_buffers, M_DEVBUF); - MPRINTF("free(DEVBUF)", fc->fc_buffers); - fc->fc_buffers = NULL; /* XXX */ - FREE(fc, M_DEVBUF); - MPRINTF("FREE(DEVBUF)", fc); - fc = NULL; /* XXX */ -} - -void -fwohci_ctx_init(struct fwohci_softc *sc, struct fwohci_ctx *fc) -{ - struct fwohci_buf *fb, *nfb; - struct fwohci_desc *fd; - struct fwohci_handler *fh; - int n; - - //splassert(IPL_BIO); - - TAILQ_FOREACH(fb, &fc->fc_buf, fb_list) { - bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap, - (caddr_t)fd - (caddr_t)sc->sc_desc, - sizeof(struct fwohci_desc), BUS_DMASYNC_PREWRITE); - nfb = TAILQ_NEXT(fb, fb_list); - fb->fb_off = 0; - fd = fb->fb_desc; - fd->fd_branch = (nfb != NULL) ? (nfb->fb_daddr | 1) : 0; - fd->fd_rescount = fd->fd_reqcount; - bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap, - (caddr_t)fd - (caddr_t)sc->sc_desc, - sizeof(struct fwohci_desc), BUS_DMASYNC_POSTWRITE); - } - -#if DOUBLEBUF - TAILQ_FOREACH(fb, &fc->fc_buf2, fb_list) { - bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap, - (caddr_t)fd - (caddr_t)sc->sc_desc, - sizeof(struct fwohci_desc), BUS_DMASYNC_PREWRITE); - nfb = TAILQ_NEXT(fb, fb_list); - fb->fb_off = 0; - fd = fb->fb_desc; - fd->fd_branch = (nfb != NULL) ? (nfb->fb_daddr | 1) : 0; - fd->fd_rescount = fd->fd_reqcount; - bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap, - (caddr_t)fd - (caddr_t)sc->sc_desc, - sizeof(struct fwohci_desc), BUS_DMASYNC_POSTWRITE); - } -#endif /* DOUBLEBUF */ - - n = fc->fc_ctx; - fb = TAILQ_FIRST(&fc->fc_buf); - if (fc->fc_type != FWOHCI_CTX_ASYNC) { - OHCI_SYNC_RX_DMA_WRITE(sc, n, OHCI_SUBREG_CommandPtr, - fb->fb_daddr | 1); - MPRINTF("OHCI_SUBREG_CommandPtr(SYNC_RX)", fb->fb_daddr); - OHCI_SYNC_RX_DMA_WRITE(sc, n, OHCI_SUBREG_ContextControlClear, - OHCI_CTXCTL_RX_BUFFER_FILL | - OHCI_CTXCTL_RX_CYCLE_MATCH_ENABLE | - OHCI_CTXCTL_RX_MULTI_CHAN_MODE | - OHCI_CTXCTL_RX_DUAL_BUFFER_MODE); - OHCI_SYNC_RX_DMA_WRITE(sc, n, OHCI_SUBREG_ContextControlSet, - OHCI_CTXCTL_RX_ISOCH_HEADER); - if (fc->fc_type == FWOHCI_CTX_ISO_MULTI) { - OHCI_SYNC_RX_DMA_WRITE(sc, n, - OHCI_SUBREG_ContextControlSet, - OHCI_CTXCTL_RX_BUFFER_FILL); - } - fh = LIST_FIRST(&fc->fc_handler); - OHCI_SYNC_RX_DMA_WRITE(sc, n, OHCI_SUBREG_ContextMatch, - (OHCI_CTXMATCH_TAG0 << fh->fh_key2) | fh->fh_key1); - } else { - OHCI_ASYNC_DMA_WRITE(sc, n, OHCI_SUBREG_CommandPtr, - fb->fb_daddr | 1); - MPRINTF("OHCI_SUBREG_CommandPtr(ASYNC)", fb->fb_daddr); - } -} - -/* - * DMA data buffer. - */ -int -fwohci_buf_alloc(struct fwohci_softc *sc, struct fwohci_buf *fb) -{ - int error; - - if (!fb->fb_nseg) - fb->fb_nseg = 1; - - if ((error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, fb->fb_nseg, - PAGE_SIZE, 0, BUS_DMA_WAITOK, &fb->fb_dmamap)) != 0) { - printf("%s: unable to create buffer DMA map, " - "error = %d\n", sc->sc_sc1394.sc1394_dev.dv_xname, - error); - goto fail_0; - } - MPRINTF("bus_dmamap_create", fb->fb_dmamap); - - if ((error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, - PAGE_SIZE, &fb->fb_seg, 1, &fb->fb_nseg, BUS_DMA_WAITOK)) != 0) { - printf("%s: unable to allocate buffer, error = %d\n", - sc->sc_sc1394.sc1394_dev.dv_xname, error); - goto fail_1; - } - MPRINTF("bus_dmamem_alloc", fb->fb_seg.ds_addr); - - if ((error = bus_dmamem_map(sc->sc_dmat, &fb->fb_seg, - fb->fb_nseg, PAGE_SIZE, &fb->fb_buf, - BUS_DMA_COHERENT | BUS_DMA_WAITOK)) != 0) { - printf("%s: unable to map buffer, error = %d\n", - sc->sc_sc1394.sc1394_dev.dv_xname, error); - goto fail_2; - } - -#if 0 - if ((error = bus_dmamap_load(sc->sc_dmat, fb->fb_dmamap, - fb->fb_buf, PAGE_SIZE, NULL, BUS_DMA_WAITOK)) != 0) { -#else - if ((error = bus_dmamap_load_raw(sc->sc_dmat, fb->fb_dmamap, - &fb->fb_seg, fb->fb_nseg, PAGE_SIZE, BUS_DMA_WAITOK)) != 0) { -#endif - printf("%s: unable to load buffer DMA map, " - "error = %d\n", sc->sc_sc1394.sc1394_dev.dv_xname, - error); - goto fail_3; - } - - return 0; - - bus_dmamap_unload(sc->sc_dmat, fb->fb_dmamap); - fail_3: - bus_dmamem_unmap(sc->sc_dmat, fb->fb_buf, PAGE_SIZE); - fail_2: - bus_dmamem_free(sc->sc_dmat, &fb->fb_seg, fb->fb_nseg); - MPRINTF("bus_dmamem_free", fb->fb_seg.ds_addr); - fail_1: - bus_dmamap_destroy(sc->sc_dmat, fb->fb_dmamap); - MPRINTF("bus_dmamap_destroy", fb->fb_dmamap); - fail_0: - return error; -} - -void -fwohci_buf_free(struct fwohci_softc *sc, struct fwohci_buf *fb) -{ - - bus_dmamap_unload(sc->sc_dmat, fb->fb_dmamap); - bus_dmamem_unmap(sc->sc_dmat, fb->fb_buf, PAGE_SIZE); - bus_dmamem_free(sc->sc_dmat, &fb->fb_seg, fb->fb_nseg); - MPRINTF("bus_dmamem_free", fb->fb_seg.ds_addr); - bus_dmamap_destroy(sc->sc_dmat, fb->fb_dmamap); - MPRINTF("bus_dmamap_destroy", fb->fb_dmamap); -} - -void -fwohci_buf_init_rx(struct fwohci_softc *sc) -{ - int i; - - //splassert(IPL_BIO); - - /* - * Initialize for Asynchronous Receive Queue. - */ - fwohci_ctx_init(sc, sc->sc_ctx_arrq); - fwohci_ctx_init(sc, sc->sc_ctx_arrs); - - /* - * Initialize for Isochronous Receive Queue. - */ - for (i = 0; i < sc->sc_isoctx; i++) { - if (sc->sc_ctx_ir[i] != NULL) - fwohci_ctx_init(sc, sc->sc_ctx_ir[i]); - } -} - -void -fwohci_buf_start_rx(struct fwohci_softc *sc) -{ - int i; - -// splassert(IPL_BIO); - - OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_RX_REQUEST, - OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN); - OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_RX_RESPONSE, - OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN); - for (i = 0; i < sc->sc_isoctx; i++) { - if (sc->sc_ctx_ir[i] != NULL) - OHCI_SYNC_RX_DMA_WRITE(sc, i, - OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN); - } -} - -void -fwohci_buf_stop_tx(struct fwohci_softc *sc) -{ - int i; - -// splassert(IPL_BIO); - - OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_TX_REQUEST, - OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); - OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_TX_RESPONSE, - OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); - - /* - * Make sure the transmitter is stopped. - */ - for (i = 0; i < OHCI_LOOP; i++) { - DELAY(10); - if (OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_TX_REQUEST, - OHCI_SUBREG_ContextControlClear) & OHCI_CTXCTL_ACTIVE) - continue; - if (OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_TX_RESPONSE, - OHCI_SUBREG_ContextControlClear) & OHCI_CTXCTL_ACTIVE) - continue; - break; - } - - /* - * Initialize for Asynchronous Transmit Queue. - */ - fwohci_at_done(sc, sc->sc_ctx_atrq, 1); - fwohci_at_done(sc, sc->sc_ctx_atrs, 1); -} - -void -fwohci_buf_stop_rx(struct fwohci_softc *sc) -{ - int i; - - //splassert(IPL_BIO); - - OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_RX_REQUEST, - OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); - OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_RX_RESPONSE, - OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); - for (i = 0; i < sc->sc_isoctx; i++) { - OHCI_SYNC_RX_DMA_WRITE(sc, i, - OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); - } -} - -void -fwohci_buf_next(struct fwohci_softc *sc, struct fwohci_ctx *fc) -{ - struct fwohci_buf *fb, *tfb; - -#if DOUBLEBUF - if (fc->fc_type != FWOHCI_CTX_ISO_MULTI) { -#endif - while ((fb = TAILQ_FIRST(&fc->fc_buf)) != NULL) { - if (fc->fc_type != FWOHCI_CTX_ASYNC) { - if (fb->fb_off == 0) - break; - } else { - if (fb->fb_off != fb->fb_desc->fd_reqcount || - fb->fb_desc->fd_rescount != 0) - break; - } - TAILQ_REMOVE(&fc->fc_buf, fb, fb_list); - fb->fb_desc->fd_rescount = fb->fb_desc->fd_reqcount; - fb->fb_off = 0; - fb->fb_desc->fd_branch = 0; - tfb = TAILQ_LAST(&fc->fc_buf, fwohci_buf_s); - tfb->fb_desc->fd_branch = fb->fb_daddr | 1; - TAILQ_INSERT_TAIL(&fc->fc_buf, fb, fb_list); - } -#if DOUBLEBUF - } else { - struct fwohci_buf_s fctmp; - - /* Cleaning buffer. */ - TAILQ_FOREACH(fb, &fc->fc_buf, fb_list) { - fb->fb_off = 0; - fb->fb_desc->fd_rescount = fb->fb_desc->fd_reqcount; - } - - /* Rotating buffer. */ - fctmp = fc->fc_buf; - fc->fc_buf = fc->fc_buf2; - fc->fc_buf2 = fctmp; - } -#endif -} - -int -fwohci_buf_pktget(struct fwohci_softc *sc, struct fwohci_buf **fbp, - caddr_t *pp, int reqlen) -{ - struct fwohci_buf *fb; - struct fwohci_desc *fd; - int bufend, len = reqlen; -#ifdef FWOHCI_DEBUG - int i; -#endif /* FWOHCI_DEBUG */ - - fb = *fbp; -again: - fd = fb->fb_desc; - DPRINTFN(1, ("%s: desc %ld, off %d, req %d, res %d, len %d, avail %d", - __func__, (long)(fd - sc->sc_desc), fb->fb_off, fd->fd_reqcount, - fd->fd_rescount, len, - fd->fd_reqcount - fd->fd_rescount - fb->fb_off)); - bufend = fd->fd_reqcount - fd->fd_rescount; - if (fb->fb_off >= bufend) { - DPRINTFN(5, ("\n\tbuf %08x finish req %d res %d off %d", - fb->fb_desc->fd_data, fd->fd_reqcount, fd->fd_rescount, - fb->fb_off)); - if (fd->fd_rescount == 0) { - *fbp = fb = TAILQ_NEXT(fb, fb_list); - if (fb != TAILQ_END(fb)) - goto again; - } - return 0; - } - if (fb->fb_off + len > bufend) - len = bufend - fb->fb_off; - bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, fb->fb_off, len, - BUS_DMASYNC_POSTREAD); - -#ifdef FWOHCI_DEBUG - for (i=0; i < (roundup(len, 4) / 4); i++) { - if ((i % 8) == 0) DPRINTFN(5, ("\n ")); - DPRINTFN(5, (" %08x", - ((u_int32_t *)(fb->fb_buf + fb->fb_off))[i])); - } -#endif /* FWOHCI_DEBUG */ - DPRINTF(("\n")); - *pp = fb->fb_buf + fb->fb_off; - fb->fb_off += roundup(len, 4); - return len; -} - -int -fwohci_buf_input(struct fwohci_softc *sc, struct fwohci_ctx *fc, - struct fwohci_pkt *pkt) -{ - caddr_t p; - struct fwohci_buf *fb; - int len, count, i; - - bzero(pkt, sizeof(*pkt)); - pkt->fp_uio.uio_iov = pkt->fp_iov; - pkt->fp_uio.uio_rw = UIO_WRITE; - pkt->fp_uio.uio_segflg = UIO_SYSSPACE; - - /* Get first quadlet. */ - fb = TAILQ_FIRST(&fc->fc_buf); - count = 4; - len = fwohci_buf_pktget(sc, &fb, &p, count); - if (len <= 0) { - DPRINTFN(1, ("%s: no input for %d\n", __func__, fc->fc_ctx)); - return 0; - } - pkt->fp_hdr[0] = *(u_int32_t *)p; /* XXX Alignment !!! */ - pkt->fp_tcode = (pkt->fp_hdr[0] & 0x000000F0) >> 4; - switch (pkt->fp_tcode) { - case IEEE1394_TCODE_WRITE_REQUEST_QUADLET: - case IEEE1394_TCODE_READ_RESPONSE_QUADLET: - pkt->fp_hlen = 12; - pkt->fp_dlen = 4; - break; - case IEEE1394_TCODE_READ_REQUEST_DATABLOCK: - pkt->fp_hlen = 16; - pkt->fp_dlen = 0; - break; - case IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK: - case IEEE1394_TCODE_READ_RESPONSE_DATABLOCK: - case IEEE1394_TCODE_LOCK_REQUEST: - case IEEE1394_TCODE_LOCK_RESPONSE: - pkt->fp_hlen = 16; - break; - case IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK: -#ifdef DIAGNOSTIC - if (fc->fc_type == FWOHCI_CTX_ISO_MULTI) -#endif - { - pkt->fp_hlen = 4; - pkt->fp_dlen = (pkt->fp_hdr[0] >> 16) & 0xFFFF; - DPRINTFN(5, ("[%d]", pkt->fp_dlen)); - break; - } -#ifdef DIAGNOSTIC - else { - printf("%s: bad tcode: STREAM_DATA\n", __func__); - return 0; - } -#endif - default: - pkt->fp_hlen = 12; - pkt->fp_dlen = 0; - break; - } - - /* Get header. */ - while (count < pkt->fp_hlen) { - len = fwohci_buf_pktget(sc, &fb, &p, pkt->fp_hlen - count); - if (len == 0) { - printf("%s: malformed input 1: %d\n", __func__, - pkt->fp_hlen - count); - return 0; - } -#ifdef FWOHCI_DEBUG - fwptr = p; fwlen = len; fwbuf = fb; -#endif /* FWOHCI_DEBUG */ - bcopy(p, (caddr_t)pkt->fp_hdr + count, len); -#ifdef FWOHCI_DEBUG - fwptr = NULL; fwlen = 0; fwbuf = NULL; -#endif /* FWOHCI_DEBUG */ - count += len; - } - if (pkt->fp_hlen == 16 && - pkt->fp_tcode != IEEE1394_TCODE_READ_REQUEST_DATABLOCK) - pkt->fp_dlen = pkt->fp_hdr[3] >> 16; - DPRINTFN(1, ("%s: tcode=0x%x, hlen=%d, dlen=%d\n", __func__, - pkt->fp_tcode, pkt->fp_hlen, pkt->fp_dlen)); - - /* Get data. */ - count = 0; - i = 0; - while (i < 6 && count < pkt->fp_dlen) { - len = fwohci_buf_pktget(sc, &fb, - (caddr_t *)&pkt->fp_iov[i].iov_base, - pkt->fp_dlen - count); - if (len == 0) { - printf("%s: malformed input 2: %d\n", __func__, - pkt->fp_dlen - count); - return 0; - } - pkt->fp_iov[i++].iov_len = len; - count += len; - } - pkt->fp_uio.uio_iovcnt = i; - pkt->fp_uio.uio_resid = count; - - if (count < pkt->fp_dlen) { /* Eat the remainder of the packet. */ - printf("%s: %d iov exhausted, %d bytes not gotten\n", - __func__, i, pkt->fp_dlen - count); - while (count < pkt->fp_dlen) { - len = fwohci_buf_pktget(sc, &fb, - (caddr_t *)&pkt->fp_trail, - ((pkt->fp_dlen - count) > sizeof(*pkt->fp_trail)) ? - sizeof(*pkt->fp_trail) : (pkt->fp_dlen - count)); - count += len; - } - } - - /* Get trailer. */ - len = fwohci_buf_pktget(sc, &fb, (caddr_t *)&pkt->fp_trail, - sizeof(*pkt->fp_trail)); - if (len <= 0) { - printf("%s: malformed input 3: %d\n", __func__, - pkt->fp_hlen - count); - return 0; - } - return 1; -} - -int -fwohci_buf_input_ppb(struct fwohci_softc *sc, struct fwohci_ctx *fc, - struct fwohci_pkt *pkt) -{ - caddr_t p; - int len; - struct fwohci_buf *fb; - struct fwohci_desc *fd; - - if (fc->fc_type == FWOHCI_CTX_ISO_MULTI) { - return fwohci_buf_input(sc, fc, pkt); - } - - bzero(pkt, sizeof(*pkt)); - pkt->fp_uio.uio_iov = pkt->fp_iov; - pkt->fp_uio.uio_rw = UIO_WRITE; - pkt->fp_uio.uio_segflg = UIO_SYSSPACE; - - TAILQ_FOREACH(fb, &fc->fc_buf, fb_list) { - if (fb->fb_off == 0) - break; - } - if (fb == NULL) - return 0; - - fd = fb->fb_desc; - len = fd->fd_reqcount - fd->fd_rescount; - if (len == 0) - return 0; - bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, fb->fb_off, len, - BUS_DMASYNC_POSTREAD); - - p = fb->fb_buf; - fb->fb_off += roundup(len, 4); - if (len < 8) { - printf("%s: malformed input 1: %d\n", __func__, len); - return 0; - } - - /* - * Get trailer first, may be bogus data unless status update - * in descriptor is set. - */ - pkt->fp_trail = (u_int32_t *)p; - *pkt->fp_trail = (*pkt->fp_trail & 0xFFFF) | (fd->fd_status << 16); - pkt->fp_hdr[0] = ((u_int32_t *)p)[1]; - pkt->fp_tcode = (pkt->fp_hdr[0] & 0x000000F0) >> 4; -#ifdef DIAGNOSTIC - if (pkt->fp_tcode != IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK) { - printf("%s: bad tcode: 0x%x\n", __func__, pkt->fp_tcode); - return 0; - } -#endif - pkt->fp_hlen = 4; - pkt->fp_dlen = pkt->fp_hdr[0] >> 16; - p += 8; - len -= 8; - if (pkt->fp_dlen != len) { - printf("%s: malformed input 2: %d != %d\n", __func__, - pkt->fp_dlen, len); - return 0; - } - DPRINTFN(1, ("%s: tcode=0x%x, hlen=%d, dlen=%d\n", __func__, - pkt->fp_tcode, pkt->fp_hlen, pkt->fp_dlen)); - pkt->fp_iov[0].iov_base = p; - pkt->fp_iov[0].iov_len = len; - pkt->fp_uio.uio_iovcnt = 1; - pkt->fp_uio.uio_resid = len; - return 1; -} - -int -fwohci_handler_set(struct fwohci_softc *sc, int tcode, - u_int32_t key1, u_int32_t key2, u_int32_t key3, - int (*handler)(struct fwohci_softc *, void *, struct fwohci_pkt *), - void *arg) -{ - struct fwohci_ctx *fc; - struct fwohci_handler *fh; - int i, j, s; - - if (tcode == IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK) { - int isasync = key1 & OHCI_ASYNC_STREAM; - - key1 &= IEEE1394_ISOCH_MASK; - j = sc->sc_isoctx; - fh = NULL; - for (i = 0; i < sc->sc_isoctx; i++) { - if ((fc = sc->sc_ctx_ir[i]) == NULL) { - if (j == sc->sc_isoctx) - j = i; - continue; - } - fh = LIST_FIRST(&fc->fc_handler); - if (fh->fh_tcode == tcode && - fh->fh_key1 == key1 && fh->fh_key2 == key2) - break; - fh = NULL; - } - if (fh == NULL) { - if (handler == NULL) - return 0; - if (j == sc->sc_isoctx) { - DPRINTF(("%s: no more free context\n", - __func__)); - return ENOMEM; - } - if ((fc = sc->sc_ctx_ir[j]) == NULL) { - fwohci_ctx_alloc(sc, &fc, OHCI_BUF_IR_CNT, j, - isasync ? FWOHCI_CTX_ISO_SINGLE : - FWOHCI_CTX_ISO_MULTI); - sc->sc_ctx_ir[j] = fc; - } - } - } else { - switch (tcode) { - case IEEE1394_TCODE_WRITE_REQUEST_QUADLET: - case IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK: - case IEEE1394_TCODE_READ_REQUEST_QUADLET: - case IEEE1394_TCODE_READ_REQUEST_DATABLOCK: - case IEEE1394_TCODE_LOCK_REQUEST: - fc = sc->sc_ctx_arrq; - break; - case IEEE1394_TCODE_WRITE_RESPONSE: - case IEEE1394_TCODE_READ_RESPONSE_QUADLET: - case IEEE1394_TCODE_READ_RESPONSE_DATABLOCK: - case IEEE1394_TCODE_LOCK_RESPONSE: - fc = sc->sc_ctx_arrs; - break; - default: - return EIO; - } - LIST_FOREACH(fh, &fc->fc_handler, fh_list) { - if (fh->fh_tcode == tcode && - fh->fh_key1 == key1 && - fh->fh_key2 == key2 && - fh->fh_key3 == key3) - break; - } - } - if (handler == NULL) { - if (fh != NULL) { - LIST_REMOVE(fh, fh_list); - FREE(fh, M_DEVBUF); - MPRINTF("FREE(DEVBUF)", fh); - fh = NULL; /* XXX */ - } - if (tcode == IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK) { - OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx, - OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); - sc->sc_ctx_ir[fc->fc_ctx] = NULL; - fwohci_ctx_free(sc, fc); - } - DPRINTFN(1, ("%s: ctx %d, tcode %x, key 0x%x, 0x%x, 0x%x [NULL]\n", - __func__, fc->fc_ctx, tcode, key1, key2, key3)); - - return 0; - } - s = splbio(); - if (fh == NULL) { - MALLOC(fh, struct fwohci_handler *, sizeof(*fh), - M_DEVBUF, M_WAITOK); - MPRINTF("MALLOC(DEVBUF)", fh); - bzero(fh, sizeof(*fh)); - } - fh->fh_tcode = tcode; - fh->fh_key1 = key1; - fh->fh_key2 = key2; - fh->fh_key3 = key3; - fh->fh_handler = handler; - fh->fh_handarg = arg; - - if (fh->fh_list.le_prev == NULL) - LIST_INSERT_HEAD(&fc->fc_handler, fh, fh_list); - splx(s); - - DPRINTFN(1, ("%s: ctx %d, tcode %x, key 0x%x, 0x%x, 0x%x [%08x]\n", - __func__, fc->fc_ctx, tcode, key1, key2, key3, (u_int32_t)handler)); - - if (tcode == IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK) { - s = splbio(); - fwohci_ctx_init(sc, fc); - OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx, - OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN); - splx(s); - DPRINTFN(1, ("%s: SYNC desc %ld\n", __func__, - (long)(TAILQ_FIRST(&fc->fc_buf)->fb_desc - sc->sc_desc))); - } - return 0; -} - -int -fwohci_block_handler_set(struct fwohci_softc *sc, int tcode, - u_int32_t key1, u_int32_t key2, u_int32_t key3, int len, - int (*handler)(struct fwohci_softc *, void *, struct fwohci_pkt *), - void *arg) -{ - u_int32_t key3n = (key3 & 0xFFFF) | ((len & 0xFFFF) << 16); - - return (fwohci_handler_set(sc, tcode, key1, key2, key3n, handler, arg)); -} - -/* - * Asynchronous Receive Requests input frontend. - */ -void -fwohci_arrq_input(struct fwohci_softc *sc, struct fwohci_ctx *fc) -{ - u_int16_t srcid, datalen = 0; - int rcode, tlabel; - u_int32_t key1, key2; - struct fwohci_handler *fh; - struct fwohci_pkt pkt, res; - - /* - * Do not return if next packet is in the buffer, or the next - * packet cannot be received until the next receive interrupt. - */ - while (fwohci_buf_input(sc, fc, &pkt)) { - switch(pkt.fp_tcode) { - case OHCI_TCODE_PHY: - fwohci_phy_input(sc, &pkt); - continue; break; - case IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK: - datalen = pkt.fp_dlen; - break; - case IEEE1394_TCODE_READ_REQUEST_DATABLOCK: - datalen = pkt.fp_hdr[3] >> 16; - break; - } - key1 = pkt.fp_hdr[1] & 0xFFFF; - key2 = pkt.fp_hdr[2]; - bzero(&res, sizeof(res)); - res.fp_uio.uio_rw = UIO_WRITE; - res.fp_uio.uio_segflg = UIO_SYSSPACE; - srcid = pkt.fp_hdr[1] >> 16; - tlabel = (pkt.fp_hdr[0] & 0x0000FC00) >> 10; - DPRINTFN(1, ("%s: tcode 0x%x, from 0x%04x, tlabel 0x%x, " - "hlen %d, dlen %d\n", __func__, pkt.fp_tcode, - srcid, tlabel, pkt.fp_hlen, pkt.fp_dlen)); - LIST_FOREACH(fh, &fc->fc_handler, fh_list) { - if (pkt.fp_tcode == fh->fh_tcode && - ((fh->fh_key3 & 0xFFFF) == OHCI_NodeId_NodeNumber || - (srcid & OHCI_NodeId_NodeNumber) == - (fh->fh_key3 & 0xFFFF)) && - ((key1 == fh->fh_key1 && key2 == fh->fh_key2) || - (datalen && key1 == fh->fh_key1 && - key2 >= fh->fh_key2 && - (key2 + datalen) <= - (fh->fh_key2 + (fh->fh_key3 >> 16))))) - { - DPRINTFN(5, ("%s: handler 0x%08x(0x%08x)\n", - __func__, (u_int32_t)(*fh->fh_handler), - (u_int32_t)(fh->fh_handarg))); - rcode = (*fh->fh_handler)(sc, fh->fh_handarg, - &pkt); - DPRINTFN(5, ("%s: --> rcode %d\n", __func__, - rcode)); - break; - } - } - if (fh == NULL) { - rcode = IEEE1394_RCODE_ADDRESS_ERROR; - DPRINTFN(1, ("%s: no listener: tcode 0x%x, " - "addr=0x%04x%08x\n", __func__, pkt.fp_tcode, - key1, key2)); - } - if (((*pkt.fp_trail & 0x001F0000) >> 16) != - OHCI_CTXCTL_EVENT_ACK_PENDING) - continue; - if (rcode != -1) - fwohci_atrs_output(sc, rcode, &pkt, &res); - } - fwohci_buf_next(sc, fc); - OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, OHCI_SUBREG_ContextControlSet, - OHCI_CTXCTL_WAKE); -} - - -/* - * Asynchronous Receive Response input frontend. - */ -void -fwohci_arrs_input(struct fwohci_softc *sc, struct fwohci_ctx *fc) -{ - struct fwohci_pkt pkt; - struct fwohci_handler *fh; - u_int16_t srcid; - int rcode, tlabel; - - while (fwohci_buf_input(sc, fc, &pkt)) { - srcid = pkt.fp_hdr[1] >> 16; - rcode = (pkt.fp_hdr[1] & 0x0000F000) >> 12; - tlabel = (pkt.fp_hdr[0] & 0x0000FC00) >> 10; - DPRINTFN(1, ("%s: tcode 0x%x, from 0x%04x, tlabel 0x%x, " - "rcode 0x%x, hlen %d, dlen %d\n", __func__, - pkt.fp_tcode, srcid, tlabel, rcode, pkt.fp_hlen, - pkt.fp_dlen)); - LIST_FOREACH(fh, &fc->fc_handler, fh_list) { - if (pkt.fp_tcode == fh->fh_tcode && - (srcid & OHCI_NodeId_NodeNumber) == fh->fh_key1 && - tlabel == fh->fh_key2) { - (*fh->fh_handler)(sc, fh->fh_handarg, &pkt); - LIST_REMOVE(fh, fh_list); - FREE(fh, M_DEVBUF); - MPRINTF("FREE(DEVBUF)", fh); - fh = NULL; /* XXX */ - break; - } - } - if (fh == NULL) - DPRINTFN(1, ("%s: no listener\n", __func__)); - } - fwohci_buf_next(sc, fc); - OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, OHCI_SUBREG_ContextControlSet, - OHCI_CTXCTL_WAKE); -} - -/* - * Isochronous Receive input frontend. - */ -void -fwohci_ir_input(struct fwohci_softc *sc, struct fwohci_ctx *fc) -{ - int rcode, chan, tag; - struct iovec *iov; - struct fwohci_handler *fh; - struct fwohci_pkt pkt; - -#if DOUBLEBUF - if (fc->fc_type == FWOHCI_CTX_ISO_MULTI) { - struct fwohci_buf *fb; - int i; - u_int32_t reg; - - /* Stop dma engine before read buffer. */ - reg = OHCI_SYNC_RX_DMA_READ(sc, fc->fc_ctx, - OHCI_SUBREG_ContextControlClear); - DPRINTFN(5, ("%s: %08x =>", __func__, reg)); - if (reg & OHCI_CTXCTL_RUN) { - OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx, - OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); - } - DPRINTFN(5, (" %08x\n", OHCI_SYNC_RX_DMA_READ(sc, fc->fc_ctx, - OHCI_SUBREG_ContextControlClear))); - - i = 0; - while ((reg = OHCI_SYNC_RX_DMA_READ(sc, fc->fc_ctx, - OHCI_SUBREG_ContextControlSet)) & OHCI_CTXCTL_ACTIVE) { - delay(10); - if (++i > 10000) { - printf("cannot stop dma engine 0x%08x\n", reg); - return; - } - } - - /* Rotate dma buffer. */ - fb = TAILQ_FIRST(&fc->fc_buf2); - OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx, OHCI_SUBREG_CommandPtr, - fb->fb_daddr | 1); - MPRINTF("OHCI_SUBREG_CommandPtr(SYNC_RX)", fb->fb_daddr); - /* Start dma engine. */ - OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx, - OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN); - OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntEventClear, - (1 << fc->fc_ctx)); - } -#endif - - while (fwohci_buf_input_ppb(sc, fc, &pkt)) { - chan = (pkt.fp_hdr[0] & 0x00003F00) >> 8; - tag = (pkt.fp_hdr[0] & 0x0000C000) >> 14; - DPRINTFN(1, ("%s: hdr 0x%08x, tcode 0x%0x, hlen %d, dlen %d\n", - __func__, pkt.fp_hdr[0], pkt.fp_tcode, pkt.fp_hlen, - pkt.fp_dlen)); - if (tag == IEEE1394_TAG_GASP) { - /* - * The pkt with tag=3 is GASP format. - * Move GASP header to header part. - */ - if (pkt.fp_dlen < 8) - continue; - iov = pkt.fp_iov; - /* Assuming pkt per buffer mode. */ - pkt.fp_hdr[1] = ntohl(((u_int32_t *)iov->iov_base)[0]); - pkt.fp_hdr[2] = ntohl(((u_int32_t *)iov->iov_base)[1]); - iov->iov_base = (caddr_t)iov->iov_base + 8; - iov->iov_len -= 8; - pkt.fp_hlen += 8; - pkt.fp_dlen -= 8; - } - sc->sc_isopktcnt.ev_count++; - LIST_FOREACH(fh, &fc->fc_handler, fh_list) { - if (pkt.fp_tcode == fh->fh_tcode && - chan == fh->fh_key1 && tag == fh->fh_key2) { - rcode = (*fh->fh_handler)(sc, fh->fh_handarg, - &pkt); - break; - } - } -#ifdef FWOHCI_DEBUG - if (fh == NULL) { - DPRINTFN(1, ("%s: no handler\n", __func__)); - } else { - DPRINTFN(1, ("%s: rcode %d\n", __func__, rcode)); - } -#endif /* FWOHCI_DEBUG */ - } - fwohci_buf_next(sc, fc); - - if (fc->fc_type == FWOHCI_CTX_ISO_SINGLE) { - OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx, - OHCI_SUBREG_ContextControlSet, - OHCI_CTXCTL_WAKE); - } -} - -/* - * Asynchronous Transmit common routine. - */ -int -fwohci_at_output(struct fwohci_softc *sc, struct fwohci_ctx *fc, - struct fwohci_pkt *pkt) -{ - struct fwohci_buf *fb; - struct fwohci_desc *fd; - struct mbuf *m, *m0; - int i, ndesc, error, off, len; - u_int32_t val; -#ifdef FWOHCI_DEBUG - struct iovec *iov; -#endif /* FWOHCI_DEBUG */ - - if ((sc->sc_nodeid & OHCI_NodeId_NodeNumber) == IEEE1394_BCAST_PHY_ID) - /* We can't send anything during selfid duration */ - return EAGAIN; - -#ifdef FWOHCI_DEBUG - DPRINTFN(1, ("%s: tcode 0x%x, hlen %d, dlen %d", __func__, - pkt->fp_tcode, pkt->fp_hlen, pkt->fp_dlen)); - for (i = 0; i < pkt->fp_hlen/4; i++) - DPRINTFN(2, ("%s%08x", i?" ":"\n ", pkt->fp_hdr[i])); - DPRINTFN(2, (" $")); - if (pkt->fp_uio.uio_iovcnt) { - for (ndesc = 0, iov = pkt->fp_iov; - ndesc < pkt->fp_uio.uio_iovcnt; ndesc++, iov++) { - for (i = 0; i < iov->iov_len; i++) - DPRINTFN(2, ("%s%02x", (i%32)?((i%4)?"":" ") - :"\n ", - ((u_int8_t *)iov->iov_base)[i])); - DPRINTFN(2, (" $")); - } - } - DPRINTFN(1, ("\n")); -#endif /* FWOHCI_DEBUG */ - - if ((m = pkt->fp_m) != NULL) { - for (ndesc = 2; m != NULL; m = m->m_next) - ndesc++; - if (ndesc > OHCI_DESC_MAX) { - m0 = NULL; - ndesc = 2; - for (off = 0; off < pkt->fp_dlen; off += len) { - if (m0 == NULL) { - MGETHDR(m0, M_DONTWAIT, MT_DATA); - MPRINTF("MGETHDR", m0); - if (m0 != NULL) { -#ifdef __NetBSD__ - M_COPY_PKTHDR(m0, pkt->fp_m); -#else - M_DUP_PKTHDR(m0, pkt->fp_m); -#endif - } - m = m0; - } else { - MGET(m->m_next, M_DONTWAIT, MT_DATA); - MPRINTF("MGET", m->m_next); - m = m->m_next; - } - if (m != NULL) - MCLGET(m, M_DONTWAIT); - if (m == NULL || (m->m_flags & M_EXT) == 0) { - m_freem(m0); - MPRINTF("m_freem", m0); - return ENOMEM; - } - len = pkt->fp_dlen - off; - if (len > m->m_ext.ext_size) - len = m->m_ext.ext_size; - m_copydata(pkt->fp_m, off, len, - mtod(m, caddr_t)); - m->m_len = len; - ndesc++; - } - m_freem(pkt->fp_m); - MPRINTF("m_freem", pkt->fp_m); - pkt->fp_m = m0; - } - } else - ndesc = 2 + pkt->fp_uio.uio_iovcnt; - - if (ndesc > OHCI_DESC_MAX) - return ENOBUFS; - - if (fc->fc_bufcnt > 50) /* XXX */ - return ENOBUFS; - - fb = malloc(sizeof(*fb), M_DEVBUF, M_WAITOK); - MPRINTF("malloc(DEVBUF)", fb); - fb->fb_nseg = ndesc; - fb->fb_desc = fwohci_desc_get(sc, ndesc); - if (fb->fb_desc == NULL) { - free(fb, M_DEVBUF); - MPRINTF("free(DEVBUF)", fb); - fb = NULL; /* XXX */ - return ENOBUFS; - } - fb->fb_daddr = sc->sc_ddmamap->dm_segs[0].ds_addr + - ((caddr_t)fb->fb_desc - (caddr_t)sc->sc_desc); - fb->fb_m = pkt->fp_m; - fb->fb_callback = pkt->fp_callback; - fb->fb_statuscb = pkt->fp_statuscb; - fb->fb_statusarg = pkt->fp_statusarg; - - if (ndesc > 2) { - if ((error = bus_dmamap_create(sc->sc_dmat, pkt->fp_dlen, ndesc, - PAGE_SIZE, 0, BUS_DMA_WAITOK, &fb->fb_dmamap)) != 0) { - fwohci_desc_put(sc, fb->fb_desc, ndesc); - free(fb, M_DEVBUF); - MPRINTF("free(DEVBUF)", fb); - fb = NULL; /* XXX */ - return error; - } - MPRINTF("bus_dmamap_create", fb->fb_dmamap); - - if (pkt->fp_m != NULL) - error = bus_dmamap_load_mbuf(sc->sc_dmat, fb->fb_dmamap, - pkt->fp_m, BUS_DMA_WAITOK); - else - error = bus_dmamap_load_uio(sc->sc_dmat, fb->fb_dmamap, - &pkt->fp_uio, BUS_DMA_WAITOK); - if (error != 0) { - bus_dmamap_destroy(sc->sc_dmat, fb->fb_dmamap); - MPRINTF("bus_dmamap_destroy", fb->fb_dmamap); - fwohci_desc_put(sc, fb->fb_desc, ndesc); - free(fb, M_DEVBUF); - MPRINTF("free(DEVBUF)", fb); - fb = NULL; /* XXX */ - return error; - } - bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, 0, pkt->fp_dlen, - BUS_DMASYNC_PREWRITE); - } - - fd = fb->fb_desc; - fd->fd_flags = OHCI_DESC_IMMED; - fd->fd_reqcount = pkt->fp_hlen; - fd->fd_data = 0; - fd->fd_branch = 0; - fd->fd_status = 0; - if (fc->fc_ctx == OHCI_CTX_ASYNC_TX_RESPONSE) { - i = 3; /* XXX: 3 sec */ - val = OHCI_CSR_READ(sc, OHCI_REG_IsochronousCycleTimer); - fd->fd_timestamp = ((val >> 12) & 0x1FFF) | - ((((val >> 25) + i) & 0x7) << 13); - } else - fd->fd_timestamp = 0; - -#if 1 /* XXX */ - bcopy(pkt->fp_hdr, fd + 1, pkt->fp_hlen); -#else - bcopy(pkt->fp_hdr, fd->fd_immed, pkt->fp_hlen); -#endif - - if (ndesc > 2) { - for (i = 0; i < ndesc - 2; i++) { - fd = fb->fb_desc + 2 + i; - fd->fd_flags = 0; - fd->fd_reqcount = fb->fb_dmamap->dm_segs[i].ds_len; - fd->fd_data = fb->fb_dmamap->dm_segs[i].ds_addr; - fd->fd_branch = 0; - fd->fd_status = 0; - fd->fd_timestamp = 0; - } - bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, 0, pkt->fp_dlen, - BUS_DMASYNC_POSTWRITE); - } - fd->fd_flags |= OHCI_DESC_LAST | OHCI_DESC_BRANCH; - fd->fd_flags |= OHCI_DESC_INTR_ALWAYS; - -#ifdef FWOHCI_DEBUG - DPRINTFN(1, ("%s: desc %ld", __func__, - (long)(fb->fb_desc - sc->sc_desc))); - for (i = 0; i < ndesc * 4; i++) - DPRINTFN(2, ("%s%08x", i&7?" ":"\n ", - ((u_int32_t *)fb->fb_desc)[i])); - DPRINTFN(1, ("\n")); -#endif /* FWOHCI_DEBUG */ - - val = OHCI_ASYNC_DMA_READ(sc, fc->fc_ctx, - OHCI_SUBREG_ContextControlClear); - - if (val & OHCI_CTXCTL_RUN) { - if (fc->fc_branch == NULL) { - OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, - OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); - goto run; - } - *fc->fc_branch = fb->fb_daddr | ndesc; - OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, - OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_WAKE); - } else { - run: - OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, - OHCI_SUBREG_CommandPtr, fb->fb_daddr | ndesc); - MPRINTF("OHCI_SUBREG_CommandPtr(ASYNC)", fb->fb_daddr); - OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, - OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN); - } - fc->fc_branch = &fd->fd_branch; - - fc->fc_bufcnt++; - TAILQ_INSERT_TAIL(&fc->fc_buf, fb, fb_list); - pkt->fp_m = NULL; - return 0; -} - -void -fwohci_at_done(struct fwohci_softc *sc, struct fwohci_ctx *fc, int force) -{ - struct fwohci_buf *fb; - struct fwohci_desc *fd; - struct fwohci_pkt pkt; - int i; - -// splassert(IPL_BIO); - - while ((fb = TAILQ_FIRST(&fc->fc_buf)) != NULL) { - fd = fb->fb_desc; -#ifdef FWOHCI_DEBUG - DPRINTFN(1, ("%s: %sdesc %ld (%d)", __func__, - force ? "force " : "", (long)(fd - sc->sc_desc), - fb->fb_nseg)); - for (i = 0; i < fb->fb_nseg * 4; i++) - DPRINTFN(2, ("%s%08x", i&7?" ":"\n ", - ((u_int32_t *)fd)[i])); - DPRINTFN(1, ("\n")); -#endif /* FWOHCI_DEBUG */ - if (fb->fb_nseg > 2) - fd += fb->fb_nseg - 1; - if (!force && !(fd->fd_status & OHCI_CTXCTL_ACTIVE)) - break; - TAILQ_REMOVE(&fc->fc_buf, fb, fb_list); - if (fc->fc_branch == &fd->fd_branch) { - OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, - OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN); - fc->fc_branch = NULL; - for (i = 0; i < OHCI_LOOP; i++) { - if (!(OHCI_ASYNC_DMA_READ(sc, fc->fc_ctx, - OHCI_SUBREG_ContextControlClear) & - OHCI_CTXCTL_ACTIVE)) - break; - DELAY(10); - } - } - - if (fb->fb_statuscb) { - bzero(&pkt, sizeof(pkt)); - pkt.fp_status = fd->fd_status; - bcopy(fd + 1, pkt.fp_hdr, sizeof(pkt.fp_hdr[0])); - - /* Indicate this is just returning the status bits. */ - pkt.fp_tcode = -1; - (*fb->fb_statuscb)(sc, fb->fb_statusarg, &pkt); - fb->fb_statuscb = NULL; - fb->fb_statusarg = NULL; - } - fwohci_desc_put(sc, fb->fb_desc, fb->fb_nseg); - if (fb->fb_nseg > 2) { - bus_dmamap_destroy(sc->sc_dmat, fb->fb_dmamap); - MPRINTF("bus_dmamap_destroy", fb->fb_dmamap); - } - fc->fc_bufcnt--; - if (fb->fb_callback) { - (*fb->fb_callback)(sc->sc_sc1394.sc1394_if, fb->fb_m); - fb->fb_callback = NULL; - } else if (fb->fb_m != NULL) { - m_freem(fb->fb_m); - MPRINTF("m_freem", fb->fb_m); - } - free(fb, M_DEVBUF); - MPRINTF("free(DEVBUF)", fb); - fb = NULL; /* XXX */ - } -} - -/* - * Asynchronous Transmit Reponse -- in response to request packet. - */ -void -fwohci_atrs_output(struct fwohci_softc *sc, int rcode, struct fwohci_pkt *req, - struct fwohci_pkt *res) -{ - - if (((*req->fp_trail & 0x001F0000) >> 16) != - OHCI_CTXCTL_EVENT_ACK_PENDING) - return; - - res->fp_hdr[0] = (req->fp_hdr[0] & 0x0000FC00) | 0x00000100; - res->fp_hdr[1] = (req->fp_hdr[1] & 0xFFFF0000) | (rcode << 12); - switch (req->fp_tcode) { - case IEEE1394_TCODE_WRITE_REQUEST_QUADLET: - case IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK: - res->fp_tcode = IEEE1394_TCODE_WRITE_RESPONSE; - res->fp_hlen = 12; - break; - case IEEE1394_TCODE_READ_REQUEST_QUADLET: - res->fp_tcode = IEEE1394_TCODE_READ_RESPONSE_QUADLET; - res->fp_hlen = 16; - res->fp_dlen = 0; - if (res->fp_uio.uio_iovcnt == 1 && res->fp_iov[0].iov_len == 4) - res->fp_hdr[3] = - *(u_int32_t *)res->fp_iov[0].iov_base; - res->fp_uio.uio_iovcnt = 0; - break; - case IEEE1394_TCODE_READ_REQUEST_DATABLOCK: - case IEEE1394_TCODE_LOCK_REQUEST: - if (req->fp_tcode == IEEE1394_TCODE_LOCK_REQUEST) - res->fp_tcode = IEEE1394_TCODE_LOCK_RESPONSE; - else - res->fp_tcode = IEEE1394_TCODE_READ_RESPONSE_DATABLOCK; - res->fp_hlen = 16; - res->fp_dlen = res->fp_uio.uio_resid; - res->fp_hdr[3] = res->fp_dlen << 16; - break; - } - res->fp_hdr[0] |= (res->fp_tcode << 4); - fwohci_at_output(sc, sc->sc_ctx_atrs, res); -} - -/* - * APPLICATION LAYER SERVICES. - */ - -/* - * Retrieve Global UID from GUID ROM. - */ -int -fwohci_guidrom_init(struct fwohci_softc *sc) -{ - int i, n, off; - u_int32_t val1, val2; - - /* - * Extract the Global UID. - */ - val1 = OHCI_CSR_READ(sc, OHCI_REG_GUIDHi); - val2 = OHCI_CSR_READ(sc, OHCI_REG_GUIDLo); - - if (val1 != 0 || val2 != 0) { - sc->sc_sc1394.sc1394_guid[0] = (val1 >> 24) & 0xFF; - sc->sc_sc1394.sc1394_guid[1] = (val1 >> 16) & 0xFF; - sc->sc_sc1394.sc1394_guid[2] = (val1 >> 8) & 0xFF; - sc->sc_sc1394.sc1394_guid[3] = (val1 >> 0) & 0xFF; - sc->sc_sc1394.sc1394_guid[4] = (val2 >> 24) & 0xFF; - sc->sc_sc1394.sc1394_guid[5] = (val2 >> 16) & 0xFF; - sc->sc_sc1394.sc1394_guid[6] = (val2 >> 8) & 0xFF; - sc->sc_sc1394.sc1394_guid[7] = (val2 >> 0) & 0xFF; - } else { - val1 = OHCI_CSR_READ(sc, OHCI_REG_Version); - if ((val1 & OHCI_Version_GUID_ROM) == 0) - return -1; - OHCI_CSR_WRITE(sc, OHCI_REG_Guid_Rom, OHCI_Guid_AddrReset); - for (i = 0; i < OHCI_LOOP; i++) { - val1 = OHCI_CSR_READ(sc, OHCI_REG_Guid_Rom); - if (!(val1 & OHCI_Guid_AddrReset)) - break; - DELAY(10); - } - off = OHCI_BITVAL(val1, OHCI_Guid_MiniROM) + 4; - val2 = 0; - for (n = 0; n < off + sizeof(sc->sc_sc1394.sc1394_guid); n++) { - OHCI_CSR_WRITE(sc, OHCI_REG_Guid_Rom, - OHCI_Guid_RdStart); - for (i = 0; i < OHCI_LOOP; i++) { - val1 = OHCI_CSR_READ(sc, OHCI_REG_Guid_Rom); - if (!(val1 & OHCI_Guid_RdStart)) - break; - DELAY(10); - } - if (n < off) - continue; - val1 = OHCI_BITVAL(val1, OHCI_Guid_RdData); - sc->sc_sc1394.sc1394_guid[n - off] = val1; - val2 |= val1; - } - if (val2 == 0) - return -1; - } - return 0; -} - -/* - * Initialization for Configuration ROM (no DMA context). - */ - -#define CFR_MAXUNIT 20 - -typedef struct configromctx { - u_int32_t *ptr; - int curunit; - struct { - u_int32_t *start; - int length; - u_int32_t *refer; - int refunit; - } unit[CFR_MAXUNIT]; -} configromctx; - -#define CFR_PUT_DATA4(cfr, d1, d2, d3, d4) \ - (*(cfr)->ptr++ = (((d1)<<24) | ((d2)<<16) | ((d3)<<8) | (d4))) - -#define CFR_PUT_DATA1(cfr, d) (*(cfr)->ptr++ = (d)) - -#define CFR_PUT_VALUE(cfr, key, d) (*(cfr)->ptr++ = ((key)<<24) | (d)) - -#define CFR_PUT_CRC(cfr, n) \ - (*(cfr)->unit[n].start = ((cfr)->unit[n].length << 16) | \ - fwohci_crc16((cfr)->unit[n].start + 1, (cfr)->unit[n].length)) - -#define CFR_START_UNIT(cfr, n) \ -do { \ - if ((cfr)->unit[n].refer != NULL) { \ - *(cfr)->unit[n].refer |= \ - (cfr)->ptr - (cfr)->unit[n].refer; \ - CFR_PUT_CRC(cfr, (cfr)->unit[n].refunit); \ - } \ - (cfr)->curunit = (n); \ - (cfr)->unit[n].start = (cfr)->ptr++; \ -} while (0) - -#define CFR_PUT_REFER(cfr, key, n) \ -do { \ - (cfr)->unit[n].refer = (cfr)->ptr; \ - (cfr)->unit[n].refunit = (cfr)->curunit; \ - *(cfr)->ptr++ = (key) << 24; \ -} while (0) - -#define CFR_END_UNIT(cfr) \ -do { \ - (cfr)->unit[(cfr)->curunit].length = (cfr)->ptr - \ - ((cfr)->unit[(cfr)->curunit].start + 1); \ - CFR_PUT_CRC(cfr, (cfr)->curunit); \ -} while (0) - -u_int16_t -fwohci_crc16(u_int32_t *ptr, int len) -{ - int shift; - u_int32_t crc, sum, data; - - crc = 0; - while (len-- > 0) { - data = *ptr++; - for (shift = 28; shift >= 0; shift -= 4) { - sum = ((crc >> 12) ^ (data >> shift)) & 0x000F; - crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ sum; - } - crc &= 0xFFFF; - } - return crc; -} - -void -fwohci_configrom_init(struct fwohci_softc *sc) -{ - int i, val; - struct fwohci_buf *fb; - u_int32_t *hdr; - struct configromctx cfr; - - //splassert(IPL_BIO); - - fb = &sc->sc_buf_cnfrom; - bzero(&cfr, sizeof(cfr)); - cfr.ptr = hdr = (u_int32_t *)fb->fb_buf; - - /* Headers. */ - CFR_START_UNIT(&cfr, 0); - CFR_PUT_DATA1(&cfr, OHCI_CSR_READ(sc, OHCI_REG_BusId)); - CFR_PUT_DATA1(&cfr, OHCI_CSR_READ(sc, OHCI_REG_BusOptions)); - CFR_PUT_DATA1(&cfr, OHCI_CSR_READ(sc, OHCI_REG_GUIDHi)); - CFR_PUT_DATA1(&cfr, OHCI_CSR_READ(sc, OHCI_REG_GUIDLo)); - CFR_END_UNIT(&cfr); - /* Copy info_length from crc_length. */ - *hdr |= (*hdr & 0x00FF0000) << 8; - OHCI_CSR_WRITE(sc, OHCI_REG_ConfigROMhdr, *hdr); - - /* Root directory. */ - CFR_START_UNIT(&cfr, 1); - CFR_PUT_VALUE(&cfr, 0x03, 0x00005E); /* Vendor ID. */ - CFR_PUT_REFER(&cfr, 0x81, 2); /* Textual descriptor offset. */ - CFR_PUT_VALUE(&cfr, 0x0C, 0x0083C0); /* Node capability. */ - /* spt,64,fix,lst,drq */ -#ifdef INET - CFR_PUT_REFER(&cfr, 0xD1, 3); /* IPv4 unit directory. */ -#endif /* INET */ -#ifdef INET6 - CFR_PUT_REFER(&cfr, 0xD1, 4); /* IPv6 unit directory. */ -#endif /* INET6 */ - CFR_END_UNIT(&cfr); - - CFR_START_UNIT(&cfr, 2); - CFR_PUT_VALUE(&cfr, 0, 0); /* Textual descriptor. */ - CFR_PUT_DATA1(&cfr, 0); /* Minimal ASCII. */ -#ifdef __NetBSD__ - CFR_PUT_DATA4(&cfr, 'N', 'e', 't', 'B'); - CFR_PUT_DATA4(&cfr, 'S', 'D', 0x00, 0x00); -#else - CFR_PUT_DATA4(&cfr, 'O', 'p', 'e', 'n'); - CFR_PUT_DATA4(&cfr, 'B', 'S', 'D', 0x00); -#endif - CFR_END_UNIT(&cfr); - -#ifdef INET - /* IPv4 unit directory. */ - CFR_START_UNIT(&cfr, 3); - CFR_PUT_VALUE(&cfr, 0x12, 0x00005E); /* Unit spec ID. */ - CFR_PUT_REFER(&cfr, 0x81, 6); /* Textual descriptor offset. */ - CFR_PUT_VALUE(&cfr, 0x13, 0x000001); /* Unit sw version. */ - CFR_PUT_REFER(&cfr, 0x81, 7); /* Textual descriptor offset. */ - CFR_PUT_REFER(&cfr, 0x95, 8); /* unit location. */ - CFR_END_UNIT(&cfr); - - CFR_START_UNIT(&cfr, 6); - CFR_PUT_VALUE(&cfr, 0, 0); /* Textual descriptor. */ - CFR_PUT_DATA1(&cfr, 0); /* Minimal ASCII. */ - CFR_PUT_DATA4(&cfr, 'I', 'A', 'N', 'A'); - CFR_END_UNIT(&cfr); - - CFR_START_UNIT(&cfr, 7); - CFR_PUT_VALUE(&cfr, 0, 0); /* Textual descriptor. */ - CFR_PUT_DATA1(&cfr, 0); /* Minimal ASCII. */ - CFR_PUT_DATA4(&cfr, 'I', 'P', 'v', '4'); - CFR_END_UNIT(&cfr); - - CFR_START_UNIT(&cfr, 8); /* Spec's valid addr range. */ - CFR_PUT_DATA1(&cfr, FW_FIFO_HI); - CFR_PUT_DATA1(&cfr, (FW_FIFO_LO | 0x1)); - CFR_PUT_DATA1(&cfr, FW_FIFO_HI); - CFR_PUT_DATA1(&cfr, FW_FIFO_LO); - CFR_END_UNIT(&cfr); - -#endif /* INET */ - -#ifdef INET6 - /* IPv6 unit directory. */ - CFR_START_UNIT(&cfr, 4); - CFR_PUT_VALUE(&cfr, 0x12, 0x00005E); /* Unit spec id. */ - CFR_PUT_REFER(&cfr, 0x81, 9); /* Textual descriptor offset. */ - CFR_PUT_VALUE(&cfr, 0x13, 0x000002); /* Unit sw version. */ - /* XXX: TBA by IANA */ - CFR_PUT_REFER(&cfr, 0x81, 10); /* Textual descriptor offset. */ - CFR_PUT_REFER(&cfr, 0x95, 11); /* Unit location. */ - CFR_END_UNIT(&cfr); - - CFR_START_UNIT(&cfr, 9); - CFR_PUT_VALUE(&cfr, 0, 0); /* Textual descriptor. */ - CFR_PUT_DATA1(&cfr, 0); /* Minimal ASCII. */ - CFR_PUT_DATA4(&cfr, 'I', 'A', 'N', 'A'); - CFR_END_UNIT(&cfr); - - CFR_START_UNIT(&cfr, 10); - CFR_PUT_VALUE(&cfr, 0, 0); /* Textual descriptor. */ - CFR_PUT_DATA1(&cfr, 0); - CFR_PUT_DATA4(&cfr, 'I', 'P', 'v', '6'); - CFR_END_UNIT(&cfr); - - CFR_START_UNIT(&cfr, 11); /* Spec's valid addr range. */ - CFR_PUT_DATA1(&cfr, FW_FIFO_HI); - CFR_PUT_DATA1(&cfr, (FW_FIFO_LO | 0x1)); - CFR_PUT_DATA1(&cfr, FW_FIFO_HI); - CFR_PUT_DATA1(&cfr, FW_FIFO_LO); - CFR_END_UNIT(&cfr); - -#endif /* INET6 */ - - fb->fb_off = cfr.ptr - hdr; -#ifdef FWOHCI_DEBUG - DPRINTF(("%s: Config ROM:", sc->sc_sc1394.sc1394_dev.dv_xname)); - for (i = 0; i < fb->fb_off; i++) - DPRINTF(("%s%08x", i&7?" ":"\n ", hdr[i])); - DPRINTF(("\n")); -#endif /* FWOHCI_DEBUG */ - - /* - * Make network byte order for DMA. - */ - for (i = 0; i < fb->fb_off; i++) - HTONL(hdr[i]); - bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, 0, - (caddr_t)cfr.ptr - fb->fb_buf, BUS_DMASYNC_PREWRITE); - - OHCI_CSR_WRITE(sc, OHCI_REG_ConfigROMmap, - fb->fb_dmamap->dm_segs[0].ds_addr); - - /* This register is only valid on OHCI 1.1. */ - val = OHCI_CSR_READ(sc, OHCI_REG_Version); - if ((OHCI_Version_GET_Version(val) == 1) && - (OHCI_Version_GET_Revision(val) == 1)) - OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, - OHCI_HCControl_BIBImageValid); - - /* Just allow quad reads of the rom, from every nodes. */ - for (i = 0; i < fb->fb_off; i++) - fwohci_handler_set(sc, IEEE1394_TCODE_READ_REQUEST_QUADLET, - CSR_BASE_HI, CSR_BASE_LO + CSR_CONFIG_ROM + (i * 4), - OHCI_NodeId_NodeNumber, fwohci_configrom_input, NULL); -} - -int -fwohci_configrom_input(struct fwohci_softc *sc, void *arg, - struct fwohci_pkt *pkt) -{ - struct fwohci_pkt res; - u_int32_t loc, *rom; - - /* This will be used as an array index so size accordingly. */ - loc = pkt->fp_hdr[2] - (CSR_BASE_LO + CSR_CONFIG_ROM); - if ((loc & 0x03) != 0) { - /* Alignment error. */ - return IEEE1394_RCODE_ADDRESS_ERROR; - } - else - loc /= 4; - rom = (u_int32_t *)sc->sc_buf_cnfrom.fb_buf; - - DPRINTFN(1, ("%s: ConfigRom[0x%04x]: 0x%08x\n", __func__, loc, - ntohl(rom[loc]))); - - bzero(&res, sizeof(res)); - res.fp_hdr[3] = rom[loc]; - fwohci_atrs_output(sc, IEEE1394_RCODE_COMPLETE, pkt, &res); - return -1; -} - -/* - * SelfID buffer (no DMA context). - */ -void -fwohci_selfid_init(struct fwohci_softc *sc) -{ - struct fwohci_buf *fb; - - //splassert(IPL_BIO); - - fb = &sc->sc_buf_selfid; -#ifdef DIAGNOSTIC - if ((fb->fb_dmamap->dm_segs[0].ds_addr & 0x7FF) != 0) - panic("fwohci_selfid_init: not aligned: %ld (%ld) %p", - (unsigned long)fb->fb_dmamap->dm_segs[0].ds_addr, - (unsigned long)fb->fb_dmamap->dm_segs[0].ds_len, fb->fb_buf); -#endif - bzero(fb->fb_buf, fb->fb_dmamap->dm_segs[0].ds_len); - bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, 0, - fb->fb_dmamap->dm_segs[0].ds_len, BUS_DMASYNC_PREREAD); - - OHCI_CSR_WRITE(sc, OHCI_REG_SelfIDBuffer, - fb->fb_dmamap->dm_segs[0].ds_addr); -} - -int -fwohci_selfid_input(struct fwohci_softc *sc) -{ - int i; - u_int32_t count, val, gen; - u_int32_t *buf; - - buf = (u_int32_t *)sc->sc_buf_selfid.fb_buf; - val = OHCI_CSR_READ(sc, OHCI_REG_SelfIDCount); - again: - if (val & OHCI_SelfID_Error) { - printf("%s: SelfID Error\n", sc->sc_sc1394.sc1394_dev.dv_xname); - return (-1); - } - count = OHCI_BITVAL(val, OHCI_SelfID_Size); - - bus_dmamap_sync(sc->sc_dmat, sc->sc_buf_selfid.fb_dmamap, - 0, count << 2, BUS_DMASYNC_POSTREAD); - gen = OHCI_BITVAL(buf[0], OHCI_SelfID_Gen); - -#ifdef FWOHCI_DEBUG - DPRINTFN(1, ("%s: SelfID: 0x%08x", sc->sc_sc1394.sc1394_dev.dv_xname, - val)); - for (i = 0; i < count; i++) - DPRINTFN(2, ("%s%08x", i&7?" ":"\n ", buf[i])); - DPRINTFN(1, ("\n")); -#endif /* FWOHCI_DEBUG */ - - for (i = 1; i < count; i += 2) { - if (buf[i] != ~buf[i + 1]) - break; -#if defined(FWOHCI_DEBUG) - if (fwohcidebug > 2) - fwohci_show_phypkt(sc, buf[i]); -#endif /* FWOHCI_DEBUG */ - if (buf[i] & IEEE1394_SELFID_MORE_PACKETS) - continue; /* More pkt. */ - if (buf[i] & IEEE1394_SELFID_EXTENDED) - continue; /* Extended ID. */ - sc->sc_rootid = OHCI_BITVAL(buf[i], IEEE1394_PHY_ID); - if ((buf[i] & - (IEEE1394_SELFID_LINK_ACTIVE|IEEE1394_SELFID_CONTENDER)) - == (IEEE1394_SELFID_LINK_ACTIVE|IEEE1394_SELFID_CONTENDER)) - sc->sc_irmid = sc->sc_rootid; - } - - val = OHCI_CSR_READ(sc, OHCI_REG_SelfIDCount); - if (OHCI_BITVAL(val, OHCI_SelfID_Gen) != gen) { - if (OHCI_BITVAL(val, OHCI_SelfID_Gen) != - OHCI_BITVAL(buf[0], OHCI_SelfID_Gen)) - goto again; - DPRINTF(("%s: SelfID Gen mismatch (%d, %d)\n", - sc->sc_sc1394.sc1394_dev.dv_xname, gen, - OHCI_BITVAL(val, OHCI_SelfID_Gen))); - return (-1); - } - if (i != count) { - printf("%s: SelfID corrupted (%d, 0x%08x, 0x%08x)\n", - sc->sc_sc1394.sc1394_dev.dv_xname, i, buf[i], buf[i + 1]); -#if 1 - if (i == 1 && buf[i] == 0 && buf[i + 1] == 0) { - /* - * XXX: CXD3222 sometimes fails to DMA - * selfid packet?? - */ - sc->sc_rootid = (count - 1) / 2 - 1; - sc->sc_irmid = sc->sc_rootid; - } else -#endif - return (-1); - } - - val = OHCI_CSR_READ(sc, OHCI_REG_NodeId); - if ((val & OHCI_NodeId_IDValid) == 0) { - sc->sc_nodeid = 0xFFFF; /* Invalid. */ - printf("%s: nodeid is invalid\n", - sc->sc_sc1394.sc1394_dev.dv_xname); - return (-1); - } - sc->sc_nodeid = val & 0xFFFF; - - DPRINTF(("%s: nodeid=0x%04x(%d), rootid=%d, irmid=%d\n", - sc->sc_sc1394.sc1394_dev.dv_xname, sc->sc_nodeid, - sc->sc_nodeid & OHCI_NodeId_NodeNumber, sc->sc_rootid, - sc->sc_irmid)); - - if ((sc->sc_nodeid & OHCI_NodeId_NodeNumber) > sc->sc_rootid) - return (-1); - - if ((sc->sc_nodeid & OHCI_NodeId_NodeNumber) == sc->sc_rootid) - OHCI_CSR_WRITE(sc, OHCI_REG_LinkControlSet, - OHCI_LinkControl_CycleMaster); - else - OHCI_CSR_WRITE(sc, OHCI_REG_LinkControlClear, - OHCI_LinkControl_CycleMaster); - return (0); -} - -/* - * Some CSRs are handled by driver. - */ -void -fwohci_csr_init(struct fwohci_softc *sc) -{ - int i; - static u_int32_t csr[] = { - CSR_STATE_CLEAR, CSR_STATE_SET, CSR_SB_CYCLE_TIME, - CSR_SB_BUS_TIME, CSR_SB_BUSY_TIMEOUT, CSR_SB_BUS_MANAGER_ID, - CSR_SB_CHANNEL_AVAILABLE_HI, CSR_SB_CHANNEL_AVAILABLE_LO, - CSR_SB_BROADCAST_CHANNEL - }; - - //splassert(IPL_BIO); - - for (i = 0; i < sizeof(csr) / sizeof(csr[0]); i++) { - fwohci_handler_set(sc, IEEE1394_TCODE_WRITE_REQUEST_QUADLET, - CSR_BASE_HI, CSR_BASE_LO + csr[i], OHCI_NodeId_NodeNumber, - fwohci_csr_input, NULL); - fwohci_handler_set(sc, IEEE1394_TCODE_READ_REQUEST_QUADLET, - CSR_BASE_HI, CSR_BASE_LO + csr[i], OHCI_NodeId_NodeNumber, - fwohci_csr_input, NULL); - } - sc->sc_csr[CSR_SB_BROADCAST_CHANNEL] = 31; /*XXX*/ -} - -int -fwohci_csr_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt) -{ - struct fwohci_pkt res; - u_int32_t reg; - - /* - * XXX Need to do special functionality other than just r/w... - */ - reg = pkt->fp_hdr[2] - CSR_BASE_LO; - - if ((reg & 0x03) != 0) { - /* Alignment error. */ - return IEEE1394_RCODE_ADDRESS_ERROR; - } - DPRINTFN(1, ("%s: CSR[0x%04x]: 0x%08x", __func__, reg, - *(u_int32_t *)(&sc->sc_csr[reg]))); - if (pkt->fp_tcode == IEEE1394_TCODE_WRITE_REQUEST_QUADLET) { - DPRINTFN(1, (" -> 0x%08x\n", - ntohl(*(u_int32_t *)pkt->fp_iov[0].iov_base))); - *(u_int32_t *)&sc->sc_csr[reg] = - ntohl(*(u_int32_t *)pkt->fp_iov[0].iov_base); - } else { - DPRINTFN(1, ("\n")); - res.fp_hdr[3] = htonl(*(u_int32_t *)&sc->sc_csr[reg]); - res.fp_iov[0].iov_base = &res.fp_hdr[3]; - res.fp_iov[0].iov_len = 4; - res.fp_uio.uio_resid = 4; - res.fp_uio.uio_iovcnt = 1; - fwohci_atrs_output(sc, IEEE1394_RCODE_COMPLETE, pkt, &res); - return -1; - } - return IEEE1394_RCODE_COMPLETE; -} - -/* - * Mapping between nodeid and unique ID (EUI-64). - * - * Track old mappings and simply update their devices with the new id's when - * they match an existing EUI. This allows proper renumeration of the bus. - */ -void -fwohci_uid_collect(struct fwohci_softc *sc) -{ - int i, count, val, phy_id; - struct fwohci_uidtbl *fu; - struct ieee1394_softc *iea; - u_int32_t *selfid_buf; - - selfid_buf = (u_int32_t *)sc->sc_buf_selfid.fb_buf; - - LIST_FOREACH(iea, &sc->sc_nodelist, sc1394_node) - iea->sc1394_node_id = 0xFFFF; - - if (sc->sc_uidtbl != NULL) { - free(sc->sc_uidtbl, M_DEVBUF); - MPRINTF("free(DEVBUF)", sc->sc_uidtbl); - sc->sc_uidtbl = NULL; /* XXX */ - } -#ifdef M_ZERO - sc->sc_uidtbl = malloc(sizeof(*fu) * (sc->sc_rootid + 1), M_DEVBUF, - M_NOWAIT|M_ZERO); /* XXX M_WAITOK requires locks. */ - MPRINTF("malloc(DEVBUF)", sc->sc_uidtbl); -#else - sc->sc_uidtbl = malloc(sizeof(*fu) * (sc->sc_rootid + 1), M_DEVBUF, - M_NOWAIT); /* XXX M_WAITOK requires locks. */ - MPRINTF("malloc(DEVBUF)", sc->sc_uidtbl); -#endif - if (sc->sc_uidtbl == NULL) { - DPRINTF(("sc_uidtbl malloc failed.")); - return; - } -#ifndef M_ZERO - bzero(sc->sc_uidtbl, sizeof(*fu) * (sc->sc_rootid + 1)); -#endif - - /* Update each node's link speed from SelfID buf. */ - count = OHCI_BITVAL(OHCI_CSR_READ(sc, OHCI_REG_SelfIDCount), - OHCI_SelfID_Size); - for (i = 1; i < count; i += 2) { - if (selfid_buf[i] & IEEE1394_SELFID_EXTENDED) - continue; /* No link speed info in Extended ID. */ - phy_id = OHCI_BITVAL(selfid_buf[i], IEEE1394_PHY_ID); - if (phy_id > sc->sc_rootid) - continue; /* Bogus !!! */ - val = OHCI_BITVAL(selfid_buf[i], IEEE1394_SELFID_SPEED); - sc->sc_uidtbl[phy_id].fu_link_speed = val; - } - - for (i = 0, fu = sc->sc_uidtbl; i <= sc->sc_rootid; i++, fu++) { - if (i == (sc->sc_nodeid & OHCI_NodeId_NodeNumber)) { - bcopy(sc->sc_sc1394.sc1394_guid, fu->fu_uid, 8); - fu->fu_valid = 3; - - iea = (struct ieee1394_softc *)sc->sc_sc1394.sc1394_if; - if (iea) { - iea->sc1394_node_id = i; - DPRINTF(("%s: Updating nodeid to %d\n", - iea->sc1394_dev.dv_xname, - iea->sc1394_node_id)); - if (iea->sc1394_callback.cb1394_busreset) { - iea->sc1394_callback.cb1394_busreset( - iea); - } - } - } else { - fu->fu_valid = 0; - fwohci_uid_req(sc, i); - } - } - if (sc->sc_rootid == 0) - fwohci_check_nodes(sc); -} - -void -fwohci_uid_req(struct fwohci_softc *sc, int phyid) -{ - struct fwohci_pkt pkt; - - bzero(&pkt, sizeof(pkt)); - pkt.fp_tcode = IEEE1394_TCODE_READ_REQUEST_QUADLET; - pkt.fp_hlen = 12; - pkt.fp_dlen = 0; - pkt.fp_hdr[0] = 0x00000100 | (sc->sc_tlabel << 10) | - (pkt.fp_tcode << 4); - pkt.fp_hdr[1] = ((0xFFC0 | phyid) << 16) | CSR_BASE_HI; - pkt.fp_hdr[2] = CSR_BASE_LO + CSR_CONFIG_ROM + 12; - fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESPONSE_QUADLET, phyid, - sc->sc_tlabel, OHCI_NodeId_NodeNumber, fwohci_uid_input, (void *)0); - sc->sc_tlabel = (sc->sc_tlabel + 1) & 0x3F; - fwohci_at_output(sc, sc->sc_ctx_atrq, &pkt); - - pkt.fp_hdr[0] = 0x00000100 | (sc->sc_tlabel << 10) | - (pkt.fp_tcode << 4); - pkt.fp_hdr[2] = CSR_BASE_LO + CSR_CONFIG_ROM + 16; - fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESPONSE_QUADLET, phyid, - sc->sc_tlabel, OHCI_NodeId_NodeNumber, fwohci_uid_input, (void *)1); - sc->sc_tlabel = (sc->sc_tlabel + 1) & 0x3F; - fwohci_at_output(sc, sc->sc_ctx_atrq, &pkt); -} - -int -fwohci_uid_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *res) -{ - struct fwohci_uidtbl *fu; - struct ieee1394_softc *iea; - struct ieee1394_attach_args fwa; - int i, n, done, rcode, found; - - found = 0; - - n = (res->fp_hdr[1] >> 16) & OHCI_NodeId_NodeNumber; - rcode = (res->fp_hdr[1] & 0x0000F000) >> 12; - if (rcode != IEEE1394_RCODE_COMPLETE || - sc->sc_uidtbl == NULL || - n > sc->sc_rootid) - return 0; - fu = &sc->sc_uidtbl[n]; - if (arg == 0) { - bcopy(res->fp_iov[0].iov_base, fu->fu_uid, 4); - fu->fu_valid |= 0x1; - } else { - bcopy(res->fp_iov[0].iov_base, fu->fu_uid + 4, 4); - fu->fu_valid |= 0x2; - } - if (fu->fu_valid == 0x3) { - DPRINTFN(1, ("%s: Node %d, UID %02x:%02x:%02x:%02x:%02x:%02x:" - "%02x:%02x\n", __func__, n, - fu->fu_uid[0], fu->fu_uid[1], fu->fu_uid[2], fu->fu_uid[3], - fu->fu_uid[4], fu->fu_uid[5], fu->fu_uid[6], fu->fu_uid[7])); - LIST_FOREACH(iea, &sc->sc_nodelist, sc1394_node) { - if (memcmp(iea->sc1394_guid, fu->fu_uid, 8) == 0) { - found = 1; - iea->sc1394_node_id = n; - iea->sc1394_link_speed = fu->fu_link_speed; - DPRINTF(("%s: Updating nodeid to %d, speed %d\n", - iea->sc1394_dev.dv_xname, - iea->sc1394_node_id, - fu->fu_link_speed)); - if (iea->sc1394_callback.cb1394_busreset) { - iea->sc1394_callback.cb1394_busreset( - iea); - } - break; - } - } - if (!found) { - strlcpy(fwa.name, "fwnode", sizeof fwa.name); - fwa.link_speed = fu->fu_link_speed; - bcopy(fu->fu_uid, fwa.uid, 8); - fwa.nodeid = n; - fwa.read = fwohci_read; - fwa.write = fwohci_write; - fwa.inreg = fwohci_inreg; - fwa.unreg = fwohci_unreg; - iea = (struct ieee1394_softc *) - config_found_sm(&sc->sc_sc1394.sc1394_dev, &fwa, - fwohci_print, fwohci_submatch); - if (iea != NULL) { - DPRINTF(("%s: Update speed to %d.", - iea->sc1394_dev.dv_xname, - fu->fu_link_speed)); - iea->sc1394_link_speed = fu->fu_link_speed; - LIST_INSERT_HEAD(&sc->sc_nodelist, iea, - sc1394_node); - } - } - } - done = 1; - - for (i = 0; i <= sc->sc_rootid; i++) { - fu = &sc->sc_uidtbl[i]; - if (fu->fu_valid != 0x3) { - done = 0; - break; - } - } - if (done) - fwohci_check_nodes(sc); - - return 0; -} - -void -fwohci_check_nodes(struct fwohci_softc *sc) -{ - struct device *detach = NULL; - struct ieee1394_softc *iea; - - LIST_FOREACH(iea, &sc->sc_nodelist, sc1394_node) { - - /* - * Have to defer detachment until the next - * loop iteration since config_detach - * free's the softc and the loop iterator - * needs data from the softc to move - * forward. - */ - - if (detach) { -// config_detach_children(detach, 0); - config_detach(detach, 0); - detach = NULL; - } - if (iea->sc1394_node_id == 0xFFFF) { - detach = (struct device *)iea; - LIST_REMOVE(iea, sc1394_node); - } - } - if (detach) { -// config_detach_children(detach, 0); - config_detach(detach, 0); - } -} - -int -fwohci_uid_lookup(struct fwohci_softc *sc, const u_int8_t *uid) -{ - struct fwohci_uidtbl *fu; - int n; - static const u_int8_t bcast[] = - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - - fu = sc->sc_uidtbl; - if (fu == NULL) { - if (memcmp(uid, bcast, sizeof(bcast)) == 0) - return IEEE1394_BCAST_PHY_ID; - fwohci_uid_collect(sc); /* Try to get. */ - return -1; - } - for (n = 0; n <= sc->sc_rootid; n++, fu++) { - if (fu->fu_valid == 0x3 && memcmp(fu->fu_uid, uid, 8) == 0) - return n; - } - if (memcmp(uid, bcast, sizeof(bcast)) == 0) - return IEEE1394_BCAST_PHY_ID; - for (n = 0, fu = sc->sc_uidtbl; n <= sc->sc_rootid; n++, fu++) { - if (fu->fu_valid != 0x3) { - /* - * XXX: Need timer before retransmission. - */ - fwohci_uid_req(sc, n); - } - } - return -1; -} - -/* - * Functions to support network interface. - */ -int -fwohci_if_inreg(struct device *self, u_int32_t offhi, u_int32_t offlo, - void (*handler)(struct device *, struct mbuf *)) -{ - struct fwohci_softc *sc = (struct fwohci_softc *)self; - - fwohci_handler_set(sc, IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK, - offhi, offlo, OHCI_NodeId_NodeNumber, - handler ? fwohci_if_input : NULL, handler); - fwohci_handler_set(sc, IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK, - (sc->sc_csr[CSR_SB_BROADCAST_CHANNEL] & IEEE1394_ISOCH_MASK) | - OHCI_ASYNC_STREAM, IEEE1394_TAG_GASP, 0, - handler ? fwohci_if_input : NULL, handler); - return 0; -} - -int -fwohci_if_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt) -{ - int n, len; - struct mbuf *m; - struct iovec *iov; - void (*handler)(struct device *, struct mbuf *) = arg; - -#ifdef FWOHCI_DEBUG - int i; - DPRINTFN(1, ("tcode=0x%x, dlen=%d\n", pkt->fp_tcode, pkt->fp_dlen)); - for (i = 0; fwohcidebug > 5 && i < pkt->fp_hlen/4; i++) - DPRINTFN(5, ("%s %08x", i?"":" ", pkt->fp_hdr[i])); - DPRINTFN(5, (" $\n")); - if (pkt->fp_dlen) { - for (n = 0, len = pkt->fp_dlen; len > 0; len -= i, n++){ - iov = &pkt->fp_iov[n]; - for (i = 0; fwohcidebug > 5 && i < iov->iov_len; i++) - DPRINTFN(5, ("%s%02x", - i&31?i&3?"":" ":i?"\n ":" ", - ((u_int8_t *)iov->iov_base)[i])); - DPRINTFN(5, (" $\n")); - } - } -#endif /* FWOHCI_DEBUG */ - len = pkt->fp_dlen; - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) - return IEEE1394_RCODE_COMPLETE; - m->m_len = 16; - if (len + m->m_len > MHLEN) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - m_freem(m); - MPRINTF("m_freem", m); - return IEEE1394_RCODE_COMPLETE; - } - } - n = (pkt->fp_hdr[1] >> 16) & OHCI_NodeId_NodeNumber; - if (sc->sc_uidtbl == NULL || n > sc->sc_rootid || - sc->sc_uidtbl[n].fu_valid != 0x3) { - printf("%s: packet from unknown node: phy id %d\n", - sc->sc_sc1394.sc1394_dev.dv_xname, n); - m_freem(m); - MPRINTF("m_freem", m); - fwohci_uid_req(sc, n); - return IEEE1394_RCODE_COMPLETE; - } - bcopy(sc->sc_uidtbl[n].fu_uid, mtod(m, caddr_t), 8); - if (pkt->fp_tcode == IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK) { - m->m_flags |= M_BCAST; - mtod(m, u_int32_t *)[2] = mtod(m, u_int32_t *)[3] = 0; - } else { - mtod(m, u_int32_t *)[2] = htonl(pkt->fp_hdr[1]); - mtod(m, u_int32_t *)[3] = htonl(pkt->fp_hdr[2]); - } - mtod(m, u_int8_t *)[8] = n; /*XXX: Node id for debug. */ - mtod(m, u_int8_t *)[9] = OHCI_BITVAL(*pkt->fp_trail, OHCI_CTXCTL_SPD); - - m->m_pkthdr.rcvif = NULL; /* set in child */ - m->m_pkthdr.len = len + m->m_len; - /* - * We may use receive buffer by external mbuf instead of copy here. - * But asynchronous receive buffer must be operate in buffer fill - * mode, so that each receive buffer will shared by multiple mbufs. - * If upper layer doesn't free mbuf soon, e.g. application program - * is suspended, buffer must be reallocated. - * Isochronous buffer must be operate in packet buffer mode, and - * it is easy to map receive buffer to external mbuf. But it is - * used for broadcast/multicast only, and is expected not so - * performance sensitive for now. - * XXX: The performance may be important for multicast case, - * so we should revisit here later. - * -- onoe - */ - n = 0; - iov = pkt->fp_uio.uio_iov; - while (len > 0) { - bcopy(iov->iov_base, mtod(m, caddr_t) + m->m_len, - iov->iov_len); - m->m_len += iov->iov_len; - len -= iov->iov_len; - iov++; - } - (*handler)(sc->sc_sc1394.sc1394_if, m); - return IEEE1394_RCODE_COMPLETE; -} - -int -fwohci_if_input_iso(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt) -{ - int n, len; - int chan, tag; - struct mbuf *m; - struct iovec *iov; - void (*handler)(struct device *, struct mbuf *) = arg; -#if defined(FWOHCI_DEBUG) - int i; -#endif /* FWOHCI_DEBUG */ - - chan = (pkt->fp_hdr[0] & 0x00003F00) >> 8; - tag = (pkt->fp_hdr[0] & 0x0000C000) >> 14; -#ifdef FWOHCI_DEBUG - DPRINTFN(1, ("%s: tcode=0x%x, chan=%d, tag=%x, dlen=%d", __func__, - pkt->fp_tcode, chan, tag, pkt->fp_dlen)); - for (i = 0; i < pkt->fp_hlen/4; i++) - DPRINTFN(2, ("%s%08x", i?" ":"\n\t", pkt->fp_hdr[i])); - DPRINTFN(2, ("$")); - if (pkt->fp_dlen) { - for (n = 0, len = pkt->fp_dlen; len > 0; len -= i, n++){ - iov = &pkt->fp_iov[n]; - for (i = 0; i < iov->iov_len; i++) - DPRINTFN(2, ("%s%02x", - (i%32)?((i%4)?"":" "):"\n\t", - ((u_int8_t *)iov->iov_base)[i])); - DPRINTFN(2, ("$")); - } - } - DPRINTFN(2, ("\n")); -#endif /* FWOHCI_DEBUG */ - len = pkt->fp_dlen; - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) - return IEEE1394_RCODE_COMPLETE; - m->m_len = 16; - if (m->m_len + len > MHLEN) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - m_freem(m); - MPRINTF("m_freem", m); - return IEEE1394_RCODE_COMPLETE; - } - } - - m->m_flags |= M_BCAST; - - if (tag == IEEE1394_TAG_GASP) { - n = (pkt->fp_hdr[1] >> 16) & OHCI_NodeId_NodeNumber; - if (sc->sc_uidtbl == NULL || n > sc->sc_rootid || - sc->sc_uidtbl[n].fu_valid != 0x3) { - printf("%s: packet from unknown node: phy id %d\n", - sc->sc_sc1394.sc1394_dev.dv_xname, n); - m_freem(m); - MPRINTF("m_freem", m); - return IEEE1394_RCODE_COMPLETE; - } - bcopy(sc->sc_uidtbl[n].fu_uid, mtod(m, caddr_t), 8); - mtod(m, u_int32_t *)[2] = htonl(pkt->fp_hdr[1]); - mtod(m, u_int32_t *)[3] = htonl(pkt->fp_hdr[2]); - mtod(m, u_int8_t *)[8] = n; /*XXX: node id for debug */ - mtod(m, u_int8_t *)[9] = - OHCI_BITVAL(*pkt->fp_trail, OHCI_CTXCTL_SPD); - } - mtod(m, u_int8_t *)[14] = chan; - mtod(m, u_int8_t *)[15] = tag; - - - m->m_pkthdr.rcvif = NULL; /* set in child */ - m->m_pkthdr.len = len + m->m_len; - /* - * We may use receive buffer by external mbuf instead of copy here. - * But asynchronous receive buffer must be operate in buffer fill - * mode, so that each receive buffer will shared by multiple mbufs. - * If upper layer doesn't free mbuf soon, e.g. application program - * is suspended, buffer must be reallocated. - * Isochronous buffer must be operate in packet buffer mode, and - * it is easy to map receive buffer to external mbuf. But it is - * used for broadcast/multicast only, and is expected not so - * performance sensitive for now. - * XXX: The performance may be important for multicast case, - * so we should revisit here later. - * -- onoe - */ - n = 0; - iov = pkt->fp_uio.uio_iov; - while (len > 0) { - bcopy(iov->iov_base, mtod(m, caddr_t) + m->m_len, - iov->iov_len); - m->m_len += iov->iov_len; - len -= iov->iov_len; - iov++; - } - (*handler)(sc->sc_sc1394.sc1394_if, m); - return IEEE1394_RCODE_COMPLETE; -} - - - -int -fwohci_if_output(struct device *self, struct mbuf *m0, - void (*callback)(struct device *, struct mbuf *)) -{ - struct fwohci_softc *sc = (struct fwohci_softc *)self; - struct fwohci_pkt pkt; - u_int8_t *p; - int n, error, spd, hdrlen, maxrec; -#ifdef FWOHCI_DEBUG - struct mbuf *m; -#endif /* FWOHCI_DEBUG */ - - p = mtod(m0, u_int8_t *); - if (m0->m_flags & (M_BCAST | M_MCAST)) { - spd = IEEE1394_SPD_S100; /*XXX*/ - maxrec = 512; /*XXX*/ - hdrlen = 8; - } else { - n = fwohci_uid_lookup(sc, p); - if (n < 0) { - printf("%s: nodeid unknown:" - " %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - sc->sc_sc1394.sc1394_dev.dv_xname, - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - error = EHOSTUNREACH; - goto end; - } - if (n == IEEE1394_BCAST_PHY_ID) { - printf("%s: broadcast with !M_MCAST\n", - sc->sc_sc1394.sc1394_dev.dv_xname); -#ifdef FWOHCI_DEBUG - DPRINTFN(2, ("packet:")); - for (m = m0; m != NULL; m = m->m_next) { - for (n = 0; n < m->m_len; n++) - DPRINTFN(2, ("%s%02x", (n%32)? - ((n%4)?"":" "):"\n ", - mtod(m, u_int8_t *)[n])); - DPRINTFN(2, ("$")); - } - DPRINTFN(2, ("\n")); -#endif /* FWOHCI_DEBUG */ - error = EHOSTUNREACH; - goto end; - } - maxrec = 2 << p[8]; - spd = p[9]; - hdrlen = 0; - } - if (spd > sc->sc_sc1394.sc1394_link_speed) { - DPRINTF(("%s: spd (%d) is faster than %d\n", __func__, - spd, sc->sc_sc1394.sc1394_link_speed)); - spd = sc->sc_sc1394.sc1394_link_speed; - } - if (maxrec > (512 << spd)) { - DPRINTF(("%s: maxrec (%d) is larger for spd (%d)\n", __func__, - maxrec, spd)); - maxrec = 512 << spd; - } - while (maxrec > sc->sc_sc1394.sc1394_max_receive) { - DPRINTF(("%s: maxrec (%d) is larger than %d\n", __func__, - maxrec, sc->sc_sc1394.sc1394_max_receive)); - maxrec >>= 1; - } - if (maxrec < 512) { - DPRINTF(("%s: maxrec (%d) is smaller than minimum\n", - __func__, maxrec)); - maxrec = 512; - } - - m_adj(m0, 16 - hdrlen); - if (m0->m_pkthdr.len > maxrec) { - DPRINTF(("%s: packet too big: hdr %d, pktlen %d, maxrec %d\n", - __func__, hdrlen, m0->m_pkthdr.len, maxrec)); - error = E2BIG; /*XXX*/ - goto end; - } - - bzero(&pkt, sizeof(pkt)); - pkt.fp_uio.uio_iov = pkt.fp_iov; - pkt.fp_uio.uio_segflg = UIO_SYSSPACE; - pkt.fp_uio.uio_rw = UIO_WRITE; - if (m0->m_flags & (M_BCAST | M_MCAST)) { - /* Construct GASP header. */ - p = mtod(m0, u_int8_t *); - p[0] = sc->sc_nodeid >> 8; - p[1] = sc->sc_nodeid & 0xFF; - p[2] = 0x00; p[3] = 0x00; p[4] = 0x5E; - p[5] = 0x00; p[6] = 0x00; p[7] = 0x01; - pkt.fp_tcode = IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK; - pkt.fp_hlen = 8; - pkt.fp_hdr[0] = (spd << 16) | (IEEE1394_TAG_GASP << 14) | - ((sc->sc_csr[CSR_SB_BROADCAST_CHANNEL] & - OHCI_NodeId_NodeNumber) << 8); - pkt.fp_hdr[1] = m0->m_pkthdr.len << 16; - } else { - pkt.fp_tcode = IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK; - pkt.fp_hlen = 16; - pkt.fp_hdr[0] = 0x00800100 | (sc->sc_tlabel << 10) | - (spd << 16); - pkt.fp_hdr[1] = - (((sc->sc_nodeid & OHCI_NodeId_BusNumber) | n) << 16) | - (p[10] << 8) | p[11]; - pkt.fp_hdr[2] = (p[12]<<24) | (p[13]<<16) | (p[14]<<8) | p[15]; - pkt.fp_hdr[3] = m0->m_pkthdr.len << 16; - sc->sc_tlabel = (sc->sc_tlabel + 1) & 0x3F; - } - pkt.fp_hdr[0] |= (pkt.fp_tcode << 4); - pkt.fp_dlen = m0->m_pkthdr.len; - pkt.fp_m = m0; - pkt.fp_callback = callback; - error = fwohci_at_output(sc, sc->sc_ctx_atrq, &pkt); - m0 = pkt.fp_m; - end: - if (m0 != NULL) { - if (callback) { - (*callback)(sc->sc_sc1394.sc1394_if, m0); - } else { - m_freem(m0); - MPRINTF("m_freem", m0); - } - } - return error; -} - -/* - * High level routines to provide abstraction to attaching layers to - * send/receive data. - */ - -/* - * These break down into 4 routines as follows: - * - * int fwohci_read(struct ieee1394_abuf *) - * - * This routine will attempt to read a region from the requested node. - * A callback must be provided which will be called when either the completed - * read is done or an unrecoverable error occurs. This is mainly a convenience - * routine since it will encapsulate retrying a region as quadlet vs. block - * reads and recombining all the returned data. This could also be done with a - * series of write/inreg's for each packet sent. - * - * int fwohci_write(struct ieee1394_abuf *) - * - * The work horse main entry point for putting packets on the bus. This is the - * generalized interface for fwnode/etc code to put packets out onto the bus. - * It accepts all standard ieee1394 tcodes (XXX: only a few today) and - * optionally will callback via a func pointer to the calling code with the - * resulting ACK code from the packet. If the ACK code is to be ignored (i.e. - * no cb) then the write routine will take care of free'ing the abuf since the - * fwnode/etc code won't have any knowledge of when to do this. This allows for - * simple one-off packets to be sent from the upper-level code without worrying - * about a callback for cleanup. - * - * int fwohci_inreg(struct ieee1394_abuf *, int) - * - * This is very simple. It evals the abuf passed in and registers an internal - * handler as the callback for packets received for that operation. - * The integer argument specifies whether on a block read/write operation to - * allow sub-regions to be read/written (in block form) as well. - * - * XXX: This whole structure needs to be redone as a list of regions and - * operations allowed on those regions. - * - * int fwohci_unreg(struct ieee1394_abuf *, int) - * - * This simply unregisters the respective callback done via inreg for items - * that only need to register an area for a one-time operation (like a status - * buffer a remote node will write to when the current operation is done). The - * int argument specifies the same behavior as inreg, except in reverse (i.e. - * it unregisters). - */ - -int -fwohci_read(struct ieee1394_abuf *ab) -{ - struct fwohci_pkt pkt; - struct ieee1394_softc *sc = ab->ab_req; - struct fwohci_softc *psc = - (struct fwohci_softc *)sc->sc1394_dev.dv_parent; - struct fwohci_cb *fcb; - u_int32_t high, lo; - int rv, tcode; - - /* Have to have a callback when reading. */ - if (ab->ab_cb == NULL) - return -1; - - MALLOC(fcb, struct fwohci_cb *, sizeof(*fcb), M_DEVBUF, M_WAITOK); - MPRINTF("MALLOC(DEVBUF)", fcb); - fcb->ab = ab; - fcb->count = 0; - fcb->abuf_valid = 1; - - high = ((ab->ab_addr & 0x0000FFFF00000000) >> 32); - lo = (ab->ab_addr & 0x00000000FFFFFFFF); - - bzero(&pkt, sizeof(pkt)); - pkt.fp_hdr[1] = ((0xFFC0 | ab->ab_req->sc1394_node_id) << 16) | high; - pkt.fp_hdr[2] = lo; - pkt.fp_dlen = 0; - - if (ab->ab_length == 4) { - pkt.fp_tcode = IEEE1394_TCODE_READ_REQUEST_QUADLET; - tcode = IEEE1394_TCODE_READ_RESPONSE_QUADLET; - pkt.fp_hlen = 12; - } else { - pkt.fp_tcode = IEEE1394_TCODE_READ_REQUEST_DATABLOCK; - pkt.fp_hlen = 16; - tcode = IEEE1394_TCODE_READ_RESPONSE_DATABLOCK; - pkt.fp_hdr[3] = (ab->ab_length << 16); - } - pkt.fp_hdr[0] = 0x00000100 | (sc->sc1394_link_speed << 16) | - (psc->sc_tlabel << 10) | (pkt.fp_tcode << 4); - - pkt.fp_statusarg = fcb; - pkt.fp_statuscb = fwohci_read_resp; - - rv = fwohci_handler_set(psc, tcode, ab->ab_req->sc1394_node_id, - psc->sc_tlabel, 0, fwohci_read_resp, fcb); - if (rv) - return rv; - rv = fwohci_at_output(psc, psc->sc_ctx_atrq, &pkt); - if (rv) - fwohci_handler_set(psc, tcode, ab->ab_req->sc1394_node_id, - psc->sc_tlabel, 0, NULL, NULL); - psc->sc_tlabel = (psc->sc_tlabel + 1) & 0x3F; - fcb->count = 1; - return rv; -} - -int -fwohci_write(struct ieee1394_abuf *ab) -{ - struct fwohci_pkt pkt; - struct ieee1394_softc *sc = ab->ab_req; - struct fwohci_softc *psc = - (struct fwohci_softc *)sc->sc1394_dev.dv_parent; - u_int32_t high, lo; - int rv; - - if ((ab->ab_tcode == IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK && - ab->ab_length > IEEE1394_MAX_REC(sc->sc1394_max_receive)) || - ab->ab_length > IEEE1394_MAX_ASYNC(sc->sc1394_link_speed)) { - DPRINTF(("%s: Packet too large: %d\n", __func__, - ab->ab_length)); - return E2BIG; - } - - if (ab->ab_data && ab->ab_uio) - panic("Can't call with uio and data set"); - if ((ab->ab_data == NULL) && (ab->ab_uio == NULL)) - panic("One of either ab_data or ab_uio must be set"); - - bzero(&pkt, sizeof(pkt)); - - pkt.fp_tcode = ab->ab_tcode; - if (ab->ab_data) { - pkt.fp_uio.uio_iov = pkt.fp_iov; - pkt.fp_uio.uio_segflg = UIO_SYSSPACE; - pkt.fp_uio.uio_rw = UIO_WRITE; - } else - bcopy(ab->ab_uio, &pkt.fp_uio, sizeof(struct uio)); - - pkt.fp_statusarg = ab; - pkt.fp_statuscb = fwohci_write_ack; - - switch (ab->ab_tcode) { - case IEEE1394_TCODE_WRITE_RESPONSE: - pkt.fp_hlen = 12; - case IEEE1394_TCODE_READ_RESPONSE_QUADLET: - case IEEE1394_TCODE_READ_RESPONSE_DATABLOCK: - if (!pkt.fp_hlen) - pkt.fp_hlen = 16; - high = ab->ab_retlen; - ab->ab_retlen = 0; - lo = 0; - pkt.fp_hdr[0] = 0x00000100 | (sc->sc1394_link_speed << 16) | - (ab->ab_tlabel << 10) | (pkt.fp_tcode << 4); - break; - default: - pkt.fp_hlen = 16; - high = ((ab->ab_addr & 0x0000FFFF00000000) >> 32); - lo = (ab->ab_addr & 0x00000000FFFFFFFF); - pkt.fp_hdr[0] = 0x00000100 | (sc->sc1394_link_speed << 16) | - (psc->sc_tlabel << 10) | (pkt.fp_tcode << 4); - break; - } - - pkt.fp_hdr[1] = ((0xFFC0 | ab->ab_req->sc1394_node_id) << 16) | high; - pkt.fp_hdr[2] = lo; - if (pkt.fp_hlen == 16) { - if (ab->ab_length == 4) { - pkt.fp_hdr[3] = ab->ab_data[0]; - pkt.fp_dlen = 0; - } else { - pkt.fp_hdr[3] = (ab->ab_length << 16); - pkt.fp_dlen = ab->ab_length; - if (ab->ab_data) { - pkt.fp_uio.uio_iovcnt = 1; - pkt.fp_uio.uio_resid = ab->ab_length; - pkt.fp_iov[0].iov_base = ab->ab_data; - pkt.fp_iov[0].iov_len = ab->ab_length; - } - } - } - switch (ab->ab_tcode) { - case IEEE1394_TCODE_WRITE_RESPONSE: - case IEEE1394_TCODE_READ_RESPONSE_QUADLET: - case IEEE1394_TCODE_READ_RESPONSE_DATABLOCK: - rv = fwohci_at_output(psc, psc->sc_ctx_atrs, &pkt); - break; - default: - rv = fwohci_at_output(psc, psc->sc_ctx_atrq, &pkt); - break; - } - return rv; -} - -int -fwohci_read_resp(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt) -{ - struct fwohci_cb *fcb = arg; - struct ieee1394_abuf *ab = fcb->ab; - struct fwohci_pkt newpkt; - u_int32_t *cur, high, lo; - int i, tcode, rcode, status, rv; - - /* - * Both the ACK handling and normal response callbacks are handled here. - * The main reason for this is the various error conditions that can - * occur trying to block read some areas and the ways that gets reported - * back to calling station. This is a variety of ACK codes, responses, - * etc which makes it much more difficult to process if both aren't - * handled here. - */ - - /* Check for status packet. */ - - if (pkt->fp_tcode == -1) { - status = pkt->fp_status & OHCI_DESC_STATUS_ACK_MASK; - rcode = -1; - tcode = (pkt->fp_hdr[0] >> 4) & 0xF; - if ((status != OHCI_CTXCTL_EVENT_ACK_COMPLETE) && - (status != OHCI_CTXCTL_EVENT_ACK_PENDING)) - DPRINTFN(2, ("%s: Got status packet: 0x%02x\n", - __func__, (unsigned int)status)); - fcb->count--; - - /* - * Got all the ack's back and the buffer is invalid (i.e. the - * callback has been called). Clean up. - */ - - if (fcb->abuf_valid == 0) { - if (fcb->count == 0) { - FREE(fcb, M_DEVBUF); - MPRINTF("FREE(DEVBUF)", fcb); - fcb = NULL; /* XXX */ - } - return IEEE1394_RCODE_COMPLETE; - } - } else { - status = -1; - tcode = pkt->fp_tcode; - rcode = (pkt->fp_hdr[1] & 0x0000F000) >> 12; - } - - /* - * Some areas (like the config rom) want to be read as quadlets only. - * - * The current ideas to try are: - * - * Got an ACK_TYPE_ERROR on a block read. - * - * Got either RCODE_TYPE or RCODE_ADDRESS errors in a block read - * response. - * - * In all cases construct a new packet for a quadlet read and let - * multi_resp handle the iteration over the space. - */ - - if (((status == OHCI_CTXCTL_EVENT_ACK_TYPE_ERROR) && - (tcode == IEEE1394_TCODE_READ_REQUEST_DATABLOCK)) || - (((rcode == IEEE1394_RCODE_TYPE_ERROR) || - (rcode == IEEE1394_RCODE_ADDRESS_ERROR)) && - (tcode == IEEE1394_TCODE_READ_RESPONSE_DATABLOCK))) { - - /* Read the area in quadlet chunks (internally track this). */ - - bzero(&newpkt, sizeof(newpkt)); - - high = ((ab->ab_addr & 0x0000FFFF00000000) >> 32); - lo = (ab->ab_addr & 0x00000000FFFFFFFF); - - newpkt.fp_tcode = IEEE1394_TCODE_READ_REQUEST_QUADLET; - newpkt.fp_hlen = 12; - newpkt.fp_dlen = 0; - newpkt.fp_hdr[1] = - ((0xFFC0 | ab->ab_req->sc1394_node_id) << 16) | high; - newpkt.fp_hdr[2] = lo; - newpkt.fp_hdr[0] = 0x00000100 | (sc->sc_tlabel << 10) | - (newpkt.fp_tcode << 4); - - rv = fwohci_handler_set(sc, - IEEE1394_TCODE_READ_RESPONSE_QUADLET, - ab->ab_req->sc1394_node_id, sc->sc_tlabel, 0, - fwohci_read_multi_resp, fcb); - if (rv) { - (*ab->ab_cb)(ab, -1); - goto cleanup; - } - newpkt.fp_statusarg = fcb; - newpkt.fp_statuscb = fwohci_read_resp; - rv = fwohci_at_output(sc, sc->sc_ctx_atrq, &newpkt); - if (rv) { - fwohci_handler_set(sc, - IEEE1394_TCODE_READ_RESPONSE_QUADLET, - ab->ab_req->sc1394_node_id, sc->sc_tlabel, 0, - NULL, NULL); - (*ab->ab_cb)(ab, -1); - goto cleanup; - } - fcb->count++; - sc->sc_tlabel = (sc->sc_tlabel + 1) & 0x3F; - return IEEE1394_RCODE_COMPLETE; - } else if ((rcode != -1) || ((status != -1) && - (status != OHCI_CTXCTL_EVENT_ACK_COMPLETE) && - (status != OHCI_CTXCTL_EVENT_ACK_PENDING))) { - - /* - * Recombine all the iov data into 1 chunk for higher - * level code. - */ - - if (rcode != -1) { - cur = ab->ab_data; - - assert(pkt->fp_uio.uio_iovcnt > 0); - - for (i = 0; i < pkt->fp_uio.uio_iovcnt; i++) { - /* - * Make sure and don't exceed the buffer - * allocated for return. - */ - if ((ab->ab_retlen + pkt->fp_iov[i].iov_len) > - ab->ab_length) { - bcopy(pkt->fp_iov[i].iov_base, cur, - (ab->ab_length - ab->ab_retlen)); - ab->ab_retlen = ab->ab_length; - break; - } - bcopy(pkt->fp_iov[i].iov_base, cur, - pkt->fp_iov[i].iov_len); - (caddr_t)cur += pkt->fp_iov[i].iov_len; - ab->ab_retlen += pkt->fp_iov[i].iov_len; - } - DPRINTF(("%s: retlen=%d\n", __func__, ab->ab_retlen)); - } - if (status != -1) - /* XXX: Need a complete tlabel interface. */ - for (i = 0; i < 64; i++) - fwohci_handler_set(sc, - IEEE1394_TCODE_READ_RESPONSE_QUADLET, - ab->ab_req->sc1394_node_id, i, 0, - NULL, NULL); - (*ab->ab_cb)(ab, rcode); - goto cleanup; - } else - /* Good ack packet. */ - return IEEE1394_RCODE_COMPLETE; - - /* Can't get here unless ab->ab_cb has been called. */ - - cleanup: - fcb->abuf_valid = 0; - if (fcb->count == 0) { - FREE(fcb, M_DEVBUF); - MPRINTF("FREE(DEVBUF)", fcb); - fcb = NULL; - } - return IEEE1394_RCODE_COMPLETE; -} - -int -fwohci_read_multi_resp(struct fwohci_softc *sc, void *arg, - struct fwohci_pkt *pkt) -{ - struct fwohci_cb *fcb = arg; - struct ieee1394_abuf *ab = fcb->ab; - struct fwohci_pkt newpkt; - u_int32_t high, lo; - int rcode, rv; - - /* - * Bad return codes from the wire, just return what's already in the - * buf. - */ - - /* Make sure a response packet didn't arrive after a bad ACK. */ - if (fcb->abuf_valid == 0) - return IEEE1394_RCODE_COMPLETE; - - rcode = (pkt->fp_hdr[1] & 0x0000F000) >> 12; - - if (rcode) { - (*ab->ab_cb)(ab, rcode); - goto cleanup; - } - - if ((ab->ab_retlen + pkt->fp_iov[0].iov_len) > ab->ab_length) { - bcopy(pkt->fp_iov[0].iov_base, - ((char *)ab->ab_data + ab->ab_retlen), - (ab->ab_length - ab->ab_retlen)); - ab->ab_retlen = ab->ab_length; - } else { - bcopy(pkt->fp_iov[0].iov_base, - ((char *)ab->ab_data + ab->ab_retlen), 4); - ab->ab_retlen += 4; - } - DPRINTF(("%s: retlen=%d\n", __func__, ab->ab_retlen)); - /* Still more, loop and read 4 more bytes. */ - if (ab->ab_retlen < ab->ab_length) { - bzero(&newpkt, sizeof(newpkt)); - - high = ((ab->ab_addr & 0x0000FFFF00000000) >> 32); - lo = (ab->ab_addr & 0x00000000FFFFFFFF) + ab->ab_retlen; - - newpkt.fp_tcode = IEEE1394_TCODE_READ_REQUEST_QUADLET; - newpkt.fp_hlen = 12; - newpkt.fp_dlen = 0; - newpkt.fp_hdr[1] = - ((0xFFC0 | ab->ab_req->sc1394_node_id) << 16) | high; - newpkt.fp_hdr[2] = lo; - newpkt.fp_hdr[0] = 0x00000100 | (sc->sc_tlabel << 10) | - (newpkt.fp_tcode << 4); - - newpkt.fp_statusarg = fcb; - newpkt.fp_statuscb = fwohci_read_resp; - - /* - * Bad return code. Just give up and return what's - * come in now. - */ - rv = fwohci_handler_set(sc, - IEEE1394_TCODE_READ_RESPONSE_QUADLET, - ab->ab_req->sc1394_node_id, sc->sc_tlabel, 0, - fwohci_read_multi_resp, fcb); - if (rv) - (*ab->ab_cb)(ab, -1); - else { - rv = fwohci_at_output(sc, sc->sc_ctx_atrq, &newpkt); - if (rv) { - fwohci_handler_set(sc, - IEEE1394_TCODE_READ_RESPONSE_QUADLET, - ab->ab_req->sc1394_node_id, sc->sc_tlabel, - 0, NULL, NULL); - (*ab->ab_cb)(ab, -1); - } else { - sc->sc_tlabel = (sc->sc_tlabel + 1) & 0x3F; - fcb->count++; - return IEEE1394_RCODE_COMPLETE; - } - } - } else - (*ab->ab_cb)(ab, IEEE1394_RCODE_COMPLETE); - - cleanup: - /* Can't get here unless ab_cb has been called. */ - fcb->abuf_valid = 0; - if (fcb->count == 0) { - FREE(fcb, M_DEVBUF); - MPRINTF("FREE(DEVBUF)", fcb); - fcb = NULL; - } - return IEEE1394_RCODE_COMPLETE; -} - -int -fwohci_write_ack(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt) -{ - struct ieee1394_abuf *ab = arg; - u_int16_t status; - - - status = pkt->fp_status & OHCI_DESC_STATUS_ACK_MASK; - if ((status != OHCI_CTXCTL_EVENT_ACK_COMPLETE) && - (status != OHCI_CTXCTL_EVENT_ACK_PENDING)) - DPRINTF(("%s: Got status packet: 0x%02x\n", __func__, - (unsigned int)status)); - - /* No callback means this level should free the buffers. */ - if (ab->ab_cb) - (*ab->ab_cb)(ab, status); - else { - if (ab->ab_data) { - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; /* XXX */ - } - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - } - return IEEE1394_RCODE_COMPLETE; -} - -int -fwohci_inreg(struct ieee1394_abuf *ab, int allow) -{ - struct ieee1394_softc *sc = ab->ab_req; - struct fwohci_softc *psc = - (struct fwohci_softc *)sc->sc1394_dev.dv_parent; - u_int32_t high, lo; - int rv; - - high = ((ab->ab_addr & 0x0000FFFF00000000) >> 32); - lo = (ab->ab_addr & 0x00000000FFFFFFFF); - - rv = 0; - switch (ab->ab_tcode) { - case IEEE1394_TCODE_READ_REQUEST_QUADLET: - case IEEE1394_TCODE_WRITE_REQUEST_QUADLET: - if (ab->ab_cb) - rv = fwohci_handler_set(psc, ab->ab_tcode, high, lo, - sc->sc1394_node_id, fwohci_parse_input, ab); - else - fwohci_handler_set(psc, ab->ab_tcode, high, lo, - sc->sc1394_node_id, NULL, NULL); - break; - case IEEE1394_TCODE_READ_REQUEST_DATABLOCK: - case IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK: - if (allow) { - if (ab->ab_cb) - rv = fwohci_block_handler_set(psc, ab->ab_tcode, - high, lo, sc->sc1394_node_id, ab->ab_length, - fwohci_parse_input, ab); - else - fwohci_block_handler_set(psc, ab->ab_tcode, - high, lo, sc->sc1394_node_id, ab->ab_length, - NULL, NULL); - /* - * XXX: Need something to indicate writing a smaller - * amount is ok. - */ - if (ab->ab_cb) - ab->ab_data = (void *)1; - } else { - if (ab->ab_cb) - rv = fwohci_handler_set(psc, ab->ab_tcode, - high, lo, sc->sc1394_node_id, - fwohci_parse_input, ab); - else - fwohci_handler_set(psc, ab->ab_tcode, high, lo, - sc->sc1394_node_id, NULL, NULL); - } - break; - default: - DPRINTF(("%s: Invalid registration tcode: %d\n", __func__, - ab->ab_tcode)); - return -1; - break; - } - return rv; -} - -int -fwohci_unreg(struct ieee1394_abuf *ab, int allow) -{ - void *save; - int rv; - - save = ab->ab_cb; - ab->ab_cb = NULL; - rv = fwohci_inreg(ab, allow); - ab->ab_cb = save; - return rv; -} - -int -fwohci_parse_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt) -{ - struct ieee1394_abuf *ab = (struct ieee1394_abuf *)arg; - u_int64_t addr; - u_int32_t *cur; - int i, count; - - ab->ab_tcode = (pkt->fp_hdr[0] >> 4) & 0xF; - ab->ab_tlabel = (pkt->fp_hdr[0] >> 10) & 0x3F; - addr = (((u_int64_t)(pkt->fp_hdr[1] & 0xFFFF) << 32) | pkt->fp_hdr[2]); - - DPRINTFN(3, ("%s: ab=0x%08x ab_cb=0x%08x\n\ttcode=%d tlabel=0x%02x" - " addr=%04x%08x\n", __func__, (u_int32_t)ab, (u_int32_t)ab->ab_cb, - ab->ab_tcode, ab->ab_tlabel, pkt->fp_hdr[1] & 0xffff, - pkt->fp_hdr[2])); - - switch (ab->ab_tcode) { - case IEEE1394_TCODE_READ_REQUEST_QUADLET: - ab->ab_retlen = 4; - break; - case IEEE1394_TCODE_READ_REQUEST_DATABLOCK: - ab->ab_retlen = (pkt->fp_hdr[3] >> 16) & 0xFFFF; - if ((ab->ab_retlen > ab->ab_length) || - ((addr + ab->ab_retlen) > (ab->ab_addr + ab->ab_length))) - return IEEE1394_RCODE_ADDRESS_ERROR; - - if ((caddr_t)ab->ab_data > (caddr_t)1) { - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; - } - break; - case IEEE1394_TCODE_WRITE_REQUEST_QUADLET: - ab->ab_retlen = 4; - case IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK: - if (!ab->ab_retlen) - ab->ab_retlen = (pkt->fp_hdr[3] >> 16) & 0xFFFF; - else { -#ifdef FWOHCI_DEBUG - if (ab->ab_retlen != ((pkt->fp_hdr[3] >> 16) & 0xFFFF)) - DPRINTF(("%s: retlen(%d) <> pktlen(%d)\n", - __func__, ab->ab_retlen, - (pkt->fp_hdr[3] >> 16) & 0xFFFF)); -#endif /* FWOHCI_DEBUG */ -#if 0 - ab->ab_retlen = (pkt->fp_hdr[3] >> 16) & 0xFFFF; -#endif - } - if ((ab->ab_retlen > ab->ab_length) || - ((addr + ab->ab_retlen) > (ab->ab_addr + ab->ab_length))) - return IEEE1394_RCODE_ADDRESS_ERROR; - - if ((caddr_t)ab->ab_data > (caddr_t)1) { - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; - } - ab->ab_data = malloc(ab->ab_retlen, M_1394DATA, M_WAITOK); - MPRINTF("malloc(1394DATA)", ab->ab_data); - - if (ab->ab_tcode == IEEE1394_TCODE_WRITE_REQUEST_QUADLET) - ab->ab_data[0] = pkt->fp_hdr[3]; - else { - count = 0; - cur = ab->ab_data; - - assert(pkt->fp_uio.uio_iovcnt > 0); - - for (i = 0; i < pkt->fp_uio.uio_iovcnt; i++) { - DPRINTFN(3, ("\t%d : bcopy(0x%08x, 0x%08x," - " 0x%x)\n", i, - (u_int32_t)pkt->fp_iov[i].iov_base, - (u_int32_t)cur, pkt->fp_iov[i].iov_len)); - bcopy(pkt->fp_iov[i].iov_base, cur, - pkt->fp_iov[i].iov_len); - (caddr_t)cur += pkt->fp_iov[i].iov_len; - count += pkt->fp_iov[i].iov_len; - } - if (ab->ab_retlen != count) - panic("Packet claims %d length " - "but %d bytes returned", - ab->ab_retlen, count); - } - break; - default: - panic("Got a callback for a tcode that wasn't requested: %d", - ab->ab_tcode); - break; - } - ab->ab_addr = addr; - ab->ab_cb(ab, IEEE1394_RCODE_COMPLETE); - return -1; -} - -#ifdef __NetBSD__ -int -fwohci_submatch(struct device *parent, struct cfdata *cf, void *aux) -#else -int -fwohci_submatch(struct device *parent, void *vcf, void *aux) -#endif -{ - struct ieee1394_attach_args *fwa = aux; -#ifdef __OpenBSD__ - struct cfdata *cf = (struct cfdata *)vcf; -#endif - - /* Both halves must be filled in for a match. */ - if ((cf->fwbuscf_idhi == FWBUS_UNK_IDHI && - cf->fwbuscf_idlo == FWBUS_UNK_IDLO) || - (cf->fwbuscf_idhi == ntohl(*((u_int32_t *)&fwa->uid[0])) && - cf->fwbuscf_idlo == ntohl(*((u_int32_t *)&fwa->uid[4])))) - return ((*cf->cf_attach->ca_match)(parent, cf, aux)); - return 0; -} - -int -fwohci_detach(struct fwohci_softc *sc, int flags) -{ - int rv = 0; - - *sc->sc_dying = 1; /* Stop the event thread. */ - wakeup(fwohci_event_thread); - DPRINTF(("%s: waiting 0x%08x\n", __func__, sc->sc_dying)); - tsleep(sc->sc_dying, PZERO, "detach", 3 * hz); - DPRINTF(("%s: woken up...\n", __func__)); - FREE(sc->sc_dying, M_DEVBUF); - MPRINTF("FREE(DEVBUF)", sc->sc_dying); - sc->sc_dying = NULL; /* XXX */ - - if (sc->sc_sc1394.sc1394_if != NULL) { - rv = config_detach_children(sc->sc_sc1394.sc1394_if, flags); - rv |= config_detach(sc->sc_sc1394.sc1394_if, flags); - } - if (rv) - return (rv); - -#ifdef __NetBSD__ - callout_stop(&sc->sc_selfid_callout); -#else - timeout_del(&sc->sc_selfid_callout); -#endif - - if (sc->sc_powerhook != NULL) - powerhook_disestablish(sc->sc_powerhook); - if (sc->sc_shutdownhook != NULL) - shutdownhook_disestablish(sc->sc_shutdownhook); - - return (rv); -} - -int -fwohci_activate(struct device *self, enum devact act) -{ - struct fwohci_softc *sc = (struct fwohci_softc *)self; - int s, rv = 0; - - s = splhigh(); - switch (act) { - case DVACT_ACTIVATE: - rv = EOPNOTSUPP; - break; - - case DVACT_DEACTIVATE: - if (sc->sc_sc1394.sc1394_if != NULL) - rv = config_deactivate(sc->sc_sc1394.sc1394_if); - break; - } - splx(s); - - return (rv); -} - -#ifdef FWOHCI_DEBUG -void -fwohci_show_intr(struct fwohci_softc *sc, u_int32_t intmask) -{ - - DPRINTF(("%s: intmask=0x%08x:", sc->sc_sc1394.sc1394_dev.dv_xname, - intmask)); - if (intmask & OHCI_Int_CycleTooLong) - DPRINTF((" CycleTooLong")); - if (intmask & OHCI_Int_UnrecoverableError) - DPRINTF((" UnrecoverableError")); - if (intmask & OHCI_Int_CycleInconsistent) - DPRINTF((" CycleInconsistent")); - if (intmask & OHCI_Int_BusReset) - DPRINTF((" BusReset")); - if (intmask & OHCI_Int_SelfIDComplete) - DPRINTF((" SelfIDComplete")); - if (intmask & OHCI_Int_LockRespErr) - DPRINTF((" LockRespErr")); - if (intmask & OHCI_Int_PostedWriteErr) - DPRINTF((" PostedWriteErr")); - if (intmask & OHCI_Int_ReqTxComplete) - DPRINTF((" ReqTxComplete(0x%04x)", - OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_TX_REQUEST, - OHCI_SUBREG_ContextControlClear))); - if (intmask & OHCI_Int_RespTxComplete) - DPRINTF((" RespTxComplete(0x%04x)", - OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_TX_RESPONSE, - OHCI_SUBREG_ContextControlClear))); - if (intmask & OHCI_Int_ARRS) - DPRINTF((" ARRS(0x%04x)", - OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_RX_RESPONSE, - OHCI_SUBREG_ContextControlClear))); - if (intmask & OHCI_Int_ARRQ) - DPRINTF((" ARRQ(0x%04x)", - OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_RX_REQUEST, - OHCI_SUBREG_ContextControlClear))); - if (intmask & OHCI_Int_IsochRx) - DPRINTF((" IsochRx(0x%08x)", - OHCI_CSR_READ(sc, OHCI_REG_IsoRecvIntEventClear))); - if (intmask & OHCI_Int_IsochTx) - DPRINTF((" IsochTx(0x%08x)", - OHCI_CSR_READ(sc, OHCI_REG_IsoXmitIntEventClear))); - if (intmask & OHCI_Int_RQPkt) - DPRINTF((" RQPkt(0x%04x)", - OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_RX_REQUEST, - OHCI_SUBREG_ContextControlClear))); - if (intmask & OHCI_Int_RSPkt) - DPRINTF((" RSPkt(0x%04x)", - OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_RX_RESPONSE, - OHCI_SUBREG_ContextControlClear))); - DPRINTF(("\n")); -} - -void -fwohci_show_phypkt(struct fwohci_softc *sc, u_int32_t val) -{ - u_int8_t key, phyid; - - key = OHCI_BITVAL(val, IEEE1394_PHY_TYPE); - phyid = OHCI_BITVAL(val, IEEE1394_PHY_ID); - DPRINTF(("%s: PHY packet from %d: ", - sc->sc_sc1394.sc1394_dev.dv_xname, phyid)); - switch (key) { - case 0: - DPRINTF(("PHY Config:")); - if (val & IEEE1394_CONFIG_FORCE_ROOT) - DPRINTF((" ForceRoot")); - if (val & IEEE1394_CONFIG_SET_GAPCNT) - DPRINTF((" Gap=%x", - OHCI_BITVAL(val, IEEE1394_CONFIG_GAPCNT))); - DPRINTF(("\n")); - break; - case 1: - DPRINTF(("Link-on\n")); - break; - case 2: - DPRINTF(("SelfID:")); - if (val & IEEE1394_SELFID_EXTENDED) { - DPRINTF((" #%d", - OHCI_BITVAL(val, IEEE1394_SELFID_EXT_SEQ))); - } else { - if (val & IEEE1394_SELFID_LINK_ACTIVE) - DPRINTF((" LinkActive")); - DPRINTF((" Gap=%x", - OHCI_BITVAL(val, IEEE1394_SELFID_GAPCNT))); - DPRINTF((" Spd=S%d", - 100 << OHCI_BITVAL(val, IEEE1394_SELFID_SPEED))); - DPRINTF((" Pow=%s", ieee1394_power[OHCI_BITVAL(val, - IEEE1394_SELFID_POWER)])); - if (val & IEEE1394_SELFID_CONTENDER) - DPRINTF((" Cont")); - if (val & IEEE1394_SELFID_INITIATED_RESET) - DPRINTF((" InitiateBusReset")); - } - if (val & IEEE1394_SELFID_MORE_PACKETS) - DPRINTF((" +")); - DPRINTF(("\n")); - break; - default: - DPRINTF(("unknown: 0x%08x\n", val)); - break; - } -} -#endif /* FWOHCI_DEBUG */ diff --git a/sys/dev/ieee1394/fwohcireg.h b/sys/dev/ieee1394/fwohcireg.h deleted file mode 100644 index c9d47538f74..00000000000 --- a/sys/dev/ieee1394/fwohcireg.h +++ /dev/null @@ -1,560 +0,0 @@ -/* $OpenBSD: fwohcireg.h,v 1.4 2003/10/22 09:31:30 jmc Exp $ */ -/* $NetBSD: fwohcireg.h,v 1.11 2002/01/26 16:34:27 ichiro Exp $ */ - -/* - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Matt Thomas of 3am Software Foundry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_IEEE1394_FWOHCIREG_H_ -#define _DEV_IEEE1394_FWOHCIREG_H_ - -/* PCI/CardBus-Specific definitions - */ - -/* In the PCI Class Code Register ... - */ -#define PCI_INTERFACE_OHCI 0x10 - -/* The OHCI Registers are in PCI BAR0. - */ -#define PCI_OHCI_MAP_REGISTER 0x10 - -/* HCI Control Register (in PCI config space) - */ -#define PCI_OHCI_CONTROL_REGISTER 0x40 - -/* If the following bit, all OHCI register access - * and DMA transactions are byte swapped. - */ -#define PCI_GLOBAL_SWAP_BE 0x00000001 - -/* Bus Independent Definitions */ - -#define OHCI_CONFIG_SIZE 1024 -#define OHCI_CONFIG_ALIGNMENT 1024 - -/* OHCI Registers - * OHCI Registers are divided into four spaces: - * 1) 0x000 .. 0x17C = Control register space - * 2) 0x180 .. 0x1FC = Asynchronous DMA context register space - * (4 contexts) - * 3) 0x200 .. 0x3FC = Isochronous Transmit DMA context register space - * (32 contexts) - * 4) 0x400 .. 0x7FC = Isochronous Receive DMA context register space - * (32 contexts) - */ -#define OHCI_REG_Version 0x000 -#define OHCI_REG_Guid_Rom 0x004 -#define OHCI_REG_ATRetries 0x008 -#define OHCI_REG_CsrReadData 0x00C -#define OHCI_REG_CsrCompareData 0x010 -#define OHCI_REG_CsrControl 0x014 -#define OHCI_REG_ConfigROMhdr 0x018 -#define OHCI_REG_BusId 0x01C -#define OHCI_REG_BusOptions 0x020 -#define OHCI_REG_GUIDHi 0x024 -#define OHCI_REG_GUIDLo 0x028 -#define OHCI_REG_reserved_02c 0x02C -#define OHCI_REG_reserved_030 0x030 -#define OHCI_REG_ConfigROMmap 0x034 -#define OHCI_REG_PostedWriteAddressLo 0x038 -#define OHCI_REG_PostedWriteAddressHi 0x03C -#define OHCI_REG_VendorId 0x040 -#define OHCI_REG_reserved_044 0x044 -#define OHCI_REG_reserved_048 0x048 -#define OHCI_REG_reserved_04c 0x04C -#define OHCI_REG_HCControlSet 0x050 -#define OHCI_REG_HCControlClear 0x054 -#define OHCI_REG_reserved_058 0x058 -#define OHCI_REG_reserved_05c 0x05C -#define OHCI_REG_reserved_060 0x060 -#define OHCI_REG_SelfIDBuffer 0x064 -#define OHCI_REG_SelfIDCount 0x068 -#define OHCI_REG_reserved_06c 0x06C -#define OHCI_REG_IRMultiChanMaskHiSet 0x070 -#define OHCI_REG_IRMultiChanMaskHiClear 0x074 -#define OHCI_REG_IRMultiChanMaskLoSet 0x078 -#define OHCI_REG_IRMultiChanMaskLoClear 0x07C -#define OHCI_REG_IntEventSet 0x080 -#define OHCI_REG_IntEventClear 0x084 -#define OHCI_REG_IntMaskSet 0x088 -#define OHCI_REG_IntMaskClear 0x08C -#define OHCI_REG_IsoXmitIntEventSet 0x090 -#define OHCI_REG_IsoXmitIntEventClear 0x094 -#define OHCI_REG_IsoXmitIntMaskSet 0x098 -#define OHCI_REG_IsoXmitIntMaskClear 0x09C -#define OHCI_REG_IsoRecvIntEventSet 0x0A0 -#define OHCI_REG_IsoRecvIntEventClear 0x0A4 -#define OHCI_REG_IsoRecvIntMaskSet 0x0A8 -#define OHCI_REG_IsoRecvIntMaskClear 0x0AC -#define OHCI_REG_InitialBandwidthAvailable 0x0B0 -#define OHCI_REG_InitialChannelsAvailableHi 0x0B4 -#define OHCI_REG_InitialChannelsAvailableLo 0x0B8 -#define OHCI_REG_reserved_0bc 0x0BC -#define OHCI_REG_reserved_0c0 0x0C0 -#define OHCI_REG_reserved_0c4 0x0C4 -#define OHCI_REG_reserved_0c8 0x0C8 -#define OHCI_REG_reserved_0cc 0x0CC -#define OHCI_REG_reserved_0d0 0x0D0 -#define OHCI_REG_reserved_0d4 0x0D4 -#define OHCI_REG_reserved_0d8 0x0D8 -#define OHCI_REG_FairnessConctrol 0x0DC -#define OHCI_REG_LinkControlSet 0x0E0 -#define OHCI_REG_LinkControlClear 0x0E4 -#define OHCI_REG_NodeId 0x0E8 -#define OHCI_REG_PhyControl 0x0EC -#define OHCI_REG_IsochronousCycleTimer 0x0F0 -#define OHCI_REG_reserved_0f0 0x0F4 -#define OHCI_REG_reserved_0f8 0x0F8 -#define OHCI_REG_reserved_0fc 0x0FC -#define OHCI_REG_AsynchronousRequestFilterHiSet 0x100 -#define OHCI_REG_AsynchronousRequestFilterHiClear 0x104 -#define OHCI_REG_AsynchronousRequestFilterLoSet 0x108 -#define OHCI_REG_AsynchronousRequestFilterLoClear 0x10C -#define OHCI_REG_PhysicalRequestFilterHiSet 0x110 -#define OHCI_REG_PhysicalRequestFilterHiClear 0x114 -#define OHCI_REG_PhysicalRequestFilterLoSet 0x118 -#define OHCI_REG_PhysicalRequestFilterLoClear 0x11C -#define OHCI_REG_PhysicalUpperBound 0x120 -#define OHCI_REG_reserved_124 0x124 -#define OHCI_REG_reserved_128 0x128 -#define OHCI_REG_reserved_12c 0x12C -#define OHCI_REG_reserved_130 0x130 -#define OHCI_REG_reserved_134 0x134 -#define OHCI_REG_reserved_138 0x138 -#define OHCI_REG_reserved_13c 0x13C -#define OHCI_REG_reserved_140 0x140 -#define OHCI_REG_reserved_144 0x144 -#define OHCI_REG_reserved_148 0x148 -#define OHCI_REG_reserved_14c 0x14C -#define OHCI_REG_reserved_150 0x150 -#define OHCI_REG_reserved_154 0x154 -#define OHCI_REG_reserved_158 0x158 -#define OHCI_REG_reserved_15c 0x15C -#define OHCI_REG_reserved_160 0x160 -#define OHCI_REG_reserved_164 0x164 -#define OHCI_REG_reserved_168 0x168 -#define OHCI_REG_reserved_16c 0x16C -#define OHCI_REG_reserved_170 0x170 -#define OHCI_REG_reserved_174 0x174 -#define OHCI_REG_reserved_178 0x178 -#define OHCI_REG_reserved_17c 0x17C - - -#define OHCI_REG_ASYNC_DMA_BASE 0x180 -#define OHCI_CTX_ASYNC_TX_REQUEST 0 -#define OHCI_CTX_ASYNC_TX_RESPONSE 1 -#define OHCI_CTX_ASYNC_RX_REQUEST 2 -#define OHCI_CTX_ASYNC_RX_RESPONSE 3 -#define OHCI_SUBREG_ContextControlSet 0x000 -#define OHCI_SUBREG_ContextControlClear 0x004 -#define OHCI_SUBREG_reserved_008 0x008 -#define OHCI_SUBREG_CommandPtr 0x00C -#define OHCI_SUBREG_ContextMatch 0x010 -#define OHCI_SUBREG_reserved_014 0x014 -#define OHCI_SUBREG_reserved_018 0x018 -#define OHCI_SUBREG_reserved_01c 0x01C -#define OHCI_ASYNC_DMA_WRITE(sc, ctx, reg, val) \ - OHCI_CSR_WRITE(sc, OHCI_REG_ASYNC_DMA_BASE + 32*(ctx) + (reg), val) -#define OHCI_ASYNC_DMA_READ(sc, ctx, reg) \ - OHCI_CSR_READ(sc, OHCI_REG_ASYNC_DMA_BASE + 32*(ctx) + (reg)) - -#define OHCI_REG_SYNC_TX_DMA_BASE 0x200 -#define OHCI_SYNC_TX_DMA_WRITE(sc, ctx, reg, val) \ - OHCI_CSR_WRITE(sc, OHCI_REG_SYNC_TX_DMA_BASE + 16*(ctx) + (reg), val) -#define OHCI_SYNC_TX_DMA_READ(sc, ctx, reg) \ - OHCI_CSR_READ(sc, OHCI_REG_SYNC_TX_DMA_BASE + 16*(ctx) + (reg)) - -#define OHCI_REG_SYNC_RX_DMA_BASE 0x400 -#define OHCI_SYNC_RX_DMA_WRITE(sc, ctx, reg, val) \ - OHCI_CSR_WRITE(sc, OHCI_REG_SYNC_RX_DMA_BASE + 32*(ctx) + (reg), val) -#define OHCI_SYNC_RX_DMA_READ(sc, ctx, reg) \ - OHCI_CSR_READ(sc, OHCI_REG_SYNC_RX_DMA_BASE + 32*(ctx) + (reg)) - -#define OHCI_BITVAL(val, name) \ - ((((val) & name##_MASK) >> name##_BITPOS)) -#define OHCI_BITSET(val, name) \ - ((((val) << name##_BITPOS) & name##_MASK)) - -/* OHCI_REG_Version - */ -#define OHCI_Version_GUID_ROM 0x01000000 -#define OHCI_Version_GET_Version(x) \ - ((((x) >> 16) & 0xF) + (((x) >> 20) & 0xF) * 10) -#define OHCI_Version_GET_Revision(x) \ - ((((x) >> 4) & 0xF) + ((x) & 0xF) * 10) - -/* OHCI_REG_Guid_Rom - */ -#define OHCI_Guid_AddrReset 0x80000000 -#define OHCI_Guid_RdStart 0x02000000 -#define OHCI_Guid_RdData_MASK 0x00FF0000 -#define OHCI_Guid_RdData_BITPOS 16 -#define OHCI_Guid_MiniROM_MASK 0x000000FF -#define OHCI_Guid_MiniROM_BITPOS 0 - -/* OHCI_REG_GUIDxx - */ - -/* OHCI_REG_CsrControl - */ -#define OHCI_CsrControl_Done 0x80000000 -#define OHCI_CsrControl_SelMASK 0x00000003 -#define OHCI_CsrControl_BusManId 0 -#define OHCI_CsrControl_BWAvail 1 -#define OHCI_CsrControl_ChanAvailHi 2 -#define OHCI_CsrControl_ChanAvailLo 3 - -/* OHCI_REG_BusOptions - */ -#define OHCI_BusOptions_LinkSpd_MASK 0x00000007 -#define OHCI_BusOptions_LinkSpd_BITPOS 0 -#define OHCI_BusOptions_G_MASK 0x000000C0 -#define OHCI_BusOptions_G_BITPOS 6 -#define OHCI_BusOptions_MaxRec_MASK 0x0000F000 -#define OHCI_BusOptions_MaxRec_BITPOS 12 -#define OHCI_BusOptions_CycClkAcc_MASK 0x00FF0000 -#define OHCI_BusOptions_CycClkAcc_BITPOS 16 -#define OHCI_BusOptions_PMC 0x08000000 -#define OHCI_BusOptions_BMC 0x10000000 -#define OHCI_BusOptions_ISC 0x20000000 -#define OHCI_BusOptions_CMC 0x40000000 -#define OHCI_BusOptions_IRMC 0x80000000 -#define OHCI_BusOptions_reserved 0x07000F38 - -/* OHCI_REG_HCControl - */ - -#define OHCI_HCControl_SoftReset 0x00010000 -#define OHCI_HCControl_LinkEnable 0x00020000 -#define OHCI_HCControl_PostedWriteEnable 0x00040000 -#define OHCI_HCControl_LPS 0x00080000 -#define OHCI_HCControl_APhyEnhanceEnable 0x00400000 -#define OHCI_HCControl_ProgramPhyEnable 0x00800000 -#define OHCI_HCControl_NoByteSwapData 0x40000000 -#define OHCI_HCControl_BIBImageValid 0x80000000 - -/* OHCI_REG_SelfID - */ -#define OHCI_SelfID_Error 0x80000000 -#define OHCI_SelfID_Gen_MASK 0x00FF0000 -#define OHCI_SelfID_Gen_BITPOS 16 -#define OHCI_SelfID_Size_MASK 0x000007FC -#define OHCI_SelfID_Size_BITPOS 2 - -/* OHCI_REG_Int{Event|Mask}* - */ -#define OHCI_Int_MasterEnable 0x80000000 -#define OHCI_Int_VendorSpecific 0x40000000 -#define OHCI_Int_SoftInterrupt 0x20000000 -#define OHCI_Int_Ack_Tardy 0x08000000 -#define OHCI_Int_PhyRegRcvd 0x04000000 -#define OHCI_Int_CycleTooLong 0x02000000 -#define OHCI_Int_UnrecoverableError 0x01000000 -#define OHCI_Int_CycleInconsistent 0x00800000 -#define OHCI_Int_CycleLost 0x00400000 -#define OHCI_Int_Cycle64Seconds 0x00200000 -#define OHCI_Int_CycleSynch 0x00100000 -#define OHCI_Int_Phy 0x00080000 -#define OHCI_Int_RegAccessFail 0x00040000 -#define OHCI_Int_BusReset 0x00020000 -#define OHCI_Int_SelfIDComplete 0x00010000 -#define OHCI_Int_SelfIDCOmplete2 0x00008000 -#define OHCI_Int_LockRespErr 0x00000200 -#define OHCI_Int_PostedWriteErr 0x00000100 -#define OHCI_Int_IsochRx 0x00000080 -#define OHCI_Int_IsochTx 0x00000040 -#define OHCI_Int_RSPkt 0x00000020 -#define OHCI_Int_RQPkt 0x00000010 -#define OHCI_Int_ARRS 0x00000008 -#define OHCI_Int_ARRQ 0x00000004 -#define OHCI_Int_RespTxComplete 0x00000002 -#define OHCI_Int_ReqTxComplete 0x00000001 - -/* OHCI_REG_LinkControl - */ -#define OHCI_LinkControl_CycleSource 0x00400000 -#define OHCI_LinkControl_CycleMaster 0x00200000 -#define OHCI_LinkControl_CycleTimerEnable 0x00100000 -#define OHCI_LinkControl_RcvPhyPkt 0x00000400 -#define OHCI_LinkControl_RcvSelfID 0x00000200 -#define OHCI_LinkControl_Tag1SyncFilterLock 0x00000040 - -/* OHCI_REG_NodeId - */ -#define OHCI_NodeId_IDValid 0x80000000 -#define OHCI_NodeId_ROOT 0x40000000 -#define OHCI_NodeId_CPS 0x08000000 -#define OHCI_NodeId_BusNumber 0x0000FFC0 -#define OHCI_NodeId_NodeNumber 0x0000003F - -/* OHCI_REG_PhyControl - */ -#define OHCI_PhyControl_RdDone 0x80000000 -#define OHCI_PhyControl_RdAddr_MASK 0x0F000000 -#define OHCI_PhyControl_RdAddr_BITPOS 24 -#define OHCI_PhyControl_RdData_MASK 0x00FF0000 -#define OHCI_PhyControl_RdData_BITPOS 16 -#define OHCI_PhyControl_RdReg 0x00008000 -#define OHCI_PhyControl_WrReg 0x00004000 -#define OHCI_PhyControl_RegAddr_MASK 0x00000F00 -#define OHCI_PhyControl_RegAddr_BITPOS 8 -#define OHCI_PhyControl_WrData_MASK 0x000000FF -#define OHCI_PhyControl_WrData_BITPOS 0 - -/* - * Section 3.1.1: ContextControl register - * - * - */ -#define OHCI_CTXCTL_RUN 0x00008000 -#define OHCI_CTXCTL_WAKE 0x00001000 -#define OHCI_CTXCTL_DEAD 0x00000800 -#define OHCI_CTXCTL_ACTIVE 0x00000400 - -#define OHCI_CTXCTL_SPD_MASK 0x00E00000 -#define OHCI_CTXCTL_SPD_BITPOS 21 - -#define OHCI_CTXCTL_SPD_100 0 -#define OHCI_CTXCTL_SPD_200 1 -#define OHCI_CTXCTL_SPD_400 2 - -#define OHCI_CTXCTL_EVENT_MASK 0x0000001F -#define OHCI_CTXCTL_EVENT_BITPOS 0 - -/* Events from 0 to 15 are generated by the OpenHCI controller. - * Events from 16 to 31 are four-bit IEEE 1394 ack codes or'ed with bit 4 set. - */ -#define OHCI_CTXCTL_EVENT_NO_STATUS 0 -#define OHCI_CTXCTL_EVENT_RESERVED1 1 - -/* The received data length was greater than the buffer's data_length. - */ -#define OHCI_CTXCTL_EVENT_LONG_PACKET 2 - -/* A subaction gap was detected before an ack arrived or the received - * ack had a parity error. - */ -#define OHCI_CTXCTL_EVENT_MISSING_ACK 3 - -/* Underrun on the corresponding FIFO. The packet was truncated. - */ -#define OHCI_CTXCTL_EVENT_UNDERRUN 4 - -/* A receive FIFO overflowed during the reception of an isochronous packet. - */ -#define OHCI_CTXCTL_EVENT_OVERRUN 5 - -/* An unrecoverable error occurred while the Host Controller was reading - * a descriptor block. - */ -#define OHCI_CTXCTL_EVENT_DESCRIPTOR_READ 6 - -/* An error occurred while the Host Controller was attempting to read - * from host memory in the data stage of descriptor processing. - */ -#define OHCI_CTXCTL_EVENT_DATA_READ 7 - -/* An error occurred while the Host Controller was attempting to write - * to host memory either in the data stage of descriptor processing - * (AR, IR), or when processing a single 16-bit host * memory write (IT). - */ -#define OHCI_CTXCTL_EVENT_DATA_WRITE 8 - -/* Identifies a PHY packet in the receive buffer as being the synthesized - * bus reset packet. (See section 8.4.2.3). - */ -#define OHCI_CTXCTL_EVENT_BUS_RESET 9 - -/* Indicates that the asynchronous transmit response packet expired and - * was not transmitted, or that an IT DMA context experienced a skip - * processing overflow (See section 9.3.3). - */ -#define OHCI_CTXCTL_EVENT_TIMEOUT 10 - -/* A bad tCode is associated with this packet. The packet was flushed. - */ -#define OHCI_CTXCTL_EVENT_TCODE_ERR 11 -#define OHCI_CTXCTL_EVENT_RESERVED12 12 -#define OHCI_CTXCTL_EVENT_RESERVED13 13 - -/* An error condition has occurred that cannot be represented - * by any other event codes defined herein. - */ -#define OHCI_CTXCTL_EVENT_UNKNOWN 14 - -/* Sent by the link side of the output FIFO when asynchronous - * packets are being flushed due to a bus reset. - */ -#define OHCI_CTXCTL_EVENT_FLUSHED 15 - -/* IEEE1394 derived ACK codes follow - */ -#define OHCI_CTXCTL_EVENT_RESERVED16 16 - -/* For asynchronous request and response packets, this event - * indicates the destination node has successfully accepted - * the packet. If the packet was a request subaction, the - * destination node has successfully completed the transaction - * and no response subaction shall follow. The event code for - * transmitted PHY, isochronous, asynchronous stream and broadcast - * packets, none of which yields a 1394 ack code, shall be set - * by hardware to ack_complete unless an event occurs. - */ -#define OHCI_CTXCTL_EVENT_ACK_COMPLETE 17 - -/* The destination node has successfully accepted the packet. - * If the packet was a request subaction, a response subaction - * should follow at a later time. This code is not returned for - * a response subaction. - */ -#define OHCI_CTXCTL_EVENT_ACK_PENDING 18 -#define OHCI_CTXCTL_EVENT_RESERVED19 19 - -/* The packet could not be accepted after max ATRetries (see - * section 5.4) attempts, and the last ack received was ack_busy_X. - */ -#define OHCI_CTXCTL_EVENT_ACK_BUSY_X 20 - -/* The packet could not be accepted after max ATRetries (see - * section 5.4) attempts, and the last ack received was ack_busy_A. - */ -#define OHCI_CTXCTL_EVENT_ACK_BUSY_A 21 - -/* The packet could not be accepted after max AT Retries (see - * section 5.4) attempts, and the last ack received was ack_busy_B. - */ -#define OHCI_CTXCTL_EVENT_ACK_BUSY_B 22 -#define OHCI_CTXCTL_EVENT_RESERVED23 23 -#define OHCI_CTXCTL_EVENT_RESERVED24 24 -#define OHCI_CTXCTL_EVENT_RESERVED25 25 -#define OHCI_CTXCTL_EVENT_RESERVED26 26 - -/* The destination node could not accept the packet because - * the link and higher layers are in a suspended state. - */ -#define OHCI_CTXCTL_EVENT_ACK_TARDY 27 -#define OHCI_CTXCTL_EVENT_RESERVED28 28 - -/* An AT context received an ack_data_error, or an IR context - * in packet-per-buffer mode detected a data field CRC or - * data_length error. - */ -#define OHCI_CTXCTL_EVENT_ACK_DATA_ERROR 29 - -/* A field in the request packet header was set to an unsupported or - * incorrect value, or an invalid transaction was attempted (e.g., a - * write to a read-only address). - */ -#define OHCI_CTXCTL_EVENT_ACK_TYPE_ERROR 30 -#define OHCI_CTXCTL_EVENT_RESERVED31 31 - -/* Context Control for isochronous transmit context - */ -#define OHCI_CTXCTL_TX_CYCLE_MATCH_ENABLE 0x80000000 -#define OHCI_CTXCTL_TX_CYCLE_MATCH_MASK 0x7FFF0000 -#define OHCI_CTXCTL_TX_CYCLE_MATCH_BITPOS 16 - -#define OHCI_CTXCTL_RX_BUFFER_FILL 0x80000000 -#define OHCI_CTXCTL_RX_ISOCH_HEADER 0x40000000 -#define OHCI_CTXCTL_RX_CYCLE_MATCH_ENABLE 0x20000000 -#define OHCI_CTXCTL_RX_MULTI_CHAN_MODE 0x10000000 -#define OHCI_CTXCTL_RX_DUAL_BUFFER_MODE 0x08000000 - -/* Context Match registers - */ -#define OHCI_CTXMATCH_TAG3 0x80000000 -#define OHCI_CTXMATCH_TAG2 0x40000000 -#define OHCI_CTXMATCH_TAG1 0x20000000 -#define OHCI_CTXMATCH_TAG0 0x10000000 -#define OHCI_CTXMATCH_CYCLE_MATCH_MASK 0x07FFF000 -#define OHCI_CTXMATCH_CYCLE_MATCH_BITPOS 12 -#define OHCI_CTXMATCH_SYNC_MASK 0x00000F00 -#define OHCI_CTXMATCH_SYNC_BITPOS 8 -#define OHCI_CTXMATCH_TAG1_SYNC_FILTER 0x00000040 -#define OHCI_CTXMATCH_CHANNEL_NUMBER_MASK 0x0000003F -#define OHCI_CTXMATCH_CHANNEL_NUMBER_BITPOS 0 - -/* - * Miscellaneous definitions. - */ - -#define OHCI_TCODE_PHY 0xE - -#if BYTE_ORDER == BIG_ENDIAN -typedef struct fwohci_desc { - u_int16_t fd_flags; - u_int16_t fd_reqcount; - u_int32_t fd_data; - u_int32_t fd_branch; - u_int16_t fd_status; - u_int16_t fd_rescount; -#if 0 /* XXX */ - u_int32_t fd_immed[4]; -#endif -} fwohci_desc; -#endif -#if BYTE_ORDER == LITTLE_ENDIAN -typedef struct fwohci_desc { - u_int16_t fd_reqcount; - u_int16_t fd_flags; - u_int32_t fd_data; - u_int32_t fd_branch; - u_int16_t fd_rescount; - u_int16_t fd_status; -#if 0 /* XXX */ - u_int32_t fd_immed[4]; -#endif -} fwohci_desc; -#endif -#define fd_timestamp fd_rescount - -#define OHCI_DESC_INPUT 0x2000 -#define OHCI_DESC_LAST 0x1000 -#define OHCI_DESC_STATUS 0x0800 -#define OHCI_DESC_IMMED 0x0200 -#define OHCI_DESC_PING 0x0080 -#define OHCI_DESC_INTR_ALWAYS 0x0030 -#define OHCI_DESC_INTR_ERR 0x0010 -#define OHCI_DESC_BRANCH 0x000C -#define OHCI_DESC_WAIT 0x0003 - -#define OHCI_DESC_MAX 8 - -/* Some constants for passing ACK values around with from status reg's */ - -#define OHCI_DESC_STATUS_ACK_MASK 0x1F - -#endif /* _DEV_IEEE1394_FWOHCIREG_ */ diff --git a/sys/dev/ieee1394/fwohcivar.h b/sys/dev/ieee1394/fwohcivar.h deleted file mode 100644 index 51e3e12c359..00000000000 --- a/sys/dev/ieee1394/fwohcivar.h +++ /dev/null @@ -1,252 +0,0 @@ -/* $OpenBSD: fwohcivar.h,v 1.4 2003/01/12 12:03:48 tdeval Exp $ */ -/* $NetBSD: fwohcivar.h,v 1.17 2002/01/16 01:47:37 eeh Exp $ */ - -/* - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Matt Thomas of the 3am Software Foundry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_IEEE1394_FWOHCIVAR_H_ -#define _DEV_IEEE1394_FWOHCIVAR_H_ - -#ifdef __NetBSD__ -#include <sys/callout.h> -#else -#include <sys/timeout.h> -#endif -#include <sys/queue.h> - -#include <machine/bus.h> - -#define OHCI_PAGE_SIZE 0x0800 -#define OHCI_BUF_ARRQ_CNT 16 -#define OHCI_BUF_ARRS_CNT 8 -#define OHCI_BUF_ATRQ_CNT (8*8) -#define OHCI_BUF_ATRS_CNT (8*8) -#define OHCI_BUF_IR_CNT 8 -#define OHCI_BUF_CNT \ - (OHCI_BUF_ARRQ_CNT + OHCI_BUF_ARRS_CNT + OHCI_BUF_ATRQ_CNT + \ - OHCI_BUF_ATRS_CNT + OHCI_BUF_IR_CNT + 1 + 1) - -#define OHCI_LOOP 1000 -#define OHCI_SELFID_TIMEOUT (3 * hz) -#define OHCI_ASYNC_STREAM 0x40 - -struct fwohci_softc; -struct fwohci_pkt; -struct mbuf; - -typedef struct fwohci_buf { - TAILQ_ENTRY(fwohci_buf) fb_list; - bus_dma_segment_t fb_seg; - int fb_nseg; - bus_dmamap_t fb_dmamap; /* DMA map of the buffer */ - caddr_t fb_buf; /* kernel vaddr of the buffer */ - struct fwohci_desc *fb_desc; /* kernel vaddr of descriptor */ - bus_addr_t fb_daddr; /* paddr of the descriptor */ - int fb_off; - struct mbuf *fb_m; - void *fb_statusarg; - void (*fb_callback)(struct device *, struct mbuf *); - int (*fb_statuscb)(struct fwohci_softc *, void *, - struct fwohci_pkt *); -} fwohci_buf; - -typedef struct fwohci_pkt { - int fp_tcode; - int fp_hlen; - int fp_dlen; - u_int32_t fp_hdr[4]; - struct uio fp_uio; - struct iovec fp_iov[6]; - u_int32_t *fp_trail; - struct mbuf *fp_m; - u_int16_t fp_status; - void *fp_statusarg; - void (*fp_callback)(struct device *, struct mbuf *); - int (*fp_statuscb)(struct fwohci_softc *, void *, - struct fwohci_pkt *); -} fwohci_pkt; - -typedef struct fwohci_handler { - LIST_ENTRY(fwohci_handler) fh_list; - u_int32_t fh_tcode; /* ARRQ / ARRS / IR */ - u_int32_t fh_key1; /* addrhi / srcid / chan */ - u_int32_t fh_key2; /* addrlo / tlabel / tag */ - u_int32_t fh_key3; /* node_id : count */ - int (*fh_handler)(struct fwohci_softc *, void *, - struct fwohci_pkt *); - void *fh_handarg; -} fwohci_handler; - -typedef struct fwohci_ctx { - int fc_ctx; - int fc_type; /* - * FWOHCI_CTX_(ASYNC| - * ISO_SINGLE| - * ISO_MULTI) - */ - int fc_bufcnt; - u_int32_t *fc_branch; - TAILQ_HEAD(fwohci_buf_s, fwohci_buf) fc_buf; - struct fwohci_buf_s fc_buf2; /* for iso */ - LIST_HEAD(, fwohci_handler) fc_handler; - struct fwohci_buf *fc_buffers; -} fwohci_ctx; - -typedef struct fwohci_uidtbl { - int fu_valid; - int fu_link_speed; - u_int8_t fu_uid[8]; -} fwohci_uidtbl; - -/* - * Needed to keep track of outstanding packets during a read op. Since the - * packet stream is asynch it's possible to parse a response packet before the - * ack bits are processed. In this case something needs to track whether the - * abuf is still valid before possibly attempting to use items from within it. - */ - -typedef struct fwohci_cb { - struct ieee1394_abuf *ab; - int count; - int abuf_valid; -} fwohci_cb; - -typedef struct fwohci_softc { - struct ieee1394_softc sc_sc1394; - struct evcnt sc_intrcnt; - struct evcnt sc_isocnt; - struct evcnt sc_isopktcnt; - - bus_space_tag_t sc_memt; - bus_space_handle_t sc_memh; - bus_dma_tag_t sc_dmat; - bus_size_t sc_memsize; -#if 0 - -/* - * Mandatory structures to get the link enabled. - */ - bus_dmamap_t sc_configrom_map; - bus_dmamap_t sc_selfid_map; - u_int32_t *sc_selfid_buf; - u_int32_t *sc_configrom; -#endif - - bus_dma_segment_t sc_dseg; - int sc_dnseg; - bus_dmamap_t sc_ddmamap; - struct fwohci_desc *sc_desc; - u_int8_t *sc_descmap; - int sc_descsize; - int sc_isoctx; - - void *sc_shutdownhook; - void *sc_powerhook; -#ifdef __NetBSD__ - struct callout sc_selfid_callout; -#else - struct timeout sc_selfid_callout; -#endif - int sc_selfid_fail; - - struct fwohci_ctx *sc_ctx_arrq; - struct fwohci_ctx *sc_ctx_arrs; - struct fwohci_ctx *sc_ctx_atrq; - struct fwohci_ctx *sc_ctx_atrs; - struct fwohci_ctx **sc_ctx_ir; - struct fwohci_buf sc_buf_cnfrom; - struct fwohci_buf sc_buf_selfid; - - struct proc *sc_event_thread; - - int *sc_dying; - u_int32_t sc_intmask; - u_int32_t sc_iso; - u_int32_t sc_isorxrst; - u_int32_t sc_isotxrst; - - u_int8_t sc_csr[CSR_SB_END]; - - struct fwohci_uidtbl *sc_uidtbl; - u_int16_t sc_nodeid; /* Full Node ID of this node */ - u_int8_t sc_rootid; /* Phy ID of Root */ - u_int8_t sc_irmid; /* Phy ID of IRM */ - u_int8_t sc_tlabel; /* Transaction Label */ - - LIST_HEAD(, ieee1394_softc) sc_nodelist; -} fwohci_softc; - -int fwohci_init (struct fwohci_softc *, const struct evcnt *); -int fwohci_intr (void *); -int fwohci_print (void *, const char *); -int fwohci_detach(struct fwohci_softc *, int); -int fwohci_activate(struct device *, enum devact); - -/* Macros to read and write the OHCI registers - */ -#define OHCI_CSR_WRITE(sc, reg, val) \ - bus_space_write_4((sc)->sc_memt, (sc)->sc_memh, reg, htole32(val)) -#ifdef __NetBSD__ -#define OHCI_CSR_READ(sc, reg) \ - le32toh(bus_space_read_4((sc)->sc_memt, (sc)->sc_memh, reg)) -#else -#define OHCI_CSR_READ(sc, reg) \ - letoh32(bus_space_read_4((sc)->sc_memt, (sc)->sc_memh, reg)) -#endif - -#define FWOHCI_CTX_ASYNC 0 -#define FWOHCI_CTX_ISO_SINGLE 1 /* for async stream */ -#define FWOHCI_CTX_ISO_MULTI 2 /* for isochronous */ - -/* Locators. */ - -#ifdef __NetBSD__ -#include "locators.h" -#else -/* dup from sys/conf/files */ -#define FWBUSCF_IDHI_DEFAULT (-1) -#define FWBUSCF_IDLO_DEFAULT (-1) -#define FWBUSCF_IDHI 1 -#define FWBUSCF_IDLO 0 -#endif - -#define fwbuscf_idhi cf_loc[FWBUSCF_IDHI] -#define FWBUS_UNK_IDHI FWBUSCF_IDHI_DEFAULT - -#define fwbuscf_idlo cf_loc[FWBUSCF_IDLO] -#define FWBUS_UNK_IDLO FWBUSCF_IDLO_DEFAULT - -#endif /* _DEV_IEEE1394_FWOHCIVAR_H_ */ diff --git a/sys/dev/ieee1394/fwscsi.c b/sys/dev/ieee1394/fwscsi.c deleted file mode 100644 index 14e3d540e32..00000000000 --- a/sys/dev/ieee1394/fwscsi.c +++ /dev/null @@ -1,1090 +0,0 @@ -/* $OpenBSD: fwscsi.c,v 1.15 2004/04/19 05:48:53 brad Exp $ */ - -/* - * Copyright (c) 2002 Thierry Deval. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/kernel.h> -#include <sys/device.h> -#include <sys/systm.h> -#include <sys/malloc.h> -#include <sys/buf.h> -#include <sys/uio.h> -#include <sys/types.h> -#include <sys/proc.h> -#include <sys/kthread.h> -#include <sys/timeout.h> - -#include <dev/rndvar.h> -#include <machine/bus.h> - -#ifdef __NetBSD__ -#include <dev/scsipi/scsi_all.h> -#include <dev/scsipi/scsipi_all.h> -#include <dev/scsipi/scsiconf.h> -#else -#include <scsi/scsi_all.h> -#include <scsi/scsiconf.h> -#endif - -#include <dev/std/ieee1212reg.h> -#include <dev/std/ieee1212var.h> -#include <dev/std/sbp2reg.h> -#include <dev/std/sbp2var.h> -#include <dev/ieee1394/ieee1394reg.h> -#include <dev/ieee1394/ieee1394var.h> -#include <dev/ieee1394/fwohcivar.h> -#include <dev/ieee1394/fwnodevar.h> -#include <dev/ieee1394/fwnodereg.h> - -#ifdef FWSCSI_DEBUG -#include <sys/syslog.h> -extern int log_open; -int fwscsi_oldlog; -#define DPRINTF(x) if (fwscsidebug&3) do { \ - fwscsi_oldlog = log_open; log_open = 1; \ - addlog x; log_open = fwscsi_oldlog; \ -} while (0) -#define DPRINTFN(n,x) if ((fwscsidebug&3)>(n)) do { \ - fwscsi_oldlog = log_open; log_open = 1; \ - addlog x; log_open = fwscsi_oldlog; \ -} while (0) -#ifdef FW_MALLOC_DEBUG -#define MPRINTF(x,y) DPRINTF(("%s[%d]: %s 0x%08x\n", \ - __func__, __LINE__, (x), (u_int32_t)(y))) -#else /* !FW_MALLOC_DEBUG */ -#define MPRINTF(x,y) -#endif /* FW_MALLOC_DEBUG */ -int fwscsidebug = 0; -#else /* FWSCSI_DEBUG */ -#define DPRINTF(x) -#define DPRINTFN(n,x) -#define MPRINTF(x,y) -#endif /* !FWSCSI_DEBUG */ - -#ifdef __NetBSD__ -int fwscsi_match(struct device *, struct cfdata *, void *); -#else -int fwscsi_match(struct device *, void *, void *); -#endif -void fwscsi_attach(struct device *, struct device *, void *); -void fwscsi_config_thread(void *); -void fwscsi_login_cb(void *, struct sbp2_status_notification *); -void fwscsi_agent_init(void *); -void fwscsi_status_notify(void *, struct sbp2_status_notification *); -int fwscsi_detach(struct device *, int); -#ifdef __NetBSD__ -void fwscsi_scsipi_request(struct scsipi_channel *, scsipi_adapter_req_t, - void *); -void fwscsi_scsipi_minphys(struct buf *); -#else -int fwscsi_scsi_cmd(struct scsi_xfer *); -void fwscsi_minphys(struct buf *); -#endif -void fwscsi_command_timeout(void *); -void fwscsi_command_wait(void *, struct sbp2_status_notification *); -void fwscsi_command_data(struct ieee1394_abuf *, int); - -typedef struct fwscsi_orb_data { - u_int32_t data_hash; - u_int32_t data_mask; - size_t data_len; - caddr_t data_addr; - struct ieee1394_abuf *data_ab; - TAILQ_ENTRY(fwscsi_orb_data) data_chain; -} fwscsi_orb_data; -static TAILQ_HEAD(fwscsi_data_tq, fwscsi_orb_data) fwscsi_datalist; -static int fwscsi_data_valid; - -typedef struct fwscsi_status { - u_int8_t flags; - u_int8_t status; - u_int16_t orb_offset_hi; - u_int32_t orb_offset_lo; - u_int8_t scsi_status; -#define FWSCSI_SCSI_STATUS 0x3F -#define FWSCSI_STATUS_FMT_MASK 0xC0 -#define FWSCSI_STATUS_FMT_SHIFT 6 -#define FWSCSI_SFMT_CURRENT 0x00 -#define FWSCSI_SFMT_DEFERRED 0x40 -#define FWSCSI_SFMT_FUTURE 0x80 -#define FWSCSI_SFMT_VENDOR 0xC0 - u_int8_t sense_key; -#define FWSCSI_INFO_VALID 0x80 -#define FWSCSI_MEI 0x70 -#define FWSCSI_SENSE_KEY 0x0F - u_int8_t sense_code; - u_int8_t sense_qual; - u_int32_t information; - u_int32_t cmd_spec_info; - u_int32_t sense_key_info; - u_int32_t vendor_info[2]; -} fwscsi_status; - -#ifdef __OpenBSD__ -struct scsi_adapter fwscsi_switch = { - fwscsi_scsi_cmd, /* scsi_cmd */ - fwscsi_minphys, /* scsi_minphys */ - NULL, /* open_target_lu */ - NULL, /* close_target_lu */ - NULL /* ioctl */ -}; - -struct scsi_device fwscsi_dev = { - NULL, /* Use default error handler */ - NULL, /* have a queue, served by this */ - NULL, /* have no async handler */ - NULL /* Use default 'done' routine */ -}; -#endif - -typedef struct fwscsi_softc { - struct device sc_dev; - struct p1212_dir **sc_unitdir; - int sc_units; - - struct scsi_link sc_adapter_link; - - u_int16_t sc_lun; - u_int8_t sc_speed; /* log2(n / 100M) */ - u_int8_t sc_maxpayload; /* log2(n / 4) */ - - struct scsibus_softc *sc_bus; -} fwscsi_softc; - -struct cfattach fwscsi_ca = { - sizeof(struct fwscsi_softc), fwscsi_match, fwscsi_attach, fwscsi_detach -}; - -#ifdef __OpenBSD__ -struct cfdriver fwscsi_cd = { - NULL, "fwscsi", DV_DULL -}; -#endif - -struct fwscsi_orb_data *fwscsi_datafind(struct fwscsi_softc *, u_int32_t); -struct fwscsi_orb_data * -fwscsi_datafind(struct fwscsi_softc *sc, u_int32_t hash) -{ - struct fwscsi_orb_data *data; - - TAILQ_FOREACH(data, &fwscsi_datalist, data_chain) { - if ((data->data_hash & data->data_mask) == - (hash & data->data_mask)) - break; - } - - return (data); -} - -#ifdef __NetBSD__ -int -fwscsi_match(struct device *parent, struct cfdata *match, void *aux) -#else -int -fwscsi_match(struct device *parent, void *match, void *aux) -#endif -{ - struct p1212_key **key; - struct p1212_dir **udirs = aux; - - key = p1212_find(*udirs, P1212_KEYTYPE_Immediate, - P1212_KEYVALUE_Unit_Spec_Id, 0); - if (!key || key[0]->val != SBP2_UNIT_SPEC_ID) { - if (key != NULL) { - free(key, M_DEVBUF); - MPRINTF("free(DEVBUF)", key); - key = NULL; /* XXX */ - } - return 0; - } - free(key, M_DEVBUF); - MPRINTF("free(DEVBUF)", key); - key = NULL; /* XXX */ - - key = p1212_find(*udirs, P1212_KEYTYPE_Immediate, - P1212_KEYVALUE_Unit_Sw_Version, 0); - if (!key || key[0]->val != SBP2_UNIT_SW_VERSION) { - if (key != NULL) { - free(key, M_DEVBUF); - MPRINTF("free(DEVBUF)", key); - key = NULL; /* XXX */ - } - return 0; - } - free(key, M_DEVBUF); - MPRINTF("free(DEVBUF)", key); - key = NULL; /* XXX */ - - key = p1212_find(*udirs, P1212_KEYTYPE_Immediate, - SBP2_KEYVALUE_Command_Set_Spec_Id, 0); - if (!key || key[0]->val != 0x00609E) { - if (key != NULL) { - free(key, M_DEVBUF); - MPRINTF("free(DEVBUF)", key); - key = NULL; /* XXX */ - } - return 0; - } - free(key, M_DEVBUF); - MPRINTF("free(DEVBUF)", key); - key = NULL; /* XXX */ - - key = p1212_find(*udirs, P1212_KEYTYPE_Immediate, - SBP2_KEYVALUE_Command_Set, 0); - if (!key || key[0]->val != 0x0104D8) { - if (key != NULL) { - free(key, M_DEVBUF); - MPRINTF("free(DEVBUF)", key); - key = NULL; /* XXX */ - } - return 0; - } - free(key, M_DEVBUF); - MPRINTF("free(DEVBUF)", key); - key = NULL; /* XXX */ - - return 1; -} - -void -fwscsi_attach(struct device *parent, struct device *self, void *aux) -{ - struct fwnode_softc *fwsc = (struct fwnode_softc *)parent; - struct fwscsi_softc *sc = (struct fwscsi_softc *)self; - struct p1212_dir **udir = (struct p1212_dir **)aux; - struct sbp2_login_orb *login_orb; - int lun; - - printf("\n"); - - for (sc->sc_units = 0; udir[sc->sc_units]; sc->sc_units++) {}; - DPRINTF(("%s: cpl = %d(%08x), %d unit(s)\n", __func__, - cpl, cpl, sc->sc_units)); - - if (!sc->sc_units) { - sc->sc_unitdir = NULL; - return; - } - - if (!fwscsi_data_valid) { - TAILQ_INIT(&fwscsi_datalist); - fwscsi_data_valid = 1; - } - sc->sc_adapter_link.adapter_target = 7; - sc->sc_adapter_link.adapter_buswidth = 8; - sc->sc_adapter_link.openings = 2; - sc->sc_adapter_link.device = &fwscsi_dev; - sc->sc_adapter_link.device_softc = sc; - sc->sc_adapter_link.adapter = &fwscsi_switch; - sc->sc_adapter_link.adapter_softc = sc; - sc->sc_adapter_link.flags = 0; - sc->sc_adapter_link.inquiry_flags = 0; - sc->sc_adapter_link.quirks |= SDEV_NOTAGS | SDEV_ONLYBIG; - - sc->sc_speed = fwsc->sc_sc1394.sc1394_link_speed; - sc->sc_maxpayload = fwsc->sc_sc1394.sc1394_max_receive - 1; - - sc->sc_lun = 0; - - sc->sc_unitdir = malloc(sc->sc_units * sizeof(*sc->sc_unitdir), - M_DEVBUF, M_NOWAIT); - MPRINTF("malloc(DEVBUF)", sc->sc_unitdir); - if (sc->sc_unitdir == NULL) { - printf("%s: memory allocation failure.\n", sc->sc_dev.dv_xname); - return; - } - bcopy(udir, sc->sc_unitdir, sc->sc_units * sizeof(*sc->sc_unitdir)); - - lun = sbp2_init(fwsc, *sc->sc_unitdir); - if (lun < 0) { - DPRINTF(("%s: initialization failure... (-1)\n", __func__)); - return; - } - sc->sc_lun = (u_int16_t)lun; - -#ifdef FWSCSI_DEBUG - if (fwscsidebug & 4) - Debugger(); -#endif /* FWSCSI_DEBUG */ - - login_orb = malloc(sizeof(struct sbp2_login_orb), M_1394DATA, M_WAITOK); - MPRINTF("malloc(1394DATA)", login_orb); - bzero(login_orb, sizeof(struct sbp2_login_orb)); - - login_orb->lun = htons(sc->sc_lun); - sbp2_login(fwsc, login_orb, fwscsi_login_cb, (void *)sc); -} - -void -fwscsi_login_cb(void *arg, struct sbp2_status_notification *notification) -{ - struct fwscsi_softc * const sc = arg; - struct sbp2_login_orb *login_orb = - (struct sbp2_login_orb *)notification->origin; -#ifdef FWSCSI_DEBUG - struct sbp2_status_block *status = notification->status; - int i; - - DPRINTF(("%s: cpl = %d(%08x)\n", __func__, cpl, cpl)); - - DPRINTF(("%s: origin=0x%08x csr=0x%016qx", __func__, - (u_int32_t)login_orb, - ((u_int64_t)(ntohs(status->orb_offset_hi)) << 32) + - ntohl(status->orb_offset_lo))); - - for (i = 0; i < sizeof(*status); i++) { - DPRINTFN(1, ("%s %02.2x", (i % 16)?"":"\n ", - ((u_int8_t *)status)[i])); - } - DPRINTF(("\n")); -#endif /* FWSCSI_DEBUG */ - - if (login_orb != NULL) { - free(login_orb, M_1394DATA); - MPRINTF("free(1394DATA)", login_orb); - login_orb = NULL; /* XXX */ - } - - sc->sc_bus = NULL; - -#ifdef FWSCSI_DEBUG - if (fwscsidebug & 4) - Debugger(); -#endif /* FWSCSI_DEBUG */ - - if (kthread_create(fwscsi_config_thread, sc, NULL, "%s", - sc->sc_dev.dv_xname)) - { - printf("%s: unable to create config thread\n", - sc->sc_dev.dv_xname); - } -} - -void -fwscsi_config_thread(void *arg) -{ - struct device *dev; - struct fwscsi_softc * const sc = arg; - - dev = config_found((void *)sc, &sc->sc_adapter_link, scsiprint); - sc->sc_bus = (struct scsibus_softc *)dev; - if (sc->sc_bus != NULL) { - sc->sc_bus->sc_buswidth = 8; - } - - DPRINTF(("%s: exiting...\n", __func__)); - - kthread_exit(0); -} - -void -fwscsi_status_notify(void *arg, struct sbp2_status_notification *notification) -{ - struct sbp2_status_block *status = notification->status; - void *wakemeup = notification->origin; - - DPRINTF(("%s: origin=0x%08x csr=0x%016qx\n", __func__, - (u_int32_t)wakemeup, - ((u_int64_t)(ntohs(status->orb_offset_hi)) << 32) + - ntohl(status->orb_offset_lo))); - - if (wakemeup != NULL) { - ((void **)wakemeup)[0] = status; - DPRINTF(("%s: Wake-up 0x%08x\n", __func__, - (u_int32_t)wakemeup)); - wakeup(wakemeup); - } -} - -int -fwscsi_detach(struct device *self, int flags) -{ - struct fwscsi_softc *sc = (struct fwscsi_softc *)self; - struct fwnode_softc *fwsc = - (struct fwnode_softc *)sc->sc_dev.dv_parent; - struct device *dev = (struct device *)sc->sc_bus; - int s, rv; - - DPRINTF(("%s: cpl = %d(%08x)\n", __func__, cpl, cpl)); - - rv = 0; - - if (sc->sc_bus) { - DPRINTF(("%s: detach %s\n", __func__, dev->dv_xname)); - s = splbio(); - rv += config_detach(dev, flags); - splx(s); - } - if (sc->sc_unitdir) { - sbp2_clean(fwsc, *sc->sc_unitdir, 0); - free(sc->sc_unitdir, M_DEVBUF); - MPRINTF("free(DEVBUF)", sc->sc_unitdir); - sc->sc_unitdir = NULL; /* XXX */ - } - - return (rv); -} - -#ifdef __NetBSD__ -void -fwscsi_scsipi_request(struct scsipi_channel *channel, - scsipi_adapter_req_t req, void *arg) -{ - /*struct scsipi_adapter *adapt = channel->chan_adapter; - struct fwscsi_softc *sc = (struct fwscsi_softc *)adapt->adapt_dev;*/ - struct scsipi_xfer *xs = arg; - int i; - - DPRINTF(("Called fwscsi_scsipi_request\n")); - - switch (req) { - case ADAPTER_REQ_RUN_XFER: - xs->error = XS_DRIVER_STUFFUP; - DPRINTF(("Got req_run_xfer\n")); - DPRINTF(("xs control: 0x%08x, timeout: %d\n", xs->xs_control, - xs->timeout)); - DPRINTF(("opcode: 0x%02x\n", (u_int8_t)xs->cmd->opcode)); - for (i = 0; i < 15; i++) - DPRINTF(("0x%02.2x ",(u_int8_t)xs->cmd->bytes[i])); - DPRINTF(("\n")); - scsipi_done(xs); - break; - case ADAPTER_REQ_GROW_RESOURCES: - DPRINTF(("Got req_grow_resources\n")); - break; - case ADAPTER_REQ_SET_XFER_MODE: - DPRINTF(("Got set xfer mode\n")); - break; - default: - panic("Unknown request: %d", (int)req); - } -} -#else -int -fwscsi_scsi_cmd(struct scsi_xfer *xs) -{ - struct sbp2_command_orb *cmd_orb; - struct fwscsi_orb_data *data_elm; - struct fwscsi_softc *sc = - (struct fwscsi_softc *)xs->sc_link->adapter_softc; - struct fwnode_softc *fwsc = - (struct fwnode_softc *)sc->sc_dev.dv_parent; - struct fwohci_softc *ohsc; - struct ieee1394_abuf *data_ab; - u_int32_t dhash, hash_mask; - u_int16_t options, host_id; - size_t datalen; - int datashift, s; -#ifdef FWSCSI_DEBUG - struct uio *data_uio; - int i; - - DPRINTF(("%s: cpl:%d(%x), xs:0x%08x\n", __func__, cpl, cpl, xs)); - DPRINTF((" flags:%05x retries:%d timeout:%d target:%d lun:%d\n", - xs->flags, xs->retries, xs->timeout, - xs->sc_link->target, xs->sc_link->lun)); - DPRINTF((" cmd[%d]:", xs->cmdlen)); - for (i=0; i<xs->cmdlen; i++) - DPRINTF((" %02.2x", ((u_int8_t *)xs->cmd)[i])); - DPRINTF(("\n data[%u]:0x%08x", xs->datalen, (caddr_t)xs->data)); - if (xs->flags & SCSI_DATA_UIO) { - data_uio = (struct uio *)xs->data; - DPRINTF(("/UIO:0x%08x(%d)/0x%08x", (u_int32_t)data_uio->uio_iov, - data_uio->uio_iovcnt, data_uio->uio_resid)); - } - if (xs->bp != NULL) - DPRINTF((" buf[%u/%u]:0x%08x", xs->bp->b_bcount, - xs->bp->b_bufsize, (u_int32_t)xs->bp->b_data)); - DPRINTF(("\n")); - if (xs->flags & SCSI_DATA_UIO) { - for (i=0; i<data_uio->uio_iovcnt; i++) - DPRINTFN(1,(" uio_segment[%d]: 0x%p(%d)\n", i, - (void *)data_uio->uio_iov[i].iov_base, - data_uio->uio_iov[i].iov_len)); - } -#endif /* FWSCSI_DEBUG */ - - //s = splbio(); - - /* Always reset xs->stimeout, lest we timeout_del() with trash. */ - timeout_set(&xs->stimeout, fwscsi_command_timeout, (void *)xs); - bzero(&xs->sense, sizeof(struct scsi_mode_sense)); - - /* Don't probe for unsupported targets. */ - if (xs->sc_link->target != sc->sc_lun || xs->sc_link->lun != 0) { - DPRINTF((" device not available...\n")); - xs->error = XS_SELTIMEOUT; - xs->status = SCSI_CHECK; - xs->flags |= ITSDONE | SCSI_SILENT; - xs->sense.flags = SKEY_ILLEGAL_REQUEST; - xs->sense.add_sense_code = 0x25; /* LOGIC UNIT NOT SUPPORTED */ - xs->sense.error_code = 0x70; - s = splbio(); - scsi_done(xs); - splx(s); - return (COMPLETE); - } - - cmd_orb = malloc(sizeof(struct sbp2_command_orb) + 8, - M_1394DATA, M_NOWAIT); - if (cmd_orb == NULL) { - printf("%s: can't alloc cmd_orb for target %d lun %d\n", - sc->sc_dev.dv_xname, xs->sc_link->target, - xs->sc_link->lun); - xs->error = XS_DRIVER_STUFFUP; - //splx(s); - return (TRY_AGAIN_LATER); - } - MPRINTF("malloc(1394DATA)", cmd_orb); - bzero(cmd_orb, sizeof(struct sbp2_command_orb) + 8); - - options = 0x8000 | ((fwsc->sc_sc1394.sc1394_link_speed & 0x7) << 8); - - datalen = 0; - if (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) { - ohsc = (struct fwohci_softc *) - ((struct device *)fwsc)->dv_parent; - host_id = ohsc->sc_nodeid; - DPRINTFN(1, ("%s: host=0x%04hx data=0x%08x[%d/%d]", - __func__, host_id, (u_int32_t)(xs->data), - xs->datalen, xs->resid)); - datashift = 0; - datalen = xs->datalen / (1 << SBP2_DATA_SHIFT); - while (datalen) { - datashift++; - datalen /= 2; - } - hash_mask = ~(1 << datashift) + 1; - do { - dhash = arc4random(); - } while (!dhash || fwscsi_datafind(sc, dhash) != NULL); - - MALLOC(data_elm, struct fwscsi_orb_data *, sizeof(*data_elm), - M_1394CTL, M_NOWAIT); - MPRINTF("MALLOC(1394CTL)", data_elm); - if (data_elm == NULL) { - printf("%s: can't alloc data_elm for target %d lun" - " %d\n", sc->sc_dev.dv_xname, xs->sc_link->target, - xs->sc_link->lun); - xs->error = XS_DRIVER_STUFFUP; - free(cmd_orb, M_1394DATA); - MPRINTF("free(1394DATA)", cmd_orb); - //splx(s); - return (TRY_AGAIN_LATER); - } - bzero(data_elm, sizeof(*data_elm)); - - MALLOC(data_ab, struct ieee1394_abuf *, sizeof(*data_ab), - M_1394DATA, M_NOWAIT); - MPRINTF("MALLOC(1394DATA)", data_ab); - if (data_ab == NULL) { - printf("%s: can't alloc data_ab for target %d lun" - " %d\n", sc->sc_dev.dv_xname, xs->sc_link->target, - xs->sc_link->lun); - xs->error = XS_DRIVER_STUFFUP; - free(data_elm, M_1394CTL); - MPRINTF("FREE(1394CTL)", data_elm); - free(cmd_orb, M_1394DATA); - MPRINTF("free(1394DATA)", cmd_orb); - //splx(s); - return (TRY_AGAIN_LATER); - } - bzero(data_ab, sizeof(*data_ab)); - - data_elm->data_hash = dhash; - data_elm->data_mask = hash_mask; - data_elm->data_addr = xs->data; - data_elm->data_len = xs->datalen; - - data_ab->ab_req = (struct ieee1394_softc *)fwsc; - data_ab->ab_retlen = 0; - datalen = roundup(xs->datalen, 4); - data_ab->ab_length = datalen & 0xffff; - data_ab->ab_addr = SBP2_DATA_BLOCK + - ((u_int64_t)(dhash & hash_mask) << SBP2_DATA_SHIFT); - data_ab->ab_cb = fwscsi_command_data; - data_ab->ab_cbarg = xs; - - TAILQ_INSERT_TAIL(&fwscsi_datalist, data_elm, data_chain); - xs->data = (u_char *)data_elm; - - /* Check direction of data transfer. */ - if (xs->flags & SCSI_DATA_OUT) { - data_ab->ab_tcode = - IEEE1394_TCODE_READ_REQUEST_DATABLOCK; - options |= (7 + fwsc->sc_sc1394.sc1394_link_speed) << 4; - DPRINTFN(1, (" -- OUT(%d/%X)\n", datalen, - (options >> 4) & 0xf)); - } else { - data_ab->ab_tcode = - IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK; - options |= 0x0800; - options |= (7 + fwsc->sc_sc1394.sc1394_link_speed) << 4; - DPRINTFN(1, (" -- IN(%d/%X)\n", datalen, - (options >> 4) & 0xf)); - } -#ifdef FWSCSI_DEBUG - for (i=0; i<xs->datalen; i++) { - DPRINTFN(2, ("%s %02.2x", (i % 16)?"":"\n ", - data_elm->data_addr[i])); - } - DPRINTFN(2, ("\n")); -#endif /* FWSCSI_DEBUG */ - fwsc->sc1394_inreg(data_ab, TRUE); - data_elm->data_ab = data_ab; - - cmd_orb->data_descriptor.node_id = htons(host_id); - cmd_orb->data_descriptor.hi = - htons((u_int16_t)(data_ab->ab_addr >> 32)); - cmd_orb->data_descriptor.lo = - htonl((u_int32_t)(data_ab->ab_addr & 0xFFFFFFFF)); - cmd_orb->data_size = htons(datalen & 0xFFFF); - } - - cmd_orb->options = htons(options); - - bcopy(xs->cmd, (void*)(&cmd_orb->command_block[0]), xs->cmdlen); - xs->cmd = (struct scsi_generic *) cmd_orb; - - timeout_add(&xs->stimeout, (xs->timeout * hz) / 1000); - sbp2_command_add(fwsc, sc->sc_lun, cmd_orb, 8, xs->data, - fwscsi_command_wait, (void *)xs); - - //splx(s); - return (SUCCESSFULLY_QUEUED); -} - -void -fwscsi_command_timeout(void *arg) -{ - struct sbp2_status_notification notification; - struct sbp2_status_block *status; - int s; - - DPRINTF(("%s: cpl = %d(%08x)\n", __func__, cpl, cpl)); - - MALLOC(status, struct sbp2_status_block *, sizeof(*status), - M_1394DATA, M_WAITOK); - bzero(status, sizeof(*status)); - - status->flags = 0x41; - status->flags |= SBP2_STATUS_RESP_TRANS_FAILURE | SBP2_STATUS_DEAD; - status->status = SBP2_STATUS_OBJECT_ORB | SBP2_STATUS_SERIAL_TIMEOUT; - - notification.origin = ((struct scsi_xfer *)arg)->cmd; - notification.status = status; - s = spl0(); - fwscsi_command_wait(arg, ¬ification); - splx(s); -} - -void -fwscsi_command_wait(void *aux, struct sbp2_status_notification *notification) -{ - struct scsi_xfer *xs = (struct scsi_xfer *)aux; - struct fwscsi_orb_data *data_elm = (struct fwscsi_orb_data *)xs->data; - struct fwscsi_softc *sc = xs->sc_link->adapter_softc; - struct fwnode_softc *fwsc = - (struct fwnode_softc *)sc->sc_dev.dv_parent; - struct sbp2_command_orb *cmd_orb; - struct ieee1394_abuf *data_ab; - struct fwscsi_status *status = NULL; - const char *error_str; - u_int32_t tmp; - int s; -#ifdef FWSCSI_DEBUG - void *orb = notification->origin; - int i; -#endif /* FWSCSI_DEBUG */ - - splassert(IPL_NONE); - DPRINTF(("%s: cpl = %d(%08x)\n", __func__, cpl, cpl)); - - s = splbio(); - timeout_del(&xs->stimeout); - splx(s); - status = (struct fwscsi_status *)notification->status; - -#ifdef FWSCSI_DEBUG - if (status != NULL) { - DPRINTF(("origin=0x%08x csr=0x%012qx\n", (u_int32_t)orb, - ((u_int64_t)(ntohs(status->orb_offset_hi)) << 32) + - ntohl(status->orb_offset_lo))); - for (i = 0; fwscsidebug > 2 && i < sizeof(*status); i++) { - DPRINTFN(2, ("%s %02.2x", i?(i % 16)?"":"\n ":" ", - ((u_int8_t *)status)[i])); - } - DPRINTFN(2, ("\n")); - } -#endif /* FWSCSI_DEBUG */ - - cmd_orb = (struct sbp2_command_orb *)(xs->cmd); - xs->cmd = &xs->cmdstore; - - if (data_elm != NULL) { - data_ab = data_elm->data_ab; - if (data_ab) { - data_ab->ab_addr = SBP2_DATA_BLOCK + - ((u_int64_t)(data_elm->data_hash & - data_elm->data_mask) << SBP2_DATA_SHIFT); - fwsc->sc1394_unreg(data_ab, TRUE); - if ((void *)data_ab->ab_data > (void *)1) { /* XXX */ - free(data_ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", data_ab->ab_data); - data_ab->ab_data = NULL; /* XXX */ - } - FREE(data_ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", data_ab); - data_ab = NULL; /* XXX */ - } - - xs->data = data_elm->data_addr; - s = splbio(); - TAILQ_REMOVE(&fwscsi_datalist, data_elm, data_chain); - splx(s); - FREE(data_elm, M_1394CTL); - MPRINTF("FREE(1394CTL)", data_elm); - data_elm = NULL; /* XXX */ - } - - if (status != NULL) { - switch (status->flags & SBP2_STATUS_RESPONSE_MASK) { - - case SBP2_STATUS_RESP_REQ_COMPLETE: - - switch (status->status) { - - case SBP2_STATUS_NONE: - case SBP2_STATUS_DUMMY_ORB_COMPLETE: - error_str = "NOERROR"; - xs->error = XS_NOERROR; - break; - - case SBP2_STATUS_UNSUPPORTED_TYPE: - case SBP2_STATUS_UNSUPPORTED_SPEED: - case SBP2_STATUS_UNSUPPORTED_PGSIZ: - case SBP2_STATUS_UNSUPPORTED_LUN: - case SBP2_STATUS_MAX_PAYLOAD_SMALL: - case SBP2_STATUS_INVALID_LOGINID: - case SBP2_STATUS_UNSPECIFIED: - /* - * These should really be handled at the - * SBP2 level for retry/correction. - */ - error_str = "DRIVER_STUFFUP"; - xs->error = XS_DRIVER_STUFFUP; - status->flags = 1; /* Exit from here. */ - break; - - case SBP2_STATUS_ACCESS_DENIED: - case SBP2_STATUS_RESOURCE_UNAVAIL: - case SBP2_STATUS_FUNCTION_REJECTED: - case SBP2_STATUS_REQUEST_ABORTED: - default: - error_str = "SENSE"; - xs->error = XS_SENSE; - break; - } - DPRINTFN(1, ("sbp_status 0x%02x, scsi_status 0x%02x" - " --> XS_%s\n", status->status, - status->scsi_status, error_str)); - - if ((status->flags & SBP2_STATUS_LEN_MASK) == 1) - break; - - /* Construct the sense info from the returned data. */ - xs->status = status->scsi_status & FWSCSI_SCSI_STATUS; - xs->sense.error_code = SSD_ERRCODE_VALID | 0x70 | - (status->scsi_status >> FWSCSI_STATUS_FMT_SHIFT); - xs->sense.flags = - (status->sense_key & FWSCSI_SENSE_KEY) | - ((status->sense_key & FWSCSI_MEI) << 1); - if (status->sense_key & FWSCSI_INFO_VALID) { - tmp = ntohl(status->information); - bcopy(&tmp, &xs->sense.info, sizeof(u_int32_t)); - //xs->sense.error_code |= 0x80; - } - xs->sense.add_sense_code = status->sense_code; - xs->sense.add_sense_code_qual = status->sense_qual; - tmp = ntohl(status->sense_key_info); - bcopy(&tmp, &xs->sense.fru, sizeof(u_int32_t)); - tmp = ntohl(status->cmd_spec_info); - bcopy(&tmp, &xs->sense.cmd_spec_info, - sizeof(u_int32_t)); - tmp = ntohl(status->vendor_info[0]); - bcopy(&tmp, &xs->sense.extra_bytes[0], - sizeof(u_int32_t)); - tmp = ntohl(status->vendor_info[1]); - bcopy(&tmp, &xs->sense.extra_bytes[4], - sizeof(u_int32_t)); - - break; - - case SBP2_STATUS_RESP_TRANS_FAILURE: - - switch (status->status & SBP2_STATUS_OBJECT_MASK) { - - case SBP2_STATUS_OBJECT_ORB: - case SBP2_STATUS_OBJECT_DATA_BUF: - case SBP2_STATUS_OBJECT_PAGE_TABLE: - case SBP2_STATUS_OBJECT_UNSPECIFIED: - default: - break; - } - - switch (status->status & SBP2_STATUS_SERIAL_MASK) { - - case SBP2_STATUS_SERIAL_ACK_MISSING: - error_str = "NOERROR"; - xs->error = XS_NOERROR; - break; - - case SBP2_STATUS_SERIAL_TIMEOUT: - error_str = "TIMEOUT"; - xs->error = XS_TIMEOUT; - break; - - case SBP2_STATUS_SERIAL_ACK_BUSY_X: - case SBP2_STATUS_SERIAL_ACK_BUSY_A: - case SBP2_STATUS_SERIAL_ACK_BUSY_B: - error_str = "BUSY"; - xs->error = XS_BUSY; - break; - - case SBP2_STATUS_SERIAL_TARDY_RETRY: - error_str = "SELTIMEOUT"; - xs->error = XS_SELTIMEOUT; - break; - - case SBP2_STATUS_SERIAL_CONFLICT: - case SBP2_STATUS_SERIAL_DATA: - case SBP2_STATUS_SERIAL_TYPE: - case SBP2_STATUS_SERIAL_ADDRESS: - default: - error_str = "SENSE"; - xs->error = XS_SENSE; - xs->status = SCSI_CHECK; - //xs->flags |= ITSDONE; - xs->sense.flags = SKEY_HARDWARE_ERROR; - xs->sense.add_sense_code = status->status; - break; - } - DPRINTFN(1, ("device error (flags 0x%02x, status 0x%02x)" - " --> XS_%s\n", status->flags, status->status, - error_str)); - - break; - - case SBP2_STATUS_RESP_ILLEGAL_REQ: - case SBP2_STATUS_RESP_VENDOR: - default: - break; - } - - DPRINTF(("%s: Free status(0x%08x)\n", __func__, - (u_int32_t)status)); - FREE(status, M_1394DATA); - MPRINTF("FREE(1394DATA)", status); - status = NULL; /* XXX */ - } else { - /* Probably bad to be here... */ - } - -#if 0 - /* - * Now, if we've come here with no error code, i.e. we've kept the - * initial XS_NOERROR, and the status code signals that we should - * check sense, we'll need to set up a request sense cmd block and - * push the command back into the ready queue *before* any other - * commands for this target/lunit, else we lose the sense info. - * We don't support chk sense conditions for the request sense cmd. - */ - if (xs->error == XS_NOERROR) { - if (status->flags & SBP2_STATUS_RESPONSE_MASK) { - xs->error = XS_SENSE; - error_str = "SENSE"; - } else if (status->flags & SBP2_STATUS_DEAD) { - xs->error = XS_DRIVER_STUFFUP; - error_str = "DRIVER_STUFFUP"; - } else { - error_str = "NOERROR"; - } - DPRINTFN(1, (" --> XS_%s\n", error_str)); - } -#endif - - if (cmd_orb != NULL) { - DPRINTF(("%s: Nullify orb(0x%08x)\n", __func__, - (u_int32_t)cmd_orb)); - cmd_orb->options = htons(SBP2_DUMMY_TYPE); - sbp2_command_del(fwsc, sc->sc_lun, cmd_orb); - free(cmd_orb, M_1394DATA); - MPRINTF("free(1394DATA)", cmd_orb); - cmd_orb = NULL; /* XXX */ - } - - xs->flags |= ITSDONE; - //xs->resid = 0; - - s = splbio(); - scsi_done(xs); - splx(s); -} - -void -fwscsi_command_data(struct ieee1394_abuf *ab, int rcode) -{ - struct fwscsi_orb_data *data_elm; - struct ieee1394_abuf *data_ab; - struct fwnode_softc *sc = (struct fwnode_softc *)ab->ab_req; - struct scsi_xfer *xs = ab->ab_cbarg; - size_t datalen; - caddr_t dataptr; -#ifdef FWSCSI_DEBUG - int i; -#endif /* FWSCSI_DEBUG */ - - DPRINTF(("%s: cpl = %d(%08x)\n", __func__, cpl, cpl)); - - if (rcode || (xs == NULL)) { -#ifdef FWSCSI_DEBUG - DPRINTF(("%s: Bad return code: %d\n", __func__, rcode)); -#endif /* FWSCSI_DEBUG */ - if ((void *)ab->ab_data > (void *)1) { /* XXX */ - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; - } - return; - } - - data_elm = (struct fwscsi_orb_data *)xs->data; - - datalen = MIN(ab->ab_retlen, ab->ab_length); - dataptr = data_elm->data_addr + - (size_t)((ab->ab_addr & SBP2_DATA_MASK) - - ((u_int64_t)(data_elm->data_hash & data_elm->data_mask) - << SBP2_DATA_SHIFT)); - - if ((dataptr < data_elm->data_addr) || - ((dataptr + datalen) > - (data_elm->data_addr + roundup(data_elm->data_len, 4)))) { - DPRINTF(("%s: Data (0x%08x[%d]) out of range (0x%08x[%d])\n", - __func__, dataptr, datalen, data_elm->data_addr, - data_elm->data_len)); - if ((void *)ab->ab_data > (void *)1) { /* XXX */ - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; - } - return; - } - - DPRINTF(("%s: tcode:%d data:0x%08x[%d/%d/%d/%d]", - __func__, ab->ab_tcode, dataptr, ab->ab_length, - ab->ab_retlen, data_elm->data_len, xs->resid)); - - switch (ab->ab_tcode) { - - /* Got a read so allocate the buffer and write out the response. */ - case IEEE1394_TCODE_READ_REQUEST_DATABLOCK: - - MALLOC(data_ab, struct ieee1394_abuf *, sizeof(*data_ab), - M_1394DATA, M_WAITOK); - MPRINTF("MALLOC(1394DATA)", data_ab); - bcopy(ab, data_ab, sizeof(*data_ab)); - - data_ab->ab_data = malloc(datalen, M_1394DATA, M_WAITOK); - MPRINTF("malloc(1394DATA)", data_ab->ab_data); - bzero(data_ab->ab_data, datalen); - bcopy(dataptr, data_ab->ab_data, - MIN(data_elm->data_len, datalen)); - - data_ab->ab_retlen = 0; - data_ab->ab_cb = NULL; - data_ab->ab_cbarg = NULL; - data_ab->ab_tcode = IEEE1394_TCODE_READ_RESPONSE_DATABLOCK; - data_ab->ab_length = datalen; - -#ifdef FWSCSI_DEBUG - for (i = 0; i < data_ab->ab_length; i++) { - DPRINTFN(1, ("%s %02.2x", (i % 16)?"":"\n ", - ((u_int8_t *)data_ab->ab_data)[i])); - } -#endif /* FWSCSI_DEBUG */ - - sc->sc1394_write(data_ab); - - break; - - case IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK: - -#ifdef FWSCSI_DEBUG - for (i = 0; i < ab->ab_retlen; i++) { - DPRINTFN(1, ("%s %02.2x", (i % 16)?"":"\n ", - ((u_int8_t *)ab->ab_data)[i])); - } -#endif /* FWSCSI_DEBUG */ - - bcopy(ab->ab_data, dataptr, datalen); - - break; - - default: - break; - } - DPRINTF(("\n")); - - if (xs->resid <= datalen) { - xs->resid = 0; - DPRINTFN(1, ("%s: Data block complete", __func__)); - } else { - xs->resid -= datalen; - DPRINTFN(1, ("%s: Wait more", __func__)); - } - DPRINTFN(1, (" -- resid = %d\n", xs->resid)); -} -#endif - -#ifdef __NetBSD__ -void -fwscsi_scsipi_minphys(struct buf *buf) -#else -void -fwscsi_minphys(struct buf *buf) -#endif -{ - DPRINTF(("%s: cpl = %d(%08x)\n", __func__, cpl, cpl)); - -#if 0 /* XXX - Only small transfers, until we implement data pages. */ - if (buf->b_bcount > SBP2_MAX_TRANS) - buf->b_bcount = SBP2_MAX_TRANS; -#else - if (buf->b_bcount > 0x8000) - buf->b_bcount = 0x8000; -#endif - - minphys(buf); -} diff --git a/sys/dev/ieee1394/ieee1394reg.h b/sys/dev/ieee1394/ieee1394reg.h deleted file mode 100644 index 87a3938cfd7..00000000000 --- a/sys/dev/ieee1394/ieee1394reg.h +++ /dev/null @@ -1,294 +0,0 @@ -/* $OpenBSD: ieee1394reg.h,v 1.4 2003/01/12 12:01:33 tdeval Exp $ */ -/* $NetBSD: ieee1394reg.h,v 1.12 2002/02/27 05:07:25 jmc Exp $ */ - -/* - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_IEEE1394_IEEE1394REG_H_ -#define _DEV_IEEE1394_IEEE1394REG_H_ - -#include <dev/std/ieee1212reg.h> - -/* - * Transaction Codes (Table 6-9) - */ -#define IEEE1394_TCODE_WRITE_REQUEST_QUADLET 0 -#define IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK 1 -#define IEEE1394_TCODE_WRITE_RESPONSE 2 -#define IEEE1394_TCODE_RESERVED_3 3 -#define IEEE1394_TCODE_READ_REQUEST_QUADLET 4 -#define IEEE1394_TCODE_READ_REQUEST_DATABLOCK 5 -#define IEEE1394_TCODE_READ_RESPONSE_QUADLET 6 -#define IEEE1394_TCODE_READ_RESPONSE_DATABLOCK 7 -#define IEEE1394_TCODE_CYCLE_START 8 -#define IEEE1394_TCODE_LOCK_REQUEST 9 -#define IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK 10 -#define IEEE1394_TCODE_LOCK_RESPONSE 11 -#define IEEE1394_TCODE_RESERVED_12 12 -#define IEEE1394_TCODE_RESERVED_13 13 -#define IEEE1394_TCODE_RESERVED_14 14 -#define IEEE1394_TCODE_RESERVED_15 15 - -/* - * Extended transaction codes (Table 6-10) - */ -#define IEEE1394_XTCODE_RESERVED_0 P1212_LOCK_RESERVED_0 -#define IEEE1394_XTCODE_MASK_SWAP P1212_LOCK_MASK_SWAP -#define IEEE1394_XTCODE_COMPARE_SWAP P1212_LOCK_COMPARE_SWAP -#define IEEE1394_XTCODE_FETCH_ADD P1212_LOCK_FETCH_ADD -#define IEEE1394_XTCODE_LITTLE_ADD P1212_LOCK_LITTLE_ADD -#define IEEE1394_XTCODE_BOUNDED_ADD P1212_LOCK_BOUNDED_ADD -#define IEEE1394_XTCODE_WRAP_ADD P1212_LOCK_WRAP_ADD -#define IEEE1394_XTCODE_VENDOR_DEPENDENT P1212_LOCK_VENDOR_DEPENDENT -/* - * 0x0008 .. 0xFFFF are reserved. - */ - -/* - * Response codes (Table 6-11) - */ -#define IEEE1394_RCODE_COMPLETE 0 -#define IEEE1394_RCODE_RESERVED_1 1 -#define IEEE1394_RCODE_RESERVED_2 2 -#define IEEE1394_RCODE_RESERVED_3 3 -#define IEEE1394_RCODE_CONFLICT_ERROR 4 -#define IEEE1394_RCODE_DATA_ERROR 5 -#define IEEE1394_RCODE_TYPE_ERROR 6 -#define IEEE1394_RCODE_ADDRESS_ERROR 7 -#define IEEE1394_RCODE_RESERVED_8 8 -#define IEEE1394_RCODE_RESERVED_9 9 -#define IEEE1394_RCODE_RESERVED_10 10 -#define IEEE1394_RCODE_RESERVED_11 11 -#define IEEE1394_RCODE_RESERVED_12 12 -#define IEEE1394_RCODE_RESERVED_13 13 -#define IEEE1394_RCODE_RESERVED_14 14 -#define IEEE1394_RCODE_RESERVED_15 15 - -#define IEEE1394_TAG_UNFORMATTED 0 -#define IEEE1394_TAG_RESERVED_1 1 -#define IEEE1394_TAG_RESERVED_2 2 -#define IEEE1394_TAG_RESERVED_3 3 - -#define IEEE1394_ACK_RESERVED_0 0 -#define IEEE1394_ACK_COMPLETE 1 -#define IEEE1394_ACK_PENDING 2 -#define IEEE1394_ACK_RESERVED_3 3 -#define IEEE1394_ACK_BUSY_X 4 -#define IEEE1394_ACK_BUSY_A 5 -#define IEEE1394_ACK_BUSY_B 6 -#define IEEE1394_ACK_RESERVED_7 7 -#define IEEE1394_ACK_RESERVED_8 8 -#define IEEE1394_ACK_RESERVED_9 9 -#define IEEE1394_ACK_RESERVED_10 10 -#define IEEE1394_ACK_RESERVED_11 11 -#define IEEE1394_ACK_RESERVED_12 12 -#define IEEE1394_ACK_DATA_ERROR 13 -#define IEEE1394_ACK_TYPE_ERROR 14 -#define IEEE1394_ACK_RESERVED_15 15 - -/* - * PHY packet types. - */ -#define IEEE1394_PHY_TYPE_MASK 0xC0000000 -#define IEEE1394_PHY_TYPE_BITPOS 30 -#define IEEE1394_PHY_SELF_ID 0x80000000 -#define IEEE1394_PHY_LINK_ON 0x40000000 -#define IEEE1394_PHY_CONFIG 0x00000000 -#define IEEE1394_PHY_ID_MASK 0x3F000000 -#define IEEE1394_PHY_ID_BITPOS 24 - -/* - * Link-On PHY Packet Fields. - */ -/* There is no other field than the PHY_ID. */ - -/* - * Configuration PHY Packet Fields. - */ -#define IEEE1394_CONFIG_FORCE_ROOT 0x00800000 -#define IEEE1394_CONFIG_SET_GAPCNT 0x00400000 -#define IEEE1394_CONFIG_GAPCNT_MASK 0x003F0000 -#define IEEE1394_CONFIG_GAPCNT_BITPOS 16 - -/* - * Self-ID PHY Packet Fields. - */ -#define IEEE1394_SELFID_EXTENDED 0x00800000 -#define IEEE1394_SELFID_LINK_ACTIVE 0x00400000 -#define IEEE1394_SELFID_CONTENDER 0x00000800 -#define IEEE1394_SELFID_INITIATED_RESET 0x00000002 -#define IEEE1394_SELFID_MORE_PACKETS 0x00000001 -#define IEEE1394_SELFID_GAPCNT_MASK 0x003F0000 -#define IEEE1394_SELFID_GAPCNT_BITPOS 16 -#define IEEE1394_SELFID_SPEED_MASK 0x0000C000 -#define IEEE1394_SELFID_SPEED_BITPOS 14 -#define IEEE1394_SELFID_DELAY_MASK 0x00003000 -#define IEEE1394_SELFID_DELAY_BITPOS 12 -#define IEEE1394_SELFID_POWER_MASK 0x00000700 -#define IEEE1394_SELFID_POWER_BITPOS 8 -#define IEEE1394_SELFID_EXT_SEQ_MASK 0x00700000 -#define IEEE1394_SELFID_EXT_SEQ_BITPOS 20 - -/* - * Node's port status. - */ -#define IEEE1394_SELFID_PORT_STATUS(packet,port) \ - (((packet) >> (16 - 2 * (port))) & 0x3) -#define IEEE1394_PORT_NOT_PRESENT 0 -#define IEEE1394_PORT_NOT_CONNECTED 1 -#define IEEE1394_PORT_CONNECT_PARENT 2 -#define IEEE1394_PORT_CONNECT_CHILD 3 - -/* - * Defined IEEE 1394 power classes. - */ -#define IEEE1394_POW_NONE 0 /* No power feature. */ -#define IEEE1394_POW_SELF_15W 1 /* Provides 15W. */ -#define IEEE1394_POW_SELF_30W 2 /* Provides 30W. */ -#define IEEE1394_POW_SELF_45W 3 /* Provides 45W. */ -#define IEEE1394_POW_USES_1W 4 /* Uses up to 1W. */ -#define IEEE1394_POW_USES_2W 5 /* Uses up to 2W. */ -#define IEEE1394_POW_USES_5W 6 /* Uses up to 5W. */ -#define IEEE1394_POW_USES_9W 7 /* Uses up to 9W. */ - -#define IEEE1394_POW_STRINGS "None", "15W_Src", "30W_Src", \ - "45W_Src", "1W_Sink", "2W_Sink", \ - "5W_Sink", "9W_Sink" - -/* - * Defined IEEE 1394 speeds. - */ -#define IEEE1394_SPD_S100 0 /* 1394-1995 */ -#define IEEE1394_SPD_S200 1 /* 1394-1995 */ -#define IEEE1394_SPD_S400 2 /* 1394-1995 */ -#define IEEE1394_SPD_S800 3 /* 1394b */ -#define IEEE1394_SPD_S1600 4 /* 1394b */ -#define IEEE1394_SPD_S3200 5 /* 1394b */ -#define IEEE1394_SPD_MAX 6 - -#define IEEE1394_SPD_STRINGS "100Mb/s", "200Mb/s", "400Mb/s", "800Mb/s", \ - "1.6Gb/s", "3.2Gb/s" - -#if 0 -typedef struct ieee1394_async_nodata { - u_int32_t an_header_crc; -} ieee1394_async_nodata __attribute((__packed__)); -#endif - -#define IEEE1394_BCAST_PHY_ID 0x3f -#define IEEE1394_ISOCH_MASK 0x3f - -/* - * Signature - */ -#define IEEE1394_SIGNATURE 0x31333934 - -/* - * Tag value - */ -#define IEEE1394_TAG_GASP 0x3 - -/* - * Control and Status Registers (IEEE1212 & IEEE1394) - */ -#define CSR_BASE_HI 0x0000ffff -#define CSR_BASE_LO 0xf0000000 -#define CSR_BASE 0x0000fffff0000000UL - -#define CSR_STATE_CLEAR 0x0000 -#define CSR_STATE_SET 0x0004 -#define CSR_NODE_IDS 0x0008 -#define CSR_RESET_START 0x000c -#define CSR_INDIRECT_ADDRESS 0x0010 -#define CSR_INDIRECT_DATA 0x0014 -#define CSR_SPLIT_TIMEOUT_HI 0x0018 -#define CSR_SPLIT_TIMEOUT_LO 0x001c -#define CSR_ARGUMENT_HI 0x0020 -#define CSR_ARGUMENT_LO 0x0024 -#define CSR_TEST_START 0x0028 -#define CSR_TEST_STATUS 0x002c -#define CSR_INTERRUPT_TARGET 0x0050 -#define CSR_INTERRUPT_MASK 0x0054 -#define CSR_CLOCK_VALUE 0x0058 -#define CSR_CLOCK_PERIOD 0x005c -#define CSR_CLOCK_STROBE_ARRIVED 0x0060 -#define CSR_CLOCK_INFO 0x0064 -#define CSR_MESSAGE_REQUEST 0x0080 -#define CSR_MESSAGE_RESPONSE 0x00c0 - -#define CSR_SB_CYCLE_TIME 0x0200 -#define CSR_SB_BUS_TIME 0x0204 -#define CSR_SB_POWER_FAIL_IMMINENT 0x0208 -#define CSR_SB_POWER_SOURCE 0x020c -#define CSR_SB_BUSY_TIMEOUT 0x0210 -#define CSR_SB_PRIORITY_BUDGET_HI 0x0214 -#define CSR_SB_PRIORITY_BUDGET_LO 0x0218 -#define CSR_SB_BUS_MANAGER_ID 0x021c -#define CSR_SB_BANDWIDTH_AVAILABLE 0x0220 -#define CSR_SB_CHANNEL_AVAILABLE_HI 0x0224 -#define CSR_SB_CHANNEL_AVAILABLE_LO 0x0228 -#define CSR_SB_MAINT_CONTROL 0x022c -#define CSR_SB_MAINT_UTILITY 0x0230 -#define CSR_SB_BROADCAST_CHANNEL 0x0234 - -#define CSR_CONFIG_ROM 0x0400 - -#define CSR_SB_OUTPUT_MASTER_PLUG 0x0900 -#define CSR_SB_OUTPUT_PLUG 0x0904 -#define CSR_SB_INPUT_MASTER_PLUG 0x0980 -#define CSR_SB_INPUT_PLUG 0x0984 -#define CSR_SB_FCP_COMMAND_FRAME 0x0b00 -#define CSR_SB_FCP_RESPONSE_FRAME 0x0d00 -#define CSR_SB_TOPOLOGY_MAP 0x1000 -#define CSR_SB_END 0x1400 - -#define IEEE1394_MAX_REC(i) (0x1 << ((i) + 1)) -#define IEEE1394_MAX_ASYNC(i) (0x200 << (i)) -#define IEEE1394_BUSINFO_LEN 3 - -#define IEEE1394_GET_MAX_REC(i) (((i) & 0x0000f000) >> 12) -#define IEEE1394_GET_LINK_SPD(i) ((i) & 0x00000007) - -/* - * XXX. Should be at if_fw level but needed here for constructing the config - * rom. An interface for if_fw to send up a config rom should be done (probably - * in the p1212 routines. - */ - -#define FW_FIFO_HI 0x2000 -#define FW_FIFO_LO 0x00000000 - -#endif /* _DEV_IEEE1394_IEEE1394REG_H_ */ diff --git a/sys/dev/ieee1394/ieee1394var.h b/sys/dev/ieee1394/ieee1394var.h deleted file mode 100644 index f7cb929f201..00000000000 --- a/sys/dev/ieee1394/ieee1394var.h +++ /dev/null @@ -1,124 +0,0 @@ -/* $OpenBSD: ieee1394var.h,v 1.5 2003/01/12 12:02:51 tdeval Exp $ */ -/* $NetBSD: ieee1394var.h,v 1.15 2002/02/27 05:04:28 jmc Exp $ */ - -/* - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_IEEE1394_IEEE1394VAR_H_ -#define _DEV_IEEE1394_IEEE1394VAR_H_ - -extern const char * const ieee1394_speeds[]; - -struct ieee1394_softc; -struct ieee1394_node; - -/* These buffers have no reference counting. It is assumed that - * the upper level buffer (struct buf or struct mbuf) will have the - * requisite reference counting. - */ -typedef struct ieee1394_abuf { - struct ieee1394_softc *ab_req; /* requestor */ - struct ieee1394_softc *ab_resp; /* response */ - u_int32_t *ab_data; - struct uio *ab_uio; - u_int64_t ab_addr; - u_int8_t ab_tcode; - u_int8_t ab_tlabel; - u_int32_t ab_length; - u_int32_t ab_retlen; /* length returned from read. */ - u_int32_t ab_retries; - void (*ab_cb)(struct ieee1394_abuf *, int); - void *ab_cbarg; -} ieee1394_abuf; - -typedef struct ieee1394_callbacks { - void (*cb1394_busreset)(struct ieee1394_softc *); - void (*cb1394_at_queue)(struct ieee1394_softc *, int type, - struct ieee1394_abuf *); - void (*cb1394_at_done) (struct ieee1394_softc *, - struct ieee1394_abuf *); -} ieee1394_callbacks; - -typedef struct ieee1394_attach_args { - char name[7]; - u_int8_t link_speed; - u_int8_t uid[8]; - u_int16_t nodeid; - int (*read) (struct ieee1394_abuf *); - int (*write)(struct ieee1394_abuf *); - int (*inreg)(struct ieee1394_abuf *, int); - int (*unreg)(struct ieee1394_abuf *, int); -} ieee1394_attach_args; - -typedef struct ieee1394_softc { - struct device sc1394_dev; - struct device *sc1394_if; /* Move to fwohci level. */ - - struct ieee1394_callbacks sc1394_callback; /* Nuke probably. */ - u_int32_t *sc1394_configrom; - u_int32_t sc1394_configrom_len; /* quadlets. */ - u_int32_t sc1394_max_receive; - u_int8_t sc1394_guid[8]; - u_int8_t sc1394_link_speed; /* IEEE1394_SPD_* */ - u_int16_t sc1394_node_id; /* my node id - * in network order */ - int (*sc1394_ifoutput)(struct device *, struct mbuf *, - void (*)(struct device *, struct mbuf *)); - /* Nuke. */ - int (*sc1394_ifinreg)(struct device *, u_int32_t, u_int32_t, - void (*)(struct device *, struct mbuf *)); - /* Nuke */ - int (*sc1394_ifsetiso)(struct device *, u_int32_t, u_int32_t, - u_int32_t, void (*)(struct device *, struct mbuf *)); - /* Nuke */ - - LIST_ENTRY(ieee1394_softc) sc1394_node; -} ieee1394_softc; - -typedef struct ieee1394_node { - struct device node_dev; - - struct ieee1394_softc *node_sc; /* owning bus */ - u_int32_t *node_configrom; - size_t node_configrom_len; -} ieee1394_node; - -int ieee1394_init(struct ieee1394_softc *); - -#define IEEE1394_ARGTYPE_PTR 0 -#define IEEE1394_ARGTYPE_MBUF 1 - -#endif /* _DEV_IEEE1394_IEEE1394VAR_H_ */ diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci index 69156be13be..96ca9c4f7ae 100644 --- a/sys/dev/pci/files.pci +++ b/sys/dev/pci/files.pci @@ -1,4 +1,4 @@ -# $OpenBSD: files.pci,v 1.171 2005/02/15 20:51:22 damien Exp $ +# $OpenBSD: files.pci,v 1.172 2005/03/05 23:58:44 tdeval Exp $ # $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $ # # Config file and device description for machine-independent PCI code. @@ -497,14 +497,6 @@ device viaenv attach viaenv at pci file dev/pci/viaenv.c viaenv -# OHCI IEEE 1394 controller -attach fwohci at pci with fwohci_pci -file dev/pci/fwohci_pci.c fwohci_pci - -# IEEE 1394 TI "Lynx" controller -attach fwlynx at pci with fwlynx_pci -file dev/pci/fwlynx_pci.c fwlynx_pci - # Broadcom BCM4401 gigabit ethernet device bce: ether, ifnet, mii, ifmedia, mii_phy attach bce at pci diff --git a/sys/dev/pci/fwlynx_pci.c b/sys/dev/pci/fwlynx_pci.c deleted file mode 100644 index af1b1e2c5a0..00000000000 --- a/sys/dev/pci/fwlynx_pci.c +++ /dev/null @@ -1,146 +0,0 @@ -/* $OpenBSD: fwlynx_pci.c,v 1.5 2004/10/01 04:08:46 jsg Exp $ */ - -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Matt Thomas of 3am Software Foundry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: fwlynx_pci.c,v 1.3 2001/11/15 09:48:12 lukem Exp $"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/socket.h> -#include <sys/device.h> - -#include <machine/bus.h> -#include <machine/intr.h> - -#include <dev/pci/pcireg.h> -#include <dev/pci/pcivar.h> -#include <dev/ieee1394/ieee1394reg.h> -#include <dev/ieee1394/ieee1394var.h> -#include <dev/ieee1394/fwlynxreg.h> -#include <dev/ieee1394/fwlynxvar.h> - -struct fwlynx_pci_softc { - struct fwlynx_softc psc_sc; - pci_chipset_tag_t psc_pc; - void *psc_ih; -}; - -static int fwlynx_pci_match(struct device *, struct cfdata *, void *); -static void fwlynx_pci_attach(struct device *, struct device *, void *); - -struct cfattach fwlynx_pci_ca = { - sizeof(struct fwlynx_pci_softc), fwlynx_pci_match, fwlynx_pci_attach, -#if 0 - fwlynx_pci_detach, fwlynx_activate -#endif -}; - -static int -fwlynx_pci_match(struct device *parent, struct cfdata *match, void *aux) -{ - struct pci_attach_args *pa = (struct pci_attach_args *) aux; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_TI && - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_TI_TSB12LV21) - return 1; - - return 0; -} - -static void -fwlynx_pci_attach(struct device *parent, struct device *self, void *aux) -{ - struct pci_attach_args *pa = (struct pci_attach_args *) aux; - struct fwlynx_pci_softc *psc = (struct fwlynx_pci_softc *) self; - char const *intrstr; - pci_intr_handle_t ih; - u_int32_t csr; - -#ifdef __NetBSD__ - char devinfo[256]; - pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof devinfo); - printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class)); -#endif - - psc->psc_sc.sc_dmat = pa->pa_dmat; - psc->psc_pc = pa->pa_pc; - psc->psc_tag = pa->pa_tag; - - /* Map I/O registers */ - if (pci_mapreg_map(pa, PCI_LYNX_MAP_REGISTER, PCI_MAPREG_TYPE_MEM, 0, - &psc->psc_sc.sc_memt, &psc->psc_sc.sc_memh, - NULL, &psc->psc_sc.sc_memsize)) { - printf(": can't map register space\n"); - return; - } - - /* Disable interrupts, so we don't get any spurious ones. */ - pci_conf_write(psc->psc_pc, psc->psc_tag, 0); - - /* Enable the device. */ - csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); - pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, - csr | PCI_COMMAND_MASTER_ENABLE); - - /* Map and establish the interrupt. */ - if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin, - pa->pa_intrline, &ih)) { - printf(": couldn't map interrupt\n"); - bus_space_unmap(psc->psc_sc.sc_memt, psc->psc_sc.sc_memh, - psc->psc_sc.sc_memsize); - return; - } - intrstr = pci_intr_string(pa->pa_pc, ih); - psc->psc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, fwlynx_intr, &psc->psc_sc); - if (psc->psc_ih == NULL) { - printf(": couldn't establish interrupt"); - if (intrstr != NULL) - printf(" at %s", intrstr); - printf("\n"); - bus_space_unmap(psc->psc_sc.sc_memt, psc->psc_sc.sc_memh, - psc->psc_sc.sc_memsize); - return; - } - printf(": %s\n", intrstr); - - if (fwlynx_init(&psc->psc_sc, pci_intr_evcnt(pa->pa_pc, ih)) != 0) { - pci_intr_disestablish(pa->pa_pc, psc->psc_ih); - bus_space_unmap(psc->psc_sc.sc_memt, psc->psc_sc.sc_memh, - psc->psc_sc.sc_memsize); - } -} diff --git a/sys/dev/pci/fwohci_pci.c b/sys/dev/pci/fwohci_pci.c deleted file mode 100644 index 7dc29c075a7..00000000000 --- a/sys/dev/pci/fwohci_pci.c +++ /dev/null @@ -1,176 +0,0 @@ -/* $OpenBSD: fwohci_pci.c,v 1.4 2003/01/09 15:28:53 mickey Exp $ */ -/* $NetBSD: fwohci_pci.c,v 1.13 2002/01/26 16:30:00 ichiro Exp $ */ - -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Matt Thomas of 3am Software Foundry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -#ifdef __KERNEL_RCSID -__KERNEL_RCSID(0, "$NetBSD: fwohci_pci.c,v 1.13 2002/01/26 16:30:00 ichiro Exp $"); -#endif - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/socket.h> -#include <sys/device.h> - -#include <machine/bus.h> -#include <machine/intr.h> - -#include <dev/pci/pcireg.h> -#include <dev/pci/pcivar.h> -#include <dev/ieee1394/ieee1394reg.h> -#include <dev/ieee1394/ieee1394var.h> -#include <dev/ieee1394/fwohcireg.h> -#include <dev/ieee1394/fwohcivar.h> - -struct fwohci_pci_softc { - struct fwohci_softc psc_sc; - pci_chipset_tag_t psc_pc; - void *psc_ih; -}; - -#ifdef __NetBSD__ -int fwohci_pci_match(struct device *, struct cfdata *, void *); -#else -int fwohci_pci_match(struct device *, void *, void *); -#endif -void fwohci_pci_attach(struct device *, struct device *, void *); - -struct cfattach fwohci_pci_ca = { - sizeof(struct fwohci_pci_softc), fwohci_pci_match, fwohci_pci_attach, -#if 0 - fwohci_pci_detach, fwohci_activate -#endif -}; - -#ifdef __NetBSD__ -int -fwohci_pci_match(struct device *parent, struct cfdata *match, void *aux) -#else -int -fwohci_pci_match(struct device *parent, void *match, void *aux) -#endif -{ - struct pci_attach_args *pa = (struct pci_attach_args *) aux; - - if (PCI_CLASS(pa->pa_class) == PCI_CLASS_SERIALBUS && - PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_SERIALBUS_FIREWIRE && - PCI_INTERFACE(pa->pa_class) == PCI_INTERFACE_OHCI) - return (1); - - return (0); -} - -void -fwohci_pci_attach(struct device *parent, struct device *self, void *aux) -{ - struct pci_attach_args *pa = (struct pci_attach_args *) aux; - struct fwohci_pci_softc *psc = (struct fwohci_pci_softc *) self; - char const *intrstr; - pci_intr_handle_t ih; - u_int32_t csr; - - psc->psc_sc.sc_dmat = pa->pa_dmat; - psc->psc_pc = pa->pa_pc; - - /* Map I/O registers */ -#ifdef __NetBSD__ - if (pci_mapreg_map(pa, PCI_OHCI_MAP_REGISTER, PCI_MAPREG_TYPE_MEM, 0, - &psc->psc_sc.sc_memt, &psc->psc_sc.sc_memh, - NULL, &psc->psc_sc.sc_memsize)) -#else - if (pci_mapreg_map(pa, PCI_OHCI_MAP_REGISTER, PCI_MAPREG_TYPE_MEM, 0, - &psc->psc_sc.sc_memt, &psc->psc_sc.sc_memh, - NULL, &psc->psc_sc.sc_memsize, 0)) -#endif - { - printf(": can't map OHCI register space\n"); - return; - } - - /* Disable interrupts, so we don't get any spurious ones. */ - OHCI_CSR_WRITE(&psc->psc_sc, OHCI_REG_IntMaskClear, - OHCI_Int_MasterEnable); - - /* Enable the device. */ - csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); - pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, - csr | PCI_COMMAND_MASTER_ENABLE); - -#if BYTE_ORDER == BIG_ENDIAN - csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_OHCI_CONTROL_REGISTER); - pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_OHCI_CONTROL_REGISTER, - csr | PCI_GLOBAL_SWAP_BE); -#endif - - /* Map and establish the interrupt. */ - if (pci_intr_map(pa, &ih)) { - printf(": couldn't map interrupt\n"); - bus_space_unmap(psc->psc_sc.sc_memt, psc->psc_sc.sc_memh, - psc->psc_sc.sc_memsize); - return; - } - intrstr = pci_intr_string(pa->pa_pc, ih); -#ifdef __NetBSD__ - psc->psc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, fwohci_intr, - &psc->psc_sc); -#else - psc->psc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, fwohci_intr, - &psc->psc_sc, self->dv_xname); -#endif - if (psc->psc_ih == NULL) { - printf(": couldn't establish interrupt"); - if (intrstr != NULL) - printf(" at %s", intrstr); - printf("\n"); - bus_space_unmap(psc->psc_sc.sc_memt, psc->psc_sc.sc_memh, - psc->psc_sc.sc_memsize); - return; - } - printf(": %s\n", intrstr); - -#ifdef __NetBSD__ - if (fwohci_init(&psc->psc_sc, pci_intr_evcnt(pa->pa_pc, ih)) != 0) -#else - if (fwohci_init(&psc->psc_sc, NULL) != 0) -#endif - { - pci_intr_disestablish(pa->pa_pc, psc->psc_ih); - bus_space_unmap(psc->psc_sc.sc_memt, psc->psc_sc.sc_memh, - psc->psc_sc.sc_memsize); - } -} diff --git a/sys/dev/std/SBP2.roadmap b/sys/dev/std/SBP2.roadmap deleted file mode 100644 index 55be1d19517..00000000000 --- a/sys/dev/std/SBP2.roadmap +++ /dev/null @@ -1,149 +0,0 @@ -- configuration rom - - p1212 takes care of this, though it might be useful to compile the info into - a direct usable form (a struct) - -- access control - - target login_descriptors : context of a login - - lun - - login_owner_id - - login_owner_EUI_64 - - status_fifo_addr - - exclusive_flag - - fetch_agent_csr - - login_id - - reconnect_hold - - login procedure - - 8-byte (login_request_addr) block-write transaction to the - management_agent_csr - - target reads the initiator's EUI64 with 2 quadlet-read transactions - - target reads the login_request_orb at login_request_addr - - if initiator's EUI64 exists in login_owner_EUI_64 : access denied - - if initiator wants exclusive and lun already used : access denied - - if exclusive_flag set on lun's login_descriptor : access denied - - if no login_descriptor is available : resources unavailable - - if it's ok, target return a valid login_response - - reconnection procedure - - 8-byte (reconnect_request_addr) block-write transaction to the - management_agent_csr - - target reads the initiator's EUI64 with 2 quadlet-read transactions - - target reads the reconnect_request_orb at reconnect_request_addr - - a completion status is sent back to the initiator - - logout procedure - - 8-byte (logout_request_addr) block-write transaction to the - management_agent_csr - - a completion status is sent back to the initiator -- command execution - - requests and request-lists - - fetch agent initialization - - initiator allocates a dummy_orb, with a null pointer as next_orb, - of at least the minimum orb size - - initiator resets target fetch agent with a quadlet-write to - AGENT_RESET register - - initiator writes dummy_orb_addr with 8-byte block-write to - ORB_POINTER register - - fetch agent transition to ACTIVE state - - fetch agent reads the terminating dummy_orb and transition to - SUSPENDED state - - dynamic appends to request lists - - initiator constructs a linked-list of orbs in system memory, the - last orb's next_orb is null - - initiator updates the current last orb's next_orb to the first orb - of the linked-list - - initiator transmits a quadlet-write to the target's DOORBELL register - if the target is already in SUSPENDED state, the initiator may write - the first orb to ORB_POINTER register, and no DOORBELL is necessary - - data transfer - - completion status - - unsolicited status -- task management - - task sets - - basic task management model - - all tasks in a task set share the same execution characteristics : - reorderable/ordered - - reorderable/ordered feature is target dependent, see config_rom - - each task is identified by its orb's serial bus address - - all targets must at least implement the abort task, abort task set and - target reset management functions - - error conditions : entire task set is cleared on error condition - - fetch agent transitions to dead state - - target waits for sent status completion of all the completed tasks - - then target sends status completion for the faulty task, with dead bit - - task management requests - - abort task - - modify the rq_fmt to 3 in the task to be aborted's orb - - setup an ABORT_TASK management orb with the task orb's serial bus addr - - if target fetch an aborted task, sends REQUEST_COMPLETE on dummy_orb - - initiator may not reuse the memory of the task to abort until - completion has been received - - abort task set - - initiator sends an ABORT_TASK_SET management orb with login_id to target - - fetch agent transitions to dead state - - target waits for sent status completion of all the completed tasks - - then target sends status completion into the supplied status buffer - - initiator may not reuse the memory of any task in the task set until - a completion status is received for the abort task set management task - - logical unit reset (optional) - - initiator sends a LOGICAL_UNIT_RESET management orb with login_id to - target - - fetch agent transitions to dead state for all the lun's fetch agents - - target creates a logical unit attention condition to all the initiators - logged in to that lun (except the one initiating the reset) - - then target sends status completion into the supplied status buffer - - initiator may not reuse the memory of any task in the task set until - a completion status is received for the logical unit reset management - task - - target reset - - initiator sends a TARGET_RESET management orb with login_id to target - - fetch agent transitions to dead state for all the fetch agents - - target creates a logical unit attention condition to all the initiators - except the one initiating the reset - - then target sends status completion into the supplied status buffer - - initiator may not reuse the memory of any task in the task set until - a completion status is received for the target reset management task - -- data structures - - ORB : rq_fmt_dep:128|notify:1|rq_fmt:2|rq_fmt_dep:29|rq_fmt_dep:nq - rq_fmt = 0|std, 1|rsvd, 2|vend, 3|nop - - Dummy ORB : next_ORB:64|ignore:64|notify:1|3:2|ignore:29|ignore:nq - - Command ORB : next_ORB:64|data_descr:64|notify:1|0:2|rsvd:1|direction:1| - speed:3|max_payload:4|page_table_present:1|page_size:3| - data_size:16|command_block:nq - speed = 0|S100, 1|S200, 2|S400, 3|S800, 4|S1600, 5|S3200 - max payload = 2 ^ (max_payload + 2) - page size = 2 ^ (page_size + 8), if page_size != 0 - (page_table_present):(page_size == 0)?unrestricted:normalized - (page_table_present):data_size = # of table elements - ?data_size = data_descriptor size - - Management ORB : func_dep:128|notify:1|0:2|rsvd:9|function:4|func_dep:16| - func_dep:32|status_fifo:64 - function = 0|LOGIN, 1|QUERY_LOGINS, 3|RECONNECT, 4|SET_PASSWORD, - 7|LOGOUT, B|ABORT_TASK, C|ABORT_TASK_SET, - E|LOGICAL_UNIT_RESET, F|TARGET_RESET - - Access ORB - - LOGIN ORB : password:64|login_response:64|notify:1|0:2|exclusive:1| - rsvd:4|reconnect:4|0:4|lun:16|password_length:16| - login_response_length:16|status_fifo:64 - login_response_length >= 12 - reconnect timeout = 2 ^ reconnect - - login response : length:16|login_ID:16|command_block_agent:64| - rsvd:16|reconnect_hold:16 - reconnect_hold <= 2 ^ reconnect - 1 - - QUERY_LOGINS ORB : rsvd:64|query_response:64|n0..1:16|lun:16|rsvd:16| - query_response_length:16|status_fifo:64 - - query response : length:16|max_logins:16| - (node_ID:16|login_ID:16|initiator_EUI_64:64)*n - - RECONNECT ORB : rsvd:128|n0..3:16|login_ID:16|rsvd:32|status_fifo:64 - - LOGOUT ORB : rsvd:128|n0..7:16|login_ID:16|rsvd:32|status_fifo:64 - - Task Management ORB : ORB_offset:064|rsvd:64|n0..fn:16|login_ID:16| - rsvd:32|status_fifo:64 - fn = B|ABORT_TASK, C|ABORT_TASK_SET, - E|LOGICAL_UNIT_RESET, F|TARGET_RESET - if ABORT_TASK, ORB_offset is relevant - - page tables - - unrestricted page table : segment_length:16|segment_base:48 - - normalized page table : segment_length:16|segment_base..segment_offset:48 - - status block : src:2|resp:2|dead:1|len:3|sbp_status:8|ORB_offset:48|cmd_dep - - address pointer : node_ID:16|offset:46|rsvd:2 - - ORB pointer : null:1|rsvd:15|offset:46|rsvd:2 -- CSR - diff --git a/sys/dev/std/ieee1212.c b/sys/dev/std/ieee1212.c deleted file mode 100644 index 04f69ecc3c3..00000000000 --- a/sys/dev/std/ieee1212.c +++ /dev/null @@ -1,1593 +0,0 @@ -/* $OpenBSD: ieee1212.c,v 1.6 2003/01/12 12:06:28 tdeval Exp $ */ -/* $NetBSD: ieee1212.c,v 1.3 2002/05/23 00:10:46 jmc Exp $ */ - -/* - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by James Chacon. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/device.h> -#include <sys/kernel.h> -#include <sys/malloc.h> - -#include <dev/std/ieee1212reg.h> -#include <dev/std/ieee1212var.h> -#include <dev/std/sbp2reg.h> -#include <dev/std/sbp2var.h> - -static const char * const p1212_keytype_strings[] = P1212_KEYTYPE_STRINGS; -static const char * const p1212_keyvalue_strings[] = P1212_KEYVALUE_STRINGS; - -u_int16_t p1212_calc_crc(u_int16_t, u_int32_t *, int, int); -int p1212_parse_directory(struct p1212_dir *, u_int32_t *, u_int32_t); -struct p1212_leafdata *p1212_parse_leaf(u_int32_t *); -int p1212_parse_textdir(struct p1212_com *, u_int32_t *); -struct p1212_textdata *p1212_parse_text_desc(u_int32_t *); -void p1212_print_node(struct p1212_key *, void *); -int p1212_validate_offset(u_int16_t, u_int32_t); -int p1212_validate_immed(u_int16_t, u_int32_t); -int p1212_validate_leaf(u_int16_t, u_int32_t); -int p1212_validate_dir(u_int16_t, u_int32_t); - -#ifdef P1212_DEBUG -#include <sys/syslog.h> -extern int log_open; -int p1212_oldlog; -#define DPRINTF(x) if (p1212debug) do { \ - p1212_oldlog = log_open; log_open = 1; \ - addlog x; log_open = p1212_oldlog; \ -} while (0) -#define DPRINTFN(n,x) if (p1212debug>(n)) do { \ - p1212_oldlog = log_open; log_open = 1; \ - addlog x; log_open = p1212_oldlog; \ -} while (0) -#ifdef FW_MALLOC_DEBUG -#define MPRINTF(x,y) DPRINTF(("%s[%d]: %s 0x%08x\n", \ - __func__, __LINE__, (x), (u_int32_t)(y))) -#else /* !FW_MALLOC_DEBUG */ -#define MPRINTF(x,y) -#endif /* FW_MALLOC_DEBUG */ - -int p1212debug = 0; -#else /* P1212_DEBUG */ -#define DPRINTF(x) -#define DPRINTFN(n,x) -#define MPRINTF(x,y) -#endif /* ! P1212_DEBUG */ - -/* - * Routines to parse the ROM into a tree that's usable. Also verify integrity - * vs. the P1212 standard - */ - -/* - * A buffer of u_int32_t's and a size in quads gets passed in. The output will - * return -1 on error, or 0 on success and possibly reset *size to a larger - * value. - * - * NOTE: Rom's are guarentee'd per the ISO spec to be contiguous but only the - * first 1k is directly mapped. Anything past 1k is supposed to use a loop - * around the indirect registers to read in the rom. This code only assumes the - * buffer passed in represents a total rom regardless of end size. It is the - * callers responsibility to treat a size > 1024 as a special case. - */ - -int -p1212_iscomplete(u_int32_t *t, u_int32_t *size) -{ - u_int16_t infolen, crclen, len; - u_int32_t newlen, offset, test; - int complete, i, numdirs, type, val, *dirs; -#ifdef __OpenBSD__ - int *p; -#endif /* __OpenBSD__ */ - - dirs = NULL; - - if (*size == 0) { - DPRINTF(("Invalid size for ROM: %d\n", (unsigned int)*size)); - return -1; - } - - infolen = P1212_ROMFMT_GET_INFOLEN((ntohl(t[0]))); - if (infolen <= 1) { - DPRINTF(("ROM not initialized or minimal ROM: Info " - "length: %d\n", infolen)); - return -1; - } - crclen = P1212_ROMFMT_GET_CRCLEN((ntohl(t[0]))); - if (crclen < infolen) { - DPRINTF(("CRC len less than info len. CRC len: %d, " - "Info len: %d\n", crclen, infolen)); - return -1; - } - - /* - * Now loop through it to check if all the offsets referenced are - * within the image stored so far. If not, get those as well. - */ - - offset = infolen + 1; - - /* - * Make sure at least the bus info block is in memory + the root dir - * header quad. Add 1 here since offset is an array offset and size is - * the total array size we want. If this is getting the root dir - * then add another since infolen doesn't end on the root dir entry but - * right before it. - */ - - if ((*size == 1) || (*size < (offset + 1))) { - *size = (crclen > infolen) ? crclen : infolen; - if (crclen == infolen) - (*size)++; - (*size)++; - return 0; - } - - complete = 0; - numdirs = 0; - newlen = 0; - - while (!complete) { - - /* - * Make sure the whole directory is in memory. If not, bail now - * and read it in. - */ - - newlen = P1212_DIRENT_GET_LEN((ntohl(t[offset]))); - if ((offset + newlen + 1) > *size) { - newlen += offset + 1; - break; - } - - if (newlen == 0) { - DPRINTF(("Impossible directory length of 0!\n")); - return -1; - } - - /* - * Starting with the first byte of the directory, read through - * and check the values found. On offsets and directories read - * them in if appropriate (always for offsets, if not in memory - * for leaf/directories). - */ - - offset++; - len = newlen; - newlen = 0; - for (i = 0; i < len; i++) { - type = P1212_DIRENT_GET_KEYTYPE((ntohl(t[offset+i]))); - val = P1212_DIRENT_GET_VALUE((ntohl(t[offset+i]))); - switch (type) { - case P1212_KEYTYPE_Immediate: - case P1212_KEYTYPE_Offset: - break; - case P1212_KEYTYPE_Leaf: - - /* - * If a leaf is found, and it's beyond the - * current rom length and it's beyond the - * current newlen setting, - * then set newlen accordingly. - */ - - test = offset + i + val + 1; - if ((test > *size) && (test > newlen)) { - newlen = test; - break; - } - - /* - * For leaf nodes just make sure the whole leaf - * length is in the buffer. There's no data - * inside of them that can refer to outside - * nodes. (Uless it's vendor specific and then - * you're on your own anyways). - */ - - test--; - infolen = - P1212_DIRENT_GET_LEN((ntohl(t[test]))); - test++; - test += infolen; - if ((test > *size) && (test > newlen)) { - newlen = test; - } - break; - - case P1212_KEYTYPE_Directory: - - /* Make sure the first quad is in memory. */ - - test = offset + i + val + 1; - if ((test > *size) && (test > newlen)) { - newlen = test; - break; - } - - /* - * Can't just walk the ROM looking at type - * codes since these are only valid on - * directory entries. So save any directories - * we find into a queue and the bottom of the - * while loop will pop the last one off and - * walk that directory. - */ - - test--; -#ifdef __NetBSD__ - dirs = realloc(dirs, - sizeof(int) * (numdirs + 1), M_DEVBUF, - M_WAITOK); -#else /* __NetBSD__ */ - p = malloc(sizeof(int) * (numdirs + 1), - M_DEVBUF, M_WAITOK); - MPRINTF("malloc(DEVBUF)", p); - if (dirs != NULL) { - bcopy(dirs, p, sizeof(int) * numdirs); - free(dirs, M_DEVBUF); - MPRINTF("free(DEVBUF)", dirs); - dirs = NULL; /* XXX */ - } - dirs = p; -#endif /* ! __NetBSD__ */ - dirs[numdirs++] = test; - break; - default: - panic("Impossible type code: 0x%04hx", - (unsigned short)type); - break; - } - } - - if (newlen) { - /* Cleanup. */ - if (dirs) { - free(dirs, M_DEVBUF); - MPRINTF("free(DEVBUF)", dirs); - dirs = NULL; /* XXX */ - } - break; - } - if (dirs != NULL) { - offset = dirs[--numdirs]; - if (numdirs) { -#ifdef __NetBSD__ - dirs = realloc(dirs, sizeof(int) * numdirs, - M_DEVBUF, M_WAITOK); -#else /* __NetBSD__ */ - p = malloc(sizeof(int) * numdirs, - M_DEVBUF, M_WAITOK); - MPRINTF("malloc(DEVBUF)", p); - bcopy(dirs, p, sizeof(int) * numdirs); - free(dirs, M_DEVBUF); - MPRINTF("free(DEVBUF)", dirs); - dirs = p; -#endif /* ! __NetBSD__ */ - } else { - free(dirs, M_DEVBUF); - MPRINTF("free(DEVBUF)", dirs); - dirs = NULL; - } - } else - complete = 1; - } - - if (newlen) - *size = newlen; - return 0; - -} - -struct p1212_rom * -p1212_parse(u_int32_t *t, u_int32_t size, u_int32_t mask) -{ - - u_int16_t crc, romcrc, crc1, crc2; - u_int32_t next, check; - struct p1212_rom *rom; - int i, crclen; - - check = size; - - if (p1212_iscomplete(t, &check) == -1) { - DPRINTF(("ROM is not complete\n")); - return NULL; - } - if (check != size) { - DPRINTF(("ROM is not complete (check != size)\n")); - return NULL; - } - - /* Calculate both a good and known bad crc. */ - - /* CRC's are calculated from everything except the first quad. */ - - crclen = P1212_ROMFMT_GET_CRCLEN((ntohl(t[0]))); - romcrc = P1212_ROMFMT_GET_CRC((ntohl(t[0]))); - - crc = p1212_calc_crc(0, &t[1], crclen, 0); - - if (crc != romcrc) { - crc1 = p1212_calc_crc(0, &t[1], crclen, 1); - crc2 = p1212_calc_crc(0, &t[1], crclen, 2); - if ((crc1 != romcrc) && (crc2 != romcrc)) { - DPRINTF(("Invalid ROM: CRC: 0x%04hx, Calculated " - "CRC: 0x%04hx, CRC1: 0x%04hx, CRC2: 0x%04hx\n", - (unsigned short)romcrc, (unsigned short)crc, - (unsigned short)crc1, (unsigned short)crc2)); -#if 0 /* Continue anyway. We'll choke later if any entry is invalid. */ - return NULL; -#endif - } - } - if (romcrc == crc2) - DPRINTF(("%s: warning byte-swapping rom problems\n", __func__)); - - /* Now, walk the ROM. */ - - /* Get the initial offset for the root dir. */ - - MALLOC(rom, struct p1212_rom *, sizeof(*rom), M_DEVBUF, M_WAITOK); - MPRINTF("MALLOC(DEVBUF)", rom); - rom->len = P1212_ROMFMT_GET_INFOLEN((ntohl(t[0]))); - next = rom->len + 1; - - if ((rom->len < 1) || (rom->len > size)) { - DPRINTF(("Invalid ROM info length: %d\n", rom->len)); - FREE(rom, M_DEVBUF); - MPRINTF("FREE(DEVBUF)", rom); - rom = NULL; /* XXX */ - return NULL; - } - - /* Exclude the quad which covers the bus name. */ - rom->len--; - - if (rom->len) { - rom->data = malloc(sizeof(u_int32_t) * rom->len, M_DEVBUF, - M_WAITOK); - MPRINTF("malloc(DEVBUF)", rom->data); - /* Add 2 to account for info/crc and bus name skipped. */ - for (i = 0; i < rom->len; i++) - rom->data[i] = t[i + 2]; - } - - /* The name field is always 4 bytes and always the 2nd field. */ - strncpy(rom->name, (char *)&t[1], 4); - rom->name[4] = 0; - - /* - * Fill out the root directory. All these values are hardcoded so the - * parse/print/match routines have a standard layout to work against. - */ - -#ifdef M_ZERO - MALLOC(rom->root, struct p1212_dir *, sizeof(*rom->root), - M_DEVBUF, M_WAITOK|M_ZERO); - MPRINTF("MALLOC(DEVBUF)", rom->root); -#else /* M_ZERO */ - MALLOC(rom->root, struct p1212_dir *, sizeof(*rom->root), - M_DEVBUF, M_WAITOK); - MPRINTF("MALLOC(DEVBUF)", rom->root); - bzero(rom->root, sizeof(*rom->root)); -#endif /* ! M_ZERO */ - rom->root->com.key.key_type = P1212_KEYTYPE_Directory; - rom->root->com.key.key_value = 0; - rom->root->com.key.key = (u_int8_t)P1212_KEYTYPE_Directory; - rom->root->com.key.val = 0; - TAILQ_INIT(&rom->root->data_root); - TAILQ_INIT(&rom->root->subdir_root); - - if (p1212_parse_directory(rom->root, &t[next], mask)) { - DPRINTF(("Parse error in ROM. Bailing\n")); - p1212_free(rom); - return NULL; - } - return rom; -} - -int -p1212_parse_directory(struct p1212_dir *root, u_int32_t *addr, u_int32_t mask) -{ - struct p1212_dir *dir, *sdir; - struct p1212_data *data; - struct p1212_com *com; - u_int32_t *t, desc; - u_int16_t crclen, crc, crc1, crc2, romcrc; - u_int8_t type, val; - unsigned long size; - int i, module_vendor_flag, module_sw_flag, node_sw_flag, unit_sw_flag; - int node_capabilities_flag, offset, unit_location_flag, unitdir_cnt; - int leafoff; - int textcnt; - int draft; -#ifdef __OpenBSD__ - struct p1212_textdata **p; -#endif /* __OpenBSD__ */ - - t = addr; - dir = root; - - module_vendor_flag = 0; - module_sw_flag = 0; - node_sw_flag = 0; - node_capabilities_flag = 0; - unitdir_cnt = 0; - offset = 0; - textcnt = 0; - draft = 0; - - while (dir) { - dir->match = 0; - crclen = P1212_DIRENT_GET_LEN((ntohl(t[offset]))); - romcrc = P1212_DIRENT_GET_CRC((ntohl(t[offset]))); - - crc = p1212_calc_crc(0, &t[offset + 1], crclen, 0); - if (crc != romcrc) { - crc1 = p1212_calc_crc(0, &t[offset + 1], crclen, 1); - crc2 = p1212_calc_crc(0, &t[offset + 1], crclen, 2); - if ((crc1 != romcrc) && (crc2 != romcrc)) { - DPRINTF(("Invalid ROM: CRC: 0x%04hx, " - "Calculated CRC: " - "0x%04hx, CRC1: 0x%04hx", - ", CRC2: 0x%04hx\n", - (unsigned short)romcrc, - (unsigned short)crc, - (unsigned short)crc1, - (unsigned short)crc2)); - return 1; - } - } - if (romcrc == crc2) { - draft = 1; - DPRINTF(("%s: warning byte-swapping rom problems" - " (off: 0x%04hx)\n", __func__, (u_int16_t)offset)); - } - com = NULL; - unit_sw_flag = 0; - unit_location_flag = 0; - offset++; - - if ((dir->parent == NULL) && dir->com.key.val) { - DPRINTF(("Invalid root dir. key.val is 0x%0x and not" - " 0x0\n", dir->com.key.val)); - return 1; - } - - for (i = offset; i < (offset + crclen); i++) { - desc = ntohl(t[i]); - type = P1212_DIRENT_GET_KEYTYPE(desc); - val = P1212_DIRENT_GET_KEYVALUE(desc); - - /* - * Sanity check for valid types/locations/etc. - * - * See pages 79-100 of - * ISO/IEC 13213:1194(ANSI/IEEE Std 1212, 1994 edition) - * for specifics. - * - * XXX: These all really should be broken out into - * subroutines as it's grown large and complicated - * in certain cases. - */ - - switch (val) { - case P1212_KEYVALUE_Unit_Spec_Id: - case P1212_KEYVALUE_Unit_Sw_Version: - case P1212_KEYVALUE_Unit_Dependent_Info: - case P1212_KEYVALUE_Unit_Location: - case P1212_KEYVALUE_Unit_Poll_Mask: - if (dir->parent == NULL) { - DPRINTF(("Invalid ROM: %s is not " - "valid in the root directory.\n", - p1212_keyvalue_strings[val])); - return 1; - } - break; - default: - if (dir->com.key.val == - P1212_KEYVALUE_Unit_Directory) { - DPRINTF(("Invalid ROM: %s is " - "not valid in a unit directory.\n", - p1212_keyvalue_strings[val])); - return 1; - } - break; - } - - switch (type) { - case P1212_KEYTYPE_Immediate: - if (p1212_validate_immed(val, mask)) { - DPRINTF(("Invalid ROM: Can't have an " - "immediate type with %s value. Key" - " used at location 0x%0x in ROM\n", - p1212_keyvalue_strings[val], - (unsigned int)(&t[i]-&addr[0]))); - return 1; - } - break; - case P1212_KEYTYPE_Offset: - if (draft && val == 0) - break; - if (p1212_validate_offset(val, mask)) { - DPRINTF(("Invalid ROM: Can't have " - "an offset type with key %s." - " Used at location 0x%0x in ROM\n", - p1212_keyvalue_strings[val], - (unsigned int)(&t[i]-&addr[0]))); - return 1; - } - break; - case P1212_KEYTYPE_Leaf: - if (p1212_validate_leaf(val, mask)) { - DPRINTF(("Invalid ROM: Can't have a " - "leaf type with %s value. Key " - "used at location 0x%0x in ROM\n", - p1212_keyvalue_strings[val], - (unsigned int)(&t[i]-&addr[0]))); - return 1; - } - break; - case P1212_KEYTYPE_Directory: - if (p1212_validate_dir(val, mask)) { - DPRINTF(("Invalid ROM: Can't have a " - "directory type with %s value. Key" - " used at location 0x%0x in ROM\n", - p1212_keyvalue_strings[val], - (unsigned int)(&t[i]-&addr[0]))); - return 1; - } - break; - default: - panic("Impossible type code: 0x%04hx", - (unsigned short)type); - break; - } - - /* Note flags for required fields. */ - - if (val == P1212_KEYVALUE_Module_Vendor_Id) { - module_vendor_flag = 1; - } - - if (val == P1212_KEYVALUE_Node_Capabilities) { - node_capabilities_flag = 1; - } - - if (val == P1212_KEYVALUE_Unit_Sw_Version) - unit_sw_flag = 1; - - if (val == P1212_KEYVALUE_Unit_Location) - unit_location_flag = 1; - - /* - * This is just easier to spell out. You can't have - * a module sw version if you include a node sw version - * and vice-versa. Both aren't allowed if you have unit - * dirs. - */ - - if (val == P1212_KEYVALUE_Module_Sw_Version) { - if (node_sw_flag) { - DPRINTF(("Can't have a module software" - " version along with a node " - "software version entry\n")); - return 1; - } - if (!draft && unitdir_cnt) { - DPRINTF(("Can't have unit directories " - "with module software version " - "defined.\n")); - return 1; - } - module_sw_flag = 1; - } - - if (val == P1212_KEYVALUE_Node_Sw_Version) { - if (module_sw_flag) { - DPRINTF(("Can't have a node software " - "version along with a module " - "software version entry\n")); - return 1; - } - if (!draft && unitdir_cnt) { - DPRINTF(("Can't have unit directories " - "with node software version " - "defined.\n")); - return 1; - } - node_sw_flag = 1; - } - - if (val == P1212_KEYVALUE_Unit_Directory) { - if (!draft && - (module_sw_flag || node_sw_flag)) { - DPRINTF(("Can't have unit directories " - "with either module or node " - "software version defined.\n")); - return 1; - } - unitdir_cnt++; - } - - /* - * Text descriptors are special. They describe the - * last entry they follow. So they need to be included - * with it's struct and there's nothing in the spec - * preventing one from putting text descriptors after - * directory descriptors. Also they can be a single - * value or a list of them in a directory format so - * account for either. Finally if they're in a - * directory those can be the only types in a - * directory. - */ - - if (val == P1212_KEYVALUE_Textual_Descriptor) { - - size = sizeof(*p); - leafoff = P1212_DIRENT_GET_VALUE(desc); - leafoff += i; - - if (com == NULL) { - DPRINTF(("Can't have a text descriptor" - " as the first entry in a " - "directory\n")); - return 1; - } - - if (textcnt++ != 0) { - DPRINTF(("Text descriptors can't " - "follow each other in a " - "directory\n")); - return 1; - } - - if (type == P1212_KEYTYPE_Leaf) { -#ifdef __NetBSD__ - com->text = realloc(com->text, - size * (com->textcnt + 1), - M_DEVBUF, M_WAITOK); -#else /* __NetBSD__ */ - p = malloc(size * (com->textcnt + 1), - M_DEVBUF, M_WAITOK); - MPRINTF("malloc(DEVBUF)", p); - if (com->text != NULL) { - bcopy(com->text, p, - size * com->textcnt); - free(com->text, M_DEVBUF); - MPRINTF("free(DEVBUF)", com->text); - com->text = NULL; /* XXX */ - } - com->text = p; -#endif /* ! __NetBSD__ */ - com->text[com->textcnt] = - p1212_parse_text_desc(&t[leafoff]); - if (com->text[com->textcnt] == NULL) { - DPRINTF(("Got an error parsing" - " text descriptor at " - "offset 0x%0x\n", - &t[leafoff]-&addr[0])); - free(com->text, M_DEVBUF); - MPRINTF("free(DEVBUF)", com->text); - com->text = NULL; /* XXX */ - return 1; - } - com->textcnt++; - } else { - i = p1212_parse_textdir(com, - &t[leafoff]); - if (i) - return 1; - textcnt = 0; - } - } else - textcnt = 0; - - if ((type != P1212_KEYTYPE_Directory) && - (val != P1212_KEYVALUE_Textual_Descriptor)) { -#ifdef M_ZERO - MALLOC(data, struct p1212_data *, sizeof(*data), - M_DEVBUF, M_WAITOK|M_ZERO); - MPRINTF("MALLOC(DEVBUF)", data); -#else /* M_ZERO */ - MALLOC(data, struct p1212_data *, sizeof(*data), - M_DEVBUF, M_WAITOK); - MPRINTF("MALLOC(DEVBUF)", data); - bzero(data, sizeof(struct p1212_data)); -#endif /* ! M_ZERO */ - data->com.key.key_type = type; - data->com.key.key_value = val; - data->com.key.key = - P1212_DIRENT_GET_KEY((ntohl(t[i]))); - data->com.key.val = - P1212_DIRENT_GET_VALUE((ntohl(t[i]))); - com = &data->com; - - /* - * Don't try and read the offset. It may be - * a register or something special. Generally - * these are node specific so let the upper - * level code figure it out. - */ - - if ((type == P1212_KEYTYPE_Immediate) || - (type == P1212_KEYTYPE_Offset)) - data->val = data->com.key.val; - - data->leafdata = NULL; - TAILQ_INSERT_TAIL(&dir->data_root, data, data); - - if (type == P1212_KEYTYPE_Leaf) { - leafoff = i + data->com.key.val; - data->leafdata = - p1212_parse_leaf(&t[leafoff]); - if (data->leafdata == NULL) { - DPRINTF(("Error parsing leaf\n")); - return 1; - } - } - } - if (type == P1212_KEYTYPE_Directory) { - -#ifdef M_ZERO - MALLOC(sdir, struct p1212_dir *, sizeof(*sdir), - M_DEVBUF, M_WAITOK|M_ZERO); - MPRINTF("MALLOC(DEVBUF)", sdir); -#else /* M_ZERO */ - MALLOC(sdir, struct p1212_dir *, sizeof(*sdir), - M_DEVBUF, M_WAITOK); - MPRINTF("MALLOC(DEVBUF)", sdir); - bzero(sdir, sizeof(struct p1212_dir)); -#endif /* ! M_ZERO */ - sdir->parent = dir; - sdir->com.key.key_type = type; - sdir->com.key.key_value = val; - sdir->com.key.key = - P1212_DIRENT_GET_KEY((ntohl(t[i]))); - sdir->com.key.val = - P1212_DIRENT_GET_VALUE((ntohl(t[i]))); - com = &sdir->com; - sdir->match = sdir->com.key.val + i; - TAILQ_INIT(&sdir->data_root); - TAILQ_INIT(&sdir->subdir_root); - TAILQ_INSERT_TAIL(&dir->subdir_root, sdir,dir); - } - } - - /* More validity checks. */ - - if (dir->parent == NULL) { - if (module_vendor_flag == 0) { - DPRINTF(("Missing module vendor entry in root " - "directory.\n")); - return 1; - } -#if 0 /* XXX : Not Mandatory */ - if (node_capabilities_flag == 0) { - DPRINTF(("Missing node capabilities entry in " - "root directory.\n")); - return 1; - } -#endif - } else { - if ((unitdir_cnt > 1) && (unit_location_flag == 0)) { - DPRINTF(("Must have a unit location in each " - "unit directory when more than one unit " - "directory exists.\n")); - return 1; - } - } - - /* - * Ok, done with this directory and it's sanity checked. Now - * loop through and either find an unparsed subdir or one - * farther back up the chain. - */ - - if (!TAILQ_EMPTY(&dir->subdir_root)) { - sdir = TAILQ_FIRST(&dir->subdir_root); - } else { - do { - sdir = TAILQ_NEXT(dir, dir); - if (sdir == NULL) { - dir = dir->parent; - } - } while ((sdir == NULL) && (dir != NULL)); - } - if (dir) { - dir = sdir; - if (!dir->match) { - DPRINTF(("Invalid subdir..Has no offset\n")); - return 1; - } - offset = dir->match; - } - } - return 0; -} - -struct p1212_leafdata * -p1212_parse_leaf(u_int32_t *t) -{ - u_int16_t crclen, crc, crc1, crc2, romcrc; - struct p1212_leafdata *leafdata; - int i; - - crclen = P1212_DIRENT_GET_LEN((ntohl(t[0]))); - romcrc = P1212_DIRENT_GET_CRC((ntohl(t[0]))); - crc = p1212_calc_crc(0, &t[1], crclen, 0); - crc1 = p1212_calc_crc(0,&t[1], crclen, 1); - crc2 = p1212_calc_crc(0,&t[1], crclen, 2); - if ((crc != romcrc) && (crc1 != romcrc) && (crc2 != romcrc)) { - DPRINTF(("Invalid ROM: CRC: 0x%04hx, Calculated CRC: " - "0x%04hx, CRC1: 0x%04hx, CRC2: 0x%04hx\n", - (unsigned short)romcrc, (unsigned short)crc, - (unsigned short)crc1, (unsigned short)crc2)); - return NULL; - } - if (romcrc == crc2) - DPRINTF(("%s: warning byte-swapping rom problems\n", __func__)); - t++; - - /* - * Most of these are vendor specific so don't bother trying to map them - * out. Anything which needs them later on can extract them. - */ - - MALLOC(leafdata, struct p1212_leafdata *, sizeof(*leafdata), - M_DEVBUF, M_WAITOK); - MPRINTF("MALLOC(DEVBUF)", leafdata); - leafdata->data = malloc((sizeof(u_int32_t) * crclen), M_DEVBUF, - M_WAITOK); - MPRINTF("malloc(DEVBUF)", leafdata->data); - leafdata->len = crclen; - for (i = 0; i < crclen; i++) - leafdata->data[i] = ntohl(t[i]); - return leafdata; -} - -int -p1212_parse_textdir(struct p1212_com *com, u_int32_t *addr) -{ - u_int32_t *t, entry, new; - u_int16_t crclen, crc, crc1, crc2, romcrc; - u_int8_t type, val; -#ifdef __OpenBSD__ - struct p1212_textdata **p; -#endif /* __OpenBSD__ */ - - int i, size; - - /* - * A bit more complicated. A directory for a text descriptor can - * contain text descriptor leaf nodes only. - */ - - com->text = NULL; - size = sizeof(*p); - - crclen = P1212_DIRENT_GET_LEN((ntohl(t[0]))); - romcrc = P1212_DIRENT_GET_CRC((ntohl(t[0]))); - crc = p1212_calc_crc(0, &t[1], crclen, 0); - crc1 = p1212_calc_crc(0,&t[1], crclen, 1); - crc2 = p1212_calc_crc(0,&t[1], crclen, 2); - if ((crc != romcrc) && (crc1 != romcrc) && (crc2 != romcrc)) { - DPRINTF(("Invalid ROM: CRC: 0x%04hx, Calculated CRC: " - "0x%04hx, CRC1: 0x%04hx, CRC2: 0x%04hx\n", - (unsigned short)romcrc, (unsigned short)crc, - (unsigned short)crc1, (unsigned short)crc2)); - return 1; - } - if (romcrc == crc2) - DPRINTF(("%s: warning byte-swapping rom problems\n", __func__)); - t++; - for (i = 0; i < crclen; i++) { - entry = ntohl(t[i]); - - type = P1212_DIRENT_GET_KEYTYPE(entry); - val = P1212_DIRENT_GET_KEYVALUE(entry); - if ((type != P1212_KEYTYPE_Leaf) || - (val != P1212_KEYVALUE_Textual_Descriptor)) { - DPRINTF(("Text descriptor directories can only " - "contain text descriptors. Type: %s, value: %s " - "isn't valid at offset 0x%0x\n", - p1212_keytype_strings[type], - p1212_keyvalue_strings[val], &t[i]-&addr[0])); - return 1; - } - - new = P1212_DIRENT_GET_VALUE(entry); -#ifdef __NetBSD__ - com->text = realloc(com->text, size * (com->textcnt + 1), - M_DEVBUF, M_WAITOK); -#else /* __NetBSD__ */ - p = malloc(size * (com->textcnt + 1), M_DEVBUF, M_WAITOK); - MPRINTF("malloc(DEVBUF)", p); - bzero(&p[com->textcnt], size); - if (com->text != NULL) { - bcopy(com->text, p, size * (com->textcnt)); - free(com->text, M_DEVBUF); - MPRINTF("free(DEVBUF)", com->text); - com->text = NULL; /* XXX */ - } - com->text = p; -#endif /* ! __NetBSD__ */ - if ((com->text[i] = p1212_parse_text_desc(&t[i+new])) == NULL) { - DPRINTF(("Got an error parsing text descriptor.\n")); - if (com->textcnt == 0) { - free(com->text, M_DEVBUF); - MPRINTF("free(DEVBUF)", com->text); - com->text = NULL; /* XXX */ - } - return 1; - } - com->textcnt++; - } - return 0; -} - -struct p1212_textdata * -p1212_parse_text_desc(u_int32_t *addr) -{ - u_int32_t *t; - u_int16_t crclen, crc, crc1, crc2, romcrc; - struct p1212_textdata *text; - int size; - - t = addr; - - crclen = P1212_DIRENT_GET_LEN((ntohl(t[0]))); - romcrc = P1212_DIRENT_GET_CRC((ntohl(t[0]))); - - if (crclen < P1212_TEXT_Min_Leaf_Length) { - DPRINTF(("Invalid ROM: text descriptor too short\n")); - return NULL; - } - - crc = p1212_calc_crc(0, &t[1], crclen, 0); - if (crc != romcrc) { - crc1 = p1212_calc_crc(0, &t[1], crclen, 1); - crc2 = p1212_calc_crc(0, &t[1], crclen, 2); - if ((crc1 != romcrc) && (crc2 != romcrc)) { - DPRINTF(("Invalid ROM: CRC: 0x%04hx, Calculated CRC: " - "0x%04hx, CRC1: 0x%04hx, CRC1: 0x%04hx\n", - (unsigned short)romcrc, (unsigned short)crc, - (unsigned short)crc1, (unsigned short)crc2)); - return NULL; - } - } - if (romcrc == crc2) - DPRINTF(("%s: warning byte-swapping rom problems\n", __func__)); - - t++; - MALLOC(text, struct p1212_textdata *, sizeof(*text), M_DEVBUF, - M_WAITOK); - MPRINTF("MALLOC(DEVBUF)", text); - text->spec_type = P1212_TEXT_GET_Spec_Type((ntohl(t[0]))); - text->spec_id = P1212_TEXT_GET_Spec_Id((ntohl(t[0]))); - text->lang_id = ntohl(t[1]); - - t++; - t++; - crclen -= 2; - size = (crclen * sizeof(u_int32_t)); - -#ifdef M_ZERO - text->text = malloc(size + 1, M_DEVBUF, M_WAITOK|M_ZERO); - MPRINTF("malloc(DEVBUF)", text->text); -#else /* M_ZERO */ - text->text = malloc(size + 1, M_DEVBUF, M_WAITOK); - MPRINTF("malloc(DEVBUF)", text->text); - bzero(text->text, size + 1); -#endif /* ! M_ZERO */ - - bcopy(&t[0], text->text, size); - - return text; -} - -struct p1212_key ** -p1212_find(struct p1212_dir *root, int type, int value, int flags) -{ - struct p1212_key **retkeys; - struct p1212_dir *dir, *sdir, *parent; - struct p1212_data *data; - int numkeys; -#ifdef __OpenBSD__ - struct p1212_key **p; -#endif /* __OpenBSD__ */ - - numkeys = 0; - retkeys = NULL; - - if ((type < P1212_KEYTYPE_Immediate) || - (type > P1212_KEYTYPE_Directory)) { - DPRINTF(("p1212_find: invalid type - %d\n", type)); - return NULL; - } - - if ((value < -1) || - (value > (sizeof(p1212_keyvalue_strings) / sizeof(char *)))) { - DPRINTF(("p1212_find: invalid value - %d\n", value)); - return NULL; - } - - if (flags & ~(P1212_FIND_SEARCHALL | P1212_FIND_RETURNALL)) { - DPRINTF(("p1212_find: invalid flags - %d\n", flags)); - return NULL; - } - - /* - * Part of this is copied from p1212_walk to do depth first traversal - * without using recursion. Using the walk API would have made things - * more complicated in trying to build up the return struct otherwise. - */ - - dir = root; - sdir = NULL; - - parent = root->parent; - root->parent = NULL; - - while (dir) { - if (type == P1212_KEYTYPE_Directory) { - TAILQ_FOREACH(sdir, &dir->subdir_root, dir) { - if ((sdir->com.key.key_value == value) || - (value == -1)) { - numkeys++; -#ifdef __NetBSD__ - retkeys = realloc(retkeys, - sizeof(struct p1212_key *) * - (numkeys + 1), M_DEVBUF, M_WAITOK); -#else /* __NetBSD__ */ - p = malloc(sizeof(struct p1212_key *) * - (numkeys + 1), M_DEVBUF, M_WAITOK); - MPRINTF("malloc(DEVBUF)", p); - if (retkeys != NULL) { - bcopy(retkeys, p, numkeys * - sizeof(struct p1212_key *)); - free(retkeys, M_DEVBUF); - MPRINTF("free(DEVBUF)", retkeys); - retkeys = NULL; /* XXX */ - } - retkeys = p; -#endif /* ! __NetBSD__ */ - retkeys[numkeys - 1] = &sdir->com.key; - retkeys[numkeys] = NULL; - if ((flags & P1212_FIND_RETURNALL) - == 0) { - root->parent = parent; - return retkeys; - } - } - } - } else { - TAILQ_FOREACH(data, &dir->data_root, data) { - if (((data->com.key.key_type == type) && - (data->com.key.key_value == value)) || - ((data->com.key.key_type == type) && - (value == -1))) { - numkeys++; -#ifdef __NetBSD__ - retkeys = realloc(retkeys, - sizeof(struct p1212_key *) * - (numkeys + 1), M_DEVBUF, M_WAITOK); -#else /* __NetBSD__ */ - p = malloc(sizeof(struct p1212_key *) * - (numkeys + 1), M_DEVBUF, M_WAITOK); - MPRINTF("malloc(DEVBUF)", p); - if (retkeys != NULL) { - bcopy(retkeys, p, numkeys * - sizeof(struct p1212_key *)); - free(retkeys, M_DEVBUF); - MPRINTF("free(DEVBUF)", retkeys); - retkeys = NULL; /* XXX */ - } - retkeys = p; -#endif /* ! __NetBSD__ */ - retkeys[numkeys - 1] = &data->com.key; - retkeys[numkeys] = NULL; - if ((flags & P1212_FIND_RETURNALL) - == 0) { - root->parent = parent; - return retkeys; - } - } - } - } - if (flags & P1212_FIND_SEARCHALL) { - do { - sdir = TAILQ_NEXT(dir, dir); - if (sdir == NULL) { - dir = dir->parent; - } - } while ((sdir == NULL) && (dir != NULL)); - dir = sdir; - } else - dir = NULL; - } - root->parent = parent; - return retkeys; -} - -void -p1212_walk(struct p1212_dir *root, void *arg, - void (*func)(struct p1212_key *, void *)) -{ - struct p1212_data *data; - struct p1212_dir *sdir, *dir, *parent; - - dir = root; - sdir = NULL; - - if (func == NULL) { - DPRINTF(("p1212_walk: Passed in NULL function\n")); - return; - } - if (root == NULL) { - DPRINTF(("p1212_walk: Called with NULL root\n")); - return; - } - - /* Allow walking from any point. Just mark the starting point. */ - parent = root->parent; - root->parent = NULL; - - /* - * Depth first traversal that doesn't use recursion. - * - * Call the function first for the directory node and then loop through - * all the data nodes and call the function for them. - * - * Finally, figure out the next possible directory node if one is - * available or bail out. - */ - - while (dir) { - func((struct p1212_key *) dir, arg); - TAILQ_FOREACH(data, &dir->data_root, data) - func((struct p1212_key *) data, arg); - if (!TAILQ_EMPTY(&dir->subdir_root)) { - sdir = TAILQ_FIRST(&dir->subdir_root); - } else { - do { - sdir = TAILQ_NEXT(dir, dir); - if (sdir == NULL) { - dir = dir->parent; - } - } while ((sdir == NULL) && dir); - } - dir = sdir; - } - - root->parent = parent; -} - -void -p1212_print(struct p1212_dir *dir) -{ - int indent; - - indent = 0; - - p1212_walk(dir, &indent, p1212_print_node); - printf("\n"); -} - -void -p1212_print_node(struct p1212_key *key, void *arg) -{ - - struct p1212_data *data; - struct p1212_dir *sdir, *dir; - int i, j, *indent; - - indent = arg; - - if (key->key_type == P1212_KEYTYPE_Directory) { - dir = (struct p1212_dir *) key; - data = NULL; - } else { - data = (struct p1212_data *) key; - dir = NULL; - } - - /* Recompute the indent level on each directory. */ - if (dir) { - *indent = 0; - sdir = dir->parent; - while (sdir != NULL) { - (*indent)++; - sdir = sdir->parent; - } - } - - if (dir && dir->parent) - printf("\n"); - - /* Set the indent string up. 4 spaces per level. */ - for (i = 0; i < (*indent * 4); i++) - printf(" "); - - if (dir) { - printf("Directory: "); - if (dir->print) - dir->print(dir); - else { - if (key->key_value >= - (sizeof(p1212_keyvalue_strings) / sizeof(char *))) - printf("Unknown type 0x%04hx\n", - (unsigned short)key->key_value); - else - printf("%s\n", - p1212_keyvalue_strings[key->key_value]); - } - if (dir->com.textcnt) { - for (i = 0; i < dir->com.textcnt; i++) { - for (j = 0; j < (*indent * 4); j++) - printf(" "); - printf("Text descriptor: %s\n", - dir->com.text[i]->text); - } - } - printf("\n"); - } else { - if (data->print) - data->print(data); - else { - if (key->key_value >= - (sizeof(p1212_keyvalue_strings) / sizeof(char *))) - printf("Unknown type 0x%04hx: ", - (unsigned short)key->key_value); - else - printf("%s: ", - p1212_keyvalue_strings[key->key_value]); - - printf("0x%08x\n", key->val); -#ifdef DIAGNOSTIC - if ((data->com.key.key_type == P1212_KEYTYPE_Leaf) && - (data->leafdata == NULL)) - panic("Invalid data node in configrom tree"); -#endif /* DIAGNOSTIC */ - - if (data->leafdata) { - for (i = 0; i < data->leafdata->len; i++) { - for (j = 0; j < (*indent * 4); j++) - printf(" "); - printf ("Leaf data: 0x%08x\n", - data->leafdata->data[i]); - } - } - if (data->com.textcnt) - for (i = 0; i < data->com.textcnt; i++) { - for (j = 0; j < (*indent * 4); j++) - printf(" "); - printf("Text descriptor: %s\n", - data->com.text[i]->text); - } - - } - } -} - - -void -p1212_free(struct p1212_rom *rom) -{ - struct p1212_dir *sdir, *dir; - struct p1212_data *data; - int i; - - dir = rom->root; - - /* Avoid recursing. Find the bottom most node and work back. */ - while (dir) { - if (!TAILQ_EMPTY(&dir->subdir_root)) { - sdir = TAILQ_FIRST(&dir->subdir_root); - if (TAILQ_EMPTY(&sdir->subdir_root)) { - TAILQ_REMOVE(&dir->subdir_root, sdir, dir); - dir = sdir; - } - else { - dir = sdir; - continue; - } - } else { - if (dir->parent) - TAILQ_REMOVE(&dir->parent->subdir_root, dir, - dir); - } - - while ((data = TAILQ_FIRST(&dir->data_root))) { - if (data->leafdata) { - if (data->leafdata->data) { - free(data->leafdata->data, M_DEVBUF); - MPRINTF("free(DEVBUF)", data->leafdata->data); - data->leafdata->data = NULL; /* XXX */ - } - FREE(data->leafdata, M_DEVBUF); - MPRINTF("FREE(DEVBUF)", data->leafdata); - data->leafdata = NULL; /* XXX */ - } - TAILQ_REMOVE(&dir->data_root, data, data); - if (data->com.textcnt) { - for (i = 0; i < data->com.textcnt; i++) { - free(data->com.text[i]->text, M_DEVBUF); - MPRINTF("free(DEVBUF)", data->com.text[i]->text); - data->com.text[i]->text = NULL; /* XXX */ - FREE(data->com.text[i], M_DEVBUF); - MPRINTF("FREE(DEVBUF)", data->com.text[i]); - data->com.text[i] = NULL; /* XXX */ - } - free(data->com.text, M_DEVBUF); - MPRINTF("free(DEVBUF)", data->com.text); - data->com.text = NULL; /* XXX */ - } - FREE(data, M_DEVBUF); - MPRINTF("FREE(DEVBUF)", data); - data = NULL; /* XXX */ - } - sdir = dir; - if (dir->parent) - dir = dir->parent; - else - dir = NULL; - if (sdir->com.textcnt) { - for (i = 0; i < sdir->com.textcnt; i++) { - FREE(sdir->com.text[i], M_DEVBUF); - MPRINTF("FREE(DEVBUF)", sdir->com.text[i]); - sdir->com.text[i] = NULL; /* XXX */ - } - free(sdir->com.text, M_DEVBUF); - MPRINTF("free(DEVBUF)", sdir->com.text); - sdir->com.text = NULL; /* XXX */ - } - FREE(sdir, M_DEVBUF); - MPRINTF("FREE(DEVBUF)", sdir); - sdir = NULL; /* XXX */ - } - if (rom->len) { - free(rom->data, M_DEVBUF); - MPRINTF("free(DEVBUF)", rom->data); - rom->data = NULL; /* XXX */ - } - FREE(rom, M_DEVBUF); - MPRINTF("FREE(DEVBUF)", rom); - rom = NULL; /* XXX */ -} - -/* - * A fairly well published reference implementation of the CRC routine had - * a typo in it and some devices may be using it rather than the correct one - * in calculating their ROM CRC's. To compensate an interface for generating - * either is provided. - * - * len is the number of u_int32_t entries, not bytes. - */ - -u_int16_t -p1212_calc_crc(u_int16_t seed, u_int32_t *data, int len, int broke) -{ - u_int16_t sum, crc = seed; - int i, shift; - - for (i = 0; i < len; i++) { - for (shift = 28; shift >= 0; shift -= 4) { - /* - * The 1st broken implementation doesn't do the - * last shift. - */ - if (shift == 0 && broke == 1) - break; - - if (broke == 2) - sum = ((crc >> 12) ^ - (letoh32(data[i]) >> shift)) & 0xF; - else - sum = ((crc >> 12) ^ - (ntohl(data[i]) >> shift)) & 0xF; - crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ sum; - } - } - - if (broke == 2) - return swap16(crc); - else - return (crc); -} - -/* - * This is almost identical to the standard autoconf *match idea except it - * can match and attach multiple children in one pass. - */ - -struct device ** -p1212_match_units(struct device *sc, struct p1212_dir *dir, - int (*print)(void *, const char *)) -{ - struct p1212_dir **udirs; - struct device **devret, *dev; - int numdev, i; -#ifdef __OpenBSD__ - struct device **p; -#endif /* __OpenBSD__ */ - - /* - * Setup typically return val. Always allocate one extra pointer for a - * NULL guard end pointer. - */ - - numdev = 0; - devret = malloc(sizeof(struct device *) * 2, M_DEVBUF, M_WAITOK); - MPRINTF("malloc(DEVBUF)", devret); - devret[0] = devret[1] = NULL; - - udirs = (struct p1212_dir **)p1212_find(dir, P1212_KEYTYPE_Directory, - P1212_KEYVALUE_Unit_Directory, - P1212_FIND_SEARCHALL|P1212_FIND_RETURNALL); - - if (udirs) { - i = 0; - do { - dev = config_found_sm(sc, &udirs[i], print, NULL); - if (dev && numdev) { -#ifdef __NetBSD__ - devret = realloc(devret, - sizeof(struct device *) * - (numdev + 2), M_DEVBUF, M_WAITOK); -#else /* __NetBSD__ */ - p = malloc(sizeof(struct device *) * - (numdev + 2), M_DEVBUF, M_WAITOK); - MPRINTF("malloc(DEVBUF)", p); - bcopy(devret, p, - numdev * sizeof(struct device *)); - free(devret, M_DEVBUF); - MPRINTF("free(DEVBUF)", devret); - devret = p; -#endif /* ! __NetBSD__ */ - devret[numdev++] = dev; - devret[numdev] = NULL; - } else if (dev) { - devret[0] = dev; - numdev++; - } - } while (udirs[++i]); - - free(udirs, M_DEVBUF); - MPRINTF("free(DEVBUF)", udirs); - udirs = NULL; /* XXX */ - } - if (numdev == 0) { - free(devret, M_DEVBUF); - MPRINTF("free(DEVBUF)", devret); - devret = NULL; /* XXX */ - return NULL; - } - return devret; -} - -/* - * Make these their own functions as they have slightly complicated rules. - * - * For example: - * - * Under normal circumstances only the 2 extent types can be offset - * types. However some spec's which use p1212 like SBP2 for - * firewire/1394 will define a dependent info type as an offset value. - * Allow the upper level code to flag this and pass it down during - * parsing. The same thing applies to immediate types. - */ - -int -p1212_validate_offset(u_int16_t val, u_int32_t mask) -{ - if ((val == P1212_KEYVALUE_Node_Units_Extent) || - (val == P1212_KEYVALUE_Node_Memory_Extent) || - ((mask & P1212_ALLOW_DEPENDENT_INFO_OFFSET_TYPE) && - ((val == P1212_KEYVALUE_Unit_Dependent_Info) || - (val == P1212_KEYVALUE_Node_Dependent_Info) || - (val == P1212_KEYVALUE_Module_Dependent_Info)))) - return 0; - return 1; -} - -int -p1212_validate_immed(u_int16_t val, u_int32_t mask) -{ - switch (val) { - case P1212_KEYVALUE_Textual_Descriptor: - case P1212_KEYVALUE_Bus_Dependent_Info: - case P1212_KEYVALUE_Module_Dependent_Info: - case P1212_KEYVALUE_Node_Unique_Id: - case P1212_KEYVALUE_Node_Dependent_Info: - case P1212_KEYVALUE_Unit_Directory: - case P1212_KEYVALUE_Unit_Dependent_Info: - case P1212_KEYVALUE_Unit_Location: - if ((mask & P1212_ALLOW_DEPENDENT_INFO_IMMED_TYPE) && - ((val == P1212_KEYVALUE_Module_Dependent_Info) || - (val == P1212_KEYVALUE_Node_Dependent_Info) || - (val == P1212_KEYVALUE_Unit_Dependent_Info))) - break; - return 1; - break; - default: - break; - } - return 0; -} - -int -p1212_validate_leaf(u_int16_t val, u_int32_t mask) -{ - switch(val) { - case P1212_KEYVALUE_Textual_Descriptor: - case P1212_KEYVALUE_Bus_Dependent_Info: - case P1212_KEYVALUE_Module_Dependent_Info: - case P1212_KEYVALUE_Node_Unique_Id: - case P1212_KEYVALUE_Node_Dependent_Info: - case P1212_KEYVALUE_Unit_Dependent_Info: - case P1212_KEYVALUE_Unit_Location: - break; - default: - return 1; - break; - } - return 0; -} - -int -p1212_validate_dir(u_int16_t val, u_int32_t mask) -{ - switch(val) { - case P1212_KEYVALUE_Textual_Descriptor: - case P1212_KEYVALUE_Bus_Dependent_Info: - case P1212_KEYVALUE_Module_Dependent_Info: - case P1212_KEYVALUE_Node_Dependent_Info: - case P1212_KEYVALUE_Unit_Directory: - case P1212_KEYVALUE_Unit_Dependent_Info: - break; - default: - if ((mask & P1212_ALLOW_VENDOR_DIRECTORY_TYPE) && - (val == P1212_KEYVALUE_Module_Vendor_Id)) - break; - return 1; - break; - } - return 0; -} diff --git a/sys/dev/std/ieee1212reg.h b/sys/dev/std/ieee1212reg.h deleted file mode 100644 index bf7d920021d..00000000000 --- a/sys/dev/std/ieee1212reg.h +++ /dev/null @@ -1,265 +0,0 @@ -/* $OpenBSD: ieee1212reg.h,v 1.2 2002/12/13 02:52:11 tdeval Exp $ */ -/* $NetBSD: ieee1212reg.h,v 1.7 2002/04/02 10:10:54 jmc Exp $ */ - -/* - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_STD_IEEE1212REG_H_ -#define _DEV_STD_IEEE1212REG_H_ - -/* This file contains definitions from ISO/IEC 1312 or ANSI/IEEE Std 1212 - * Informaton techonology - * Microprocessor systems - * Control and Status Registers (CSR) - * Architecture for microcomputer buses - * First edition 1994-10-05 - */ - -/* Lock transaction codes (Table 5) - */ -#define P1212_XTCODE_RESERVED_0 0 -#define P1212_XTCODE_MASK_SWAP 1 -#define P1212_XTCODE_COMPARE_SWAP 2 -#define P1212_XTCODE_FETCH_ADD 3 -#define P1212_XTCODE_LITTLE_ADD 4 -#define P1212_XTCODE_BOUNDED_ADD 5 -#define P1212_XTCODE_WRAP_ADD 6 -#define P1212_XTCODE_VENDOR_DEPENDENT 7 - -/* Header: Rom Format (1 Quadlet) - * Bus Info Block: <info-length> Quadlets - * Root Directory - * Unit Directory - * Root & Unit Leaves - * Vendor Dependent Information - */ -/* ROM Formats - * 0x00-0x000000 Initializing - * 0x01-0xzzyyxx Minimal (zz-yy-xx is an OUI) - * 0xii-0xcc-0xllll General (ii is info-length, - * cc is crc-length, llll is length) - */ - -#define P1212_ROMFMT_INIT 0x00 -#define P1212_ROMFMT_MINIMAL 0x01 - -/* uint32_t P1212_ROMFMT_MK_INIT(void) - */ -#define P1212_ROMFMT_MK_INIT() 0x00000000 - -/* uint32_t P1212_ROMFMT_MK_MINIMAL(const uint8_t *oui); - */ -#define P1212_ROMFMT_MK_MINIMAL(oui) \ - ((P1212_ROMFMT_MINIMAL << 24) \ - | ((oui[0]) << 16) \ - | ((oui[1]) << 8) \ - | ((oui[2]) << 0)) - -/* uint32_t P1212_ROMFMT_MK_GENERAL(size_t info_len, size_t crc_len, - * uint16_t crc); - */ -#define P1212_ROMFMT_MK_GENERAL(info_len, crc_len, crc_value) \ - (((info_len) << 24) \ - | ((crc_len) << 16) \ - | ((crc_value) << 0)) - -/* unsigned P1212_ROMFMT_GET_FMT(uint32_t); - */ -#define P1212_ROMFMT_GET_FMT(quadlet) (((quadlet) >> 24) & 0xff) - -/* void P1212_ROMFMT_GET_OUI(uint32_t quadlet, uint8_t *oui); - */ -#define P1212_ROMTFMT_GET_OUI(quadlet, oui) do { \ - (oui)[0] = ((quadlet) >> 16) & 0xff; \ - (oui)[1] = ((quadlet) >> 8) & 0xff; \ - (oui)[2] = ((quadlet) >> 0) & 0xff; \ - } while (0) - -/* size_t P1212_ROMGET_GET_INFOLEN(uint32_t quadlet); - */ -#define P1212_ROMFMT_GET_INFOLEN(quadlet) (((quadlet) >> 24) & 0xff) - -/* size_t P1212_ROMGET_GET_CRCLEN(uint32_t quadlet); - */ -#define P1212_ROMFMT_GET_CRCLEN(quadlet) (((quadlet) >> 16) & 0xff) - -/* size_t P1212_ROMGET_GET_CRC(uint32_t quadlet); - */ -#define P1212_ROMFMT_GET_CRC(quadlet) ((uint16_t)(quadlet)) - -/* uint8_t P1212_DIRENT_GET_KEY(uint32_t quadlet); - */ -#define P1212_DIRENT_GET_KEY(quadlet) (((quadlet) >> 24) & 0xff) - -/* unsigned int P1212_DIRENT_GET_KEYTYPE(uint32_t quadlet); - */ -#define P1212_DIRENT_GET_KEYTYPE(quadlet) (((quadlet) >> 30) & 0x03) - -/* unsigned int P1212_DIRENT_GET_KEYVALUE(uint32_t quadlet); - */ -#define P1212_DIRENT_GET_KEYVALUE(quadlet) (((quadlet) >> 24) & 0x3f) - -/* unsigned int P1212_DIRENT_GET_OFFSET(uint32_t quadlet); - */ -#define P1212_DIRENT_GET_OFFSET(quadlet) ((quadlet) & 0xffffff) - -/* unsigned int P1212_DIRENT_GET_VALUE(uint32_t quadlet); - */ -#define P1212_DIRENT_GET_VALUE(quadlet) ((quadlet) & 0xffffff) - -/* u_int16_t P1212_DIRENT_GET_LEN(quadlet); - */ -#define P1212_DIRENT_GET_LEN(quadlet) (((quadlet) >> 16) & 0xffff) - -/* u_int16_t P1212_DIRENT_GET_CRC(quadlet); - */ -#define P1212_DIRENT_GET_CRC(quadlet) ((uint16_t)(quadlet)) - -/* Key Types are stored in bits 31-30 of a directory entry. - */ - -#define P1212_KEYTYPE_Immediate 0x00 -#define P1212_KEYTYPE_Offset 0x01 -#define P1212_KEYTYPE_Leaf 0x02 -#define P1212_KEYTYPE_Directory 0x03 - -/* Key Values are stored in bits 29-24 of a directory entry. - */ -#define P1212_KEYVALUE_Textual_Descriptor 0x01 /* leaf | directory */ -#define P1212_KEYVALUE_Bus_Dependent_Info 0x02 /* leaf | directory */ -#define P1212_KEYVALUE_Module_Vendor_Id 0x03 /* immediate */ -#define P1212_KEYVALUE_Module_Hw_Version 0x04 /* immediate */ -#define P1212_KEYVALUE_Module_Spec_Id 0x05 /* immediate */ -#define P1212_KEYVALUE_Module_Sw_Version 0x06 /* immediate */ -#define P1212_KEYVALUE_Module_Dependent_Info 0x07 /* leaf | directory */ -#define P1212_KEYVALUE_Node_Vendor_Id 0x08 /* immediate */ -#define P1212_KEYVALUE_Node_Hw_Version 0x09 /* immediate */ -#define P1212_KEYVALUE_Node_Spec_Id 0x0a /* immediate */ -#define P1212_KEYVALUE_Node_Sw_Version 0x0b /* immediate */ -#define P1212_KEYVALUE_Node_Capabilities 0x0c /* immediate */ -#define P1212_KEYVALUE_Node_Unique_Id 0x0d /* leaf */ -#define P1212_KEYVALUE_Node_Units_Extent 0x0e /* immediate | offset */ -#define P1212_KEYVALUE_Node_Memory_Extent 0x0f /* immediate | offset */ -#define P1212_KEYVALUE_Node_Dependent_Info 0x10 /* leaf | directory */ -#define P1212_KEYVALUE_Unit_Directory 0x11 /* directory */ -#define P1212_KEYVALUE_Unit_Spec_Id 0x12 /* immediate */ -#define P1212_KEYVALUE_Unit_Sw_Version 0x13 /* immediate */ -#define P1212_KEYVALUE_Unit_Dependent_Info 0x14 /* imm|off|leaf|dir */ -#define P1212_KEYVALUE_Unit_Location 0x15 /* leaf */ -#define P1212_KEYVALUE_Unit_Poll_Mask 0x16 /* immediate */ - -/* - * Items not in original p1212 standard but are in proposed drafts and in use - * already in some roms. - */ - -#define P1212_KEYVALUE_Model 0x17 /* immediate */ -#define P1212_KEYVALUR_Instance_Directory 0x18 /* directory */ -#define P1212_KEYVALUE_Keyword 0x19 /* leaf */ -#define P1212_KEYVALUE_Feature_Directory 0x1A /* directory */ -#define P1212_KEYVALUE_Extended_ROM 0x1B /* leaf */ -#define P1212_KEYVALUE_Extended_Key_Spec_Id 0x1C /* immediate */ -#define P1212_KEYVALUE_Extended_Key 0x1D /* immediate */ -#define P1212_KEYVALUE_Extended_Data 0x1E /* imm|off|leaf|dir */ -#define P1212_KEYVALUE_Modifiable_Descriptor 0x1F /* leaf */ -#define P1212_KEYVALUE_Directory_Id 0x20 /* immediate */ - -#define P1212_KEYTYPE_STRINGS { "Immediate", "Offset", "Leaf", "Directory" } - -#define P1212_KEYVALUE_STRINGS { "Root-Directory", \ - "Textual-Descriptor", "Bus-Dependent-Info", "Module-Vendor-Id", \ - "Module-Hw-Version", "Module-Spec-Id", "Module-Sw-Version", \ - "Module-Dependent-Info", "Node-Vendor-Id", "Node-Hw_Version", \ - "Node-Spec-Id", "Node-Sw-Verson", "Node-Capabilities", \ - "Node-Unique-Id", "Node-Units-Extent", "Node-Memory-Extent", \ - "Node-Dependent-Info", "Unit-Directory", "Unit-Spec-Id", \ - "Unit-Sw-Version", "Unit-Dependent-Info", "Unit-Location", \ - "Unit-Poll-Mask", "Model", "Instance-Directory", "Keyword", \ - "Feature-Directory", "Extended-ROM", "Extended-Key-Spec-Id", \ - "Extended-Key", "Extended-Data", "Modifiable-Descriptor", \ - "Directory-Id", NULL /* 0x21 */, NULL /* 0x22 */, NULL /* 0x23 */, \ - NULL /* 0x24 */, NULL /* 0x25 */, NULL /* 0x26 */, NULL /* 0x27 */, \ - NULL /* 0x28 */, NULL /* 0x29 */, NULL /* 0x2A */, NULL /* 0x2B */, \ - NULL /* 0x2C */, NULL /* 0x2D */, NULL /* 0x2E */, NULL /* 0x2F */, \ - NULL /* 0x30 */, NULL /* 0x31 */, NULL /* 0x32 */, NULL /* 0x33 */, \ - NULL /* 0x34 */, NULL /* 0x35 */, NULL /* 0x36 */, NULL /* 0x37 */, \ - "Command-Set-Spec-ID", "Commant-Set", "Unit-Characteristics", \ - "Command-Set-Revision", "Firmware-Revision", "Reconnect-Timeout", \ -} - -/* Leaf nodes look like: - * - * [0] 0xnnnn-0xcccc length, crc16 - * [n] - * - * Text leaves look like: - * [0] 0xnnnn-0xcccc length, crc16 - * [1] 0xtt-0xiiiiii specifier type, specifier id - * [2] 0xllllllll language id - */ - -#define P1212_TEXT_Min_Leaf_Length 0x3 -#define P1212_TEXT_GET_Spec_Type(quadlet) (((quadlet) & 0xff000000) >> 24) -#define P1212_TEXT_GET_Spec_Id(quadlet) ((quadlet) & 0xffffff) - -/* - * Directory nodes look like: - * [0] 0xnnnn-0xcccc length, crc16 - * [1] direntry - * [n] direntry - */ - -/* Some definitions for the p1212_find routines. */ - -#define P1212_FIND_SEARCHALL 0x1 -#define P1212_FIND_RETURNALL 0x2 - -/* Mask definitions for overriding the p1212 standard checks. */ - -/* - * XXX: Note that some of these go away if full p1212r support is done as - * a lot of the restrictions were lifted there in what can go where. - */ - - -/* Normally dependent info can only be leaf or directory. Allow offsets also */ -#define P1212_ALLOW_DEPENDENT_INFO_OFFSET_TYPE 0x1 - -/* Same thing applies for immediate types. */ -#define P1212_ALLOW_DEPENDENT_INFO_IMMED_TYPE 0x2 -#define P1212_ALLOW_VENDOR_DIRECTORY_TYPE 0x4 - -#endif /* _DEV_STD_IEEE1212REG_H_ */ diff --git a/sys/dev/std/ieee1212var.h b/sys/dev/std/ieee1212var.h deleted file mode 100644 index 8c525750cc1..00000000000 --- a/sys/dev/std/ieee1212var.h +++ /dev/null @@ -1,107 +0,0 @@ -/* $OpenBSD: ieee1212var.h,v 1.2 2002/12/13 02:52:11 tdeval Exp $ */ -/* $NetBSD: ieee1212var.h,v 1.1 2002/02/27 04:58:51 jmc Exp $ */ - -/* - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by James Chacon. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_STD_IEEE1212VAR_H -#define _DEV_STD_IEEE1212VAR_H - -struct p1212_dir; - -typedef struct p1212_key { - u_int8_t key_type; - u_int8_t key_value; - u_int8_t key; - u_int32_t val; -} p1212_key; - -typedef struct p1212_leafdata { - u_int32_t len; - u_int32_t *data; -} p1212_leafdata; - -typedef struct p1212_textdata { - u_int8_t spec_type; - u_int32_t spec_id; - u_int32_t lang_id; - char *text; -} p1212_textdata; - -typedef struct p1212_com { - struct p1212_key key; - u_int32_t textcnt; - struct p1212_textdata **text; -} p1212_com; - -typedef struct p1212_data { - struct p1212_com com; - - u_int32_t val; - struct p1212_leafdata *leafdata; - void (*print)(struct p1212_data *); - TAILQ_ENTRY(p1212_data) data; -} p1212_data; - -typedef struct p1212_dir { - struct p1212_com com; - - int match; - void (*print)(struct p1212_dir *); - struct p1212_dir *parent; - TAILQ_HEAD(, p1212_data) data_root; - TAILQ_HEAD(, p1212_dir) subdir_root; - TAILQ_ENTRY(p1212_dir) dir; -} p1212_dir; - -typedef struct p1212_rom { - char name[5]; - u_int32_t len; - u_int32_t *data; - struct p1212_dir *root; -} p1212_rom; - -int p1212_iscomplete(u_int32_t *, u_int32_t *); -struct p1212_rom *p1212_parse(u_int32_t *, u_int32_t, u_int32_t); -void p1212_walk(struct p1212_dir *, void *, - void (*)(struct p1212_key *, void *)); -struct p1212_key **p1212_find(struct p1212_dir *, int, int, int); -void p1212_print(struct p1212_dir *); -void p1212_free(struct p1212_rom *); -struct device **p1212_match_units(struct device *, struct p1212_dir *, - int (*)(void *, const char *)); - -#endif /* _DEV_STD_IEEE1212VAR_H */ diff --git a/sys/dev/std/sbp2.c b/sys/dev/std/sbp2.c deleted file mode 100644 index c00d33ddcef..00000000000 --- a/sys/dev/std/sbp2.c +++ /dev/null @@ -1,1358 +0,0 @@ -/* $OpenBSD: sbp2.c,v 1.6 2004/04/08 16:08:21 henning Exp $ */ - -/* - * Copyright (c) 2002 Thierry Deval. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * sbp2.c - * - * Basic implementation of the ANSI NCITS 325-1998 Serial Bus Protocol2 (SBP-2). - * - * ANSI NCITS 325-1998 - * Information Technology - Serial Bus Protocol 2 (SBP-2) - * - * Defines a protocol for the transport of commands and data over high - * performance serial bus, as specified in American National Standard for - * High Performance Serial Bus, ANSI/IEEE 1394-1995. The transport protocol, - * Serial Bus Protocol 2 or SBP-2, requires implementations to conform to the - * requirements of the aforementioned standard as well as to International - * Standard for Control and Status Register (CSR) Architecture for - * Microcomputer Buses, ISO/IEC 13213:1994 (IEEE 1212-1994), and permits the - * exchange of commands, data and status between initiators and targets - * connected to Serial Bus. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/socket.h> -#ifdef __NetBSD__ -#include <sys/callout.h> -#else -#include <sys/timeout.h> -#endif -#include <sys/device.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#ifdef __OpenBSD__ -#include <sys/endian.h> -#endif - -#if __NetBSD_Version__ >= 105010000 || !defined(__NetBSD__) -#include <uvm/uvm_extern.h> -#else -#include <vm/vm.h> -#endif - -#include <machine/bus.h> -#include <machine/intr.h> - -#include <dev/rndvar.h> - -#include <dev/ieee1394/ieee1394reg.h> -#include <dev/ieee1394/fwohcireg.h> -#include <dev/ieee1394/fwnodereg.h> -#include <dev/std/ieee1212reg.h> -#include <dev/std/sbp2reg.h> - -#include <dev/ieee1394/ieee1394var.h> -#include <dev/ieee1394/fwohcivar.h> -#include <dev/ieee1394/fwnodevar.h> -#include <dev/std/ieee1212var.h> -#include <dev/std/sbp2var.h> - -#if 0 -void sbp2_print(struct p1212_dir *); -void sbp2_print_node(struct p1212_key *, void *); -#endif - -void sbp2_login_send(struct ieee1394_abuf *, int); -void sbp2_status_resp(struct ieee1394_abuf *, int); -void sbp2_command_send(struct ieee1394_abuf *, int); -void sbp2_reconnect(struct ieee1394_softc *); -void sbp2_reconnect_send(struct ieee1394_abuf *, int); - -#ifdef SBP2_DEBUG -#include <sys/syslog.h> -extern int log_open; -int sbp2_oldlog; -#define DPRINTF(x) do { \ - if (sbp2debug) { \ - sbp2_oldlog = log_open; log_open = 1; \ - addlog x; log_open = sbp2_oldlog; \ - } \ -} while (0) -#define DPRINTFN(n,x) do { \ - if (sbp2debug>(n)) { \ - sbp2_oldlog = log_open; log_open = 1; \ - addlog x; log_open = sbp2_oldlog; \ - } \ -} while (0) -#ifdef FW_MALLOC_DEBUG -#define MPRINTF(x,y) DPRINTF(("%s[%d]: %s 0x%08x\n", \ - __func__, __LINE__, (x), (u_int32_t)(y))) -#else /* !FW_MALLOC_DEBUG */ -#define MPRINTF(x,y) -#endif /* FW_MALLOC_DEBUG */ - -int sbp2debug = 0; -#else /* SBP2_DEBUG */ -#define DPRINTF(x) -#define DPRINTFN(n,x) -#define MPRINTF(x,y) -#endif /* ! SBP2_DEBUG */ - -typedef struct sbp2_account { - struct fwnode_softc *ac_softc; - struct ieee1394_abuf *ac_status_ab; - struct sbp2_task_management_orb *ac_mgmt_orb; - struct sbp2_status_block *ac_status_block; - void *ac_response_block; - void (*ac_cb)(void *, - struct sbp2_status_notification *); - void *ac_cbarg; - u_int64_t ac_mgmt_agent; - u_int64_t ac_fetch_agent; - u_int64_t ac_response; - u_int64_t ac_status_fifo; - u_int16_t ac_nodeid; - u_int16_t ac_lun; - u_int16_t ac_login; - u_int16_t ac_reconnect_hold; - u_int16_t ac_valid; - SLIST_ENTRY(sbp2_account) ac_chain; -} sbp2_account; -static SLIST_HEAD(, sbp2_account) sbp2_ac_head; - -typedef struct sbp2_orb_element { - struct sbp2_account *elm_ac; - struct ieee1394_abuf *elm_orb_ab; - struct sbp2_command_orb *elm_orb; - size_t elm_orblen; - u_int32_t elm_hash; - void *elm_data; - size_t elm_datasize; - void (*elm_cb)(void *, - struct sbp2_status_notification *); - void *elm_cbarg; - TAILQ_ENTRY(sbp2_orb_element) elm_chain; -} sbp2_orb_element; -static TAILQ_HEAD(sbp2_orb_tq, sbp2_orb_element) sbp2_elm_head; - -static int sbp2_ac_valid; - -struct sbp2_account *sbp2_acfind(struct fwnode_softc *, int); -struct sbp2_orb_element *sbp2_elfind_hash(u_int32_t); -struct sbp2_orb_element *sbp2_elfind_orb(struct sbp2_command_orb *); -struct sbp2_orb_element *sbp2_elfind_first(struct sbp2_account *); -struct sbp2_orb_element *sbp2_elfind_last(struct sbp2_account *); - -struct sbp2_account * -sbp2_acfind(struct fwnode_softc *sc, int lun) -{ - struct sbp2_account *ac; - - SLIST_FOREACH(ac, &sbp2_ac_head, ac_chain) { - if (ac != NULL && ac->ac_softc == sc && ac->ac_lun == lun) - break; - } - - return (ac); -} - -struct sbp2_orb_element * -sbp2_elfind_hash(u_int32_t hash) -{ - struct sbp2_orb_element *elm; - - TAILQ_FOREACH(elm, &sbp2_elm_head, elm_chain) { - if (elm->elm_hash == hash) - break; - } - - return (elm); -} - -struct sbp2_orb_element * -sbp2_elfind_orb(struct sbp2_command_orb *orb) -{ - struct sbp2_orb_element *elm; - - TAILQ_FOREACH(elm, &sbp2_elm_head, elm_chain) { - if (elm->elm_orb == orb) - break; - } - - return (elm); -} - -struct sbp2_orb_element * -sbp2_elfind_first(struct sbp2_account *ac) -{ - struct sbp2_orb_element *elm; - - TAILQ_FOREACH(elm, &sbp2_elm_head, elm_chain) { - if (elm->elm_ac == ac) - break; - } - - return (elm); -} - -struct sbp2_orb_element * -sbp2_elfind_last(struct sbp2_account *ac) -{ - struct sbp2_orb_element *elm; - - TAILQ_FOREACH_REVERSE(elm, &sbp2_elm_head, sbp2_orb_tq, elm_chain) { - if (elm->elm_ac == ac) - break; - } - - return (elm); -} - -void -sbp2_print_data(struct p1212_data *data) -{ - struct p1212_key *key = (struct p1212_key *)data; - - switch (key->key_value) { - case SBP2_KEYVALUE_Command_Set: - DPRINTF(("SBP2 Command Set: ")); - if (key->val == 0x104D8) - DPRINTF(("SCSI 2\n")); - else - DPRINTF(("0x%08x\n", key->val)); - break; - case SBP2_KEYVALUE_Unit_Characteristics: - DPRINTF(("SBP2 Unit Characteristics: 0x%08x\n", key->val)); - break; - case SBP2_KEYVALUE_Command_Set_Revision: - DPRINTF(("SBP2 Command Set Revision: 0x%08x\n", key->val)); - break; - case SBP2_KEYVALUE_Command_Set_Spec_Id: - DPRINTF(("SBP2 Command Set Spec Id: 0x%08x\n", key->val)); - break; - case SBP2_KEYVALUE_Firmware_Revision: - DPRINTF(("SBP2 Firmware Revision: 0x%08x\n", key->val)); - break; - case SBP2_KEYVALUE_Reconnect_Timeout: - DPRINTF(("SBP2 Reconnect Timeout: 0x%08x\n", key->val)); - break; - case SBP2_KEYVALUE_Unit_Unique_Id: - DPRINTF(("SBP2 Unit Unique Id: 0x%08x\n", key->val)); - break; - case P1212_KEYVALUE_Unit_Dependent_Info: - if (key->key_type == P1212_KEYTYPE_Immediate) - DPRINTF(("SBP2 Logical Unit Number: 0x%08x\n", key->val)); - else if (key->key_type == P1212_KEYTYPE_Offset) - DPRINTF(("SBP2 Management Agent: 0x%08x\n", key->val)); - break; - default: - break; - } -} - -void -sbp2_print_dir(struct p1212_dir *dir) -{ - u_int8_t dir_type = ((struct p1212_key *)dir)->key_type; - - switch(dir_type) { - case SBP2_KEYVALUE_Logical_Unit_Directory: - DPRINTF(("Logical Unit ")); - break; - default: - break; - } -} - -int -sbp2_init(struct fwnode_softc *sc, struct p1212_dir *unitdir) -{ - struct p1212_key **key; - struct p1212_dir *dir; - struct sbp2_account *ac; - int loc; - -#ifdef SBP2_DEBUG - if (sbp2debug > 1) - p1212_print(unitdir); -#endif - - key = p1212_find(unitdir, P1212_KEYTYPE_Offset, - SBP2_KEYVALUE_Management_Agent, 0); - if (key == NULL) return (-1); - - if (!sbp2_ac_valid) { - SLIST_INIT(&sbp2_ac_head); - TAILQ_INIT(&sbp2_elm_head); - sbp2_ac_valid = 1; - } - - MALLOC(ac, struct sbp2_account *, sizeof(*ac), M_1394CTL, M_WAITOK); - MPRINTF("MALLOC(1394CTL)", ac); - bzero(ac, sizeof(*ac)); - - loc = key[0]->val; - DPRINTF(("%s: Node %d (sc 0x%08x):" - " UID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - __func__, sc->sc_sc1394.sc1394_node_id, sc, - sc->sc_sc1394.sc1394_guid[0], sc->sc_sc1394.sc1394_guid[1], - sc->sc_sc1394.sc1394_guid[2], sc->sc_sc1394.sc1394_guid[3], - sc->sc_sc1394.sc1394_guid[4], sc->sc_sc1394.sc1394_guid[5], - sc->sc_sc1394.sc1394_guid[6], sc->sc_sc1394.sc1394_guid[7])); - free(key, M_DEVBUF); - MPRINTF("free(DEVBUF)", key); - key = NULL; /* XXX */ - - ac->ac_softc = sc; - ac->ac_nodeid = sc->sc_sc1394.sc1394_node_id; - ac->ac_login = 0; - ac->ac_mgmt_agent = CSR_BASE + 4 * loc; - DPRINTF(("%s: mgmt_agent = 0x%012qx\n", __func__, ac->ac_mgmt_agent)); - - if ((key = p1212_find(unitdir, P1212_KEYTYPE_Immediate, - SBP2_KEYVALUE_Logical_Unit_Number, 0)) != NULL) { - ac->ac_lun = (*key)->val & 0xFFFF; - free(key, M_DEVBUF); - MPRINTF("free(DEVBUF)", key); - key = NULL; /* XXX */ - } else if ((key = p1212_find(unitdir, P1212_KEYTYPE_Directory, - SBP2_KEYVALUE_Logical_Unit_Directory, 0)) != NULL) { - dir = (struct p1212_dir *)*key; - free(key, M_DEVBUF); - MPRINTF("free(DEVBUF)", key); - key = NULL; /* XXX */ - key = p1212_find(dir, P1212_KEYTYPE_Immediate, - SBP2_KEYVALUE_Logical_Unit_Number, 0); - if (key != NULL) { - ac->ac_lun = (*key)->val & 0xFFFF; - free(key, M_DEVBUF); - MPRINTF("free(DEVBUF)", key); - key = NULL; /* XXX */ - } - } - DPRINTF(("%s: lun = %04x\n", __func__, ac->ac_lun)); - - SLIST_INSERT_HEAD(&sbp2_ac_head, ac, ac_chain); - - return (ac->ac_lun); -} - -void -sbp2_clean(struct fwnode_softc *sc, struct p1212_dir *unitdir, int logout) -{ - struct sbp2_account *ac; - struct sbp2_orb_element *elm; - struct p1212_key **key; - struct p1212_dir **dir,*d; - int lun,i; - - DPRINTF(("%s: start\n", __func__)); - - if ((key = p1212_find(unitdir, P1212_KEYTYPE_Immediate, - SBP2_KEYVALUE_Logical_Unit_Number, 0)) != NULL) { - lun = (*key)->val & 0xFFFF; - if ((ac = sbp2_acfind(sc, lun)) != NULL) { - DPRINTF(("%s: clean lun %d\n", __func__, lun)); - i = 0; - TAILQ_FOREACH_REVERSE(elm, &sbp2_elm_head, sbp2_orb_tq, - elm_chain) { - DPRINTF(("%s%d", i++?" ":"", i)); - if (elm != NULL && elm->elm_ac == ac) { - TAILQ_REMOVE(&sbp2_elm_head, elm, - elm_chain); - FREE(elm, M_1394CTL); - MPRINTF("FREE(1394CTL)", elm); - //elm = NULL; /* XXX */ - } - } - if (i) DPRINTF(("\n")); - SLIST_REMOVE(&sbp2_ac_head, ac, sbp2_account, ac_chain); - if (ac->ac_status_ab) { - sc->sc1394_unreg(ac->ac_status_ab, FALSE); - FREE(ac->ac_status_ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ac->ac_status_ab); - ac->ac_status_ab = NULL; /* XXX */ - } - if (ac->ac_status_block) { - FREE(ac->ac_status_block, M_1394DATA); - MPRINTF("FREE(1394DATA)", ac->ac_status_block); - ac->ac_status_block = NULL; /* XXX */ - } - FREE(ac, M_1394CTL); - MPRINTF("FREE(1394CTL)", ac); - ac = NULL; /* XXX */ - } - free(key, M_DEVBUF); - MPRINTF("free(DEVBUF)", key); - key = NULL; /* XXX */ - } else if ((key = p1212_find(unitdir, P1212_KEYTYPE_Directory, - SBP2_KEYVALUE_Logical_Unit_Directory, 0)) != NULL) { - dir = (struct p1212_dir **)key; - i = 0; - d = dir[i++]; - while (d != NULL) { - key = p1212_find(d, P1212_KEYTYPE_Immediate, - SBP2_KEYVALUE_Logical_Unit_Number, 0); - if (key != NULL) { - lun = (*key)->val & 0xFFFF; - if ((ac = sbp2_acfind(sc, lun)) != NULL) { - DPRINTF(("%s: clean lun %d\n", - __func__, lun)); - TAILQ_FOREACH(elm, &sbp2_elm_head, - elm_chain) { - if (elm != NULL && - elm->elm_ac == ac) { - FREE(elm, M_1394CTL); - MPRINTF("FREE(1394CTL)", elm); - elm = NULL; /* XXX */ - } - } - SLIST_REMOVE(&sbp2_ac_head, ac, - sbp2_account, ac_chain); - if (ac->ac_status_ab) { - sc->sc1394_unreg(ac - ->ac_status_ab, FALSE); - FREE(ac->ac_status_ab, - M_1394DATA); - MPRINTF("FREE(1394DATA)", ac->ac_status_ab); - ac->ac_status_ab = NULL; /* XXX */ - } - if (ac->ac_status_block) { - FREE(ac->ac_status_block, - M_1394DATA); - MPRINTF("FREE(1394DATA)", ac->ac_status_block); - ac->ac_status_block = NULL; /* XXX */ - } - FREE(ac, M_1394CTL); - MPRINTF("FREE(1394CTL)", ac); - ac = NULL; /* XXX */ - } - free(key, M_DEVBUF); - MPRINTF("free(DEVBUF)", key); - key = NULL; /* XXX */ - } - d = dir[i++]; - } - free(dir, M_DEVBUF); - MPRINTF("free(DEVBUF)", dir); - dir = NULL; /* XXX */ - } else { - DPRINTF(("%s: no LUN in configrom 0x%08x ???\n", __func__, - (u_int32_t)sc->sc_configrom->root)); - } - - DPRINTF(("%s: end\n", __func__)); -} - -void -sbp2_login(struct fwnode_softc *sc, struct sbp2_login_orb *orb, - void (*cb)(void *, struct sbp2_status_notification *), void *cbarg) -{ - struct ieee1394_abuf *ab, *ab2; - struct sbp2_account *ac; - u_int64_t addr; - - if ((ac = sbp2_acfind(sc, ntohs(orb->lun))) == NULL) { - DPRINTF(("%s: destination not initialized\n", __func__)); - return; - } - - DPRINTF(("%s:", __func__)); - - ac->ac_mgmt_orb = (struct sbp2_task_management_orb *)orb; - if (cb != NULL) { - ac->ac_cb = cb; - ac->ac_cbarg = cbarg; - } - - MALLOC(ab, struct ieee1394_abuf *, sizeof(*ab), M_1394DATA, M_WAITOK); - MPRINTF("MALLOC(1394DATA)", ab); - bzero(ab, sizeof(*ab)); - MALLOC(ab2, struct ieee1394_abuf *, sizeof(*ab2), M_1394DATA, M_WAITOK); - MPRINTF("MALLOC(1394DATA)", ab2); - bzero(ab2, sizeof(*ab2)); - - ab->ab_req = (struct ieee1394_softc *)sc; - ab->ab_length = 8; - ab->ab_retlen = 0; - ab->ab_cb = NULL; - ab->ab_cbarg = NULL; - ab->ab_addr = ac->ac_mgmt_agent; - ab->ab_tcode = IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK; - - ab->ab_data = malloc(8, M_1394DATA, M_WAITOK); - MPRINTF("malloc(1394DATA)", ab->ab_data); - - addr = SBP2_MGMT_ORB + - ((u_int64_t)ac->ac_nodeid << SBP2_NODE_SHIFT) + - ((u_int64_t)ac->ac_lun << SBP2_LUN_SHIFT); - ab->ab_data[0] = htonl((u_int32_t)(addr >> 32)); - ab->ab_data[1] = htonl((u_int32_t)(addr & 0xFFFFFFFF)); - DPRINTF((" CSR = 0x%012qx", ac->ac_mgmt_agent)); - DPRINTF((", ORB = 0x%012qx\n", addr)); - - ab2->ab_length = sizeof(struct sbp2_login_orb); - ab2->ab_tcode = IEEE1394_TCODE_READ_REQUEST_DATABLOCK; - ab2->ab_retlen = 0; - ab2->ab_data = NULL; - ab2->ab_addr = addr; - ab2->ab_cb = sbp2_login_send; - ab2->ab_cbarg = ac; - ab2->ab_req = (struct ieee1394_softc *)sc; - - sc->sc1394_inreg(ab2, FALSE); - sc->sc1394_write(ab); - DPRINTF(("%s: LOGIN submitted\n", __func__)); -} - -void -sbp2_login_send(struct ieee1394_abuf *ab, int rcode) -{ - struct fwnode_softc *sc = (struct fwnode_softc *)ab->ab_req; - struct sbp2_account *ac = ab->ab_cbarg; - struct sbp2_login_orb *login_orb; - struct ieee1394_abuf *stat_ab, *resp_ab, *orb_ab; - u_int64_t addr; -#ifdef SBP2_DEBUG - int i; -#endif /* SBP2_DEBUG */ - - /* Got a read so allocate the buffer and write out the response. */ - - if (rcode || (ac == NULL)) { - DPRINTF(("%s: Bad return code: %d\n", __func__, rcode)); - if (ab->ab_data) { - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; /* XXX */ - } - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - return; - } - - MALLOC(orb_ab, struct ieee1394_abuf *, sizeof(*orb_ab), - M_1394DATA, M_WAITOK); - MPRINTF("MALLOC(1394DATA)", orb_ab); - bcopy(ab, orb_ab, sizeof(*orb_ab)); - - sc->sc1394_unreg(ab, FALSE); - - if (ab->ab_data) { - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; /* XXX */ - orb_ab->ab_data = NULL; - } - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - - MALLOC(resp_ab, struct ieee1394_abuf *, sizeof(*resp_ab), - M_1394DATA, M_WAITOK); - MPRINTF("MALLOC(1394DATA)", resp_ab); - MALLOC(stat_ab, struct ieee1394_abuf *, sizeof(*stat_ab), - M_1394DATA, M_WAITOK); - MPRINTF("MALLOC(1394DATA)", stat_ab); - bzero(resp_ab, sizeof(*resp_ab)); - bzero(stat_ab, sizeof(*stat_ab)); - - /* Fill in a login packet. First 2 quads are 0 for password. */ - login_orb = (struct sbp2_login_orb *)ac->ac_mgmt_orb; - - /* Addr for response. */ - addr = SBP2_RESP_BLOCK + - ((u_int64_t)ac->ac_nodeid << SBP2_NODE_SHIFT) + - ((u_int64_t)ac->ac_lun << SBP2_LUN_SHIFT); - resp_ab->ab_length = sizeof(struct sbp2_login_response); - resp_ab->ab_tcode = IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK; - resp_ab->ab_retlen = 0; - resp_ab->ab_data = NULL; - resp_ab->ab_addr = addr; - resp_ab->ab_cb = sbp2_status_resp; - resp_ab->ab_cbarg = ac; - resp_ab->ab_req = orb_ab->ab_req; - - login_orb->login_response.hi = htons((u_int16_t)(addr >> 32)); - login_orb->login_response.lo = htonl((u_int32_t)(addr & 0xFFFFFFFF)); - DPRINTF(("%s: RESP_ORB = 0x%012qx", __func__, addr)); - - sc->sc1394_inreg(resp_ab, FALSE); - - /* Set notify and exclusive use bits. */ - login_orb->options = htons(0x8000); - login_orb->lun = htons(ac->ac_lun); - - /* Password length (0) and login response length (16) */ - login_orb->password_length = htons(0); - login_orb->login_response_length = htons(16); - - /* Addr for status packet. */ -#if 0 - addr = SBP2_STATUS_BLOCK + - ((u_int64_t)ac->ac_nodeid << SBP2_NODE_SHIFT) + - ((u_int64_t)ac->ac_lun << SBP2_LUN_SHIFT); -#else - addr = SBP2_STATUS_BLOCK; -#endif - stat_ab->ab_length = sizeof(struct sbp2_status_block); - stat_ab->ab_tcode = IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK; - stat_ab->ab_retlen = 0; - stat_ab->ab_data = NULL; - stat_ab->ab_addr = addr; - stat_ab->ab_cb = sbp2_status_resp; - stat_ab->ab_cbarg = ac; - stat_ab->ab_req = orb_ab->ab_req; - - ac->ac_status_ab = stat_ab; - sc->sc1394_inreg(stat_ab, FALSE); - - login_orb->status_fifo.hi = htons((u_int16_t)(addr >> 32)); - login_orb->status_fifo.lo = htonl((u_int32_t)(addr & 0xFFFFFFFF)); - DPRINTF((", STATUS_ORB = 0x%012qx", addr)); - - orb_ab->ab_data = malloc(sizeof(*login_orb), M_1394DATA, M_WAITOK); - MPRINTF("malloc(1394DATA)", orb_ab->ab_data); - bcopy(login_orb, orb_ab->ab_data, sizeof(*login_orb)); -#ifdef SBP2_DEBUG - for (i = 0; i < (sizeof(*login_orb) / 4); i++) { - if ((i % 8) == 0) DPRINTFN(2, ("\n ")); - DPRINTFN(2, (" %08x", ntohl(orb_ab->ab_data[i]))); - } -#endif /* SBP2_DEBUG */ - DPRINTF(("\n")); - - orb_ab->ab_retlen = 0; - orb_ab->ab_cb = NULL; - orb_ab->ab_cbarg = NULL; - orb_ab->ab_tcode = IEEE1394_TCODE_READ_RESPONSE_DATABLOCK; - orb_ab->ab_length = sizeof(struct sbp2_login_orb); - - sc->sc1394_write(orb_ab); -} - -void -sbp2_status_resp(struct ieee1394_abuf *ab, int rcode) -{ - struct fwnode_softc *sc = (struct fwnode_softc *)ab->ab_req; - struct sbp2_account *ac = ab->ab_cbarg; - struct sbp2_login_response *login_resp; - struct sbp2_status_block *cmd_status; - struct sbp2_status_notification *status_notify; - struct sbp2_orb_element *elm; - int resp, src, status, len, dead; - u_int64_t csr, stat_addr = 0; -#ifdef SBP2_DEBUG - int i; -#endif /* SBP2_DEBUG */ - - if (!ac) { - DPRINTF(("%s: Callback Arg is NULL\n", __func__)); - - if (ab->ab_data) { - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; /* XXX */ - } - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - return; - } -#if 0 - stat_addr = SBP2_STATUS_BLOCK + - ((u_int64_t)ac->ac_nodeid << SBP2_NODE_SHIFT) + - ((u_int64_t)ac->ac_lun << SBP2_LUN_SHIFT); -#else - stat_addr = SBP2_STATUS_BLOCK; -#endif - - if (rcode) { - DPRINTF(("%s: Bad return code: %d\n", __func__, rcode)); - - if (ab->ab_data) { - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; /* XXX */ - } - if (ab->ab_addr != stat_addr) { - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - } - return; - } - -#ifdef SBP2_DEBUG - DPRINTF(("%s: CSR = 0x%012qx, ac = 0x%08x", __func__, - (quad_t)ab->ab_addr, (u_int32_t)ac)); - for (i = 0; i < (ab->ab_retlen / 4); i++) { - if ((i % 8) == 0) DPRINTFN(2, ("\n ")); - DPRINTFN(2, (" %08x", ntohl(ab->ab_data[i]))); - } - DPRINTF(("\n")); -#endif /* SBP2_DEBUG */ - - if (ab->ab_addr == stat_addr) { - MALLOC(cmd_status, struct sbp2_status_block *, - sizeof(*cmd_status), M_1394DATA, M_WAITOK); - MPRINTF("MALLOC(1394DATA)", cmd_status); - bzero(cmd_status, sizeof(*cmd_status)); - bcopy(ab->ab_data, cmd_status, ab->ab_retlen); - - /* Reset status ab for subsequent notifications. */ - ab->ab_retlen = 0; - ab->ab_length = sizeof(*cmd_status); - - src = (cmd_status->flags >> 6) & 0x3; - resp = (cmd_status->flags >> 4) & 0x3; - dead = (cmd_status->flags >> 3) & 0x1; - len = cmd_status->flags & 0x7; - status = cmd_status->status; - csr = ((u_int64_t)(ntohs(cmd_status->orb_offset_hi)) << 32) + - ntohl(cmd_status->orb_offset_lo); - DPRINTF((" status -- src: %d, resp: %d, dead: %d, len: %d, " - "status: %d\n status -- csr: 0x%012qx\n", src, resp, dead, - (len + 1) * 4, status, (quad_t)csr)); - if (ac->ac_valid & 4) { - DPRINTF(("Notify callback\n")); - elm = sbp2_elfind_hash((u_int32_t)(csr >> - (SBP2_NODE_SHIFT - 8 * sizeof(u_int32_t)))); - if (elm == NULL) { - DPRINTF(("%s: no element found for hash" - " 0x%08x\n", __func__, - (u_int32_t)(csr >> (SBP2_NODE_SHIFT - - 8 * sizeof(u_int32_t))))); - FREE(cmd_status, M_1394DATA); - MPRINTF("FREE(1394DATA)", cmd_status); - cmd_status = NULL; /* XXX */ - goto leave; - } - MALLOC(status_notify, struct sbp2_status_notification *, - sizeof(*status_notify), M_1394CTL, M_WAITOK); - MPRINTF("MALLOC(1394CTL)", status_notify); - status_notify->origin = elm->elm_orb; - status_notify->status = cmd_status; - elm->elm_cb(elm->elm_cbarg, status_notify); - FREE(status_notify, M_1394CTL); - MPRINTF("FREE(1394CTL)", status_notify); - status_notify = NULL; /* XXX */ - } else if (((src & 2) == 0) && (resp == 0) && (dead == 0) && - (status == 0) && (csr == (SBP2_MGMT_ORB + - ((u_int64_t)ac->ac_nodeid << SBP2_NODE_SHIFT) + - ((u_int64_t)ac->ac_lun << SBP2_LUN_SHIFT)))) { - if (ac->ac_status_block) { - FREE(ac->ac_status_block, M_1394DATA); - MPRINTF("FREE(1394DATA)", ac->ac_status_block); - ac->ac_status_block = NULL; /* XXX */ - } - ac->ac_status_block = cmd_status; - DPRINTF(("Got a valid status\n")); - ac->ac_valid |= 2; - } else { - FREE(cmd_status, M_1394DATA); - MPRINTF("FREE(1394DATA)", cmd_status); - cmd_status = NULL; /* XXX */ - } - - } else if (ab->ab_addr == (SBP2_RESP_BLOCK + - ((u_int64_t)ac->ac_nodeid << SBP2_NODE_SHIFT) + - ((u_int64_t)ac->ac_lun << SBP2_LUN_SHIFT))) { - login_resp = (struct sbp2_login_response *)ab->ab_data; - - ac->ac_response_block = login_resp; - ac->ac_login = ntohs(login_resp->login_id); - ac->ac_fetch_agent = - ((u_int64_t)(ntohs(login_resp->fetch_agent.hi)) << 32) + - ntohl(login_resp->fetch_agent.lo); - ac->ac_reconnect_hold = ntohs(login_resp->reconnect_hold); - - sc->sc_sc1394.sc1394_callback.cb1394_busreset = sbp2_reconnect; - - DPRINTF(("Got a valid response\n")); - DPRINTF(("Login ID : 0x%04x, Command Agent : 0x%012qx\n", - ac->ac_login, ac->ac_fetch_agent)); - - ac->ac_valid |= 1; - } - if ((ac->ac_valid & 7) == 3) { - DPRINTF(("Valid response : notify callback\n")); - if (ac->ac_cb != NULL) { - MALLOC(status_notify, struct sbp2_status_notification *, - sizeof(*status_notify), M_1394CTL, M_WAITOK); - MPRINTF("MALLOC(1394CTL)", status_notify); - status_notify->origin = ac->ac_mgmt_orb; - status_notify->status = cmd_status; - ac->ac_cb(ac->ac_cbarg, status_notify); - FREE(status_notify, M_1394CTL); - MPRINTF("FREE(1394CTL)", status_notify); - status_notify = NULL; /* XXX */ - } - ac->ac_valid |= 4; - } - - /* - * Leave the handler for status since unsolicited status will get sent - * to the addr specified in the login packet. - */ - -leave: - if (ab->ab_data != NULL) { - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; - } - - if (ab->ab_addr != stat_addr) { - sc->sc1394_unreg(ab, FALSE); - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - } - -} - -void -sbp2_query_logins(struct fwnode_softc *sc, struct sbp2_query_logins_orb *orb, - void (*cb)(void *, struct sbp2_status_notification *), void *arg) -{ -} - -void -sbp2_command_add(struct fwnode_softc *sc, int lun, - struct sbp2_command_orb *orb, int qlen, void *data, - void (*cb)(void *, struct sbp2_status_notification *), void *cbarg) -{ - struct ieee1394_abuf *ab, *ab2; - struct sbp2_account *ac; - struct sbp2_orb_element *elm, *elast; - u_int64_t addr; - u_int32_t ehash; - - if ((ac = sbp2_acfind(sc, lun)) == NULL) { - DPRINTF(("%s: destination not initialized\n", __func__)); - return; - } - - DPRINTF(("%s:\n", __func__)); - - /* Initialise orb address hash. */ - do { - ehash = arc4random(); - } while (sbp2_elfind_hash(ehash) != TAILQ_END(&sbp2_elm_head)); - - addr = SBP2_CMD_ORB + - ((u_int64_t)sc->sc_sc1394.sc1394_node_id << SBP2_NODE_SHIFT) + - ((u_int64_t)ehash << (SBP2_NODE_SHIFT - 8 * sizeof(u_int32_t))); - orb->next_orb.flag = htons(SBP2_NULL_ORB); - - MALLOC(elm, struct sbp2_orb_element *, sizeof(*elm), - M_1394CTL, M_WAITOK); - MPRINTF("MALLOC(1394CTL)", elm); - bzero(elm, sizeof(*elm)); - elm->elm_hash = ehash; - elm->elm_orb = orb; - elm->elm_orblen = qlen; - elm->elm_data = data; - elm->elm_datasize = ntohs(orb->data_size); - elm->elm_cb = cb; - elm->elm_cbarg = cbarg; - TAILQ_INSERT_TAIL(&sbp2_elm_head, elm, elm_chain); - - MALLOC(ab2, struct ieee1394_abuf *, sizeof(*ab2), M_1394DATA, M_WAITOK); - MPRINTF("MALLOC(1394DATA)", ab2); - bzero(ab2, sizeof(*ab2)); - - ab2->ab_length = sizeof(u_int32_t) * qlen; - ab2->ab_tcode = IEEE1394_TCODE_READ_REQUEST_DATABLOCK; - ab2->ab_retlen = 0; - ab2->ab_data = NULL; - ab2->ab_addr = addr; - ab2->ab_cb = sbp2_command_send; - ab2->ab_cbarg = ac; - ab2->ab_req = (struct ieee1394_softc *)sc; - - elm->elm_orb_ab = ab2; - sc->sc1394_inreg(ab2, FALSE); - - elast = sbp2_elfind_last(ac); - if (elast != TAILQ_END(&sbp2_elm_head)) { - DPRINTF(("%s: chaining to orb 0x%08x", __func__, - elast->elm_orb)); - elast->elm_orb->next_orb.flag = 0; - elast->elm_orb->next_orb.hi = htons((u_int16_t)(addr >> 32)); - elast->elm_orb->next_orb.lo = - htonl((u_int32_t)(addr & 0xFFFFFFFF)); - sbp2_agent_tickle(sc, lun); - } else { - MALLOC(ab, struct ieee1394_abuf *, sizeof(*ab), - M_1394DATA, M_WAITOK); - MPRINTF("MALLOC(1394DATA)", ab); - bzero(ab, sizeof(*ab)); - - ab->ab_req = (struct ieee1394_softc *)sc; - ab->ab_length = 8; - ab->ab_retlen = 0; - ab->ab_cb = NULL; - ab->ab_cbarg = NULL; - ab->ab_addr = ac->ac_fetch_agent + SBP2_ORB_POINTER; - ab->ab_tcode = IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK; - - ab->ab_data = malloc(8, M_1394DATA, M_WAITOK); - MPRINTF("malloc(1394DATA)", ab->ab_data); - ab->ab_data[0] = htonl((u_int32_t)(addr >> 32)); - ab->ab_data[1] = htonl((u_int32_t)(addr & 0xFFFFFFFF)); - ac->ac_valid |= 8; - - sbp2_agent_reset(sc, lun); - - DPRINTF(("%s: CSR = 0x%012qx", __func__, ab->ab_addr)); - sc->sc1394_write(ab); - } - - DPRINTF((", ORB = 0x%012qx", addr)); - DPRINTF((", orb = 0x%08x", (u_int32_t)orb)); - DPRINTF((", ac = 0x%08x\n", (u_int32_t)ac)); - DPRINTF(("%s: COMMAND submitted\n", __func__)); - - return; -} - -void -sbp2_command_del(struct fwnode_softc *sc, int lun, struct sbp2_command_orb *orb) -{ - struct sbp2_account *ac; - struct sbp2_orb_element *elm; - - if ((ac = sbp2_acfind(sc, lun)) == NULL) { - DPRINTF(("%s: destination not initialized\n", __func__)); - return; - } - - DPRINTF(("%s:", __func__)); - - if ((elm = sbp2_elfind_orb(orb)) == TAILQ_END(&sbp2_elm_head)) { -#ifdef SBP2_DEBUG - DPRINTF((" ORB not found: 0x%08x\n", (u_int32_t)orb)); -#endif /* SBP2_DEBUG */ - return; - } - - DPRINTF((" orb=0x%08x hash=0x%08x len=%d data=0x%08x size=%d\n", - (u_int32_t)(elm->elm_orb), elm->elm_hash, elm->elm_orblen, - (u_int32_t)(elm->elm_data), elm->elm_datasize)); - - if (elm->elm_orb_ab != NULL) { - sc->sc1394_unreg(elm->elm_orb_ab, FALSE); - if (elm->elm_orb_ab->ab_data != NULL) { - free(elm->elm_orb_ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", elm->elm_orb_ab->ab_data); - elm->elm_orb_ab->ab_data = NULL; /* XXX */ - } - FREE(elm->elm_orb_ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", elm->elm_orb_ab); - elm->elm_orb_ab = NULL; /* XXX */ - } - - TAILQ_REMOVE(&sbp2_elm_head, elm, elm_chain); - FREE(elm, M_1394CTL); - MPRINTF("FREE(1394CTL)", elm); - elm = NULL; /* XXX */ - - if (sbp2_elfind_last(ac) == TAILQ_END(&sbp2_elm_head)) - ac->ac_valid &= ~8; -} - -void -sbp2_command_send(struct ieee1394_abuf *ab, int rcode) -{ - struct fwnode_softc *sc = (struct fwnode_softc *)ab->ab_req; - struct sbp2_account *ac = ab->ab_cbarg; - struct sbp2_orb_element *elm; - struct ieee1394_abuf *cmd_ab; - int i; - - /* Got a read so allocate the buffer and write out the response. */ - - if (rcode || (ac == NULL)) { -#ifdef SBP2_DEBUG - DPRINTF(("%s: Bad return code: %d\n", __func__, rcode)); -#endif /* SBP2_DEBUG */ - if (ab->ab_data) { - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; /* XXX */ - } - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - return; - } - - if (ab->ab_data != NULL) { - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; - } - - if ((elm = sbp2_elfind_hash((u_int32_t)(ab->ab_addr >> - (SBP2_NODE_SHIFT - 8 * sizeof(u_int32_t))))) - == TAILQ_END(&sbp2_elm_head)) { -#ifdef SBP2_DEBUG - DPRINTF(("%s: ORB not found: 0x%012qx\n", __func__, - ab->ab_addr)); -#endif /* SBP2_DEBUG */ - if (ab->ab_data != NULL) { - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; /* XXX */ - } - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - return; - } - - DPRINTF(("%s: orb=0x%08x hash=0x%08x len=%d data=0x%08x size=%d\n", - __func__, (u_int32_t)(elm->elm_orb), elm->elm_hash, - elm->elm_orblen, (u_int32_t)(elm->elm_data), elm->elm_datasize)); - - MALLOC(cmd_ab, struct ieee1394_abuf *, sizeof(*cmd_ab), - M_1394DATA, M_WAITOK); - MPRINTF("MALLOC(1394DATA)", cmd_ab); - bcopy(ab, cmd_ab, sizeof(*cmd_ab)); - - cmd_ab->ab_retlen = 0; - cmd_ab->ab_cb = NULL; - cmd_ab->ab_cbarg = NULL; - cmd_ab->ab_tcode = IEEE1394_TCODE_READ_RESPONSE_DATABLOCK; - cmd_ab->ab_length = ab->ab_retlen; - - cmd_ab->ab_data = malloc(elm->elm_orblen * 4, M_1394DATA, M_WAITOK); - MPRINTF("malloc(1394DATA)", cmd_ab->ab_data); - bcopy(elm->elm_orb, cmd_ab->ab_data, elm->elm_orblen * 4); - for (i = 0; i < elm->elm_orblen; i++) { - if ((i % 8) == 0) DPRINTF((" ")); - DPRINTF((" %08x", ntohl(cmd_ab->ab_data[i]))); - if ((i % 8) == 7 && i != (elm->elm_orblen - 1)) DPRINTF(("\n")); - } - DPRINTF(("\n")); - - sc->sc1394_write(cmd_ab); -} - -void -sbp2_reconnect(struct ieee1394_softc *sc) -{ - struct ieee1394_abuf *ab, *orb_ab, *stat_ab; - struct sbp2_account *ac; - struct sbp2_reconnect_orb *orb; - struct fwnode_softc *fwsc = (struct fwnode_softc *)sc; - u_int16_t old_nodeid; - u_int64_t addr; - - DPRINTF(("%s:", __func__)); - - SLIST_FOREACH(ac, &sbp2_ac_head, ac_chain) { - if (ac != NULL && ac->ac_softc == fwsc) { - - MALLOC(ab, struct ieee1394_abuf *, sizeof(*ab), - M_1394DATA, M_NOWAIT); - MPRINTF("MALLOC(1394DATA)", ab); - if (!ab) { - printf("%s: memory allocation failure.\n", - __func__); - return; - } - bzero(ab, sizeof(*ab)); - ab->ab_data = malloc(8, M_1394DATA, M_NOWAIT); - MPRINTF("malloc(1394DATA)", ab->ab_data); - if (!ab->ab_data) { - printf("%s: memory allocation failure.\n", - __func__); - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - return; - } - MALLOC(orb_ab, struct ieee1394_abuf *, sizeof(*orb_ab), - M_1394DATA, M_NOWAIT); - MPRINTF("MALLOC(1394DATA)", orb_ab); - if (!orb_ab) { - printf("%s: memory allocation failure.\n", - __func__); - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - return; - } - bzero(orb_ab, sizeof(*orb_ab)); - MALLOC(stat_ab, struct ieee1394_abuf *, - sizeof(*stat_ab), M_1394DATA, M_NOWAIT); - MPRINTF("MALLOC(1394DATA)", stat_ab); - if (!stat_ab) { - printf("%s: memory allocation failure.\n", - __func__); - FREE(orb_ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", orb_ab); - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - return; - } - bzero(stat_ab, sizeof(*stat_ab)); - orb = malloc(sizeof(*orb), M_1394DATA, M_NOWAIT); - MPRINTF("malloc(1394DATA)", orb); - if (!orb) { - printf("%s: memory allocation failure.\n", - __func__); - FREE(stat_ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", stat_ab); - FREE(orb_ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", orb_ab); - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - return; - } - bzero(orb, sizeof(*orb)); - - old_nodeid = ac->ac_nodeid; - ac->ac_nodeid = sc->sc1394_node_id; - //ac->ac_valid = 1; - - /* Re-register the status block with the new nodeid. */ - sc->sc1394_node_id = old_nodeid; - fwsc->sc1394_unreg(ac->ac_status_ab, FALSE); - sc->sc1394_node_id = ac->ac_nodeid; - fwsc->sc1394_inreg(ac->ac_status_ab, FALSE); - - /* Register a transient status block. */ - addr = SBP2_STATUS_BLOCK + - ((u_int64_t)ac->ac_nodeid << SBP2_NODE_SHIFT) + - ((u_int64_t)ac->ac_lun << SBP2_LUN_SHIFT) + - SBP2_RECONNECT_OFFSET; - stat_ab->ab_length = sizeof(struct sbp2_status_block); - stat_ab->ab_tcode = - IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK; - stat_ab->ab_retlen = 0; - stat_ab->ab_data = NULL; - stat_ab->ab_addr = addr; - stat_ab->ab_cb = sbp2_status_resp; - stat_ab->ab_cbarg = ac; - stat_ab->ab_req = sc; - - fwsc->sc1394_inreg(stat_ab, FALSE); - - /* Construct the RECONNECT orb. */ - orb->options = htons(SBP2_ORB_RECONNECT); - orb->login_id = htons(ac->ac_login); - orb->status_fifo.hi = - htons((u_int16_t)(addr >> 32)); - orb->status_fifo.lo = - htonl((u_int32_t)(addr & 0xFFFFFFFF)); - - addr = SBP2_MGMT_ORB + - ((u_int64_t)ac->ac_nodeid << SBP2_NODE_SHIFT) + - ((u_int64_t)ac->ac_lun << SBP2_LUN_SHIFT); - orb_ab->ab_length = sizeof(struct sbp2_reconnect_orb); - orb_ab->ab_tcode = - IEEE1394_TCODE_READ_REQUEST_DATABLOCK; - orb_ab->ab_retlen = 0; - orb_ab->ab_data = NULL; - orb_ab->ab_addr = addr; - orb_ab->ab_cb = sbp2_reconnect_send; - orb_ab->ab_cbarg = orb; - orb_ab->ab_req = sc; - - fwsc->sc1394_inreg(orb_ab, FALSE); - - /* Invoque the RECONNECT management command. */ - ab->ab_req = sc; - ab->ab_length = 8; - ab->ab_retlen = 0; - ab->ab_cb = NULL; - ab->ab_cbarg = NULL; - ab->ab_addr = ac->ac_mgmt_agent; - ab->ab_tcode = IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK; - ab->ab_data[0] = htonl((u_int32_t)(addr >> 32)); - ab->ab_data[1] = htonl((u_int32_t)(addr & 0xFFFFFFFF)); - DPRINTF((" CSR = 0x%012qx", ac->ac_mgmt_agent)); - DPRINTF((", ORB = 0x%012qx\n", addr)); - - fwsc->sc1394_write(ab); - DPRINTF(("%s: %04x RECONNECT submitted\n", __func__, - ac->ac_login)); - } - } -} - -void -sbp2_reconnect_send(struct ieee1394_abuf *ab, int rcode) -{ - struct ieee1394_abuf *orb_ab; - struct fwnode_softc *sc = (struct fwnode_softc *)ab->ab_req; - - if (rcode) { - DPRINTF(("%s: Bad return code: %d\n", __func__, rcode)); - if (ab->ab_data > (u_int32_t *)1) { - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; /* XXX */ - } - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - return; - } - - MALLOC(orb_ab, struct ieee1394_abuf *, sizeof(*orb_ab), - M_1394DATA, M_NOWAIT); - MPRINTF("MALLOC(1394DATA)", orb_ab); - if (!orb_ab) { - printf("%s: memory allocation failure.\n", - __func__); - return; - } - - bcopy(ab, orb_ab, sizeof(*orb_ab)); - - sc->sc1394_unreg(ab, FALSE); - if (ab->ab_data) { - free(ab->ab_data, M_1394DATA); - MPRINTF("free(1394DATA)", ab->ab_data); - ab->ab_data = NULL; /* XXX */ - orb_ab->ab_data = NULL; - } - FREE(ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", ab); - ab = NULL; /* XXX */ - - if (!orb_ab->ab_cbarg) { - DPRINTF(("%s: orb lost !\n", __func__)); - FREE(orb_ab, M_1394DATA); - MPRINTF("FREE(1394DATA)", orb_ab); - orb_ab = NULL; /* XXX */ - return; - } - orb_ab->ab_data = (u_int32_t *)orb_ab->ab_cbarg; - orb_ab->ab_length = sizeof(struct sbp2_reconnect_orb); - orb_ab->ab_retlen = 0; - orb_ab->ab_cb = NULL; - orb_ab->ab_cbarg = NULL; - orb_ab->ab_tcode = IEEE1394_TCODE_READ_RESPONSE_DATABLOCK; - - sc->sc1394_write(orb_ab); -} - -void -sbp2_agent_reset(struct fwnode_softc *sc, int lun) -{ - struct ieee1394_abuf *ab; - struct sbp2_account *ac; - - if ((ac = sbp2_acfind(sc, lun)) == NULL) { - DPRINTF(("%s: destination not initialized\n", __func__)); - return; - } - - DPRINTF(("%s:", __func__)); - - MALLOC(ab, struct ieee1394_abuf *, sizeof(*ab), M_1394DATA, M_WAITOK); - MPRINTF("MALLOC(1394DATA)", ab); - bzero(ab, sizeof(*ab)); - - ab->ab_req = (struct ieee1394_softc *)sc; - ab->ab_length = 4; - ab->ab_retlen = 0; - ab->ab_cb = NULL; - ab->ab_cbarg = NULL; - ab->ab_addr = ac->ac_fetch_agent + SBP2_AGENT_RESET; - ab->ab_tcode = IEEE1394_TCODE_WRITE_REQUEST_QUADLET; - - ab->ab_data = malloc(4, M_1394DATA, M_WAITOK); - MPRINTF("malloc(1394DATA)", ab->ab_data); - ab->ab_data[0] = 0; - DPRINTF((" CSR = 0x%012qx\n", ab->ab_addr)); - - sc->sc1394_write(ab); - DPRINTF(("%s: AGENT_RESET submitted\n", __func__)); - -} - -void -sbp2_agent_tickle(struct fwnode_softc *sc, int lun) -{ - struct ieee1394_abuf *ab; - struct sbp2_account *ac; - - if ((ac = sbp2_acfind(sc, lun)) == NULL) { - DPRINTF(("%s: destination not initialized\n", __func__)); - return; - } - - DPRINTF(("%s:", __func__)); - - MALLOC(ab, struct ieee1394_abuf *, sizeof(*ab), M_1394DATA, M_WAITOK); - MPRINTF("MALLOC(1394DATA)", ab); - bzero(ab, sizeof(*ab)); - - ab->ab_req = (struct ieee1394_softc *)sc; - ab->ab_length = 4; - ab->ab_retlen = 0; - ab->ab_cb = NULL; - ab->ab_cbarg = NULL; - ab->ab_addr = ac->ac_fetch_agent + SBP2_DOORBEL; - ab->ab_tcode = IEEE1394_TCODE_WRITE_REQUEST_QUADLET; - - ab->ab_data = malloc(4, M_1394DATA, M_WAITOK); - MPRINTF("malloc(1394DATA)", ab->ab_data); - ab->ab_data[0] = 0; - DPRINTF((" CSR = 0x%012qx\n", ab->ab_addr)); - - sc->sc1394_write(ab); - DPRINTF(("%s: DOORBEL submitted\n", __func__)); - -} - -int -sbp2_agent_state(struct fwnode_softc *sc, int lun) -{ - return (0); -} - -void -sbp2_task_management(struct fwnode_softc *sc, - struct sbp2_task_management_orb *orb, - void (*cb)(void *, struct sbp2_status_notification *), void *arg) -{ -} - diff --git a/sys/dev/std/sbp2reg.h b/sys/dev/std/sbp2reg.h deleted file mode 100644 index bc42cf4b87f..00000000000 --- a/sys/dev/std/sbp2reg.h +++ /dev/null @@ -1,115 +0,0 @@ -/* $OpenBSD: sbp2reg.h,v 1.2 2002/12/30 11:48:34 tdeval Exp $ */ - -/* - * Copyright (c) 2002 Thierry Deval. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_STD_SBP2REG_H_ -#define _DEV_STD_SBP2REG_H_ - -#define SBP2_UNIT_SPEC_ID 0x00609E /* NCITS OUI */ -#define SBP2_UNIT_SW_VERSION 0x010483 - -/* 0x38/8, oui/24 Unit Directory - */ -#define SBP2_KEYVALUE_Command_Set_Spec_Id 0x38 /* immediate (OUI) */ - -/* 0x39/8, oui/24 Unit Directory - */ -#define SBP2_KEYVALUE_Command_Set 0x39 /* immediate (OUI) */ - -/* 0x54/8, offset/24 Unit Directory - */ -#define SBP2_KEYVALUE_Management_Agent \ - P1212_KEYVALUE_Unit_Dependent_Info /* offset */ - -/* 0x3A/8, reserved/8, Unit Directory - * msg_ORB_timeout/8, ORB_size/8 - */ -#define SBP2_KEYVALUE_Unit_Characteristics 0x3A /* immediate */ - -/* 0x3B/8, reserver/8, max_reconnect_hold/16 Unit Directory - */ -#define SBP2_KEYVALUE_Command_Set_Revision 0x3B /* immediate */ - -/* 0x3C/8, firmware_revision/24 Unit Directory - */ -#define SBP2_KEYVALUE_Firmware_Revision 0x3C /* immediate */ - -/* 0x3D/8, reserver/8, max_reconnect_hold/16 Unit Directory - */ -#define SBP2_KEYVALUE_Reconnect_Timeout 0x3D /* immediate */ - -/* 0xD4/8, indirect_offset/24 Unit Directory - */ -#define SBP2_KEYVALUE_Logical_Unit_Directory \ - P1212_KEYVALUE_Unit_Dependent_Info /* directory */ - -/* 0x14/8, reserved/1, ordered/1, reserved/1 Unit Directory - * device_type/5, lun/16 - */ -#define SBP2_KEYVALUE_Logical_Unit_Number \ - P1212_KEYVALUE_Unit_Dependent_Info /* immediate */ - -/* 0x8D/8, indirect_offset/24 Unit Directory - */ -#define SBP2_KEYVALUE_Unit_Unique_Id \ - P1212_KEYVALUE_Node_Unique_Id /* leaf */ - -#define SBP2_ORB_LOGIN 0 -#define SBP2_ORB_QUERY_LOGINS 1 -#define SBP2_ORB_RECONNECT 3 -#define SBP2_ORB_LOGOUT 7 - -#define SBP2_NULL_ORB_PTR 0x8000000000000000UL - -#define SBP2_MGMT_ORB 0x400000000000UL -#define SBP2_CMD_ORB 0x440000000000UL - -#define SBP2_RESP_BLOCK 0x480000000000UL -#define SBP2_STATUS_BLOCK 0x4C0000000000UL -#define SBP2_DATA_BLOCK 0x500000000000UL - -#define SBP2_DATA_MASK 0x03FFFFFFFFFFUL -#define SBP2_DATA_LEN 42 -#define SBP2_DATA_SHIFT 10 /* With 32 bits hash. */ - -/* - * Some convention to separate addresses between nodes and luns. - */ -#define SBP2_NODE_MASK 0x03F000000000UL -#define SBP2_NODE_SHIFT 36 -#define SBP2_LUN_MASK 0x000FFFF00000UL -#define SBP2_LUN_SHIFT 20 -#define SBP2_RECONNECT_OFFSET 0x70 /* Transient status. */ - -#define SBP2_AGENT_STATE 0x00 -#define SBP2_AGENT_RESET 0x04 -#define SBP2_ORB_POINTER 0x08 -#define SBP2_DOORBEL 0x10 -#define SBP2_UNSOLICITED_STATUS_ENABLE 0x14 - -#define SBP2_MAX_TRANS (1024 * 1024) -#define SBP2_MAX_LUNS 8 - -#endif /* _DEV_STD_SBP2REG_H_ */ diff --git a/sys/dev/std/sbp2var.h b/sys/dev/std/sbp2var.h deleted file mode 100644 index 50310e35ae5..00000000000 --- a/sys/dev/std/sbp2var.h +++ /dev/null @@ -1,198 +0,0 @@ -/* $OpenBSD: sbp2var.h,v 1.2 2002/12/30 11:48:34 tdeval Exp $ */ - -/* - * Copyright (c) 2002 Thierry Deval. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_STD_SBP2VAR_H_ -#define _DEV_STD_SBP2VAR_H_ - -struct fwnode_softc; -struct fwnode_device_cap; -struct p1212_dir; - -typedef struct sbp2_addr { - u_int16_t node_id; - u_int16_t hi; - u_int32_t lo; -} sbp2_addr_t; - -typedef struct sbp2_orb { - u_int16_t flag; -#define SBP2_NULL_ORB 0x8000 - u_int16_t hi; - u_int32_t lo; -} sbp2_orb_t; - -typedef struct sbp2_pte_u { - u_int16_t segmentLength; - u_int16_t segmentBaseAddress_Hi; - u_int32_t segmentBaseAddress_Lo; -} sbp2_pte_u; - -typedef struct sbp2_pte_n { - u_int16_t segmentLength; - u_int16_t segmentBaseAddress_Hi; - u_int32_t segmentBaseAddress_Offset; -} sbp2_pte_n; - -typedef struct sbp2_command_orb { - sbp2_orb_t next_orb; - sbp2_addr_t data_descriptor; - u_int16_t options; -#define SBP2_DUMMY_TYPE 0x6000 - u_int16_t data_size; - u_int32_t command_block[1]; /* most certainly more */ -} sbp2_command_orb; - -typedef struct sbp2_task_management_orb { - sbp2_orb_t orb_offset; - u_int32_t reserved[2]; - u_int16_t options; - u_int16_t login_id; - u_int32_t reserved2; - sbp2_addr_t status_fifo; -} sbp2_task_management_orb; - -typedef struct sbp2_login_orb { - sbp2_addr_t password; - sbp2_addr_t login_response; - u_int16_t options; - u_int16_t lun; - u_int16_t password_length; - u_int16_t login_response_length; - sbp2_addr_t status_fifo; -} sbp2_login_orb; - -typedef struct sbp2_login_response { - u_int16_t length; - u_int16_t login_id; - sbp2_addr_t fetch_agent; - u_int16_t reserved; - u_int16_t reconnect_hold; -} sbp2_login_response; - -typedef struct sbp2_reconnect_orb { - u_int32_t reserved[4]; - u_int16_t options; - u_int16_t login_id; - u_int32_t reserved2; - sbp2_addr_t status_fifo; -} sbp2_reconnect_orb; - -typedef struct sbp2_query_logins_orb { - u_int32_t reserved[2]; - sbp2_addr_t query_response; - u_int16_t options; - u_int16_t lun; - u_int16_t reserved2; - u_int16_t query_response_length; - sbp2_addr_t status_fifo; -} sbp2_query_logins_orb; - -typedef struct sbp2_query_logins_response { - u_int16_t length; - u_int16_t max_logins; - struct { - u_int16_t node_id; - u_int16_t login_id; - sbp2_addr_t initiator; - } login_info[1]; /* most certainly more */ -} sbp2_query_logins_response; - -typedef struct sbp2_status_block { - u_int8_t flags; -#define SBP2_STATUS_SRC_MASK 0xC0 -#define SBP2_STATUS_RESPONSE_MASK 0x30 -#define SBP2_STATUS_RESP_REQ_COMPLETE 0x00 -#define SBP2_STATUS_RESP_TRANS_FAILURE 0x10 -#define SBP2_STATUS_RESP_ILLEGAL_REQ 0x20 -#define SBP2_STATUS_RESP_VENDOR 0x30 -#define SBP2_STATUS_DEAD 0x08 -#define SBP2_STATUS_LEN_MASK 0x07 - u_int8_t status; -#define SBP2_STATUS_NONE 0x00 -#define SBP2_STATUS_UNSUPPORTED_TYPE 0x01 -#define SBP2_STATUS_UNSUPPORTED_SPEED 0x02 -#define SBP2_STATUS_UNSUPPORTED_PGSIZ 0x03 -#define SBP2_STATUS_ACCESS_DENIED 0x04 -#define SBP2_STATUS_UNSUPPORTED_LUN 0x05 -#define SBP2_STATUS_MAX_PAYLOAD_SMALL 0x06 -#define SBP2_STATUS_RESOURCE_UNAVAIL 0x08 -#define SBP2_STATUS_FUNCTION_REJECTED 0x09 -#define SBP2_STATUS_INVALID_LOGINID 0x0A -#define SBP2_STATUS_DUMMY_ORB_COMPLETE 0x0B -#define SBP2_STATUS_REQUEST_ABORTED 0x0C -#define SBP2_STATUS_UNSPECIFIED 0xFF -#define SBP2_STATUS_OBJECT_MASK 0xC0 -#define SBP2_STATUS_OBJECT_ORB 0x00 -#define SBP2_STATUS_OBJECT_DATA_BUF 0x40 -#define SBP2_STATUS_OBJECT_PAGE_TABLE 0x80 -#define SBP2_STATUS_OBJECT_UNSPECIFIED 0xC0 -#define SBP2_STATUS_SERIAL_MASK 0x0F -#define SBP2_STATUS_SERIAL_ACK_MISSING 0x00 -#define SBP2_STATUS_SERIAL_TIMEOUT 0x02 -#define SBP2_STATUS_SERIAL_ACK_BUSY_X 0x04 -#define SBP2_STATUS_SERIAL_ACK_BUSY_A 0x05 -#define SBP2_STATUS_SERIAL_ACK_BUSY_B 0x06 -#define SBP2_STATUS_SERIAL_TARDY_RETRY 0x0B -#define SBP2_STATUS_SERIAL_CONFLICT 0x0C -#define SBP2_STATUS_SERIAL_DATA 0x0D -#define SBP2_STATUS_SERIAL_TYPE 0x0E -#define SBP2_STATUS_SERIAL_ADDRESS 0x0F - u_int16_t orb_offset_hi; - u_int32_t orb_offset_lo; - u_int32_t status_info[6]; -} sbp2_status_block; - - -/* - * A Status Notification structure containing both a reference to the - * original ORB, and the returned status info. - */ -typedef struct sbp2_status_notification { - void *origin; - struct sbp2_status_block *status; -} sbp2_status_notification; - - -int sbp2_match(struct device *, void *, void *); -void sbp2_print_dir(struct p1212_dir *); -void sbp2_print_data(struct p1212_data *); -int sbp2_init(struct fwnode_softc *, struct p1212_dir *); -void sbp2_clean(struct fwnode_softc *, struct p1212_dir *, int); -void sbp2_login(struct fwnode_softc *, struct sbp2_login_orb *, - void (*)(void *, struct sbp2_status_notification *), void *); -void sbp2_query_logins(struct fwnode_softc *, struct sbp2_query_logins_orb *, - void (*)(void *, struct sbp2_status_notification *), void *); -void sbp2_command_add(struct fwnode_softc *, int, struct sbp2_command_orb *, - int, void *, void (*)(void *, struct sbp2_status_notification *), void *); -void sbp2_command_del(struct fwnode_softc *, int, struct sbp2_command_orb *); -void sbp2_agent_reset(struct fwnode_softc *, int); -void sbp2_agent_tickle(struct fwnode_softc *, int); -int sbp2_agent_state(struct fwnode_softc *, int); -void sbp2_task_management(struct fwnode_softc *, - struct sbp2_task_management_orb *, - void (*)(void *, struct sbp2_status_notification *), void *); - -#endif /* _DEV_STD_SBP2VAR_H_ */ |