summaryrefslogtreecommitdiff
path: root/sys/dev/ieee1394/fwohci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ieee1394/fwohci.c')
-rw-r--r--sys/dev/ieee1394/fwohci.c1885
1 files changed, 1241 insertions, 644 deletions
diff --git a/sys/dev/ieee1394/fwohci.c b/sys/dev/ieee1394/fwohci.c
index 30ddb2787ca..05116581f96 100644
--- a/sys/dev/ieee1394/fwohci.c
+++ b/sys/dev/ieee1394/fwohci.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: fwohci.c,v 1.4 2002/10/12 02:03:46 krw Exp $ */
+/* $OpenBSD: fwohci.c,v 1.5 2002/12/13 02:52:04 tdeval Exp $ */
/* $NetBSD: fwohci.c,v 1.54 2002/03/29 05:06:42 jmc Exp $ */
-/*-
+/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
@@ -18,8 +18,8 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
@@ -50,14 +50,14 @@
*/
#include <sys/cdefs.h>
-#ifdef __KERNEL_RCSID
+#ifdef __KERNEL_RCSID
__KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.54 2002/03/29 05:06:42 jmc Exp $");
#endif
-#define DOUBLEBUF 1
-#define NO_THREAD 0
+#define DOUBLEBUF 0
+#define NO_THREAD 0
-#ifdef __NetBSD__
+#ifdef __NetBSD__
#include "opt_inet.h"
#endif
@@ -65,7 +65,7 @@ __KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.54 2002/03/29 05:06:42 jmc Exp $");
#include <sys/systm.h>
#include <sys/kthread.h>
#include <sys/socket.h>
-#ifdef __NetBSD__
+#ifdef __NetBSD__
#include <sys/callout.h>
#else
#include <sys/timeout.h>
@@ -74,11 +74,11 @@ __KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.54 2002/03/29 05:06:42 jmc Exp $");
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
-#ifdef __OpenBSD__
+#ifdef __OpenBSD__
#include <sys/endian.h>
#endif
-#if __NetBSD_Version__ >= 105010000 || !defined(__NetBSD__)
+#if __NetBSD_Version__ >= 105010000 || !defined(__NetBSD__)
#include <uvm/uvm_extern.h>
#else
#include <vm/vm.h>
@@ -93,21 +93,23 @@ __KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.54 2002/03/29 05:06:42 jmc Exp $");
#include <dev/ieee1394/ieee1394var.h>
#include <dev/ieee1394/fwohcivar.h>
-static const char * const ieee1394_speeds[] = { IEEE1394_SPD_STRINGS };
+const char * const ieee1394_speeds[] = { IEEE1394_SPD_STRINGS };
#if 0
-int fwohci_dnamem_alloc(struct fwohci_softc *sc, int size,
+int fwohci_dmamem_alloc(struct fwohci_softc *sc, int size,
int alignment, bus_dmamap_t *mapp, caddr_t *kvap, int flags);
#endif
void fwohci_create_event_thread(void *);
void fwohci_thread_init(void *);
void fwohci_event_thread(struct fwohci_softc *);
+void fwohci_event_dispatch(struct fwohci_softc *);
void fwohci_hw_init(struct fwohci_softc *);
void fwohci_power(int, void *);
void fwohci_shutdown(void *);
int fwohci_desc_alloc(struct fwohci_softc *);
+void fwohci_desc_free(struct fwohci_softc *);
struct fwohci_desc *fwohci_desc_get(struct fwohci_softc *, int);
void fwohci_desc_put(struct fwohci_softc *, struct fwohci_desc *, int);
@@ -120,8 +122,8 @@ int fwohci_buf_alloc(struct fwohci_softc *, struct fwohci_buf *);
void fwohci_buf_free(struct fwohci_softc *, struct fwohci_buf *);
void fwohci_buf_init_rx(struct fwohci_softc *);
void fwohci_buf_start_rx(struct fwohci_softc *);
-void fwohci_buf_stop_tx(struct fwohci_softc *);
void fwohci_buf_stop_rx(struct fwohci_softc *);
+void fwohci_buf_stop_tx(struct fwohci_softc *);
void fwohci_buf_next(struct fwohci_softc *, struct fwohci_ctx *);
int fwohci_buf_pktget(struct fwohci_softc *, struct fwohci_buf **,
caddr_t *, int);
@@ -137,6 +139,8 @@ void fwohci_phy_input(struct fwohci_softc *, struct fwohci_pkt *);
int fwohci_handler_set(struct fwohci_softc *, int, u_int32_t, u_int32_t,
int (*)(struct fwohci_softc *, void *, struct fwohci_pkt *), void *);
+int fwohci_block_handler_set(struct fwohci_softc *, int, u_int32_t, u_int32_t,
+ int, int (*)(struct fwohci_softc *, void *, struct fwohci_pkt *), void *);
void fwohci_arrq_input(struct fwohci_softc *, struct fwohci_ctx *);
void fwohci_arrs_input(struct fwohci_softc *, struct fwohci_ctx *);
@@ -184,28 +188,45 @@ int fwohci_inreg(struct ieee1394_abuf *, int);
int fwohci_unreg(struct ieee1394_abuf *, int);
int fwohci_parse_input(struct fwohci_softc *, void *,
struct fwohci_pkt *);
-#ifdef __NetBSD__
+#ifdef __NetBSD__
int fwohci_submatch(struct device *, struct cfdata *, void *);
#else
int fwohci_submatch(struct device *, void *, void *);
#endif
u_int16_t fwohci_crc16(u_int32_t *, int);
-#ifdef FW_DEBUG
+#ifdef FWOHCI_DEBUG
void fwohci_show_intr(struct fwohci_softc *, u_int32_t);
void fwohci_show_phypkt(struct fwohci_softc *, u_int32_t);
/* 1 is normal debug, 2 is verbose debug, 3 is complete (packet dumps). */
-#define DPRINTF(x) if (fwdebug) printf x
-#define DPRINTFN(n,x) if (fwdebug>(n)) printf x
-int fwdebug = 1;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#ifdef __OpenBSD__
+#include <sys/syslog.h>
+extern int log_open;
+int fwohci_oldlog;
+#define DPRINTF(x) if (fwohcidebug) do { \
+ fwohci_oldlog = log_open; log_open = 1; \
+ addlog x; log_open = fwohci_oldlog; \
+} while (0)
+#define DPRINTFN(n,x) if (fwohcidebug>(n)) do { \
+ fwohci_oldlog = log_open; log_open = 1; \
+ addlog x; log_open = fwohci_oldlog; \
+} while (0)
+#define MPRINTF(x,y) DPRINTF(("%s[%d]: %s 0x%08x\n", \
+ __func__, __LINE__, (x), (u_int32_t)(y)))
+
+int fwohcidebug = 0;
+int fwintr = 0;
+caddr_t fwptr = 0;
+int fwlen = 0;
+struct fwohci_buf *fwbuf = NULL;
+#else /* FWOHCI_DEBUG */
+#define DPRINTF(x)
+#define DPRINTFN(n,x)
+#define MPRINTF(x,y)
+#endif /* ! FWOHCI_DEBUG */
+
+#ifdef __OpenBSD__
struct cfdriver fwohci_cd = {
NULL, "fwohci", DV_DULL
};
@@ -220,7 +241,7 @@ fwohci_init(struct fwohci_softc *sc, const struct evcnt *ev)
int error;
#endif
-#ifdef __NetBSD__
+#ifdef __NetBSD__
evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ev,
sc->sc_sc1394.sc1394_dev.dv_xname, "intr");
@@ -231,7 +252,7 @@ fwohci_init(struct fwohci_softc *sc, const struct evcnt *ev)
#endif
/*
- * Wait for reset completion
+ * Wait for reset completion.
*/
for (i = 0; i < OHCI_LOOP; i++) {
val = OHCI_CSR_READ(sc, OHCI_REG_HCControlClear);
@@ -240,7 +261,8 @@ fwohci_init(struct fwohci_softc *sc, const struct evcnt *ev)
DELAY(10);
}
- /* What dialect of OHCI is this device?
+ /*
+ * What dialect of OHCI is this device ?
*/
val = OHCI_CSR_READ(sc, OHCI_REG_Version);
printf("%s: OHCI %u.%u", sc->sc_sc1394.sc1394_dev.dv_xname,
@@ -260,7 +282,8 @@ fwohci_init(struct fwohci_softc *sc, const struct evcnt *ev)
sc->sc_sc1394.sc1394_guid[4], sc->sc_sc1394.sc1394_guid[5],
sc->sc_sc1394.sc1394_guid[6], sc->sc_sc1394.sc1394_guid[7]);
- /* Get the maximum link speed and receive size
+ /*
+ * Get the maximum link speed and receive size.
*/
val = OHCI_CSR_READ(sc, OHCI_REG_BusOptions);
sc->sc_sc1394.sc1394_link_speed =
@@ -271,8 +294,9 @@ fwohci_init(struct fwohci_softc *sc, const struct evcnt *ev)
} else {
printf(", unknown speed %u", sc->sc_sc1394.sc1394_link_speed);
}
-
- /* MaxRec is encoded as log2(max_rec_octets)-1
+
+ /*
+ * MaxRec is encoded as log2(max_rec_octets)-1
*/
sc->sc_sc1394.sc1394_max_receive =
1 << (OHCI_BITVAL(val, OHCI_BusOptions_MaxRec) + 1);
@@ -290,26 +314,29 @@ fwohci_init(struct fwohci_softc *sc, const struct evcnt *ev)
}
sc->sc_isoctx = i;
printf(", %d iso_ctx", sc->sc_isoctx);
-
+
printf("\n");
#if 0
- error = fwohci_dnamem_alloc(sc, OHCI_CONFIG_SIZE,
+ error = fwohci_dmamem_alloc(sc, OHCI_CONFIG_SIZE,
OHCI_CONFIG_ALIGNMENT, &sc->sc_configrom_map,
(caddr_t *) &sc->sc_configrom, BUS_DMA_WAITOK|BUS_DMA_COHERENT);
return error;
#endif
- sc->sc_dying = 0;
+ MALLOC(sc->sc_dying, int *, sizeof(int), M_DEVBUF, M_WAITOK);
+ //MPRINTF_OLD("MALLOC(DEVBUF)", sc->sc_dying);
+ DPRINTF(("%s: sc_dying 0x%08x\n", __func__, (u_int32_t)sc->sc_dying));
+ *sc->sc_dying = 0;
sc->sc_nodeid = 0xffff; /* invalid */
-#ifdef __NetBSD__
+#ifdef __NetBSD__
kthread_create(fwohci_create_event_thread, sc);
#else
if (initproc == NULL)
kthread_create_deferred(fwohci_create_event_thread, sc);
- else /* late binding, threads
- already running */
+ else
+ /* Late binding, threads already running. */
fwohci_create_event_thread(sc);
#endif
@@ -329,7 +356,7 @@ fwohci_if_setiso(struct device *self, u_int32_t channel, u_int32_t tag,
}
s = splnet();
- retval = fwohci_handler_set(sc, IEEE1394_TCODE_STREAM_DATA,
+ retval = fwohci_handler_set(sc, IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK,
channel, tag, fwohci_if_input_iso, handler);
splx(s);
@@ -348,45 +375,92 @@ int
fwohci_intr(void *arg)
{
struct fwohci_softc * const sc = arg;
+#if 1
int progress = 0;
+#else
+ int progress = (sc->sc_intmask != 0);
+#endif
u_int32_t intmask, iso;
+ splassert(IPL_BIO);
+
+#ifdef FWOHCI_DEBUG
+ //DPRINTFN(3,("%s: in(%d)\n", __func__, fwintr));
+ fwintr++;
+#endif /* FWOHCI_DEBUG */
+
+#if 1
for (;;) {
+#endif
intmask = OHCI_CSR_READ(sc, OHCI_REG_IntEventClear);
/*
* On a bus reset, everything except bus reset gets
- * cleared. That can't get cleared until the selfid
+ * cleared. That can't get cleared until the selfid
* phase completes (which happens outside the
* interrupt routines). So if just a bus reset is left
* in the mask and it's already in the sc_intmask,
* just return.
*/
- if ((intmask == 0) ||
+ if ((intmask == 0xffffffff) || (intmask == 0) ||
(progress && (intmask == OHCI_Int_BusReset) &&
- (sc->sc_intmask & OHCI_Int_BusReset))) {
- if (progress)
+ (sc->sc_intmask & OHCI_Int_BusReset))) {
+
+ if (intmask == 0xffffffff)
+ config_detach(((struct device *)sc)
+ ->dv_parent, 0);
+
+ if (progress) {
+#if NO_THREAD
+ fwohci_event_dispatch(sc);
+#else /* NO_THREAD */
wakeup(fwohci_event_thread);
- return progress;
+#endif /* NO_THREAD */
+ }
+
+#ifdef FWOHCI_DEBUG
+ --fwintr;
+ //DPRINTFN(3,("%s: out(%d)\n", __func__, fwintr));
+#endif /* FWOHCI_DEBUG */
+
+ return (progress);
}
+#if 1
+ OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear,
+ intmask & ~OHCI_Int_BusReset);
+#else
+ DPRINTFN(2,("%s: IntEventClear(0x%08x) IntMaskClear(0x%08x)\n",
+ __func__,
+ intmask & ~OHCI_Int_BusReset,
+ intmask & ~OHCI_Int_BusReset & ~OHCI_Int_MasterEnable));
+ OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskClear,
+ intmask & ~OHCI_Int_BusReset & ~OHCI_Int_MasterEnable);
OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear,
intmask & ~OHCI_Int_BusReset);
-#ifdef FW_DEBUG
- if (fwdebug > 1)
- fwohci_show_intr(sc, intmask);
#endif
+#ifdef FWOHCI_DEBUG
+ if (fwohcidebug > 1)
+ fwohci_show_intr(sc, intmask);
+#endif /* FWOHCI_DEBUG */
if (intmask & OHCI_Int_BusReset) {
/*
* According to OHCI spec 6.1.1 "busReset",
- * All asynchronous transmit must be stopped before
- * clearing BusReset. Moreover, the BusReset
+ * all asynchronous transmit must be stopped before
+ * clearing BusReset. Moreover, the BusReset
* interrupt bit should not be cleared during the
- * SelfID phase. Thus we turned off interrupt mask
+ * SelfID phase. Thus we turned off interrupt mask
* bit of BusReset instead until SelfID completion
* or SelfID timeout.
*/
+#if 0
+ DPRINTFN(2,("%s: IntMaskSet(0x%08x)"
+ " IntMaskClear(0x%08x)\n", __func__,
+ intmask & ~OHCI_Int_BusReset, OHCI_Int_BusReset));
+ OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet,
+ intmask & ~OHCI_Int_BusReset);
+#endif
intmask &= OHCI_Int_SelfIDComplete;
OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskClear,
OHCI_Int_BusReset);
@@ -396,26 +470,39 @@ fwohci_intr(void *arg)
if (intmask & OHCI_Int_IsochTx) {
iso = OHCI_CSR_READ(sc, OHCI_REG_IsoXmitIntEventClear);
+#if 1
OHCI_CSR_WRITE(sc, OHCI_REG_IsoXmitIntEventClear, iso);
+#else
+ OHCI_CSR_WRITE(sc, OHCI_REG_IsoXmitIntEventClear,
+ sc->sc_isotxrst);
+#endif
}
if (intmask & OHCI_Int_IsochRx) {
-#if NO_THREAD
+#if NO_THREAD
int i;
int asyncstream = 0;
-#endif
+#endif /* NO_THREAD */
iso = OHCI_CSR_READ(sc, OHCI_REG_IsoRecvIntEventClear);
+#if 1
OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntEventClear, iso);
-#if NO_THREAD
+#else
+ OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntEventClear,
+ sc->sc_isorxrst);
+#endif
+#if NO_THREAD
for (i = 0; i < sc->sc_isoctx; i++) {
- if ((iso & (1<<i)) && sc->sc_ctx_ir[i] != NULL) {
- if (sc->sc_ctx_ir[i]->fc_type == FWOHCI_CTX_ISO_SINGLE) {
+ if ((iso & (1<<i)) &&
+ sc->sc_ctx_ir[i] != NULL) {
+ if (sc->sc_ctx_ir[i]->fc_type ==
+ FWOHCI_CTX_ISO_SINGLE) {
asyncstream |= (1 << i);
continue;
}
bus_dmamap_sync(sc->sc_dmat,
sc->sc_ddmamap,
- 0, sizeof(struct fwohci_desc) * sc->sc_descsize,
+ 0, sizeof(struct fwohci_desc) *
+ sc->sc_descsize,
BUS_DMASYNC_PREREAD);
sc->sc_isocnt.ev_count++;
@@ -425,19 +512,30 @@ fwohci_intr(void *arg)
if (asyncstream != 0) {
sc->sc_iso |= asyncstream;
} else {
- /* all iso intr is pure isochronous */
+ /* All iso intr is pure isochronous. */
sc->sc_intmask &= ~OHCI_Int_IsochRx;
}
-#else
+#else /* NO_THREAD */
sc->sc_iso |= iso;
-#endif /* NO_THREAD */
+#endif /* NO_THREAD */
}
if (!progress) {
sc->sc_intrcnt.ev_count++;
+#if 1
progress = 1;
+#endif
}
+#if 1
}
+#else
+#ifdef FWOHCI_DEBUG
+ --fwintr;
+ //DPRINTF(("%s: out(%d)\n", __func__, fwintr));
+#endif /* FWOHCI_DEBUG */
+
+ return (progress);
+#endif
}
void
@@ -445,7 +543,7 @@ fwohci_create_event_thread(void *arg)
{
struct fwohci_softc *sc = arg;
-#ifdef __NetBSD__
+#ifdef __NetBSD__
if (kthread_create1(fwohci_thread_init, sc, &sc->sc_event_thread, "%s",
sc->sc_sc1394.sc1394_dev.dv_xname))
#else
@@ -466,7 +564,7 @@ fwohci_thread_init(void *arg)
int i;
/*
- * Allocate descriptors
+ * Allocate descriptors.
*/
if (fwohci_desc_alloc(sc)) {
printf("%s: not enabling interrupts\n",
@@ -475,34 +573,35 @@ fwohci_thread_init(void *arg)
}
/*
- * Enable Link Power
+ * Enable Link Power.
*/
OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, OHCI_HCControl_LPS);
/*
- * Allocate DMA Context
+ * Allocate DMA Context.
*/
fwohci_ctx_alloc(sc, &sc->sc_ctx_arrq, OHCI_BUF_ARRQ_CNT,
OHCI_CTX_ASYNC_RX_REQUEST, FWOHCI_CTX_ASYNC);
fwohci_ctx_alloc(sc, &sc->sc_ctx_arrs, OHCI_BUF_ARRS_CNT,
OHCI_CTX_ASYNC_RX_RESPONSE, FWOHCI_CTX_ASYNC);
- fwohci_ctx_alloc(sc, &sc->sc_ctx_atrq, 0, OHCI_CTX_ASYNC_TX_REQUEST,
- FWOHCI_CTX_ASYNC);
- fwohci_ctx_alloc(sc, &sc->sc_ctx_atrs, 0, OHCI_CTX_ASYNC_TX_RESPONSE,
- FWOHCI_CTX_ASYNC);
+ fwohci_ctx_alloc(sc, &sc->sc_ctx_atrq, 0,
+ OHCI_CTX_ASYNC_TX_REQUEST, FWOHCI_CTX_ASYNC);
+ fwohci_ctx_alloc(sc, &sc->sc_ctx_atrs, 0,
+ OHCI_CTX_ASYNC_TX_RESPONSE, FWOHCI_CTX_ASYNC);
sc->sc_ctx_ir = malloc(sizeof(sc->sc_ctx_ir[0]) * sc->sc_isoctx,
M_DEVBUF, M_WAITOK);
+ //MPRINTF_OLD("malloc(DEVBUF)", sc->sc_ctx_ir);
for (i = 0; i < sc->sc_isoctx; i++)
sc->sc_ctx_ir[i] = NULL;
/*
- * Allocate buffer for configuration ROM and SelfID buffer
+ * Allocate buffer for configuration ROM and SelfID buffer.
*/
fwohci_buf_alloc(sc, &sc->sc_buf_cnfrom);
fwohci_buf_alloc(sc, &sc->sc_buf_selfid);
-#ifdef __NetBSD__
+#ifdef __NetBSD__
callout_init(&sc->sc_selfid_callout);
#else
bzero(&sc->sc_selfid_callout, sizeof(sc->sc_selfid_callout));
@@ -513,7 +612,7 @@ fwohci_thread_init(void *arg)
sc->sc_sc1394.sc1394_ifsetiso = fwohci_if_setiso;
/*
- * establish hooks for shutdown and suspend/resume
+ * Establish hooks for shutdown and suspend/resume.
*/
sc->sc_shutdownhook = shutdownhook_establish(fwohci_shutdown, sc);
sc->sc_powerhook = powerhook_establish(fwohci_power, sc);
@@ -524,15 +623,41 @@ fwohci_thread_init(void *arg)
/* Main loop. It's not coming back normally. */
fwohci_event_thread(sc);
+ printf("%s: event thread exited\n", __func__);
+
+ if (sc->sc_uidtbl != NULL) {
+ free(sc->sc_uidtbl, M_DEVBUF);
+ //MPRINTF_OLD("free(DEVBUF)", sc->sc_uidtbl);
+ sc->sc_uidtbl = NULL;
+ }
+ fwohci_buf_free(sc, &sc->sc_buf_selfid);
+ fwohci_buf_free(sc, &sc->sc_buf_cnfrom);
+
+ free(sc->sc_ctx_ir, M_DEVBUF);
+ //MPRINTF_OLD("free(DEVBUF)", sc->sc_ctx_ir);
+ sc->sc_ctx_ir = NULL; /* XXX */
+ fwohci_ctx_free(sc, sc->sc_ctx_atrs);
+ fwohci_ctx_free(sc, sc->sc_ctx_atrq);
+ fwohci_ctx_free(sc, sc->sc_ctx_arrs);
+ fwohci_ctx_free(sc, sc->sc_ctx_arrq);
+
+ fwohci_desc_free(sc);
+
+ DPRINTF(("%s: waking up... 0x%08x\n", __func__,
+ (u_int32_t)sc->sc_dying));
+ wakeup(sc->sc_dying);
kthread_exit(0);
}
void
fwohci_event_thread(struct fwohci_softc *sc)
{
- int i, s;
- u_int32_t intmask, iso;
+ int s;
+#if ! NO_THREAD
+ int i;
+ uint32_t intmask, iso;
+#endif /* NO_THREAD */
s = splbio();
@@ -542,29 +667,41 @@ fwohci_event_thread(struct fwohci_softc *sc)
fwohci_hw_init(sc);
- /* Initial Bus Reset */
+ /* Initial Bus Reset. */
fwohci_phy_busreset(sc);
splx(s);
- while (!sc->sc_dying) {
+ while (! *sc->sc_dying) {
+#if ! NO_THREAD
s = splbio();
intmask = sc->sc_intmask;
if (intmask == 0) {
+#endif /* NO_THREAD */
+#if 1
+ tsleep(fwohci_event_thread, PZERO, "fwohciev", 8);
+#else
tsleep(fwohci_event_thread, PZERO, "fwohciev", 0);
+#endif
+#if ! NO_THREAD
splx(s);
continue;
}
sc->sc_intmask = 0;
splx(s);
+ DPRINTFN(2, ("%s: treating interrupts 0x%08x\n", __func__,
+ intmask));
if (intmask & OHCI_Int_BusReset) {
+// s = splbio();
fwohci_buf_stop_tx(sc);
+// splx(s);
if (sc->sc_uidtbl != NULL) {
free(sc->sc_uidtbl, M_DEVBUF);
+ //MPRINTF_OLD("free(DEVBUF)", sc->sc_uidtbl);
sc->sc_uidtbl = NULL;
}
-#ifdef __NetBSD__
+#ifdef __NetBSD__
callout_reset(&sc->sc_selfid_callout,
OHCI_SELFID_TIMEOUT,
(void (*)(void *))fwohci_phy_busreset, sc);
@@ -574,7 +711,7 @@ fwohci_event_thread(struct fwohci_softc *sc)
timeout_add(&sc->sc_selfid_callout,
OHCI_SELFID_TIMEOUT);
#endif
- sc->sc_nodeid = 0xffff; /* indicate invalid */
+ sc->sc_nodeid = 0xffff; /* Indicate invalid. */
sc->sc_rootid = 0;
sc->sc_irmid = IEEE1394_BCAST_PHY_ID;
}
@@ -585,24 +722,34 @@ fwohci_event_thread(struct fwohci_softc *sc)
OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet,
OHCI_Int_BusReset);
splx(s);
-#ifdef __NetBSD__
+#ifdef __NetBSD__
callout_stop(&sc->sc_selfid_callout);
#else
timeout_del(&sc->sc_selfid_callout);
#endif
if (fwohci_selfid_input(sc) == 0) {
+// s = splbio();
fwohci_buf_start_rx(sc);
+// splx(s);
fwohci_uid_collect(sc);
}
}
- if (intmask & OHCI_Int_ReqTxComplete)
+ if (intmask & OHCI_Int_ReqTxComplete) {
+// s = splbio();
fwohci_at_done(sc, sc->sc_ctx_atrq, 0);
- if (intmask & OHCI_Int_RespTxComplete)
+// splx(s);
+ }
+ if (intmask & OHCI_Int_RespTxComplete) {
+// s = splbio();
fwohci_at_done(sc, sc->sc_ctx_atrs, 0);
- if (intmask & OHCI_Int_RQPkt)
+// splx(s);
+ }
+ if (intmask & OHCI_Int_RQPkt) {
fwohci_arrq_input(sc, sc->sc_ctx_arrq);
- if (intmask & OHCI_Int_RSPkt)
+ }
+ if (intmask & OHCI_Int_RSPkt) {
fwohci_arrs_input(sc, sc->sc_ctx_arrs);
+ }
if (intmask & OHCI_Int_IsochRx) {
s = splbio();
iso = sc->sc_iso;
@@ -616,12 +763,125 @@ fwohci_event_thread(struct fwohci_softc *sc)
}
}
}
+#if 0
+ DPRINTF(("%s: IntMaskSet(0x%08x)\n",
+ __func__, intmask & ~OHCI_Int_BusReset));
+ s = splbio();
+// OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear,
+// intmask & ~OHCI_Int_BusReset);
+ OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet,
+ intmask & ~OHCI_Int_BusReset);
+ splx(s);
+#endif
+#endif /* NO_THREAD */
+ }
+}
+
+#if NO_THREAD
+void
+fwohci_event_dispatch(struct fwohci_softc *sc)
+{
+ int i, s;
+ u_int32_t intmask, iso;
+
+ splassert(IPL_BIO);
+ intmask = sc->sc_intmask;
+ if (intmask == 0)
+ return;
+
+ sc->sc_intmask = 0;
+ s = spl0();
+ DPRINTFN(2, ("%s: treating interrupts 0x%08x\n", __func__, intmask));
+
+ if (intmask & OHCI_Int_BusReset) {
+// s = splbio();
+ fwohci_buf_stop_tx(sc);
+// splx(s);
+ if (sc->sc_uidtbl != NULL) {
+ free(sc->sc_uidtbl, M_DEVBUF);
+ //MPRINTF_OLD("free(DEVBUF)", sc->sc_uidtbl);
+ sc->sc_uidtbl = NULL;
+ }
+
+#ifdef __NetBSD__
+ callout_reset(&sc->sc_selfid_callout,
+ OHCI_SELFID_TIMEOUT,
+ (void (*)(void *))fwohci_phy_busreset, sc);
+#else
+ timeout_set(&sc->sc_selfid_callout,
+ (void (*)(void *))fwohci_phy_busreset, sc);
+ timeout_add(&sc->sc_selfid_callout,
+ OHCI_SELFID_TIMEOUT);
+#endif
+ sc->sc_nodeid = 0xffff; /* Indicate invalid. */
+ sc->sc_rootid = 0;
+ sc->sc_irmid = IEEE1394_BCAST_PHY_ID;
+ }
+ if (intmask & OHCI_Int_SelfIDComplete) {
+ splx(s);
+ OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear,
+ OHCI_Int_BusReset);
+ OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet,
+ OHCI_Int_BusReset);
+ s = spl0();
+#ifdef __NetBSD__
+ callout_stop(&sc->sc_selfid_callout);
+#else
+ timeout_del(&sc->sc_selfid_callout);
+#endif
+ if (fwohci_selfid_input(sc) == 0) {
+// s = splbio();
+ fwohci_buf_start_rx(sc);
+// splx(s);
+ fwohci_uid_collect(sc);
+ }
+ }
+ if (intmask & OHCI_Int_ReqTxComplete) {
+// s = splbio();
+ fwohci_at_done(sc, sc->sc_ctx_atrq, 0);
+// splx(s);
+ }
+ if (intmask & OHCI_Int_RespTxComplete) {
+// s = splbio();
+ fwohci_at_done(sc, sc->sc_ctx_atrs, 0);
+// splx(s);
+ }
+ if (intmask & OHCI_Int_RQPkt) {
+ fwohci_arrq_input(sc, sc->sc_ctx_arrq);
+ }
+ if (intmask & OHCI_Int_RSPkt) {
+ fwohci_arrs_input(sc, sc->sc_ctx_arrs);
+ }
+ if (intmask & OHCI_Int_IsochRx) {
+ splx(s);
+ iso = sc->sc_iso;
+ sc->sc_iso = 0;
+ s = spl0();
+ for (i = 0; i < sc->sc_isoctx; i++) {
+ if ((iso & (1 << i)) &&
+ sc->sc_ctx_ir[i] != NULL) {
+ fwohci_ir_input(sc, sc->sc_ctx_ir[i]);
+ sc->sc_isocnt.ev_count++;
+ }
+ }
}
+#if 0
+ DPRINTF(("%s: IntMaskSet(0x%08x)\n",
+ __func__, intmask & ~OHCI_Int_BusReset));
+ s = splbio();
+// OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear,
+// intmask & ~OHCI_Int_BusReset);
+ OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, intmask & ~OHCI_Int_BusReset);
+ splx(s);
+#endif
+ splx(s);
}
+#endif /* NO_THREAD */
+
#if 0
int
-fwohci_dnamem_alloc(struct fwohci_softc *sc, int size, int alignment,
+fwohci_dmamem_alloc(struct fwohci_softc *sc, int size, int alignment,
bus_dmamap_t *mapp, caddr_t *kvap, int flags)
{
bus_dma_segment_t segs[1];
@@ -632,6 +892,7 @@ fwohci_dnamem_alloc(struct fwohci_softc *sc, int size, int alignment,
segs, 1, &nsegs, flags);
if (error)
goto cleanup;
+ //MPRINTF_OLD("bus_dmamem_alloc", segs->ds_addr);
steps = 1;
error = bus_dmamem_map(sc->sc_dmat, segs, nsegs, segs[0].ds_len,
@@ -644,6 +905,8 @@ fwohci_dnamem_alloc(struct fwohci_softc *sc, int size, int alignment,
size, flags, mapp);
if (error)
goto cleanup;
+ //MPRINTF_OLD("bus_dmamap_create", mapp);
+
if (error == 0)
error = bus_dmamap_load(sc->sc_dmat, *mapp, *kvap, size, NULL,
flags);
@@ -654,6 +917,7 @@ fwohci_dnamem_alloc(struct fwohci_softc *sc, int size, int alignment,
switch (steps) {
case 1:
bus_dmamem_free(sc->sc_dmat, segs, nsegs);
+ //MPRINTF_OLD("bus_dmamem_free", segs->ds_addr);
}
return error;
@@ -677,6 +941,8 @@ fwohci_hw_init(struct fwohci_softc *sc)
int i;
u_int32_t val;
+ splassert(IPL_BIO);
+
/*
* Software Reset.
*/
@@ -689,18 +955,20 @@ fwohci_hw_init(struct fwohci_softc *sc)
}
OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, OHCI_HCControl_LPS);
+ DELAY(100000);
/*
- * First, initilize CSRs with undefined value to default settings.
+ * First, initialize CSRs with undefined value to default settings.
*/
val = OHCI_CSR_READ(sc, OHCI_REG_BusOptions);
val |= OHCI_BusOptions_ISC | OHCI_BusOptions_CMC;
-#if 0
+#if 1
val |= OHCI_BusOptions_BMC | OHCI_BusOptions_IRMC;
+ val |= OHCI_BusOptions_PMC;
#else
val &= ~(OHCI_BusOptions_BMC | OHCI_BusOptions_IRMC);
-#endif
val &= ~(OHCI_BusOptions_PMC);
+#endif
OHCI_CSR_WRITE(sc, OHCI_REG_BusOptions, val);
for (i = 0; i < sc->sc_isoctx; i++) {
OHCI_SYNC_RX_DMA_WRITE(sc, i, OHCI_SUBREG_ContextControlClear,
@@ -720,18 +988,32 @@ fwohci_hw_init(struct fwohci_softc *sc)
OHCI_LinkControl_CycleTimerEnable |
OHCI_LinkControl_RcvSelfID | OHCI_LinkControl_RcvPhyPkt);
+#if 0
OHCI_CSR_WRITE(sc, OHCI_REG_ATRetries, 0x00000888); /*XXX*/
+#else
+ OHCI_CSR_WRITE(sc, OHCI_REG_ATRetries, 0xffff0fff); /*XXX*/
+#endif
- /* clear receive filter */
+ /* Clear receive filter. */
OHCI_CSR_WRITE(sc, OHCI_REG_IRMultiChanMaskHiClear, ~0);
OHCI_CSR_WRITE(sc, OHCI_REG_IRMultiChanMaskLoClear, ~0);
OHCI_CSR_WRITE(sc, OHCI_REG_AsynchronousRequestFilterHiSet, 0x80000000);
+ OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet,
+ OHCI_HCControl_ProgramPhyEnable);
+#if 0
OHCI_CSR_WRITE(sc, OHCI_REG_HCControlClear,
- OHCI_HCControl_NoByteSwapData | OHCI_HCControl_APhyEnhanceEnable);
+ OHCI_HCControl_APhyEnhanceEnable);
+#else
+ OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet,
+ OHCI_HCControl_APhyEnhanceEnable);
+#endif
#if BYTE_ORDER == BIG_ENDIAN
OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet,
OHCI_HCControl_NoByteSwapData);
+#else
+ OHCI_CSR_WRITE(sc, OHCI_REG_HCControlClear,
+ OHCI_HCControl_NoByteSwapData);
#endif
OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskClear, ~0);
@@ -749,7 +1031,7 @@ fwohci_hw_init(struct fwohci_softc *sc)
OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet, OHCI_HCControl_LinkEnable);
/*
- * Start the receivers
+ * Start the receivers.
*/
fwohci_buf_start_rx(sc);
}
@@ -770,7 +1052,7 @@ fwohci_power(int why, void *arg)
fwohci_hw_init(sc);
fwohci_phy_busreset(sc);
break;
-#ifdef __NetBSD__
+#ifdef __NetBSD__
case PWR_SOFTSUSPEND:
case PWR_SOFTSTANDBY:
case PWR_SOFTRESUME:
@@ -786,12 +1068,14 @@ fwohci_shutdown(void *arg)
struct fwohci_softc *sc = arg;
u_int32_t val;
-#ifdef __NetBSD__
+ splassert(IPL_BIO);
+
+#ifdef __NetBSD__
callout_stop(&sc->sc_selfid_callout);
#else
timeout_del(&sc->sc_selfid_callout);
#endif
- /* disable all interrupt */
+ /* Disable all interrupt. */
OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskClear, OHCI_Int_MasterEnable);
fwohci_buf_stop_tx(sc);
fwohci_buf_stop_rx(sc);
@@ -806,11 +1090,11 @@ fwohci_shutdown(void *arg)
}
/*
- * COMMON FUNCTIONS
+ * COMMON FUNCTIONS.
*/
/*
- * read the PHY Register.
+ * Read the PHY Register.
*/
u_int8_t
fwohci_phy_read(struct fwohci_softc *sc, u_int8_t reg)
@@ -818,27 +1102,31 @@ fwohci_phy_read(struct fwohci_softc *sc, u_int8_t reg)
int i;
u_int32_t val;
+ splassert(IPL_BIO);
+
OHCI_CSR_WRITE(sc, OHCI_REG_PhyControl,
OHCI_PhyControl_RdReg |
((reg & 0xf) << OHCI_PhyControl_RegAddr_BITPOS));
for (i = 0; i < OHCI_LOOP; i++) {
- if (OHCI_CSR_READ(sc, OHCI_REG_PhyControl) &
- OHCI_PhyControl_RdDone)
+ val = OHCI_CSR_READ(sc, OHCI_REG_PhyControl);
+ if (!(val & OHCI_PhyControl_RdReg) &&
+ (val & OHCI_PhyControl_RdDone))
break;
DELAY(10);
}
- val = OHCI_CSR_READ(sc, OHCI_REG_PhyControl);
return (val & OHCI_PhyControl_RdData) >> OHCI_PhyControl_RdData_BITPOS;
}
/*
- * write the PHY Register.
+ * Write the PHY Register.
*/
void
fwohci_phy_write(struct fwohci_softc *sc, u_int8_t reg, u_int8_t val)
{
int i;
+ splassert(IPL_BIO);
+
OHCI_CSR_WRITE(sc, OHCI_REG_PhyControl, OHCI_PhyControl_WrReg |
((reg & 0xf) << OHCI_PhyControl_RegAddr_BITPOS) |
(val << OHCI_PhyControl_WrData_BITPOS));
@@ -851,7 +1139,7 @@ fwohci_phy_write(struct fwohci_softc *sc, u_int8_t reg, u_int8_t val)
}
/*
- * Initiate Bus Reset
+ * Initiate Bus Reset.
*/
void
fwohci_phy_busreset(struct fwohci_softc *sc)
@@ -859,25 +1147,27 @@ fwohci_phy_busreset(struct fwohci_softc *sc)
int s;
u_int8_t val;
+ splassert(IPL_BIO);
+
s = splbio();
OHCI_CSR_WRITE(sc, OHCI_REG_IntEventClear,
OHCI_Int_BusReset | OHCI_Int_SelfIDComplete);
OHCI_CSR_WRITE(sc, OHCI_REG_IntMaskSet, OHCI_Int_BusReset);
-#ifdef __NetBSD__
+#ifdef __NetBSD__
callout_stop(&sc->sc_selfid_callout);
#else
timeout_del(&sc->sc_selfid_callout);
#endif
val = fwohci_phy_read(sc, 1);
- val = (val & 0x80) | /* preserve RHB (force root) */
- 0x40 | /* Initiate Bus Reset */
- 0x3f; /* default GAP count */
+ val = (val & 0x80) | /* Preserve RHB (force root). */
+ 0x40 | /* Initiate Bus Reset. */
+ 0x3f; /* Default GAP count. */
fwohci_phy_write(sc, 1, val);
splx(s);
}
/*
- * PHY Packet
+ * PHY Packet.
*/
void
fwohci_phy_input(struct fwohci_softc *sc, struct fwohci_pkt *pkt)
@@ -888,7 +1178,7 @@ fwohci_phy_input(struct fwohci_softc *sc, struct fwohci_pkt *pkt)
if (val != ~pkt->fp_hdr[2]) {
if (val == 0 && ((*pkt->fp_trail & 0x001f0000) >> 16) ==
OHCI_CTXCTL_EVENT_BUS_RESET) {
- DPRINTFN(1, ("fwohci_phy_input: BusReset: 0x%08x\n",
+ DPRINTFN(1, ("%s: BusReset: 0x%08x\n", __func__,
pkt->fp_hdr[2]));
} else {
printf("%s: phy packet corrupted (0x%08x, 0x%08x)\n",
@@ -897,10 +1187,10 @@ fwohci_phy_input(struct fwohci_softc *sc, struct fwohci_pkt *pkt)
}
return;
}
-#ifdef FW_DEBUG
- if (fwdebug > 1)
+#ifdef FWOHCI_DEBUG
+ if (fwohcidebug > 1)
fwohci_show_phypkt(sc, val);
-#endif
+#endif /* FWOHCI_DEBUG */
}
/*
@@ -912,7 +1202,7 @@ fwohci_desc_alloc(struct fwohci_softc *sc)
int error, mapsize, dsize;
/*
- * allocate descriptor buffer
+ * Allocate descriptor buffer.
*/
sc->sc_descsize = OHCI_BUF_ARRQ_CNT + OHCI_BUF_ARRS_CNT +
@@ -920,37 +1210,50 @@ fwohci_desc_alloc(struct fwohci_softc *sc)
OHCI_BUF_IR_CNT * sc->sc_isoctx + 2;
dsize = sizeof(struct fwohci_desc) * sc->sc_descsize;
mapsize = howmany(sc->sc_descsize, NBBY);
-#ifdef M_ZERO
+#ifdef M_ZERO
sc->sc_descmap = malloc(mapsize, M_DEVBUF, M_WAITOK|M_ZERO);
+ //MPRINTF_OLD("malloc(DEVBUF)", sc->sc_descmap);
#else
sc->sc_descmap = malloc(mapsize, M_DEVBUF, M_WAITOK);
+ //MPRINTF_OLD("malloc(DEVBUF)", sc->sc_descmap);
bzero(sc->sc_descmap, mapsize);
#endif
+#if 1 /* XXX Added when reorganizing dmamap stuff... */
+ sc->sc_dnseg = 1;
+#endif
+
+ if ((error = bus_dmamap_create(sc->sc_dmat, dsize, sc->sc_dnseg,
+ dsize, 0, BUS_DMA_WAITOK, &sc->sc_ddmamap)) != 0) {
+ printf("%s: unable to create descriptor buffer DMA map, "
+ "error = %d\n", sc->sc_sc1394.sc1394_dev.dv_xname, error);
+ goto fail_0;
+ }
+ //MPRINTF_OLD("bus_dmamap_create", sc->sc_ddmamap);
+
if ((error = bus_dmamem_alloc(sc->sc_dmat, dsize, PAGE_SIZE, 0,
- &sc->sc_dseg, 1, &sc->sc_dnseg, 0)) != 0) {
+ &sc->sc_dseg, 1, &sc->sc_dnseg, BUS_DMA_WAITOK)) != 0) {
printf("%s: unable to allocate descriptor buffer, error = %d\n",
sc->sc_sc1394.sc1394_dev.dv_xname, error);
- goto fail_0;
+ goto fail_1;
}
+ //MPRINTF_OLD("bus_dmamem_alloc", sc->sc_dseg.ds_addr);
if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dseg, sc->sc_dnseg,
dsize, (caddr_t *)&sc->sc_desc, BUS_DMA_COHERENT | BUS_DMA_WAITOK))
!= 0) {
printf("%s: unable to map descriptor buffer, error = %d\n",
sc->sc_sc1394.sc1394_dev.dv_xname, error);
- goto fail_1;
- }
-
- if ((error = bus_dmamap_create(sc->sc_dmat, dsize, sc->sc_dnseg,
- dsize, 0, BUS_DMA_WAITOK, &sc->sc_ddmamap)) != 0) {
- printf("%s: unable to create descriptor buffer DMA map, "
- "error = %d\n", sc->sc_sc1394.sc1394_dev.dv_xname, error);
goto fail_2;
}
+#if 0
if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_ddmamap, sc->sc_desc,
dsize, NULL, BUS_DMA_WAITOK)) != 0) {
+#else
+ if ((error = bus_dmamap_load_raw(sc->sc_dmat, sc->sc_ddmamap,
+ &sc->sc_dseg, sc->sc_dnseg, dsize, BUS_DMA_WAITOK)) != 0) {
+#endif
printf("%s: unable to load descriptor buffer DMA map, "
"error = %d\n", sc->sc_sc1394.sc1394_dev.dv_xname, error);
goto fail_3;
@@ -959,20 +1262,41 @@ fwohci_desc_alloc(struct fwohci_softc *sc)
return 0;
fail_3:
- bus_dmamap_destroy(sc->sc_dmat, sc->sc_ddmamap);
- fail_2:
bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_desc, dsize);
- fail_1:
+ fail_2:
bus_dmamem_free(sc->sc_dmat, &sc->sc_dseg, sc->sc_dnseg);
+ //MPRINTF_OLD("bus_dmamem_free", sc->sc_dseg.ds_addr);
+ fail_1:
+ bus_dmamap_destroy(sc->sc_dmat, sc->sc_ddmamap);
+ //MPRINTF_OLD("bus_dmamap_destroy", sc->sc_ddmamap);
fail_0:
return error;
}
+void
+fwohci_desc_free(struct fwohci_softc *sc)
+{
+ int dsize = sizeof(struct fwohci_desc) * sc->sc_descsize;
+
+ bus_dmamap_unload(sc->sc_dmat, sc->sc_ddmamap);
+ bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_desc, dsize);
+ bus_dmamem_free(sc->sc_dmat, &sc->sc_dseg, sc->sc_dnseg);
+ //MPRINTF_OLD("bus_dmamem_free", sc->sc_dseg.ds_addr);
+ bus_dmamap_destroy(sc->sc_dmat, sc->sc_ddmamap);
+ //MPRINTF_OLD("bus_dmamap_destroy", sc->sc_ddmamap);
+
+ free(sc->sc_descmap, M_DEVBUF);
+ //MPRINTF_OLD("free(DEVBUF)", sc->sc_descmap);
+ sc->sc_descmap = NULL; /* XXX */
+}
+
struct fwohci_desc *
fwohci_desc_get(struct fwohci_softc *sc, int ndesc)
{
int i, n;
+ assert(ndesc > 0);
+
for (n = 0; n <= sc->sc_descsize - ndesc; n++) {
for (i = 0; ; i++) {
if (i == ndesc) {
@@ -992,9 +1316,11 @@ fwohci_desc_put(struct fwohci_softc *sc, struct fwohci_desc *fd, int ndesc)
{
int i, n;
+ assert(ndesc > 0);
+
n = fd - sc->sc_desc;
for (i = 0; i < ndesc; i++, n++) {
-#ifdef DIAGNOSTIC
+#ifdef DIAGNOSTIC
if (isclr(sc->sc_descmap, n))
panic("fwohci_desc_put: duplicated free");
#endif
@@ -1003,7 +1329,7 @@ fwohci_desc_put(struct fwohci_softc *sc, struct fwohci_desc *fd, int ndesc)
}
/*
- * Asyncronous/Isochronous Transmit/Receive Context
+ * Asyncronous/Isochronous Transmit/Receive Context.
*/
int
fwohci_ctx_alloc(struct fwohci_softc *sc, struct fwohci_ctx **fcp,
@@ -1017,24 +1343,32 @@ fwohci_ctx_alloc(struct fwohci_softc *sc, struct fwohci_ctx **fcp,
int buf2cnt;
#endif
-#ifdef M_ZERO
- fc = malloc(sizeof(*fc), M_DEVBUF, M_WAITOK|M_ZERO);
+#ifdef M_ZERO
+ MALLOC(fc, struct fwohci_ctx *, sizeof(*fc), M_DEVBUF, M_WAITOK|M_ZERO);
+ //MPRINTF_OLD("MALLOC(DEVBUF)", fc);
#else
- fc = malloc(sizeof(*fc), M_DEVBUF, M_WAITOK);
+ MALLOC(fc, struct fwohci_ctx *, sizeof(*fc), M_DEVBUF, M_WAITOK);
+ //MPRINTF_OLD("MALLOC(DEVBUF)", fc);
bzero(fc, sizeof(*fc));
#endif
LIST_INIT(&fc->fc_handler);
TAILQ_INIT(&fc->fc_buf);
fc->fc_ctx = ctx;
-#ifdef M_ZERO
- fc->fc_buffers = fb = malloc(sizeof(*fb) * bufcnt, M_DEVBUF, M_WAITOK|M_ZERO);
+#ifdef M_ZERO
+ fc->fc_buffers = fb = malloc(sizeof(*fb) * bufcnt,
+ M_DEVBUF, M_WAITOK|M_ZERO);
+ //MPRINTF_OLD("malloc(DEVBUF)", fc->fc_buffers);
#else
fc->fc_buffers = fb = malloc(sizeof(*fb) * bufcnt, M_DEVBUF, M_WAITOK);
+ //MPRINTF_OLD("malloc(DEVBUF)", fc->fc_buffers);
bzero(fb, sizeof(*fb) * bufcnt);
#endif
fc->fc_bufcnt = bufcnt;
+ if (bufcnt == 0) /* Asynchronous transmit... */
+ goto ok;
+
#if DOUBLEBUF
- TAILQ_INIT(&fc->fc_buf2); /* for isochronous */
+ TAILQ_INIT(&fc->fc_buf2); /* For isochronous. */
if (ctxtype == FWOHCI_CTX_ISO_MULTI) {
buf2cnt = bufcnt/2;
bufcnt -= buf2cnt;
@@ -1053,11 +1387,17 @@ fwohci_ctx_alloc(struct fwohci_softc *sc, struct fwohci_ctx **fcp,
fb->fb_desc = fd;
fb->fb_daddr = sc->sc_ddmamap->dm_segs[0].ds_addr +
((caddr_t)fd - (caddr_t)sc->sc_desc);
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap,
+ (caddr_t)fd - (caddr_t)sc->sc_desc,
+ sizeof(struct fwohci_desc), BUS_DMASYNC_PREWRITE);
fd->fd_flags = OHCI_DESC_INPUT | OHCI_DESC_STATUS |
OHCI_DESC_INTR_ALWAYS | OHCI_DESC_BRANCH;
fd->fd_reqcount = fb->fb_dmamap->dm_segs[0].ds_len;
fd->fd_data = fb->fb_dmamap->dm_segs[0].ds_addr;
TAILQ_INSERT_TAIL(&fc->fc_buf, fb, fb_list);
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap,
+ (caddr_t)fd - (caddr_t)sc->sc_desc,
+ sizeof(struct fwohci_desc), BUS_DMASYNC_POSTWRITE);
}
#if DOUBLEBUF
if (ctxtype == FWOHCI_CTX_ISO_MULTI) {
@@ -1072,19 +1412,20 @@ fwohci_ctx_alloc(struct fwohci_softc *sc, struct fwohci_ctx **fcp,
fb->fb_daddr = sc->sc_ddmamap->dm_segs[0].ds_addr +
((caddr_t)fd - (caddr_t)sc->sc_desc);
bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap,
- (caddr_t)fd - (caddr_t)sc->sc_desc, sizeof(struct fwohci_desc),
- BUS_DMASYNC_PREWRITE);
+ (caddr_t)fd - (caddr_t)sc->sc_desc,
+ sizeof(struct fwohci_desc), BUS_DMASYNC_PREWRITE);
fd->fd_flags = OHCI_DESC_INPUT | OHCI_DESC_STATUS |
OHCI_DESC_INTR_ALWAYS | OHCI_DESC_BRANCH;
fd->fd_reqcount = fb->fb_dmamap->dm_segs[0].ds_len;
fd->fd_data = fb->fb_dmamap->dm_segs[0].ds_addr;
TAILQ_INSERT_TAIL(&fc->fc_buf2, fb, fb_list);
bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap,
- (caddr_t)fd - (caddr_t)sc->sc_desc, sizeof(struct fwohci_desc),
- BUS_DMASYNC_POSTWRITE);
+ (caddr_t)fd - (caddr_t)sc->sc_desc,
+ sizeof(struct fwohci_desc), BUS_DMASYNC_POSTWRITE);
}
}
#endif /* DOUBLEBUF */
+ ok:
fc->fc_type = ctxtype;
*fcp = fc;
return 0;
@@ -1096,7 +1437,9 @@ fwohci_ctx_alloc(struct fwohci_softc *sc, struct fwohci_ctx **fcp,
fwohci_desc_put(sc, fb->fb_desc, 1);
fwohci_buf_free(sc, fb);
}
- free(fc, M_DEVBUF);
+ FREE(fc, M_DEVBUF);
+ //MPRINTF_OLD("FREE(DEVBUF)", fc);
+ fc = NULL; /* XXX */
return error;
}
@@ -1125,16 +1468,20 @@ fwohci_ctx_free(struct fwohci_softc *sc, struct fwohci_ctx *fc)
fwohci_desc_put(sc, fb->fb_desc, 1);
fwohci_buf_free(sc, fb);
}
-#if DOUBLEBUF
+#if DOUBLEBUF
while ((fb = TAILQ_FIRST(&fc->fc_buf2)) != NULL) {
TAILQ_REMOVE(&fc->fc_buf2, fb, fb_list);
if (fb->fb_desc)
fwohci_desc_put(sc, fb->fb_desc, 1);
fwohci_buf_free(sc, fb);
}
-#endif /* DOUBLEBUF */
+#endif /* DOUBLEBUF */
free(fc->fc_buffers, M_DEVBUF);
- free(fc, M_DEVBUF);
+ //MPRINTF_OLD("free(DEVBUF)", fc->fc_buffers);
+ fc->fc_buffers = NULL; /* XXX */
+ FREE(fc, M_DEVBUF);
+ //MPRINTF_OLD("FREE(DEVBUF)", fc);
+ fc = NULL; /* XXX */
}
void
@@ -1145,27 +1492,35 @@ fwohci_ctx_init(struct fwohci_softc *sc, struct fwohci_ctx *fc)
struct fwohci_handler *fh;
int n;
- for (fb = TAILQ_FIRST(&fc->fc_buf); fb != NULL; fb = nfb) {
+ splassert(IPL_BIO);
+
+ TAILQ_FOREACH(fb, &fc->fc_buf, fb_list) {
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap,
+ (caddr_t)fd - (caddr_t)sc->sc_desc,
+ sizeof(struct fwohci_desc), BUS_DMASYNC_PREWRITE);
nfb = TAILQ_NEXT(fb, fb_list);
fb->fb_off = 0;
fd = fb->fb_desc;
fd->fd_branch = (nfb != NULL) ? (nfb->fb_daddr | 1) : 0;
fd->fd_rescount = fd->fd_reqcount;
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap,
+ (caddr_t)fd - (caddr_t)sc->sc_desc,
+ sizeof(struct fwohci_desc), BUS_DMASYNC_POSTWRITE);
}
#if DOUBLEBUF
- for (fb = TAILQ_FIRST(&fc->fc_buf2); fb != NULL; fb = nfb) {
+ TAILQ_FOREACH(fb, &fc->fc_buf2, fb_list) {
bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap,
- (caddr_t)fd - (caddr_t)sc->sc_desc, sizeof(struct fwohci_desc),
- BUS_DMASYNC_PREWRITE);
+ (caddr_t)fd - (caddr_t)sc->sc_desc,
+ sizeof(struct fwohci_desc), BUS_DMASYNC_PREWRITE);
nfb = TAILQ_NEXT(fb, fb_list);
fb->fb_off = 0;
fd = fb->fb_desc;
fd->fd_branch = (nfb != NULL) ? (nfb->fb_daddr | 1) : 0;
fd->fd_rescount = fd->fd_reqcount;
bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap,
- (caddr_t)fd - (caddr_t)sc->sc_desc, sizeof(struct fwohci_desc),
- BUS_DMASYNC_POSTWRITE);
+ (caddr_t)fd - (caddr_t)sc->sc_desc,
+ sizeof(struct fwohci_desc), BUS_DMASYNC_POSTWRITE);
}
#endif /* DOUBLEBUF */
@@ -1174,6 +1529,7 @@ fwohci_ctx_init(struct fwohci_softc *sc, struct fwohci_ctx *fc)
if (fc->fc_type != FWOHCI_CTX_ASYNC) {
OHCI_SYNC_RX_DMA_WRITE(sc, n, OHCI_SUBREG_CommandPtr,
fb->fb_daddr | 1);
+ MPRINTF("OHCI_SUBREG_CommandPtr(SYNC_RX)", fb->fb_daddr);
OHCI_SYNC_RX_DMA_WRITE(sc, n, OHCI_SUBREG_ContextControlClear,
OHCI_CTXCTL_RX_BUFFER_FILL |
OHCI_CTXCTL_RX_CYCLE_MATCH_ENABLE |
@@ -1192,41 +1548,53 @@ fwohci_ctx_init(struct fwohci_softc *sc, struct fwohci_ctx *fc)
} else {
OHCI_ASYNC_DMA_WRITE(sc, n, OHCI_SUBREG_CommandPtr,
fb->fb_daddr | 1);
+ MPRINTF("OHCI_SUBREG_CommandPtr(ASYNC)", fb->fb_daddr);
}
}
/*
- * DMA data buffer
+ * DMA data buffer.
*/
int
fwohci_buf_alloc(struct fwohci_softc *sc, struct fwohci_buf *fb)
{
int error;
+ if (!fb->fb_nseg)
+ fb->fb_nseg = 1;
+
+ if ((error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, fb->fb_nseg,
+ PAGE_SIZE, 0, BUS_DMA_WAITOK, &fb->fb_dmamap)) != 0) {
+ printf("%s: unable to create buffer DMA map, "
+ "error = %d\n", sc->sc_sc1394.sc1394_dev.dv_xname,
+ error);
+ goto fail_0;
+ }
+ //MPRINTF_OLD("bus_dmamap_create", fb->fb_dmamap);
+
if ((error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE,
PAGE_SIZE, &fb->fb_seg, 1, &fb->fb_nseg, BUS_DMA_WAITOK)) != 0) {
printf("%s: unable to allocate buffer, error = %d\n",
sc->sc_sc1394.sc1394_dev.dv_xname, error);
- goto fail_0;
+ goto fail_1;
}
+ //MPRINTF_OLD("bus_dmamem_alloc", fb->fb_seg.ds_addr);
if ((error = bus_dmamem_map(sc->sc_dmat, &fb->fb_seg,
- fb->fb_nseg, PAGE_SIZE, &fb->fb_buf, BUS_DMA_WAITOK)) != 0) {
+ fb->fb_nseg, PAGE_SIZE, &fb->fb_buf,
+ BUS_DMA_COHERENT | BUS_DMA_WAITOK)) != 0) {
printf("%s: unable to map buffer, error = %d\n",
sc->sc_sc1394.sc1394_dev.dv_xname, error);
- goto fail_1;
- }
-
- if ((error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, fb->fb_nseg,
- PAGE_SIZE, 0, BUS_DMA_WAITOK, &fb->fb_dmamap)) != 0) {
- printf("%s: unable to create buffer DMA map, "
- "error = %d\n", sc->sc_sc1394.sc1394_dev.dv_xname,
- error);
goto fail_2;
}
+#if 0
if ((error = bus_dmamap_load(sc->sc_dmat, fb->fb_dmamap,
fb->fb_buf, PAGE_SIZE, NULL, BUS_DMA_WAITOK)) != 0) {
+#else
+ if ((error = bus_dmamap_load_raw(sc->sc_dmat, fb->fb_dmamap,
+ &fb->fb_seg, fb->fb_nseg, PAGE_SIZE, BUS_DMA_WAITOK)) != 0) {
+#endif
printf("%s: unable to load buffer DMA map, "
"error = %d\n", sc->sc_sc1394.sc1394_dev.dv_xname,
error);
@@ -1237,11 +1605,13 @@ fwohci_buf_alloc(struct fwohci_softc *sc, struct fwohci_buf *fb)
bus_dmamap_unload(sc->sc_dmat, fb->fb_dmamap);
fail_3:
- bus_dmamap_destroy(sc->sc_dmat, fb->fb_dmamap);
- fail_2:
bus_dmamem_unmap(sc->sc_dmat, fb->fb_buf, PAGE_SIZE);
- fail_1:
+ fail_2:
bus_dmamem_free(sc->sc_dmat, &fb->fb_seg, fb->fb_nseg);
+ //MPRINTF_OLD("bus_dmamem_free", fb->fb_seg.ds_addr);
+ fail_1:
+ bus_dmamap_destroy(sc->sc_dmat, fb->fb_dmamap);
+ //MPRINTF_OLD("bus_dmamap_destroy", fb->fb_dmamap);
fail_0:
return error;
}
@@ -1251,9 +1621,11 @@ fwohci_buf_free(struct fwohci_softc *sc, struct fwohci_buf *fb)
{
bus_dmamap_unload(sc->sc_dmat, fb->fb_dmamap);
- bus_dmamap_destroy(sc->sc_dmat, fb->fb_dmamap);
bus_dmamem_unmap(sc->sc_dmat, fb->fb_buf, PAGE_SIZE);
bus_dmamem_free(sc->sc_dmat, &fb->fb_seg, fb->fb_nseg);
+ //MPRINTF_OLD("bus_dmamem_free", fb->fb_seg.ds_addr);
+ bus_dmamap_destroy(sc->sc_dmat, fb->fb_dmamap);
+ //MPRINTF_OLD("bus_dmamap_destroy", fb->fb_dmamap);
}
void
@@ -1261,6 +1633,8 @@ fwohci_buf_init_rx(struct fwohci_softc *sc)
{
int i;
+ splassert(IPL_BIO);
+
/*
* Initialize for Asynchronous Receive Queue.
*/
@@ -1281,6 +1655,8 @@ fwohci_buf_start_rx(struct fwohci_softc *sc)
{
int i;
+// splassert(IPL_BIO);
+
OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_RX_REQUEST,
OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN);
OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_RX_RESPONSE,
@@ -1297,6 +1673,8 @@ fwohci_buf_stop_tx(struct fwohci_softc *sc)
{
int i;
+// splassert(IPL_BIO);
+
OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_TX_REQUEST,
OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN);
OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_TX_RESPONSE,
@@ -1328,6 +1706,8 @@ fwohci_buf_stop_rx(struct fwohci_softc *sc)
{
int i;
+ splassert(IPL_BIO);
+
OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_RX_REQUEST,
OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN);
OHCI_ASYNC_DMA_WRITE(sc, OHCI_CTX_ASYNC_RX_RESPONSE,
@@ -1347,7 +1727,7 @@ fwohci_buf_next(struct fwohci_softc *sc, struct fwohci_ctx *fc)
if (fc->fc_type != FWOHCI_CTX_ISO_MULTI) {
#endif
while ((fb = TAILQ_FIRST(&fc->fc_buf)) != NULL) {
- if (fc->fc_type) {
+ if (fc->fc_type != FWOHCI_CTX_ASYNC) {
if (fb->fb_off == 0)
break;
} else {
@@ -1367,14 +1747,13 @@ fwohci_buf_next(struct fwohci_softc *sc, struct fwohci_ctx *fc)
} else {
struct fwohci_buf_s fctmp;
- /* cleaning buffer */
- for (fb = TAILQ_FIRST(&fc->fc_buf); fb != NULL;
- fb = TAILQ_NEXT(fb, fb_list)) {
+ /* Cleaning buffer. */
+ TAILQ_FOREACH(fb, &fc->fc_buf, fb_list) {
fb->fb_off = 0;
fb->fb_desc->fd_rescount = fb->fb_desc->fd_reqcount;
}
-
- /* rotating buffer */
+
+ /* Rotating buffer. */
fctmp = fc->fc_buf;
fc->fc_buf = fc->fc_buf2;
fc->fc_buf2 = fctmp;
@@ -1383,28 +1762,31 @@ fwohci_buf_next(struct fwohci_softc *sc, struct fwohci_ctx *fc)
}
int
-fwohci_buf_pktget(struct fwohci_softc *sc, struct fwohci_buf **fbp, caddr_t *pp,
- int len)
+fwohci_buf_pktget(struct fwohci_softc *sc, struct fwohci_buf **fbp,
+ caddr_t *pp, int reqlen)
{
struct fwohci_buf *fb;
struct fwohci_desc *fd;
- int bufend;
+ int bufend, len = reqlen;
+#ifdef FWOHCI_DEBUG
+ int i;
+#endif /* FWOHCI_DEBUG */
fb = *fbp;
- again:
+again:
fd = fb->fb_desc;
- DPRINTFN(1, ("fwohci_buf_pktget: desc %ld, off %d, req %d, res %d,"
- " len %d, avail %d\n", (long)(fd - sc->sc_desc), fb->fb_off,
- fd->fd_reqcount, fd->fd_rescount, len,
+ DPRINTFN(1, ("%s: desc %ld, off %d, req %d, res %d, len %d, avail %d",
+ __func__, (long)(fd - sc->sc_desc), fb->fb_off, fd->fd_reqcount,
+ fd->fd_rescount, len,
fd->fd_reqcount - fd->fd_rescount - fb->fb_off));
bufend = fd->fd_reqcount - fd->fd_rescount;
if (fb->fb_off >= bufend) {
- DPRINTFN(5, ("buf %x finish req %d res %d off %d ",
+ DPRINTFN(5, ("\n\tbuf %08x finish req %d res %d off %d",
fb->fb_desc->fd_data, fd->fd_reqcount, fd->fd_rescount,
fb->fb_off));
if (fd->fd_rescount == 0) {
*fbp = fb = TAILQ_NEXT(fb, fb_list);
- if (fb != NULL)
+ if (fb != TAILQ_END(fb))
goto again;
}
return 0;
@@ -1413,6 +1795,15 @@ fwohci_buf_pktget(struct fwohci_softc *sc, struct fwohci_buf **fbp, caddr_t *pp,
len = bufend - fb->fb_off;
bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, fb->fb_off, len,
BUS_DMASYNC_POSTREAD);
+
+#ifdef FWOHCI_DEBUG
+ for (i=0; i < (roundup(len, 4) / 4); i++) {
+ if ((i % 8) == 0) DPRINTFN(5, ("\n "));
+ DPRINTFN(5, (" %08x",
+ ((u_int32_t *)(fb->fb_buf + fb->fb_off))[i]));
+ }
+#endif /* FWOHCI_DEBUG */
+ DPRINTF(("\n"));
*pp = fb->fb_buf + fb->fb_off;
fb->fb_off += roundup(len, 4);
return len;
@@ -1426,51 +1817,50 @@ fwohci_buf_input(struct fwohci_softc *sc, struct fwohci_ctx *fc,
struct fwohci_buf *fb;
int len, count, i;
- memset(pkt, 0, sizeof(*pkt));
+ bzero(pkt, sizeof(*pkt));
pkt->fp_uio.uio_iov = pkt->fp_iov;
pkt->fp_uio.uio_rw = UIO_WRITE;
pkt->fp_uio.uio_segflg = UIO_SYSSPACE;
- /* get first quadlet */
+ /* Get first quadlet. */
fb = TAILQ_FIRST(&fc->fc_buf);
count = 4;
len = fwohci_buf_pktget(sc, &fb, &p, count);
if (len <= 0) {
- DPRINTFN(1, ("fwohci_buf_input: no input for %d\n",
- fc->fc_ctx));
+ DPRINTFN(1, ("%s: no input for %d\n", __func__, fc->fc_ctx));
return 0;
}
- pkt->fp_hdr[0] = *(u_int32_t *)p;
+ pkt->fp_hdr[0] = *(u_int32_t *)p; /* XXX Alignment !!! */
pkt->fp_tcode = (pkt->fp_hdr[0] & 0x000000f0) >> 4;
switch (pkt->fp_tcode) {
- case IEEE1394_TCODE_WRITE_REQ_QUAD:
- case IEEE1394_TCODE_READ_RESP_QUAD:
+ case IEEE1394_TCODE_WRITE_REQUEST_QUADLET:
+ case IEEE1394_TCODE_READ_RESPONSE_QUADLET:
pkt->fp_hlen = 12;
pkt->fp_dlen = 4;
break;
- case IEEE1394_TCODE_READ_REQ_BLOCK:
+ case IEEE1394_TCODE_READ_REQUEST_DATABLOCK:
pkt->fp_hlen = 16;
pkt->fp_dlen = 0;
break;
- case IEEE1394_TCODE_WRITE_REQ_BLOCK:
- case IEEE1394_TCODE_READ_RESP_BLOCK:
- case IEEE1394_TCODE_LOCK_REQ:
- case IEEE1394_TCODE_LOCK_RESP:
+ case IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK:
+ case IEEE1394_TCODE_READ_RESPONSE_DATABLOCK:
+ case IEEE1394_TCODE_LOCK_REQUEST:
+ case IEEE1394_TCODE_LOCK_RESPONSE:
pkt->fp_hlen = 16;
break;
- case IEEE1394_TCODE_STREAM_DATA:
-#ifdef DIAGNOSTIC
+ case IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK:
+#ifdef DIAGNOSTIC
if (fc->fc_type == FWOHCI_CTX_ISO_MULTI)
#endif
{
pkt->fp_hlen = 4;
- pkt->fp_dlen = pkt->fp_hdr[0] >> 16;
+ pkt->fp_dlen = (pkt->fp_hdr[0] >> 16) & 0xffff;
DPRINTFN(5, ("[%d]", pkt->fp_dlen));
break;
}
-#ifdef DIAGNOSTIC
+#ifdef DIAGNOSTIC
else {
- printf("fwohci_buf_input: bad tcode: STREAM_DATA\n");
+ printf("%s: bad tcode: STREAM_DATA\n", __func__);
return 0;
}
#endif
@@ -1480,32 +1870,38 @@ fwohci_buf_input(struct fwohci_softc *sc, struct fwohci_ctx *fc,
break;
}
- /* get header */
+ /* Get header. */
while (count < pkt->fp_hlen) {
len = fwohci_buf_pktget(sc, &fb, &p, pkt->fp_hlen - count);
if (len == 0) {
- printf("fwohci_buf_input: malformed input 1: %d\n",
+ printf("%s: malformed input 1: %d\n", __func__,
pkt->fp_hlen - count);
return 0;
}
- memcpy((caddr_t)pkt->fp_hdr + count, p, len);
+#ifdef FWOHCI_DEBUG
+ fwptr = p; fwlen = len; fwbuf = fb;
+#endif /* FWOHCI_DEBUG */
+ bcopy(p, (caddr_t)pkt->fp_hdr + count, len);
+#ifdef FWOHCI_DEBUG
+ fwptr = NULL; fwlen = 0; fwbuf = NULL;
+#endif /* FWOHCI_DEBUG */
count += len;
}
if (pkt->fp_hlen == 16 &&
- pkt->fp_tcode != IEEE1394_TCODE_READ_REQ_BLOCK)
+ pkt->fp_tcode != IEEE1394_TCODE_READ_REQUEST_DATABLOCK)
pkt->fp_dlen = pkt->fp_hdr[3] >> 16;
- DPRINTFN(1, ("fwohci_buf_input: tcode=0x%x, hlen=%d, dlen=%d\n",
+ DPRINTFN(1, ("%s: tcode=0x%x, hlen=%d, dlen=%d\n", __func__,
pkt->fp_tcode, pkt->fp_hlen, pkt->fp_dlen));
- /* get data */
+ /* Get data. */
count = 0;
i = 0;
- while (count < pkt->fp_dlen) {
+ while (i < 6 && count < pkt->fp_dlen) {
len = fwohci_buf_pktget(sc, &fb,
(caddr_t *)&pkt->fp_iov[i].iov_base,
pkt->fp_dlen - count);
if (len == 0) {
- printf("fwohci_buf_input: malformed input 2: %d\n",
+ printf("%s: malformed input 2: %d\n", __func__,
pkt->fp_dlen - count);
return 0;
}
@@ -1515,11 +1911,23 @@ fwohci_buf_input(struct fwohci_softc *sc, struct fwohci_ctx *fc,
pkt->fp_uio.uio_iovcnt = i;
pkt->fp_uio.uio_resid = count;
- /* get trailer */
+ if (count < pkt->fp_dlen) { /* Eat the remainder of the packet. */
+ printf("%s: %d iov exhausted, %d bytes not gotten\n",
+ __func__, i, pkt->fp_dlen - count);
+ while (count < pkt->fp_dlen) {
+ len = fwohci_buf_pktget(sc, &fb,
+ (caddr_t *)&pkt->fp_trail,
+ ((pkt->fp_dlen - count) > sizeof(*pkt->fp_trail)) ?
+ sizeof(*pkt->fp_trail) : (pkt->fp_dlen - count));
+ count += len;
+ }
+ }
+
+ /* Get trailer. */
len = fwohci_buf_pktget(sc, &fb, (caddr_t *)&pkt->fp_trail,
sizeof(*pkt->fp_trail));
if (len <= 0) {
- printf("fwohci_buf_input: malformed input 3: %d\n",
+ printf("%s: malformed input 3: %d\n", __func__,
pkt->fp_hlen - count);
return 0;
}
@@ -1539,17 +1947,18 @@ fwohci_buf_input_ppb(struct fwohci_softc *sc, struct fwohci_ctx *fc,
return fwohci_buf_input(sc, fc, pkt);
}
- memset(pkt, 0, sizeof(*pkt));
+ bzero(pkt, sizeof(*pkt));
pkt->fp_uio.uio_iov = pkt->fp_iov;
pkt->fp_uio.uio_rw = UIO_WRITE;
pkt->fp_uio.uio_segflg = UIO_SYSSPACE;
- for (fb = TAILQ_FIRST(&fc->fc_buf); ; fb = TAILQ_NEXT(fb, fb_list)) {
- if (fb == NULL)
- return 0;
+ TAILQ_FOREACH(fb, &fc->fc_buf, fb_list) {
if (fb->fb_off == 0)
break;
}
+ if (fb == NULL)
+ return 0;
+
fd = fb->fb_desc;
len = fd->fd_reqcount - fd->fd_rescount;
if (len == 0)
@@ -1560,22 +1969,21 @@ fwohci_buf_input_ppb(struct fwohci_softc *sc, struct fwohci_ctx *fc,
p = fb->fb_buf;
fb->fb_off += roundup(len, 4);
if (len < 8) {
- printf("fwohci_buf_input_ppb: malformed input 1: %d\n", len);
+ printf("%s: malformed input 1: %d\n", __func__, len);
return 0;
}
/*
- * get trailer first, may be bogus data unless status update
+ * Get trailer first, may be bogus data unless status update
* in descriptor is set.
*/
pkt->fp_trail = (u_int32_t *)p;
*pkt->fp_trail = (*pkt->fp_trail & 0xffff) | (fd->fd_status << 16);
pkt->fp_hdr[0] = ((u_int32_t *)p)[1];
pkt->fp_tcode = (pkt->fp_hdr[0] & 0x000000f0) >> 4;
-#ifdef DIAGNOSTIC
- if (pkt->fp_tcode != IEEE1394_TCODE_STREAM_DATA) {
- printf("fwohci_buf_input_ppb: bad tcode: 0x%x\n",
- pkt->fp_tcode);
+#ifdef DIAGNOSTIC
+ if (pkt->fp_tcode != IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK) {
+ printf("%s: bad tcode: 0x%x\n", __func__, pkt->fp_tcode);
return 0;
}
#endif
@@ -1584,30 +1992,29 @@ fwohci_buf_input_ppb(struct fwohci_softc *sc, struct fwohci_ctx *fc,
p += 8;
len -= 8;
if (pkt->fp_dlen != len) {
- printf("fwohci_buf_input_ppb: malformed input 2: %d != %d\n",
+ printf("%s: malformed input 2: %d != %d\n", __func__,
pkt->fp_dlen, len);
return 0;
}
- DPRINTFN(1, ("fwohci_buf_input_ppb: tcode=0x%x, hlen=%d, dlen=%d\n",
+ DPRINTFN(1, ("%s: tcode=0x%x, hlen=%d, dlen=%d\n", __func__,
pkt->fp_tcode, pkt->fp_hlen, pkt->fp_dlen));
pkt->fp_iov[0].iov_base = p;
pkt->fp_iov[0].iov_len = len;
- pkt->fp_uio.uio_iovcnt = 0;
+ pkt->fp_uio.uio_iovcnt = 1;
pkt->fp_uio.uio_resid = len;
return 1;
}
int
-fwohci_handler_set(struct fwohci_softc *sc,
- int tcode, u_int32_t key1, u_int32_t key2,
- int (*handler)(struct fwohci_softc *, void *, struct fwohci_pkt *),
- void *arg)
+fwohci_handler_set(struct fwohci_softc *sc, int tcode, u_int32_t key1,
+ u_int32_t key2, int (*handler)(struct fwohci_softc *, void *,
+ struct fwohci_pkt *), void *arg)
{
struct fwohci_ctx *fc;
struct fwohci_handler *fh;
- int i, j;
+ int i, j, s;
- if (tcode == IEEE1394_TCODE_STREAM_DATA) {
+ if (tcode == IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK) {
int isasync = key1 & OHCI_ASYNC_STREAM;
key1 &= IEEE1394_ISOCH_MASK;
@@ -1629,8 +2036,8 @@ fwohci_handler_set(struct fwohci_softc *sc,
if (handler == NULL)
return 0;
if (j == sc->sc_isoctx) {
- DPRINTF(("fwohci_handler_set: no more free "
- "context\n"));
+ DPRINTF(("%s: no more free context\n",
+ __func__));
return ENOMEM;
}
if ((fc = sc->sc_ctx_ir[j]) == NULL) {
@@ -1642,24 +2049,23 @@ fwohci_handler_set(struct fwohci_softc *sc,
}
} else {
switch (tcode) {
- case IEEE1394_TCODE_WRITE_REQ_QUAD:
- case IEEE1394_TCODE_WRITE_REQ_BLOCK:
- case IEEE1394_TCODE_READ_REQ_QUAD:
- case IEEE1394_TCODE_READ_REQ_BLOCK:
- case IEEE1394_TCODE_LOCK_REQ:
+ case IEEE1394_TCODE_WRITE_REQUEST_QUADLET:
+ case IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK:
+ case IEEE1394_TCODE_READ_REQUEST_QUADLET:
+ case IEEE1394_TCODE_READ_REQUEST_DATABLOCK:
+ case IEEE1394_TCODE_LOCK_REQUEST:
fc = sc->sc_ctx_arrq;
break;
- case IEEE1394_TCODE_WRITE_RESP:
- case IEEE1394_TCODE_READ_RESP_QUAD:
- case IEEE1394_TCODE_READ_RESP_BLOCK:
- case IEEE1394_TCODE_LOCK_RESP:
+ case IEEE1394_TCODE_WRITE_RESPONSE:
+ case IEEE1394_TCODE_READ_RESPONSE_QUADLET:
+ case IEEE1394_TCODE_READ_RESPONSE_DATABLOCK:
+ case IEEE1394_TCODE_LOCK_RESPONSE:
fc = sc->sc_ctx_arrs;
break;
default:
return EIO;
}
- for (fh = LIST_FIRST(&fc->fc_handler); fh != NULL;
- fh = LIST_NEXT(fh, fh_list)) {
+ LIST_FOREACH(fh, &fc->fc_handler, fh_list) {
if (fh->fh_tcode == tcode &&
fh->fh_key1 == key1 && fh->fh_key2 == key2)
break;
@@ -1668,9 +2074,11 @@ fwohci_handler_set(struct fwohci_softc *sc,
if (handler == NULL) {
if (fh != NULL) {
LIST_REMOVE(fh, fh_list);
- free(fh, M_DEVBUF);
+ FREE(fh, M_DEVBUF);
+ //MPRINTF_OLD("FREE(DEVBUF)", fh);
+ fh = NULL; /* XXX */
}
- if (tcode == IEEE1394_TCODE_STREAM_DATA) {
+ if (tcode == IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK) {
OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx,
OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN);
sc->sc_ctx_ir[fc->fc_ctx] = NULL;
@@ -1678,35 +2086,56 @@ fwohci_handler_set(struct fwohci_softc *sc,
}
return 0;
}
+ s = splbio();
if (fh == NULL) {
- fh = malloc(sizeof(*fh), M_DEVBUF, M_WAITOK);
- LIST_INSERT_HEAD(&fc->fc_handler, fh, fh_list);
+ MALLOC(fh, struct fwohci_handler *, sizeof(*fh),
+ M_DEVBUF, M_WAITOK);
+ //MPRINTF_OLD("MALLOC(DEVBUF)", fh);
+ bzero(fh, sizeof(*fh));
}
fh->fh_tcode = tcode;
fh->fh_key1 = key1;
fh->fh_key2 = key2;
fh->fh_handler = handler;
fh->fh_handarg = arg;
- DPRINTFN(1, ("fwohci_handler_set: ctx %d, tcode %x, key 0x%x, 0x%x\n",
+
+ if (fh->fh_list.le_prev == NULL)
+ LIST_INSERT_HEAD(&fc->fc_handler, fh, fh_list);
+ splx(s);
+
+ DPRINTFN(1, ("%s: ctx %d, tcode %x, key 0x%x, 0x%x\n", __func__,
fc->fc_ctx, tcode, key1, key2));
- if (tcode == IEEE1394_TCODE_STREAM_DATA) {
+ if (tcode == IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK) {
+ s = splbio();
fwohci_ctx_init(sc, fc);
- DPRINTFN(1, ("fwohci_handler_set: SYNC desc %ld\n",
- (long)(TAILQ_FIRST(&fc->fc_buf)->fb_desc - sc->sc_desc)));
OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx,
OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN);
+ splx(s);
+ DPRINTFN(1, ("%s: SYNC desc %ld\n", __func__,
+ (long)(TAILQ_FIRST(&fc->fc_buf)->fb_desc - sc->sc_desc)));
}
return 0;
}
+int
+fwohci_block_handler_set(struct fwohci_softc *sc, int tcode, u_int32_t key1,
+ u_int32_t key2, int len, int (*handler)(struct fwohci_softc *, void *,
+ struct fwohci_pkt *), void *arg)
+{
+ u_int32_t key1_n = (key1 & 0xffff) | ((len & 0xffff) << 16);
+
+ return (fwohci_handler_set(sc, tcode, key1_n, key2, handler, arg));
+}
+
/*
* Asyncronous Receive Requests input frontend.
*/
void
fwohci_arrq_input(struct fwohci_softc *sc, struct fwohci_ctx *fc)
{
- int rcode;
+ u_int16_t srcid, datalen = 0;
+ int rcode, tlabel;
u_int32_t key1, key2;
struct fwohci_handler *fh;
struct fwohci_pkt pkt, res;
@@ -1716,40 +2145,60 @@ fwohci_arrq_input(struct fwohci_softc *sc, struct fwohci_ctx *fc)
* packet cannot be received until the next receive interrupt.
*/
while (fwohci_buf_input(sc, fc, &pkt)) {
- if (pkt.fp_tcode == OHCI_TCODE_PHY) {
+ switch(pkt.fp_tcode) {
+ case OHCI_TCODE_PHY:
fwohci_phy_input(sc, &pkt);
- continue;
+ continue; break;
+ case IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK:
+ datalen = pkt.fp_dlen;
+ break;
+ case IEEE1394_TCODE_READ_REQUEST_DATABLOCK:
+ datalen = pkt.fp_hdr[3] >> 16;
+ break;
}
key1 = pkt.fp_hdr[1] & 0xffff;
key2 = pkt.fp_hdr[2];
- memset(&res, 0, sizeof(res));
+ bzero(&res, sizeof(res));
res.fp_uio.uio_rw = UIO_WRITE;
res.fp_uio.uio_segflg = UIO_SYSSPACE;
- for (fh = LIST_FIRST(&fc->fc_handler); fh != NULL;
- fh = LIST_NEXT(fh, fh_list)) {
+ srcid = pkt.fp_hdr[1] >> 16;
+ tlabel = (pkt.fp_hdr[0] & 0x0000fc00) >> 10;
+ DPRINTFN(1, ("%s: tcode 0x%x, from 0x%04x, tlabel 0x%x, "
+ "hlen %d, dlen %d\n", __func__, pkt.fp_tcode,
+ srcid, tlabel, pkt.fp_hlen, pkt.fp_dlen));
+ LIST_FOREACH(fh, &fc->fc_handler, fh_list) {
if (pkt.fp_tcode == fh->fh_tcode &&
- key1 == fh->fh_key1 &&
- key2 == fh->fh_key2) {
+ ((key1 == fh->fh_key1 && key2 == fh->fh_key2) ||
+ (datalen && key1 == (fh->fh_key1 & 0xffff) &&
+ key2 >= fh->fh_key2 &&
+ (key2 + datalen) <=
+ (fh->fh_key2 + ((fh->fh_key1 >> 16) & 0xffff)))))
+ {
+ DPRINTFN(5, ("%s: handler 0x%08x(0x%08x)\n",
+ __func__, (u_int32_t)(*fh->fh_handler),
+ (u_int32_t)(fh->fh_handarg)));
rcode = (*fh->fh_handler)(sc, fh->fh_handarg,
&pkt);
+ DPRINTFN(5, ("%s: --> rcode %d\n", __func__,
+ rcode));
break;
}
}
if (fh == NULL) {
rcode = IEEE1394_RCODE_ADDRESS_ERROR;
- DPRINTFN(1, ("fwohci_arrq_input: no listener: tcode "
- "0x%x, addr=0x%04x %08x\n", pkt.fp_tcode, key1,
- key2));
+ DPRINTFN(1, ("%s: no listener: tcode 0x%x, "
+ "addr=0x%04x%08x\n", __func__, pkt.fp_tcode,
+ key1, key2));
}
if (((*pkt.fp_trail & 0x001f0000) >> 16) !=
OHCI_CTXCTL_EVENT_ACK_PENDING)
continue;
- if (rcode != -1)
+ if (rcode != -1)
fwohci_atrs_output(sc, rcode, &pkt, &res);
}
fwohci_buf_next(sc, fc);
- OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx,
- OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_WAKE);
+ OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, OHCI_SUBREG_ContextControlSet,
+ OHCI_CTXCTL_WAKE);
}
@@ -1768,27 +2217,28 @@ fwohci_arrs_input(struct fwohci_softc *sc, struct fwohci_ctx *fc)
srcid = pkt.fp_hdr[1] >> 16;
rcode = (pkt.fp_hdr[1] & 0x0000f000) >> 12;
tlabel = (pkt.fp_hdr[0] & 0x0000fc00) >> 10;
- DPRINTFN(1, ("fwohci_arrs_input: tcode 0x%x, from 0x%04x,"
- " tlabel 0x%x, rcode 0x%x, hlen %d, dlen %d\n",
+ DPRINTFN(1, ("%s: tcode 0x%x, from 0x%04x, tlabel 0x%x, "
+ "rcode 0x%x, hlen %d, dlen %d\n", __func__,
pkt.fp_tcode, srcid, tlabel, rcode, pkt.fp_hlen,
pkt.fp_dlen));
- for (fh = LIST_FIRST(&fc->fc_handler); fh != NULL;
- fh = LIST_NEXT(fh, fh_list)) {
+ LIST_FOREACH(fh, &fc->fc_handler, fh_list) {
if (pkt.fp_tcode == fh->fh_tcode &&
(srcid & OHCI_NodeId_NodeNumber) == fh->fh_key1 &&
tlabel == fh->fh_key2) {
(*fh->fh_handler)(sc, fh->fh_handarg, &pkt);
LIST_REMOVE(fh, fh_list);
- free(fh, M_DEVBUF);
+ FREE(fh, M_DEVBUF);
+ //MPRINTF_OLD("FREE(DEVBUF)", fh);
+ fh = NULL; /* XXX */
break;
}
}
- if (fh == NULL)
- DPRINTFN(1, ("fwohci_arrs_input: no listner\n"));
+ if (fh == NULL)
+ DPRINTFN(1, ("%s: no listener\n", __func__));
}
fwohci_buf_next(sc, fc);
- OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx,
- OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_WAKE);
+ OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx, OHCI_SUBREG_ContextControlSet,
+ OHCI_CTXCTL_WAKE);
}
/*
@@ -1808,18 +2258,20 @@ fwohci_ir_input(struct fwohci_softc *sc, struct fwohci_ctx *fc)
int i;
u_int32_t reg;
- /* stop dma engine before read buffer */
+ /* Stop dma engine before read buffer. */
reg = OHCI_SYNC_RX_DMA_READ(sc, fc->fc_ctx,
OHCI_SUBREG_ContextControlClear);
- DPRINTFN(5, ("ir_input %08x =>", reg));
+ DPRINTFN(5, ("%s: %08x =>", __func__, reg));
if (reg & OHCI_CTXCTL_RUN) {
OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx,
OHCI_SUBREG_ContextControlClear, OHCI_CTXCTL_RUN);
}
- DPRINTFN(5, (" %08x\n", OHCI_SYNC_RX_DMA_READ(sc, fc->fc_ctx, OHCI_SUBREG_ContextControlClear)));
+ DPRINTFN(5, (" %08x\n", OHCI_SYNC_RX_DMA_READ(sc, fc->fc_ctx,
+ OHCI_SUBREG_ContextControlClear)));
i = 0;
- while ((reg = OHCI_SYNC_RX_DMA_READ(sc, fc->fc_ctx, OHCI_SUBREG_ContextControlSet)) & OHCI_CTXCTL_ACTIVE) {
+ while ((reg = OHCI_SYNC_RX_DMA_READ(sc, fc->fc_ctx,
+ OHCI_SUBREG_ContextControlSet)) & OHCI_CTXCTL_ACTIVE) {
delay(10);
if (++i > 10000) {
printf("cannot stop dma engine 0x%08x\n", reg);
@@ -1827,11 +2279,12 @@ fwohci_ir_input(struct fwohci_softc *sc, struct fwohci_ctx *fc)
}
}
- /* rotate dma buffer */
+ /* Rotate dma buffer. */
fb = TAILQ_FIRST(&fc->fc_buf2);
OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx, OHCI_SUBREG_CommandPtr,
fb->fb_daddr | 1);
- /* start dma engine */
+ MPRINTF("OHCI_SUBREG_CommandPtr(SYNC_RX)", fb->fb_daddr);
+ /* Start dma engine. */
OHCI_SYNC_RX_DMA_WRITE(sc, fc->fc_ctx,
OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN);
OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntEventClear,
@@ -1842,8 +2295,8 @@ fwohci_ir_input(struct fwohci_softc *sc, struct fwohci_ctx *fc)
while (fwohci_buf_input_ppb(sc, fc, &pkt)) {
chan = (pkt.fp_hdr[0] & 0x00003f00) >> 8;
tag = (pkt.fp_hdr[0] & 0x0000c000) >> 14;
- DPRINTFN(1, ("fwohci_ir_input: hdr 0x%08x, tcode 0x%0x, hlen %d"
- ", dlen %d\n", pkt.fp_hdr[0], pkt.fp_tcode, pkt.fp_hlen,
+ DPRINTFN(1, ("%s: hdr 0x%08x, tcode 0x%0x, hlen %d, dlen %d\n",
+ __func__, pkt.fp_hdr[0], pkt.fp_tcode, pkt.fp_hlen,
pkt.fp_dlen));
if (tag == IEEE1394_TAG_GASP) {
/*
@@ -1853,7 +2306,7 @@ fwohci_ir_input(struct fwohci_softc *sc, struct fwohci_ctx *fc)
if (pkt.fp_dlen < 8)
continue;
iov = pkt.fp_iov;
- /* assuming pkt per buffer mode */
+ /* Assuming pkt per buffer mode. */
pkt.fp_hdr[1] = ntohl(((u_int32_t *)iov->iov_base)[0]);
pkt.fp_hdr[2] = ntohl(((u_int32_t *)iov->iov_base)[1]);
iov->iov_base = (caddr_t)iov->iov_base + 8;
@@ -1862,8 +2315,7 @@ fwohci_ir_input(struct fwohci_softc *sc, struct fwohci_ctx *fc)
pkt.fp_dlen -= 8;
}
sc->sc_isopktcnt.ev_count++;
- for (fh = LIST_FIRST(&fc->fc_handler); fh != NULL;
- fh = LIST_NEXT(fh, fh_list)) {
+ LIST_FOREACH(fh, &fc->fc_handler, fh_list) {
if (pkt.fp_tcode == fh->fh_tcode &&
chan == fh->fh_key1 && tag == fh->fh_key2) {
rcode = (*fh->fh_handler)(sc, fh->fh_handarg,
@@ -1871,13 +2323,13 @@ fwohci_ir_input(struct fwohci_softc *sc, struct fwohci_ctx *fc)
break;
}
}
-#ifdef FW_DEBUG
+#ifdef FWOHCI_DEBUG
if (fh == NULL) {
- DPRINTFN(1, ("fwohci_ir_input: no handler\n"));
+ DPRINTFN(1, ("%s: no handler\n", __func__));
} else {
- DPRINTFN(1, ("fwohci_ir_input: rcode %d\n", rcode));
+ DPRINTFN(1, ("%s: rcode %d\n", __func__, rcode));
}
-#endif
+#endif /* FWOHCI_DEBUG */
}
fwohci_buf_next(sc, fc);
@@ -1900,29 +2352,32 @@ fwohci_at_output(struct fwohci_softc *sc, struct fwohci_ctx *fc,
struct mbuf *m, *m0;
int i, ndesc, error, off, len;
u_int32_t val;
-#ifdef FW_DEBUG
+#ifdef FWOHCI_DEBUG
struct iovec *iov;
-#endif
-
+#endif /* FWOHCI_DEBUG */
+
if ((sc->sc_nodeid & OHCI_NodeId_NodeNumber) == IEEE1394_BCAST_PHY_ID)
/* We can't send anything during selfid duration */
return EAGAIN;
-#ifdef FW_DEBUG
- DPRINTFN(1, ("fwohci_at_output: tcode 0x%x, hlen %d, dlen %d",
+#ifdef FWOHCI_DEBUG
+ DPRINTFN(1, ("%s: tcode 0x%x, hlen %d, dlen %d", __func__,
pkt->fp_tcode, pkt->fp_hlen, pkt->fp_dlen));
- for (i = 0; i < pkt->fp_hlen/4; i++)
+ for (i = 0; i < pkt->fp_hlen/4; i++)
DPRINTFN(2, ("%s%08x", i?" ":"\n ", pkt->fp_hdr[i]));
- DPRINTFN(2, ("$"));
- for (ndesc = 0, iov = pkt->fp_iov;
- ndesc < pkt->fp_uio.uio_iovcnt; ndesc++, iov++) {
- for (i = 0; i < iov->iov_len; i++)
- DPRINTFN(2, ("%s%02x", (i%32)?((i%4)?"":" "):"\n ",
- ((u_int8_t *)iov->iov_base)[i]));
- DPRINTFN(2, ("$"));
+ DPRINTFN(2, (" $"));
+ if (pkt->fp_uio.uio_iovcnt) {
+ for (ndesc = 0, iov = pkt->fp_iov;
+ ndesc < pkt->fp_uio.uio_iovcnt; ndesc++, iov++) {
+ for (i = 0; i < iov->iov_len; i++)
+ DPRINTFN(2, ("%s%02x", (i%32)?((i%4)?"":" ")
+ :"\n ",
+ ((u_int8_t *)iov->iov_base)[i]));
+ DPRINTFN(2, (" $"));
+ }
}
DPRINTFN(1, ("\n"));
-#endif
+#endif /* FWOHCI_DEBUG */
if ((m = pkt->fp_m) != NULL) {
for (ndesc = 2; m != NULL; m = m->m_next)
@@ -1933,8 +2388,9 @@ fwohci_at_output(struct fwohci_softc *sc, struct fwohci_ctx *fc,
for (off = 0; off < pkt->fp_dlen; off += len) {
if (m0 == NULL) {
MGETHDR(m0, M_DONTWAIT, MT_DATA);
+ //MPRINTF_OLD("MGETHDR", m0);
if (m0 != NULL) {
-#ifdef __NetBSD__
+#ifdef __NetBSD__
M_COPY_PKTHDR(m0, pkt->fp_m);
#else
M_DUP_PKTHDR(m0, pkt->fp_m);
@@ -1943,12 +2399,14 @@ fwohci_at_output(struct fwohci_softc *sc, struct fwohci_ctx *fc,
m = m0;
} else {
MGET(m->m_next, M_DONTWAIT, MT_DATA);
+ //MPRINTF_OLD("MGET", m->m_next);
m = m->m_next;
}
if (m != NULL)
MCLGET(m, M_DONTWAIT);
if (m == NULL || (m->m_flags & M_EXT) == 0) {
m_freem(m0);
+ //MPRINTF_OLD("m_freem", m0);
return ENOMEM;
}
len = pkt->fp_dlen - off;
@@ -1960,6 +2418,7 @@ fwohci_at_output(struct fwohci_softc *sc, struct fwohci_ctx *fc,
ndesc++;
}
m_freem(pkt->fp_m);
+ //MPRINTF_OLD("m_freem", pkt->fp_m);
pkt->fp_m = m0;
}
} else
@@ -1968,13 +2427,17 @@ fwohci_at_output(struct fwohci_softc *sc, struct fwohci_ctx *fc,
if (ndesc > OHCI_DESC_MAX)
return ENOBUFS;
- if (fc->fc_bufcnt > 50) /*XXX*/
+ if (fc->fc_bufcnt > 50) /* XXX */
return ENOBUFS;
+
fb = malloc(sizeof(*fb), M_DEVBUF, M_WAITOK);
+ //MPRINTF_OLD("malloc(DEVBUF)", fb);
fb->fb_nseg = ndesc;
fb->fb_desc = fwohci_desc_get(sc, ndesc);
if (fb->fb_desc == NULL) {
free(fb, M_DEVBUF);
+ //MPRINTF_OLD("free(DEVBUF)", fb);
+ fb = NULL; /* XXX */
return ENOBUFS;
}
fb->fb_daddr = sc->sc_ddmamap->dm_segs[0].ds_addr +
@@ -1983,14 +2446,17 @@ fwohci_at_output(struct fwohci_softc *sc, struct fwohci_ctx *fc,
fb->fb_callback = pkt->fp_callback;
fb->fb_statuscb = pkt->fp_statuscb;
fb->fb_statusarg = pkt->fp_statusarg;
-
+
if (ndesc > 2) {
if ((error = bus_dmamap_create(sc->sc_dmat, pkt->fp_dlen, ndesc,
PAGE_SIZE, 0, BUS_DMA_WAITOK, &fb->fb_dmamap)) != 0) {
fwohci_desc_put(sc, fb->fb_desc, ndesc);
free(fb, M_DEVBUF);
+ //MPRINTF_OLD("free(DEVBUF)", fb);
+ fb = NULL; /* XXX */
return error;
}
+ //MPRINTF_OLD("bus_dmamap_create", fb->fb_dmamap);
if (pkt->fp_m != NULL)
error = bus_dmamap_load_mbuf(sc->sc_dmat, fb->fb_dmamap,
@@ -2000,8 +2466,11 @@ fwohci_at_output(struct fwohci_softc *sc, struct fwohci_ctx *fc,
&pkt->fp_uio, BUS_DMA_WAITOK);
if (error != 0) {
bus_dmamap_destroy(sc->sc_dmat, fb->fb_dmamap);
+ //MPRINTF_OLD("bus_dmamap_destroy", fb->fb_dmamap);
fwohci_desc_put(sc, fb->fb_desc, ndesc);
free(fb, M_DEVBUF);
+ //MPRINTF_OLD("free(DEVBUF)", fb);
+ fb = NULL; /* XXX */
return error;
}
bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, 0, pkt->fp_dlen,
@@ -2021,27 +2490,37 @@ fwohci_at_output(struct fwohci_softc *sc, struct fwohci_ctx *fc,
((((val >> 25) + i) & 0x7) << 13);
} else
fd->fd_timestamp = 0;
- memcpy(fd + 1, pkt->fp_hdr, pkt->fp_hlen);
- for (i = 0; i < ndesc - 2; i++) {
- fd = fb->fb_desc + 2 + i;
- fd->fd_flags = 0;
- fd->fd_reqcount = fb->fb_dmamap->dm_segs[i].ds_len;
- fd->fd_data = fb->fb_dmamap->dm_segs[i].ds_addr;
- fd->fd_branch = 0;
- fd->fd_status = 0;
- fd->fd_timestamp = 0;
+
+#if 1 /* XXX */
+ bcopy(pkt->fp_hdr, fd + 1, pkt->fp_hlen);
+#else
+ bcopy(pkt->fp_hdr, fd->fd_immed, pkt->fp_hlen);
+#endif
+
+ if (ndesc > 2) {
+ for (i = 0; i < ndesc - 2; i++) {
+ fd = fb->fb_desc + 2 + i;
+ fd->fd_flags = 0;
+ fd->fd_reqcount = fb->fb_dmamap->dm_segs[i].ds_len;
+ fd->fd_data = fb->fb_dmamap->dm_segs[i].ds_addr;
+ fd->fd_branch = 0;
+ fd->fd_status = 0;
+ fd->fd_timestamp = 0;
+ }
+ bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, 0, pkt->fp_dlen,
+ BUS_DMASYNC_POSTWRITE);
}
fd->fd_flags |= OHCI_DESC_LAST | OHCI_DESC_BRANCH;
fd->fd_flags |= OHCI_DESC_INTR_ALWAYS;
-#ifdef FW_DEBUG
- DPRINTFN(1, ("fwohci_at_output: desc %ld",
+#ifdef FWOHCI_DEBUG
+ DPRINTFN(1, ("%s: desc %ld", __func__,
(long)(fb->fb_desc - sc->sc_desc)));
for (i = 0; i < ndesc * 4; i++)
DPRINTFN(2, ("%s%08x", i&7?" ":"\n ",
((u_int32_t *)fb->fb_desc)[i]));
DPRINTFN(1, ("\n"));
-#endif
+#endif /* FWOHCI_DEBUG */
val = OHCI_ASYNC_DMA_READ(sc, fc->fc_ctx,
OHCI_SUBREG_ContextControlClear);
@@ -2059,6 +2538,7 @@ fwohci_at_output(struct fwohci_softc *sc, struct fwohci_ctx *fc,
run:
OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx,
OHCI_SUBREG_CommandPtr, fb->fb_daddr | ndesc);
+ MPRINTF("OHCI_SUBREG_CommandPtr(ASYNC)", fb->fb_daddr);
OHCI_ASYNC_DMA_WRITE(sc, fc->fc_ctx,
OHCI_SUBREG_ContextControlSet, OHCI_CTXCTL_RUN);
}
@@ -2078,17 +2558,19 @@ fwohci_at_done(struct fwohci_softc *sc, struct fwohci_ctx *fc, int force)
struct fwohci_pkt pkt;
int i;
+// splassert(IPL_BIO);
+
while ((fb = TAILQ_FIRST(&fc->fc_buf)) != NULL) {
fd = fb->fb_desc;
-#ifdef FW_DEBUG
- DPRINTFN(1, ("fwohci_at_done: %sdesc %ld (%d)",
+#ifdef FWOHCI_DEBUG
+ DPRINTFN(1, ("%s: %sdesc %ld (%d)", __func__,
force ? "force " : "", (long)(fd - sc->sc_desc),
fb->fb_nseg));
for (i = 0; i < fb->fb_nseg * 4; i++)
DPRINTFN(2, ("%s%08x", i&7?" ":"\n ",
((u_int32_t *)fd)[i]));
DPRINTFN(1, ("\n"));
-#endif
+#endif /* FWOHCI_DEBUG */
if (fb->fb_nseg > 2)
fd += fb->fb_nseg - 1;
if (!force && !(fd->fd_status & OHCI_CTXCTL_ACTIVE))
@@ -2108,10 +2590,10 @@ fwohci_at_done(struct fwohci_softc *sc, struct fwohci_ctx *fc, int force)
}
if (fb->fb_statuscb) {
- memset(&pkt, 0, sizeof(pkt));
- pkt.fp_status = fd->fd_status;
- memcpy(pkt.fp_hdr, fd + 1, sizeof(pkt.fp_hdr[0]));
-
+ bzero(&pkt, sizeof(pkt));
+ pkt.fp_status = fd->fd_status;
+ bcopy(fd + 1, pkt.fp_hdr, sizeof(pkt.fp_hdr[0]));
+
/* Indicate this is just returning the status bits. */
pkt.fp_tcode = -1;
(*fb->fb_statuscb)(sc, fb->fb_statusarg, &pkt);
@@ -2119,15 +2601,21 @@ fwohci_at_done(struct fwohci_softc *sc, struct fwohci_ctx *fc, int force)
fb->fb_statusarg = NULL;
}
fwohci_desc_put(sc, fb->fb_desc, fb->fb_nseg);
- if (fb->fb_nseg > 2)
+ if (fb->fb_nseg > 2) {
bus_dmamap_destroy(sc->sc_dmat, fb->fb_dmamap);
+ //MPRINTF_OLD("bus_dmamap_destroy", fb->fb_dmamap);
+ }
fc->fc_bufcnt--;
if (fb->fb_callback) {
(*fb->fb_callback)(sc->sc_sc1394.sc1394_if, fb->fb_m);
fb->fb_callback = NULL;
- } else if (fb->fb_m != NULL)
+ } else if (fb->fb_m != NULL) {
m_freem(fb->fb_m);
+ //MPRINTF_OLD("m_freem", fb->fb_m);
+ }
free(fb, M_DEVBUF);
+ //MPRINTF_OLD("free(DEVBUF)", fb);
+ fb = NULL; /* XXX */
}
}
@@ -2140,19 +2628,19 @@ fwohci_atrs_output(struct fwohci_softc *sc, int rcode, struct fwohci_pkt *req,
{
if (((*req->fp_trail & 0x001f0000) >> 16) !=
- OHCI_CTXCTL_EVENT_ACK_PENDING)
+ OHCI_CTXCTL_EVENT_ACK_PENDING)
return;
res->fp_hdr[0] = (req->fp_hdr[0] & 0x0000fc00) | 0x00000100;
res->fp_hdr[1] = (req->fp_hdr[1] & 0xffff0000) | (rcode << 12);
switch (req->fp_tcode) {
- case IEEE1394_TCODE_WRITE_REQ_QUAD:
- case IEEE1394_TCODE_WRITE_REQ_BLOCK:
- res->fp_tcode = IEEE1394_TCODE_WRITE_RESP;
+ case IEEE1394_TCODE_WRITE_REQUEST_QUADLET:
+ case IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK:
+ res->fp_tcode = IEEE1394_TCODE_WRITE_RESPONSE;
res->fp_hlen = 12;
break;
- case IEEE1394_TCODE_READ_REQ_QUAD:
- res->fp_tcode = IEEE1394_TCODE_READ_RESP_QUAD;
+ case IEEE1394_TCODE_READ_REQUEST_QUADLET:
+ res->fp_tcode = IEEE1394_TCODE_READ_RESPONSE_QUADLET;
res->fp_hlen = 16;
res->fp_dlen = 0;
if (res->fp_uio.uio_iovcnt == 1 && res->fp_iov[0].iov_len == 4)
@@ -2160,12 +2648,12 @@ fwohci_atrs_output(struct fwohci_softc *sc, int rcode, struct fwohci_pkt *req,
*(u_int32_t *)res->fp_iov[0].iov_base;
res->fp_uio.uio_iovcnt = 0;
break;
- case IEEE1394_TCODE_READ_REQ_BLOCK:
- case IEEE1394_TCODE_LOCK_REQ:
- if (req->fp_tcode == IEEE1394_TCODE_LOCK_REQ)
- res->fp_tcode = IEEE1394_TCODE_LOCK_RESP;
+ case IEEE1394_TCODE_READ_REQUEST_DATABLOCK:
+ case IEEE1394_TCODE_LOCK_REQUEST:
+ if (req->fp_tcode == IEEE1394_TCODE_LOCK_REQUEST)
+ res->fp_tcode = IEEE1394_TCODE_LOCK_RESPONSE;
else
- res->fp_tcode = IEEE1394_TCODE_READ_RESP_BLOCK;
+ res->fp_tcode = IEEE1394_TCODE_READ_RESPONSE_DATABLOCK;
res->fp_hlen = 16;
res->fp_dlen = res->fp_uio.uio_resid;
res->fp_hdr[3] = res->fp_dlen << 16;
@@ -2176,11 +2664,11 @@ fwohci_atrs_output(struct fwohci_softc *sc, int rcode, struct fwohci_pkt *req,
}
/*
- * APPLICATION LAYER SERVICES
+ * APPLICATION LAYER SERVICES.
*/
/*
- * Retrieve Global UID from GUID ROM
+ * Retrieve Global UID from GUID ROM.
*/
int
fwohci_guidrom_init(struct fwohci_softc *sc)
@@ -2188,7 +2676,8 @@ fwohci_guidrom_init(struct fwohci_softc *sc)
int i, n, off;
u_int32_t val1, val2;
- /* Extract the Global UID
+ /*
+ * Extract the Global UID.
*/
val1 = OHCI_CSR_READ(sc, OHCI_REG_GUIDHi);
val2 = OHCI_CSR_READ(sc, OHCI_REG_GUIDLo);
@@ -2237,26 +2726,26 @@ fwohci_guidrom_init(struct fwohci_softc *sc)
}
/*
- * Initialization for Configuration ROM (no DMA context)
+ * Initialization for Configuration ROM (no DMA context).
*/
#define CFR_MAXUNIT 20
-struct configromctx {
+typedef struct configromctx {
u_int32_t *ptr;
- int curunit;
+ int curunit;
struct {
u_int32_t *start;
- int length;
+ int length;
u_int32_t *refer;
- int refunit;
+ int refunit;
} unit[CFR_MAXUNIT];
-};
+} configromctx;
#define CFR_PUT_DATA4(cfr, d1, d2, d3, d4) \
(*(cfr)->ptr++ = (((d1)<<24) | ((d2)<<16) | ((d3)<<8) | (d4)))
-#define CFR_PUT_DATA1(cfr, d) (*(cfr)->ptr++ = (d))
+#define CFR_PUT_DATA1(cfr, d) (*(cfr)->ptr++ = (d))
#define CFR_PUT_VALUE(cfr, key, d) (*(cfr)->ptr++ = ((key)<<24) | (d))
@@ -2273,21 +2762,21 @@ do { \
} \
(cfr)->curunit = (n); \
(cfr)->unit[n].start = (cfr)->ptr++; \
-} while (0 /* CONSTCOND */)
+} while (0)
#define CFR_PUT_REFER(cfr, key, n) \
do { \
(cfr)->unit[n].refer = (cfr)->ptr; \
(cfr)->unit[n].refunit = (cfr)->curunit; \
*(cfr)->ptr++ = (key) << 24; \
-} while (0 /* CONSTCOND */)
+} while (0)
#define CFR_END_UNIT(cfr) \
do { \
(cfr)->unit[(cfr)->curunit].length = (cfr)->ptr - \
((cfr)->unit[(cfr)->curunit].start + 1); \
CFR_PUT_CRC(cfr, (cfr)->curunit); \
-} while (0 /* CONSTCOND */)
+} while (0)
u_int16_t
fwohci_crc16(u_int32_t *ptr, int len)
@@ -2315,38 +2804,40 @@ fwohci_configrom_init(struct fwohci_softc *sc)
u_int32_t *hdr;
struct configromctx cfr;
+ splassert(IPL_BIO);
+
fb = &sc->sc_buf_cnfrom;
- memset(&cfr, 0, sizeof(cfr));
+ bzero(&cfr, sizeof(cfr));
cfr.ptr = hdr = (u_int32_t *)fb->fb_buf;
- /* headers */
+ /* Headers. */
CFR_START_UNIT(&cfr, 0);
CFR_PUT_DATA1(&cfr, OHCI_CSR_READ(sc, OHCI_REG_BusId));
CFR_PUT_DATA1(&cfr, OHCI_CSR_READ(sc, OHCI_REG_BusOptions));
CFR_PUT_DATA1(&cfr, OHCI_CSR_READ(sc, OHCI_REG_GUIDHi));
CFR_PUT_DATA1(&cfr, OHCI_CSR_READ(sc, OHCI_REG_GUIDLo));
CFR_END_UNIT(&cfr);
- /* copy info_length from crc_length */
+ /* Copy info_length from crc_length. */
*hdr |= (*hdr & 0x00ff0000) << 8;
OHCI_CSR_WRITE(sc, OHCI_REG_ConfigROMhdr, *hdr);
- /* root directory */
+ /* Root directory. */
CFR_START_UNIT(&cfr, 1);
- CFR_PUT_VALUE(&cfr, 0x03, 0x00005e); /* vendor id */
- CFR_PUT_REFER(&cfr, 0x81, 2); /* textual descriptor offset */
- CFR_PUT_VALUE(&cfr, 0x0c, 0x0083c0); /* node capability */
+ CFR_PUT_VALUE(&cfr, 0x03, 0x00005e); /* Vendor ID. */
+ CFR_PUT_REFER(&cfr, 0x81, 2); /* Textual descriptor offset. */
+ CFR_PUT_VALUE(&cfr, 0x0c, 0x0083c0); /* Node capability. */
/* spt,64,fix,lst,drq */
-#ifdef INET
- CFR_PUT_REFER(&cfr, 0xd1, 3); /* IPv4 unit directory */
-#endif /* INET */
-#ifdef INET6
- CFR_PUT_REFER(&cfr, 0xd1, 4); /* IPv6 unit directory */
-#endif /* INET6 */
+#ifdef INET
+ CFR_PUT_REFER(&cfr, 0xd1, 3); /* IPv4 unit directory. */
+#endif /* INET */
+#ifdef INET6
+ CFR_PUT_REFER(&cfr, 0xd1, 4); /* IPv6 unit directory. */
+#endif /* INET6 */
CFR_END_UNIT(&cfr);
CFR_START_UNIT(&cfr, 2);
- CFR_PUT_VALUE(&cfr, 0, 0); /* textual descriptor */
- CFR_PUT_DATA1(&cfr, 0); /* minimal ASCII */
+ CFR_PUT_VALUE(&cfr, 0, 0); /* Textual descriptor. */
+ CFR_PUT_DATA1(&cfr, 0); /* Minimal ASCII. */
#ifdef __NetBSD__
CFR_PUT_DATA4(&cfr, 'N', 'e', 't', 'B');
CFR_PUT_DATA4(&cfr, 'S', 'D', 0x00, 0x00);
@@ -2356,25 +2847,25 @@ fwohci_configrom_init(struct fwohci_softc *sc)
#endif
CFR_END_UNIT(&cfr);
-#ifdef INET
- /* IPv4 unit directory */
+#ifdef INET
+ /* IPv4 unit directory. */
CFR_START_UNIT(&cfr, 3);
- CFR_PUT_VALUE(&cfr, 0x12, 0x00005e); /* unit spec id */
- CFR_PUT_REFER(&cfr, 0x81, 6); /* textual descriptor offset */
- CFR_PUT_VALUE(&cfr, 0x13, 0x000001); /* unit sw version */
- CFR_PUT_REFER(&cfr, 0x81, 7); /* textual descriptor offset */
- CFR_PUT_REFER(&cfr, 0x95, 8); /* Unit location */
+ CFR_PUT_VALUE(&cfr, 0x12, 0x00005e); /* Unit spec ID. */
+ CFR_PUT_REFER(&cfr, 0x81, 6); /* Textual descriptor offset. */
+ CFR_PUT_VALUE(&cfr, 0x13, 0x000001); /* Unit sw version. */
+ CFR_PUT_REFER(&cfr, 0x81, 7); /* Textual descriptor offset. */
+ CFR_PUT_REFER(&cfr, 0x95, 8); /* unit location. */
CFR_END_UNIT(&cfr);
CFR_START_UNIT(&cfr, 6);
- CFR_PUT_VALUE(&cfr, 0, 0); /* textual descriptor */
- CFR_PUT_DATA1(&cfr, 0); /* minimal ASCII */
+ CFR_PUT_VALUE(&cfr, 0, 0); /* Textual descriptor. */
+ CFR_PUT_DATA1(&cfr, 0); /* Minimal ASCII. */
CFR_PUT_DATA4(&cfr, 'I', 'A', 'N', 'A');
CFR_END_UNIT(&cfr);
CFR_START_UNIT(&cfr, 7);
- CFR_PUT_VALUE(&cfr, 0, 0); /* textual descriptor */
- CFR_PUT_DATA1(&cfr, 0); /* minimal ASCII */
+ CFR_PUT_VALUE(&cfr, 0, 0); /* Textual descriptor. */
+ CFR_PUT_DATA1(&cfr, 0); /* Minimal ASCII. */
CFR_PUT_DATA4(&cfr, 'I', 'P', 'v', '4');
CFR_END_UNIT(&cfr);
@@ -2384,28 +2875,28 @@ fwohci_configrom_init(struct fwohci_softc *sc)
CFR_PUT_DATA1(&cfr, FW_FIFO_HI);
CFR_PUT_DATA1(&cfr, FW_FIFO_LO);
CFR_END_UNIT(&cfr);
-
-#endif /* INET */
-#ifdef INET6
- /* IPv6 unit directory */
+#endif /* INET */
+
+#ifdef INET6
+ /* IPv6 unit directory. */
CFR_START_UNIT(&cfr, 4);
- CFR_PUT_VALUE(&cfr, 0x12, 0x00005e); /* unit spec id */
- CFR_PUT_REFER(&cfr, 0x81, 9); /* textual descriptor offset */
- CFR_PUT_VALUE(&cfr, 0x13, 0x000002); /* unit sw version */
+ CFR_PUT_VALUE(&cfr, 0x12, 0x00005e); /* Unit spec id. */
+ CFR_PUT_REFER(&cfr, 0x81, 9); /* Textual descriptor offset. */
+ CFR_PUT_VALUE(&cfr, 0x13, 0x000002); /* Unit sw version. */
/* XXX: TBA by IANA */
- CFR_PUT_REFER(&cfr, 0x81, 10); /* textual descriptor offset */
- CFR_PUT_REFER(&cfr, 0x95, 11); /* Unit location */
+ CFR_PUT_REFER(&cfr, 0x81, 10); /* Textual descriptor offset. */
+ CFR_PUT_REFER(&cfr, 0x95, 11); /* Unit location. */
CFR_END_UNIT(&cfr);
CFR_START_UNIT(&cfr, 9);
- CFR_PUT_VALUE(&cfr, 0, 0); /* textual descriptor */
- CFR_PUT_DATA1(&cfr, 0); /* minimal ASCII */
+ CFR_PUT_VALUE(&cfr, 0, 0); /* Textual descriptor. */
+ CFR_PUT_DATA1(&cfr, 0); /* Minimal ASCII. */
CFR_PUT_DATA4(&cfr, 'I', 'A', 'N', 'A');
CFR_END_UNIT(&cfr);
CFR_START_UNIT(&cfr, 10);
- CFR_PUT_VALUE(&cfr, 0, 0); /* textual descriptor */
+ CFR_PUT_VALUE(&cfr, 0, 0); /* Textual descriptor. */
CFR_PUT_DATA1(&cfr, 0);
CFR_PUT_DATA4(&cfr, 'I', 'P', 'v', '6');
CFR_END_UNIT(&cfr);
@@ -2416,19 +2907,19 @@ fwohci_configrom_init(struct fwohci_softc *sc)
CFR_PUT_DATA1(&cfr, FW_FIFO_HI);
CFR_PUT_DATA1(&cfr, FW_FIFO_LO);
CFR_END_UNIT(&cfr);
-
-#endif /* INET6 */
+
+#endif /* INET6 */
fb->fb_off = cfr.ptr - hdr;
-#ifdef FW_DEBUG
+#ifdef FWOHCI_DEBUG
DPRINTF(("%s: Config ROM:", sc->sc_sc1394.sc1394_dev.dv_xname));
for (i = 0; i < fb->fb_off; i++)
DPRINTF(("%s%08x", i&7?" ":"\n ", hdr[i]));
DPRINTF(("\n"));
-#endif /* FW_DEBUG */
+#endif /* FWOHCI_DEBUG */
/*
- * Make network byte order for DMA
+ * Make network byte order for DMA.
*/
for (i = 0; i < fb->fb_off; i++)
HTONL(hdr[i]);
@@ -2444,10 +2935,10 @@ fwohci_configrom_init(struct fwohci_softc *sc)
(OHCI_Version_GET_Revision(val) == 1))
OHCI_CSR_WRITE(sc, OHCI_REG_HCControlSet,
OHCI_HCControl_BIBImageValid);
-
+
/* Just allow quad reads of the rom. */
- for (i = 0; i < fb->fb_off; i++)
- fwohci_handler_set(sc, IEEE1394_TCODE_READ_REQ_QUAD,
+ for (i = 0; i < fb->fb_off; i++)
+ fwohci_handler_set(sc, IEEE1394_TCODE_READ_REQUEST_QUADLET,
CSR_BASE_HI, CSR_BASE_LO + CSR_CONFIG_ROM + (i * 4),
fwohci_configrom_input, NULL);
}
@@ -2462,38 +2953,40 @@ fwohci_configrom_input(struct fwohci_softc *sc, void *arg,
/* This will be used as an array index so size accordingly. */
loc = pkt->fp_hdr[2] - (CSR_BASE_LO + CSR_CONFIG_ROM);
if ((loc & 0x03) != 0) {
- /* alignment error */
+ /* Alignment error. */
return IEEE1394_RCODE_ADDRESS_ERROR;
}
else
loc /= 4;
rom = (u_int32_t *)sc->sc_buf_cnfrom.fb_buf;
- DPRINTFN(1, ("fwohci_configrom_input: ConfigRom[0x%04x]: 0x%08x\n", loc,
+ DPRINTFN(1, ("%s: ConfigRom[0x%04x]: 0x%08x\n", __func__, loc,
ntohl(rom[loc])));
- memset(&res, 0, sizeof(res));
+ bzero(&res, sizeof(res));
res.fp_hdr[3] = rom[loc];
fwohci_atrs_output(sc, IEEE1394_RCODE_COMPLETE, pkt, &res);
return -1;
}
/*
- * SelfID buffer (no DMA context)
+ * SelfID buffer (no DMA context).
*/
void
fwohci_selfid_init(struct fwohci_softc *sc)
{
struct fwohci_buf *fb;
+ splassert(IPL_BIO);
+
fb = &sc->sc_buf_selfid;
-#ifdef DIAGNOSTIC
+#ifdef DIAGNOSTIC
if ((fb->fb_dmamap->dm_segs[0].ds_addr & 0x7ff) != 0)
panic("fwohci_selfid_init: not aligned: %ld (%ld) %p",
(unsigned long)fb->fb_dmamap->dm_segs[0].ds_addr,
(unsigned long)fb->fb_dmamap->dm_segs[0].ds_len, fb->fb_buf);
#endif
- memset(fb->fb_buf, 0, fb->fb_dmamap->dm_segs[0].ds_len);
+ bzero(fb->fb_buf, fb->fb_dmamap->dm_segs[0].ds_len);
bus_dmamap_sync(sc->sc_dmat, fb->fb_dmamap, 0,
fb->fb_dmamap->dm_segs[0].ds_len, BUS_DMASYNC_PREREAD);
@@ -2521,21 +3014,21 @@ fwohci_selfid_input(struct fwohci_softc *sc)
0, count << 2, BUS_DMASYNC_POSTREAD);
gen = OHCI_BITVAL(buf[0], OHCI_SelfID_Gen);
-#ifdef FW_DEBUG
+#ifdef FWOHCI_DEBUG
DPRINTFN(1, ("%s: SelfID: 0x%08x", sc->sc_sc1394.sc1394_dev.dv_xname,
val));
for (i = 0; i < count; i++)
DPRINTFN(2, ("%s%08x", i&7?" ":"\n ", buf[i]));
DPRINTFN(1, ("\n"));
-#endif /* FW_DEBUG */
+#endif /* FWOHCI_DEBUG */
for (i = 1; i < count; i += 2) {
if (buf[i] != ~buf[i + 1])
break;
if (buf[i] & 0x00000001)
- continue; /* more pkt */
+ continue; /* More pkt. */
if (buf[i] & 0x00800000)
- continue; /* external id */
+ continue; /* External ID. */
sc->sc_rootid = (buf[i] & 0x3f000000) >> 24;
if ((buf[i] & 0x00400800) == 0x00400800)
sc->sc_irmid = sc->sc_rootid;
@@ -2569,13 +3062,13 @@ fwohci_selfid_input(struct fwohci_softc *sc)
val = OHCI_CSR_READ(sc, OHCI_REG_NodeId);
if ((val & OHCI_NodeId_IDValid) == 0) {
- sc->sc_nodeid = 0xffff; /* invalid */
+ sc->sc_nodeid = 0xffff; /* Invalid. */
printf("%s: nodeid is invalid\n",
sc->sc_sc1394.sc1394_dev.dv_xname);
return -1;
}
sc->sc_nodeid = val & 0xffff;
-
+
DPRINTF(("%s: nodeid=0x%04x(%d), rootid=%d, irmid=%d\n",
sc->sc_sc1394.sc1394_dev.dv_xname, sc->sc_nodeid,
sc->sc_nodeid & OHCI_NodeId_NodeNumber, sc->sc_rootid,
@@ -2594,23 +3087,25 @@ fwohci_selfid_input(struct fwohci_softc *sc)
}
/*
- * some CSRs are handled by driver.
+ * Some CSRs are handled by driver.
*/
void
fwohci_csr_init(struct fwohci_softc *sc)
{
int i;
- static u_int32_t csr[] = {
+ static u_int32_t csr[] = {
CSR_STATE_CLEAR, CSR_STATE_SET, CSR_SB_CYCLE_TIME,
CSR_SB_BUS_TIME, CSR_SB_BUSY_TIMEOUT, CSR_SB_BUS_MANAGER_ID,
CSR_SB_CHANNEL_AVAILABLE_HI, CSR_SB_CHANNEL_AVAILABLE_LO,
CSR_SB_BROADCAST_CHANNEL
};
+ splassert(IPL_BIO);
+
for (i = 0; i < sizeof(csr) / sizeof(csr[0]); i++) {
- fwohci_handler_set(sc, IEEE1394_TCODE_WRITE_REQ_QUAD,
+ fwohci_handler_set(sc, IEEE1394_TCODE_WRITE_REQUEST_QUADLET,
CSR_BASE_HI, CSR_BASE_LO + csr[i], fwohci_csr_input, NULL);
- fwohci_handler_set(sc, IEEE1394_TCODE_READ_REQ_QUAD,
+ fwohci_handler_set(sc, IEEE1394_TCODE_READ_REQUEST_QUADLET,
CSR_BASE_HI, CSR_BASE_LO + csr[i], fwohci_csr_input, NULL);
}
sc->sc_csr[CSR_SB_BROADCAST_CHANNEL] = 31; /*XXX*/
@@ -2623,17 +3118,17 @@ fwohci_csr_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
u_int32_t reg;
/*
- * XXX need to do special functionality other than just r/w...
+ * XXX Need to do special functionality other than just r/w...
*/
reg = pkt->fp_hdr[2] - CSR_BASE_LO;
if ((reg & 0x03) != 0) {
- /* alignment error */
+ /* Alignment error. */
return IEEE1394_RCODE_ADDRESS_ERROR;
}
- DPRINTFN(1, ("fwohci_csr_input: CSR[0x%04x]: 0x%08x", reg,
+ DPRINTFN(1, ("%s: CSR[0x%04x]: 0x%08x", __func__, reg,
*(u_int32_t *)(&sc->sc_csr[reg])));
- if (pkt->fp_tcode == IEEE1394_TCODE_WRITE_REQ_QUAD) {
+ if (pkt->fp_tcode == IEEE1394_TCODE_WRITE_REQUEST_QUADLET) {
DPRINTFN(1, (" -> 0x%08x\n",
ntohl(*(u_int32_t *)pkt->fp_iov[0].iov_base)));
*(u_int32_t *)&sc->sc_csr[reg] =
@@ -2667,28 +3162,35 @@ fwohci_uid_collect(struct fwohci_softc *sc)
LIST_FOREACH(iea, &sc->sc_nodelist, sc1394_node)
iea->sc1394_node_id = 0xffff;
- if (sc->sc_uidtbl != NULL)
+ if (sc->sc_uidtbl != NULL) {
free(sc->sc_uidtbl, M_DEVBUF);
-#ifdef M_ZERO
+ //MPRINTF_OLD("free(DEVBUF)", sc->sc_uidtbl);
+ sc->sc_uidtbl = NULL; /* XXX */
+ }
+#ifdef M_ZERO
sc->sc_uidtbl = malloc(sizeof(*fu) * (sc->sc_rootid + 1), M_DEVBUF,
- M_NOWAIT|M_ZERO); /* XXX M_WAITOK requires locks */
+ M_NOWAIT|M_ZERO); /* XXX M_WAITOK requires locks. */
+ //MPRINTF_OLD("malloc(DEVBUF)", sc->sc_uidtbl);
#else
sc->sc_uidtbl = malloc(sizeof(*fu) * (sc->sc_rootid + 1), M_DEVBUF,
- M_NOWAIT); /* XXX M_WAITOK requires locks */
- bzero(sc->sc_uidtbl, sizeof(*fu) * (sc->sc_rootid + 1));
+ M_NOWAIT); /* XXX M_WAITOK requires locks. */
+ //MPRINTF_OLD("malloc(DEVBUF)", sc->sc_uidtbl);
#endif
if (sc->sc_uidtbl == NULL)
return;
+#ifndef M_ZERO
+ bzero(sc->sc_uidtbl, sizeof(*fu) * (sc->sc_rootid + 1));
+#endif
for (i = 0, fu = sc->sc_uidtbl; i <= sc->sc_rootid; i++, fu++) {
if (i == (sc->sc_nodeid & OHCI_NodeId_NodeNumber)) {
- memcpy(fu->fu_uid, sc->sc_sc1394.sc1394_guid, 8);
+ bcopy(sc->sc_sc1394.sc1394_guid, fu->fu_uid, 8);
fu->fu_valid = 3;
iea = (struct ieee1394_softc *)sc->sc_sc1394.sc1394_if;
if (iea) {
iea->sc1394_node_id = i;
- DPRINTF(("%s: Updating nodeid to %d\n",
+ DPRINTF(("%s: Updating nodeid to %d\n",
iea->sc1394_dev.dv_xname,
iea->sc1394_node_id));
}
@@ -2706,23 +3208,23 @@ fwohci_uid_req(struct fwohci_softc *sc, int phyid)
{
struct fwohci_pkt pkt;
- memset(&pkt, 0, sizeof(pkt));
- pkt.fp_tcode = IEEE1394_TCODE_READ_REQ_QUAD;
+ bzero(&pkt, sizeof(pkt));
+ pkt.fp_tcode = IEEE1394_TCODE_READ_REQUEST_QUADLET;
pkt.fp_hlen = 12;
pkt.fp_dlen = 0;
- pkt.fp_hdr[0] = 0x00000100 | (sc->sc_tlabel << 10) |
+ pkt.fp_hdr[0] = 0x00000100 | (sc->sc_tlabel << 10) |
(pkt.fp_tcode << 4);
pkt.fp_hdr[1] = ((0xffc0 | phyid) << 16) | CSR_BASE_HI;
pkt.fp_hdr[2] = CSR_BASE_LO + CSR_CONFIG_ROM + 12;
- fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESP_QUAD, phyid,
+ fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESPONSE_QUADLET, phyid,
sc->sc_tlabel, fwohci_uid_input, (void *)0);
sc->sc_tlabel = (sc->sc_tlabel + 1) & 0x3f;
fwohci_at_output(sc, sc->sc_ctx_atrq, &pkt);
- pkt.fp_hdr[0] = 0x00000100 | (sc->sc_tlabel << 10) |
+ pkt.fp_hdr[0] = 0x00000100 | (sc->sc_tlabel << 10) |
(pkt.fp_tcode << 4);
pkt.fp_hdr[2] = CSR_BASE_LO + CSR_CONFIG_ROM + 16;
- fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESP_QUAD, phyid,
+ fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESPONSE_QUADLET, phyid,
sc->sc_tlabel, fwohci_uid_input, (void *)1);
sc->sc_tlabel = (sc->sc_tlabel + 1) & 0x3f;
fwohci_at_output(sc, sc->sc_ctx_atrq, &pkt);
@@ -2746,39 +3248,39 @@ fwohci_uid_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *res)
return 0;
fu = &sc->sc_uidtbl[n];
if (arg == 0) {
- memcpy(fu->fu_uid, res->fp_iov[0].iov_base, 4);
+ bcopy(res->fp_iov[0].iov_base, fu->fu_uid, 4);
fu->fu_valid |= 0x1;
} else {
- memcpy(fu->fu_uid + 4, res->fp_iov[0].iov_base, 4);
+ bcopy(res->fp_iov[0].iov_base, fu->fu_uid + 4, 4);
fu->fu_valid |= 0x2;
}
-#ifdef FW_DEBUG
+#ifdef FWOHCI_DEBUG
if (fu->fu_valid == 0x3)
- DPRINTFN(1, ("fwohci_uid_input: "
- "Node %d, UID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", n,
+ DPRINTFN(1, ("%s: Node %d, UID %02x:%02x:%02x:%02x:%02x:%02x:"
+ "%02x:%02x\n", __func__, n,
fu->fu_uid[0], fu->fu_uid[1], fu->fu_uid[2], fu->fu_uid[3],
fu->fu_uid[4], fu->fu_uid[5], fu->fu_uid[6], fu->fu_uid[7]));
-#endif
+#endif /* FWOHCI_DEBUG */
if (fu->fu_valid == 0x3) {
LIST_FOREACH(iea, &sc->sc_nodelist, sc1394_node)
if (memcmp(iea->sc1394_guid, fu->fu_uid, 8) == 0) {
found = 1;
iea->sc1394_node_id = n;
- DPRINTF(("%s: Updating nodeid to %d\n",
+ DPRINTF(("%s: Updating nodeid to %d\n",
iea->sc1394_dev.dv_xname,
iea->sc1394_node_id));
break;
}
if (!found) {
strcpy(fwa.name, "fwnode");
- memcpy(fwa.uid, fu->fu_uid, 8);
+ bcopy(fu->fu_uid, fwa.uid, 8);
fwa.nodeid = n;
fwa.read = fwohci_read;
fwa.write = fwohci_write;
fwa.inreg = fwohci_inreg;
fwa.unreg = fwohci_unreg;
iea = (struct ieee1394_softc *)
- config_found_sm(&sc->sc_sc1394.sc1394_dev, &fwa,
+ config_found_sm(&sc->sc_sc1394.sc1394_dev, &fwa,
fwohci_print, fwohci_submatch);
if (iea != NULL)
LIST_INSERT_HEAD(&sc->sc_nodelist, iea,
@@ -2787,7 +3289,7 @@ fwohci_uid_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *res)
}
done = 1;
- for (i = 0; i < sc->sc_rootid + 1; i++) {
+ for (i = 0; i <= sc->sc_rootid; i++) {
fu = &sc->sc_uidtbl[i];
if (fu->fu_valid != 0x3) {
done = 0;
@@ -2817,6 +3319,7 @@ fwohci_check_nodes(struct fwohci_softc *sc)
*/
if (detach) {
+// config_detach_children(detach, 0);
config_detach(detach, 0);
detach = NULL;
}
@@ -2825,8 +3328,10 @@ fwohci_check_nodes(struct fwohci_softc *sc)
LIST_REMOVE(iea, sc1394_node);
}
}
- if (detach)
+ if (detach) {
+// config_detach_children(detach, 0);
config_detach(detach, 0);
+ }
}
int
@@ -2841,7 +3346,7 @@ fwohci_uid_lookup(struct fwohci_softc *sc, const u_int8_t *uid)
if (fu == NULL) {
if (memcmp(uid, bcast, sizeof(bcast)) == 0)
return IEEE1394_BCAST_PHY_ID;
- fwohci_uid_collect(sc); /* try to get */
+ fwohci_uid_collect(sc); /* Try to get. */
return -1;
}
for (n = 0; n <= sc->sc_rootid; n++, fu++) {
@@ -2853,7 +3358,7 @@ fwohci_uid_lookup(struct fwohci_softc *sc, const u_int8_t *uid)
for (n = 0, fu = sc->sc_uidtbl; n <= sc->sc_rootid; n++, fu++) {
if (fu->fu_valid != 0x3) {
/*
- * XXX: need timer before retransmission
+ * XXX: Need timer before retransmission.
*/
fwohci_uid_req(sc, n);
}
@@ -2862,7 +3367,7 @@ fwohci_uid_lookup(struct fwohci_softc *sc, const u_int8_t *uid)
}
/*
- * functions to support network interface
+ * Functions to support network interface.
*/
int
fwohci_if_inreg(struct device *self, u_int32_t offhi, u_int32_t offlo,
@@ -2870,9 +3375,9 @@ fwohci_if_inreg(struct device *self, u_int32_t offhi, u_int32_t offlo,
{
struct fwohci_softc *sc = (struct fwohci_softc *)self;
- fwohci_handler_set(sc, IEEE1394_TCODE_WRITE_REQ_BLOCK, offhi, offlo,
- handler ? fwohci_if_input : NULL, handler);
- fwohci_handler_set(sc, IEEE1394_TCODE_STREAM_DATA,
+ fwohci_handler_set(sc, IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK, offhi,
+ offlo, handler ? fwohci_if_input : NULL, handler);
+ fwohci_handler_set(sc, IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK,
(sc->sc_csr[CSR_SB_BROADCAST_CHANNEL] & IEEE1394_ISOCH_MASK) |
OHCI_ASYNC_STREAM,
IEEE1394_TAG_GASP, handler ? fwohci_if_input : NULL, handler);
@@ -2887,22 +3392,25 @@ fwohci_if_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
struct iovec *iov;
void (*handler)(struct device *, struct mbuf *) = arg;
-#ifdef FW_DEBUG
+#ifdef FWOHCI_DEBUG
int i;
- DPRINTFN(1, ("fwohci_if_input: tcode=0x%x, dlen=%d", pkt->fp_tcode,
+ DPRINTFN(1, ("%s: tcode=0x%x, dlen=%d", __func__, pkt->fp_tcode,
pkt->fp_dlen));
for (i = 0; i < pkt->fp_hlen/4; i++)
DPRINTFN(2, ("%s%08x", i?" ":"\n ", pkt->fp_hdr[i]));
DPRINTFN(2, ("$"));
- for (n = 0, len = pkt->fp_dlen; len > 0; len -= i, n++){
- iov = &pkt->fp_iov[n];
- for (i = 0; i < iov->iov_len; i++)
- DPRINTFN(2, ("%s%02x", (i%32)?((i%4)?"":" "):"\n ",
- ((u_int8_t *)iov->iov_base)[i]));
- DPRINTFN(2, ("$"));
+ if (pkt->fp_dlen) {
+ for (n = 0, len = pkt->fp_dlen; len > 0; len -= i, n++){
+ iov = &pkt->fp_iov[n];
+ for (i = 0; i < iov->iov_len; i++)
+ DPRINTFN(2, ("%s%02x", (i%32)?((i%4)?"":" ")
+ :"\n ",
+ ((u_int8_t *)iov->iov_base)[i]));
+ DPRINTFN(2, ("$"));
+ }
}
DPRINTFN(1, ("\n"));
-#endif /* FW_DEBUG */
+#endif /* FWOHCI_DEBUG */
len = pkt->fp_dlen;
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == NULL)
@@ -2912,6 +3420,7 @@ fwohci_if_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
MCLGET(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
m_freem(m);
+ //MPRINTF_OLD("m_freem", m);
return IEEE1394_RCODE_COMPLETE;
}
}
@@ -2921,18 +3430,19 @@ fwohci_if_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
printf("%s: packet from unknown node: phy id %d\n",
sc->sc_sc1394.sc1394_dev.dv_xname, n);
m_freem(m);
+ //MPRINTF_OLD("m_freem", m);
fwohci_uid_req(sc, n);
return IEEE1394_RCODE_COMPLETE;
}
- memcpy(mtod(m, caddr_t), sc->sc_uidtbl[n].fu_uid, 8);
- if (pkt->fp_tcode == IEEE1394_TCODE_STREAM_DATA) {
+ bcopy(sc->sc_uidtbl[n].fu_uid, mtod(m, caddr_t), 8);
+ if (pkt->fp_tcode == IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK) {
m->m_flags |= M_BCAST;
mtod(m, u_int32_t *)[2] = mtod(m, u_int32_t *)[3] = 0;
} else {
mtod(m, u_int32_t *)[2] = htonl(pkt->fp_hdr[1]);
mtod(m, u_int32_t *)[3] = htonl(pkt->fp_hdr[2]);
}
- mtod(m, u_int8_t *)[8] = n; /*XXX: node id for debug */
+ mtod(m, u_int8_t *)[8] = n; /*XXX: Node id for debug. */
mtod(m, u_int8_t *)[9] =
(*pkt->fp_trail >> (16 + OHCI_CTXCTL_SPD_BITPOS)) &
((1 << OHCI_CTXCTL_SPD_BITLEN) - 1);
@@ -2946,7 +3456,7 @@ fwohci_if_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
* If upper layer doesn't free mbuf soon, e.g. application program
* is suspended, buffer must be reallocated.
* Isochronous buffer must be operate in packet buffer mode, and
- * it is easy to map receive buffer to external mbuf. But it is
+ * it is easy to map receive buffer to external mbuf. But it is
* used for broadcast/multicast only, and is expected not so
* performance sensitive for now.
* XXX: The performance may be important for multicast case,
@@ -2956,7 +3466,7 @@ fwohci_if_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
n = 0;
iov = pkt->fp_uio.uio_iov;
while (len > 0) {
- memcpy(mtod(m, caddr_t) + m->m_len, iov->iov_base,
+ bcopy(iov->iov_base, mtod(m, caddr_t) + m->m_len,
iov->iov_len);
m->m_len += iov->iov_len;
len -= iov->iov_len;
@@ -2974,29 +3484,30 @@ fwohci_if_input_iso(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
struct mbuf *m;
struct iovec *iov;
void (*handler)(struct device *, struct mbuf *) = arg;
-#ifdef FW_DEBUG
+#ifdef FWOHCI_DEBUG
int i;
-#endif
+#endif /* FWOHCI_DEBUG */
chan = (pkt->fp_hdr[0] & 0x00003f00) >> 8;
tag = (pkt->fp_hdr[0] & 0x0000c000) >> 14;
-#ifdef FW_DEBUG
- DPRINTFN(1, ("fwohci_if_input_iso: "
- "tcode=0x%x, chan=%d, tag=%x, dlen=%d",
+#ifdef FWOHCI_DEBUG
+ DPRINTFN(1, ("%s: tcode=0x%x, chan=%d, tag=%x, dlen=%d", __func__,
pkt->fp_tcode, chan, tag, pkt->fp_dlen));
for (i = 0; i < pkt->fp_hlen/4; i++)
DPRINTFN(2, ("%s%08x", i?" ":"\n\t", pkt->fp_hdr[i]));
DPRINTFN(2, ("$"));
- for (n = 0, len = pkt->fp_dlen; len > 0; len -= i, n++){
- iov = &pkt->fp_iov[n];
- for (i = 0; i < iov->iov_len; i++)
- DPRINTFN(2, ("%s%02x",
- (i%32)?((i%4)?"":" "):"\n\t",
- ((u_int8_t *)iov->iov_base)[i]));
- DPRINTFN(2, ("$"));
+ if (pkt->fp_dlen) {
+ for (n = 0, len = pkt->fp_dlen; len > 0; len -= i, n++){
+ iov = &pkt->fp_iov[n];
+ for (i = 0; i < iov->iov_len; i++)
+ DPRINTFN(2, ("%s%02x",
+ (i%32)?((i%4)?"":" "):"\n\t",
+ ((u_int8_t *)iov->iov_base)[i]));
+ DPRINTFN(2, ("$"));
+ }
}
DPRINTFN(2, ("\n"));
-#endif /* FW_DEBUG */
+#endif /* FWOHCI_DEBUG */
len = pkt->fp_dlen;
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == NULL)
@@ -3006,6 +3517,7 @@ fwohci_if_input_iso(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
MCLGET(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
m_freem(m);
+ //MPRINTF_OLD("m_freem", m);
return IEEE1394_RCODE_COMPLETE;
}
}
@@ -3019,9 +3531,10 @@ fwohci_if_input_iso(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
printf("%s: packet from unknown node: phy id %d\n",
sc->sc_sc1394.sc1394_dev.dv_xname, n);
m_freem(m);
+ //MPRINTF_OLD("m_freem", m);
return IEEE1394_RCODE_COMPLETE;
}
- memcpy(mtod(m, caddr_t), sc->sc_uidtbl[n].fu_uid, 8);
+ bcopy(sc->sc_uidtbl[n].fu_uid, mtod(m, caddr_t), 8);
mtod(m, u_int32_t *)[2] = htonl(pkt->fp_hdr[1]);
mtod(m, u_int32_t *)[3] = htonl(pkt->fp_hdr[2]);
mtod(m, u_int8_t *)[8] = n; /*XXX: node id for debug */
@@ -3042,7 +3555,7 @@ fwohci_if_input_iso(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
* If upper layer doesn't free mbuf soon, e.g. application program
* is suspended, buffer must be reallocated.
* Isochronous buffer must be operate in packet buffer mode, and
- * it is easy to map receive buffer to external mbuf. But it is
+ * it is easy to map receive buffer to external mbuf. But it is
* used for broadcast/multicast only, and is expected not so
* performance sensitive for now.
* XXX: The performance may be important for multicast case,
@@ -3052,10 +3565,10 @@ fwohci_if_input_iso(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
n = 0;
iov = pkt->fp_uio.uio_iov;
while (len > 0) {
- memcpy(mtod(m, caddr_t) + m->m_len, iov->iov_base,
+ bcopy(iov->iov_base, mtod(m, caddr_t) + m->m_len,
iov->iov_len);
- m->m_len += iov->iov_len;
- len -= iov->iov_len;
+ m->m_len += iov->iov_len;
+ len -= iov->iov_len;
iov++;
}
(*handler)(sc->sc_sc1394.sc1394_if, m);
@@ -3072,9 +3585,9 @@ fwohci_if_output(struct device *self, struct mbuf *m0,
struct fwohci_pkt pkt;
u_int8_t *p;
int n, error, spd, hdrlen, maxrec;
-#ifdef FW_DEBUG
+#ifdef FWOHCI_DEBUG
struct mbuf *m;
-#endif
+#endif /* FWOHCI_DEBUG */
p = mtod(m0, u_int8_t *);
if (m0->m_flags & (M_BCAST | M_MCAST)) {
@@ -3094,7 +3607,7 @@ fwohci_if_output(struct device *self, struct mbuf *m0,
if (n == IEEE1394_BCAST_PHY_ID) {
printf("%s: broadcast with !M_MCAST\n",
sc->sc_sc1394.sc1394_dev.dv_xname);
-#ifdef FW_DEBUG
+#ifdef FWOHCI_DEBUG
DPRINTFN(2, ("packet:"));
for (m = m0; m != NULL; m = m->m_next) {
for (n = 0; n < m->m_len; n++)
@@ -3104,7 +3617,7 @@ fwohci_if_output(struct device *self, struct mbuf *m0,
DPRINTFN(2, ("$"));
}
DPRINTFN(2, ("\n"));
-#endif
+#endif /* FWOHCI_DEBUG */
error = EHOSTUNREACH;
goto end;
}
@@ -3113,53 +3626,53 @@ fwohci_if_output(struct device *self, struct mbuf *m0,
hdrlen = 0;
}
if (spd > sc->sc_sc1394.sc1394_link_speed) {
- DPRINTF(("fwohci_if_output: spd (%d) is faster than %d\n",
+ DPRINTF(("%s: spd (%d) is faster than %d\n", __func__,
spd, sc->sc_sc1394.sc1394_link_speed));
spd = sc->sc_sc1394.sc1394_link_speed;
}
if (maxrec > (512 << spd)) {
- DPRINTF(("fwohci_if_output: maxrec (%d) is larger for spd (%d)"
- "\n", maxrec, spd));
+ DPRINTF(("%s: maxrec (%d) is larger for spd (%d)\n", __func__,
+ maxrec, spd));
maxrec = 512 << spd;
}
while (maxrec > sc->sc_sc1394.sc1394_max_receive) {
- DPRINTF(("fwohci_if_output: maxrec (%d) is larger than"
- " %d\n", maxrec, sc->sc_sc1394.sc1394_max_receive));
+ DPRINTF(("%s: maxrec (%d) is larger than %d\n", __func__,
+ maxrec, sc->sc_sc1394.sc1394_max_receive));
maxrec >>= 1;
}
if (maxrec < 512) {
- DPRINTF(("fwohci_if_output: maxrec (%d) is smaller than "
- "minimum\n", maxrec));
+ DPRINTF(("%s: maxrec (%d) is smaller than minimum\n",
+ __func__, maxrec));
maxrec = 512;
}
m_adj(m0, 16 - hdrlen);
if (m0->m_pkthdr.len > maxrec) {
- DPRINTF(("fwohci_if_output: packet too big: hdr %d, pktlen "
- "%d, maxrec %d\n", hdrlen, m0->m_pkthdr.len, maxrec));
+ DPRINTF(("%s: packet too big: hdr %d, pktlen %d, maxrec %d\n",
+ __func__, hdrlen, m0->m_pkthdr.len, maxrec));
error = E2BIG; /*XXX*/
goto end;
}
- memset(&pkt, 0, sizeof(pkt));
+ bzero(&pkt, sizeof(pkt));
pkt.fp_uio.uio_iov = pkt.fp_iov;
pkt.fp_uio.uio_segflg = UIO_SYSSPACE;
pkt.fp_uio.uio_rw = UIO_WRITE;
if (m0->m_flags & (M_BCAST | M_MCAST)) {
- /* construct GASP header */
+ /* Construct GASP header. */
p = mtod(m0, u_int8_t *);
p[0] = sc->sc_nodeid >> 8;
p[1] = sc->sc_nodeid & 0xff;
p[2] = 0x00; p[3] = 0x00; p[4] = 0x5e;
p[5] = 0x00; p[6] = 0x00; p[7] = 0x01;
- pkt.fp_tcode = IEEE1394_TCODE_STREAM_DATA;
+ pkt.fp_tcode = IEEE1394_TCODE_ISOCHRONOUS_DATABLOCK;
pkt.fp_hlen = 8;
pkt.fp_hdr[0] = (spd << 16) | (IEEE1394_TAG_GASP << 14) |
((sc->sc_csr[CSR_SB_BROADCAST_CHANNEL] &
OHCI_NodeId_NodeNumber) << 8);
pkt.fp_hdr[1] = m0->m_pkthdr.len << 16;
} else {
- pkt.fp_tcode = IEEE1394_TCODE_WRITE_REQ_BLOCK;
+ pkt.fp_tcode = IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK;
pkt.fp_hlen = 16;
pkt.fp_hdr[0] = 0x00800100 | (sc->sc_tlabel << 10) |
(spd << 16);
@@ -3178,10 +3691,12 @@ fwohci_if_output(struct device *self, struct mbuf *m0,
m0 = pkt.fp_m;
end:
if (m0 != NULL) {
- if (callback)
+ if (callback) {
(*callback)(sc->sc_sc1394.sc1394_if, m0);
- else
+ } else {
m_freem(m0);
+ //MPRINTF_OLD("m_freem", m0);
+ }
}
return error;
}
@@ -3199,18 +3714,18 @@ fwohci_if_output(struct device *self, struct mbuf *m0,
* This routine will attempt to read a region from the requested node.
* A callback must be provided which will be called when either the completed
* read is done or an unrecoverable error occurs. This is mainly a convenience
- * routine since it will encapsulate retrying a region as quadlet vs. block
- * reads and recombining all the returned data. This could also be done with a
+ * routine since it will encapsulate retrying a region as quadlet vs. block
+ * reads and recombining all the returned data. This could also be done with a
* series of write/inreg's for each packet sent.
*
* int fwohci_write(struct ieee1394_abuf *)
*
* The work horse main entry point for putting packets on the bus. This is the
* generalized interface for fwnode/etc code to put packets out onto the bus.
- * It accepts all standard ieee1394 tcodes (XXX: only a few today) and
- * optionally will callback via a func pointer to the calling code with the
- * resulting ACK code from the packet. If the ACK code is to be ignored (i.e.
- * no cb) then the write routine will take care of free'ing the abuf since the
+ * It accepts all standard ieee1394 tcodes (XXX: only a few today) and
+ * optionally will callback via a func pointer to the calling code with the
+ * resulting ACK code from the packet. If the ACK code is to be ignored (i.e.
+ * no cb) then the write routine will take care of free'ing the abuf since the
* fwnode/etc code won't have any knowledge of when to do this. This allows for
* simple one-off packets to be sent from the upper-level code without worrying
* about a callback for cleanup.
@@ -3228,12 +3743,12 @@ fwohci_if_output(struct device *self, struct mbuf *m0,
* int fwohci_unreg(struct ieee1394_abuf *, int)
*
* This simply unregisters the respective callback done via inreg for items
- * which only need to register an area for a one-time operation (like a status
+ * that only need to register an area for a one-time operation (like a status
* buffer a remote node will write to when the current operation is done). The
* int argument specifies the same behavior as inreg, except in reverse (i.e.
* it unregisters).
*/
-
+
int
fwohci_read(struct ieee1394_abuf *ab)
{
@@ -3249,27 +3764,28 @@ fwohci_read(struct ieee1394_abuf *ab)
if (ab->ab_cb == NULL)
return -1;
- fcb = malloc(sizeof(struct fwohci_cb), M_DEVBUF, M_WAITOK);
+ MALLOC(fcb, struct fwohci_cb *, sizeof(*fcb), M_DEVBUF, M_WAITOK);
+ //MPRINTF_OLD("MALLOC(DEVBUF)", fcb);
fcb->ab = ab;
fcb->count = 0;
fcb->abuf_valid = 1;
-
+
high = ((ab->ab_addr & 0x0000ffff00000000) >> 32);
lo = (ab->ab_addr & 0x00000000ffffffff);
- memset(&pkt, 0, sizeof(pkt));
+ bzero(&pkt, sizeof(pkt));
pkt.fp_hdr[1] = ((0xffc0 | ab->ab_req->sc1394_node_id) << 16) | high;
pkt.fp_hdr[2] = lo;
pkt.fp_dlen = 0;
if (ab->ab_length == 4) {
- pkt.fp_tcode = IEEE1394_TCODE_READ_REQ_QUAD;
- tcode = IEEE1394_TCODE_READ_RESP_QUAD;
+ pkt.fp_tcode = IEEE1394_TCODE_READ_REQUEST_QUADLET;
+ tcode = IEEE1394_TCODE_READ_RESPONSE_QUADLET;
pkt.fp_hlen = 12;
} else {
- pkt.fp_tcode = IEEE1394_TCODE_READ_REQ_BLOCK;
+ pkt.fp_tcode = IEEE1394_TCODE_READ_REQUEST_DATABLOCK;
pkt.fp_hlen = 16;
- tcode = IEEE1394_TCODE_READ_RESP_BLOCK;
+ tcode = IEEE1394_TCODE_READ_RESPONSE_DATABLOCK;
pkt.fp_hdr[3] = (ab->ab_length << 16);
}
pkt.fp_hdr[0] = 0x00000100 | (sc->sc1394_link_speed << 16) |
@@ -3280,7 +3796,7 @@ fwohci_read(struct ieee1394_abuf *ab)
rv = fwohci_handler_set(psc, tcode, ab->ab_req->sc1394_node_id,
psc->sc_tlabel, fwohci_read_resp, fcb);
- if (rv)
+ if (rv)
return rv;
rv = fwohci_at_output(psc, psc->sc_ctx_atrq, &pkt);
if (rv)
@@ -3297,12 +3813,13 @@ fwohci_write(struct ieee1394_abuf *ab)
struct fwohci_pkt pkt;
struct ieee1394_softc *sc = ab->ab_req;
struct fwohci_softc *psc =
- (struct fwohci_softc *)sc->sc1394_dev.dv_parent;
+ (struct fwohci_softc *)sc->sc1394_dev.dv_parent;
u_int32_t high, lo;
int rv;
if (ab->ab_length > IEEE1394_MAX_REC(sc->sc1394_max_receive)) {
- DPRINTF(("Packet too large: %d\n", ab->ab_length));
+ DPRINTF(("%s: Packet too large: %d\n", __func__,
+ ab->ab_length));
return E2BIG;
}
@@ -3311,24 +3828,24 @@ fwohci_write(struct ieee1394_abuf *ab)
if ((ab->ab_data == NULL) && (ab->ab_uio == NULL))
panic("One of either ab_data or ab_uio must be set");
- memset(&pkt, 0, sizeof(pkt));
+ bzero(&pkt, sizeof(pkt));
pkt.fp_tcode = ab->ab_tcode;
if (ab->ab_data) {
pkt.fp_uio.uio_iov = pkt.fp_iov;
pkt.fp_uio.uio_segflg = UIO_SYSSPACE;
pkt.fp_uio.uio_rw = UIO_WRITE;
- } else
- memcpy(&pkt.fp_uio, ab->ab_uio, sizeof(struct uio));
-
+ } else
+ bcopy(ab->ab_uio, &pkt.fp_uio, sizeof(struct uio));
+
pkt.fp_statusarg = ab;
pkt.fp_statuscb = fwohci_write_ack;
switch (ab->ab_tcode) {
- case IEEE1394_TCODE_WRITE_RESP:
+ case IEEE1394_TCODE_WRITE_RESPONSE:
pkt.fp_hlen = 12;
- case IEEE1394_TCODE_READ_RESP_QUAD:
- case IEEE1394_TCODE_READ_RESP_BLOCK:
+ case IEEE1394_TCODE_READ_RESPONSE_QUADLET:
+ case IEEE1394_TCODE_READ_RESPONSE_DATABLOCK:
if (!pkt.fp_hlen)
pkt.fp_hlen = 16;
high = ab->ab_retlen;
@@ -3364,9 +3881,9 @@ fwohci_write(struct ieee1394_abuf *ab)
}
}
switch (ab->ab_tcode) {
- case IEEE1394_TCODE_WRITE_RESP:
- case IEEE1394_TCODE_READ_RESP_QUAD:
- case IEEE1394_TCODE_READ_RESP_BLOCK:
+ case IEEE1394_TCODE_WRITE_RESPONSE:
+ case IEEE1394_TCODE_READ_RESPONSE_QUADLET:
+ case IEEE1394_TCODE_READ_RESPONSE_DATABLOCK:
rv = fwohci_at_output(psc, psc->sc_ctx_atrs, &pkt);
break;
default:
@@ -3393,7 +3910,7 @@ fwohci_read_resp(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
* etc which makes it much more difficult to process if both aren't
* handled here.
*/
-
+
/* Check for status packet. */
if (pkt->fp_tcode == -1) {
@@ -3402,18 +3919,21 @@ fwohci_read_resp(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
tcode = (pkt->fp_hdr[0] >> 4) & 0xf;
if ((status != OHCI_CTXCTL_EVENT_ACK_COMPLETE) &&
(status != OHCI_CTXCTL_EVENT_ACK_PENDING))
- DPRINTFN(2, ("Got status packet: 0x%02x\n",
- (unsigned int)status));
+ DPRINTFN(2, ("%s: Got status packet: 0x%02x\n",
+ __func__, (unsigned int)status));
fcb->count--;
/*
* Got all the ack's back and the buffer is invalid (i.e. the
- * callback has been called. Clean up.
+ * callback has been called). Clean up.
*/
-
+
if (fcb->abuf_valid == 0) {
- if (fcb->count == 0)
- free(fcb, M_DEVBUF);
+ if (fcb->count == 0) {
+ FREE(fcb, M_DEVBUF);
+ //MPRINTF_OLD("FREE(DEVBUF)", fcb);
+ fcb = NULL; /* XXX */
+ }
return IEEE1394_RCODE_COMPLETE;
}
} else {
@@ -3423,7 +3943,7 @@ fwohci_read_resp(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
}
/*
- * Some area's (like the config rom want to be read as quadlets only.
+ * Some areas (like the config rom) want to be read as quadlets only.
*
* The current ideas to try are:
*
@@ -3433,23 +3953,23 @@ fwohci_read_resp(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
* response.
*
* In all cases construct a new packet for a quadlet read and let
- * mutli_resp handle the iteration over the space.
+ * multi_resp handle the iteration over the space.
*/
if (((status == OHCI_CTXCTL_EVENT_ACK_TYPE_ERROR) &&
- (tcode == IEEE1394_TCODE_READ_REQ_BLOCK)) ||
+ (tcode == IEEE1394_TCODE_READ_REQUEST_DATABLOCK)) ||
(((rcode == IEEE1394_RCODE_TYPE_ERROR) ||
- (rcode == IEEE1394_RCODE_ADDRESS_ERROR)) &&
- (tcode == IEEE1394_TCODE_READ_RESP_BLOCK))) {
+ (rcode == IEEE1394_RCODE_ADDRESS_ERROR)) &&
+ (tcode == IEEE1394_TCODE_READ_RESPONSE_DATABLOCK))) {
/* Read the area in quadlet chunks (internally track this). */
- memset(&newpkt, 0, sizeof(newpkt));
+ bzero(&newpkt, sizeof(newpkt));
high = ((ab->ab_addr & 0x0000ffff00000000) >> 32);
lo = (ab->ab_addr & 0x00000000ffffffff);
- newpkt.fp_tcode = IEEE1394_TCODE_READ_REQ_QUAD;
+ newpkt.fp_tcode = IEEE1394_TCODE_READ_REQUEST_QUADLET;
newpkt.fp_hlen = 12;
newpkt.fp_dlen = 0;
newpkt.fp_hdr[1] =
@@ -3458,7 +3978,8 @@ fwohci_read_resp(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
newpkt.fp_hdr[0] = 0x00000100 | (sc->sc_tlabel << 10) |
(newpkt.fp_tcode << 4);
- rv = fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESP_QUAD,
+ rv = fwohci_handler_set(sc,
+ IEEE1394_TCODE_READ_RESPONSE_QUADLET,
ab->ab_req->sc1394_node_id, sc->sc_tlabel,
fwohci_read_multi_resp, fcb);
if (rv) {
@@ -3469,7 +3990,8 @@ fwohci_read_resp(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
newpkt.fp_statuscb = fwohci_read_resp;
rv = fwohci_at_output(sc, sc->sc_ctx_atrq, &newpkt);
if (rv) {
- fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESP_QUAD,
+ fwohci_handler_set(sc,
+ IEEE1394_TCODE_READ_RESPONSE_QUADLET,
ab->ab_req->sc1394_node_id, sc->sc_tlabel, NULL,
NULL);
(*ab->ab_cb)(ab, -1);
@@ -3489,6 +4011,9 @@ fwohci_read_resp(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
if (rcode != -1) {
cur = ab->ab_data;
+
+ assert(pkt->fp_uio.uio_iovcnt > 0);
+
for (i = 0; i < pkt->fp_uio.uio_iovcnt; i++) {
/*
* Make sure and don't exceed the buffer
@@ -3496,22 +4021,23 @@ fwohci_read_resp(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
*/
if ((ab->ab_retlen + pkt->fp_iov[i].iov_len) >
ab->ab_length) {
- memcpy(cur, pkt->fp_iov[i].iov_base,
+ bcopy(pkt->fp_iov[i].iov_base, cur,
(ab->ab_length - ab->ab_retlen));
ab->ab_retlen = ab->ab_length;
break;
}
- memcpy(cur, pkt->fp_iov[i].iov_base,
+ bcopy(pkt->fp_iov[i].iov_base, cur,
pkt->fp_iov[i].iov_len);
- cur += pkt->fp_iov[i].iov_len;
+ (caddr_t)cur += pkt->fp_iov[i].iov_len;
ab->ab_retlen += pkt->fp_iov[i].iov_len;
}
+ DPRINTF(("%s: retlen=%d\n", __func__, ab->ab_retlen));
}
- if (status != -1)
+ if (status != -1)
/* XXX: Need a complete tlabel interface. */
for (i = 0; i < 64; i++)
fwohci_handler_set(sc,
- IEEE1394_TCODE_READ_RESP_QUAD,
+ IEEE1394_TCODE_READ_RESPONSE_QUADLET,
ab->ab_req->sc1394_node_id, i, NULL, NULL);
(*ab->ab_cb)(ab, rcode);
goto cleanup;
@@ -3520,11 +4046,14 @@ fwohci_read_resp(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
return IEEE1394_RCODE_COMPLETE;
/* Can't get here unless ab->ab_cb has been called. */
-
+
cleanup:
fcb->abuf_valid = 0;
- if (fcb->count == 0)
- free(fcb, M_DEVBUF);
+ if (fcb->count == 0) {
+ FREE(fcb, M_DEVBUF);
+ //MPRINTF_OLD("FREE(DEVBUF)", fcb);
+ fcb = NULL;
+ }
return IEEE1394_RCODE_COMPLETE;
}
@@ -3555,22 +4084,24 @@ fwohci_read_multi_resp(struct fwohci_softc *sc, void *arg,
}
if ((ab->ab_retlen + pkt->fp_iov[0].iov_len) > ab->ab_length) {
- memcpy(((char *)ab->ab_data + ab->ab_retlen),
- pkt->fp_iov[0].iov_base, (ab->ab_length - ab->ab_retlen));
+ bcopy(pkt->fp_iov[0].iov_base,
+ ((char *)ab->ab_data + ab->ab_retlen),
+ (ab->ab_length - ab->ab_retlen));
ab->ab_retlen = ab->ab_length;
} else {
- memcpy(((char *)ab->ab_data + ab->ab_retlen),
- pkt->fp_iov[0].iov_base, 4);
+ bcopy(pkt->fp_iov[0].iov_base,
+ ((char *)ab->ab_data + ab->ab_retlen), 4);
ab->ab_retlen += 4;
}
+ DPRINTF(("%s: retlen=%d\n", __func__, ab->ab_retlen));
/* Still more, loop and read 4 more bytes. */
if (ab->ab_retlen < ab->ab_length) {
- memset(&newpkt, 0, sizeof(newpkt));
+ bzero(&newpkt, sizeof(newpkt));
high = ((ab->ab_addr & 0x0000ffff00000000) >> 32);
lo = (ab->ab_addr & 0x00000000ffffffff) + ab->ab_retlen;
- newpkt.fp_tcode = IEEE1394_TCODE_READ_REQ_QUAD;
+ newpkt.fp_tcode = IEEE1394_TCODE_READ_REQUEST_QUADLET;
newpkt.fp_hlen = 12;
newpkt.fp_dlen = 0;
newpkt.fp_hdr[1] =
@@ -3583,19 +4114,20 @@ fwohci_read_multi_resp(struct fwohci_softc *sc, void *arg,
newpkt.fp_statuscb = fwohci_read_resp;
/*
- * Bad return code. Just give up and return what's
+ * Bad return code. Just give up and return what's
* come in now.
*/
- rv = fwohci_handler_set(sc, IEEE1394_TCODE_READ_RESP_QUAD,
+ rv = fwohci_handler_set(sc,
+ IEEE1394_TCODE_READ_RESPONSE_QUADLET,
ab->ab_req->sc1394_node_id, sc->sc_tlabel,
fwohci_read_multi_resp, fcb);
- if (rv)
+ if (rv)
(*ab->ab_cb)(ab, -1);
else {
rv = fwohci_at_output(sc, sc->sc_ctx_atrq, &newpkt);
if (rv) {
fwohci_handler_set(sc,
- IEEE1394_TCODE_READ_RESP_QUAD,
+ IEEE1394_TCODE_READ_RESPONSE_QUADLET,
ab->ab_req->sc1394_node_id, sc->sc_tlabel,
NULL, NULL);
(*ab->ab_cb)(ab, -1);
@@ -3611,8 +4143,11 @@ fwohci_read_multi_resp(struct fwohci_softc *sc, void *arg,
cleanup:
/* Can't get here unless ab_cb has been called. */
fcb->abuf_valid = 0;
- if (fcb->count == 0)
- free(fcb, M_DEVBUF);
+ if (fcb->count == 0) {
+ FREE(fcb, M_DEVBUF);
+ //MPRINTF_OLD("FREE(DEVBUF)", fcb);
+ fcb = NULL;
+ }
return IEEE1394_RCODE_COMPLETE;
}
@@ -3626,16 +4161,21 @@ fwohci_write_ack(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
status = pkt->fp_status & OHCI_DESC_STATUS_ACK_MASK;
if ((status != OHCI_CTXCTL_EVENT_ACK_COMPLETE) &&
(status != OHCI_CTXCTL_EVENT_ACK_PENDING))
- DPRINTF(("Got status packet: 0x%02x\n",
+ DPRINTF(("%s: Got status packet: 0x%02x\n", __func__,
(unsigned int)status));
/* No callback means this level should free the buffers. */
if (ab->ab_cb)
(*ab->ab_cb)(ab, status);
else {
- if (ab->ab_data)
+ if (ab->ab_data) {
free(ab->ab_data, M_1394DATA);
- free(ab, M_1394DATA);
+ //MPRINTF_OLD("free(1394DATA)", ab->ab_data);
+ ab->ab_data = NULL; /* XXX */
+ }
+ FREE(ab, M_1394DATA);
+ //MPRINTF_OLD("FREE(1394DATA)", ab);
+ ab = NULL; /* XXX */
}
return IEEE1394_RCODE_COMPLETE;
}
@@ -3645,27 +4185,36 @@ fwohci_inreg(struct ieee1394_abuf *ab, int allow)
{
struct ieee1394_softc *sc = ab->ab_req;
struct fwohci_softc *psc =
- (struct fwohci_softc *)sc->sc1394_dev.dv_parent;
+ (struct fwohci_softc *)sc->sc1394_dev.dv_parent;
u_int32_t high, lo;
- int i, j, rv;
+#if 0 /* use fwohci_block_handler_set */
+ int i, j;
+#endif
+ int rv;
high = ((ab->ab_addr & 0x0000ffff00000000) >> 32);
lo = (ab->ab_addr & 0x00000000ffffffff);
+#ifdef FWOHCI_DEBUG
+ if (ab->ab_retlen)
+ DPRINTF(("%s: retlen=%d\n", __func__, ab->ab_retlen));
+#endif /* FWOHCI_DEBUG */
+
rv = 0;
switch (ab->ab_tcode) {
- case IEEE1394_TCODE_READ_REQ_QUAD:
- case IEEE1394_TCODE_WRITE_REQ_QUAD:
+ case IEEE1394_TCODE_READ_REQUEST_QUADLET:
+ case IEEE1394_TCODE_WRITE_REQUEST_QUADLET:
if (ab->ab_cb)
rv = fwohci_handler_set(psc, ab->ab_tcode, high, lo,
fwohci_parse_input, ab);
else
- fwohci_handler_set(psc, ab->ab_tcode, high, lo, NULL,
- NULL);
+ fwohci_handler_set(psc, ab->ab_tcode, high, lo,
+ NULL, NULL);
break;
- case IEEE1394_TCODE_READ_REQ_BLOCK:
- case IEEE1394_TCODE_WRITE_REQ_BLOCK:
+ case IEEE1394_TCODE_READ_REQUEST_DATABLOCK:
+ case IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK:
if (allow) {
+#if 0 /* use fwohci_block_handler_set */
for (i = 0; i < (ab->ab_length / 4); i++) {
if (ab->ab_cb) {
rv = fwohci_handler_set(psc,
@@ -3679,18 +4228,27 @@ fwohci_inreg(struct ieee1394_abuf *ab, int allow)
}
if (i != (ab->ab_length / 4)) {
j = i + 1;
- for (i = 0; i < j; i++)
+ for (i = 0; i < j; i++)
fwohci_handler_set(psc, ab->ab_tcode,
high, lo + (i * 4), NULL, NULL);
}
+#else /* use fwohci_block_handler_set */
+ if (ab->ab_cb)
+ rv = fwohci_block_handler_set(psc, ab->ab_tcode,
+ high, lo, ab->ab_length, fwohci_parse_input,
+ ab);
+ else
+ fwohci_block_handler_set(psc, ab->ab_tcode,
+ high, lo, ab->ab_length, NULL, NULL);
+#endif /* use fwohci_block_handler_set */
/*
* XXX: Need something to indicate writing a smaller
* amount is ok.
- */
+ */
if (ab->ab_cb)
- ab->ab_data = (void *)1;
+ ab->ab_data = (void *)1;
} else {
- if (ab->ab_cb)
+ if (ab->ab_cb)
rv = fwohci_handler_set(psc, ab->ab_tcode, high,
lo, fwohci_parse_input, ab);
else
@@ -3699,7 +4257,8 @@ fwohci_inreg(struct ieee1394_abuf *ab, int allow)
}
break;
default:
- DPRINTF(("Invalid registration tcode: %d\n", ab->ab_tcode));
+ DPRINTF(("%s: Invalid registration tcode: %d\n", __func__,
+ ab->ab_tcode));
return -1;
break;
}
@@ -3711,7 +4270,7 @@ fwohci_unreg(struct ieee1394_abuf *ab, int allow)
{
void *save;
int rv;
-
+
save = ab->ab_cb;
ab->ab_cb = NULL;
rv = fwohci_inreg(ab, allow);
@@ -3731,50 +4290,76 @@ fwohci_parse_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
ab->ab_tlabel = (pkt->fp_hdr[0] >> 10) & 0x3f;
addr = (((u_int64_t)(pkt->fp_hdr[1] & 0xffff) << 32) | pkt->fp_hdr[2]);
+ DPRINTFN(3, ("%s: ab=0x%08x ab_cb=0x%08x\n\ttcode=%d tlabel=0x%02x"
+ " addr=%04x%08x\n", __func__, (u_int32_t)ab, (u_int32_t)ab->ab_cb,
+ ab->ab_tcode, ab->ab_tlabel, pkt->fp_hdr[1] & 0xffff,
+ pkt->fp_hdr[2]));
+
switch (ab->ab_tcode) {
- case IEEE1394_TCODE_READ_REQ_QUAD:
+ case IEEE1394_TCODE_READ_REQUEST_QUADLET:
ab->ab_retlen = 4;
break;
- case IEEE1394_TCODE_READ_REQ_BLOCK:
+ case IEEE1394_TCODE_READ_REQUEST_DATABLOCK:
ab->ab_retlen = (pkt->fp_hdr[3] >> 16) & 0xffff;
- if (ab->ab_data) {
- if ((addr + ab->ab_retlen) >
- (ab->ab_addr + ab->ab_length))
- return IEEE1394_RCODE_ADDRESS_ERROR;
+ if ((ab->ab_retlen > ab->ab_length) ||
+ ((addr + ab->ab_retlen) > (ab->ab_addr + ab->ab_length)))
+ return IEEE1394_RCODE_ADDRESS_ERROR;
+
+ if ((caddr_t)ab->ab_data > (caddr_t)1) {
+ free(ab->ab_data, M_1394DATA);
+ //MPRINTF_OLD("free(1394DATA)", ab->ab_data);
ab->ab_data = NULL;
- } else
- if (ab->ab_retlen != ab->ab_length)
- return IEEE1394_RCODE_ADDRESS_ERROR;
+ }
break;
- case IEEE1394_TCODE_WRITE_REQ_QUAD:
+ case IEEE1394_TCODE_WRITE_REQUEST_QUADLET:
ab->ab_retlen = 4;
- case IEEE1394_TCODE_WRITE_REQ_BLOCK:
- if (!ab->ab_retlen)
+ case IEEE1394_TCODE_WRITE_REQUEST_DATABLOCK:
+ if (!ab->ab_retlen)
ab->ab_retlen = (pkt->fp_hdr[3] >> 16) & 0xffff;
- if (ab->ab_data) {
- if ((addr + ab->ab_retlen) >
- (ab->ab_addr + ab->ab_length))
- return IEEE1394_RCODE_ADDRESS_ERROR;
- ab->ab_data = NULL;
- } else
- if (ab->ab_retlen != ab->ab_length)
- return IEEE1394_RCODE_ADDRESS_ERROR;
+ else {
+#ifdef FWOHCI_DEBUG
+ if (ab->ab_retlen != ((pkt->fp_hdr[3] >> 16) & 0xffff))
+ DPRINTF(("%s: retlen(%d) <> pktlen(%d)\n",
+ __func__, ab->ab_retlen,
+ (pkt->fp_hdr[3] >> 16) & 0xffff));
+#endif /* FWOHCI_DEBUG */
+#if 0
+ ab->ab_retlen = (pkt->fp_hdr[3] >> 16) & 0xffff;
+#endif
+ }
+ if ((ab->ab_retlen > ab->ab_length) ||
+ ((addr + ab->ab_retlen) > (ab->ab_addr + ab->ab_length)))
+ return IEEE1394_RCODE_ADDRESS_ERROR;
+ if ((caddr_t)ab->ab_data > (caddr_t)1) {
+ free(ab->ab_data, M_1394DATA);
+ //MPRINTF_OLD("free(1394DATA)", ab->ab_data);
+ ab->ab_data = NULL;
+ }
ab->ab_data = malloc(ab->ab_retlen, M_1394DATA, M_WAITOK);
- if (ab->ab_tcode == IEEE1394_TCODE_WRITE_REQ_QUAD)
+ //MPRINTF_OLD("malloc(1394DATA)", ab->ab_data);
+
+ if (ab->ab_tcode == IEEE1394_TCODE_WRITE_REQUEST_QUADLET)
ab->ab_data[0] = pkt->fp_hdr[3];
else {
count = 0;
cur = ab->ab_data;
+
+ assert(pkt->fp_uio.uio_iovcnt > 0);
+
for (i = 0; i < pkt->fp_uio.uio_iovcnt; i++) {
- memcpy(cur, pkt->fp_iov[i].iov_base,
+ DPRINTFN(3, ("\t%d : bcopy(0x%08x, 0x%08x,"
+ " 0x%x)\n", i,
+ (u_int32_t)pkt->fp_iov[i].iov_base,
+ (u_int32_t)cur, pkt->fp_iov[i].iov_len));
+ bcopy(pkt->fp_iov[i].iov_base, cur,
pkt->fp_iov[i].iov_len);
- cur += pkt->fp_iov[i].iov_len;
+ (caddr_t)cur += pkt->fp_iov[i].iov_len;
count += pkt->fp_iov[i].iov_len;
}
if (ab->ab_retlen != count)
panic("Packet claims %d length "
- "but only %d bytes returned",
+ "but %d bytes returned",
ab->ab_retlen, count);
}
break;
@@ -3788,7 +4373,7 @@ fwohci_parse_input(struct fwohci_softc *sc, void *arg, struct fwohci_pkt *pkt)
return -1;
}
-#ifdef __NetBSD__
+#ifdef __NetBSD__
int
fwohci_submatch(struct device *parent, struct cfdata *cf, void *aux)
#else
@@ -3797,7 +4382,7 @@ fwohci_submatch(struct device *parent, void *vcf, void *aux)
#endif
{
struct ieee1394_attach_args *fwa = aux;
-#ifdef __OpenBSD__
+#ifdef __OpenBSD__
struct cfdata *cf = (struct cfdata *)vcf;
#endif
@@ -3815,12 +4400,23 @@ fwohci_detach(struct fwohci_softc *sc, int flags)
{
int rv = 0;
- if (sc->sc_sc1394.sc1394_if != NULL)
- rv = config_detach(sc->sc_sc1394.sc1394_if, flags);
- if (rv != 0)
+ *sc->sc_dying = 1; /* Stop the event thread. */
+ wakeup(fwohci_event_thread);
+ DPRINTF(("%s: waiting 0x%08x\n", __func__, sc->sc_dying));
+ tsleep(sc->sc_dying, PZERO, "detach", 3 * hz);
+ DPRINTF(("%s: woken up...\n", __func__));
+ FREE(sc->sc_dying, M_DEVBUF);
+ //MPRINTF_OLD("FREE(DEVBUF)", sc->sc_dying);
+ sc->sc_dying = NULL; /* XXX */
+
+ if (sc->sc_sc1394.sc1394_if != NULL) {
+ rv = config_detach_children(sc->sc_sc1394.sc1394_if, flags);
+ rv |= config_detach(sc->sc_sc1394.sc1394_if, flags);
+ }
+ if (rv)
return (rv);
-#ifdef __NetBSD__
+#ifdef __NetBSD__
callout_stop(&sc->sc_selfid_callout);
#else
timeout_del(&sc->sc_selfid_callout);
@@ -3848,66 +4444,66 @@ fwohci_activate(struct device *self, enum devact act)
case DVACT_DEACTIVATE:
if (sc->sc_sc1394.sc1394_if != NULL)
- rv = config_deactivate(sc->sc_sc1394.sc1394_if);
- break;
+ rv = config_deactivate(sc->sc_sc1394.sc1394_if);
+ break;
}
splx(s);
return (rv);
}
-#ifdef FW_DEBUG
+#ifdef FWOHCI_DEBUG
void
fwohci_show_intr(struct fwohci_softc *sc, u_int32_t intmask)
{
- printf("%s: intmask=0x%08x:", sc->sc_sc1394.sc1394_dev.dv_xname,
- intmask);
+ DPRINTF(("%s: intmask=0x%08x:", sc->sc_sc1394.sc1394_dev.dv_xname,
+ intmask));
if (intmask & OHCI_Int_CycleTooLong)
- printf(" CycleTooLong");
+ DPRINTF((" CycleTooLong"));
if (intmask & OHCI_Int_UnrecoverableError)
- printf(" UnrecoverableError");
+ DPRINTF((" UnrecoverableError"));
if (intmask & OHCI_Int_CycleInconsistent)
- printf(" CycleInconsistent");
+ DPRINTF((" CycleInconsistent"));
if (intmask & OHCI_Int_BusReset)
- printf(" BusReset");
+ DPRINTF((" BusReset"));
if (intmask & OHCI_Int_SelfIDComplete)
- printf(" SelfIDComplete");
+ DPRINTF((" SelfIDComplete"));
if (intmask & OHCI_Int_LockRespErr)
- printf(" LockRespErr");
+ DPRINTF((" LockRespErr"));
if (intmask & OHCI_Int_PostedWriteErr)
- printf(" PostedWriteErr");
+ DPRINTF((" PostedWriteErr"));
if (intmask & OHCI_Int_ReqTxComplete)
- printf(" ReqTxComplete(0x%04x)",
+ DPRINTF((" ReqTxComplete(0x%04x)",
OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_TX_REQUEST,
- OHCI_SUBREG_ContextControlClear));
+ OHCI_SUBREG_ContextControlClear)));
if (intmask & OHCI_Int_RespTxComplete)
- printf(" RespTxComplete(0x%04x)",
+ DPRINTF((" RespTxComplete(0x%04x)",
OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_TX_RESPONSE,
- OHCI_SUBREG_ContextControlClear));
+ OHCI_SUBREG_ContextControlClear)));
if (intmask & OHCI_Int_ARRS)
- printf(" ARRS(0x%04x)",
+ DPRINTF((" ARRS(0x%04x)",
OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_RX_RESPONSE,
- OHCI_SUBREG_ContextControlClear));
+ OHCI_SUBREG_ContextControlClear)));
if (intmask & OHCI_Int_ARRQ)
- printf(" ARRQ(0x%04x)",
+ DPRINTF((" ARRQ(0x%04x)",
OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_RX_REQUEST,
- OHCI_SUBREG_ContextControlClear));
+ OHCI_SUBREG_ContextControlClear)));
if (intmask & OHCI_Int_IsochRx)
- printf(" IsochRx(0x%08x)",
- OHCI_CSR_READ(sc, OHCI_REG_IsoRecvIntEventClear));
+ DPRINTF((" IsochRx(0x%08x)",
+ OHCI_CSR_READ(sc, OHCI_REG_IsoRecvIntEventClear)));
if (intmask & OHCI_Int_IsochTx)
- printf(" IsochTx(0x%08x)",
- OHCI_CSR_READ(sc, OHCI_REG_IsoXmitIntEventClear));
+ DPRINTF((" IsochTx(0x%08x)",
+ OHCI_CSR_READ(sc, OHCI_REG_IsoXmitIntEventClear)));
if (intmask & OHCI_Int_RQPkt)
- printf(" RQPkt(0x%04x)",
+ DPRINTF((" RQPkt(0x%04x)",
OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_RX_REQUEST,
- OHCI_SUBREG_ContextControlClear));
+ OHCI_SUBREG_ContextControlClear)));
if (intmask & OHCI_Int_RSPkt)
- printf(" RSPkt(0x%04x)",
+ DPRINTF((" RSPkt(0x%04x)",
OHCI_ASYNC_DMA_READ(sc, OHCI_CTX_ASYNC_RX_RESPONSE,
- OHCI_SUBREG_ContextControlClear));
- printf("\n");
+ OHCI_SUBREG_ContextControlClear)));
+ DPRINTF(("\n"));
}
void
@@ -3917,41 +4513,42 @@ fwohci_show_phypkt(struct fwohci_softc *sc, u_int32_t val)
key = (val & 0xc0000000) >> 30;
phyid = (val & 0x3f000000) >> 24;
- printf("%s: PHY packet from %d: ",
- sc->sc_sc1394.sc1394_dev.dv_xname, phyid);
+ DPRINTF(("%s: PHY packet from %d: ",
+ sc->sc_sc1394.sc1394_dev.dv_xname, phyid));
switch (key) {
case 0:
- printf("PHY Config:");
+ DPRINTF(("PHY Config:"));
if (val & 0x00800000)
- printf(" ForceRoot");
+ DPRINTF((" ForceRoot"));
if (val & 0x00400000)
- printf(" Gap=%x", (val & 0x003f0000) >> 16);
- printf("\n");
+ DPRINTF((" Gap=%x", (val & 0x003f0000) >> 16));
+ DPRINTF(("\n"));
break;
case 1:
- printf("Link-on\n");
+ DPRINTF(("Link-on\n"));
break;
case 2:
- printf("SelfID:");
+ DPRINTF(("SelfID:"));
if (val & 0x00800000) {
- printf(" #%d", (val & 0x00700000) >> 20);
+ DPRINTF((" #%d", (val & 0x00700000) >> 20));
} else {
if (val & 0x00400000)
- printf(" LinkActive");
- printf(" Gap=%x", (val & 0x003f0000) >> 16);
- printf(" Spd=S%d", 100 << ((val & 0x0000c000) >> 14));
+ DPRINTF((" LinkActive"));
+ DPRINTF((" Gap=%x", (val & 0x003f0000) >> 16));
+ DPRINTF((" Spd=S%d", 100 <<
+ ((val & 0x0000c000) >> 14)));
if (val & 0x00000800)
- printf(" Cont");
+ DPRINTF((" Cont"));
if (val & 0x00000002)
- printf(" InitiateBusReset");
+ DPRINTF((" InitiateBusReset"));
}
if (val & 0x00000001)
- printf(" +");
- printf("\n");
+ DPRINTF((" +"));
+ DPRINTF(("\n"));
break;
default:
- printf("unknown: 0x%08x\n", val);
+ DPRINTF(("unknown: 0x%08x\n", val));
break;
}
}
-#endif /* FW_DEBUG */
+#endif /* FWOHCI_DEBUG */