svn commit: r222695 - in projects/pseries: cam/ata cddl/compat/opensolaris/kern cddl/compat/opensolaris/sys conf contrib/pf/net dev/ath dev/ath/ath_dfs/null dev/ath/ath_hal dev/ath/ath_hal/ar5212 d...

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sat Jun 4 19:16:46 UTC 2011


Author: nwhitehorn
Date: Sat Jun  4 19:16:46 2011
New Revision: 222695
URL: http://svn.freebsd.org/changeset/base/222695

Log:
  IFC @ 222694 to propagate some bug fixes back from HEAD.

Added:
  projects/pseries/powerpc/powermac/windtunnel.c
     - copied unchanged from r222694, head/sys/powerpc/powermac/windtunnel.c
Modified:
  projects/pseries/cam/ata/ata_da.c
  projects/pseries/cddl/compat/opensolaris/kern/opensolaris.c
  projects/pseries/cddl/compat/opensolaris/sys/time.h
  projects/pseries/conf/files.powerpc
  projects/pseries/contrib/pf/net/pf.c
  projects/pseries/dev/ath/ath_dfs/null/dfs_null.c
  projects/pseries/dev/ath/ath_hal/ah.h
  projects/pseries/dev/ath/ath_hal/ar5212/ar5212.h
  projects/pseries/dev/ath/ath_hal/ar5212/ar5212_attach.c
  projects/pseries/dev/ath/ath_hal/ar5212/ar5212_misc.c
  projects/pseries/dev/ath/ath_hal/ar5212/ar5212reg.h
  projects/pseries/dev/ath/ath_hal/ar5416/ar5416.h
  projects/pseries/dev/ath/ath_hal/ar5416/ar5416_attach.c
  projects/pseries/dev/ath/ath_hal/ar5416/ar5416_misc.c
  projects/pseries/dev/ath/if_ath.c
  projects/pseries/dev/ath/if_athdfs.h
  projects/pseries/dev/ath/if_athvar.h
  projects/pseries/dev/iicbus/ds1775.c
  projects/pseries/dev/iicbus/max6690.c
  projects/pseries/dev/iwn/if_iwn.c
  projects/pseries/dev/puc/pucdata.c
  projects/pseries/fs/nfsserver/nfs_nfsdport.c
  projects/pseries/geom/geom_disk.c
  projects/pseries/geom/part/g_part.c
  projects/pseries/mips/cavium/octeon_ebt3000_cf.c
  projects/pseries/net/if_tun.c
  projects/pseries/net80211/ieee80211_ht.c
  projects/pseries/net80211/ieee80211_output.c
  projects/pseries/netinet/in_pcb.c
  projects/pseries/netinet/in_pcb.h
  projects/pseries/netinet/ip_divert.c
  projects/pseries/netinet/tcp_input.c
  projects/pseries/netinet/tcp_syncache.c
  projects/pseries/netinet/udp_usrreq.c
  projects/pseries/netinet6/in6_pcb.c
  projects/pseries/netinet6/in6_pcb.h
  projects/pseries/netinet6/udp6_usrreq.c
  projects/pseries/powerpc/aim/locore64.S
  projects/pseries/powerpc/aim/mmu_oea64.c
  projects/pseries/powerpc/conf/GENERIC
  projects/pseries/powerpc/conf/NOTES
  projects/pseries/powerpc/ofw/ofw_machdep.c
  projects/pseries/powerpc/powermac/fcu.c
  projects/pseries/powerpc/powermac/powermac_thermal.c
  projects/pseries/powerpc/powermac/powermac_thermal.h
Directory Properties:
  projects/pseries/   (props changed)
  projects/pseries/amd64/include/xen/   (props changed)
  projects/pseries/boot/   (props changed)
  projects/pseries/boot/i386/efi/   (props changed)
  projects/pseries/boot/ia64/efi/   (props changed)
  projects/pseries/boot/ia64/ski/   (props changed)
  projects/pseries/boot/powerpc/boot1.chrp/   (props changed)
  projects/pseries/boot/powerpc/ofw/   (props changed)
  projects/pseries/cddl/contrib/opensolaris/   (props changed)
  projects/pseries/conf/   (props changed)
  projects/pseries/contrib/dev/acpica/   (props changed)
  projects/pseries/contrib/octeon-sdk/   (props changed)
  projects/pseries/contrib/pf/   (props changed)
  projects/pseries/contrib/x86emu/   (props changed)

Modified: projects/pseries/cam/ata/ata_da.c
==============================================================================
--- projects/pseries/cam/ata/ata_da.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/cam/ata/ata_da.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -114,11 +114,12 @@ struct disk_params {
 	u_int64_t sectors;	/* Total number sectors */
 };
 
