Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 29 Nov 2015 11:28:04 +0000 (UTC)
From:      Michal Meloun <mmel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r291444 - head/sys/dev/ahci
Message-ID:  <201511291128.tATBS48l058154@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mmel
Date: Sun Nov 29 11:28:04 2015
New Revision: 291444
URL: https://svnweb.freebsd.org/changeset/base/291444

Log:
  AHCI: Fix AHCI driver for ARM.
  On ARM, we must ensure proper interdevice write ordering.
  The AHCI interrupt status register must be updated in HW before
  registers in interrupt controller.
  Unfortunately, only way how we can do it is readback.
  
  Discussed with:	mav
  Approved by:	kib (mentor)
  Differential Revision: https://reviews.freebsd.org/D4240

Modified:
  head/sys/dev/ahci/ahci.c
  head/sys/dev/ahci/ahci.h

Modified: head/sys/dev/ahci/ahci.c
==============================================================================
--- head/sys/dev/ahci/ahci.c	Sun Nov 29 07:20:30 2015	(r291443)
+++ head/sys/dev/ahci/ahci.c	Sun Nov 29 11:28:04 2015	(r291444)
@@ -483,6 +483,7 @@ ahci_intr(void *data)
 	/* AHCI declares level triggered IS. */
 	if (!(ctlr->quirks & AHCI_Q_EDGEIS))
 		ATA_OUTL(ctlr->r_mem, AHCI_IS, is);
+	ATA_RBL(ctlr->r_mem, AHCI_IS);
 }
 
 /*
@@ -501,6 +502,7 @@ ahci_intr_one(void *data)
 	    ctlr->interrupt[unit].function(arg);
 	/* AHCI declares level triggered IS. */
 	ATA_OUTL(ctlr->r_mem, AHCI_IS, 1 << unit);
+	ATA_RBL(ctlr->r_mem, AHCI_IS);
 }
 
 static void
@@ -516,6 +518,7 @@ ahci_intr_one_edge(void *data)
 	ATA_OUTL(ctlr->r_mem, AHCI_IS, 1 << unit);
 	if ((arg = ctlr->interrupt[unit].argument))
 		ctlr->interrupt[unit].function(arg);
+	ATA_RBL(ctlr->r_mem, AHCI_IS);
 }
 
 struct resource *

Modified: head/sys/dev/ahci/ahci.h
==============================================================================
--- head/sys/dev/ahci/ahci.h	Sun Nov 29 07:20:30 2015	(r291443)
+++ head/sys/dev/ahci/ahci.h	Sun Nov 29 11:28:04 2015	(r291444)
@@ -562,6 +562,20 @@ enum ahci_err_type {
 #define ATA_OUTSL_STRM(res, offset, addr, count) \
 	bus_write_multi_stream_4((res), (offset), (addr), (count))
 
+/*
+ * On some platforms, we must ensure proper interdevice write ordering.
+ * The AHCI interrupt status register must be updated in HW before
+ * registers in interrupt controller.
+ * Unfortunately, only way how we can do it is readback.
+ *
+ * Currently, only ARM is known to have this issue.
+ */
+#if defined(__arm__)
+#define ATA_RBL(res, offset) \
+	bus_read_4((res), (offset))
+#else
+#define ATA_RBL(res, offset)
+#endif
 
 #define AHCI_Q_NOFORCE		0x00000001
 #define AHCI_Q_NOPMP		0x00000002



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201511291128.tATBS48l058154>