From owner-svn-src-all@FreeBSD.ORG Tue Mar 17 13:07:12 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1C20D1065741; Tue, 17 Mar 2009 13:07:12 +0000 (UTC) (envelope-from sbruno@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 09E028FC0C; Tue, 17 Mar 2009 13:07:12 +0000 (UTC) (envelope-from sbruno@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n2HD7BVh095717; Tue, 17 Mar 2009 13:07:11 GMT (envelope-from sbruno@svn.freebsd.org) Received: (from sbruno@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n2HD7BKS095716; Tue, 17 Mar 2009 13:07:11 GMT (envelope-from sbruno@svn.freebsd.org) Message-Id: <200903171307.n2HD7BKS095716@svn.freebsd.org> From: Sean Bruno Date: Tue, 17 Mar 2009 13:07:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r189928 - head/sys/dev/firewire X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Mar 2009 13:07:12 -0000 Author: sbruno Date: Tue Mar 17 13:07:11 2009 New Revision: 189928 URL: http://svn.freebsd.org/changeset/base/189928 Log: Reviewed by: scott (scottl@freebsd.org) Obtained from: Hideotshi Shimokawa This update is based on comments from Hidetoshi. Changeset 183550 removed the call to crom_load() in fw_busreset(). Restore that call such that the Configuration ROM is valid. Stash and update fwdev settings in fw_explore_node() so that negotiation works again. Modified: head/sys/dev/firewire/firewire.c Modified: head/sys/dev/firewire/firewire.c ============================================================================== --- head/sys/dev/firewire/firewire.c Tue Mar 17 12:53:28 2009 (r189927) +++ head/sys/dev/firewire/firewire.c Tue Mar 17 13:07:11 2009 (r189928) @@ -685,7 +685,8 @@ fw_init_crom(struct firewire_comm *fc) src->businfo.cyc_clk_acc = 100; src->businfo.max_rec = fc->maxrec; src->businfo.max_rom = MAXROM_4; - src->businfo.generation = 0; +#define FW_GENERATION_CHANGEABLE 2 + src->businfo.generation = FW_GENERATION_CHANGEABLE; src->businfo.link_spd = fc->speed; src->businfo.eui64.hi = fc->eui.hi; @@ -734,6 +735,7 @@ fw_busreset(struct firewire_comm *fc, ui struct firewire_dev_comm *fdc; struct crom_src *src; device_t *devlistp; + uint32_t *newrom; int i, devcnt; FW_GLOCK_ASSERT(fc); @@ -759,18 +761,31 @@ fw_busreset(struct firewire_comm *fc, ui } src = &fc->crom_src_buf->src; - /* - * 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; + /* + * If the old config rom needs to be overwritten, + * bump the businfo.generation indicator to + * indicate that we need to be reprobed + * See 1394a-2000 8.3.2.5.4 for more details. + * generation starts at 2 and rolls over at 0xF + * back to 2. + * + * A generation of 0 indicates a device + * that is not 1394a-2000 compliant. + * A generation of 1 indicates a device that + * does not change it's Bus Info Block or + * Configuration ROM. + */ +#define FW_MAX_GENERATION 0xF + newrom = malloc(CROMSIZE, M_FW, M_NOWAIT | M_ZERO); + src = &fc->crom_src_buf->src; + crom_load(src, newrom, CROMSIZE); + if (bcmp(newrom, fc->config_rom, CROMSIZE) != 0) { + if ( src->businfo.generation++ > FW_MAX_GENERATION ) + src->businfo.generation = FW_GENERATION_CHANGEABLE; + bcopy(newrom, (void *)fc->config_rom, CROMSIZE); + } + free(newrom, M_FW); + } /* Call once after reboot */ @@ -1590,6 +1605,10 @@ fw_explore_node(struct fw_device *dfwdev } fwdev->fc = fc; fwdev->eui = binfo->eui64; + fwdev->dst = dfwdev->dst; + fwdev->maxrec = dfwdev->maxrec; + fwdev->status = dfwdev->status; + /* * Pre-1394a-2000 didn't have link_spd in * the Bus Info block, so try and use the @@ -1599,7 +1618,7 @@ fw_explore_node(struct fw_device *dfwdev * ignore the speed map alltogether. SWB */ if ( binfo->link_spd == FWSPD_S100 /* 0 */) { - device_printf(fc->bdev, "%s" + device_printf(fc->bdev, "%s: " "Pre 1394a-2000 detected\n", __func__); fwdev->speed = fc->speed_map->speed[fc->nodeid][node]; @@ -1609,21 +1628,19 @@ fw_explore_node(struct fw_device *dfwdev * Test this speed with a read to the CSRROM. * If it fails, slow down the speed and retry. */ - while (fwdev->speed > 0) { + while (fwdev->speed > FWSPD_S100 /* 0 */) { err = fw_explore_read_quads(fwdev, CSRROMOFF, &speed_test, 1); - if (err) + if (err) { + device_printf(fc->bdev, "%s: fwdev->speed(%s)" + " decremented due to negotiation\n", + __func__, + linkspeed[fwdev->speed]); fwdev->speed--; - else + } 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) { @@ -1641,15 +1658,15 @@ fw_explore_node(struct fw_device *dfwdev device_printf(fc->bdev, "New %s device ID:%08x%08x\n", linkspeed[fwdev->speed], fwdev->eui.hi, fwdev->eui.lo); - } - fwdev->dst = node; - fwdev->status = FWDEVINIT; - - /* unchanged ? */ - if (bcmp(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5) == 0) { - if (firewire_debug) - device_printf(fc->dev, "node%d: crom unchanged\n", node); - return (0); + } else { + fwdev->dst = node; + fwdev->status = FWDEVINIT; + /* unchanged ? */ + if (bcmp(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5) == 0) { + if (firewire_debug) + device_printf(fc->dev, "node%d: crom unchanged\n", node); + return (0); + } } bzero(&fwdev->csrrom[0], CROMSIZE); @@ -1661,6 +1678,9 @@ fw_explore_node(struct fw_device *dfwdev err = fw_explore_csrblock(fwdev, 0x14, 1); /* root directory */ if (err) { + if (firewire_debug) + device_printf(fc->dev, "%s: explore csrblock failed err(%d)\n", + __func__, err); fwdev->status = FWDEVINVAL; fwdev->csrrom[0] = 0; }