diff options
Diffstat (limited to 'sys/dev/ieee1394/fwohci.c')
-rw-r--r-- | sys/dev/ieee1394/fwohci.c | 1885 |
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 */ |