[mythtv-users] 8T Seagate Archive: my experience

Warpme warpme at o2.pl
Wed Jul 22 17:21:24 UTC 2015


On 20/07/15 21:26, jedi wrote:
> On Mon, Jul 20, 2015 at 08:30:16PM +0200, Warpme wrote:
>> On 20/07/15 11:04, Stuart Auchterlonie wrote:
>>
>> It looks like Seagate isn't interested much in Linux user base (sad)
>> and didn't see negative impact on it's image by non-usability this
>> model under Linux (strange!).
>> I looked little over kernel code and I think fix in kernel to
>> tolerate 1-3min of SATA freezes will be not easy task (multiple
>> layers had cascade of timeouts so increasing SATA timeout needs
>> touching also DMA/FS/kernel process timeouts).
>>
>> Seagate is not willing to mod drive firmware to make this drive
>> usable under Linux 4.x+
>
Hmm,
It looks like I have to revoke my words about drive/firmware issue.
Actually it looks like my issues are result of kernel 3.19+ bug.
Attached patch allows me to successful write 7T of test data without any 
SATA error.
Without this patch drive interface goes down after 50-150G of writes.

-------------- next part --------------
diff -Naur linux-4.0.8-old/drivers/ata/libata-core.c linux-4.0.8-new/drivers/ata/libata-core.c
--- linux-4.0.8-old/drivers/ata/libata-core.c	2015-07-10 18:46:16.000000000 +0200
+++ linux-4.0.8-new/drivers/ata/libata-core.c	2015-07-19 15:08:20.573594890 +0200
@@ -1043,8 +1043,8 @@
  *	None.
  *
  *	RETURNS:
- *	Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, %ATA_DEV_PMP,
- *	%ATA_DEV_ZAC, or %ATA_DEV_UNKNOWN the event of failure.
+ *	Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, %ATA_DEV_PMP or
+ *	%ATA_DEV_UNKNOWN the event of failure.
  */
 unsigned int ata_dev_classify(const struct ata_taskfile *tf)
 {
@@ -1089,11 +1089,6 @@
 		return ATA_DEV_SEMB;
 	}
 
-	if ((tf->lbam == 0xcd) && (tf->lbah == 0xab)) {
-		DPRINTK("found ZAC device by sig\n");
-		return ATA_DEV_ZAC;
-	}
-
 	DPRINTK("unknown device\n");
 	return ATA_DEV_UNKNOWN;
 }
@@ -1334,7 +1329,7 @@
 	int rc;
 
 	/* do we need to do it? */
