[linux-yocto] [PATCH 21/30] drivers/rapidio/lsi: squash a bunch rapidio stuff together and Cleanup

Charlie Paul cpaul.windriver at gmail.com
Thu May 1 08:29:43 PDT 2014


From: ningligong <ning.li at lsi.com>

Remove extraneous diagnostic message.

fixed getting vsid and dse_id from interrupt register

The CNTLZW macro only works if interrupts bits 0,1,2,3,4,8,16, it does
not work for other cases. Thus made a fix so that the proper vsid and
dse_id can be retrieved from the interrupt register.

Reset the AXXIA RIO controller to use 'port index' of 0 in all cases
to reduce addressing errors.  Also, fix a confusion in the AXXIA RIO
specific driver code between 'id' and 'port index'.

Add definition for AXXIA_RIO_SYSMEM_BARRIER() for ARM platform using
assembly directive '__asm__ __volatile__ ("dmb" : : : "memory")'.

Update diagnostic messages and compile headers for lock debugging.
Add initialization of component tag for AXXIA RIO endpoints that
prevents full network enumeration of boards with multiple controllers.

This patch adds support for enumeration of multiple SRIO controllers
to the Axxia AXM55xx platform.  Note that special handling is needed
to disambiguate an interlock issue.  This patch only improves the
enumeration algorithm for instances of this platform.

Add 'cookie' to private data structure and test for it when performing
local memory accesses.  Also improve bounds checking in code that tests
for available DMEs when opening/closing mailboxes.

Signed-off-by: ningligong <ning.li at lsi.com>
Signed-off-by: Paul Butler <paul.butler at windriver.com>
Signed-off-by: Michael Bringmann <michael.bringmann at lsi.com>
---
 arch/arm/boot/dts/axm55xx.dts                   |   21 +-
 arch/arm/include/asm/axxia-rio.h                |   46 +-
 arch/arm/include/asm/rio.h                      |    4 +
 arch/arm/mach-axxia/rapidio.c                   |   26 +-
 arch/powerpc/include/asm/axxia-rio.h            |   32 +-
 arch/powerpc/include/asm/rio.h                  |    5 +
 drivers/net/rionet.c                            |    3 +-
 drivers/rapidio/devices/lsi/axxia-rio-ds.c      |  624 ++++++++++++-----------
 drivers/rapidio/devices/lsi/axxia-rio-ds.h      |   42 +-
 drivers/rapidio/devices/lsi/axxia-rio-hotplug.c |   50 +-
 drivers/rapidio/devices/lsi/axxia-rio-irg-dbg.h |    3 +-
 drivers/rapidio/devices/lsi/axxia-rio-irq.c     |  131 +++--
 drivers/rapidio/devices/lsi/axxia-rio-sysfs.c   |    5 +-
 drivers/rapidio/devices/lsi/axxia-rio.c         |  271 ++++++----
 drivers/rapidio/devices/lsi/axxia-rio.h         |   28 +-
 drivers/rapidio/rio-locks.c                     |   16 +-
 drivers/rapidio/rio-locks.h                     |    2 +
 drivers/rapidio/rio-net2.c                      |   10 +-
 drivers/rapidio/rio.h                           |   28 +
 19 files changed, 820 insertions(+), 527 deletions(-)
 mode change 100644 => 100755 drivers/rapidio/devices/lsi/axxia-rio-ds.c
 mode change 100644 => 100755 drivers/rapidio/devices/lsi/axxia-rio-ds.h

diff --git a/arch/arm/boot/dts/axm55xx.dts b/arch/arm/boot/dts/axm55xx.dts
index 7ecb177..f18550b 100644
--- a/arch/arm/boot/dts/axm55xx.dts
+++ b/arch/arm/boot/dts/axm55xx.dts
@@ -36,6 +36,7 @@
 		timer	  = &axxia_timers;
 		ethernet0 = &axxia_femac0;
 		rapidio0  = &rio0;
+		rapidio1  = &rio1;
 	};
 
 	cpus {
@@ -92,7 +93,7 @@
 		};
 
 		cpu at 7 {
-			device_type = "cpua";
+			device_type = "cpu";
 			compatible = "arm,cortex-a15";
 			reg = <7>;
 			cpu-release-addr = <0>; // Fixed by the boot loader
@@ -425,7 +426,7 @@
 		interrupts = <0 45 4>;
 	};
 
-        rio0: rapidio {
+        rio0: rapidio at 0x3100000000 {
                 index = <0>;
                 status = "disabled";
                 #address-cells = <2>;
@@ -437,6 +438,22 @@
                 linkdown-reset = <0x0200 0x100 0x0020 0x10000000 0x0 0x000010000>;
                 interrupts = <0 89 4>;
                 outb-dmes = <2 0x00000003 1 0x00000000>;
+		enable_ds = <1>;
+        };
+
+        rio1: rapidio at 0x3140000000 {
+                index = <1>;
+                status = "disabled";
+                #address-cells = <2>;
+                #size-cells = <2>;
+                compatible = "axxia,rapidio-delta";
+                device_type = "rapidio";
+                reg = <0x0020 0x20143000 0x0 0x1000>; /* SRIO Conf 1 region */
+                ranges = <0x0 0x0 0x0031 0x40000000 0x0 0x40000000>;
+                linkdown-reset = <0x0200 0x200 0x0020 0x10000000 0x0 0x000010000>;
+                interrupts = <0 90 4>;
+                outb-dmes = <2 0x00000003 1 0x00000000>;
+		enable_ds = <1>;
         };
 
 };
diff --git a/arch/arm/include/asm/axxia-rio.h b/arch/arm/include/asm/axxia-rio.h
index f244c85..e01d6a3 100644
--- a/arch/arm/include/asm/axxia-rio.h
+++ b/arch/arm/include/asm/axxia-rio.h
@@ -9,7 +9,8 @@
 
 #define AXXIA_RIO_SMALL_SYSTEM
 
-#define AXXIA_RIO_SYSMEM_BARRIER()
+#define AXXIA_RIO_SYSMEM_BARRIER() \
+		__asm__ __volatile__ ("dmb" : : : "memory")
 
 #define AXXIA_RIO_DISABLE_MACHINE_CHECK()
 #define AXXIA_RIO_ENABLE_MACHINE_CHECK()
@@ -27,6 +28,47 @@
 #define CORRECT_GRIO(a)		_SWAP32(a)
 #define CORRECT_RAB(a)		(a)
 
+/* AXXIA RIO Patching Macros */
+
+#define RAPIDIO_REDUNDANT_PATH_LOCK_FAULT()				\
+	{								\
+		u32 __id;						\
+		rio_mport_read_config_32(prev->hport, destid, hopcount,	\
+					RIO_DEV_ID_CAR, &__id);		\
+		if ((lock == prev->hport->host_deviceid) &&		\
+				(__id == 0x5120000a)) {				\
+			pr_debug("axxia-rio: Patch 1 for HBDIDLCSR[%x:%x]\n", \
+				(__id & 0xffff), (((__id) >> 16) & 0xffff)); \
+			goto out;					\
+		}							\
+	}
+
+#define RAPIDIO_HW_LOCK_LOCK_ERR()					\
+	{								\
+		u32 __id;						\
+		rio_mport_read_config_32(port, destid, hopcount,	\
+					RIO_DEV_ID_CAR,	&__id);		\
+		if (__id == 0x5120000a) {				\
+			pr_debug("axxia-rio: Patch 2 for HBDIDLCSR[%x:%x]\n", \
+				(__id & 0xffff), (((__id) >> 16) & 0xffff)); \
+			goto done;					\
+		}							\
+	}
+
+#define RAPIDIO_HW_UNLOCK_LOCK_ERR()					\
+	{								\
+		u32 __id;						\
+		rio_mport_read_config_32(port, destid,			\
+					hopcount,			\
+					RIO_DEV_ID_CAR, &__id);		\
+		if ((lock == 0xffff) && (__id == 0x5120000a)) {		\
+			pr_debug("axxia-rio: Patch 3 for HBDIDLCSR[%x:%x]\n", \
+				(__id & 0xffff), (((__id) >> 16) & 0xffff)); \
+			goto done;					\
+		}							\
+	}
+
+
 /* ACP RIO board-specific stuff */
 
 extern int axxia_rio_apio_enable(struct rio_mport *mport, u32 mask, u32 bits);
@@ -34,7 +76,7 @@ extern int axxia_rio_apio_disable(struct rio_mport *mport);
 extern int axxia_rio_rpio_enable(struct rio_mport *mport, u32 mask, u32 bits);
 extern int axxia_rio_rpio_disable(struct rio_mport *mport);
 
-extern int axxia_rapidio_board_init(void);
+extern int axxia_rapidio_board_init(int devNum, int *portNdx);
 
 
 /*****************************/
diff --git a/arch/arm/include/asm/rio.h b/arch/arm/include/asm/rio.h
index 10da207..7559fbd 100644
--- a/arch/arm/include/asm/rio.h
+++ b/arch/arm/include/asm/rio.h
@@ -30,4 +30,8 @@ extern void platform_rio_init(void);
 
 #define iosync()
 
+#endif /* ASM_ARM_RIO_H */
+
+#if defined(CONFIG_AXXIA_RIO) && defined(DRIVERS_RAPIDIO_RIO_H)
+#include <asm/axxia-rio.h>
 #endif
diff --git a/arch/arm/mach-axxia/rapidio.c b/arch/arm/mach-axxia/rapidio.c
index a9da46b..82deeaa 100644
--- a/arch/arm/mach-axxia/rapidio.c
+++ b/arch/arm/mach-axxia/rapidio.c
@@ -29,16 +29,40 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <asm/io.h>
+
+#include <../../../drivers/misc/lsi-ncr.h>
 
 
 /**
  * axxia_rapidio_board_init -
  *   Perform board-specific initialization to support use of RapidIO busses
  *
+ * @ndx:     [IN] Which instance of SRIOC driver needs support
+ * @portNdx: [OUT] Which port to use for the specified controller
+ *
  * Returns 0 on success or an error code.
  */
 int
-axxia_rapidio_board_init(void)
+axxia_rapidio_board_init(
+	int devNum,
+	int *portNdx)
 {
+	void __iomem *gpregBase = ioremap(0x2010094000, 0x1000);
+	unsigned long srioCfg = 0;
+
+	if (gpregBase == NULL)
+		return -EFAULT;
+
+	srioCfg = inl((long unsigned int)(gpregBase + 0x60));
+
+	srioCfg &= ~(0xf << (devNum * 4));
+
+	outl_p(srioCfg, (long unsigned int)(gpregBase + 0x60));
+
+	(*portNdx) = 0;
+
+	iounmap(gpregBase);
+
 	return 0;
 }
diff --git a/arch/powerpc/include/asm/axxia-rio.h b/arch/powerpc/include/asm/axxia-rio.h
index 2d18ee1..b461b80 100644
--- a/arch/powerpc/include/asm/axxia-rio.h
+++ b/arch/powerpc/include/asm/axxia-rio.h
@@ -10,26 +10,26 @@
 #define AXXIA_RIO_SYSMEM_BARRIER()	__asm__ __volatile__("msync")
 
 #define		AXXIA_RIO_DISABLE_MACHINE_CHECK()	\
