Re: [Fwd: [BUG] sata_via doesn't detect anymore my disks (broken between rc1 and rc3)]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Aug 25, 2006 at 09:16:41PM +0900, Tejun Heo wrote:
> Thierry Vignaud wrote:
> >Thierry Vignaud <tvignaud@xxxxxxxxxxxx> writes:
> >
> >>>Can you please test two patches attached in this mail?  Just quick
> >>>result will be enough.  If both don't work, I'll go ahead and
> >>>create a third one - which emulates the old phy hardreset exactly
> >>>as I did for softreset of vt6420.
> >>I'll.
> >>
> >>As, I've tested that using:
> >>- ata_std_prereset + ata_std_softreset didn't work
> >>- vt6420_prereset + ata_std_softreset worked
> >>- vt6420_prereset w/o ata_std_softreset didn't work
> >>
> >>I simple interdiff between your two patches makes me think the odds're
> >>higher the second will succeed but you've done some extra changes
> >>since your previous patch.
> >>I'll you tell you more about this tomorrow.
> >
> >none of both these patches worked :-(
> 
> The second didn't work?  But you said the following one liner worked.
> 
> --- drivers/ata/sata_via.c.tv6	2006-08-20 16:37:41.000000000 +0200
> +++ drivers/ata/sata_via.c	2006-08-20 17:20:23.000000000 +0200
> @@ -244,7 +244,7 @@
> 
>  static void vt6421_error_handler(struct ata_port *ap)
>  {
> -	return ata_bmdma_drive_eh(ap, ata_std_prereset, NULL,
> +	return ata_bmdma_drive_eh(ap, vt6420_prereset, ata_std_softreset,
>  				  sata_std_hardreset, ata_std_postreset);
>  }
> 
> The second patch is essentially identical to what you did the one liner. 
>  Can you please check it once more?  I'll prepare old-sequence 
> hardreset in the meantime.

Okay, here's the old-sequence hardreset patch.  This should have the
highest chance of working.  This patch should be applied on top of the
vt6420 patch.

Thanks.

Index: work-c3/drivers/scsi/sata_via.c
===================================================================
--- work-c3.orig/drivers/scsi/sata_via.c	2006-08-25 22:53:32.000000000 +0900
+++ work-c3/drivers/scsi/sata_via.c	2006-08-25 22:53:34.000000000 +0900
@@ -75,6 +75,7 @@ static int svia_init_one (struct pci_dev
 static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static void vt6420_error_handler(struct ata_port *ap);
+static void vt6421_error_handler(struct ata_port *ap);
 
 static const struct pci_device_id svia_pci_tbl[] = {
 	{ 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 },
@@ -159,15 +160,12 @@ static const struct ata_port_operations 
 
 	.freeze			= ata_bmdma_freeze,
 	.thaw			= ata_bmdma_thaw,
-	.error_handler		= ata_bmdma_error_handler,
+	.error_handler		= vt6421_error_handler,
 	.post_internal_cmd	= ata_bmdma_post_internal_cmd,
 
 	.irq_handler		= ata_interrupt,
 	.irq_clear		= ata_bmdma_irq_clear,
 
-	.scr_read		= svia_scr_read,
-	.scr_write		= svia_scr_write,
-
 	.port_start		= ata_port_start,
 	.port_stop		= ata_port_stop,
 	.host_stop		= ata_host_stop,
@@ -203,35 +201,28 @@ static void svia_scr_write (struct ata_p
 }
 
 /**
- *	vt6420_prereset - prereset for vt6420
+ *	svia_link_resume - custom link resume
  *	@ap: target ATA port
  *
- *	SCR registers on vt6420 are pieces of shit and may hang the
- *	whole machine completely if accessed with the wrong timing.
- *	To avoid such catastrophe, vt6420 doesn't provide generic SCR
- *	access operations, but uses SStatus and SControl only during
- *	boot probing in controlled way.
- *
- *	As the old (pre EH update) probing code is proven to work, we
- *	strictly follow the access pattern.
+ *	SCR registers on these controllers are pieces of shit and may
+ *	hang the whole machine completely or cause device detection
+ *	failure if accessed with the wrong timing.  To avoid such
+ *	catastrophe, generic SCR access operations aren't provided,
+ *	but SStatus and SControl are used only during boot probing in
+ *	controlled way.
  *
  *	LOCKING:
- *	Kernel thread context (may sleep)
+ *	Kernel thread context (may sleep).
  *
  *	RETURNS:
- *	0 on success, -errno otherwise.
+ *	1 if link is online, 0 otherwise.
  */
-static int vt6420_prereset(struct ata_port *ap)
+static int svia_link_resume(struct ata_port *ap)
 {
-	struct ata_eh_context *ehc = &ap->eh_context;
 	unsigned long timeout = jiffies + (HZ * 5);
 	u32 sstatus, scontrol;
 	int online;
 
-	/* don't do any SCR stuff if we're not loading */
-	if (!ATA_PFLAG_LOADING)
-		goto skip_scr;
-
 	/* Resume phy.  This is the old resume sequence from
 	 * __sata_phy_reset().
 	 */
@@ -258,13 +249,37 @@ static int vt6420_prereset(struct ata_po
 	/* SStatus is read one more time */
 	svia_scr_read(ap, SCR_STATUS);
 
-	if (!online) {
-		/* tell EH to bail */
-		ehc->i.action &= ~ATA_EH_RESET_MASK;
-		return 0;
+	return online;
+}
+
+/**
+ *	vt6420_prereset - prereset for vt6420
+ *	@ap: target ATA port
+ *
+ *	Prereset for vt6420.  SCR registers on vt6420 can lock the
+ *	whole system up if accessed with the wrong timing.  Allow
+ *	controlled SCR access only for link resume while loading.
+ *	This keeps the code act almost identically to pre-EH code.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ *
+ *	RETURNS:
+ *	0 on sucees, -errno otherwise.
+ */
+static int vt6420_prereset(struct ata_port *ap)
+{
+	struct ata_eh_context *ehc = &ap->eh_context;
+
+	/* resume PHY iff we're loading */
+	if (ap->flags & ATA_PFLAG_LOADING) {
+		if (!svia_link_resume(ap)) {
+			/* tell EH to bail */
+			ehc->i.action &= ~ATA_EH_RESET_MASK;
+			return 0;
+		}
 	}
 
- skip_scr:
 	/* wait for !BSY */
 	ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
 
@@ -277,6 +292,64 @@ static void vt6420_error_handler(struct 
 				  NULL, ata_std_postreset);
 }
 
+/**
+ *	vt6421_hardreset - hardreset for vt6421
+ *	@ap: target ATA port
+ *	@class: resulting class of attached device
+ *
+ *	Hardreset for vt6421.  vt6421 fails to detect attached device
+ *	if SCR registers are accessed with the wrong timing.  Allow
+ *	controlled SCR access only during hardreset.  This keeps the
+ *	code act almost identically to pre-EH code.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep)
+ *
+ *	RETURNS:
+ *	0 on success, -errno otherwise.
+ */
+static int vt6421_hardreset(struct ata_port *ap, unsigned int *class)
+{
+	struct ata_taskfile tf;
+
+	/* issue reset */
+	svia_scr_write(ap, SCR_CONTROL, 0x301);
+	svia_scr_read(ap, SCR_CONTROL); /* flush */
+	msleep(1);
+
+	/* resume link */
+	if (!(svia_link_resume(ap))) {
+		*class = ATA_DEV_NONE;
+		return 0;
+	}
+
+	/* wait for device to become ready */
+	if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
+		ata_port_printk(ap, KERN_ERR,
+				"COMRESET failed (device not ready)\n");
+		return -EIO;
+	}
+
+	/* classify */
+	memset(&tf, 0, sizeof(tf));
+	ap->ops->dev_select(ap, 0);
+	ata_tf_read(ap, &tf);
+
+	*class = ata_dev_classify(&tf);
+	if (*class == ATA_DEV_UNKNOWN)
+		*class = ATA_DEV_NONE;
+	else if ((*class == ATA_DEV_ATA) && (ata_chk_status(ap) == 0))
+		*class = ATA_DEV_NONE;
+
+	return 0;
+}
+
+static void vt6421_error_handler(struct ata_port *ap)
+{
+	return ata_bmdma_drive_eh(ap, NULL, NULL, vt6421_hardreset,
+				  ata_std_postreset);
+}
+
 static const unsigned int svia_bar_sizes[] = {
 	8, 4, 8, 4, 16, 256
 };

-
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux