Re: firewire disk stopped working

Sean Bruno <[email protected]>
Newsgroups gmane.os.freebsd.devel.firewire
Message-ID <[email protected]>
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

_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-firewire
To unsubscribe, send any mail to "[email protected]"
firewire.diff (text/x-patch, 4.5 KB)
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;
 	}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.