From owner-freebsd-firewire@FreeBSD.ORG Thu Jul 9 04:15:52 2009 Return-Path: Delivered-To: freebsd-firewire@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1B9D91065802 for ; Thu, 9 Jul 2009 04:15:52 +0000 (UTC) (envelope-from sean.bruno@dsl-only.net) Received: from iron2.pdx.net (iron2.pdx.net [69.64.224.71]) by mx1.freebsd.org (Postfix) with ESMTP id E48998FC1A for ; Thu, 9 Jul 2009 04:15:51 +0000 (UTC) (envelope-from sean.bruno@dsl-only.net) Received: (qmail 2158 invoked from network); 8 Jul 2009 15:49:06 -0700 Received: from host-244-242.pubnet.pdx.edu (HELO ?131.252.244.242?) (131.252.244.242) by iron2.pdx.net with (DHE-RSA-AES256-SHA encrypted) SMTP; 8 Jul 2009 15:49:06 -0700 From: Sean Bruno To: Julian Stecklina In-Reply-To: <87bpnwszf9.fsf@tabernacle.lan> References: <1246316092.3981.11.camel@Lappy> <87hbxxp5ot.fsf@tabernacle.lan> <1246483794.3443.6.camel@Lappy> <87fxdguj4a.fsf@tabernacle.lan> <878wj2r3t1.fsf@tabernacle.lan> <1246894876.2966.8.camel@Lappy> <87k52kt505.fsf@tabernacle.lan> <87bpnwszf9.fsf@tabernacle.lan> Content-Type: multipart/mixed; boundary="=-Z1PMy3ujl2uNspxmxomY" Date: Wed, 08 Jul 2009 15:49:08 -0700 Message-Id: <1247093348.2552.4.camel@Lappy> Mime-Version: 1.0 X-Mailer: Evolution 2.26.2 (2.26.2-1.fc11) Cc: freebsd-firewire@freebsd.org Subject: Re: 8-CURRENT Firewire X-BeenThere: freebsd-firewire@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Firewire support in FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Jul 2009 04:15:52 -0000 --=-Z1PMy3ujl2uNspxmxomY Content-Type: text/plain Content-Transfer-Encoding: 7bit > >> Hrm ... I think that fwohci() or firewire() is getting stuck. > >> > >> Can you turn up debug and re-run your boot up sequence just like the > >> above dmesg? > >> > >> firewire_debug=3 > >> sbp_debug=3 > > > > I think I am too stupid to set these variables. I tried > > debug.firewire_debug=3 in loader.conf, but it doesn't work. After > > loading the modules they are always set to zero. Setting via sysctl > > doesn't work either, since they don't exist before loading > > firewire/sbp. So how do I set these? > > Okay, I hardcoded them in the source... > > http://os.inf.tu-dresden.de/~jsteckli/fbsd/fw-log.txt > > Regards, For fun, please try to apply this diff and retest. Sean --=-Z1PMy3ujl2uNspxmxomY Content-Disposition: attachment; filename="fwohci.c.diff" Content-Type: text/x-patch; name="fwohci.c.diff"; charset="UTF-8" Content-Transfer-Encoding: 7bit Index: fwohci.c =================================================================== --- fwohci.c (revision 195344) +++ fwohci.c (working copy) @@ -280,7 +280,8 @@ fun = (PHYDEV_WRCMD | (addr << PHYDEV_REGADDR) | (data << PHYDEV_WRDATA)); OWRITE(sc, OHCI_PHYACCESS, fun); - DELAY(100); + bus_space_barrier(sc->bst, sc->bsh, OHCI_PHYACCESS, + 4, BUS_SPACE_BARRIER_WRITE); return(fwphy_rddata( sc, addr)); } @@ -316,43 +317,65 @@ fwphy_rddata(struct fwohci_softc *sc, u_int addr) { uint32_t fun, stat; - u_int i, retry = 0; + int retry = 0; addr &= 0xf; -#define MAX_RETRY 100 -again: + + + /* + * Read requested data from OHCI PHY + * If we generate an INT_REG_FAIL error + * from our request, most likely SCLK has + * not been started yet. pause() and retry. + * Mechanics of RDCMD and RDDONE are in + * ohci 1.1 Table 5-19 + */ + + /* Clear error register */ + stat = OREAD(sc, FWOHCI_INTSTAT); + stat &= ~OHCI_INT_REG_FAIL; OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_REG_FAIL); + + /* Issue requested command to PHY */ fun = PHYDEV_RDCMD | (addr << PHYDEV_REGADDR); OWRITE(sc, OHCI_PHYACCESS, fun); - for ( i = 0 ; i < MAX_RETRY ; i ++ ){ - fun = OREAD(sc, OHCI_PHYACCESS); - if ((fun & PHYDEV_RDCMD) == 0 && (fun & PHYDEV_RDDONE) != 0) - break; - DELAY(100); - } - if(i >= MAX_RETRY) { - if (firewire_debug) - device_printf(sc->fc.dev, "%s: failed(1).\n", __func__); - if (++retry < MAX_RETRY) { - DELAY(100); - goto again; - } - } - /* Make sure that SCLK is started */ - stat = OREAD(sc, FWOHCI_INTSTAT); - if ((stat & OHCI_INT_REG_FAIL) != 0 || + bus_space_barrier(sc->bst, sc->bsh, OHCI_PHYACCESS, + 4, BUS_SPACE_BARRIER_WRITE); +#define MAX_RETRY 5 + for ( retry = 0 ; retry < MAX_RETRY ; retry++ ){ + /* Check for error, sleep if error reg set */ + stat = OREAD(sc, FWOHCI_INTSTAT); + if ((stat & OHCI_INT_REG_FAIL) != 0 || ((fun >> PHYDEV_REGADDR) & 0xf) != addr) { - if (firewire_debug) - device_printf(sc->fc.dev, "%s: failed(2).\n", __func__); - if (++retry < MAX_RETRY) { - DELAY(100); - goto again; + if (firewire_debug) + device_printf(sc->fc.dev, "%s: " + "OHCI_INT_REG_FAIL.\n", __func__); + /* Clear error register */ + stat = OREAD(sc, FWOHCI_INTSTAT); + stat &= ~OHCI_INT_REG_FAIL; + OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_REG_FAIL); + pause("fwphyr", (50 * hz + 999) / 1000); + /* Issue requested command to PHY */ + fun = PHYDEV_RDCMD | (addr << PHYDEV_REGADDR); + OWRITE(sc, OHCI_PHYACCESS, fun); + bus_space_barrier(sc->bst, sc->bsh, OHCI_PHYACCESS, + 4, BUS_SPACE_BARRIER_WRITE); + } else { /* no error, check for command completion */ + fun = OREAD(sc, OHCI_PHYACCESS); + bus_space_barrier(sc->bst, sc->bsh, OHCI_PHYACCESS, + 4, BUS_SPACE_BARRIER_READ); + if ((fun & PHYDEV_RDCMD) == 0 && (fun & PHYDEV_RDDONE) != 0) { + retry = MAX_RETRY; /* exit loop. command complete */ + } else { /* pause for 100 usec to allow command completion */ + pause("fwphyr", hz/10); + } } + } - if (firewire_debug > 1 || retry >= MAX_RETRY) + if (firewire_debug > 1 || retry > MAX_RETRY) device_printf(sc->fc.dev, - "%s:: 0x%x loop=%d, retry=%d\n", - __func__, addr, i, retry); + "%s:: 0x%x, retry=%d\n", + __func__, addr, retry); #undef MAX_RETRY return((fun >> PHYDEV_RDDATA )& 0xff); } @@ -426,20 +449,45 @@ static int fwohci_probe_phy(struct fwohci_softc *sc, device_t dev) { - uint32_t reg, reg2; + uint32_t lps, reg, reg2; + int lps_counter = 0; int e1394a = 1; -/* - * probe PHY parameters - * 0. to prove PHY version, whether compliance of 1394a. - * 1. to probe maximum speed supported by the PHY and - * number of port supported by core-logic. - * It is not actually available port on your PC . - */ + + /* + * Enable LPS(Link Power Status as per + * section 5.7 of OHCI v1.1 + * This allows PHY communication after + * a hard/soft reset + * + * Some users report that the code + * will crash without the pause due + * to the lps bit being set and the + * PHY not being up. Implement pause + * here to work around this error. + */ OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LPS); - DELAY(500); - + bus_space_barrier(sc->bst, sc->bsh, OHCI_HCCCTL, 4, BUS_SPACE_BARRIER_WRITE); + for (lps = 0, lps_counter = 0; !lps && lps_counter < 3; lps_counter++) { + pause("fwlps", (50 * hz + 999) / 1000); + lps = (OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_LPS); + } + /* + * probe PHY parameters + * 0. to prove PHY version, whether compliance of 1394a. + * 1. to probe maximum speed supported by the PHY and + * number of port supported by core-logic. + * It is not actually available port on your PC . + */ reg = fwphy_rddata(sc, FW_PHY_SPD_REG); + /* + * ref 1394-2000 table 5B-1 + * ref 1394-1995 table J.12 + * If Extended is not set + * Assume 1394-1995 + * If Extended is set + * Assume 1394-2000(1394a) + */ if((reg >> 5) != 7 ){ sc->fc.mode &= ~FWPHYASYST; sc->fc.nport = reg & FW_PHY_NP; @@ -453,12 +501,12 @@ "Phy 1394 only %s, %d ports.\n", linkspeed[sc->fc.speed], sc->fc.nport); }else{ - reg2 = fwphy_rddata(sc, FW_PHY_ESPD_REG); sc->fc.mode |= FWPHYASYST; sc->fc.nport = reg & FW_PHY_NP; + reg2 = fwphy_rddata(sc, FW_PHY_ESPD_REG); sc->fc.speed = (reg2 & FW_PHY_ESPD) >> 5; if (sc->fc.speed > MAX_SPEED) { - device_printf(dev, "invalid speed %d (fixed to %d).\n", + device_printf(dev, "invalid extended speed %d (fixed to %d).\n", sc->fc.speed, MAX_SPEED); sc->fc.speed = MAX_SPEED; } @@ -468,11 +516,7 @@ /* check programPhyEnable */ reg2 = fwphy_rddata(sc, 5); -#if 0 - if (e1394a && (OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_PRPHY)) { -#else /* XXX force to enable 1394a */ if (e1394a) { -#endif if (firewire_debug) device_printf(dev, "Enable 1394a Enhancements\n"); @@ -488,6 +532,13 @@ reg2 = fwphy_wrdata(sc, 5, reg2); } + /* + * Re-read and check for extended 1394a + * PHY Register map. + * Then set the Contender bit on. + * This makes us a possible bus or isoc + * resource manager. (ieee 1394a-2000, 5B.1) + */ reg = fwphy_rddata(sc, FW_PHY_SPD_REG); if((reg >> 5) == 7 ){ reg = fwphy_rddata(sc, 4); --=-Z1PMy3ujl2uNspxmxomY--