-	if ((dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC) ||
+	if (dev->class != ATA_DEV_ATA ||
 	    !ata_id_has_lba(dev->id) || !ata_id_hpa_enabled(dev->id) ||
 	    (dev->horkage & ATA_HORKAGE_BROKEN_HPA))
 		return 0;
@@ -1865,7 +1860,6 @@
 	case ATA_DEV_SEMB:
 		class = ATA_DEV_ATA;	/* some hard drives report SEMB sig */
 	case ATA_DEV_ATA:
-	case ATA_DEV_ZAC:
 		tf.command = ATA_CMD_ID_ATA;
 		break;
 	case ATA_DEV_ATAPI:
@@ -1957,7 +1951,7 @@
 	rc = -EINVAL;
 	reason = "device reports invalid type";
 
-	if (class == ATA_DEV_ATA || class == ATA_DEV_ZAC) {
+	if (class == ATA_DEV_ATA) {
 		if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
 			goto err_out;
 		if (ap->host->flags & ATA_HOST_IGNORE_ATA &&
@@ -1992,8 +1986,7 @@
 			goto retry;
 	}
 
-	if ((flags & ATA_READID_POSTRESET) &&
-	    (class == ATA_DEV_ATA || class == ATA_DEV_ZAC)) {
+	if ((flags & ATA_READID_POSTRESET) && class == ATA_DEV_ATA) {
 		/*
 		 * The exact sequence expected by certain pre-ATA4 drives is:
 		 * SRST RESET
@@ -2258,7 +2251,7 @@
 			sizeof(modelbuf));
 
 	/* ATA-specific feature tests */
-	if (dev->class == ATA_DEV_ATA || dev->class == ATA_DEV_ZAC) {
+	if (dev->class == ATA_DEV_ATA) {
 		if (ata_id_is_cfa(id)) {
 			/* CPRM may make this media unusable */
 			if (id[ATA_ID_CFA_KEY_MGMT] & 1)
@@ -4011,7 +4004,6 @@
 	if (ata_class_enabled(new_class) &&
 	    new_class != ATA_DEV_ATA &&
 	    new_class != ATA_DEV_ATAPI &&
-	    new_class != ATA_DEV_ZAC &&
 	    new_class != ATA_DEV_SEMB) {
 		ata_dev_info(dev, "class mismatch %u != %u\n",
 			     dev->class, new_class);
diff -Naur linux-4.0.8-old/drivers/ata/libata-eh.c linux-4.0.8-new/drivers/ata/libata-eh.c
--- linux-4.0.8-old/drivers/ata/libata-eh.c	2015-07-10 18:46:16.000000000 +0200
+++ linux-4.0.8-new/drivers/ata/libata-eh.c	2015-07-19 15:08:20.576928212 +0200
@@ -1808,7 +1808,6 @@
 
 	switch (qc->dev->class) {
 	case ATA_DEV_ATA:
-	case ATA_DEV_ZAC:
 		if (err & ATA_ICRC)
 			qc->err_mask |= AC_ERR_ATA_BUS;
 		if (err & (ATA_UNC | ATA_AMNF))
@@ -3794,8 +3793,7 @@
 				struct ata_eh_context *ehc = &link->eh_context;
 				unsigned long tmp;
 
-				if (dev->class != ATA_DEV_ATA &&
-				    dev->class != ATA_DEV_ZAC)
+				if (dev->class != ATA_DEV_ATA)
 					continue;
 				if (!(ehc->i.dev_action[dev->devno] &
 				      ATA_EH_PARK))
@@ -3876,8 +3874,7 @@
 
 		/* retry flush if necessary */
 		ata_for_each_dev(dev, link, ALL) {
-			if (dev->class != ATA_DEV_ATA &&
-			    dev->class != ATA_DEV_ZAC)
+			if (dev->class != ATA_DEV_ATA)
 				continue;
 			rc = ata_eh_maybe_retry_flush(dev);
 			if (rc)
diff -Naur linux-4.0.8-old/drivers/ata/libata-scsi.c linux-4.0.8-new/drivers/ata/libata-scsi.c
--- linux-4.0.8-old/drivers/ata/libata-scsi.c	2015-07-10 18:46:16.000000000 +0200
+++ linux-4.0.8-new/drivers/ata/libata-scsi.c	2015-07-19 15:08:20.576928212 +0200
@@ -235,8 +235,7 @@
 		rc = -ENODEV;
 		goto unlock;
 	}
-	if (dev->class != ATA_DEV_ATA &&
-	    dev->class != ATA_DEV_ZAC) {
+	if (dev->class != ATA_DEV_ATA) {
 		rc = -EOPNOTSUPP;
 		goto unlock;
 	}
@@ -1962,7 +1961,6 @@
 static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
 {
 	const u8 versions[] = {
-		0x00,
 		0x60,	/* SAM-3 (no version claimed) */
 
 		0x03,
@@ -1971,20 +1969,6 @@
 		0x02,
 		0x60	/* SPC-3 (no version claimed) */
 	};
-	const u8 versions_zbc[] = {
-		0x00,
-		0xA0,	/* SAM-5 (no version claimed) */
-
-		0x04,
-		0xC0,	/* SBC-3 (no version claimed) */
-
-		0x04,
-		0x60,	/* SPC-4 (no version claimed) */
-
-		0x60,
-		0x20,   /* ZBC (no version claimed) */
-	};
-
 	u8 hdr[] = {
 		TYPE_DISK,
 		0,
@@ -1999,11 +1983,6 @@
 	if (ata_id_removable(args->id))
 		hdr[1] |= (1 << 7);
 
-	if (args->dev->class == ATA_DEV_ZAC) {
-		hdr[0] = TYPE_ZBC;
-		hdr[2] = 0x6; /* ZBC is defined in SPC-4 */
-	}
-
 	memcpy(rbuf, hdr, sizeof(hdr));
 	memcpy(&rbuf[8], "ATA     ", 8);
 	ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16);
@@ -2016,10 +1995,7 @@
 	if (rbuf[32] == 0 || rbuf[32] == ' ')
 		memcpy(&rbuf[32], "n/a ", 4);
 
-	if (args->dev->class == ATA_DEV_ZAC)
-		memcpy(rbuf + 58, versions_zbc, sizeof(versions_zbc));
-	else
-		memcpy(rbuf + 58, versions, sizeof(versions));
+	memcpy(rbuf + 59, versions, sizeof(versions));
 
 	return 0;
 }
@@ -3430,7 +3406,7 @@
 	ata_xlat_func_t xlat_func;
 	int rc = 0;
 
-	if (dev->class == ATA_DEV_ATA || dev->class == ATA_DEV_ZAC) {
+	if (dev->class == ATA_DEV_ATA) {
 		if (unlikely(!scmd->cmd_len || scmd->cmd_len > dev->cdb_len))
 			goto bad_cdb_len;
 
diff -Naur linux-4.0.8-old/drivers/ata/libata-transport.c linux-4.0.8-new/drivers/ata/libata-transport.c
--- linux-4.0.8-old/drivers/ata/libata-transport.c	2015-07-10 18:46:16.000000000 +0200
+++ linux-4.0.8-new/drivers/ata/libata-transport.c	2015-07-19 15:08:20.576928212 +0200
@@ -143,7 +143,6 @@
 	{ ATA_DEV_PMP_UNSUP,		"pmp" },
 	{ ATA_DEV_SEMB,			"semb" },
 	{ ATA_DEV_SEMB_UNSUP,		"semb" },
-	{ ATA_DEV_ZAC,			"zac" },
 	{ ATA_DEV_NONE,			"none" }
 };
 ata_bitfield_name_search(class, ata_class_names)
diff -Naur linux-4.0.8-old/include/linux/libata.h linux-4.0.8-new/include/linux/libata.h
--- linux-4.0.8-old/include/linux/libata.h	2015-07-10 18:46:16.000000000 +0200
+++ linux-4.0.8-new/include/linux/libata.h	2015-07-19 15:08:20.576928212 +0200
@@ -191,8 +191,7 @@
 	ATA_DEV_PMP_UNSUP	= 6,	/* SATA port multiplier (unsupported) */
 	ATA_DEV_SEMB		= 7,	/* SEMB */
 	ATA_DEV_SEMB_UNSUP	= 8,	/* SEMB (unsupported) */
-	ATA_DEV_ZAC		= 9,	/* ZAC device */
-	ATA_DEV_NONE		= 10,	/* no device */
+	ATA_DEV_NONE		= 9,	/* no device */
 
 	/* struct ata_link flags */
 	ATA_LFLAG_NO_HRST	= (1 << 1), /* avoid hardreset */
@@ -1512,8 +1511,7 @@
 static inline unsigned int ata_class_enabled(unsigned int class)
 {
 	return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI ||
-		class == ATA_DEV_PMP || class == ATA_DEV_SEMB ||
-		class == ATA_DEV_ZAC;
+		class == ATA_DEV_PMP || class == ATA_DEV_SEMB;
 }
 
 static inline unsigned int ata_class_disabled(unsigned int class)


More information about the mythtv-users mailing list