From owner-freebsd-firewire@FreeBSD.ORG Mon Feb 16 23:57:29 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 28BC01065672 for ; Mon, 16 Feb 2009 23:57:29 +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 02E958FC14 for ; Mon, 16 Feb 2009 23:57:28 +0000 (UTC) (envelope-from sean.bruno@dsl-only.net) Received: (qmail 6517 invoked from network); 16 Feb 2009 15:56:35 -0800 Received: from 069-064-235-060.pdx.net (HELO ?192.168.1.51?) (69.64.235.60) by iron2.pdx.net with SMTP; 16 Feb 2009 15:56:35 -0800 From: Sean Bruno To: freebsd-firewire@FreeBSD.org Content-Type: multipart/mixed; boundary="=-WogEZ4mKZH42tVk8wBBN" Date: Mon, 16 Feb 2009 15:57:27 -0800 Message-Id: <1234828647.5736.3.camel@localhost.localdomain> Mime-Version: 1.0 X-Mailer: Evolution 2.24.3 (2.24.3-1.fc10) Cc: scottl Subject: Enhance speed detection 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: Mon, 16 Feb 2009 23:57:29 -0000 --=-WogEZ4mKZH42tVk8wBBN Content-Type: text/plain Content-Transfer-Encoding: 7bit Synopsis: If speed of link between two devices is slower than the reported max speed of both endpoints, the current driver will fail and be unable to negotiate. Summary: Test negotiated speed by reading the CSRROM into a dummy variable. If that read fails, decrement our speed and retry. If all else fails, go to lowest speed possible. Report speed to the user. Add display of the Bus Info Block when debug.firewire_debug > 1 Support the Bus Info Block(1394a-2000) method of speed detection. --=-WogEZ4mKZH42tVk8wBBN Content-Disposition: attachment; filename="firewire.c.diff" Content-Type: text/x-patch; name="firewire.c.diff"; charset="UTF-8" Content-Transfer-Encoding: 7bit Index: firewire.c =================================================================== --- firewire.c (revision 188697) +++ firewire.c (working copy) @@ -77,7 +77,7 @@ struct crom_chunk hw; }; -int firewire_debug=0, try_bmr=1, hold_count=3; +int firewire_debug=0, try_bmr=1, hold_count=0; SYSCTL_INT(_debug, OID_AUTO, firewire_debug, CTLFLAG_RW, &firewire_debug, 0, "FireWire driver debug flag"); SYSCTL_NODE(_hw, OID_AUTO, firewire, CTLFLAG_RD, 0, "FireWire Subsystem"); @@ -1503,7 +1503,8 @@ uint32_t *csr; struct csrhdr *hdr; struct bus_info *binfo; - int err, node, spd; + int err, node; + uint32_t speed_test = 0; fc = dfwdev->fc; csr = dfwdev->csrrom; @@ -1511,8 +1512,12 @@ /* First quad */ err = fw_explore_read_quads(dfwdev, CSRROMOFF, &csr[0], 1); - if (err) + if (err) { + device_printf(fc->bdev, "%s: node%d: explore_read_quads failure\n", + __func__, node); + dfwdev->status = FWDEVINVAL; return (-1); + } hdr = (struct csrhdr *)&csr[0]; if (hdr->info_len != 4) { if (firewire_debug) @@ -1532,7 +1537,18 @@ node, binfo->bus_name); return (-1); } - spd = fc->speed_map->speed[fc->nodeid][node]; + + if (firewire_debug) + device_printf(fc->bdev, "%s: node(%d) BUS INFO BLOCK:\n" + "irmc(%d) cmc(%d) isc(%d) bmc(%d) pmc(%d) " + "cyc_clk_acc(%d) max_rec(%d) max_rom(%d) " + "generation(%d) link_spd(%d)\n", + __func__, node, + binfo->irmc, binfo->cmc, binfo->isc, + binfo->bmc, binfo->pmc, binfo->cyc_clk_acc, + binfo->max_rec, binfo->max_rom, + binfo->generation, binfo->link_spd); + STAILQ_FOREACH(fwdev, &fc->devices, link) if (FW_EUI64_EQUAL(fwdev->eui, binfo->eui64)) break; @@ -1547,6 +1563,40 @@ } fwdev->fc = fc; fwdev->eui = binfo->eui64; + /* + * Pre-1394a-2000 didn't have link_spd in + * the Bus Info block, so try and use the + * speed map value. + * 1394a-2000 compliant devices only use + * the Bus Info Block link spd value, so + * ignore the speed map alltogether. SWB + */ + if ( binfo->link_spd == FWSPD_S100 /* 0 */) { + device_printf(fc->bdev, "%s" + "Pre 1394a-2000 detected\n", + __func__); + fwdev->speed = fc->speed_map->speed[fc->nodeid][node]; + } else + fwdev->speed = binfo->link_spd; + /* + * Test this speed with a read to the CSRROM. + * If it fails, slow down the speed and retry. + */ + while (fwdev->speed > 0) { + err = fw_explore_read_quads(fwdev, CSRROMOFF, + &speed_test, 1); + if (err) + fwdev->speed--; + else + break; + + } + if (fwdev->speed != binfo->link_spd) + device_printf(fc->bdev, "%s: fwdev->speed(%s)" + " set lower than binfo->link_spd(%s)\n", + __func__, + linkspeed[fwdev->speed], + linkspeed[binfo->link_spd]); /* inesrt into sorted fwdev list */ pfwdev = NULL; STAILQ_FOREACH(tfwdev, &fc->devices, link) { @@ -1562,12 +1612,11 @@ STAILQ_INSERT_AFTER(&fc->devices, pfwdev, fwdev, link); device_printf(fc->bdev, "New %s device ID:%08x%08x\n", - linkspeed[spd], + linkspeed[fwdev->speed], fwdev->eui.hi, fwdev->eui.lo); } fwdev->dst = node; fwdev->status = FWDEVINIT; - fwdev->speed = spd; /* unchanged ? */ if (bcmp(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5) == 0) { --=-WogEZ4mKZH42tVk8wBBN--