-#define TRIM_MAX_BLOCKS	4
-#define TRIM_MAX_RANGES	TRIM_MAX_BLOCKS * 64
+#define TRIM_MAX_BLOCKS	8
+#define TRIM_MAX_RANGES	(TRIM_MAX_BLOCKS * 64)
+#define TRIM_MAX_BIOS	(TRIM_MAX_RANGES * 4)
 struct trim_request {
 	uint8_t		data[TRIM_MAX_RANGES * 8];
-	struct bio	*bps[TRIM_MAX_RANGES];
+	struct bio	*bps[TRIM_MAX_BIOS];
 };
 
 struct ada_softc {
@@ -1067,7 +1068,8 @@ adastart(struct cam_periph *periph, unio
 		    (bp = bioq_first(&softc->trim_queue)) != 0) {
 			struct trim_request *req = &softc->trim_req;
 			struct bio *bp1;
-			int bps = 0, ranges = 0;
+			uint64_t lastlba = (uint64_t)-1;
+			int bps = 0, c, lastcount = 0, off, ranges = 0;
 
 			softc->trim_running = 1;
 			bzero(req, sizeof(*req));
@@ -1078,10 +1080,22 @@ adastart(struct cam_periph *periph, unio
 				    softc->params.secsize;
 
 				bioq_remove(&softc->trim_queue, bp1);
-				while (count > 0) {
-					int c = min(count, 0xffff);
-					int off = ranges * 8;
 
+				/* Try to extend the previous range. */
+				if (lba == lastlba) {
+					c = min(count, 0xffff - lastcount);
+					lastcount += c;
+					off = (ranges - 1) * 8;
+					req->data[off + 6] = lastcount & 0xff;
+					req->data[off + 7] =
+					    (lastcount >> 8) & 0xff;
+					count -= c;
+					lba += c;
+				}
+
+				while (count > 0) {
+					c = min(count, 0xffff);
+					off = ranges * 8;
 					req->data[off + 0] = lba & 0xff;
 					req->data[off + 1] = (lba >> 8) & 0xff;
 					req->data[off + 2] = (lba >> 16) & 0xff;
@@ -1092,11 +1106,14 @@ adastart(struct cam_periph *periph, unio
 					req->data[off + 7] = (c >> 8) & 0xff;
 					lba += c;
 					count -= c;
+					lastcount = c;
 					ranges++;
 				}
+				lastlba = lba;
 				req->bps[bps++] = bp1;
 				bp1 = bioq_first(&softc->trim_queue);
-				if (bp1 == NULL ||
+				if (bps >= TRIM_MAX_BIOS ||
+				    bp1 == NULL ||
 				    bp1->bio_bcount / softc->params.secsize >
 				    (softc->trim_max_ranges - ranges) * 0xffff)
 					break;
@@ -1370,8 +1387,7 @@ adadone(struct cam_periph *periph, union
 			    (struct trim_request *)ataio->data_ptr;
 			int i;
 
-			for (i = 1; i < softc->trim_max_ranges &&
-			    req->bps[i]; i++) {
+			for (i = 1; i < TRIM_MAX_BIOS && req->bps[i]; i++) {
 				struct bio *bp1 = req->bps[i];
 				
 				bp1->bio_resid = bp->bio_resid;

Modified: projects/pseries/cddl/compat/opensolaris/kern/opensolaris.c
==============================================================================
--- projects/pseries/cddl/compat/opensolaris/kern/opensolaris.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/cddl/compat/opensolaris/kern/opensolaris.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -40,6 +40,7 @@
 cpu_core_t	cpu_core[MAXCPU];
 kmutex_t	cpu_lock;
 solaris_cpu_t	solaris_cpu[MAXCPU];
+int		nsec_per_tick;
 
 /*
  *  OpenSolaris subsystem initialisation.
@@ -60,6 +61,8 @@ opensolaris_load(void *dummy)
 	}
 
 	mutex_init(&cpu_lock, "OpenSolaris CPU lock", MUTEX_DEFAULT, NULL);
+
+	nsec_per_tick = NANOSEC / hz;
 }
 
 SYSINIT(opensolaris_register, SI_SUB_OPENSOLARIS, SI_ORDER_FIRST, opensolaris_load, NULL);

Modified: projects/pseries/cddl/compat/opensolaris/sys/time.h
==============================================================================
--- projects/pseries/cddl/compat/opensolaris/sys/time.h	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/cddl/compat/opensolaris/sys/time.h	Sat Jun  4 19:16:46 2011	(r222695)
@@ -62,8 +62,21 @@ gethrtime(void) {
 #define	gethrestime(ts)		getnanotime(ts)
 #define	gethrtime_waitfree()	gethrtime()
 
-#define	ddi_get_lbolt()		((gethrtime() * hz) / NANOSEC)
-#define	ddi_get_lbolt64()	(int64_t)((gethrtime() * hz) / NANOSEC)
+extern int nsec_per_tick;	/* nanoseconds per clock tick */
+
+static __inline int64_t
+ddi_get_lbolt64(void)
+{
+
+	return (gethrtime() / nsec_per_tick);
+}
+
+static __inline clock_t
+ddi_get_lbolt(void)
+{
+
+	return (ddi_get_lbolt64());
+}
 
 #else
 

Modified: projects/pseries/conf/files.powerpc
==============================================================================
--- projects/pseries/conf/files.powerpc	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/conf/files.powerpc	Sat Jun  4 19:16:46 2011	(r222695)
@@ -162,6 +162,7 @@ powerpc/powermac/smusat.c	optional	power
 powerpc/powermac/uninorth.c	optional	powermac
 powerpc/powermac/uninorthpci.c	optional	powermac pci
 powerpc/powermac/vcoregpio.c	optional	powermac 
+powerpc/powermac/windtunnel.c	optional	powermac windtunnel
 powerpc/powerpc/altivec.c	optional	aim
 powerpc/powerpc/atomic.S	standard
 powerpc/powerpc/autoconf.c	standard

Modified: projects/pseries/contrib/pf/net/pf.c
==============================================================================
--- projects/pseries/contrib/pf/net/pf.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/contrib/pf/net/pf.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -3034,6 +3034,10 @@ pf_socket_lookup(int direction, struct p
 #ifdef INET
 	case AF_INET:
 #ifdef __FreeBSD__
+		/*
+		 * XXXRW: would be nice if we had an mbuf here so that we
+		 * could use in_pcblookup_mbuf().
+		 */
 		inp = in_pcblookup(pi, saddr->v4, sport, daddr->v4,
 			dport, INPLOOKUP_RLOCKPCB, NULL);
 		if (inp == NULL) {
@@ -3056,6 +3060,10 @@ pf_socket_lookup(int direction, struct p
 #ifdef INET6
 	case AF_INET6:
 #ifdef __FreeBSD__
+		/*
+		 * XXXRW: would be nice if we had an mbuf here so that we
+		 * could use in6_pcblookup_mbuf().
+		 */
 		inp = in6_pcblookup(pi, &saddr->v6, sport,
 			&daddr->v6, dport, INPLOOKUP_RLOCKPCB, NULL);
 		if (inp == NULL) {

Modified: projects/pseries/dev/ath/ath_dfs/null/dfs_null.c
==============================================================================
--- projects/pseries/dev/ath/ath_dfs/null/dfs_null.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/ath/ath_dfs/null/dfs_null.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -107,7 +107,7 @@ ath_dfs_radar_enable(struct ath_softc *s
  * Process DFS related PHY errors
  */
 void
-ath_dfs_process_phy_err(struct ath_softc *sc, struct ath_desc *ds,
+ath_dfs_process_phy_err(struct ath_softc *sc, const char *buf,
     uint64_t tsf, struct ath_rx_status *rxstat)
 {
 

Modified: projects/pseries/dev/ath/ath_hal/ah.h
==============================================================================
--- projects/pseries/dev/ath/ath_hal/ah.h	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/ath/ath_hal/ah.h	Sat Jun  4 19:16:46 2011	(r222695)
@@ -736,6 +736,16 @@ typedef struct {
 
 
 /*
+ * Flag for setting QUIET period
+ */
+typedef enum {
+	HAL_QUIET_DISABLE		= 0x0,
+	HAL_QUIET_ENABLE		= 0x1,
+	HAL_QUIET_ADD_CURRENT_TSF	= 0x2,	/* add current TSF to next_start offset */
+	HAL_QUIET_ADD_SWBA_RESP_TIME	= 0x4,	/* add beacon response time to next_start offset */
+} HAL_QUIET_FLAG;
+
+/*
  * Hardware Access Layer (HAL) API.
  *
  * Clients of the HAL call ath_hal_attach to obtain a reference to an
@@ -909,6 +919,9 @@ struct ath_hal {
 	u_int	  __ahdecl(*ah_getCTSTimeout)(struct ath_hal*);
 	HAL_BOOL  __ahdecl(*ah_setDecompMask)(struct ath_hal*, uint16_t, int);
 	void	  __ahdecl(*ah_setCoverageClass)(struct ath_hal*, uint8_t, int);
+	HAL_STATUS	__ahdecl(*ah_setQuiet)(struct ath_hal *ah, uint32_t period,
+				uint32_t duration, uint32_t nextStart,
+				HAL_QUIET_FLAG flag);
 
 	/* DFS functions */
 	void	  __ahdecl(*ah_enableDfs)(struct ath_hal *ah,

Modified: projects/pseries/dev/ath/ath_hal/ar5212/ar5212.h
==============================================================================
--- projects/pseries/dev/ath/ath_hal/ar5212/ar5212.h	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/ath/ath_hal/ar5212/ar5212.h	Sat Jun  4 19:16:46 2011	(r222695)
@@ -506,6 +506,8 @@ extern	HAL_BOOL ar5212SetCapability(stru
 extern	HAL_BOOL ar5212GetDiagState(struct ath_hal *ah, int request,
 		const void *args, uint32_t argsize,
 		void **result, uint32_t *resultsize);
+extern	HAL_STATUS ar5212SetQuiet(struct ath_hal *ah, uint32_t period,
+		uint32_t duration, uint32_t nextStart, HAL_QUIET_FLAG flag);
 
 extern	HAL_BOOL ar5212SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode,
 		int setChip);

Modified: projects/pseries/dev/ath/ath_hal/ar5212/ar5212_attach.c
==============================================================================
--- projects/pseries/dev/ath/ath_hal/ar5212/ar5212_attach.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/ath/ath_hal/ar5212/ar5212_attach.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -127,6 +127,7 @@ static const struct ath_hal_private ar52
 	.ah_getCTSTimeout		= ar5212GetCTSTimeout,
 	.ah_setDecompMask               = ar5212SetDecompMask,
 	.ah_setCoverageClass            = ar5212SetCoverageClass,
+	.ah_setQuiet			= ar5212SetQuiet,
 
 	/* DFS Functions */
 	.ah_enableDfs			= ar5212EnableDfs,

Modified: projects/pseries/dev/ath/ath_hal/ar5212/ar5212_misc.c
==============================================================================
--- projects/pseries/dev/ath/ath_hal/ar5212/ar5212_misc.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/ath/ath_hal/ar5212/ar5212_misc.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -634,6 +634,20 @@ ar5212SetCoverageClass(struct ath_hal *a
 	}
 }
 
+HAL_STATUS
+ar5212SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration,
+    uint32_t nextStart, HAL_QUIET_FLAG flag)
+{
+	OS_REG_WRITE(ah, AR_QUIET2, period | (duration << AR_QUIET2_QUIET_DUR_S));
+	if (flag & HAL_QUIET_ENABLE) {
+		OS_REG_WRITE(ah, AR_QUIET1, nextStart | (1 << 16));
+	}
+	else {
+		OS_REG_WRITE(ah, AR_QUIET1, nextStart);
+	}
+	return HAL_OK;
+}
+
 void
 ar5212SetPCUConfig(struct ath_hal *ah)
 {

Modified: projects/pseries/dev/ath/ath_hal/ar5212/ar5212reg.h
==============================================================================
--- projects/pseries/dev/ath/ath_hal/ar5212/ar5212reg.h	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/ath/ath_hal/ar5212/ar5212reg.h	Sat Jun  4 19:16:46 2011	(r222695)
@@ -300,6 +300,7 @@
 #define AR_QUIET1_NEXT_QUIET    0xffff
 #define AR_QUIET1_QUIET_ENABLE  0x10000 /* Enable Quiet time operation */
 #define AR_QUIET1_QUIET_ACK_CTS_ENABLE  0x20000 /* Do we ack/cts during quiet period */
+#define	AR_QUIET1_QUIET_ACK_CTS_ENABLE_S 17
 
 #define AR_QUIET2   0x8100  /* More Quiet time programming */
 #define AR_QUIET2_QUIET_PER_S   0   /* Periodicity of quiet period (TU) */

Modified: projects/pseries/dev/ath/ath_hal/ar5416/ar5416.h
==============================================================================
--- projects/pseries/dev/ath/ath_hal/ar5416/ar5416.h	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/ath/ath_hal/ar5416/ar5416.h	Sat Jun  4 19:16:46 2011	(r222695)
@@ -194,6 +194,8 @@ extern	uint32_t ar5416Get11nExtBusy(stru
 extern	void ar5416Set11nMac2040(struct ath_hal *ah, HAL_HT_MACMODE mode);
 extern	HAL_HT_RXCLEAR ar5416Get11nRxClear(struct ath_hal *ah);
 extern	void ar5416Set11nRxClear(struct ath_hal *ah, HAL_HT_RXCLEAR rxclear);
+extern	HAL_STATUS ar5416SetQuiet(struct ath_hal *ah, uint32_t period,
+	    uint32_t duration, uint32_t nextStart, HAL_QUIET_FLAG flag);
 extern	HAL_STATUS ar5416GetCapability(struct ath_hal *ah,
 	    HAL_CAPABILITY_TYPE type, uint32_t capability, uint32_t *result);
 extern	HAL_BOOL ar5416GetDiagState(struct ath_hal *ah, int request,

Modified: projects/pseries/dev/ath/ath_hal/ar5416/ar5416_attach.c
==============================================================================
--- projects/pseries/dev/ath/ath_hal/ar5416/ar5416_attach.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/ath/ath_hal/ar5416/ar5416_attach.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -139,6 +139,7 @@ ar5416InitState(struct ath_hal_5416 *ahp
 	ah->ah_setAntennaSwitch		= ar5416SetAntennaSwitch;
 	ah->ah_setDecompMask		= ar5416SetDecompMask;
 	ah->ah_setCoverageClass		= ar5416SetCoverageClass;
+	ah->ah_setQuiet			= ar5416SetQuiet;
 
 	ah->ah_resetKeyCacheEntry	= ar5416ResetKeyCacheEntry;
 	ah->ah_setKeyCacheEntry		= ar5416SetKeyCacheEntry;

Modified: projects/pseries/dev/ath/ath_hal/ar5416/ar5416_misc.c
==============================================================================
--- projects/pseries/dev/ath/ath_hal/ar5416/ar5416_misc.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/ath/ath_hal/ar5416/ar5416_misc.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -273,6 +273,35 @@ ar5416Set11nRxClear(struct ath_hal *ah, 
     }
 }
 
+/* XXX shouldn't be here! */
+#define	TU_TO_USEC(_tu)		((_tu) << 10)
+
+HAL_STATUS
+ar5416SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration,
+    uint32_t nextStart, HAL_QUIET_FLAG flag)
+{
+	uint32_t period_us = TU_TO_USEC(period); /* convert to us unit */
+	uint32_t nextStart_us = TU_TO_USEC(nextStart); /* convert to us unit */
+	if (flag & HAL_QUIET_ENABLE) {
+		if ((!nextStart) || (flag & HAL_QUIET_ADD_CURRENT_TSF)) {
+			/* Add the nextStart offset to the current TSF */
+			nextStart_us += OS_REG_READ(ah, AR_TSF_L32);
+		}
+		if (flag & HAL_QUIET_ADD_SWBA_RESP_TIME) {
+			nextStart_us += ath_hal_sw_beacon_response_time;
+		}
+		OS_REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
+		OS_REG_WRITE(ah, AR_QUIET2, SM(duration, AR_QUIET2_QUIET_DUR));
+		OS_REG_WRITE(ah, AR_QUIET_PERIOD, period_us);
+		OS_REG_WRITE(ah, AR_NEXT_QUIET, nextStart_us);
+		OS_REG_SET_BIT(ah, AR_TIMER_MODE, AR_TIMER_MODE_QUIET);
+	} else {
+		OS_REG_CLR_BIT(ah, AR_TIMER_MODE, AR_TIMER_MODE_QUIET);
+	}
+	return HAL_OK;
+}
+#undef	TU_TO_USEC
+
 HAL_STATUS
 ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
         uint32_t capability, uint32_t *result)

Modified: projects/pseries/dev/ath/if_ath.c
==============================================================================
--- projects/pseries/dev/ath/if_ath.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/ath/if_ath.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -1261,6 +1261,10 @@ ath_resume(struct ath_softc *sc)
 	    sc->sc_curchan != NULL ? sc->sc_curchan : ic->ic_curchan,
 	    AH_FALSE, &status);
 	ath_reset_keycache(sc);
+
+	/* Let DFS at it in case it's a DFS channel */
+	ath_dfs_radar_enable(sc, ic->ic_curchan);
+
 	if (sc->sc_resume_up) {
 		if (ic->ic_opmode == IEEE80211_M_STA) {
 			ath_init(sc);
@@ -2013,6 +2017,10 @@ ath_calcrxfilter(struct ath_softc *sc)
 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
 		rfilt |= HAL_RX_FILTER_CONTROL;
 
+	if (sc->sc_dodfs) {
+		rfilt |= HAL_RX_FILTER_PHYRADAR;
+	}
+
 	/*
 	 * Enable RX of compressed BAR frames only when doing
 	 * 802.11n. Required for A-MPDU.
@@ -3465,7 +3473,7 @@ ath_rx_proc(void *arg, int npending)
 			if (rs->rs_status & HAL_RXERR_PHY) {
 				sc->sc_stats.ast_rx_phyerr++;
 				/* Process DFS radar events */
-				ath_dfs_process_phy_err(sc, ds, tsf, rs);
+				ath_dfs_process_phy_err(sc, mtod(m, char *), tsf, rs);
 
 				/* Be suitably paranoid about receiving phy errors out of the stats array bounds */
 				if (rs->rs_phyerr < 64)

Modified: projects/pseries/dev/ath/if_athdfs.h
==============================================================================
--- projects/pseries/dev/ath/if_athdfs.h	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/ath/if_athdfs.h	Sat Jun  4 19:16:46 2011	(r222695)
@@ -35,7 +35,7 @@ extern	int ath_dfs_attach(struct ath_sof
 extern	int ath_dfs_detach(struct ath_softc *sc);
 extern	void ath_dfs_radar_enable(struct ath_softc *,
     struct ieee80211_channel *chan);
-extern	void ath_dfs_process_phy_err(struct ath_softc *sc, struct ath_desc *ds,
+extern	void ath_dfs_process_phy_err(struct ath_softc *sc, const char *buf,
     uint64_t tsf, struct ath_rx_status *rxstat);
 extern	int ath_dfs_process_radar_event(struct ath_softc *sc,
     struct ieee80211_channel *chan);

Modified: projects/pseries/dev/ath/if_athvar.h
==============================================================================
--- projects/pseries/dev/ath/if_athvar.h	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/ath/if_athvar.h	Sat Jun  4 19:16:46 2011	(r222695)
@@ -360,6 +360,7 @@ struct ath_softc {
 
 	/* DFS related state */
 	void			*sc_dfs;	/* Used by an optional DFS module */
+	int			sc_dodfs;	/* Whether to enable DFS rx filter bits */
 	struct task		sc_dfstask;	/* DFS processing task */
 };
 

Modified: projects/pseries/dev/iicbus/ds1775.c
==============================================================================
--- projects/pseries/dev/iicbus/ds1775.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/iicbus/ds1775.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -51,8 +51,6 @@ __FBSDID("$FreeBSD$");
 #include <dev/ofw/ofw_bus.h>
 #include <powerpc/powermac/powermac_thermal.h>
 
-#define FCU_ZERO_C_TO_K     2732
-
 /* Drivebay sensor: LM75/DS1775. */
 #define DS1775_TEMP         0x0
 
@@ -95,20 +93,28 @@ static int
 ds1775_read_2(device_t dev, uint32_t addr, uint8_t reg, uint16_t *data)
 {
 	uint8_t buf[4];
+	int err, try = 0;
 
 	struct iic_msg msg[2] = {
 	    { addr, IIC_M_WR | IIC_M_NOSTOP, 1, &reg },
 	    { addr, IIC_M_RD, 2, buf },
 	};
 
-	if (iicbus_transfer(dev, msg, 2) != 0) {
-		device_printf(dev, "iicbus read failed\n");
-		return (EIO);
+	for (;;)
+	{
+		err = iicbus_transfer(dev, msg, 2);
+		if (err != 0)
+			goto retry;
+
+		*data = *((uint16_t*)buf);
+		return (0);
+	retry:
+		if (++try > 5) {
+			device_printf(dev, "iicbus read failed\n");
+			return (-1);
+		}
+		pause("ds1775_read_2", hz);
 	}
-
-	*data = *((uint16_t*)buf);
-
-	return (0);
 }
 
 static int
@@ -182,7 +188,10 @@ ds1775_start(void *xdev)
 	ctx = device_get_sysctl_ctx(dev);
 	sensroot_oid = device_get_sysctl_tree(dev);
 
-	OF_getprop(child, "hwsensor-zone", &sc->sc_sensor.zone, sizeof(int));
+	if (OF_getprop(child, "hwsensor-zone", &sc->sc_sensor.zone,
+		       sizeof(int)) < 0)
+		sc->sc_sensor.zone = 0;
+
 	plen = OF_getprop(child, "hwsensor-location", sc->sc_sensor.name,
 			  sizeof(sc->sc_sensor.name));
 	units = "C";
@@ -199,8 +208,14 @@ ds1775_start(void *xdev)
 	}
 
 	/* Make up target temperatures. These are low, for the drive bay. */
-	sc->sc_sensor.target_temp = 300 + FCU_ZERO_C_TO_K;
-	sc->sc_sensor.max_temp = 600 + FCU_ZERO_C_TO_K;
+	if (sc->sc_sensor.zone == 0) {
+		sc->sc_sensor.target_temp = 500 + ZERO_C_TO_K;
+		sc->sc_sensor.max_temp = 600 + ZERO_C_TO_K;
+	}
+	else {
+		sc->sc_sensor.target_temp = 300 + ZERO_C_TO_K;
+		sc->sc_sensor.max_temp = 600 + ZERO_C_TO_K;
+	}
 
 	sc->sc_sensor.read =
 	    (int (*)(struct pmac_therm *sc))(ds1775_sensor_read);
@@ -220,15 +235,18 @@ ds1775_sensor_read(struct ds1775_softc *
 {
 	uint16_t buf[2];
 	uint16_t read;
+	int err;
 
-	ds1775_read_2(sc->sc_dev, sc->sc_addr, DS1775_TEMP, buf);
+	err = ds1775_read_2(sc->sc_dev, sc->sc_addr, DS1775_TEMP, buf);
+	if (err < 0)
+		return (-1);
 
 	read = *((int16_t *)buf);
 
 	/* The default mode of the ADC is 9 bit, the resolution is 0.5 C per
 	   bit. The temperature is in tenth kelvin.
 	*/
-	return (((int16_t)(read) >> 7) * 5 + FCU_ZERO_C_TO_K);
+	return (((int16_t)(read) >> 7) * 5 + ZERO_C_TO_K);
 }
 
 static int
@@ -243,6 +261,8 @@ ds1775_sensor_sysctl(SYSCTL_HANDLER_ARGS
 	sc = device_get_softc(dev);
 
 	temp = ds1775_sensor_read(sc);
+	if (temp < 0)
+		return (EIO);
 
 	error = sysctl_handle_int(oidp, &temp, 0, req);
 

Modified: projects/pseries/dev/iicbus/max6690.c
==============================================================================
--- projects/pseries/dev/iicbus/max6690.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/iicbus/max6690.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -51,12 +51,11 @@ __FBSDID("$FreeBSD$");
 #include <dev/ofw/ofw_bus.h>
 #include <powerpc/powermac/powermac_thermal.h>
 
-#define FCU_ZERO_C_TO_K     2732
-
 /* Inlet, Backside, U3 Heatsink sensor: MAX6690. */
 
 #define MAX6690_INT_TEMP    0x0
 #define MAX6690_EXT_TEMP    0x1
+#define MAX6690_RSL_STATUS  0x2
 #define MAX6690_EEXT_TEMP   0x10
 #define MAX6690_IEXT_TEMP   0x11
 #define MAX6690_TEMP_MASK   0xe0
@@ -76,8 +75,8 @@ static int  max6690_attach(device_t);
 static int  max6690_sensor_read(struct max6690_sensor *sens);
 static int  max6690_sensor_sysctl(SYSCTL_HANDLER_ARGS);
 static void max6690_start(void *xdev);
-static int  max6690_read_1(device_t dev, uint32_t addr, uint8_t reg,
-			   uint8_t *data);
+static int  max6690_read(device_t dev, uint32_t addr, uint8_t reg,
+			 uint8_t *data);
 
 struct max6690_softc {
 	device_t		sc_dev;
@@ -105,23 +104,43 @@ DRIVER_MODULE(max6690, iicbus, max6690_d
 MALLOC_DEFINE(M_MAX6690, "max6690", "Temp-Monitor MAX6690");
 
 static int
-max6690_read_1(device_t dev, uint32_t addr, uint8_t reg, uint8_t *data)
+max6690_read(device_t dev, uint32_t addr, uint8_t reg, uint8_t *data)
 {
 	uint8_t buf[4];
+	uint8_t busy[1], rsl;
+	int err, try = 0;
 
-	struct iic_msg msg[2] = {
+	/* Busy register RSL. */
+	rsl = MAX6690_RSL_STATUS;
+	/* first read the status register, 0x2. If busy, retry. */
+	struct iic_msg msg[4] = {
+	    { addr, IIC_M_WR | IIC_M_NOSTOP, 1, &rsl },
+	    { addr, IIC_M_RD, 1, busy },
 	    { addr, IIC_M_WR | IIC_M_NOSTOP, 1, &reg },
 	    { addr, IIC_M_RD, 1, buf },
 	};
 
-	if (iicbus_transfer(dev, msg, 2) != 0) {
-		device_printf(dev, "iicbus read failed\n");
-		return (EIO);
+	for (;;)
+	{
+		err = iicbus_transfer(dev, msg, 4);
+		if (err != 0)
+			goto retry;
+		if (busy[0] & 0x80)
+			goto retry;
+		/* Check for invalid value and retry. */
+		if (buf[0] == 0xff)
+			goto retry;
+
+		*data = *((uint8_t*)buf);
+		return (0);
+
+	retry:
+		if (++try > 5) {
+			device_printf(dev, "iicbus read failed\n");
+			return (-1);
+		}
+		pause("max6690_read", hz);
 	}
-
-	*data = *((uint8_t*)buf);
-
-	return (0);
 }
 
 static int
@@ -193,8 +212,8 @@ max6690_fill_sensor_prop(device_t dev)
 	for (j = 0; j < i; j++) {
 		sc->sc_sensors[j].dev = dev;
 
-		sc->sc_sensors[j].therm.target_temp = 400 + 2732;
-		sc->sc_sensors[j].therm.max_temp = 800 + 2732;
+		sc->sc_sensors[j].therm.target_temp = 400 + ZERO_C_TO_K;
+		sc->sc_sensors[j].therm.max_temp = 800 + ZERO_C_TO_K;
 
 		sc->sc_sensors[j].therm.read =
 		    (int (*)(struct pmac_therm *))(max6690_sensor_read);
@@ -302,14 +321,15 @@ static int
 max6690_sensor_read(struct max6690_sensor *sens)
 {
 	uint8_t reg_int = 0, reg_ext = 0;
-	uint8_t integer;
-	uint8_t fraction;
-	int temp;
+	uint8_t integer = 0;
+	uint8_t fraction = 0;
+	int err, temp;
+
 	struct max6690_softc *sc;
 
 	sc = device_get_softc(sens->dev);
 
-	/* The internal sensor id's are even, the external ar odd. */
+	/* The internal sensor id's are even, the external are odd. */
 	if ((sens->id % 2) == 0) {
 		reg_int = MAX6690_INT_TEMP;
 		reg_ext = MAX6690_IEXT_TEMP;
@@ -318,9 +338,11 @@ max6690_sensor_read(struct max6690_senso
 		reg_ext = MAX6690_EEXT_TEMP;
 	}
 
-	max6690_read_1(sc->sc_dev, sc->sc_addr, reg_int, &integer);
+	err = max6690_read(sc->sc_dev, sc->sc_addr, reg_int, &integer);
+	err = max6690_read(sc->sc_dev, sc->sc_addr, reg_ext, &fraction);
 
-	max6690_read_1(sc->sc_dev, sc->sc_addr, reg_ext, &fraction);
+	if (err < 0)
+		return (-1);
 
 	fraction &= MAX6690_TEMP_MASK;
 
@@ -329,7 +351,7 @@ max6690_sensor_read(struct max6690_senso
 	*/
 	temp = (integer * 10) + (fraction >> 5) * 10 / 8;
 
-	return (temp + FCU_ZERO_C_TO_K);
+	return (temp + ZERO_C_TO_K);
 }
 
 static int

Modified: projects/pseries/dev/iwn/if_iwn.c
==============================================================================
--- projects/pseries/dev/iwn/if_iwn.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/iwn/if_iwn.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -567,6 +567,7 @@ iwn_attach(device_t dev)
 	ic->ic_caps =
 		  IEEE80211_C_STA		/* station mode supported */
 		| IEEE80211_C_MONITOR		/* monitor mode supported */
+		| IEEE80211_C_BGSCAN		/* background scanning */
 		| IEEE80211_C_TXPMGT		/* tx power management */
 		| IEEE80211_C_SHSLOT		/* short slot time supported */
 		| IEEE80211_C_WPA
@@ -576,8 +577,6 @@ iwn_attach(device_t dev)
 #endif
 		| IEEE80211_C_WME		/* WME */
 		;
-	if (sc->hw_type != IWN_HW_REV_TYPE_4965)
-		ic->ic_caps |= IEEE80211_C_BGSCAN; /* background scanning */
 
 	/* Read MAC address, channels, etc from EEPROM. */
 	if ((error = iwn_read_eeprom(sc, macaddr)) != 0) {
@@ -607,9 +606,9 @@ iwn_attach(device_t dev)
 		ic->ic_htcaps =
 			  IEEE80211_HTCAP_SMPS_OFF	/* SMPS mode disabled */
 			| IEEE80211_HTCAP_SHORTGI20	/* short GI in 20MHz */
-#ifdef notyet
 			| IEEE80211_HTCAP_CHWIDTH40	/* 40MHz channel width*/
 			| IEEE80211_HTCAP_SHORTGI40	/* short GI in 40MHz */
+#ifdef notyet
 			| IEEE80211_HTCAP_GREENFIELD
 #if IWN_RBUF_SIZE == 8192
 			| IEEE80211_HTCAP_MAXAMSDU_7935	/* max A-MSDU length */
@@ -3315,7 +3314,8 @@ iwn_tx_data(struct iwn_softc *sc, struct
 	}
 	ac = M_WME_GETAC(m);
 
-	if (IEEE80211_AMPDU_RUNNING(&ni->ni_tx_ampdu[ac])) {
+	if (IEEE80211_QOS_HAS_SEQ(wh) &&
+	    IEEE80211_AMPDU_RUNNING(&ni->ni_tx_ampdu[ac])) {
 		struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[ac];
 
 		ring = &sc->txq[*(int *)tap->txa_private];
@@ -5161,7 +5161,7 @@ iwn_scan(struct iwn_softc *sc)
 	if (IEEE80211_IS_CHAN_A(ic->ic_curchan) &&
 	    sc->hw_type == IWN_HW_REV_TYPE_4965) {
 		/* Ant A must be avoided in 5GHz because of an HW bug. */
-		rxchain |= IWN_RXCHAIN_FORCE_SEL(IWN_ANT_BC);
+		rxchain |= IWN_RXCHAIN_FORCE_SEL(IWN_ANT_B);
 	} else	/* Use all available RX antennas. */
 		rxchain |= IWN_RXCHAIN_FORCE_SEL(sc->rxchainmask);
 	hdr->rxchain = htole16(rxchain);
@@ -5172,14 +5172,19 @@ iwn_scan(struct iwn_softc *sc)
 	tx->id = sc->broadcast_id;
 	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
 
-	if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) {
+	if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) {
 		/* Send probe requests at 6Mbps. */
 		tx->rate = htole32(0xd);
 		rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
 	} else {
 		hdr->flags = htole32(IWN_RXON_24GHZ | IWN_RXON_AUTO);
-		/* Send probe requests at 1Mbps. */
-		tx->rate = htole32(10 | IWN_RFLAG_CCK);
+		if (sc->hw_type == IWN_HW_REV_TYPE_4965 &&
+		    sc->rxon.associd && sc->rxon.chan > 14)
+			tx->rate = htole32(0xd);
+		else {
+			/* Send probe requests at 1Mbps. */
+			tx->rate = htole32(10 | IWN_RFLAG_CCK);
+		}
 		rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
 	}
 	/* Use the first valid TX antenna. */

Modified: projects/pseries/dev/puc/pucdata.c
==============================================================================
--- projects/pseries/dev/puc/pucdata.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/dev/puc/pucdata.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -48,8 +48,8 @@ __FBSDID("$FreeBSD$");
 #include <dev/puc/puc_bfe.h>
 
 static puc_config_f puc_config_amc;
-static puc_config_f puc_config_cronyx;
 static puc_config_f puc_config_diva;
+static puc_config_f puc_config_exar;
 static puc_config_f puc_config_icbook;
 static puc_config_f puc_config_quatech;
 static puc_config_f puc_config_syba;
@@ -548,11 +548,25 @@ const struct puc_cfg puc_pci_devices[] =
 	    PUC_PORT_8S, 0x18, 0, 8,
 	},
 
+	{   0x13a8, 0x0152, 0xffff, 0,
+	    "Exar XR17C/D152",
+	    DEFAULT_RCLK * 8,
+	    PUC_PORT_2S, 0x10, 0, -1,
+	    .config_function = puc_config_exar
+	},
+
+	{   0x13a8, 0x0154, 0xffff, 0,
+	    "Exar XR17C154",
+	    DEFAULT_RCLK * 8,
+	    PUC_PORT_4S, 0x10, 0, -1,
+	    .config_function = puc_config_exar
+	},
+
 	{   0x13a8, 0x0158, 0xffff, 0,
-	    "Cronyx Omega2-PCI",
+	    "Exar XR17C158",
 	    DEFAULT_RCLK * 8,
 	    PUC_PORT_8S, 0x10, 0, -1,
-	    .config_function = puc_config_cronyx
+	    .config_function = puc_config_exar
 	},
 
 	{   0x13a8, 0x0258, 0xffff, 0,
@@ -1014,28 +1028,28 @@ puc_config_amc(struct puc_softc *sc, enu
 }
 
 static int
-puc_config_cronyx(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
+puc_config_diva(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
     intptr_t *res)
 {
+	const struct puc_cfg *cfg = sc->sc_cfg;
+
 	if (cmd == PUC_CFG_GET_OFS) {
-		*res = port * 0x200;
+		if (cfg->subdevice == 0x1282)		/* Everest SP */
+			port <<= 1;
+		else if (cfg->subdevice == 0x104b)	/* Maestro SP2 */
+			port = (port == 3) ? 4 : port;
+		*res = port * 8 + ((port > 2) ? 0x18 : 0);
 		return (0);
 	}
 	return (ENXIO);
 }
 
 static int
-puc_config_diva(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
+puc_config_exar(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
     intptr_t *res)
 {
-	const struct puc_cfg *cfg = sc->sc_cfg;
-
 	if (cmd == PUC_CFG_GET_OFS) {
-		if (cfg->subdevice == 0x1282)		/* Everest SP */
-			port <<= 1;
-		else if (cfg->subdevice == 0x104b)	/* Maestro SP2 */
-			port = (port == 3) ? 4 : port;
-		*res = port * 8 + ((port > 2) ? 0x18 : 0);
+		*res = port * 0x200;
 		return (0);
 	}
 	return (ENXIO);

Modified: projects/pseries/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- projects/pseries/fs/nfsserver/nfs_nfsdport.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/fs/nfsserver/nfs_nfsdport.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -2592,6 +2592,36 @@ nfsvno_pathconf(struct vnode *vp, int fl
 	int error;
 
 	error = VOP_PATHCONF(vp, flag, retf);
+	if (error == EOPNOTSUPP || error == EINVAL) {
+		/*
+		 * Some file systems return EINVAL for name arguments not
+		 * supported and some return EOPNOTSUPP for this case.
+		 * So the NFSv3 Pathconf RPC doesn't fail for these cases,
+		 * just fake them.
+		 */
+		switch (flag) {
+		case _PC_LINK_MAX:
+			*retf = LINK_MAX;
+			break;
+		case _PC_NAME_MAX:
+			*retf = NAME_MAX;
+			break;
+		case _PC_CHOWN_RESTRICTED:
+			*retf = 1;
+			break;
+		case _PC_NO_TRUNC:
+			*retf = 1;
+			break;
+		default:
+			/*
+			 * Only happens if a _PC_xxx is added to the server,
+			 * but this isn't updated.
+			 */
+			*retf = 0;
+			printf("nfsrvd pathconf flag=%d not supp\n", flag);
+		};
+		error = 0;
+	}
 	return (error);
 }
 

Modified: projects/pseries/geom/geom_disk.c
==============================================================================
--- projects/pseries/geom/geom_disk.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/geom/geom_disk.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -154,6 +154,12 @@ g_disk_access(struct g_provider *pp, int
 		}
 		pp->mediasize = dp->d_mediasize;
 		pp->sectorsize = dp->d_sectorsize;
+		if (dp->d_flags & DISKFLAG_CANDELETE)
+			pp->flags |= G_PF_CANDELETE;
+		else
+			pp->flags &= ~G_PF_CANDELETE;
+		pp->stripeoffset = dp->d_stripeoffset;
+		pp->stripesize = dp->d_stripesize;
 		dp->d_flags |= DISKFLAG_OPEN;
 		if (dp->d_maxsize == 0) {
 			printf("WARNING: Disk drive %s%d has no d_maxsize\n",

Modified: projects/pseries/geom/part/g_part.c
==============================================================================
--- projects/pseries/geom/part/g_part.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/geom/part/g_part.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -248,6 +248,7 @@ g_part_check_integrity(struct g_part_tab
 {
 	struct g_part_entry *e1, *e2;
 	struct g_provider *pp;
+	off_t offset;
 	int failed;
 
 	failed = 0;
@@ -294,6 +295,16 @@ g_part_check_integrity(struct g_part_tab
 			    (intmax_t)table->gpt_last);
 			failed++;
 		}
+		if (pp->stripesize > 0) {
+			offset = e1->gpe_start * pp->sectorsize;
+			if (e1->gpe_offset > offset)
+				offset = e1->gpe_offset;
+			if ((offset + pp->stripeoffset) % pp->stripesize) {
+				DPRINTF("partition %d is not aligned on %u "
+				    "bytes\n", e1->gpe_index, pp->stripesize);
+				/* Don't treat this as a critical failure */
+			}
+		}
 		e2 = e1;
 		while ((e2 = LIST_NEXT(e2, gpe_entry)) != NULL) {
 			if (e2->gpe_deleted || e2->gpe_internal)
@@ -723,7 +734,11 @@ g_part_ctl_add(struct gctl_req *req, str
 	if (gpp->gpp_parms & G_PART_PARM_OUTPUT) {
 		sb = sbuf_new_auto();
 		G_PART_FULLNAME(table, entry, sb, gp->name);
-		sbuf_cat(sb, " added\n");
+		if (pp->stripesize > 0 && entry->gpe_pp->stripeoffset != 0)
+			sbuf_printf(sb, " added, but partition is not "
+			    "aligned on %u bytes\n", pp->stripesize);
+		else
+			sbuf_cat(sb, " added\n");
 		sbuf_finish(sb);
 		gctl_set_param(req, "output", sbuf_data(sb), sbuf_len(sb) + 1);
 		sbuf_delete(sb);

Modified: projects/pseries/mips/cavium/octeon_ebt3000_cf.c
==============================================================================
--- projects/pseries/mips/cavium/octeon_ebt3000_cf.c	Sat Jun  4 17:31:06 2011	(r222694)
+++ projects/pseries/mips/cavium/octeon_ebt3000_cf.c	Sat Jun  4 19:16:46 2011	(r222695)
@@ -104,12 +104,40 @@ __FBSDID("$FreeBSD$");
 extern cvmx_bootinfo_t *octeon_bootinfo;
 
 /* Globals */
-int	bus_width;
+/*
+ * There's three bus types supported by this driver.
+ *
+ * CF_8 -- Traditional PC Card IDE interface on an 8-bit wide bus.  We assume
+ * the bool loader has configure attribute memory properly.  We then access
+ * the device like old-school 8-bit IDE card (which is all a traditional PC Card
+ * interface really is).
+ * CF_16 -- Traditional PC Card IDE interface on a 16-bit wide bus.  Registers on
+ * this bus are 16-bits wide too.  When accessing registers in the task file, you
+ * have to do it in 16-bit chunks, and worry about masking out what you don't want
+ * or ORing together the traditional 8-bit values.  We assume the bootloader does
+ * the right attribute memory initialization dance.
+ * CF_TRUE_IDE_8 - CF Card wired to True IDE mode.  There's no Attribute memory
+ * space at all.  Instead all the traditional 8-bit registers are there, but
+ * on a 16-bit bus where addr0 isn't wired.  This means we need to read/write them
+ * 16-bit chunks, but only the lower 8 bits are valid.  We do not (and can not)
+ * access this like CF_16 with the comingled registers.  Yet we can't access
+ * this like CF_8 because of the register offset.  Except the TF_DATA register
+ * appears to be full width?
+ */
 void	*base_addr;
+int	bus_type;
+#define CF_8		1	/* 8-bit bus, no offsets - PC Card */
+#define CF_16		2	/* 16-bit bus, registers shared - PC Card */
+#define CF_TRUE_IDE_8	3	/* 16-bit bus, only lower 8-bits, TrueIDE */
+const char *const cf_type[] = {
+	"impossible type",
+	"CF 8-bit",
+	"CF 16-bit",
+	"True IDE"
+};
 
 /* Device softc */
 struct cf_priv {
-
 	device_t dev;
 	struct drive_param *drive_param;
 
@@ -230,9 +258,65 @@ static void cf_start (struct bio *bp)
 
 static int cf_ioctl (struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td)
 {
-    return (0);
+	return (0);
+}
+
+
+static uint8_t cf_inb_8(int port)
+{
+	/*
+	 * Traditional 8-bit PC Card/CF bus access.
+	 */
+	if (bus_type == CF_8) {
+		volatile uint8_t *task_file = (volatile uint8_t *)base_addr;
+		return task_file[port];
+	}
+
+	/*
+	 * True IDE access.  lower 8 bits on a 16-bit bus (see above).
+	 */
+	volatile uint16_t *task_file = (volatile uint16_t *)base_addr;
+	return task_file[port] & 0xff;
+}
+
+static void cf_outb_8(int port, uint8_t val)
+{
+	/*
+	 * Traditional 8-bit PC Card/CF bus access.
+	 */
+	if (bus_type == CF_8) {
+		volatile uint8_t *task_file = (volatile uint8_t *)base_addr;
+		task_file[port] = val;
+	}
+
+	/*
+	 * True IDE access.  lower 8 bits on a 16-bit bus (see above).
+	 */
+	volatile uint16_t *task_file = (volatile uint16_t *)base_addr;
+	task_file[port] = val & 0xff;
+}
+
+static uint8_t cf_inb_16(int port)
+{
+	volatile uint16_t *task_file = (volatile uint16_t *)base_addr;
+	uint16_t val = task_file[port / 2];
+	if (port & 1)
+		return (val >> 8) & 0xff;
+	return val & 0xff;
+}
+
+static uint16_t cf_inw_16(int port)
+{
+	volatile uint16_t *task_file = (volatile uint16_t *)base_addr;
+	uint16_t val = task_file[port / 2];
+	return val;
 }
 
+static void cf_outw_16(int port, uint16_t val)
+{
+	volatile uint16_t *task_file = (volatile uint16_t *)base_addr;
+	task_file[port / 2] = val;
+}
 
 /* ------------------------------------------------------------------- *
  *                      cf_cmd_read()                                  *
@@ -264,25 +348,29 @@ static int cf_cmd_read (uint32_t nr_sect
 			return (error);
 		}
 
-		if (bus_width == 8) {
-			volatile uint8_t *task_file = (volatile uint8_t*)base_addr;
-        		volatile uint8_t dummy;
+		switch (bus_type)
+		{
+		case CF_8:
 			for (count = 0; count < SECTOR_SIZE; count++) {
-				*ptr_8++ = task_file[TF_DATA];
-				if ((count & 0xf) == 0) dummy = task_file[TF_STATUS];
+				*ptr_8++ = cf_inb_8(TF_DATA);
+				if ((count & 0xf) == 0)
+					(void)cf_inb_8(TF_STATUS);
 			}
-		} else {
-			volatile uint16_t *task_file = (volatile uint16_t*)base_addr;
-        		volatile uint16_t dummy;
+			break;
+		case CF_TRUE_IDE_8:
+		case CF_16:
+		default:
 			for (count = 0; count < SECTOR_SIZE; count+=2) {
 				uint16_t temp;
-				temp = task_file[TF_DATA];
+				temp = cf_inw_16(TF_DATA);
 				*ptr_16++ = SWAP_SHORT(temp);
-				if ((count & 0xf) == 0) dummy = task_file[TF_STATUS/2];
+				if ((count & 0xf) == 0)
+					(void)cf_inb_16(TF_STATUS);
 			}
+			break;
 		}  
 
-		lba ++;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list