Date: Mon, 19 Jan 2009 19:50:12 -0800 From: Sean Bruno <sean.bruno@dsl-only.net> To: freebsd-firewire <freebsd-firewire@FreeBSD.org> Cc: scottl@freebsd.org Subject: Firewire patch Message-ID: <1232423412.8966.2.camel@localhost.localdomain>
next in thread | raw e-mail | index | archive | help
--=-xypXswgjkkGUKFRM3GFa Content-Type: text/plain Content-Transfer-Encoding: 7bit Sorry it's taking me so long to wrap my brain around this code folks. Here is a small-ish patch I'd like to get comitted soon. This removes the filter implementation of the bus reset interrupt. It moves some malloc's into a more appropriate area and fixes a potential deadlock in SBP. Take a peak and give it a spin on stable/7 Sean --=-xypXswgjkkGUKFRM3GFa Content-Disposition: attachment; filename="firewire.diff" Content-Type: text/x-patch; name="firewire.diff"; charset="UTF-8" Content-Transfer-Encoding: 7bit Index: fwohci_pci.c =================================================================== --- fwohci_pci.c (revision 187454) +++ fwohci_pci.c (working copy) @@ -31,7 +31,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD$ + * $FreeBSD: stable/7/sys/dev/firewire/fwohci_pci.c 170374 2007-06-06 14:31:36Z simokawa $ */ #define BOUNCE_BUFFER_TEST 0 @@ -337,11 +337,8 @@ err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, -#if FWOHCI_INTFILT - fwohci_filt, NULL, sc, &sc->ih); -#else NULL, (driver_intr_t *) fwohci_intr, sc, &sc->ih); -#endif + #if defined(__DragonFly__) || __FreeBSD_version < 500000 /* XXX splcam() should mask this irq for sbp.c*/ err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_CAM, Index: firewire.c =================================================================== --- firewire.c (revision 187454) +++ firewire.c (working copy) @@ -31,7 +31,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD$ + * $FreeBSD: stable/7/sys/dev/firewire/firewire.c 171513 2007-07-20 03:42:57Z simokawa $ * */ @@ -429,6 +429,16 @@ fwdev_makedev(sc); + fc->crom_src_buf = (struct crom_src_buf *)malloc( + sizeof(struct crom_src_buf), + M_FW, M_NOWAIT | M_ZERO); + fc->topology_map = (struct fw_topology_map *)malloc( + sizeof(struct fw_topology_map), + M_FW, M_NOWAIT | M_ZERO); + fc->speed_map = (struct fw_speed_map *)malloc( + sizeof(struct fw_speed_map), + M_FW, M_NOWAIT | M_ZERO); + mtx_init(&fc->wait_lock, "fwwait", NULL, MTX_DEF); mtx_init(&fc->tlabel_lock, "fwtlabel", NULL, MTX_DEF); CALLOUT_INIT(&fc->timeout_callout); @@ -450,7 +460,9 @@ bus_generic_attach(dev); /* bus_reset */ + FW_GLOCK(fc); fw_busreset(fc, FWBUSNOTREADY); + FW_GUNLOCK(fc); fc->ibr(fc); return 0; @@ -638,11 +650,6 @@ { struct crom_src *src; - fc->crom_src_buf = (struct crom_src_buf *) - malloc(sizeof(struct crom_src_buf), M_FW, M_WAITOK | M_ZERO); - if (fc->crom_src_buf == NULL) - return; - src = &fc->crom_src_buf->src; bzero(src, sizeof(struct crom_src)); @@ -659,7 +666,7 @@ src->businfo.cyc_clk_acc = 100; src->businfo.max_rec = fc->maxrec; src->businfo.max_rom = MAXROM_4; - src->businfo.generation = 1; + src->businfo.generation = 0; src->businfo.link_spd = fc->speed; src->businfo.eui64.hi = fc->eui.hi; @@ -678,9 +685,6 @@ struct crom_src *src; struct crom_chunk *root; - if (fc->crom_src_buf == NULL) - fw_init_crom(fc); - buf = fc->crom_src_buf; src = fc->crom_src; root = fc->crom_root; @@ -711,18 +715,18 @@ struct firewire_dev_comm *fdc; struct crom_src *src; device_t *devlistp; - void *newrom; int i, devcnt; - switch(fc->status){ - case FWBUSMGRELECT: - callout_stop(&fc->bmr_callout); - break; - default: - break; - } + FW_GLOCK_ASSERT(fc); + if (fc->status == FWBUSMGRELECT) + callout_stop(&fc->bmr_callout); + fc->status = new_status; fw_reset_csr(fc); + + if (fc->status == FWBUSNOTREADY) + fw_init_crom(fc); + fw_reset_crom(fc); if (device_get_children(fc->bdev, &devlistp, &devcnt) == 0) { @@ -735,19 +739,19 @@ free(devlistp, M_TEMP); } - newrom = malloc(CROMSIZE, M_FW, M_NOWAIT | M_ZERO); src = &fc->crom_src_buf->src; - crom_load(src, (uint32_t *)newrom, CROMSIZE); - if (bcmp(newrom, fc->config_rom, CROMSIZE) != 0) { - /* bump generation and reload */ - src->businfo.generation ++; - /* generation must be between 0x2 and 0xF */ - if (src->businfo.generation < 2) - src->businfo.generation ++; - crom_load(src, (uint32_t *)newrom, CROMSIZE); - bcopy(newrom, (void *)fc->config_rom, CROMSIZE); - } - free(newrom, M_FW); + /* + * If the old config rom needs to be overwritten, + * bump the businfo.generation indicator to + * indicate that we need to be reprobed + */ + if (bcmp(src, fc->config_rom, CROMSIZE) != 0) { + /* generation is a 2 bit field */ + /* valid values are only from 0 - 3 */ + src->businfo.generation = 1; + bcopy(src, (void *)fc->config_rom, CROMSIZE); + } else + src->businfo.generation = 0; } /* Call once after reboot */ @@ -803,13 +807,6 @@ fc->ir[i]->maxq = FWMAXQUEUE; fc->it[i]->maxq = FWMAXQUEUE; } -/* Initialize csr registers */ - fc->topology_map = (struct fw_topology_map *)malloc( - sizeof(struct fw_topology_map), - M_FW, M_NOWAIT | M_ZERO); - fc->speed_map = (struct fw_speed_map *)malloc( - sizeof(struct fw_speed_map), - M_FW, M_NOWAIT | M_ZERO); CSRARC(fc, TOPO_MAP) = 0x3f1 << 16; CSRARC(fc, TOPO_MAP + 4) = 1; CSRARC(fc, SPED_MAP) = 0x3f1 << 16; @@ -1555,7 +1552,7 @@ /* unchanged ? */ if (bcmp(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5) == 0) { if (firewire_debug) - printf("node%d: crom unchanged\n", node); + device_printf(fc->dev, "node(%d): crom unchanged\n", node); return (0); } Index: fwohci.c =================================================================== --- fwohci.c (revision 187454) +++ fwohci.c (working copy) @@ -31,7 +31,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD$ + * $FreeBSD: stable/7/sys/dev/firewire/fwohci.c 170427 2007-06-08 09:04:30Z simokawa $ * */ @@ -1003,7 +1003,7 @@ if (maxdesc < db_tr->dbcnt) { maxdesc = db_tr->dbcnt; if (firewire_debug) - device_printf(sc->fc.dev, "maxdesc: %d\n", maxdesc); + device_printf(sc->fc.dev, "%s: maxdesc %d\n", __func__, maxdesc); } /* last db */ LAST_DB(db_tr, db); @@ -1843,6 +1843,7 @@ struct firewire_comm *fc = (struct firewire_comm *)sc; uint32_t node_id, plen; + FW_GLOCK_ASSERT(fc); if ((stat & OHCI_INT_PHY_BUS_R) && (fc->status != FWBUSRESET)) { fc->status = FWBUSRESET; /* Disable bus reset interrupt until sid recv. */ @@ -1885,8 +1886,8 @@ plen = OREAD(sc, OHCI_SID_CNT); fc->nodeid = node_id & 0x3f; - device_printf(fc->dev, "node_id=0x%08x, gen=%d, ", - node_id, (plen >> 16) & 0xff); + device_printf(fc->dev, "node_id=0x%08x, SelfID Count=%d, ", + fc->nodeid, (plen >> 16) & 0xff); if (!(node_id & OHCI_NODE_VALID)) { printf("Bus reset failure\n"); goto sidout; @@ -1997,9 +1998,11 @@ { struct fwohci_softc *sc = (struct fwohci_softc *)arg; + FW_GLOCK(&sc->fc); fw_busreset(&sc->fc, FWBUSRESET); OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0])); OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2])); + FW_GUNLOCK(&sc->fc); } static void @@ -2062,6 +2065,7 @@ { uint32_t stat, irstat, itstat; + FW_GLOCK_ASSERT(&sc->fc); stat = OREAD(sc, FWOHCI_INTSTAT); if (stat == 0xffffffff) { device_printf(sc->fc.dev, @@ -2091,29 +2095,23 @@ return (FILTER_HANDLED); } -int -fwohci_filt(void *arg) +void +fwohci_intr(void *arg) { struct fwohci_softc *sc = (struct fwohci_softc *)arg; - if (!(sc->intmask & OHCI_INT_EN)) { - /* polling mode */ - return (FILTER_STRAY); - } - return (fwohci_check_stat(sc)); + FW_GLOCK(&sc->fc); + fwohci_check_stat(sc); + FW_GUNLOCK(&sc->fc); } void -fwohci_intr(void *arg) -{ - fwohci_filt(arg); -} - -void fwohci_poll(struct firewire_comm *fc, int quick, int count) { struct fwohci_softc *sc = (struct fwohci_softc *)fc; + FW_GLOCK(fc); fwohci_check_stat(sc); + FW_GUNLOCK(fc); } static void @@ -2471,6 +2469,7 @@ * Make sure our cached values from the config rom are * initialised. */ + FW_GLOCK(fc); OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0])); OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2])); @@ -2487,6 +2486,7 @@ fun |= FW_PHY_ISBR | FW_PHY_RHB; fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun); #endif + FW_GUNLOCK(fc); } void Index: sbp.c =================================================================== --- sbp.c (revision 187454) +++ sbp.c (working copy) @@ -31,7 +31,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD$ + * $FreeBSD: stable/7/sys/dev/firewire/sbp.c 170872 2007-06-17 05:55:54Z scottl $ * */ @@ -1255,11 +1255,18 @@ htonl(((sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS )<< 16)); xfer->send.payload[1] = htonl((uint32_t)ocb->bus_addr); + /* + * sbp_xfer_free() will attempt to acquire + * the SBP lock on entrance. Also, this removes + * a LOR between the firewire layer and sbp + */ + SBP_UNLOCK(sdev->target->sbp); if(fw_asyreq(xfer->fc, -1, xfer) != 0){ sbp_xfer_free(xfer); ocb->ccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(ocb->ccb); } + SBP_LOCK(sdev->target->sbp); } static void Index: fwohcivar.h =================================================================== --- fwohcivar.h (revision 187454) +++ fwohcivar.h (working copy) @@ -31,18 +31,12 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD$ + * $FreeBSD: stable/7/sys/dev/firewire/fwohcivar.h 170374 2007-06-06 14:31:36Z simokawa $ * */ #include <sys/taskqueue.h> -#if defined(__DragonFly__) || __FreeBSD_version < 700043 -#define FWOHCI_INTFILT 0 -#else -#define FWOHCI_INTFILT 1 -#endif - typedef struct fwohci_softc { struct firewire_comm fc; bus_space_tag_t bst; --=-xypXswgjkkGUKFRM3GFa--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1232423412.8966.2.camel>