Date: Mon, 02 Mar 2009 20:59:40 -0800 From: Sean Bruno <sean.bruno@dsl-only.net> To: Daniel Thiele <dthiele@gmx.net> Cc: freebsd-firewire@freebsd.org, Boris Kotzev <boris.kotzev@gmail.com> Subject: Re: firewire disk stopped working Message-ID: <1236056380.11182.5.camel@localhost.localdomain> In-Reply-To: <49A9B245.8030804@gmx.net> References: <200902150012.49329.boris.kotzev@gmail.com> <200902211751.53298.boris.kotzev@gmail.com> <1235451657.25955.24.camel@localhost.localdomain> <200902252344.03339.boris.kotzev@gmail.com> <49A9B245.8030804@gmx.net>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Sorry for the long time between updates folks. I've been down with the
flu.
Here is a patch for you folks. I'm still unclear why your drives have
stopped working, but I suspect it is related to the code I am patching
in this email.
Sean
[-- Attachment #2 --]
Index: fwmem.h
===================================================================
--- fwmem.h (revision 189289)
+++ fwmem.h (working copy)
@@ -34,7 +34,7 @@
* $FreeBSD$
*/
-struct fw_xfer *fwmem_read_quad(struct fw_device *, caddr_t, uint8_t,
+struct fw_xfer *fwmem_read_quad(struct fw_device *, caddr_t, int8_t,
uint16_t, uint32_t, void *, void (*)(struct fw_xfer *));
struct fw_xfer *fwmem_write_quad(struct fw_device *, caddr_t, uint8_t,
uint16_t, uint32_t, void *, void (*)(struct fw_xfer *));
Index: fwmem.c
===================================================================
--- fwmem.c (revision 189289)
+++ fwmem.c (working copy)
@@ -127,7 +127,7 @@
fwmem_read_quad(
struct fw_device *fwdev,
caddr_t sc,
- uint8_t spd,
+ int8_t spd,
uint16_t dst_hi,
uint32_t dst_lo,
void *data,
Index: firewire.c
===================================================================
--- firewire.c (revision 189289)
+++ firewire.c (working copy)
@@ -685,7 +685,8 @@
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;
@@ -763,14 +764,21 @@
* 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
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;
+ if ( src->businfo.generation++ > FW_MAX_GENERATION )
+ src->businfo.generation = FW_GENERATION_CHANGEABLE;
bcopy(src, (void *)fc->config_rom, CROMSIZE);
- } else
- src->businfo.generation = 0;
+ }
}
/* Call once after reboot */
@@ -1590,6 +1598,10 @@
}
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 +1611,7 @@
* 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 +1621,19 @@
* 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 +1651,16 @@
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;
+ } 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);
+ }
- /* 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 +1672,9 @@
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;
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1236056380.11182.5.camel>
