summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorkiyohara <kiyohara@NetBSD.org>2010-03-29 03:05:27 +0000
committerkiyohara <kiyohara@NetBSD.org>2010-03-29 03:05:27 +0000
commitaf09db112bcc2edf9000478840d7969acbb47de6 (patch)
treec9d7967429348bdcbca8ed447d3f15e9eb45cc92 /sys/dev
parent3fa2c4cfe9c9e11c2344b14ea5fd00695d97811a (diff)
Bye-bye fw_port.h.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/cardbus/fwohci_cardbus.c11
-rw-r--r--sys/dev/ieee1394/firewire.c2564
-rw-r--r--sys/dev/ieee1394/firewire.h105
-rw-r--r--sys/dev/ieee1394/firewire_phy.h8
-rw-r--r--sys/dev/ieee1394/firewirereg.h103
-rw-r--r--sys/dev/ieee1394/fw_port.h809
-rw-r--r--sys/dev/ieee1394/fwcrom.c163
-rw-r--r--sys/dev/ieee1394/fwdev.c842
-rw-r--r--sys/dev/ieee1394/fwdma.c212
-rw-r--r--sys/dev/ieee1394/fwdma.h69
-rw-r--r--sys/dev/ieee1394/fwmem.c497
-rw-r--r--sys/dev/ieee1394/fwmem.h45
-rw-r--r--sys/dev/ieee1394/fwohci.c3341
-rw-r--r--sys/dev/ieee1394/fwohcireg.h93
-rw-r--r--sys/dev/ieee1394/fwohcivar.h55
-rw-r--r--sys/dev/ieee1394/fwphyreg.h27
-rw-r--r--sys/dev/ieee1394/iec13213.h17
-rw-r--r--sys/dev/ieee1394/iec68113.h9
-rw-r--r--sys/dev/ieee1394/if_fwip.c826
-rw-r--r--sys/dev/ieee1394/if_fwipvar.h52
-rw-r--r--sys/dev/ieee1394/sbp.c2546
-rw-r--r--sys/dev/ieee1394/sbp.h12
-rw-r--r--sys/dev/pci/fwohci_pci.c26
23 files changed, 5167 insertions, 7265 deletions
diff --git a/sys/dev/cardbus/fwohci_cardbus.c b/sys/dev/cardbus/fwohci_cardbus.c
index 61fffce5784..5065167ab83 100644
--- a/sys/dev/cardbus/fwohci_cardbus.c
+++ b/sys/dev/cardbus/fwohci_cardbus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fwohci_cardbus.c,v 1.31 2010/03/05 00:36:06 dyoung Exp $ */
+/* $NetBSD: fwohci_cardbus.c,v 1.32 2010/03/29 03:05:27 kiyohara Exp $ */
/*-
* Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fwohci_cardbus.c,v 1.31 2010/03/05 00:36:06 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fwohci_cardbus.c,v 1.32 2010/03/29 03:05:27 kiyohara Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -47,7 +47,6 @@ __KERNEL_RCSID(0, "$NetBSD: fwohci_cardbus.c,v 1.31 2010/03/05 00:36:06 dyoung E
#include <dev/cardbus/cardbusvar.h>
#include <dev/pci/pcidevs.h>
-#include <dev/ieee1394/fw_port.h>
#include <dev/ieee1394/firewire.h>
#include <dev/ieee1394/firewirereg.h>
#include <dev/ieee1394/fwdma.h>
@@ -116,7 +115,7 @@ fwohci_cardbus_attach(device_t parent, device_t self, void *aux)
sc->sc_ct = ct;
/* Disable interrupts, so we don't get any spurious ones. */
- OHCI_CSR_WRITE(&sc->sc_sc, FWOHCI_INTMASKCLR, OHCI_INT_EN);
+ OWRITE(&sc->sc_sc, FWOHCI_INTMASKCLR, OHCI_INT_EN);
/* Enable the device. */
csr = Cardbus_conf_read(ct, ca->ca_tag, PCI_COMMAND_STATUS_REG);
@@ -124,14 +123,14 @@ fwohci_cardbus_attach(device_t parent, device_t self, void *aux)
csr | PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE);
sc->sc_ih = Cardbus_intr_establish(ct, ca->ca_intrline,
- IPL_BIO, fwohci_filt, sc);
+ IPL_BIO, fwohci_intr, sc);
if (sc->sc_ih == NULL) {
aprint_error_dev(self, "couldn't establish interrupt\n");
return;
}
/* XXX NULL should be replaced by some call to Cardbus coed */
- if (fwohci_init(&sc->sc_sc, sc->sc_sc.fc.dev) != 0) {
+ if (fwohci_init(&sc->sc_sc) != 0) {
Cardbus_intr_disestablish(ct, sc->sc_ih);
sc->sc_ih = NULL;
}
diff --git a/sys/dev/ieee1394/firewire.c b/sys/dev/ieee1394/firewire.c
index a33355f3feb..8a41023864f 100644
--- a/sys/dev/ieee1394/firewire.c
+++ b/sys/dev/ieee1394/firewire.c
@@ -1,4 +1,4 @@
-/* $NetBSD: firewire.c,v 1.26 2010/03/11 04:00:36 mrg Exp $ */
+/* $NetBSD: firewire.c,v 1.27 2010/03/29 03:05:27 kiyohara Exp $ */
/*-
* Copyright (c) 2003 Hidetoshi Shimokawa
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
@@ -31,55 +31,21 @@
* 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.
- *
- * $FreeBSD: src/sys/dev/firewire/firewire.c,v 1.101 2007/10/20 23:23:14 julian Exp $
+ *
+ * $FreeBSD: src/sys/dev/firewire/firewire.c,v 1.110 2009/04/07 02:33:46 sbruno Exp $
*
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: firewire.c,v 1.26 2010/03/11 04:00:36 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: firewire.c,v 1.27 2010/03/29 03:05:27 kiyohara Exp $");
-#if defined(__FreeBSD__)
#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/types.h>
-
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/conf.h>
-#include <sys/sysctl.h>
-#include <sys/kthread.h>
-
-#include <sys/kdb.h>
-
-#if defined(__DragonFly__) || __FreeBSD_version < 500000
-#include <machine/clock.h> /* for DELAY() */
-#endif
-
-#include <sys/bus.h> /* used by smbus and newbus */
#include <sys/bus.h>
-
-#ifdef __DragonFly__
-#include "fw_port.h"
-#include "firewire.h"
-#include "firewirereg.h"
-#include "fwmem.h"
-#include "iec13213.h"
-#include "iec68113.h"
-#else
-#include <dev/firewire/fw_port.h>
-#include <dev/firewire/firewire.h>
-#include <dev/firewire/firewirereg.h>
-#include <dev/firewire/fwmem.h>
-#include <dev/firewire/iec13213.h>
-#include <dev/firewire/iec68113.h>
-#endif
-#elif defined(__NetBSD__)
-#include <sys/param.h>
+#include <sys/callout.h>
+#include <sys/condvar.h>
+#include <sys/conf.h>
#include <sys/device.h>
#include <sys/errno.h>
-#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/malloc.h>
@@ -87,9 +53,6 @@ __KERNEL_RCSID(0, "$NetBSD: firewire.c,v 1.26 2010/03/11 04:00:36 mrg Exp $");
#include <sys/sysctl.h>
#include <sys/systm.h>
-#include <sys/bus.h>
-
-#include <dev/ieee1394/fw_port.h>
#include <dev/ieee1394/firewire.h>
#include <dev/ieee1394/firewirereg.h>
#include <dev/ieee1394/fwmem.h>
@@ -97,7 +60,6 @@ __KERNEL_RCSID(0, "$NetBSD: firewire.c,v 1.26 2010/03/11 04:00:36 mrg Exp $");
#include <dev/ieee1394/iec68113.h>
#include "locators.h"
-#endif
struct crom_src_buf {
struct crom_src src;
@@ -106,19 +68,7 @@ struct crom_src_buf {
struct crom_chunk hw;
};
-int firewire_debug=0, try_bmr=1, hold_count=3;
-#if defined(__FreeBSD__)
-SYSCTL_INT(_debug, OID_AUTO, firewire_debug, CTLFLAG_RW, &firewire_debug, 0,
- "FireWire driver debug flag");
-SYSCTL_NODE(_hw, OID_AUTO, firewire, CTLFLAG_RD, 0, "FireWire Subsystem");
-SYSCTL_INT(_hw_firewire, OID_AUTO, try_bmr, CTLFLAG_RW, &try_bmr, 0,
- "Try to be a bus manager");
-SYSCTL_INT(_hw_firewire, OID_AUTO, hold_count, CTLFLAG_RW, &hold_count, 0,
- "Number of count of bus resets for removing lost device information");
-
-MALLOC_DEFINE(M_FW, "firewire", "FireWire");
-MALLOC_DEFINE(M_FWXFER, "fw_xfer", "XFER/FireWire");
-#elif defined(__NetBSD__)
+int firewire_debug = 0, try_bmr = 1, hold_count = 0;
/*
* Setup sysctl(3) MIB, hw.ieee1394if.*
*
@@ -174,69 +124,54 @@ SYSCTL_SETUP(sysctl_ieee1394if, "sysctl ieee1394if(4) subtree setup")
return;
err:
- printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
+ aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
}
MALLOC_DEFINE(M_FW, "ieee1394", "IEEE1394");
MALLOC_DEFINE(M_FWXFER, "fw_xfer", "XFER/IEEE1394");
-#endif
#define FW_MAXASYRTY 4
-#if defined(__FreeBSD__)
-devclass_t firewire_devclass;
+#define FW_GENERATION_CHANGEABLE 2
+
+static int firewirematch (device_t, cfdata_t, void *);
+static void firewireattach (device_t, device_t, void *);
+static int firewiredetach (device_t, int);
+static int firewire_print (void *, const char *);
-static void firewire_identify (driver_t *, device_t);
-static int firewire_probe (device_t);
-static int firewire_attach (device_t);
-static int firewire_detach (device_t);
-static int firewire_resume (device_t);
-#if 0
-static int firewire_shutdown (device_t);
-#endif
-static device_t firewire_add_child (device_t, int, const char *, int);
-#elif defined(__NetBSD__)
-int firewirematch (device_t, cfdata_t, void *);
-void firewireattach (device_t, device_t, void *);
-int firewiredetach (device_t, int);
-int firewire_print (void *, const char *);
int firewire_resume (struct firewire_comm *);
-#endif
-static void firewire_xfer_timeout(void *, int);
-static void fw_try_bmr (void *);
-static void fw_try_bmr_callback (struct fw_xfer *);
-static void fw_asystart (struct fw_xfer *);
-static int fw_get_tlabel (struct firewire_comm *, struct fw_xfer *);
-static void fw_bus_probe (struct firewire_comm *);
-static void fw_attach_dev (struct firewire_comm *);
-static void fw_bus_probe_thread(void *);
-#ifdef FW_VMACCESS
-static void fw_vmaccess (struct fw_xfer *);
-#endif
-static int fw_bmr (struct firewire_comm *);
+
+static void fw_asystart(struct fw_xfer *);
+static void firewire_xfer_timeout(struct firewire_comm *);
+static void firewire_watchdog(void *);
+static void fw_xferq_drain(struct fw_xferq *);
+static void fw_reset_csr(struct firewire_comm *);
+static void fw_init_crom(struct firewire_comm *);
+static void fw_reset_crom(struct firewire_comm *);
static void fw_dump_hdr(struct fw_pkt *, const char *);
+static void fw_tl_free(struct firewire_comm *, struct fw_xfer *);
+static struct fw_xfer *fw_tl2xfer(struct firewire_comm *, int, int, int);
+static void fw_phy_config(struct firewire_comm *, int, int);
+static void fw_print_sid(uint32_t);
+static void fw_bus_probe(struct firewire_comm *);
+static int fw_explore_read_quads(struct fw_device *, int, uint32_t *, int);
+static int fw_explore_csrblock(struct fw_device *, int, int);
+static int fw_explore_node(struct fw_device *);
+static union fw_self_id *fw_find_self_id(struct firewire_comm *, int);
+static void fw_explore(struct firewire_comm *);
+static void fw_bus_probe_thread(void *);
+static void fw_attach_dev(struct firewire_comm *);
+static int fw_get_tlabel(struct firewire_comm *, struct fw_xfer *);
+static void fw_rcv_copy(struct fw_rcv_buf *);
+static void fw_try_bmr_callback(struct fw_xfer *);
+static void fw_try_bmr(void *);
+static int fw_bmr(struct firewire_comm *);
+
-#if defined(__FreeBSD__)
-static device_method_t firewire_methods[] = {
- /* Device interface */
- DEVMETHOD(device_identify, firewire_identify),
- DEVMETHOD(device_probe, firewire_probe),
- DEVMETHOD(device_attach, firewire_attach),
- DEVMETHOD(device_detach, firewire_detach),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, firewire_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_add_child, firewire_add_child),
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- { 0, 0 }
-};
-#elif defined(__NetBSD__)
CFATTACH_DECL_NEW(ieee1394if, sizeof(struct firewire_softc),
firewirematch, firewireattach, firewiredetach, NULL);
-#endif
+
+
const char *fw_linkspeed[] = {
"S100", "S200", "S400", "S800",
"S1600", "S3200", "undef", "undef"
@@ -254,13 +189,175 @@ static const char *tcode_str[] = {
u_int gap_cnt[] = { 5, 5, 7, 8, 10, 13, 16, 18,
21, 24, 26, 29, 32, 35, 37, 40};
-#if defined(__FreeBSD__)
-static driver_t firewire_driver = {
- "firewire",
- firewire_methods,
- sizeof(struct firewire_softc),
-};
-#endif
+
+static int
+firewirematch(device_t parent, cfdata_t cf, void *aux)
+{
+
+ return 1; /* always match */
+}
+
+static void
+firewireattach(device_t parent, device_t self, void *aux)
+{
+ struct firewire_softc *sc = device_private(self);
+ struct firewire_comm *fc = device_private(parent);
+ struct fw_attach_args faa;
+ struct firewire_dev_list *devlist;
+
+ aprint_naive("\n");
+ aprint_normal(": IEEE1394 bus\n");
+
+ fc->bdev = sc->dev = self;
+ sc->fc = fc;
+ SLIST_INIT(&sc->devlist);
+
+ fc->status = FWBUSNOTREADY;
+
+ if (fc->nisodma > FWMAXNDMA)
+ fc->nisodma = FWMAXNDMA;
+
+ fc->crom_src_buf =
+ (struct crom_src_buf *)malloc(sizeof(struct crom_src_buf),
+ M_FW, M_NOWAIT | M_ZERO);
+ if (fc->crom_src_buf == NULL) {
+ aprint_error_dev(fc->bdev, "Malloc Failure crom src buff\n");
+ return;
+ }
+ fc->topology_map =
+ (struct fw_topology_map *)malloc(sizeof(struct fw_topology_map),
+ M_FW, M_NOWAIT | M_ZERO);
+ if (fc->topology_map == NULL) {
+ aprint_error_dev(fc->dev, "Malloc Failure topology map\n");
+ free(fc->crom_src_buf, M_FW);
+ return;
+ }
+ fc->speed_map =
+ (struct fw_speed_map *)malloc(sizeof(struct fw_speed_map),
+ M_FW, M_NOWAIT | M_ZERO);
+ if (fc->speed_map == NULL) {
+ aprint_error_dev(fc->dev, "Malloc Failure speed map\n");
+ free(fc->crom_src_buf, M_FW);
+ free(fc->topology_map, M_FW);
+ return;
+ }
+
+ mutex_init(&fc->tlabel_lock, MUTEX_DEFAULT, IPL_VM);
+ mutex_init(&fc->fc_mtx, MUTEX_DEFAULT, IPL_VM);
+ mutex_init(&fc->wait_lock, MUTEX_DEFAULT, IPL_VM);
+ cv_init(&fc->fc_cv, "ieee1394");
+
+ callout_init(&fc->timeout_callout, CALLOUT_MPSAFE);
+ callout_setfunc(&fc->timeout_callout, firewire_watchdog, fc);
+ callout_init(&fc->bmr_callout, CALLOUT_MPSAFE);
+ callout_setfunc(&fc->bmr_callout, fw_try_bmr, fc);
+ callout_init(&fc->busprobe_callout, CALLOUT_MPSAFE);
+ callout_setfunc(&fc->busprobe_callout, (void *)fw_bus_probe, fc);
+
+ callout_schedule(&fc->timeout_callout, hz);
+
+ /* create thread */
+ if (kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, fw_bus_probe_thread,
+ fc, &fc->probe_thread, "fw%dprobe", device_unit(fc->bdev)))
+ aprint_error_dev(self, "kthread_create failed\n");
+ config_pending_incr();
+
+ devlist = malloc(sizeof(struct firewire_dev_list), M_DEVBUF, M_NOWAIT);
+ if (devlist == NULL) {
+ aprint_error_dev(self, "device list allocation failed\n");
+ return;
+ }
+
+ faa.name = "fwip";
+ faa.fc = fc;
+ faa.fwdev = NULL;
+ devlist->dev = config_found(sc->dev, &faa, firewire_print);
+ if (devlist->dev == NULL)
+ free(devlist, M_DEVBUF);
+ else
+ SLIST_INSERT_HEAD(&sc->devlist, devlist, link);
+
+ /* bus_reset */
+ fw_busreset(fc, FWBUSNOTREADY);
+ fc->ibr(fc);
+
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
+
+ return;
+}
+
+static int
+firewiredetach(device_t self, int flags)
+{
+ struct firewire_softc *sc = device_private(self);
+ struct firewire_comm *fc;
+ struct fw_device *fwdev, *fwdev_next;
+ struct firewire_dev_list *devlist;
+ int err;
+
+ fc = sc->fc;
+ mutex_enter(&fc->wait_lock);
+ fc->status = FWBUSDETACH;
+ cv_signal(&fc->fc_cv);
+ while (fc->status != FWBUSDETACHOK) {
+ err = cv_timedwait_sig(&fc->fc_cv, &fc->wait_lock, hz * 60);
+ if (err == EWOULDBLOCK) {
+ aprint_error_dev(self,
+ "firewire probe thread didn't die\n");
+ break;
+ }
+ }
+ mutex_exit(&fc->wait_lock);
+
+
+ while ((devlist = SLIST_FIRST(&sc->devlist)) != NULL) {
+ if ((err = config_detach(devlist->dev, flags)) != 0)
+ return err;
+ SLIST_REMOVE(&sc->devlist, devlist, firewire_dev_list, link);
+ free(devlist, M_DEVBUF);
+ }
+
+ callout_stop(&fc->timeout_callout);
+ callout_stop(&fc->bmr_callout);
+ callout_stop(&fc->busprobe_callout);
+
+ /* XXX xfer_free and untimeout on all xfers */
+ for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL;
+ fwdev = fwdev_next) {
+ fwdev_next = STAILQ_NEXT(fwdev, link);
+ free(fwdev, M_FW);
+ }
+ free(fc->topology_map, M_FW);
+ free(fc->speed_map, M_FW);
+ free(fc->crom_src_buf, M_FW);
+
+ cv_destroy(&fc->fc_cv);
+ mutex_destroy(&fc->wait_lock);
+ mutex_destroy(&fc->fc_mtx);
+ mutex_destroy(&fc->tlabel_lock);
+ return 0;
+}
+
+static int
+firewire_print(void *aux, const char *pnp)
+{
+ struct fw_attach_args *fwa = (struct fw_attach_args *)aux;
+
+ if (pnp)
+ aprint_normal("%s at %s", fwa->name, pnp);
+
+ return UNCONF;
+}
+
+int
+firewire_resume(struct firewire_comm *fc)
+{
+
+ fc->status = FWBUSNOTREADY;
+ return 0;
+}
+
/*
* Lookup fwdev by node id.
@@ -269,15 +366,12 @@ struct fw_device *
fw_noderesolve_nodeid(struct firewire_comm *fc, int dst)
{
struct fw_device *fwdev;
- int s;
- s = splfw();
- FW_GLOCK(fc);
+ mutex_enter(&fc->fc_mtx);
STAILQ_FOREACH(fwdev, &fc->devices, link)
if (fwdev->dst == dst && fwdev->status != FWDEVINVAL)
break;
- FW_GUNLOCK(fc);
- splx(s);
+ mutex_exit(&fc->fc_mtx);
return fwdev;
}
@@ -289,16 +383,17 @@ struct fw_device *
fw_noderesolve_eui64(struct firewire_comm *fc, struct fw_eui64 *eui)
{
struct fw_device *fwdev;
- int s;
- s = splfw();
+ mutex_enter(&fc->fc_mtx);
STAILQ_FOREACH(fwdev, &fc->devices, link)
if (FW_EUI64_EQUAL(fwdev->eui, *eui))
break;
- splx(s);
+ mutex_exit(&fc->fc_mtx);
- if(fwdev == NULL) return NULL;
- if(fwdev->status == FWDEVINVAL) return NULL;
+ if (fwdev == NULL)
+ return NULL;
+ if (fwdev->status == FWDEVINVAL)
+ return NULL;
return fwdev;
}
@@ -308,16 +403,16 @@ fw_noderesolve_eui64(struct firewire_comm *fc, struct fw_eui64 *eui)
int
fw_asyreq(struct firewire_comm *fc, int sub, struct fw_xfer *xfer)
{
- int err = 0;
struct fw_xferq *xferq;
int len;
struct fw_pkt *fp;
int tcode;
const struct tcode_info *info;
- if(xfer == NULL) return EINVAL;
- if(xfer->hand == NULL){
- printf("hand == NULL\n");
+ if (xfer == NULL)
+ return EINVAL;
+ if (xfer->hand == NULL) {
+ aprint_error_dev(fc->bdev, "hand == NULL\n");
return EINVAL;
}
fp = &xfer->send.hdr;
@@ -325,18 +420,18 @@ fw_asyreq(struct firewire_comm *fc, int sub, struct fw_xfer *xfer)
tcode = fp->mode.common.tcode & 0xf;
info = &fc->tcode[tcode];
if (info->flag == 0) {
- printf("invalid tcode=%x\n", tcode);
+ aprint_error_dev(fc->bdev, "invalid tcode=%x\n", tcode);
return EINVAL;
}
/* XXX allow bus explore packets only after bus rest */
if ((fc->status < FWBUSEXPLORE) &&
((tcode != FWTCODE_RREQQ) || (fp->mode.rreqq.dest_hi != 0xffff) ||
- (fp->mode.rreqq.dest_lo < 0xf0000000) ||
+ (fp->mode.rreqq.dest_lo < 0xf0000000) ||
(fp->mode.rreqq.dest_lo >= 0xf0001000))) {
xfer->resp = EAGAIN;
xfer->flag = FWXF_BUSY;
- return (EAGAIN);
+ return EAGAIN;
}
if (info->flag & FWTI_REQ)
@@ -345,7 +440,7 @@ fw_asyreq(struct firewire_comm *fc, int sub, struct fw_xfer *xfer)
xferq = fc->ats;
len = info->hdr_len;
if (xfer->send.pay_len > MAXREC(fc->maxrec)) {
- printf("send.pay_len > maxrec\n");
+ aprint_error_dev(fc->bdev, "send.pay_len > maxrec\n");
return EINVAL;
}
if (info->flag & FWTI_BLOCK_STR)
@@ -354,369 +449,85 @@ fw_asyreq(struct firewire_comm *fc, int sub, struct fw_xfer *xfer)
len = fp->mode.rresb.len;
else
len = 0;
- if (len != xfer->send.pay_len){
- printf("len(%d) != send.pay_len(%d) %s(%x)\n",
+ if (len != xfer->send.pay_len) {
+ aprint_error_dev(fc->bdev,
+ "len(%d) != send.pay_len(%d) %s(%x)\n",
len, xfer->send.pay_len, tcode_str[tcode], tcode);
- return EINVAL;
+ return EINVAL;
}
- if(xferq->start == NULL){
- printf("xferq->start == NULL\n");
+ if (xferq->start == NULL) {
+ aprint_error_dev(fc->bdev, "xferq->start == NULL\n");
return EINVAL;
}
- if(!(xferq->queued < xferq->maxq)){
- fw_printf(fc->bdev, "Discard a packet (queued=%d)\n",
+ if (!(xferq->queued < xferq->maxq)) {
+ aprint_error_dev(fc->bdev, "Discard a packet (queued=%d)\n",
xferq->queued);
return EAGAIN;
}
xfer->tl = -1;
- if (info->flag & FWTI_TLABEL) {
+ if (info->flag & FWTI_TLABEL)
if (fw_get_tlabel(fc, xfer) < 0)
return EAGAIN;
- }
xfer->resp = 0;
xfer->fc = fc;
xfer->q = xferq;
fw_asystart(xfer);
- return err;
+ return 0;
}
+
/*
* Wakeup blocked process.
*/
void
fw_xferwake(struct fw_xfer *xfer)
{
- fw_mtx_t lock = &xfer->fc->wait_lock;
- fw_mtx_lock(lock);
+ mutex_enter(&xfer->fc->wait_lock);
xfer->flag |= FWXF_WAKE;
- fw_mtx_unlock(lock);
+ cv_signal(&xfer->cv);
+ mutex_exit(&xfer->fc->wait_lock);
- wakeup(xfer);
return;
}
int
fw_xferwait(struct fw_xfer *xfer)
{
- fw_mtx_t lock = &xfer->fc->wait_lock;
- int err = 0;
-
- fw_mtx_lock(lock);
- if ((xfer->flag & FWXF_WAKE) == 0)
- err = fw_msleep((void *)xfer, lock, PWAIT|PCATCH, "fw_xferwait", 0);
- fw_mtx_unlock(lock);
-
- return (err);
-}
-
-/*
- * Async. request with given xfer structure.
- */
-static void
-fw_asystart(struct fw_xfer *xfer)
-{
struct firewire_comm *fc = xfer->fc;
- int s;
- s = splfw();
- /* Protect from interrupt/timeout */
- FW_GLOCK(fc);
- xfer->flag = FWXF_INQ;
- STAILQ_INSERT_TAIL(&xfer->q->q, xfer, link);
-#if 0
- xfer->q->queued ++;
-#endif
- FW_GUNLOCK(fc);
- splx(s);
- /* XXX just queue for mbuf */
- if (xfer->mbuf == NULL)
- xfer->q->start(fc);
- return;
-}
-
-#if defined(__FreeBSD__)
-static void
-firewire_identify(driver_t *driver, device_t parent)
-{
- BUS_ADD_CHILD(parent, 0, "firewire", -1);
-}
-
-static int
-firewire_probe(device_t dev)
-{
- device_set_desc(dev, "IEEE1394(FireWire) bus");
- return (0);
-}
-#elif defined(__NetBSD__)
-int
-firewirematch(device_t parent, cfdata_t cf, void *aux)
-{
- struct fwbus_attach_args *faa = (struct fwbus_attach_args *)aux;
-
- if (strcmp(faa->name, "ieee1394if") == 0)
- return (1);
- return (0);
-}
-#endif
-
-static void
-firewire_xfer_timeout(void *arg, int pending)
-{
- struct firewire_comm *fc = (struct firewire_comm *)arg;
- struct fw_xfer *xfer, *txfer;
- struct timeval tv;
- struct timeval split_timeout;
- STAILQ_HEAD(, fw_xfer) xfer_timeout;
- int i, s;
-
- split_timeout.tv_sec = 0;
- split_timeout.tv_usec = 200 * 1000; /* 200 msec */
-
- microtime(&tv);
- fw_timevalsub(&tv, &split_timeout);
- STAILQ_INIT(&xfer_timeout);
-
- s = splfw();
- fw_mtx_lock(&fc->tlabel_lock);
- for (i = 0; i < 0x40; i ++) {
- while ((xfer = STAILQ_FIRST(&fc->tlabels[i])) != NULL) {
- if ((xfer->flag & FWXF_SENT) == 0)
- /* not sent yet */
- break;
- if (fw_timevalcmp(&xfer->tv, &tv, >))
- /* the rests are newer than this */
- break;
- fw_printf(fc->bdev,
- "split transaction timeout: "
- "tl=0x%x flag=0x%02x\n", i, xfer->flag);
- fw_dump_hdr(&xfer->send.hdr, "send");
- xfer->resp = ETIMEDOUT;
- STAILQ_REMOVE_HEAD(&fc->tlabels[i], tlabel);
- STAILQ_INSERT_TAIL(&xfer_timeout, xfer, tlabel);
- }
- }
- fw_mtx_unlock(&fc->tlabel_lock);
- splx(s);
- fc->timeout(fc);
-
- STAILQ_FOREACH_SAFE(xfer, &xfer_timeout, tlabel, txfer)
- xfer->hand(xfer);
-}
-
-#define WATCHDOG_HZ 10
-static void
-firewire_watchdog(void *arg)
-{
- struct firewire_comm *fc;
- static int watchdog_clock = 0;
-
- fc = (struct firewire_comm *)arg;
-
- /*
- * At boot stage, the device interrupt is disabled and
- * We encounter a timeout easily. To avoid this,
- * ignore clock interrupt for a while.
- */
- if (watchdog_clock > WATCHDOG_HZ * 15)
- fw_taskqueue_enqueue(fc->taskqueue, &fc->task_timeout);
- else
- watchdog_clock ++;
-
- fw_callout_reset(&fc->timeout_callout, hz / WATCHDOG_HZ,
- (void *)firewire_watchdog, (void *)fc);
-}
-
-/*
- * The attach routine.
- */
-FW_ATTACH(firewire)
-{
- FW_ATTACH_START(firewire, sc, fwa);
- FIREWIRE_ATTACH_START;
-
-#ifdef __NetBSD__
- aprint_naive("\n");
-#endif
-
- sc->fc = fc;
- fc->status = FWBUSNOTREADY;
-
- if( fc->nisodma > FWMAXNDMA) fc->nisodma = FWMAXNDMA;
-
- FWDEV_MAKEDEV(sc);
-
- fw_mtx_init(&fc->wait_lock, "fwwait", NULL, MTX_DEF);
- fw_mtx_init(&fc->tlabel_lock, "fwtlabel", NULL, MTX_DEF);
- fw_callout_init(&fc->timeout_callout);
- fw_callout_init(&fc->bmr_callout);
- fw_callout_init(&fc->busprobe_callout);
- FW_TASK_INIT(&fc->task_timeout, 0, firewire_xfer_timeout, (void *)fc);
-
- fw_callout_reset(&sc->fc->timeout_callout, hz,
- (void *)firewire_watchdog, (void *)sc->fc);
-
- /* create thread */
- fw_kthread_create(fw_bus_probe_thread, (void *)fc, &fc->probe_thread,
- "fw%d_probe", fw_get_unit(fc->bdev));
- fw_config_pending_incr();
-
- FIREWIRE_GENERIC_ATTACH;
-
- /* bus_reset */
- fw_busreset(fc, FWBUSNOTREADY);
- fc->ibr(fc);
-
-#ifdef __NetBSD__
- if (!pmf_device_register(self, NULL, NULL))
- aprint_error_dev(self, "couldn't establish power handler\n");
-#endif
-
- FW_ATTACH_RETURN(0);
-}
-
-#if defined(__FreeBSD__)
-/*
- * Attach it as child.
- */
-static device_t
-firewire_add_child(device_t dev, int order, const char *name, int unit)
-{
- device_t child;
- struct firewire_softc *sc;
- struct fw_attach_args fwa;
-
- sc = (struct firewire_softc *)device_get_softc(dev);
- child = device_add_child(dev, name, unit);
- if (child) {
- fwa.name = name;
- fwa.fc = sc->fc;
- fwa.fwdev = NULL;
- device_set_ivars(child, &fwa);
- device_probe_and_attach(child);
- }
-
- return child;
-}
-
-static int
-firewire_resume(device_t dev)
-{
- struct firewire_softc *sc;
-
- sc = (struct firewire_softc *)device_get_softc(dev);
- sc->fc->status = FWBUSNOTREADY;
-
- bus_generic_resume(dev);
-
- return(0);
-}
-#endif
-
-/*
- * Dettach it.
- */
-FW_DETACH(firewire)
-{
- FW_DETACH_START(firewire, sc);
- struct firewire_comm *fc;
- struct fw_device *fwdev, *fwdev_next;
-
- fc = sc->fc;
- fw_mtx_lock(&fc->wait_lock);
- fc->status = FWBUSDETACH;
- wakeup(fc);
- if (fw_msleep(fc->probe_thread,
- &fc->wait_lock, PWAIT, "fwthr", hz * 60))
- printf("firewire probe thread didn't die\n");
- fw_mtx_unlock(&fc->wait_lock);
-
- FWDEV_DESTROYDEV(sc);
- FIREWIRE_GENERIC_DETACH;
-
- fw_callout_stop(&fc->timeout_callout);
- fw_callout_stop(&fc->bmr_callout);
- fw_callout_stop(&fc->busprobe_callout);
-
- /* XXX xfree_free and untimeout on all xfers */
- for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL;
- fwdev = fwdev_next) {
- fwdev_next = STAILQ_NEXT(fwdev, link);
- free(fwdev, M_FW);
- }
- free(fc->topology_map, M_FW);
- free(fc->speed_map, M_FW);
- free(fc->crom_src_buf, M_FW);
-
- fw_mtx_destroy(&fc->wait_lock);
- fw_mtx_destroy(&fc->tlabel_lock);
- return(0);
-}
-#if defined(__FreeBSD__)
-#if 0
-static int
-firewire_shutdown( device_t dev )
-{
- return 0;
-}
-#endif
-#elif defined(__NetBSD__)
-int
-firewire_print(void *aux, const char *pnp)
-{
- struct fw_attach_args *fwa = (struct fw_attach_args *)aux;
-
- if (pnp)
- aprint_normal("%s at %s", fwa->name, pnp);
-
- return UNCONF;
-}
-
-int
-firewire_resume(struct firewire_comm *fc)
-{
-
- fc->status = FWBUSNOTREADY;
- return 0;
-}
-#endif
+ int err = 0;
-static void
-fw_xferq_drain(struct fw_xferq *xferq)
-{
- struct fw_xfer *xfer;
+ mutex_enter(&fc->wait_lock);
+ while (!(xfer->flag & FWXF_WAKE))
+ err = cv_wait_sig(&xfer->cv, &fc->wait_lock);
+ mutex_exit(&fc->wait_lock);
- while ((xfer = STAILQ_FIRST(&xferq->q)) != NULL) {
- STAILQ_REMOVE_HEAD(&xferq->q, link);
-#if 0
- xferq->queued --;
-#endif
- xfer->resp = EAGAIN;
- xfer->flag = FWXF_SENTERR;
- fw_xfer_done(xfer);
- }
+ return err;
}
void
fw_drain_txq(struct firewire_comm *fc)
{
- struct fw_xfer *xfer, *txfer;
+ struct fw_xfer *xfer;
STAILQ_HEAD(, fw_xfer) xfer_drain;
int i;
STAILQ_INIT(&xfer_drain);
- FW_GLOCK(fc);
+ mutex_enter(&fc->atq->q_mtx);
fw_xferq_drain(fc->atq);
+ mutex_exit(&fc->atq->q_mtx);
+ mutex_enter(&fc->ats->q_mtx);
fw_xferq_drain(fc->ats);
- for(i = 0; i < fc->nisodma; i++)
+ mutex_exit(&fc->ats->q_mtx);
+ for (i = 0; i < fc->nisodma; i++)
fw_xferq_drain(fc->it[i]);
- FW_GUNLOCK(fc);
- fw_mtx_lock(&fc->tlabel_lock);
- for (i = 0; i < 0x40; i ++)
+ mutex_enter(&fc->tlabel_lock);
+ for (i = 0; i < 0x40; i++)
while ((xfer = STAILQ_FIRST(&fc->tlabels[i])) != NULL) {
if (firewire_debug)
printf("tl=%d flag=%d\n", i, xfer->flag);
@@ -724,167 +535,73 @@ fw_drain_txq(struct firewire_comm *fc)
STAILQ_REMOVE_HEAD(&fc->tlabels[i], tlabel);
STAILQ_INSERT_TAIL(&xfer_drain, xfer, tlabel);
}
- fw_mtx_unlock(&fc->tlabel_lock);
+ mutex_exit(&fc->tlabel_lock);
- STAILQ_FOREACH_SAFE(xfer, &xfer_drain, tlabel, txfer)
+ STAILQ_FOREACH(xfer, &xfer_drain, tlabel)
xfer->hand(xfer);
}
-static void
-fw_reset_csr(struct firewire_comm *fc)
-{
- int i;
-
- CSRARC(fc, STATE_CLEAR)
- = 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14 ;
- CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
- CSRARC(fc, NODE_IDS) = 0x3f;
-
- CSRARC(fc, TOPO_MAP + 8) = 0;
- fc->irm = -1;
-
- fc->max_node = -1;
-
- for(i = 2; i < 0x100/4 - 2 ; i++){
- CSRARC(fc, SPED_MAP + i * 4) = 0;
- }
- CSRARC(fc, STATE_CLEAR) = 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14 ;
- CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
- CSRARC(fc, RESET_START) = 0;
- CSRARC(fc, SPLIT_TIMEOUT_HI) = 0;
- CSRARC(fc, SPLIT_TIMEOUT_LO) = 800 << 19;
- CSRARC(fc, CYCLE_TIME) = 0x0;
- CSRARC(fc, BUS_TIME) = 0x0;
- CSRARC(fc, BUS_MGR_ID) = 0x3f;
- CSRARC(fc, BANDWIDTH_AV) = 4915;
- CSRARC(fc, CHANNELS_AV_HI) = 0xffffffff;
- CSRARC(fc, CHANNELS_AV_LO) = 0xffffffff;
- CSRARC(fc, IP_CHANNELS) = (1 << 31);
-
- CSRARC(fc, CONF_ROM) = 0x04 << 24;
- CSRARC(fc, CONF_ROM + 4) = 0x31333934; /* means strings 1394 */
- CSRARC(fc, CONF_ROM + 8) = 1 << 31 | 1 << 30 | 1 << 29 |
- 1 << 28 | 0xff << 16 | 0x09 << 8;
- CSRARC(fc, CONF_ROM + 0xc) = 0;
-
-/* DV depend CSRs see blue book */
- CSRARC(fc, oPCR) &= ~DV_BROADCAST_ON;
- CSRARC(fc, iPCR) &= ~DV_BROADCAST_ON;
-
- CSRARC(fc, STATE_CLEAR) &= ~(1 << 23 | 1 << 15 | 1 << 14 );
- CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
-}
-
-static void
-fw_init_crom(struct firewire_comm *fc)
-{
- struct crom_src *src;
-
- fc->crom_src_buf = (struct crom_src_buf *)
- malloc(sizeof(struct crom_src_buf), M_FW, M_WAITOK | M_ZERO);
- if (fc->crom_src_buf == NULL)
- return;
-
- src = &fc->crom_src_buf->src;
- memset(src, 0, sizeof(struct crom_src));
-
- /* BUS info sample */
- src->hdr.info_len = 4;
-
- src->businfo.bus_name = CSR_BUS_NAME_IEEE1394;
-
- src->businfo.irmc = 1;
- src->businfo.cmc = 1;
- src->businfo.isc = 1;
- src->businfo.bmc = 1;
- src->businfo.pmc = 0;
- src->businfo.cyc_clk_acc = 100;
- src->businfo.max_rec = fc->maxrec;
- src->businfo.max_rom = MAXROM_4;
- src->businfo.generation = 1;
- src->businfo.link_spd = fc->speed;
-
- src->businfo.eui64.hi = fc->eui.hi;
- src->businfo.eui64.lo = fc->eui.lo;
-
- STAILQ_INIT(&src->chunk_list);
-
- fc->crom_src = src;
- fc->crom_root = &fc->crom_src_buf->root;
-}
-
-static void
-fw_reset_crom(struct firewire_comm *fc)
-{
- struct crom_src_buf *buf;
- struct crom_src *src;
- struct crom_chunk *root;
-
- if (fc->crom_src_buf == NULL)
- fw_init_crom(fc);
-
- buf = fc->crom_src_buf;
- src = fc->crom_src;
- root = fc->crom_root;
-
- STAILQ_INIT(&src->chunk_list);
-
- memset(root, 0, sizeof(struct crom_chunk));
- crom_add_chunk(src, NULL, root, 0);
- crom_add_entry(root, CSRKEY_NCAP, 0x0083c0); /* XXX */
- /* private company_id */
- crom_add_entry(root, CSRKEY_VENDOR, CSRVAL_VENDOR_PRIVATE);
- crom_add_simple_text(src, root, &buf->vendor, PROJECT_STR);
- crom_add_entry(root, CSRKEY_HW, OS_VER);
- crom_add_simple_text(src, root, &buf->hw, hostname);
-}
-
/*
* Called after bus reset.
*/
void
fw_busreset(struct firewire_comm *fc, uint32_t new_status)
{
+ struct firewire_softc *sc = device_private(fc->bdev);
+ struct firewire_dev_list *devlist;
struct firewire_dev_comm *fdc;
struct crom_src *src;
- void *newrom;
+ uint32_t *newrom;
+
+ if (fc->status == FWBUSMGRELECT)
+ callout_stop(&fc->bmr_callout);
- switch(fc->status){
- case FWBUSMGRELECT:
- fw_callout_stop(&fc->bmr_callout);
- break;
- default:
- break;
- }
fc->status = new_status;
fw_reset_csr(fc);
+
+ if (fc->status == FWBUSNOTREADY)
+ fw_init_crom(fc);
+
fw_reset_crom(fc);
- FIREWIRE_CHILDREN_FOREACH_FUNC(post_busreset, fdc);
+ /* How many safe this access? */
+ SLIST_FOREACH(devlist, &sc->devlist, link) {
+ fdc = device_private(devlist->dev);
+ if (fdc->post_busreset != NULL)
+ fdc->post_busreset(fdc);
+ }
+ /*
+ * If the old config rom needs to be overwritten,
+ * bump the businfo.generation indicator to
+ * indicate that we need to be reprobed
+ * See 1394a-2000 8.3.2.5.4 for more details.
+ * generation starts at 2 and rolls over at 0xF
+ * back to 2.
+ *
+ * A generation of 0 indicates a device
+ * that is not 1394a-2000 compliant.
+ * A generation of 1 indicates a device that
+ * does not change it's Bus Info Block or
+ * Configuration ROM.
+ */
+#define FW_MAX_GENERATION 0xF
newrom = malloc(CROMSIZE, M_FW, M_NOWAIT | M_ZERO);
src = &fc->crom_src_buf->src;
- crom_load(src, (uint32_t *)newrom, CROMSIZE);
+ crom_load(src, newrom, CROMSIZE);
if (memcmp(newrom, fc->config_rom, CROMSIZE) != 0) {
- /* bump generation and reload */
- src->businfo.generation ++;
- /* generation must be between 0x2 and 0xF */
- if (src->businfo.generation < 2)
- src->businfo.generation ++;
- crom_load(src, (uint32_t *)newrom, CROMSIZE);
- bcopy(newrom, (void *)fc->config_rom, CROMSIZE);
+ if (src->businfo.generation++ > FW_MAX_GENERATION)
+ src->businfo.generation = FW_GENERATION_CHANGEABLE;
+ memcpy((void *)fc->config_rom, newrom, CROMSIZE);
}
free(newrom, M_FW);
}
/* Call once after reboot */
-void fw_init(struct firewire_comm *fc)
+void
+fw_init(struct firewire_comm *fc)
{
int i;
-#ifdef FW_VMACCESS
- struct fw_xfer *xfer;
- struct fw_bind *fwb;
-#endif
fc->arq->queued = 0;
fc->ars->queued = 0;
@@ -903,8 +620,12 @@ void fw_init(struct firewire_comm *fc)
STAILQ_INIT(&fc->atq->q);
STAILQ_INIT(&fc->ats->q);
+ mutex_init(&fc->arq->q_mtx, MUTEX_DEFAULT, IPL_VM);
+ mutex_init(&fc->ars->q_mtx, MUTEX_DEFAULT, IPL_VM);
+ mutex_init(&fc->atq->q_mtx, MUTEX_DEFAULT, IPL_VM);
+ mutex_init(&fc->ats->q_mtx, MUTEX_DEFAULT, IPL_VM);
- for( i = 0 ; i < fc->nisodma ; i ++ ){
+ for (i = 0; i < fc->nisodma; i++) {
fc->it[i]->queued = 0;
fc->ir[i]->queued = 0;
@@ -926,17 +647,11 @@ void fw_init(struct firewire_comm *fc)
fc->atq->maxq = FWMAXQUEUE;
fc->ats->maxq = FWMAXQUEUE;
- for( i = 0 ; i < fc->nisodma ; i++){
+ for (i = 0; i < fc->nisodma; i++) {
fc->ir[i]->maxq = FWMAXQUEUE;
fc->it[i]->maxq = FWMAXQUEUE;
}
-/* Initialize csr registers */
- fc->topology_map = (struct fw_topology_map *)malloc(
- sizeof(struct fw_topology_map),
- M_FW, M_NOWAIT | M_ZERO);
- fc->speed_map = (struct fw_speed_map *)malloc(
- sizeof(struct fw_speed_map),
- M_FW, M_NOWAIT | M_ZERO);
+
CSRARC(fc, TOPO_MAP) = 0x3f1 << 16;
CSRARC(fc, TOPO_MAP + 4) = 1;
CSRARC(fc, SPED_MAP) = 0x3f1 << 16;
@@ -946,50 +661,27 @@ void fw_init(struct firewire_comm *fc)
/* Initialize Async handlers */
STAILQ_INIT(&fc->binds);
- for( i = 0 ; i < 0x40 ; i++){
+ for (i = 0; i < 0x40; i++)
STAILQ_INIT(&fc->tlabels[i]);
- }
/* DV depend CSRs see blue book */
#if 0
CSRARC(fc, oMPR) = 0x3fff0001; /* # output channel = 1 */
CSRARC(fc, oPCR) = 0x8000007a;
- for(i = 4 ; i < 0x7c/4 ; i+=4){
- CSRARC(fc, i + oPCR) = 0x8000007a;
- }
-
+ for (i = 4; i < 0x7c/4; i+=4)
+ CSRARC(fc, i + oPCR) = 0x8000007a;
+
CSRARC(fc, iMPR) = 0x00ff0001; /* # input channel = 1 */
CSRARC(fc, iPCR) = 0x803f0000;
- for(i = 4 ; i < 0x7c/4 ; i+=4){
- CSRARC(fc, i + iPCR) = 0x0;
- }
+ for (i = 4; i < 0x7c/4; i+=4)
+ CSRARC(fc, i + iPCR) = 0x0;
#endif
fc->crom_src_buf = NULL;
-
-#ifdef FW_VMACCESS
- xfer = fw_xfer_alloc();
- if(xfer == NULL) return;
-
- fwb = (struct fw_bind *)malloc(sizeof (struct fw_bind), M_FW, M_NOWAIT);
- if(fwb == NULL){
- fw_xfer_free(xfer);
- return;
- }
- xfer->hand = fw_vmaccess;
- xfer->fc = fc;
- xfer->sc = NULL;
-
- fwb->start_hi = 0x2;
- fwb->start_lo = 0;
- fwb->addrlen = 0xffffffff;
- fwb->xfer = xfer;
- fw_bindadd(fc, fwb);
-#endif
}
-#define BIND_CMP(addr, fwb) (((addr) < (fwb)->start)?-1:\
- ((fwb)->end < (addr))?1:0)
+#define BIND_CMP(addr, fwb) \
+ (((addr) < (fwb)->start) ? -1 : ((fwb)->end < (addr)) ? 1 : 0)
/*
* To lookup bound process from IEEE1394 address.
@@ -1001,14 +693,14 @@ fw_bindlookup(struct firewire_comm *fc, uint16_t dest_hi, uint32_t dest_lo)
struct fw_bind *tfw, *r = NULL;
addr = ((u_int64_t)dest_hi << 32) | dest_lo;
- FW_GLOCK(fc);
+ mutex_enter(&fc->fc_mtx);
STAILQ_FOREACH(tfw, &fc->binds, fclist)
if (BIND_CMP(addr, tfw) == 0) {
r = tfw;
break;
}
- FW_GUNLOCK(fc);
- return(r);
+ mutex_exit(&fc->fc_mtx);
+ return r;
}
/*
@@ -1021,11 +713,11 @@ fw_bindadd(struct firewire_comm *fc, struct fw_bind *fwb)
int r = 0;
if (fwb->start > fwb->end) {
- printf("%s: invalid range\n", __func__);
+ aprint_error_dev(fc->bdev, "invalid range\n");
return EINVAL;
}
- FW_GLOCK(fc);
+ mutex_enter(&fc->fc_mtx);
STAILQ_FOREACH(tfw, &fc->binds, fclist) {
if (fwb->end < tfw->start)
break;
@@ -1036,11 +728,11 @@ fw_bindadd(struct firewire_comm *fc, struct fw_bind *fwb)
else if (prev->end < fwb->start)
STAILQ_INSERT_AFTER(&fc->binds, prev, fwb, fclist);
else {
- printf("%s: bind failed\n", __func__);
+ aprint_error_dev(fc->bdev, "bind failed\n");
r = EBUSY;
}
- FW_GUNLOCK(fc);
- return (r);
+ mutex_exit(&fc->fc_mtx);
+ return r;
}
/*
@@ -1053,20 +745,18 @@ fw_bindremove(struct firewire_comm *fc, struct fw_bind *fwb)
struct fw_xfer *xfer, *next;
#endif
struct fw_bind *tfw;
- int s;
- s = splfw();
- FW_GLOCK(fc);
+ mutex_enter(&fc->fc_mtx);
STAILQ_FOREACH(tfw, &fc->binds, fclist)
if (tfw == fwb) {
STAILQ_REMOVE(&fc->binds, fwb, fw_bind, fclist);
+ mutex_exit(&fc->fc_mtx);
goto found;
}
- printf("%s: no such binding\n", __func__);
- FW_GUNLOCK(fc);
- splx(s);
- return (1);
+ mutex_exit(&fc->fc_mtx);
+ aprint_error_dev(fc->bdev, "no such binding\n");
+ return 1;
found:
#if 0
/* shall we do this? */
@@ -1076,32 +766,28 @@ found:
}
STAILQ_INIT(&fwb->xferlist);
#endif
- FW_GUNLOCK(fc);
- splx(s);
return 0;
}
int
-fw_xferlist_add(struct fw_xferlist *q, struct malloc_type *type,
- int slen, int rlen, int n,
- struct firewire_comm *fc, void *sc, void (*hand)(struct fw_xfer *))
+fw_xferlist_add(struct fw_xferlist *q, struct malloc_type *type, int slen,
+ int rlen, int n, struct firewire_comm *fc, void *sc,
+ void (*hand)(struct fw_xfer *))
{
- int i, s;
struct fw_xfer *xfer;
+ int i;
for (i = 0; i < n; i++) {
xfer = fw_xfer_alloc_buf(type, slen, rlen);
if (xfer == NULL)
- return (n);
+ return n;
xfer->fc = fc;
xfer->sc = sc;
xfer->hand = hand;
- s = splfw();
STAILQ_INSERT_TAIL(q, xfer, link);
- splx(s);
}
- return (n);
+ return n;
}
void
@@ -1117,94 +803,6 @@ fw_xferlist_remove(struct fw_xferlist *q)
}
/*
- * dump packet header
- */
-static void
-fw_dump_hdr(struct fw_pkt *fp, const char *prefix)
-{
- printf("%s: dst=0x%02x tl=0x%02x rt=%d tcode=0x%x pri=0x%x "
- "src=0x%03x\n", prefix,
- fp->mode.hdr.dst & 0x3f,
- fp->mode.hdr.tlrt >> 2, fp->mode.hdr.tlrt & 3,
- fp->mode.hdr.tcode, fp->mode.hdr.pri,
- fp->mode.hdr.src);
-}
-
-/*
- * To free transaction label.
- */
-static void
-fw_tl_free(struct firewire_comm *fc, struct fw_xfer *xfer)
-{
- struct fw_xfer *txfer;
- int s;
-
- if (xfer->tl < 0)
- return;
-
- s = splfw();
- fw_mtx_lock(&fc->tlabel_lock);
-#if 1 /* make sure the label is allocated */
- STAILQ_FOREACH(txfer, &fc->tlabels[xfer->tl], tlabel)
- if(txfer == xfer)
- break;
- if (txfer == NULL) {
- printf("%s: the xfer is not in the queue "
- "(tlabel=%d, flag=0x%x)\n",
- __func__, xfer->tl, xfer->flag);
- fw_dump_hdr(&xfer->send.hdr, "send");
- fw_dump_hdr(&xfer->recv.hdr, "recv");
- kdb_backtrace();
- fw_mtx_unlock(&fc->tlabel_lock);
- splx(s);
- return;
- }
-#endif
-
- STAILQ_REMOVE(&fc->tlabels[xfer->tl], xfer, fw_xfer, tlabel);
- fw_mtx_unlock(&fc->tlabel_lock);
- splx(s);
- return;
-}
-
-/*
- * To obtain XFER structure by transaction label.
- */
-static struct fw_xfer *
-fw_tl2xfer(struct firewire_comm *fc, int node, int tlabel, int tcode)
-{
- struct fw_xfer *xfer;
- int s = splfw();
- int req;
-
- fw_mtx_lock(&fc->tlabel_lock);
- STAILQ_FOREACH(xfer, &fc->tlabels[tlabel], tlabel)
- if(xfer->send.hdr.mode.hdr.dst == node) {
- fw_mtx_unlock(&fc->tlabel_lock);
- splx(s);
- FW_KASSERT(xfer->tl == tlabel,
- ("xfer->tl 0x%x != 0x%x", xfer->tl, tlabel));
- /* extra sanity check */
- req = xfer->send.hdr.mode.hdr.tcode;
- if (xfer->fc->tcode[req].valid_res != tcode) {
- printf("%s: invalid response tcode "
- "(0x%x for 0x%x)\n", __func__,
- tcode, req);
- return(NULL);
- }
-
- if (firewire_debug > 2)
- printf("fw_tl2xfer: found tl=%d\n", tlabel);
- return(xfer);
- }
- fw_mtx_unlock(&fc->tlabel_lock);
- if (firewire_debug > 1)
- printf("fw_tl2xfer: not found tl=%d\n", tlabel);
- splx(s);
- return(NULL);
-}
-
-/*
* To allocate IEEE1394 XFER structure.
*/
struct fw_xfer *
@@ -1217,6 +815,7 @@ fw_xfer_alloc(struct malloc_type *type)
return xfer;
xfer->malloc = type;
+ cv_init(&xfer->cv, "fwxfer");
return xfer;
}
@@ -1228,14 +827,14 @@ fw_xfer_alloc_buf(struct malloc_type *type, int send_len, int recv_len)
xfer = fw_xfer_alloc(type);
if (xfer == NULL)
- return(NULL);
+ return NULL;
xfer->send.pay_len = send_len;
xfer->recv.pay_len = recv_len;
if (send_len > 0) {
xfer->send.payload = malloc(send_len, type, M_NOWAIT | M_ZERO);
if (xfer->send.payload == NULL) {
fw_xfer_free(xfer);
- return(NULL);
+ return NULL;
}
}
if (recv_len > 0) {
@@ -1244,10 +843,10 @@ fw_xfer_alloc_buf(struct malloc_type *type, int send_len, int recv_len)
if (xfer->send.payload != NULL)
free(xfer->send.payload, type);
fw_xfer_free(xfer);
- return(NULL);
+ return NULL;
}
}
- return(xfer);
+ return xfer;
}
/*
@@ -1256,8 +855,9 @@ fw_xfer_alloc_buf(struct malloc_type *type, int send_len, int recv_len)
void
fw_xfer_done(struct fw_xfer *xfer)
{
+
if (xfer->hand == NULL) {
- printf("hand == NULL\n");
+ aprint_error_dev(xfer->fc->bdev, "hand == NULL\n");
return;
}
@@ -1271,202 +871,147 @@ fw_xfer_done(struct fw_xfer *xfer)
void
fw_xfer_unload(struct fw_xfer* xfer)
{
- int s;
- if(xfer == NULL ) return;
- if(xfer->flag & FWXF_INQ){
- printf("fw_xfer_free FWXF_INQ\n");
- s = splfw();
- FW_GLOCK(xfer->fc);
+ if (xfer == NULL)
+ return;
+ if (xfer->flag & FWXF_INQ) {
+ aprint_error_dev(xfer->fc->bdev, "fw_xfer_free FWXF_INQ\n");
+ mutex_enter(&xfer->q->q_mtx);
STAILQ_REMOVE(&xfer->q->q, xfer, fw_xfer, link);
#if 0
- xfer->q->queued --;
+ xfer->q->queued--;
#endif
- FW_GUNLOCK(xfer->fc);
- splx(s);
+ mutex_exit(&xfer->q->q_mtx);
}
if (xfer->fc != NULL) {
#if 1
- if(xfer->flag == FWXF_START)
+ if (xfer->flag == FWXF_START)
/*
* This could happen if:
* 1. We call fwohci_arcv() before fwohci_txd().
* 2. firewire_watch() is called.
*/
- printf("fw_xfer_free FWXF_START\n");
+ aprint_error_dev(xfer->fc->bdev,
+ "fw_xfer_free FWXF_START\n");
#endif
}
xfer->flag = FWXF_INIT;
xfer->resp = 0;
}
+
/*
- * To free IEEE1394 XFER structure.
+ * To free IEEE1394 XFER structure.
*/
void
-fw_xfer_free_buf( struct fw_xfer* xfer)
+fw_xfer_free(struct fw_xfer* xfer)
{
+
if (xfer == NULL) {
- printf("%s: xfer == NULL\n", __func__);
+ aprint_error_dev(xfer->fc->bdev, "xfer == NULL\n");
return;
}
fw_xfer_unload(xfer);
- if(xfer->send.payload != NULL){
- free(xfer->send.payload, xfer->malloc);
- }
- if(xfer->recv.payload != NULL){
- free(xfer->recv.payload, xfer->malloc);
- }
+ cv_destroy(&xfer->cv);
free(xfer, xfer->malloc);
}
void
-fw_xfer_free( struct fw_xfer* xfer)
+fw_xfer_free_buf(struct fw_xfer* xfer)
{
+
if (xfer == NULL) {
- printf("%s: xfer == NULL\n", __func__);
+ aprint_error_dev(xfer->fc->bdev, "xfer == NULL\n");
return;
}
fw_xfer_unload(xfer);
+ if (xfer->send.payload != NULL) {
+ free(xfer->send.payload, xfer->malloc);
+ }
+ if (xfer->recv.payload != NULL) {
+ free(xfer->recv.payload, xfer->malloc);
+ }
+ cv_destroy(&xfer->cv);
free(xfer, xfer->malloc);
}
void
fw_asy_callback_free(struct fw_xfer *xfer)
{
+
#if 0
- printf("asyreq done flag=%d resp=%d\n",
- xfer->flag, xfer->resp);
+ printf("asyreq done flag=%d resp=%d\n", xfer->flag, xfer->resp);
#endif
fw_xfer_free(xfer);
}
/*
- * To configure PHY.
+ * To receive self ID.
*/
-static void
-fw_phy_config(struct firewire_comm *fc, int root_node, int gap_count)
-{
- struct fw_xfer *xfer;
- struct fw_pkt *fp;
-
- fc->status = FWBUSPHYCONF;
-
- xfer = fw_xfer_alloc(M_FWXFER);
- if (xfer == NULL)
- return;
- xfer->fc = fc;
- xfer->hand = fw_asy_callback_free;
-
- fp = &xfer->send.hdr;
- fp->mode.ld[1] = 0;
- if (root_node >= 0)
- fp->mode.ld[1] |= (root_node & 0x3f) << 24 | 1 << 23;
- if (gap_count >= 0)
- fp->mode.ld[1] |= 1 << 22 | (gap_count & 0x3f) << 16;
- fp->mode.ld[2] = ~fp->mode.ld[1];
-/* XXX Dangerous, how to pass PHY packet to device driver */
- fp->mode.common.tcode |= FWTCODE_PHY;
-
- if (firewire_debug)
- printf("send phy_config root_node=%d gap_count=%d\n",
- root_node, gap_count);
- fw_asyreq(fc, -1, xfer);
-}
-
-#if 0
-/*
- * Dump self ID.
- */
-static void
-fw_print_sid(uint32_t sid)
-{
- union fw_self_id *s;
- s = (union fw_self_id *) &sid;
- printf("node:%d link:%d gap:%d spd:%d del:%d con:%d pwr:%d"
- " p0:%d p1:%d p2:%d i:%d m:%d\n",
- s->p0.phy_id, s->p0.link_active, s->p0.gap_count,
- s->p0.phy_speed, s->p0.phy_delay, s->p0.contender,
- s->p0.power_class, s->p0.port0, s->p0.port1,
- s->p0.port2, s->p0.initiated_reset, s->p0.more_packets);
-}
-#endif
-
-/*
- * To receive self ID.
- */
-void fw_sidrcv(struct firewire_comm* fc, uint32_t *sid, u_int len)
+void
+fw_sidrcv(struct firewire_comm* fc, uint32_t *sid, u_int len)
{
uint32_t *p;
union fw_self_id *self_id;
u_int i, j, node, c_port = 0, i_branch = 0;
- fc->sid_cnt = len /(sizeof(uint32_t) * 2);
+ fc->sid_cnt = len / (sizeof(uint32_t) * 2);
fc->max_node = fc->nodeid & 0x3f;
CSRARC(fc, NODE_IDS) = ((uint32_t)fc->nodeid) << 16;
fc->status = FWBUSCYMELECT;
fc->topology_map->crc_len = 2;
- fc->topology_map->generation ++;
+ fc->topology_map->generation++;
fc->topology_map->self_id_count = 0;
fc->topology_map->node_count = 0;
- fc->speed_map->generation ++;
+ fc->speed_map->generation++;
fc->speed_map->crc_len = 1 + (64*64 + 3) / 4;
- self_id = &fc->topology_map->self_id[0];
- for(i = 0; i < fc->sid_cnt; i ++){
+ self_id = fc->topology_map->self_id;
+ for (i = 0; i < fc->sid_cnt; i++) {
if (sid[1] != ~sid[0]) {
- printf("fw_sidrcv: invalid self-id packet\n");
+ aprint_error_dev(fc->bdev,
+ "ERROR invalid self-id packet\n");
sid += 2;
continue;
}
*self_id = *((union fw_self_id *)sid);
fc->topology_map->crc_len++;
- if(self_id->p0.sequel == 0){
- fc->topology_map->node_count ++;
+ if (self_id->p0.sequel == 0) {
+ fc->topology_map->node_count++;
c_port = 0;
-#if 0
- fw_print_sid(sid[0]);
-#endif
+ if (firewire_debug)
+ fw_print_sid(sid[0]);
node = self_id->p0.phy_id;
- if(fc->max_node < node){
+ if (fc->max_node < node)
fc->max_node = self_id->p0.phy_id;
- }
/* XXX I'm not sure this is the right speed_map */
- fc->speed_map->speed[node][node]
- = self_id->p0.phy_speed;
- for (j = 0; j < node; j ++) {
- fc->speed_map->speed[j][node]
- = fc->speed_map->speed[node][j]
- = min(fc->speed_map->speed[j][j],
+ fc->speed_map->speed[node][node] =
+ self_id->p0.phy_speed;
+ for (j = 0; j < node; j++)
+ fc->speed_map->speed[j][node] =
+ fc->speed_map->speed[node][j] =
+ min(fc->speed_map->speed[j][j],
self_id->p0.phy_speed);
- }
if ((fc->irm == -1 || self_id->p0.phy_id > fc->irm) &&
- (self_id->p0.link_active && self_id->p0.contender)) {
+ (self_id->p0.link_active && self_id->p0.contender))
fc->irm = self_id->p0.phy_id;
- }
- if(self_id->p0.port0 >= 0x2){
+ if (self_id->p0.port0 >= 0x2)
c_port++;
- }
- if(self_id->p0.port1 >= 0x2){
+ if (self_id->p0.port1 >= 0x2)
c_port++;
- }
- if(self_id->p0.port2 >= 0x2){
+ if (self_id->p0.port2 >= 0x2)
c_port++;
- }
}
- if(c_port > 2){
+ if (c_port > 2)
i_branch += (c_port - 2);
- }
sid += 2;
self_id++;
- fc->topology_map->self_id_count ++;
+ fc->topology_map->self_id_count++;
}
- fw_printf(fc->bdev, "%d nodes", fc->max_node + 1);
/* CRC */
- fc->topology_map->crc = fw_crc16(
- (uint32_t *)&fc->topology_map->generation,
- fc->topology_map->crc_len * 4);
- fc->speed_map->crc = fw_crc16(
- (uint32_t *)&fc->speed_map->generation,
- fc->speed_map->crc_len * 4);
+ fc->topology_map->crc =
+ fw_crc16((uint32_t *)&fc->topology_map->generation,
+ fc->topology_map->crc_len * 4);
+ fc->speed_map->crc = fw_crc16((uint32_t *)&fc->speed_map->generation,
+ fc->speed_map->crc_len * 4);
/* byteswap and copy to CSR */
p = (uint32_t *)fc->topology_map;
for (i = 0; i <= fc->topology_map->crc_len; i++)
@@ -1475,19 +1020,14 @@ void fw_sidrcv(struct firewire_comm* fc, uint32_t *sid, u_int len)
CSRARC(fc, SPED_MAP) = htonl(*p++);
CSRARC(fc, SPED_MAP + 4) = htonl(*p++);
/* don't byte-swap uint8_t array */
- bcopy(p, &CSRARC(fc, SPED_MAP + 8), (fc->speed_map->crc_len - 1)*4);
+ memcpy(&CSRARC(fc, SPED_MAP + 8), p, (fc->speed_map->crc_len - 1) * 4);
fc->max_hop = fc->max_node - i_branch;
- aprint_normal(", maxhop <= %d", fc->max_hop);
-
- if(fc->irm == -1 ){
- aprint_normal(", Not found IRM capable node");
- }else{
- aprint_normal(", cable IRM = %d", fc->irm);
- if (fc->irm == fc->nodeid)
- aprint_normal(" (me)");
- }
- aprint_normal("\n");
+ aprint_normal_dev(fc->bdev, "%d nodes, maxhop <= %d %s irm(%d)%s\n",
+ fc->max_node + 1, fc->max_hop,
+ (fc->irm == -1) ? "Not IRM capable" : "cable IRM",
+ fc->irm,
+ (fc->irm == fc->nodeid) ? " (me)" : "");
if (try_bmr && (fc->irm != -1) && (CSRARC(fc, BUS_MGR_ID) == 0x3f)) {
if (fc->irm == fc->nodeid) {
@@ -1496,54 +1036,617 @@ void fw_sidrcv(struct firewire_comm* fc, uint32_t *sid, u_int len)
fw_bmr(fc);
} else {
fc->status = FWBUSMGRELECT;
- fw_callout_reset(&fc->bmr_callout, hz/8,
- (void *)fw_try_bmr, (void *)fc);
+ callout_schedule(&fc->bmr_callout, hz/8);
}
} else
fc->status = FWBUSMGRDONE;
- fw_callout_reset(&fc->busprobe_callout, hz/4,
- (void *)fw_bus_probe, (void *)fc);
+ callout_schedule(&fc->busprobe_callout, hz/4);
}
/*
- * To probe devices on the IEEE1394 bus.
+ * Generic packet receiving process.
+ */
+#if 0
+int dbgflg = 0;
+#endif
+void
+fw_rcv(struct fw_rcv_buf *rb)
+{
+ struct fw_pkt *fp, *resfp;
+ struct fw_bind *bind;
+ int tcode;
+ int i, len, oldstate;
+#if 0
+ {
+ uint32_t *qld;
+ int i;
+ qld = (uint32_t *)buf;
+ printf("spd %d len:%d\n", spd, len);
+ for (i = 0; i <= len && i < 32; i+= 4) {
+ printf("0x%08x ", ntohl(qld[i/4]));
+ if ((i % 16) == 15) printf("\n");
+ }
+ if ((i % 16) != 15) printf("\n");
+ }
+#endif
+ fp = (struct fw_pkt *)rb->vec[0].iov_base;
+ tcode = fp->mode.common.tcode;
+ switch (tcode) {
+ case FWTCODE_WRES:
+ case FWTCODE_RRESQ:
+ case FWTCODE_RRESB:
+ case FWTCODE_LRES:
+ rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src,
+ fp->mode.hdr.tlrt >> 2, tcode);
+ if (rb->xfer == NULL) {
+ aprint_error_dev(rb->fc->bdev, "unknown response"
+ " %s(%x) src=0x%x tl=0x%x rt=%d data=0x%x\n",
+ tcode_str[tcode], tcode,
+ fp->mode.hdr.src,
+ fp->mode.hdr.tlrt >> 2,
+ fp->mode.hdr.tlrt & 3,
+ fp->mode.rresq.data);
+#if 0
+dbgflg=8;
+#endif
+#if 0
+ printf("try ad-hoc work around!!\n");
+ rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src,
+ (fp->mode.hdr.tlrt >> 2) ^ 3);
+ if (rb->xfer == NULL) {
+ printf("no use...\n");
+ return;
+ }
+#else
+ return;
+#endif
+ }
+ fw_rcv_copy(rb);
+ if (rb->xfer->recv.hdr.mode.wres.rtcode != RESP_CMP)
+ rb->xfer->resp = EIO;
+ else
+ rb->xfer->resp = 0;
+ /* make sure the packet is drained in AT queue */
+ oldstate = rb->xfer->flag;
+ rb->xfer->flag = FWXF_RCVD;
+ switch (oldstate) {
+ case FWXF_SENT:
+ fw_xfer_done(rb->xfer);
+ break;
+ case FWXF_START:
+#if 0
+ if (firewire_debug)
+ printf("not sent yet tl=%x\n", rb->xfer->tl);
+#endif
+ break;
+ default:
+ aprint_error_dev(rb->fc->bdev,
+ "unexpected flag 0x%02x\n", rb->xfer->flag);
+ }
+ return;
+ case FWTCODE_WREQQ:
+ case FWTCODE_WREQB:
+ case FWTCODE_RREQQ:
+ case FWTCODE_RREQB:
+ case FWTCODE_LREQ:
+ bind = fw_bindlookup(rb->fc, fp->mode.rreqq.dest_hi,
+ fp->mode.rreqq.dest_lo);
+ if (bind == NULL) {
+#if 1
+ aprint_error_dev(rb->fc->bdev, "Unknown service addr"
+ " 0x%04x:0x%08x %s(%x) src=0x%x data=%x\n",
+ fp->mode.wreqq.dest_hi, fp->mode.wreqq.dest_lo,
+ tcode_str[tcode], tcode,
+ fp->mode.hdr.src, ntohl(fp->mode.wreqq.data));
+#endif
+ if (rb->fc->status == FWBUSINIT) {
+ aprint_error_dev(rb->fc->bdev,
+ "cannot respond(bus reset)!\n");
+ return;
+ }
+ rb->xfer = fw_xfer_alloc(M_FWXFER);
+ if (rb->xfer == NULL)
+ return;
+ rb->xfer->send.spd = rb->spd;
+ rb->xfer->send.pay_len = 0;
+ resfp = &rb->xfer->send.hdr;
+ switch (tcode) {
+ case FWTCODE_WREQQ:
+ case FWTCODE_WREQB:
+ resfp->mode.hdr.tcode = FWTCODE_WRES;
+ break;
+ case FWTCODE_RREQQ:
+ resfp->mode.hdr.tcode = FWTCODE_RRESQ;
+ break;
+ case FWTCODE_RREQB:
+ resfp->mode.hdr.tcode = FWTCODE_RRESB;
+ break;
+ case FWTCODE_LREQ:
+ resfp->mode.hdr.tcode = FWTCODE_LRES;
+ break;
+ }
+ resfp->mode.hdr.dst = fp->mode.hdr.src;
+ resfp->mode.hdr.tlrt = fp->mode.hdr.tlrt;
+ resfp->mode.hdr.pri = fp->mode.hdr.pri;
+ resfp->mode.rresb.rtcode = RESP_ADDRESS_ERROR;
+ resfp->mode.rresb.extcode = 0;
+ resfp->mode.rresb.len = 0;
+/*
+ rb->xfer->hand = fw_xferwake;
+*/
+ rb->xfer->hand = fw_xfer_free;
+ if (fw_asyreq(rb->fc, -1, rb->xfer)) {
+ fw_xfer_free(rb->xfer);
+ return;
+ }
+ return;
+ }
+ len = 0;
+ for (i = 0; i < rb->nvec; i++)
+ len += rb->vec[i].iov_len;
+ mutex_enter(&bind->fwb_mtx);
+ rb->xfer = STAILQ_FIRST(&bind->xferlist);
+ if (rb->xfer == NULL) {
+ mutex_exit(&bind->fwb_mtx);
+#if 1
+ aprint_error_dev(rb->fc->bdev,
+ "Discard a packet for this bind.\n");
+#endif
+ return;
+ }
+ STAILQ_REMOVE_HEAD(&bind->xferlist, link);
+ mutex_exit(&bind->fwb_mtx);
+ fw_rcv_copy(rb);
+ rb->xfer->hand(rb->xfer);
+ return;
+
+ default:
+ aprint_error_dev(rb->fc->bdev, "unknow tcode %d\n", tcode);
+ break;
+ }
+}
+
+/*
+ * CRC16 check-sum for IEEE1394 register blocks.
+ */
+uint16_t
+fw_crc16(uint32_t *ptr, uint32_t len)
+{
+ uint32_t i, sum, crc = 0;
+ int shift;
+
+ len = (len + 3) & ~3;
+ for (i = 0; i < len; i+= 4) {
+ for (shift = 28; shift >= 0; shift -= 4) {
+ sum = ((crc >> 12) ^ (ptr[i/4] >> shift)) & 0xf;
+ crc = (crc << 4) ^ (sum << 12) ^ (sum << 5) ^ sum;
+ }
+ crc &= 0xffff;
+ }
+ return (uint16_t)crc;
+}
+
+int
+fw_open_isodma(struct firewire_comm *fc, int tx)
+{
+ struct fw_xferq **xferqa;
+ struct fw_xferq *xferq;
+ int i;
+
+ if (tx)
+ xferqa = fc->it;
+ else
+ xferqa = fc->ir;
+
+ mutex_enter(&fc->fc_mtx);
+ for (i = 0; i < fc->nisodma; i++) {
+ xferq = xferqa[i];
+ if (!(xferq->flag & FWXFERQ_OPEN)) {
+ xferq->flag |= FWXFERQ_OPEN;
+ break;
+ }
+ }
+ if (i == fc->nisodma) {
+ aprint_error_dev(fc->bdev, "no free dma channel (tx=%d)\n", tx);
+ i = -1;
+ }
+ mutex_exit(&fc->fc_mtx);
+ return i;
+}
+
+/*
+ * Async. request with given xfer structure.
+ */
+static void
+fw_asystart(struct fw_xfer *xfer)
+{
+ struct firewire_comm *fc = xfer->fc;
+
+ /* Protect from interrupt/timeout */
+ mutex_enter(&xfer->q->q_mtx);
+ xfer->flag = FWXF_INQ;
+ STAILQ_INSERT_TAIL(&xfer->q->q, xfer, link);
+#if 0
+ xfer->q->queued++;
+#endif
+ mutex_exit(&xfer->q->q_mtx);
+ /* XXX just queue for mbuf */
+ if (xfer->mbuf == NULL)
+ xfer->q->start(fc);
+ return;
+}
+
+static void
+firewire_xfer_timeout(struct firewire_comm *fc)
+{
+ struct fw_xfer *xfer;
+ struct timeval tv;
+ struct timeval split_timeout;
+ STAILQ_HEAD(, fw_xfer) xfer_timeout;
+ int i;
+
+ split_timeout.tv_sec = 0;
+ split_timeout.tv_usec = 200 * 1000; /* 200 msec */
+
+ microtime(&tv);
+ timersub(&tv, &split_timeout, &tv);
+ STAILQ_INIT(&xfer_timeout);
+
+ mutex_enter(&fc->tlabel_lock);
+ for (i = 0; i < 0x40; i++) {
+ while ((xfer = STAILQ_FIRST(&fc->tlabels[i])) != NULL) {
+ if ((xfer->flag & FWXF_SENT) == 0)
+ /* not sent yet */
+ break;
+ if (timercmp(&xfer->tv, &tv, >))
+ /* the rests are newer than this */
+ break;
+ aprint_error_dev(fc->bdev,
+ "split transaction timeout: tl=0x%x flag=0x%02x\n",
+ i, xfer->flag);
+ fw_dump_hdr(&xfer->send.hdr, "send");
+ xfer->resp = ETIMEDOUT;
+ STAILQ_REMOVE_HEAD(&fc->tlabels[i], tlabel);
+ STAILQ_INSERT_TAIL(&xfer_timeout, xfer, tlabel);
+ }
+ }
+ mutex_exit(&fc->tlabel_lock);
+ fc->timeout(fc);
+
+ STAILQ_FOREACH(xfer, &xfer_timeout, tlabel)
+ xfer->hand(xfer);
+}
+
+#define WATCHDOG_HZ 10
+static void
+firewire_watchdog(void *arg)
+{
+ struct firewire_comm *fc;
+ static int watchdog_clock = 0;
+
+ fc = (struct firewire_comm *)arg;
+
+ /*
+ * At boot stage, the device interrupt is disabled and
+ * We encounter a timeout easily. To avoid this,
+ * ignore clock interrupt for a while.
+ */
+ if (watchdog_clock > WATCHDOG_HZ * 15)
+ firewire_xfer_timeout(fc);
+ else
+ watchdog_clock++;
+
+ callout_schedule(&fc->timeout_callout, hz / WATCHDOG_HZ);
+}
+
+static void
+fw_xferq_drain(struct fw_xferq *xferq)
+{
+ struct fw_xfer *xfer;
+
+ while ((xfer = STAILQ_FIRST(&xferq->q)) != NULL) {
+ STAILQ_REMOVE_HEAD(&xferq->q, link);
+#if 0
+ xferq->queued--;
+#endif
+ xfer->resp = EAGAIN;
+ xfer->flag = FWXF_SENTERR;
+ fw_xfer_done(xfer);
+ }
+}
+
+static void
+fw_reset_csr(struct firewire_comm *fc)
+{
+ int i;
+
+ CSRARC(fc, STATE_CLEAR) =
+ 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14;
+ CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
+ CSRARC(fc, NODE_IDS) = 0x3f;
+
+ CSRARC(fc, TOPO_MAP + 8) = 0;
+ fc->irm = -1;
+
+ fc->max_node = -1;
+
+ for (i = 2; i < 0x100/4 - 2; i++)
+ CSRARC(fc, SPED_MAP + i * 4) = 0;
+ CSRARC(fc, STATE_CLEAR) =
+ 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14;
+ CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
+ CSRARC(fc, RESET_START) = 0;
+ CSRARC(fc, SPLIT_TIMEOUT_HI) = 0;
+ CSRARC(fc, SPLIT_TIMEOUT_LO) = 800 << 19;
+ CSRARC(fc, CYCLE_TIME) = 0x0;
+ CSRARC(fc, BUS_TIME) = 0x0;
+ CSRARC(fc, BUS_MGR_ID) = 0x3f;
+ CSRARC(fc, BANDWIDTH_AV) = 4915;
+ CSRARC(fc, CHANNELS_AV_HI) = 0xffffffff;
+ CSRARC(fc, CHANNELS_AV_LO) = 0xffffffff;
+ CSRARC(fc, IP_CHANNELS) = (1 << 31);
+
+ CSRARC(fc, CONF_ROM) = 0x04 << 24;
+ CSRARC(fc, CONF_ROM + 4) = 0x31333934; /* means strings 1394 */
+ CSRARC(fc, CONF_ROM + 8) =
+ 1 << 31 | 1 << 30 | 1 << 29 | 1 << 28 | 0xff << 16 | 0x09 << 8;
+ CSRARC(fc, CONF_ROM + 0xc) = 0;
+
+/* DV depend CSRs see blue book */
+ CSRARC(fc, oPCR) &= ~DV_BROADCAST_ON;
+ CSRARC(fc, iPCR) &= ~DV_BROADCAST_ON;
+
+ CSRARC(fc, STATE_CLEAR) &= ~(1 << 23 | 1 << 15 | 1 << 14);
+ CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
+}
+
+static void
+fw_init_crom(struct firewire_comm *fc)
+{
+ struct crom_src *src;
+
+ src = &fc->crom_src_buf->src;
+ memset(src, 0, sizeof(struct crom_src));
+
+ /* BUS info sample */
+ src->hdr.info_len = 4;
+
+ src->businfo.bus_name = CSR_BUS_NAME_IEEE1394;
+
+ src->businfo.irmc = 1;
+ src->businfo.cmc = 1;
+ src->businfo.isc = 1;
+ src->businfo.bmc = 1;
+ src->businfo.pmc = 0;
+ src->businfo.cyc_clk_acc = 100;
+ src->businfo.max_rec = fc->maxrec;
+ src->businfo.max_rom = MAXROM_4;
+ src->businfo.generation = FW_GENERATION_CHANGEABLE;
+ src->businfo.link_spd = fc->speed;
+
+ src->businfo.eui64.hi = fc->eui.hi;
+ src->businfo.eui64.lo = fc->eui.lo;
+
+ STAILQ_INIT(&src->chunk_list);
+
+ fc->crom_src = src;
+ fc->crom_root = &fc->crom_src_buf->root;
+}
+
+static void
+fw_reset_crom(struct firewire_comm *fc)
+{
+ struct crom_src_buf *buf;
+ struct crom_src *src;
+ struct crom_chunk *root;
+
+ buf = fc->crom_src_buf;
+ src = fc->crom_src;
+ root = fc->crom_root;
+
+ STAILQ_INIT(&src->chunk_list);
+
+ memset(root, 0, sizeof(struct crom_chunk));
+ crom_add_chunk(src, NULL, root, 0);
+ crom_add_entry(root, CSRKEY_NCAP, 0x0083c0); /* XXX */
+ /* private company_id */
+ crom_add_entry(root, CSRKEY_VENDOR, CSRVAL_VENDOR_PRIVATE);
+ crom_add_simple_text(src, root, &buf->vendor, PROJECT_STR);
+ crom_add_entry(root, CSRKEY_HW, __NetBSD_Version__);
+ crom_add_simple_text(src, root, &buf->hw, hostname);
+}
+
+/*
+ * dump packet header
+ */
+static void
+fw_dump_hdr(struct fw_pkt *fp, const char *prefix)
+{
+
+ printf("%s: dst=0x%02x tl=0x%02x rt=%d tcode=0x%x pri=0x%x "
+ "src=0x%03x\n", prefix,
+ fp->mode.hdr.dst & 0x3f,
+ fp->mode.hdr.tlrt >> 2, fp->mode.hdr.tlrt & 3,
+ fp->mode.hdr.tcode, fp->mode.hdr.pri,
+ fp->mode.hdr.src);
+}
+
+/*
+ * To free transaction label.
+ */
+static void
+fw_tl_free(struct firewire_comm *fc, struct fw_xfer *xfer)
+{
+ struct fw_xfer *txfer;
+
+ if (xfer->tl < 0)
+ return;
+
+ mutex_enter(&fc->tlabel_lock);
+#if 1 /* make sure the label is allocated */
+ STAILQ_FOREACH(txfer, &fc->tlabels[xfer->tl], tlabel)
+ if (txfer == xfer)
+ break;
+ if (txfer == NULL) {
+ mutex_exit(&fc->tlabel_lock);
+ aprint_error_dev(fc->bdev,
+ "the xfer is not in the queue (tlabel=%d, flag=0x%x)\n",
+ xfer->tl, xfer->flag);
+ fw_dump_hdr(&xfer->send.hdr, "send");
+ fw_dump_hdr(&xfer->recv.hdr, "recv");
+ cpu_Debugger();
+ return;
+ }
+#endif
+
+ STAILQ_REMOVE(&fc->tlabels[xfer->tl], xfer, fw_xfer, tlabel);
+ mutex_exit(&fc->tlabel_lock);
+ return;
+}
+
+/*
+ * To obtain XFER structure by transaction label.
+ */
+static struct fw_xfer *
+fw_tl2xfer(struct firewire_comm *fc, int node, int tlabel, int tcode)
+{
+ struct fw_xfer *xfer;
+ int req;
+
+ mutex_enter(&fc->tlabel_lock);
+ STAILQ_FOREACH(xfer, &fc->tlabels[tlabel], tlabel)
+ if (xfer->send.hdr.mode.hdr.dst == node) {
+ mutex_exit(&fc->tlabel_lock);
+ KASSERT(xfer->tl == tlabel);
+ /* extra sanity check */
+ req = xfer->send.hdr.mode.hdr.tcode;
+ if (xfer->fc->tcode[req].valid_res != tcode) {
+ aprint_error_dev(fc->bdev,
+ "invalid response tcode (0x%x for 0x%x)\n",
+ tcode, req);
+ return NULL;
+ }
+
+ if (firewire_debug > 2)
+ printf("fw_tl2xfer: found tl=%d\n", tlabel);
+ return xfer;
+ }
+ mutex_exit(&fc->tlabel_lock);
+ if (firewire_debug > 1)
+ printf("fw_tl2xfer: not found tl=%d\n", tlabel);
+ return NULL;
+}
+
+/*
+ * To configure PHY.
+ */
+static void
+fw_phy_config(struct firewire_comm *fc, int root_node, int gap_count)
+{
+ struct fw_xfer *xfer;
+ struct fw_pkt *fp;
+
+ fc->status = FWBUSPHYCONF;
+
+ xfer = fw_xfer_alloc(M_FWXFER);
+ if (xfer == NULL)
+ return;
+ xfer->fc = fc;
+ xfer->hand = fw_asy_callback_free;
+
+ fp = &xfer->send.hdr;
+ fp->mode.ld[1] = 0;
+ if (root_node >= 0)
+ fp->mode.ld[1] |= (root_node & 0x3f) << 24 | 1 << 23;
+ if (gap_count >= 0)
+ fp->mode.ld[1] |= 1 << 22 | (gap_count & 0x3f) << 16;
+ fp->mode.ld[2] = ~fp->mode.ld[1];
+/* XXX Dangerous, how to pass PHY packet to device driver */
+ fp->mode.common.tcode |= FWTCODE_PHY;
+
+ if (firewire_debug)
+ printf("root_node=%d gap_count=%d\n", root_node, gap_count);
+ fw_asyreq(fc, -1, xfer);
+}
+
+/*
+ * Dump self ID.
+ */
+static void
+fw_print_sid(uint32_t sid)
+{
+ union fw_self_id *s;
+
+ s = (union fw_self_id *) &sid;
+ if (s->p0.sequel) {
+ if (s->p1.sequence_num == FW_SELF_ID_PAGE0)
+ printf("node:%d p3:%d p4:%d p5:%d p6:%d p7:%d"
+ "p8:%d p9:%d p10:%d\n",
+ s->p1.phy_id, s->p1.port3, s->p1.port4,
+ s->p1.port5, s->p1.port6, s->p1.port7,
+ s->p1.port8, s->p1.port9, s->p1.port10);
+ else if (s->p2.sequence_num == FW_SELF_ID_PAGE1)
+ printf("node:%d p11:%d p12:%d p13:%d p14:%d p15:%d\n",
+ s->p2.phy_id, s->p2.port11, s->p2.port12,
+ s->p2.port13, s->p2.port14, s->p2.port15);
+ else
+ printf("node:%d Unknown Self ID Page number %d\n",
+ s->p1.phy_id, s->p1.sequence_num);
+ } else
+ printf("node:%d link:%d gap:%d spd:%d con:%d pwr:%d"
+ " p0:%d p1:%d p2:%d i:%d m:%d\n",
+ s->p0.phy_id, s->p0.link_active, s->p0.gap_count,
+ s->p0.phy_speed, s->p0.contender,
+ s->p0.power_class, s->p0.port0, s->p0.port1,
+ s->p0.port2, s->p0.initiated_reset, s->p0.more_packets);
+}
+
+/*
+ * To probe devices on the IEEE1394 bus.
*/
static void
fw_bus_probe(struct firewire_comm *fc)
{
- int s;
struct fw_device *fwdev;
- s = splfw();
+ mutex_enter(&fc->wait_lock);
fc->status = FWBUSEXPLORE;
/* Invalidate all devices, just after bus reset. */
+ if (firewire_debug)
+ printf("iterate and invalidate all nodes\n");
+ mutex_enter(&fc->fc_mtx);
STAILQ_FOREACH(fwdev, &fc->devices, link)
if (fwdev->status != FWDEVINVAL) {
fwdev->status = FWDEVINVAL;
fwdev->rcnt = 0;
- }
- splx(s);
+ if (firewire_debug)
+ printf("Invalidate Dev ID: %08x%08x\n",
+ fwdev->eui.hi, fwdev->eui.lo);
+ } else
+ if (firewire_debug)
+ printf("Dev ID: %08x%08x already invalid\n",
+ fwdev->eui.hi, fwdev->eui.lo);
+ mutex_exit(&fc->fc_mtx);
- wakeup((void *)fc);
+ cv_signal(&fc->fc_cv);
+ mutex_exit(&fc->wait_lock);
}
static int
-fw_explore_read_quads(struct fw_device *fwdev, int offset,
- uint32_t *quad, int n)
+fw_explore_read_quads(struct fw_device *fwdev, int offset, uint32_t *quad,
+ int length)
{
struct fw_xfer *xfer;
uint32_t tmp;
int i, error;
-
- for (i = 0; i < n; i ++, offset += sizeof(uint32_t)) {
- xfer = fwmem_read_quad(fwdev, NULL, -1,
- 0xffff, 0xf0000000 | offset, (void *)&tmp,
- fw_xferwake);
+ for (i = 0; i < length; i++, offset += sizeof(uint32_t)) {
+ xfer = fwmem_read_quad(fwdev, NULL, -1, 0xffff,
+ 0xf0000000 | offset, (void *)&tmp, fw_xferwake);
if (xfer == NULL)
- return (-1);
+ return -1;
fw_xferwait(xfer);
if (xfer->resp == 0)
@@ -1552,9 +1655,9 @@ fw_explore_read_quads(struct fw_device *fwdev, int offset,
error = xfer->resp;
fw_xfer_free(xfer);
if (error)
- return (error);
+ return error;
}
- return (0);
+ return 0;
}
@@ -1567,17 +1670,17 @@ fw_explore_csrblock(struct fw_device *fwdev, int offset, int recur)
dir = (struct csrdirectory *)&fwdev->csrrom[offset/sizeof(uint32_t)];
- err = fw_explore_read_quads(fwdev, CSRROMOFF + offset,
- (uint32_t *)dir, 1);
+ err = fw_explore_read_quads(fwdev, CSRROMOFF + offset, (uint32_t *)dir,
+ 1);
if (err)
- return (-1);
+ return -1;
offset += sizeof(uint32_t);
- reg = (struct csrreg *)&fwdev->csrrom[offset/sizeof(uint32_t)];
- err = fw_explore_read_quads(fwdev, CSRROMOFF + offset,
- (uint32_t *)reg, dir->crc_len);
+ reg = (struct csrreg *)&fwdev->csrrom[offset / sizeof(uint32_t)];
+ err = fw_explore_read_quads(fwdev, CSRROMOFF + offset, (uint32_t *)reg,
+ dir->crc_len);
if (err)
- return (-1);
+ return -1;
/* XXX check CRC */
@@ -1586,9 +1689,9 @@ fw_explore_csrblock(struct fw_device *fwdev, int offset, int recur)
fwdev->rommax = off;
if (recur == 0)
- return (0);
+ return 0;
- for (i = 0; i < dir->crc_len; i ++, offset += sizeof(uint32_t)) {
+ for (i = 0; i < dir->crc_len; i++, offset += sizeof(uint32_t)) {
if ((reg[i].key & CSRTYPE_MASK) == CSRTYPE_D)
recur = 1;
else if ((reg[i].key & CSRTYPE_MASK) == CSRTYPE_L)
@@ -1598,14 +1701,15 @@ fw_explore_csrblock(struct fw_device *fwdev, int offset, int recur)
off = offset + reg[i].val * sizeof(uint32_t);
if (off > CROMSIZE) {
- printf("%s: invalid offset %d\n", __func__, off);
- return(-1);
+ aprint_error_dev(fwdev->fc->bdev, "invalid offset %d\n",
+ off);
+ return -1;
}
err = fw_explore_csrblock(fwdev, off, recur);
if (err)
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
static int
@@ -1613,60 +1717,126 @@ fw_explore_node(struct fw_device *dfwdev)
{
struct firewire_comm *fc;
struct fw_device *fwdev, *pfwdev, *tfwdev;
- uint32_t *csr;
struct csrhdr *hdr;
struct bus_info *binfo;
- int err, node, spd;
+ uint32_t *csr, speed_test = 0;
+ int err, node;
fc = dfwdev->fc;
csr = dfwdev->csrrom;
node = dfwdev->dst;
/* First quad */
- err = fw_explore_read_quads(dfwdev, CSRROMOFF, &csr[0], 1);
- if (err)
- return (-1);
- hdr = (struct csrhdr *)&csr[0];
+#if 0
+printf("%s: speed=0x%x(0x%x)\n", __func__, dfwdev->speed, fc->speed_map->speed[fc->nodeid][node]);
+if (dfwdev->speed == 0)
+ dfwdev->speed = fc->speed_map->speed[fc->nodeid][node];
+else if (dfwdev->speed == 2)
+ dfwdev->speed = 1;
+else
+ dfwdev->speed = 0;
+printf("%s: Re: speed=0x%x\n", __func__, dfwdev->speed);
+#endif
+ err = fw_explore_read_quads(dfwdev, CSRROMOFF, csr, 1);
+ if (err) {
+ aprint_error_dev(fc->bdev,
+ "node%d: explore_read_quads failure\n", node);
+printf("err=%d\n", err);
+ dfwdev->status = FWDEVINVAL;
+ return -1;
+ }
+ hdr = (struct csrhdr *)csr;
if (hdr->info_len != 4) {
if (firewire_debug)
printf("node%d: wrong bus info len(%d)\n",
node, hdr->info_len);
- return (-1);
+ dfwdev->status = FWDEVINVAL;
+ return -1;
}
/* bus info */
err = fw_explore_read_quads(dfwdev, CSRROMOFF + 0x04, &csr[1], 4);
- if (err)
- return (-1);
+ if (err) {
+ aprint_error_dev(fc->bdev, "node%d: error reading 0x04\n",
+ node);
+ dfwdev->status = FWDEVINVAL;
+ return -1;
+ }
binfo = (struct bus_info *)&csr[1];
if (binfo->bus_name != CSR_BUS_NAME_IEEE1394) {
- if (firewire_debug)
- printf("node%d: invalid bus name 0x%08x\n",
- node, binfo->bus_name);
- return (-1);
+ aprint_error_dev(fc->bdev, "node%d: invalid bus name 0x%08x\n",
+ node, binfo->bus_name);
+ dfwdev->status = FWDEVINVAL;
+ return -1;
}
- spd = fc->speed_map->speed[fc->nodeid][node];
+ if (firewire_debug)
+ printf("node(%d) BUS INFO BLOCK:\n"
+ "irmc(%d) cmc(%d) isc(%d) bmc(%d) pmc(%d) "
+ "cyc_clk_acc(%d) max_rec(%d) max_rom(%d) "
+ "generation(%d) link_spd(%d)\n",
+ node, binfo->irmc, binfo->cmc, binfo->isc,
+ binfo->bmc, binfo->pmc, binfo->cyc_clk_acc,
+ binfo->max_rec, binfo->max_rom,
+ binfo->generation, binfo->link_spd);
+
+ mutex_enter(&fc->fc_mtx);
STAILQ_FOREACH(fwdev, &fc->devices, link)
if (FW_EUI64_EQUAL(fwdev->eui, binfo->eui64))
break;
+ mutex_exit(&fc->fc_mtx);
if (fwdev == NULL) {
/* new device */
- fwdev = malloc(sizeof(struct fw_device), M_FW,
- M_NOWAIT | M_ZERO);
+ fwdev =
+ malloc(sizeof(struct fw_device), M_FW, M_NOWAIT | M_ZERO);
if (fwdev == NULL) {
if (firewire_debug)
printf("node%d: no memory\n", node);
- return (-1);
+ return -1;
}
fwdev->fc = fc;
fwdev->eui = binfo->eui64;
+ fwdev->dst = dfwdev->dst;
+ fwdev->maxrec = dfwdev->maxrec;
fwdev->status = FWDEVNEW;
- /* insert into sorted fwdev list */
+ /*
+ * Pre-1394a-2000 didn't have link_spd in
+ * the Bus Info block, so try and use the
+ * speed map value.
+ * 1394a-2000 compliant devices only use
+ * the Bus Info Block link spd value, so
+ * ignore the speed map alltogether. SWB
+ */
+ if (binfo->link_spd == FWSPD_S100 /* 0 */) {
+ aprint_normal_dev(fc->bdev,
+ "Pre 1394a-2000 detected\n");
+ fwdev->speed = fc->speed_map->speed[fc->nodeid][node];
+ } else
+ fwdev->speed = binfo->link_spd;
+ /*
+ * Test this speed with a read to the CSRROM.
+ * If it fails, slow down the speed and retry.
+ */
+ while (fwdev->speed > FWSPD_S100 /* 0 */) {
+ err = fw_explore_read_quads(fwdev, CSRROMOFF,
+ &speed_test, 1);
+ if (err) {
+ aprint_error_dev(fc->bdev, "fwdev->speed(%s)"
+ " decremented due to negotiation\n",
+ fw_linkspeed[fwdev->speed]);
+ fwdev->speed--;
+ } else
+ break;
+ }
+ /*
+ * If the fwdev is not found in the
+ * fc->devices TAILQ, then we will add it.
+ */
pfwdev = NULL;
+ mutex_enter(&fc->fc_mtx);
STAILQ_FOREACH(tfwdev, &fc->devices, link) {
if (tfwdev->eui.hi > fwdev->eui.hi ||
- (tfwdev->eui.hi == fwdev->eui.hi &&
- tfwdev->eui.lo > fwdev->eui.lo))
+ (tfwdev->eui.hi == fwdev->eui.hi &&
+ tfwdev->eui.lo > fwdev->eui.lo))
break;
pfwdev = tfwdev;
}
@@ -1674,37 +1844,36 @@ fw_explore_node(struct fw_device *dfwdev)
STAILQ_INSERT_HEAD(&fc->devices, fwdev, link);
else
STAILQ_INSERT_AFTER(&fc->devices, pfwdev, fwdev, link);
+ mutex_exit(&fc->fc_mtx);
- fw_printf(fc->bdev, "New %s device ID:%08x%08x\n",
- fw_linkspeed[spd],
- fwdev->eui.hi, fwdev->eui.lo);
-
- } else
+ aprint_normal_dev(fc->bdev, "New %s device ID:%08x%08x\n",
+ fw_linkspeed[fwdev->speed], fwdev->eui.hi, fwdev->eui.lo);
+ } else {
+ fwdev->dst = node;
fwdev->status = FWDEVINIT;
- fwdev->dst = node;
- fwdev->speed = spd;
-
- /* unchanged ? */
- if (memcmp(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5) == 0) {
- if (firewire_debug)
- printf("node%d: crom unchanged\n", node);
- return (0);
+ /* unchanged ? */
+ if (memcmp(csr, fwdev->csrrom, sizeof(uint32_t) * 5) == 0) {
+ if (firewire_debug)
+ printf("node%d: crom unchanged\n", node);
+ return 0;
+ }
}
- memset(&fwdev->csrrom[0], 0, CROMSIZE);
+ memset(fwdev->csrrom, 0, CROMSIZE);
/* copy first quad and bus info block */
- bcopy(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5);
+ memcpy(fwdev->csrrom, csr, sizeof(uint32_t) * 5);
fwdev->rommax = CSRROMOFF + sizeof(uint32_t) * 4;
err = fw_explore_csrblock(fwdev, 0x14, 1); /* root directory */
if (err) {
+ if (firewire_debug)
+ printf("explore csrblock failed err(%d)\n", err);
fwdev->status = FWDEVINVAL;
fwdev->csrrom[0] = 0;
}
- return (err);
-
+ return err;
}
/*
@@ -1715,7 +1884,7 @@ fw_find_self_id(struct firewire_comm *fc, int node)
{
uint32_t i;
union fw_self_id *s;
-
+
for (i = 0; i < fc->topology_map->self_id_count; i++) {
s = &fc->topology_map->self_id[i];
if (s->p0.sequel)
@@ -1729,10 +1898,10 @@ fw_find_self_id(struct firewire_comm *fc, int node)
static void
fw_explore(struct firewire_comm *fc)
{
- int node, err, s, i, todo, todo2, trys;
- char nodes[63];
struct fw_device *dfwdev;
union fw_self_id *fwsid;
+ int node, err, i, todo, todo2, trys;
+ char nodes[63];
todo = 0;
dfwdev = malloc(sizeof(*dfwdev), M_TEMP, M_NOWAIT);
@@ -1744,10 +1913,17 @@ fw_explore(struct firewire_comm *fc)
dfwdev->maxrec = 8; /* 512 */
dfwdev->status = FWDEVINIT;
- for (node = 0; node <= fc->max_node; node ++) {
+ for (node = 0; node <= fc->max_node; node++) {
/* We don't probe myself and linkdown nodes */
- if (node == fc->nodeid)
+ if (node == fc->nodeid) {
+ if (firewire_debug)
+ printf("found myself node(%d) fc->nodeid(%d)"
+ " fc->max_node(%d)\n",
+ node, fc->nodeid, fc->max_node);
continue;
+ } else if (firewire_debug)
+ printf("node(%d) fc->max_node(%d) found\n",
+ node, fc->max_node);
fwsid = fw_find_self_id(fc, node);
if (!fwsid || !fwsid->p0.link_active) {
if (firewire_debug)
@@ -1757,48 +1933,47 @@ fw_explore(struct firewire_comm *fc)
nodes[todo++] = node;
}
- s = splfw();
- for (trys = 0; todo > 0 && trys < 3; trys ++) {
+ for (trys = 0; todo > 0 && trys < 3; trys++) {
todo2 = 0;
- for (i = 0; i < todo; i ++) {
+ for (i = 0; i < todo; i++) {
dfwdev->dst = nodes[i];
err = fw_explore_node(dfwdev);
if (err)
nodes[todo2++] = nodes[i];
if (firewire_debug)
- printf("%s: node %d, err = %d\n",
- __func__, node, err);
+ printf("node %d, err = %d\n", nodes[i], err);
}
todo = todo2;
}
- splx(s);
free(dfwdev, M_TEMP);
}
static void
fw_bus_probe_thread(void *arg)
{
- struct firewire_comm *fc;
-
- fc = (struct firewire_comm *)arg;
+ struct firewire_comm *fc = (struct firewire_comm *)arg;
- fw_config_pending_decr();
+ config_pending_decr();
- fw_mtx_lock(&fc->wait_lock);
+ mutex_enter(&fc->wait_lock);
while (fc->status != FWBUSDETACH) {
if (fc->status == FWBUSEXPLORE) {
- fw_mtx_unlock(&fc->wait_lock);
+ mutex_exit(&fc->wait_lock);
fw_explore(fc);
fc->status = FWBUSEXPDONE;
if (firewire_debug)
printf("bus_explore done\n");
fw_attach_dev(fc);
- fw_mtx_lock(&fc->wait_lock);
+ mutex_enter(&fc->wait_lock);
}
- fw_msleep((void *)fc, &fc->wait_lock, PWAIT|PCATCH, "-", 0);
+ cv_wait_sig(&fc->fc_cv, &fc->wait_lock);
}
- fw_mtx_unlock(&fc->wait_lock);
- fw_kthread_exit(0);
+ fc->status = FWBUSDETACHOK;
+ cv_signal(&fc->fc_cv);
+ mutex_exit(&fc->wait_lock);
+ kthread_exit(0);
+
+ /* NOTREACHED */
}
@@ -1808,18 +1983,56 @@ fw_bus_probe_thread(void *arg)
static void
fw_attach_dev(struct firewire_comm *fc)
{
+ struct firewire_softc *sc = device_private(fc->bdev);
+ struct firewire_dev_list *devlist, *elm;
struct fw_device *fwdev, *next;
struct firewire_dev_comm *fdc;
struct fw_attach_args fwa;
+ int locs[IEEE1394IFCF_NLOCS];
fwa.name = "sbp";
fwa.fc = fc;
+ mutex_enter(&fc->fc_mtx);
for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL; fwdev = next) {
next = STAILQ_NEXT(fwdev, link);
+ mutex_exit(&fc->fc_mtx);
switch (fwdev->status) {
case FWDEVNEW:
- FIREWIRE_SBP_ATTACH;
+ devlist = malloc(sizeof(struct firewire_dev_list),
+ M_DEVBUF, M_NOWAIT);
+ if (devlist == NULL) {
+ aprint_error_dev(fc->bdev,
+ "memory allocation failed\n");
+ break;
+ }
+
+ locs[IEEE1394IFCF_EUIHI] = fwdev->eui.hi;
+ locs[IEEE1394IFCF_EUILO] = fwdev->eui.lo;
+
+ fwa.fwdev = fwdev;
+ fwdev->sbp = config_found_sm_loc(sc->dev, "ieee1394if",
+ locs, &fwa, firewire_print, config_stdsubmatch);
+ if (fwdev->sbp == NULL) {
+ free(devlist, M_DEVBUF);
+ break;
+ }
+
+ devlist->fwdev = fwdev;
+ devlist->dev = fwdev->sbp;
+
+ mutex_enter(&fc->fc_mtx);
+ if (SLIST_EMPTY(&sc->devlist))
+ SLIST_INSERT_HEAD(&sc->devlist, devlist, link);
+ else {
+ for (elm = SLIST_FIRST(&sc->devlist);
+ SLIST_NEXT(elm, link) != NULL;
+ elm = SLIST_NEXT(elm, link));
+ SLIST_INSERT_AFTER(elm, devlist, link);
+ }
+ mutex_exit(&fc->fc_mtx);
+
+ /* FALLTHROUGH */
case FWDEVINIT:
case FWDEVATTACHED:
@@ -1827,16 +2040,25 @@ fw_attach_dev(struct firewire_comm *fc)
break;
case FWDEVINVAL:
- fwdev->rcnt ++;
+ fwdev->rcnt++;
+ if (firewire_debug)
+ printf("fwdev->rcnt(%d), hold_count(%d)\n",
+ fwdev->rcnt, hold_count);
break;
default:
/* XXX */
break;
}
+ mutex_enter(&fc->fc_mtx);
}
+ mutex_exit(&fc->fc_mtx);
- FIREWIRE_CHILDREN_FOREACH_FUNC(post_explore, fdc);
+ SLIST_FOREACH(devlist, &sc->devlist, link) {
+ fdc = device_private(devlist->dev);
+ if (fdc->post_explore != NULL)
+ fdc->post_explore(fdc);
+ }
for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL; fwdev = next) {
next = STAILQ_NEXT(fwdev, link);
@@ -1845,7 +2067,19 @@ fw_attach_dev(struct firewire_comm *fc)
* Remove devices which have not been seen
* for a while.
*/
- FIREWIRE_SBP_DETACH;
+ SLIST_FOREACH(devlist, &sc->devlist, link)
+ if (devlist->fwdev == fwdev)
+ break;
+ if (devlist->fwdev != fwdev)
+ panic("already detached");
+
+ SLIST_REMOVE(&sc->devlist, devlist, firewire_dev_list,
+ link);
+ free(devlist, M_DEVBUF);
+
+ if (config_detach(fwdev->sbp, DETACH_FORCE) != 0)
+ return;
+
STAILQ_REMOVE(&fc->devices, fwdev, fw_device, link);
free(fwdev, M_FW);
}
@@ -1862,32 +2096,29 @@ fw_get_tlabel(struct firewire_comm *fc, struct fw_xfer *xfer)
{
u_int dst, new_tlabel;
struct fw_xfer *txfer;
- int s;
dst = xfer->send.hdr.mode.hdr.dst & 0x3f;
- s = splfw();
- fw_mtx_lock(&fc->tlabel_lock);
+ mutex_enter(&fc->tlabel_lock);
new_tlabel = (fc->last_tlabel[dst] + 1) & 0x3f;
STAILQ_FOREACH(txfer, &fc->tlabels[new_tlabel], tlabel)
if ((txfer->send.hdr.mode.hdr.dst & 0x3f) == dst)
break;
- if(txfer == NULL) {
+ if (txfer == NULL) {
fc->last_tlabel[dst] = new_tlabel;
STAILQ_INSERT_TAIL(&fc->tlabels[new_tlabel], xfer, tlabel);
- fw_mtx_unlock(&fc->tlabel_lock);
- splx(s);
+ mutex_exit(&fc->tlabel_lock);
xfer->tl = new_tlabel;
xfer->send.hdr.mode.hdr.tlrt = new_tlabel << 2;
if (firewire_debug > 1)
- printf("fw_get_tlabel: dst=%d tl=%d\n", dst, new_tlabel);
- return (new_tlabel);
+ printf("fw_get_tlabel: dst=%d tl=%d\n",
+ dst, new_tlabel);
+ return new_tlabel;
}
- fw_mtx_unlock(&fc->tlabel_lock);
- splx(s);
+ mutex_exit(&fc->tlabel_lock);
if (firewire_debug > 1)
printf("fw_get_tlabel: no free tlabel\n");
- return (-1);
+ return -1;
}
static void
@@ -1903,9 +2134,9 @@ fw_rcv_copy(struct fw_rcv_buf *rb)
pkt = (struct fw_pkt *)rb->vec->iov_base;
tinfo = &rb->fc->tcode[pkt->mode.hdr.tcode];
- /* Copy header */
+ /* Copy header */
p = (u_char *)&rb->xfer->recv.hdr;
- bcopy(rb->vec->iov_base, p, tinfo->hdr_len);
+ memcpy(p, rb->vec->iov_base, tinfo->hdr_len);
rb->vec->iov_base = (u_char *)rb->vec->iov_base + tinfo->hdr_len;
rb->vec->iov_len -= tinfo->hdr_len;
@@ -1929,12 +2160,13 @@ fw_rcv_copy(struct fw_rcv_buf *rb)
for (i = 0; i < rb->nvec; i++, rb->vec++) {
len = MIN(rb->vec->iov_len, plen);
if (res < len) {
- printf("rcv buffer(%d) is %d bytes short.\n",
+ aprint_error_dev(rb->fc->bdev,
+ "rcv buffer(%d) is %d bytes short.\n",
rb->xfer->recv.pay_len, len - res);
len = res;
}
if (p) {
- bcopy(rb->vec->iov_base, p, len);
+ memcpy(p, rb->vec->iov_base, len);
p += len;
}
res -= len;
@@ -1947,206 +2179,6 @@ fw_rcv_copy(struct fw_rcv_buf *rb)
}
/*
- * Generic packet receiving process.
- */
-void
-fw_rcv(struct fw_rcv_buf *rb)
-{
- struct fw_pkt *fp, *resfp;
- struct fw_bind *bind;
- int tcode;
- int i, len, oldstate;
-#if 0
- {
- uint32_t *qld;
- int i;
- qld = (uint32_t *)buf;
- printf("spd %d len:%d\n", spd, len);
- for( i = 0 ; i <= len && i < 32; i+= 4){
- printf("0x%08x ", ntohl(qld[i/4]));
- if((i % 16) == 15) printf("\n");
- }
- if((i % 16) != 15) printf("\n");
- }
-#endif
- fp = (struct fw_pkt *)rb->vec[0].iov_base;
- tcode = fp->mode.common.tcode;
- switch (tcode) {
- case FWTCODE_WRES:
- case FWTCODE_RRESQ:
- case FWTCODE_RRESB:
- case FWTCODE_LRES:
- rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src,
- fp->mode.hdr.tlrt >> 2, fp->mode.hdr.tcode);
- if(rb->xfer == NULL) {
- printf("fw_rcv: unknown response "
- "%s(%x) src=0x%x tl=0x%x rt=%d data=0x%x\n",
- tcode_str[tcode], tcode,
- fp->mode.hdr.src,
- fp->mode.hdr.tlrt >> 2,
- fp->mode.hdr.tlrt & 3,
- fp->mode.rresq.data);
-#if 0
- printf("try ad-hoc work around!!\n");
- rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src,
- (fp->mode.hdr.tlrt >> 2)^3);
- if (rb->xfer == NULL) {
- printf("no use...\n");
- return;
- }
-#else
- return;
-#endif
- }
- fw_rcv_copy(rb);
- if (rb->xfer->recv.hdr.mode.wres.rtcode != RESP_CMP)
- rb->xfer->resp = EIO;
- else
- rb->xfer->resp = 0;
- /* make sure the packet is drained in AT queue */
- oldstate = rb->xfer->flag;
- rb->xfer->flag = FWXF_RCVD;
- switch (oldstate) {
- case FWXF_SENT:
- fw_xfer_done(rb->xfer);
- break;
- case FWXF_START:
-#if 0
- if (firewire_debug)
- printf("not sent yet tl=%x\n", rb->xfer->tl);
-#endif
- break;
- default:
- printf("unexpected flag 0x%02x\n", rb->xfer->flag);
- }
- return;
- case FWTCODE_WREQQ:
- case FWTCODE_WREQB:
- case FWTCODE_RREQQ:
- case FWTCODE_RREQB:
- case FWTCODE_LREQ:
- bind = fw_bindlookup(rb->fc, fp->mode.rreqq.dest_hi,
- fp->mode.rreqq.dest_lo);
- if(bind == NULL){
-#if 1
- printf("Unknown service addr 0x%04x:0x%08x %s(%x)"
-#if defined(__DragonFly__) || \
- (defined(__FreeBSD__) && __FreeBSD_version < 500000)
- " src=0x%x data=%lx\n",
-#else
- " src=0x%x data=%x\n",
-#endif
- fp->mode.wreqq.dest_hi, fp->mode.wreqq.dest_lo,
- tcode_str[tcode], tcode,
- fp->mode.hdr.src, ntohl(fp->mode.wreqq.data));
-#endif
- if (rb->fc->status == FWBUSINIT) {
- printf("fw_rcv: cannot respond(bus reset)!\n");
- return;
- }
- rb->xfer = fw_xfer_alloc(M_FWXFER);
- if(rb->xfer == NULL){
- return;
- }
- rb->xfer->send.spd = rb->spd;
- rb->xfer->send.pay_len = 0;
- resfp = &rb->xfer->send.hdr;
- switch (tcode) {
- case FWTCODE_WREQQ:
- case FWTCODE_WREQB:
- resfp->mode.hdr.tcode = FWTCODE_WRES;
- break;
- case FWTCODE_RREQQ:
- resfp->mode.hdr.tcode = FWTCODE_RRESQ;
- break;
- case FWTCODE_RREQB:
- resfp->mode.hdr.tcode = FWTCODE_RRESB;
- break;
- case FWTCODE_LREQ:
- resfp->mode.hdr.tcode = FWTCODE_LRES;
- break;
- }
- resfp->mode.hdr.dst = fp->mode.hdr.src;
- resfp->mode.hdr.tlrt = fp->mode.hdr.tlrt;
- resfp->mode.hdr.pri = fp->mode.hdr.pri;
- resfp->mode.rresb.rtcode = RESP_ADDRESS_ERROR;
- resfp->mode.rresb.extcode = 0;
- resfp->mode.rresb.len = 0;
-/*
- rb->xfer->hand = fw_xferwake;
-*/
- rb->xfer->hand = fw_xfer_free;
- if(fw_asyreq(rb->fc, -1, rb->xfer)){
- fw_xfer_free(rb->xfer);
- return;
- }
- return;
- }
- len = 0;
- for (i = 0; i < rb->nvec; i ++)
- len += rb->vec[i].iov_len;
- rb->xfer = STAILQ_FIRST(&bind->xferlist);
- if (rb->xfer == NULL) {
-#if 1
- printf("Discard a packet for this bind.\n");
-#endif
- return;
- }
- STAILQ_REMOVE_HEAD(&bind->xferlist, link);
- fw_rcv_copy(rb);
- rb->xfer->hand(rb->xfer);
- return;
-#if 0 /* shouldn't happen ?? or for GASP */
- case FWTCODE_STREAM:
- {
- struct fw_xferq *xferq;
-
- xferq = rb->fc->ir[sub];
-#if 0
- printf("stream rcv dma %d len %d off %d spd %d\n",
- sub, len, off, spd);
-#endif
- if(xferq->queued >= xferq->maxq) {
- printf("receive queue is full\n");
- return;
- }
- /* XXX get xfer from xfer queue, we don't need copy for
- per packet mode */
- rb->xfer = fw_xfer_alloc_buf(M_FWXFER, 0, /* XXX */
- vec[0].iov_len);
- if (rb->xfer == NULL)
- return;
- fw_rcv_copy(rb)
- s = splfw();
- xferq->queued++;
- STAILQ_INSERT_TAIL(&xferq->q, rb->xfer, link);
- splx(s);
- sc = device_get_softc(rb->fc->bdev);
-#if defined(__DragonFly__) || \
- (defined(__FreeBSD__) && __FreeBSD_version < 500000)
- if (&xferq->rsel.si_pid != 0)
-#else
- if (SEL_WAITING(&xferq->rsel))
-#endif
- selwakeuppri(&xferq->rsel, FWPRI);
- if (xferq->flag & FWXFERQ_WAKEUP) {
- xferq->flag &= ~FWXFERQ_WAKEUP;
- wakeup((void *)xferq);
- }
- if (xferq->flag & FWXFERQ_HANDLER) {
- xferq->hand(xferq);
- }
- return;
- break;
- }
-#endif
- default:
- printf("fw_rcv: unknow tcode %d\n", tcode);
- break;
- }
-}
-
-/*
* Post process for Bus Manager election process.
*/
static void
@@ -2175,7 +2207,7 @@ fw_try_bmr_callback(struct fw_xfer *xfer)
return;
error:
- fw_printf(fc->bdev, "bus manager election failed\n");
+ aprint_error_dev(fc->bdev, "bus manager election failed\n");
fw_xfer_free_buf(xfer);
}
@@ -2192,9 +2224,8 @@ fw_try_bmr(void *arg)
int err = 0;
xfer = fw_xfer_alloc_buf(M_FWXFER, 8, 4);
- if(xfer == NULL){
+ if (xfer == NULL)
return;
- }
xfer->send.spd = 0;
fc->status = FWBUSMGRELECT;
@@ -2213,107 +2244,19 @@ fw_try_bmr(void *arg)
xfer->hand = fw_try_bmr_callback;
err = fw_asyreq(fc, -1, xfer);
- if(err){
+ if (err) {
fw_xfer_free_buf(xfer);
return;
}
return;
}
-#ifdef FW_VMACCESS
/*
- * Software implementation for physical memory block access.
- * XXX:Too slow, usef for debug purpose only.
+ * Find the root node, if it is not
+ * Cycle Master Capable, then we should
+ * override this and become the Cycle
+ * Master
*/
-static void
-fw_vmaccess(struct fw_xfer *xfer){
- struct fw_pkt *rfp, *sfp = NULL;
- uint32_t *ld = (uint32_t *)xfer->recv.buf;
-
- printf("vmaccess spd:%2x len:%03x data:%08x %08x %08x %08x\n",
- xfer->spd, xfer->recv.len, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3]));
- printf("vmaccess data:%08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
- if(xfer->resp != 0){
- fw_xfer_free( xfer);
- return;
- }
- if(xfer->recv.buf == NULL){
- fw_xfer_free( xfer);
- return;
- }
- rfp = (struct fw_pkt *)xfer->recv.buf;
- switch(rfp->mode.hdr.tcode){
- /* XXX need fix for 64bit arch */
- case FWTCODE_WREQB:
- xfer->send.buf = malloc(12, M_FW, M_NOWAIT);
- xfer->send.len = 12;
- sfp = (struct fw_pkt *)xfer->send.buf;
- bcopy(rfp->mode.wreqb.payload,
- (void *)ntohl(rfp->mode.wreqb.dest_lo), ntohs(rfp->mode.wreqb.len));
- sfp->mode.wres.tcode = FWTCODE_WRES;
- sfp->mode.wres.rtcode = 0;
- break;
- case FWTCODE_WREQQ:
- xfer->send.buf = malloc(12, M_FW, M_NOWAIT);
- xfer->send.len = 12;
- sfp->mode.wres.tcode = FWTCODE_WRES;
- *((uint32_t *)(ntohl(rfp->mode.wreqb.dest_lo))) = rfp->mode.wreqq.data;
- sfp->mode.wres.rtcode = 0;
- break;
- case FWTCODE_RREQB:
- xfer->send.buf = malloc(16 + rfp->mode.rreqb.len, M_FW, M_NOWAIT);
- xfer->send.len = 16 + ntohs(rfp->mode.rreqb.len);
- sfp = (struct fw_pkt *)xfer->send.buf;
- bcopy((void *)ntohl(rfp->mode.rreqb.dest_lo),
- sfp->mode.rresb.payload, (uint16_t)ntohs(rfp->mode.rreqb.len));
- sfp->mode.rresb.tcode = FWTCODE_RRESB;
- sfp->mode.rresb.len = rfp->mode.rreqb.len;
- sfp->mode.rresb.rtcode = 0;
- sfp->mode.rresb.extcode = 0;
- break;
- case FWTCODE_RREQQ:
- xfer->send.buf = malloc(16, M_FW, M_NOWAIT);
- xfer->send.len = 16;
- sfp = (struct fw_pkt *)xfer->send.buf;
- sfp->mode.rresq.data = *(uint32_t *)(ntohl(rfp->mode.rreqq.dest_lo));
- sfp->mode.wres.tcode = FWTCODE_RRESQ;
- sfp->mode.rresb.rtcode = 0;
- break;
- default:
- fw_xfer_free( xfer);
- return;
- }
- sfp->mode.hdr.dst = rfp->mode.hdr.src;
- xfer->dst = ntohs(rfp->mode.hdr.src);
- xfer->hand = fw_xfer_free;
-
- sfp->mode.hdr.tlrt = rfp->mode.hdr.tlrt;
- sfp->mode.hdr.pri = 0;
-
- fw_asyreq(xfer->fc, -1, xfer);
-/**/
- return;
-}
-#endif
-
-/*
- * CRC16 check-sum for IEEE1394 register blocks.
- */
-uint16_t
-fw_crc16(uint32_t *ptr, uint32_t len){
- uint32_t i, sum, crc = 0;
- int shift;
- len = (len + 3) & ~3;
- for(i = 0 ; i < len ; i+= 4){
- for( shift = 28 ; shift >= 0 ; shift -= 4){
- sum = ((crc >> 12) ^ (ptr[i/4] >> shift)) & 0xf;
- crc = (crc << 4) ^ ( sum << 12 ) ^ ( sum << 5) ^ sum;
- }
- crc &= 0xffff;
- }
- return((uint16_t) crc);
-}
-
static int
fw_bmr(struct firewire_comm *fc)
{
@@ -2329,7 +2272,7 @@ fw_bmr(struct firewire_comm *fc)
if (self_id->p0.link_active && self_id->p0.contender)
cmstr = fc->max_node;
else {
- fw_printf(fc->bdev,
+ aprint_normal_dev(fc->bdev,
"root node is not cycle master capable\n");
/* XXX shall we be the cycle master? */
cmstr = fc->nodeid;
@@ -2338,16 +2281,15 @@ fw_bmr(struct firewire_comm *fc)
} else
cmstr = -1;
- fw_printf(fc->bdev, "bus manager %d ", CSRARC(fc, BUS_MGR_ID));
- if(CSRARC(fc, BUS_MGR_ID) != fc->nodeid) {
+ aprint_normal_dev(fc->bdev, "bus manager %d%s\n",
+ CSRARC(fc, BUS_MGR_ID),
+ (CSRARC(fc, BUS_MGR_ID) != fc->nodeid) ? " (me)" : "");
+ if (CSRARC(fc, BUS_MGR_ID) != fc->nodeid)
/* We are not the bus manager */
- aprint_normal("\n");
- return(0);
- }
- aprint_normal("(me)\n");
+ return 0;
/* Optimize gapcount */
- if(fc->max_hop <= MAX_GAPHOP )
+ if (fc->max_hop <= MAX_GAPHOP)
fw_phy_config(fc, cmstr, gap_cnt[fc->max_hop]);
/* If we are the cycle master, nothing to do */
if (cmstr == fc->nodeid || cmstr == -1)
@@ -2361,74 +2303,8 @@ fw_bmr(struct firewire_comm *fc)
fwdev.status = FWDEVINIT;
/* Set cmstr bit on the cycle master */
quad = htonl(1 << 8);
- fwmem_write_quad(&fwdev, NULL, 0/*spd*/,
- 0xffff, 0xf0000000 | STATE_SET, &quad, fw_asy_callback_free);
+ fwmem_write_quad(&fwdev, NULL, 0/*spd*/, 0xffff, 0xf0000000 | STATE_SET,
+ &quad, fw_asy_callback_free);
return 0;
}
-
-int
-fw_open_isodma(struct firewire_comm *fc, int tx)
-{
- struct fw_xferq **xferqa;
- struct fw_xferq *xferq;
- int i;
-
- if (tx)
- xferqa = &fc->it[0];
- else
- xferqa = &fc->ir[0];
-
- FW_GLOCK(fc);
- for (i = 0; i < fc->nisodma; i ++) {
- xferq = xferqa[i];
- if ((xferq->flag & FWXFERQ_OPEN) == 0) {
- xferq->flag |= FWXFERQ_OPEN;
- break;
- }
- }
- if (i == fc->nisodma) {
- printf("no free dma channel (tx=%d)\n", tx);
- i = -1;
- }
- FW_GUNLOCK(fc);
- return (i);
-}
-
-#if defined(__FreeBSD__)
-static int
-fw_modevent(module_t mode, int type, void *data)
-{
- int err = 0;
-#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
- static eventhandler_tag fwdev_ehtag = NULL;
-#endif
-
- switch (type) {
- case MOD_LOAD:
-#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
- fwdev_ehtag = EVENTHANDLER_REGISTER(dev_clone,
- fwdev_clone, 0, 1000);
-#endif
- break;
- case MOD_UNLOAD:
-#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
- if (fwdev_ehtag != NULL)
- EVENTHANDLER_DEREGISTER(dev_clone, fwdev_ehtag);
-#endif
- break;
- case MOD_SHUTDOWN:
- break;
- default:
- return (EOPNOTSUPP);
- }
- return (err);
-}
-
-
-#ifdef __DragonFly__
-DECLARE_DUMMY_MODULE(firewire);
-#endif
-DRIVER_MODULE(firewire,fwohci,firewire_driver,firewire_devclass,fw_modevent,0);
-MODULE_VERSION(firewire, 1);
-#endif
diff --git a/sys/dev/ieee1394/firewire.h b/sys/dev/ieee1394/firewire.h
index f59c55b6528..dc0c835b755 100644
--- a/sys/dev/ieee1394/firewire.h
+++ b/sys/dev/ieee1394/firewire.h
@@ -1,4 +1,4 @@
-/* $NetBSD: firewire.h,v 1.4 2007/11/05 19:08:56 kiyohara Exp $ */
+/* $NetBSD: firewire.h,v 1.5 2010/03/29 03:05:27 kiyohara Exp $ */
/*-
* Copyright (c) 2003 Hidetoshi Shimokawa
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
@@ -31,13 +31,13 @@
* 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.
- *
- * $FreeBSD: src/sys/dev/firewire/firewire.h,v 1.21 2007/04/24 12:15:05 simokawa Exp $
+ *
+ * $FreeBSD: src/sys/dev/firewire/firewire.h,v 1.25 2009/02/17 19:37:04 sbruno Exp $
*
*/
-#ifndef _FIREWIRE_H
-#define _FIREWIRE_H 1
+#ifndef _FIREWIRE_H_
+#define _FIREWIRE_H_
#define DEV_DEF 0
#define DEV_DV 2
@@ -100,9 +100,16 @@ struct fw_reg_req_t {
#define FWRCODE_ER_TYPE 6
#define FWRCODE_ER_ADDR 7
+/*
+ * Defined 1394a-2000
+ * Table 5B-1
+ */
#define FWSPD_S100 0
#define FWSPD_S200 1
#define FWSPD_S400 2
+#define FWSPD_S800 3
+#define FWSPD_S1600 4
+#define FWSPD_S3200 5
#define FWP_TL_VALID (1 << 7)
@@ -278,10 +285,18 @@ struct fw_devlstreq {
struct fw_devinfo dev[FW_MAX_DEVLST];
};
+/*
+ * Defined in IEEE 1394a-2000
+ * 4.3.4.1
+ */
#define FW_SELF_ID_PORT_CONNECTED_TO_CHILD 3
#define FW_SELF_ID_PORT_CONNECTED_TO_PARENT 2
#define FW_SELF_ID_PORT_NOT_CONNECTED 1
#define FW_SELF_ID_PORT_NOT_EXISTS 0
+
+#define FW_SELF_ID_PAGE0 0
+#define FW_SELF_ID_PAGE1 1
+
#if BYTE_ORDER == BIG_ENDIAN
union fw_self_id {
struct {
@@ -291,7 +306,7 @@ union fw_self_id {
link_active:1,
gap_count:6,
phy_speed:2,
- phy_delay:2,
+ reserved:2,
contender:1,
power_class:3,
port0:2,
@@ -306,18 +321,32 @@ union fw_self_id {
phy_id:6,
sequel:1,
sequence_num:3,
- :2,
- porta:2,
- portb:2,
- portc:2,
- portd:2,
- porte:2,
- portf:2,
- portg:2,
- porth:2,
- :1,
+ reserved2:2,
+ port3:2,
+ port4:2,
+ port5:2,
+ port6:2,
+ port7:2,
+ port8:2,
+ port9:2,
+ port10:2,
+ reserved1:1,
more_packets:1;
} p1;
+ struct {
+ uint32_t
+ id:2,
+ phy_id:6,
+ sequel:1,
+ sequence_num:3,
+ :2,
+ port11:2,
+ port12:2,
+ port13:2,
+ port14:2,
+ port15:2,
+ :8;
+ } p2;
};
#else
union fw_self_id {
@@ -329,7 +358,7 @@ union fw_self_id {
port0:2,
power_class:3,
contender:1,
- phy_delay:2,
+ reserved:2,
phy_speed:2,
gap_count:6,
link_active:1,
@@ -340,20 +369,34 @@ union fw_self_id {
struct {
uint32_t more_packets:1,
reserved1:1,
- porth:2,
- portg:2,
- portf:2,
- porte:2,
- portd:2,
- portc:2,
- portb:2,
- porta:2,
+ port10:2,
+ port9:2,
+ port8:2,
+ port7:2,
+ port6:2,
+ port5:2,
+ port4:2,
+ port3:2,
reserved2:2,
sequence_num:3,
sequel:1,
phy_id:6,
id:2;
} p1;
+ struct {
+ uint32_t
+ reserved3:8,
+ port15:2,
+ port14:2,
+ port13:2,
+ port12:2,
+ port11:2,
+ reserved4:2,
+ sequence_num:3,
+ sequel:1,
+ phy_id:6,
+ id:2;
+ } p2;
};
#endif
@@ -412,15 +455,15 @@ struct fw_crom_buf {
#define FWMAXNDMA 0x100 /* 8 bits DMA channel id. in device No. */
-#define MAKEMINOR(f, u, s) \
- fw_unit2minor((f) | (((u) & 0xff) << 8) | (s & 0xff))
-#define DEV2UNIT(x) ((fw_dev2unit(x) & 0xff00) >> 8)
-#define DEV2SUB(x) (fw_dev2unit(x) & 0xff)
+#define unit2minor(x) (((x) & 0xff) | (((x) << 12) & ~0xfffff))
+#define MAKEMINOR(f, u, s) ((f) | (((u) & 0xff) << 8) | ((s) & 0xff))
+#define DEV2UNIT(x) ((minor(x) & 0xff00) >> 8)
+#define DEV2SUB(x) (minor(x) & 0xff)
#define FW_UNITMASK MAKEMINOR(0, -1, 0)
#define FW_UNIT(unit) MAKEMINOR(0, unit, 0)
#define FWMEM_FLAG 0x10000
-#define DEV_FWMEM(x) (fw_dev2unit(x) & FWMEM_FLAG)
+#define DEV_FWMEM(x) (minor(x) & FWMEM_FLAG)
struct fw_attach_args {
const char *name;
@@ -429,4 +472,4 @@ struct fw_attach_args {
};
#endif
-#endif
+#endif /* _FIREWIRE_H_ */
diff --git a/sys/dev/ieee1394/firewire_phy.h b/sys/dev/ieee1394/firewire_phy.h
index d2c7412d2fd..b4a0f805080 100644
--- a/sys/dev/ieee1394/firewire_phy.h
+++ b/sys/dev/ieee1394/firewire_phy.h
@@ -1,4 +1,4 @@
-/* $NetBSD: firewire_phy.h,v 1.2 2005/12/11 12:22:02 christos Exp $ */
+/* $NetBSD: firewire_phy.h,v 1.3 2010/03/29 03:05:27 kiyohara Exp $ */
/*-
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
* All rights reserved.
@@ -30,10 +30,12 @@
* 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.
- *
+ *
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/firewire_phy.h,v 1.3 2005/01/06 01:42:41 imp Exp $
*
*/
+#ifndef _FIREWIRE_PHY_H_
+#define _FIREWIRE_PHY_H_
#define FW_PHY_PHYSID_REG 0x00
#define FW_PHY_PHYSID (63<<2)
@@ -84,3 +86,5 @@
#define FW_PHY_EDEL_REG 0x03
#define FW_PHY_EDEL 15<<0
+
+#endif /* _FIREWIRE_PHY_H_ */
diff --git a/sys/dev/ieee1394/firewirereg.h b/sys/dev/ieee1394/firewirereg.h
index f513a97b289..8b748e25cf6 100644
--- a/sys/dev/ieee1394/firewirereg.h
+++ b/sys/dev/ieee1394/firewirereg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: firewirereg.h,v 1.10 2009/06/20 20:18:32 dyoung Exp $ */
+/* $NetBSD: firewirereg.h,v 1.11 2010/03/29 03:05:27 kiyohara Exp $ */
/*-
* Copyright (c) 2003 Hidetoshi Shimokawa
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
@@ -31,16 +31,20 @@
* 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.
- *
+ *
* $FreeBSD: src/sys/dev/firewire/firewirereg.h,v 1.50 2007/07/20 03:42:57 simokawa Exp $
*
*/
+#ifndef _FIREWIREREG_H_
+#define _FIREWIREREG_H_
#include <sys/uio.h>
+#define PROJECT_STR "The NetBSD Project"
+
STAILQ_HEAD(fw_xferlist, fw_xfer);
-struct fw_device{
+struct fw_device {
uint16_t dst;
struct fw_eui64 eui;
uint8_t speed;
@@ -66,9 +70,9 @@ struct firewire_softc {
device_t dev;
SLIST_HEAD(, firewire_dev_list) devlist;
void *si_drv1;
- int si_iosize_max;
struct firewire_comm *fc;
};
+
struct firewire_dev_list {
SLIST_ENTRY(firewire_dev_list) link;
device_t dev;
@@ -97,7 +101,7 @@ struct tcode_info {
u_char valid_res;
};
-struct firewire_comm{
+struct firewire_comm {
device_t dev;
device_t bdev;
uint16_t busid:10,
@@ -111,6 +115,7 @@ struct firewire_comm{
u_int max_hop;
#define FWPHYASYST (1 << 0)
uint32_t status;
+#define FWBUSDETACHOK (-3)
#define FWBUSDETACH (-2)
#define FWBUSNOTREADY (-1)
#define FWBUSRESET 0
@@ -128,7 +133,7 @@ struct firewire_comm{
*arq, *atq, *ars, *ats, *it[FW_MAX_DMACH],*ir[FW_MAX_DMACH];
struct fw_xferlist tlabels[0x40];
u_char last_tlabel[0x40];
- fw_mtx_t tlabel_lock;
+ kmutex_t tlabel_lock;
STAILQ_HEAD(, fw_bind) binds;
STAILQ_HEAD(, fw_device) devices;
u_int sid_cnt;
@@ -144,33 +149,27 @@ struct firewire_comm{
struct callout busprobe_callout;
struct callout bmr_callout;
struct callout timeout_callout;
- fw_task_t task_timeout;
uint32_t (*cyctimer) (struct firewire_comm *);
void (*ibr) (struct firewire_comm *);
uint32_t (*set_bmr) (struct firewire_comm *, uint32_t);
- int (*ioctl) (fw_dev_t, u_long, void *, int, fw_proc_t);
+ int (*ioctl) (dev_t, u_long, void *, int, struct lwp *);
int (*irx_enable) (struct firewire_comm *, int);
int (*irx_disable) (struct firewire_comm *, int);
int (*itx_enable) (struct firewire_comm *, int);
int (*itx_disable) (struct firewire_comm *, int);
- void (*timeout) (void *);
- void (*poll) (struct firewire_comm *, int, int);
+ void (*timeout) (struct firewire_comm *);
void (*set_intr) (struct firewire_comm *, int);
void (*irx_post) (struct firewire_comm *, uint32_t *);
void (*itx_post) (struct firewire_comm *, uint32_t *);
const struct tcode_info *tcode;
bus_dma_tag_t dmat;
- fw_mtx_t mtx;
- fw_mtx_t wait_lock;
- struct taskqueue *taskqueue;
- fw_proc_t probe_thread;
+ kmutex_t fc_mtx;
+ kmutex_t wait_lock;
+ kcondvar_t fc_cv;
+ struct lwp *probe_thread;
};
#define CSRARC(sc, offset) ((sc)->csr_arc[(offset)/4])
-#define FW_GMTX(fc) (&(fc)->mtx)
-#define FW_GLOCK(fc) fw_mtx_lock(FW_GMTX(fc))
-#define FW_GUNLOCK(fc) fw_mtx_unlock(FW_GMTX(fc))
-#define FW_GLOCK_ASSERT(fc) fw_mtx_assert(FW_GMTX(fc), MA_OWNED)
struct fw_xferq {
int flag;
@@ -203,9 +202,15 @@ struct fw_xferq {
struct selinfo rsel;
void *sc;
void (*hand) (struct fw_xferq *);
+ kmutex_t q_mtx;
};
-struct fw_bulkxfer{
+#define FW_GMTX(fc) (&(fc)->fc_mtx)
+#define FW_GLOCK(fc) fw_mtx_lock(FW_GMTX(fc))
+#define FW_GUNLOCK(fc) fw_mtx_unlock(FW_GMTX(fc))
+#define FW_GLOCK_ASSERT(fc) fw_mtx_assert(FW_GMTX(fc), MA_OWNED)
+
+struct fw_bulkxfer {
int poffset;
struct mbuf *mbuf;
STAILQ_ENTRY(fw_bulkxfer) link;
@@ -214,16 +219,17 @@ struct fw_bulkxfer{
int resp;
};
-struct fw_bind{
+struct fw_bind {
u_int64_t start;
u_int64_t end;
struct fw_xferlist xferlist;
STAILQ_ENTRY(fw_bind) fclist;
STAILQ_ENTRY(fw_bind) chlist;
void *sc;
+ kmutex_t fwb_mtx;
};
-struct fw_xfer{
+struct fw_xfer {
void *sc;
struct firewire_comm *fc;
struct fw_xferq *q;
@@ -251,6 +257,7 @@ struct fw_xfer{
STAILQ_ENTRY(fw_xfer) link;
STAILQ_ENTRY(fw_xfer) tlabel;
struct malloc_type *malloc;
+ kcondvar_t cv;
};
struct fw_rcv_buf {
@@ -261,39 +268,39 @@ struct fw_rcv_buf {
uint8_t spd;
};
-void fw_sidrcv (struct firewire_comm *, uint32_t *, u_int);
-void fw_rcv (struct fw_rcv_buf *);
-void fw_xfer_unload ( struct fw_xfer*);
-void fw_xfer_free_buf ( struct fw_xfer*);
-void fw_xfer_free ( struct fw_xfer*);
-struct fw_xfer *fw_xfer_alloc (struct malloc_type *);
-struct fw_xfer *fw_xfer_alloc_buf (struct malloc_type *, int, int);
-void fw_init (struct firewire_comm *);
int fw_tbuf_update (struct firewire_comm *, int, int);
int fw_rbuf_update (struct firewire_comm *, int, int);
-int fw_bindadd (struct firewire_comm *, struct fw_bind *);
-int fw_bindremove (struct firewire_comm *, struct fw_bind *);
-int fw_xferlist_add (struct fw_xferlist *, struct malloc_type *, int, int, int,
- struct firewire_comm *, void *, void (*)(struct fw_xfer *));
-void fw_xferlist_remove (struct fw_xferlist *);
-int fw_asyreq (struct firewire_comm *, int, struct fw_xfer*);
-void fw_busreset (struct firewire_comm *, uint32_t);
-uint16_t fw_crc16 (uint32_t *, uint32_t);
-void fw_xfer_timeout (void *);
-void fw_xfer_done (struct fw_xfer *);
-void fw_xferwake (struct fw_xfer *);
-int fw_xferwait (struct fw_xfer *);
-void fw_asy_callback_free (struct fw_xfer *);
-struct fw_device *fw_noderesolve_nodeid (struct firewire_comm *, int);
-struct fw_device *fw_noderesolve_eui64 (struct firewire_comm *, struct fw_eui64 *);
-struct fw_bind *fw_bindlookup (struct firewire_comm *, uint16_t, uint32_t);
-void fw_drain_txq (struct firewire_comm *);
int fwdev_makedev (struct firewire_softc *);
int fwdev_destroydev (struct firewire_softc *);
+
+struct fw_device *fw_noderesolve_nodeid(struct firewire_comm *, int);
+struct fw_device *fw_noderesolve_eui64(struct firewire_comm *,
+ struct fw_eui64 *);
+int fw_asyreq(struct firewire_comm *, int, struct fw_xfer*);
+void fw_xferwake(struct fw_xfer *);
+int fw_xferwait(struct fw_xfer *);
+void fw_drain_txq(struct firewire_comm *);
+void fw_busreset(struct firewire_comm *, uint32_t);
+void fw_init(struct firewire_comm *);
+struct fw_bind *fw_bindlookup(struct firewire_comm *, uint16_t, uint32_t);
+int fw_bindadd(struct firewire_comm *, struct fw_bind *);
+int fw_bindremove(struct firewire_comm *, struct fw_bind *);
+int fw_xferlist_add(struct fw_xferlist *, struct malloc_type *, int, int, int,
+ struct firewire_comm *, void *, void (*)(struct fw_xfer *));
+void fw_xferlist_remove(struct fw_xferlist *);
+struct fw_xfer *fw_xfer_alloc(struct malloc_type *);
+struct fw_xfer *fw_xfer_alloc_buf(struct malloc_type *, int, int);
+void fw_xfer_done(struct fw_xfer *);
+void fw_xfer_unload(struct fw_xfer*);
+void fw_xfer_free(struct fw_xfer*);
+void fw_xfer_free_buf(struct fw_xfer*);
+void fw_asy_callback_free(struct fw_xfer *);
+void fw_sidrcv(struct firewire_comm *, uint32_t *, u_int);
+void fw_rcv(struct fw_rcv_buf *);
+uint16_t fw_crc16(uint32_t *, uint32_t);
int fw_open_isodma(struct firewire_comm *, int);
extern int firewire_debug;
-extern struct cfdriver ieee1394if_cd;
extern int firewire_phydma_enable;
#define FWPRI ((PZERO+8)|PCATCH)
@@ -314,3 +321,5 @@ extern int firewire_phydma_enable;
MALLOC_DECLARE(M_FW);
MALLOC_DECLARE(M_FWXFER);
+
+#endif /* _FIREWIREREG_H_ */
diff --git a/sys/dev/ieee1394/fw_port.h b/sys/dev/ieee1394/fw_port.h
deleted file mode 100644
index 1d3c82343a6..00000000000
--- a/sys/dev/ieee1394/fw_port.h
+++ /dev/null
@@ -1,809 +0,0 @@
-/* $NetBSD: fw_port.h,v 1.33 2009/08/07 00:10:53 dyoung Exp $ */
-/*
- * Copyright (c) 2004 KIYOHARA Takashi
- * 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 _FW_PORT_H
-#define _FW_PORT_H
-
-#ifdef _KERNEL
-
-#define OS_STR "NetBSD"
-#define OS_VER __NetBSD_Version__
-#define OS_VER_STR "NetBSD-2"
-#define PROJECT_STR "NetBSD Project"
-
-#define fw_dev_t dev_t
-
-struct fwbus_attach_args {
- const char *name;
-};
-
-struct fw_hwaddr {
- uint32_t sender_unique_ID_hi;
- uint32_t sender_unique_ID_lo;
- uint8_t sender_max_rec;
- uint8_t sspd;
- uint16_t sender_unicast_FIFO_hi;
- uint32_t sender_unicast_FIFO_lo;
-};
-
-
-#define fw_dev2unit(x) minor(x)
-#define fw_unit2minor(x) (((x) & 0xff) | (((x) << 12) & ~0xfffff))
-
-#define fw_timevalcmp(tv1, tv2, op) timercmp((tv1), (tv2), op)
-#define fw_timevalsub(tv1, tv2) timersub((tv1), (tv2), (tv1))
-
-#define fw_get_nameunit(dev) device_xname(dev)
-#define fw_get_unit(dev) device_unit((dev))
-
-#define fw_printf(dev, ...) aprint_normal_dev((dev), __VA_ARGS__)
-
-/* atomic macros */
-/* XXXX: unsafe... */
-#define fw_atomic_set_int(P, V) (*(u_int *)(P) |= (V))
-static __inline int
-fw_atomic_readandclear_int(int *p)
-{
- int _p = *p;
-
- *p = 0;
- return _p;
-}
-
-/* mutex macros */
-/* XXXX: unsafe... */
-typedef void *fw_mtx_t;
-#define fw_mtx_init(mutex, name, type, opts)
-#define fw_mtx_lock(mutex) (void)(mutex) /* XXXX */
-#define fw_mtx_unlock(mutex) (void)(mutex) /* XXXX */
-#define fw_mtx_destroy(mutex)
-#define fw_mtx_assert(mutex, what)
-
-#define fw_msleep(ident, mtx, priority, wmesg, timo) \
- tsleep((ident), (priority), (wmesg), (timo))
-
-/* taskqueue macros */
-/* XXXX: unsafe... */
-typedef void (*task_fn_t)(void *context, int pending);
-typedef struct {
- STAILQ_ENTRY(task) ta_link; /* link for queue */
- u_short ta_pending; /* count times queued */
- u_short ta_priority; /* priority of task in queue */
- task_fn_t ta_func; /* task handler */
- void *ta_context; /* argument for handler */
-} fw_task_t;
-#define fw_taskqueue_enqueue(queue, task) \
- (task)->ta_func((task)->ta_context, 0)
-#define FW_TASK_INIT(task, priority, func, context) \
- do { \
- (task)->ta_priority = (priority); \
- (task)->ta_func = (func); \
- (task)->ta_context = (context); \
- } while (/*CONSTCOND*/0)
-#define fw_taskqueue_create_fast(name, mflags, enqueue, taskqueue) \
- NULL
-#define fw_taskqueue_start_threads(taskqueue, n, x, fmt, ...)
-
-/* kthread macros */
-typedef struct proc fw_thread_t;
-typedef struct lwp *fw_proc_t;
-#define fw_kthread_create(func, arg, newpp, fmt, ...) \
- kthread_create(PRI_NONE, 0, NULL, \
- (func), (arg), (newpp), (fmt), __VA_ARGS__)
-#define fw_kthread_exit(ecode) kthread_exit((ecode))
-
-/* callout macros */
-#define fw_callout_init(c) callout_init((c), 0)
-#define fw_callout_reset(c, ticks, func, arg) \
- callout_reset((c), (ticks), (func), (arg))
-#define fw_callout_stop(c) callout_stop((c))
-
-/* bus_dma macros */
-#include <sys/malloc.h>
-#include <sys/bus.h>
-struct fw_bus_dma_tag {
- bus_dma_tag_t tag;
- bus_size_t alignment;
- bus_size_t boundary;
- bus_size_t size;
- int nsegments;
- bus_size_t maxsegsz;
- int flags;
-};
-typedef struct fw_bus_dma_tag *fw_bus_dma_tag_t;
-typedef int bus_dmasync_op_t;
-typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
-typedef void
- bus_dmamap_callback2_t(void *, bus_dma_segment_t *, int, bus_size_t, int);
-
-#define fw_bus_dma_tag_create( \
- p, a, b, la, ha, ffunc, farg, maxsz, \
- nseg, maxsegsz, f, lfunc, larg, dmat) \
- \
- _fw_bus_dma_tag_create((p), (a), (b), (la), (ha), \
- (ffunc), (farg), (maxsz), (nseg), (maxsegsz), (f), (dmat))
-
-static __inline int
-_fw_bus_dma_tag_create(bus_dma_tag_t parent,
- bus_size_t alignment, bus_size_t boundary,
- bus_addr_t lowaddr, bus_addr_t highaddr,
- void *filtfunc, void *filtfuncarg,
- bus_size_t maxsize, int nsegments, bus_size_t maxsegsz,
- int flags, fw_bus_dma_tag_t *fwdmat)
-{
- fw_bus_dma_tag_t tag;
-
- tag = malloc(sizeof(struct fw_bus_dma_tag), M_DEVBUF, M_NOWAIT);
- if (tag == NULL)
- return ENOMEM;
-
-/* XXXX */
-#define BUS_SPACE_MAXADDR_32BIT 0
-#define BUS_SPACE_MAXADDR 0
-
- tag->tag = parent;
- tag->alignment = alignment;
- tag->boundary = boundary;
- tag->size = maxsize;
- tag->nsegments = nsegments;
- tag->maxsegsz = maxsegsz;
- tag->flags = flags;
-
- *fwdmat = tag;
-
- return 0;
-}
-#define fw_bus_dma_tag_destroy(ft) \
- free(ft, M_DEVBUF)
-#define fw_bus_dmamap_create(ft, f, mp) \
- bus_dmamap_create((ft)->tag, (ft)->size,\
- (ft)->nsegments, (ft)->maxsegsz, (ft)->boundary, (f), (mp))
-#define fw_bus_dmamap_destroy(ft, m) \
- bus_dmamap_destroy((ft)->tag, (m))
-static __inline int
-fw_bus_dmamap_load(fw_bus_dma_tag_t ft, bus_dmamap_t m,
- void *b, bus_size_t l, bus_dmamap_callback_t *func, void *a, int f)
-{
- int lf = f & (BUS_DMA_WAITOK | BUS_DMA_NOWAIT | BUS_DMA_STREAMING |
- BUS_DMA_READ | BUS_DMA_WRITE |
- BUS_DMA_BUS1 | BUS_DMA_BUS2 | BUS_DMA_BUS3 | BUS_DMA_BUS4);
- int err = bus_dmamap_load(ft->tag, m, b, l, NULL, lf);
- (func)(a, m->dm_segs, m->dm_nsegs, err);
- return err;
-}
-static __inline int
-fw_bus_dmamap_load_mbuf(fw_bus_dma_tag_t ft, bus_dmamap_t m,
- struct mbuf *b, bus_dmamap_callback2_t *func, void *a, int f)
-{
- int lf = f & (BUS_DMA_WAITOK | BUS_DMA_NOWAIT | BUS_DMA_STREAMING |
- BUS_DMA_READ | BUS_DMA_WRITE |
- BUS_DMA_BUS1 | BUS_DMA_BUS2 | BUS_DMA_BUS3 | BUS_DMA_BUS4);
- int err = bus_dmamap_load_mbuf(ft->tag, m, b, lf);
- (func)(a, m->dm_segs, m->dm_nsegs, m->dm_mapsize, err);
- return err;
-}
-#define fw_bus_dmamap_unload(ft, m) \
- bus_dmamap_unload((ft)->tag, (m))
-#define fw_bus_dmamap_sync(ft, m, op) \
- bus_dmamap_sync((ft)->tag, (m), 0, (m)->dm_mapsize, (op))
-static __inline int
-fw_bus_dmamem_alloc(fw_bus_dma_tag_t ft, void **vp, int f, bus_dmamap_t *mp)
-{
- bus_dma_segment_t segs;
- int nsegs, err;
- int af, mf, cf;
-
- af = f & (BUS_DMA_WAITOK | BUS_DMA_NOWAIT | BUS_DMA_STREAMING |
- BUS_DMA_BUS1 | BUS_DMA_BUS2 | BUS_DMA_BUS3 | BUS_DMA_BUS4);
- err = bus_dmamem_alloc(ft->tag, ft->size,
- ft->alignment, ft->boundary, &segs, ft->nsegments, &nsegs, af);
- if (err) {
- printf("fw_bus_dmamem_alloc: failed(1)\n");
- return err;
- }
-
- mf = f & (BUS_DMA_WAITOK | BUS_DMA_NOWAIT |
- BUS_DMA_BUS1 | BUS_DMA_BUS2 | BUS_DMA_BUS3 | BUS_DMA_BUS4 |
- BUS_DMA_COHERENT | BUS_DMA_NOCACHE);
- err = bus_dmamem_map(ft->tag,
- &segs, nsegs, ft->size, (void **)vp, mf);
- if (err) {
- printf("fw_bus_dmamem_alloc: failed(2)\n");
- bus_dmamem_free(ft->tag, &segs, nsegs);
- return err;
- }
-
- if (*mp != NULL)
- return err;
-
- cf = f & (BUS_DMA_WAITOK | BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW |
- BUS_DMA_BUS1 | BUS_DMA_BUS2 | BUS_DMA_BUS3 | BUS_DMA_BUS4);
- err = bus_dmamap_create(ft->tag,
- ft->size, nsegs, ft->maxsegsz, ft->boundary, cf, mp);
- if (err) {
- printf("fw_bus_dmamem_alloc: failed(3)\n");
- bus_dmamem_unmap(ft->tag, (void *)*vp, ft->size);
- bus_dmamem_free(ft->tag, &segs, nsegs);\
- }
-
- return err;
-}
-#define fw_bus_dmamem_free(ft, v, m) \
- do { \
- bus_dmamem_unmap((ft)->tag, (v), (ft)->size); \
- bus_dmamem_free((ft)->tag, (m)->dm_segs, (m)->dm_nsegs);\
- bus_dmamap_destroy((ft)->tag, (m)); \
- } while (/*CONSTCOND*/0)
-
-#define fw_config_pending_incr() config_pending_incr()
-#define fw_config_pending_decr() config_pending_decr()
-
-#define splfw() splvm()
-#define splfwnet() splnet()
-#define splfwsbp() splbio()
-#define splsoftvm() splbio()
-
-#include <sys/select.h>
-
-#define FW_KASSERT(expression, str) \
- KASSERT(expression)
-
-/*
- * fw attach macro for NetBSD
- */
-#define FW_ATTACH(dname) \
- void \
- __CONCAT(dname,attach) \
- (device_t parent, device_t self, void *aux)
-#define FW_ATTACH_START(dname, sc, fwa) \
- struct __CONCAT(dname,_softc) *sc = device_private(self); \
- __unused struct fw_attach_args *fwa = (struct fw_attach_args *)aux
-#define FW_ATTACH_RETURN(r) return
-
-/*
- * fw detach macro for NetBSD
- */
-#define FW_DETACH(dname) \
- int \
- __CONCAT(dname,detach)(device_t self, int flags)
-#define FW_DETACH_START(dname, sc) \
- struct __CONCAT(dname,_softc) *sc = device_private(self)
-
-/*
- * fw open macro for NetBSD
- */
-#define FW_OPEN(dname) \
- int \
- __CONCAT(dname,_open)(dev_t _dev, int flags, int fmt, fw_proc_t td)
-#define FW_OPEN_START \
- struct firewire_softc *sc, *dev; \
- \
- sc = dev = device_lookup_private(&ieee1394if_cd, DEV2UNIT(_dev));\
- if (dev == NULL) \
- return ENXIO
-
-/*
- * fw close macro for NetBSD
- */
-#define FW_CLOSE(dname) \
- int \
- __CONCAT(dname,_close)(dev_t _dev, int flags, int fmt, fw_proc_t td)
-#define FW_CLOSE_START \
- int unit = DEV2UNIT(_dev); \
- struct firewire_softc *dev; \
- \
- dev = device_lookup_private(&ieee1394if_cd, unit); \
- if (dev == NULL) \
- return ENXIO
-
-/*
- * fw read macro for NetBSD
- */
-#define FW_READ(dname) \
- int \
- __CONCAT(dname,_read)(dev_t _dev, struct uio *uio, int ioflag)
-#define FW_READ_START \
- int unit = DEV2UNIT(_dev); \
- struct firewire_softc *dev; \
- \
- dev = device_lookup_private(&ieee1394if_cd, unit); \
- if (dev == NULL) \
- return ENXIO
-
-/*
- * fw write macro for NetBSD
- */
-#define FW_WRITE(dname) \
- int \
- __CONCAT(dname,_write)(dev_t _dev, struct uio *uio, int ioflag)
-#define FW_WRITE_START \
- int unit = DEV2UNIT(_dev); \
- struct firewire_softc *dev; \
- \
- dev = device_lookup_private(&ieee1394if_cd, unit); \
- if (dev == NULL) \
- return ENXIO
-
-/*
- * fw ioctl macro for NetBSD
- */
-#define FW_IOCTL(dname) \
- int \
- __CONCAT(dname,_ioctl) \
- (dev_t _dev, u_long cmd, void *data, int flag, fw_proc_t td)
-#define FW_IOCTL_START \
- int unit = DEV2UNIT(_dev); \
- struct firewire_softc *sc, *dev; \
- \
- sc = dev = device_lookup_private(&ieee1394if_cd, unit); \
- if (dev == NULL) \
- return ENXIO
-
-/*
- * fw poll macro for NetBSD
- */
-#define FW_POLL(dname) \
- int \
- __CONCAT(dname,_poll)(dev_t _dev, int events, fw_proc_t td)
-#define FW_POLL_START \
- int unit = DEV2UNIT(_dev); \
- struct firewire_softc *dev; \
- \
- dev = device_lookup_private(&ieee1394if_cd, unit); \
- if (dev == NULL) \
- return ENXIO
-
-/*
- * fw mmap macro for NetBSD
- */
-#define FW_MMAP(dname) \
- paddr_t \
- __CONCAT(dname,_mmap)(dev_t _dev, off_t offset, int nproto)
-#define FW_MMAP_START \
- int unit = DEV2UNIT(_dev); \
- struct firewire_softc *dev; \
- \
- dev = device_lookup_private(&ieee1394if_cd, unit); \
- if (dev == NULL) \
- return ENXIO
-
-/*
- * fw strategy macro for NetBSD
- */
-#define FW_STRATEGY_START \
- dev_t _dev = bp->bio_dev; \
- int unit = DEV2UNIT(_dev); \
- struct firewire_softc *sc, *dev; \
- \
- sc = dev = device_lookup_private(&ieee1394if_cd, unit); \
- if (dev == NULL) \
- return
-
-/*
- * if macro for NetBSD
- */
-#define IF_DETACH_START(dname, sc) \
- struct __CONCAT(dname,_softc) *sc = device_private(self)
-#define IF_IOCTL_START(dname, sc) \
- struct __CONCAT(dname,_softc) *sc = \
- ((struct fwip_eth_softc *)ifp->if_softc)->fwip
-#define IF_INIT(dname) \
- int \
- __CONCAT(dname,_init)(struct ifnet *ifp)
-#define IF_INIT_START(dname, sc, ifp) \
- struct __CONCAT(dname,_softc) *sc = \
- ((struct fwip_eth_softc *)(ifp)->if_softc)->fwip
-#define IF_INIT_RETURN(r) return (r)
-#define IF_STOP(dname) \
- void \
- __CONCAT(dname,_stop)(struct ifnet *ifp, int disable)
-#define IF_STOP_START(dname, ifp, sc) \
- struct __CONCAT(dname,_softc) *sc = \
- ((struct fwip_eth_softc *)(ifp)->if_softc)->fwip
-
-/*
- * fwohci macro for NetBSD
- */
-#define FWOHCI_DETACH() \
- int \
- fwohci_detach(struct fwohci_softc *sc, int flags)
-#define FWOHCI_DETACH_START \
- if (sc->fc.bdev != NULL) \
- config_detach(sc->fc.bdev, flags)
-#define FWOHCI_DETACH_END
-#define FWOHCI_INIT_END \
- do { \
- struct fwbus_attach_args faa; \
- faa.name = "ieee1394if"; \
- sc->fc.bdev = config_found(sc->fc.dev, &faa, fwohci_print); \
- } while (/*CONSTCOND*/0)
-
-/*
- * firewire macro for NetBSD
- */
-#define FIREWIRE_ATTACH_START \
- struct firewire_comm *fc = device_private(parent); \
- \
- aprint_normal(": IEEE1394 bus\n"); \
- \
- fc->bdev = sc->dev = self; \
- SLIST_INIT(&sc->devlist)
-#define FWDEV_DESTROYDEV(sc)
-#define FIREWIRE_GENERIC_ATTACH \
- do { \
- struct fw_attach_args faa; \
- struct firewire_dev_list *devlist, *elm; \
- \
- devlist = malloc( \
- sizeof(struct firewire_dev_list), M_DEVBUF, M_NOWAIT); \
- if (devlist == NULL) \
- break; \
- \
- faa.name = "fwip"; \
- faa.fc = fc; \
- faa.fwdev = NULL; \
- devlist->dev = config_found(sc->dev, &faa, firewire_print); \
- if (devlist->dev == NULL) { \
- free(devlist, M_DEVBUF); \
- break; \
- } \
- \
- if (SLIST_EMPTY(&sc->devlist)) \
- SLIST_INSERT_HEAD(&sc->devlist, devlist, link); \
- else { \
- for (elm = SLIST_FIRST(&sc->devlist); \
- SLIST_NEXT(elm, link) != NULL; \
- elm = SLIST_NEXT(elm, link)); \
- SLIST_INSERT_AFTER(elm, devlist, link); \
- } \
- } while (/*CONSTCOND*/0)
-#define FIREWIRE_GENERIC_DETACH \
- do { \
- struct firewire_dev_list *devlist; \
- int err; \
- \
- while ((devlist = SLIST_FIRST(&sc->devlist)) != NULL) { \
- if ((err = config_detach(devlist->dev, flags)) != 0) \
- return err; \
- SLIST_REMOVE( \
- &sc->devlist, devlist, firewire_dev_list, link); \
- free(devlist, M_DEVBUF); \
- } \
- } while (/*CONSTCOND*/0)
-#define FIREWIRE_SBP_ATTACH \
- do { \
- struct firewire_softc *sc = device_private(fc->bdev); \
- struct firewire_dev_list *devlist, *elm; \
- int locs[IEEE1394IFCF_NLOCS]; \
- \
- devlist = malloc( \
- sizeof(struct firewire_dev_list), M_DEVBUF, M_NOWAIT); \
- if (devlist == NULL) { \
- printf("memory allocation failed\n"); \
- break; \
- } \
- \
- locs[IEEE1394IFCF_EUIHI] = fwdev->eui.hi; \
- locs[IEEE1394IFCF_EUILO] = fwdev->eui.lo; \
- \
- fwa.fwdev = fwdev; \
- fwdev->sbp = config_found_sm_loc(sc->dev, "ieee1394if", \
- locs, &fwa, firewire_print, config_stdsubmatch); \
- if (fwdev->sbp == NULL) { \
- free(devlist, M_DEVBUF); \
- break; \
- } \
- \
- devlist->fwdev = fwdev; \
- devlist->dev = fwdev->sbp; \
- \
- if (SLIST_EMPTY(&sc->devlist)) \
- SLIST_INSERT_HEAD(&sc->devlist, devlist, link); \
- else { \
- for (elm = SLIST_FIRST(&sc->devlist); \
- SLIST_NEXT(elm, link) != NULL; \
- elm = SLIST_NEXT(elm, link)); \
- SLIST_INSERT_AFTER(elm, devlist, link); \
- } \
- } while (/*CONSTCOND*/0)
-#define FIREWIRE_SBP_DETACH \
- do { \
- struct firewire_softc *sc = device_private(fc->bdev); \
- struct firewire_dev_list *devlist; \
- \
- SLIST_FOREACH(devlist, &sc->devlist, link) { \
- if (devlist->fwdev != fwdev) \
- continue; \
- SLIST_REMOVE( \
- &sc->devlist, devlist, firewire_dev_list, link); \
- free(devlist, M_DEVBUF); \
- \
- if (config_detach(fwdev->sbp, DETACH_FORCE) != 0) \
- return; \
- } \
- } while (/*CONSTCOND*/0)
-#define FIREWIRE_CHILDREN_FOREACH_FUNC(func, fdc) \
- do { \
- struct firewire_dev_list *devlist; \
- struct firewire_softc *sc = device_private(fc->bdev); \
- \
- if (!SLIST_EMPTY(&sc->devlist)) { \
- SLIST_FOREACH(devlist, &sc->devlist, link) { \
- (fdc) = device_private(devlist->dev); \
- if ((fdc)->func != NULL) \
- (fdc)->func((fdc)); \
- } \
- } \
- } while (/*CONSTCOND*/0)
-
-/*
- * sbp macro for NetBSD
- */
-#define SBP_ATTACH_START \
- do { \
- aprint_normal(": SBP-2/SCSI over IEEE1394\n"); \
- \
- sbp->fd.dev = self; \
- } while (/*CONSTCOND*/0)
-#define SBP_SCSIBUS_ATTACH \
- do { \
- struct scsipi_adapter *sc_adapter = &sbp->sc_adapter; \
- struct scsipi_channel *sc_channel = &sbp->sc_channel; \
- struct sbp_target *target = &sbp->target; \
- \
- sc_adapter->adapt_dev = sbp->fd.dev; \
- sc_adapter->adapt_nchannels = 1; \
- sc_adapter->adapt_max_periph = 1; \
- sc_adapter->adapt_request = sbp_scsipi_request; \
- sc_adapter->adapt_minphys = sbp_minphys; \
- sc_adapter->adapt_openings = 8; \
- /*Start with some. Grow as needed.*/\
- \
- sc_channel->chan_adapter = sc_adapter; \
- sc_channel->chan_bustype = &scsi_bustype; \
- sc_channel->chan_defquirks = PQUIRK_ONLYBIG; \
- sc_channel->chan_channel = 0; \
- sc_channel->chan_flags = \
- SCSIPI_CHAN_CANGROW | SCSIPI_CHAN_NOSETTLE; \
- \
- /* We set nluns 0 now */ \
- sc_channel->chan_ntargets = 1; \
- sc_channel->chan_nluns = target->num_lun; \
- sc_channel->chan_id = 1; \
- \
- if ((sbp->sc_bus = \
- config_found(sbp->fd.dev, sc_channel, scsiprint)) == \
- NULL) { \
- fw_printf(sbp->fd.dev, "attach failed\n"); \
- return; \
- } \
- } while (/*CONSTCOND*/0)
-#define SBP_DEVICE(d) ((d)->periph)
-#define SBP_DEVICE_FREEZE(d, x) scsipi_periph_freeze((d)->periph, (x));
-#define SBP_DEVICE_THAW(d, x) \
- do { \
- if ((d)->periph) \
- scsipi_periph_thaw((d)->periph, (x)); \
- /* XXXX */ \
- scsipi_channel_thaw(&(d)->target->sbp->sc_channel, 0); \
- } while (/*CONSTCOND*/0)
-#define SBP_BUS_FREEZE(b) scsipi_channel_freeze(&(b)->sc_channel, 1)
-#define SBP_BUS_THAW(b) scsipi_channel_thaw(&(b)->sc_channel, 1)
-#define SBP_DEVICE_PREATTACH() \
- do { \
- if (!sbp->lwp) { \
- /* create thread */ \
- if (kthread_create(PRI_NONE, 0, NULL, \
- sbp_scsipi_scan_target, &sbp->target, \
- &sbp->lwp, "sbp%d_attach", \
- device_unit(sbp->fd.dev))) { \
- fw_printf(sbp->fd.dev, \
- "unable to create thread"); \
- panic("fw_kthread_create"); \
- } \
- } \
- } while (/*CONSTCOND*/0)
-
-/*
- * fwip macro for NetBSD
- */
-#define FWIP_ATTACH_START \
- device_t dev = self; \
- struct fw_hwaddr *hwaddr;
-#define FWIP_ATTACH_SETUP \
- do { \
- aprint_normal(": IP over IEEE1394\n"); \
- fwip->fd.dev = self; \
- fwip->fw_softc.fwip_ifp = &fwip->fw_softc.fwcom.fc_if; \
- hwaddr = (struct fw_hwaddr *)&fwip->fw_softc.fwcom.ic_hwaddr; \
- } while (/*CONSTCOND*/0)
-
-#define FWDEV_MAKEDEV(sc)
-#define FIREWIRE_IFATTACH(ifp, ha) \
- do { \
- if_attach((ifp)); \
- ieee1394_ifattach((ifp), (const struct ieee1394_hwaddr *)(ha));\
- } while (/*CONSTCOND*/0)
-#define FIREWIRE_IFDETACH(ifp) \
- do { \
- ieee1394_ifdetach(ifp); \
- if_detach(ifp); \
- } while (/*CONSTCOND*/0)
-#define FIREWIRE_BUSRESET(ifp) ieee1394_drain((ifp))
-#define FIREWIRE_INPUT(ifp, m, src) \
- ieee1394_input((ifp), (m), (src))
-#define FWIP_INIT(sc) fwip_init((sc)->fw_softc.fwip_ifp)
-#define FWIP_STOP(sc) fwip_stop((sc)->fw_softc.fwip_ifp, 1)
-#define FIREWIRE_IOCTL(ifp, cmd, data) \
- ieee1394_ioctl((ifp), (cmd), (data))
-#define IF_INITNAME(ifp, dev, unit) \
- strlcpy((ifp)->if_xname, device_xname(dev), IFNAMSIZ);
-#define SET_IFFUNC(ifp, start, ioctl, init, stop) \
- do { \
- (ifp)->if_start = (start); \
- (ifp)->if_ioctl = (ioctl); \
- (ifp)->if_init = (init); \
- (ifp)->if_stop = (stop); \
- } while (/*CONSTCOND*/0)
-
-/*
- * fwdev macro for NetBSD
- */
-#define FWDEV_OPEN_START \
- if (DEV_FWMEM(_dev)) \
- return fwmem_open(_dev, flags, fmt, td)
-#define FWDEV_CLOSE_START \
- if (DEV_FWMEM(_dev)) \
- return fwmem_close(_dev, flags, fmt, td)
-#define FWDEV_READ_START \
- if (DEV_FWMEM(_dev)) \
- return physio(fw_strategy, NULL, _dev, ioflag, minphys, uio)
-#define FWDEV_WRITE_START \
- if (DEV_FWMEM(_dev)) \
- return physio(fw_strategy, NULL, _dev, ioflag, minphys, uio)
-#define FWDEV_IOCTL_START \
- if (DEV_FWMEM(_dev)) \
- return fwmem_ioctl(_dev, cmd, data, flag, td)
-#define FWDEV_IOCTL_REDIRECT fc->ioctl(_dev, cmd, data, flag, td)
-#define FWDEV_POLL_START \
- if (DEV_FWMEM(_dev)) \
- return fwmem_poll(_dev, events, td)
-#define FWDEV_MMAP_START \
- if (DEV_FWMEM(_dev)) \
- return fwmem_mmap(_dev, offset, nproto)
-#define FWDEV_STRATEGY_START \
- if (DEV_FWMEM(_dev)) { \
- fwmem_strategy(bp); \
- return; \
- }
-
-#define XS_REQ_INVALID XS_DRIVER_STUFFUP
-#define XS_SCSI_BUS_RESET XS_RESET
-#define XS_BDR_SENT XS_RESET
-#define XS_DEV_NOT_THERE XS_DRIVER_STUFFUP
-#define XS_CMD_TIMEOUT XS_TIMEOUT
-#define XS_REQUEUE_REQ XS_REQUEUE
-#define XS_REQ_CMP XS_NOERROR
-#define XS_REQ_CMP_ERR XS_DRIVER_STUFFUP
-#define XS_UA_ABORT XS_DRIVER_STUFFUP
-
-typedef struct scsipi_xfer sbp_scsi_xfer;
-typedef struct scsipi_inquiry_data sbp_scsi_inquiry_data;
-
-#define SCSI_XFER_TARGET(x) ((x)->xs_periph->periph_target)
-#define SCSI_XFER_LUN(x) ((x)->xs_periph->periph_lun)
-#define SCSI_XFER_ERROR(x) ((x)->error)
-#define SCSI_XFER_DIR(x) \
- ((x)->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT))
-#define SCSI_XFER_DATA_IN XS_CTL_DATA_IN
-#define SCSI_XFER_CALLOUT(x) ((x)->xs_callout)
-#define SCSI_XFER_TIMEOUT(x) ((x)->timeout)
-#define SCSI_XFER_OPECODE(x) ((x)->cmd->opcode)
-#define SCSI_XFER_STATUS(x) ((x)->xs_status)
-#define SCSI_XFER_EVPD(x) ((x)->cmd->bytes[0] & SI_EVPD)
-#define SI_EVPD 0x01
-#define SCSI_XFER_CMDLEN(x) ((x)->cmdlen)
-#define SCSI_XFER_CMD(x) ((x)->cmd)
-#define SCSI_XFER_DATALEN(x) ((x)->datalen)
-#define SCSI_XFER_DATA(x) ((x)->data)
-#define SCSI_XFER_SENSELEN(x) (0 /* XXXXX */)
-#define SCSI_SENSE_DATA(x) (&(x)->sense.scsi_sense)
-#define SCSI_INQUIRY_DATA(x) ((x)->data)
-#define SCSI_XFER_FUNCCODE(x) XPT_SCSI_IO
-#define SCSI_XFER_10BCMD_DUMP(x)\
- ((x)->cmd->opcode), \
- ((x)->cmd->bytes[0]), \
- ((x)->cmd->bytes[1]), \
- ((x)->cmd->bytes[2]), \
- ((x)->cmd->bytes[3]), \
- ((x)->cmd->bytes[4]), \
- ((x)->cmd->bytes[5]), \
- ((x)->cmd->bytes[6]), \
- ((x)->cmd->bytes[7]), \
- ((x)->cmd->bytes[8])
-#define SCSI_XFER_REQUEST_COMPLETE(x) \
- ((x)->resid = 0)
-#define SCSI_TRANSFER_DONE(x) scsipi_done((x))
-
-#define NOT_LUN_WILDCARD(l) (1)
-#define CAM_XFER_FLAGS(x) (0) /* XXX */
-#define CAM_SCATTER_VALID (0) /* XXX */
-#define CAM_DATA_PHYS (0) /* XXX */
-#define XPT_SCSI_IO (1) /* XXX */
-
-#ifndef rounddown
-#define rounddown(x, y) ((x) / (y) * (y))
-#endif
-
-/*
- * additional mbuf macros for NetBSD
- */
-#include <sys/mbuf.h>
-#define M_TRYWAIT M_WAITOK
-
-#define MTAG_FIREWIRE 1394
-#define MTAG_FIREWIRE_HWADDR 0
-#define MTAG_FIREWIRE_SENDER_EUID 1
-
-#define m_tag_alloc(cookie, type, len, wait) \
- m_tag_get((type), (len), (wait))
-#define m_tag_locate(m, cookie, type, t) \
- m_tag_find((m), (type), (t))
-
-/* additional bpf macros */
-#define bpf_peers_present(if_bpf) (if_bpf)
-
-
-#define CTR0(m, format)
-#define CTR1(m, format, p1)
-
-#define OHCI_CSR_WRITE(sc, reg, val) \
- bus_space_write_4((sc)->bst, (sc)->bsh, reg, val)
-
-#define FILTER_STRAY 0
-#define FILTER_HANDLED 1
-
-#define SSD_CURRENT_ERROR 0x70
-#define SSD_DEFERRED_ERROR 0x71
-
-#define T_RBC T_SIMPLE_DIRECT
-
-#define SCSI_STATUS_CHECK_COND SCSI_CHECK
-#define SCSI_STATUS_BUSY SCSI_BUSY
-#define SCSI_STATUS_CMD_TERMINATED SCSI_TERMINATED
-
-#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
-
-#define DFLTPHYS (64 * 1024) /* fake */
-
-#define kdb_backtrace()
-#define kdb_active 0
-
-#endif
-#define vm_offset_t void *
-#endif
diff --git a/sys/dev/ieee1394/fwcrom.c b/sys/dev/ieee1394/fwcrom.c
index 9f7fa18abcb..1a4e90f3bf6 100644
--- a/sys/dev/ieee1394/fwcrom.c
+++ b/sys/dev/ieee1394/fwcrom.c
@@ -1,8 +1,8 @@
-/* $NetBSD: fwcrom.c,v 1.10 2009/04/18 14:58:02 tsutsui Exp $ */
+/* $NetBSD: fwcrom.c,v 1.11 2010/03/29 03:05:27 kiyohara Exp $ */
/*-
* Copyright (c) 2002-2003
* Hidetoshi Shimokawa. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +19,7 @@
* 4. Neither the name of the author 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 REGENTS 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
@@ -34,44 +34,8 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fwcrom.c,v 1.10 2009/04/18 14:58:02 tsutsui Exp $");
-#ifdef __FreeBSD__
-__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/fwcrom.c,v 1.14 2006/02/04 21:37:39 imp Exp $");
-#endif
+__KERNEL_RCSID(0, "$NetBSD: fwcrom.c,v 1.11 2010/03/29 03:05:27 kiyohara Exp $");
-#if defined(__FreeBSD__)
-#include <sys/param.h>
-
-#ifdef _BOOT
-#include <stand.h>
-#include <bootstrap.h>
-#else
-#if defined(_KERNEL) || defined(TEST)
-#include <sys/queue.h>
-#endif
-#ifdef _KERNEL
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#else
-#include <netinet/in.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <err.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-#endif
-
-#ifdef __DragonFly__
-#include "fw_port.h"
-#include "firewire.h"
-#include "iec13213.h"
-#else
-#include <dev/firewire/fw_port.h>
-#include <dev/firewire/firewire.h>
-#include <dev/firewire/iec13213.h>
-#endif
-#elif defined(__NetBSD__)
#include <sys/param.h>
#ifdef _KERNEL
#include <sys/device.h>
@@ -81,10 +45,8 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/fwcrom.c,v 1.14 2006/02
#include <stdio.h>
#include <string.h>
#endif
-#include <dev/ieee1394/fw_port.h>
#include <dev/ieee1394/firewire.h>
#include <dev/ieee1394/iec13213.h>
-#endif
#define MAX_ROM (1024 - sizeof(uint32_t) * 5)
#define CROM_END(cc) ((char *)(cc)->stack[0].dir + MAX_ROM - 1)
@@ -118,7 +80,7 @@ crom_get(struct crom_context *cc)
struct crom_ptr *ptr;
ptr = &cc->stack[cc->depth];
- return (&ptr->dir->entry[ptr->index]);
+ return &ptr->dir->entry[ptr->index];
}
void
@@ -135,19 +97,19 @@ crom_next(struct crom_context *cc)
printf("crom_next: too deep\n");
goto again;
}
- cc->depth ++;
+ cc->depth++;
ptr = &cc->stack[cc->depth];
- ptr->dir = (struct csrdirectory *) (reg + reg->val);
+ ptr->dir = (struct csrdirectory *)(reg + reg->val);
ptr->index = 0;
goto check;
}
again:
ptr = &cc->stack[cc->depth];
- ptr->index ++;
+ ptr->index++;
check:
if (ptr->index < ptr->dir->crc_len &&
- (char *)crom_get(cc) <= CROM_END(cc))
+ (char *)crom_get(cc) <= CROM_END(cc))
return;
if (ptr->index < ptr->dir->crc_len)
@@ -167,7 +129,7 @@ crom_search_key(struct crom_context *cc, uint8_t key)
{
struct csrreg *reg;
- while(cc->depth >= 0) {
+ while (cc->depth >= 0) {
reg = crom_get(cc);
if (reg->key == key)
return reg;
@@ -185,7 +147,7 @@ crom_has_specver(uint32_t *p, uint32_t spec, uint32_t ver)
cc = &c;
crom_init_context(cc, p);
- while(cc->depth >= 0) {
+ while (cc->depth >= 0) {
reg = crom_get(cc);
if (state == 0) {
if (reg->key == CSRKEY_SPEC && reg->val == spec)
@@ -217,7 +179,7 @@ crom_parse_text(struct crom_context *cc, char *buf, int len)
reg = crom_get(cc);
if (reg->key != CROM_TEXTLEAF ||
- (char *)(reg + reg->val) > CROM_END(cc)) {
+ (char *)(reg + reg->val) > CROM_END(cc)) {
strncpy(buf, nullstr, len);
return;
}
@@ -230,11 +192,11 @@ crom_parse_text(struct crom_context *cc, char *buf, int len)
/* XXX should check spec and type */
- bp = (uint32_t *)&buf[0];
+ bp = (uint32_t *)buf;
qlen = textleaf->crc_len - 2;
if (len < qlen * 4)
qlen = len/4;
- for (i = 0; i < qlen; i ++)
+ for (i = 0; i < qlen; i++)
*bp++ = ntohl(textleaf->text[i]);
/* make sure to terminate the string */
if (len <= qlen * 4)
@@ -257,7 +219,7 @@ crom_crc(uint32_t *ptr, int len)
}
crc &= 0xffff;
}
- return((uint16_t) crc);
+ return (uint16_t)crc;
}
#if !defined(_KERNEL) && !defined(_BOOT)
@@ -333,18 +295,17 @@ crom_desc(struct crom_context *cc, char *buf, int len)
#endif
break;
case CSRTYPE_C:
- len -= snprintf(buf, len, "offset=0x%04x(%d)",
- reg->val, reg->val);
+ len -=
+ snprintf(buf, len, "offset=0x%04x(%d)", reg->val, reg->val);
buf += strlen(buf);
break;
case CSRTYPE_L:
/* XXX fall through */
case CSRTYPE_D:
dir = (struct csrdirectory *) (reg + reg->val);
- crc = crom_crc((uint32_t *)&dir->entry[0], dir->crc_len);
+ crc = crom_crc((uint32_t *)dir->entry, dir->crc_len);
len -= snprintf(buf, len, "len=%d crc=0x%04x(%s) ",
- dir->crc_len, dir->crc,
- (crc == dir->crc) ? "OK" : "NG");
+ dir->crc_len, dir->crc, (crc == dir->crc) ? "OK" : "NG");
buf += strlen(buf);
}
switch (reg->key) {
@@ -418,11 +379,11 @@ crom_add_quad(struct crom_chunk *chunk, uint32_t entry)
index = chunk->data.crc_len;
if (index >= CROM_MAX_CHUNK_LEN - 1) {
printf("too large chunk %d\n", index);
- return(-1);
+ return -1;
}
chunk->data.buf[index] = entry;
chunk->data.crc_len++;
- return(index);
+ return index;
}
int
@@ -432,42 +393,37 @@ crom_add_entry(struct crom_chunk *chunk, int key, int val)
struct csrreg reg;
uint32_t i;
} foo;
-
+
foo.reg.key = key;
foo.reg.val = val;
- return(crom_add_quad(chunk, foo.i));
+ return crom_add_quad(chunk, foo.i);
}
int
crom_add_chunk(struct crom_src *src, struct crom_chunk *parent,
- struct crom_chunk *child, int key)
+ struct crom_chunk *child, int key)
{
int index;
if (parent == NULL) {
STAILQ_INSERT_TAIL(&src->chunk_list, child, link);
- return(0);
+ return 0;
}
index = crom_add_entry(parent, key, 0);
- if (index < 0) {
- return(-1);
- }
+ if (index < 0)
+ return -1;
child->ref_chunk = parent;
child->ref_index = index;
STAILQ_INSERT_TAIL(&src->chunk_list, child, link);
- return(index);
+ return index;
}
-#if defined(__FreeBSD__)
-#define MAX_TEXT ((CROM_MAX_CHUNK_LEN + 1) * 4 - sizeof(struct csrtext))
-#elif defined(__NetBSD__)
#define MAX_TEXT (int)((CROM_MAX_CHUNK_LEN + 1) * 4 - sizeof(struct csrtext))
-#endif
int
crom_add_simple_text(struct crom_src *src, struct crom_chunk *parent,
- struct crom_chunk *chunk, const char *buf)
+ struct crom_chunk *chunk, const char *buf)
{
struct csrtext *tl;
uint32_t *p;
@@ -476,11 +432,7 @@ crom_add_simple_text(struct crom_src *src, struct crom_chunk *parent,
len = strlen(buf);
if (len > MAX_TEXT) {
-#if defined(__DragonFly__) || __FreeBSD_version < 500000 || defined(__NetBSD__)
printf("text(%d) trancated to %d.\n", len, MAX_TEXT);
-#else
- printf("text(%d) trancated to %td.\n", len, MAX_TEXT);
-#endif
len = MAX_TEXT;
}
@@ -489,24 +441,25 @@ crom_add_simple_text(struct crom_src *src, struct crom_chunk *parent,
tl->spec_id = 0;
tl->spec_type = 0;
tl->lang_id = 0;
- memset(&t[0], 0, roundup2(len, sizeof(uint32_t)));
- memcpy(&t[0], buf, len);
- p = (uint32_t *)&t[0];
- for (i = 0; i < howmany(len, sizeof(uint32_t)); i ++)
+ memset(t, 0, roundup2(len, sizeof(uint32_t)));
+ memcpy(t, buf, len);
+ p = (uint32_t *)t;
+ for (i = 0; i < howmany(len, sizeof(uint32_t)); i++)
tl->text[i] = ntohl(*p++);
- return (crom_add_chunk(src, parent, chunk, CROM_TEXTLEAF));
+ return crom_add_chunk(src, parent, chunk, CROM_TEXTLEAF);
}
static int
crom_copy(uint32_t *src, uint32_t *dst, int *offset, int len, int maxlen)
{
+
if (*offset + len > maxlen) {
printf("Config. ROM is too large for the buffer\n");
- return(-1);
+ return -1;
}
memcpy((char *)(dst + *offset), src, len * sizeof(uint32_t));
*offset += len;
- return(0);
+ return 0;
}
int
@@ -529,27 +482,28 @@ crom_load(struct crom_src *src, uint32_t *buf, int maxlen)
parent = chunk->ref_chunk;
if (parent != NULL) {
struct csrreg *reg;
- reg = (struct csrreg *)
- &parent->data.buf[chunk->ref_index];
- reg->val = offset -
- (parent->offset + 1 + chunk->ref_index);
+ const int ref_index = chunk->ref_index;
+
+ reg = (struct csrreg *)&parent->data.buf[ref_index];
+ reg->val =
+ offset - (parent->offset + 1 + chunk->ref_index);
}
- offset += 1 + chunk->data.crc_len;
+ offset += (1 + chunk->data.crc_len);
}
/* Calculate CRC and dump to the buffer */
len = 1 + src->hdr.info_len;
count = 0;
if (crom_copy((uint32_t *)&src->hdr, buf, &count, len, maxlen) < 0)
- return(-1);
+ return -1;
STAILQ_FOREACH(chunk, &src->chunk_list, link) {
chunk->data.crc =
- crom_crc(&chunk->data.buf[0], chunk->data.crc_len);
+ crom_crc(chunk->data.buf, chunk->data.crc_len);
len = 1 + chunk->data.crc_len;
- if (crom_copy((uint32_t *)&chunk->data, buf,
- &count, len, maxlen) < 0)
- return(-1);
+ if (crom_copy((uint32_t *)&chunk->data, buf, &count, len,
+ maxlen) < 0)
+ return -1;
}
hdr = (struct csrhdr *)buf;
hdr->crc_len = count - 1;
@@ -558,13 +512,13 @@ crom_load(struct crom_src *src, uint32_t *buf, int maxlen)
#if defined(_KERNEL) || defined(_BOOT)
/* byte swap */
ptr = buf;
- for (i = 0; i < count; i ++) {
+ for (i = 0; i < count; i++) {
*ptr = htonl(*ptr);
ptr++;
}
#endif
- return(count);
+ return count;
}
#endif
@@ -572,10 +526,11 @@ crom_load(struct crom_src *src, uint32_t *buf, int maxlen)
int
main () {
struct crom_src src;
- struct crom_chunk root,unit1,unit2,unit3;
- struct crom_chunk text1,text2,text3,text4,text5,text6,text7;
+ struct crom_chunk root, unit1, unit2, unit3;
+ struct crom_chunk text1, text2, text3, text4, text5, text6, text7;
uint32_t buf[256], *p;
int i;
+ extern const char ostype[];
memset(&src, 0, sizeof(src));
memset(&root, 0, sizeof(root));
@@ -614,8 +569,8 @@ main () {
/* private company_id */
crom_add_entry(&root, CSRKEY_VENDOR, 0xacde48);
- crom_add_simple_text(&src, &root, &text1, OS_STR);
- crom_add_entry(&root, CSRKEY_HW, OS_VER);
+ crom_add_simple_text(&src, &root, &text1, ostype);
+ crom_add_entry(&root, CSRKEY_HW, __NetBSD_Version__);
crom_add_simple_text(&src, &root, &text2, OS_VER_STR);
/* SBP unit directory */
@@ -648,12 +603,12 @@ main () {
crom_load(&src, buf, 256);
p = buf;
-#define DUMP_FORMAT "%08x %08x %08x %08x %08x %08x %08x %08x\n"
- for (i = 0; i < 256/8; i ++) {
+#define DUMP_FORMAT "%08x %08x %08x %08x %08x %08x %08x %08x\n"
+ for (i = 0; i < 256 / 8; i++) {
printf(DUMP_FORMAT,
- p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
p += 8;
}
- return(0);
+ return 0;
}
#endif
diff --git a/sys/dev/ieee1394/fwdev.c b/sys/dev/ieee1394/fwdev.c
index d082d83b0e5..b49aa6f1165 100644
--- a/sys/dev/ieee1394/fwdev.c
+++ b/sys/dev/ieee1394/fwdev.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fwdev.c,v 1.17 2009/04/18 14:58:02 tsutsui Exp $ */
+/* $NetBSD: fwdev.c,v 1.18 2010/03/29 03:05:27 kiyohara Exp $ */
/*-
* Copyright (c) 2003 Hidetoshi Shimokawa
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
@@ -31,111 +31,37 @@
* 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.
- *
+ *
* $FreeBSD: src/sys/dev/firewire/fwdev.c,v 1.52 2007/06/06 14:31:36 simokawa Exp $
*
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fwdev.c,v 1.17 2009/04/18 14:58:02 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fwdev.c,v 1.18 2010/03/29 03:05:27 kiyohara Exp $");
-#if defined(__FreeBSD__)
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/types.h>
-#include <sys/mbuf.h>
-#if defined(__DragonFly__) || __FreeBSD_version < 500000
-#include <sys/buf.h>
-#else
-#include <sys/bio.h>
-#endif
-
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/conf.h>
-#include <sys/poll.h>
-
-#include <sys/bus.h>
-#include <sys/ctype.h>
-#include <sys/bus.h>
-
-#include <sys/ioccom.h>
-
-#ifdef __DragonFly__
-#include "fw_port.h"
-#include "firewire.h"
-#include "firewirereg.h"
-#include "fwdma.h"
-#include "fwmem.h"
-#include "iec68113.h"
-#else
-#include <dev/firewire/fw_port.h>
-#include <dev/firewire/firewire.h>
-#include <dev/firewire/firewirereg.h>
-#include <dev/firewire/fwdma.h>
-#include <dev/firewire/fwmem.h>
-#include <dev/firewire/iec68113.h>
-#endif
-#elif defined(__NetBSD__)
#include <sys/param.h>
#include <sys/device.h>
#include <sys/errno.h>
#include <sys/buf.h>
+#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/poll.h>
#include <sys/proc.h>
+#include <sys/select.h>
-#include <sys/bus.h>
-
-#include <dev/ieee1394/fw_port.h>
#include <dev/ieee1394/firewire.h>
#include <dev/ieee1394/firewirereg.h>
#include <dev/ieee1394/fwdma.h>
#include <dev/ieee1394/fwmem.h>
#include <dev/ieee1394/iec68113.h>
-#endif
+
+#include "ioconf.h"
#define FWNODE_INVAL 0xffff
-#if defined(__FreeBSD__)
-static d_open_t fw_open;
-static d_close_t fw_close;
-static d_ioctl_t fw_ioctl;
-static d_poll_t fw_poll;
-static d_read_t fw_read; /* for Isochronous packet */
-static d_write_t fw_write;
-static d_mmap_t fw_mmap;
-static d_strategy_t fw_strategy;
-
-struct cdevsw firewire_cdevsw = {
-#ifdef __DragonFly__
-#define CDEV_MAJOR 127
- "fw", CDEV_MAJOR, D_MEM, NULL, 0,
- fw_open, fw_close, fw_read, fw_write, fw_ioctl,
- fw_poll, fw_mmap, fw_strategy, nodump, nopsize,
-#elif __FreeBSD_version >= 500104
- .d_version = D_VERSION,
- .d_open = fw_open,
- .d_close = fw_close,
- .d_read = fw_read,
- .d_write = fw_write,
- .d_ioctl = fw_ioctl,
- .d_poll = fw_poll,
- .d_mmap = fw_mmap,
- .d_strategy = fw_strategy,
- .d_name = "fw",
- .d_flags = D_MEM
-#else
-#define CDEV_MAJOR 127
- fw_open, fw_close, fw_read, fw_write, fw_ioctl,
- fw_poll, fw_mmap, fw_strategy, "fw", CDEV_MAJOR,
- nodump, nopsize, D_MEM, -1
-#endif
-};
-#elif defined(__NetBSD__)
dev_type_open(fw_open);
dev_type_close(fw_close);
dev_type_read(fw_read);
@@ -153,7 +79,6 @@ const struct cdevsw fw_cdevsw = {
fw_open, fw_close, fw_read, fw_write, fw_ioctl,
nostop, notty, fw_poll, fw_mmap, nokqfilter, D_OTHER,
};
-#endif
struct fw_drv1 {
struct firewire_comm *fc;
@@ -164,103 +89,42 @@ struct fw_drv1 {
STAILQ_HEAD(, fw_xfer) rq;
};
-static int
-fwdev_allocbuf(struct firewire_comm *fc, struct fw_xferq *q,
- struct fw_bufspec *b)
-{
- int i;
-
- if (q->flag & (FWXFERQ_RUNNING | FWXFERQ_EXTBUF))
- return(EBUSY);
-
- q->bulkxfer = (struct fw_bulkxfer *) malloc(
- sizeof(struct fw_bulkxfer) * b->nchunk,
- M_FW, M_WAITOK);
- if (q->bulkxfer == NULL)
- return(ENOMEM);
-
- b->psize = roundup2(b->psize, sizeof(uint32_t));
- q->buf = fwdma_malloc_multiseg(fc, sizeof(uint32_t),
- b->psize, b->nchunk * b->npacket, BUS_DMA_WAITOK);
-
- if (q->buf == NULL) {
- free(q->bulkxfer, M_FW);
- q->bulkxfer = NULL;
- return(ENOMEM);
- }
- q->bnchunk = b->nchunk;
- q->bnpacket = b->npacket;
- q->psize = (b->psize + 3) & ~3;
- q->queued = 0;
+static int fwdev_allocbuf(struct firewire_comm *, struct fw_xferq *,
+ struct fw_bufspec *);
+static int fwdev_freebuf(struct fw_xferq *);
+static int fw_read_async(struct fw_drv1 *, struct uio *, int);
+static int fw_write_async(struct fw_drv1 *, struct uio *, int);
+static void fw_hand(struct fw_xfer *);
- STAILQ_INIT(&q->stvalid);
- STAILQ_INIT(&q->stfree);
- STAILQ_INIT(&q->stdma);
- q->stproc = NULL;
- for(i = 0 ; i < q->bnchunk; i++){
- q->bulkxfer[i].poffset = i * q->bnpacket;
- q->bulkxfer[i].mbuf = NULL;
- STAILQ_INSERT_TAIL(&q->stfree, &q->bulkxfer[i], link);
- }
-
- q->flag &= ~FWXFERQ_MODEMASK;
- q->flag |= FWXFERQ_STREAM;
- q->flag |= FWXFERQ_EXTBUF;
-
- return (0);
-}
-
-static int
-fwdev_freebuf(struct fw_xferq *q)
-{
- if (q->flag & FWXFERQ_EXTBUF) {
- if (q->buf != NULL)
- fwdma_free_multiseg(q->buf);
- q->buf = NULL;
- free(q->bulkxfer, M_FW);
- q->bulkxfer = NULL;
- q->flag &= ~FWXFERQ_EXTBUF;
- q->psize = 0;
- q->maxq = FWMAXQUEUE;
- }
- return (0);
-}
-
-
-FW_OPEN(fw)
+int
+fw_open(dev_t dev, int flags, int fmt, struct lwp *td)
{
- int err = 0;
+ struct firewire_softc *sc;
struct fw_drv1 *d;
- FW_OPEN_START;
+ int err = 0;
- FWDEV_OPEN_START;
+ sc = device_lookup_private(&ieee1394if_cd, DEV2UNIT(dev));
+ if (sc == NULL)
+ return ENXIO;
+
+ if (DEV_FWMEM(dev))
+ return fwmem_open(dev, flags, fmt, td);
- FW_GLOCK(sc->fc);
- if (dev->si_drv1 != NULL) {
- FW_GUNLOCK(sc->fc);
- return (EBUSY);
+ mutex_enter(&sc->fc->fc_mtx);
+ if (sc->si_drv1 != NULL) {
+ mutex_exit(&sc->fc->fc_mtx);
+ return EBUSY;
}
/* set dummy value for allocation */
- dev->si_drv1 = (void *)-1;
- FW_GUNLOCK(sc->fc);
-
- dev->si_drv1 = malloc(sizeof(struct fw_drv1), M_FW, M_WAITOK | M_ZERO);
- if (dev->si_drv1 == NULL)
- return (ENOMEM);
+ sc->si_drv1 = (void *)-1;
+ mutex_exit(&sc->fc->fc_mtx);
-#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
- if ((dev->si_flags & SI_NAMED) == 0) {
- int unit = DEV2UNIT(dev);
- int sub = DEV2SUB(dev);
-
- make_dev(&firewire_cdevsw, minor(dev),
- UID_ROOT, GID_OPERATOR, 0660,
- "fw%d.%d", unit, sub);
- }
-#endif
+ sc->si_drv1 = malloc(sizeof(struct fw_drv1), M_FW, M_WAITOK | M_ZERO);
+ if (sc->si_drv1 == NULL)
+ return ENOMEM;
- d = (struct fw_drv1 *)dev->si_drv1;
+ d = (struct fw_drv1 *)sc->si_drv1;
d->fc = sc->fc;
STAILQ_INIT(&d->binds);
STAILQ_INIT(&d->rq);
@@ -268,23 +132,29 @@ FW_OPEN(fw)
return err;
}
-FW_CLOSE(fw)
+int
+fw_close(dev_t dev, int flags, int fmt, struct lwp *td)
{
+ struct firewire_softc *sc;
struct firewire_comm *fc;
struct fw_drv1 *d;
struct fw_xfer *xfer;
struct fw_bind *fwb;
- int err = 0;
- FW_CLOSE_START;
+ int err = 0;
- FWDEV_CLOSE_START;
+ sc = device_lookup_private(&ieee1394if_cd, DEV2UNIT(dev));
+ if (sc == NULL)
+ return ENXIO;
+
+ if (DEV_FWMEM(dev))
+ return fwmem_close(dev, flags, fmt, td);
- d = (struct fw_drv1 *)dev->si_drv1;
+ d = (struct fw_drv1 *)sc->si_drv1;
fc = d->fc;
/* remove binding */
for (fwb = STAILQ_FIRST(&d->binds); fwb != NULL;
- fwb = STAILQ_FIRST(&d->binds)) {
+ fwb = STAILQ_FIRST(&d->binds)) {
fw_bindremove(fc, fwb);
STAILQ_REMOVE_HEAD(&d->binds, chlist);
fw_xferlist_remove(&fwb->xferlist);
@@ -294,7 +164,7 @@ FW_CLOSE(fw)
struct fw_xferq *ir = d->ir;
if ((ir->flag & FWXFERQ_OPEN) == 0)
- return (EINVAL);
+ return EINVAL;
if (ir->flag & FWXFERQ_RUNNING) {
ir->flag &= ~FWXFERQ_RUNNING;
fc->irx_disable(fc, ir->dmach);
@@ -302,16 +172,16 @@ FW_CLOSE(fw)
/* free extbuf */
fwdev_freebuf(ir);
/* drain receiving buffer */
- for (xfer = STAILQ_FIRST(&ir->q);
- xfer != NULL; xfer = STAILQ_FIRST(&ir->q)) {
- ir->queued --;
+ for (xfer = STAILQ_FIRST(&ir->q); xfer != NULL;
+ xfer = STAILQ_FIRST(&ir->q)) {
+ ir->queued--;
STAILQ_REMOVE_HEAD(&ir->q, link);
xfer->resp = 0;
fw_xfer_done(xfer);
}
- ir->flag &= ~(FWXFERQ_OPEN |
- FWXFERQ_MODEMASK | FWXFERQ_CHTAGMASK);
+ ir->flag &=
+ ~(FWXFERQ_OPEN | FWXFERQ_MODEMASK | FWXFERQ_CHTAGMASK);
d->ir = NULL;
}
@@ -319,100 +189,57 @@ FW_CLOSE(fw)
struct fw_xferq *it = d->it;
if ((it->flag & FWXFERQ_OPEN) == 0)
- return (EINVAL);
+ return EINVAL;
if (it->flag & FWXFERQ_RUNNING) {
it->flag &= ~FWXFERQ_RUNNING;
fc->itx_disable(fc, it->dmach);
}
/* free extbuf */
fwdev_freebuf(it);
- it->flag &= ~(FWXFERQ_OPEN |
- FWXFERQ_MODEMASK | FWXFERQ_CHTAGMASK);
+ it->flag &=
+ ~(FWXFERQ_OPEN | FWXFERQ_MODEMASK | FWXFERQ_CHTAGMASK);
d->it = NULL;
}
- free(dev->si_drv1, M_FW);
- dev->si_drv1 = NULL;
+ free(sc->si_drv1, M_FW);
+ sc->si_drv1 = NULL;
return err;
}
-static int
-fw_read_async(struct fw_drv1 *d, struct uio *uio, int ioflag)
-{
- int err = 0, s;
- struct fw_xfer *xfer;
- struct fw_bind *fwb;
- struct fw_pkt *fp;
- const struct tcode_info *tinfo;
-
- FW_GLOCK(d->fc);
- while ((xfer = STAILQ_FIRST(&d->rq)) == NULL && err == 0)
- err = fw_msleep(&d->rq, FW_GMTX(d->fc), FWPRI, "fwra", 0);
-
- if (err != 0) {
- FW_GUNLOCK(d->fc);
- return (err);
- }
-
- s = splfw();
- STAILQ_REMOVE_HEAD(&d->rq, link);
- FW_GUNLOCK(xfer->fc);
- splx(s);
- fp = &xfer->recv.hdr;
-#if 0 /* for GASP ?? */
- if (fc->irx_post != NULL)
- fc->irx_post(fc, fp->mode.ld);
-#endif
- tinfo = &xfer->fc->tcode[fp->mode.hdr.tcode];
- err = uiomove((void *)fp, tinfo->hdr_len, uio);
- if (err)
- goto out;
- err = uiomove((void *)xfer->recv.payload, xfer->recv.pay_len, uio);
-
-out:
- /* recycle this xfer */
- fwb = (struct fw_bind *)xfer->sc;
- fw_xfer_unload(xfer);
- xfer->recv.pay_len = PAGE_SIZE;
- FW_GLOCK(xfer->fc);
- STAILQ_INSERT_TAIL(&fwb->xferlist, xfer, link);
- FW_GUNLOCK(xfer->fc);
- return (err);
-}
-
-/*
- * read request.
- */
-FW_READ(fw)
+int
+fw_read(dev_t dev, struct uio *uio, int ioflag)
{
- FW_READ_START;
+ struct firewire_softc *sc;
+ struct firewire_comm *fc;
struct fw_drv1 *d;
struct fw_xferq *ir;
- struct firewire_comm *fc;
- int err = 0, s, slept = 0;
struct fw_pkt *fp;
+ int err = 0, slept = 0;
- FWDEV_READ_START;
+ sc = device_lookup_private(&ieee1394if_cd, DEV2UNIT(dev));
+ if (sc == NULL)
+ return ENXIO;
+
+ if (DEV_FWMEM(dev))
+ return physio(fw_strategy, NULL, dev, ioflag, minphys, uio);
- d = (struct fw_drv1 *)dev->si_drv1;
+ d = (struct fw_drv1 *)sc->si_drv1;
fc = d->fc;
ir = d->ir;
if (ir == NULL)
- return (fw_read_async(d, uio, ioflag));
+ return fw_read_async(d, uio, ioflag);
if (ir->buf == NULL)
- return (EIO);
+ return EIO;
- FW_GLOCK(fc);
+ mutex_enter(&fc->fc_mtx);
readloop:
if (ir->stproc == NULL) {
/* iso bulkxfer */
ir->stproc = STAILQ_FIRST(&ir->stvalid);
if (ir->stproc != NULL) {
- s = splfw();
STAILQ_REMOVE_HEAD(&ir->stvalid, link);
- splx(s);
ir->queued = 0;
}
}
@@ -421,129 +248,74 @@ readloop:
if (slept == 0) {
slept = 1;
ir->flag |= FWXFERQ_WAKEUP;
- err = fw_msleep(ir, FW_GMTX(fc), FWPRI, "fw_read", hz);
+ err = tsleep(ir, FWPRI, "fw_read", hz);
ir->flag &= ~FWXFERQ_WAKEUP;
if (err == 0)
goto readloop;
} else if (slept == 1)
err = EIO;
- FW_GUNLOCK(fc);
+ mutex_exit(&fc->fc_mtx);
return err;
- } else if(ir->stproc != NULL) {
+ } else if (ir->stproc != NULL) {
/* iso bulkxfer */
- FW_GUNLOCK(fc);
- fp = (struct fw_pkt *)fwdma_v_addr(ir->buf,
- ir->stproc->poffset + ir->queued);
- if(fc->irx_post != NULL)
+ mutex_exit(&fc->fc_mtx);
+ fp = (struct fw_pkt *)fwdma_v_addr(ir->buf,
+ ir->stproc->poffset + ir->queued);
+ if (fc->irx_post != NULL)
fc->irx_post(fc, fp->mode.ld);
- if(fp->mode.stream.len == 0){
- err = EIO;
- return err;
- }
+ if (fp->mode.stream.len == 0)
+ return EIO;
err = uiomove((void *)fp,
- fp->mode.stream.len + sizeof(uint32_t), uio);
- ir->queued ++;
- if(ir->queued >= ir->bnpacket){
- s = splfw();
+ fp->mode.stream.len + sizeof(uint32_t), uio);
+ ir->queued++;
+ if (ir->queued >= ir->bnpacket) {
STAILQ_INSERT_TAIL(&ir->stfree, ir->stproc, link);
- splx(s);
fc->irx_enable(fc, ir->dmach);
ir->stproc = NULL;
}
if (uio->uio_resid >= ir->psize) {
slept = -1;
- FW_GLOCK(fc);
+ mutex_enter(&fc->fc_mtx);
goto readloop;
}
- }
+ } else
+ mutex_exit(&fc->fc_mtx);
return err;
}
-static int
-fw_write_async(struct fw_drv1 *d, struct uio *uio, int ioflag)
-{
- struct fw_xfer *xfer;
- struct fw_pkt pkt;
- const struct tcode_info *tinfo;
- int err;
-
- memset(&pkt, 0, sizeof(struct fw_pkt));
- if ((err = uiomove((void *)&pkt, sizeof(uint32_t), uio)))
- return (err);
- tinfo = &d->fc->tcode[pkt.mode.hdr.tcode];
- if ((err = uiomove((char *)&pkt + sizeof(uint32_t),
- tinfo->hdr_len - sizeof(uint32_t), uio)))
- return (err);
-
- if ((xfer = fw_xfer_alloc_buf(M_FWXFER, uio->uio_resid,
- PAGE_SIZE/*XXX*/)) == NULL)
- return (ENOMEM);
-
- memcpy(&xfer->send.hdr, &pkt, sizeof(struct fw_pkt));
- xfer->send.pay_len = uio->uio_resid;
- if (uio->uio_resid > 0) {
- if ((err = uiomove((void *)&xfer->send.payload[0],
- uio->uio_resid, uio)))
- goto out;
- }
-
- xfer->fc = d->fc;
- xfer->sc = NULL;
- xfer->hand = fw_xferwake;
- xfer->send.spd = 2 /* XXX */;
-
- if ((err = fw_asyreq(xfer->fc, -1, xfer)))
- goto out;
-
- if ((err = fw_xferwait(xfer)))
- goto out;
-
- if (xfer->resp != 0) {
- err = xfer->resp;
- goto out;
- }
-
- if (xfer->flag == FWXF_RCVD) {
- FW_GLOCK(xfer->fc);
- STAILQ_INSERT_TAIL(&d->rq, xfer, link);
- FW_GUNLOCK(xfer->fc);
- return (0);
- }
-
-out:
- fw_xfer_free(xfer);
- return (err);
-}
-
-FW_WRITE(fw)
+int
+fw_write(dev_t dev, struct uio *uio, int ioflag)
{
- FW_WRITE_START;
- int err = 0;
- int s, slept = 0;
+ struct firewire_softc *sc;
+ struct firewire_comm *fc;
struct fw_drv1 *d;
struct fw_pkt *fp;
- struct firewire_comm *fc;
struct fw_xferq *it;
+ int slept = 0, err = 0;
+
+ sc = device_lookup_private(&ieee1394if_cd, DEV2UNIT(dev));
+ if (sc == NULL)
+ return ENXIO;
+
+ if (DEV_FWMEM(dev))
+ return physio(fw_strategy, NULL, dev, ioflag, minphys, uio);
- FWDEV_WRITE_START;
- d = (struct fw_drv1 *)dev->si_drv1;
+ d = (struct fw_drv1 *)sc->si_drv1;
fc = d->fc;
it = d->it;
if (it == NULL)
- return (fw_write_async(d, uio, ioflag));
+ return fw_write_async(d, uio, ioflag);
if (it->buf == NULL)
- return (EIO);
+ return EIO;
- FW_GLOCK(fc);
+ mutex_enter(&fc->fc_mtx);
isoloop:
if (it->stproc == NULL) {
it->stproc = STAILQ_FIRST(&it->stfree);
if (it->stproc != NULL) {
- s = splfw();
STAILQ_REMOVE_HEAD(&it->stfree, link);
- splx(s);
it->queued = 0;
} else if (slept == 0) {
slept = 1;
@@ -552,7 +324,7 @@ isoloop:
if (err)
goto out;
#endif
- err = fw_msleep(it, FW_GMTX(fc), FWPRI, "fw_write", hz);
+ err = tsleep(it, FWPRI, "fw_write", hz);
if (err)
goto out;
goto isoloop;
@@ -561,76 +333,64 @@ isoloop:
goto out;
}
}
- FW_GUNLOCK(fc);
+ mutex_exit(&fc->fc_mtx);
fp = (struct fw_pkt *)fwdma_v_addr(it->buf,
- it->stproc->poffset + it->queued);
+ it->stproc->poffset + it->queued);
err = uiomove((void *)fp, sizeof(struct fw_isohdr), uio);
- err = uiomove((void *)fp->mode.stream.payload,
- fp->mode.stream.len, uio);
- it->queued ++;
+ if (err != 0)
+ return err;
+ err =
+ uiomove((void *)fp->mode.stream.payload, fp->mode.stream.len, uio);
+ it->queued++;
if (it->queued >= it->bnpacket) {
- s = splfw();
STAILQ_INSERT_TAIL(&it->stvalid, it->stproc, link);
- splx(s);
it->stproc = NULL;
err = fc->itx_enable(fc, it->dmach);
}
if (uio->uio_resid >= sizeof(struct fw_isohdr)) {
slept = 0;
- FW_GLOCK(fc);
+ mutex_enter(&fc->fc_mtx);
goto isoloop;
}
return err;
out:
- FW_GUNLOCK(fc);
+ mutex_exit(&fc->fc_mtx);
return err;
}
-static void
-fw_hand(struct fw_xfer *xfer)
-{
- struct fw_bind *fwb;
- struct fw_drv1 *d;
-
- fwb = (struct fw_bind *)xfer->sc;
- d = (struct fw_drv1 *)fwb->sc;
- FW_GLOCK(xfer->fc);
- STAILQ_INSERT_TAIL(&d->rq, xfer, link);
- FW_GUNLOCK(xfer->fc);
- wakeup(&d->rq);
-}
-
-/*
- * ioctl support.
- */
-FW_IOCTL(fw)
+int
+fw_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *td)
{
- FW_IOCTL_START;
+ struct firewire_softc *sc;
struct firewire_comm *fc;
struct fw_drv1 *d;
- int i, len, err = 0;
struct fw_device *fwdev;
struct fw_bind *fwb;
struct fw_xferq *ir, *it;
struct fw_xfer *xfer;
struct fw_pkt *fp;
struct fw_devinfo *devinfo;
- void *ptr;
-
struct fw_devlstreq *fwdevlst = (struct fw_devlstreq *)data;
struct fw_asyreq *asyreq = (struct fw_asyreq *)data;
struct fw_isochreq *ichreq = (struct fw_isochreq *)data;
struct fw_isobufreq *ibufreq = (struct fw_isobufreq *)data;
struct fw_asybindreq *bindreq = (struct fw_asybindreq *)data;
struct fw_crom_buf *crom_buf = (struct fw_crom_buf *)data;
+ int i, len, err = 0;
+ void *ptr;
+
+ sc = device_lookup_private(&ieee1394if_cd, DEV2UNIT(dev));
+ if (sc == NULL)
+ return ENXIO;
- FWDEV_IOCTL_START;
+ if (DEV_FWMEM(dev))
+ return fwmem_ioctl(dev, cmd, data, flag, td);
if (!data)
- return(EINVAL);
+ return EINVAL;
- d = (struct fw_drv1 *)dev->si_drv1;
+ d = (struct fw_drv1 *)sc->si_drv1;
fc = d->fc;
ir = d->ir;
it = d->it;
@@ -655,6 +415,7 @@ FW_IOCTL(fw)
it->flag |= ((0x3 & ichreq->tag) << 6);
d->it = it;
break;
+
case FW_GTSTREAM:
if (it != NULL) {
ichreq->ch = it->flag & 0x3f;
@@ -662,6 +423,7 @@ FW_IOCTL(fw)
} else
err = EINVAL;
break;
+
case FW_SRSTREAM:
if (ir == NULL) {
i = fw_open_isodma(fc, /* tx */0);
@@ -682,6 +444,7 @@ FW_IOCTL(fw)
d->ir = ir;
err = fc->irx_enable(fc, ir->dmach);
break;
+
case FW_GRSTREAM:
if (d->ir != NULL) {
ichreq->ch = ir->flag & 0x3f;
@@ -689,9 +452,11 @@ FW_IOCTL(fw)
} else
err = EINVAL;
break;
+
case FW_SSTBUF:
memcpy(&d->bufreq, ibufreq, sizeof(d->bufreq));
break;
+
case FW_GSTBUF:
memset(&ibufreq->rx, 0, sizeof(ibufreq->rx));
if (ir != NULL) {
@@ -706,6 +471,7 @@ FW_IOCTL(fw)
ibufreq->tx.psize = it->psize;
}
break;
+
case FW_ASYREQ:
{
const struct tcode_info *tinfo;
@@ -719,24 +485,27 @@ FW_IOCTL(fw)
xfer = fw_xfer_alloc_buf(M_FWXFER, pay_len, PAGE_SIZE/*XXX*/);
if (xfer == NULL)
- return (ENOMEM);
+ return ENOMEM;
switch (asyreq->req.type) {
case FWASREQNODE:
break;
+
case FWASREQEUI:
- fwdev = fw_noderesolve_eui64(fc,
- &asyreq->req.dst.eui);
+ fwdev = fw_noderesolve_eui64(fc, &asyreq->req.dst.eui);
if (fwdev == NULL) {
- fw_printf(fc->bdev, "cannot find node\n");
+ aprint_error_dev(fc->bdev,
+ "cannot find node\n");
err = EINVAL;
goto out;
}
fp->mode.hdr.dst = FWLOCALBUS | fwdev->dst;
break;
+
case FWASRESTL:
/* XXX what's this? */
break;
+
case FWASREQSTREAM:
/* nothing to do */
break;
@@ -744,8 +513,8 @@ FW_IOCTL(fw)
memcpy((void *)&xfer->send.hdr, fp, tinfo->hdr_len);
if (pay_len > 0)
- bcopy((char *)fp + tinfo->hdr_len,
- (void *)xfer->send.payload, pay_len);
+ memcpy((void *)xfer->send.payload,
+ (char *)fp + tinfo->hdr_len, pay_len);
xfer->send.spd = asyreq->req.sped;
xfer->hand = fw_xferwake;
@@ -765,29 +534,31 @@ FW_IOCTL(fw)
if (xfer->recv.hdr.mode.hdr.tcode == FWTCODE_RRESB ||
xfer->recv.hdr.mode.hdr.tcode == FWTCODE_LRES) {
pay_len = xfer->recv.pay_len;
- if (asyreq->req.len >= xfer->recv.pay_len + tinfo->hdr_len) {
- asyreq->req.len = xfer->recv.pay_len +
- tinfo->hdr_len;
- } else {
+ if (asyreq->req.len >=
+ xfer->recv.pay_len + tinfo->hdr_len)
+ asyreq->req.len =
+ xfer->recv.pay_len + tinfo->hdr_len;
+ else {
err = EINVAL;
pay_len = 0;
}
- } else {
+ } else
pay_len = 0;
- }
memcpy(fp, &xfer->recv.hdr, tinfo->hdr_len);
- memcpy((char *)fp + tinfo->hdr_len, xfer->recv.payload, pay_len);
+ memcpy((char *)fp + tinfo->hdr_len, xfer->recv.payload,
+ pay_len);
out:
fw_xfer_free_buf(xfer);
break;
}
+
case FW_IBUSRST:
fc->ibr(fc);
break;
+
case FW_CBINDADDR:
- fwb = fw_bindlookup(fc,
- bindreq->start.hi, bindreq->start.lo);
- if(fwb == NULL){
+ fwb = fw_bindlookup(fc, bindreq->start.hi, bindreq->start.lo);
+ if (fwb == NULL) {
err = EINVAL;
break;
}
@@ -796,17 +567,19 @@ out:
fw_xferlist_remove(&fwb->xferlist);
free(fwb, M_FW);
break;
+
case FW_SBINDADDR:
- if(bindreq->len <= 0 ){
+ if (bindreq->len <= 0 ) {
err = EINVAL;
break;
}
- if(bindreq->start.hi > 0xffff ){
+ if (bindreq->start.hi > 0xffff ) {
err = EINVAL;
break;
}
- fwb = (struct fw_bind *)malloc(sizeof (struct fw_bind), M_FW, M_WAITOK);
- if(fwb == NULL){
+ fwb = (struct fw_bind *)malloc(sizeof(struct fw_bind),
+ M_FW, M_WAITOK);
+ if (fwb == NULL) {
err = ENOMEM;
break;
}
@@ -819,25 +592,25 @@ out:
if (err == 0) {
fw_xferlist_add(&fwb->xferlist, M_FWXFER,
/* XXX */
- PAGE_SIZE, PAGE_SIZE, 5,
- fc, (void *)fwb, fw_hand);
+ PAGE_SIZE, PAGE_SIZE, 5, fc, (void *)fwb, fw_hand);
STAILQ_INSERT_TAIL(&d->binds, fwb, chlist);
}
break;
+
case FW_GDEVLST:
i = len = 1;
/* myself */
- devinfo = &fwdevlst->dev[0];
+ devinfo = fwdevlst->dev;
devinfo->dst = fc->nodeid;
devinfo->status = 0; /* XXX */
devinfo->eui.hi = fc->eui.hi;
devinfo->eui.lo = fc->eui.lo;
STAILQ_FOREACH(fwdev, &fc->devices, link) {
- if(len < FW_MAX_DEVLST){
+ if (len < FW_MAX_DEVLST) {
devinfo = &fwdevlst->dev[len++];
devinfo->dst = fwdev->dst;
- devinfo->status =
- (fwdev->status == FWDEVINVAL)?0:1;
+ devinfo->status =
+ (fwdev->status == FWDEVINVAL) ? 0 : 1;
devinfo->eui.hi = fwdev->eui.hi;
devinfo->eui.lo = fwdev->eui.lo;
}
@@ -846,10 +619,12 @@ out:
fwdevlst->n = i;
fwdevlst->info_len = len;
break;
+
case FW_GTPMAP:
memcpy(data, fc->topology_map,
- (fc->topology_map->crc_len + 1) * 4);
+ (fc->topology_map->crc_len + 1) * 4);
break;
+
case FW_GCROM:
STAILQ_FOREACH(fwdev, &fc->devices, link)
if (FW_EUI64_EQUAL(fwdev->eui, crom_buf->eui))
@@ -863,11 +638,10 @@ out:
ptr = malloc(CROMSIZE, M_FW, M_WAITOK);
len = CROMSIZE;
for (i = 0; i < CROMSIZE/4; i++)
- ((uint32_t *)ptr)[i]
- = ntohl(fc->config_rom[i]);
+ ((uint32_t *)ptr)[i] = ntohl(fc->config_rom[i]);
} else {
/* found */
- ptr = (void *)&fwdev->csrrom[0];
+ ptr = (void *)fwdev->csrrom;
if (fwdev->rommax < CSRROMOFF)
len = 0;
else
@@ -882,23 +656,26 @@ out:
/* myself */
free(ptr, M_FW);
break;
+
default:
- FWDEV_IOCTL_REDIRECT;
+ fc->ioctl(dev, cmd, data, flag, td);
break;
}
return err;
}
-FW_POLL(fw)
+int
+fw_poll(dev_t dev, int events, struct lwp *td)
{
- FW_POLL_START;
+ struct firewire_softc *sc;
struct fw_xferq *ir;
- int revents;
- int tmp;
+ int revents, tmp;
- FWDEV_POLL_START;
+ sc = device_lookup_private(&ieee1394if_cd, DEV2UNIT(dev));
+ if (sc == NULL)
+ return ENXIO;
- ir = ((struct fw_drv1 *)dev->si_drv1)->ir;
+ ir = ((struct fw_drv1 *)sc->si_drv1)->ir;
revents = 0;
tmp = POLLIN | POLLRDNORM;
if (events & tmp) {
@@ -908,19 +685,21 @@ FW_POLL(fw)
selrecord(td, &ir->rsel);
}
tmp = POLLOUT | POLLWRNORM;
- if (events & tmp) {
- /* XXX should be fixed */
+ if (events & tmp)
+ /* XXX should be fixed */
revents |= tmp;
- }
return revents;
}
-FW_MMAP(fw)
-{
- FW_MMAP_START;
+paddr_t
+fw_mmap(dev_t dev, off_t offset, int nproto)
+{
+ struct firewire_softc *sc;
- FWDEV_MMAP_START;
+ sc = device_lookup_private(&ieee1394if_cd, DEV2UNIT(dev));
+ if (sc == NULL)
+ return ENXIO;
return EINVAL;
}
@@ -928,109 +707,196 @@ FW_MMAP(fw)
void
fw_strategy(struct bio *bp)
{
- FW_STRATEGY_START;
+ struct firewire_softc *sc;
+ dev_t dev = bp->bio_dev;
- FWDEV_STRATEGY_START;
+ sc = device_lookup_private(&ieee1394if_cd, DEV2UNIT(dev));
+ if (sc == NULL)
+ return;
+
+ if (DEV_FWMEM(dev)) {
+ fwmem_strategy(bp);
+ return;
+ }
bp->bio_error = EOPNOTSUPP;
bp->bio_resid = bp->bio_bcount;
biodone(bp);
}
-#if defined(__FreeBSD__)
-int
-fwdev_makedev(struct firewire_softc *sc)
+
+static int
+fwdev_allocbuf(struct firewire_comm *fc, struct fw_xferq *q,
+ struct fw_bufspec *b)
{
- int err = 0;
+ int i;
-#if defined(__DragonFly__)
- int unit;
-
- unit = fw_get_unit(sc->fc->bdev);
- cdevsw_add(&firewire_cdevsw, FW_UNITMASK, FW_UNIT(unit));
-#elif __FreeBSD_version < 500000
- cdevsw_add(&firewire_cdevsw);
-#else
- fw_dev_t d;
- int unit;
-
- unit = fw_get_unit(sc->fc->bdev);
- sc->dev = make_dev(&firewire_cdevsw, MAKEMINOR(0, unit, 0),
- UID_ROOT, GID_OPERATOR, 0660,
- "fw%d.%d", unit, 0);
- d = make_dev(&firewire_cdevsw,
- MAKEMINOR(FWMEM_FLAG, unit, 0),
- UID_ROOT, GID_OPERATOR, 0660,
- "fwmem%d.%d", unit, 0);
- dev_depends(sc->dev, d);
- make_dev_alias(sc->dev, "fw%d", unit);
- make_dev_alias(d, "fwmem%d", unit);
-#endif
+ if (q->flag & (FWXFERQ_RUNNING | FWXFERQ_EXTBUF))
+ return EBUSY;
+
+ q->bulkxfer =
+ (struct fw_bulkxfer *)malloc(sizeof(struct fw_bulkxfer) * b->nchunk,
+ M_FW, M_WAITOK);
+ if (q->bulkxfer == NULL)
+ return ENOMEM;
+
+ b->psize = roundup2(b->psize, sizeof(uint32_t));
+ q->buf = fwdma_malloc_multiseg(fc, sizeof(uint32_t), b->psize,
+ b->nchunk * b->npacket, BUS_DMA_WAITOK);
+
+ if (q->buf == NULL) {
+ free(q->bulkxfer, M_FW);
+ q->bulkxfer = NULL;
+ return ENOMEM;
+ }
+ q->bnchunk = b->nchunk;
+ q->bnpacket = b->npacket;
+ q->psize = (b->psize + 3) & ~3;
+ q->queued = 0;
+
+ STAILQ_INIT(&q->stvalid);
+ STAILQ_INIT(&q->stfree);
+ STAILQ_INIT(&q->stdma);
+ q->stproc = NULL;
+
+ for (i = 0 ; i < q->bnchunk; i++) {
+ q->bulkxfer[i].poffset = i * q->bnpacket;
+ q->bulkxfer[i].mbuf = NULL;
+ STAILQ_INSERT_TAIL(&q->stfree, &q->bulkxfer[i], link);
+ }
+
+ q->flag &= ~FWXFERQ_MODEMASK;
+ q->flag |= FWXFERQ_STREAM;
+ q->flag |= FWXFERQ_EXTBUF;
- return (err);
+ return 0;
}
-int
-fwdev_destroydev(struct firewire_softc *sc)
+static int
+fwdev_freebuf(struct fw_xferq *q)
{
+
+ if (q->flag & FWXFERQ_EXTBUF) {
+ if (q->buf != NULL)
+ fwdma_free_multiseg(q->buf);
+ q->buf = NULL;
+ free(q->bulkxfer, M_FW);
+ q->bulkxfer = NULL;
+ q->flag &= ~FWXFERQ_EXTBUF;
+ q->psize = 0;
+ q->maxq = FWMAXQUEUE;
+ }
+ return 0;
+}
+
+static int
+fw_read_async(struct fw_drv1 *d, struct uio *uio, int ioflag)
+{
+ struct fw_xfer *xfer;
+ struct fw_bind *fwb;
+ struct fw_pkt *fp;
+ const struct tcode_info *tinfo;
int err = 0;
-#if defined(__DragonFly__)
- int unit;
+ mutex_enter(&d->fc->fc_mtx);
+ while ((xfer = STAILQ_FIRST(&d->rq)) == NULL && err == 0)
+ err = tsleep(&d->rq, FWPRI, "fwra", 0);
+
+ if (err != 0) {
+ mutex_exit(&d->fc->fc_mtx);
+ return err;
+ }
- unit = fw_get_unit(sc->fc->bdev);
- cdevsw_remove(&firewire_cdevsw, FW_UNITMASK, FW_UNIT(unit));
-#elif __FreeBSD_version < 500000
- cdevsw_remove(&firewire_cdevsw);
-#else
- destroy_dev(sc->dev);
+ STAILQ_REMOVE_HEAD(&d->rq, link);
+ mutex_exit(&d->fc->fc_mtx);
+ fp = &xfer->recv.hdr;
+#if 0 /* for GASP ?? */
+ if (fc->irx_post != NULL)
+ fc->irx_post(fc, fp->mode.ld);
#endif
- return (err);
+ tinfo = &xfer->fc->tcode[fp->mode.hdr.tcode];
+ err = uiomove((void *)fp, tinfo->hdr_len, uio);
+ if (err)
+ goto out;
+ err = uiomove((void *)xfer->recv.payload, xfer->recv.pay_len, uio);
+
+out:
+ /* recycle this xfer */
+ fwb = (struct fw_bind *)xfer->sc;
+ fw_xfer_unload(xfer);
+ xfer->recv.pay_len = PAGE_SIZE;
+ mutex_enter(&d->fc->fc_mtx);
+ STAILQ_INSERT_TAIL(&fwb->xferlist, xfer, link);
+ mutex_exit(&d->fc->fc_mtx);
+ return err;
}
-#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
-#define NDEVTYPE 2
-void
-fwdev_clone(void *arg, struct ucred *cred, char *name, int namelen,
- struct cdev **dev)
+static int
+fw_write_async(struct fw_drv1 *d, struct uio *uio, int ioflag)
{
- struct firewire_softc *sc;
- char *devnames[NDEVTYPE] = {"fw", "fwmem"};
- char *subp = NULL;
- int devflag[NDEVTYPE] = {0, FWMEM_FLAG};
- int i, unit = 0, sub = 0;
+ struct fw_xfer *xfer;
+ struct fw_pkt pkt;
+ const struct tcode_info *tinfo;
+ int err;
- if (*dev != NULL)
- return;
+ memset(&pkt, 0, sizeof(struct fw_pkt));
+ if ((err = uiomove((void *)&pkt, sizeof(uint32_t), uio)))
+ return err;
+ tinfo = &d->fc->tcode[pkt.mode.hdr.tcode];
+ if ((err = uiomove((char *)&pkt + sizeof(uint32_t),
+ tinfo->hdr_len - sizeof(uint32_t), uio)))
+ return err;
- for (i = 0; i < NDEVTYPE; i++)
- if (dev_stdclone(name, &subp, devnames[i], &unit) == 2)
- goto found;
- /* not match */
- return;
-found:
+ if ((xfer = fw_xfer_alloc_buf(M_FWXFER, uio->uio_resid,
+ PAGE_SIZE/*XXX*/)) == NULL)
+ return ENOMEM;
- if (subp == NULL || *subp++ != '.')
- return;
+ memcpy(&xfer->send.hdr, &pkt, sizeof(struct fw_pkt));
+ xfer->send.pay_len = uio->uio_resid;
+ if (uio->uio_resid > 0) {
+ if ((err =
+ uiomove((void *)xfer->send.payload, uio->uio_resid, uio)))
+ goto out;
+ }
+
+ xfer->fc = d->fc;
+ xfer->sc = NULL;
+ xfer->hand = fw_xferwake;
+ xfer->send.spd = 2 /* XXX */;
+
+ if ((err = fw_asyreq(xfer->fc, -1, xfer)))
+ goto out;
+
+ if ((err = fw_xferwait(xfer)))
+ goto out;
+
+ if (xfer->resp != 0) {
+ err = xfer->resp;
+ goto out;
+ }
- /* /dev/fwU.S */
- while (isdigit(*subp)) {
- sub *= 10;
- sub += *subp++ - '0';
+ if (xfer->flag == FWXF_RCVD) {
+ mutex_enter(&xfer->fc->fc_mtx);
+ STAILQ_INSERT_TAIL(&d->rq, xfer, link);
+ mutex_exit(&xfer->fc->fc_mtx);
+ return 0;
}
- if (*subp != '\0')
- return;
- sc = devclass_get_softc(firewire_devclass, unit);
- if (sc == NULL)
- return;
- *dev = make_dev(&firewire_cdevsw, MAKEMINOR(devflag[i], unit, sub),
- UID_ROOT, GID_OPERATOR, 0660,
- "%s%d.%d", devnames[i], unit, sub);
- dev_ref(*dev);
- (*dev)->si_flags |= SI_CHEAPCLONE;
- dev_depends(sc->dev, *dev);
- return;
+out:
+ fw_xfer_free(xfer);
+ return err;
+}
+
+static void
+fw_hand(struct fw_xfer *xfer)
+{
+ struct fw_bind *fwb;
+ struct fw_drv1 *d;
+
+ fwb = (struct fw_bind *)xfer->sc;
+ d = (struct fw_drv1 *)fwb->sc;
+ mutex_enter(&xfer->fc->fc_mtx);
+ STAILQ_INSERT_TAIL(&d->rq, xfer, link);
+ mutex_exit(&xfer->fc->fc_mtx);
+ wakeup(&d->rq);
}
-#endif
-#endif
diff --git a/sys/dev/ieee1394/fwdma.c b/sys/dev/ieee1394/fwdma.c
index dac1598db2e..7357d6f2d34 100644
--- a/sys/dev/ieee1394/fwdma.c
+++ b/sys/dev/ieee1394/fwdma.c
@@ -1,8 +1,8 @@
-/* $NetBSD: fwdma.c,v 1.12 2008/01/04 21:17:59 ad Exp $ */
+/* $NetBSD: fwdma.c,v 1.13 2010/03/29 03:05:27 kiyohara Exp $ */
/*-
* Copyright (c) 2003
* Hidetoshi Shimokawa. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +19,7 @@
* 4. Neither the name of the author 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 REGENTS 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
@@ -31,156 +31,112 @@
* 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: fwdma.c,v 1.12 2008/01/04 21:17:59 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fwdma.c,v 1.13 2010/03/29 03:05:27 kiyohara Exp $");
#if defined(__FreeBSD__)
__FBSDID("$FreeBSD: src/sys/dev/firewire/fwdma.c,v 1.9 2007/06/06 14:31:36 simokawa Exp $");
#endif
-#if defined(__FreeBSD__)
#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/types.h>
-#include <sys/kernel.h>
-#include <sys/conf.h>
-#include <sys/malloc.h>
-#if defined(__FreeBSD__) && __FreeBSD_version >= 501102
-#include <sys/mutex.h>
-#endif
-
#include <sys/bus.h>
-#include <sys/bus.h>
-
-#ifdef __DragonFly__
-#include <bus/firewire/fw_port.h>
-#include <bus/firewire/firewire.h>
-#include <bus/firewire/firewirereg.h>
-#include <bus/firewire/fwdma.h>
-#else
-#include <dev/firewire/fw_port.h>
-#include <dev/firewire/firewire.h>
-#include <dev/firewire/firewirereg.h>
-#include <dev/firewire/fwdma.h>
-#endif
-#elif defined(__NetBSD__)
-#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <sys/types.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/select.h>
-#include <sys/bus.h>
+#include <machine/vmparam.h>
-#include <dev/ieee1394/fw_port.h>
#include <dev/ieee1394/firewire.h>
#include <dev/ieee1394/firewirereg.h>
#include <dev/ieee1394/fwdma.h>
-#endif
-static void
-fwdma_map_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- bus_addr_t *baddr;
+#define BUS_SPACE_MAXSIZE_32BIT 0xffffffff
- if (error)
- printf("fwdma_map_cb: error=%d\n", error);
- baddr = (bus_addr_t *)arg;
- *baddr = segs->ds_addr;
-}
void *
-fwdma_malloc(struct firewire_comm *fc, int alignment, bus_size_t size,
- struct fwdma_alloc *dma, int flag)
+fwdma_malloc(device_t dev, bus_dma_tag_t dmat, bus_dmamap_t *dmamap,
+ bus_size_t size, int alignment, int flags)
{
+ bus_dma_segment_t segs;
+ int nsegs;
int err;
+ void *v_addr;
- dma->v_addr = NULL;
- err = fw_bus_dma_tag_create(
- /*parent*/ fc->dmat,
- /*alignment*/ alignment,
- /*boundary*/ 0,
- /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
- /*highaddr*/ BUS_SPACE_MAXADDR,
- /*filter*/NULL, /*filterarg*/NULL,
- /*maxsize*/ size,
- /*nsegments*/ 1,
- /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/ BUS_DMA_ALLOCNOW,
- /*lockfunc*/busdma_lock_mutex,
- /*lockarg*/FW_GMTX(fc),
- &dma->fw_dma_tag);
+ err = bus_dmamem_alloc(dmat, size, alignment, 0, &segs, 1,
+ &nsegs, flags);
if (err) {
- printf("fwdma_malloc: failed(1)\n");
- return(NULL);
+ aprint_error_dev(dev, "DMA memory allocation failed %d\n", err);
+ return NULL;
}
- err = fw_bus_dmamem_alloc(dma->fw_dma_tag, &dma->v_addr,
- flag, &dma->dma_map);
+ err = bus_dmamem_map(dmat, &segs, nsegs, size, &v_addr, flags);
if (err) {
- printf("fwdma_malloc: failed(2)\n");
- fw_bus_dma_tag_destroy(dma->fw_dma_tag);
- return(NULL);
+ aprint_error_dev(dev, "DMA memory map failed %d\n", err);
+ bus_dmamem_free(dmat, &segs, nsegs);
+ return NULL;
+ }
+
+ if (*dmamap == NULL) {
+ err = bus_dmamap_create(dmat, size, nsegs,
+ BUS_SPACE_MAXSIZE_32BIT, 0, flags, dmamap);
+ if (err) {
+ aprint_error_dev(dev,
+ "DMA map create failed %d\n", err);
+ bus_dmamem_unmap(dmat, v_addr, size);
+ bus_dmamem_free(dmat, &segs, nsegs);
+ return NULL;
+ }
}
- err = fw_bus_dmamap_load(dma->fw_dma_tag, dma->dma_map, dma->v_addr,
- size, fwdma_map_cb, &dma->bus_addr, flag);
+ err = bus_dmamap_load(dmat, *dmamap, v_addr, size, NULL, flags);
if (err != 0) {
- printf("fwdma_malloc: failed(3)\n");
- fw_bus_dmamem_free(dma->fw_dma_tag, dma->v_addr, dma->dma_map);
- fw_bus_dma_tag_destroy(dma->fw_dma_tag);
- return(NULL);
+ aprint_error_dev(dev, "DMA map load failed %d\n", err);
+ bus_dmamap_destroy(dmat, *dmamap);
+ bus_dmamem_unmap(dmat, v_addr, size);
+ bus_dmamem_free(dmat, &segs, nsegs);
+ return NULL;
}
- return(dma->v_addr);
+ return v_addr;
}
void
-fwdma_free(struct firewire_comm *fc, struct fwdma_alloc *dma)
+fwdma_free(bus_dma_tag_t dmat, bus_dmamap_t dmamap, void *vaddr)
{
- fw_bus_dmamap_unload(dma->fw_dma_tag, dma->dma_map);
- fw_bus_dmamem_free(dma->fw_dma_tag, dma->v_addr, dma->dma_map);
- fw_bus_dma_tag_destroy(dma->fw_dma_tag);
+
+ bus_dmamap_unload(dmat, dmamap);
+ bus_dmamem_unmap(dmat, vaddr, dmamap->dm_mapsize);
+ bus_dmamem_free(dmat, dmamap->dm_segs, dmamap->dm_nsegs);
+ bus_dmamap_destroy(dmat, dmamap);
}
void *
-fwdma_malloc_size(fw_bus_dma_tag_t dmat, bus_dmamap_t *dmamap,
- bus_size_t size, bus_addr_t *bus_addr, int flag)
+fwdma_alloc_setup(device_t dev, bus_dma_tag_t dmat, bus_size_t size,
+ struct fwdma_alloc *dma, int alignment, int flags)
{
- void *v_addr;
- if (fw_bus_dmamem_alloc(dmat, &v_addr, flag, dmamap)) {
- printf("fwdma_malloc_size: failed(1)\n");
- return(NULL);
+ dma->v_addr =
+ fwdma_malloc(dev, dmat, &dma->dma_map, size, alignment, flags);
+ if (dma->v_addr != NULL) {
+ dma->dma_tag = dmat;
+ dma->bus_addr = dma->dma_map->dm_segs[0].ds_addr;
}
- if (fw_bus_dmamap_load(dmat, *dmamap, v_addr, size,
- fwdma_map_cb, bus_addr, flag)) {
- printf("fwdma_malloc_size: failed(2)\n");
- fw_bus_dmamem_free(dmat, v_addr, *dmamap);
- return(NULL);
- }
- return(v_addr);
+ return dma->v_addr;
}
-void
-fwdma_free_size(fw_bus_dma_tag_t dmat, bus_dmamap_t dmamap, void *vaddr,
- bus_size_t size)
-{
- fw_bus_dmamap_unload(dmat, dmamap);
- fw_bus_dmamem_free(dmat, vaddr, dmamap);
-}
-
/*
* Allocate multisegment dma buffers
* each segment size is eqaul to ssize except last segment.
*/
struct fwdma_alloc_multi *
-fwdma_malloc_multiseg(struct firewire_comm *fc, int alignment,
- int esize, int n, int flag)
+fwdma_malloc_multiseg(struct firewire_comm *fc, int alignment, int esize, int n,
+ int flags)
{
struct fwdma_alloc_multi *am;
struct fwdma_seg *seg;
@@ -196,55 +152,32 @@ fwdma_malloc_multiseg(struct firewire_comm *fc, int alignment,
ssize = rounddown(PAGE_SIZE, esize);
nseg = howmany(n, ssize / esize);
}
- size = sizeof (struct fwdma_alloc_multi) +
- sizeof (struct fwdma_seg) * nseg;
+ size = sizeof(struct fwdma_alloc_multi) +
+ sizeof(struct fwdma_seg) * nseg;
am = (struct fwdma_alloc_multi *)malloc(size, M_FW, M_WAITOK);
if (am == NULL) {
- printf("fwdma_malloc_multiseg: malloc failed\n");
- return(NULL);
+ aprint_error_dev(fc->dev, "malloc failed\n");
+ return NULL;
}
memset(am, 0, size);
am->ssize = ssize;
am->esize = esize;
am->nseg = 0;
- if (fw_bus_dma_tag_create(
- /*parent*/ fc->dmat,
- /*alignment*/ alignment,
- /*boundary*/ 0,
- /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
- /*highaddr*/ BUS_SPACE_MAXADDR,
- /*filter*/NULL, /*filterarg*/NULL,
- /*maxsize*/ ssize,
- /*nsegments*/ 1,
- /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/ BUS_DMA_ALLOCNOW,
- /*lockfunc*/busdma_lock_mutex,
- /*lockarg*/FW_GMTX(fc),
- &am->fw_dma_tag)) {
- printf("fwdma_malloc_multiseg: tag_create failed\n");
- free(am, M_FW);
- return(NULL);
- }
+ am->dma_tag = fc->dmat;
-#if 0
-#if defined(__DragonFly__) || __FreeBSD_version < 500000
- printf("malloc_multi: ssize=%d nseg=%d\n", ssize, nseg);
-#else
- printf("malloc_multi: ssize=%td nseg=%d\n", ssize, nseg);
-#endif
-#endif
- for (seg = &am->seg[0]; nseg --; seg ++) {
- seg->v_addr = fwdma_malloc_size(am->fw_dma_tag, &seg->dma_map,
- ssize, &seg->bus_addr, flag);
+ for (seg = am->seg; nseg--; seg++) {
+ seg->v_addr = fwdma_malloc(fc->dev, am->dma_tag, &seg->dma_map,
+ ssize, alignment, flags);
if (seg->v_addr == NULL) {
- printf("fwdma_malloc_multi: malloc_size failed %d\n",
- am->nseg);
+ aprint_error_dev(fc->dev, "malloc_size failed %d\n",
+ am->nseg);
fwdma_free_multiseg(am);
- return(NULL);
+ return NULL;
}
+ seg->bus_addr = seg->dma_map->dm_segs[0].ds_addr;
am->nseg++;
}
- return(am);
+ return am;
}
void
@@ -252,10 +185,7 @@ fwdma_free_multiseg(struct fwdma_alloc_multi *am)
{
struct fwdma_seg *seg;
- for (seg = &am->seg[0]; am->nseg --; seg ++) {
- fwdma_free_size(am->fw_dma_tag, seg->dma_map,
- seg->v_addr, am->ssize);
- }
- fw_bus_dma_tag_destroy(am->fw_dma_tag);
+ for (seg = am->seg; am->nseg--; seg++)
+ fwdma_free(am->dma_tag, seg->dma_map, seg->v_addr);
free(am, M_FW);
}
diff --git a/sys/dev/ieee1394/fwdma.h b/sys/dev/ieee1394/fwdma.h
index e349db4b420..c558fea3256 100644
--- a/sys/dev/ieee1394/fwdma.h
+++ b/sys/dev/ieee1394/fwdma.h
@@ -1,8 +1,8 @@
-/* $NetBSD: fwdma.h,v 1.5 2007/03/04 06:02:05 christos Exp $ */
+/* $NetBSD: fwdma.h,v 1.6 2010/03/29 03:05:27 kiyohara Exp $ */
/*-
* Copyright (C) 2003
* Hidetoshi Shimokawa. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +19,7 @@
* 4. Neither the name of the author 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 REGENTS 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
@@ -31,12 +31,15 @@
* 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.
- *
+ *
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/fwdma.h,v 1.3 2005/01/06 01:42:41 imp Exp $
*/
+#ifndef _FWDMA_H_
+#define _FWDMA_H_
+
struct fwdma_alloc {
- fw_bus_dma_tag_t fw_dma_tag;
+ bus_dma_tag_t dma_tag;
bus_dmamap_t dma_map;
void * v_addr;
bus_addr_t bus_addr;
@@ -52,7 +55,7 @@ struct fwdma_alloc_multi {
bus_size_t ssize;
bus_size_t esize;
int nseg;
- fw_bus_dma_tag_t fw_dma_tag;
+ bus_dma_tag_t dma_tag;
struct fwdma_seg seg[0];
};
@@ -62,7 +65,7 @@ fwdma_v_addr(struct fwdma_alloc_multi *am, int index)
bus_size_t ssize = am->ssize;
int offset = am->esize * index;
- return ((char *)am->seg[offset / ssize].v_addr + (offset % ssize));
+ return (char *)am->seg[offset / ssize].v_addr + (offset % ssize);
}
static __inline bus_addr_t
@@ -71,44 +74,56 @@ fwdma_bus_addr(struct fwdma_alloc_multi *am, int index)
bus_size_t ssize = am->ssize;
int offset = am->esize * index;
- return (am->seg[offset / ssize].bus_addr + (offset % ssize));
+ return am->seg[offset / ssize].bus_addr + (offset % ssize);
}
static __inline void
-fwdma_sync(struct fwdma_alloc *dma, bus_dmasync_op_t op)
-{
- fw_bus_dmamap_sync(dma->fw_dma_tag, dma->dma_map, op);
-}
-
-static __inline void
-fwdma_sync_multiseg(struct fwdma_alloc_multi *am,
- int start, int end, bus_dmasync_op_t op)
+fwdma_sync_multiseg(struct fwdma_alloc_multi *am, int start, int end, int op)
{
struct fwdma_seg *seg, *eseg;
+ bus_addr_t off, eoff;
+ off = (am->esize * start) % am->ssize;
+ eoff = (am->esize * end) % am->ssize;
seg = &am->seg[am->esize * start / am->ssize];
eseg = &am->seg[am->esize * end / am->ssize];
- for (; seg <= eseg; seg ++)
- fw_bus_dmamap_sync(am->fw_dma_tag, seg->dma_map, op);
+
+ if (start > end) {
+ for (; seg < &am->seg[am->nseg]; seg++) {
+ bus_dmamap_sync(am->dma_tag, seg->dma_map,
+ off, seg->dma_map->dm_mapsize - off, op);
+ off = 0;
+ }
+ seg = am->seg;
+ }
+ for (; seg < eseg; seg++) {
+ bus_dmamap_sync(am->dma_tag, seg->dma_map,
+ off, seg->dma_map->dm_mapsize - off, op);
+ off = 0;
+ }
+ bus_dmamap_sync(am->dma_tag, seg->dma_map,
+ off, eoff - off + am->esize, op);
}
static __inline void
-fwdma_sync_multiseg_all(struct fwdma_alloc_multi *am, bus_dmasync_op_t op)
+fwdma_sync_multiseg_all(struct fwdma_alloc_multi *am, int op)
{
struct fwdma_seg *seg;
int i;
- seg = &am->seg[0];
+ seg = am->seg;
for (i = 0; i < am->nseg; i++, seg++)
- fw_bus_dmamap_sync(am->fw_dma_tag, seg->dma_map, op);
+ bus_dmamap_sync(am->dma_tag, seg->dma_map,
+ 0, seg->dma_map->dm_mapsize, op);
}
-void *fwdma_malloc(struct firewire_comm *, int, bus_size_t, struct fwdma_alloc *, int);
-void fwdma_free(struct firewire_comm *, struct fwdma_alloc *);
-void *fwdma_malloc_size(
- fw_bus_dma_tag_t, bus_dmamap_t *, bus_size_t, bus_addr_t *, int);
-void fwdma_free_size(fw_bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t);
+void *fwdma_malloc(device_t, bus_dma_tag_t, bus_dmamap_t *, bus_size_t, int,
+ int);
+void fwdma_free(bus_dma_tag_t, bus_dmamap_t, void *);
+void *fwdma_alloc_setup(device_t, bus_dma_tag_t, bus_size_t,
+ struct fwdma_alloc *, int, int);
struct fwdma_alloc_multi *fwdma_malloc_multiseg(struct firewire_comm *,
- int, int, int, int);
+ int, int, int, int);
void fwdma_free_multiseg(struct fwdma_alloc_multi *);
+#endif /* _FWDMA_H_ */
diff --git a/sys/dev/ieee1394/fwmem.c b/sys/dev/ieee1394/fwmem.c
index 74c691d881f..2bd9955945e 100644
--- a/sys/dev/ieee1394/fwmem.c
+++ b/sys/dev/ieee1394/fwmem.c
@@ -1,8 +1,8 @@
-/* $NetBSD: fwmem.c,v 1.11 2009/04/18 14:58:02 tsutsui Exp $ */
+/* $NetBSD: fwmem.c,v 1.12 2010/03/29 03:05:27 kiyohara Exp $ */
/*-
* Copyright (c) 2002-2003
* Hidetoshi Shimokawa. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +19,7 @@
* 4. Neither the name of the author 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 REGENTS 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
@@ -31,87 +31,38 @@
* 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: fwmem.c,v 1.11 2009/04/18 14:58:02 tsutsui Exp $");
-#if defined(__FreeBSD__)
-__FBSDID("$FreeBSD: src/sys/dev/firewire/fwmem.c,v 1.34 2007/06/06 14:31:36 simokawa Exp $");
-#endif
+__KERNEL_RCSID(0, "$NetBSD: fwmem.c,v 1.12 2010/03/29 03:05:27 kiyohara Exp $");
-#if defined(__FreeBSD__)
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/types.h>
-
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/conf.h>
-#include <sys/sysctl.h>
-#if defined(__DragonFly__) || __FreeBSD_version < 500000
-#include <sys/buf.h>
-#else
-#include <sys/bio.h>
-#endif
-
-#include <sys/bus.h>
-#include <sys/bus.h>
-
-#include <sys/signal.h>
-#include <sys/mman.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/ktr.h>
-
-#ifdef __DragonFly__
-#include "fw_port.h"
-#include "firewire.h"
-#include "firewirereg.h"
-#include "fwmem.h"
-#else
-#include <dev/firewire/fw_port.h>
-#include <dev/firewire/firewire.h>
-#include <dev/firewire/firewirereg.h>
-#include <dev/firewire/fwmem.h>
-#endif
-#elif defined(__NetBSD__)
#include <sys/param.h>
#include <sys/device.h>
#include <sys/errno.h>
#include <sys/buf.h>
+#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/fcntl.h>
#include <sys/malloc.h>
#include <sys/sysctl.h>
-#include <sys/bus.h>
-
-#include <dev/ieee1394/fw_port.h>
#include <dev/ieee1394/firewire.h>
#include <dev/ieee1394/firewirereg.h>
#include <dev/ieee1394/fwmem.h>
-#endif
+
+#include "ioconf.h"
static int fwmem_speed=2, fwmem_debug=0;
static struct fw_eui64 fwmem_eui64;
-#if defined(__FreeBSD__)
-SYSCTL_DECL(_hw_firewire);
-SYSCTL_NODE(_hw_firewire, OID_AUTO, fwmem, CTLFLAG_RD, 0,
- "FireWire Memory Access");
-SYSCTL_UINT(_hw_firewire_fwmem, OID_AUTO, eui64_hi, CTLFLAG_RW,
- &fwmem_eui64.hi, 0, "Fwmem target EUI64 high");
-SYSCTL_UINT(_hw_firewire_fwmem, OID_AUTO, eui64_lo, CTLFLAG_RW,
- &fwmem_eui64.lo, 0, "Fwmem target EUI64 low");
-SYSCTL_INT(_hw_firewire_fwmem, OID_AUTO, speed, CTLFLAG_RW, &fwmem_speed, 0,
- "Fwmem link speed");
-SYSCTL_INT(_debug, OID_AUTO, fwmem_debug, CTLFLAG_RW, &fwmem_debug, 0,
- "Fwmem driver debug flag");
-MALLOC_DEFINE(M_FWMEM, "fwmem", "fwmem/FireWire");
-#elif defined(__NetBSD__)
+
static int sysctl_fwmem_verify(SYSCTLFN_PROTO, int, int);
static int sysctl_fwmem_verify_speed(SYSCTLFN_PROTO);
+static struct fw_xfer *fwmem_xfer_req(struct fw_device *, void *, int, int,
+ int, void *);
+static void fwmem_biodone(struct fw_xfer *);
+
/*
* Setup sysctl(3) MIB, hw.fwmem.*
*
@@ -187,24 +138,24 @@ sysctl_fwmem_verify(SYSCTLFN_ARGS, int lower, int upper)
node.sysctl_data = &t;
error = sysctl_lookup(SYSCTLFN_CALL(&node));
if (error || newp == NULL)
- return (error);
+ return error;
if (t < lower || t > upper)
- return (EINVAL);
+ return EINVAL;
*(int*)rnode->sysctl_data = t;
- return (0);
+ return 0;
}
-static int
+static int
sysctl_fwmem_verify_speed(SYSCTLFN_ARGS)
{
- return (sysctl_fwmem_verify(SYSCTLFN_CALL(rnode), 0, FWSPD_S400));
+
+ return sysctl_fwmem_verify(SYSCTLFN_CALL(rnode), 0, FWSPD_S400);
}
MALLOC_DEFINE(M_FWMEM, "fwmem", "fwmem/IEEE1394");
-#endif
#define MAXLEN (512 << fwmem_speed)
@@ -215,52 +166,175 @@ struct fwmem_softc {
STAILQ_HEAD(, fw_xfer) xferlist;
};
-static struct fw_xfer *
-fwmem_xfer_req(
- struct fw_device *fwdev,
- void *sc,
- int spd,
- int slen,
- int rlen,
- void *hand)
+
+int
+fwmem_open(dev_t dev, int flags, int fmt, struct lwp *td)
{
+ struct firewire_softc *sc;
+ struct fwmem_softc *fms;
struct fw_xfer *xfer;
- xfer = fw_xfer_alloc(M_FWMEM);
- if (xfer == NULL)
- return NULL;
+ sc = device_lookup_private(&ieee1394if_cd, DEV2UNIT(dev));
+ if (sc == NULL)
+ return ENXIO;
- xfer->fc = fwdev->fc;
- xfer->send.hdr.mode.hdr.dst = FWLOCALBUS | fwdev->dst;
- if (spd < 0)
- xfer->send.spd = fwdev->speed;
- else
- xfer->send.spd = min(spd, fwdev->speed);
- xfer->hand = hand;
- xfer->sc = sc;
- xfer->send.pay_len = slen;
- xfer->recv.pay_len = rlen;
+ if (sc->si_drv1 != NULL) {
+ if ((flags & FWRITE) != 0) {
+ return EBUSY;
+ }
+ fms = (struct fwmem_softc *)sc->si_drv1;
+ fms->refcount++;
+ } else {
+ sc->si_drv1 = (void *)-1;
+ sc->si_drv1 = malloc(sizeof(struct fwmem_softc),
+ M_FWMEM, M_WAITOK);
+ if (sc->si_drv1 == NULL)
+ return ENOMEM;
+ fms = (struct fwmem_softc *)sc->si_drv1;
+ memcpy(&fms->eui, &fwmem_eui64, sizeof(struct fw_eui64));
+ fms->sc = sc;
+ fms->refcount = 1;
+ STAILQ_INIT(&fms->xferlist);
+ xfer = fw_xfer_alloc(M_FWMEM);
+ STAILQ_INSERT_TAIL(&fms->xferlist, xfer, link);
+ }
+ if (fwmem_debug)
+ printf("%s: refcount=%d\n", __func__, fms->refcount);
- return xfer;
+ return 0;
+}
+
+int
+fwmem_close(dev_t dev, int flags, int fmt, struct lwp *td)
+{
+ struct firewire_softc *sc;
+ struct fwmem_softc *fms;
+ struct fw_xfer *xfer;
+
+ sc = device_lookup_private(&ieee1394if_cd, DEV2UNIT(dev));
+ if (sc == NULL)
+ return ENXIO;
+
+ fms = (struct fwmem_softc *)sc->si_drv1;
+
+ fms->refcount--;
+ if (fwmem_debug)
+ printf("%s: refcount=%d\n", __func__, fms->refcount);
+ if (fms->refcount < 1) {
+ while ((xfer = STAILQ_FIRST(&fms->xferlist)) != NULL) {
+ STAILQ_REMOVE_HEAD(&fms->xferlist, link);
+ fw_xfer_free(xfer);
+ }
+ free(sc->si_drv1, M_FW);
+ sc->si_drv1 = NULL;
+ }
+
+ return 0;
+}
+
+void
+fwmem_strategy(struct bio *bp)
+{
+ struct firewire_softc *sc;
+ struct fwmem_softc *fms;
+ struct fw_device *fwdev;
+ struct fw_xfer *xfer;
+ dev_t dev = bp->bio_dev;
+ int iolen, err = 0, s;
+
+ sc = device_lookup_private(&ieee1394if_cd, DEV2UNIT(dev));
+ if (sc == NULL)
+ return;
+
+ /* XXX check request length */
+
+ s = splvm();
+ fms = (struct fwmem_softc *)sc->si_drv1;
+ fwdev = fw_noderesolve_eui64(fms->sc->fc, &fms->eui);
+ if (fwdev == NULL) {
+ if (fwmem_debug)
+ printf("fwmem: no such device ID:%08x%08x\n",
+ fms->eui.hi, fms->eui.lo);
+ err = EINVAL;
+ goto error;
+ }
+
+ iolen = MIN(bp->bio_bcount, MAXLEN);
+ if ((bp->bio_cmd & BIO_READ) == BIO_READ) {
+ if (iolen == 4 && (bp->bio_offset & 3) == 0)
+ xfer = fwmem_read_quad(fwdev, (void *) bp, fwmem_speed,
+ bp->bio_offset >> 32, bp->bio_offset & 0xffffffff,
+ bp->bio_data, fwmem_biodone);
+ else
+ xfer = fwmem_read_block(fwdev, (void *) bp, fwmem_speed,
+ bp->bio_offset >> 32, bp->bio_offset & 0xffffffff,
+ iolen, bp->bio_data, fwmem_biodone);
+ } else {
+ if (iolen == 4 && (bp->bio_offset & 3) == 0)
+ xfer = fwmem_write_quad(fwdev, (void *)bp, fwmem_speed,
+ bp->bio_offset >> 32, bp->bio_offset & 0xffffffff,
+ bp->bio_data, fwmem_biodone);
+ else
+ xfer = fwmem_write_block(fwdev, (void *)bp, fwmem_speed,
+ bp->bio_offset >> 32, bp->bio_offset & 0xffffffff,
+ iolen, bp->bio_data, fwmem_biodone);
+ }
+ if (xfer == NULL) {
+ err = EIO;
+ goto error;
+ }
+ /* XXX */
+ bp->bio_resid = bp->bio_bcount - iolen;
+error:
+ splx(s);
+ if (err != 0) {
+ if (fwmem_debug)
+ printf("%s: err=%d\n", __func__, err);
+ bp->bio_error = err;
+ bp->bio_resid = bp->bio_bcount;
+ biodone(bp);
+ }
+}
+
+int
+fwmem_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *td)
+{
+ struct firewire_softc *sc;
+ struct fwmem_softc *fms;
+ int err = 0;
+
+ sc = device_lookup_private(&ieee1394if_cd, DEV2UNIT(dev));
+ if (sc == NULL)
+ return ENXIO;
+
+ fms = (struct fwmem_softc *)sc->si_drv1;
+ switch (cmd) {
+ case FW_SDEUI64:
+ memcpy(&fms->eui, data, sizeof(struct fw_eui64));
+ break;
+
+ case FW_GDEUI64:
+ memcpy(data, &fms->eui, sizeof(struct fw_eui64));
+ break;
+
+ default:
+ err = EINVAL;
+ }
+ return err;
}
+
struct fw_xfer *
-fwmem_read_quad(
- struct fw_device *fwdev,
- void * sc,
- uint8_t spd,
- uint16_t dst_hi,
- uint32_t dst_lo,
- void *data,
- void (*hand)(struct fw_xfer *))
+fwmem_read_quad(struct fw_device *fwdev, void * sc, uint8_t spd,
+ uint16_t dst_hi, uint32_t dst_lo, void *data,
+ void (*hand)(struct fw_xfer *))
{
struct fw_xfer *xfer;
struct fw_pkt *fp;
xfer = fwmem_xfer_req(fwdev, (void *)sc, spd, 0, 4, hand);
- if (xfer == NULL) {
+ if (xfer == NULL)
return NULL;
- }
fp = &xfer->send.hdr;
fp->mode.rreqq.tcode = FWTCODE_RREQQ;
@@ -271,8 +345,8 @@ fwmem_read_quad(
xfer->recv.payload = (uint32_t *)data;
if (fwmem_debug)
- printf("fwmem_read_quad: %d %04x:%08x\n", fwdev->dst,
- dst_hi, dst_lo);
+ aprint_error("fwmem_read_quad: %d %04x:%08x\n",
+ fwdev->dst, dst_hi, dst_lo);
if (fw_asyreq(xfer->fc, -1, xfer) == 0)
return xfer;
@@ -282,14 +356,9 @@ fwmem_read_quad(
}
struct fw_xfer *
-fwmem_write_quad(
- struct fw_device *fwdev,
- void * sc,
- uint8_t spd,
- uint16_t dst_hi,
- uint32_t dst_lo,
- void *data,
- void (*hand)(struct fw_xfer *))
+fwmem_write_quad(struct fw_device *fwdev, void *sc, uint8_t spd,
+ uint16_t dst_hi, uint32_t dst_lo, void *data,
+ void (*hand)(struct fw_xfer *))
{
struct fw_xfer *xfer;
struct fw_pkt *fp;
@@ -307,8 +376,8 @@ fwmem_write_quad(
xfer->send.payload = xfer->recv.payload = NULL;
if (fwmem_debug)
- printf("fwmem_write_quad: %d %04x:%08x %08x\n", fwdev->dst,
- dst_hi, dst_lo, *(uint32_t *)data);
+ aprint_error("fwmem_write_quad: %d %04x:%08x %08x\n",
+ fwdev->dst, dst_hi, dst_lo, *(uint32_t *)data);
if (fw_asyreq(xfer->fc, -1, xfer) == 0)
return xfer;
@@ -318,19 +387,13 @@ fwmem_write_quad(
}
struct fw_xfer *
-fwmem_read_block(
- struct fw_device *fwdev,
- void * sc,
- uint8_t spd,
- uint16_t dst_hi,
- uint32_t dst_lo,
- int len,
- void *data,
- void (*hand)(struct fw_xfer *))
+fwmem_read_block(struct fw_device *fwdev, void *sc, uint8_t spd,
+ uint16_t dst_hi, uint32_t dst_lo, int len, void *data,
+ void (*hand)(struct fw_xfer *))
{
struct fw_xfer *xfer;
struct fw_pkt *fp;
-
+
xfer = fwmem_xfer_req(fwdev, sc, spd, 0, roundup2(len, 4), hand);
if (xfer == NULL)
return NULL;
@@ -346,8 +409,8 @@ fwmem_read_block(
xfer->recv.payload = data;
if (fwmem_debug)
- printf("fwmem_read_block: %d %04x:%08x %d\n", fwdev->dst,
- dst_hi, dst_lo, len);
+ aprint_error("fwmem_read_block: %d %04x:%08x %d\n",
+ fwdev->dst, dst_hi, dst_lo, len);
if (fw_asyreq(xfer->fc, -1, xfer) == 0)
return xfer;
@@ -356,15 +419,9 @@ fwmem_read_block(
}
struct fw_xfer *
-fwmem_write_block(
- struct fw_device *fwdev,
- void * sc,
- uint8_t spd,
- uint16_t dst_hi,
- uint32_t dst_lo,
- int len,
- void *data,
- void (*hand)(struct fw_xfer *))
+fwmem_write_block(struct fw_device *fwdev, void *sc, uint8_t spd,
+ uint16_t dst_hi, uint32_t dst_lo, int len, void *data,
+ void (*hand)(struct fw_xfer *))
{
struct fw_xfer *xfer;
struct fw_pkt *fp;
@@ -384,8 +441,8 @@ fwmem_write_block(
xfer->recv.payload = NULL;
if (fwmem_debug)
- printf("fwmem_write_block: %d %04x:%08x %d\n", fwdev->dst,
- dst_hi, dst_lo, len);
+ aprint_error("fwmem_write_block: %d %04x:%08x %d\n",
+ fwdev->dst, dst_hi, dst_lo, len);
if (fw_asyreq(xfer->fc, -1, xfer) == 0)
return xfer;
@@ -394,68 +451,30 @@ fwmem_write_block(
}
-FW_OPEN(fwmem)
-{
- struct fwmem_softc *fms;
- struct fw_xfer *xfer;
- FW_OPEN_START;
-
- if (dev->si_drv1 != NULL) {
- if ((flags & FWRITE) != 0) {
- FW_GUNLOCK(sc->fc);
- return (EBUSY);
- }
- FW_GUNLOCK(sc->fc);
- fms = (struct fwmem_softc *)dev->si_drv1;
- fms->refcount ++;
- } else {
- dev->si_drv1 = (void *)-1;
- FW_GUNLOCK(sc->fc);
- dev->si_drv1 = malloc(sizeof(struct fwmem_softc),
- M_FWMEM, M_WAITOK);
- if (dev->si_drv1 == NULL)
- return ENOMEM;
- dev->si_iosize_max = DFLTPHYS;
- fms = (struct fwmem_softc *)dev->si_drv1;
- memcpy(&fms->eui, &fwmem_eui64, sizeof(struct fw_eui64));
- fms->sc = sc;
- fms->refcount = 1;
- STAILQ_INIT(&fms->xferlist);
- xfer = fw_xfer_alloc(M_FWMEM);
- STAILQ_INSERT_TAIL(&fms->xferlist, xfer, link);
- }
- if (fwmem_debug)
- printf("%s: refcount=%d\n", __func__, fms->refcount);
-
- return (0);
-}
-
-FW_CLOSE(fwmem)
+static struct fw_xfer *
+fwmem_xfer_req(struct fw_device *fwdev, void *sc, int spd, int slen, int rlen,
+ void *hand)
{
- struct fwmem_softc *fms;
struct fw_xfer *xfer;
- FW_CLOSE_START;
- fms = (struct fwmem_softc *)dev->si_drv1;
+ xfer = fw_xfer_alloc(M_FWMEM);
+ if (xfer == NULL)
+ return NULL;
- FW_GLOCK(fms->sc->fc);
- fms->refcount --;
- FW_GUNLOCK(fms->sc->fc);
- if (fwmem_debug)
- printf("%s: refcount=%d\n", __func__, fms->refcount);
- if (fms->refcount < 1) {
- while ((xfer = STAILQ_FIRST(&fms->xferlist)) != NULL) {
- STAILQ_REMOVE_HEAD(&fms->xferlist, link);
- fw_xfer_free(xfer);
- }
- free(dev->si_drv1, M_FW);
- dev->si_drv1 = NULL;
- }
+ xfer->fc = fwdev->fc;
+ xfer->send.hdr.mode.hdr.dst = FWLOCALBUS | fwdev->dst;
+ if (spd < 0)
+ xfer->send.spd = fwdev->speed;
+ else
+ xfer->send.spd = min(spd, fwdev->speed);
+ xfer->hand = hand;
+ xfer->sc = sc;
+ xfer->send.pay_len = slen;
+ xfer->recv.pay_len = rlen;
- return (0);
+ return xfer;
}
-
static void
fwmem_biodone(struct fw_xfer *xfer)
{
@@ -470,104 +489,6 @@ fwmem_biodone(struct fw_xfer *xfer)
bp->bio_resid = bp->bio_bcount;
}
- CTR0(KTR_DEV, "biodone0");
fw_xfer_free(xfer);
- CTR0(KTR_DEV, "biodone1");
biodone(bp);
- CTR0(KTR_DEV, "biodone2");
-}
-
-void
-fwmem_strategy(struct bio *bp)
-{
- FW_STRATEGY_START;
- struct fwmem_softc *fms;
- struct fw_device *fwdev;
- struct fw_xfer *xfer;
- int err = 0, s, iolen;
-
- CTR0(KTR_DEV, "strategy");
-
- /* XXX check request length */
-
- s = splfw();
- fms = (struct fwmem_softc *)dev->si_drv1;
- fwdev = fw_noderesolve_eui64(fms->sc->fc, &fms->eui);
- if (fwdev == NULL) {
- if (fwmem_debug)
- printf("fwmem: no such device ID:%08x%08x\n",
- fms->eui.hi, fms->eui.lo);
- err = EINVAL;
- goto error;
- }
-
- iolen = MIN(bp->bio_bcount, MAXLEN);
- if ((bp->bio_cmd & BIO_READ) == BIO_READ) {
- if (iolen == 4 && (bp->bio_offset & 3) == 0)
- xfer = fwmem_read_quad(fwdev,
- (void *) bp, fwmem_speed,
- bp->bio_offset >> 32, bp->bio_offset & 0xffffffff,
- bp->bio_data, fwmem_biodone);
- else
- xfer = fwmem_read_block(fwdev,
- (void *) bp, fwmem_speed,
- bp->bio_offset >> 32, bp->bio_offset & 0xffffffff,
- iolen, bp->bio_data, fwmem_biodone);
- } else {
- if (iolen == 4 && (bp->bio_offset & 3) == 0)
- xfer = fwmem_write_quad(fwdev,
- (void *)bp, fwmem_speed,
- bp->bio_offset >> 32, bp->bio_offset & 0xffffffff,
- bp->bio_data, fwmem_biodone);
- else
- xfer = fwmem_write_block(fwdev,
- (void *)bp, fwmem_speed,
- bp->bio_offset >> 32, bp->bio_offset & 0xffffffff,
- iolen, bp->bio_data, fwmem_biodone);
- }
- if (xfer == NULL) {
- err = EIO;
- goto error;
- }
- /* XXX */
- bp->bio_resid = bp->bio_bcount - iolen;
-error:
- splx(s);
- if (err != 0) {
- if (fwmem_debug)
- printf("%s: err=%d\n", __func__, err);
- bp->bio_error = err;
- bp->bio_resid = bp->bio_bcount;
- biodone(bp);
- }
-}
-
-FW_IOCTL(fwmem)
-{
- FW_IOCTL_START;
- struct fwmem_softc *fms;
- int err = 0;
-
- fms = (struct fwmem_softc *)dev->si_drv1;
- switch (cmd) {
- case FW_SDEUI64:
- memcpy(&fms->eui, data, sizeof(struct fw_eui64));
- break;
- case FW_GDEUI64:
- memcpy(data, &fms->eui, sizeof(struct fw_eui64));
- break;
- default:
- err = EINVAL;
- }
- return(err);
-}
-
-FW_POLL(fwmem)
-{
- return EINVAL;
-}
-
-FW_MMAP(fwmem)
-{
- return EINVAL;
}
diff --git a/sys/dev/ieee1394/fwmem.h b/sys/dev/ieee1394/fwmem.h
index 1bb0094e19a..ca9aee2b699 100644
--- a/sys/dev/ieee1394/fwmem.h
+++ b/sys/dev/ieee1394/fwmem.h
@@ -1,8 +1,8 @@
-/* $NetBSD: fwmem.h,v 1.3 2007/03/04 06:02:05 christos Exp $ */
+/* $NetBSD: fwmem.h,v 1.4 2010/03/29 03:05:27 kiyohara Exp $ */
/*-
* Copyright (C) 2002-2003
* Hidetoshi Shimokawa. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +19,7 @@
* 4. Neither the name of the author 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 REGENTS 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
@@ -31,35 +31,26 @@
* 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.
- *
+ *
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/fwmem.h,v 1.8 2005/01/06 01:42:41 imp Exp $
*/
+#ifndef _FWMEM_H_
+#define _FWMEM_H_
-struct fw_xfer *fwmem_read_quad(struct fw_device *, void *, uint8_t,
- uint16_t, uint32_t, void *, void (*)(struct fw_xfer *));
-struct fw_xfer *fwmem_write_quad(struct fw_device *, void *, uint8_t,
- uint16_t, uint32_t, void *, void (*)(struct fw_xfer *));
-struct fw_xfer *fwmem_read_block(struct fw_device *, void *, uint8_t,
- uint16_t, uint32_t, int, void *, void (*)(struct fw_xfer *));
-struct fw_xfer *fwmem_write_block(struct fw_device *, void *, uint8_t,
- uint16_t, uint32_t, int, void *, void (*)(struct fw_xfer *));
+struct fw_xfer *fwmem_read_quad(struct fw_device *, void *, uint8_t, uint16_t,
+ uint32_t, void *, void (*)(struct fw_xfer *));
+struct fw_xfer *fwmem_write_quad(struct fw_device *, void *, uint8_t, uint16_t,
+ uint32_t, void *, void (*)(struct fw_xfer *));
+struct fw_xfer *fwmem_read_block(struct fw_device *, void *, uint8_t, uint16_t,
+ uint32_t, int, void *,
+ void (*)(struct fw_xfer *));
+struct fw_xfer *fwmem_write_block(struct fw_device *, void *, uint8_t, uint16_t,
+ uint32_t, int, void *,
+ void (*)(struct fw_xfer *));
-#if defined(__FreeBSD__)
-d_open_t fwmem_open;
-d_close_t fwmem_close;
-d_ioctl_t fwmem_ioctl;
-d_read_t fwmem_read;
-d_write_t fwmem_write;
-d_poll_t fwmem_poll;
-d_mmap_t fwmem_mmap;
-d_strategy_t fwmem_strategy;
-#elif defined(__NetBSD__)
dev_type_open(fwmem_open);
dev_type_close(fwmem_close);
dev_type_ioctl(fwmem_ioctl);
-dev_type_read(fwmem_read);
-dev_type_write(fwmem_write);
-dev_type_poll(fwmem_poll);
-dev_type_mmap(fwmem_mmap);
dev_type_strategy(fwmem_strategy);
-#endif
+
+#endif /* _FWMEM_H_ */
diff --git a/sys/dev/ieee1394/fwohci.c b/sys/dev/ieee1394/fwohci.c
index 695d5ee1ae5..5e561951bc2 100644
--- a/sys/dev/ieee1394/fwohci.c
+++ b/sys/dev/ieee1394/fwohci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fwohci.c,v 1.120 2009/04/18 14:58:02 tsutsui Exp $ */
+/* $NetBSD: fwohci.c,v 1.121 2010/03/29 03:05:27 kiyohara Exp $ */
/*-
* Copyright (c) 2003 Hidetoshi Shimokawa
@@ -33,57 +33,15 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: src/sys/dev/firewire/fwohci.c,v 1.93 2007/06/08 09:04:30 simokawa Exp $
+ * $FreeBSD: src/sys/dev/firewire/fwohci.c,v 1.98 2009/02/13 17:44:07 sbruno Exp $
*
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.120 2009/04/18 14:58:02 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.121 2010/03/29 03:05:27 kiyohara Exp $");
-#define ATRQ_CH 0
-#define ATRS_CH 1
-#define ARRQ_CH 2
-#define ARRS_CH 3
-#define ITX_CH 4
-#define IRX_CH 0x24
-
-#if defined(__FreeBSD__)
#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/malloc.h>
-#include <sys/sockio.h>
-#include <sys/sysctl.h>
+#include <sys/atomic.h>
#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/conf.h>
-#include <sys/endian.h>
-#include <sys/kdb.h>
-
-#include <machine/bus.h>
-
-#if defined(__DragonFly__) || __FreeBSD_version < 500000
-#include <machine/clock.h> /* for DELAY() */
-#endif
-
-#ifdef __DragonFly__
-#include "fw_port.h"
-#include "firewire.h"
-#include "firewirereg.h"
-#include "fwdma.h"
-#include "fwohcireg.h"
-#include "fwohcivar.h"
-#include "firewire_phy.h"
-#else
-#include <dev/firewire/fw_port.h>
-#include <dev/firewire/firewire.h>
-#include <dev/firewire/firewirereg.h>
-#include <dev/firewire/fwdma.h>
-#include <dev/firewire/fwohcireg.h>
-#include <dev/firewire/fwohcivar.h>
-#include <dev/firewire/firewire_phy.h>
-#endif
-#elif defined(__NetBSD__)
-#include <sys/param.h>
#include <sys/device.h>
#include <sys/errno.h>
#include <sys/conf.h>
@@ -92,12 +50,10 @@ __KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.120 2009/04/18 14:58:02 tsutsui Exp $")
#include <sys/mbuf.h>
#include <sys/proc.h>
#include <sys/reboot.h>
+#include <sys/select.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
-#include <sys/bus.h>
-
-#include <dev/ieee1394/fw_port.h>
#include <dev/ieee1394/firewire.h>
#include <dev/ieee1394/firewirereg.h>
#include <dev/ieee1394/fwdma.h>
@@ -106,20 +62,11 @@ __KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.120 2009/04/18 14:58:02 tsutsui Exp $")
#include <dev/ieee1394/firewire_phy.h>
#include "ioconf.h"
-#endif
#undef OHCI_DEBUG
static int nocyclemaster = 0;
int firewire_phydma_enable = 1;
-#if defined(__FreeBSD__)
-SYSCTL_DECL(_hw_firewire);
-SYSCTL_INT(_hw_firewire, OID_AUTO, nocyclemaster, CTLFLAG_RW, &nocyclemaster, 0,
- "Do not send cycle start packets");
-SYSCTL_INT(_hw_firewire, OID_AUTO, phydma_enable, CTLFLAG_RW,
- &firewire_phydma_enable, 1, "Allow physical request DMA from firewire");
-TUNABLE_INT("hw.firewire.phydma_enable", &firewire_phydma_enable);
-#elif defined(__NetBSD__)
/*
* Setup sysctl(3) MIB, hw.fwohci.*
*
@@ -164,94 +111,113 @@ SYSCTL_SETUP(sysctl_fwohci, "sysctl fwohci(4) subtree setup")
return;
err:
- printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
+ aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
}
-#endif
-static const char * const dbcode[16] = {"OUTM", "OUTL","INPM","INPL",
- "STOR","LOAD","NOP ","STOP",
- "", "", "", "", "", "", "", ""};
+static const char * const dbcode[16] = {
+ "OUTM", "OUTL", "INPM", "INPL", "STOR", "LOAD", "NOP ", "STOP",
+ "", "", "", "", "", "", "", ""
+};
-static const char * const dbkey[8] = {"ST0", "ST1","ST2","ST3",
- "UNDEF","REG","SYS","DEV"};
-static const char * const dbcond[4] = {"NEV","C=1", "C=0", "ALL"};
+static const char * const dbkey[8] = {
+ "ST0", "ST1", "ST2", "ST3", "UNDEF", "REG", "SYS", "DEV"
+};
+
+static const char * const dbcond[4] = { "NEV", "C=1", "C=0", "ALL" };
static const char * const fwohcicode[32] = {
- "No stat","Undef","long","miss Ack err",
- "FIFO underrun","FIFO overrun","desc err", "data read err",
- "data write err","bus reset","timeout","tcode err",
- "Undef","Undef","unknown event","flushed",
- "Undef","ack complete","ack pend","Undef",
- "ack busy_X","ack busy_A","ack busy_B","Undef",
- "Undef","Undef","Undef","ack tardy",
- "Undef","ack data_err","ack type_err",""};
+ "No stat", "Undef", "long", "miss Ack err",
+ "FIFO underrun","FIFO overrun", "desc err", "data read err",
+ "data write err","bus reset", "timeout", "tcode err",
+ "Undef", "Undef", "unknown event","flushed",
+ "Undef", "ack complete", "ack pend", "Undef",
+ "ack busy_X", "ack busy_A", "ack busy_B", "Undef",
+ "Undef", "Undef", "Undef", "ack tardy",
+ "Undef", "ack data_err", "ack type_err", ""
+};
#define MAX_SPEED 3
extern const char *fw_linkspeed[];
-static uint32_t const tagbit[4] = { 1 << 28, 1 << 29, 1 << 30, 1 << 31};
+static uint32_t const tagbit[4] = { 1 << 28, 1 << 29, 1 << 30, 1 << 31 };
static const struct tcode_info tinfo[] = {
-/* hdr_len block flag valid_response*/
-/* 0 WREQQ */ {16, FWTI_REQ | FWTI_TLABEL, FWTCODE_WRES},
-/* 1 WREQB */ {16, FWTI_REQ | FWTI_TLABEL | FWTI_BLOCK_ASY, FWTCODE_WRES},
-/* 2 WRES */ {12, FWTI_RES, 0xff},
-/* 3 XXX */ { 0, 0, 0xff},
-/* 4 RREQQ */ {12, FWTI_REQ | FWTI_TLABEL, FWTCODE_RRESQ},
-/* 5 RREQB */ {16, FWTI_REQ | FWTI_TLABEL, FWTCODE_RRESB},
-/* 6 RRESQ */ {16, FWTI_RES, 0xff},
-/* 7 RRESB */ {16, FWTI_RES | FWTI_BLOCK_ASY, 0xff},
-/* 8 CYCS */ { 0, 0, 0xff},
-/* 9 LREQ */ {16, FWTI_REQ | FWTI_TLABEL | FWTI_BLOCK_ASY, FWTCODE_LRES},
-/* a STREAM */ { 4, FWTI_REQ | FWTI_BLOCK_STR, 0xff},
-/* b LRES */ {16, FWTI_RES | FWTI_BLOCK_ASY, 0xff},
-/* c XXX */ { 0, 0, 0xff},
-/* d XXX */ { 0, 0, 0xff},
-/* e PHY */ {12, FWTI_REQ, 0xff},
-/* f XXX */ { 0, 0, 0xff}
+/* hdr_len block flag valid_response */
+/* 0 WREQQ */ { 16, FWTI_REQ | FWTI_TLABEL, FWTCODE_WRES },
+/* 1 WREQB */ { 16, FWTI_REQ | FWTI_TLABEL | FWTI_BLOCK_ASY, FWTCODE_WRES },
+/* 2 WRES */ { 12, FWTI_RES, 0xff },
+/* 3 XXX */ { 0, 0, 0xff },
+/* 4 RREQQ */ { 12, FWTI_REQ | FWTI_TLABEL, FWTCODE_RRESQ },
+/* 5 RREQB */ { 16, FWTI_REQ | FWTI_TLABEL, FWTCODE_RRESB },
+/* 6 RRESQ */ { 16, FWTI_RES, 0xff },
+/* 7 RRESB */ { 16, FWTI_RES | FWTI_BLOCK_ASY, 0xff },
+/* 8 CYCS */ { 0, 0, 0xff },
+/* 9 LREQ */ { 16, FWTI_REQ | FWTI_TLABEL | FWTI_BLOCK_ASY, FWTCODE_LRES },
+/* a STREAM */ { 4, FWTI_REQ | FWTI_BLOCK_STR, 0xff },
+/* b LRES */ { 16, FWTI_RES | FWTI_BLOCK_ASY, 0xff },
+/* c XXX */ { 0, 0, 0xff },
+/* d XXX */ { 0, 0, 0xff },
+/* e PHY */ { 12, FWTI_REQ, 0xff },
+/* f XXX */ { 0, 0, 0xff }
};
#define OHCI_WRITE_SIGMASK 0xffff0000
#define OHCI_READ_SIGMASK 0xffff0000
-#define OWRITE(sc, r, x) bus_space_write_4((sc)->bst, (sc)->bsh, (r), (x))
-#define OREAD(sc, r) bus_space_read_4((sc)->bst, (sc)->bsh, (r))
-
-static void fwohci_ibr (struct firewire_comm *);
-static void fwohci_db_init (struct fwohci_softc *, struct fwohci_dbch *);
-static void fwohci_db_free (struct fwohci_dbch *);
-static void fwohci_arcv (struct fwohci_softc *, struct fwohci_dbch *, int);
-static void fwohci_txd (struct fwohci_softc *, struct fwohci_dbch *);
-static void fwohci_start_atq (struct firewire_comm *);
-static void fwohci_start_ats (struct firewire_comm *);
-static void fwohci_start (struct fwohci_softc *, struct fwohci_dbch *);
-static uint32_t fwphy_wrdata ( struct fwohci_softc *, uint32_t, uint32_t);
-static uint32_t fwphy_rddata ( struct fwohci_softc *, uint32_t);
-static int fwohci_rx_enable (struct fwohci_softc *, struct fwohci_dbch *);
-static int fwohci_tx_enable (struct fwohci_softc *, struct fwohci_dbch *);
-static int fwohci_irx_enable (struct firewire_comm *, int);
-static int fwohci_irx_disable (struct firewire_comm *, int);
+
+int fwohci_print(void *, const char *);
+
+static int fwohci_ioctl(dev_t, u_long, void *, int, struct lwp *);
+
+static uint32_t fwohci_cyctimer(struct firewire_comm *);
+static uint32_t fwohci_set_bus_manager(struct firewire_comm *, u_int);
+static void fwohci_ibr(struct firewire_comm *);
+static int fwohci_irx_enable(struct firewire_comm *, int);
+static int fwohci_irx_disable(struct firewire_comm *, int);
+static int fwohci_itxbuf_enable(struct firewire_comm *, int);
+static int fwohci_itx_disable(struct firewire_comm *, int);
+static void fwohci_timeout(struct firewire_comm *fc);
#if BYTE_ORDER == BIG_ENDIAN
-static void fwohci_irx_post (struct firewire_comm *, uint32_t *);
+static void fwohci_irx_post(struct firewire_comm *, uint32_t *);
#endif
-static int fwohci_itxbuf_enable (struct firewire_comm *, int);
-static int fwohci_itx_disable (struct firewire_comm *, int);
-static void fwohci_timeout (void *);
-static void fwohci_set_intr (struct firewire_comm *, int);
-
-static int fwohci_add_rx_buf (struct fwohci_dbch *, struct fwohcidb_tr *, int, struct fwdma_alloc *);
-static int fwohci_add_tx_buf (struct fwohci_dbch *, struct fwohcidb_tr *, int);
-static void dump_db (struct fwohci_softc *, uint32_t);
-static void print_db (struct fwohcidb_tr *, struct fwohcidb *, uint32_t , uint32_t);
-static void dump_dma (struct fwohci_softc *, uint32_t);
-static uint32_t fwohci_cyctimer (struct firewire_comm *);
-static void fwohci_rbuf_update (struct fwohci_softc *, int);
-static void fwohci_tbuf_update (struct fwohci_softc *, int);
-void fwohci_txbufdb (struct fwohci_softc *, int , struct fw_bulkxfer *);
-static void fwohci_task_busreset(void *, int);
-static void fwohci_task_sid(void *, int);
-static void fwohci_task_dma(void *, int);
-#if defined(__NetBSD__)
-int fwohci_print(void *, const char *);
+static void fwohci_set_intr(struct firewire_comm *, int);
+
+static uint32_t fwphy_rddata(struct fwohci_softc *, uint32_t);
+static uint32_t fwphy_wrdata(struct fwohci_softc *, uint32_t, uint32_t);
+static int fwohci_probe_phy(struct fwohci_softc *);
+static void fwohci_reset(struct fwohci_softc *);
+static void fwohci_execute_db(struct fwohcidb_tr *, bus_dmamap_t);
+static void fwohci_start(struct fwohci_softc *, struct fwohci_dbch *);
+static void fwohci_start_atq(struct firewire_comm *);
+static void fwohci_start_ats(struct firewire_comm *);
+static void fwohci_txd(struct fwohci_softc *, struct fwohci_dbch *);
+static void fwohci_db_free(struct fwohci_softc *, struct fwohci_dbch *);
+static void fwohci_db_init(struct fwohci_softc *, struct fwohci_dbch *);
+static int fwohci_rx_enable(struct fwohci_softc *, struct fwohci_dbch *);
+static int fwohci_tx_enable(struct fwohci_softc *, struct fwohci_dbch *);
+static int fwohci_next_cycle(struct fwohci_softc *, int);
+#ifdef OHCI_DEBUG
+static void fwohci_dump_intr(struct fwohci_softc *, uint32_t);
#endif
+static void fwohci_intr_core(struct fwohci_softc *, uint32_t);
+static void fwohci_intr_dma(struct fwohci_softc *, uint32_t);
+static void fwohci_task_sid(struct fwohci_softc *);
+static void fwohci_task_dma(struct fwohci_softc *);
+static void fwohci_tbuf_update(struct fwohci_softc *, int);
+static void fwohci_rbuf_update(struct fwohci_softc *, int);
+static void dump_dma(struct fwohci_softc *, uint32_t);
+static void dump_db(struct fwohci_softc *, uint32_t);
+static void print_db(struct fwohcidb_tr *, struct fwohcidb *, uint32_t,
+ uint32_t);
+static void fwohci_txbufdb(struct fwohci_softc *, int, struct fw_bulkxfer *);
+static int fwohci_add_tx_buf(struct fwohci_dbch *, struct fwohcidb_tr *, int);
+static int fwohci_add_rx_buf(struct fwohci_dbch *, struct fwohcidb_tr *, int,
+ struct fwdma_alloc *);
+static int fwohci_arcv_swap(struct fw_pkt *, int);
+static int fwohci_get_plen(struct fwohci_softc *, struct fwohci_dbch *,
+ struct fw_pkt *);
+static void fwohci_arcv_free_buf(struct fwohci_softc *, struct fwohci_dbch *,
+ struct fwohcidb_tr *, int);
+static void fwohci_arcv(struct fwohci_softc *, struct fwohci_dbch *);
+
/*
* memory allocated for DMA programs
@@ -260,24 +226,24 @@ int fwohci_print(void *, const char *);
#define NDB FWMAXQUEUE
-#define OHCI_VERSION 0x00
-#define OHCI_ATRETRY 0x08
-#define OHCI_CROMHDR 0x18
-#define OHCI_BUS_OPT 0x20
+#define OHCI_VERSION 0x000
+#define OHCI_ATRETRY 0x008
+#define OHCI_CROMHDR 0x018
+#define OHCI_BUS_OPT 0x020
#define OHCI_BUSIRMC (1 << 31)
#define OHCI_BUSCMC (1 << 30)
#define OHCI_BUSISC (1 << 29)
#define OHCI_BUSBMC (1 << 28)
#define OHCI_BUSPMC (1 << 27)
-#define OHCI_BUSFNC OHCI_BUSIRMC | OHCI_BUSCMC | OHCI_BUSISC |\
- OHCI_BUSBMC | OHCI_BUSPMC
+#define OHCI_BUSFNC \
+ (OHCI_BUSIRMC | OHCI_BUSCMC | OHCI_BUSISC | OHCI_BUSBMC | OHCI_BUSPMC)
-#define OHCI_EUID_HI 0x24
-#define OHCI_EUID_LO 0x28
+#define OHCI_EUID_HI 0x024
+#define OHCI_EUID_LO 0x028
-#define OHCI_CROMPTR 0x34
-#define OHCI_HCCCTL 0x50
-#define OHCI_HCCCTLCLR 0x54
+#define OHCI_CROMPTR 0x034
+#define OHCI_HCCCTL 0x050
+#define OHCI_HCCCTLCLR 0x054
#define OHCI_AREQHI 0x100
#define OHCI_AREQHICLR 0x104
#define OHCI_AREQLO 0x108
@@ -288,98 +254,482 @@ int fwohci_print(void *, const char *);
#define OHCI_PREQLOCLR 0x11c
#define OHCI_PREQUPPER 0x120
-#define OHCI_SID_BUF 0x64
-#define OHCI_SID_CNT 0x68
+#define OHCI_SID_BUF 0x064
+#define OHCI_SID_CNT 0x068
#define OHCI_SID_ERR (1 << 31)
#define OHCI_SID_CNT_MASK 0xffc
-#define OHCI_IT_STAT 0x90
-#define OHCI_IT_STATCLR 0x94
-#define OHCI_IT_MASK 0x98
-#define OHCI_IT_MASKCLR 0x9c
+#define OHCI_IT_STAT 0x090
+#define OHCI_IT_STATCLR 0x094
+#define OHCI_IT_MASK 0x098
+#define OHCI_IT_MASKCLR 0x09c
-#define OHCI_IR_STAT 0xa0
-#define OHCI_IR_STATCLR 0xa4
-#define OHCI_IR_MASK 0xa8
-#define OHCI_IR_MASKCLR 0xac
+#define OHCI_IR_STAT 0x0a0
+#define OHCI_IR_STATCLR 0x0a4
+#define OHCI_IR_MASK 0x0a8
+#define OHCI_IR_MASKCLR 0x0ac
-#define OHCI_LNKCTL 0xe0
-#define OHCI_LNKCTLCLR 0xe4
+#define OHCI_LNKCTL 0x0e0
+#define OHCI_LNKCTLCLR 0x0e4
-#define OHCI_PHYACCESS 0xec
-#define OHCI_CYCLETIMER 0xf0
+#define OHCI_PHYACCESS 0x0ec
+#define OHCI_CYCLETIMER 0x0f0
#define OHCI_DMACTL(off) (off)
-#define OHCI_DMACTLCLR(off) (off + 4)
-#define OHCI_DMACMD(off) (off + 0xc)
+#define OHCI_DMACTLCLR(off) (off + 0x04)
+#define OHCI_DMACMD(off) (off + 0x0c)
#define OHCI_DMAMATCH(off) (off + 0x10)
#define OHCI_ATQOFF 0x180
#define OHCI_ATQCTL OHCI_ATQOFF
-#define OHCI_ATQCTLCLR (OHCI_ATQOFF + 4)
-#define OHCI_ATQCMD (OHCI_ATQOFF + 0xc)
+#define OHCI_ATQCTLCLR (OHCI_ATQOFF + 0x04)
+#define OHCI_ATQCMD (OHCI_ATQOFF + 0x0c)
#define OHCI_ATQMATCH (OHCI_ATQOFF + 0x10)
#define OHCI_ATSOFF 0x1a0
#define OHCI_ATSCTL OHCI_ATSOFF
-#define OHCI_ATSCTLCLR (OHCI_ATSOFF + 4)
-#define OHCI_ATSCMD (OHCI_ATSOFF + 0xc)
+#define OHCI_ATSCTLCLR (OHCI_ATSOFF + 0x04)
+#define OHCI_ATSCMD (OHCI_ATSOFF + 0x0c)
#define OHCI_ATSMATCH (OHCI_ATSOFF + 0x10)
#define OHCI_ARQOFF 0x1c0
#define OHCI_ARQCTL OHCI_ARQOFF
-#define OHCI_ARQCTLCLR (OHCI_ARQOFF + 4)
-#define OHCI_ARQCMD (OHCI_ARQOFF + 0xc)
+#define OHCI_ARQCTLCLR (OHCI_ARQOFF + 0x04)
+#define OHCI_ARQCMD (OHCI_ARQOFF + 0x0c)
#define OHCI_ARQMATCH (OHCI_ARQOFF + 0x10)
#define OHCI_ARSOFF 0x1e0
#define OHCI_ARSCTL OHCI_ARSOFF
-#define OHCI_ARSCTLCLR (OHCI_ARSOFF + 4)
-#define OHCI_ARSCMD (OHCI_ARSOFF + 0xc)
+#define OHCI_ARSCTLCLR (OHCI_ARSOFF + 0x04)
+#define OHCI_ARSCMD (OHCI_ARSOFF + 0x0c)
#define OHCI_ARSMATCH (OHCI_ARSOFF + 0x10)
#define OHCI_ITOFF(CH) (0x200 + 0x10 * (CH))
#define OHCI_ITCTL(CH) (OHCI_ITOFF(CH))
-#define OHCI_ITCTLCLR(CH) (OHCI_ITOFF(CH) + 4)
-#define OHCI_ITCMD(CH) (OHCI_ITOFF(CH) + 0xc)
+#define OHCI_ITCTLCLR(CH) (OHCI_ITOFF(CH) + 0x04)
+#define OHCI_ITCMD(CH) (OHCI_ITOFF(CH) + 0x0c)
#define OHCI_IROFF(CH) (0x400 + 0x20 * (CH))
#define OHCI_IRCTL(CH) (OHCI_IROFF(CH))
-#define OHCI_IRCTLCLR(CH) (OHCI_IROFF(CH) + 4)
-#define OHCI_IRCMD(CH) (OHCI_IROFF(CH) + 0xc)
+#define OHCI_IRCTLCLR(CH) (OHCI_IROFF(CH) + 0x04)
+#define OHCI_IRCMD(CH) (OHCI_IROFF(CH) + 0x0c)
#define OHCI_IRMATCH(CH) (OHCI_IROFF(CH) + 0x10)
-#if defined(__FreeBSD__)
-d_ioctl_t fwohci_ioctl;
-#elif defined(__NetBSD__)
-dev_type_ioctl(fwohci_ioctl);
+#define ATRQ_CH 0
+#define ATRS_CH 1
+#define ARRQ_CH 2
+#define ARRS_CH 3
+#define ITX_CH 4
+#define IRX_CH 36
+
+
+int
+fwohci_init(struct fwohci_softc *sc)
+{
+ uint32_t reg;
+ uint8_t ui[8];
+ int i, mver;
+
+/* OHCI version */
+ reg = OREAD(sc, OHCI_VERSION);
+ mver = (reg >> 16) & 0xff;
+ aprint_normal_dev(sc->fc.dev, "OHCI version %x.%x (ROM=%d)\n",
+ mver, reg & 0xff, (reg >> 24) & 1);
+ if (mver < 1 || mver > 9) {
+ aprint_error_dev(sc->fc.dev, "invalid OHCI version\n");
+ return ENXIO;
+ }
+
+/* Available Isochronous DMA channel probe */
+ OWRITE(sc, OHCI_IT_MASK, 0xffffffff);
+ OWRITE(sc, OHCI_IR_MASK, 0xffffffff);
+ reg = OREAD(sc, OHCI_IT_MASK) & OREAD(sc, OHCI_IR_MASK);
+ OWRITE(sc, OHCI_IT_MASKCLR, 0xffffffff);
+ OWRITE(sc, OHCI_IR_MASKCLR, 0xffffffff);
+ for (i = 0; i < 0x20; i++)
+ if ((reg & (1 << i)) == 0)
+ break;
+ sc->fc.nisodma = i;
+ aprint_normal_dev(sc->fc.dev, "No. of Isochronous channels is %d.\n",
+ i);
+ if (i == 0)
+ return ENXIO;
+
+ sc->fc.arq = &sc->arrq.xferq;
+ sc->fc.ars = &sc->arrs.xferq;
+ sc->fc.atq = &sc->atrq.xferq;
+ sc->fc.ats = &sc->atrs.xferq;
+
+ sc->arrq.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
+ sc->arrs.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
+ sc->atrq.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
+ sc->atrs.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
+
+ sc->arrq.xferq.start = NULL;
+ sc->arrs.xferq.start = NULL;
+ sc->atrq.xferq.start = fwohci_start_atq;
+ sc->atrs.xferq.start = fwohci_start_ats;
+
+ sc->arrq.xferq.buf = NULL;
+ sc->arrs.xferq.buf = NULL;
+ sc->atrq.xferq.buf = NULL;
+ sc->atrs.xferq.buf = NULL;
+
+ sc->arrq.xferq.dmach = -1;
+ sc->arrs.xferq.dmach = -1;
+ sc->atrq.xferq.dmach = -1;
+ sc->atrs.xferq.dmach = -1;
+
+ sc->arrq.ndesc = 1;
+ sc->arrs.ndesc = 1;
+ sc->atrq.ndesc = 8; /* equal to maximum of mbuf chains */
+ sc->atrs.ndesc = 2;
+
+ sc->arrq.ndb = NDB;
+ sc->arrs.ndb = NDB / 2;
+ sc->atrq.ndb = NDB;
+ sc->atrs.ndb = NDB / 2;
+
+ sc->arrq.off = OHCI_ARQOFF;
+ sc->arrs.off = OHCI_ARSOFF;
+ sc->atrq.off = OHCI_ATQOFF;
+ sc->atrs.off = OHCI_ATSOFF;
+
+ for (i = 0; i < sc->fc.nisodma; i++) {
+ sc->fc.it[i] = &sc->it[i].xferq;
+ sc->fc.ir[i] = &sc->ir[i].xferq;
+ sc->it[i].xferq.dmach = i;
+ sc->ir[i].xferq.dmach = i;
+ sc->it[i].ndb = 0;
+ sc->ir[i].ndb = 0;
+ sc->it[i].off = OHCI_ITOFF(i);
+ sc->ir[i].off = OHCI_IROFF(i);
+ }
+
+ sc->fc.tcode = tinfo;
+
+ sc->fc.config_rom = fwdma_alloc_setup(sc->fc.dev, sc->fc.dmat,
+ CROMSIZE, &sc->crom_dma, CROMSIZE, BUS_DMA_NOWAIT);
+ if (sc->fc.config_rom == NULL) {
+ aprint_error_dev(sc->fc.dev, "config_rom alloc failed.");
+ return ENOMEM;
+ }
+
+#if 0
+ memset(sc->fc.config_rom, 0, CROMSIZE);
+ sc->fc.config_rom[1] = 0x31333934;
+ sc->fc.config_rom[2] = 0xf000a002;
+ sc->fc.config_rom[3] = OREAD(sc, OHCI_EUID_HI);
+ sc->fc.config_rom[4] = OREAD(sc, OHCI_EUID_LO);
+ sc->fc.config_rom[5] = 0;
+ sc->fc.config_rom[0] = (4 << 24) | (5 << 16);
+
+ sc->fc.config_rom[0] |= fw_crc16(&sc->fc.config_rom[1], 5*4);
#endif
-/*
- * Communication with PHY device
- */
-/* XXX need lock for phy access */
-static uint32_t
-fwphy_wrdata( struct fwohci_softc *sc, uint32_t addr, uint32_t data)
+/* SID recieve buffer must align 2^11 */
+#define OHCI_SIDSIZE (1 << 11)
+ sc->sid_buf = fwdma_alloc_setup(sc->fc.dev, sc->fc.dmat, OHCI_SIDSIZE,
+ &sc->sid_dma, OHCI_SIDSIZE, BUS_DMA_NOWAIT);
+ if (sc->sid_buf == NULL) {
+ aprint_error_dev(sc->fc.dev, "sid_buf alloc failed.");
+ return ENOMEM;
+ }
+
+ fwdma_alloc_setup(sc->fc.dev, sc->fc.dmat, sizeof(uint32_t),
+ &sc->dummy_dma, sizeof(uint32_t), BUS_DMA_NOWAIT);
+ if (sc->dummy_dma.v_addr == NULL) {
+ aprint_error_dev(sc->fc.dev, "dummy_dma alloc failed.");
+ return ENOMEM;
+ }
+
+ fwohci_db_init(sc, &sc->arrq);
+ if ((sc->arrq.flags & FWOHCI_DBCH_INIT) == 0)
+ return ENOMEM;
+
+ fwohci_db_init(sc, &sc->arrs);
+ if ((sc->arrs.flags & FWOHCI_DBCH_INIT) == 0)
+ return ENOMEM;
+
+ fwohci_db_init(sc, &sc->atrq);
+ if ((sc->atrq.flags & FWOHCI_DBCH_INIT) == 0)
+ return ENOMEM;
+
+ fwohci_db_init(sc, &sc->atrs);
+ if ((sc->atrs.flags & FWOHCI_DBCH_INIT) == 0)
+ return ENOMEM;
+
+ sc->fc.eui.hi = OREAD(sc, FWOHCIGUID_H);
+ sc->fc.eui.lo = OREAD(sc, FWOHCIGUID_L);
+ for (i = 0; i < 8; i++)
+ ui[i] = FW_EUI64_BYTE(&sc->fc.eui, i);
+ aprint_normal_dev(sc->fc.dev,
+ "EUI64 %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ ui[0], ui[1], ui[2], ui[3], ui[4], ui[5], ui[6], ui[7]);
+
+ sc->fc.cyctimer = fwohci_cyctimer;
+ sc->fc.ibr = fwohci_ibr;
+ sc->fc.set_bmr = fwohci_set_bus_manager;
+ sc->fc.ioctl = fwohci_ioctl;
+ sc->fc.irx_enable = fwohci_irx_enable;
+ sc->fc.irx_disable = fwohci_irx_disable;
+
+ sc->fc.itx_enable = fwohci_itxbuf_enable;
+ sc->fc.itx_disable = fwohci_itx_disable;
+ sc->fc.timeout = fwohci_timeout;
+ sc->fc.set_intr = fwohci_set_intr;
+#if BYTE_ORDER == BIG_ENDIAN
+ sc->fc.irx_post = fwohci_irx_post;
+#else
+ sc->fc.irx_post = NULL;
+#endif
+ sc->fc.itx_post = NULL;
+
+ sc->intmask = sc->irstat = sc->itstat = 0;
+
+ fw_init(&sc->fc);
+ fwohci_reset(sc);
+
+ sc->fc.bdev =
+ config_found(sc->fc.dev, __UNCONST("ieee1394if"), fwohci_print);
+
+ return 0;
+}
+
+int
+fwohci_detach(struct fwohci_softc *sc, int flags)
{
- uint32_t fun;
+ int i;
- addr &= 0xf;
- data &= 0xff;
+ if (sc->fc.bdev != NULL)
+ config_detach(sc->fc.bdev, flags);
+ if (sc->sid_buf != NULL)
+ fwdma_free(sc->sid_dma.dma_tag, sc->sid_dma.dma_map,
+ sc->sid_dma.v_addr);
+ if (sc->fc.config_rom != NULL)
+ fwdma_free(sc->crom_dma.dma_tag, sc->crom_dma.dma_map,
+ sc->crom_dma.v_addr);
- fun = (PHYDEV_WRCMD | (addr << PHYDEV_REGADDR) | (data << PHYDEV_WRDATA));
- OWRITE(sc, OHCI_PHYACCESS, fun);
- DELAY(100);
+ fwohci_db_free(sc, &sc->arrq);
+ fwohci_db_free(sc, &sc->arrs);
+ fwohci_db_free(sc, &sc->atrq);
+ fwohci_db_free(sc, &sc->atrs);
+ for (i = 0; i < sc->fc.nisodma; i++) {
+ fwohci_db_free(sc, &sc->it[i]);
+ fwohci_db_free(sc, &sc->ir[i]);
+ }
+
+ mutex_destroy(&sc->arrq.xferq.q_mtx);
+ mutex_destroy(&sc->arrs.xferq.q_mtx);
+ mutex_destroy(&sc->atrq.xferq.q_mtx);
+ mutex_destroy(&sc->atrs.xferq.q_mtx);
+
+ return 0;
+}
+
+int
+fwohci_intr(void *arg)
+{
+ struct fwohci_softc *sc = (struct fwohci_softc *)arg;
+ uint32_t stat, irstat, itstat;
+
+ if (!device_is_active(sc->fc.dev))
+ return 0;
+
+ if (!(sc->intmask & OHCI_INT_EN))
+ /* polling mode? */
+ return 0;
+
+ stat = OREAD(sc, FWOHCI_INTSTAT);
+ if (stat == 0xffffffff) {
+ aprint_error_dev(sc->fc.dev, "device physically ejected?\n");
+ return 0;
+ }
+ if (stat)
+ OWRITE(sc, FWOHCI_INTSTATCLR, stat & ~OHCI_INT_PHY_BUS_R);
+
+ stat &= sc->intmask;
+ if (stat == 0)
+ return 0;
+
+ atomic_swap_32(&sc->intstat, stat);
+ if (stat & OHCI_INT_DMA_IR) {
+ irstat = OREAD(sc, OHCI_IR_STAT);
+ OWRITE(sc, OHCI_IR_STATCLR, irstat);
+ atomic_swap_32(&sc->irstat, irstat);
+ }
+ if (stat & OHCI_INT_DMA_IT) {
+ itstat = OREAD(sc, OHCI_IT_STAT);
+ OWRITE(sc, OHCI_IT_STATCLR, itstat);
+ atomic_swap_32(&sc->itstat, itstat);
+ }
+
+ fwohci_intr_core(sc, stat);
+ return 1;
+}
+
+int
+fwohci_resume(struct fwohci_softc *sc)
+{
+ struct fw_xferq *ir;
+ struct fw_bulkxfer *chunk;
+ int i;
+ extern int firewire_resume(struct firewire_comm *);
+
+ fwohci_reset(sc);
+ /* XXX resume isochronous receive automatically. (how about TX?) */
+ for (i = 0; i < sc->fc.nisodma; i++) {
+ ir = &sc->ir[i].xferq;
+ if ((ir->flag & FWXFERQ_RUNNING) != 0) {
+ aprint_normal_dev(sc->fc.dev,
+ "resume iso receive ch: %d\n", i);
+ ir->flag &= ~FWXFERQ_RUNNING;
+ /* requeue stdma to stfree */
+ while ((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
+ STAILQ_REMOVE_HEAD(&ir->stdma, link);
+ STAILQ_INSERT_TAIL(&ir->stfree, chunk, link);
+ }
+ sc->fc.irx_enable(&sc->fc, i);
+ }
+ }
+
+ firewire_resume(&sc->fc);
+ sc->fc.ibr(&sc->fc);
+ return 0;
+}
+
+int
+fwohci_stop(struct fwohci_softc *sc)
+{
+ u_int i;
+
+ fwohci_set_intr(&sc->fc, 0);
+
+/* Now stopping all DMA channel */
+ OWRITE(sc, OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
+
+ for (i = 0; i < sc->fc.nisodma; i++) {
+ OWRITE(sc, OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN);
+ }
+
+#if 0 /* Let dcons(4) be accessed */
+/* Stop interrupt */
+ OWRITE(sc, FWOHCI_INTMASKCLR,
+ OHCI_INT_EN |
+ OHCI_INT_ERR |
+ OHCI_INT_PHY_SID |
+ OHCI_INT_PHY_INT |
+ OHCI_INT_DMA_ATRQ |
+ OHCI_INT_DMA_ATRS |
+ OHCI_INT_DMA_PRRQ |
+ OHCI_INT_DMA_PRRS |
+ OHCI_INT_DMA_ARRQ |
+ OHCI_INT_DMA_ARRS |
+ OHCI_INT_PHY_BUS_R);
+
+/* FLUSH FIFO and reset Transmitter/Reciever */
+ OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_RESET);
+#endif
+
+/* XXX Link down? Bus reset? */
+ return 0;
+}
+
+
+static int
+fwohci_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *td)
+{
+ struct fwohci_softc *sc;
+ struct fw_reg_req_t *reg = (struct fw_reg_req_t *)data;
+ uint32_t *dmach = (uint32_t *)data;
+ int err = 0;
+
+ sc = device_lookup_private(&fwohci_cd, DEV2UNIT(dev));
+ if (sc == NULL)
+ return ENXIO;
+
+ if (!data)
+ return EINVAL;
+
+ switch (cmd) {
+ case FWOHCI_WRREG:
+#define OHCI_MAX_REG 0x800
+ if (reg->addr <= OHCI_MAX_REG) {
+ OWRITE(sc, reg->addr, reg->data);
+ reg->data = OREAD(sc, reg->addr);
+ } else
+ err = EINVAL;
+ break;
+
+ case FWOHCI_RDREG:
+ if (reg->addr <= OHCI_MAX_REG)
+ reg->data = OREAD(sc, reg->addr);
+ else
+ err = EINVAL;
+ break;
+
+/* Read DMA descriptors for debug */
+ case DUMPDMA:
+ if (*dmach <= OHCI_MAX_DMA_CH) {
+ dump_dma(sc, *dmach);
+ dump_db(sc, *dmach);
+ } else
+ err = EINVAL;
+ break;
+
+/* Read/Write Phy registers */
+#define OHCI_MAX_PHY_REG 0xf
+ case FWOHCI_RDPHYREG:
+ if (reg->addr <= OHCI_MAX_PHY_REG)
+ reg->data = fwphy_rddata(sc, reg->addr);
+ else
+ err = EINVAL;
+ break;
+
+ case FWOHCI_WRPHYREG:
+ if (reg->addr <= OHCI_MAX_PHY_REG)
+ reg->data = fwphy_wrdata(sc, reg->addr, reg->data);
+ else
+ err = EINVAL;
+ break;
+
+ default:
+ err = EINVAL;
+ break;
+ }
+ return err;
+}
+
+int
+fwohci_print(void *aux, const char *pnp)
+{
+ struct fw_attach_args *fwa = (struct fw_attach_args *)aux;
- return(fwphy_rddata( sc, addr));
+ if (pnp)
+ aprint_normal("%s at %s", fwa->name, pnp);
+
+ return UNCONF;
+}
+
+
+static uint32_t
+fwohci_cyctimer(struct firewire_comm *fc)
+{
+ struct fwohci_softc *sc = (struct fwohci_softc *)fc;
+
+ return OREAD(sc, OHCI_CYCLETIMER);
}
static uint32_t
fwohci_set_bus_manager(struct firewire_comm *fc, u_int node)
{
struct fwohci_softc *sc = (struct fwohci_softc *)fc;
- int i;
uint32_t bm;
+ int i;
#define OHCI_CSR_DATA 0x0c
#define OHCI_CSR_COMP 0x10
@@ -392,17 +742,334 @@ fwohci_set_bus_manager(struct firewire_comm *fc, u_int node)
for (i = 0; !(OREAD(sc, OHCI_CSR_CONT) & (1<<31)) && (i < 1000); i++)
DELAY(10);
bm = OREAD(sc, OHCI_CSR_DATA);
- if((bm & 0x3f) == 0x3f)
+ if ((bm & 0x3f) == 0x3f)
bm = node;
if (firewire_debug)
- fw_printf(sc->fc.dev,
- "fw_set_bus_manager: %d->%d (loop=%d)\n", bm, node, i);
+ printf("fw_set_bus_manager: %d->%d (loop=%d)\n", bm, node, i);
+
+ return bm;
+}
+
+static void
+fwohci_ibr(struct firewire_comm *fc)
+{
+ struct fwohci_softc *sc = (struct fwohci_softc *)fc;
+ uint32_t fun;
+
+ aprint_normal_dev(fc->dev, "Initiate bus reset\n");
+
+ /*
+ * Make sure our cached values from the config rom are
+ * initialised.
+ */
+ OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
+ OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
+
+ /*
+ * Set root hold-off bit so that non cyclemaster capable node
+ * shouldn't became the root node.
+ */
+#if 1
+ fun = fwphy_rddata(sc, FW_PHY_IBR_REG);
+ fun |= FW_PHY_IBR | FW_PHY_RHB;
+ fun = fwphy_wrdata(sc, FW_PHY_IBR_REG, fun);
+#else /* Short bus reset */
+ fun = fwphy_rddata(sc, FW_PHY_ISBR_REG);
+ fun |= FW_PHY_ISBR | FW_PHY_RHB;
+ fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun);
+#endif
+}
+
+static int
+fwohci_irx_enable(struct firewire_comm *fc, int dmach)
+{
+ struct fwohci_softc *sc = (struct fwohci_softc *)fc;
+ struct fwohci_dbch *dbch;
+ struct fwohcidb_tr *db_tr;
+ struct fw_bulkxfer *first, *prev, *chunk, *txfer;
+ struct fw_xferq *ir;
+ uint32_t stat;
+ unsigned short tag, ich;
+ int err = 0, ldesc;
+
+ dbch = &sc->ir[dmach];
+ ir = &dbch->xferq;
+
+ if ((ir->flag & FWXFERQ_RUNNING) == 0) {
+ tag = (ir->flag >> 6) & 3;
+ ich = ir->flag & 0x3f;
+ OWRITE(sc, OHCI_IRMATCH(dmach), tagbit[tag] | ich);
+
+ ir->queued = 0;
+ dbch->ndb = ir->bnpacket * ir->bnchunk;
+ dbch->ndesc = 2;
+ fwohci_db_init(sc, dbch);
+ if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
+ return ENOMEM;
+ err = fwohci_rx_enable(sc, dbch);
+ if (err)
+ return err;
+ }
+
+ first = STAILQ_FIRST(&ir->stfree);
+ if (first == NULL) {
+ aprint_error_dev(fc->dev, "IR DMA no free chunk\n");
+ return 0;
+ }
+
+ ldesc = dbch->ndesc - 1;
+ prev = NULL;
+ STAILQ_FOREACH(txfer, &ir->stdma, link)
+ prev = txfer;
+ while ((chunk = STAILQ_FIRST(&ir->stfree)) != NULL) {
+ struct fwohcidb *db;
+
+ if (chunk->mbuf != NULL) {
+ db_tr = (struct fwohcidb_tr *)(chunk->start);
+ db_tr->dbcnt = 1;
+ err = bus_dmamap_load_mbuf(fc->dmat, db_tr->dma_map,
+ chunk->mbuf, BUS_DMA_NOWAIT);
+ if (err == 0)
+ fwohci_execute_db(db_tr, db_tr->dma_map);
+ else
+ aprint_error_dev(fc->dev,
+ "mbuf load failed: %d\n", err);
+ FWOHCI_DMA_SET(db_tr->db[1].db.desc.cmd,
+ OHCI_UPDATE |
+ OHCI_INPUT_LAST |
+ OHCI_INTERRUPT_ALWAYS |
+ OHCI_BRANCH_ALWAYS);
+ }
+ db = ((struct fwohcidb_tr *)(chunk->end))->db;
+ FWOHCI_DMA_WRITE(db[ldesc].db.desc.res, 0);
+ FWOHCI_DMA_CLEAR(db[ldesc].db.desc.depend, 0xf);
+ if (prev != NULL) {
+ db = ((struct fwohcidb_tr *)(prev->end))->db;
+ FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
+ }
+ STAILQ_REMOVE_HEAD(&ir->stfree, link);
+ STAILQ_INSERT_TAIL(&ir->stdma, chunk, link);
+ prev = chunk;
+ }
+ fwdma_sync_multiseg_all(dbch->am,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ stat = OREAD(sc, OHCI_IRCTL(dmach));
+ if (stat & OHCI_CNTL_DMA_ACTIVE)
+ return 0;
+ if (stat & OHCI_CNTL_DMA_RUN) {
+ OWRITE(sc, OHCI_IRCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
+ aprint_error_dev(fc->dev, "IR DMA overrun (0x%08x)\n", stat);
+ }
+
+ if (firewire_debug)
+ printf("start IR DMA 0x%x\n", stat);
+ OWRITE(sc, OHCI_IR_MASKCLR, 1 << dmach);
+ OWRITE(sc, OHCI_IR_STATCLR, 1 << dmach);
+ OWRITE(sc, OHCI_IR_MASK, 1 << dmach);
+ OWRITE(sc, OHCI_IRCTLCLR(dmach), 0xf0000000);
+ OWRITE(sc, OHCI_IRCTL(dmach), OHCI_CNTL_ISOHDR);
+ OWRITE(sc, OHCI_IRCMD(dmach),
+ ((struct fwohcidb_tr *)(first->start))->bus_addr | dbch->ndesc);
+ OWRITE(sc, OHCI_IRCTL(dmach), OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IR);
+#if 0
+ dump_db(sc, IRX_CH + dmach);
+#endif
+ return err;
+}
- return(bm);
+static int
+fwohci_irx_disable(struct firewire_comm *fc, int dmach)
+{
+ struct fwohci_softc *sc = (struct fwohci_softc *)fc;
+ int sleepch;
+
+ OWRITE(sc, OHCI_IRCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, OHCI_IR_MASKCLR, 1 << dmach);
+ OWRITE(sc, OHCI_IR_STATCLR, 1 << dmach);
+ /* XXX we cannot free buffers until the DMA really stops */
+ tsleep((void *)&sleepch, FWPRI, "fwirxd", hz);
+ fwohci_db_free(sc, &sc->ir[dmach]);
+ sc->ir[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
+ return 0;
}
+
+static int
+fwohci_itxbuf_enable(struct firewire_comm *fc, int dmach)
+{
+ struct fwohci_softc *sc = (struct fwohci_softc *)fc;
+ struct fwohci_dbch *dbch;
+ struct fw_bulkxfer *first, *chunk, *prev, *txfer;
+ struct fw_xferq *it;
+ uint32_t stat;
+ int cycle_match, cycle_now, ldesc, err = 0;
+ unsigned short tag, ich;
+
+ dbch = &sc->it[dmach];
+ it = &dbch->xferq;
+
+ tag = (it->flag >> 6) & 3;
+ ich = it->flag & 0x3f;
+ if ((dbch->flags & FWOHCI_DBCH_INIT) == 0) {
+ dbch->ndb = it->bnpacket * it->bnchunk;
+ dbch->ndesc = 3;
+ fwohci_db_init(sc, dbch);
+ if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
+ return ENOMEM;
+
+ err = fwohci_tx_enable(sc, dbch);
+ if (err)
+ return err;
+ }
+
+ ldesc = dbch->ndesc - 1;
+ prev = NULL;
+ STAILQ_FOREACH(txfer, &it->stdma, link)
+ prev = txfer;
+ while ((chunk = STAILQ_FIRST(&it->stvalid)) != NULL) {
+ struct fwohcidb *db;
+
+ fwdma_sync_multiseg(it->buf, chunk->poffset, it->bnpacket,
+ BUS_DMASYNC_PREWRITE);
+ fwohci_txbufdb(sc, dmach, chunk);
+ if (prev != NULL) {
+ db = ((struct fwohcidb_tr *)(prev->end))->db;
+#if 0 /* XXX necessary? */
+ FWOHCI_DMA_SET(db[ldesc].db.desc.cmd,
+ OHCI_BRANCH_ALWAYS);
+#endif
+#if 0 /* if bulkxfer->npacket changes */
+ db[ldesc].db.desc.depend = db[0].db.desc.depend =
+ ((struct fwohcidb_tr *)(chunk->start))->bus_addr |
+ dbch->ndesc;
+#else
+ FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
+ FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
+#endif
+ }
+ STAILQ_REMOVE_HEAD(&it->stvalid, link);
+ STAILQ_INSERT_TAIL(&it->stdma, chunk, link);
+ prev = chunk;
+ }
+ fwdma_sync_multiseg_all(dbch->am,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ stat = OREAD(sc, OHCI_ITCTL(dmach));
+ if (firewire_debug && (stat & OHCI_CNTL_CYCMATCH_S))
+ printf("stat 0x%x\n", stat);
+
+ if (stat & (OHCI_CNTL_DMA_ACTIVE | OHCI_CNTL_CYCMATCH_S))
+ return 0;
+
+#if 0
+ OWRITE(sc, OHCI_ITCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
+#endif
+ OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach);
+ OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach);
+ OWRITE(sc, OHCI_IT_MASK, 1 << dmach);
+ OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IT);
+
+ first = STAILQ_FIRST(&it->stdma);
+ OWRITE(sc, OHCI_ITCMD(dmach),
+ ((struct fwohcidb_tr *)(first->start))->bus_addr | dbch->ndesc);
+ if (firewire_debug > 1) {
+ printf("fwohci_itxbuf_enable: kick 0x%08x\n", stat);
+#if 1
+ dump_dma(sc, ITX_CH + dmach);
+#endif
+ }
+ if ((stat & OHCI_CNTL_DMA_RUN) == 0) {
+#if 1
+ /* Don't start until all chunks are buffered */
+ if (STAILQ_FIRST(&it->stfree) != NULL)
+ goto out;
+#endif
+#if 1
+ /* Clear cycle match counter bits */
+ OWRITE(sc, OHCI_ITCTLCLR(dmach), 0xffff0000);
+
+ /* 2bit second + 13bit cycle */
+ cycle_now = (fc->cyctimer(fc) >> 12) & 0x7fff;
+ cycle_match = fwohci_next_cycle(sc, cycle_now);
+
+ OWRITE(sc, OHCI_ITCTL(dmach),
+ OHCI_CNTL_CYCMATCH_S | (cycle_match << 16) |
+ OHCI_CNTL_DMA_RUN);
+#else
+ OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_RUN);
+#endif
+ if (firewire_debug > 1) {
+ printf("cycle_match: 0x%04x->0x%04x\n",
+ cycle_now, cycle_match);
+ dump_dma(sc, ITX_CH + dmach);
+ dump_db(sc, ITX_CH + dmach);
+ }
+ } else if ((stat & OHCI_CNTL_CYCMATCH_S) == 0) {
+ aprint_error_dev(fc->dev, "IT DMA underrun (0x%08x)\n", stat);
+ OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_WAKE);
+ }
+out:
+ return err;
+}
+
+static int
+fwohci_itx_disable(struct firewire_comm *fc, int dmach)
+{
+ struct fwohci_softc *sc = (struct fwohci_softc *)fc;
+ int sleepch;
+
+ OWRITE(sc, OHCI_ITCTLCLR(dmach),
+ OHCI_CNTL_DMA_RUN | OHCI_CNTL_CYCMATCH_S);
+ OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach);
+ OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach);
+ /* XXX we cannot free buffers until the DMA really stops */
+ tsleep((void *)&sleepch, FWPRI, "fwitxd", hz);
+ fwohci_db_free(sc, &sc->it[dmach]);
+ sc->it[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
+ return 0;
+}
+
+static void
+fwohci_timeout(struct firewire_comm *fc)
+{
+#if 0
+ struct fwohci_softc *sc = (struct fwohci_softc *)fc;
+#endif
+ /* nothing? */
+}
+
+#if BYTE_ORDER == BIG_ENDIAN
+static void
+fwohci_irx_post (struct firewire_comm *fc, uint32_t *qld)
+{
+
+ qld[0] = FWOHCI_DMA_READ(qld[0]);
+ return;
+}
+#endif
+
+static void
+fwohci_set_intr(struct firewire_comm *fc, int enable)
+{
+ struct fwohci_softc *sc = (struct fwohci_softc *)fc;
+
+ if (firewire_debug)
+ printf("fwohci_set_intr: %d\n", enable);
+ if (enable) {
+ sc->intmask |= OHCI_INT_EN;
+ OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_EN);
+ } else {
+ sc->intmask &= ~OHCI_INT_EN;
+ OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_EN);
+ }
+}
+
+/*
+ * Communication with PHY device
+ */
+/* XXX need lock for phy access */
static uint32_t
-fwphy_rddata(struct fwohci_softc *sc, u_int addr)
+fwphy_rddata(struct fwohci_softc *sc, u_int addr)
{
uint32_t fun, stat;
u_int i, retry = 0;
@@ -413,15 +1080,15 @@ again:
OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_REG_FAIL);
fun = PHYDEV_RDCMD | (addr << PHYDEV_REGADDR);
OWRITE(sc, OHCI_PHYACCESS, fun);
- for ( i = 0 ; i < MAX_RETRY ; i ++ ){
+ for (i = 0; i < MAX_RETRY; i++) {
fun = OREAD(sc, OHCI_PHYACCESS);
if ((fun & PHYDEV_RDCMD) == 0 && (fun & PHYDEV_RDDONE) != 0)
break;
DELAY(100);
}
- if(i >= MAX_RETRY) {
+ if (i >= MAX_RETRY) {
if (firewire_debug)
- fw_printf(sc->fc.dev, "phy read failed(1).\n");
+ printf("phy read failed(1).\n");
if (++retry < MAX_RETRY) {
DELAY(100);
goto again;
@@ -430,89 +1097,44 @@ again:
/* Make sure that SCLK is started */
stat = OREAD(sc, FWOHCI_INTSTAT);
if ((stat & OHCI_INT_REG_FAIL) != 0 ||
- ((fun >> PHYDEV_REGADDR) & 0xf) != addr) {
+ ((fun >> PHYDEV_REGADDR) & 0xf) != addr) {
if (firewire_debug)
- fw_printf(sc->fc.dev, "phy read failed(2).\n");
+ printf("phy read failed(2).\n");
if (++retry < MAX_RETRY) {
DELAY(100);
goto again;
}
}
if (firewire_debug || retry >= MAX_RETRY)
- fw_printf(sc->fc.dev,
- "fwphy_rddata: 0x%x loop=%d, retry=%d\n", addr, i, retry);
+ aprint_error_dev(sc->fc.dev,
+ "fwphy_rddata: 0x%x loop=%d, retry=%d\n",
+ addr, i, retry);
#undef MAX_RETRY
- return((fun >> PHYDEV_RDDATA )& 0xff);
+ return (fun >> PHYDEV_RDDATA) & 0xff;
}
-/* Device specific ioctl. */
-FW_IOCTL(fwohci)
+
+static uint32_t
+fwphy_wrdata(struct fwohci_softc *sc, uint32_t addr, uint32_t data)
{
- FW_IOCTL_START;
- struct fwohci_softc *fc;
- int err = 0;
- struct fw_reg_req_t *reg = (struct fw_reg_req_t *) data;
- uint32_t *dmach = (uint32_t *) data;
+ uint32_t fun;
- if(sc == NULL){
- return(EINVAL);
- }
- fc = (struct fwohci_softc *)sc->fc;
+ addr &= 0xf;
+ data &= 0xff;
- if (!data)
- return(EINVAL);
+ fun =
+ (PHYDEV_WRCMD | (addr << PHYDEV_REGADDR) | (data << PHYDEV_WRDATA));
+ OWRITE(sc, OHCI_PHYACCESS, fun);
+ DELAY(100);
- switch (cmd) {
- case FWOHCI_WRREG:
-#define OHCI_MAX_REG 0x800
- if(reg->addr <= OHCI_MAX_REG){
- OWRITE(fc, reg->addr, reg->data);
- reg->data = OREAD(fc, reg->addr);
- }else{
- err = EINVAL;
- }
- break;
- case FWOHCI_RDREG:
- if(reg->addr <= OHCI_MAX_REG){
- reg->data = OREAD(fc, reg->addr);
- }else{
- err = EINVAL;
- }
- break;
-/* Read DMA descriptors for debug */
- case DUMPDMA:
- if(*dmach <= OHCI_MAX_DMA_CH ){
- dump_dma(fc, *dmach);
- dump_db(fc, *dmach);
- }else{
- err = EINVAL;
- }
- break;
-/* Read/Write Phy registers */
-#define OHCI_MAX_PHY_REG 0xf
- case FWOHCI_RDPHYREG:
- if (reg->addr <= OHCI_MAX_PHY_REG)
- reg->data = fwphy_rddata(fc, reg->addr);
- else
- err = EINVAL;
- break;
- case FWOHCI_WRPHYREG:
- if (reg->addr <= OHCI_MAX_PHY_REG)
- reg->data = fwphy_wrdata(fc, reg->addr, reg->data);
- else
- err = EINVAL;
- break;
- default:
- err = EINVAL;
- break;
- }
- return err;
+ return fwphy_rddata(sc, addr);
}
static int
-fwohci_probe_phy(struct fwohci_softc *sc, device_t dev)
+fwohci_probe_phy(struct fwohci_softc *sc)
{
uint32_t reg, reg2;
int e1394a = 1;
+
/*
* probe PHY parameters
* 0. to prove PHY version, whether compliance of 1394a.
@@ -525,29 +1147,32 @@ fwohci_probe_phy(struct fwohci_softc *sc, device_t dev)
reg = fwphy_rddata(sc, FW_PHY_SPD_REG);
- if((reg >> 5) != 7 ){
+ if ((reg >> 5) != 7) {
sc->fc.mode &= ~FWPHYASYST;
sc->fc.nport = reg & FW_PHY_NP;
sc->fc.speed = reg & FW_PHY_SPD >> 6;
if (sc->fc.speed > MAX_SPEED) {
- fw_printf(dev, "invalid speed %d (fixed to %d).\n",
- sc->fc.speed, MAX_SPEED);
+ aprint_error_dev(sc->fc.dev,
+ "invalid speed %d (fixed to %d).\n",
+ sc->fc.speed, MAX_SPEED);
sc->fc.speed = MAX_SPEED;
}
- fw_printf(dev, "Phy 1394 only %s, %d ports.\n",
- fw_linkspeed[sc->fc.speed], sc->fc.nport);
- }else{
+ aprint_normal_dev(sc->fc.dev, "Phy 1394 only %s, %d ports.\n",
+ fw_linkspeed[sc->fc.speed], sc->fc.nport);
+ } else {
reg2 = fwphy_rddata(sc, FW_PHY_ESPD_REG);
sc->fc.mode |= FWPHYASYST;
sc->fc.nport = reg & FW_PHY_NP;
sc->fc.speed = (reg2 & FW_PHY_ESPD) >> 5;
if (sc->fc.speed > MAX_SPEED) {
- fw_printf(dev, "invalid speed %d (fixed to %d).\n",
- sc->fc.speed, MAX_SPEED);
+ aprint_error_dev(sc->fc.dev,
+ "invalid speed %d (fixed to %d).\n",
+ sc->fc.speed, MAX_SPEED);
sc->fc.speed = MAX_SPEED;
}
- fw_printf(dev, "Phy 1394a available %s, %d ports.\n",
- fw_linkspeed[sc->fc.speed], sc->fc.nport);
+ aprint_normal_dev(sc->fc.dev,
+ "Phy 1394a available %s, %d ports.\n",
+ fw_linkspeed[sc->fc.speed], sc->fc.nport);
/* check programPhyEnable */
reg2 = fwphy_rddata(sc, 5);
@@ -557,7 +1182,7 @@ fwohci_probe_phy(struct fwohci_softc *sc, device_t dev)
if (e1394a) {
#endif
if (firewire_debug)
- fw_printf(dev, "Enable 1394a Enhancements\n");
+ printf("Enable 1394a Enhancements\n");
/* enable EAA EMC */
reg2 |= 0x03;
/* set aPhyEnhanceEnable */
@@ -574,7 +1199,7 @@ fwohci_probe_phy(struct fwohci_softc *sc, device_t dev)
}
reg = fwphy_rddata(sc, FW_PHY_SPD_REG);
- if((reg >> 5) == 7 ){
+ if ((reg >> 5) == 7) {
reg = fwphy_rddata(sc, 4);
reg |= 1 << 6;
fwphy_wrdata(sc, 4, reg);
@@ -583,61 +1208,61 @@ fwohci_probe_phy(struct fwohci_softc *sc, device_t dev)
return 0;
}
-
-void
-fwohci_reset(struct fwohci_softc *sc, device_t dev)
+static void
+fwohci_reset(struct fwohci_softc *sc)
{
- int i, max_rec, speed;
- uint32_t reg, reg2;
struct fwohcidb_tr *db_tr;
+ uint32_t reg, reg2;
+ int i, max_rec, speed;
/* Disable interrupts */
OWRITE(sc, FWOHCI_INTMASKCLR, ~0);
/* Now stopping all DMA channels */
- OWRITE(sc, OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
- OWRITE(sc, OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN);
- OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
- OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
- OWRITE(sc, OHCI_IR_MASKCLR, ~0);
- for( i = 0 ; i < sc->fc.nisodma ; i ++ ){
- OWRITE(sc, OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN);
- OWRITE(sc, OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, OHCI_IR_MASKCLR, ~0);
+ for (i = 0; i < sc->fc.nisodma; i++) {
+ OWRITE(sc, OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN);
}
/* FLUSH FIFO and reset Transmitter/Reciever */
OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_RESET);
if (firewire_debug)
- fw_printf(dev, "resetting OHCI...");
+ printf("resetting OHCI...");
i = 0;
- while(OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_RESET) {
- if (i++ > 100) break;
+ while (OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_RESET) {
+ if (i++ > 100)
+ break;
DELAY(1000);
}
if (firewire_debug)
printf("done (loop=%d)\n", i);
/* Probe phy */
- fwohci_probe_phy(sc, dev);
+ fwohci_probe_phy(sc);
/* Probe link */
- reg = OREAD(sc, OHCI_BUS_OPT);
+ reg = OREAD(sc, OHCI_BUS_OPT);
reg2 = reg | OHCI_BUSFNC;
max_rec = (reg & 0x0000f000) >> 12;
speed = (reg & 0x00000007);
- fw_printf(dev, "Link %s, max_rec %d bytes.\n",
- fw_linkspeed[speed], MAXREC(max_rec));
+ aprint_normal_dev(sc->fc.dev, "Link %s, max_rec %d bytes.\n",
+ fw_linkspeed[speed], MAXREC(max_rec));
/* XXX fix max_rec */
sc->fc.maxrec = sc->fc.speed + 8;
if (max_rec != sc->fc.maxrec) {
reg2 = (reg2 & 0xffff0fff) | (sc->fc.maxrec << 12);
- fw_printf(dev, "max_rec %d -> %d\n",
- MAXREC(max_rec), MAXREC(sc->fc.maxrec));
+ aprint_normal_dev(sc->fc.dev, "max_rec %d -> %d\n",
+ MAXREC(max_rec), MAXREC(sc->fc.maxrec));
}
if (firewire_debug)
- fw_printf(dev, "BUS_OPT 0x%x -> 0x%x\n", reg, reg2);
- OWRITE(sc, OHCI_BUS_OPT, reg2);
+ printf("BUS_OPT 0x%x -> 0x%x\n", reg, reg2);
+ OWRITE(sc, OHCI_BUS_OPT, reg2);
/* Initialize registers */
OWRITE(sc, OHCI_CROMHDR, sc->fc.config_rom[0]);
@@ -662,272 +1287,46 @@ fwohci_reset(struct fwohci_softc *sc, device_t dev)
/* AT Retries */
OWRITE(sc, FWOHCI_RETRY,
- /* CycleLimit PhyRespRetries ATRespRetries ATReqRetries */
- (0xffff << 16 ) | (0x0f << 8) | (0x0f << 4) | 0x0f) ;
+ /* CycleLimit PhyRespRetries ATRespRetries ATReqRetries */
+ (0xffff << 16) | (0x0f << 8) | (0x0f << 4) | 0x0f);
sc->atrq.top = STAILQ_FIRST(&sc->atrq.db_trq);
sc->atrs.top = STAILQ_FIRST(&sc->atrs.db_trq);
sc->atrq.bottom = sc->atrq.top;
sc->atrs.bottom = sc->atrs.top;
- for( i = 0, db_tr = sc->atrq.top; i < sc->atrq.ndb ;
- i ++, db_tr = STAILQ_NEXT(db_tr, link)){
+ for (i = 0, db_tr = sc->atrq.top; i < sc->atrq.ndb;
+ i++, db_tr = STAILQ_NEXT(db_tr, link))
db_tr->xfer = NULL;
- }
- for( i = 0, db_tr = sc->atrs.top; i < sc->atrs.ndb ;
- i ++, db_tr = STAILQ_NEXT(db_tr, link)){
+ for (i = 0, db_tr = sc->atrs.top; i < sc->atrs.ndb;
+ i++, db_tr = STAILQ_NEXT(db_tr, link))
db_tr->xfer = NULL;
- }
/* Enable interrupts */
- sc->intmask = (OHCI_INT_ERR | OHCI_INT_PHY_SID
+ sc->intmask = (OHCI_INT_ERR | OHCI_INT_PHY_SID
| OHCI_INT_DMA_ATRQ | OHCI_INT_DMA_ATRS
| OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS
| OHCI_INT_PHY_BUS_R | OHCI_INT_PW_ERR);
- sc->intmask |= OHCI_INT_DMA_IR | OHCI_INT_DMA_IT;
- sc->intmask |= OHCI_INT_CYC_LOST | OHCI_INT_PHY_INT;
+ sc->intmask |= OHCI_INT_DMA_IR | OHCI_INT_DMA_IT;
+ sc->intmask |= OHCI_INT_CYC_LOST | OHCI_INT_PHY_INT;
OWRITE(sc, FWOHCI_INTMASK, sc->intmask);
fwohci_set_intr(&sc->fc, 1);
}
-int
-fwohci_init(struct fwohci_softc *sc, device_t dev)
-{
- int i, mver;
- uint32_t reg;
- uint8_t ui[8];
-
-/* OHCI version */
- reg = OREAD(sc, OHCI_VERSION);
- mver = (reg >> 16) & 0xff;
- fw_printf(dev, "OHCI version %x.%x (ROM=%d)\n",
- mver, reg & 0xff, (reg>>24) & 1);
- if (mver < 1 || mver > 9) {
- fw_printf(dev, "invalid OHCI version\n");
- return (ENXIO);
- }
-
-/* Available Isochronous DMA channel probe */
- OWRITE(sc, OHCI_IT_MASK, 0xffffffff);
- OWRITE(sc, OHCI_IR_MASK, 0xffffffff);
- reg = OREAD(sc, OHCI_IT_MASK) & OREAD(sc, OHCI_IR_MASK);
- OWRITE(sc, OHCI_IT_MASKCLR, 0xffffffff);
- OWRITE(sc, OHCI_IR_MASKCLR, 0xffffffff);
- for (i = 0; i < 0x20; i++)
- if ((reg & (1 << i)) == 0)
- break;
- sc->fc.nisodma = i;
- fw_printf(dev, "No. of Isochronous channels is %d.\n", i);
- if (i == 0)
- return (ENXIO);
-
- sc->fc.arq = &sc->arrq.xferq;
- sc->fc.ars = &sc->arrs.xferq;
- sc->fc.atq = &sc->atrq.xferq;
- sc->fc.ats = &sc->atrs.xferq;
-
- sc->arrq.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
- sc->arrs.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
- sc->atrq.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
- sc->atrs.xferq.psize = roundup2(FWPMAX_S400, PAGE_SIZE);
-
- sc->arrq.xferq.start = NULL;
- sc->arrs.xferq.start = NULL;
- sc->atrq.xferq.start = fwohci_start_atq;
- sc->atrs.xferq.start = fwohci_start_ats;
-
- sc->arrq.xferq.buf = NULL;
- sc->arrs.xferq.buf = NULL;
- sc->atrq.xferq.buf = NULL;
- sc->atrs.xferq.buf = NULL;
-
- sc->arrq.xferq.dmach = -1;
- sc->arrs.xferq.dmach = -1;
- sc->atrq.xferq.dmach = -1;
- sc->atrs.xferq.dmach = -1;
-
- sc->arrq.ndesc = 1;
- sc->arrs.ndesc = 1;
- sc->atrq.ndesc = 8; /* equal to maximum of mbuf chains */
- sc->atrs.ndesc = 2;
-
- sc->arrq.ndb = NDB;
- sc->arrs.ndb = NDB / 2;
- sc->atrq.ndb = NDB;
- sc->atrs.ndb = NDB / 2;
-
- for( i = 0 ; i < sc->fc.nisodma ; i ++ ){
- sc->fc.it[i] = &sc->it[i].xferq;
- sc->fc.ir[i] = &sc->ir[i].xferq;
- sc->it[i].xferq.dmach = i;
- sc->ir[i].xferq.dmach = i;
- sc->it[i].ndb = 0;
- sc->ir[i].ndb = 0;
- }
-
- sc->fc.tcode = tinfo;
- sc->fc.dev = dev;
-
- sc->fc.config_rom = fwdma_malloc(&sc->fc, CROMSIZE, CROMSIZE,
- &sc->crom_dma, BUS_DMA_WAITOK);
- if(sc->fc.config_rom == NULL){
- fw_printf(dev, "config_rom alloc failed.");
- return ENOMEM;
- }
-
-#if 0
- memset(&sc->fc.config_rom[0], 0, CROMSIZE);
- sc->fc.config_rom[1] = 0x31333934;
- sc->fc.config_rom[2] = 0xf000a002;
- sc->fc.config_rom[3] = OREAD(sc, OHCI_EUID_HI);
- sc->fc.config_rom[4] = OREAD(sc, OHCI_EUID_LO);
- sc->fc.config_rom[5] = 0;
- sc->fc.config_rom[0] = (4 << 24) | (5 << 16);
-
- sc->fc.config_rom[0] |= fw_crc16(&sc->fc.config_rom[1], 5*4);
-#endif
-
-/* SID recieve buffer must align 2^11 */
-#define OHCI_SIDSIZE (1 << 11)
- sc->sid_buf = fwdma_malloc(&sc->fc, OHCI_SIDSIZE, OHCI_SIDSIZE,
- &sc->sid_dma, BUS_DMA_WAITOK);
- if (sc->sid_buf == NULL) {
- fw_printf(dev, "sid_buf alloc failed.");
- return ENOMEM;
- }
-
- fwdma_malloc(&sc->fc, sizeof(uint32_t), sizeof(uint32_t),
- &sc->dummy_dma, BUS_DMA_WAITOK);
-
- if (sc->dummy_dma.v_addr == NULL) {
- fw_printf(dev, "dummy_dma alloc failed.");
- return ENOMEM;
- }
-
- fwohci_db_init(sc, &sc->arrq);
- if ((sc->arrq.flags & FWOHCI_DBCH_INIT) == 0)
- return ENOMEM;
-
- fwohci_db_init(sc, &sc->arrs);
- if ((sc->arrs.flags & FWOHCI_DBCH_INIT) == 0)
- return ENOMEM;
-
- fwohci_db_init(sc, &sc->atrq);
- if ((sc->atrq.flags & FWOHCI_DBCH_INIT) == 0)
- return ENOMEM;
-
- fwohci_db_init(sc, &sc->atrs);
- if ((sc->atrs.flags & FWOHCI_DBCH_INIT) == 0)
- return ENOMEM;
-
- sc->fc.eui.hi = OREAD(sc, FWOHCIGUID_H);
- sc->fc.eui.lo = OREAD(sc, FWOHCIGUID_L);
- for( i = 0 ; i < 8 ; i ++)
- ui[i] = FW_EUI64_BYTE(&sc->fc.eui,i);
- fw_printf(dev, "EUI64 %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
- ui[0], ui[1], ui[2], ui[3], ui[4], ui[5], ui[6], ui[7]);
-
- sc->fc.ioctl = fwohci_ioctl;
- sc->fc.cyctimer = fwohci_cyctimer;
- sc->fc.set_bmr = fwohci_set_bus_manager;
- sc->fc.ibr = fwohci_ibr;
- sc->fc.irx_enable = fwohci_irx_enable;
- sc->fc.irx_disable = fwohci_irx_disable;
-
- sc->fc.itx_enable = fwohci_itxbuf_enable;
- sc->fc.itx_disable = fwohci_itx_disable;
-#if BYTE_ORDER == BIG_ENDIAN
- sc->fc.irx_post = fwohci_irx_post;
-#else
- sc->fc.irx_post = NULL;
-#endif
- sc->fc.itx_post = NULL;
- sc->fc.timeout = fwohci_timeout;
- sc->fc.poll = fwohci_poll;
- sc->fc.set_intr = fwohci_set_intr;
-
- sc->intmask = sc->irstat = sc->itstat = 0;
-
- /* Init task queue */
- sc->fc.taskqueue = fw_taskqueue_create_fast("fw_taskq", M_WAITOK,
- fw_taskqueue_thread_enqueue, &sc->fc.taskqueue);
- fw_taskqueue_start_threads(&sc->fc.taskqueue, 1, PI_NET, "fw%d_taskq",
- fw_get_unit(dev));
- FW_TASK_INIT(&sc->fwohci_task_busreset, 2, fwohci_task_busreset, sc);
- FW_TASK_INIT(&sc->fwohci_task_sid, 1, fwohci_task_sid, sc);
- FW_TASK_INIT(&sc->fwohci_task_dma, 0, fwohci_task_dma, sc);
-
- fw_init(&sc->fc);
- fwohci_reset(sc, dev);
- FWOHCI_INIT_END;
-
- return 0;
-}
-
-void
-fwohci_timeout(void *arg)
-{
- struct fwohci_softc *sc;
-
- sc = (struct fwohci_softc *)arg;
-}
-
-uint32_t
-fwohci_cyctimer(struct firewire_comm *fc)
-{
- struct fwohci_softc *sc = (struct fwohci_softc *)fc;
- return(OREAD(sc, OHCI_CYCLETIMER));
-}
-
-FWOHCI_DETACH()
-{
- int i;
-
- FWOHCI_DETACH_START;
- if (sc->sid_buf != NULL)
- fwdma_free(&sc->fc, &sc->sid_dma);
- if (sc->fc.config_rom != NULL)
- fwdma_free(&sc->fc, &sc->crom_dma);
-
- fwohci_db_free(&sc->arrq);
- fwohci_db_free(&sc->arrs);
-
- fwohci_db_free(&sc->atrq);
- fwohci_db_free(&sc->atrs);
-
- for( i = 0 ; i < sc->fc.nisodma ; i ++ ){
- fwohci_db_free(&sc->it[i]);
- fwohci_db_free(&sc->ir[i]);
- }
- FWOHCI_DETACH_END;
-
- return 0;
-}
-
-#define LAST_DB(dbtr, db) do { \
- struct fwohcidb_tr *_dbtr = (dbtr); \
- int _cnt = _dbtr->dbcnt; \
- db = &_dbtr->db[ (_cnt > 2) ? (_cnt -1) : 0]; \
-} while (0)
+#define LAST_DB(dbtr) \
+ &dbtr->db[(dbtr->dbcnt > 2) ? (dbtr->dbcnt - 1) : 0];
static void
-fwohci_execute_db(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+fwohci_execute_db(struct fwohcidb_tr *db_tr, bus_dmamap_t dmamap)
{
- struct fwohcidb_tr *db_tr;
struct fwohcidb *db;
bus_dma_segment_t *s;
int i;
- db_tr = (struct fwohcidb_tr *)arg;
db = &db_tr->db[db_tr->dbcnt];
- if (error) {
- if (firewire_debug || error != EFBIG)
- printf("fwohci_execute_db: error=%d\n", error);
- return;
- }
- for (i = 0; i < nseg; i++) {
- s = &segs[i];
+ for (i = 0; i < dmamap->dm_nsegs; i++) {
+ s = &dmamap->dm_segs[i];
FWOHCI_DMA_WRITE(db->db.desc.addr, s->ds_addr);
FWOHCI_DMA_WRITE(db->db.desc.cmd, s->ds_len);
FWOHCI_DMA_WRITE(db->db.desc.res, 0);
@@ -937,54 +1336,43 @@ fwohci_execute_db(void *arg, bus_dma_segment_t *segs, int nseg, int error)
}
static void
-fwohci_execute_db2(void *arg, bus_dma_segment_t *segs, int nseg,
- bus_size_t size, int error)
-{
- fwohci_execute_db(arg, segs, nseg, error);
-}
-
-static void
fwohci_start(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
{
- int i, s;
- int tcode, hdr_len, pl_off;
- int fsegment = -1;
- uint32_t off;
struct fw_xfer *xfer;
struct fw_pkt *fp;
struct fwohci_txpkthdr *ohcifp;
- struct fwohcidb_tr *db_tr;
+ struct fwohcidb_tr *db_tr, *kick;
struct fwohcidb *db;
uint32_t *ld;
+ int tcode, hdr_len, pl_off, fsegment = -1, i;
const struct tcode_info *info;
- static int maxdesc=0;
+ static int maxdesc = 0;
- FW_GLOCK_ASSERT(&sc->fc);
+ KASSERT(mutex_owned(&dbch->xferq.q_mtx));
- if(&sc->atrq == dbch){
- off = OHCI_ATQOFF;
- }else if(&sc->atrs == dbch){
- off = OHCI_ATSOFF;
- }else{
- return;
- }
+#if DIAGNOSTIC
+ if (dbch->off != OHCI_ATQOFF &&
+ dbch->off != OHCI_ATSOFF)
+ panic("not async tx");
+#endif
if (dbch->flags & FWOHCI_DBCH_FULL)
return;
- s = splfw();
- fwdma_sync_multiseg_all(dbch->am,
- BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
db_tr = dbch->top;
+ kick = db_tr;
+ if (dbch->pdb_tr != NULL) {
+ kick = dbch->pdb_tr;
+ fwdma_sync_multiseg(dbch->am, kick->idx, kick->idx,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ }
txloop:
xfer = STAILQ_FIRST(&dbch->xferq.q);
- if(xfer == NULL){
+ if (xfer == NULL)
goto kick;
- }
#if 0
- if(dbch->xferq.queued == 0 ){
- fw_printf(sc->fc.dev, "TX queue empty\n");
- }
+ if (dbch->xferq.queued == 0)
+ aprint_error_dev(sc->fc.dev, "TX queue empty\n");
#endif
STAILQ_REMOVE_HEAD(&dbch->xferq.q, link);
db_tr->xfer = xfer;
@@ -997,13 +1385,13 @@ txloop:
info = &tinfo[tcode];
hdr_len = pl_off = info->hdr_len;
- ld = &ohcifp->mode.ld[0];
+ ld = ohcifp->mode.ld;
ld[0] = ld[1] = ld[2] = ld[3] = 0;
- for( i = 0 ; i < pl_off ; i+= 4)
- ld[i/4] = fp->mode.ld[i/4];
+ for (i = 0; i < pl_off / 4; i++)
+ ld[i] = fp->mode.ld[i];
ohcifp->mode.common.spd = xfer->send.spd & 0x7;
- if (tcode == FWTCODE_STREAM ){
+ if (tcode == FWTCODE_STREAM) {
hdr_len = 8;
ohcifp->mode.stream.len = fp->mode.stream.len;
} else if (tcode == FWTCODE_PHY) {
@@ -1017,20 +1405,19 @@ txloop:
ohcifp->mode.asycomm.srcbus = OHCI_ASYSRCBUS;
ohcifp->mode.asycomm.tlrt |= FWRETRY_X;
}
- db = &db_tr->db[0];
+ db = db_tr->db;
FWOHCI_DMA_WRITE(db->db.desc.cmd,
- OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | hdr_len);
+ OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | hdr_len);
FWOHCI_DMA_WRITE(db->db.desc.addr, 0);
FWOHCI_DMA_WRITE(db->db.desc.res, 0);
/* Specify bound timer of asy. responce */
- if(&sc->atrs == dbch){
+ if (dbch->off != OHCI_ATSOFF)
FWOHCI_DMA_WRITE(db->db.desc.res,
- (OREAD(sc, OHCI_CYCLETIMER) >> 12) + (1 << 13));
- }
+ (OREAD(sc, OHCI_CYCLETIMER) >> 12) + (1 << 13));
#if BYTE_ORDER == BIG_ENDIAN
if (tcode == FWTCODE_WREQQ || tcode == FWTCODE_RRESQ)
hdr_len = 12;
- for (i = 0; i < hdr_len/4; i ++)
+ for (i = 0; i < hdr_len / 4; i++)
FWOHCI_DMA_WRITE(ld[i], ld[i]);
#endif
@@ -1040,93 +1427,92 @@ again:
if (xfer->send.pay_len > 0) {
int err;
/* handle payload */
- if (xfer->mbuf == NULL) {
- err = fw_bus_dmamap_load(dbch->dmat, db_tr->dma_map,
- &xfer->send.payload[0], xfer->send.pay_len,
- fwohci_execute_db, db_tr,
- BUS_DMA_WAITOK);
- } else {
+ if (xfer->mbuf == NULL)
+ err = bus_dmamap_load(sc->fc.dmat, db_tr->dma_map,
+ xfer->send.payload, xfer->send.pay_len, NULL,
+ BUS_DMA_WAITOK);
+ else {
/* XXX we can handle only 6 (=8-2) mbuf chains */
- err = fw_bus_dmamap_load_mbuf(dbch->dmat,
- db_tr->dma_map, xfer->mbuf,
- fwohci_execute_db2, db_tr,
- BUS_DMA_WAITOK);
+ err = bus_dmamap_load_mbuf(sc->fc.dmat, db_tr->dma_map,
+ xfer->mbuf, BUS_DMA_WAITOK);
if (err == EFBIG) {
struct mbuf *m0;
if (firewire_debug)
- fw_printf(sc->fc.dev, "EFBIG.\n");
+ printf("EFBIG.\n");
m0 = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
if (m0 != NULL) {
m_copydata(xfer->mbuf, 0,
- xfer->mbuf->m_pkthdr.len,
- mtod(m0, void *));
+ xfer->mbuf->m_pkthdr.len,
+ mtod(m0, void *));
m0->m_len = m0->m_pkthdr.len =
- xfer->mbuf->m_pkthdr.len;
+ xfer->mbuf->m_pkthdr.len;
m_freem(xfer->mbuf);
xfer->mbuf = m0;
goto again;
}
- fw_printf(sc->fc.dev, "m_getcl failed.\n");
+ aprint_error_dev(sc->fc.dev,
+ "m_getcl failed.\n");
}
}
- if (err)
- printf("dmamap_load: err=%d\n", err);
- fw_bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
- BUS_DMASYNC_PREWRITE);
+ if (!err)
+ fwohci_execute_db(db_tr, db_tr->dma_map);
+ else
+ aprint_error_dev(sc->fc.dev,
+ "dmamap_load: err=%d\n", err);
+ bus_dmamap_sync(sc->fc.dmat, db_tr->dma_map,
+ 0, db_tr->dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
#if 0 /* OHCI_OUTPUT_MODE == 0 */
for (i = 2; i < db_tr->dbcnt; i++)
FWOHCI_DMA_SET(db_tr->db[i].db.desc.cmd,
- OHCI_OUTPUT_MORE);
+ OHCI_OUTPUT_MORE);
#endif
}
if (maxdesc < db_tr->dbcnt) {
maxdesc = db_tr->dbcnt;
if (firewire_debug)
- fw_printf(sc->fc.dev, "maxdesc: %d\n", maxdesc);
+ printf("maxdesc: %d\n", maxdesc);
}
/* last db */
- LAST_DB(db_tr, db);
+ db = LAST_DB(db_tr);
FWOHCI_DMA_SET(db->db.desc.cmd,
- OHCI_OUTPUT_LAST | OHCI_INTERRUPT_ALWAYS | OHCI_BRANCH_ALWAYS);
+ OHCI_OUTPUT_LAST | OHCI_INTERRUPT_ALWAYS | OHCI_BRANCH_ALWAYS);
FWOHCI_DMA_WRITE(db->db.desc.depend,
- STAILQ_NEXT(db_tr, link)->bus_addr);
+ STAILQ_NEXT(db_tr, link)->bus_addr);
- if(fsegment == -1 )
+ if (fsegment == -1)
fsegment = db_tr->dbcnt;
if (dbch->pdb_tr != NULL) {
- LAST_DB(dbch->pdb_tr, db);
+ db = LAST_DB(dbch->pdb_tr);
FWOHCI_DMA_SET(db->db.desc.depend, db_tr->dbcnt);
}
- dbch->xferq.queued ++;
+ dbch->xferq.queued++;
dbch->pdb_tr = db_tr;
db_tr = STAILQ_NEXT(db_tr, link);
- if(db_tr != dbch->bottom){
+ if (db_tr != dbch->bottom)
goto txloop;
- } else {
- fw_printf(sc->fc.dev, "fwohci_start: lack of db_trq\n");
+ else {
+ aprint_error_dev(sc->fc.dev, "fwohci_start: lack of db_trq\n");
dbch->flags |= FWOHCI_DBCH_FULL;
}
kick:
/* kick asy q */
- fwdma_sync_multiseg_all(dbch->am,
+ fwdma_sync_multiseg(dbch->am, kick->idx, dbch->pdb_tr->idx,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- if(dbch->xferq.flag & FWXFERQ_RUNNING) {
- OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
- } else {
+ if (dbch->xferq.flag & FWXFERQ_RUNNING)
+ OWRITE(sc, OHCI_DMACTL(dbch->off), OHCI_CNTL_DMA_WAKE);
+ else {
if (firewire_debug)
- fw_printf(sc->fc.dev, "start AT DMA status=%x\n",
- OREAD(sc, OHCI_DMACTL(off)));
- OWRITE(sc, OHCI_DMACMD(off), dbch->top->bus_addr | fsegment);
- OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_RUN);
+ printf("start AT DMA status=%x\n",
+ OREAD(sc, OHCI_DMACTL(dbch->off)));
+ OWRITE(sc, OHCI_DMACMD(dbch->off),
+ dbch->top->bus_addr | fsegment);
+ OWRITE(sc, OHCI_DMACTL(dbch->off), OHCI_CNTL_DMA_RUN);
dbch->xferq.flag |= FWXFERQ_RUNNING;
}
- CTR0(KTR_DEV, "start kick done");
- CTR0(KTR_DEV, "start kick done2");
dbch->top = db_tr;
- splx(s);
return;
}
@@ -1134,9 +1520,11 @@ static void
fwohci_start_atq(struct firewire_comm *fc)
{
struct fwohci_softc *sc = (struct fwohci_softc *)fc;
- FW_GLOCK(&sc->fc);
- fwohci_start( sc, &(sc->atrq));
- FW_GUNLOCK(&sc->fc);
+ struct fwohci_dbch *dbch = &sc->atrq;
+
+ mutex_enter(&dbch->xferq.q_mtx);
+ fwohci_start(sc, dbch);
+ mutex_exit(&dbch->xferq.q_mtx);
return;
}
@@ -1144,84 +1532,88 @@ static void
fwohci_start_ats(struct firewire_comm *fc)
{
struct fwohci_softc *sc = (struct fwohci_softc *)fc;
- FW_GLOCK(&sc->fc);
- fwohci_start( sc, &(sc->atrs));
- FW_GUNLOCK(&sc->fc);
+ struct fwohci_dbch *dbch = &sc->atrs;
+
+ mutex_enter(&dbch->xferq.q_mtx);
+ fwohci_start(sc, dbch);
+ mutex_exit(&dbch->xferq.q_mtx);
return;
}
-void
+static void
fwohci_txd(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
{
- int s, ch, err = 0;
+ struct firewire_comm *fc = &sc->fc;
struct fwohcidb_tr *tr;
struct fwohcidb *db;
struct fw_xfer *xfer;
- uint32_t off;
u_int stat, status;
- int packets;
- struct firewire_comm *fc = (struct firewire_comm *)sc;
+ int packets = 0, ch, err = 0;
- if(&sc->atrq == dbch){
- off = OHCI_ATQOFF;
+#if DIAGNOSTIC
+ if (dbch->off != OHCI_ATQOFF &&
+ dbch->off != OHCI_ATSOFF)
+ panic("not async tx");
+#endif
+ if (dbch->off == OHCI_ATQOFF)
ch = ATRQ_CH;
- }else if(&sc->atrs == dbch){
- off = OHCI_ATSOFF;
+ else /* OHCI_ATSOFF */
ch = ATRS_CH;
- }else{
- return;
- }
- s = splfw();
+
+ mutex_enter(&dbch->xferq.q_mtx);
tr = dbch->bottom;
- packets = 0;
- fwdma_sync_multiseg_all(dbch->am,
- BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- while(dbch->xferq.queued > 0){
- LAST_DB(tr, db);
+ while (dbch->xferq.queued > 0) {
+ fwdma_sync_multiseg(dbch->am, tr->idx, tr->idx,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ db = LAST_DB(tr);
status = FWOHCI_DMA_READ(db->db.desc.res) >> OHCI_STATUS_SHIFT;
- if(!(status & OHCI_CNTL_DMA_ACTIVE)){
- if (fc->status != FWBUSINIT)
- /* maybe out of order?? */
+ if (!(status & OHCI_CNTL_DMA_ACTIVE))
+ if (fc->status != FWBUSINIT)
goto out;
- }
if (tr->xfer->send.pay_len > 0) {
- fw_bus_dmamap_sync(dbch->dmat, tr->dma_map,
- BUS_DMASYNC_POSTWRITE);
- fw_bus_dmamap_unload(dbch->dmat, tr->dma_map);
+ bus_dmamap_sync(fc->dmat, tr->dma_map,
+ 0, tr->dma_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(fc->dmat, tr->dma_map);
}
#if 1
if (firewire_debug > 1)
dump_db(sc, ch);
#endif
- if(status & OHCI_CNTL_DMA_DEAD) {
+ if (status & OHCI_CNTL_DMA_DEAD) {
/* Stop DMA */
- OWRITE(sc, OHCI_DMACTLCLR(off), OHCI_CNTL_DMA_RUN);
- fw_printf(sc->fc.dev, "force reset AT FIFO\n");
+ OWRITE(sc, OHCI_DMACTLCLR(dbch->off),
+ OHCI_CNTL_DMA_RUN);
+ aprint_error_dev(fc->dev, "force reset AT FIFO\n");
OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_LINKEN);
OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LPS | OHCI_HCC_LINKEN);
- OWRITE(sc, OHCI_DMACTLCLR(off), OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, OHCI_DMACTLCLR(dbch->off),
+ OHCI_CNTL_DMA_RUN);
}
stat = status & FWOHCIEV_MASK;
- switch(stat){
+ switch(stat) {
case FWOHCIEV_ACKPEND:
- CTR0(KTR_DEV, "txd: ack pending");
- /* fall through */
+
+ /* FALLTHROUGH */
+
case FWOHCIEV_ACKCOMPL:
err = 0;
break;
+
case FWOHCIEV_ACKBSA:
case FWOHCIEV_ACKBSB:
case FWOHCIEV_ACKBSX:
- fw_printf(sc->fc.dev, "txd err=%2x %s\n", stat,
+ aprint_error_dev(fc->dev, "txd err=%2x %s\n", stat,
fwohcicode[stat]);
err = EBUSY;
break;
+
case FWOHCIEV_FLUSHED:
case FWOHCIEV_ACKTARD:
- fw_printf(sc->fc.dev, "txd err=%2x %s\n", stat,
+ aprint_error_dev(fc->dev, "txd err=%2x %s\n", stat,
fwohcicode[stat]);
err = EAGAIN;
break;
+
case FWOHCIEV_MISSACK:
case FWOHCIEV_UNDRRUN:
case FWOHCIEV_OVRRUN:
@@ -1233,14 +1625,17 @@ fwohci_txd(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
case FWOHCIEV_ACKDERR:
case FWOHCIEV_ACKTERR:
default:
- fw_printf(sc->fc.dev, "txd err=%2x %s\n",
- stat, fwohcicode[stat]);
+ aprint_error_dev(fc->dev, "txd err=%2x %s\n", stat,
+ fwohcicode[stat]);
err = EINVAL;
break;
}
+ dbch->xferq.queued--;
+ dbch->bottom = STAILQ_NEXT(tr, link);
if (tr->xfer != NULL) {
xfer = tr->xfer;
- CTR0(KTR_DEV, "txd");
+ tr->xfer = NULL;
+ mutex_exit(&dbch->xferq.q_mtx);
if (xfer->flag & FWXF_RCVD) {
#if 0
if (firewire_debug)
@@ -1263,60 +1658,50 @@ fwohci_txd(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
fw_xfer_done(xfer);
}
}
+ mutex_enter(&dbch->xferq.q_mtx);
/*
* The watchdog timer takes care of split
* transcation timeout for ACKPEND case.
*/
- } else {
- printf("this shouldn't happen\n");
- }
- FW_GLOCK(fc);
- dbch->xferq.queued --;
- FW_GUNLOCK(fc);
- tr->xfer = NULL;
-
- fwdma_sync_multiseg_all(dbch->am, BUS_DMASYNC_PREREAD);
- packets ++;
- tr = STAILQ_NEXT(tr, link);
- dbch->bottom = tr;
+ } else
+ aprint_error_dev(fc->dev, "this shouldn't happen\n");
+ packets++;
if (dbch->bottom == dbch->top) {
/* we reaches the end of context program */
if (firewire_debug && dbch->xferq.queued > 0)
printf("queued > 0\n");
break;
}
+ tr = dbch->bottom;
}
out:
+ if (dbch->xferq.queued > 0 || packets > 0)
+ fwdma_sync_multiseg(dbch->am, tr->idx, tr->idx,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
if ((dbch->flags & FWOHCI_DBCH_FULL) && packets > 0) {
- printf("make free slot\n");
+ aprint_normal_dev(fc->dev, "make free slot\n");
dbch->flags &= ~FWOHCI_DBCH_FULL;
- FW_GLOCK(fc);
fwohci_start(sc, dbch);
- FW_GUNLOCK(fc);
}
- fwdma_sync_multiseg_all(
- dbch->am, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- splx(s);
+ mutex_exit(&dbch->xferq.q_mtx);
}
static void
-fwohci_db_free(struct fwohci_dbch *dbch)
+fwohci_db_free(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
{
struct fwohcidb_tr *db_tr;
- int idb;
if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
return;
- for(db_tr = STAILQ_FIRST(&dbch->db_trq), idb = 0; idb < dbch->ndb;
- db_tr = STAILQ_NEXT(db_tr, link), idb++){
+ for (db_tr = STAILQ_FIRST(&dbch->db_trq); db_tr != NULL;
+ db_tr = STAILQ_NEXT(db_tr, link)) {
+ bus_dmamap_destroy(sc->fc.dmat, db_tr->dma_map);
if ((dbch->xferq.flag & FWXFERQ_EXTBUF) == 0 &&
- db_tr->buf != NULL) {
- fwdma_free_size(dbch->dmat, db_tr->dma_map,
- db_tr->buf, dbch->xferq.psize);
+ db_tr->buf != NULL) {
+ fwdma_free(sc->fc.dmat, db_tr->dma_map, db_tr->buf);
db_tr->buf = NULL;
- } else if (db_tr->dma_map != NULL)
- fw_bus_dmamap_destroy(dbch->dmat, db_tr->dma_map);
+ }
}
dbch->ndb = 0;
db_tr = STAILQ_FIRST(&dbch->db_trq);
@@ -1330,74 +1715,82 @@ fwohci_db_free(struct fwohci_dbch *dbch)
static void
fwohci_db_init(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
{
- int idb;
- struct fwohcidb_tr *db_tr;
+ struct firewire_comm *fc = &sc->fc;
+ struct fwohcidb_tr *db_tr, *lastq, *tmpq;
+ int idb;
+ const int db_tr_sz = sizeof(struct fwohcidb_tr) * dbch->ndb;
if ((dbch->flags & FWOHCI_DBCH_INIT) != 0)
goto out;
- /* create dma_tag for buffers */
-#define MAX_REQCOUNT 0xffff
- if (fw_bus_dma_tag_create(/*parent*/ sc->fc.dmat,
- /*alignment*/ 1, /*boundary*/ 0,
- /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
- /*highaddr*/ BUS_SPACE_MAXADDR,
- /*filter*/NULL, /*filterarg*/NULL,
- /*maxsize*/ dbch->xferq.psize,
- /*nsegments*/ dbch->ndesc > 3 ? dbch->ndesc - 2 : 1,
- /*maxsegsz*/ MAX_REQCOUNT,
- /*flags*/ 0,
- /*lockfunc*/busdma_lock_mutex,
- /*lockarg*/FW_GMTX(&sc->fc),
- &dbch->dmat))
- return;
-
/* allocate DB entries and attach one to each DMA channels */
/* DB entry must start at 16 bytes bounary. */
STAILQ_INIT(&dbch->db_trq);
- db_tr = (struct fwohcidb_tr *)
- malloc(sizeof(struct fwohcidb_tr) * dbch->ndb,
- M_FW, M_WAITOK | M_ZERO);
- if(db_tr == NULL){
- printf("fwohci_db_init: malloc(1) failed\n");
+ db_tr = (struct fwohcidb_tr *)malloc(db_tr_sz, M_FW, M_WAITOK | M_ZERO);
+ if (db_tr == NULL) {
+ aprint_error_dev(fc->dev, "malloc(1) failed\n");
return;
}
#define DB_SIZE(x) (sizeof(struct fwohcidb) * (x)->ndesc)
- dbch->am = fwdma_malloc_multiseg(&sc->fc, DB_SIZE(dbch),
- DB_SIZE(dbch), dbch->ndb, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
+ dbch->am = fwdma_malloc_multiseg(fc, DB_SIZE(dbch), DB_SIZE(dbch),
+#if 0
+ dbch->ndb, BUS_DMA_WAITOK);
+#else /* Ooops, debugging now... */
+ dbch->ndb, BUS_DMA_WAITOK |
+ (dbch->off == OHCI_ARQOFF || dbch->off == OHCI_ARSOFF) ?
+ BUS_DMA_COHERENT : 0);
+#endif
if (dbch->am == NULL) {
- printf("fwohci_db_init: fwdma_malloc_multiseg failed\n");
+ aprint_error_dev(fc->dev, "fwdma_malloc_multiseg failed\n");
free(db_tr, M_FW);
return;
}
/* Attach DB to DMA ch. */
- for(idb = 0 ; idb < dbch->ndb ; idb++){
+ for (idb = 0; idb < dbch->ndb; idb++) {
+ db_tr->idx = idb;
db_tr->dbcnt = 0;
db_tr->db = (struct fwohcidb *)fwdma_v_addr(dbch->am, idb);
db_tr->bus_addr = fwdma_bus_addr(dbch->am, idb);
/* create dmamap for buffers */
- /* XXX do we need 4bytes alignment tag? */
- /* XXX don't alloc dma_map for AR */
- if (fw_bus_dmamap_create(dbch->dmat, 0, &db_tr->dma_map) != 0) {
- printf("fw_bus_dmamap_create failed\n");
+#define MAX_REQCOUNT 0xffff
+ if (bus_dmamap_create(fc->dmat, dbch->xferq.psize,
+ dbch->ndesc > 3 ? dbch->ndesc - 2 : 1, MAX_REQCOUNT, 0,
+ 0, &db_tr->dma_map) != 0) {
+ aprint_error_dev(fc->dev, "bus_dmamap_create failed\n");
dbch->flags = FWOHCI_DBCH_INIT; /* XXX fake */
- fwohci_db_free(dbch);
+ fwohci_db_free(sc, dbch);
return;
}
+ if (dbch->off == OHCI_ARQOFF ||
+ dbch->off == OHCI_ARSOFF) {
+ db_tr->buf = fwdma_malloc(fc->dev, fc->dmat,
+ &db_tr->dma_map, dbch->xferq.psize, 1,
+ BUS_DMA_NOWAIT);
+ if (db_tr->buf == NULL) {
+ aprint_error_dev(fc->dev,
+ "fwdma_malloc failed\n");
+ dbch->flags = FWOHCI_DBCH_INIT; /* XXX fake */
+ fwohci_db_free(sc, dbch);
+ return;
+ }
+ }
STAILQ_INSERT_TAIL(&dbch->db_trq, db_tr, link);
if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
+ struct fw_bulkxfer *bulkxfer =
+ &dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket];
+
if (idb % dbch->xferq.bnpacket == 0)
- dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket
- ].start = (void *)db_tr;
+ bulkxfer->start = (void *)db_tr;
if ((idb + 1) % dbch->xferq.bnpacket == 0)
- dbch->xferq.bulkxfer[idb / dbch->xferq.bnpacket
- ].end = (void *)db_tr;
+ bulkxfer->end = (void *)db_tr;
}
db_tr++;
}
- STAILQ_LAST(&dbch->db_trq, fwohcidb_tr,link)->link.stqe_next
- = STAILQ_FIRST(&dbch->db_trq);
+ lastq = NULL;
+ STAILQ_FOREACH(tmpq, &dbch->db_trq, link)
+ lastq = tmpq;
+ lastq->link.stqe_next = STAILQ_FIRST(&dbch->db_trq);
out:
dbch->xferq.queued = 0;
dbch->pdb_tr = NULL;
@@ -1408,186 +1801,115 @@ out:
}
static int
-fwohci_itx_disable(struct firewire_comm *fc, int dmach)
-{
- struct fwohci_softc *sc = (struct fwohci_softc *)fc;
- int sleepch;
-
- OWRITE(sc, OHCI_ITCTLCLR(dmach),
- OHCI_CNTL_DMA_RUN | OHCI_CNTL_CYCMATCH_S);
- OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach);
- OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach);
- /* XXX we cannot free buffers until the DMA really stops */
- tsleep((void *)&sleepch, FWPRI, "fwitxd", hz);
- fwohci_db_free(&sc->it[dmach]);
- sc->it[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
- return 0;
-}
-
-static int
-fwohci_irx_disable(struct firewire_comm *fc, int dmach)
-{
- struct fwohci_softc *sc = (struct fwohci_softc *)fc;
- int sleepch;
-
- OWRITE(sc, OHCI_IRCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
- OWRITE(sc, OHCI_IR_MASKCLR, 1 << dmach);
- OWRITE(sc, OHCI_IR_STATCLR, 1 << dmach);
- /* XXX we cannot free buffers until the DMA really stops */
- tsleep((void *)&sleepch, FWPRI, "fwirxd", hz);
- fwohci_db_free(&sc->ir[dmach]);
- sc->ir[dmach].xferq.flag &= ~FWXFERQ_RUNNING;
- return 0;
-}
-
-#if BYTE_ORDER == BIG_ENDIAN
-static void
-fwohci_irx_post (struct firewire_comm *fc , uint32_t *qld)
-{
- qld[0] = FWOHCI_DMA_READ(qld[0]);
- return;
-}
-#endif
-
-static int
fwohci_tx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
{
int err = 0;
int idb, z, i, dmach = 0, ldesc;
- uint32_t off = 0;
struct fwohcidb_tr *db_tr;
struct fwohcidb *db;
- if(!(dbch->xferq.flag & FWXFERQ_EXTBUF)){
+ if (!(dbch->xferq.flag & FWXFERQ_EXTBUF)) {
err = EINVAL;
return err;
}
z = dbch->ndesc;
- for(dmach = 0 ; dmach < sc->fc.nisodma ; dmach++){
- if( &sc->it[dmach] == dbch){
- off = OHCI_ITOFF(dmach);
+ for (dmach = 0; dmach < sc->fc.nisodma; dmach++)
+ if (dbch->off == sc->it[dmach].off)
break;
- }
- }
- if(off == 0){
+ if (dmach == sc->fc.nisodma) {
err = EINVAL;
return err;
}
- if(dbch->xferq.flag & FWXFERQ_RUNNING)
+ if (dbch->xferq.flag & FWXFERQ_RUNNING)
return err;
dbch->xferq.flag |= FWXFERQ_RUNNING;
- for( i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++){
+ for (i = 0, dbch->bottom = dbch->top; i < dbch->ndb - 1; i++)
dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
- }
db_tr = dbch->top;
- for (idb = 0; idb < dbch->ndb; idb ++) {
+ for (idb = 0; idb < dbch->ndb; idb++) {
fwohci_add_tx_buf(dbch, db_tr, idb);
- if(STAILQ_NEXT(db_tr, link) == NULL){
+ if (STAILQ_NEXT(db_tr, link) == NULL)
break;
- }
db = db_tr->db;
ldesc = db_tr->dbcnt - 1;
FWOHCI_DMA_WRITE(db[0].db.desc.depend,
- STAILQ_NEXT(db_tr, link)->bus_addr | z);
+ STAILQ_NEXT(db_tr, link)->bus_addr | z);
db[ldesc].db.desc.depend = db[0].db.desc.depend;
- if(dbch->xferq.flag & FWXFERQ_EXTBUF){
- if(((idb + 1 ) % dbch->xferq.bnpacket) == 0){
- FWOHCI_DMA_SET(
- db[ldesc].db.desc.cmd,
- OHCI_INTERRUPT_ALWAYS);
+ if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
+ if (((idb + 1) % dbch->xferq.bnpacket) == 0) {
+ FWOHCI_DMA_SET(db[ldesc].db.desc.cmd,
+ OHCI_INTERRUPT_ALWAYS);
/* OHCI 1.1 and above */
- FWOHCI_DMA_SET(
- db[0].db.desc.cmd,
- OHCI_INTERRUPT_ALWAYS);
+ FWOHCI_DMA_SET(db[0].db.desc.cmd,
+ OHCI_INTERRUPT_ALWAYS);
}
}
db_tr = STAILQ_NEXT(db_tr, link);
}
FWOHCI_DMA_CLEAR(
- dbch->bottom->db[dbch->bottom->dbcnt - 1].db.desc.depend, 0xf);
+ dbch->bottom->db[dbch->bottom->dbcnt - 1].db.desc.depend, 0xf);
return err;
}
static int
fwohci_rx_enable(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
{
- int err = 0;
- int idb, z, i, dmach = 0, ldesc;
- uint32_t off = 0;
struct fwohcidb_tr *db_tr;
struct fwohcidb *db;
+ int idb, z, i, ldesc, err = 0;
z = dbch->ndesc;
- if(&sc->arrq == dbch){
- off = OHCI_ARQOFF;
- }else if(&sc->arrs == dbch){
- off = OHCI_ARSOFF;
- }else{
- for(dmach = 0 ; dmach < sc->fc.nisodma ; dmach++){
- if( &sc->ir[dmach] == dbch){
- off = OHCI_IROFF(dmach);
- break;
- }
- }
- }
- if(off == 0){
- err = EINVAL;
- return err;
- }
- if(dbch->xferq.flag & FWXFERQ_STREAM){
- if(dbch->xferq.flag & FWXFERQ_RUNNING)
+ if (dbch->xferq.flag & FWXFERQ_STREAM) {
+ if (dbch->xferq.flag & FWXFERQ_RUNNING)
return err;
- }else{
- if(dbch->xferq.flag & FWXFERQ_RUNNING){
+ } else
+ if (dbch->xferq.flag & FWXFERQ_RUNNING) {
err = EBUSY;
return err;
}
- }
dbch->xferq.flag |= FWXFERQ_RUNNING;
dbch->top = STAILQ_FIRST(&dbch->db_trq);
- for( i = 0, dbch->bottom = dbch->top; i < (dbch->ndb - 1); i++){
+ for (i = 0, dbch->bottom = dbch->top; i < dbch->ndb - 1; i++)
dbch->bottom = STAILQ_NEXT(dbch->bottom, link);
- }
db_tr = dbch->top;
if (db_tr->dbcnt != 0)
goto run;
- for (idb = 0; idb < dbch->ndb; idb ++) {
+ for (idb = 0; idb < dbch->ndb; idb++) {
+ if (dbch->off == OHCI_ARQOFF ||
+ dbch->off == OHCI_ARSOFF)
+ bus_dmamap_sync(sc->fc.dmat, db_tr->dma_map,
+ 0, db_tr->dma_map->dm_mapsize, BUS_DMASYNC_PREREAD);
fwohci_add_rx_buf(dbch, db_tr, idb, &sc->dummy_dma);
if (STAILQ_NEXT(db_tr, link) == NULL)
break;
db = db_tr->db;
ldesc = db_tr->dbcnt - 1;
FWOHCI_DMA_WRITE(db[ldesc].db.desc.depend,
- STAILQ_NEXT(db_tr, link)->bus_addr | z);
- if(dbch->xferq.flag & FWXFERQ_EXTBUF){
- if(((idb + 1 ) % dbch->xferq.bnpacket) == 0){
- FWOHCI_DMA_SET(
- db[ldesc].db.desc.cmd,
- OHCI_INTERRUPT_ALWAYS);
- FWOHCI_DMA_CLEAR(
- db[ldesc].db.desc.depend,
- 0xf);
+ STAILQ_NEXT(db_tr, link)->bus_addr | z);
+ if (dbch->xferq.flag & FWXFERQ_EXTBUF) {
+ if (((idb + 1) % dbch->xferq.bnpacket) == 0) {
+ FWOHCI_DMA_SET(db[ldesc].db.desc.cmd,
+ OHCI_INTERRUPT_ALWAYS);
+ FWOHCI_DMA_CLEAR(db[ldesc].db.desc.depend, 0xf);
}
}
db_tr = STAILQ_NEXT(db_tr, link);
}
- FWOHCI_DMA_CLEAR(
- dbch->bottom->db[db_tr->dbcnt - 1].db.desc.depend, 0xf);
+ FWOHCI_DMA_CLEAR(dbch->bottom->db[db_tr->dbcnt - 1].db.desc.depend,
+ 0xf);
dbch->buf_offset = 0;
run:
fwdma_sync_multiseg_all(dbch->am,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- if(dbch->xferq.flag & FWXFERQ_STREAM){
- return err;
- }else{
- OWRITE(sc, OHCI_DMACMD(off), dbch->top->bus_addr | z);
+ if (!(dbch->xferq.flag & FWXFERQ_STREAM)) {
+ OWRITE(sc, OHCI_DMACMD(dbch->off), dbch->top->bus_addr | z);
+ OWRITE(sc, OHCI_DMACTL(dbch->off), OHCI_CNTL_DMA_RUN);
}
- OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_RUN);
return err;
}
static int
-fwohci_next_cycle(struct firewire_comm *fc, int cycle_now)
+fwohci_next_cycle(struct fwohci_softc *sc, int cycle_now)
{
int sec, cycle, cycle_match;
@@ -1601,12 +1923,12 @@ fwohci_next_cycle(struct firewire_comm *fc, int cycle_now)
#endif
cycle = cycle + CYCLE_DELAY;
if (cycle >= 8000) {
- sec ++;
+ sec++;
cycle -= 8000;
}
cycle = roundup2(cycle, CYCLE_MOD);
if (cycle >= 8000) {
- sec ++;
+ sec++;
if (cycle == 8000)
cycle = 0;
else
@@ -1614,358 +1936,68 @@ fwohci_next_cycle(struct firewire_comm *fc, int cycle_now)
}
cycle_match = ((sec << 13) | cycle) & 0x7ffff;
- return(cycle_match);
-}
-
-static int
-fwohci_itxbuf_enable(struct firewire_comm *fc, int dmach)
-{
- struct fwohci_softc *sc = (struct fwohci_softc *)fc;
- int err = 0;
- unsigned short tag, ich;
- struct fwohci_dbch *dbch;
- int cycle_match, cycle_now, s, ldesc;
- uint32_t stat;
- struct fw_bulkxfer *first, *chunk, *prev;
- struct fw_xferq *it;
-
- dbch = &sc->it[dmach];
- it = &dbch->xferq;
-
- tag = (it->flag >> 6) & 3;
- ich = it->flag & 0x3f;
- if ((dbch->flags & FWOHCI_DBCH_INIT) == 0) {
- dbch->ndb = it->bnpacket * it->bnchunk;
- dbch->ndesc = 3;
- fwohci_db_init(sc, dbch);
- if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
- return ENOMEM;
-
- err = fwohci_tx_enable(sc, dbch);
- }
- if(err)
- return err;
-
- ldesc = dbch->ndesc - 1;
- s = splfw();
- FW_GLOCK(fc);
- prev = STAILQ_LAST(&it->stdma, fw_bulkxfer, link);
- while ((chunk = STAILQ_FIRST(&it->stvalid)) != NULL) {
- struct fwohcidb *db;
-
- fwdma_sync_multiseg(it->buf, chunk->poffset, it->bnpacket,
- BUS_DMASYNC_PREWRITE);
- fwohci_txbufdb(sc, dmach, chunk);
- if (prev != NULL) {
- db = ((struct fwohcidb_tr *)(prev->end))->db;
-#if 0 /* XXX necessary? */
- FWOHCI_DMA_SET(db[ldesc].db.desc.cmd,
- OHCI_BRANCH_ALWAYS);
-#endif
-#if 0 /* if bulkxfer->npacket changes */
- db[ldesc].db.desc.depend = db[0].db.desc.depend =
- ((struct fwohcidb_tr *)
- (chunk->start))->bus_addr | dbch->ndesc;
-#else
- FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
- FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
-#endif
- }
- STAILQ_REMOVE_HEAD(&it->stvalid, link);
- STAILQ_INSERT_TAIL(&it->stdma, chunk, link);
- prev = chunk;
- }
- FW_GUNLOCK(fc);
- fwdma_sync_multiseg_all(dbch->am,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- splx(s);
- stat = OREAD(sc, OHCI_ITCTL(dmach));
- if (firewire_debug && (stat & OHCI_CNTL_CYCMATCH_S))
- printf("stat 0x%x\n", stat);
-
- if (stat & (OHCI_CNTL_DMA_ACTIVE | OHCI_CNTL_CYCMATCH_S))
- return 0;
-
-#if 0
- OWRITE(sc, OHCI_ITCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
-#endif
- OWRITE(sc, OHCI_IT_MASKCLR, 1 << dmach);
- OWRITE(sc, OHCI_IT_STATCLR, 1 << dmach);
- OWRITE(sc, OHCI_IT_MASK, 1 << dmach);
- OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IT);
-
- first = STAILQ_FIRST(&it->stdma);
- OWRITE(sc, OHCI_ITCMD(dmach),
- ((struct fwohcidb_tr *)(first->start))->bus_addr | dbch->ndesc);
- if (firewire_debug > 1) {
- printf("fwohci_itxbuf_enable: kick 0x%08x\n", stat);
-#if 1
- dump_dma(sc, ITX_CH + dmach);
-#endif
- }
- if ((stat & OHCI_CNTL_DMA_RUN) == 0) {
-#if 1
- /* Don't start until all chunks are buffered */
- if (STAILQ_FIRST(&it->stfree) != NULL)
- goto out;
-#endif
-#if 1
- /* Clear cycle match counter bits */
- OWRITE(sc, OHCI_ITCTLCLR(dmach), 0xffff0000);
-
- /* 2bit second + 13bit cycle */
- cycle_now = (fc->cyctimer(fc) >> 12) & 0x7fff;
- cycle_match = fwohci_next_cycle(fc, cycle_now);
-
- OWRITE(sc, OHCI_ITCTL(dmach),
- OHCI_CNTL_CYCMATCH_S | (cycle_match << 16)
- | OHCI_CNTL_DMA_RUN);
-#else
- OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_RUN);
-#endif
- if (firewire_debug > 1) {
- printf("cycle_match: 0x%04x->0x%04x\n",
- cycle_now, cycle_match);
- dump_dma(sc, ITX_CH + dmach);
- dump_db(sc, ITX_CH + dmach);
- }
- } else if ((stat & OHCI_CNTL_CYCMATCH_S) == 0) {
- fw_printf(sc->fc.dev, "IT DMA underrun (0x%08x)\n", stat);
- OWRITE(sc, OHCI_ITCTL(dmach), OHCI_CNTL_DMA_WAKE);
- }
-out:
- return err;
-}
-
-static int
-fwohci_irx_enable(struct firewire_comm *fc, int dmach)
-{
- struct fwohci_softc *sc = (struct fwohci_softc *)fc;
- int err = 0, s, ldesc;
- unsigned short tag, ich;
- uint32_t stat;
- struct fwohci_dbch *dbch;
- struct fwohcidb_tr *db_tr;
- struct fw_bulkxfer *first, *prev, *chunk;
- struct fw_xferq *ir;
-
- dbch = &sc->ir[dmach];
- ir = &dbch->xferq;
-
- if ((ir->flag & FWXFERQ_RUNNING) == 0) {
- tag = (ir->flag >> 6) & 3;
- ich = ir->flag & 0x3f;
- OWRITE(sc, OHCI_IRMATCH(dmach), tagbit[tag] | ich);
-
- ir->queued = 0;
- dbch->ndb = ir->bnpacket * ir->bnchunk;
- dbch->ndesc = 2;
- fwohci_db_init(sc, dbch);
- if ((dbch->flags & FWOHCI_DBCH_INIT) == 0)
- return ENOMEM;
- err = fwohci_rx_enable(sc, dbch);
- }
- if(err)
- return err;
-
- first = STAILQ_FIRST(&ir->stfree);
- if (first == NULL) {
- fw_printf(fc->dev, "IR DMA no free chunk\n");
- return 0;
- }
-
- ldesc = dbch->ndesc - 1;
- s = splfw();
- if ((ir->flag & FWXFERQ_HANDLER) == 0)
- FW_GLOCK(fc);
- prev = STAILQ_LAST(&ir->stdma, fw_bulkxfer, link);
- while ((chunk = STAILQ_FIRST(&ir->stfree)) != NULL) {
- struct fwohcidb *db;
-
-#if 1 /* XXX for if_fwe */
- if (chunk->mbuf != NULL) {
- db_tr = (struct fwohcidb_tr *)(chunk->start);
- db_tr->dbcnt = 1;
- err = fw_bus_dmamap_load_mbuf(
- dbch->dmat, db_tr->dma_map,
- chunk->mbuf, fwohci_execute_db2, db_tr,
- BUS_DMA_WAITOK);
- FWOHCI_DMA_SET(db_tr->db[1].db.desc.cmd,
- OHCI_UPDATE | OHCI_INPUT_LAST |
- OHCI_INTERRUPT_ALWAYS | OHCI_BRANCH_ALWAYS);
- }
-#endif
- db = ((struct fwohcidb_tr *)(chunk->end))->db;
- FWOHCI_DMA_WRITE(db[ldesc].db.desc.res, 0);
- FWOHCI_DMA_CLEAR(db[ldesc].db.desc.depend, 0xf);
- if (prev != NULL) {
- db = ((struct fwohcidb_tr *)(prev->end))->db;
- FWOHCI_DMA_SET(db[ldesc].db.desc.depend, dbch->ndesc);
- }
- STAILQ_REMOVE_HEAD(&ir->stfree, link);
- STAILQ_INSERT_TAIL(&ir->stdma, chunk, link);
- prev = chunk;
- }
- if ((ir->flag & FWXFERQ_HANDLER) == 0)
- FW_GUNLOCK(fc);
- fwdma_sync_multiseg_all(dbch->am,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- splx(s);
- stat = OREAD(sc, OHCI_IRCTL(dmach));
- if (stat & OHCI_CNTL_DMA_ACTIVE)
- return 0;
- if (stat & OHCI_CNTL_DMA_RUN) {
- OWRITE(sc, OHCI_IRCTLCLR(dmach), OHCI_CNTL_DMA_RUN);
- fw_printf(sc->fc.dev, "IR DMA overrun (0x%08x)\n", stat);
- }
-
- if (firewire_debug)
- printf("start IR DMA 0x%x\n", stat);
- OWRITE(sc, OHCI_IR_MASKCLR, 1 << dmach);
- OWRITE(sc, OHCI_IR_STATCLR, 1 << dmach);
- OWRITE(sc, OHCI_IR_MASK, 1 << dmach);
- OWRITE(sc, OHCI_IRCTLCLR(dmach), 0xf0000000);
- OWRITE(sc, OHCI_IRCTL(dmach), OHCI_CNTL_ISOHDR);
- OWRITE(sc, OHCI_IRCMD(dmach),
- ((struct fwohcidb_tr *)(first->start))->bus_addr
- | dbch->ndesc);
- OWRITE(sc, OHCI_IRCTL(dmach), OHCI_CNTL_DMA_RUN);
- OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_DMA_IR);
-#if 0
- dump_db(sc, IRX_CH + dmach);
-#endif
- return err;
-}
-
-int
-fwohci_stop(struct fwohci_softc *sc, device_t dev)
-{
- u_int i;
-
-/* Now stopping all DMA channel */
- OWRITE(sc, OHCI_ARQCTLCLR, OHCI_CNTL_DMA_RUN);
- OWRITE(sc, OHCI_ARSCTLCLR, OHCI_CNTL_DMA_RUN);
- OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
- OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
-
- for( i = 0 ; i < sc->fc.nisodma ; i ++ ){
- OWRITE(sc, OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN);
- OWRITE(sc, OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN);
- }
-
- if (sc->fc.arq !=0 && sc->fc.arq->maxq > 0)
- fw_drain_txq(&sc->fc);
-
-#if 0 /* Let dcons(4) be accessed */
-/* Stop interrupt */
- OWRITE(sc, FWOHCI_INTMASKCLR,
- OHCI_INT_EN | OHCI_INT_ERR | OHCI_INT_PHY_SID
- | OHCI_INT_PHY_INT
- | OHCI_INT_DMA_ATRQ | OHCI_INT_DMA_ATRS
- | OHCI_INT_DMA_PRRQ | OHCI_INT_DMA_PRRS
- | OHCI_INT_DMA_ARRQ | OHCI_INT_DMA_ARRS
- | OHCI_INT_PHY_BUS_R);
-
-/* FLUSH FIFO and reset Transmitter/Reciever */
- OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_RESET);
-#endif
-
-/* XXX Link down? Bus reset? */
- return 0;
-}
-
-int
-fwohci_resume(struct fwohci_softc *sc, device_t dev)
-{
- int i;
- struct fw_xferq *ir;
- struct fw_bulkxfer *chunk;
-
- fwohci_reset(sc, dev);
- /* XXX resume isochronous receive automatically. (how about TX?) */
- for(i = 0; i < sc->fc.nisodma; i ++) {
- ir = &sc->ir[i].xferq;
- if((ir->flag & FWXFERQ_RUNNING) != 0) {
- fw_printf(sc->fc.dev,
- "resume iso receive ch: %d\n", i);
- ir->flag &= ~FWXFERQ_RUNNING;
- /* requeue stdma to stfree */
- while((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
- STAILQ_REMOVE_HEAD(&ir->stdma, link);
- STAILQ_INSERT_TAIL(&ir->stfree, chunk, link);
- }
- sc->fc.irx_enable(&sc->fc, i);
- }
- }
-
-#if defined(__FreeBSD__)
- bus_generic_resume(dev);
-#elif defined(__NetBSD__)
- {
- extern int firewire_resume(struct firewire_comm *);
- firewire_resume(&sc->fc);
- }
-#endif
- sc->fc.ibr(&sc->fc);
- return 0;
+ return cycle_match;
}
#ifdef OHCI_DEBUG
static void
fwohci_dump_intr(struct fwohci_softc *sc, uint32_t stat)
{
- if(stat & OREAD(sc, FWOHCI_INTMASK))
- fw_printf(fc->dev, "INTERRUPT < %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s> 0x%08x, 0x%08x\n",
- stat & OHCI_INT_EN ? "DMA_EN ":"",
- stat & OHCI_INT_PHY_REG ? "PHY_REG ":"",
- stat & OHCI_INT_CYC_LONG ? "CYC_LONG ":"",
- stat & OHCI_INT_ERR ? "INT_ERR ":"",
- stat & OHCI_INT_CYC_ERR ? "CYC_ERR ":"",
- stat & OHCI_INT_CYC_LOST ? "CYC_LOST ":"",
- stat & OHCI_INT_CYC_64SECOND ? "CYC_64SECOND ":"",
- stat & OHCI_INT_CYC_START ? "CYC_START ":"",
- stat & OHCI_INT_PHY_INT ? "PHY_INT ":"",
- stat & OHCI_INT_PHY_BUS_R ? "BUS_RESET ":"",
- stat & OHCI_INT_PHY_SID ? "SID ":"",
- stat & OHCI_INT_LR_ERR ? "DMA_LR_ERR ":"",
- stat & OHCI_INT_PW_ERR ? "DMA_PW_ERR ":"",
- stat & OHCI_INT_DMA_IR ? "DMA_IR ":"",
- stat & OHCI_INT_DMA_IT ? "DMA_IT " :"",
- stat & OHCI_INT_DMA_PRRS ? "DMA_PRRS " :"",
- stat & OHCI_INT_DMA_PRRQ ? "DMA_PRRQ " :"",
- stat & OHCI_INT_DMA_ARRS ? "DMA_ARRS " :"",
- stat & OHCI_INT_DMA_ARRQ ? "DMA_ARRQ " :"",
- stat & OHCI_INT_DMA_ATRS ? "DMA_ATRS " :"",
- stat & OHCI_INT_DMA_ATRQ ? "DMA_ATRQ " :"",
- stat, OREAD(sc, FWOHCI_INTMASK)
+
+ if (stat & OREAD(sc, FWOHCI_INTMASK))
+ print("%s: INTERRUPT"
+ " < %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>"
+ " 0x%08x, 0x%08x\n",
+ device_xname(fc->dev),
+ stat & OHCI_INT_EN ? "DMA_EN ":"",
+ stat & OHCI_INT_PHY_REG ? "PHY_REG ":"",
+ stat & OHCI_INT_CYC_LONG ? "CYC_LONG ":"",
+ stat & OHCI_INT_ERR ? "INT_ERR ":"",
+ stat & OHCI_INT_CYC_ERR ? "CYC_ERR ":"",
+ stat & OHCI_INT_CYC_LOST ? "CYC_LOST ":"",
+ stat & OHCI_INT_CYC_64SECOND ? "CYC_64SECOND ":"",
+ stat & OHCI_INT_CYC_START ? "CYC_START ":"",
+ stat & OHCI_INT_PHY_INT ? "PHY_INT ":"",
+ stat & OHCI_INT_PHY_BUS_R ? "BUS_RESET ":"",
+ stat & OHCI_INT_PHY_SID ? "SID ":"",
+ stat & OHCI_INT_LR_ERR ? "DMA_LR_ERR ":"",
+ stat & OHCI_INT_PW_ERR ? "DMA_PW_ERR ":"",
+ stat & OHCI_INT_DMA_IR ? "DMA_IR ":"",
+ stat & OHCI_INT_DMA_IT ? "DMA_IT " :"",
+ stat & OHCI_INT_DMA_PRRS ? "DMA_PRRS " :"",
+ stat & OHCI_INT_DMA_PRRQ ? "DMA_PRRQ " :"",
+ stat & OHCI_INT_DMA_ARRS ? "DMA_ARRS " :"",
+ stat & OHCI_INT_DMA_ARRQ ? "DMA_ARRQ " :"",
+ stat & OHCI_INT_DMA_ATRS ? "DMA_ATRS " :"",
+ stat & OHCI_INT_DMA_ATRQ ? "DMA_ATRQ " :"",
+ stat, OREAD(sc, FWOHCI_INTMASK)
);
}
#endif
+
static void
-fwohci_intr_core(struct fwohci_softc *sc, uint32_t stat, int count)
+fwohci_intr_core(struct fwohci_softc *sc, uint32_t stat)
{
- struct firewire_comm *fc = (struct firewire_comm *)sc;
+ struct firewire_comm *fc = &sc->fc;
uint32_t node_id, plen;
- CTR0(KTR_DEV, "fwohci_intr_core");
-
if ((stat & OHCI_INT_PHY_BUS_R) && (fc->status != FWBUSRESET)) {
fc->status = FWBUSRESET;
/* Disable bus reset interrupt until sid recv. */
- OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_PHY_BUS_R);
+ OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_PHY_BUS_R);
- fw_printf(fc->dev, "BUS reset\n");
- OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST);
+ aprint_normal_dev(fc->dev, "BUS reset\n");
+ OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST);
OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCSRC);
- OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN);
sc->atrq.xferq.flag &= ~FWXFERQ_RUNNING;
- OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
+ OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN);
sc->atrs.xferq.flag &= ~FWXFERQ_RUNNING;
- if (!kdb_active)
- fw_taskqueue_enqueue(sc->fc.taskqueue,
- &sc->fwohci_task_busreset);
+ fw_busreset(&sc->fc, FWBUSRESET);
+ OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
+ OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
}
if (stat & OHCI_INT_PHY_SID) {
/* Enable bus reset interrupt */
@@ -1992,7 +2024,7 @@ fwohci_intr_core(struct fwohci_softc *sc, uint32_t stat, int count)
plen = OREAD(sc, OHCI_SID_CNT);
fc->nodeid = node_id & 0x3f;
- fw_printf(fc->dev, "node_id=0x%08x, gen=%d, ",
+ aprint_normal_dev(fc->dev, "node_id=0x%08x, gen=%d, ",
node_id, (plen >> 16) & 0xff);
if (!(node_id & OHCI_NODE_VALID)) {
aprint_error("Bus reset failure\n");
@@ -2001,7 +2033,7 @@ fwohci_intr_core(struct fwohci_softc *sc, uint32_t stat, int count)
/* cycle timer */
sc->cycle_lost = 0;
- OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_CYC_LOST);
+ OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_CYC_LOST);
if ((node_id & OHCI_NODE_ROOT) && !nocyclemaster) {
aprint_normal("CYCLEMASTER mode\n");
OWRITE(sc, OHCI_LNKCTL,
@@ -2014,110 +2046,84 @@ fwohci_intr_core(struct fwohci_softc *sc, uint32_t stat, int count)
fc->status = FWBUSINIT;
- if (!kdb_active)
- fw_taskqueue_enqueue(sc->fc.taskqueue,
- &sc->fwohci_task_sid);
+ fwohci_task_sid(sc);
}
sidout:
- if ((stat & ~(OHCI_INT_PHY_BUS_R | OHCI_INT_PHY_SID)) && (!kdb_active))
- fw_taskqueue_enqueue(sc->fc.taskqueue, &sc->fwohci_task_dma);
-
- CTR0(KTR_DEV, "fwohci_intr_core done");
+ if ((stat & ~(OHCI_INT_PHY_BUS_R | OHCI_INT_PHY_SID)))
+ fwohci_task_dma(sc);
}
static void
-fwohci_intr_dma(struct fwohci_softc *sc, uint32_t stat, int count)
+fwohci_intr_dma(struct fwohci_softc *sc, uint32_t stat)
{
+ struct firewire_comm *fc = &sc->fc;
uint32_t irstat, itstat;
u_int i;
- struct firewire_comm *fc = (struct firewire_comm *)sc;
- CTR0(KTR_DEV, "fwohci_intr_dma");
if (stat & OHCI_INT_DMA_IR) {
- irstat = fw_atomic_readandclear_int(&sc->irstat);
- for(i = 0; i < fc->nisodma ; i++){
- struct fwohci_dbch *dbch;
+ irstat = atomic_swap_32(&sc->irstat, 0);
+ for (i = 0; i < fc->nisodma; i++)
+ if ((irstat & (1 << i)) != 0) {
+ struct fwohci_dbch *dbch = &sc->ir[i];
- if((irstat & (1 << i)) != 0){
- dbch = &sc->ir[i];
if ((dbch->xferq.flag & FWXFERQ_OPEN) == 0) {
- fw_printf(sc->fc.dev,
- "dma(%d) not active\n", i);
+ aprint_error_dev(fc->dev,
+ "dma(%d) not active\n", i);
continue;
}
fwohci_rbuf_update(sc, i);
}
- }
}
if (stat & OHCI_INT_DMA_IT) {
- itstat = fw_atomic_readandclear_int(&sc->itstat);
- for(i = 0; i < fc->nisodma ; i++){
- if((itstat & (1 << i)) != 0){
+ itstat = atomic_swap_32(&sc->itstat, 0);
+ for (i = 0; i < fc->nisodma; i++)
+ if ((itstat & (1 << i)) != 0)
fwohci_tbuf_update(sc, i);
- }
- }
}
if (stat & OHCI_INT_DMA_PRRS) {
#if 0
dump_dma(sc, ARRS_CH);
dump_db(sc, ARRS_CH);
#endif
- fwohci_arcv(sc, &sc->arrs, count);
+ fwohci_arcv(sc, &sc->arrs);
}
if (stat & OHCI_INT_DMA_PRRQ) {
#if 0
dump_dma(sc, ARRQ_CH);
dump_db(sc, ARRQ_CH);
#endif
- fwohci_arcv(sc, &sc->arrq, count);
+ fwohci_arcv(sc, &sc->arrq);
}
if (stat & OHCI_INT_CYC_LOST) {
if (sc->cycle_lost >= 0)
- sc->cycle_lost ++;
+ sc->cycle_lost++;
if (sc->cycle_lost > 10) {
sc->cycle_lost = -1;
#if 0
OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCTIMER);
#endif
- OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST);
- fw_printf(fc->dev, "too many cycle lost, "
+ OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST);
+ aprint_error_dev(fc->dev, "too many cycle lost, "
"no cycle master presents?\n");
}
}
- if (stat & OHCI_INT_DMA_ATRQ) {
+ if (stat & OHCI_INT_DMA_ATRQ)
fwohci_txd(sc, &(sc->atrq));
- }
- if (stat & OHCI_INT_DMA_ATRS) {
+ if (stat & OHCI_INT_DMA_ATRS)
fwohci_txd(sc, &(sc->atrs));
- }
- if (stat & OHCI_INT_PW_ERR) {
- fw_printf(fc->dev, "posted write error\n");
- }
- if (stat & OHCI_INT_ERR) {
- fw_printf(fc->dev, "unrecoverable error\n");
- }
- if (stat & OHCI_INT_PHY_INT) {
- fw_printf(fc->dev, "phy int\n");
- }
+ if (stat & OHCI_INT_PW_ERR)
+ aprint_error_dev(fc->dev, "posted write error\n");
+ if (stat & OHCI_INT_ERR)
+ aprint_error_dev(fc->dev, "unrecoverable error\n");
+ if (stat & OHCI_INT_PHY_INT)
+ aprint_normal_dev(fc->dev, "phy int\n");
- CTR0(KTR_DEV, "fwohci_intr_dma done");
return;
}
static void
-fwohci_task_busreset(void *arg, int pending)
-{
- struct fwohci_softc *sc = (struct fwohci_softc *)arg;
-
- fw_busreset(&sc->fc, FWBUSRESET);
- OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
- OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
-}
-
-static void
-fwohci_task_sid(void *arg, int pending)
+fwohci_task_sid(struct fwohci_softc *sc)
{
- struct fwohci_softc *sc = (struct fwohci_softc *)arg;
struct firewire_comm *fc = &sc->fc;
uint32_t *buf;
int i, plen;
@@ -2125,28 +2131,28 @@ fwohci_task_sid(void *arg, int pending)
plen = OREAD(sc, OHCI_SID_CNT);
if (plen & OHCI_SID_ERR) {
- fw_printf(fc->dev, "SID Error\n");
+ aprint_error_dev(fc->dev, "SID Error\n");
return;
}
plen &= OHCI_SID_CNT_MASK;
if (plen < 4 || plen > OHCI_SIDSIZE) {
- fw_printf(fc->dev, "invalid SID len = %d\n", plen);
+ aprint_error_dev(fc->dev, "invalid SID len = %d\n", plen);
return;
}
plen -= 4; /* chop control info */
buf = (uint32_t *)malloc(OHCI_SIDSIZE, M_FW, M_NOWAIT);
if (buf == NULL) {
- fw_printf(fc->dev, "malloc failed\n");
+ aprint_error_dev(fc->dev, "malloc failed\n");
return;
}
- for (i = 0; i < plen / 4; i ++)
- buf[i] = FWOHCI_DMA_READ(sc->sid_buf[i+1]);
+ for (i = 0; i < plen / 4; i++)
+ buf[i] = FWOHCI_DMA_READ(sc->sid_buf[i + 1]);
#if 1 /* XXX needed?? */
/* pending all pre-bus_reset packets */
fwohci_txd(sc, &sc->atrq);
fwohci_txd(sc, &sc->atrs);
- fwohci_arcv(sc, &sc->arrs, -1);
- fwohci_arcv(sc, &sc->arrq, -1);
+ fwohci_arcv(sc, &sc->arrs);
+ fwohci_arcv(sc, &sc->arrq);
fw_drain_txq(fc);
#endif
fw_sidrcv(fc, buf, plen);
@@ -2154,105 +2160,19 @@ fwohci_task_sid(void *arg, int pending)
}
static void
-fwohci_task_dma(void *arg, int pending)
+fwohci_task_dma(struct fwohci_softc *sc)
{
- struct fwohci_softc *sc = (struct fwohci_softc *)arg;
uint32_t stat;
again:
- stat = fw_atomic_readandclear_int(&sc->intstat);
+ stat = atomic_swap_32(&sc->intstat, 0);
if (stat)
- fwohci_intr_dma(sc, stat, -1);
+ fwohci_intr_dma(sc, stat);
else
return;
goto again;
}
-static int
-fwohci_check_stat(struct fwohci_softc *sc)
-{
- uint32_t stat, irstat, itstat;
-
- stat = OREAD(sc, FWOHCI_INTSTAT);
- CTR1(KTR_DEV, "fwoch_check_stat 0x%08x", stat);
- if (stat == 0xffffffff) {
- fw_printf(sc->fc.dev,
- "device physically ejected?\n");
- return (FILTER_STRAY);
- }
- if (stat)
- OWRITE(sc, FWOHCI_INTSTATCLR, stat & ~OHCI_INT_PHY_BUS_R);
-
- stat &= sc->intmask;
- if (stat == 0)
- return (FILTER_STRAY);
-
- fw_atomic_set_int(&sc->intstat, stat);
- if (stat & OHCI_INT_DMA_IR) {
- irstat = OREAD(sc, OHCI_IR_STAT);
- OWRITE(sc, OHCI_IR_STATCLR, irstat);
- fw_atomic_set_int(&sc->irstat, irstat);
- }
- if (stat & OHCI_INT_DMA_IT) {
- itstat = OREAD(sc, OHCI_IT_STAT);
- OWRITE(sc, OHCI_IT_STATCLR, itstat);
- fw_atomic_set_int(&sc->itstat, itstat);
- }
-
- fwohci_intr_core(sc, stat, -1);
- return (FILTER_HANDLED);
-}
-
-int
-fwohci_filt(void *arg)
-{
- struct fwohci_softc *sc = (struct fwohci_softc *)arg;
-
-#if defined(__NetBSD__)
- if (!device_is_active(sc->fc.dev))
- return (FILTER_STRAY);
-#endif
-
- if (!(sc->intmask & OHCI_INT_EN)) {
- /* polling mode */
- return (FILTER_STRAY);
- }
- return (fwohci_check_stat(sc));
-}
-
-void
-fwohci_intr(void *arg)
-{
-
- fwohci_filt(arg);
- CTR0(KTR_DEV, "fwohci_intr end");
-}
-
-void
-fwohci_poll(struct firewire_comm *fc, int quick, int count)
-{
- struct fwohci_softc *sc = (struct fwohci_softc *)fc;
-
- fwohci_check_stat(sc);
-}
-
-static void
-fwohci_set_intr(struct firewire_comm *fc, int enable)
-{
- struct fwohci_softc *sc;
-
- sc = (struct fwohci_softc *)fc;
- if (firewire_debug)
- fw_printf(sc->fc.dev, "fwohci_set_intr: %d\n", enable);
- if (enable) {
- sc->intmask |= OHCI_INT_EN;
- OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_EN);
- } else {
- sc->intmask &= ~OHCI_INT_EN;
- OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_EN);
- }
-}
-
static void
fwohci_tbuf_update(struct fwohci_softc *sc, int dmach)
{
@@ -2261,42 +2181,40 @@ fwohci_tbuf_update(struct fwohci_softc *sc, int dmach)
struct fw_bulkxfer *chunk;
struct fw_xferq *it;
uint32_t stat, count;
- int s, w=0, ldesc;
+ int w = 0, ldesc;
it = fc->it[dmach];
ldesc = sc->it[dmach].ndesc - 1;
- s = splfw(); /* unnecessary ? */
- FW_GLOCK(fc);
+ mutex_enter(&fc->fc_mtx);
fwdma_sync_multiseg_all(sc->it[dmach].am, BUS_DMASYNC_POSTREAD);
if (firewire_debug)
dump_db(sc, ITX_CH + dmach);
while ((chunk = STAILQ_FIRST(&it->stdma)) != NULL) {
db = ((struct fwohcidb_tr *)(chunk->end))->db;
- stat = FWOHCI_DMA_READ(db[ldesc].db.desc.res)
- >> OHCI_STATUS_SHIFT;
+ stat =
+ FWOHCI_DMA_READ(db[ldesc].db.desc.res) >> OHCI_STATUS_SHIFT;
db = ((struct fwohcidb_tr *)(chunk->start))->db;
/* timestamp */
- count = FWOHCI_DMA_READ(db[ldesc].db.desc.res)
- & OHCI_COUNT_MASK;
+ count =
+ FWOHCI_DMA_READ(db[ldesc].db.desc.res) & OHCI_COUNT_MASK;
if (stat == 0)
break;
STAILQ_REMOVE_HEAD(&it->stdma, link);
- switch (stat & FWOHCIEV_MASK){
+ switch (stat & FWOHCIEV_MASK) {
case FWOHCIEV_ACKCOMPL:
#if 0
- fw_printf(fc->dev, "0x%08x\n", count);
+ printf("0x%08x\n", count);
#endif
break;
default:
- fw_printf(fc->dev,
- "Isochronous transmit err %02x(%s)\n",
- stat, fwohcicode[stat & 0x1f]);
+ aprint_error_dev(fc->dev,
+ "Isochronous transmit err %02x(%s)\n",
+ stat, fwohcicode[stat & 0x1f]);
}
STAILQ_INSERT_TAIL(&it->stfree, chunk, link);
w++;
}
- FW_GUNLOCK(fc);
- splx(s);
+ mutex_exit(&fc->fc_mtx);
if (w)
wakeup(it);
}
@@ -2309,7 +2227,7 @@ fwohci_rbuf_update(struct fwohci_softc *sc, int dmach)
struct fw_bulkxfer *chunk;
struct fw_xferq *ir;
uint32_t stat;
- int s, w = 0, ldesc;
+ int w = 0, ldesc;
ir = fc->ir[dmach];
ldesc = sc->ir[dmach].ndesc - 1;
@@ -2317,29 +2235,27 @@ fwohci_rbuf_update(struct fwohci_softc *sc, int dmach)
#if 0
dump_db(sc, dmach);
#endif
- s = splfw();
if ((ir->flag & FWXFERQ_HANDLER) == 0)
- FW_GLOCK(fc);
+ mutex_enter(&fc->fc_mtx);
fwdma_sync_multiseg_all(sc->ir[dmach].am, BUS_DMASYNC_POSTREAD);
while ((chunk = STAILQ_FIRST(&ir->stdma)) != NULL) {
db_tr = (struct fwohcidb_tr *)chunk->end;
- stat = FWOHCI_DMA_READ(db_tr->db[ldesc].db.desc.res)
- >> OHCI_STATUS_SHIFT;
+ stat = FWOHCI_DMA_READ(db_tr->db[ldesc].db.desc.res) >>
+ OHCI_STATUS_SHIFT;
if (stat == 0)
break;
if (chunk->mbuf != NULL) {
- fw_bus_dmamap_sync(sc->ir[dmach].dmat, db_tr->dma_map,
- BUS_DMASYNC_POSTREAD);
- fw_bus_dmamap_unload(
- sc->ir[dmach].dmat, db_tr->dma_map);
- } else if (ir->buf != NULL) {
+ bus_dmamap_sync(fc->dmat, db_tr->dma_map, 0,
+ db_tr->dma_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(fc->dmat, db_tr->dma_map);
+ } else if (ir->buf != NULL)
fwdma_sync_multiseg(ir->buf, chunk->poffset,
- ir->bnpacket, BUS_DMASYNC_POSTREAD);
- } else {
+ ir->bnpacket, BUS_DMASYNC_POSTREAD);
+ else
/* XXX */
- printf("fwohci_rbuf_update: this shouldn't happend\n");
- }
+ aprint_error_dev(fc->dev,
+ "fwohci_rbuf_update: this shouldn't happend\n");
STAILQ_REMOVE_HEAD(&ir->stdma, link);
STAILQ_INSERT_TAIL(&ir->stvalid, chunk, link);
@@ -2349,14 +2265,14 @@ fwohci_rbuf_update(struct fwohci_softc *sc, int dmach)
break;
default:
chunk->resp = EINVAL;
- fw_printf(fc->dev, "Isochronous receive err %02x(%s)\n",
- stat, fwohcicode[stat & 0x1f]);
+ aprint_error_dev(fc->dev,
+ "Isochronous receive err %02x(%s)\n",
+ stat, fwohcicode[stat & 0x1f]);
}
w++;
}
if ((ir->flag & FWXFERQ_HANDLER) == 0)
- FW_GUNLOCK(fc);
- splx(s);
+ mutex_exit(&fc->fc_mtx);
if (w == 0)
return;
if (ir->flag & FWXFERQ_HANDLER)
@@ -2365,251 +2281,195 @@ fwohci_rbuf_update(struct fwohci_softc *sc, int dmach)
wakeup(ir);
}
-void
+static void
dump_dma(struct fwohci_softc *sc, uint32_t ch)
{
- uint32_t off, cntl, stat, cmd, match;
-
- if(ch == 0){
- off = OHCI_ATQOFF;
- }else if(ch == 1){
- off = OHCI_ATSOFF;
- }else if(ch == 2){
- off = OHCI_ARQOFF;
- }else if(ch == 3){
- off = OHCI_ARSOFF;
- }else if(ch < IRX_CH){
- off = OHCI_ITCTL(ch - ITX_CH);
- }else{
- off = OHCI_IRCTL(ch - IRX_CH);
- }
- cntl = stat = OREAD(sc, off);
- cmd = OREAD(sc, off + 0xc);
- match = OREAD(sc, off + 0x10);
-
- fw_printf(sc->fc.dev, "ch %1x cntl:0x%08x cmd:0x%08x match:0x%08x\n",
- ch,
- cntl,
- cmd,
- match);
- stat &= 0xffff ;
- if (stat) {
- fw_printf(sc->fc.dev, "dma %d ch:%s%s%s%s%s%s %s(%x)\n",
- ch,
- stat & OHCI_CNTL_DMA_RUN ? "RUN," : "",
- stat & OHCI_CNTL_DMA_WAKE ? "WAKE," : "",
- stat & OHCI_CNTL_DMA_DEAD ? "DEAD," : "",
- stat & OHCI_CNTL_DMA_ACTIVE ? "ACTIVE," : "",
- stat & OHCI_CNTL_DMA_BT ? "BRANCH," : "",
- stat & OHCI_CNTL_DMA_BAD ? "BADDMA," : "",
- fwohcicode[stat & 0x1f],
- stat & 0x1f
+ struct fwohci_dbch *dbch;
+ uint32_t cntl, stat, cmd, match;
+
+ if (ch == ATRQ_CH)
+ dbch = &sc->atrq;
+ else if (ch == ATRS_CH)
+ dbch = &sc->atrs;
+ else if (ch == ARRQ_CH)
+ dbch = &sc->arrq;
+ else if (ch == ARRS_CH)
+ dbch = &sc->arrs;
+ else if (ch < IRX_CH)
+ dbch = &sc->it[ch - ITX_CH];
+ else
+ dbch = &sc->ir[ch - IRX_CH];
+ cntl = stat = OREAD(sc, dbch->off);
+ cmd = OREAD(sc, dbch->off + 0xc);
+ match = OREAD(sc, dbch->off + 0x10);
+
+ aprint_normal_dev(sc->fc.dev,
+ "ch %1x cntl:0x%08x cmd:0x%08x match:0x%08x\n",
+ ch,
+ cntl,
+ cmd,
+ match);
+ stat &= 0xffff;
+ if (stat)
+ aprint_normal_dev(sc->fc.dev, "dma %d ch:%s%s%s%s%s%s %s(%x)\n",
+ ch,
+ stat & OHCI_CNTL_DMA_RUN ? "RUN," : "",
+ stat & OHCI_CNTL_DMA_WAKE ? "WAKE," : "",
+ stat & OHCI_CNTL_DMA_DEAD ? "DEAD," : "",
+ stat & OHCI_CNTL_DMA_ACTIVE ? "ACTIVE," : "",
+ stat & OHCI_CNTL_DMA_BT ? "BRANCH," : "",
+ stat & OHCI_CNTL_DMA_BAD ? "BADDMA," : "",
+ fwohcicode[stat & 0x1f],
+ stat & 0x1f
);
- }else{
- fw_printf(sc->fc.dev, "dma %d ch: Nostat\n", ch);
- }
+ else
+ aprint_normal_dev(sc->fc.dev, "dma %d ch: Nostat\n", ch);
}
-void
+static void
dump_db(struct fwohci_softc *sc, uint32_t ch)
{
struct fwohci_dbch *dbch;
struct fwohcidb_tr *cp = NULL, *pp, *np = NULL;
struct fwohcidb *curr = NULL, *prev, *next = NULL;
int idb, jdb;
- uint32_t cmd, off;
- if(ch == 0){
- off = OHCI_ATQOFF;
+ uint32_t cmd;
+
+ if (ch == ATRQ_CH)
dbch = &sc->atrq;
- }else if(ch == 1){
- off = OHCI_ATSOFF;
+ else if (ch == ATRS_CH)
dbch = &sc->atrs;
- }else if(ch == 2){
- off = OHCI_ARQOFF;
+ else if (ch == ARRQ_CH)
dbch = &sc->arrq;
- }else if(ch == 3){
- off = OHCI_ARSOFF;
+ else if (ch == ARRS_CH)
dbch = &sc->arrs;
- }else if(ch < IRX_CH){
- off = OHCI_ITCTL(ch - ITX_CH);
+ else if (ch < IRX_CH)
dbch = &sc->it[ch - ITX_CH];
- }else {
- off = OHCI_IRCTL(ch - IRX_CH);
+ else
dbch = &sc->ir[ch - IRX_CH];
- }
- cmd = OREAD(sc, off + 0xc);
+ cmd = OREAD(sc, dbch->off + 0xc);
- if( dbch->ndb == 0 ){
- fw_printf(sc->fc.dev, "No DB is attached ch=%d\n", ch);
+ if (dbch->ndb == 0) {
+ aprint_error_dev(sc->fc.dev, "No DB is attached ch=%d\n", ch);
return;
}
pp = dbch->top;
prev = pp->db;
- for(idb = 0 ; idb < dbch->ndb ; idb ++ ){
+ for (idb = 0; idb < dbch->ndb; idb++) {
cp = STAILQ_NEXT(pp, link);
- if(cp == NULL){
+ if (cp == NULL) {
curr = NULL;
goto outdb;
}
np = STAILQ_NEXT(cp, link);
- for(jdb = 0 ; jdb < dbch->ndesc ; jdb ++ ){
- if ((cmd & 0xfffffff0) == cp->bus_addr) {
+ for (jdb = 0; jdb < dbch->ndesc; jdb++)
+ if ((cmd & 0xfffffff0) == cp->bus_addr) {
curr = cp->db;
- if(np != NULL){
+ if (np != NULL)
next = np->db;
- }else{
+ else
next = NULL;
- }
goto outdb;
}
- }
pp = STAILQ_NEXT(pp, link);
- if(pp == NULL){
+ if (pp == NULL) {
curr = NULL;
goto outdb;
}
prev = pp->db;
}
outdb:
- if( curr != NULL){
+ if (curr != NULL) {
#if 0
- printf("Prev DB %d\n", ch);
+ aprint_normal("Prev DB %d\n", ch);
print_db(pp, prev, ch, dbch->ndesc);
#endif
- printf("Current DB %d\n", ch);
+ aprint_normal("Current DB %d\n", ch);
print_db(cp, curr, ch, dbch->ndesc);
#if 0
- printf("Next DB %d\n", ch);
+ aprint_normal("Next DB %d\n", ch);
print_db(np, next, ch, dbch->ndesc);
#endif
- }else{
- printf("dbdump err ch = %d cmd = 0x%08x\n", ch, cmd);
- }
+ } else
+ aprint_error("dbdump err ch = %d cmd = 0x%08x\n", ch, cmd);
return;
}
-void
-print_db(struct fwohcidb_tr *db_tr, struct fwohcidb *db,
- uint32_t ch, uint32_t hogemax)
+static void
+print_db(struct fwohcidb_tr *db_tr, struct fwohcidb *db, uint32_t ch,
+ uint32_t hogemax)
{
fwohcireg_t stat;
int i, key;
uint32_t cmd, res;
- if(db == NULL){
- printf("No Descriptor is found\n");
+ if (db == NULL) {
+ aprint_error("No Descriptor is found\n");
return;
}
- printf("ch = %d\n%8s %s %s %s %s %4s %8s %8s %4s:%4s\n",
- ch,
- "Current",
- "OP ",
- "KEY",
- "INT",
- "BR ",
- "len",
- "Addr",
- "Depend",
- "Stat",
- "Cnt");
- for( i = 0 ; i <= hogemax ; i ++){
+ aprint_normal("ch = %d\n%8s %s %s %s %s %4s %8s %8s %4s:%4s\n",
+ ch,
+ "Current",
+ "OP ",
+ "KEY",
+ "INT",
+ "BR ",
+ "len",
+ "Addr",
+ "Depend",
+ "Stat",
+ "Cnt");
+ for (i = 0; i <= hogemax; i++) {
cmd = FWOHCI_DMA_READ(db[i].db.desc.cmd);
res = FWOHCI_DMA_READ(db[i].db.desc.res);
key = cmd & OHCI_KEY_MASK;
stat = res >> OHCI_STATUS_SHIFT;
-#if defined(__DragonFly__) || \
- (defined(__FreeBSD__) && __FreeBSD_version < 500000)
- printf("%08x %s %s %s %s %5d %08x %08x %04x:%04x",
- db_tr->bus_addr,
-#else
- printf("%08jx %s %s %s %s %5d %08x %08x %04x:%04x",
- (uintmax_t)db_tr->bus_addr,
-#endif
- dbcode[(cmd >> 28) & 0xf],
- dbkey[(cmd >> 24) & 0x7],
- dbcond[(cmd >> 20) & 0x3],
- dbcond[(cmd >> 18) & 0x3],
- cmd & OHCI_COUNT_MASK,
- FWOHCI_DMA_READ(db[i].db.desc.addr),
- FWOHCI_DMA_READ(db[i].db.desc.depend),
- stat,
- res & OHCI_COUNT_MASK);
- if(stat & 0xff00){
- printf(" %s%s%s%s%s%s %s(%x)\n",
- stat & OHCI_CNTL_DMA_RUN ? "RUN," : "",
- stat & OHCI_CNTL_DMA_WAKE ? "WAKE," : "",
- stat & OHCI_CNTL_DMA_DEAD ? "DEAD," : "",
- stat & OHCI_CNTL_DMA_ACTIVE ? "ACTIVE," : "",
- stat & OHCI_CNTL_DMA_BT ? "BRANCH," : "",
- stat & OHCI_CNTL_DMA_BAD ? "BADDMA," : "",
- fwohcicode[stat & 0x1f],
- stat & 0x1f
+ aprint_normal("%08jx %s %s %s %s %5d %08x %08x %04x:%04x",
+ (uintmax_t)db_tr->bus_addr,
+ dbcode[(cmd >> 28) & 0xf],
+ dbkey[(cmd >> 24) & 0x7],
+ dbcond[(cmd >> 20) & 0x3],
+ dbcond[(cmd >> 18) & 0x3],
+ cmd & OHCI_COUNT_MASK,
+ FWOHCI_DMA_READ(db[i].db.desc.addr),
+ FWOHCI_DMA_READ(db[i].db.desc.depend),
+ stat,
+ res & OHCI_COUNT_MASK);
+ if (stat & 0xff00)
+ aprint_normal(" %s%s%s%s%s%s %s(%x)\n",
+ stat & OHCI_CNTL_DMA_RUN ? "RUN," : "",
+ stat & OHCI_CNTL_DMA_WAKE ? "WAKE," : "",
+ stat & OHCI_CNTL_DMA_DEAD ? "DEAD," : "",
+ stat & OHCI_CNTL_DMA_ACTIVE ? "ACTIVE," : "",
+ stat & OHCI_CNTL_DMA_BT ? "BRANCH," : "",
+ stat & OHCI_CNTL_DMA_BAD ? "BADDMA," : "",
+ fwohcicode[stat & 0x1f],
+ stat & 0x1f
);
- }else{
- printf(" Nostat\n");
- }
- if(key == OHCI_KEY_ST2 ){
- printf("0x%08x 0x%08x 0x%08x 0x%08x\n",
- FWOHCI_DMA_READ(db[i+1].db.immed[0]),
- FWOHCI_DMA_READ(db[i+1].db.immed[1]),
- FWOHCI_DMA_READ(db[i+1].db.immed[2]),
- FWOHCI_DMA_READ(db[i+1].db.immed[3]));
- }
- if(key == OHCI_KEY_DEVICE){
+ else
+ aprint_normal(" Nostat\n");
+ if (key == OHCI_KEY_ST2)
+ aprint_normal("0x%08x 0x%08x 0x%08x 0x%08x\n",
+ FWOHCI_DMA_READ(db[i+1].db.immed[0]),
+ FWOHCI_DMA_READ(db[i+1].db.immed[1]),
+ FWOHCI_DMA_READ(db[i+1].db.immed[2]),
+ FWOHCI_DMA_READ(db[i+1].db.immed[3]));
+ if (key == OHCI_KEY_DEVICE)
return;
- }
- if((cmd & OHCI_BRANCH_MASK)
- == OHCI_BRANCH_ALWAYS){
+ if ((cmd & OHCI_BRANCH_MASK) == OHCI_BRANCH_ALWAYS)
return;
- }
- if((cmd & OHCI_CMD_MASK)
- == OHCI_OUTPUT_LAST){
+ if ((cmd & OHCI_CMD_MASK) == OHCI_OUTPUT_LAST)
return;
- }
- if((cmd & OHCI_CMD_MASK)
- == OHCI_INPUT_LAST){
+ if ((cmd & OHCI_CMD_MASK) == OHCI_INPUT_LAST)
return;
- }
- if(key == OHCI_KEY_ST2 ){
+ if (key == OHCI_KEY_ST2)
i++;
- }
}
return;
}
-void
-fwohci_ibr(struct firewire_comm *fc)
-{
- struct fwohci_softc *sc;
- uint32_t fun;
-
- fw_printf(fc->dev, "Initiate bus reset\n");
- sc = (struct fwohci_softc *)fc;
-
- /*
- * Make sure our cached values from the config rom are
- * initialised.
- */
- OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0]));
- OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2]));
-
- /*
- * Set root hold-off bit so that non cyclemaster capable node
- * shouldn't became the root node.
- */
-#if 1
- fun = fwphy_rddata(sc, FW_PHY_IBR_REG);
- fun |= FW_PHY_IBR | FW_PHY_RHB;
- fun = fwphy_wrdata(sc, FW_PHY_IBR_REG, fun);
-#else /* Short bus reset */
- fun = fwphy_rddata(sc, FW_PHY_ISBR_REG);
- fun |= FW_PHY_ISBR | FW_PHY_RHB;
- fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun);
-#endif
-}
-
-void
+static void
fwohci_txbufdb(struct fwohci_softc *sc, int dmach, struct fw_bulkxfer *bulkxfer)
{
struct fwohcidb_tr *db_tr, *fdb_tr;
@@ -2620,7 +2480,7 @@ fwohci_txbufdb(struct fwohci_softc *sc, int dmach, struct fw_bulkxfer *bulkxfer)
unsigned short chtag;
int idb;
- FW_GLOCK_ASSERT(&sc->fc);
+ KASSERT(mutex_owner(&sc->fc.fc_mtx));
dbch = &sc->it[dmach];
chtag = sc->it[dmach].xferq.flag & 0xff;
@@ -2628,9 +2488,9 @@ fwohci_txbufdb(struct fwohci_softc *sc, int dmach, struct fw_bulkxfer *bulkxfer)
db_tr = (struct fwohcidb_tr *)(bulkxfer->start);
fdb_tr = (struct fwohcidb_tr *)(bulkxfer->end);
/*
-fw_printf(sc->fc.dev, "DB %08x %08x %08x\n", bulkxfer, db_tr->bus_addr, fdb_tr->bus_addr);
+aprint_normal(sc->fc.dev, "DB %08x %08x %08x\n", bulkxfer, db_tr->bus_addr, fdb_tr->bus_addr);
*/
- for (idb = 0; idb < dbch->xferq.bnpacket; idb ++) {
+ for (idb = 0; idb < dbch->xferq.bnpacket; idb++) {
db = db_tr->db;
fp = (struct fw_pkt *)db_tr->buf;
ohcifp = (struct fwohci_txpkthdr *) db[1].db.immed;
@@ -2648,12 +2508,10 @@ fw_printf(sc->fc.dev, "DB %08x %08x %08x\n", bulkxfer, db_tr->bus_addr, fdb_tr->
FWOHCI_DMA_SET(db[2].db.desc.cmd, fp->mode.stream.len);
FWOHCI_DMA_WRITE(db[2].db.desc.res, 0);
#if 0 /* if bulkxfer->npackets changes */
- db[2].db.desc.cmd = OHCI_OUTPUT_LAST
- | OHCI_UPDATE
- | OHCI_BRANCH_ALWAYS;
- db[0].db.desc.depend =
- = db[dbch->ndesc - 1].db.desc.depend
- = STAILQ_NEXT(db_tr, link)->bus_addr | dbch->ndesc;
+ db[2].db.desc.cmd =
+ OHCI_OUTPUT_LAST | OHCI_UPDATE | OHCI_BRANCH_ALWAYS;
+ db[0].db.desc.depend = db[dbch->ndesc - 1].db.desc.depend =
+ STAILQ_NEXT(db_tr, link)->bus_addr | dbch->ndesc;
#else
FWOHCI_DMA_SET(db[0].db.desc.depend, dbch->ndesc);
FWOHCI_DMA_SET(db[dbch->ndesc - 1].db.desc.depend, dbch->ndesc);
@@ -2672,21 +2530,21 @@ fw_printf(sc->fc.dev, "DB %08x %08x %08x\n", bulkxfer, db_tr->bus_addr, fdb_tr->
/*
db_tr = (struct fwohcidb_tr *)bulkxfer->start;
fdb_tr = (struct fwohcidb_tr *)bulkxfer->end;
-fw_printf(sc->fc.dev, "DB %08x %3d %08x %08x\n", bulkxfer, bulkxfer->npacket, db_tr->bus_addr, fdb_tr->bus_addr);
+aprint_normal(sc->fc.dev, "DB %08x %3d %08x %08x\n", bulkxfer, bulkxfer->npacket, db_tr->bus_addr, fdb_tr->bus_addr);
*/
return;
}
static int
fwohci_add_tx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
- int poffset)
+ int poffset)
{
struct fwohcidb *db = db_tr->db;
struct fw_xferq *it;
int err = 0;
it = &dbch->xferq;
- if(it->buf == 0){
+ if (it->buf == 0) {
err = EINVAL;
return err;
}
@@ -2694,14 +2552,14 @@ fwohci_add_tx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
db_tr->dbcnt = 3;
FWOHCI_DMA_WRITE(db[0].db.desc.cmd,
- OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | 8);
+ OHCI_OUTPUT_MORE | OHCI_KEY_ST2 | 8);
FWOHCI_DMA_WRITE(db[0].db.desc.addr, 0);
- memset((void *)&db[1].db.immed[0], 0, sizeof(db[1].db.immed));
+ memset((void *)db[1].db.immed, 0, sizeof(db[1].db.immed));
FWOHCI_DMA_WRITE(db[2].db.desc.addr,
fwdma_bus_addr(it->buf, poffset) + sizeof(uint32_t));
FWOHCI_DMA_WRITE(db[2].db.desc.cmd,
- OHCI_OUTPUT_LAST | OHCI_UPDATE | OHCI_BRANCH_ALWAYS);
+ OHCI_OUTPUT_LAST | OHCI_UPDATE | OHCI_BRANCH_ALWAYS);
#if 1
FWOHCI_DMA_WRITE(db[0].db.desc.res, 0);
FWOHCI_DMA_WRITE(db[2].db.desc.res, 0);
@@ -2711,51 +2569,42 @@ fwohci_add_tx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
int
fwohci_add_rx_buf(struct fwohci_dbch *dbch, struct fwohcidb_tr *db_tr,
- int poffset, struct fwdma_alloc *dummy_dma)
+ int poffset, struct fwdma_alloc *dummy_dma)
{
struct fwohcidb *db = db_tr->db;
- struct fw_xferq *ir;
+ struct fw_xferq *rq;
int i, ldesc;
bus_addr_t dbuf[2];
int dsiz[2];
- ir = &dbch->xferq;
- if (ir->buf == NULL && (dbch->xferq.flag & FWXFERQ_EXTBUF) == 0) {
- if (db_tr->buf == NULL)
- db_tr->buf = fwdma_malloc_size(
- dbch->dmat, &db_tr->dma_map,
- ir->psize, &dbuf[0], BUS_DMA_NOWAIT);
- if (db_tr->buf == NULL)
- return(ENOMEM);
+ rq = &dbch->xferq;
+ if (rq->buf == NULL && (dbch->xferq.flag & FWXFERQ_EXTBUF) == 0) {
+ /* async */
db_tr->dbcnt = 1;
- dsiz[0] = ir->psize;
- fw_bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
- BUS_DMASYNC_PREREAD);
+ dsiz[0] = rq->psize;
+ dbuf[0] = db_tr->dma_map->dm_segs[0].ds_addr;
} else {
+ /* isoc */
db_tr->dbcnt = 0;
- if (dummy_dma != NULL) {
- dsiz[db_tr->dbcnt] = sizeof(uint32_t);
- dbuf[db_tr->dbcnt++] = dummy_dma->bus_addr;
- }
- dsiz[db_tr->dbcnt] = ir->psize;
- if (ir->buf != NULL) {
- db_tr->buf = fwdma_v_addr(ir->buf, poffset);
- dbuf[db_tr->dbcnt] = fwdma_bus_addr( ir->buf, poffset);
+ dsiz[db_tr->dbcnt] = sizeof(uint32_t);
+ dbuf[db_tr->dbcnt++] = dummy_dma->bus_addr;
+ dsiz[db_tr->dbcnt] = rq->psize;
+ if (rq->buf != NULL) {
+ db_tr->buf = fwdma_v_addr(rq->buf, poffset);
+ dbuf[db_tr->dbcnt] = fwdma_bus_addr(rq->buf, poffset);
}
db_tr->dbcnt++;
}
- for(i = 0 ; i < db_tr->dbcnt ; i++){
+ for (i = 0; i < db_tr->dbcnt; i++) {
FWOHCI_DMA_WRITE(db[i].db.desc.addr, dbuf[i]);
FWOHCI_DMA_WRITE(db[i].db.desc.cmd, OHCI_INPUT_MORE | dsiz[i]);
- if (ir->flag & FWXFERQ_STREAM) {
+ if (rq->flag & FWXFERQ_STREAM)
FWOHCI_DMA_SET(db[i].db.desc.cmd, OHCI_UPDATE);
- }
FWOHCI_DMA_WRITE(db[i].db.desc.res, dsiz[i]);
}
ldesc = db_tr->dbcnt - 1;
- if (ir->flag & FWXFERQ_STREAM) {
+ if (rq->flag & FWXFERQ_STREAM)
FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_INPUT_LAST);
- }
FWOHCI_DMA_SET(db[ldesc].db.desc.cmd, OHCI_BRANCH_ALWAYS);
return 0;
}
@@ -2779,13 +2628,13 @@ fwohci_arcv_swap(struct fw_pkt *fp, int len)
/* determine length to swap */
switch (fp0->mode.common.tcode) {
case FWTCODE_WRES:
- CTR0(KTR_DEV, "WRES");
case FWTCODE_RREQQ:
case FWTCODE_WREQQ:
case FWTCODE_RRESQ:
case FWOHCITCODE_PHY:
slen = 12;
break;
+
case FWTCODE_RREQB:
case FWTCODE_WREQB:
case FWTCODE_LREQ:
@@ -2793,44 +2642,46 @@ fwohci_arcv_swap(struct fw_pkt *fp, int len)
case FWTCODE_LRES:
slen = 16;
break;
+
default:
- printf("Unknown tcode %d\n", fp0->mode.common.tcode);
- return(0);
+ aprint_error("Unknown tcode %d\n", fp0->mode.common.tcode);
+ return 0;
}
hlen = tinfo[fp0->mode.common.tcode].hdr_len;
if (hlen > len) {
if (firewire_debug)
printf("splitted header\n");
- return(-hlen);
+ return len - hlen;
}
#if BYTE_ORDER == BIG_ENDIAN
- for(i = 0; i < slen/4; i ++)
+ for (i = 0; i < slen / 4; i++)
fp->mode.ld[i] = FWOHCI_DMA_READ(fp->mode.ld[i]);
#endif
- return(hlen);
+ return hlen;
}
static int
-fwohci_get_plen(struct fwohci_softc *sc, struct fwohci_dbch *dbch, struct fw_pkt *fp)
+fwohci_get_plen(struct fwohci_softc *sc, struct fwohci_dbch *dbch,
+ struct fw_pkt *fp)
{
const struct tcode_info *info;
int r;
info = &tinfo[fp->mode.common.tcode];
r = info->hdr_len + sizeof(uint32_t);
- if ((info->flag & FWTI_BLOCK_ASY) != 0)
+ if (info->flag & FWTI_BLOCK_ASY)
r += roundup2(fp->mode.wreqb.len, sizeof(uint32_t));
if (r == sizeof(uint32_t)) {
/* XXX */
- fw_printf(sc->fc.dev, "Unknown tcode %d\n",
- fp->mode.common.tcode);
- return (-1);
+ aprint_error_dev(sc->fc.dev, "Unknown tcode %d\n",
+ fp->mode.common.tcode);
+ return -1;
}
if (r > dbch->xferq.psize) {
- fw_printf(sc->fc.dev, "Invalid packet length %d\n", r);
- return (-1);
+ aprint_error_dev(sc->fc.dev, "Invalid packet length %d\n", r);
+ return -1;
/* panic ? */
}
@@ -2839,103 +2690,108 @@ fwohci_get_plen(struct fwohci_softc *sc, struct fwohci_dbch *dbch, struct fw_pkt
static void
fwohci_arcv_free_buf(struct fwohci_softc *sc, struct fwohci_dbch *dbch,
- struct fwohcidb_tr *db_tr, uint32_t off, int wake)
+ struct fwohcidb_tr *db_tr, int wake)
{
- struct fwohcidb *db = &db_tr->db[0];
+ struct fwohcidb *db = db_tr->db;
+ struct fwohcidb_tr *bdb_tr = dbch->bottom;
FWOHCI_DMA_CLEAR(db->db.desc.depend, 0xf);
FWOHCI_DMA_WRITE(db->db.desc.res, dbch->xferq.psize);
- FWOHCI_DMA_SET(dbch->bottom->db[0].db.desc.depend, 1);
- fwdma_sync_multiseg_all(dbch->am,
+
+ fwdma_sync_multiseg(dbch->am, bdb_tr->idx, bdb_tr->idx,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ FWOHCI_DMA_SET(bdb_tr->db[0].db.desc.depend, dbch->ndesc);
+
+ fwdma_sync_multiseg(dbch->am, bdb_tr->idx, db_tr->idx,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
dbch->bottom = db_tr;
if (wake)
- OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
+ OWRITE(sc, OHCI_DMACTL(dbch->off), OHCI_CNTL_DMA_WAKE);
}
static void
-fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count)
+fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch)
{
struct fwohcidb_tr *db_tr;
+ struct fw_pkt pktbuf, *fp;
struct iovec vec[2];
- struct fw_pkt pktbuf;
- int nvec;
- struct fw_pkt *fp;
- uint8_t *ld;
- uint32_t stat, off, status, event;
+ bus_addr_t m;
+ bus_size_t n;
u_int spd;
- int len, plen, hlen, pcnt, offset;
- int s;
- void *buf;
- int resCount;
-
- CTR0(KTR_DEV, "fwohci_arv");
-
- if(&sc->arrq == dbch){
- off = OHCI_ARQOFF;
- }else if(&sc->arrs == dbch){
- off = OHCI_ARSOFF;
- }else{
- return;
- }
+ uint32_t stat, status, event;
+ uint8_t *ld;
+ int nvec, resCount, len, plen, hlen, offset;
+ const int psize = dbch->xferq.psize;
+#if 0
+static int prev_resCounts[16], i;
+#endif
+
+#if DIAGNOSTIC
+ if (dbch->off != OHCI_ARQOFF &&
+ dbch->off != OHCI_ARSOFF)
+ panic("not async rx");
+#endif
- s = splfw();
+ mutex_enter(&dbch->xferq.q_mtx);
db_tr = dbch->top;
- pcnt = 0;
/* XXX we cannot handle a packet which lies in more than two buf */
- fwdma_sync_multiseg_all(dbch->am,
+ fwdma_sync_multiseg(dbch->am, db_tr->idx, db_tr->idx,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) >> OHCI_STATUS_SHIFT;
resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) & OHCI_COUNT_MASK;
while (status & OHCI_CNTL_DMA_ACTIVE) {
#if 0
-
- if (off == OHCI_ARQOFF)
- printf("buf 0x%08x, status 0x%04x, resCount 0x%04x\n",
+prev_resCounts[i] = resCount;
+i = (i + 1) & 0xf;
+#endif
+#if 0
+ if (dbch->off == OHCI_ARQOFF)
+ aprint_normal_dev(sc->fc.dev,
+ "buf 0x%08x, status 0x%04x, resCount 0x%04x\n",
db_tr->bus_addr, status, resCount);
#endif
- len = dbch->xferq.psize - resCount;
+ n = 0;
+ len = psize - resCount;
ld = (uint8_t *)db_tr->buf;
if (dbch->pdb_tr == NULL) {
len -= dbch->buf_offset;
ld += dbch->buf_offset;
- }
+ m = dbch->buf_offset;
+ } else
+ m = 0;
if (len > 0)
- fw_bus_dmamap_sync(dbch->dmat, db_tr->dma_map,
- BUS_DMASYNC_POSTREAD);
- while (len > 0 ) {
- if (count >= 0 && count-- == 0)
- goto out;
- if(dbch->pdb_tr != NULL){
+ bus_dmamap_sync(sc->fc.dmat, db_tr->dma_map,
+ m, len, BUS_DMASYNC_POSTREAD);
+ while (len > 0) {
+ if (dbch->pdb_tr != NULL) {
/* we have a fragment in previous buffer */
- int rlen;
+ int rlen = 0;
+ void *buf;
- offset = dbch->buf_offset;
- if (offset < 0)
- offset = - offset;
- buf = (char *)dbch->pdb_tr->buf + offset;
- rlen = dbch->xferq.psize - offset;
- if (firewire_debug)
- printf("rlen=%d, offset=%d\n",
- rlen, dbch->buf_offset);
if (dbch->buf_offset < 0) {
/* splitted in header, pull up */
char *p;
+ rlen -= dbch->buf_offset;
+ buf = (char *)dbch->pdb_tr->buf +
+ psize - rlen;
+
+ KASSERT(rlen <= sizeof(pktbuf));
+
p = (char *)&pktbuf;
memcpy(p, buf, rlen);
p += rlen;
/* this must be too long but harmless */
rlen = sizeof(pktbuf) - rlen;
- if (rlen < 0)
- printf("why rlen < 0\n");
memcpy(p, db_tr->buf, rlen);
ld += rlen;
len -= rlen;
- hlen = fwohci_arcv_swap(&pktbuf, sizeof(pktbuf));
+ hlen = fwohci_arcv_swap(&pktbuf,
+ sizeof(pktbuf));
if (hlen <= 0) {
- printf("hlen should be positive.");
+ aprint_error_dev(sc->fc.dev,
+ "hlen should be positive.");
goto err;
}
offset = sizeof(pktbuf);
@@ -2943,24 +2799,31 @@ fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count)
vec[0].iov_len = offset;
} else {
/* splitted in payload */
+ buf = (char *)dbch->pdb_tr->buf +
+ dbch->buf_offset;
+ rlen = psize - dbch->buf_offset;
+ if (firewire_debug)
+ printf("rlen=%d, offset=%d\n",
+ rlen, dbch->buf_offset);
offset = rlen;
vec[0].iov_base = buf;
vec[0].iov_len = rlen;
}
- fp=(struct fw_pkt *)vec[0].iov_base;
+ fp = (struct fw_pkt *)vec[0].iov_base;
nvec = 1;
} else {
/* no fragment in previous buffer */
- fp=(struct fw_pkt *)ld;
+ fp = (struct fw_pkt *)ld;
hlen = fwohci_arcv_swap(fp, len);
if (hlen == 0)
goto err;
if (hlen < 0) {
dbch->pdb_tr = db_tr;
- dbch->buf_offset = - dbch->buf_offset;
+ dbch->buf_offset -= psize;
/* sanity check */
if (resCount != 0) {
- printf("resCount=%d hlen=%d\n",
+ aprint_error_dev(sc->fc.dev,
+ "resCount=%d hlen=%d\n",
resCount, hlen);
goto err;
}
@@ -2971,9 +2834,12 @@ fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count)
}
plen = fwohci_get_plen(sc, dbch, fp) - offset;
if (plen < 0) {
- /* minimum header size + trailer
- = sizeof(fw_pkt) so this shouldn't happens */
- printf("plen(%d) is negative! offset=%d\n",
+ /*
+ * minimum header size + trailer =
+ * sizeof(fw_pkt) so this shouldn't happens
+ */
+ aprint_error_dev(sc->fc.dev,
+ "plen(%d) is negative! offset=%d\n",
plen, offset);
goto err;
}
@@ -2984,8 +2850,9 @@ fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count)
if (firewire_debug)
printf("splitted payload\n");
/* sanity check */
- if (resCount != 0) {
- printf("resCount=%d plen=%d"
+ if (resCount != 0) {
+ aprint_error_dev(sc->fc.dev,
+ "resCount=%d plen=%d"
" len=%d\n",
resCount, plen, len);
goto err;
@@ -2994,33 +2861,35 @@ fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count)
}
vec[nvec].iov_base = ld;
vec[nvec].iov_len = plen;
- nvec ++;
+ nvec++;
ld += plen;
}
- dbch->buf_offset = ld - (uint8_t *)db_tr->buf;
if (nvec == 0)
- printf("nvec == 0\n");
+ aprint_error_dev(sc->fc.dev, "nvec == 0\n");
/* DMA result-code will be written at the tail of packet */
- stat = FWOHCI_DMA_READ(*(uint32_t *)(ld - sizeof(struct fwohci_trailer)));
+ stat = FWOHCI_DMA_READ(*(uint32_t *)(ld -
+ sizeof(struct fwohci_trailer)));
#if 0
- printf("plen: %d, stat %x\n",
- plen ,stat);
+ aprint_normal("plen: %d, stat %x\n", plen, stat);
#endif
spd = (stat >> 21) & 0x3;
event = (stat >> 16) & 0x1f;
switch (event) {
case FWOHCIEV_ACKPEND:
#if 0
- printf("fwohci_arcv: ack pending tcode=0x%x..\n", fp->mode.common.tcode);
+ aprint_normal(sc->fc.dev,
+ "ack pending tcode=0x%x..\n",
+ fp->mode.common.tcode);
#endif
/* fall through */
case FWOHCIEV_ACKCOMPL:
{
struct fw_rcv_buf rb;
- if ((vec[nvec-1].iov_len -=
- sizeof(struct fwohci_trailer)) == 0)
+ vec[nvec - 1].iov_len -=
+ sizeof(struct fwohci_trailer);
+ if (vec[nvec - 1].iov_len == 0)
nvec--;
rb.fc = &sc->fc;
rb.vec = vec;
@@ -3032,97 +2901,155 @@ fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count)
case FWOHCIEV_BUSRST:
if ((sc->fc.status != FWBUSRESET) &&
(sc->fc.status != FWBUSINIT))
- printf("got BUSRST packet!?\n");
+ aprint_error_dev(sc->fc.dev,
+ "got BUSRST packet!?\n");
break;
default:
- fw_printf(sc->fc.dev,
+ aprint_error_dev(sc->fc.dev,
"Async DMA Receive error err=%02x %s"
" plen=%d offset=%d len=%d status=0x%08x"
" tcode=0x%x, stat=0x%08x\n",
event, fwohcicode[event], plen,
- dbch->buf_offset, len,
- OREAD(sc, OHCI_DMACTL(off)),
+ (int)(ld - (uint8_t *)db_tr->buf - plen),
+ len, OREAD(sc, OHCI_DMACTL(dbch->off)),
fp->mode.common.tcode, stat);
#if 1 /* XXX */
goto err;
#endif
break;
}
- pcnt ++;
+#if 0
+{
+extern int dbgflg;
+if (dbgflg) {
+ if (dbgflg == 8) {
+ int j;
+
+ printf("%s: i=%d, resCount=%d", __func__, i, prev_resCounts[0]);
+ for (j = 1; j < 16; j++)
+ printf(", %d", prev_resCounts[j]);
+ printf("\n");
+ }
+ printf("%s:", __func__);
+ if (dbch->off == OHCI_ARQOFF)
+ printf(" ARQ:");
+ else
+ printf(" ARS:");
+ printf(" plen=%d, offset=%d, buf_offset=%d,", plen, offset, dbch->buf_offset);
+ printf(" idx=%d, resCount=%d,", db_tr->idx, resCount);
+ if (dbch->pdb_tr != NULL)
+ printf(" pdb=%p", &dbch->pdb_tr->db[0].db);
+ printf(" db=%p\n", &db_tr->db[0].db);
+ dbgflg--;
+}
+}
+#endif
if (dbch->pdb_tr != NULL) {
- fwohci_arcv_free_buf(sc, dbch, dbch->pdb_tr,
- off, 1);
+ if (dbch->buf_offset < 0)
+ bus_dmamap_sync(sc->fc.dmat,
+ dbch->pdb_tr->dma_map,
+ psize + dbch->buf_offset,
+ 0 - dbch->buf_offset,
+ BUS_DMASYNC_PREREAD);
+ else
+ bus_dmamap_sync(sc->fc.dmat,
+ dbch->pdb_tr->dma_map,
+ dbch->buf_offset,
+ psize - dbch->buf_offset,
+ BUS_DMASYNC_PREREAD);
+ fwohci_arcv_free_buf(sc, dbch, dbch->pdb_tr, 1);
dbch->pdb_tr = NULL;
}
-
+ dbch->buf_offset = ld - (uint8_t *)db_tr->buf;
+ n += (plen + offset);
}
out:
- if (resCount == 0) {
- /* done on this buffer */
- if (dbch->pdb_tr == NULL) {
- fwohci_arcv_free_buf(sc, dbch, db_tr, off, 1);
- dbch->buf_offset = 0;
- } else
- if (dbch->pdb_tr != db_tr)
- printf("pdb_tr != db_tr\n");
- db_tr = STAILQ_NEXT(db_tr, link);
- fwdma_sync_multiseg_all(dbch->am,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
- >> OHCI_STATUS_SHIFT;
- resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
- & OHCI_COUNT_MASK;
- /* XXX check buffer overrun */
- dbch->top = db_tr;
- } else {
- dbch->buf_offset = dbch->xferq.psize - resCount;
- fw_bus_dmamap_sync(
- dbch->dmat, db_tr->dma_map, BUS_DMASYNC_PREREAD);
+ if (n > 0)
+ bus_dmamap_sync(sc->fc.dmat, db_tr->dma_map, m, n,
+ BUS_DMASYNC_PREREAD);
+
+ if (resCount != 0) {
+ dbch->buf_offset = psize - resCount;
break;
}
+
+ /* done on this buffer */
+
+ if (dbch->pdb_tr == NULL) {
+ fwohci_arcv_free_buf(sc, dbch, db_tr, 1);
+ dbch->buf_offset = 0;
+ } else
+ if (dbch->pdb_tr != db_tr)
+ aprint_error_dev(sc->fc.dev,
+ "pdb_tr != db_tr\n");
+ dbch->top = STAILQ_NEXT(db_tr, link);
+
+ db_tr = dbch->top;
+ fwdma_sync_multiseg(dbch->am, db_tr->idx, db_tr->idx,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) >>
+ OHCI_STATUS_SHIFT;
+ resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
+ & OHCI_COUNT_MASK;
+
+ /* XXX check buffer overrun */
+
/* XXX make sure DMA is not dead */
}
+ fwdma_sync_multiseg(dbch->am, db_tr->idx, db_tr->idx,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
#if 0
- if (pcnt < 1)
- printf("fwohci_arcv: no packets\n");
+{
+uint32_t _status;
+
+fwdma_sync_multiseg(dbch->am, db_tr->idx, db_tr->idx, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+_status = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res) >> OHCI_STATUS_SHIFT;
+if (status != _status)
+printf("Ooops status ? 0x%x : 0x%x, %p\n", status, _status, db_tr->db);
+fwdma_sync_multiseg(dbch->am, db_tr->idx, db_tr->idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+_status = FWOHCI_DMA_READ(((struct fwohcidb *)MIPS_PHYS_TO_KSEG1(MIPS_KSEG0_TO_PHYS(db_tr->db)))[0].db.desc.res) >> OHCI_STATUS_SHIFT;
+if (status != _status)
+printf("Ooooops status ? 0x%x : 0x%x\n", status, _status);
+}
+#endif
+ mutex_exit(&dbch->xferq.q_mtx);
+#if 0
+prev_resCounts[i] = resCount;
+i = (i + 1) & 0xf;
#endif
- fwdma_sync_multiseg_all(dbch->am,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- splx(s);
return;
err:
- fw_printf(sc->fc.dev, "AR DMA status=%x, ",
- OREAD(sc, OHCI_DMACTL(off)));
- dbch->pdb_tr = NULL;
+ aprint_error_dev(sc->fc.dev, "AR DMA status=%x, ",
+ OREAD(sc, OHCI_DMACTL(dbch->off)));
+ if (dbch->pdb_tr != NULL) {
+ if (dbch->buf_offset < 0)
+ bus_dmamap_sync(sc->fc.dmat, dbch->pdb_tr->dma_map,
+ psize + dbch->buf_offset, 0 - dbch->buf_offset,
+ BUS_DMASYNC_PREREAD);
+ else
+ bus_dmamap_sync(sc->fc.dmat, dbch->pdb_tr->dma_map,
+ dbch->buf_offset, psize - dbch->buf_offset,
+ BUS_DMASYNC_PREREAD);
+ fwohci_arcv_free_buf(sc, dbch, dbch->pdb_tr, 1);
+ dbch->pdb_tr = NULL;
+ }
/* skip until resCount != 0 */
- printf(" skip buffer");
+ aprint_error(" skip buffer");
while (resCount == 0) {
- printf(" #");
- fwohci_arcv_free_buf(sc, dbch, db_tr, off, 0);
+ aprint_error(" #");
+ fwohci_arcv_free_buf(sc, dbch, db_tr, 0);
db_tr = STAILQ_NEXT(db_tr, link);
resCount = FWOHCI_DMA_READ(db_tr->db[0].db.desc.res)
- & OHCI_COUNT_MASK;
+ & OHCI_COUNT_MASK;
}
- printf(" done\n");
+ aprint_error(" done\n");
dbch->top = db_tr;
- dbch->buf_offset = dbch->xferq.psize - resCount;
- OWRITE(sc, OHCI_DMACTL(off), OHCI_CNTL_DMA_WAKE);
- fwdma_sync_multiseg_all(
- dbch->am, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- fw_bus_dmamap_sync(dbch->dmat, db_tr->dma_map, BUS_DMASYNC_PREREAD);
- splx(s);
-}
-#if defined(__NetBSD__)
-
-int
-fwohci_print(void *aux, const char *pnp)
-{
- struct fw_attach_args *fwa = (struct fw_attach_args *)aux;
-
- if (pnp)
- aprint_normal("%s at %s", fwa->name, pnp);
-
- return UNCONF;
+ dbch->buf_offset = psize - resCount;
+ OWRITE(sc, OHCI_DMACTL(dbch->off), OHCI_CNTL_DMA_WAKE);
+ fwdma_sync_multiseg(dbch->am, db_tr->idx, db_tr->idx,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ bus_dmamap_sync(sc->fc.dmat, db_tr->dma_map,
+ 0, db_tr->dma_map->dm_mapsize, BUS_DMASYNC_PREREAD);
+ mutex_exit(&dbch->xferq.q_mtx);
}
-#endif
diff --git a/sys/dev/ieee1394/fwohcireg.h b/sys/dev/ieee1394/fwohcireg.h
index 3a468c6ed80..f1853f781ba 100644
--- a/sys/dev/ieee1394/fwohcireg.h
+++ b/sys/dev/ieee1394/fwohcireg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: fwohcireg.h,v 1.17 2007/11/05 19:08:57 kiyohara Exp $ */
+/* $NetBSD: fwohcireg.h,v 1.18 2010/03/29 03:05:27 kiyohara Exp $ */
/*-
* Copyright (c) 2003 Hidetoshi Shimokawa
@@ -32,10 +32,13 @@
* 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.
- *
- * $FreeBSD: src/sys/dev/firewire/fwohcireg.h,v 1.23 2007/04/30 14:06:30 simokawa Exp $
+ *
+ * $FreeBSD: src/sys/dev/firewire/fwohcireg.h,v 1.24 2009/02/12 03:05:42 sbruno Exp $
*
*/
+#ifndef _FWOHCIREG_H_
+#define _FWOHCIREG_H_
+
#define PCI_CBMEM PCIR_BAR(0)
#define FW_VENDORID_NATSEMI 0x100B
@@ -83,16 +86,12 @@
#define PCI_INTERFACE_OHCI 0x10
-#if defined(__FreeBSD__)
-#define FW_OHCI_BASE_REG 0x10
-#elif defined(__NetBSD__)
#define PCI_OHCI_MAP_REGISTER 0x10
-#endif
-#define OHCI_DMA_ITCH 0x20
-#define OHCI_DMA_IRCH 0x20
+#define OHCI_DMA_ITCH 0x20
+#define OHCI_DMA_IRCH 0x20
-#define OHCI_MAX_DMA_CH (0x4 + OHCI_DMA_ITCH + OHCI_DMA_IRCH)
+#define OHCI_MAX_DMA_CH (0x4 + OHCI_DMA_ITCH + OHCI_DMA_IRCH)
typedef uint32_t fwohcireg_t;
@@ -190,7 +189,7 @@ struct fwohcidb {
#define FWOHCIEV_MASK 0x1f
-struct ohci_dma{
+struct ohci_dma {
fwohcireg_t cntl;
#define OHCI_CNTL_CYCMATCH_S (0x1 << 31)
@@ -217,7 +216,7 @@ struct ohci_dma{
fwohcireg_t dummy3;
};
-struct ohci_itdma{
+struct ohci_itdma {
fwohcireg_t cntl;
fwohcireg_t cntl_clr;
fwohcireg_t dummy0;
@@ -268,20 +267,20 @@ struct ohci_registers {
#define FWOHCI_INTSTATCLR 0x84
#define FWOHCI_INTMASK 0x88
#define FWOHCI_INTMASKCLR 0x8c
- fwohcireg_t int_stat; /* 0x80 */
- fwohcireg_t int_clear; /* 0x84 */
- fwohcireg_t int_mask; /* 0x88 */
- fwohcireg_t int_mask_clear; /* 0x8c */
- fwohcireg_t it_int_stat; /* 0x90 */
- fwohcireg_t it_int_clear; /* 0x94 */
- fwohcireg_t it_int_mask; /* 0x98 */
- fwohcireg_t it_mask_clear; /* 0x9c */
- fwohcireg_t ir_int_stat; /* 0xa0 */
- fwohcireg_t ir_int_clear; /* 0xa4 */
- fwohcireg_t ir_int_mask; /* 0xa8 */
- fwohcireg_t ir_mask_clear; /* 0xac */
- fwohcireg_t dummy5[11]; /* dummy 0xb0-d8 */
- fwohcireg_t fairness; /* fairness control 0xdc */
+ fwohcireg_t int_stat; /* 0x80 */
+ fwohcireg_t int_clear; /* 0x84 */
+ fwohcireg_t int_mask; /* 0x88 */
+ fwohcireg_t int_mask_clear; /* 0x8c */
+ fwohcireg_t it_int_stat; /* 0x90 */
+ fwohcireg_t it_int_clear; /* 0x94 */
+ fwohcireg_t it_int_mask; /* 0x98 */
+ fwohcireg_t it_mask_clear; /* 0x9c */
+ fwohcireg_t ir_int_stat; /* 0xa0 */
+ fwohcireg_t ir_int_clear; /* 0xa4 */
+ fwohcireg_t ir_int_mask; /* 0xa8 */
+ fwohcireg_t ir_mask_clear; /* 0xac */
+ fwohcireg_t dummy5[11]; /* dummy 0xb0-d8 */
+ fwohcireg_t fairness; /* fairness control 0xdc */
fwohcireg_t link_cntl; /* Chip control 0xe0*/
fwohcireg_t link_cntl_clr; /* Chip control clear 0xe4*/
#define FWOHCI_NODEID 0xe8
@@ -334,7 +333,8 @@ struct ohci_registers {
struct ohci_dma dma_irch[0x20];
};
-struct fwohcidb_tr{
+struct fwohcidb_tr {
+ int idx;
STAILQ_ENTRY(fwohcidb_tr) link;
struct fw_xfer *xfer;
struct fwohcidb *db;
@@ -347,8 +347,8 @@ struct fwohcidb_tr{
/*
* OHCI info structure.
*/
-struct fwohci_txpkthdr{
- union{
+struct fwohci_txpkthdr {
+ union {
uint32_t ld[4];
struct {
#if BYTE_ORDER == BIG_ENDIAN
@@ -362,7 +362,7 @@ struct fwohci_txpkthdr{
:8,
spd:16; /* XXX include reserved fields */
#endif
- }common;
+ } common;
struct {
#if BYTE_ORDER == BIG_ENDIAN
uint32_t :8,
@@ -382,11 +382,11 @@ struct fwohci_txpkthdr{
:8;
#endif
BIT16x2(dst, );
- }asycomm;
+ } asycomm;
struct {
#if BYTE_ORDER == BIG_ENDIAN
uint32_t :13,
- spd:3,
+ spd:3,
chtag:8,
tcode:4,
sy:4;
@@ -394,14 +394,14 @@ struct fwohci_txpkthdr{
uint32_t sy:4,
tcode:4,
chtag:8,
- spd:3,
+ spd:3,
:13;
#endif
BIT16x2(len, );
- }stream;
- }mode;
+ } stream;
+ } mode;
};
-struct fwohci_trailer{
+struct fwohci_trailer {
#if BYTE_ORDER == BIG_ENDIAN
uint32_t stat:16,
time:16;
@@ -417,38 +417,39 @@ struct fwohci_trailer{
#define OHCI_CNTL_PHYPKT (0x1 << 10)
#define OHCI_CNTL_SID (0x1 << 9)
+/*
+ * defined in OHCI 1.1
+ * chapter 6.1
+ */
#define OHCI_INT_DMA_ATRQ (0x1 << 0)
#define OHCI_INT_DMA_ATRS (0x1 << 1)
#define OHCI_INT_DMA_ARRQ (0x1 << 2)
#define OHCI_INT_DMA_ARRS (0x1 << 3)
#define OHCI_INT_DMA_PRRQ (0x1 << 4)
#define OHCI_INT_DMA_PRRS (0x1 << 5)
-#define OHCI_INT_DMA_IT (0x1 << 6)
-#define OHCI_INT_DMA_IR (0x1 << 7)
-#define OHCI_INT_PW_ERR (0x1 << 8)
-#define OHCI_INT_LR_ERR (0x1 << 9)
-
+#define OHCI_INT_DMA_IT (0x1 << 6)
+#define OHCI_INT_DMA_IR (0x1 << 7)
+#define OHCI_INT_PW_ERR (0x1 << 8)
+#define OHCI_INT_LR_ERR (0x1 << 9)
#define OHCI_INT_PHY_SID (0x1 << 16)
#define OHCI_INT_PHY_BUS_R (0x1 << 17)
-
#define OHCI_INT_REG_FAIL (0x1 << 18)
-
#define OHCI_INT_PHY_INT (0x1 << 19)
#define OHCI_INT_CYC_START (0x1 << 20)
#define OHCI_INT_CYC_64SECOND (0x1 << 21)
#define OHCI_INT_CYC_LOST (0x1 << 22)
#define OHCI_INT_CYC_ERR (0x1 << 23)
-
#define OHCI_INT_ERR (0x1 << 24)
#define OHCI_INT_CYC_LONG (0x1 << 25)
#define OHCI_INT_PHY_REG (0x1 << 26)
-
#define OHCI_INT_EN (0x1 << 31)
-#define IP_CHANNELS 0x0234
+#define IP_CHANNELS 0x0234
#define FWOHCI_MAXREC 2048
#define OHCI_ISORA 0x02
#define OHCI_ISORB 0x04
#define FWOHCITCODE_PHY 0xe
+
+#endif /* _FWOHCIREG_H_ */
diff --git a/sys/dev/ieee1394/fwohcivar.h b/sys/dev/ieee1394/fwohcivar.h
index 0543c5d9fb2..04f0e32758f 100644
--- a/sys/dev/ieee1394/fwohcivar.h
+++ b/sys/dev/ieee1394/fwohcivar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: fwohcivar.h,v 1.29 2007/11/06 15:24:11 kiyohara Exp $ */
+/* $NetBSD: fwohcivar.h,v 1.30 2010/03/29 03:05:28 kiyohara Exp $ */
/*-
* Copyright (c) 2003 Hidetoshi SHimokawa
@@ -36,31 +36,24 @@
* $FreeBSD: src/sys/dev/firewire/fwohcivar.h,v 1.16 2007/06/06 14:31:36 simokawa Exp $
*
*/
+#ifndef _FWOHCIVAR_H_
+#define _FWOHCIVAR_H_
-#if defined(__NetBSD__)
MALLOC_DECLARE(M_FW);
-#endif
-typedef struct fwohci_softc {
+struct fwohci_softc {
struct firewire_comm fc;
bus_space_tag_t bst;
bus_space_handle_t bsh;
-#if defined(__FreeBSD__)
- void *ih;
-#if defined(__DragonFly__) || __FreeBSD_version < 500000
- void *ih_cam;
- void *ih_bio;
-#endif
- struct resource *bsr;
- struct resource *irq_res;
-#elif defined(__NetBSD__)
bus_size_t bssize;
-#endif
- struct fwohci_dbch{
+ struct fwohci_dbch {
+ int off;
u_int ndb;
u_int ndesc;
STAILQ_HEAD(, fwohcidb_tr) db_trq;
- struct fwohcidb_tr *top, *bottom, *pdb_tr;
+ struct fwohcidb_tr *top;
+ struct fwohcidb_tr *bottom;
+ struct fwohcidb_tr *pdb_tr;
struct fw_xferq xferq;
int flags;
#define FWOHCI_DBCH_INIT (1<<0)
@@ -70,30 +63,26 @@ typedef struct fwohci_softc {
#define FWOHCI_DBCH_MAX_PAGES 32
/* Context programs buffer */
struct fwdma_alloc_multi *am;
- fw_bus_dma_tag_t dmat;
} arrq, arrs, atrq, atrs, it[OHCI_DMA_ITCH], ir[OHCI_DMA_IRCH];
u_int maxrec;
uint32_t *sid_buf;
struct fwdma_alloc sid_dma;
struct fwdma_alloc crom_dma;
struct fwdma_alloc dummy_dma;
- uint32_t intmask, irstat, itstat;
+ uint32_t intmask;
uint32_t intstat;
- fw_task_t fwohci_task_busreset;
- fw_task_t fwohci_task_sid;
- fw_task_t fwohci_task_dma;
+ uint32_t irstat;
+ uint32_t itstat;
int cycle_lost;
-} fwohci_softc_t;
+};
-void fwohci_intr (void *arg);
-int fwohci_filt (void *arg);
-int fwohci_init (struct fwohci_softc *, device_t);
-void fwohci_poll (struct firewire_comm *, int, int);
-void fwohci_reset (struct fwohci_softc *, device_t);
-#if defined(__FreeBSD__)
-int fwohci_detach(struct fwohci_softc *, device_t);
-#elif defined(__NetBSD__)
+#define OWRITE(sc, r, x) bus_space_write_4((sc)->bst, (sc)->bsh, (r), (x))
+#define OREAD(sc, r) bus_space_read_4((sc)->bst, (sc)->bsh, (r))
+
+int fwohci_init(struct fwohci_softc *);
int fwohci_detach(struct fwohci_softc *, int);
-#endif
-int fwohci_resume (struct fwohci_softc *, device_t);
-int fwohci_stop (struct fwohci_softc *, device_t dev);
+int fwohci_intr(void *arg);
+int fwohci_resume(struct fwohci_softc *);
+int fwohci_stop(struct fwohci_softc *);
+
+#endif /* _FWOHCIVAR_H_ */
diff --git a/sys/dev/ieee1394/fwphyreg.h b/sys/dev/ieee1394/fwphyreg.h
index 07bb1442957..791a2e5d3a9 100644
--- a/sys/dev/ieee1394/fwphyreg.h
+++ b/sys/dev/ieee1394/fwphyreg.h
@@ -1,8 +1,8 @@
-/* $NetBSD: fwphyreg.h,v 1.2 2005/12/11 12:22:02 christos Exp $ */
+/* $NetBSD: fwphyreg.h,v 1.3 2010/03/29 03:05:28 kiyohara Exp $ */
/*-
* Copyright (C) 2003
* Hidetoshi Shimokawa. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +19,7 @@
* 4. Neither the name of the author 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 REGENTS 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
@@ -31,10 +31,17 @@
* 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.
- *
- * $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/fwphyreg.h,v 1.3 2005/01/06 01:42:41 imp Exp $
+ *
+ * $FreeBSD: src/sys/dev/firewire/fwphyreg.h,v 1.4 2009/02/12 03:05:42 sbruno Exp $
*/
+#ifndef _FWPHYREG_H_
+#define _FWPHYREG_H_
+
+/*
+ * IEEE 1394a
+ * Figure 5B - 1
+ */
struct phyreg_base {
#if BYTE_ORDER == BIG_ENDIAN
uint8_t phy_id:6,
@@ -101,6 +108,10 @@ struct phyreg_base {
#endif
};
+/*
+ * IEEE 1394a
+ * Figure 5B - 2
+ */
struct phyreg_page0 {
#if BYTE_ORDER == BIG_ENDIAN
uint8_t astat:2,
@@ -161,9 +172,15 @@ struct phyreg_page0 {
#endif
};
+/*
+ * IEEE 1394a
+ * Figure 5B - 3
+ */
struct phyreg_page1 {
uint8_t compliance;
uint8_t :8;
uint8_t vendor_id[3];
uint8_t product_id[3];
};
+
+#endif /* _FWPHYREG_H_ */
diff --git a/sys/dev/ieee1394/iec13213.h b/sys/dev/ieee1394/iec13213.h
index bcae4ffdf1c..75a91588bc2 100644
--- a/sys/dev/ieee1394/iec13213.h
+++ b/sys/dev/ieee1394/iec13213.h
@@ -1,4 +1,4 @@
-/* $NetBSD: iec13213.h,v 1.3 2008/05/02 19:50:04 xtraeme Exp $ */
+/* $NetBSD: iec13213.h,v 1.4 2010/03/29 03:05:28 kiyohara Exp $ */
/*-
* Copyright (c) 2003 Hidetoshi Shimokawa
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
@@ -31,11 +31,14 @@
* 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.
- *
+ *
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/iec13213.h,v 1.14 2005/01/06 01:42:41 imp Exp $
*
*/
+#ifndef _IEC13213_H_
+#define _IEC13213_H_
+
#define STATE_CLEAR 0x0000
#define STATE_SET 0x0004
#define NODE_IDS 0x0008
@@ -162,7 +165,7 @@ struct csrtext {
struct bus_info {
#define CSR_BUS_NAME_IEEE1394 0x31333934
- uint32_t bus_name;
+ uint32_t bus_name;
#if BYTE_ORDER == BIG_ENDIAN
uint32_t irmc:1, /* iso. resource manager capable */
cmc:1, /* cycle master capable */
@@ -233,12 +236,12 @@ struct crom_src {
struct crom_chunk {
STAILQ_ENTRY(crom_chunk) link;
- struct crom_chunk *ref_chunk;
- int ref_index;
+ struct crom_chunk *ref_chunk;
+ int ref_index;
int offset;
struct {
BIT16x2(crc_len, crc);
- uint32_t buf[CROM_MAX_CHUNK_LEN];
+ uint32_t buf[CROM_MAX_CHUNK_LEN];
} data;
};
@@ -250,3 +253,5 @@ extern int crom_add_simple_text(struct crom_src *src, struct crom_chunk *,
struct crom_chunk *, const char *);
extern int crom_load(struct crom_src *, uint32_t *, int);
#endif
+
+#endif /* _IEC13213_H_ */
diff --git a/sys/dev/ieee1394/iec68113.h b/sys/dev/ieee1394/iec68113.h
index effec445d26..1396db25146 100644
--- a/sys/dev/ieee1394/iec68113.h
+++ b/sys/dev/ieee1394/iec68113.h
@@ -1,4 +1,4 @@
-/* $NetBSD: iec68113.h,v 1.3 2008/09/08 23:36:54 gmcgarry Exp $ */
+/* $NetBSD: iec68113.h,v 1.4 2010/03/29 03:05:28 kiyohara Exp $ */
/*-
* Copyright (c) 2003 Hidetoshi Shimokawa
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
@@ -31,11 +31,14 @@
* 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.
- *
+ *
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/iec68113.h,v 1.9 2005/01/06 01:42:41 imp Exp $
*
*/
+#ifndef _IEC68113_H_
+#define _IEC68113_H_
+
#define DV_BROADCAST_ON (1<<30)
#define oMPR 0x900
#define oPCR 0x904
@@ -126,3 +129,5 @@ struct dvdbc{
uint8_t payload[77];
#define DV_DSF_12 0x80 /* PAL: payload[0] in Header DIF */
};
+
+#endif /* _IEC68113_H_ */
diff --git a/sys/dev/ieee1394/if_fwip.c b/sys/dev/ieee1394/if_fwip.c
index 8d5e33506b2..88b3ceeb7d1 100644
--- a/sys/dev/ieee1394/if_fwip.c
+++ b/sys/dev/ieee1394/if_fwip.c
@@ -1,10 +1,10 @@
-/* $NetBSD: if_fwip.c,v 1.21 2010/03/11 04:00:37 mrg Exp $ */
+/* $NetBSD: if_fwip.c,v 1.22 2010/03/29 03:05:28 kiyohara Exp $ */
/*-
* Copyright (c) 2004
* Doug Rabson
* Copyright (c) 2002-2003
* Hidetoshi Shimokawa. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +21,7 @@
* 4. Neither the name of the author 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 REGENTS 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
@@ -33,69 +33,31 @@
* 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.
- *
- * $FreeBSD: src/sys/dev/firewire/if_fwip.c,v 1.16 2007/06/06 14:31:36 simokawa Exp $
+ *
+ * $FreeBSD: src/sys/dev/firewire/if_fwip.c,v 1.18 2009/02/09 16:58:18 fjoe Exp $
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_fwip.c,v 1.21 2010/03/11 04:00:37 mrg Exp $");
-
-#ifdef HAVE_KERNEL_OPTION_HEADERS
-#include "opt_device_polling.h"
-#include "opt_inet.h"
-#endif
+__KERNEL_RCSID(0, "$NetBSD: if_fwip.c,v 1.22 2010/03/29 03:05:28 kiyohara Exp $");
-#if defined(__FreeBSD__)
#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/sysctl.h>
-#include <sys/systm.h>
-#include <sys/taskqueue.h>
-#include <sys/module.h>
#include <sys/bus.h>
-#include <sys/bus.h>
-
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/firewire.h>
-#include <net/if_arp.h>
-#include <net/if_types.h>
-#ifdef __DragonFly__
-#include <bus/firewire/fw_port.h>
-#include <bus/firewire/firewire.h>
-#include <bus/firewire/firewirereg.h>
-#include "if_fwipvar.h"
-#else
-#include <dev/firewire/fw_port.h>
-#include <dev/firewire/firewire.h>
-#include <dev/firewire/firewirereg.h>
-#include <dev/firewire/iec13213.h>
-#include <dev/firewire/if_fwipvar.h>
-#endif
-#elif defined(__NetBSD__)
-#include <sys/param.h>
#include <sys/device.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#include <sys/mutex.h>
#include <sys/sysctl.h>
-#include <sys/bus.h>
-
+#include <net/bpf.h>
#include <net/if.h>
#include <net/if_ieee1394.h>
#include <net/if_types.h>
-#include <dev/ieee1394/fw_port.h>
#include <dev/ieee1394/firewire.h>
#include <dev/ieee1394/firewirereg.h>
#include <dev/ieee1394/iec13213.h>
#include <dev/ieee1394/if_fwipvar.h>
-#endif
/*
* We really need a mechanism for allocating regions in the FIFO
@@ -106,36 +68,35 @@ __KERNEL_RCSID(0, "$NetBSD: if_fwip.c,v 1.21 2010/03/11 04:00:37 mrg Exp $");
*/
#define INET_FIFO 0xfffe00000000LL
-#if defined(__FreeBSD__)
-#define FWIPDEBUG if (fwipdebug) if_printf
-#elif defined(__NetBSD__)
#define FWIPDEBUG if (fwipdebug) aprint_debug_ifnet
-#endif
#define TX_MAX_QUEUE (FWMAXQUEUE - 1)
-#if defined(__NetBSD__)
-int fwipmatch (device_t, cfdata_t, void *);
-void fwipattach (device_t, device_t, void *);
-int fwipdetach (device_t, int);
-int fwipactivate (device_t, enum devact);
-#endif
+struct fw_hwaddr {
+ uint32_t sender_unique_ID_hi;
+ uint32_t sender_unique_ID_lo;
+ uint8_t sender_max_rec;
+ uint8_t sspd;
+ uint16_t sender_unicast_FIFO_hi;
+ uint32_t sender_unicast_FIFO_lo;
+};
+
+
+static int fwipmatch(device_t, cfdata_t, void *);
+static void fwipattach(device_t, device_t, void *);
+static int fwipdetach(device_t, int);
+static int fwipactivate(device_t, enum devact);
+
/* network interface */
-static void fwip_start (struct ifnet *);
-static int fwip_ioctl (struct ifnet *, u_long, void *);
-#if defined(__FreeBSD__)
-static void fwip_init(void *);
-static void fwip_stop(struct fwip_softc *);
-#elif defined(__NetBSD__)
+static void fwip_start(struct ifnet *);
+static int fwip_ioctl(struct ifnet *, u_long, void *);
static int fwip_init(struct ifnet *);
static void fwip_stop(struct ifnet *, int);
-#endif
-static void fwip_post_busreset (void *);
-static void fwip_output_callback (struct fw_xfer *);
-static void fwip_async_output (struct fwip_softc *, struct ifnet *);
-static void fwip_start_send (void *, int);
-static void fwip_stream_input (struct fw_xferq *);
+static void fwip_post_busreset(void *);
+static void fwip_output_callback(struct fw_xfer *);
+static void fwip_async_output(struct fwip_softc *, struct ifnet *);
+static void fwip_stream_input(struct fw_xferq *);
static void fwip_unicast_input(struct fw_xfer *);
static int fwipdebug = 0;
@@ -143,17 +104,6 @@ static int broadcast_channel = 0xc0 | 0x1f; /* tag | channel(XXX) */
static int tx_speed = 2;
static int rx_queue_len = FWMAXQUEUE;
-#if defined(__FreeBSD__)
-MALLOC_DEFINE(M_FWIP, "if_fwip", "IP over FireWire interface");
-SYSCTL_INT(_debug, OID_AUTO, if_fwip_debug, CTLFLAG_RW, &fwipdebug, 0, "");
-SYSCTL_DECL(_hw_firewire);
-SYSCTL_NODE(_hw_firewire, OID_AUTO, fwip, CTLFLAG_RD, 0,
- "Firewire ip subsystem");
-SYSCTL_INT(_hw_firewire_fwip, OID_AUTO, rx_queue_len, CTLFLAG_RW, &rx_queue_len,
- 0, "Length of the receive queue");
-
-TUNABLE_INT("hw.firewire.fwip.rx_queue_len", &rx_queue_len);
-#elif defined(__NetBSD__)
MALLOC_DEFINE(M_FWIP, "if_fwip", "IP over IEEE1394 interface");
/*
* Setup sysctl(3) MIB, hw.fwip.*
@@ -200,222 +150,190 @@ SYSCTL_SETUP(sysctl_fwip, "sysctl fwip(4) subtree setup")
return;
err:
- printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
+ aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
}
-#endif
-#ifdef DEVICE_POLLING
-static poll_handler_t fwip_poll;
-static void
-fwip_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
-{
- struct fwip_softc *fwip;
- struct firewire_comm *fc;
-
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- return;
+CFATTACH_DECL_NEW(fwip, sizeof(struct fwip_softc),
+ fwipmatch, fwipattach, fwipdetach, fwipactivate);
- fwip = ((struct fwip_eth_softc *)ifp->if_softc)->fwip;
- fc = fwip->fd.fc;
- fc->poll(fc, (cmd == POLL_AND_CHECK_STATUS)?0:1, count);
-}
-#endif /* DEVICE_POLLING */
-#if defined(__FreeBSD__)
-static void
-fwip_identify(driver_t *driver, device_t parent)
-{
- BUS_ADD_CHILD(parent, 0, "fwip", fw_get_unit(parent));
-}
static int
-fwip_probe(device_t dev)
-{
- device_t pa;
-
- pa = device_get_parent(dev);
- if(fw_get_unit(dev) != fw_get_unit(pa)){
- return(ENXIO);
- }
-
- device_set_desc(dev, "IP over FireWire");
- return (0);
-}
-#elif defined(__NetBSD__)
-int
fwipmatch(device_t parent, cfdata_t cf, void *aux)
{
struct fw_attach_args *fwa = aux;
if (strcmp(fwa->name, "fwip") == 0)
- return (1);
- return (0);
+ return 1;
+ return 0;
}
-#endif
-FW_ATTACH(fwip)
+static void
+fwipattach(device_t parent, device_t self, void *aux)
{
- FW_ATTACH_START(fwip, fwip, fwa);
- FWIP_ATTACH_START;
+ struct fwip_softc *sc = device_private(self);
+ struct fw_attach_args *fwa = (struct fw_attach_args *)aux;
+ struct fw_hwaddr *hwaddr;
struct ifnet *ifp;
- int s;
- FWIP_ATTACH_SETUP;
+ aprint_naive("\n");
+ aprint_normal(": IP over IEEE1394\n");
- ifp = fwip->fw_softc.fwip_ifp;
- if (ifp == NULL)
- FW_ATTACH_RETURN(ENOSPC);
+ sc->sc_fd.dev = self;
+ sc->sc_eth.fwip_ifp = &sc->sc_eth.fwcom.fc_if;
+ hwaddr = (struct fw_hwaddr *)&sc->sc_eth.fwcom.ic_hwaddr;
-#ifdef __NetBSD__
- aprint_naive("\n");
-#endif
+ ifp = sc->sc_eth.fwip_ifp;
+
+ mutex_init(&sc->sc_fwb.fwb_mtx, MUTEX_DEFAULT, IPL_NET);
+ mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NET);
- fw_mtx_init(&fwip->mtx, "fwip", NULL, MTX_DEF);
/* XXX */
- fwip->dma_ch = -1;
+ sc->sc_dma_ch = -1;
- fwip->fd.fc = fwa->fc;
+ sc->sc_fd.fc = fwa->fc;
if (tx_speed < 0)
- tx_speed = fwip->fd.fc->speed;
+ tx_speed = sc->sc_fd.fc->speed;
- fwip->fd.post_explore = NULL;
- fwip->fd.post_busreset = fwip_post_busreset;
- fwip->fw_softc.fwip = fwip;
- FW_TASK_INIT(&fwip->start_send, 0, fwip_start_send, fwip);
+ sc->sc_fd.post_explore = NULL;
+ sc->sc_fd.post_busreset = fwip_post_busreset;
+ sc->sc_eth.fwip = sc;
/*
* Encode our hardware the way that arp likes it.
*/
- hwaddr->sender_unique_ID_hi = htonl(fwip->fd.fc->eui.hi);
- hwaddr->sender_unique_ID_lo = htonl(fwip->fd.fc->eui.lo);
- hwaddr->sender_max_rec = fwip->fd.fc->maxrec;
- hwaddr->sspd = fwip->fd.fc->speed;
+ hwaddr->sender_unique_ID_hi = htonl(sc->sc_fd.fc->eui.hi);
+ hwaddr->sender_unique_ID_lo = htonl(sc->sc_fd.fc->eui.lo);
+ hwaddr->sender_max_rec = sc->sc_fd.fc->maxrec;
+ hwaddr->sspd = sc->sc_fd.fc->speed;
hwaddr->sender_unicast_FIFO_hi = htons((uint16_t)(INET_FIFO >> 32));
hwaddr->sender_unicast_FIFO_lo = htonl((uint32_t)INET_FIFO);
- /* fill the rest and attach interface */
- ifp->if_softc = &fwip->fw_softc;
+ /* fill the rest and attach interface */
+ ifp->if_softc = &sc->sc_eth;
-#if __FreeBSD_version >= 501113 || defined(__DragonFly__) || defined(__NetBSD__)
- IF_INITNAME(ifp, dev, unit);
-#else
- ifp->if_unit = unit;
- ifp->if_name = "fwip";
-#endif
-#if defined(__NetBSD__)
- IFQ_SET_READY(&ifp->if_snd);
-#endif
- SET_IFFUNC(ifp, fwip_start, fwip_ioctl, fwip_init, fwip_stop);
+ strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
+ ifp->if_start = fwip_start;
+ ifp->if_ioctl = fwip_ioctl;
+ ifp->if_init = fwip_init;
+ ifp->if_stop = fwip_stop;
ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST);
- ifp->if_snd.ifq_maxlen = TX_MAX_QUEUE;
-#ifdef DEVICE_POLLING
- ifp->if_capabilities |= IFCAP_POLLING;
-#endif
+ IFQ_SET_READY(&ifp->if_snd);
+ IFQ_SET_MAXLEN(&ifp->if_snd, TX_MAX_QUEUE);
- s = splfwnet();
- FIREWIRE_IFATTACH(ifp, hwaddr);
- splx(s);
+ if_attach(ifp);
+ ieee1394_ifattach(ifp, (const struct ieee1394_hwaddr *)hwaddr);
-#if defined(__NetBSD__)
if (!pmf_device_register(self, NULL, NULL))
aprint_error_dev(self, "couldn't establish power handler\n");
else
pmf_class_network_register(self, ifp);
-#endif
FWIPDEBUG(ifp, "interface created\n");
- FW_ATTACH_RETURN(0);
+ return;
}
-IF_STOP(fwip)
+static int
+fwipdetach(device_t self, int flags)
{
- IF_STOP_START(fwip, ifp, fwip);
- struct firewire_comm *fc;
- struct fw_xferq *xferq;
- struct fw_xfer *xfer, *next;
- int i;
+ struct fwip_softc *sc = device_private(self);
+ struct ifnet *ifp = sc->sc_eth.fwip_ifp;
+
+ fwip_stop(sc->sc_eth.fwip_ifp, 1);
+ ieee1394_ifdetach(ifp);
+ if_detach(ifp);
+ mutex_destroy(&sc->sc_mtx);
+ mutex_destroy(&sc->sc_fwb.fwb_mtx);
+ return 0;
+}
- fc = fwip->fd.fc;
+static int
+fwipactivate(device_t self, enum devact act)
+{
+ struct fwip_softc *sc = device_private(self);
- if (fwip->dma_ch >= 0) {
- xferq = fc->ir[fwip->dma_ch];
+ switch (act) {
+ case DVACT_DEACTIVATE:
+ if_deactivate(sc->sc_eth.fwip_ifp);
+ return 0;
+ default:
+ return EOPNOTSUPP;
+ }
+}
- if (xferq->flag & FWXFERQ_RUNNING)
- fc->irx_disable(fc, fwip->dma_ch);
- xferq->flag &=
- ~(FWXFERQ_MODEMASK | FWXFERQ_OPEN | FWXFERQ_STREAM |
- FWXFERQ_EXTBUF | FWXFERQ_HANDLER | FWXFERQ_CHTAGMASK);
- xferq->hand = NULL;
+static void
+fwip_start(struct ifnet *ifp)
+{
+ struct fwip_softc *sc = ((struct fwip_eth_softc *)ifp->if_softc)->fwip;
- for (i = 0; i < xferq->bnchunk; i ++)
- m_freem(xferq->bulkxfer[i].mbuf);
- free(xferq->bulkxfer, M_FWIP);
+ FWIPDEBUG(ifp, "starting\n");
- fw_bindremove(fc, &fwip->fwb);
- for (xfer = STAILQ_FIRST(&fwip->fwb.xferlist); xfer != NULL;
- xfer = next) {
- next = STAILQ_NEXT(xfer, link);
- fw_xfer_free(xfer);
- }
+ if (sc->sc_dma_ch < 0) {
+ struct mbuf *m = NULL;
- for (xfer = STAILQ_FIRST(&fwip->xferlist); xfer != NULL;
- xfer = next) {
- next = STAILQ_NEXT(xfer, link);
- fw_xfer_free(xfer);
- }
- STAILQ_INIT(&fwip->xferlist);
+ FWIPDEBUG(ifp, "not ready\n");
+
+ do {
+ IF_DEQUEUE(&ifp->if_snd, m);
+ if (m != NULL)
+ m_freem(m);
+ ifp->if_oerrors++;
+ } while (m != NULL);
- xferq->bulkxfer = NULL;
- fwip->dma_ch = -1;
+ return;
}
-#if defined(__FreeBSD__)
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-#elif defined(__NetBSD__)
- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-#endif
+ ifp->if_flags |= IFF_OACTIVE;
+
+ if (ifp->if_snd.ifq_len != 0)
+ fwip_async_output(sc, ifp);
+
+ ifp->if_flags &= ~IFF_OACTIVE;
}
-FW_DETACH(fwip)
+static int
+fwip_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
- IF_DETACH_START(fwip, fwip);
- struct ifnet *ifp;
- int s;
+ int s, error = 0;
- ifp = fwip->fw_softc.fwip_ifp;
+ s = splnet();
-#ifdef DEVICE_POLLING
- if (ifp->if_capenable & IFCAP_POLLING)
- ether_poll_deregister(ifp);
-#endif
+ switch (cmd) {
+ case SIOCSIFFLAGS:
+ if ((error = ifioctl_common(ifp, cmd, data)) != 0)
+ break;
+ switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
+ case IFF_RUNNING:
+ fwip_stop(ifp, 0);
+ break;
+ case IFF_UP:
+ fwip_init(ifp);
+ break;
+ default:
+ break;
+ }
+ break;
- s = splfwnet();
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ break;
- FWIP_STOP(fwip);
- FIREWIRE_IFDETACH(ifp);
- fw_mtx_destroy(&fwip->mtx);
+ default:
+ error = ieee1394_ioctl(ifp, cmd, data);
+ if (error == ENETRESET)
+ error = 0;
+ break;
+ }
splx(s);
- return 0;
-}
-
-int
-fwipactivate(device_t self, enum devact act)
-{
- struct fwip_softc *fwip = device_private(self);
- switch (act) {
- case DVACT_DEACTIVATE:
- if_deactivate(fwip->fw_softc.fwip_ifp);
- return 0;
- default:
- return EOPNOTSUPP;
- }
+ return error;
}
-IF_INIT(fwip)
+static int
+fwip_init(struct ifnet *ifp)
{
- IF_INIT_START(fwip, fwip, ifp);
+ struct fwip_softc *sc = ((struct fwip_eth_softc *)ifp->if_softc)->fwip;
struct firewire_comm *fc;
struct fw_xferq *xferq;
struct fw_xfer *xfer;
@@ -424,19 +342,18 @@ IF_INIT(fwip)
FWIPDEBUG(ifp, "initializing\n");
- fc = fwip->fd.fc;
-#define START 0
- if (fwip->dma_ch < 0) {
- fwip->dma_ch = fw_open_isodma(fc, /* tx */0);
- if (fwip->dma_ch < 0)
- IF_INIT_RETURN(ENXIO);
- xferq = fc->ir[fwip->dma_ch];
+ fc = sc->sc_fd.fc;
+ if (sc->sc_dma_ch < 0) {
+ sc->sc_dma_ch = fw_open_isodma(fc, /* tx */0);
+ if (sc->sc_dma_ch < 0)
+ return ENXIO;
+ xferq = fc->ir[sc->sc_dma_ch];
xferq->flag |=
FWXFERQ_EXTBUF | FWXFERQ_HANDLER | FWXFERQ_STREAM;
xferq->flag &= ~0xff;
xferq->flag |= broadcast_channel & 0xff;
/* register fwip_input handler */
- xferq->sc = (void *) fwip;
+ xferq->sc = (void *) sc;
xferq->hand = fwip_stream_input;
xferq->bnchunk = rx_queue_len;
xferq->bnpacket = 1;
@@ -447,259 +364,179 @@ IF_INIT(fwip)
sizeof(struct fw_bulkxfer) * xferq->bnchunk,
M_FWIP, M_WAITOK);
if (xferq->bulkxfer == NULL) {
- printf("if_fwip: malloc failed\n");
- IF_INIT_RETURN(ENOMEM);
+ aprint_error_ifnet(ifp, "if_fwip: malloc failed\n");
+ return ENOMEM;
}
STAILQ_INIT(&xferq->stvalid);
STAILQ_INIT(&xferq->stfree);
STAILQ_INIT(&xferq->stdma);
xferq->stproc = NULL;
- for (i = 0; i < xferq->bnchunk; i ++) {
- m =
-#if defined(__DragonFly__) || __FreeBSD_version < 500000
- m_getcl(M_WAIT, MT_DATA, M_PKTHDR);
-#else
- m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR);
-#endif
+ for (i = 0; i < xferq->bnchunk; i++) {
+ m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR);
xferq->bulkxfer[i].mbuf = m;
if (m != NULL) {
m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
STAILQ_INSERT_TAIL(&xferq->stfree,
&xferq->bulkxfer[i], link);
} else
- printf("fwip_as_input: m_getcl failed\n");
+ aprint_error_ifnet(ifp,
+ "fwip_as_input: m_getcl failed\n");
}
- fwip->fwb.start = INET_FIFO;
- fwip->fwb.end = INET_FIFO + 16384; /* S3200 packet size */
+ sc->sc_fwb.start = INET_FIFO;
+ sc->sc_fwb.end = INET_FIFO + 16384; /* S3200 packet size */
/* pre-allocate xfer */
- STAILQ_INIT(&fwip->fwb.xferlist);
- for (i = 0; i < rx_queue_len; i ++) {
+ STAILQ_INIT(&sc->sc_fwb.xferlist);
+ for (i = 0; i < rx_queue_len; i++) {
xfer = fw_xfer_alloc(M_FWIP);
if (xfer == NULL)
break;
- m = m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR);
+ m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR);
xfer->recv.payload = mtod(m, uint32_t *);
xfer->recv.pay_len = MCLBYTES;
xfer->hand = fwip_unicast_input;
xfer->fc = fc;
- xfer->sc = (void *)fwip;
+ xfer->sc = (void *) sc;
xfer->mbuf = m;
- STAILQ_INSERT_TAIL(&fwip->fwb.xferlist, xfer, link);
+ STAILQ_INSERT_TAIL(&sc->sc_fwb.xferlist, xfer, link);
}
- fw_bindadd(fc, &fwip->fwb);
+ fw_bindadd(fc, &sc->sc_fwb);
- STAILQ_INIT(&fwip->xferlist);
+ STAILQ_INIT(&sc->sc_xferlist);
for (i = 0; i < TX_MAX_QUEUE; i++) {
xfer = fw_xfer_alloc(M_FWIP);
if (xfer == NULL)
break;
xfer->send.spd = tx_speed;
- xfer->fc = fwip->fd.fc;
- xfer->sc = (void *)fwip;
+ xfer->fc = sc->sc_fd.fc;
+ xfer->sc = (void *)sc;
xfer->hand = fwip_output_callback;
- STAILQ_INSERT_TAIL(&fwip->xferlist, xfer, link);
+ STAILQ_INSERT_TAIL(&sc->sc_xferlist, xfer, link);
}
} else
- xferq = fc->ir[fwip->dma_ch];
+ xferq = fc->ir[sc->sc_dma_ch];
- fwip->last_dest.hi = 0;
- fwip->last_dest.lo = 0;
+ sc->sc_last_dest.hi = 0;
+ sc->sc_last_dest.lo = 0;
/* start dma */
if ((xferq->flag & FWXFERQ_RUNNING) == 0)
- fc->irx_enable(fc, fwip->dma_ch);
+ fc->irx_enable(fc, sc->sc_dma_ch);
-#if defined(__FreeBSD__)
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-#elif defined(__NetBSD__)
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
-#endif
#if 0
/* attempt to start output */
fwip_start(ifp);
#endif
- IF_INIT_RETURN(0);
+ return 0;
}
-static int
-fwip_ioctl(struct ifnet *ifp, u_long cmd, void *data)
+static void
+fwip_stop(struct ifnet *ifp, int disable)
{
- IF_IOCTL_START(fwip, fwip);
- int s, error = 0;
+ struct fwip_softc *sc = ((struct fwip_eth_softc *)ifp->if_softc)->fwip;
+ struct firewire_comm *fc = sc->sc_fd.fc;
+ struct fw_xferq *xferq;
+ struct fw_xfer *xfer, *next;
+ int i;
- switch (cmd) {
- case SIOCSIFFLAGS:
- s = splfwnet();
- if ((error = ifioctl_common(ifp, cmd, data)) != 0)
- ;
- else if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_flags & IFF_RUNNING))
- FWIP_INIT(fwip);
- } else {
- if (ifp->if_flags & IFF_RUNNING)
- FWIP_STOP(fwip);
- }
- splx(s);
- break;
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- break;
- case SIOCSIFCAP:
- if ((error = FIREWIRE_IOCTL(ifp, cmd, data)) != ENETRESET)
- break;
- error = 0;
-#ifdef DEVICE_POLLING
- {
- struct ifreq *ifr = (struct ifreq *) data;
- struct firewire_comm *fc = fc = fwip->fd.fc;
-
- if (ifr->ifr_reqcap & IFCAP_POLLING &&
- !(ifp->if_capenable & IFCAP_POLLING)) {
- error = ether_poll_register(fwip_poll, ifp);
- if (error)
- return(error);
- /* Disable interrupts */
- fc->set_intr(fc, 0);
- ifp->if_capenable |= IFCAP_POLLING;
- return (error);
+ if (sc->sc_dma_ch >= 0) {
+ xferq = fc->ir[sc->sc_dma_ch];
+
+ if (xferq->flag & FWXFERQ_RUNNING)
+ fc->irx_disable(fc, sc->sc_dma_ch);
+ xferq->flag &=
+ ~(FWXFERQ_MODEMASK | FWXFERQ_OPEN | FWXFERQ_STREAM |
+ FWXFERQ_EXTBUF | FWXFERQ_HANDLER | FWXFERQ_CHTAGMASK);
+ xferq->hand = NULL;
+
+ for (i = 0; i < xferq->bnchunk; i++)
+ m_freem(xferq->bulkxfer[i].mbuf);
+ free(xferq->bulkxfer, M_FWIP);
+ fw_bindremove(fc, &sc->sc_fwb);
+ for (xfer = STAILQ_FIRST(&sc->sc_fwb.xferlist); xfer != NULL;
+ xfer = next) {
+ next = STAILQ_NEXT(xfer, link);
+ fw_xfer_free(xfer);
}
- if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
- ifp->if_capenable & IFCAP_POLLING) {
- error = ether_poll_deregister(ifp);
- /* Enable interrupts. */
- fc->set_intr(fc, 1);
- ifp->if_capenable &= ~IFCAP_POLLING;
- return (error);
+
+ for (xfer = STAILQ_FIRST(&sc->sc_xferlist); xfer != NULL;
+ xfer = next) {
+ next = STAILQ_NEXT(xfer, link);
+ fw_xfer_free(xfer);
}
- }
-#endif /* DEVICE_POLLING */
- break;
- default:
- s = splfwnet();
- error = FIREWIRE_IOCTL(ifp, cmd, data);
- splx(s);
- return (error);
+ xferq->bulkxfer = NULL;
+ sc->sc_dma_ch = -1;
}
- return error;
+ ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
}
static void
fwip_post_busreset(void *arg)
{
- struct fwip_softc *fwip = arg;
+ struct fwip_softc *sc = arg;
struct crom_src *src;
struct crom_chunk *root;
- src = fwip->fd.fc->crom_src;
- root = fwip->fd.fc->crom_root;
+ src = sc->sc_fd.fc->crom_src;
+ root = sc->sc_fd.fc->crom_root;
/* RFC2734 IPv4 over IEEE1394 */
- memset(&fwip->unit4, 0, sizeof(struct crom_chunk));
- crom_add_chunk(src, root, &fwip->unit4, CROM_UDIR);
- crom_add_entry(&fwip->unit4, CSRKEY_SPEC, CSRVAL_IETF);
- crom_add_simple_text(src, &fwip->unit4, &fwip->spec4, "IANA");
- crom_add_entry(&fwip->unit4, CSRKEY_VER, 1);
- crom_add_simple_text(src, &fwip->unit4, &fwip->ver4, "IPv4");
+ memset(&sc->sc_unit4, 0, sizeof(struct crom_chunk));
+ crom_add_chunk(src, root, &sc->sc_unit4, CROM_UDIR);
+ crom_add_entry(&sc->sc_unit4, CSRKEY_SPEC, CSRVAL_IETF);
+ crom_add_simple_text(src, &sc->sc_unit4, &sc->sc_spec4, "IANA");
+ crom_add_entry(&sc->sc_unit4, CSRKEY_VER, 1);
+ crom_add_simple_text(src, &sc->sc_unit4, &sc->sc_ver4, "IPv4");
/* RFC3146 IPv6 over IEEE1394 */
- memset(&fwip->unit6, 0, sizeof(struct crom_chunk));
- crom_add_chunk(src, root, &fwip->unit6, CROM_UDIR);
- crom_add_entry(&fwip->unit6, CSRKEY_SPEC, CSRVAL_IETF);
- crom_add_simple_text(src, &fwip->unit6, &fwip->spec6, "IANA");
- crom_add_entry(&fwip->unit6, CSRKEY_VER, 2);
- crom_add_simple_text(src, &fwip->unit6, &fwip->ver6, "IPv6");
-
- fwip->last_dest.hi = 0;
- fwip->last_dest.lo = 0;
- FIREWIRE_BUSRESET(fwip->fw_softc.fwip_ifp);
+ memset(&sc->sc_unit6, 0, sizeof(struct crom_chunk));
+ crom_add_chunk(src, root, &sc->sc_unit6, CROM_UDIR);
+ crom_add_entry(&sc->sc_unit6, CSRKEY_SPEC, CSRVAL_IETF);
+ crom_add_simple_text(src, &sc->sc_unit6, &sc->sc_spec6, "IANA");
+ crom_add_entry(&sc->sc_unit6, CSRKEY_VER, 2);
+ crom_add_simple_text(src, &sc->sc_unit6, &sc->sc_ver6, "IPv6");
+
+ sc->sc_last_dest.hi = 0;
+ sc->sc_last_dest.lo = 0;
+ ieee1394_drain(sc->sc_eth.fwip_ifp);
}
static void
fwip_output_callback(struct fw_xfer *xfer)
{
- struct fwip_softc *fwip;
+ struct fwip_softc *sc = (struct fwip_softc *)xfer->sc;
struct ifnet *ifp;
- int s;
- fwip = (struct fwip_softc *)xfer->sc;
- ifp = fwip->fw_softc.fwip_ifp;
+ ifp = sc->sc_eth.fwip_ifp;
/* XXX error check */
FWIPDEBUG(ifp, "resp = %d\n", xfer->resp);
if (xfer->resp != 0)
- ifp->if_oerrors ++;
-
+ ifp->if_oerrors++;
+
m_freem(xfer->mbuf);
fw_xfer_unload(xfer);
- s = splfwnet();
- FWIP_LOCK(fwip);
- STAILQ_INSERT_TAIL(&fwip->xferlist, xfer, link);
- FWIP_UNLOCK(fwip);
- splx(s);
+ mutex_enter(&sc->sc_mtx);
+ STAILQ_INSERT_TAIL(&sc->sc_xferlist, xfer, link);
+ mutex_exit(&sc->sc_mtx);
/* for queue full */
- if (ifp->if_snd.ifq_head != NULL) {
+ if (ifp->if_snd.ifq_head != NULL)
fwip_start(ifp);
- }
-}
-
-static void
-fwip_start(struct ifnet *ifp)
-{
- struct fwip_softc *fwip =
- ((struct fwip_eth_softc *)ifp->if_softc)->fwip;
- int s;
-
- FWIPDEBUG(ifp, "starting\n");
-
- if (fwip->dma_ch < 0) {
- struct mbuf *m = NULL;
-
- FWIPDEBUG(ifp, "not ready\n");
-
- s = splfwnet();
- do {
- IF_DEQUEUE(&ifp->if_snd, m);
- if (m != NULL)
- m_freem(m);
- ifp->if_oerrors ++;
- } while (m != NULL);
- splx(s);
-
- return;
- }
-
- s = splfwnet();
-#if defined(__FreeBSD__)
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-#elif defined(__NetBSD__)
- ifp->if_flags |= IFF_OACTIVE;
-#endif
-
- if (ifp->if_snd.ifq_len != 0)
- fwip_async_output(fwip, ifp);
-
-#if defined(__FreeBSD__)
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-#elif defined(__NetBSD__)
- ifp->if_flags &= ~IFF_OACTIVE;
-#endif
- splx(s);
}
/* Async. stream output */
static void
-fwip_async_output(struct fwip_softc *fwip, struct ifnet *ifp)
+fwip_async_output(struct fwip_softc *sc, struct ifnet *ifp)
{
- struct firewire_comm *fc = fwip->fd.fc;
+ struct firewire_comm *fc = sc->sc_fd.fc;
struct mbuf *m;
struct m_tag *mtag;
struct fw_hwaddr *destfw;
@@ -714,25 +551,22 @@ fwip_async_output(struct fwip_softc *fwip, struct ifnet *ifp)
xferq = fc->atq;
while ((xferq->queued < xferq->maxq - 1) &&
(ifp->if_snd.ifq_head != NULL)) {
- FWIP_LOCK(fwip);
- xfer = STAILQ_FIRST(&fwip->xferlist);
- if (xfer == NULL) {
- FWIP_UNLOCK(fwip);
+ mutex_enter(&sc->sc_mtx);
+ if (STAILQ_EMPTY(&sc->sc_xferlist)) {
+ mutex_exit(&sc->sc_mtx);
#if 0
- printf("if_fwip: lack of xfer\n");
+ aprint_normal("if_fwip: lack of xfer\n");
#endif
break;
}
- STAILQ_REMOVE_HEAD(&fwip->xferlist, link);
- FWIP_UNLOCK(fwip);
-
IF_DEQUEUE(&ifp->if_snd, m);
if (m == NULL) {
- FWIP_LOCK(fwip);
- STAILQ_INSERT_HEAD(&fwip->xferlist, xfer, link);
- FWIP_UNLOCK(fwip);
+ mutex_exit(&sc->sc_mtx);
break;
}
+ xfer = STAILQ_FIRST(&sc->sc_xferlist);
+ STAILQ_REMOVE_HEAD(&sc->sc_xferlist, link);
+ mutex_exit(&sc->sc_mtx);
/*
* Dig out the link-level address which
@@ -740,19 +574,13 @@ fwip_async_output(struct fwip_softc *fwip, struct ifnet *ifp)
* discovery. If we don't have a link-level address,
* just stick the thing on the broadcast channel.
*/
- mtag = m_tag_locate(m, MTAG_FIREWIRE, MTAG_FIREWIRE_HWADDR, 0);
+ mtag = m_tag_find(m, MTAG_FIREWIRE_HWADDR, 0);
if (mtag == NULL)
destfw = 0;
else
destfw = (struct fw_hwaddr *) (mtag + 1);
/*
- * We don't do any bpf stuff here - the generic code
- * in firewire_output gives the packet to bpf before
- * it adds the link-level encapsulation.
- */
-
- /*
* Put the mbuf in the xfer early in case we hit an
* error case below - fwip_output_callback will free
* the mbuf.
@@ -774,7 +602,7 @@ fwip_async_output(struct fwip_softc *fwip, struct ifnet *ifp)
*/
uint32_t *p;
- M_PREPEND(m, 2*sizeof(uint32_t), M_DONTWAIT);
+ M_PREPEND(m, 2 * sizeof(uint32_t), M_DONTWAIT);
p = mtod(m, uint32_t *);
fp->mode.stream.len = m->m_pkthdr.len;
fp->mode.stream.chtag = broadcast_channel;
@@ -799,31 +627,33 @@ fwip_async_output(struct fwip_softc *fwip, struct ifnet *ifp)
eui.hi = ntohl(destfw->sender_unique_ID_hi);
eui.lo = ntohl(destfw->sender_unique_ID_lo);
- if (fwip->last_dest.hi != eui.hi ||
- fwip->last_dest.lo != eui.lo) {
+ if (sc->sc_last_dest.hi != eui.hi ||
+ sc->sc_last_dest.lo != eui.lo) {
fd = fw_noderesolve_eui64(fc, &eui);
if (!fd) {
/* error */
- ifp->if_oerrors ++;
+ ifp->if_oerrors++;
/* XXX set error code */
fwip_output_callback(xfer);
continue;
}
- fwip->last_hdr.mode.wreqb.dst = FWLOCALBUS | fd->dst;
- fwip->last_hdr.mode.wreqb.tlrt = 0;
- fwip->last_hdr.mode.wreqb.tcode = FWTCODE_WREQB;
- fwip->last_hdr.mode.wreqb.pri = 0;
- fwip->last_hdr.mode.wreqb.src = nodeid;
- fwip->last_hdr.mode.wreqb.dest_hi =
+ sc->sc_last_hdr.mode.wreqb.dst =
+ FWLOCALBUS | fd->dst;
+ sc->sc_last_hdr.mode.wreqb.tlrt = 0;
+ sc->sc_last_hdr.mode.wreqb.tcode =
+ FWTCODE_WREQB;
+ sc->sc_last_hdr.mode.wreqb.pri = 0;
+ sc->sc_last_hdr.mode.wreqb.src = nodeid;
+ sc->sc_last_hdr.mode.wreqb.dest_hi =
ntohs(destfw->sender_unicast_FIFO_hi);
- fwip->last_hdr.mode.wreqb.dest_lo =
+ sc->sc_last_hdr.mode.wreqb.dest_lo =
ntohl(destfw->sender_unicast_FIFO_lo);
- fwip->last_hdr.mode.wreqb.extcode = 0;
- fwip->last_dest = eui;
+ sc->sc_last_hdr.mode.wreqb.extcode = 0;
+ sc->sc_last_dest = eui;
}
- fp->mode.wreqb = fwip->last_hdr.mode.wreqb;
+ fp->mode.wreqb = sc->sc_last_hdr.mode.wreqb;
fp->mode.wreqb.len = m->m_pkthdr.len;
xfer->send.spd = min(destfw->sspd, fc->speed);
}
@@ -837,39 +667,31 @@ fwip_async_output(struct fwip_softc *fwip, struct ifnet *ifp)
* for later transmission.
*/
xfer->mbuf = 0;
- FWIP_LOCK(fwip);
- STAILQ_INSERT_TAIL(&fwip->xferlist, xfer, link);
- FWIP_UNLOCK(fwip);
+ mutex_enter(&sc->sc_mtx);
+ STAILQ_INSERT_TAIL(&sc->sc_xferlist, xfer, link);
+ mutex_exit(&sc->sc_mtx);
IF_PREPEND(&ifp->if_snd, m);
break;
}
if (error) {
/* error */
- ifp->if_oerrors ++;
+ ifp->if_oerrors++;
/* XXX set error code */
fwip_output_callback(xfer);
continue;
} else {
- ifp->if_opackets ++;
+ ifp->if_opackets++;
i++;
}
}
#if 0
if (i > 1)
- printf("%d queued\n", i);
+ aprint_normal("%d queued\n", i);
#endif
if (i > 0)
xferq->start(fc);
}
-static void
-fwip_start_send (void *arg, int count)
-{
- struct fwip_softc *fwip = arg;
-
- fwip->fd.fc->atq->start(fwip->fd.fc);
-}
-
/* Async. stream output */
static void
fwip_stream_input(struct fw_xferq *xferq)
@@ -877,19 +699,19 @@ fwip_stream_input(struct fw_xferq *xferq)
struct mbuf *m, *m0;
struct m_tag *mtag;
struct ifnet *ifp;
- struct fwip_softc *fwip;
+ struct fwip_softc *sc;
struct fw_bulkxfer *sxfer;
struct fw_pkt *fp;
uint16_t src;
uint32_t *p;
- fwip = (struct fwip_softc *)xferq->sc;
- ifp = fwip->fw_softc.fwip_ifp;
+ sc = (struct fwip_softc *)xferq->sc;
+ ifp = sc->sc_eth.fwip_ifp;
while ((sxfer = STAILQ_FIRST(&xferq->stvalid)) != NULL) {
STAILQ_REMOVE_HEAD(&xferq->stvalid, link);
fp = mtod(sxfer->mbuf, struct fw_pkt *);
- if (fwip->fd.fc->irx_post != NULL)
- fwip->fd.fc->irx_post(fwip->fd.fc, fp->mode.ld);
+ if (sc->sc_fd.fc->irx_post != NULL)
+ sc->sc_fd.fc->irx_post(sc->sc_fd.fc, fp->mode.ld);
m = sxfer->mbuf;
/* insert new rbuf */
@@ -898,7 +720,8 @@ fwip_stream_input(struct fw_xferq *xferq)
m0->m_len = m0->m_pkthdr.len = m0->m_ext.ext_size;
STAILQ_INSERT_TAIL(&xferq->stfree, sxfer, link);
} else
- printf("fwip_as_input: m_getcl failed\n");
+ aprint_error_ifnet(ifp,
+ "fwip_as_input: m_getcl failed\n");
/*
* We must have a GASP header - leave the
@@ -907,10 +730,10 @@ fwip_stream_input(struct fw_xferq *xferq)
* stream header even though that isn't accounted for
* in mode.stream.len.
*/
- if (sxfer->resp != 0 || fp->mode.stream.len <
- 2*sizeof(uint32_t)) {
+ if (sxfer->resp != 0 ||
+ fp->mode.stream.len < 2 * sizeof(uint32_t)) {
m_freem(m);
- ifp->if_ierrors ++;
+ ifp->if_ierrors++;
continue;
}
m->m_len = m->m_pkthdr.len = fp->mode.stream.len
@@ -931,12 +754,13 @@ fwip_stream_input(struct fw_xferq *xferq)
* version.
*/
p = mtod(m, uint32_t *);
- if ((((ntohl(p[1]) & 0xffff) << 8) | ntohl(p[2]) >> 24) != 0x00005e
- || (ntohl(p[2]) & 0xffffff) != 1) {
+ if ((((ntohl(p[1]) & 0xffff) << 8) | ntohl(p[2]) >> 24) !=
+ 0x00005e ||
+ (ntohl(p[2]) & 0xffffff) != 1) {
FWIPDEBUG(ifp, "Unrecognised GASP header %#08x %#08x\n",
ntohl(p[1]), ntohl(p[2]));
m_freem(m);
- ifp->if_ierrors ++;
+ ifp->if_ierrors++;
continue;
}
@@ -944,15 +768,15 @@ fwip_stream_input(struct fw_xferq *xferq)
* Record the sender ID for possible BPF usage.
*/
src = ntohl(p[1]) >> 16;
- if (bpf_peers_present(ifp->if_bpf)) {
- mtag = m_tag_alloc(MTAG_FIREWIRE,
- MTAG_FIREWIRE_SENDER_EUID,
- 2*sizeof(uint32_t), M_NOWAIT);
+ if (ifp->if_bpf) {
+ mtag = m_tag_get(MTAG_FIREWIRE_SENDER_EUID,
+ 2 * sizeof(uint32_t), M_NOWAIT);
if (mtag) {
/* bpf wants it in network byte order */
struct fw_device *fd;
uint32_t *p2 = (uint32_t *) (mtag + 1);
- fd = fw_noderesolve_nodeid(fwip->fd.fc,
+
+ fd = fw_noderesolve_nodeid(sc->sc_fd.fc,
src & 0x3f);
if (fd) {
p2[0] = htonl(fd->eui.hi);
@@ -970,15 +794,15 @@ fwip_stream_input(struct fw_xferq *xferq)
*/
m_adj(m, 3*sizeof(uint32_t));
m->m_pkthdr.rcvif = ifp;
- FIREWIRE_INPUT(ifp, m, src);
- ifp->if_ipackets ++;
+ ieee1394_input(ifp, m, src);
+ ifp->if_ipackets++;
}
if (STAILQ_FIRST(&xferq->stfree) != NULL)
- fwip->fd.fc->irx_enable(fwip->fd.fc, fwip->dma_ch);
+ sc->sc_fd.fc->irx_enable(sc->sc_fd.fc, sc->sc_dma_ch);
}
static inline void
-fwip_unicast_input_recycle(struct fwip_softc *fwip, struct fw_xfer *xfer)
+fwip_unicast_input_recycle(struct fwip_softc *sc, struct fw_xfer *xfer)
{
struct mbuf *m;
@@ -988,12 +812,14 @@ fwip_unicast_input_recycle(struct fwip_softc *fwip, struct fw_xfer *xfer)
*/
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
if (m == NULL)
- printf("fwip_unicast_input_recycle: m_getcl failed\n");
- xfer->mbuf = m;
+ aprint_error_dev(sc->sc_fd.dev,
+ "fwip_unicast_input_recycle: m_getcl failed\n");
xfer->recv.payload = mtod(m, uint32_t *);
xfer->recv.pay_len = MCLBYTES;
xfer->mbuf = m;
- STAILQ_INSERT_TAIL(&fwip->fwb.xferlist, xfer, link);
+ mutex_enter(&sc->sc_fwb.fwb_mtx);
+ STAILQ_INSERT_TAIL(&sc->sc_fwb.xferlist, xfer, link);
+ mutex_exit(&sc->sc_fwb.fwb_mtx);
}
static void
@@ -1003,13 +829,12 @@ fwip_unicast_input(struct fw_xfer *xfer)
struct mbuf *m;
struct m_tag *mtag;
struct ifnet *ifp;
- struct fwip_softc *fwip;
+ struct fwip_softc *sc;
struct fw_pkt *fp;
- //struct fw_pkt *sfp;
int rtcode;
- fwip = (struct fwip_softc *)xfer->sc;
- ifp = fwip->fw_softc.fwip_ifp;
+ sc = (struct fwip_softc *)xfer->sc;
+ ifp = sc->sc_eth.fwip_ifp;
m = xfer->mbuf;
xfer->mbuf = 0;
fp = &xfer->recv.hdr;
@@ -1032,28 +857,29 @@ fwip_unicast_input(struct fw_xfer *xfer)
* Pick up a new mbuf and stick it on the back of the receive
* queue.
*/
- fwip_unicast_input_recycle(fwip, xfer);
+ fwip_unicast_input_recycle(sc, xfer);
/*
* If we've already rejected the packet, give up now.
*/
if (rtcode != FWRCODE_COMPLETE) {
m_freem(m);
- ifp->if_ierrors ++;
+ ifp->if_ierrors++;
return;
}
- if (bpf_peers_present(ifp->if_bpf)) {
+ if (ifp->if_bpf) {
/*
* Record the sender ID for possible BPF usage.
*/
- mtag = m_tag_alloc(MTAG_FIREWIRE, MTAG_FIREWIRE_SENDER_EUID,
- 2*sizeof(uint32_t), M_NOWAIT);
+ mtag = m_tag_get(MTAG_FIREWIRE_SENDER_EUID,
+ 2 * sizeof(uint32_t), M_NOWAIT);
if (mtag) {
/* bpf wants it in network byte order */
struct fw_device *fd;
uint32_t *p = (uint32_t *) (mtag + 1);
- fd = fw_noderesolve_nodeid(fwip->fd.fc,
+
+ fd = fw_noderesolve_nodeid(sc->sc_fd.fc,
fp->mode.wreqb.src & 0x3f);
if (fd) {
p[0] = htonl(fd->eui.hi);
@@ -1073,36 +899,6 @@ fwip_unicast_input(struct fw_xfer *xfer)
*/
m->m_len = m->m_pkthdr.len = fp->mode.wreqb.len;
m->m_pkthdr.rcvif = ifp;
- FIREWIRE_INPUT(ifp, m, fp->mode.wreqb.src);
- ifp->if_ipackets ++;
+ ieee1394_input(ifp, m, fp->mode.wreqb.src);
+ ifp->if_ipackets++;
}
-
-#if defined(__FreeBSD__)
-static devclass_t fwip_devclass;
-
-static device_method_t fwip_methods[] = {
- /* device interface */
- DEVMETHOD(device_identify, fwip_identify),
- DEVMETHOD(device_probe, fwip_probe),
- DEVMETHOD(device_attach, fwip_attach),
- DEVMETHOD(device_detach, fwip_detach),
- { 0, 0 }
-};
-
-static driver_t fwip_driver = {
- "fwip",
- fwip_methods,
- sizeof(struct fwip_softc),
-};
-
-
-#ifdef __DragonFly__
-DECLARE_DUMMY_MODULE(fwip);
-#endif
-DRIVER_MODULE(fwip, firewire, fwip_driver, fwip_devclass, 0, 0);
-MODULE_VERSION(fwip, 1);
-MODULE_DEPEND(fwip, firewire, 1, 1, 1);
-#elif defined(__NetBSD__)
-CFATTACH_DECL_NEW(fwip, sizeof(struct fwip_softc),
- fwipmatch, fwipattach, fwipdetach, NULL);
-#endif
diff --git a/sys/dev/ieee1394/if_fwipvar.h b/sys/dev/ieee1394/if_fwipvar.h
index c0bc90559e8..e7947c5e903 100644
--- a/sys/dev/ieee1394/if_fwipvar.h
+++ b/sys/dev/ieee1394/if_fwipvar.h
@@ -1,10 +1,10 @@
-/* $NetBSD: if_fwipvar.h,v 1.4 2007/11/05 19:08:57 kiyohara Exp $ */
+/* $NetBSD: if_fwipvar.h,v 1.5 2010/03/29 03:05:28 kiyohara Exp $ */
/*-
* Copyright (c) 2004
* Doug Rabson
* Copyright (c) 2002-2003
* Hidetoshi Shimokawa. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +21,7 @@
* 4. Neither the name of the author 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 REGENTS 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
@@ -33,39 +33,37 @@
* 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.
- *
+ *
* $FreeBSD: src/sys/dev/firewire/if_fwipvar.h,v 1.5 2007/06/06 14:31:36 simokawa Exp $
*/
-#ifndef _NET_IF_FWIPVAR_H_
-#define _NET_IF_FWIPVAR_H_
+#ifndef _IF_FWIPVAR_H_
+#define _IF_FWIPVAR_H_
+
+#define MTAG_FIREWIRE_HWADDR 0
+#define MTAG_FIREWIRE_SENDER_EUID 1
+
struct fwip_softc {
/* XXX this must be first for fd.post_explore() */
- struct firewire_dev_comm fd;
- short dma_ch;
- struct fw_bind fwb;
- struct fw_eui64 last_dest;
- struct fw_pkt last_hdr;
- fw_task_t start_send;
- STAILQ_HEAD(, fw_xfer) xferlist;
- struct crom_chunk unit4; /* unit directory for IPv4 */
- struct crom_chunk spec4; /* specifier description IPv4 */
- struct crom_chunk ver4; /* version description IPv4 */
- struct crom_chunk unit6; /* unit directory for IPv6 */
- struct crom_chunk spec6; /* specifier description IPv6 */
- struct crom_chunk ver6; /* version description IPv6 */
+ struct firewire_dev_comm sc_fd;
+ short sc_dma_ch;
+ struct fw_bind sc_fwb;
+ struct fw_eui64 sc_last_dest;
+ struct fw_pkt sc_last_hdr;
+ STAILQ_HEAD(, fw_xfer) sc_xferlist;
+ struct crom_chunk sc_unit4; /* unit directory for IPv4 */
+ struct crom_chunk sc_spec4; /* specifier description IPv4 */
+ struct crom_chunk sc_ver4; /* version description IPv4 */
+ struct crom_chunk sc_unit6; /* unit directory for IPv6 */
+ struct crom_chunk sc_spec6; /* specifier description IPv6 */
+ struct crom_chunk sc_ver6; /* version description IPv6 */
struct fwip_eth_softc {
-#if defined(__NetBSD__)
struct ieee1394com fwcom;
-#endif
struct ifnet *fwip_ifp;
struct fwip_softc *fwip;
- } fw_softc;
- fw_mtx_t mtx;
+ } sc_eth;
+ kmutex_t sc_mtx;
};
-#define FWIP_LOCK(fwip) fw_mtx_lock(&(fwip)->mtx)
-#define FWIP_UNLOCK(fwip) fw_mtx_unlock(&(fwip)->mtx)
-
-#endif /* !_NET_IF_FWIPVAR_H_ */
+#endif /* !_IF_FWIPVAR_H_ */
diff --git a/sys/dev/ieee1394/sbp.c b/sys/dev/ieee1394/sbp.c
index 704ec84f6e9..c5338dfceff 100644
--- a/sys/dev/ieee1394/sbp.c
+++ b/sys/dev/ieee1394/sbp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sbp.c,v 1.28 2009/05/12 12:16:55 cegger Exp $ */
+/* $NetBSD: sbp.c,v 1.29 2010/03/29 03:05:28 kiyohara Exp $ */
/*-
* Copyright (c) 2003 Hidetoshi Shimokawa
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
@@ -31,72 +31,25 @@
* 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.
- *
- * $FreeBSD: src/sys/dev/firewire/sbp.c,v 1.92 2007/06/06 14:31:36 simokawa Exp $
+ *
+ * $FreeBSD: src/sys/dev/firewire/sbp.c,v 1.100 2009/02/18 18:41:34 sbruno Exp $
*
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sbp.c,v 1.28 2009/05/12 12:16:55 cegger Exp $");
-
-#if defined(__FreeBSD__)
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/sysctl.h>
-#include <sys/bus.h>
-#include <sys/malloc.h>
-#if defined(__FreeBSD__) && __FreeBSD_version >= 501102
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#endif
+__KERNEL_RCSID(0, "$NetBSD: sbp.c,v 1.29 2010/03/29 03:05:28 kiyohara Exp $");
-#if defined(__DragonFly__) || __FreeBSD_version < 500106
-#include <sys/devicestat.h> /* for struct devstat */
-#endif
-#ifdef __DragonFly__
-#include <bus/cam/cam.h>
-#include <bus/cam/cam_ccb.h>
-#include <bus/cam/cam_sim.h>
-#include <bus/cam/cam_xpt_sim.h>
-#include <bus/cam/cam_debug.h>
-#include <bus/cam/cam_periph.h>
-#include <bus/cam/scsi/scsi_all.h>
-
-#include <bus/firewire/fw_port.h>
-#include <bus/firewire/firewire.h>
-#include <bus/firewire/firewirereg.h>
-#include <bus/firewire/fwdma.h>
-#include <bus/firewire/iec13213.h>
-#include "sbp.h"
-#else
-#include <cam/cam.h>
-#include <cam/cam_ccb.h>
-#include <cam/cam_sim.h>
-#include <cam/cam_xpt_sim.h>
-#include <cam/cam_debug.h>
-#include <cam/cam_periph.h>
-#include <cam/scsi/scsi_all.h>
-
-#include <dev/firewire/fw_port.h>
-#include <dev/firewire/firewire.h>
-#include <dev/firewire/firewirereg.h>
-#include <dev/firewire/fwdma.h>
-#include <dev/firewire/iec13213.h>
-#include <dev/firewire/sbp.h>
-#endif
-#elif defined(__NetBSD__)
#include <sys/param.h>
#include <sys/device.h>
#include <sys/errno.h>
#include <sys/buf.h>
+#include <sys/callout.h>
+#include <sys/condvar.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/malloc.h>
+#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
@@ -108,7 +61,6 @@ __KERNEL_RCSID(0, "$NetBSD: sbp.c,v 1.28 2009/05/12 12:16:55 cegger Exp $");
#include <dev/scsipi/scsiconf.h>
#include <dev/scsipi/scsipiconf.h>
-#include <dev/ieee1394/fw_port.h>
#include <dev/ieee1394/firewire.h>
#include <dev/ieee1394/firewirereg.h>
#include <dev/ieee1394/fwdma.h>
@@ -116,32 +68,28 @@ __KERNEL_RCSID(0, "$NetBSD: sbp.c,v 1.28 2009/05/12 12:16:55 cegger Exp $");
#include <dev/ieee1394/sbp.h>
#include "locators.h"
-#endif
-#define ccb_sdev_ptr spriv_ptr0
-#define ccb_sbp_ptr spriv_ptr1
-#define SBP_NUM_TARGETS 8 /* MAX 64 */
-/*
- * Scan_bus doesn't work for more than 8 LUNs
- * because of CAM_SCSI2_MAXLUN in cam_xpt.c
- */
-#define SBP_NUM_LUNS 64
-#define SBP_MAXPHYS MIN(MAXPHYS, (512*1024) /* 512KB */)
-#define SBP_DMA_SIZE PAGE_SIZE
-#define SBP_LOGIN_SIZE sizeof(struct sbp_login_res)
+#define SBP_FWDEV_ALIVE(fwdev) (((fwdev)->status == FWDEVATTACHED) \
+ && crom_has_specver((fwdev)->csrrom, CSRVAL_ANSIT10, CSRVAL_T10SBP2))
+
+#define SBP_NUM_TARGETS 8 /* MAX 64 */
+#define SBP_NUM_LUNS 64
+#define SBP_MAXPHYS MIN(MAXPHYS, (512*1024) /* 512KB */)
+#define SBP_DMA_SIZE PAGE_SIZE
+#define SBP_LOGIN_SIZE sizeof(struct sbp_login_res)
#define SBP_QUEUE_LEN ((SBP_DMA_SIZE - SBP_LOGIN_SIZE) / sizeof(struct sbp_ocb))
-#define SBP_NUM_OCB (SBP_QUEUE_LEN * SBP_NUM_TARGETS)
+#define SBP_NUM_OCB (SBP_QUEUE_LEN * SBP_NUM_TARGETS)
-/*
+/*
* STATUS FIFO addressing
* bit
* -----------------------
* 0- 1( 2): 0 (alignment)
* 2- 9( 8): lun
* 10-31(14): unit
- * 32-47(16): SBP_BIND_HI
- * 48-64(16): bus_id, node_id
+ * 32-47(16): SBP_BIND_HI
+ * 48-64(16): bus_id, node_id
*/
#define SBP_BIND_HI 0x1
#define SBP_DEV2ADDR(u, l) \
@@ -166,34 +114,6 @@ static int scan_delay = 500; /* msec */
static int use_doorbell = 0;
static int sbp_tags = 0;
-#if defined(__FreeBSD__)
-SYSCTL_DECL(_hw_firewire);
-SYSCTL_NODE(_hw_firewire, OID_AUTO, sbp, CTLFLAG_RD, 0, "SBP-II Subsystem");
-SYSCTL_INT(_debug, OID_AUTO, sbp_debug, CTLFLAG_RW, &debug, 0,
- "SBP debug flag");
-SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, auto_login, CTLFLAG_RW, &auto_login, 0,
- "SBP perform login automatically");
-SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, max_speed, CTLFLAG_RW, &max_speed, 0,
- "SBP transfer max speed");
-SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, exclusive_login, CTLFLAG_RW,
- &ex_login, 0, "SBP enable exclusive login");
-SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, login_delay, CTLFLAG_RW,
- &login_delay, 0, "SBP login delay in msec");
-SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, scan_delay, CTLFLAG_RW,
- &scan_delay, 0, "SBP scan delay in msec");
-SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, use_doorbell, CTLFLAG_RW,
- &use_doorbell, 0, "SBP use doorbell request");
-SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, tags, CTLFLAG_RW, &sbp_tags, 0,
- "SBP tagged queuing support");
-
-TUNABLE_INT("hw.firewire.sbp.auto_login", &auto_login);
-TUNABLE_INT("hw.firewire.sbp.max_speed", &max_speed);
-TUNABLE_INT("hw.firewire.sbp.exclusive_login", &ex_login);
-TUNABLE_INT("hw.firewire.sbp.login_delay", &login_delay);
-TUNABLE_INT("hw.firewire.sbp.scan_delay", &scan_delay);
-TUNABLE_INT("hw.firewire.sbp.use_doorbell", &use_doorbell);
-TUNABLE_INT("hw.firewire.sbp.tags", &sbp_tags);
-#elif defined(__NetBSD__)
static int sysctl_sbp_verify(SYSCTLFN_PROTO, int lower, int upper);
static int sysctl_sbp_verify_max_speed(SYSCTLFN_PROTO);
static int sysctl_sbp_verify_tags(SYSCTLFN_PROTO);
@@ -210,16 +130,14 @@ SYSCTL_SETUP(sysctl_sbp, "sysctl sbp(4) subtree setup")
if ((rc = sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
- NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) {
+ NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0)
goto err;
- }
if ((rc = sysctl_createv(clog, 0, NULL, &node,
CTLFLAG_PERMANENT, CTLTYPE_NODE, "sbp",
SYSCTL_DESCR("sbp controls"), NULL, 0, NULL,
- 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0) {
+ 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
goto err;
- }
sbp_node_num = node->sysctl_num;
/* sbp auto login flag */
@@ -227,77 +145,69 @@ SYSCTL_SETUP(sysctl_sbp, "sysctl sbp(4) subtree setup")
CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
"auto_login", SYSCTL_DESCR("SBP perform login automatically"),
NULL, 0, &auto_login,
- 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
+ 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0)
goto err;
- }
/* sbp max speed */
if ((rc = sysctl_createv(clog, 0, NULL, &node,
CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
"max_speed", SYSCTL_DESCR("SBP transfer max speed"),
sysctl_sbp_verify_max_speed, 0, &max_speed,
- 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
+ 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0)
goto err;
- }
/* sbp exclusive login flag */
if ((rc = sysctl_createv(clog, 0, NULL, &node,
CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
"exclusive_login", SYSCTL_DESCR("SBP enable exclusive login"),
NULL, 0, &ex_login,
- 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
+ 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0)
goto err;
- }
/* sbp login delay */
if ((rc = sysctl_createv(clog, 0, NULL, &node,
CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
"login_delay", SYSCTL_DESCR("SBP login delay in msec"),
NULL, 0, &login_delay,
- 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
+ 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0)
goto err;
- }
/* sbp scan delay */
if ((rc = sysctl_createv(clog, 0, NULL, &node,
CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
"scan_delay", SYSCTL_DESCR("SBP scan delay in msec"),
NULL, 0, &scan_delay,
- 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
+ 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0)
goto err;
- }
/* sbp use doorbell flag */
if ((rc = sysctl_createv(clog, 0, NULL, &node,
CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
"use_doorbell", SYSCTL_DESCR("SBP use doorbell request"),
NULL, 0, &use_doorbell,
- 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
+ 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0)
goto err;
- }
/* sbp force tagged queuing */
if ((rc = sysctl_createv(clog, 0, NULL, &node,
CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
"tags", SYSCTL_DESCR("SBP tagged queuing support"),
sysctl_sbp_verify_tags, 0, &sbp_tags,
- 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
+ 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0)
goto err;
- }
/* sbp driver debug flag */
if ((rc = sysctl_createv(clog, 0, NULL, &node,
CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
"sbp_debug", SYSCTL_DESCR("SBP debug flag"),
NULL, 0, &debug,
- 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0) {
+ 0, CTL_HW, sbp_node_num, CTL_CREATE, CTL_EOL)) != 0)
goto err;
- }
return;
err:
- printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
+ aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
}
static int
@@ -311,28 +221,29 @@ sysctl_sbp_verify(SYSCTLFN_ARGS, int lower, int upper)
node.sysctl_data = &t;
error = sysctl_lookup(SYSCTLFN_CALL(&node));
if (error || newp == NULL)
- return (error);
+ return error;
if (t < lower || t > upper)
- return (EINVAL);
+ return EINVAL;
*(int*)rnode->sysctl_data = t;
- return (0);
+ return 0;
}
static int
sysctl_sbp_verify_max_speed(SYSCTLFN_ARGS)
{
- return (sysctl_sbp_verify(SYSCTLFN_CALL(rnode), 0, FWSPD_S400));
+
+ return sysctl_sbp_verify(SYSCTLFN_CALL(rnode), 0, FWSPD_S400);
}
static int
sysctl_sbp_verify_tags(SYSCTLFN_ARGS)
{
- return (sysctl_sbp_verify(SYSCTLFN_CALL(rnode), -1, 1));
+
+ return sysctl_sbp_verify(SYSCTLFN_CALL(rnode), -1, 1);
}
-#endif
#define NEED_RESPONSE 0
@@ -343,17 +254,23 @@ sysctl_sbp_verify_tags(SYSCTLFN_ARGS)
#define SBP_IND_MAX howmany(SBP_MAXPHYS, PAGE_SIZE)
#endif
struct sbp_ocb {
- STAILQ_ENTRY(sbp_ocb) ocb;
- sbp_scsi_xfer *sxfer;
- bus_addr_t bus_addr;
uint32_t orb[8];
-#define IND_PTR_OFFSET (8*sizeof(uint32_t))
- struct ind_ptr ind_ptr[SBP_IND_MAX];
+#define IND_PTR_OFFSET (sizeof(uint32_t) * 8)
+ struct ind_ptr ind_ptr[SBP_IND_MAX];
+ struct scsipi_xfer *xs;
struct sbp_dev *sdev;
- int flags; /* XXX should be removed */
+ uint16_t index;
+ uint16_t flags; /* XXX should be removed */
bus_dmamap_t dmamap;
+ bus_addr_t bus_addr;
+ STAILQ_ENTRY(sbp_ocb) ocb;
};
+#define SBP_ORB_DMA_SYNC(dma, i, op) \
+ bus_dmamap_sync((dma).dma_tag, (dma).dma_map, \
+ sizeof(struct sbp_ocb) * (i), \
+ sizeof(ocb->orb) + sizeof(ocb->ind_ptr), (op));
+
#define OCB_ACT_MGM 0
#define OCB_ACT_CMD 1
#define OCB_MATCH(o,s) ((o)->bus_addr == ntohl((s)->orb_lo))
@@ -382,11 +299,7 @@ struct sbp_dev{
#define ORB_DOORBELL_NEED (1 << 5)
#define ORB_SHORTAGE (1 << 6)
uint16_t flags;
-#if defined(__FreeBSD__)
- struct cam_path *path;
-#elif defined(__NetBSD__)
struct scsipi_periph *periph;
-#endif
struct sbp_target *target;
struct fwdma_alloc dma;
struct sbp_login_res *login;
@@ -398,6 +311,7 @@ struct sbp_dev{
char vendor[32];
char product[32];
char revision[10];
+ char bustgtlun[32];
};
struct sbp_target {
@@ -410,88 +324,87 @@ struct sbp_target {
struct sbp_ocb *mgm_ocb_cur;
STAILQ_HEAD(, sbp_ocb) mgm_ocb_queue;
struct callout mgm_ocb_timeout;
- struct callout scan_callout;
STAILQ_HEAD(, fw_xfer) xferlist;
int n_xfer;
};
struct sbp_softc {
- struct firewire_dev_comm fd;
-#if defined(__FreeBSD__)
- struct cam_sim *sim;
- struct cam_path *path;
-#elif defined(__NetBSD__)
- struct scsipi_adapter sc_adapter;
+ struct firewire_dev_comm sc_fd;
+ struct scsipi_adapter sc_adapter;
struct scsipi_channel sc_channel;
device_t sc_bus;
- struct lwp *lwp;
-#endif
- struct sbp_target target;
- struct fw_bind fwb;
- fw_bus_dma_tag_t dmat;
- struct timeval last_busreset;
-#define SIMQ_FREEZED 1
- int flags;
- fw_mtx_t mtx;
+ struct lwp *sc_lwp;
+ struct sbp_target sc_target;
+ struct fw_bind sc_fwb;
+ bus_dma_tag_t sc_dmat;
+ struct timeval sc_last_busreset;
+ int sc_flags;
+ kmutex_t sc_mtx;
+ kcondvar_t sc_cv;
};
-#define SBP_LOCK(sbp) fw_mtx_lock(&(sbp)->mtx)
-#define SBP_UNLOCK(sbp) fw_mtx_unlock(&(sbp)->mtx)
-#if defined(__NetBSD__)
-int sbpmatch (device_t, cfdata_t, void *);
-void sbpattach (device_t parent, device_t self, void *aux);
-int sbpdetach (device_t self, int flags);
-#endif
-static void sbp_post_explore (void *);
-static void sbp_recv (struct fw_xfer *);
-static void sbp_mgm_callback (struct fw_xfer *);
-#if 0
-static void sbp_cmd_callback (struct fw_xfer *);
-#endif
-static void sbp_orb_pointer (struct sbp_dev *, struct sbp_ocb *);
-static void sbp_doorbell(struct sbp_dev *);
-static void sbp_execute_ocb (void *, bus_dma_segment_t *, int, int);
-static void sbp_free_ocb (struct sbp_dev *, struct sbp_ocb *);
-static void sbp_abort_ocb (struct sbp_ocb *, int);
-static void sbp_abort_all_ocbs (struct sbp_dev *, int);
-static struct fw_xfer * sbp_write_cmd (struct sbp_dev *, int, int);
-static struct sbp_ocb * sbp_get_ocb (struct sbp_dev *);
-static struct sbp_ocb * sbp_enqueue_ocb (struct sbp_dev *, struct sbp_ocb *);
-static struct sbp_ocb * sbp_dequeue_ocb (struct sbp_dev *, struct sbp_status *);
-static void sbp_free_sdev(struct sbp_dev *);
-static void sbp_free_target (struct sbp_target *);
-static void sbp_mgm_timeout (void *arg);
-static void sbp_timeout (void *arg);
-static void sbp_mgm_orb (struct sbp_dev *, int, struct sbp_ocb *);
-#if defined(__FreeBSD__)
-
-MALLOC_DEFINE(M_SBP, "sbp", "SBP-II/FireWire");
-#elif defined(__NetBSD__)
-static void sbp_scsipi_request(
- struct scsipi_channel *, scsipi_adapter_req_t, void *);
+MALLOC_DEFINE(M_SBP, "sbp", "SBP-II/IEEE1394");
+
+
+static int sbpmatch(device_t, cfdata_t, void *);
+static void sbpattach(device_t, device_t, void *);
+static int sbpdetach(device_t, int);
+
+static void sbp_scsipi_request(struct scsipi_channel *, scsipi_adapter_req_t,
+ void *);
static void sbp_minphys(struct buf *);
-MALLOC_DEFINE(M_SBP, "sbp", "SBP-II/IEEE1394");
+static void sbp_show_sdev_info(struct sbp_dev *);
+static void sbp_alloc_lun(struct sbp_target *);
+static struct sbp_target *sbp_alloc_target(struct sbp_softc *,
+ struct fw_device *);
+static void sbp_probe_lun(struct sbp_dev *);
+static void sbp_login_callout(void *);
+static void sbp_login(struct sbp_dev *);
+static void sbp_probe_target(void *);
+static void sbp_post_busreset(void *);
+static void sbp_post_explore(void *);
+#if NEED_RESPONSE
+static void sbp_loginres_callback(struct fw_xfer *);
#endif
+static inline void sbp_xfer_free(struct fw_xfer *);
+static void sbp_reset_start_callback(struct fw_xfer *);
+static void sbp_reset_start(struct sbp_dev *);
+static void sbp_mgm_callback(struct fw_xfer *);
+static void sbp_scsipi_scan_target(void *);
+static inline void sbp_scan_dev(struct sbp_dev *);
+static void sbp_do_attach(struct fw_xfer *);
+static void sbp_agent_reset_callback(struct fw_xfer *);
+static void sbp_agent_reset(struct sbp_dev *);
+static void sbp_busy_timeout_callback(struct fw_xfer *);
+static void sbp_busy_timeout(struct sbp_dev *);
+static void sbp_orb_pointer_callback(struct fw_xfer *);
+static void sbp_orb_pointer(struct sbp_dev *, struct sbp_ocb *);
+static void sbp_doorbell_callback(struct fw_xfer *);
+static void sbp_doorbell(struct sbp_dev *);
+static struct fw_xfer *sbp_write_cmd(struct sbp_dev *, int, int);
+static void sbp_mgm_orb(struct sbp_dev *, int, struct sbp_ocb *);
+static void sbp_print_scsi_cmd(struct sbp_ocb *);
+static void sbp_scsi_status(struct sbp_status *, struct sbp_ocb *);
+static void sbp_fix_inq_data(struct sbp_ocb *);
+static void sbp_recv(struct fw_xfer *);
+static int sbp_logout_all(struct sbp_softc *);
+static void sbp_free_sdev(struct sbp_dev *);
+static void sbp_free_target(struct sbp_target *);
+static void sbp_scsipi_detach_sdev(struct sbp_dev *);
+static void sbp_scsipi_detach_target(struct sbp_target *);
+static void sbp_target_reset(struct sbp_dev *, int);
+static void sbp_mgm_timeout(void *);
+static void sbp_timeout(void *);
+static void sbp_action1(struct sbp_softc *, struct scsipi_xfer *);
+static void sbp_execute_ocb(struct sbp_ocb *, bus_dma_segment_t *, int);
+static struct sbp_ocb *sbp_dequeue_ocb(struct sbp_dev *, struct sbp_status *);
+static struct sbp_ocb *sbp_enqueue_ocb(struct sbp_dev *, struct sbp_ocb *);
+static struct sbp_ocb *sbp_get_ocb(struct sbp_dev *);
+static void sbp_free_ocb(struct sbp_dev *, struct sbp_ocb *);
+static void sbp_abort_ocb(struct sbp_ocb *, int);
+static void sbp_abort_all_ocbs(struct sbp_dev *, int);
-#if defined(__FreeBSD__)
-/* cam related functions */
-static void sbp_action(struct cam_sim *, sbp_scsi_xfer *sxfer);
-static void sbp_poll(struct cam_sim *);
-static void sbp_cam_scan_lun(struct cam_periph *, sbp_scsi_xfer *);
-static void sbp_cam_scan_target(void *);
-static void sbp_cam_detach_sdev(struct sbp_dev *);
-static void sbp_cam_detach_target (struct sbp_target *);
-#define SBP_DETACH_SDEV(sd) sbp_cam_detach_sdev((sd))
-#define SBP_DETACH_TARGET(st) sbp_cam_detach_target((st))
-#elif defined(__NetBSD__)
-/* scsipi related functions */
-static void sbp_scsipi_scan_target(void *);
-static void sbp_scsipi_detach_sdev(struct sbp_dev *);
-static void sbp_scsipi_detach_target (struct sbp_target *);
-#define SBP_DETACH_SDEV(sd) sbp_scsipi_detach_sdev((sd))
-#define SBP_DETACH_TARGET(st) sbp_scsipi_detach_target((st))
-#endif
static const char *orb_status0[] = {
/* 0 */ "No additional information to report",
@@ -537,88 +450,213 @@ static const char *orb_status1_serial_bus_error[] = {
/* F */ "Address error"
};
-#if defined(__FreeBSD__)
-#if 0
-static void
-sbp_identify(driver_t *driver, device_t parent)
+
+CFATTACH_DECL_NEW(sbp, sizeof(struct sbp_softc),
+ sbpmatch, sbpattach, sbpdetach, NULL);
+
+
+int
+sbpmatch(device_t parent, cfdata_t cf, void *aux)
{
- device_t child;
-SBP_DEBUG(0)
- printf("sbp_identify\n");
-END_DEBUG
+ struct fw_attach_args *fwa = aux;
- child = BUS_ADD_CHILD(parent, 0, "sbp", fw_get_unit(parent));
+ if (strcmp(fwa->name, "sbp") == 0)
+ return 1;
+ return 0;
}
-#endif
-/*
- * sbp_probe()
- */
-static int
-sbp_probe(device_t dev)
+static void
+sbpattach(device_t parent, device_t self, void *aux)
{
- device_t pa;
+ struct sbp_softc *sc = device_private(self);
+ struct fw_attach_args *fwa = (struct fw_attach_args *)aux;
+ struct firewire_comm *fc;
+ struct scsipi_adapter *sc_adapter = &sc->sc_adapter;
+ struct scsipi_channel *sc_channel = &sc->sc_channel;
+ struct sbp_target *target = &sc->sc_target;
+ int dv_unit;
-SBP_DEBUG(0)
- printf("sbp_probe\n");
-END_DEBUG
+ aprint_naive("\n");
+ aprint_normal(": SBP-2/SCSI over IEEE1394\n");
+
+ sc->sc_fd.dev = self;
+
+ if (cold)
+ sbp_cold++;
+ sc->sc_fd.fc = fc = fwa->fc;
+ mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_VM);
+ cv_init(&sc->sc_cv, "sbp");
+
+ if (max_speed < 0)
+ max_speed = fc->speed;
+
+ sc->sc_dmat = fc->dmat;
+
+ sc->sc_target.fwdev = NULL;
+ sc->sc_target.luns = NULL;
- pa = device_get_parent(dev);
- if(fw_get_unit(dev) != fw_get_unit(pa)){
- return(ENXIO);
+ if (sbp_alloc_target(sc, fwa->fwdev) == NULL)
+ return;
+
+ sc_adapter->adapt_dev = sc->sc_fd.dev;
+ sc_adapter->adapt_nchannels = 1;
+ sc_adapter->adapt_max_periph = 1;
+ sc_adapter->adapt_request = sbp_scsipi_request;
+ sc_adapter->adapt_minphys = sbp_minphys;
+ sc_adapter->adapt_openings = 8;
+
+ sc_channel->chan_adapter = sc_adapter;
+ sc_channel->chan_bustype = &scsi_bustype;
+ sc_channel->chan_defquirks = PQUIRK_ONLYBIG;
+ sc_channel->chan_channel = 0;
+ sc_channel->chan_flags = SCSIPI_CHAN_CANGROW | SCSIPI_CHAN_NOSETTLE;
+
+ sc_channel->chan_ntargets = 1;
+ sc_channel->chan_nluns = target->num_lun; /* We set nluns 0 now */
+ sc_channel->chan_id = 1;
+
+ sc->sc_bus = config_found(sc->sc_fd.dev, sc_channel, scsiprint);
+ if (sc->sc_bus == NULL) {
+ aprint_error_dev(self, "attach failed\n");
+ return;
}
- device_set_desc(dev, "SBP-2/SCSI over FireWire");
+ /* We reserve 16 bit space (4 bytes X 64 unit X 256 luns) */
+ dv_unit = device_unit(sc->sc_fd.dev);
+ sc->sc_fwb.start = SBP_DEV2ADDR(dv_unit, 0);
+ sc->sc_fwb.end = SBP_DEV2ADDR(dv_unit, -1);
+ mutex_init(&sc->sc_fwb.fwb_mtx, MUTEX_DEFAULT, IPL_VM);
+ /* pre-allocate xfer */
+ STAILQ_INIT(&sc->sc_fwb.xferlist);
+ fw_xferlist_add(&sc->sc_fwb.xferlist, M_SBP,
+ /*send*/ 0, /*recv*/ SBP_RECV_LEN, SBP_NUM_OCB / 2,
+ fc, (void *)sc, sbp_recv);
+ fw_bindadd(fc, &sc->sc_fwb);
-#if 0
- if (bootverbose)
- debug = bootverbose;
-#endif
+ sc->sc_fd.post_busreset = sbp_post_busreset;
+ sc->sc_fd.post_explore = sbp_post_explore;
- return (0);
+ if (fc->status != FWBUSNOTREADY) {
+ sbp_post_busreset((void *)sc);
+ sbp_post_explore((void *)sc);
+ }
}
-#elif defined(__NetBSD__)
-int
-sbpmatch(device_t parent, cfdata_t cf, void *aux)
+
+static int
+sbpdetach(device_t self, int flags)
{
- struct fw_attach_args *fwa = aux;
+ struct sbp_softc *sc = device_private(self);
+ struct firewire_comm *fc = sc->sc_fd.fc;
+
+ sbp_scsipi_detach_target(&sc->sc_target);
+
+ if (SBP_FWDEV_ALIVE(sc->sc_target.fwdev)) {
+ sbp_logout_all(sc);
+
+ /* XXX wait for logout completion */
+ mutex_enter(&sc->sc_mtx);
+ cv_timedwait_sig(&sc->sc_cv, &sc->sc_mtx, hz/2);
+ mutex_exit(&sc->sc_mtx);
+ }
+
+ sbp_free_target(&sc->sc_target);
+
+ fw_bindremove(fc, &sc->sc_fwb);
+ fw_xferlist_remove(&sc->sc_fwb.xferlist);
+ mutex_destroy(&sc->sc_fwb.fwb_mtx);
+
+ mutex_destroy(&sc->sc_mtx);
- if (strcmp(fwa->name, "sbp") == 0)
- return 1;
return 0;
}
-#endif
+
static void
-sbp_show_sdev_info(struct sbp_dev *sdev, int new)
+sbp_scsipi_request(struct scsipi_channel *channel, scsipi_adapter_req_t req,
+ void *arg)
{
- struct fw_device *fwdev;
+ struct sbp_softc *sc = device_private(channel->chan_adapter->adapt_dev);
+ struct scsipi_xfer *xs = arg;
+ int i;
- printf("%s:%d:%d ",
- fw_get_nameunit(sdev->target->sbp->fd.dev),
- sdev->target->target_id,
- sdev->lun_id
- );
- if (new == 2) {
- return;
- }
- fwdev = sdev->target->fwdev;
- printf("ordered:%d type:%d EUI:%08x%08x node:%d "
- "speed:%d maxrec:%d",
- (sdev->type & 0x40) >> 6,
- (sdev->type & 0x1f),
- fwdev->eui.hi,
- fwdev->eui.lo,
- fwdev->dst,
- fwdev->speed,
- fwdev->maxrec
- );
- if (new)
- printf(" new!\n");
- else
+SBP_DEBUG(1)
+ printf("Called sbp_scsipi_request\n");
+END_DEBUG
+
+ switch (req) {
+ case ADAPTER_REQ_RUN_XFER:
+SBP_DEBUG(1)
+ printf("Got req_run_xfer\n");
+ printf("xs control: 0x%08x, timeout: %d\n",
+ xs->xs_control, xs->timeout);
+ printf("opcode: 0x%02x\n", (int)xs->cmd->opcode);
+ for (i = 0; i < 15; i++)
+ printf("0x%02x ",(int)xs->cmd->bytes[i]);
printf("\n");
- sbp_show_sdev_info(sdev, 2);
- printf("'%s' '%s' '%s'\n", sdev->vendor, sdev->product, sdev->revision);
+END_DEBUG
+ if (xs->xs_control & XS_CTL_RESET) {
+SBP_DEBUG(1)
+ printf("XS_CTL_RESET not support\n");
+END_DEBUG
+ break;
+ }
+#define SBPSCSI_SBP2_MAX_CDB 12
+ if (xs->cmdlen > SBPSCSI_SBP2_MAX_CDB) {
+SBP_DEBUG(0)
+ printf(
+ "sbp doesn't support cdb's larger than %d bytes\n",
+ SBPSCSI_SBP2_MAX_CDB);
+END_DEBUG
+ xs->error = XS_DRIVER_STUFFUP;
+ scsipi_done(xs);
+ return;
+ }
+ sbp_action1(sc, xs);
+
+ break;
+ case ADAPTER_REQ_GROW_RESOURCES:
+SBP_DEBUG(1)
+ printf("Got req_grow_resources\n");
+END_DEBUG
+ break;
+ case ADAPTER_REQ_SET_XFER_MODE:
+SBP_DEBUG(1)
+ printf("Got set xfer mode\n");
+END_DEBUG
+ break;
+ default:
+ panic("Unknown request: %d\n", (int)req);
+ }
+}
+
+static void
+sbp_minphys(struct buf *bp)
+{
+
+ minphys(bp);
+}
+
+
+/*
+ * Display device characteristics on the console
+ */
+static void
+sbp_show_sdev_info(struct sbp_dev *sdev)
+{
+ struct fw_device *fwdev = sdev->target->fwdev;
+ struct sbp_softc *sc = sdev->target->sbp;
+
+ aprint_normal_dev(sc->sc_fd.dev,
+ "ordered:%d type:%d EUI:%08x%08x node:%d speed:%d maxrec:%d\n",
+ (sdev->type & 0x40) >> 6,
+ (sdev->type & 0x1f),
+ fwdev->eui.hi,
+ fwdev->eui.lo,
+ fwdev->dst,
+ fwdev->speed,
+ fwdev->maxrec);
+ aprint_normal_dev(sc->sc_fd.dev, "%s '%s' '%s' '%s'\n",
+ sdev->bustgtlun, sdev->vendor, sdev->product, sdev->revision);
}
static void
@@ -627,10 +665,10 @@ sbp_alloc_lun(struct sbp_target *target)
struct crom_context cc;
struct csrreg *reg;
struct sbp_dev *sdev, **newluns;
- struct sbp_softc *sbp;
+ struct sbp_softc *sc;
int maxlun, lun, i;
- sbp = target->sbp;
+ sc = target->sbp;
crom_init_context(&cc, target->fwdev->csrrom);
/* XXX shoud parse appropriate unit directories only */
maxlun = -1;
@@ -647,24 +685,24 @@ END_DEBUG
crom_next(&cc);
}
if (maxlun < 0)
- printf("%s:%d no LUN found\n",
- fw_get_nameunit(target->sbp->fd.dev),
+ aprint_normal_dev(sc->sc_fd.dev, "%d: no LUN found\n",
target->target_id);
- maxlun ++;
+ maxlun++;
if (maxlun >= SBP_NUM_LUNS)
maxlun = SBP_NUM_LUNS;
/* Invalidiate stale devices */
- for (lun = 0; lun < target->num_lun; lun ++) {
+ for (lun = 0; lun < target->num_lun; lun++) {
sdev = target->luns[lun];
if (sdev == NULL)
continue;
sdev->flags &= ~VALID_LUN;
if (lun >= maxlun) {
/* lost device */
- SBP_DETACH_SDEV(sdev);
+ sbp_scsipi_detach_sdev(sdev);
sbp_free_sdev(sdev);
+ target->luns[lun] = NULL;
}
}
@@ -673,9 +711,9 @@ END_DEBUG
newluns = (struct sbp_dev **) realloc(target->luns,
sizeof(struct sbp_dev *) * maxlun,
M_SBP, M_NOWAIT | M_ZERO);
-
+
if (newluns == NULL) {
- printf("%s: realloc failed\n", __func__);
+ aprint_error_dev(sc->sc_fd.dev, "realloc failed\n");
newluns = target->luns;
maxlun = target->num_lun;
}
@@ -684,10 +722,12 @@ END_DEBUG
* We must zero the extended region for the case
* realloc() doesn't allocate new buffer.
*/
- if (maxlun > target->num_lun)
+ if (maxlun > target->num_lun) {
+ const int sbp_dev_p_sz = sizeof(struct sbp_dev *);
+
memset(&newluns[target->num_lun], 0,
- sizeof(struct sbp_dev *) *
- (maxlun - target->num_lun));
+ sbp_dev_p_sz * (maxlun - target->num_lun));
+ }
target->luns = newluns;
target->num_lun = maxlun;
@@ -702,7 +742,8 @@ END_DEBUG
break;
lun = reg->val & 0xffff;
if (lun >= SBP_NUM_LUNS) {
- printf("too large lun %d\n", lun);
+ aprint_error_dev(sc->sc_fd.dev, "too large lun %d\n",
+ lun);
goto next;
}
@@ -711,17 +752,31 @@ END_DEBUG
sdev = malloc(sizeof(struct sbp_dev),
M_SBP, M_NOWAIT | M_ZERO);
if (sdev == NULL) {
- printf("%s: malloc failed\n", __func__);
+ aprint_error_dev(sc->sc_fd.dev,
+ "malloc failed\n");
goto next;
}
target->luns[lun] = sdev;
sdev->lun_id = lun;
sdev->target = target;
STAILQ_INIT(&sdev->ocbs);
- fw_callout_init(&sdev->login_callout);
+ callout_init(&sdev->login_callout, CALLOUT_MPSAFE);
+ callout_setfunc(&sdev->login_callout,
+ sbp_login_callout, sdev);
sdev->status = SBP_DEV_RESET;
new = 1;
- SBP_DEVICE_PREATTACH();
+ snprintf(sdev->bustgtlun, 32, "%s:%d:%d",
+ device_xname(sc->sc_fd.dev),
+ sdev->target->target_id,
+ sdev->lun_id);
+ if (!sc->sc_lwp)
+ if (kthread_create(
+ PRI_NONE, KTHREAD_MPSAFE, NULL,
+ sbp_scsipi_scan_target, &sc->sc_target,
+ &sc->sc_lwp,
+ "sbp%d_attach", device_unit(sc->sc_fd.dev)))
+ aprint_error_dev(sc->sc_fd.dev,
+ "unable to create thread");
}
sdev->flags |= VALID_LUN;
sdev->type = (reg->val & 0xff0000) >> 16;
@@ -729,45 +784,42 @@ END_DEBUG
if (new == 0)
goto next;
- fwdma_malloc(sbp->fd.fc,
- /* alignment */ sizeof(uint32_t),
- SBP_DMA_SIZE, &sdev->dma, BUS_DMA_NOWAIT);
+ fwdma_alloc_setup(sc->sc_fd.dev, sc->sc_dmat, SBP_DMA_SIZE,
+ &sdev->dma, sizeof(uint32_t), BUS_DMA_NOWAIT);
if (sdev->dma.v_addr == NULL) {
- printf("%s: dma space allocation failed\n",
- __func__);
free(sdev, M_SBP);
target->luns[lun] = NULL;
goto next;
}
- sdev->login = (struct sbp_login_res *) sdev->dma.v_addr;
- sdev->ocb = (struct sbp_ocb *)
- ((char *)sdev->dma.v_addr + SBP_LOGIN_SIZE);
+ sdev->ocb = (struct sbp_ocb *)sdev->dma.v_addr;
+ sdev->login = (struct sbp_login_res *)&sdev->ocb[SBP_QUEUE_LEN];
memset((char *)sdev->ocb, 0,
- sizeof (struct sbp_ocb) * SBP_QUEUE_LEN);
+ sizeof(struct sbp_ocb) * SBP_QUEUE_LEN);
STAILQ_INIT(&sdev->free_ocbs);
for (i = 0; i < SBP_QUEUE_LEN; i++) {
- struct sbp_ocb *ocb;
- ocb = &sdev->ocb[i];
- ocb->bus_addr = sdev->dma.bus_addr
- + SBP_LOGIN_SIZE
- + sizeof(struct sbp_ocb) * i
- + offsetof(struct sbp_ocb, orb[0]);
- if (fw_bus_dmamap_create(sbp->dmat, 0, &ocb->dmamap)) {
- printf("sbp_attach: cannot create dmamap\n");
+ struct sbp_ocb *ocb = &sdev->ocb[i];
+
+ ocb->index = i;
+ ocb->bus_addr =
+ sdev->dma.bus_addr + sizeof(struct sbp_ocb) * i;
+ if (bus_dmamap_create(sc->sc_dmat, 0x100000,
+ SBP_IND_MAX, SBP_SEG_MAX, 0, 0, &ocb->dmamap)) {
+ aprint_error_dev(sc->sc_fd.dev,
+ "cannot create dmamap %d\n", i);
/* XXX */
goto next;
}
- sbp_free_ocb(sdev, ocb);
+ sbp_free_ocb(sdev, ocb); /* into free queue */
}
next:
crom_next(&cc);
}
- for (lun = 0; lun < target->num_lun; lun ++) {
+ for (lun = 0; lun < target->num_lun; lun++) {
sdev = target->luns[lun];
if (sdev != NULL && (sdev->flags & VALID_LUN) == 0) {
- SBP_DETACH_SDEV(sdev);
+ sbp_scsipi_detach_sdev(sdev);
sbp_free_sdev(sdev);
target->luns[lun] = NULL;
}
@@ -775,7 +827,7 @@ next:
}
static struct sbp_target *
-sbp_alloc_target(struct sbp_softc *sbp, struct fw_device *fwdev)
+sbp_alloc_target(struct sbp_softc *sc, struct fw_device *fwdev)
{
struct sbp_target *target;
struct crom_context cc;
@@ -785,8 +837,8 @@ SBP_DEBUG(1)
printf("sbp_alloc_target\n");
END_DEBUG
/* new target */
- target = &sbp->target;
- target->sbp = sbp;
+ target = &sc->sc_target;
+ target->sbp = sc;
target->fwdev = fwdev;
target->target_id = 0;
/* XXX we may want to reload mgm port after each bus reset */
@@ -794,7 +846,7 @@ END_DEBUG
crom_init_context(&cc, target->fwdev->csrrom);
reg = crom_search_key(&cc, CROM_MGM);
if (reg == NULL || reg->val == 0) {
- printf("NULL management address\n");
+ aprint_error_dev(sc->sc_fd.dev, "NULL management address\n");
target->fwdev = NULL;
return NULL;
}
@@ -807,8 +859,7 @@ END_DEBUG
STAILQ_INIT(&target->xferlist);
target->n_xfer = 0;
STAILQ_INIT(&target->mgm_ocb_queue);
- fw_callout_init(&target->mgm_ocb_timeout);
- fw_callout_init(&target->scan_callout);
+ callout_init(&target->mgm_ocb_timeout, CALLOUT_MPSAFE);
target->luns = NULL;
target->num_lun = 0;
@@ -840,8 +891,8 @@ sbp_probe_lun(struct sbp_dev *sdev)
/* get firmware revision */
reg = crom_search_key(cc, CSRKEY_FIRM_VER);
if (reg != NULL)
- snprintf(sdev->revision, sizeof(sdev->revision),
- "%06x", reg->val);
+ snprintf(sdev->revision, sizeof(sdev->revision), "%06x",
+ reg->val);
/* get product string */
crom_search_key(cc, CSRKEY_MODEL);
crom_next(cc);
@@ -852,119 +903,81 @@ static void
sbp_login_callout(void *arg)
{
struct sbp_dev *sdev = (struct sbp_dev *)arg;
+
sbp_mgm_orb(sdev, ORB_FUN_LGI, NULL);
}
static void
sbp_login(struct sbp_dev *sdev)
{
+ struct sbp_softc *sc = sdev->target->sbp;
struct timeval delta;
struct timeval t;
int ticks = 0;
microtime(&delta);
- fw_timevalsub(&delta, &sdev->target->sbp->last_busreset);
+ timersub(&delta, &sc->sc_last_busreset, &delta);
t.tv_sec = login_delay / 1000;
t.tv_usec = (login_delay % 1000) * 1000;
- fw_timevalsub(&t, &delta);
+ timersub(&t, &delta, &t);
if (t.tv_sec >= 0 && t.tv_usec > 0)
ticks = (t.tv_sec * 1000 + t.tv_usec / 1000) * hz / 1000;
SBP_DEBUG(0)
printf("%s: sec = %lld usec = %ld ticks = %d\n", __func__,
(long long)t.tv_sec, (long)t.tv_usec, ticks);
END_DEBUG
- fw_callout_reset(&sdev->login_callout, ticks,
- sbp_login_callout, (void *)(sdev));
+ callout_schedule(&sdev->login_callout, ticks);
}
static void
sbp_probe_target(void *arg)
{
struct sbp_target *target = (struct sbp_target *)arg;
- struct sbp_softc *sbp;
struct sbp_dev *sdev;
- struct firewire_comm *fc;
int i;
SBP_DEBUG(1)
printf("sbp_probe_target %d\n", target->target_id);
END_DEBUG
- sbp = target->sbp;
- fc = target->sbp->fd.fc;
sbp_alloc_lun(target);
/* XXX untimeout mgm_ocb and dequeue */
- for (i=0; i < target->num_lun; i++) {
+ for (i = 0; i < target->num_lun; i++) {
sdev = target->luns[i];
- if (sdev == NULL)
+ if (sdev == NULL || sdev->status == SBP_DEV_DEAD)
continue;
- if (sdev->status != SBP_DEV_DEAD) {
- if (SBP_DEVICE(sdev) != NULL) {
- SBP_LOCK(sbp);
- SBP_DEVICE_FREEZE(sdev, 1);
- sdev->freeze ++;
- SBP_UNLOCK(sbp);
- }
- sbp_probe_lun(sdev);
-SBP_DEBUG(0)
- sbp_show_sdev_info(sdev,
- (sdev->status == SBP_DEV_RESET));
-END_DEBUG
- sbp_abort_all_ocbs(sdev, XS_SCSI_BUS_RESET);
- switch (sdev->status) {
- case SBP_DEV_RESET:
- /* new or revived target */
- if (auto_login)
- sbp_login(sdev);
- break;
- case SBP_DEV_TOATTACH:
- case SBP_DEV_PROBE:
- case SBP_DEV_ATTACHED:
- case SBP_DEV_RETRY:
- default:
- sbp_mgm_orb(sdev, ORB_FUN_RCN, NULL);
- break;
- }
- } else {
- switch (sdev->status) {
- case SBP_DEV_ATTACHED:
-SBP_DEBUG(0)
- /* the device has gone */
- sbp_show_sdev_info(sdev, 2);
- printf("lost target\n");
-END_DEBUG
- if (SBP_DEVICE(sdev) != NULL) {
- SBP_LOCK(sbp);
- SBP_DEVICE_FREEZE(sdev, 1);
- sdev->freeze ++;
- SBP_UNLOCK(sbp);
- }
- sdev->status = SBP_DEV_RETRY;
- sbp_abort_all_ocbs(sdev, XS_SCSI_BUS_RESET);
- break;
- case SBP_DEV_PROBE:
- case SBP_DEV_TOATTACH:
- sdev->status = SBP_DEV_RESET;
- break;
- case SBP_DEV_RETRY:
- case SBP_DEV_RESET:
- case SBP_DEV_DEAD:
- break;
- }
+ if (sdev->periph != NULL) {
+ scsipi_periph_freeze(sdev->periph, 1);
+ sdev->freeze++;
+ }
+ sbp_probe_lun(sdev);
+ sbp_show_sdev_info(sdev);
+
+ sbp_abort_all_ocbs(sdev, XS_RESET);
+ switch (sdev->status) {
+ case SBP_DEV_RESET:
+ /* new or revived target */
+ if (auto_login)
+ sbp_login(sdev);
+ break;
+ case SBP_DEV_TOATTACH:
+ case SBP_DEV_PROBE:
+ case SBP_DEV_ATTACHED:
+ case SBP_DEV_RETRY:
+ default:
+ sbp_mgm_orb(sdev, ORB_FUN_RCN, NULL);
+ break;
}
}
}
-#define SBP_FWDEV_ALIVE(fwdev) (((fwdev)->status == FWDEVATTACHED) \
- && crom_has_specver((fwdev)->csrrom, CSRVAL_ANSIT10, CSRVAL_T10SBP2))
-
static void
sbp_post_busreset(void *arg)
{
- struct sbp_softc *sbp = (struct sbp_softc *)arg;
- struct sbp_target *target = &sbp->target;
+ struct sbp_softc *sc = (struct sbp_softc *)arg;
+ struct sbp_target *target = &sc->sc_target;
struct fw_device *fwdev = target->fwdev;
int alive;
@@ -974,21 +987,19 @@ SBP_DEBUG(0)
if (!alive)
printf("not alive\n");
END_DEBUG
- microtime(&sbp->last_busreset);
+ microtime(&sc->sc_last_busreset);
if (!alive)
return;
- SBP_LOCK(sbp);
- SBP_BUS_FREEZE(sbp);
- SBP_UNLOCK(sbp);
+ scsipi_channel_freeze(&sc->sc_channel, 1);
}
static void
sbp_post_explore(void *arg)
{
- struct sbp_softc *sbp = (struct sbp_softc *)arg;
- struct sbp_target *target = &sbp->target;
+ struct sbp_softc *sc = (struct sbp_softc *)arg;
+ struct sbp_target *target = &sc->sc_target;
struct fw_device *fwdev = target->fwdev;
int alive;
@@ -1001,16 +1012,11 @@ END_DEBUG
if (!alive)
return;
- if (sbp_cold > 0)
- sbp_cold --;
+ if (!firewire_phydma_enable)
+ return;
-#if 0
- /*
- * XXX don't let CAM the bus rest.
- * CAM tries to do something with freezed (DEV_RETRY) devices.
- */
- xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
-#endif
+ if (sbp_cold > 0)
+ sbp_cold--;
SBP_DEBUG(0)
printf("sbp_post_explore: EUI:%08x%08x ", fwdev->eui.hi, fwdev->eui.lo);
@@ -1019,25 +1025,23 @@ END_DEBUG
if (target->num_lun == 0)
sbp_free_target(target);
- SBP_LOCK(sbp);
- SBP_BUS_THAW(sbp);
- SBP_UNLOCK(sbp);
+ scsipi_channel_thaw(&sc->sc_channel, 1);
}
#if NEED_RESPONSE
static void
-sbp_loginres_callback(struct fw_xfer *xfer){
- int s;
- struct sbp_dev *sdev;
- sdev = (struct sbp_dev *)xfer->sc;
+sbp_loginres_callback(struct fw_xfer *xfer)
+{
+ struct sbp_dev *sdev = (struct sbp_dev *)xfer->sc;
+ struct sbp_softc *sc = sdev->target->sbp;
+
SBP_DEBUG(1)
- sbp_show_sdev_info(sdev, 2);
printf("sbp_loginres_callback\n");
END_DEBUG
/* recycle */
- s = splfw();
- STAILQ_INSERT_TAIL(&sdev->target->sbp->fwb.xferlist, xfer, link);
- splx(s);
+ mutex_enter(&sc->sc_fwb.fwb_mtx);
+ STAILQ_INSERT_TAIL(&sc->sc_fwb.xferlist, xfer, link);
+ mutex_exit(&sc->sc_fwb.fwb_mtx);
return;
}
#endif
@@ -1045,16 +1049,13 @@ END_DEBUG
static inline void
sbp_xfer_free(struct fw_xfer *xfer)
{
- struct sbp_dev *sdev;
- int s;
+ struct sbp_dev *sdev = (struct sbp_dev *)xfer->sc;
+ struct sbp_softc *sc = sdev->target->sbp;
- sdev = (struct sbp_dev *)xfer->sc;
fw_xfer_unload(xfer);
- s = splfw();
- SBP_LOCK(sdev->target->sbp);
+ mutex_enter(&sc->sc_mtx);
STAILQ_INSERT_TAIL(&sdev->target->xferlist, xfer, link);
- SBP_UNLOCK(sdev->target->sbp);
- splx(s);
+ mutex_exit(&sc->sc_mtx);
}
static void
@@ -1064,10 +1065,9 @@ sbp_reset_start_callback(struct fw_xfer *xfer)
struct sbp_target *target = sdev->target;
int i;
- if (xfer->resp != 0) {
- sbp_show_sdev_info(sdev, 2);
- printf("sbp_reset_start failed: resp=%d\n", xfer->resp);
- }
+ if (xfer->resp != 0)
+ aprint_error("%s: sbp_reset_start failed: resp=%d\n",
+ sdev->bustgtlun, xfer->resp);
for (i = 0; i < target->num_lun; i++) {
tsdev = target->luns[i];
@@ -1083,17 +1083,20 @@ sbp_reset_start(struct sbp_dev *sdev)
struct fw_pkt *fp;
SBP_DEBUG(0)
- sbp_show_sdev_info(sdev, 2);
- printf("sbp_reset_start\n");
+ printf("%s: sbp_reset_start: %s\n",
+ device_xname(sdev->target->sbp->sc_fd.dev), sdev->bustgtlun);
END_DEBUG
xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0);
+ if (xfer == NULL)
+ return;
xfer->hand = sbp_reset_start_callback;
fp = &xfer->send.hdr;
fp->mode.wreqq.dest_hi = 0xffff;
fp->mode.wreqq.dest_lo = 0xf0000000 | RESET_START;
fp->mode.wreqq.data = htonl(0xf);
- fw_asyreq(xfer->fc, -1, xfer);
+ if (fw_asyreq(xfer->fc, -1, xfer) != 0)
+ sbp_xfer_free(xfer);
}
static void
@@ -1105,132 +1108,36 @@ sbp_mgm_callback(struct fw_xfer *xfer)
sdev = (struct sbp_dev *)xfer->sc;
SBP_DEBUG(1)
- sbp_show_sdev_info(sdev, 2);
- printf("sbp_mgm_callback\n");
+ printf("%s: sbp_mgm_callback: %s\n",
+ device_xname(sdev->target->sbp->sc_fd.dev), sdev->bustgtlun);
END_DEBUG
resp = xfer->resp;
sbp_xfer_free(xfer);
-#if 0
- if (resp != 0) {
- sbp_show_sdev_info(sdev, 2);
- printf("management ORB failed(%d) ... RESET_START\n", resp);
- sbp_reset_start(sdev);
- }
-#endif
return;
}
-#if defined(__FreeBSD__)
-static struct sbp_dev *
-sbp_next_dev(struct sbp_target *target, int lun)
-{
- struct sbp_dev **sdevp;
- int i;
-
- for (i = lun, sdevp = &target->luns[lun]; i < target->num_lun;
- i++, sdevp++)
- if (*sdevp != NULL && (*sdevp)->status == SBP_DEV_PROBE)
- return(*sdevp);
- return(NULL);
-}
-
-#define SCAN_PRI 1
-static void
-sbp_cam_scan_lun(struct cam_periph *periph, sbp_scsi_xfer *sxfer)
-{
- struct sbp_target *target;
- struct sbp_dev *sdev;
-
- sdev = (struct sbp_dev *) sxfer->ccb_h.ccb_sdev_ptr;
- target = sdev->target;
-SBP_DEBUG(0)
- sbp_show_sdev_info(sdev, 2);
- printf("sbp_cam_scan_lun\n");
-END_DEBUG
- if ((SCSI_XFER_ERROR(sxfer) & CAM_STATUS_MASK) == XS_REQ_CMP) {
- sdev->status = SBP_DEV_ATTACHED;
- } else {
- sbp_show_sdev_info(sdev, 2);
- printf("scan failed\n");
- }
- sdev = sbp_next_dev(target, sdev->lun_id + 1);
- if (sdev == NULL) {
- free(sxfer, M_SBP);
- return;
- }
- /* reuse sxfer */
- xpt_setup_ccb(&sxfer->ccb_h, sdev->path, SCAN_PRI);
- sxfer->ccb_h.ccb_sdev_ptr = sdev;
- xpt_action(sxfer);
- xpt_release_devq(sdev->path, sdev->freeze, TRUE);
- sdev->freeze = 1;
-}
-
-static void
-sbp_cam_scan_target(void *arg)
-{
- struct sbp_target *target = (struct sbp_target *)arg;
- struct sbp_dev *sdev;
- sbp_scsi_xfer *sxfer;
-
- sdev = sbp_next_dev(target, 0);
- if (sdev == NULL) {
- printf("sbp_cam_scan_target: nothing to do for target%d\n",
- target->target_id);
- return;
- }
-SBP_DEBUG(0)
- sbp_show_sdev_info(sdev, 2);
- printf("sbp_cam_scan_target\n");
-END_DEBUG
- sxfer = malloc(sizeof(sbp_scsi_xfer), M_SBP, M_NOWAIT | M_ZERO);
- if (sxfer == NULL) {
- printf("sbp_cam_scan_target: malloc failed\n");
- return;
- }
- xpt_setup_ccb(&sxfer->ccb_h, sdev->path, SCAN_PRI);
- sxfer->ccb_h.func_code = XPT_SCAN_LUN;
- sxfer->ccb_h.cbfcnp = sbp_cam_scan_lun;
- sxfer->ccb_h.flags |= CAM_DEV_QFREEZE;
- sxfer->crcn.flags = CAM_FLAG_NONE;
- sxfer->ccb_h.ccb_sdev_ptr = sdev;
-
- /* The scan is in progress now. */
- SBP_LOCK(target->sbp);
- xpt_action(sxfer);
- xpt_release_devq(sdev->path, sdev->freeze, TRUE);
- sdev->freeze = 1;
- SBP_UNLOCK(target->sbp);
-}
-
-static inline void
-sbp_scan_dev(struct sbp_dev *sdev)
-{
- sdev->status = SBP_DEV_PROBE;
- fw_callout_reset(&sdev->target->scan_callout, scan_delay * hz / 1000,
- sbp_cam_scan_target, (void *)sdev->target);
-}
-#elif defined(__NetBSD__)
static void
sbp_scsipi_scan_target(void *arg)
{
struct sbp_target *target = (struct sbp_target *)arg;
- struct sbp_softc *sbp = target->sbp;
+ struct sbp_softc *sc = target->sbp;
struct sbp_dev *sdev;
- struct scsipi_channel *chan = &sbp->sc_channel;
- struct scsibus_softc *sc_bus = device_private(sbp->sc_bus);
+ struct scsipi_channel *chan = &sc->sc_channel;
+ struct scsibus_softc *sc_bus = device_private(sc->sc_bus);
int lun, yet;
do {
- tsleep(target, PWAIT|PCATCH, "-", 0);
+ mutex_enter(&sc->sc_mtx);
+ cv_wait_sig(&sc->sc_cv, &sc->sc_mtx);
+ mutex_exit(&sc->sc_mtx);
yet = 0;
- for (lun = 0; lun < target->num_lun; lun ++) {
+ for (lun = 0; lun < target->num_lun; lun++) {
sdev = target->luns[lun];
if (sdev == NULL)
continue;
if (sdev->status != SBP_DEV_PROBE) {
- yet ++;
+ yet++;
continue;
}
@@ -1238,26 +1145,31 @@ sbp_scsipi_scan_target(void *arg)
if (chan->chan_nluns < target->num_lun)
chan->chan_nluns = target->num_lun;
- scsi_probe_bus(sc_bus,
- target->target_id, sdev->lun_id);
- sdev->periph = scsipi_lookup_periph(
- chan, target->target_id, lun);
+ scsi_probe_bus(sc_bus, target->target_id,
+ sdev->lun_id);
+ sdev->periph = scsipi_lookup_periph(chan,
+ target->target_id, lun);
}
sdev->status = SBP_DEV_ATTACHED;
}
} while (yet > 0);
- sbp->lwp = NULL;
+ sc->sc_lwp = NULL;
kthread_exit(0);
+
+ /* NOTREACHED */
}
static inline void
sbp_scan_dev(struct sbp_dev *sdev)
{
+ struct sbp_softc *sc = sdev->target->sbp;
+
sdev->status = SBP_DEV_PROBE;
- wakeup(sdev->target);
+ mutex_enter(&sc->sc_mtx);
+ cv_signal(&sdev->target->sbp->sc_cv);
+ mutex_exit(&sc->sc_mtx);
}
-#endif
static void
@@ -1265,35 +1177,18 @@ sbp_do_attach(struct fw_xfer *xfer)
{
struct sbp_dev *sdev;
struct sbp_target *target;
- struct sbp_softc *sbp;
+ struct sbp_softc *sc;
sdev = (struct sbp_dev *)xfer->sc;
target = sdev->target;
- sbp = target->sbp;
+ sc = target->sbp;
SBP_DEBUG(0)
- sbp_show_sdev_info(sdev, 2);
- printf("sbp_do_attach\n");
+ printf("%s:%s:%s\n", device_xname(sc->sc_fd.dev), __func__,
+ sdev->bustgtlun);
END_DEBUG
sbp_xfer_free(xfer);
-#if defined(__FreeBSD__)
- if (sdev->path == NULL)
- xpt_create_path(&sdev->path, xpt_periph,
- cam_sim_path(target->sbp->sim),
- target->target_id, sdev->lun_id);
-
- /*
- * Let CAM scan the bus if we are in the boot process.
- * XXX xpt_scan_bus cannot detect LUN larger than 0
- * if LUN 0 doesn't exists.
- */
- if (sbp_cold > 0) {
- sdev->status = SBP_DEV_ATTACHED;
- return;
- }
-#endif
-
sbp_scan_dev(sdev);
return;
}
@@ -1301,24 +1196,22 @@ END_DEBUG
static void
sbp_agent_reset_callback(struct fw_xfer *xfer)
{
- struct sbp_dev *sdev;
+ struct sbp_dev *sdev = (struct sbp_dev *)xfer->sc;
+ struct sbp_softc *sc = sdev->target->sbp;
- sdev = (struct sbp_dev *)xfer->sc;
SBP_DEBUG(1)
- sbp_show_sdev_info(sdev, 2);
- printf("%s\n", __func__);
+ printf("%s:%s:%s\n", device_xname(sc->sc_fd.dev), __func__,
+ sdev->bustgtlun);
END_DEBUG
- if (xfer->resp != 0) {
- sbp_show_sdev_info(sdev, 2);
- printf("%s: resp=%d\n", __func__, xfer->resp);
- }
+ if (xfer->resp != 0)
+ aprint_error_dev(sc->sc_fd.dev, "%s:%s: resp=%d\n", __func__,
+ sdev->bustgtlun, xfer->resp);
sbp_xfer_free(xfer);
- if (SBP_DEVICE(sdev)) {
- SBP_LOCK(sdev->target->sbp);
- SBP_DEVICE_THAW(sdev, sdev->freeze);
+ if (sdev->periph != NULL) {
+ scsipi_periph_thaw(sdev->periph, sdev->freeze);
+ scsipi_channel_thaw(&sc->sc_channel, 0);
sdev->freeze = 0;
- SBP_UNLOCK(sdev->target->sbp);
}
}
@@ -1329,8 +1222,8 @@ sbp_agent_reset(struct sbp_dev *sdev)
struct fw_pkt *fp;
SBP_DEBUG(0)
- sbp_show_sdev_info(sdev, 2);
- printf("sbp_agent_reset\n");
+ printf("%s:%s:%s\n", device_xname(sdev->target->sbp->sc_fd.dev),
+ __func__, sdev->bustgtlun);
END_DEBUG
xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x04);
if (xfer == NULL)
@@ -1341,19 +1234,19 @@ END_DEBUG
xfer->hand = sbp_do_attach;
fp = &xfer->send.hdr;
fp->mode.wreqq.data = htonl(0xf);
- fw_asyreq(xfer->fc, -1, xfer);
- sbp_abort_all_ocbs(sdev, XS_BDR_SENT);
+ if (fw_asyreq(xfer->fc, -1, xfer) != 0)
+ sbp_xfer_free(xfer);
+ sbp_abort_all_ocbs(sdev, XS_RESET);
}
static void
sbp_busy_timeout_callback(struct fw_xfer *xfer)
{
- struct sbp_dev *sdev;
+ struct sbp_dev *sdev = (struct sbp_dev *)xfer->sc;
- sdev = (struct sbp_dev *)xfer->sc;
SBP_DEBUG(1)
- sbp_show_sdev_info(sdev, 2);
- printf("sbp_busy_timeout_callback\n");
+ printf("%s:%s:%s\n", device_xname(sdev->target->sbp->sc_fd.dev),
+ __func__, sdev->bustgtlun);
END_DEBUG
sbp_xfer_free(xfer);
sbp_agent_reset(sdev);
@@ -1364,34 +1257,36 @@ sbp_busy_timeout(struct sbp_dev *sdev)
{
struct fw_pkt *fp;
struct fw_xfer *xfer;
+
SBP_DEBUG(0)
- sbp_show_sdev_info(sdev, 2);
- printf("sbp_busy_timeout\n");
+ printf("%s:%s:%s\n", device_xname(sdev->target->sbp->sc_fd.dev),
+ __func__, sdev->bustgtlun);
END_DEBUG
xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0);
-
+ if (xfer == NULL)
+ return;
xfer->hand = sbp_busy_timeout_callback;
fp = &xfer->send.hdr;
fp->mode.wreqq.dest_hi = 0xffff;
fp->mode.wreqq.dest_lo = 0xf0000000 | BUSY_TIMEOUT;
fp->mode.wreqq.data = htonl((1 << (13+12)) | 0xf);
- fw_asyreq(xfer->fc, -1, xfer);
+ if (fw_asyreq(xfer->fc, -1, xfer) != 0)
+ sbp_xfer_free(xfer);
}
static void
sbp_orb_pointer_callback(struct fw_xfer *xfer)
{
- struct sbp_dev *sdev;
- sdev = (struct sbp_dev *)xfer->sc;
+ struct sbp_dev *sdev = (struct sbp_dev *)xfer->sc;
+ struct sbp_softc *sc = sdev->target->sbp;
SBP_DEBUG(1)
- sbp_show_sdev_info(sdev, 2);
- printf("%s\n", __func__);
+ printf("%s:%s:%s\n", device_xname(sc->sc_fd.dev), __func__,
+ sdev->bustgtlun);
END_DEBUG
- if (xfer->resp != 0) {
- /* XXX */
- printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
- }
+ if (xfer->resp != 0)
+ aprint_error_dev(sc->sc_fd.dev, "%s:%s: xfer->resp = %d\n",
+ __func__, sdev->bustgtlun, xfer->resp);
sbp_xfer_free(xfer);
sdev->flags &= ~ORB_POINTER_ACTIVE;
@@ -1409,11 +1304,13 @@ END_DEBUG
static void
sbp_orb_pointer(struct sbp_dev *sdev, struct sbp_ocb *ocb)
{
+ struct sbp_softc *sc = sdev->target->sbp;
struct fw_xfer *xfer;
struct fw_pkt *fp;
+
SBP_DEBUG(1)
- sbp_show_sdev_info(sdev, 2);
- printf("%s: 0x%08x\n", __func__, (uint32_t)ocb->bus_addr);
+ printf("%s:%s:%s: 0x%08x\n", device_xname(sc->sc_fd.dev), __func__,
+ sdev->bustgtlun, (uint32_t)ocb->bus_addr);
END_DEBUG
if ((sdev->flags & ORB_POINTER_ACTIVE) != 0) {
@@ -1433,30 +1330,30 @@ END_DEBUG
fp = &xfer->send.hdr;
fp->mode.wreqb.len = 8;
fp->mode.wreqb.extcode = 0;
- xfer->send.payload[0] =
- htonl(((sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS )<< 16));
+ xfer->send.payload[0] =
+ htonl(((sc->sc_fd.fc->nodeid | FWLOCALBUS) << 16));
xfer->send.payload[1] = htonl((uint32_t)ocb->bus_addr);
- if(fw_asyreq(xfer->fc, -1, xfer) != 0){
- sbp_xfer_free(xfer);
- SCSI_XFER_ERROR(ocb->sxfer) = XS_REQ_INVALID;
- SCSI_TRANSFER_DONE(ocb->sxfer);
+ if (fw_asyreq(xfer->fc, -1, xfer) != 0) {
+ sbp_xfer_free(xfer);
+ ocb->xs->error = XS_DRIVER_STUFFUP;
+ scsipi_done(ocb->xs);
}
}
static void
sbp_doorbell_callback(struct fw_xfer *xfer)
{
- struct sbp_dev *sdev;
- sdev = (struct sbp_dev *)xfer->sc;
+ struct sbp_dev *sdev = (struct sbp_dev *)xfer->sc;
+ struct sbp_softc *sc = sdev->target->sbp;
SBP_DEBUG(1)
- sbp_show_sdev_info(sdev, 2);
- printf("sbp_doorbell_callback\n");
+ printf("%s:%s:%s\n", device_xname(sc->sc_fd.dev), __func__,
+ sdev->bustgtlun);
END_DEBUG
if (xfer->resp != 0) {
- /* XXX */
- printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
+ aprint_error_dev(sc->sc_fd.dev, "%s: xfer->resp = %d\n",
+ __func__, xfer->resp);
}
sbp_xfer_free(xfer);
sdev->flags &= ~ORB_DOORBELL_ACTIVE;
@@ -1472,9 +1369,10 @@ sbp_doorbell(struct sbp_dev *sdev)
{
struct fw_xfer *xfer;
struct fw_pkt *fp;
+
SBP_DEBUG(1)
- sbp_show_sdev_info(sdev, 2);
- printf("sbp_doorbell\n");
+ printf("%s:%s:%s\n", device_xname(sdev->target->sbp->sc_fd.dev),
+ __func__, sdev->bustgtlun);
END_DEBUG
if ((sdev->flags & ORB_DOORBELL_ACTIVE) != 0) {
@@ -1488,47 +1386,52 @@ END_DEBUG
xfer->hand = sbp_doorbell_callback;
fp = &xfer->send.hdr;
fp->mode.wreqq.data = htonl(0xf);
- fw_asyreq(xfer->fc, -1, xfer);
+ if (fw_asyreq(xfer->fc, -1, xfer) != 0)
+ sbp_xfer_free(xfer);
}
static struct fw_xfer *
sbp_write_cmd(struct sbp_dev *sdev, int tcode, int offset)
{
+ struct sbp_softc *sc;
struct fw_xfer *xfer;
struct fw_pkt *fp;
struct sbp_target *target;
- int s, new = 0;
+ int new = 0;
target = sdev->target;
- s = splfw();
+ sc = target->sbp;
+ mutex_enter(&sc->sc_mtx);
xfer = STAILQ_FIRST(&target->xferlist);
if (xfer == NULL) {
if (target->n_xfer > 5 /* XXX */) {
- printf("sbp: no more xfer for this target\n");
- splx(s);
- return(NULL);
+ aprint_error_dev(sc->sc_fd.dev,
+ "no more xfer for this target\n");
+ mutex_exit(&sc->sc_mtx);
+ return NULL;
}
xfer = fw_xfer_alloc_buf(M_SBP, 8, 0);
- if(xfer == NULL){
- printf("sbp: fw_xfer_alloc_buf failed\n");
- splx(s);
+ if (xfer == NULL) {
+ aprint_error_dev(sc->sc_fd.dev,
+ "fw_xfer_alloc_buf failed\n");
+ mutex_exit(&sc->sc_mtx);
return NULL;
}
- target->n_xfer ++;
- if (debug)
+ target->n_xfer++;
+SBP_DEBUG(0)
printf("sbp: alloc %d xfer\n", target->n_xfer);
+END_DEBUG
new = 1;
- } else {
+ } else
STAILQ_REMOVE_HEAD(&target->xferlist, link);
- }
- splx(s);
+ mutex_exit(&sc->sc_mtx);
microtime(&xfer->tv);
if (new) {
xfer->recv.pay_len = 0;
- xfer->send.spd = min(sdev->target->fwdev->speed, max_speed);
- xfer->fc = sdev->target->sbp->fd.fc;
+ xfer->send.spd = min(target->fwdev->speed, max_speed);
+ xfer->fc = target->sbp->sc_fd.fc;
}
if (tcode == FWTCODE_WREQB)
@@ -1543,7 +1446,7 @@ sbp_write_cmd(struct sbp_dev *sdev, int tcode, int offset)
fp->mode.wreqq.tlrt = 0;
fp->mode.wreqq.tcode = tcode;
fp->mode.wreqq.pri = 0;
- fp->mode.wreqq.dst = FWLOCALBUS | sdev->target->fwdev->dst;
+ fp->mode.wreqq.dst = FWLOCALBUS | target->fwdev->dst;
return xfer;
}
@@ -1555,32 +1458,29 @@ sbp_mgm_orb(struct sbp_dev *sdev, int func, struct sbp_ocb *aocb)
struct fw_pkt *fp;
struct sbp_ocb *ocb;
struct sbp_target *target;
- int s, nid, dv_unit;
+ int nid, dv_unit;
target = sdev->target;
- nid = target->sbp->fd.fc->nodeid | FWLOCALBUS;
- dv_unit = fw_get_unit(target->sbp->fd.dev);
+ nid = target->sbp->sc_fd.fc->nodeid | FWLOCALBUS;
+ dv_unit = device_unit(target->sbp->sc_fd.dev);
- s = splfw();
- SBP_LOCK(target->sbp);
+ mutex_enter(&target->sbp->sc_mtx);
if (func == ORB_FUN_RUNQUEUE) {
ocb = STAILQ_FIRST(&target->mgm_ocb_queue);
if (target->mgm_ocb_cur != NULL || ocb == NULL) {
- SBP_UNLOCK(target->sbp);
- splx(s);
+ mutex_exit(&target->sbp->sc_mtx);
return;
}
STAILQ_REMOVE_HEAD(&target->mgm_ocb_queue, ocb);
- SBP_UNLOCK(target->sbp);
+ mutex_exit(&target->sbp->sc_mtx);
goto start;
}
if ((ocb = sbp_get_ocb(sdev)) == NULL) {
- SBP_UNLOCK(target->sbp);
- splx(s);
+ mutex_exit(&target->sbp->sc_mtx);
/* XXX */
return;
}
- SBP_UNLOCK(target->sbp);
+ mutex_exit(&target->sbp->sc_mtx);
ocb->flags = OCB_ACT_MGM;
ocb->sdev = sdev;
@@ -1589,19 +1489,27 @@ sbp_mgm_orb(struct sbp_dev *sdev, int func, struct sbp_ocb *aocb)
ocb->orb[7] = htonl(SBP_DEV2ADDR(dv_unit, sdev->lun_id));
SBP_DEBUG(0)
- sbp_show_sdev_info(sdev, 2);
- printf("%s\n", orb_fun_name[(func>>16)&0xf]);
+ printf("%s:%s:%s: %s\n", device_xname(sdev->target->sbp->sc_fd.dev),
+ __func__, sdev->bustgtlun, orb_fun_name[(func>>16)&0xf]);
END_DEBUG
switch (func) {
case ORB_FUN_LGI:
+ {
+ const off_t sbp_login_off =
+ sizeof(struct sbp_ocb) * SBP_QUEUE_LEN;
+
ocb->orb[0] = ocb->orb[1] = 0; /* password */
ocb->orb[2] = htonl(nid << 16);
- ocb->orb[3] = htonl(sdev->dma.bus_addr);
+ ocb->orb[3] = htonl(sdev->dma.bus_addr + sbp_login_off);
ocb->orb[4] = htonl(ORB_NOTIFY | sdev->lun_id);
if (ex_login)
ocb->orb[4] |= htonl(ORB_EXV);
ocb->orb[5] = htonl(SBP_LOGIN_SIZE);
+ bus_dmamap_sync(sdev->dma.dma_tag, sdev->dma.dma_map,
+ sbp_login_off, SBP_LOGIN_SIZE, BUS_DMASYNC_PREREAD);
break;
+ }
+
case ORB_FUN_ATA:
ocb->orb[0] = htonl((0 << 16) | 0);
ocb->orb[1] = htonl(aocb->bus_addr & 0xffffffff);
@@ -1617,22 +1525,18 @@ END_DEBUG
if (target->mgm_ocb_cur != NULL) {
/* there is a standing ORB */
- SBP_LOCK(target->sbp);
+ mutex_enter(&target->sbp->sc_mtx);
STAILQ_INSERT_TAIL(&sdev->target->mgm_ocb_queue, ocb, ocb);
- SBP_UNLOCK(target->sbp);
- splx(s);
+ mutex_exit(&target->sbp->sc_mtx);
return;
}
start:
target->mgm_ocb_cur = ocb;
- splx(s);
- fw_callout_reset(&target->mgm_ocb_timeout, 5*hz,
- sbp_mgm_timeout, (void *)ocb);
+ callout_reset(&target->mgm_ocb_timeout, 5 * hz, sbp_mgm_timeout, ocb);
xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0);
- if(xfer == NULL){
+ if (xfer == NULL)
return;
- }
xfer->hand = sbp_mgm_callback;
fp = &xfer->send.hdr;
@@ -1642,35 +1546,33 @@ start:
fp->mode.wreqb.extcode = 0;
xfer->send.payload[0] = htonl(nid << 16);
xfer->send.payload[1] = htonl(ocb->bus_addr & 0xffffffff);
-SBP_DEBUG(0)
- sbp_show_sdev_info(sdev, 2);
- printf("mgm orb: %08x\n", (uint32_t)ocb->bus_addr);
-END_DEBUG
/* cache writeback & invalidate(required ORB_FUN_LGI func) */
/* when abort_ocb, should sync POST ope ? */
- fwdma_sync(&sdev->dma, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- fw_asyreq(xfer->fc, -1, xfer);
+ SBP_ORB_DMA_SYNC(sdev->dma, ocb->index, BUS_DMASYNC_PREWRITE);
+ if (fw_asyreq(xfer->fc, -1, xfer) != 0)
+ sbp_xfer_free(xfer);
}
static void
sbp_print_scsi_cmd(struct sbp_ocb *ocb)
{
-#if defined(__FreeBSD__)
- struct ccb_scsiio *csio;
+ struct scsipi_xfer *xs = ocb->xs;
- csio = &ocb->sxfer->csio;
-#endif
- printf("%s:%d:%d XPT_SCSI_IO: "
- "cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
- ", flags: 0x%02x, "
- "%db cmd/%db data/%db sense\n",
- fw_get_nameunit(ocb->sdev->target->sbp->fd.dev),
- SCSI_XFER_TARGET(ocb->sxfer), SCSI_XFER_LUN(ocb->sxfer),
- SCSI_XFER_10BCMD_DUMP(ocb->sxfer),
- SCSI_XFER_DIR(ocb->sxfer),
- SCSI_XFER_CMDLEN(ocb->sxfer), SCSI_XFER_DATALEN(ocb->sxfer),
- SCSI_XFER_SENSELEN(ocb->sxfer));
+ printf("%s:%d:%d:"
+ " cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x,"
+ " flags: 0x%02x, %db cmd/%db data\n",
+ device_xname(ocb->sdev->target->sbp->sc_fd.dev),
+ xs->xs_periph->periph_target,
+ xs->xs_periph->periph_lun,
+ xs->cmd->opcode,
+ xs->cmd->bytes[0], xs->cmd->bytes[1],
+ xs->cmd->bytes[2], xs->cmd->bytes[3],
+ xs->cmd->bytes[4], xs->cmd->bytes[5],
+ xs->cmd->bytes[6], xs->cmd->bytes[7],
+ xs->cmd->bytes[8],
+ xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT),
+ xs->cmdlen, xs->datalen);
}
static void
@@ -1678,48 +1580,47 @@ sbp_scsi_status(struct sbp_status *sbp_status, struct sbp_ocb *ocb)
{
struct sbp_cmd_status *sbp_cmd_status;
scsi3_sense_data_t sense =
- (scsi3_sense_data_t)SCSI_SENSE_DATA(ocb->sxfer);
+ (scsi3_sense_data_t)&ocb->xs->sense.scsi_sense;
sbp_cmd_status = (struct sbp_cmd_status *)sbp_status->data;
SBP_DEBUG(0)
sbp_print_scsi_cmd(ocb);
/* XXX need decode status */
- sbp_show_sdev_info(ocb->sdev, 2);
- printf("SCSI status %x sfmt %x valid %x key %x code %x qlfr %x len %d\n",
- sbp_cmd_status->status,
- sbp_cmd_status->sfmt,
- sbp_cmd_status->valid,
- sbp_cmd_status->s_key,
- sbp_cmd_status->s_code,
- sbp_cmd_status->s_qlfr,
- sbp_status->len
- );
+ printf("%s:"
+ " SCSI status %x sfmt %x valid %x key %x code %x qlfr %x len %d\n",
+ ocb->sdev->bustgtlun,
+ sbp_cmd_status->status,
+ sbp_cmd_status->sfmt,
+ sbp_cmd_status->valid,
+ sbp_cmd_status->s_key,
+ sbp_cmd_status->s_code,
+ sbp_cmd_status->s_qlfr,
+ sbp_status->len);
END_DEBUG
switch (sbp_cmd_status->status) {
- case SCSI_STATUS_CHECK_COND:
- case SCSI_STATUS_BUSY:
- case SCSI_STATUS_CMD_TERMINATED:
- if(sbp_cmd_status->sfmt == SBP_SFMT_CURR){
- sense->response_code = SSD_CURRENT_ERROR;
- }else{
- sense->response_code = SSD_DEFERRED_ERROR;
- }
- if(sbp_cmd_status->valid)
+ case SCSI_CHECK:
+ case SCSI_BUSY:
+ case SCSI_TERMINATED:
+ if (sbp_cmd_status->sfmt == SBP_SFMT_CURR)
+ sense->response_code = SSD_RCODE_CURRENT;
+ else
+ sense->response_code = SSD_RCODE_DEFERRED;
+ if (sbp_cmd_status->valid)
sense->response_code |= SSD_RESPONSE_CODE_VALID;
sense->flags = sbp_cmd_status->s_key;
- if(sbp_cmd_status->mark)
+ if (sbp_cmd_status->mark)
sense->flags |= SSD_FILEMARK;
- if(sbp_cmd_status->eom)
+ if (sbp_cmd_status->eom)
sense->flags |= SSD_EOM;
- if(sbp_cmd_status->ill_len)
+ if (sbp_cmd_status->ill_len)
sense->flags |= SSD_ILI;
- memcpy(&sense->information[0], &sbp_cmd_status->info, 4);
+ memcpy(sense->information, &sbp_cmd_status->info, 4);
if (sbp_status->len <= 1)
- /* XXX not scsi status. shouldn't be happened */
+ /* XXX not scsi status. shouldn't be happened */
sense->asl = 0;
else if (sbp_status->len <= 4)
/* add_sense_code(_qual), info, cmd_spec_info */
@@ -1728,62 +1629,69 @@ END_DEBUG
/* fru, sense_key_spec */
sense->asl = 10;
- memcpy(&sense->csi[0], &sbp_cmd_status->cdb, 4);
+ memcpy(sense->csi, &sbp_cmd_status->cdb, 4);
sense->asc = sbp_cmd_status->s_code;
sense->ascq = sbp_cmd_status->s_qlfr;
sense->fruc = sbp_cmd_status->fru;
- memcpy(&sense->sks[0], &sbp_cmd_status->s_keydep[0], 3);
- SCSI_XFER_ERROR(ocb->sxfer) = XS_SENSE;
- SCSI_XFER_STATUS(ocb->sxfer) = sbp_cmd_status->status;
+ memcpy(sense->sks, sbp_cmd_status->s_keydep, 3);
+ ocb->xs->error = XS_SENSE;
+ ocb->xs->xs_status = sbp_cmd_status->status;
/*
{
uint8_t j, *tmp;
tmp = sense;
- for( j = 0 ; j < 32 ; j+=8){
- printf("sense %02x%02x %02x%02x %02x%02x %02x%02x\n",
- tmp[j], tmp[j+1], tmp[j+2], tmp[j+3],
- tmp[j+4], tmp[j+5], tmp[j+6], tmp[j+7]);
- }
+ for (j = 0; j < 32; j += 8)
+ aprint_normal(
+ "sense %02x%02x %02x%02x %02x%02x %02x%02x\n",
+ tmp[j], tmp[j+1], tmp[j+2], tmp[j+3],
+ tmp[j+4], tmp[j+5], tmp[j+6], tmp[j+7]);
}
*/
break;
default:
- sbp_show_sdev_info(ocb->sdev, 2);
- printf("sbp_scsi_status: unknown scsi status 0x%x\n",
- sbp_cmd_status->status);
+ aprint_error_dev(ocb->sdev->target->sbp->sc_fd.dev,
+ "%s:%s: unknown scsi status 0x%x\n",
+ __func__, ocb->sdev->bustgtlun, sbp_cmd_status->status);
}
}
static void
sbp_fix_inq_data(struct sbp_ocb *ocb)
{
- sbp_scsi_xfer *sxfer = ocb->sxfer;
+ struct scsipi_xfer *xs = ocb->xs;
struct sbp_dev *sdev;
- scsi3_inquiry_data_t inq =
- (scsi3_inquiry_data_t)SCSI_INQUIRY_DATA(sxfer);
+ scsi3_inquiry_data_t inq = (scsi3_inquiry_data_t)xs->data;
+
sdev = ocb->sdev;
- if (SCSI_XFER_EVPD(sxfer))
+#if 0
+/*
+ * NetBSD is assuming always 0 for EVPD-bit and 'Page Code'.
+ */
+#define SI_EVPD 0x01
+ if (xs->cmd->bytes[0] & SI_EVPD)
return;
+#endif
SBP_DEBUG(1)
- sbp_show_sdev_info(sdev, 2);
- printf("sbp_fix_inq_data\n");
+ printf("%s:%s:%s\n", device_xname(sdev->target->sbp->sc_fd.dev),
+ __func__, sdev->bustgtlun);
END_DEBUG
switch (inq->device & SID_TYPE) {
case T_DIRECT:
#if 0
- /*
+ /*
* XXX Convert Direct Access device to RBC.
* I've never seen FireWire DA devices which support READ_6.
*/
if ((inq->device & SID_TYPE) == T_DIRECT)
- inq->device |= T_RBC; /* T_DIRECT == 0 */
+ inq->device |= T_SIMPLE_DIRECT; /* T_DIRECT == 0 */
#endif
- /* fall through */
- case T_RBC:
+ /* FALLTHROUGH */
+
+ case T_SIMPLE_DIRECT:
/*
* Override vendor/product/revision information.
* Some devices sometimes return strange strings.
@@ -1791,7 +1699,8 @@ END_DEBUG
#if 1
memcpy(inq->vendor, sdev->vendor, sizeof(inq->vendor));
memcpy(inq->product, sdev->product, sizeof(inq->product));
- memcpy(inq->revision, sdev->revision+2, sizeof(inq->revision));
+ memcpy(inq->revision + 2, sdev->revision,
+ sizeof(inq->revision));
#endif
break;
}
@@ -1807,13 +1716,13 @@ END_DEBUG
}
static void
-sbp_recv1(struct fw_xfer *xfer)
+sbp_recv(struct fw_xfer *xfer)
{
struct fw_pkt *rfp;
#if NEED_RESPONSE
struct fw_pkt *sfp;
#endif
- struct sbp_softc *sbp;
+ struct sbp_softc *sc;
struct sbp_dev *sdev;
struct sbp_ocb *ocb;
struct sbp_login_res *login_res = NULL;
@@ -1829,18 +1738,22 @@ printf("sbp %x %d %d %08x %08x %08x %08x\n",
printf("sbp %08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
printf("sbp %08x %08x %08x %08x\n", ntohl(ld[8]), ntohl(ld[9]), ntohl(ld[10]), ntohl(ld[11]));
*/
- sbp = (struct sbp_softc *)xfer->sc;
- if (xfer->resp != 0){
- printf("sbp_recv: xfer->resp = %d\n", xfer->resp);
+
+ sc = (struct sbp_softc *)xfer->sc;
+ if (xfer->resp != 0) {
+ aprint_error_dev(sc->sc_fd.dev,
+ "sbp_recv: xfer->resp = %d\n", xfer->resp);
goto done0;
}
- if (xfer->recv.payload == NULL){
- printf("sbp_recv: xfer->recv.payload == NULL\n");
+ if (xfer->recv.payload == NULL) {
+ aprint_error_dev(sc->sc_fd.dev,
+ "sbp_recv: xfer->recv.payload == NULL\n");
goto done0;
}
rfp = &xfer->recv.hdr;
- if(rfp->mode.wreqb.tcode != FWTCODE_WREQB){
- printf("sbp_recv: tcode = %d\n", rfp->mode.wreqb.tcode);
+ if (rfp->mode.wreqb.tcode != FWTCODE_WREQB) {
+ aprint_error_dev(sc->sc_fd.dev,
+ "sbp_recv: tcode = %d\n", rfp->mode.wreqb.tcode);
goto done0;
}
sbp_status = (struct sbp_status *)xfer->recv.payload;
@@ -1848,51 +1761,44 @@ printf("sbp %08x %08x %08x %08x\n", ntohl(ld[8]), ntohl(ld[9]), ntohl(ld[10]), n
SBP_DEBUG(2)
printf("received address 0x%x\n", addr);
END_DEBUG
- target = &sbp->target;
+ target = &sc->sc_target;
l = SBP_ADDR2LUN(addr);
if (l >= target->num_lun || target->luns[l] == NULL) {
- fw_printf(sbp->fd.dev,
+ aprint_error_dev(sc->sc_fd.dev,
"sbp_recv1: invalid lun %d (target=%d)\n",
l, target->target_id);
goto done0;
}
sdev = target->luns[l];
- fwdma_sync(&sdev->dma, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
-
ocb = NULL;
switch (sbp_status->src) {
case SRC_NEXT_EXISTS:
case SRC_NO_NEXT:
/* check mgm_ocb_cur first */
- ocb = target->mgm_ocb_cur;
- if (ocb != NULL) {
+ ocb = target->mgm_ocb_cur;
+ if (ocb != NULL)
if (OCB_MATCH(ocb, sbp_status)) {
- fw_callout_stop(&target->mgm_ocb_timeout);
+ callout_stop(&target->mgm_ocb_timeout);
target->mgm_ocb_cur = NULL;
break;
}
- }
ocb = sbp_dequeue_ocb(sdev, sbp_status);
- if (ocb == NULL) {
- sbp_show_sdev_info(sdev, 2);
-#if defined(__DragonFly__) || \
- (defined(__FreeBSD__) && __FreeBSD_version < 500000)
- printf("No ocb(%lx) on the queue\n",
-#else
- printf("No ocb(%x) on the queue\n",
-#endif
- ntohl(sbp_status->orb_lo));
- }
+ if (ocb == NULL)
+ aprint_error_dev(sc->sc_fd.dev,
+ "%s:%s: No ocb(%x) on the queue\n", __func__,
+ sdev->bustgtlun, ntohl(sbp_status->orb_lo));
break;
case SRC_UNSOL:
/* unsolicit */
- sbp_show_sdev_info(sdev, 2);
- printf("unsolicit status received\n");
+ aprint_error_dev(sc->sc_fd.dev,
+ "%s:%s: unsolicit status received\n",
+ __func__, sdev->bustgtlun);
break;
default:
- sbp_show_sdev_info(sdev, 2);
- printf("unknown sbp_status->src\n");
+ aprint_error_dev(sc->sc_fd.dev,
+ "%s:%s: unknown sbp_status->src\n",
+ __func__, sdev->bustgtlun);
}
status_valid0 = (sbp_status->src < 2
@@ -1900,22 +1806,17 @@ END_DEBUG
&& sbp_status->dead == 0);
status_valid = (status_valid0 && sbp_status->status == 0);
- if (!status_valid0 || debug > 2){
+ if (!status_valid0 || debug > 2) {
int status;
SBP_DEBUG(0)
- sbp_show_sdev_info(sdev, 2);
- printf("ORB status src:%x resp:%x dead:%x"
-#if defined(__DragonFly__) || \
- (defined(__FreeBSD__) && __FreeBSD_version < 500000)
- " len:%x stat:%x orb:%x%08lx\n",
-#else
- " len:%x stat:%x orb:%x%08x\n",
-#endif
- sbp_status->src, sbp_status->resp, sbp_status->dead,
- sbp_status->len, sbp_status->status,
- ntohs(sbp_status->orb_hi), ntohl(sbp_status->orb_lo));
+ printf("%s:%s:%s: ORB status src:%x resp:%x dead:%x"
+ " len:%x stat:%x orb:%x%08x\n",
+ device_xname(sc->sc_fd.dev), __func__, sdev->bustgtlun,
+ sbp_status->src, sbp_status->resp, sbp_status->dead,
+ sbp_status->len, sbp_status->status,
+ ntohs(sbp_status->orb_hi), ntohl(sbp_status->orb_lo));
END_DEBUG
- sbp_show_sdev_info(sdev, 2);
+ printf("%s:%s\n", device_xname(sc->sc_fd.dev), sdev->bustgtlun);
status = sbp_status->status;
switch(sbp_status->resp) {
case SBP_REQ_CMP:
@@ -1926,8 +1827,8 @@ END_DEBUG
break;
case SBP_TRANS_FAIL:
printf("Obj: %s, Error: %s\n",
- orb_status1_object[(status>>6) & 3],
- orb_status1_serial_bus_error[status & 0xf]);
+ orb_status1_object[(status>>6) & 3],
+ orb_status1_serial_bus_error[status & 0xf]);
break;
case SBP_ILLE_REQ:
printf("Illegal request\n");
@@ -1942,11 +1843,9 @@ END_DEBUG
/* we have to reset the fetch agent if it's dead */
if (sbp_status->dead) {
- if (SBP_DEVICE(sdev) != NULL) {
- SBP_LOCK(sbp);
- SBP_DEVICE_FREEZE(sdev, 1);
- sdev->freeze ++;
- SBP_UNLOCK(sbp);
+ if (sdev->periph != NULL) {
+ scsipi_periph_freeze(sdev->periph, 1);
+ sdev->freeze++;
}
reset_agent = 1;
}
@@ -1954,7 +1853,7 @@ END_DEBUG
if (ocb == NULL)
goto done;
- switch(ntohl(ocb->orb[4]) & ORB_FMT_MSK){
+ switch(ntohl(ocb->orb[4]) & ORB_FMT_MSK) {
case ORB_FMT_NOP:
break;
case ORB_FMT_VED:
@@ -1966,6 +1865,14 @@ END_DEBUG
reset_agent = 0;
switch(orb_fun) {
case ORB_FUN_LGI:
+ {
+ const struct fwdma_alloc *dma = &sdev->dma;
+ const off_t sbp_login_off =
+ sizeof(struct sbp_ocb) * SBP_QUEUE_LEN;
+
+ bus_dmamap_sync(dma->dma_tag, dma->dma_map,
+ sbp_login_off, SBP_LOGIN_SIZE,
+ BUS_DMASYNC_POSTREAD);
login_res = sdev->login;
login_res->len = ntohs(login_res->len);
login_res->id = ntohs(login_res->id);
@@ -1973,40 +1880,45 @@ END_DEBUG
login_res->cmd_lo = ntohl(login_res->cmd_lo);
if (status_valid) {
SBP_DEBUG(0)
-sbp_show_sdev_info(sdev, 2);
-printf("login: len %d, ID %d, cmd %08x%08x, recon_hold %d\n", login_res->len, login_res->id, login_res->cmd_hi, login_res->cmd_lo, ntohs(login_res->recon_hold));
+ printf("%s:%s:%s: login:"
+ " len %d, ID %d, cmd %08x%08x,"
+ " recon_hold %d\n",
+ device_xname(sc->sc_fd.dev),
+ __func__, sdev->bustgtlun,
+ login_res->len, login_res->id,
+ login_res->cmd_hi,
+ login_res->cmd_lo,
+ ntohs(login_res->recon_hold));
END_DEBUG
sbp_busy_timeout(sdev);
} else {
/* forgot logout? */
- sbp_show_sdev_info(sdev, 2);
- printf("login failed\n");
+ aprint_error_dev(sc->sc_fd.dev,
+ "%s:%s: login failed\n",
+ __func__, sdev->bustgtlun);
sdev->status = SBP_DEV_RESET;
}
break;
+ }
case ORB_FUN_RCN:
login_res = sdev->login;
if (status_valid) {
SBP_DEBUG(0)
-sbp_show_sdev_info(sdev, 2);
-printf("reconnect: len %d, ID %d, cmd %08x%08x\n", login_res->len, login_res->id, login_res->cmd_hi, login_res->cmd_lo);
+ printf("%s:%s:%s: reconnect:"
+ " len %d, ID %d, cmd %08x%08x\n",
+ device_xname(sc->sc_fd.dev),
+ __func__, sdev->bustgtlun,
+ login_res->len, login_res->id,
+ login_res->cmd_hi,
+ login_res->cmd_lo);
END_DEBUG
-#if 1
-#if defined(__FreeBSD__)
- if (sdev->status == SBP_DEV_ATTACHED)
- sbp_scan_dev(sdev);
- else
-#endif
- sbp_agent_reset(sdev);
-#else
- sdev->status = SBP_DEV_ATTACHED;
- sbp_mgm_orb(sdev, ORB_FUN_ATS, NULL);
-#endif
+ sbp_agent_reset(sdev);
} else {
/* reconnection hold time exceed? */
SBP_DEBUG(0)
- sbp_show_sdev_info(sdev, 2);
- printf("reconnect failed\n");
+ aprint_error_dev(sc->sc_fd.dev,
+ "%s:%s: reconnect failed\n",
+ __func__, sdev->bustgtlun);
END_DEBUG
sbp_login(sdev);
}
@@ -2023,44 +1935,31 @@ END_DEBUG
sbp_agent_reset(sdev);
break;
default:
- sbp_show_sdev_info(sdev, 2);
- printf("unknown function %d\n", orb_fun);
+ aprint_error_dev(sc->sc_fd.dev,
+ "%s:%s: unknown function %d\n",
+ __func__, sdev->bustgtlun, orb_fun);
break;
}
sbp_mgm_orb(sdev, ORB_FUN_RUNQUEUE, NULL);
break;
case OCB_ACT_CMD:
sdev->timeout = 0;
- if(ocb->sxfer != NULL){
- sbp_scsi_xfer *sxfer = ocb->sxfer;
-/*
- uint32_t *ld = SCSI_XFER_DATA(ocb->sxfer);
- if(ld != NULL &&
- SCSI_XFER_DATALEN(ocb->sxfer) != 0)
- printf("ptr %08x %08x %08x %08x\n", ld[0], ld[1], ld[2], ld[3]);
- else
- printf("ptr NULL\n");
-printf("len %d\n", sbp_status->len);
-*/
- if(sbp_status->len > 1){
+ if (ocb->xs != NULL) {
+ struct scsipi_xfer *xs = ocb->xs;
+
+ if (sbp_status->len > 1)
sbp_scsi_status(sbp_status, ocb);
- }else{
- if(sbp_status->resp != SBP_REQ_CMP){
- SCSI_XFER_ERROR(sxfer) =
- XS_REQ_CMP_ERR;
- }else{
- SCSI_XFER_ERROR(sxfer) =
- XS_REQ_CMP;
- SCSI_XFER_REQUEST_COMPLETE(
- sxfer);
+ else
+ if (sbp_status->resp != SBP_REQ_CMP)
+ xs->error = XS_DRIVER_STUFFUP;
+ else {
+ xs->error = XS_NOERROR;
+ xs->resid = 0;
}
- }
/* fix up inq data */
- if (SCSI_XFER_OPECODE(sxfer) == INQUIRY)
+ if (xs->cmd->opcode == INQUIRY)
sbp_fix_inq_data(ocb);
- SBP_LOCK(sbp);
- SCSI_TRANSFER_DONE(sxfer);
- SBP_UNLOCK(sbp);
+ scsipi_done(xs);
}
break;
default:
@@ -2080,7 +1979,7 @@ done0:
* the buffer. In that case, the controller return ack_complete and
* no respose is necessary.
*
- * XXX fwohci.c and firewire.c should inform event_code such as
+ * XXX fwohci.c and firewire.c should inform event_code such as
* ack_complete or ack_pending to upper driver.
*/
#if NEED_RESPONSE
@@ -2096,115 +1995,23 @@ done0:
sfp->mode.wres.rtcode = 0;
sfp->mode.wres.pri = 0;
- fw_asyreq(xfer->fc, -1, xfer);
+ if (fw_asyreq(xfer->fc, -1, xfer) != 0) {
+ aprint_error_dev(sc->sc_fd.dev, "mgm_orb failed\n");
+ mutex_enter(&sc->sc_fwb.fwb_mtx);
+ STAILQ_INSERT_TAIL(&sc->sc_fwb.xferlist, xfer, link);
+ mutex_exit(&sc->sc_fwb.fwb_mtx);
+ }
#else
/* recycle */
- STAILQ_INSERT_TAIL(&sbp->fwb.xferlist, xfer, link);
+ mutex_enter(&sc->sc_fwb.fwb_mtx);
+ STAILQ_INSERT_TAIL(&sc->sc_fwb.xferlist, xfer, link);
+ mutex_exit(&sc->sc_fwb.fwb_mtx);
#endif
return;
}
-static void
-sbp_recv(struct fw_xfer *xfer)
-{
- int s;
-
- s = splfwsbp();
- sbp_recv1(xfer);
- splx(s);
-}
-/*
- * sbp_attach()
- */
-FW_ATTACH(sbp)
-{
- FW_ATTACH_START(sbp, sbp, fwa);
- int dv_unit, error, s;
- struct firewire_comm *fc;
- SBP_ATTACH_START;
-
- if (DFLTPHYS > SBP_MAXPHYS)
- fw_printf(sbp->fd.dev,
- "Warning, DFLTPHYS(%dKB) is larger than "
- "SBP_MAXPHYS(%dKB).\n", DFLTPHYS / 1024,
- SBP_MAXPHYS / 1024);
-SBP_DEBUG(0)
- printf("sbp_attach (cold=%d)\n", cold);
-END_DEBUG
-
- if (cold)
- sbp_cold ++;
- sbp->fd.fc = fc = fwa->fc;
- fw_mtx_init(&sbp->mtx, "sbp", NULL, MTX_DEF);
-
- if (max_speed < 0)
- max_speed = fc->speed;
-
- error = fw_bus_dma_tag_create(/*parent*/fc->dmat,
- /* XXX shoud be 4 for sane backend? */
- /*alignment*/1,
- /*boundary*/0,
- /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
- /*highaddr*/BUS_SPACE_MAXADDR,
- /*filter*/NULL, /*filterarg*/NULL,
- /*maxsize*/0x100000, /*nsegments*/SBP_IND_MAX,
- /*maxsegsz*/SBP_SEG_MAX,
- /*flags*/BUS_DMA_ALLOCNOW,
- /*lockfunc*/busdma_lock_mutex,
- /*lockarg*/&sbp->mtx,
- &sbp->dmat);
- if (error != 0) {
- printf("sbp_attach: Could not allocate DMA tag "
- "- error %d\n", error);
- FW_ATTACH_RETURN(ENOMEM);
- }
-
-#if defined(__FreeBSD__)
- devq = cam_simq_alloc(/*maxopenings*/SBP_NUM_OCB);
- if (devq == NULL)
- return (ENXIO);
-#endif
-
- sbp->target.fwdev = NULL;
- sbp->target.luns = NULL;
-
- if (sbp_alloc_target(sbp, fwa->fwdev) == NULL)
- FW_ATTACH_RETURN(ENXIO);
-
- SBP_SCSIBUS_ATTACH;
-
- /* We reserve 16 bit space (4 bytes X 64 unit X 256 luns) */
- dv_unit = fw_get_unit(sbp->fd.dev);
- sbp->fwb.start = SBP_DEV2ADDR(dv_unit, 0);
- sbp->fwb.end = SBP_DEV2ADDR(dv_unit, -1);
- /* pre-allocate xfer */
- STAILQ_INIT(&sbp->fwb.xferlist);
- fw_xferlist_add(&sbp->fwb.xferlist, M_SBP,
- /*send*/ 0, /*recv*/ SBP_RECV_LEN, SBP_NUM_OCB/2,
- fc, (void *)sbp, sbp_recv);
- fw_bindadd(fc, &sbp->fwb);
-
- sbp->fd.post_busreset = sbp_post_busreset;
- sbp->fd.post_explore = sbp_post_explore;
-
- if (fc->status != FWBUSNOTREADY) {
- s = splfw();
- sbp_post_busreset((void *)sbp);
- sbp_post_explore((void *)sbp);
- splx(s);
- }
-
- FW_ATTACH_RETURN(0);
-#if defined(__FreeBSD__)
-fail:
- SBP_UNLOCK(sbp);
- cam_sim_free(sbp->sim, /*free_devq*/TRUE);
- return (ENXIO);
-#endif
-}
-
static int
sbp_logout_all(struct sbp_softc *sbp)
{
@@ -2215,62 +2022,50 @@ sbp_logout_all(struct sbp_softc *sbp)
SBP_DEBUG(0)
printf("sbp_logout_all\n");
END_DEBUG
- target = &sbp->target;
+ target = &sbp->sc_target;
if (target->luns != NULL)
for (i = 0; i < target->num_lun; i++) {
sdev = target->luns[i];
if (sdev == NULL)
continue;
- fw_callout_stop(&sdev->login_callout);
+ callout_stop(&sdev->login_callout);
if (sdev->status >= SBP_DEV_TOATTACH &&
- sdev->status <= SBP_DEV_ATTACHED)
+ sdev->status <= SBP_DEV_ATTACHED)
sbp_mgm_orb(sdev, ORB_FUN_LGO, NULL);
}
return 0;
}
-#if defined(__FreeBSD__)
-static int
-sbp_shutdown(device_t dev)
-{
- struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
-
- sbp_logout_all(sbp);
- return (0);
-}
-#endif
-
static void
sbp_free_sdev(struct sbp_dev *sdev)
{
+ struct sbp_softc *sc = sdev->target->sbp;
int i;
if (sdev == NULL)
return;
for (i = 0; i < SBP_QUEUE_LEN; i++)
- fw_bus_dmamap_destroy(sdev->target->sbp->dmat,
- sdev->ocb[i].dmamap);
- fwdma_free(sdev->target->sbp->fd.fc, &sdev->dma);
+ bus_dmamap_destroy(sc->sc_dmat, sdev->ocb[i].dmamap);
+ fwdma_free(sdev->dma.dma_tag, sdev->dma.dma_map, sdev->dma.v_addr);
free(sdev, M_SBP);
+ sdev = NULL;
}
static void
sbp_free_target(struct sbp_target *target)
{
- struct sbp_softc *sbp;
struct fw_xfer *xfer, *next;
int i;
if (target->luns == NULL)
return;
- fw_callout_stop(&target->mgm_ocb_timeout);
- sbp = target->sbp;
+ callout_stop(&target->mgm_ocb_timeout);
for (i = 0; i < target->num_lun; i++)
sbp_free_sdev(target->luns[i]);
for (xfer = STAILQ_FIRST(&target->xferlist);
- xfer != NULL; xfer = next) {
+ xfer != NULL; xfer = next) {
next = STAILQ_NEXT(xfer, link);
fw_xfer_free_buf(xfer);
}
@@ -2281,80 +2076,6 @@ sbp_free_target(struct sbp_target *target)
target->fwdev = NULL;
}
-FW_DETACH(sbp)
-{
- FW_DETACH_START(sbp, sbp);
- struct firewire_comm *fc = sbp->fd.fc;
- int i;
-
-SBP_DEBUG(0)
- printf("sbp_detach\n");
-END_DEBUG
-
- SBP_DETACH_TARGET(&sbp->target);
-#if defined(__FreeBSD__)
- SBP_LOCK(sbp);
- xpt_async(AC_LOST_DEVICE, sbp->path, NULL);
- xpt_free_path(sbp->path);
- xpt_bus_deregister(cam_sim_path(sbp->sim));
- cam_sim_free(sbp->sim, /*free_devq*/ TRUE),
- SBP_UNLOCK(sbp);
-#endif
-
- sbp_logout_all(sbp);
-
- /* XXX wait for logout completion */
- tsleep(&i, FWPRI, "sbpdtc", hz/2);
-
- sbp_free_target(&sbp->target);
-
- fw_bindremove(fc, &sbp->fwb);
- fw_xferlist_remove(&sbp->fwb.xferlist);
-
- fw_bus_dma_tag_destroy(sbp->dmat);
- fw_mtx_destroy(&sbp->mtx);
-
- return (0);
-}
-
-#if defined(__FreeBSD__)
-static void
-sbp_cam_detach_sdev(struct sbp_dev *sdev)
-{
- if (sdev == NULL)
- return;
- if (sdev->status == SBP_DEV_DEAD)
- return;
- if (sdev->status == SBP_DEV_RESET)
- return;
- sbp_abort_all_ocbs(sdev, CAM_DEV_NOT_THERE);
- if (sdev->path) {
- SBP_LOCK(sdev->target->sbp);
- xpt_release_devq(sdev->path,
- sdev->freeze, TRUE);
- sdev->freeze = 0;
- xpt_async(AC_LOST_DEVICE, sdev->path, NULL);
- xpt_free_path(sdev->path);
- sdev->path = NULL;
- SBP_UNLOCK(sdev->target->sbp);
- }
-}
-
-static void
-sbp_cam_detach_target(struct sbp_target *target)
-{
- int i;
-
- if (target->luns != NULL) {
-SBP_DEBUG(0)
- printf("sbp_detach_target %d\n", target->target_id);
-END_DEBUG
- fw_callout_stop(&target->scan_callout);
- for (i = 0; i < target->num_lun; i++)
- sbp_cam_detach_sdev(target->luns[i]);
- }
-}
-#elif defined(__NetBSD__)
static void
sbp_scsipi_detach_sdev(struct sbp_dev *sdev)
{
@@ -2374,18 +2095,17 @@ sbp_scsipi_detach_sdev(struct sbp_dev *sdev)
return;
if (sdev->status == SBP_DEV_RESET)
return;
- if (sdev->periph) {
+ if (sdev->periph != NULL) {
scsipi_periph_thaw(sdev->periph, sdev->freeze);
scsipi_channel_thaw(&sbp->sc_channel, 0); /* XXXX */
sdev->freeze = 0;
if (scsipi_target_detach(&sbp->sc_channel,
target->target_id, sdev->lun_id, DETACH_FORCE) != 0) {
- sbp_show_sdev_info(sdev, 2);
- printf("detach failed\n");
+ aprint_error_dev(sbp->sc_fd.dev, "detach failed\n");
}
sdev->periph = NULL;
}
- sbp_abort_all_ocbs(sdev, XS_DEV_NOT_THERE);
+ sbp_abort_all_ocbs(sdev, XS_DRIVER_STUFFUP);
}
static void
@@ -2398,24 +2118,24 @@ sbp_scsipi_detach_target(struct sbp_target *target)
SBP_DEBUG(0)
printf("sbp_detach_target %d\n", target->target_id);
END_DEBUG
- fw_callout_stop(&target->scan_callout);
for (i = 0; i < target->num_lun; i++)
sbp_scsipi_detach_sdev(target->luns[i]);
if (config_detach(sbp->sc_bus, DETACH_FORCE) != 0)
- fw_printf(sbp->fd.dev, "%d detach failed\n",
- target->target_id);
+ aprint_error_dev(sbp->sc_fd.dev, "%d detach failed\n",
+ target->target_id);
sbp->sc_bus = NULL;
}
}
-#endif
static void
sbp_target_reset(struct sbp_dev *sdev, int method)
{
- int i;
+ struct sbp_softc *sc;
struct sbp_target *target = sdev->target;
struct sbp_dev *tsdev;
+ int i;
+ sc = target->sbp;
for (i = 0; i < target->num_lun; i++) {
tsdev = target->luns[i];
if (tsdev == NULL)
@@ -2424,25 +2144,24 @@ sbp_target_reset(struct sbp_dev *sdev, int method)
continue;
if (tsdev->status == SBP_DEV_RESET)
continue;
- SBP_LOCK(target->sbp);
- SBP_DEVICE_FREEZE(tsdev, 1);
- tsdev->freeze ++;
- SBP_UNLOCK(target->sbp);
- sbp_abort_all_ocbs(tsdev, XS_CMD_TIMEOUT);
+ if (sdev->periph != NULL) {
+ scsipi_periph_freeze(tsdev->periph, 1);
+ tsdev->freeze++;
+ }
+ sbp_abort_all_ocbs(tsdev, XS_TIMEOUT);
if (method == 2)
tsdev->status = SBP_DEV_LOGIN;
}
switch(method) {
case 1:
- printf("target reset\n");
+ aprint_error("target reset\n");
sbp_mgm_orb(sdev, ORB_FUN_RST, NULL);
break;
case 2:
- printf("reset start\n");
+ aprint_error("reset start\n");
sbp_reset_start(sdev);
break;
}
-
}
static void
@@ -2452,20 +2171,19 @@ sbp_mgm_timeout(void *arg)
struct sbp_dev *sdev = ocb->sdev;
struct sbp_target *target = sdev->target;
- sbp_show_sdev_info(sdev, 2);
- printf("request timeout(mgm orb:0x%08x) ... ",
- (uint32_t)ocb->bus_addr);
+ aprint_error_dev(sdev->target->sbp->sc_fd.dev,
+ "%s:%s: request timeout(mgm orb:0x%08x) ... ",
+ __func__, sdev->bustgtlun, (uint32_t)ocb->bus_addr);
target->mgm_ocb_cur = NULL;
sbp_free_ocb(sdev, ocb);
#if 0
/* XXX */
- printf("run next request\n");
+ aprint_error("run next request\n");
sbp_mgm_orb(sdev, ORB_FUN_RUNQUEUE, NULL);
#endif
-#if 1
- printf("reset start\n");
+ aprint_error_dev(sdev->target->sbp->sc_fd.dev,
+ "%s:%s: reset start\n", __func__, sdev->bustgtlun);
sbp_reset_start(sdev);
-#endif
}
static void
@@ -2474,29 +2192,30 @@ sbp_timeout(void *arg)
struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
struct sbp_dev *sdev = ocb->sdev;
- sbp_show_sdev_info(sdev, 2);
- printf("request timeout(cmd orb:0x%08x) ... ",
- (uint32_t)ocb->bus_addr);
+ aprint_error_dev(sdev->target->sbp->sc_fd.dev,
+ "%s:%s: request timeout(cmd orb:0x%08x) ... ",
+ __func__, sdev->bustgtlun, (uint32_t)ocb->bus_addr);
- sdev->timeout ++;
+ sdev->timeout++;
switch(sdev->timeout) {
case 1:
- printf("agent reset\n");
- SBP_LOCK(sdev->target->sbp);
- SBP_DEVICE_FREEZE(sdev, 1);
- sdev->freeze ++;
- SBP_UNLOCK(sdev->target->sbp);
- sbp_abort_all_ocbs(sdev, XS_CMD_TIMEOUT);
+ aprint_error("agent reset\n");
+ if (sdev->periph != NULL) {
+ scsipi_periph_freeze(sdev->periph, 1);
+ sdev->freeze++;
+ }
+ sbp_abort_all_ocbs(sdev, XS_TIMEOUT);
sbp_agent_reset(sdev);
break;
case 2:
case 3:
sbp_target_reset(sdev, sdev->timeout - 1);
break;
-#if 0
default:
+ aprint_error("\n");
+#if 0
/* XXX give up */
- SBP_DETACH_TARGET(target);
+ sbp_scsipi_detach_target(target);
if (target->luns != NULL)
free(target->luns, M_SBP);
target->num_lun = 0;
@@ -2507,360 +2226,128 @@ sbp_timeout(void *arg)
}
static void
-sbp_action1(struct sbp_softc *sbp, sbp_scsi_xfer *sxfer)
+sbp_action1(struct sbp_softc *sc, struct scsipi_xfer *xs)
{
-
- struct sbp_target *target = NULL;
+ struct sbp_target *target = &sc->sc_target;
struct sbp_dev *sdev = NULL;
+ struct sbp_ocb *ocb;
+ int speed, flag, error;
+ void *cdb;
/* target:lun -> sdev mapping */
- if (sbp != NULL) {
- target = &sbp->target;
- if (target->fwdev != NULL
- && NOT_LUN_WILDCARD(SCSI_XFER_LUN(sxfer))
- && SCSI_XFER_LUN(sxfer) < target->num_lun) {
- sdev = target->luns[SCSI_XFER_LUN(sxfer)];
- if (sdev != NULL && sdev->status != SBP_DEV_ATTACHED &&
- sdev->status != SBP_DEV_PROBE)
- sdev = NULL;
- }
+ if (target->fwdev != NULL &&
+ xs->xs_periph->periph_lun < target->num_lun) {
+ sdev = target->luns[xs->xs_periph->periph_lun];
+ if (sdev != NULL && sdev->status != SBP_DEV_ATTACHED &&
+ sdev->status != SBP_DEV_PROBE)
+ sdev = NULL;
}
+ if (sdev == NULL) {
SBP_DEBUG(1)
- if (sdev == NULL)
- printf("invalid target %d lun %d\n",
- SCSI_XFER_TARGET(sxfer), SCSI_XFER_LUN(sxfer));
-END_DEBUG
-
- switch (SCSI_XFER_FUNCCODE(sxfer)) {
- case XPT_SCSI_IO:
-#if defined(__FreeBSD__)
- case XPT_RESET_DEV:
- case XPT_GET_TRAN_SETTINGS:
- case XPT_SET_TRAN_SETTINGS:
- case XPT_CALC_GEOMETRY:
-#endif
- if (sdev == NULL) {
-SBP_DEBUG(1)
- printf("%s:%d:%d:func_code 0x%04x: "
- "Invalid target (target needed)\n",
- sbp ? fw_get_nameunit(sbp->fd.dev) : "???",
- SCSI_XFER_TARGET(sxfer), SCSI_XFER_LUN(sxfer),
- SCSI_XFER_FUNCCODE(sxfer));
+ printf("%s:%d:%d: Invalid target (target needed)\n",
+ sc ? device_xname(sc->sc_fd.dev) : "???",
+ xs->xs_periph->periph_target,
+ xs->xs_periph->periph_lun);
END_DEBUG
- SCSI_XFER_ERROR(sxfer) = XS_DEV_NOT_THERE;
- SCSI_TRANSFER_DONE(sxfer);
- return;
- }
- break;
-#if defined(__FreeBSD__)
- case XPT_PATH_INQ:
- case XPT_NOOP:
- /* The opcodes sometimes aimed at a target (sc is valid),
- * sometimes aimed at the SIM (sc is invalid and target is
- * CAM_TARGET_WILDCARD)
- */
- if (sbp == NULL &&
- sxfer->ccb_h.target_id != CAM_TARGET_WILDCARD) {
-SBP_DEBUG(0)
- printf("%s:%d:%d func_code 0x%04x: "
- "Invalid target (no wildcard)\n",
- fw_get_nameunit(sbp->fd.dev),
- sxfer->ccb_h.target_id, sxfer->ccb_h.target_lun,
- sxfer->ccb_h.func_code);
-END_DEBUG
- SCSI_XFER_ERROR(sxfer) = XS_DEV_NOT_THERE;
- SCSI_TRANSFER_DONE(sxfer);
- return;
- }
- break;
-#endif
- default:
- /* XXX Hm, we should check the input parameters */
- break;
+ xs->error = XS_DRIVER_STUFFUP;
+ scsipi_done(xs);
+ return;
}
- switch (SCSI_XFER_FUNCCODE(sxfer)) {
- case XPT_SCSI_IO:
- {
- struct sbp_ocb *ocb;
- int speed;
- void *cdb;
- fw_mtx_assert(sim->mtx, MA_OWNED);
-
SBP_DEBUG(2)
- printf("%s:%d:%d XPT_SCSI_IO: "
- "cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
- ", flags: 0x%02x, "
- "%db cmd/%db data/%db sense\n",
- fw_get_nameunit(sbp->fd.dev),
- SCSI_XFER_TARGET(sxfer), SCSI_XFER_LUN(sxfer),
- SCSI_XFER_10BCMD_DUMP(sxfer),
- SCSI_XFER_DIR(sxfer),
- SCSI_XFER_CMDLEN(sxfer), SCSI_XFER_DATALEN(sxfer),
- SCSI_XFER_SENSELEN(sxfer));
+ printf("%s:%d:%d:"
+ " cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x,"
+ " flags: 0x%02x, %db cmd/%db data\n",
+ device_xname(sc->sc_fd.dev),
+ xs->xs_periph->periph_target,
+ xs->xs_periph->periph_lun,
+ xs->cmd->opcode,
+ xs->cmd->bytes[0], xs->cmd->bytes[1],
+ xs->cmd->bytes[2], xs->cmd->bytes[3],
+ xs->cmd->bytes[4], xs->cmd->bytes[5],
+ xs->cmd->bytes[6], xs->cmd->bytes[7],
+ xs->cmd->bytes[8],
+ xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT),
+ xs->cmdlen, xs->datalen);
END_DEBUG
- if(sdev == NULL){
- SCSI_XFER_ERROR(sxfer) = XS_DEV_NOT_THERE;
- SCSI_TRANSFER_DONE(sxfer);
- return;
- }
-#if 0
- /* if we are in probe stage, pass only probe commands */
- if (sdev->status == SBP_DEV_PROBE) {
- char *name;
- name = xpt_path_periph(sxfer->ccb_h.path)->periph_name;
- printf("probe stage, periph name: %s\n", name);
- if (strcmp(name, "probe") != 0) {
- SCSI_XFER_ERROR(sxfer) = XS_REQUEUE_REQ;
- SCSI_TRANSFER_DONE(sxfer);
- return;
- }
- }
-#endif
- if ((ocb = sbp_get_ocb(sdev)) == NULL) {
- SCSI_XFER_ERROR(sxfer) = XS_REQUEUE_REQ;
- if (sdev->freeze == 0) {
- SBP_LOCK(sdev->target->sbp);
- SBP_DEVICE_FREEZE(sdev, 1);
- sdev->freeze ++;
- SBP_UNLOCK(sdev->target->sbp);
- }
- SCSI_TRANSFER_DONE(sxfer);
- return;
- }
-
- ocb->flags = OCB_ACT_CMD;
- ocb->sdev = sdev;
- ocb->sxfer = sxfer;
-#if defined(__FreeBSD__)
- sxfer->ccb_h.ccb_sdev_ptr = sdev;
-#endif
- ocb->orb[0] = htonl(1 << 31);
- ocb->orb[1] = 0;
- ocb->orb[2] = htonl(((sbp->fd.fc->nodeid | FWLOCALBUS )<< 16) );
- ocb->orb[3] = htonl(ocb->bus_addr + IND_PTR_OFFSET);
- speed = min(target->fwdev->speed, max_speed);
- ocb->orb[4] = htonl(ORB_NOTIFY | ORB_CMD_SPD(speed)
- | ORB_CMD_MAXP(speed + 7));
- if(SCSI_XFER_DIR(sxfer) == SCSI_XFER_DATA_IN){
- ocb->orb[4] |= htonl(ORB_CMD_IN);
+ mutex_enter(&sc->sc_mtx);
+ ocb = sbp_get_ocb(sdev);
+ mutex_exit(&sc->sc_mtx);
+ if (ocb == NULL) {
+ xs->error = XS_REQUEUE;
+ if (sdev->freeze == 0) {
+ scsipi_periph_freeze(sdev->periph, 1);
+ sdev->freeze++;
}
+ scsipi_done(xs);
+ return;
+ }
- if (CAM_XFER_FLAGS(sxfer) & CAM_SCATTER_VALID)
- printf("sbp: CAM_SCATTER_VALID\n");
- if (CAM_XFER_FLAGS(sxfer) & CAM_DATA_PHYS)
- printf("sbp: CAM_DATA_PHYS\n");
-
- cdb = SCSI_XFER_CMD(sxfer);
- memcpy((void *)&ocb->orb[5], cdb, SCSI_XFER_CMDLEN(sxfer));
+ ocb->flags = OCB_ACT_CMD;
+ ocb->sdev = sdev;
+ ocb->xs = xs;
+ ocb->orb[0] = htonl(1 << 31);
+ ocb->orb[1] = 0;
+ ocb->orb[2] = htonl(((sc->sc_fd.fc->nodeid | FWLOCALBUS) << 16));
+ ocb->orb[3] = htonl(ocb->bus_addr + IND_PTR_OFFSET);
+ speed = min(target->fwdev->speed, max_speed);
+ ocb->orb[4] =
+ htonl(ORB_NOTIFY | ORB_CMD_SPD(speed) | ORB_CMD_MAXP(speed + 7));
+ if ((xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) ==
+ XS_CTL_DATA_IN) {
+ ocb->orb[4] |= htonl(ORB_CMD_IN);
+ flag = BUS_DMA_READ;
+ } else
+ flag = BUS_DMA_WRITE;
+
+ cdb = xs->cmd;
+ memcpy((void *)&ocb->orb[5], cdb, xs->cmdlen);
/*
printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[0]), ntohl(ocb->orb[1]), ntohl(ocb->orb[2]), ntohl(ocb->orb[3]));
printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[4]), ntohl(ocb->orb[5]), ntohl(ocb->orb[6]), ntohl(ocb->orb[7]));
*/
- if (SCSI_XFER_DATALEN(sxfer) > 0) {
- int s, error;
-
- s = splsoftvm();
- error = fw_bus_dmamap_load(/*dma tag*/sbp->dmat,
- /*dma map*/ocb->dmamap,
- SCSI_XFER_DATA(sxfer),
- SCSI_XFER_DATALEN(sxfer),
- sbp_execute_ocb,
- ocb,
- /*flags*/0);
- splx(s);
- if (error)
- printf("sbp: bus_dmamap_load error %d\n", error);
+ if (xs->datalen > 0) {
+ error = bus_dmamap_load(sc->sc_dmat, ocb->dmamap,
+ xs->data, xs->datalen, NULL, BUS_DMA_NOWAIT | flag);
+ if (error) {
+ aprint_error_dev(sc->sc_fd.dev,
+ "DMA map load error %d\n", error);
+ xs->error = XS_DRIVER_STUFFUP;
+ scsipi_done(xs);
} else
- sbp_execute_ocb(ocb, NULL, 0, 0);
- break;
- }
-#if defined(__FreeBSD__)
- case XPT_CALC_GEOMETRY:
- {
- struct ccb_calc_geometry *ccg;
-#if defined(__DragonFly__) || __FreeBSD_version < 501100
- uint32_t size_mb;
- uint32_t secs_per_cylinder;
- int extended = 1;
-#endif
+ sbp_execute_ocb(ocb, ocb->dmamap->dm_segs,
+ ocb->dmamap->dm_nsegs);
+ } else
+ sbp_execute_ocb(ocb, NULL, 0);
- ccg = &sxfer->ccg;
- if (ccg->block_size == 0) {
- printf("sbp_action1: block_size is 0.\n");
- SCSI_XFER_ERROR(sxfer) = XS_REQ_INVALID;
- SCSI_TRANSFER_DONE(sxfer);
- break;
- }
-SBP_DEBUG(1)
- printf("%s:%d:%d:%d:XPT_CALC_GEOMETRY: "
-#if defined(__DragonFly__) || __FreeBSD_version < 500000
- "Volume size = %d\n",
-#else
- "Volume size = %jd\n",
-#endif
- fw_get_nameunit(sbp->fd.dev),
- cam_sim_path(sbp->sim),
- sxfer->ccb_h.target_id, sxfer->ccb_h.target_lun,
-#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
- (uintmax_t)
-#endif
- ccg->volume_size);
-END_DEBUG
-
-#if defined(__DragonFly__) || __FreeBSD_version < 501100
- size_mb = ccg->volume_size
- / ((1024L * 1024L) / ccg->block_size);
-
- if (size_mb > 1024 && extended) {
- ccg->heads = 255;
- ccg->secs_per_track = 63;
- } else {
- ccg->heads = 64;
- ccg->secs_per_track = 32;
- }
- secs_per_cylinder = ccg->heads * ccg->secs_per_track;
- ccg->cylinders = ccg->volume_size / secs_per_cylinder;
- SCSI_XFER_ERROR(sxfer) = XS_REQ_CMP;
-#else
- cam_calc_geometry(ccg, /*extended*/1);
-#endif
- SCSI_TRANSFER_DONE(sxfer);
- break;
- }
- case XPT_RESET_BUS: /* Reset the specified SCSI bus */
- {
-
-SBP_DEBUG(1)
- printf("%s:%d:XPT_RESET_BUS: \n",
- fw_get_nameunit(sbp->fd.dev), cam_sim_path(sbp->sim));
-END_DEBUG
-
- SCSI_XFER_ERROR(sxfer) = XS_REQ_INVALID;
- SCSI_TRANSFER_DONE(sxfer);
- break;
- }
- case XPT_PATH_INQ: /* Path routing inquiry */
- {
- struct ccb_pathinq *cpi = &sxfer->cpi;
- struct cam_sim *sim = sbp->sim;
-
-SBP_DEBUG(1)
- printf("%s:%d:%d XPT_PATH_INQ:.\n",
- fw_get_nameunit(sbp->fd.dev),
- sxfer->ccb_h.target_id, sxfer->ccb_h.target_lun);
-END_DEBUG
- cpi->version_num = 1; /* XXX??? */
- cpi->hba_inquiry = PI_TAG_ABLE;
- cpi->target_sprt = 0;
- cpi->hba_misc = PIM_NOBUSRESET | PIM_NO_6_BYTE;
- cpi->hba_eng_cnt = 0;
- cpi->max_target = SBP_NUM_TARGETS - 1;
- cpi->max_lun = SBP_NUM_LUNS - 1;
- cpi->initiator_id = SBP_INITIATOR;
- cpi->bus_id = sim->bus_id;
- cpi->base_transfer_speed = 400 * 1000 / 8;
- strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
- strncpy(cpi->hba_vid, "SBP", HBA_IDLEN);
- strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN);
- cpi->unit_number = sim->unit_number;
- cpi->transport = XPORT_SPI; /* XX should havea FireWire */
- cpi->transport_version = 2;
- cpi->protocol = PROTO_SCSI;
- cpi->protocol_version = SCSI_REV_2;
-
- SCSI_XFER_ERROR(cpi) = XS_REQ_CMP;
- SCSI_TRANSFER_DONE(sxfer);
- break;
- }
- case XPT_GET_TRAN_SETTINGS:
- {
- struct ccb_trans_settings *cts = &sxfer->cts;
- struct ccb_trans_settings_scsi *scsi =
- &cts->proto_specific.scsi;
- struct ccb_trans_settings_spi *spi =
- &cts->xport_specific.spi;
-
- cts->protocol = PROTO_SCSI;
- cts->protocol_version = SCSI_REV_2;
- cts->transport = XPORT_SPI; /* should have a FireWire */
- cts->transport_version = 2;
- spi->valid = CTS_SPI_VALID_DISC;
- spi->flags = CTS_SPI_FLAGS_DISC_ENB;
- scsi->valid = CTS_SCSI_VALID_TQ;
- scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
-SBP_DEBUG(1)
- printf("%s:%d:%d XPT_GET_TRAN_SETTINGS:.\n",
- fw_get_nameunit(sbp->fd.dev),
- sxfer->ccb_h.target_id, sxfer->ccb_h.target_lun);
-END_DEBUG
- SCSI_XFER_ERROR(cts) = XS_REQ_CMP;
- SCSI_TRANSFER_DONE(sxfer);
- break;
- }
- case XPT_ABORT:
- SCSI_XFER_ERROR(sxfer) = XS_UA_ABORT;
- SCSI_TRANSFER_DONE(sxfer);
- break;
- case XPT_SET_TRAN_SETTINGS:
- /* XXX */
- default:
- SCSI_XFER_ERROR(sxfer) = XS_REQ_INVALID;
- SCSI_TRANSFER_DONE(sxfer);
- break;
-#endif
- }
return;
}
-#if defined(__FreeBSD__)
static void
-sbp_action(struct cam_sim *sim, sbp_scsi_xfer *sxfer)
+sbp_execute_ocb(struct sbp_ocb *ocb, bus_dma_segment_t *segments, int seg)
{
- int s;
-
- s = splfw();
- sbp_action1(sim->softc, sxfer);
- splx(s);
-}
-#endif
-
-static void
-sbp_execute_ocb(void *arg, bus_dma_segment_t *segments, int seg, int error)
-{
- int i;
- struct sbp_ocb *ocb;
struct sbp_ocb *prev;
bus_dma_segment_t *s;
-
- if (error)
- printf("sbp_execute_ocb: error=%d\n", error);
-
- ocb = (struct sbp_ocb *)arg;
+ int i;
SBP_DEBUG(2)
printf("sbp_execute_ocb: seg %d", seg);
for (i = 0; i < seg; i++)
-#if defined(__DragonFly__) || \
- (defined(__FreeBSD__) && __FreeBSD_version < 500000)
- printf(", %x:%d", segments[i].ds_addr, segments[i].ds_len);
-#else
printf(", %jx:%jd", (uintmax_t)segments[i].ds_addr,
- (uintmax_t)segments[i].ds_len);
-#endif
+ (uintmax_t)segments[i].ds_len);
printf("\n");
END_DEBUG
if (seg == 1) {
/* direct pointer */
- s = &segments[0];
+ s = segments;
if (s->ds_len > SBP_SEG_MAX)
panic("ds_len > SBP_SEG_MAX, fix busdma code");
ocb->orb[3] = htonl(s->ds_addr);
ocb->orb[4] |= htonl(s->ds_len);
- } else if(seg > 1) {
+ } else if (seg > 1) {
/* page table */
for (i = 0; i < seg; i++) {
s = &segments[i];
@@ -2868,13 +2355,9 @@ SBP_DEBUG(0)
/* XXX LSI Logic "< 16 byte" bug might be hit */
if (s->ds_len < 16)
printf("sbp_execute_ocb: warning, "
-#if defined(__DragonFly__) || \
- (defined(__FreeBSD__) && __FreeBSD_version < 500000)
- "segment length(%d) is less than 16."
-#else
- "segment length(%jd) is less than 16."
-#endif
- "(seg=%d/%d)\n", (uintmax_t)s->ds_len, i+1, seg);
+ "segment length(%jd) is less than 16."
+ "(seg=%d/%d)\n",
+ (uintmax_t)s->ds_len, i + 1, seg);
END_DEBUG
if (s->ds_len > SBP_SEG_MAX)
panic("ds_len > SBP_SEG_MAX, fix busdma code");
@@ -2883,170 +2366,146 @@ END_DEBUG
}
ocb->orb[4] |= htonl(ORB_CMD_PTBL | seg);
}
-
- if (seg > 0)
- fw_bus_dmamap_sync(ocb->sdev->target->sbp->dmat, ocb->dmamap,
- (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
- BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
+ if (seg > 0) {
+ struct sbp_softc *sc = ocb->sdev->target->sbp;
+ const int flag = (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
+ BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE;
+
+ bus_dmamap_sync(sc->sc_dmat, ocb->dmamap,
+ 0, ocb->dmamap->dm_mapsize, flag);
+ }
prev = sbp_enqueue_ocb(ocb->sdev, ocb);
- fwdma_sync(&ocb->sdev->dma, BUS_DMASYNC_PREWRITE);
+ SBP_ORB_DMA_SYNC(ocb->sdev->dma, ocb->index, BUS_DMASYNC_PREWRITE);
if (use_doorbell) {
if (prev == NULL) {
if (ocb->sdev->last_ocb != NULL)
sbp_doorbell(ocb->sdev);
else
- sbp_orb_pointer(ocb->sdev, ocb);
+ sbp_orb_pointer(ocb->sdev, ocb);
}
- } else {
+ } else
if (prev == NULL || (ocb->sdev->flags & ORB_LINK_DEAD) != 0) {
ocb->sdev->flags &= ~ORB_LINK_DEAD;
- sbp_orb_pointer(ocb->sdev, ocb);
+ sbp_orb_pointer(ocb->sdev, ocb);
}
- }
-}
-
-#if defined(__FreeBSD__)
-static void
-sbp_poll(struct cam_sim *sim)
-{
- struct sbp_softc *sbp;
- struct firewire_comm *fc;
-
- sbp = (struct sbp_softc *)sim->softc;
- fc = sbp->fd.fc;
-
- fc->poll(fc, 0, -1);
-
- return;
}
-#endif
static struct sbp_ocb *
sbp_dequeue_ocb(struct sbp_dev *sdev, struct sbp_status *sbp_status)
{
+ struct sbp_softc *sc = sdev->target->sbp;
struct sbp_ocb *ocb;
struct sbp_ocb *next;
- int s = splfw(), order = 0;
+ int order = 0;
int flags;
SBP_DEBUG(1)
- sbp_show_sdev_info(sdev, 2);
-#if defined(__DragonFly__) || \
- (defined(__FreeBSD__) && __FreeBSD_version < 500000)
- printf("%s: 0x%08lx src %d\n",
-#else
- printf("%s: 0x%08x src %d\n",
-#endif
- __func__, ntohl(sbp_status->orb_lo), sbp_status->src);
+ printf("%s:%s:%s: 0x%08x src %d\n", device_xname(sc->sc_fd.dev),
+ __func__, sdev->bustgtlun, ntohl(sbp_status->orb_lo),
+ sbp_status->src);
END_DEBUG
- SBP_LOCK(sdev->target->sbp);
+ mutex_enter(&sc->sc_mtx);
for (ocb = STAILQ_FIRST(&sdev->ocbs); ocb != NULL; ocb = next) {
next = STAILQ_NEXT(ocb, ocb);
flags = ocb->flags;
if (OCB_MATCH(ocb, sbp_status)) {
/* found */
+ SBP_ORB_DMA_SYNC(sdev->dma, ocb->index,
+ BUS_DMASYNC_POSTWRITE);
STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb);
- if (ocb->sxfer != NULL)
-#if defined(__DragonFly__) || defined(__NetBSD__)
- fw_callout_stop(&SCSI_XFER_CALLOUT(ocb->sxfer));
-#else
- untimeout(sbp_timeout, (void *)ocb,
- SCSI_XFER_CALLOUT(ocb->sxfer));
-#endif
+ if (ocb->xs != NULL)
+ callout_stop(&ocb->xs->xs_callout);
if (ntohl(ocb->orb[4]) & 0xffff) {
- fw_bus_dmamap_sync(sdev->target->sbp->dmat,
- ocb->dmamap,
- (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
- BUS_DMASYNC_POSTREAD :
- BUS_DMASYNC_POSTWRITE);
- fw_bus_dmamap_unload(sdev->target->sbp->dmat,
- ocb->dmamap);
+ const int flag =
+ (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
+ BUS_DMASYNC_POSTREAD :
+ BUS_DMASYNC_POSTWRITE;
+
+ bus_dmamap_sync(sc->sc_dmat, ocb->dmamap,
+ 0, ocb->dmamap->dm_mapsize, flag);
+ bus_dmamap_unload(sc->sc_dmat, ocb->dmamap);
+
}
if (!use_doorbell) {
if (sbp_status->src == SRC_NO_NEXT) {
if (next != NULL)
- sbp_orb_pointer(sdev, next);
- else if (order > 0) {
+ sbp_orb_pointer(sdev, next);
+ else if (order > 0)
/*
* Unordered execution
* We need to send pointer for
* next ORB
*/
sdev->flags |= ORB_LINK_DEAD;
- }
}
- } else {
- /*
- * XXX this is not correct for unordered
- * execution.
- */
- if (sdev->last_ocb != NULL)
- sbp_free_ocb(sdev, sdev->last_ocb);
- sdev->last_ocb = ocb;
- if (next != NULL &&
- sbp_status->src == SRC_NO_NEXT)
- sbp_doorbell(sdev);
}
break;
} else
- order ++;
+ order++;
}
- SBP_UNLOCK(sdev->target->sbp);
- splx(s);
-SBP_DEBUG(0)
- if (ocb && order > 0) {
- sbp_show_sdev_info(sdev, 2);
- printf("unordered execution order:%d\n", order);
+ mutex_exit(&sc->sc_mtx);
+
+ if (ocb && use_doorbell) {
+ /*
+ * XXX this is not correct for unordered
+ * execution.
+ */
+ if (sdev->last_ocb != NULL)
+ sbp_free_ocb(sdev, sdev->last_ocb);
+ sdev->last_ocb = ocb;
+ if (next != NULL &&
+ sbp_status->src == SRC_NO_NEXT)
+ sbp_doorbell(sdev);
}
+
+SBP_DEBUG(0)
+ if (ocb && order > 0)
+ printf("%s:%s:%s: unordered execution order:%d\n",
+ device_xname(sc->sc_fd.dev), __func__, sdev->bustgtlun,
+ order);
END_DEBUG
- return (ocb);
+ return ocb;
}
static struct sbp_ocb *
sbp_enqueue_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
{
- int s = splfw();
- struct sbp_ocb *prev, *prev2;
+ struct sbp_softc *sc = sdev->target->sbp;
+ struct sbp_ocb *tocb, *prev, *prev2;
SBP_DEBUG(1)
- sbp_show_sdev_info(sdev, 2);
-#if defined(__DragonFly__) || \
- (defined(__FreeBSD__) && __FreeBSD_version < 500000)
- printf("%s: 0x%08x\n", __func__, ocb->bus_addr);
-#else
- printf("%s: 0x%08jx\n", __func__, (uintmax_t)ocb->bus_addr);
-#endif
+ printf("%s:%s:%s: 0x%08jx\n", device_xname(sc->sc_fd.dev),
+ __func__, sdev->bustgtlun, (uintmax_t)ocb->bus_addr);
END_DEBUG
- prev2 = prev = STAILQ_LAST(&sdev->ocbs, sbp_ocb, ocb);
+ mutex_enter(&sc->sc_mtx);
+ prev = NULL;
+ STAILQ_FOREACH(tocb, &sdev->ocbs, ocb)
+ prev = tocb;
+ prev2 = prev;
STAILQ_INSERT_TAIL(&sdev->ocbs, ocb, ocb);
+ mutex_exit(&sc->sc_mtx);
- if (ocb->sxfer != NULL)
-#if defined(__DragonFly__) || defined(__NetBSD__)
- fw_callout_reset(&SCSI_XFER_CALLOUT(ocb->sxfer),
- mstohz(SCSI_XFER_TIMEOUT(ocb->sxfer)), sbp_timeout, ocb);
-#else
- SCSI_XFER_CALLOUT(ocb->sxfer) = timeout(sbp_timeout,
- (void *)ocb, mstohz(SCSI_XFER_TIMEOUT(ocb->sxfer)));
-#endif
+ callout_reset(&ocb->xs->xs_callout, mstohz(ocb->xs->timeout),
+ sbp_timeout, ocb);
if (use_doorbell && prev == NULL)
prev2 = sdev->last_ocb;
if (prev2 != NULL) {
SBP_DEBUG(2)
-#if defined(__DragonFly__) || \
- (defined(__FreeBSD__) && __FreeBSD_version < 500000)
- printf("linking chain 0x%x -> 0x%x\n",
- prev2->bus_addr, ocb->bus_addr);
-#else
printf("linking chain 0x%jx -> 0x%jx\n",
(uintmax_t)prev2->bus_addr, (uintmax_t)ocb->bus_addr);
-#endif
END_DEBUG
- prev2->orb[1] = htonl(ocb->bus_addr);
- prev2->orb[0] = 0;
+ /*
+ * Suppress compiler optimization so that orb[1] must be
+ * written first.
+ * XXX We may need an explicit memory barrier for other
+ * architectures other than i386/amd64.
+ */
+ *(volatile uint32_t *)&prev2->orb[1] = htonl(ocb->bus_addr);
+ *(volatile uint32_t *)&prev2->orb[0] = 0;
}
- splx(s);
return prev;
}
@@ -3054,78 +2513,73 @@ END_DEBUG
static struct sbp_ocb *
sbp_get_ocb(struct sbp_dev *sdev)
{
+ struct sbp_softc *sc = sdev->target->sbp;
struct sbp_ocb *ocb;
- int s = splfw();
- fw_mtx_assert(&sdev->target->sbp->mtx, MA_OWNED);
+ KASSERT(mutex_owned(&sc->sc_mtx));
+
ocb = STAILQ_FIRST(&sdev->free_ocbs);
if (ocb == NULL) {
sdev->flags |= ORB_SHORTAGE;
- printf("ocb shortage!!!\n");
- splx(s);
+ aprint_error_dev(sc->sc_fd.dev,
+ "ocb shortage!!!\n");
return NULL;
}
STAILQ_REMOVE_HEAD(&sdev->free_ocbs, ocb);
- splx(s);
- ocb->sxfer = NULL;
- return (ocb);
+ ocb->xs = NULL;
+ return ocb;
}
static void
sbp_free_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
{
+ struct sbp_softc *sc = sdev->target->sbp;
+ int count;
+
ocb->flags = 0;
- ocb->sxfer = NULL;
+ ocb->xs = NULL;
- SBP_LOCK(sdev->target->sbp);
+ mutex_enter(&sc->sc_mtx);
STAILQ_INSERT_TAIL(&sdev->free_ocbs, ocb, ocb);
- if ((sdev->flags & ORB_SHORTAGE) != 0) {
- int count;
-
+ mutex_exit(&sc->sc_mtx);
+ if (sdev->flags & ORB_SHORTAGE) {
sdev->flags &= ~ORB_SHORTAGE;
count = sdev->freeze;
sdev->freeze = 0;
- SBP_DEVICE_THAW(sdev, count);
+ if (sdev->periph)
+ scsipi_periph_thaw(sdev->periph, count);
+ scsipi_channel_thaw(&sc->sc_channel, 0);
}
- SBP_UNLOCK(sdev->target->sbp);
}
static void
sbp_abort_ocb(struct sbp_ocb *ocb, int status)
{
+ struct sbp_softc *sc;
struct sbp_dev *sdev;
sdev = ocb->sdev;
+ sc = sdev->target->sbp;
SBP_DEBUG(0)
- sbp_show_sdev_info(sdev, 2);
-#if defined(__DragonFly__) || \
- (defined(__FreeBSD__) && __FreeBSD_version < 500000)
- printf("sbp_abort_ocb 0x%x\n", ocb->bus_addr);
-#else
- printf("sbp_abort_ocb 0x%jx\n", (uintmax_t)ocb->bus_addr);
-#endif
+ printf("%s:%s:%s: sbp_abort_ocb 0x%jx\n", device_xname(sc->sc_fd.dev),
+ __func__, sdev->bustgtlun, (uintmax_t)ocb->bus_addr);
END_DEBUG
SBP_DEBUG(1)
- if (ocb->sxfer != NULL)
+ if (ocb->xs != NULL)
sbp_print_scsi_cmd(ocb);
END_DEBUG
if (ntohl(ocb->orb[4]) & 0xffff) {
- fw_bus_dmamap_sync(sdev->target->sbp->dmat, ocb->dmamap,
- (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
- BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
- fw_bus_dmamap_unload(sdev->target->sbp->dmat, ocb->dmamap);
+ const int flag = (ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
+ BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE;
+
+ bus_dmamap_sync(sc->sc_dmat, ocb->dmamap,
+ 0, ocb->dmamap->dm_mapsize, flag);
+ bus_dmamap_unload(sc->sc_dmat, ocb->dmamap);
}
- if (ocb->sxfer != NULL) {
-#if defined(__DragonFly__ ) || defined(__NetBSD__)
- fw_callout_stop(&SCSI_XFER_CALLOUT(ocb->sxfer));
-#else
- untimeout(sbp_timeout, (void *)ocb,
- SCSI_XFER_CALLOUT(ocb->sxfer));
-#endif
- SCSI_XFER_ERROR(ocb->sxfer) = status;
- SBP_LOCK(sdev->target->sbp);
- SCSI_TRANSFER_DONE(ocb->sxfer);
- SBP_UNLOCK(sdev->target->sbp);
+ if (ocb->xs != NULL) {
+ callout_stop(&ocb->xs->xs_callout);
+ ocb->xs->error = status;
+ scsipi_done(ocb->xs);
}
sbp_free_ocb(sdev, ocb);
}
@@ -3133,14 +2587,16 @@ END_DEBUG
static void
sbp_abort_all_ocbs(struct sbp_dev *sdev, int status)
{
- int s;
+ struct sbp_softc *sc = sdev->target->sbp;
struct sbp_ocb *ocb, *next;
STAILQ_HEAD(, sbp_ocb) temp;
- s = splfw();
-
- memcpy(&temp, &sdev->ocbs, sizeof(temp));
+ mutex_enter(&sc->sc_mtx);
+ STAILQ_INIT(&temp);
+ STAILQ_CONCAT(&temp, &sdev->ocbs);
STAILQ_INIT(&sdev->ocbs);
+ mutex_exit(&sc->sc_mtx);
+
for (ocb = STAILQ_FIRST(&temp); ocb != NULL; ocb = next) {
next = STAILQ_NEXT(ocb, ocb);
sbp_abort_ocb(ocb, status);
@@ -3149,98 +2605,4 @@ sbp_abort_all_ocbs(struct sbp_dev *sdev, int status)
sbp_free_ocb(sdev, sdev->last_ocb);
sdev->last_ocb = NULL;
}
-
- splx(s);
}
-
-#if defined(__FreeBSD__)
-static devclass_t sbp_devclass;
-
-static device_method_t sbp_methods[] = {
- /* device interface */
- DEVMETHOD(device_probe, sbp_probe),
- DEVMETHOD(device_attach, sbp_attach),
- DEVMETHOD(device_detach, sbp_detach),
- DEVMETHOD(device_shutdown, sbp_shutdown),
-
- { 0, 0 }
-};
-
-static driver_t sbp_driver = {
- "sbp",
- sbp_methods,
- sizeof(struct sbp_softc),
-};
-#ifdef __DragonFly__
-DECLARE_DUMMY_MODULE(sbp);
-#endif
-DRIVER_MODULE(sbp, firewire, sbp_driver, sbp_devclass, 0, 0);
-MODULE_VERSION(sbp, 1);
-MODULE_DEPEND(sbp, firewire, 1, 1, 1);
-MODULE_DEPEND(sbp, cam, 1, 1, 1);
-#elif defined(__NetBSD__)
-static void
-sbp_scsipi_request(
- struct scsipi_channel *channel, scsipi_adapter_req_t req, void *arg)
-{
- int i, s;
- struct sbp_softc *sbp =
- device_private(channel->chan_adapter->adapt_dev);
- struct scsipi_xfer *xs = arg;
-
- if (debug > 1)
- printf("Called sbpscsi_scsipi_request\n");
-
- switch (req) {
- case ADAPTER_REQ_RUN_XFER:
- if (debug > 1) {
- printf("Got req_run_xfer\n");
- printf("xs control: 0x%08x, timeout: %d\n",
- xs->xs_control, xs->timeout);
- printf("opcode: 0x%02x\n", (int)xs->cmd->opcode);
- for (i = 0; i < 15; i++)
- printf("0x%02x ",(int)xs->cmd->bytes[i]);
- printf("\n");
- }
- if (xs->xs_control & XS_CTL_RESET) {
- if (debug > 1)
- printf("XS_CTL_RESET not support\n");
- break;
- }
-#define SBPSCSI_SBP2_MAX_CDB 12
- if (xs->cmdlen > SBPSCSI_SBP2_MAX_CDB) {
- if (debug > 0)
- printf(
- "sbp doesn't support cdb's larger than %d "
- "bytes\n", SBPSCSI_SBP2_MAX_CDB);
- SCSI_XFER_ERROR(xs) = XS_REQ_INVALID;
- SCSI_TRANSFER_DONE(xs);
- return;
- }
- s = splfw();
- sbp_action1(sbp, xs);
- splx(s);
-
- break;
- case ADAPTER_REQ_GROW_RESOURCES:
- if (debug > 1)
- printf("Got req_grow_resources\n");
- break;
- case ADAPTER_REQ_SET_XFER_MODE:
- if (debug > 1)
- printf("Got set xfer mode\n");
- break;
- default:
- panic("Unknown request: %d\n", (int)req);
- }
-}
-
-static void
-sbp_minphys(struct buf *bp)
-{
- minphys(bp);
-}
-
-CFATTACH_DECL_NEW(sbp, sizeof(struct sbp_softc),
- sbpmatch, sbpattach, sbpdetach, NULL);
-#endif
diff --git a/sys/dev/ieee1394/sbp.h b/sys/dev/ieee1394/sbp.h
index 34d8a0937c6..5ce279bdfbb 100644
--- a/sys/dev/ieee1394/sbp.h
+++ b/sys/dev/ieee1394/sbp.h
@@ -1,4 +1,4 @@
-/* $NetBSD: sbp.h,v 1.3 2006/02/25 02:28:58 wiz Exp $ */
+/* $NetBSD: sbp.h,v 1.4 2010/03/29 03:05:28 kiyohara Exp $ */
/*-
* Copyright (c) 2003 Hidetoshi Shimokawa
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
@@ -31,10 +31,12 @@
* 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.
- *
- * $FreeBSD: /repoman/r/ncvs/src/sys/dev/firewire/sbp.h,v 1.5 2005/01/06 01:42:41 imp Exp $
+ *
+ * $FreeBSD: src/sys/dev/firewire/sbp.h,v 1.6 2009/04/07 02:33:46 sbruno Exp $
*
*/
+#ifndef _SBP_H_
+#define _SBP_H_
#define ORB_NOTIFY (1 << 31)
#define ORB_FMT_STD (0 << 29)
@@ -117,7 +119,7 @@ struct sbp_status{
/* 3: Page size not supported */
/* 4: Access denied */
#define STATUS_ACCESS_DENY 4
-/* 5: Logical unit not supported */
+#define STATUS_LUR 5
/* 6: Maximum payload too small */
/* 7: Reserved for future standardization */
/* 8: Resource unavailabe */
@@ -229,3 +231,5 @@ struct scsi3_sense_data {
uint8_t asb[14]; /* Additional sense bytes */
};
typedef struct scsi3_sense_data *scsi3_sense_data_t;
+
+#endif /* _SBP_H_ */
diff --git a/sys/dev/pci/fwohci_pci.c b/sys/dev/pci/fwohci_pci.c
index 2964fd57dc5..75cf99d6c43 100644
--- a/sys/dev/pci/fwohci_pci.c
+++ b/sys/dev/pci/fwohci_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fwohci_pci.c,v 1.36 2010/02/24 22:38:00 dyoung Exp $ */
+/* $NetBSD: fwohci_pci.c,v 1.37 2010/03/29 03:05:27 kiyohara Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -30,21 +30,19 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fwohci_pci.c,v 1.36 2010/02/24 22:38:00 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fwohci_pci.c,v 1.37 2010/03/29 03:05:27 kiyohara Exp $");
#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/socket.h>
-#include <sys/device.h>
-#include <sys/select.h>
-
#include <sys/bus.h>
+#include <sys/device.h>
#include <sys/intr.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <dev/pci/pcidevs.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
-#include <dev/pci/pcidevs.h>
-#include <dev/ieee1394/fw_port.h>
#include <dev/ieee1394/firewire.h>
#include <dev/ieee1394/firewirereg.h>
#include <dev/ieee1394/fwdma.h>
@@ -122,7 +120,7 @@ fwohci_pci_attach(device_t parent, device_t self, void *aux)
}
/* Disable interrupts, so we don't get any spurious ones. */
- OHCI_CSR_WRITE(&psc->psc_sc, FWOHCI_INTMASKCLR, OHCI_INT_EN);
+ OWRITE(&psc->psc_sc, FWOHCI_INTMASKCLR, OHCI_INT_EN);
/* Enable the device. */
csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
@@ -135,7 +133,7 @@ fwohci_pci_attach(device_t parent, device_t self, void *aux)
goto fail;
}
intrstr = pci_intr_string(pa->pa_pc, ih);
- psc->psc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, fwohci_filt,
+ psc->psc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, fwohci_intr,
&psc->psc_sc);
if (psc->psc_ih == NULL) {
aprint_error_dev(self, "couldn't establish interrupt");
@@ -149,7 +147,7 @@ fwohci_pci_attach(device_t parent, device_t self, void *aux)
if (!pmf_device_register(self, fwohci_pci_suspend, fwohci_pci_resume))
aprint_error_dev(self, "couldn't establish power handler\n");
- if (fwohci_init(&(psc->psc_sc), psc->psc_sc.fc.dev) != 0) {
+ if (fwohci_init(&psc->psc_sc) != 0) {
pci_intr_disestablish(pa->pa_pc, psc->psc_ih);
bus_space_unmap(psc->psc_sc.bst, psc->psc_sc.bsh,
psc->psc_sc.bssize);
@@ -172,7 +170,7 @@ fwohci_pci_suspend(device_t dv, const pmf_qual_t *qual)
int s;
s = splbio();
- fwohci_stop(&psc->psc_sc, psc->psc_sc.fc.dev);
+ fwohci_stop(&psc->psc_sc);
splx(s);
return true;
@@ -185,7 +183,7 @@ fwohci_pci_resume(device_t dv, const pmf_qual_t *qual)
int s;
s = splbio();
- fwohci_resume(&psc->psc_sc, psc->psc_sc.fc.dev);
+ fwohci_resume(&psc->psc_sc);
splx(s);
return true;