Re: 8-CURRENT Firewire
Sean Bruno <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.firewire |
|---|---|
| Message-ID | <1247093348.2552.4.camel@Lappy> |
> >> 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 _______________________________________________ [email protected] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-firewire To unsubscribe, send any mail to "[email protected]"
fwohci.c.diff
(text/x-patch, 6.1 KB)
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);