-			{									\
-			mtmsr(mfmsr() & ~(MSR_ME));		\
+			{				\
+			mtmsr(mfmsr() & ~(MSR_ME));	\
 			__asm__ __volatile__("msync");	\
 			}
 
 #define		AXXIA_RIO_ENABLE_MACHINE_CHECK()	\
-			{									\
-			mtmsr(mfmsr() | (MSR_ME));			\
-			__asm__ __volatile__("msync");		\
+			{				\
+			mtmsr(mfmsr() | (MSR_ME));	\
+			__asm__ __volatile__("msync");	\
 			}
 
 #define		AXXIA_RIO_IF_MACHINE_CHECK(mcsr)	\
-			{									\
-			__asm__ __volatile__("msync");		\
-			mcsr = mfspr(SPRN_MCSR);			\
-			if (mcsr != 0) {					\
-				/* machine check would have occurred ! */	\
-				/* clear it */								\
-				mtspr(SPRN_MCSR, 0);						\
-				__asm__ __volatile__("msync");				\
+			{				\
+			__asm__ __volatile__("msync");	\
+			mcsr = mfspr(SPRN_MCSR);	\
+			if (mcsr != 0) {		\
+				/* machine check would have occurred ! */ \
+				/* clear it */		\
+				mtspr(SPRN_MCSR, 0);	\
+				__asm__ __volatile__("msync");	\
 			} }
 
 #define __acp_read_rio_config(x, addr, err, op)			\
@@ -72,7 +72,11 @@ extern int axxia_rio_apio_disable(struct rio_mport *mport);
 extern int axxia_rio_rpio_enable(struct rio_mport *mport, u32 mask, u32 bits);
 extern int axxia_rio_rpio_disable(struct rio_mport *mport);
 
-#define	axxia_rapidio_board_init(v)	(0)
+static inline int axxia_rapidio_board_init(int devNum, int *portNdx)
+{
+	(*portNdx) = 0;
+	return 0;
+}
 
 
 /*****************************/
diff --git a/arch/powerpc/include/asm/rio.h b/arch/powerpc/include/asm/rio.h
index 02b920c..1283a9f 100644
--- a/arch/powerpc/include/asm/rio.h
+++ b/arch/powerpc/include/asm/rio.h
@@ -62,3 +62,8 @@ DEF_RIO_IN_BE(rio_in_be32, 32, "lwz")
 
 
 #endif				/* ASM_PPC_RIO_H */
+
+
+#if defined(CONFIG_AXXIA_RIO) && defined(DRIVERS_RAPIDIO_RIO_H)
+#include <asm/axxia-rio.h>
+#endif
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 3409818..f37ba0d 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -549,7 +549,7 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
 
 	/*
 	 * First time through, make sure local device is rionet
-	 * capable, setup netdev,  and set flags so this is skipped
+	 * capable, setup netdev, and set flags so this is skipped
 	 * on later probes
 	 */
 	if (!rionet_check) {
@@ -587,6 +587,7 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
 	}
 
 	rio_set_drvdata(rdev, ndev);
+	rc = 0;
 
 out:
 	return rc;
diff --git a/drivers/rapidio/devices/lsi/axxia-rio-ds.c b/drivers/rapidio/devices/lsi/axxia-rio-ds.c
old mode 100644
new mode 100755
index b681cae..f4f44a6
--- a/drivers/rapidio/devices/lsi/axxia-rio-ds.c
+++ b/drivers/rapidio/devices/lsi/axxia-rio-ds.c
@@ -145,10 +145,6 @@ static inline void __ib_dse_dw_dbg(
  *	registers.
  *
  * @mport:	pointer to the master port
- * @max_pdu_length:   Maximum PDU in size supported by the destination
- *			endpoint. It is a 16-bit field, 0 indicates 64KB.
- * @seg_support:      Number of segmentation context supported by
- *			the destination endpoint. It is a 16-bit field.
  * @mtu:	Maximum Transmission Unit - controls the data payload size for
  *			segments of an encapsulated PDU.
  * @ibds_avsid_mapping:	this field definesmapping from incoming VSID
@@ -159,8 +155,6 @@ static inline void __ib_dse_dw_dbg(
  ****************************************************************************/
 int axxia_data_stream_global_cfg(
 	struct rio_mport    *mport,
-	int			max_pdu_length,
-	int			seg_support,
 	int			mtu,
 	int			ibds_avsid_mapping)
 {
@@ -169,12 +163,11 @@ int axxia_data_stream_global_cfg(
 	struct ibds_virt_m_cfg  *ptr_virt_m_cfg;
 	struct rio_obds_dse_cfg *ptr_dse_cfg;
 	int		reg_val;
-	u32		max_pdu_len = 0;
+	u32		mtu_value = 0;
 	int	i;
 
 	/* sanity check */
-	if ((max_pdu_length > (1<<16))	||
-		(mtu < 32)		||
+	if ((mtu < 32)		||
 		(mtu > 256)) {
 		return -EINVAL;
 	}
@@ -194,41 +187,22 @@ int axxia_data_stream_global_cfg(
 			return -EINVAL;
 	}
 
-	/* TBD - The __rio_local_read_config_32( ) does not return proper
-	**	value for GRIO registers
-	*/
-#ifdef FUTURE
-	/* Data Streaming Information Capability Register */
-	/* max_pdu_len is a 16-bit field in HW, thus 0 indicates 64KB */
-	reg_val = 0;
-	reg_val |= ((seg_support << 16) & 0xFFFF0000);
-	if (max_pdu_length == (1<<16))
-		max_pdu_len = 0;
-	else
-		max_pdu_len =  max_pdu_length;
-
-	reg_val |= (max_pdu_len & 0xFFFF);
-	__rio_local_write_config_32(mport, GRIO_DSI_CAR, reg_val);
-
 	/*
 	** Data Streaming Logical Layer Control Command and Status Register
 	**	MTU bits [31:24] 8 - 32 bytes, 9 - 36 bytes etc.
 	*/
 	reg_val = 0;
 	mtu_value = mtu / 4;
-	reg_val |= ((mtu_value << 24) & 0xFF000000);
-	__rio_local_write_config_32(mport, GRIO_DSLL_CCSR, reg_val);
+	reg_val |= (mtu_value  & 0xFF);
 
-#endif /* FUTURE */
+	__rio_local_write_config_32(mport, GRIO_DSLL_CCSR, reg_val);
 
 	/* IBDS alias mapping register */
 	reg_val = 0;
-	reg_val |= (ibds_avsid_mapping & 0xFFFFFFF);
+	reg_val |= (ibds_avsid_mapping & 0xFFFFF);
 	__rio_local_write_config_32(mport, RAB_IBDS_VSID_ALIAS, reg_val);
 
 	/* save information in the system */
-	ptr_ds_priv->max_pdu_len = max_pdu_len;
-	ptr_ds_priv->seg_support = seg_support;
 	ptr_ds_priv->mtu = mtu;
 	ptr_ds_priv->ibds_avsid_mapping = ibds_avsid_mapping;
 
@@ -239,27 +213,34 @@ EXPORT_SYMBOL(axxia_data_stream_global_cfg);
 /*****************************************************************************
  * axxia_open_ob_data_stream -
  *
- *  This function sets up the descriptor chain to an available OBDS engine.
- *  It programs each header and data descriptors associated with the stream.
+ *  This function sets up a descriptor chain to an outbound data streaming
+ *  engine (DSE).
  *
- * @mport:	pointer to the master port
- * @destId:	destination ID of the data stream
- * @streamId:   traffic stream ID
- * @cos:	class of service of the stream
- * @numPDUs:	number of PDUs in the stream
- * @pduLen:	PDU length in bytes of the segmented PDU
- * @isEnableEngine: if to enable the DS engine after setting up the chain
+ *	There are two types of descriptor usage:
+ *	1. Single header descriptors. Each descriptor points to a data buffer
+ *	   that is a full PDU length.
+ *	2. Header and data descriptor combination. Each header descriptor
+ *	   points to a data descriptor, each data descriptor points to a
+ *	   4KB data buffer.
+ *
+ *  Under current implementation, only single descriptor is supported.
+ *
+ * @mport:		Pointer to the master port
+ * @dev_id:		Device specific pointer to pass on event
+ * @dse_id:		DSE ID in the range of [0, 15]
+ * @num_header_entries:	Number of header descriptors in the descriptor chain
+ * @num_data_entries:	Number of data descriptors in the descriptor chain
  *
  * Returns %0 on success
  ****************************************************************************/
 int axxia_open_ob_data_stream(
-	struct rio_mport    *mport,
-	void		*dev_id,
+	struct rio_mport	*mport,
+	void			*dev_id,
 	int			dse_id,
 	int			num_header_entries,
 	int			num_data_entries)
 {
-	int		 rc = 0;
+	int	rc = 0;
 
 	axxia_api_lock();
 
@@ -278,21 +259,14 @@ EXPORT_SYMBOL(axxia_open_ob_data_stream);
 /*****************************************************************************
  * open_ob_data_stream -
  *
- *  This function sets up the descriptor chain to an available OBDS engine.
- *  It programs each header and data descriptors associated with the stream.
- *
- * @mport:	pointer to the master port
- * @dev_id:	device specific pointer to pass on event
- * @dest_id:	destination ID of the data stream
- * @stream_id:  traffic stream ID
- * @cos:	class of service of the stream
- * @num_pdus:   number of PDUs in the stream
- * @pdu_length: PDU length in bytes of the segmented PDU
+ *  This function sets up a descriptor chain to an outbound data streaming
+ *  engine (DSE). It is called by axxia_open_ob_data_stream( ).
  *
- *  To keep the correct order of the stream, it is recommended that same
- *  stream_id goes to the same DSE descriptor chain.  However, different
- *  stream_ids can go to the same descriptor chain.  To make it simple,
- *  we make stream_id goes to the (stream_id % 16) descriptor chain.
+ * @mport:		Pointer to the master port
+ * @dev_id:		Device specific pointer to pass on event
+ * @dse_id:		DSE ID in the range of [0, 15]
+ * @num_header_entries:	Number of header descriptors in the descriptor chain
+ * @num_data_entries:	Number of data descriptors in the descriptor chain
  *
  * Returns %0 on success
  ****************************************************************************/
@@ -413,9 +387,14 @@ int open_ob_data_stream(
 	if (rc == 0) {
 		ptr_dse_cfg->max_num_hdr_desc = num_header_entries;
 		ptr_dse_cfg->num_hdr_desc_free = num_header_entries;
+		ptr_dse_cfg->hdr_read_ptr = 0;
+		ptr_dse_cfg->hdr_write_ptr = 0;
 
 		ptr_dse_cfg->max_num_data_desc = num_data_entries;
 		ptr_dse_cfg->num_data_desc_free = num_data_entries;
+		ptr_dse_cfg->data_read_ptr = 0;
+		ptr_dse_cfg->data_write_ptr = 0;
+
 	}
 
 	return rc;
@@ -424,14 +403,28 @@ int open_ob_data_stream(
 /*****************************************************************************
  * axxia_add_ob_data_stream -
  *
- *  This function copies data to an OBDS data buffer.
+ *  This function adds a descriptor and a data buffer to a descriptor chain.
+ *
+ *	To keep the correct order of a data stream, data descripors of the same
+ *	stream ID goes to the same DSE descriptor chain. However, each DSE can
+ *	handle multiple data streams. To make it simple, a data stream with
+ *	stream ID goes to (stream ID % (totoal number of DSEs)) descriptor
+ *	chain.
+ *
+ *	Under the current implementation, only header descriptor is supported.
+ *
+ *	The buffer will be freed when the associated descriptor is processed
+ *	in the ob_dse_irq_handler( ) routine.
  *
- * @mport:	  pointer to the master port
- * @dest_id:	 destination ID of the data stream
- * @stream_id:       traffic stream ID
- * @cos:	    class of service of the stream
- * @buffer:	 pointer to where the data is stored
- * @dataLength:     data length in bytes to be copied
+ * @mport:		Pointer to the master port
+ * @dest_id:		Destination ID of the data stream
+ * @stream_id:		Data stream ID
+ * @cos:		Class of service of the stream
+ * @priority:		Priority of the data stream
+ * @is_hdr_desc:	Indicate if the descriptor a header descriptor
+ *			or data descriptor
+ * @buffer:		Pointer to where the data is stored
+ * @data_len:		Data buffer length associated with the descriptor
  *
  * Returns %0 on success
  ****************************************************************************/
@@ -475,7 +468,6 @@ int axxia_add_ob_data_stream(
 
 	/* check if there is a space for the new data */
 	if (is_hdr_desc) {
-
 		if (ptr_dse_cfg->num_hdr_desc_free == 0)
 			return -ENOMEM;
 
@@ -534,8 +526,10 @@ int axxia_add_ob_data_stream(
 		if (ptr_dse_cfg->hdr_write_ptr ==
 			(ptr_dse_cfg->max_num_hdr_desc - 1)) {
 			next_desc_index = 0;
+			ptr_dse_cfg->hdr_write_ptr = 0;
 		} else {
 			next_desc_index = ptr_dse_cfg->hdr_write_ptr + 1;
+			ptr_dse_cfg->hdr_write_ptr++;
 		}
 
 		next_desc_ptr_phy = virt_to_phys((void *)
@@ -571,7 +565,7 @@ int axxia_add_ob_data_stream(
 
 		ptr_hdr_desc->virt_data_buf = (u32)buffer;
 
-		ptr_dse_cfg->hdr_write_ptr++;
+		ptr_hdr_desc->buf_status = DS_DBUF_ALLOC;
 
 		ptr_dse_cfg->num_hdr_desc_free--;
 
@@ -580,15 +574,6 @@ int axxia_add_ob_data_stream(
 		return -EINVAL;
 	}
 
-#ifdef DS_DEBUG
-	printk(KERN_INFO "OBDS HEADER DESC [%08x %08x %08x %08x %08x]\n",
-		ptr_hdr_desc->dw0,
-		ptr_hdr_desc->dw1,
-		ptr_hdr_desc->dw2,
-		ptr_hdr_desc->dw3,
-		ptr_hdr_desc->dw4);
-#endif
-
 	/* check if the DSE is in sleep mode, if it is, wake up */
 	/* find out DSE stats */
 	__rio_local_read_config_32(mport, RAB_OBDSE_STAT(dse_id), &dse_stat);
@@ -641,18 +626,36 @@ void ob_dse_irq_handler(struct rio_irq_handler *h, u32 state)
 	struct rio_ds_hdr_desc  *ptr_hdr_desc = h->data;
 	u32 dse_stat, dse_id;
 	u16 hdr_read_ptr;
+	u32	is_hdr_desc_done = 1;
 	unsigned long flags;
+	u8	i;
+
+	u32 num_desc_processed = 0;
 
 	/* find the DSE that gets interrupted, CNTLZW found the upper
 	** bit first */
-	dse_id = 31 - CNTLZW(state);
+	for (i = 0; i < 32; i++) {
+		/* if the corresponding interrupt bit is set */
+		if ((state >> i) & 0x1)
+			break;
+	}
+
+	if (i == 32)
+		return;
+
+	dse_id = i;
 
 	/* find out DSE stats */
 	__rio_local_read_config_32(mport, RAB_OBDSE_STAT(dse_id), &dse_stat);
 
-#ifdef DS_DEBUG
-	printk(KERN_INFO "dse_id = %d, dse_stat = 0x%x\n", dse_id, dse_stat);
-#endif
+
+	/*
+	** The ARM could also got interrupted with dse_stat sticky status
+	**	bits not being set. TBD
+	*/
+	if (!(dse_stat & 0x3F))
+		return;
+
 	ptr_ds_priv = &(priv->ds_priv_data);
 
 	/**
@@ -662,8 +665,6 @@ void ob_dse_irq_handler(struct rio_irq_handler *h, u32 state)
 	ptr_dse_cfg = &(ptr_ds_priv->obds_dse_cfg[dse_id]);
 	spin_lock_irqsave(&ptr_dse_cfg->lock, flags);
 
-	/* disable interrupt NING - TBD */
-
 	/*
 	** It is possible that one DSE handles multiple data streams,
 	** thus the error condition does not reflect a specific descriptor
@@ -673,66 +674,54 @@ void ob_dse_irq_handler(struct rio_irq_handler *h, u32 state)
 	/* check DSE registers for error reports */
 	__ob_dse_dbg(&(ptr_ds_priv->ob_dse_stats[dse_id]), dse_stat);
 
+
 	/* process all completed transactions - bit 1 - descriptor transaction
 	** completed */
-	if (dse_stat & 0x2) {
-		if (ptr_dse_cfg->hdr_read_ptr == ptr_dse_cfg->hdr_write_ptr) {
-			spin_unlock_irqrestore(&ptr_dse_cfg->lock, flags);
-			return;
-		}
+	hdr_read_ptr = ptr_dse_cfg->hdr_read_ptr;
 
-		while (ptr_dse_cfg->hdr_read_ptr !=
-			ptr_dse_cfg->hdr_write_ptr) {
+	ptr_hdr_desc =
+		&(ptr_dse_cfg->ptr_obds_hdr_desc[hdr_read_ptr]);
 
-			hdr_read_ptr = ptr_dse_cfg->hdr_write_ptr;
-			ptr_hdr_desc =
-			&(ptr_dse_cfg->ptr_obds_hdr_desc[hdr_read_ptr]);
+	if (dse_stat & 0x2) {
 
+		is_hdr_desc_done = (ptr_hdr_desc->dw0 & OB_HDR_DESC_DONE);
+
+		while (is_hdr_desc_done) {
+			num_desc_processed++;
 			__ob_dse_dw_dbg(&(ptr_ds_priv->ob_dse_stats[dse_id]),
 				ptr_hdr_desc->dw0);
 
-			/*
-			** check if the descriptor is done - bit 8
-			**
-			**  Since the IRQ process the descriptor one-by-one,
-			**  if the descriptor pointed by tail is not processed,
-			**  the following ones are not processed either.
-			**
-			**	Only header descriptors are supported now.
-			**	The combination of header descriptor and data
-			**		descriptor are TBD.
-			*/
-			if ((ptr_hdr_desc->dw0 & OB_HDR_DESC_DONE) == 0)
-				break;
-
-			/* set the valid bit to be zero */
-			ptr_hdr_desc->dw0 &= 0xFFFFFFFE;
-
 			/* free the buffer */
 			kfree((void *)ptr_hdr_desc->virt_data_buf);
+			ptr_hdr_desc->buf_status = DS_DBUF_FREED;
 
-			ptr_dse_cfg->data_read_ptr++;
-
-			if (ptr_dse_cfg->data_read_ptr ==
+			if (ptr_dse_cfg->hdr_read_ptr ==
 				(ptr_dse_cfg->max_num_hdr_desc - 1)) {
-				ptr_dse_cfg->data_read_ptr = 0;
+				ptr_dse_cfg->hdr_read_ptr = 0;
+			} else {
+				ptr_dse_cfg->hdr_read_ptr++;
 			}
+			/* free the buffer */
+			ptr_dse_cfg->num_hdr_desc_free++;
 
-			/* the descriptor has been processed, but there is
-			** error occurred */
-			if ((ptr_hdr_desc->dw0 & OB_HDR_DESC_AXI_ERR)) {
-				__ob_dse_dw_dbg(
-					&(ptr_ds_priv->ob_dse_stats[dse_id]),
-					ptr_hdr_desc->dw0);
-				/* callback function - TBD */
-			}
+			/* set the valid bit, done bit to be zero */
+			ptr_hdr_desc->dw0 &= 0xFFFFFFFE;
 
-			ptr_dse_cfg->num_hdr_desc_free++;
+			hdr_read_ptr = ptr_dse_cfg->hdr_read_ptr;
+
+			ptr_hdr_desc =
+				&(ptr_dse_cfg->ptr_obds_hdr_desc[hdr_read_ptr]);
+
+			is_hdr_desc_done =
+				(ptr_hdr_desc->dw0 & OB_HDR_DESC_DONE);
 		}
+	} else {
+		/* TBD when HW gets AXI error, it will stop and not go further*/
 	}
-
-	/* clear the interrupt bit - NING-TBD */
-	__rio_local_write_config_32(mport, RAB_OBDSE_STAT(dse_id), 0xFFFF);
+	/* clear the interrupt bit */
+	__rio_local_write_config_32(mport,
+					RAB_OBDSE_STAT(dse_id),
+					(dse_stat & 0x3F));
 
 	spin_unlock_irqrestore(&ptr_dse_cfg->lock, flags);
 	return;
@@ -741,12 +730,10 @@ void ob_dse_irq_handler(struct rio_irq_handler *h, u32 state)
 /*****************************************************************************
  * axxia_close_ob_data_stream -
  *
- *  This function resets variables associated with a OBDS.
+ *  This function closes an outbound data streaming associated with the DSE.
  *
- * @mport:	 pointer to the master port
- * @destId:	 destination ID of the data stream
- * @streamId:    traffic stream ID
- * @cos:	 class of service of the stream
+ * @mport:	 Pointer to the master port
+ * @dse_id:	 DSE ID
  *
  * Returns %0 on success
  ****************************************************************************/
@@ -757,7 +744,8 @@ int axxia_close_ob_data_stream(
 	struct rio_priv *priv = mport->priv;
 	struct rio_ds_priv      *ptr_ds_priv = &(priv->ds_priv_data);
 	struct rio_obds_dse_cfg *ptr_dse_cfg;
-	u32    dse_ctrl;
+	struct rio_ds_hdr_desc  *ptr_hdr_desc;
+	u32    dse_ctrl, i;
 
 	axxia_api_lock();
 
@@ -777,6 +765,17 @@ int axxia_close_ob_data_stream(
 	ptr_dse_cfg->num_hdr_desc_free = 0;
 	ptr_dse_cfg->num_data_desc_free = 0;
 
+	/* clear OBDS data buffers */
+	for (i = 0; i < (ptr_dse_cfg->max_num_data_desc); i++) {
+		ptr_hdr_desc = ptr_dse_cfg->ptr_obds_hdr_desc;
+
+		/* if an application has not yet retrieve the data */
+		if (((ptr_hdr_desc->buf_status == DS_DBUF_ALLOC)) &&
+			(ptr_hdr_desc->virt_data_buf)) {
+			kfree((void *)ptr_hdr_desc->virt_data_buf);
+		}
+	}
+
 	/* free header and data descriptor */
 	if (ptr_dse_cfg->ptr_obds_hdr_desc != NULL)
 		kfree(ptr_dse_cfg->ptr_obds_hdr_desc);
@@ -801,21 +800,25 @@ EXPORT_SYMBOL(axxia_close_ob_data_stream);
 /*****************************************************************************
  * axxia_open_ib_data_stream -
  *
- *  This function sets up the descriptor chain to an internal VSID M.
- *  The internal VSID is calculated through sourceId, cos and
- *  RAB_IBDS_VSID_ALIAS register.
+ *  This function sets up a descriptor chain to an internal alias VSID (AVSID).
+ *  The internal VSID is calculated through source_id, class of service (cos)
+ *  and the RAB_IBDS_VSID_ALIAS register.
  *
- * @mport:	pointer to the master port
- * @sourceId:   source ID of the data stream
- * @cos:	class of service of the stream
- * @numPDUs:	number of PDUs in the stream
- * @desc_dbuf_size:   PDU size this descriptor can handle.
- *		If the PDU size exceeds
- *		descriptor size (but less than maximum PDU size), appropriate
- *		error bit is set and interrupt is generated if enabled.
- *		PDU data beyond descriptor size is not written in the AXI
- *		memory to ensure that there is no corruption of data under
- *		this error case.
+ *	Please refer to the data sheet of RAB_IBDS_VSID_ALIAS register for
+ *	detail mapping information.
+ *
+ *	In the IBDS, there are only 7 buffer sizes
+ *	(1KB, 2KB, 4KB, 8KB, 16KB, 32KB, 64KB) can be programmed in the
+ *	hardware.
+ *	If the incoming PDU length is larger than the programmed buffer size,
+ *	data error will occur. Thus, an application must program desc_dbuf_size
+ *	larger than or equal to the expected PDU.
+ *
+ * @mport:			Pointer to the master port
+ * @source_id:		Source ID of the data stream
+ * @cos:			Class of service of the stream
+ * @desc_dbuf_size: Data buffer size the descriptor can handle
+ * @num_entries:	Number of descriptors in this descriptor chain
  *
  * Returns %0 on success
  ****************************************************************************/
@@ -846,22 +849,14 @@ EXPORT_SYMBOL(axxia_open_ib_data_stream);
 /*****************************************************************************
  * open_ib_data_stream -
  *
- *  This function sets up the descriptor chain to an internal VSID M.
- *  The internal VSID is calculated through sourceId, cos and
- *  RAB_IBDS_VSID_ALIAS register.
+ *  This function sets up a descriptor chain to an internal alias VSID (AVSID).
+ *  It is called by axxia_open_ib_data_stream( ).
  *
- * @mport:	pointer to the master port
- * @dev_id: Device specific pointer to pass on event
- * @source_id:   source ID of the data stream
- * @cos:	class of service of the stream
- * @desc_dbuf_size:   PDU size this descriptor can handle.
- *		If the PDU size exceeds
- *		descriptor size (but less than maximum PDU size), appropriate
- *		error bit is set and interrupt is generated if enabled.
- *		PDU data beyond descriptor size is not written in the AXI
- *		memory to ensure that there is no corruption of data under
- *		this error case.
- * @num_entries: number of entries in this descriptor chain
+ * @mport:		Pointer to the master port
+ * @source_id:		Source ID of the data stream
+ * @cos:		Class of service of the stream
+ * @desc_dbuf_size: Data buffer size the descriptor can handle
+ * @num_entries:	Number of descriptors in this descriptor chain
  *
  * Returns %0 on success
  ****************************************************************************/
@@ -879,15 +874,15 @@ int open_ib_data_stream(
 	struct rio_ids_data_desc *ptr_data_desc;
 	struct rio_irq_handler *h;
 	void	*ptr;
-	u32		temp;
+	u32	temp;
 	u32     alias_reg;
 	u32     vsid, i, next_desc_offset;
 	u16     virt_vsid;
-	u8		hw_desc_size;
-	unsigned long		desc_chain_start_addr_phy, next_desc_addr_phy;
+	u8	hw_desc_size;
+	unsigned long     desc_chain_start_addr_phy, next_desc_addr_phy;
 
 	u32     next_desc_addr_hi, vsid_addr_reg;
-
+	u32	num_int_entries;
 	int rc = 0;
 
 	/*
@@ -940,7 +935,7 @@ int open_ib_data_stream(
 	(void)axxio_virt_vsid_convert(vsid, alias_reg, &virt_vsid);
 
 	if (virt_vsid >= RIO_MAX_NUM_IBDS_VSID_M)
-		return RC_TBD;
+		return -EINVAL;
 
 	/*
 	** In the IBDS, the descriptor size allocated must be greater than
@@ -950,16 +945,26 @@ int open_ib_data_stream(
 	/* get a internal VSID M based on virt_vsid */
 	ptr_virt_m_cfg = &(ptr_ds_priv->ibds_vsid_m_cfg[virt_vsid]);
 
+	/*
+	** If the descriptor chain is already opened, return OK
+	*/
 	if (ptr_virt_m_cfg->in_use == RIO_DS_TRUE)
-		return -EINVAL;
+		return 0;
 
 	ptr_virt_m_cfg->alias_reg_value = alias_reg;
 
+	/*
+	** If the end of chain bit is not set, it is required that there is
+	**	one invalid entry left in the system.
+	*/
+	num_int_entries = num_entries + 1;
+
 	/* allocate data descriptor buffers */
-	ptr = kzalloc(num_entries * sizeof(struct rio_ids_data_desc) +
-					sizeof(struct rio_ids_data_desc) +
-					RIO_DS_DESC_ALIGNMENT,
-					GFP_KERNEL);
+	ptr = kzalloc((num_int_entries) *
+			sizeof(struct rio_ids_data_desc) +
+			sizeof(struct rio_ids_data_desc) +
+			RIO_DS_DESC_ALIGNMENT,
+			GFP_KERNEL);
 	if (ptr == NULL) {
 		return -ENOMEM;
 	} else {
@@ -979,10 +984,8 @@ int open_ib_data_stream(
 
 	ptr_virt_m_cfg->in_use = RIO_DS_TRUE;
 
-	ptr_virt_m_cfg->num_desc_free = num_entries;
-
 	/* chain the data descriptors */
-	for (i = 0; i < num_entries; i++) {
+	for (i = 0; i < num_int_entries; i++) {
 		ptr_data_desc = &(ptr_virt_m_cfg->ptr_ibds_data_desc[i]);
 
 		/* init the data descriptor */
@@ -1019,7 +1022,7 @@ int open_ib_data_stream(
 		**ptr_data_desc->dw0 |= 4;
 		*/
 
-		if (i == (num_entries-1))
+		if (i == (num_int_entries-1))
 			next_desc_offset = 0;
 		else
 			next_desc_offset = i + 1;
@@ -1075,19 +1078,34 @@ int open_ib_data_stream(
 
 	rc = alloc_irq_handler(h, (void *)ptr_virt_m_cfg, ptr_virt_m_cfg->name);
 
+	if (rc == 0) {
+		ptr_virt_m_cfg->data_read_ptr = 0;
+		ptr_virt_m_cfg->data_write_ptr = 0;
+		ptr_virt_m_cfg->buf_add_ptr = 0;
+
+		ptr_virt_m_cfg->num_desc_free = num_int_entries;
+
+		ptr_virt_m_cfg->max_num_data_desc = num_int_entries;
+
+	}
+
 	return rc;
 }
 
 /*****************************************************************************
  * axxia_add_ibds_buffer -
  *
- *  This function adds buffer to the AXXIA inbound data stream queue.
+ *  This function adds a data buffer to a descriptor chain determined by
+ *  source ID, class of service and RAB_IBDS_VSID_ALIAS register.
+ *  When the hardware receives a PDU, it writes into the data buffer.
+ *  Since we don't know the incoming PDU length, the buf_size must be
+ *  large enough.
  *
- * @mport:	pointer to the master port
- * @source_id:	source ID of the data stream
- * @cos:	class of service of the stream
- * @buf:	pointer to where the data is copied to
- * @buf_size: buffer size of the added buffer
+ * @mport:	Pointer to the master port
+ * @source_id:	Source ID of the data stream
+ * @cos:	Class of service of the stream
+ * @buf:	Pointer to where the data is stored
+ * @buf_size:	Size of the buffer
  *
  * Returns %0 on success
  ****************************************************************************/
@@ -1096,19 +1114,21 @@ int axxia_add_ibds_buffer(
 	int		   source_id,
 	int		   cos,
 	void		  *buf,
-	int			buf_size)
+	int		   buf_size)
 {
 	struct rio_priv *priv = mport->priv;
 	struct rio_ds_priv      *ptr_ds_priv = &(priv->ds_priv_data);
 	struct ibds_virt_m_cfg  *ptr_virt_m_cfg;
 	struct rio_ids_data_desc *ptr_data_desc;
-	u32				m_id;
-	u8				found_one = RIO_DS_FALSE;
-	u32				vsid_addr_reg;
+	u32			m_id;
+	u8			found_one = RIO_DS_FALSE;
+	u32			vsid_addr_reg;
 
 	unsigned long   data_addr_phy;
 	u32 data_addr_hi;
 
+	unsigned long iflags;
+
 	if (buf == NULL)
 		return -EINVAL;
 
@@ -1129,15 +1149,6 @@ int axxia_add_ibds_buffer(
 		return RC_TBD;
 
 
-	/* check if the buf_size is smaller than the desc_dbuf_size */
-	if (buf_size > ptr_virt_m_cfg->desc_dbuf_size)
-		return -EINVAL;
-
-#ifdef DS_DEBUG
-	printk(KERN_INFO "num_desc_free = %d\n",
-		ptr_virt_m_cfg->num_desc_free);
-#endif
-
 	/*
 	** check if there are descriptors left
 	**
@@ -1152,6 +1163,8 @@ int axxia_add_ibds_buffer(
 	if (ptr_virt_m_cfg->num_desc_free == 1)
 		return -ENOMEM;
 
+	spin_lock_irqsave(&ptr_virt_m_cfg->lock, iflags);
+
 	/* put user's buffer into the corresponding descriptors */
 	ptr_data_desc =
 	&(ptr_virt_m_cfg->ptr_ibds_data_desc[ptr_virt_m_cfg->buf_add_ptr]);
@@ -1176,14 +1189,8 @@ int axxia_add_ibds_buffer(
 	*/
 	ptr_data_desc->dw0 |= 0x1;
 
-#ifdef DS_DEBUG
-	printk(KERN_INFO "IBDS DESC [%08x %08x %08x %08x %08x]\n",
-		ptr_data_desc->dw0,
-		ptr_data_desc->dw1,
-		ptr_data_desc->dw2,
-		ptr_data_desc->dw3,
-		ptr_data_desc->dw4);
-#endif
+	ptr_data_desc->buf_status = DS_DBUF_ALLOC;
+
 	/*
 	** For the first descriptor, the VSID M Descriptor Chain Prefetch Enable
 	**needs to be set to 1. After that, only VSID M Descriptor Chain
@@ -1192,6 +1199,7 @@ int axxia_add_ibds_buffer(
 	__rio_local_read_config_32(mport,
 				RAB_IBDS_VSID_ADDR_HI(m_id),
 				&vsid_addr_reg);
+
 	/* if the prefetch enable is not set */
 	if (!(vsid_addr_reg & IB_VSID_M_PREFETCH_ENABLE))
 		vsid_addr_reg |= IB_VSID_M_PREFETCH_ENABLE;
@@ -1203,13 +1211,16 @@ int axxia_add_ibds_buffer(
 				vsid_addr_reg);
 
 	/* the buf_add_ptr is determined by number of free descriptors */
-	ptr_virt_m_cfg->buf_add_ptr++;
+	if (ptr_virt_m_cfg->buf_add_ptr ==
+		(ptr_virt_m_cfg->max_num_data_desc - 1)) {
+		ptr_virt_m_cfg->buf_add_ptr = 0;
+	} else {
+		ptr_virt_m_cfg->buf_add_ptr++;
+	}
 
 	ptr_virt_m_cfg->num_desc_free--;
 
-#ifdef DS_DEBUG
-	printk(KERN_INFO "buf_add_ptr = %d\n", ptr_virt_m_cfg->buf_add_ptr);
-#endif
+	spin_unlock_irqrestore(&ptr_virt_m_cfg->lock, iflags);
 
 	return 0;
 }
@@ -1220,8 +1231,8 @@ EXPORT_SYMBOL(axxia_add_ibds_buffer);
  * --- Called in threaded irq handler ---
  * @h: Pointer to interrupt-specific data
  *
- * Handles outbound data streaming interrupts.  Executes a callback,
- * if available, on each successfully sent data stream
+ * Handles inbound data streaming interrupts.  Executes a callback,
+ * if available, on each successfully received data stream
  *
 */
 void ib_dse_vsid_m_irq_handler(struct rio_irq_handler *h, u32 state)
@@ -1236,20 +1247,30 @@ void ib_dse_vsid_m_irq_handler(struct rio_irq_handler *h, u32 state)
 	u16 data_write_ptr;
 	u8  found_dse = RIO_DS_FALSE;
 	unsigned long flags;
+	u32	is_desc_done = 1;
+	u8	i;
+
+	for (i = 0; i < 32; i++) {
+		/* if the corresponding interrupt bit is set */
+		if ((state >> i) & 0x1)
+			break;
+	}
 
-	virt_vsid = 31 - CNTLZW(state);
+	if (i == 32)
+		return;
 
-#ifdef DS_DEBUG
-	printk(KERN_INFO "IBDS: interrupt virt_vsid = %d\n", virt_vsid);
-#endif
+	virt_vsid = i;
 
 	__rio_local_read_config_32(mport,
 				RAB_IBVIRT_M_STAT(virt_vsid),
 				&vsid_m_stats);
 
-#ifdef DS_DEBUG
-	printk(KERN_INFO "vsid_m_stats = 0x%x\n", vsid_m_stats);
-#endif
+	/*
+	** The ARM could also got interrupted with vsid_m_stats sticky status
+	**	bits not being set. TBD
+	*/
+	if (!(vsid_m_stats & 0x1FF))
+		return;
 
 	/* check if the chain transfer complete */
 	ptr_virt_m_cfg = &(ptr_ds_priv->ibds_vsid_m_cfg[virt_vsid]);
@@ -1327,34 +1348,32 @@ if (vsid_m_stats & IB_VIRT_M_STAT_FETCH_ERR) {
 	/* process maximum number of MAX_NUM_PROC_IBDS_DESC transactions */
 	data_write_ptr = ptr_virt_m_cfg->data_write_ptr;
 
-#ifdef DS_DEBUG
-	printk(KERN_PRINT "data_write_ptr = %d\n", data_write_ptr);
-#endif
+	ptr_data_desc =
+			&(ptr_virt_m_cfg->ptr_ibds_data_desc[data_write_ptr]);
+
+	/* get the done bit of the data descriptor */
+	is_desc_done = (ptr_data_desc->dw0 & IB_DSE_DESC_DONE);
 
-		/* check if the done bit is set */
-		ptr_data_desc =
-		&(ptr_virt_m_cfg->ptr_ibds_data_desc[data_write_ptr]);
+	while (is_desc_done) {
+		ptr_virt_m_cfg->num_hw_written_bufs++;
 
-		if ((ptr_data_desc->dw0 & IB_DSE_DESC_DONE) != 0) {
-			ptr_virt_m_cfg->num_hw_written_bufs++;
+		__ib_dse_dw_dbg(
+				&(ptr_ds_priv->ib_vsid_m_stats[virt_vsid]),
+				ptr_data_desc->dw0);
 
-#ifdef DS_DEBUG
-	printk(KERN_INFO "num_hw_written_bufs = %d\n",
-		ptr_virt_m_cfg->num_hw_written_bufs);
-#endif
+		if (data_write_ptr ==
+			(ptr_virt_m_cfg->max_num_data_desc-1))
+			data_write_ptr = 0;
+		else
+			data_write_ptr++;
 
-			if (data_write_ptr ==
-				(ptr_virt_m_cfg->max_num_data_desc-1))
-				data_write_ptr = 0;
-			else
-				data_write_ptr++;
+		/* set the valid bit to be invalid */
+		ptr_data_desc->dw0 &= 0xFFFFFFFE;
 
-			__ib_dse_dw_dbg(
-			&(ptr_ds_priv->ib_vsid_m_stats[virt_vsid]),
-			ptr_data_desc->dw0);
+		ptr_data_desc =
+			&(ptr_virt_m_cfg->ptr_ibds_data_desc[data_write_ptr]);
 
-			/* set the valid bit to be invalid */
-			ptr_data_desc->dw0 &= 0xFFFFFFFE;
+		is_desc_done = (ptr_data_desc->dw0 & IB_DSE_DESC_DONE);
 	}
 
 	ptr_virt_m_cfg->data_write_ptr = data_write_ptr;
@@ -1379,21 +1398,15 @@ if (vsid_m_stats & IB_VIRT_M_STAT_FETCH_ERR) {
 /*****************************************************************************
  * axxia_get_ibds_data -
  *
- *  This function gets IBDS data from data buffer. The ioctl() can only
- *  transfer up to 4KB each time, thus, if a PDU length is larger than
- *  4KB, an application must call this API multiple times.
+ *  This function gets an IBDS data from a descriptor chain. This function
+ *  also returns the PDU length and stream ID associated with data.
+ *  If there is no data available, a NULL pointer is returned.
  *
- *  The maximum PDU length data is copied to the pre-allocated 64K buffer
- *  in init time.
- *
- * @mport:	pointer to the master port
- * @sourceId:	source ID of the data stream
- * @cos:	class of service of the stream
- * @buffer:	pointer to where the data is copied to
- * @streamId:	pointer to where the streamID is saved
- * @pPduLength:	PDU length of the data stream
- * @pDataLenth:	data length in this transfer
- * @pRemainingDataSize: remaining data in bytes to be expected
+ * @mport:		Pointer to the master port
+ * @source_id:		Source ID of the data stream
+ * @cos:		Class of service of the stream
+ * @ptr_pdu_length:	Pointer to where the PDU length is stored
+ * @ptr_stream_id:	Pointer to where the stream ID is stored
  *
  * Returns %0 on success
  ****************************************************************************/
@@ -1412,6 +1425,7 @@ void *axxia_get_ibds_data(
 	u8		    found_one = RIO_DS_FALSE;
 	void		    *user_buf;
 	u32		pdu_length;
+	unsigned long iflags;
 
 	/* search through the virtual M table to find the one that
 	** has the same source_id and cos */
@@ -1433,13 +1447,10 @@ void *axxia_get_ibds_data(
 	if (ptr_virt_m_cfg->num_hw_written_bufs < 1)
 		return NULL;
 
-	data_read_ptr = ptr_virt_m_cfg->data_read_ptr;
 
-#ifdef DS_DEBUG
-	printk(KERN_INFO "num_hw_written_bufs = %d\n",
-		ptr_virt_m_cfg->num_hw_written_bufs);
-	printk(KERN_INFO "data_read_ptr = %d\n", data_read_ptr);
-#endif
+	spin_lock_irqsave(&ptr_virt_m_cfg->lock, iflags);
+
+	data_read_ptr = ptr_virt_m_cfg->data_read_ptr;
 
 	/* get the data descriptor */
 	ptr_data_desc =
@@ -1448,31 +1459,25 @@ void *axxia_get_ibds_data(
 	/* check if the source_id and cos matches */
 	if ((((ptr_data_desc->dw0 >> 16) & 0xFFFF) != source_id) ||
 		((ptr_data_desc->dw2 & 0xFF0000) >> 16) != cos) {
+		spin_unlock_irqrestore(&ptr_virt_m_cfg->lock, iflags);
 		return NULL;
 	}
 
-#ifdef DS_DEBUG
-	printk(KERN_INFO "data desc: [%08x %08x %08x %08x %08x]\n",
-			ptr_data_desc->dw0,
-			ptr_data_desc->dw1,
-			ptr_data_desc->dw2,
-			ptr_data_desc->dw3,
-			ptr_data_desc->dw4);
-#endif
-
 	user_buf = (void *)ptr_data_desc->virt_data_buf;
 
 	if (user_buf == NULL) {
 		*ptr_pdu_length = 0;
+		spin_unlock_irqrestore(&ptr_virt_m_cfg->lock, iflags);
 		return NULL;
 	} else {
 		pdu_length = ((ptr_data_desc->dw1 & 0xFFFF0000) >> 16);
+
 		/* the pdu_length 0 in the HW indicates 64KB */
 		if (pdu_length == 0)
 			*ptr_pdu_length = 65536;
 		else
 			*ptr_pdu_length = pdu_length;
-		*ptr_stream_id = (ptr_data_desc->dw1) & 0xFFFF;
+		*ptr_stream_id = (ptr_data_desc->dw2) & 0xFFFF;
 
 		if (ptr_virt_m_cfg->data_read_ptr ==
 			(ptr_virt_m_cfg->max_num_data_desc - 1)) {
@@ -1484,6 +1489,10 @@ void *axxia_get_ibds_data(
 		ptr_virt_m_cfg->num_hw_written_bufs--;
 		ptr_virt_m_cfg->num_desc_free++;
 
+		ptr_data_desc->buf_status = DS_DBUF_FREED;
+
+		spin_unlock_irqrestore(&ptr_virt_m_cfg->lock, iflags);
+
 		return user_buf;
 	}
 }
@@ -1492,11 +1501,11 @@ EXPORT_SYMBOL(axxia_get_ibds_data);
 /*****************************************************************************
  * axxia_close_ib_data_stream -
  *
- *  This function resets variables associated with a IBDS data stream.
+ *  This function closes an inbound data streaming.
  *
- * @mport:	  pointer to the master port
- * @sourceId:     source ID of the data stream
- * @cos:	  class of service of the stream
+ * @mport:		Pointer to the master port
+ * @source_id:		Source ID of the data stream
+ * @cos:		Class of service of the stream
  *
  * Returns %0 on success
  ****************************************************************************/
@@ -1510,6 +1519,7 @@ int axxia_close_ib_data_stream(
 	struct ibds_virt_m_cfg  *ptr_virt_m_cfg;
 	u8		      find_ava_virt_m = RIO_DS_FALSE;
 	u8      i;
+	struct rio_ids_data_desc *ptr_data_desc;
 	u8	virt_vsid;
 
 	axxia_api_lock();
@@ -1539,18 +1549,24 @@ int axxia_close_ib_data_stream(
 	ptr_virt_m_cfg->buf_add_ptr = 0;
 	ptr_virt_m_cfg->num_hw_written_bufs = 0;
 
+	/* release IRQ handler */
+	release_irq_handler(&(ptr_ds_priv->ib_dse_vsid_irq[virt_vsid]));
+
+	/* clear all the descriptors */
+	for (i = 0; i < ptr_virt_m_cfg->max_num_data_desc; i++) {
+		ptr_data_desc = &(ptr_virt_m_cfg->ptr_ibds_data_desc[i]);
+
+		/* if an application has not yet retrieve the data */
+		if (((ptr_data_desc->buf_status == DS_DBUF_ALLOC)) &&
+			(ptr_data_desc->virt_data_buf)) {
+			kfree((void *)ptr_data_desc->virt_data_buf);
+		}
+	}
+
 	/* free the data descriptor pointer */
 	if (ptr_virt_m_cfg->ptr_ibds_data_desc != NULL)
 		kfree(ptr_virt_m_cfg->ptr_ibds_data_desc);
 
-	/* disable the VSID M prefetch enable bit */
-	__rio_local_write_config_32(mport,
-				RAB_IBDS_VSID_ADDR_HI(virt_vsid),
-				0);
-
-	/* release IRQ handler */
-	release_irq_handler(&(ptr_ds_priv->ib_dse_vsid_irq[virt_vsid]));
-
 	axxia_api_unlock();
 
 	return 0;
@@ -1561,13 +1577,13 @@ EXPORT_SYMBOL(axxia_close_ib_data_stream);
  * axxio_virt_vsid_convert -
  *
  *  This function converts the VISD {16'bSourceID, 8'b cos} to the internal
- *      virtual VSID.  Please refer to Table 133 of rio_axi_datasheet.pdf
- *      for detail information.
+ *  virtual VSID.  Please refer to Table 133 of rio_axi_datasheet.pdf
+ *  for detail information.
  *
- * @vsid:	  incoming VSID
- * @alias_reg:    incoming VSID to internal VSID mapping configuration
+ * @vsid:		Incoming VSID
+ * @alias_reg:		RAB_IBDS_VSID_ALIAS register value
  *
- * @ptr_virt_vsid:pointer to where the internal VSID is stored
+ * @ptr_virt_vsid:	Pointer to where the alias VSID is stored
  *
  * Returns %0 on success
  ****************************************************************************/
@@ -1623,7 +1639,6 @@ int axxio_virt_vsid_convert(
  *
  *  This is currently a stub function to be called in axxia_rio_port_irq_init().
  *
- *
  * @h:
  *
  * Returns %0 on success
@@ -1638,7 +1653,6 @@ void release_ob_ds(struct rio_irq_handler *h)
  *
  *  This is currently a stub function to be called in axxia_rio_port_irq_init().
  *
- *
  * @h:
  *
  * Returns %0 on success
@@ -1649,17 +1663,6 @@ void release_ib_ds(struct rio_irq_handler *h)
 }
 
 /*****************************************************************************
- * release_ib_ds - TBD
- *
- *  This is currently a stub function to be called in axxia_rio_port_irq_init().
- *
- *
- * @h:
- *
- * Returns %0 on success
- ****************************************************************************/
-
-/*****************************************************************************
  * axxia_parse_dtb_ds -
  *
  *  Parse RapidIO platform entry for data streaming
@@ -1679,6 +1682,9 @@ int axxia_parse_dtb_ds(
 
 	memset(ptr_ds_dtb_info, 0, sizeof(struct rio_ds_dtb_info));
 
+	/* set the default of ds_enable to be 1 if it is on 55XX */
+	ptr_ds_dtb_info->ds_enabled = 1;
+
 	/* Check if data streaming is enabled */
 	if (!of_property_read_u32(dev->dev.of_node,
 				  "enable_ds",
@@ -1706,6 +1712,7 @@ int axxia_cfg_ds(
 	struct rio_ds_priv      *ptr_ds_priv = &(priv->ds_priv_data);
 	u8			dse_id;
 	u32			reg_val;
+	u8			ds_capable;
 
 	/*
 	** Check if the ASIC supports data streaming feature.
@@ -1713,14 +1720,25 @@ int axxia_cfg_ds(
 	*/
 	__rio_local_read_config_32(mport, RAB_VER, &reg_val);
 
+	if ((reg_val == AXXIA_SRIO_RAB_VER_VAL_55xx)	||
+		(reg_val == AXXIA_SRIO_RAB_VER_VAL_55xx_X7v1P1)) {
+		ds_capable = 1;
+	} else {
+		ds_capable = 0;
+		return -EINVAL;
+	}
+
+	if ((ds_capable == 1) &&
+		(ptr_ds_dtb_info->ds_enabled == 1)) {
+		ptr_ds_priv->is_use_ds_feature = 1;
+	} else {
+		ptr_ds_priv->is_use_ds_feature = 0;
+	}
+
 	ptr_ds_priv->num_obds_dses = RIO_MAX_NUM_OBDS_DSE;
 	ptr_ds_priv->num_ibds_virtual_m = RIO_MAX_NUM_IBDS_VSID_M;
 	ptr_ds_priv->num_ibds_dses = RIO_MAX_NUM_IBDS_DSE;
 
-	/* Set some default values - Can be configured later through
-	**                           user's API */
-	ptr_ds_priv->max_pdu_len = RIO_DS_DATA_BUF_64K;
-
 	/* Enable all DSEs */
 	for (dse_id = 0; dse_id < ptr_ds_priv->num_ibds_dses; dse_id++) {
 		__rio_local_write_config_32(mport,
@@ -1769,8 +1787,8 @@ void axxia_rio_ds_port_irq_init(
 	}
 
 	/*
-	 ** Inbound Data Streaming
-	 */
+	** Inbound Data Streaming
+	*/
 	ptr_ds_priv = &(priv->ds_priv_data);
 
 	for (i = 0; i < RIO_MAX_NUM_IBDS_VSID_M; i++) {
@@ -1778,9 +1796,9 @@ void axxia_rio_ds_port_irq_init(
 				&(ptr_ds_priv->ib_dse_vsid_irq[i].state));
 		ptr_ds_priv->ib_dse_vsid_irq[i].mport = mport;
 		ptr_ds_priv->ib_dse_vsid_irq[i].irq_enab_reg_addr =
-		RAB_INTR_ENAB_IBDS;
+			RAB_INTR_ENAB_IBDS;
 		ptr_ds_priv->ib_dse_vsid_irq[i].irq_state_reg_addr =
-		RAB_INTR_STAT_IBSE_VSID_M;
+			RAB_INTR_STAT_IBSE_VSID_M;
 		ptr_ds_priv->ib_dse_vsid_irq[i].irq_state_mask = (1 << i);
 		ptr_ds_priv->ib_dse_vsid_irq[i].thrd_irq_fn =
 				ib_dse_vsid_m_irq_handler;
diff --git a/drivers/rapidio/devices/lsi/axxia-rio-ds.h b/drivers/rapidio/devices/lsi/axxia-rio-ds.h
old mode 100644
new mode 100755
index d52a8f1..5c0d263
--- a/drivers/rapidio/devices/lsi/axxia-rio-ds.h
+++ b/drivers/rapidio/devices/lsi/axxia-rio-ds.h
@@ -24,7 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/kfifo.h>
 
-#define DS_DEBUG 1
+/* #define DS_DEBUG 1  */
 #define USE_IOCTRL 1
 
 /******************************************************************************
@@ -41,17 +41,25 @@
 
 #define RIO_DS_DATA_BUF_64K                 (0) /* HW uses 0 for 64K */
 
-#define RIO_MAX_NUM_OBDS_DSE                16
-#define RIO_MAX_NUM_IBDS_DSE				16
-#define RIO_MAX_NUM_IBDS_VSID_M             32
+#define RIO_MAX_NUM_OBDS_DSE                (16)
+#define RIO_MAX_NUM_IBDS_DSE				(16)
+#define RIO_MAX_NUM_IBDS_VSID_M             (32)
 
 #define RC_TBD                              (-1)
 
-#define RIO_DS_TRUE                         1
-#define RIO_DS_FALSE                        0
+#define RIO_DS_TRUE                         (1)
+#define RIO_DS_FALSE                        (0)
+
+#define IOCTL_BUF_SIZE                      (4096)
+#define MAX_NUM_PROC_IBDS_DESC				(10)
+
+#define DS_DBUF_FREED					    (0)
+#define DS_DBUF_ALLOC						(1)
+#define DS_DBUF_RETRIEVED					(2)
+
+#define     AXXIA_SRIO_RAB_VER_VAL_55xx           (0x00211021)
+#define     AXXIA_SRIO_RAB_VER_VAL_55xx_X7v1P1    (0x00221013)
 
-#define IOCTL_BUF_SIZE                      4096
-#define MAX_NUM_PROC_IBDS_DESC				10
 
 /*
 ** Data Streaming registers
@@ -120,11 +128,13 @@
 /* data streaming dtb related information */
 struct rio_ds_dtb_info {
 	int ds_enabled;
+	#if 0
 	int num_inb_virtaul_m;      /* number of inbound virtual M */
 	int num_outb_dses;          /* number of outbound DSEs */
 	int inb_num_data_descs;     /* number of inbound data descriptors */
 	int outb_num_hdr_descs;     /* number of outbound header descriptors */
 	int outb_num_data_descs;    /* number of outbound data descriptors */
+	#endif
 };
 
 /*
@@ -157,7 +167,7 @@ struct rio_ids_data_desc {
 
 	/* SW usage */
 	u32 virt_data_buf;
-	u32 usr_virt_data_buf;
+	u32 buf_status;
 	u32 sw2;
 };
 
@@ -174,7 +184,7 @@ struct rio_ds_hdr_desc {
 
 	/* SW usage */
 	u32     virt_data_buf;
-	u32	sw1;
+	u32		buf_status;
 	u32	sw2;
 };
 
@@ -232,6 +242,7 @@ struct ibds_virt_m_cfg {
 	u32			num_hw_written_bufs;
 
 	u32			alias_reg_value;
+
 };
 
 /* Outbound data stream stats */
@@ -268,9 +279,7 @@ struct rio_ds_ibds_vsid_m_stats {
 */
 struct rio_ds_priv {
 	/* IBDS */
-	u16			max_pdu_len;
 	u16			mtu;
-	u16			seg_support;
 	u32			ibds_avsid_mapping;
 	u16                     num_ibds_dses;/* TBR */
 	u16                     num_ibds_virtual_m;/* TBR */
@@ -283,8 +292,11 @@ struct rio_ds_priv {
 	struct rio_irq_handler  ob_dse_irq[RIO_MAX_NUM_OBDS_DSE];
 	struct rio_irq_handler  ib_dse_vsid_irq[RIO_MAX_NUM_IBDS_VSID_M];
 
-	struct rio_ds_ibds_vsid_m_stats ib_vsid_m_stats[RIO_MAX_NUM_IBDS_VSID_M];
-	struct rio_ds_obds_dse_stats	ob_dse_stats[RIO_MAX_NUM_OBDS_DSE];
+	struct rio_ds_ibds_vsid_m_stats
+		ib_vsid_m_stats[RIO_MAX_NUM_IBDS_VSID_M];
+	struct rio_ds_obds_dse_stats        ob_dse_stats[RIO_MAX_NUM_OBDS_DSE];
+
+	u8		is_use_ds_feature;
 };
 
 /* Platform driver initialization */
@@ -334,8 +346,6 @@ void ib_dse_vsid_m_irq_handler(struct rio_irq_handler *h, u32 state);
 /* data streaming global configuration */
 extern int axxia_data_stream_global_cfg(
 	struct rio_mport       *mport,
-	int			max_pdu_length,
-	int			seg_support,
 	int			mtu,
 	int			ibds_avsid_mapping);
 
diff --git a/drivers/rapidio/devices/lsi/axxia-rio-hotplug.c b/drivers/rapidio/devices/lsi/axxia-rio-hotplug.c
index a6015ff..66afff3 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio-hotplug.c
+++ b/drivers/rapidio/devices/lsi/axxia-rio-hotplug.c
@@ -105,25 +105,29 @@ static int get_input_status(struct rio_mport *mport, u32 *rsp)
 	u32 sts_csr, rsp_csr;
 
 	/* Debug: Show current state */
-	__rio_local_read_config_32(mport, RIO_ACK_STS_CSR, &sts_csr);
+	__rio_local_read_config_32(mport,
+		RIO_ACK_STS_CSR(priv->portNdx), &sts_csr);
 
-	dev_dbg(priv->dev, "RIO_ACK_STS_CSR %8.8x, IA %x, OUTA %x, OBA %x\n",
+	dev_dbg(priv->dev, "RIO_ACK_STS_CSR(%d) %8.8x, IA %x, OUTA %x, OBA %x\n",
+		priv->portNdx,
 		sts_csr, (sts_csr & RIO_ACK_STS_IA) >> 24,
 		(sts_csr & RIO_ACK_STS_OUTA) >> 8,
 		(sts_csr) & RIO_ACK_STS_OBA);
 
 	/* Read to clear valid bit... */
-	__rio_local_read_config_32(mport, RIO_MNT_RSP_CSR, &rsp_csr);
+	__rio_local_read_config_32(mport,
+		RIO_MNT_RSP_CSR(priv->portNdx), &rsp_csr);
 	udelay(50);
 
 	/* Issue Input-status command */
-	__rio_local_write_config_32(mport, RIO_MNT_REQ_CSR, RIO_MNT_REQ_CMD_IS);
+	__rio_local_write_config_32(mport,
+		RIO_MNT_REQ_CSR(priv->portNdx), RIO_MNT_REQ_CMD_IS);
 
 	/* Wait for reply */
 	checkcount = 3;
 	while (checkcount--) {
 		udelay(50);
-		__rio_local_read_config_32(mport, RIO_MNT_RSP_CSR, &rsp_csr);
+		__rio_local_read_config_32(mport, RIO_MNT_RSP_CSR(priv->portNdx), &rsp_csr);
 
 		if (rsp_csr & RIO_PORT_N_MNT_RSP_RVAL) {
 			*rsp = rsp_csr;
@@ -146,7 +150,8 @@ static int clr_sync_err(struct rio_mport *mport)
 	dev_dbg(priv->dev, "Input-status response=0x%08x\n", linkstate);
 	far_ackid = (linkstate & RIO_PORT_N_MNT_RSP_ASTAT) >> 5;
 	far_linkstat = linkstate & RIO_PORT_N_MNT_RSP_LSTAT;
-	__rio_local_read_config_32(mport, RIO_ACK_STS_CSR, &sts_csr);
+	__rio_local_read_config_32(mport,
+		RIO_ACK_STS_CSR(priv->portNdx), &sts_csr);
 	near_ackid = (sts_csr & RIO_ACK_STS_IA) >> 24;
 	dev_dbg(priv->dev,
 		"far_ackID=0x%02x far_linkstat=0x%02x near_ackID=0x%02x\n",
@@ -160,18 +165,21 @@ static int clr_sync_err(struct rio_mport *mport)
 		 * unacknowledge packets.
 		 * Should be cleande up after reset though, it may work.
 		 */
-		__rio_local_write_config_32(mport, RIO_ACK_STS_CSR,
+		__rio_local_write_config_32(mport,
+			RIO_ACK_STS_CSR(priv->portNdx),
 			(near_ackid << 24) | (far_ackid << 8) | far_ackid);
 	}
 	/* Debug: Show current state */
-	__rio_local_read_config_32(mport, RIO_ACK_STS_CSR, &sts_csr);
+	__rio_local_read_config_32(mport,
+		RIO_ACK_STS_CSR(priv->portNdx), &sts_csr);
 
-	dev_dbg(priv->dev, "RIO_ACK_STS_CSR %8.8x, IA %x, OUTA %x, OBA %x\n",
+	dev_dbg(priv->dev, "RIO_ACK_STS_CSR(%d) %8.8x, IA %x, OUTA %x, OBA %x\n",
+		priv->portNdx,
 		sts_csr, (sts_csr & RIO_ACK_STS_IA) >> 24,
 		(sts_csr & RIO_ACK_STS_OUTA) >> 8,
 		(sts_csr) & RIO_ACK_STS_OBA);
 
-	__rio_local_read_config_32(mport, RIO_ESCSR, &escsr);
+	__rio_local_read_config_32(mport, RIO_ESCSR(priv->portNdx), &escsr);
 	return escsr & (RIO_ESCSR_OES | RIO_ESCSR_IES) ? -EFAULT : 0;
 }
 
@@ -179,14 +187,14 @@ static int rio_port_stopped(struct rio_mport *mport)
 {
 	u32 escsr;
 
-	__rio_local_read_config_32(mport, RIO_ESCSR, &escsr);
+	__rio_local_read_config_32(mport, RIO_ESCSR(priv->portNdx), &escsr);
 	return escsr & RIO_ESCSR_PU;
 }
 static int rio_port_started(struct rio_mport *mport)
 {
 	u32 escsr;
 
-	__rio_local_read_config_32(mport, RIO_ESCSR, &escsr);
+	__rio_local_read_config_32(mport, RIO_ESCSR(priv->portNdx), &escsr);
 	return escsr & RIO_ESCSR_PO;
 }
 
@@ -195,9 +203,9 @@ static void rio_lp_extract(struct rio_mport *mport)
 	u32 ccsr;
 
 	/* Set port lockout */
-	__rio_local_read_config_32(mport, RIO_CCSR, &ccsr);
+	__rio_local_read_config_32(mport, RIO_CCSR(priv->portNdx), &ccsr);
 	ccsr |= RIO_PORT_N_CTL_LOCKOUT;
-	__rio_local_write_config_32(mport, RIO_CCSR, ccsr);
+	__rio_local_write_config_32(mport, RIO_CCSR(priv->portNdx), ccsr);
 
 	/* Drain output/input buffers:
 	 * Is there a way of doing this other than
@@ -210,17 +218,17 @@ static void rio_lp_extract(struct rio_mport *mport)
 
 	/* Force input state to normal */
 	ccsr |= RIO_PORT_N_CTL_PORT_DIS;
-	__rio_local_write_config_32(mport, RIO_CCSR, ccsr);
+	__rio_local_write_config_32(mport, RIO_CCSR(priv->portNdx), ccsr);
 
 	/* Clear in and outbound ACK IDs */
-	__rio_local_write_config_32(mport, RIO_ACK_STS_CSR, 0);
+	__rio_local_write_config_32(mport, RIO_ACK_STS_CSR(priv->portNdx), 0);
 
 	/* Enable input port and leave drain mode */
 	ccsr &= ~RIO_PORT_N_CTL_PORT_DIS;
-	__rio_local_write_config_32(mport, RIO_CCSR, ccsr);
+	__rio_local_write_config_32(mport, RIO_CCSR(priv->portNdx), ccsr);
 	__rio_rab_pio_enable(mport);
 	ccsr &= ~RIO_PORT_N_CTL_LOCKOUT;
-	__rio_local_write_config_32(mport, RIO_CCSR, ccsr);
+	__rio_local_write_config_32(mport, RIO_CCSR(priv->portNdx), ccsr);
 	axxia_rio_start_port(mport);
 }
 
@@ -244,14 +252,14 @@ static void rio_mp_insert(struct rio_mport *mport)
 	u32 ccsr;
 
 	/* Set port lockout */
-	__rio_local_read_config_32(mport, RIO_CCSR, &ccsr);
+	__rio_local_read_config_32(mport, RIO_CCSR(priv->portNdx), &ccsr);
 	ccsr |= RIO_PORT_N_CTL_LOCKOUT;
-	__rio_local_write_config_32(mport, RIO_CCSR, ccsr);
+	__rio_local_write_config_32(mport, RIO_CCSR(priv->portNdx), ccsr);
 	/* sync ACK IDs */
 	clr_sync_err(mport);
 	/* Clear port lockout */
 	ccsr &= ~RIO_PORT_N_CTL_LOCKOUT;
-	__rio_local_write_config_32(mport, RIO_CCSR, ccsr);
+	__rio_local_write_config_32(mport, RIO_CCSR(priv->portNdx), ccsr);
 }
 
 static void acp_rio_hotswap_work(struct work_struct *work)
diff --git a/drivers/rapidio/devices/lsi/axxia-rio-irg-dbg.h b/drivers/rapidio/devices/lsi/axxia-rio-irg-dbg.h
index 0e34b14..b21708b 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio-irg-dbg.h
+++ b/drivers/rapidio/devices/lsi/axxia-rio-irg-dbg.h
@@ -47,6 +47,7 @@ enum rio_irq_dbg {
 	RIO_MISC_OB_DB_PENDING,
 	RIO_MISC_IB_DB,
 	RIO_MISC_IB_DB_SPURIOUS,
+	RIO_LINKDOWN,
 	RIO_OB_DME_STAT_RESP_TO,
 	RIO_OB_DME_STAT_RESP_ERR,
 	RIO_OB_DME_STAT_DATA_TRANS_ERR,
@@ -167,7 +168,7 @@ static inline void __misc_info_dbg(struct rio_priv *priv, u32 misc_state)
 	/* Log only - no enable bit or state to clear */
 	if (misc_state & (UNEXP_MSG_LOG |
 			  LL_TL_INT | GRIO_INT |
-			  UNSP_RIO_REQ_INT | RIO_MISC_UNEXP)) {
+			  UNSP_RIO_REQ_INT | UNEXP_MSG_INT)) {
 		if (misc_state & UNEXP_MSG_LOG)
 			__irq_dbg(priv, RIO_MISC_LOG);
 		if (misc_state & LL_TL_INT)
diff --git a/drivers/rapidio/devices/lsi/axxia-rio-irq.c b/drivers/rapidio/devices/lsi/axxia-rio-irq.c
index a665258..e962b0c 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio-irq.c
+++ b/drivers/rapidio/devices/lsi/axxia-rio-irq.c
@@ -141,9 +141,9 @@ static inline void __misc_fatal_dbg(struct rio_priv *priv, u32 misc_state,
 static inline void __misc_info_dbg(struct rio_priv *priv, u32 misc_state)
 {
 	/* Log only - no enable bit or state to clear */
-	if (misc_state & (UNEXP_MSG_INT |
+	if (misc_state & (UNEXP_MSG_LOG | UNEXP_MSG_INT |
 			  LL_TL_INT | GRIO_INT |
-			  UNSP_RIO_REQ_INT | RIO_MISC_UNEXP)) {
+			  UNSP_RIO_REQ_INT)) {
 		if (misc_state & UNEXP_MSG_INT)
 			__irq_dbg(priv, RIO_MISC_UNEXP);
 		if (misc_state & LL_TL_INT)
@@ -362,6 +362,7 @@ static irqreturn_t thrd_irq_handler(int irq, void *data)
 	__rio_local_read_config_32(mport, h->irq_state_reg_addr, &state);
 	state &= h->irq_state_mask;
 	__rio_local_write_config_32(mport, h->irq_state_reg_addr, state);
+
 #ifdef CONFIG_SRIO_IRQ_TIME
 	if (atomic_read(&h->start_time))
 		h->thrd_tb = get_tb();
@@ -438,6 +439,8 @@ int alloc_irq_handler(struct rio_irq_handler *h,
 		mask |= h->irq_state_mask;
 		__rio_local_write_config_32(mport, h->irq_enab_reg_addr, mask);
 	}
+	if (h->irq_enab_reg_addr)
+		__rio_local_write_config_32(mport, h->irq_state_reg_addr, mask);
 
 	return rc;
 }
@@ -502,12 +505,14 @@ static inline void __misc_fatal(struct rio_mport *mport,
 	u32 aslv_state = 0;
 	u32 escsr, iecsr;
 
-	__rio_local_read_config_32(mport, RIO_ESCSR, &escsr);
-	__rio_local_read_config_32(mport, EPC_IECSR, &iecsr);
+	__rio_local_read_config_32(mport, RIO_ESCSR(priv->portNdx), &escsr);
+	__rio_local_read_config_32(mport, EPC_IECSR(priv->portNdx), &iecsr);
 
 	/* clear latched state indications */
-	__rio_local_write_config_32(mport, RIO_ESCSR, (escsr & RIO_EXCSR_WOLR));
-	__rio_local_write_config_32(mport, EPC_IECSR, (iecsr & EPC_IECSR_RETE));
+	__rio_local_write_config_32(mport,
+		RIO_ESCSR(priv->portNdx), (escsr & RIO_EXCSR_WOLR));
+	__rio_local_write_config_32(mport,
+		EPC_IECSR(priv->portNdx), (iecsr & EPC_IECSR_RETE));
 
 #if defined(CONFIG_AXXIA_RIO_STAT)
 	__add_event_dbg(priv, escsr, iecsr);
@@ -829,7 +834,7 @@ static void disable_pw(struct rio_irq_handler *h)
  */
 
 /**
- * axxia_rio_tx_db_int_handler - AXXIA inbound doorbell interrupt handler
+ * axxia_rio_rx_db_int_handler - AXXIA inbound doorbell interrupt handler
  * @mport: Master port with triggered interrupt
  * @mask: Interrupt register data
  *
@@ -951,6 +956,47 @@ static inline void dme_put(struct rio_msg_dme *me)
 		kref_put(&me->kref, release_dme);
 }
 
+static inline int check_dme(int dme_no,
+			    int *numDmes,
+			    int *dmesInUse,
+			    int *dmes)
+{
+	int i;
+	for (i = 0; i < 2; i++) {
+		if (dme_no < numDmes[i]) {
+			if (dmes[i] & (1 << dme_no)) {
+				if (dmesInUse[i] & (1 << dme_no))
+					return -EBUSY;	/* Already allocated */
+				return 0;
+			}
+		} else {
+			dme_no -= numDmes[i];
+		}
+	}
+
+	return -ENXIO;	/* Not available */
+}
+
+static inline int select_dme(int dme_no,
+			     int *numDmes,
+			     int *dmesInUse,
+			     int *dmes,
+			     int value)
+{
+	int i;
+	for (i = 0; i < 2; i++) {
+		if (dme_no < numDmes[i]) {
+			dmesInUse[i] &= ~(1 << dme_no);
+			dmesInUse[i] |= (value << dme_no);
+			return 0;
+		} else {
+			dme_no -= numDmes[i];
+		}
+	}
+
+	return -ENXIO;	/* Not available */
+}
+
 static inline int choose_ob_dme(
 	struct rio_priv	*priv,
 	int len,
@@ -990,14 +1036,21 @@ static void release_mbox(struct kref *kref)
 	struct rio_priv *priv = mb->mport->priv;
 	int letter;
 
+	/* Quickly disable the engines */
 	for (letter = 0; letter < RIO_MSG_MAX_LETTER; letter++) {
-		int i = mb->me[letter]->dme_no / 32;
-		int j = mb->me[letter]->dme_no % 32;
-		if (mb->me[letter]) {
+		if (mb->me[letter])
 			__rio_local_write_config_32(mb->mport,
 				   RAB_IB_DME_CTRL(mb->me[letter]->dme_no), 0);
+	}
+
+	/* And then release the remaining resources */
+	for (letter = 0; letter < RIO_MSG_MAX_LETTER; letter++) {
+		if (mb->me[letter]) {
 			dme_put(mb->me[letter]);
-			priv->inbDmesInUse[i] &= ~(1 << j);
+			select_dme(mb->me[letter]->dme_no,
+					&priv->numInbDmes[0],
+					&priv->inbDmesInUse[0],
+					&priv->inbDmes[0], 0);
 		}
 	}
 
@@ -1313,7 +1366,7 @@ static void ob_dme_irq_handler(struct rio_irq_handler *h, u32 state)
 static int open_outb_mbox(struct rio_mport *mport, void *dev_id, int dme_no,
 			  int entries, int prio)
 {
-	int i, di, dj, rc = -ENOMEM;
+	int i, rc = -ENOMEM;
 	struct rio_priv *priv = mport->priv;
 	struct rio_irq_handler *h = &priv->ob_dme_irq[dme_no];
 	struct rio_msg_desc *desc;
@@ -1329,15 +1382,10 @@ static int open_outb_mbox(struct rio_mport *mport, void *dev_id, int dme_no,
 		return -EBUSY;
 
 	/* Is the requested DME present & available? */
-	di = dme_no / 32;
-	dj = dme_no % 32;
-
-	if (priv->outbDmes[di] & (1 << dj)) {
-		if (priv->outbDmesInUse[di] & (1 << dj))
-			return -EBUSY;	/* Already allocated! */
-	} else {
-		return -ENXIO;	/* Not available! */
-	}
+	rc = check_dme(dme_no, &priv->numOutbDmes[0],
+			&priv->outbDmesInUse[0], &priv->outbDmes[0]);
+	if (rc < 0)
+		return rc;
 
 	buf_sz = RIO_OUTB_DME_TO_BUF_SIZE(priv, dme_no);
 
@@ -1443,7 +1491,8 @@ static int open_outb_mbox(struct rio_mport *mport, void *dev_id, int dme_no,
 	/**
 	 * And finally update the state to reflect the DME is in use
 	 */
-	priv->outbDmesInUse[di] |= (1 << dj);
+	rc = select_dme(dme_no, &priv->numOutbDmes[0],
+			&priv->outbDmesInUse[0], &priv->outbDmes[0], 1);
 
 	atomic_inc(&priv->api_user);
 	return 0;
@@ -1468,14 +1517,11 @@ static void release_outb_mbox(struct rio_irq_handler *h)
 	struct rio_priv *priv = mport->priv;
 	struct rio_msg_dme *me = h->data;
 
-	{
-		int	i = me->dme_no / 32;
-		int	j = me->dme_no % 32;
-		priv->outbDmesInUse[i] &= ~(1 << j);
-	}
-
 	__rio_local_write_config_32(mport, RAB_OB_DME_CTRL(me->dme_no), 0);
 
+	select_dme(me->dme_no, &priv->numOutbDmes[0],
+		   &priv->outbDmesInUse[0], &priv->outbDmes[0], 0);
+
 	if (me->entries_in_use) {
 		dev_warn(priv->dev,
 			"RIO: MBOX DME %d had %d messages unread at release\n",
@@ -1723,8 +1769,6 @@ static int open_inb_mbox(struct rio_mport *mport, void *dev_id,
 	 */
 	for (letter = 0; letter < RIO_MSG_MAX_LETTER; ++letter) {
 		int dme_no = (mbox * RIO_MSG_MAX_LETTER) + letter;
-		int di = dme_no / 32;
-		int dj = dme_no % 32;
 		struct rio_msg_dme *me = NULL;
 		struct rio_msg_desc *desc;
 		u32 dw0, dw1, dw2, dw3;
@@ -1732,12 +1776,10 @@ static int open_inb_mbox(struct rio_mport *mport, void *dev_id,
 		u32 dme_stat, wait = 0;
 		u32 buffer_size = (buf_sz > 256 ? 3 : 0);
 
-		if (priv->inbDmes[di] & (1 << dj)) {
-			if (priv->inbDmesInUse[di] & (1 << dj))
-				return -EBUSY;	/* Already allocated! */
-		} else {
-			return -ENXIO;	/* Not available! */
-		}
+		rc = check_dme(dme_no, &priv->numInbDmes[0],
+				&priv->inbDmesInUse[0], &priv->inbDmes[0]);
+		if (rc < 0)
+			return rc;
 
 		me = alloc_message_engine(mport,
 					  dme_no,
@@ -1809,7 +1851,8 @@ static int open_inb_mbox(struct rio_mport *mport, void *dev_id,
 		desc--;
 		dw0 |= DME_DESC_DW0_NXT_DESC_VALID;
 		if (!priv->internalDesc) {
-			descChainStart = (uintptr_t)virt_to_phys(me->descriptors);
+			descChainStart =
+				(uintptr_t)virt_to_phys(me->descriptors);
 
 			dw2  = *((u32 *)DESC_TABLE_W2_MEM(me, desc->desc_no));
 			dw2 |= (descChainStart >> 4) & 0xc0000000;
@@ -1850,7 +1893,8 @@ static int open_inb_mbox(struct rio_mport *mport, void *dev_id,
 		__rio_local_write_config_32(mport,
 					RAB_IB_DME_CTRL(dme_no), dme_ctrl);
 
-		priv->inbDmesInUse[di] |= (1 << dj);
+		select_dme(dme_no, &priv->numInbDmes[0],
+			&priv->inbDmesInUse[0], &priv->inbDmes[0], 1);
 	}
 
 	/**
@@ -1923,10 +1967,11 @@ void axxia_rio_port_get_state(struct rio_mport *mport, int cleanup)
 	}
 
 	/* Master Port state */
-	__rio_local_read_config_32(mport, RIO_ESCSR, &escsr);
-	__rio_local_read_config_32(mport, EPC_IECSR, &iecsr);
+	__rio_local_read_config_32(mport, RIO_ESCSR(priv->portNdx), &escsr);
+	__rio_local_read_config_32(mport, EPC_IECSR(priv->portNdx), &iecsr);
 
-	__rio_local_write_config_32(mport, RIO_ESCSR, (escsr & RIO_EXCSR_WOLR));
+	__rio_local_write_config_32(mport, RIO_ESCSR(priv->portNdx),
+		(escsr & RIO_EXCSR_WOLR));
 #if defined(CONFIG_AXXIA_RIO_STAT)
 	__add_state_dbg(priv, escsr);
 	if (!(escsr & RIO_ESCSR_PO)) /* Port is down */
@@ -2508,7 +2553,7 @@ void axxia_rio_port_irq_init(struct rio_mport *mport)
 #if defined(CONFIG_AXXIA_RIO_STAT)
 	priv->misc_irq.irq_state_mask |=
 		GRIO_INT | LL_TL_INT | UNEXP_MSG_LOG |
-		UNSP_RIO_REQ_INT | RIO_MISC_UNEXP;
+		UNSP_RIO_REQ_INT | UNEXP_MSG_INT;
 #endif
 	priv->misc_irq.thrd_irq_fn = misc_irq_handler;
 	priv->misc_irq.data = NULL;
@@ -2642,7 +2687,7 @@ int axxia_rio_port_op_state(struct rio_mport *mport)
 {
 	u32 escsr;
 
-	__rio_local_read_config_32(mport, RIO_ESCSR, &escsr);
+	__rio_local_read_config_32(mport, RIO_ESCSR(priv->portNdx), &escsr);
 
 	if (escsr & RIO_ESCSR_PO)
 		return MPORT_STATE_OPERATIONAL;
diff --git a/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c b/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c
index e36227c..3538162 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c
+++ b/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c
@@ -405,6 +405,7 @@ static ssize_t axxia_rio_tmo_show(struct device *dev,
 				char *buf)
 {
 	struct rio_mport *mport = dev_get_drvdata(dev);
+	struct rio_priv *priv = mport->priv;
 	u32 stat;
 	char *str = buf;
 
@@ -421,9 +422,9 @@ static ssize_t axxia_rio_tmo_show(struct device *dev,
 	__rio_local_read_config_32(mport, RAB_APIO_STAT, &stat);
 	str += sprintf(str, "RAB_APIO_STAT (%p)\t%8.8x\n",
 		       (void *)RAB_APIO_STAT, stat);
-	__rio_local_read_config_32(mport, RIO_ESCSR, &stat);
+	__rio_local_read_config_32(mport, RIO_ESCSR(priv->portNdx), &stat);
 	str += sprintf(str, "PNESCSR (%p)\t%8.8x\n",
-		       (void *)RIO_ESCSR, stat);
+		       (void *)RIO_ESCSR(priv->portNdx), stat);
 
 	return str - buf;
 }
diff --git a/drivers/rapidio/devices/lsi/axxia-rio.c b/drivers/rapidio/devices/lsi/axxia-rio.c
index 66c294b..0baa7fc 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio.c
+++ b/drivers/rapidio/devices/lsi/axxia-rio.c
@@ -85,15 +85,17 @@ static DEFINE_SPINLOCK(rio_io_lock);
  * Returns %0 on success or %-EINVAL on failure.
  */
 static int __axxia_local_config_read_actual(struct rio_priv *priv,
-					  u32 offset,
-					  u32 *data,
-					  int suppress)
+					    u32 offset,
+					    u32 *data,
+					    int suppress)
 {
 	u32 page_sel;
 
 	if (suppress)
 		AXXIA_RIO_DISABLE_MACHINE_CHECK();
 
+	AXXIA_RIO_SYSMEM_BARRIER();
+
 	/* Set correct page to operate on */
 	page_sel = (offset & 0x00fff800) << 5;
 	outl(page_sel, (long unsigned int)priv->regs_win_fixed +
@@ -134,12 +136,11 @@ static int __axxia_local_config_read_actual(struct rio_priv *priv,
 				offset);
 			*data = 0;
 		}
-	}
 
-	if (suppress)
 		AXXIA_RIO_ENABLE_MACHINE_CHECK();
+	}
 
-	IODP("rio: ACR(%08x, <%08x)\n", offset, *data);
+	IODP("rio[%d]: ACR(%08x, <%08x)\n", priv->mport->id, offset, *data);
 
 	return 0;
 }
@@ -158,15 +159,17 @@ static int __axxia_local_config_read_actual(struct rio_priv *priv,
  * Returns %0 on success or %-EINVAL on failure.
  */
 static int __axxia_local_config_write_actual(struct rio_priv *priv,
-					   u32 offset,
-					   u32 data,
-					   int suppress)
+					     u32 offset,
+					     u32 data,
+					     int suppress)
 {
 	u32 page_sel;
 
 	if (suppress)
 		AXXIA_RIO_DISABLE_MACHINE_CHECK();
 
+	AXXIA_RIO_SYSMEM_BARRIER();
+
 	/* Set correct page to operate on */
 	page_sel = (offset & 0x00fff800) << 5;
 	outl(page_sel, (long unsigned int)priv->regs_win_fixed +
@@ -195,8 +198,6 @@ static int __axxia_local_config_write_actual(struct rio_priv *priv,
 			offset);
 	}
 
-	AXXIA_RIO_SYSMEM_BARRIER();
-
 	if (suppress) {
 		int mcsr;
 		AXXIA_RIO_IF_MACHINE_CHECK(mcsr);
@@ -206,12 +207,11 @@ static int __axxia_local_config_write_actual(struct rio_priv *priv,
 				"register 0x%0x8 for AXXIA\n",
 				offset);
 		}
-	}
 
-	if (suppress)
 		AXXIA_RIO_ENABLE_MACHINE_CHECK();
+	}
 
-	IODP("rio: ACW(%08x, >%08x)\n", offset, data);
+	IODP("rio[%d]: ACW(%08x, >%08x)\n", priv->mport->id, offset, data);
 
 	return 0;
 }
@@ -235,6 +235,9 @@ static int axxia_local_config_read(struct rio_mport *mport,
 {
 	struct rio_priv *priv = mport->priv;
 
+	if ((priv == NULL) || (priv->cookie != LSI_AXXIA_RIO_COOKIE))
+		return -ENODEV;
+
 	return __axxia_local_config_read(priv, offset, data);
 }
 
@@ -254,6 +257,9 @@ static int axxia_local_config_write(struct rio_mport *mport,
 {
 	struct rio_priv *priv = mport->priv;
 
+	if ((priv == NULL) || (priv->cookie != LSI_AXXIA_RIO_COOKIE))
+		return -ENODEV;
+
 	return __axxia_local_config_write(priv, offset, data);
 }
 
@@ -271,24 +277,33 @@ static int axxia_local_config_write(struct rio_mport *mport,
  * Returns %0 on success or %-EINVAL on failure.
  */
 
-static int axxia_rio_config_read(struct rio_mport *mport, int index, u16 destid,
-			       u8 hopcount, u32 offset, int len, u32 *val)
+static int axxia_rio_config_read(struct rio_mport *mport, int index,
+				 u16 destid, u8 hopcount, u32 offset,
+				 int len, u32 *val)
 {
 	struct rio_priv *priv = mport->priv;
-	struct atmu_outb *aoutb = &priv->outb_atmu[priv->maint_win_id];
+	struct atmu_outb *aoutb = NULL;
 	u8 *addr;
 	u32 rval = 0;
 	u32 rbar = 0, ctrl;
 	int rc = 0;
 	int mcsr = 0;
 
-	AXXIA_RIO_DISABLE_MACHINE_CHECK();
+	/* Argument validation */
+	if ((priv == NULL) || (priv->cookie != LSI_AXXIA_RIO_COOKIE))
+		return -ENODEV;
+
+	aoutb = &priv->outb_atmu[priv->maint_win_id];
+	if (aoutb == NULL)
+		return -EINVAL;
 
 	/* 16MB maintenance windows possible */
 	/* Allow only aligned access to maintenance registers */
 	if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len))
 		return -EINVAL;
 
+	AXXIA_RIO_DISABLE_MACHINE_CHECK();
+
 	__axxia_local_config_read_actual(priv,
 				       RAB_APIO_AMAP_CTRL(priv->maint_win_id),
 				       &ctrl,
@@ -298,6 +313,7 @@ static int axxia_rio_config_read(struct rio_mport *mport, int index, u16 destid,
 		dev_err(priv->dev,
 			"(%s): Window is not setup for Maintenance operations. 0x%8.8x\n",
 			__func__, ctrl);
+		AXXIA_RIO_ENABLE_MACHINE_CHECK();
 		return -EINVAL;
 	}
 
@@ -318,8 +334,9 @@ static int axxia_rio_config_read(struct rio_mport *mport, int index, u16 destid,
 	addr = (u8 *) aoutb->win +
 		(offset & (CONFIG_RIO_MAINT_WIN_SIZE - 1));
 
-	switch (len) {
+	AXXIA_RIO_SYSMEM_BARRIER();
 
+	switch (len) {
 	case 1:
 		IN_SRIO8(addr, rval, rc);
 		break;
@@ -355,8 +372,8 @@ static int axxia_rio_config_read(struct rio_mport *mport, int index, u16 destid,
 	} else
 		*val = rval;
 
-	IODP("rio: RCR(did=%x, hc=%02x, %08x, <%08x)\n",
-			destid, hopcount, offset, rval);
+	IODP("rio[%d]: RCR(did=%x, hc=%02x, %08x, <%08x)\n",
+			mport->id, destid, hopcount, offset, rval);
 
 	return rc;
 }
@@ -374,32 +391,37 @@ static int axxia_rio_config_read(struct rio_mport *mport, int index, u16 destid,
  * Generates an AXXIA write maintenance transaction.
  * Returns %0 on success or %-EINVAL on failure.
  */
-static int axxia_rio_config_write(struct rio_mport *mport,
-								  int index,
-								  u16 destid,
-								  u8 hopcount,
-								  u32 offset,
-								  int len,
-								  u32 val)
+static int axxia_rio_config_write(struct rio_mport *mport, int index,
+				  u16 destid, u8 hopcount, u32 offset,
+				  int len, u32 val)
 {
 	struct rio_priv *priv = mport->priv;
-	struct atmu_outb *aoutb = &priv->outb_atmu[priv->maint_win_id];
+	struct atmu_outb *aoutb = NULL;
 	u8 *data;
 	u32 rbar = 0, ctrl, rval;
 	int rc = 0;
 	int mcsr = 0;
 
-	IODP("rio: RCW(did=%x, hc=%02x, %08x, >%08x)\n",
-			destid, hopcount, offset, val);
+	IODP("rio[%d]: RCW(did=%x, hc=%02x, %08x, >%08x)\n",
+			mport->id, destid, hopcount, offset, val);
 
-	AXXIA_RIO_DISABLE_MACHINE_CHECK();
+	/* Argument validation */
+	if ((priv == NULL) || (priv->cookie != LSI_AXXIA_RIO_COOKIE))
+		return -ENODEV;
+
+	aoutb = &priv->outb_atmu[priv->maint_win_id];
+	if (aoutb == NULL)
+		return -EINVAL;
 
 	/* 16MB maintenance windows possible */
+	if (aoutb == NULL)
+		return -EINVAL;
+
 	/* Allow only aligned access to maintenance registers */
-	if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) {
-		rc = -EINVAL;
-		goto err;
-	}
+	if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len))
+		return -EINVAL;
+
+	AXXIA_RIO_DISABLE_MACHINE_CHECK();
 
 	__axxia_local_config_read_actual(priv,
 				RAB_APIO_AMAP_CTRL(priv->maint_win_id),
@@ -437,6 +459,8 @@ static int axxia_rio_config_write(struct rio_mport *mport,
 	data = (u8 *) aoutb->win +
 		(offset & (CONFIG_RIO_MAINT_WIN_SIZE - 1));
 
+	AXXIA_RIO_SYSMEM_BARRIER();
+
 	switch (len) {
 	case 1:
 		OUT_SRIO8(data, rval);
@@ -462,7 +486,7 @@ err:
 
 	AXXIA_RIO_ENABLE_MACHINE_CHECK();
 
-	return 0;
+	return rc;
 }
 
 static inline int __flags2rio_tr_type(u32 mflags, u32 *trans_type)
@@ -717,7 +741,7 @@ static void axxia_rio_release_outb_region(struct rio_mport *mport,
 
 
 /**
- * rio_set_mport_disc_mode - Set master port discovery/eumeration mode
+ * axxia_rio_set_mport_disc_mode - Set master port discovery/eumeration mode
  *
  * @mport: Master port
  *
@@ -732,21 +756,31 @@ void axxia_rio_set_mport_disc_mode(struct rio_mport *mport)
 					    RIO_PORT_GEN_MASTER |
 					    RIO_PORT_GEN_DISCOVERED);
 	} else {
-		__rio_local_write_config_32(mport, RIO_GCCSR, 0x00000000);
+		__rio_local_write_config_32(mport, RIO_GCCSR,
+					    RIO_PORT_GEN_MASTER);
 		__rio_local_write_config_32(mport, RIO_DID_CSR,
 					    RIO_SET_DID(mport->sys_size,
 					    RIO_ANY_DESTID(mport->sys_size)));
 	}
+
+#ifdef SRIO_IODEBUG
 	__rio_local_read_config_32(mport, RIO_GCCSR, &result);
+	dev_dbg(priv->dev, "%d RIO_GEN_CTL_CSR set to 0x%X for main port\n",
+		mport->id, result);
+#endif
+
+	__rio_local_write_config_32(mport, RIO_COMPONENT_TAG_CSR, 0xFFFF);
 
 #ifdef	NOT_SUPPORTED
 	/* Use the reset default setting of (0x00000000).  RAB does not
 	 * support "Accept All=1".  We would need another ID value to use
-	 * if we wantd to set the PTPN and PTE=1. */
+	 * if we wanted to set the PTPN and PTE=1. */
 
 	/* Set to receive any dist ID for serial RapidIO controller. */
 	if (mport->phy_type == RIO_PHY_SERIAL)
-		__rio_local_write_config_32(mport, EPC_PNPTAACR, 0x00000000);
+		__rio_local_write_config_32(mport,
+				EPC_PNPTAACR(mport->portNdx),
+				0x00000000);
 #endif
 
 #ifdef CONFIG_RAPIDIO_HOTPLUG
@@ -756,9 +790,11 @@ void axxia_rio_set_mport_disc_mode(struct rio_mport *mport)
 		result = EPC_PNADIDCSR_ADE;
 		result |= EPC_PNADIDCSR_ADID_SMALL(
 				CONFIG_RAPIDIO_SECOND_DEST_ID);
-		__rio_local_write_config_32(mport, EPC_PNADIDCSR, result);
-		dev_dbg(priv->dev, "Second destination id set to 0x%X for main port\n",
-			CONFIG_RAPIDIO_SECOND_DEST_ID);
+		__rio_local_write_config_32(mport,
+				EPC_PNADIDCSR(priv->portNdx),
+				result);
+		dev_dbg(priv->dev, "Port%dAltDevIdmCSR set to 0x%X for main port\n",
+			priv->portNdx, CONFIG_RAPIDIO_SECOND_DEST_ID);
 	}
 #else
 	/* Set the Alternate Destination ID to prevent "Machine Checks"
@@ -772,20 +808,22 @@ void axxia_rio_set_mport_disc_mode(struct rio_mport *mport)
 			result |= EPC_PNADIDCSR_ADID_LARGE(~0);
 		else
 			result |= EPC_PNADIDCSR_ADID_SMALL(~0);
-		__rio_local_write_config_32(mport, EPC_PNADIDCSR, result);
-		dev_dbg(priv->dev, "Second destination id set to 0x%X for main port\n",
-			result);
+		__rio_local_write_config_32(mport,
+				EPC_PNADIDCSR(priv->portNdx),
+				result);
+		dev_dbg(priv->dev, "Port%dAltDevIdmCSR set to 0x%X for main port\n",
+			priv->portNdx, result);
 	}
 #endif
 }
 
 /**
- * rio_init_port_data - HW Setup of master port
+ * axxia_init_port_data - HW Setup of master port
  *
  * @mport: Master port
  *
  */
-static void rio_init_port_data(struct rio_mport *mport)
+static void axxia_init_port_data(struct rio_mport *mport)
 {
 	struct rio_priv *priv = mport->priv;
 	u32 ccsr, data;
@@ -796,7 +834,7 @@ static void rio_init_port_data(struct rio_mport *mport)
 				    data | RAB_SRDS_CTRL0_16B_ID);
 #endif
 	/* Probe the master port phy type */
-	__rio_local_read_config_32(mport, RIO_CCSR, &ccsr);
+	__rio_local_read_config_32(mport, RIO_CCSR(priv->portNdx), &ccsr);
 	mport->phy_type = (ccsr & 1) ? RIO_PHY_SERIAL : RIO_PHY_PARALLEL;
 	dev_dbg(priv->dev, "RapidIO PHY type: %s\n",
 		 (mport->phy_type == RIO_PHY_PARALLEL) ? "parallel" :
@@ -820,8 +858,8 @@ static void rio_init_port_data(struct rio_mport *mport)
 			if (devid == legacyids[i])
 				priv->internalDesc = 1;
 		}
-		IODP("rio: RapidIO internal descriptors: %d (%x %x)\n",
-			priv->internalDesc, devid, data);
+		IODP("rio[%d]: RapidIO internal descriptors: %d (%x %x)\n",
+			mport->id, priv->internalDesc, devid, data);
 	}
 }
 
@@ -887,8 +925,8 @@ static int rio_start_port(struct rio_mport *mport)
 	u32 ccsr, escsr;
 
 	/* Probe the master port phy type */
-	__rio_local_read_config_32(mport, RIO_CCSR, &ccsr);
-	__rio_local_read_config_32(mport, RIO_ESCSR, &escsr);
+	__rio_local_read_config_32(mport, RIO_CCSR(priv->portNdx), &ccsr);
+	__rio_local_read_config_32(mport, RIO_ESCSR(priv->portNdx), &escsr);
 
 	if (escsr & RIO_ESCSR_PU) {
 
@@ -897,22 +935,26 @@ static int rio_start_port(struct rio_mport *mport)
 			"connection...\n");
 		/* Disable ports */
 		ccsr |= RIO_CCSR_PD;
-		__rio_local_write_config_32(mport, RIO_CCSR, ccsr);
+		__rio_local_write_config_32(mport,
+			RIO_CCSR(priv->portNdx), ccsr);
 		switch (mport->phy_type) {
 		case RIO_PHY_SERIAL:
 			/* Set 1x lane */
 			ccsr &= ~RIO_CCSR_PWO;
 			ccsr |= RIO_CCSR_FORCE_LANE0;
-			__rio_local_write_config_32(mport, RIO_CCSR, ccsr);
+			__rio_local_write_config_32(mport,
+				RIO_CCSR(priv->portNdx), ccsr);
 			break;
 		case RIO_PHY_PARALLEL:
 			break;
 		}
 		/* Enable ports */
 		ccsr &= ~RIO_CCSR_PD;
-		__rio_local_write_config_32(mport, RIO_CCSR, ccsr);
+		__rio_local_write_config_32(mport,
+			RIO_CCSR(priv->portNdx), ccsr);
 		msleep(100);
-		__rio_local_read_config_32(mport, RIO_ESCSR, &escsr);
+		__rio_local_read_config_32(mport,
+			RIO_ESCSR(priv->portNdx), &escsr);
 		axxia_rio_info(priv->dev, ccsr);
 		if (escsr & RIO_ESCSR_PU) {
 			dev_dbg(priv->dev, "Port restart failed.\n");
@@ -932,19 +974,21 @@ static int rio_start_port(struct rio_mport *mport)
 		__rio_local_read_config_32(mport, RIO_DEV_ID_CAR, &didcar);
 		__rio_local_read_config_32(mport, RAB_VER, &rabver);
 
-		printk("rio[%d]: DIDCAR[%x]=%08x RAB_VER[%x]=%08x\n",
+		printk("rio[%d]: AR[%d] DIDCAR[%x]=%08x RAB_VER[%x]=%08x\n",
+			mport->id,
 			__LINE__,
 			RIO_DEV_ID_CAR, didcar,
 			RAB_VER, rabver);
-		printk(KERN_INFO "rio[%d]: CCSR[%x]=%08x ESCSR[%x]=%08x HBDIDLCSR[%x]=%08x\n",
+		printk(KERN_INFO "rio[%d]: AR[%d] CCSR[%x]=%08x ESCSR[%x]=%08x HBDIDLCSR[%x]=%08x\n",
+			mport->id,
 			__LINE__,
-			RIO_CCSR, ccsr,
-			RIO_ESCSR, escsr,
+			RIO_CCSR(priv->portNdx), ccsr,
+			RIO_ESCSR(priv->portNdx), escsr,
 			RIO_HOST_DID_LOCK_CSR, hdlcsr);
 	}
 #endif /* defined(SRIO_IODEBUG) */
 
-	dev_dbg(priv->dev, "Port Is ready\n");
+	dev_dbg(priv->dev, "Port is Ready\n");
 	return 0;
 }
 
@@ -1053,6 +1097,7 @@ void axxia_rio_static_win_release(struct rio_mport *mport)
  * rio_parse_dtb - Parse RapidIO platform entry
  *
  * @dev: RIO platform device
+ * @ndx: Which instance are we?
  * @law_start: Local Access Window start address from DTB
  * @law_size: Local Access Window size from DTB
  * @regs: RapidIO registers from DTB
@@ -1069,6 +1114,7 @@ void axxia_rio_static_win_release(struct rio_mport *mport)
  */
 static int rio_parse_dtb(
 	struct platform_device *dev,
+	int *ndx,
 	u64 *law_start,
 	u64 *law_size,
 	struct resource *regs,
@@ -1077,7 +1123,7 @@ static int rio_parse_dtb(
 	int *ibNumDmes,
 	int *inbDmes,
 	int *irq,
-	struct event_regs      *linkdown_reset)
+	struct event_regs *linkdown_reset)
 {
 	const u32 *dt_range, *cell;
 	int rlen, rc;
@@ -1089,12 +1135,16 @@ static int rio_parse_dtb(
 	}
 
 	if (!of_device_is_available(dev->dev.of_node)) {
-		IODP("AR[%d] status = not available\n", __LINE__);
+		IODP("rio[%d]: AR[%d] status = not available\n", 99, __LINE__);
 			return -ENODEV;
 	} else {
-		IODP("AR[%d] status = available\n", __LINE__);
+		IODP("rio[%d]: AR[%d] status = available\n", 99, __LINE__);
 	}
 
+	if (of_property_read_u32(dev->dev.of_node, "index", &rlen))
+		return -ENODEV;
+	*ndx = rlen;
+
 	rc = of_address_to_resource(dev->dev.of_node, 0, regs);
 	if (rc) {
 		dev_err(&dev->dev, "Can't get %s property 'reg'\n",
@@ -1138,8 +1188,8 @@ static int rio_parse_dtb(
 	*law_start = of_read_number(dt_range + aw, paw);
 	*law_size = of_read_number(dt_range + aw + paw, sw);
 
-	dev_dbg(&dev->dev, "LAW start 0x%016llx, size 0x%016llx.\n",
-		*law_start, *law_size);
+	dev_dbg(&dev->dev, "LAW: [mem 0x%016llx -- 0x%016llx]\n",
+		*law_start, *law_start + *law_size - 1);
 
 	outbDmes[0] = outbDmes[1] = 0;
 	cell = of_get_property(dev->dev.of_node, "outb-dmes", &rlen);
@@ -1213,7 +1263,8 @@ static int rio_parse_dtb(
 			linkdown_reset->reg_mask =
 				of_read_number(dt_range + 1, 1);
 			linkdown_reset->in_use = 1;
-			IODP("rio: LDR st=%llx sz=%llx RA=%x MSK=%x iu=%d\n",
+			IODP("rio[%d]: LDR st=%llx sz=%llx RA=%x MSK=%x iu=%d\n",
+				99,
 				linkdown_reset->phy_reset_start,
 				linkdown_reset->phy_reset_size,
 				linkdown_reset->reg_addr,
@@ -1274,26 +1325,31 @@ static struct rio_ops *rio_ops_setup(void)
  * Register doorbell and mbox resources with generic RIO driver
 
  * Returns:
- * ERR_PTR(-ENOMEM)        At failure
+ * -ENOMEM                 At failure
  * struct rio_mport *ptr   to initialized mport data at Success
  */
-static int rio_port_index;
 static struct rio_mem_ops axxia_mem_ops = {
 	.req_outb = axxia_rio_req_outb_region,
 	.map_outb = axxia_rio_map_outb_mem,
 	.release_outb = axxia_rio_release_outb_region,
 };
 
-static struct rio_mport *rio_mport_dtb_setup(struct platform_device *dev,
-					     u64 law_start, u64 law_size,
-					     struct rio_ops *ops)
+static int rio_mport_dtb_setup(struct platform_device *dev,
+			       int portNdx,
+			       u64 law_start,
+			       u64 law_size,
+			       struct rio_ops *ops,
+			       struct rio_mport **ptr)
 {
+	int rc = 0;
 	struct rio_mport *mport = kzalloc(sizeof(*mport), GFP_KERNEL);
 
+	(*ptr) = NULL;
+
 	if (!mport)
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 
-	mport->index = rio_port_index++; /* DTB maybe??? */
+	mport->index = portNdx;
 
 	INIT_LIST_HEAD(&mport->dbells);
 	mport->iores.start = law_start;
@@ -1310,18 +1366,19 @@ static struct rio_mport *rio_mport_dtb_setup(struct platform_device *dev,
 			"0x%016llx-0x%016llx\n",
 			(u64)mport->iores.start, (u64)mport->iores.end);
 		kfree(mport);
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 	}
 	rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
 	rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 8);
 	rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 3);
-	sprintf(mport->name, "RIO%d mport", mport->index);
+	sprintf(mport->name, "RIO%d mport", mport->id);
 
 	mport->ops = ops;
 	mport->mops = &axxia_mem_ops;
 	mport->phys_efptr = 0x100; /* define maybe */
 
-	return mport;
+	(*ptr) = mport;
+	return rc;
 }
 
 /**
@@ -1331,6 +1388,8 @@ static struct rio_mport *rio_mport_dtb_setup(struct platform_device *dev,
  * @dev: RIO platform device
  * @regs: RapidIO registers from DTB
  * @mport: master port
+ * @ndx: Instance Id of the controller description
+ * @portNdx: Port Id of the controller
  * @numObNumDmes: override num outbound DMEs available
  * @outbDmes: RapidIO outbound DMEs array available; [0] for MSeg, [1] for SSeg
  * @numIbNumDmes: override num inbound DMEs available
@@ -1348,12 +1407,14 @@ static struct rio_priv *rio_priv_dtb_setup(
 	struct platform_device *dev,
 	struct resource *regs,
 	struct rio_mport *mport,
+	int ndx,
+	int portNdx,
 	int *numOutbDmes,
 	int *outbDmes,
 	int *numInbDmes,
 	int *inbDmes,
 	int irq,
-	struct event_regs      *linkdown_reset)
+	struct event_regs *linkdown_reset)
 {
 	struct rio_priv *priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	int i, rc;
@@ -1361,8 +1422,12 @@ static struct rio_priv *rio_priv_dtb_setup(
 	if (!priv)
 		return ERR_PTR(-ENOMEM);
 
-	/* mport port driver handle */
+	/* mport port driver handle (bidirectional reference supported) */
 	mport->priv = priv;
+	priv->cookie = LSI_AXXIA_RIO_COOKIE;
+	priv->mport = mport;
+	priv->ndx = ndx;
+	priv->portNdx = portNdx;
 
 	/* Max descriptors */
 	priv->desc_max_entries = RIO_MSG_MAX_ENTRIES;
@@ -1440,7 +1505,8 @@ static struct rio_priv *rio_priv_dtb_setup(
 			rc = -ENOMEM;
 			goto err_linkdown;
 		}
-		IODP("rio: LDR win=%p\n", priv->linkdown_reset.win);
+		IODP("rio[%d]: LDR win=%p\n",
+				mport->id, priv->linkdown_reset.win);
 	}
 
 	return priv;
@@ -1496,7 +1562,7 @@ int axxia_rio_start_port(struct rio_mport *mport)
 
 	/* Enable memory mapped access
 	 */
-	rio_rab_ctrl_setup(mport); /* init */
+	rio_rab_ctrl_setup(mport);
 
 	rio_rab_pio_enable(mport);
 
@@ -1538,28 +1604,29 @@ int axxia_rio_start_port(struct rio_mport *mport)
  */
 static int axxia_rio_setup(struct platform_device *dev)
 {
+	int rc = -EFAULT;
 	struct rio_ops *ops;
 	struct rio_mport *mport;
 	struct rio_priv *priv;
-	int rc = -EFAULT;
 	struct resource regs;
-	u64 law_start, law_size;
-	int irq = 0;
-	int numObDmes[2], outbDmes[2];
-	int numIbDmes[2], inbDmes[2];
-	struct event_regs linkdown_reset = { 0 };
+	u64 law_start = 0, law_size = 0;
+	int ndx = 0, irq = 0, portNdx = 0;
+	int numObDmes[2] = { 0, }, outbDmes[2] = { 0, };
+	int numIbDmes[2] = { 0, }, inbDmes[2] = { 0, };
+	struct event_regs linkdown_reset = { 0, };
 	struct rio_ds_dtb_info ds_dtb_info; /* data_streaming */
 
-	if (axxia_rapidio_board_init())
-		return -EFAULT;
-
 	/* Get address boundaries, etc. from DTB */
-	if (rio_parse_dtb(dev, &law_start, &law_size, &regs,
+	if (rio_parse_dtb(dev, &ndx, &law_start, &law_size, &regs,
 			  &numObDmes[0], &outbDmes[0],
 			  &numIbDmes[0], &inbDmes[0],
 			  &irq, &linkdown_reset))
 		return -EFAULT;
 
+	rc = axxia_rapidio_board_init(ndx, &portNdx);
+	if (rc != 0)
+		return rc;
+
 	rc = axxia_parse_dtb_ds(dev, &ds_dtb_info);
 	if (rc != 0)
 		return rc;
@@ -1570,12 +1637,11 @@ static int axxia_rio_setup(struct platform_device *dev)
 		rc = PTR_ERR(ops);
 		goto err_ops;
 	}
-	mport = rio_mport_dtb_setup(dev, law_start, law_size, ops);
-	if (IS_ERR(mport)) {
-		rc = PTR_ERR(mport);
+	rc = rio_mport_dtb_setup(dev, portNdx, law_start, law_size,
+				 ops, &mport);
+	if (rc != 0)
 		goto err_port;
-	}
-	priv = rio_priv_dtb_setup(dev, &regs, mport,
+	priv = rio_priv_dtb_setup(dev, &regs, mport, ndx, portNdx,
 				  &numObDmes[0], &outbDmes[0],
 				  &numIbDmes[0], &inbDmes[0],
 				  irq, &linkdown_reset);
@@ -1588,7 +1654,7 @@ static int axxia_rio_setup(struct platform_device *dev)
 
 	/* Get and set master port data:
 	 */
-	rio_init_port_data(mport);
+	axxia_init_port_data(mport);
 
 	/* Start port and enable basic memmap access
 	 */
@@ -1627,7 +1693,8 @@ static int axxia_rio_setup(struct platform_device *dev)
 	 */
 	{
 		u16 id = rio_local_get_device_id(mport);
-		IODP("rio[%d] devid=%d hdid=%d\n", __LINE__,
+		IODP("rio[%d]: AR[%d] devid=%d hdid=%d\n",
+			mport->id, __LINE__,
 			mport->host_deviceid, rio_local_get_device_id(mport));
 		if (mport->host_deviceid < 0) {
 			if ((id != 0xFF) && (mport->sys_size == 0))
@@ -1646,8 +1713,8 @@ static int axxia_rio_setup(struct platform_device *dev)
 
 	axxia_rio_set_mport_disc_mode(mport);
 
-	IODP("rio: mport=%p priv=%p enum_host=%d\n", mport, priv,
-		mport->enum_host);
+	IODP("rio[%p:%d]: priv=%p enum_host=%d\n", mport, mport->id,
+		priv, mport->enum_host);
 	return 0;
 
 err_mport:
diff --git a/drivers/rapidio/devices/lsi/axxia-rio.h b/drivers/rapidio/devices/lsi/axxia-rio.h
index 09513f8d..3659138 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio.h
+++ b/drivers/rapidio/devices/lsi/axxia-rio.h
@@ -56,12 +56,12 @@
 
 /* End Point Controller Specific Registers (0x1_0000-0x1_FFFC) */
 #define EPC_REG_BASE            0x10000
-#define EPC_PNADIDCSR	        (EPC_REG_BASE + 0x100)
+#define EPC_PNADIDCSR(x)        (EPC_REG_BASE + (0x100+((x)*0x80)))
 #define  EPC_PNADIDCSR_ADE	(1 << 31)
 #define  EPC_PNADIDCSR_ADID_SMALL(id)	((u32)((id) & 0x00ff) << 16)
 #define  EPC_PNADIDCSR_ADID_LARGE(id)	((u32)((id) & 0xffff) <<  0)
-#define EPC_PNPTAACR	        (EPC_REG_BASE + 0x120)
-#define EPC_IECSR               (EPC_REG_BASE + 0x130)
+#define EPC_PNPTAACR(x)	        (EPC_REG_BASE + (0x120+((x)*0x80)))
+#define EPC_IECSR(x)            (EPC_REG_BASE + (0x130+((x)*0x80)))
 #define  EPC_IECSR_RETE         0x80000000   /*WOCL*/
 
 /* Peripheral Bus Bridge Specific Registers (0x2_0000-0x3_FFFC) */
@@ -247,7 +247,7 @@
 
 #define MISC_ERROR_INDICATION (MISC_FATAL | GRIO_INT | LL_TL_INT | \
 			       UNEXP_MSG_LOG | UNSP_RIO_REQ_INT | \
-			       RIO_MISC_UNEXP)
+			       UNEXP_MSG_INT)
 #define MISC_DB_EVENT (OB_DB_DONE_INT | IB_DB_RCV_INT)
 
 #else
@@ -394,22 +394,22 @@
 #define RIO_PRTOCCSR            0x124
 #define RIO_GCCSR		0x13c
 
-#define RIO_MNT_REQ_CSR         0x140
+#define RIO_MNT_REQ_CSR(x)      (0x140+((x)*0x20))
 #define  RIO_MNT_REQ_MASK       0x00000007
 #define  RIO_MNT_REQ_RST        0x00000003
 #define  RIO_MNT_REQ_STAT       0x00000004
 
-#define RIO_MNT_RSP_CSR         0x144
+#define RIO_MNT_RSP_CSR(x)      (0x144+((x)*0x20))
 #define  RIO_MNT_RSP_LS         0x0000001f
 #define  RIO_MNT_RSP_AS         0x000003e0
 #define  RIO_MNT_RSP_RV         0x80000000
 
-#define RIO_ACK_STS_CSR         0x148
+#define RIO_ACK_STS_CSR(x)      (0x148+((x)*0x20))
 #define  RIO_ACK_STS_IA         0x1f000000
 #define  RIO_ACK_STS_OUTA       0x00001f00
 #define  RIO_ACK_STS_OBA        0x0000001f
 
-#define RIO_ESCSR		0x158
+#define RIO_ESCSR(x)            (0x158+((x)*0x20))
 #define  RIO_ESCSR_OPD           0x04000000   /*WOCL*/
 #define  RIO_ESCSR_OFE           0x02000000   /*WOCL*/
 #define  RIO_ESCSR_ODE           0x01000000   /*WOCL*/
@@ -435,7 +435,7 @@
 		     RIO_ESCSR_ORS |		\
 		     RIO_ESCSR_OES)
 
-#define RIO_CCSR		0x15c
+#define RIO_CCSR(x)		(0x15c+((x)*0x20))
 #define  RIO_CCSR_PW             0xc0000000   /*R*/
 #define  RIO_CCSR_IPW            0x38000000   /*R*/
 #define  RIO_CCSR_PW_MASK        0x7
@@ -452,13 +452,14 @@
 
 #define RIO_PNPTAACR		0x10120
 
-#define RIO_OUTB_ATMU_WINDOWS   16
-
 
 /*************************************/
 /* *********** Constants *********** */
 /*************************************/
 
+#define RIO_OUTB_ATMU_WINDOWS   16
+
+#define LSI_AXXIA_RIO_COOKIE	0x41734230	/* aka 'AsR0' */
 
 /***********************************/
 /* *********** STRUCTS *********** */
@@ -487,9 +488,14 @@ struct rio_desc {
 };
 
 struct rio_priv {
+	u32     cookie;
+
 	spinlock_t rio_lock;
+
 	struct rio_mport *mport;
 	struct device *dev;
+	int  ndx;	/* From FDT description */
+	int  portNdx;
 
 	void __iomem *regs_win_fixed;
 	void __iomem *regs_win_paged;
diff --git a/drivers/rapidio/rio-locks.c b/drivers/rapidio/rio-locks.c
index 02c4e89..ef154a5 100644
--- a/drivers/rapidio/rio-locks.c
+++ b/drivers/rapidio/rio-locks.c
@@ -19,6 +19,7 @@
  */
 
 /* #define DEBUG */
+/* #define RIO_LOCK_DEBUG */
 
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -124,6 +125,7 @@ static int rio_hw_lock(struct rio_mport *port, u16 destid, u8 hopcount)
 
 	if (lock == port->host_deviceid)
 		goto lock_err;
+
 	/* Attempt to acquire device lock */
 	rc = rio_set_host_lock(port, destid, hopcount);
 	if (rc)
@@ -135,11 +137,11 @@ static int rio_hw_lock(struct rio_mport *port, u16 destid, u8 hopcount)
 	if (lock != port->host_deviceid)
 		goto to_err;
 
+done:
 #if defined(RIO_LOCK_DEBUG)
 	pr_debug("RIO: Device destid 0x%x hopcount %hhu locked by 0x%x\n",
 		 destid, hopcount, lock);
 #endif
-done:
 	spin_unlock(&rio_lock_lock);
 	return rc;
 
@@ -148,12 +150,13 @@ to_err:
 		 destid, hopcount, lock);
 	rc = -ETIME;
 	goto done;
+
 lock_err:
+	RAPIDIO_HW_LOCK_LOCK_ERR();
 	pr_debug("RIO: Device destid %hx hopcount %hhu is already locked by %hx\n",
 		 destid, hopcount, port->host_deviceid);
 	rc = -EFAULT;
 	goto done;
-
 }
 
 
@@ -626,11 +629,10 @@ int rio_clear_host_lock(struct rio_mport *port, u16 destid,
 done:
 	spin_unlock(&rio_lock_lock);
 	return rc;
-
 }
 
 /**
- * rio_unlock - Releases @host_device_lock for specified device
+ * rio_hw_unlock - Releases @host_device_lock for specified device
  *
  * @port: Master port to send transaction
  * @destid: Destination ID for device/switch
@@ -667,18 +669,22 @@ int rio_hw_unlock(struct rio_mport *port, u16 destid, u8 hopcount)
 
 	if (lock != 0xffff)
 		goto unlock_err;
+
+done:
 #if defined(RIO_LOCK_DEBUG)
 	pr_debug("RIO: Device destid %hx hopcount %hhu is unlocked by %hx\n",
 		 destid, hopcount, port->host_deviceid);
 #endif
-done:
 	spin_unlock(&rio_lock_lock);
 	return rc;
+
 lock_err:
+	RAPIDIO_HW_UNLOCK_LOCK_ERR();
 	pr_debug("RIO: release lock err - lock is not taken, destid %hx, hopcount %hhu, lock 0x%x",
 		 destid, hopcount, lock);
 	rc = -EINVAL;
 	goto done;
+
 unlock_err:
 	pr_debug("RIO: badness when releasing device lock %hx:%hhu\n",
 		 destid, hopcount);
diff --git a/drivers/rapidio/rio-locks.h b/drivers/rapidio/rio-locks.h
index d0cc151..cd7b3e2 100644
--- a/drivers/rapidio/rio-locks.h
+++ b/drivers/rapidio/rio-locks.h
@@ -1,6 +1,8 @@
 #ifndef _RIO_LOCK_H
 #define _RIO_LOCK_H
 
+#include <linux/sched.h>
+
 /*
  * RapidIO job support
  *
diff --git a/drivers/rapidio/rio-net2.c b/drivers/rapidio/rio-net2.c
index f9a8b1c..420efc1 100644
--- a/drivers/rapidio/rio-net2.c
+++ b/drivers/rapidio/rio-net2.c
@@ -598,6 +598,7 @@ static u8 __get_lock_mode(struct rio_mport *mport,
 	}
 	return lock_hw;
 }
+
 static int rio_enum_start(struct rio_job *job)
 {
 	int rc = -EFAULT;
@@ -719,6 +720,7 @@ static void rio_init_em(struct rio_dev *rdev)
 	if (rio_is_switch(rdev) && (rdev->em_efptr) && (rdev->rswitch->em_init))
 		rdev->rswitch->em_init(rdev);
 }
+
 static void rio_net_register_devices(struct rio_mport *mport)
 {
 	int i, num_dev = 0;
@@ -856,6 +858,7 @@ access_err:
 	goto out;
 
 lock_fault:
+	RAPIDIO_REDUNDANT_PATH_LOCK_FAULT();
 	pr_warn("RIO: %hu Unexpectedly owns lock on destid %hu hopcount %d\n",
 		lock, destid, hopcount);
 	rc = -EFAULT;
@@ -1301,6 +1304,7 @@ cleanup:
 
 	return ERR_PTR(rc);
 }
+
 static int rio_enum(struct rio_job *job,
 		    struct rio_dev *prev,
 		    u16 prev_destid, int prev_port,
@@ -1480,17 +1484,17 @@ static struct rio_dev *rio_enum_master_port(struct rio_job *job)
 		pr_warn("RIO: failed to init new net\n");
 		return ERR_PTR(rc);
 	}
+	/* Set master port destid and init destid ctr */
 	pr_debug("RIO:(%s) set master destid %hu\n",
 		 __func__, job->mport->host_deviceid);
-	/* Set master port destid and init destid ctr */
 	rio_set_master_destid(job->mport, job->mport->host_deviceid);
+	/* Set component tag for host */
 	pr_debug("RIO:(%s) set master comptag %d\n", __func__,
 		 job->mport->host_deviceid);
-	/* Set component tag for host */
 	rio_local_write_config_32(job->mport, RIO_COMPONENT_TAG_CSR,
 				  job->mport->host_deviceid);
-	pr_debug("RIO:(%s) enable master DIO\n", __func__);
 	/* Enable Input Output Port (transmitter reviever) */
+	pr_debug("RIO:(%s) enable master DIO\n", __func__);
 	rio_enable_dio(job->mport, 1, 0, 0, 0);
 	rdev = rio_setup_disc_mport(job->mport, 1);
 
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
index 6dceaa6..c6c44de 100644
--- a/drivers/rapidio/rio.h
+++ b/drivers/rapidio/rio.h
@@ -10,11 +10,15 @@
  * option) any later version.
  */
 
+#ifndef DRIVERS_RAPIDIO_RIO_H
+#define DRIVERS_RAPIDIO_RIO_H
+
 #include <linux/device.h>
 #include <linux/export.h>
 #include <linux/rwsem.h>
 #include <linux/list.h>
 #include <linux/rio.h>
+#include <asm/rio.h>
 
 #include "rio-hotplug.h"
 #include "rio-multicast.h"
@@ -105,3 +109,27 @@ extern struct rio_dev_fixup __end_rio_dev_fixup_enable[];
 					((x & 0x00ff0000) >> 16))
 #define RIO_SET_DID(size, x)	(size ? (x & 0xffff) : \
 					((x & 0x000000ff) << 16))
+
+/* ------------------------------------------------------------------------- */
+/*
+ * Patch Mechanism
+ *
+ * The following macros may be defined in the processor- or board-specific
+ * patch files to modify the operation of the generic RapidIO driver
+ * software.  If they are not defined, then the default operation will be
+ * performed.
+ */
+
+#ifndef RAPIDIO_REDUNDANT_PATH_LOCK_FAULT
+	#define RAPIDIO_REDUNDANT_PATH_LOCK_FAULT()
+#endif
+#ifndef RAPIDIO_HW_LOCK_LOCK_ERR
+	#define RAPIDIO_HW_LOCK_LOCK_ERR()
+#endif
+#ifndef RAPIDIO_HW_UNLOCK_LOCK_ERR
+	#define RAPIDIO_HW_UNLOCK_LOCK_ERR()
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#endif /* DRIVERS_RAPIDIO_RIO_H */
-- 
1.7.9.5



More information about the linux-yocto mailing list