From: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
Subject: OKI Semiconductor PCH CAN driver

This driver implements CAN controls for PCH.

Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
Acked-by: Wang Qi <qi.wang@intel.com>

---
 drivers/net/can/Kconfig                 |  5 ++
 drivers/net/can/Makefile                |  1
 drivers/net/can/pch_can/Makefile        |  7
 drivers/net/can/pch_can/pch_can_hal.c   |  4785
 drivers/net/can/pch_can/pch_can_hal.h   |  1407
 drivers/net/can/pch_can/pch_can_main.c  |  1681
 drivers/net/can/pch_can/pch_can_main.h  |  826
 drivers/net/can/pch_can/pch_can_pci.c   |  1134
 drivers/net/can/pch_can/pch_can_pci.h   |  105
 drivers/net/can/pch_can/pch_can_utils.c |  397
 drivers/net/can/pch_can/pch_can_utils.h |  127
 drivers/net/can/pch_can/pch_common.h    |  146
 drivers/net/can/pch_can/pch_debug.h     |  60
+++++++++++++++++++++++++++++++ 13 files changed, 10682 insertions(+)
diff -urN linux-2.6.33-rc3/drivers/net/can/Kconfig topcliff-2.6.33-rc3/drivers/net/can/Kconfig
--- linux-2.6.33-rc3/drivers/net/can/Kconfig	2010-01-06 09:02:46.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/can/Kconfig	2010-03-05 11:04:53.000000000 +0900
@@ -79,4 +79,9 @@
 	  a problem with CAN support and want to see more of what is going
 	  on.
 
+config PCH_CAN
+	tristate "PCH CAN"
+	---help---
+	  for PCH CAN
+
 endmenu
diff -urN linux-2.6.33-rc3/drivers/net/can/Makefile topcliff-2.6.33-rc3/drivers/net/can/Makefile
--- linux-2.6.33-rc3/drivers/net/can/Makefile	2010-01-06 09:02:46.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/can/Makefile	2010-03-05 23:15:46.000000000 +0900
@@ -15,5 +15,6 @@
 obj-$(CONFIG_CAN_TI_HECC)	+= ti_hecc.o
 obj-$(CONFIG_CAN_MCP251X)	+= mcp251x.o
 obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
+obj-$(CONFIG_PCH_CAN)		+= pch_can/
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff -urN linux-2.6.33-rc3/drivers/net/can/pch_can/Makefile topcliff-2.6.33-rc3/drivers/net/can/pch_can/Makefile
--- linux-2.6.33-rc3/drivers/net/can/pch_can/Makefile	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/can/pch_can/Makefile	2010-03-05 23:32:20.000000000 +0900
@@ -0,0 +1,7 @@
+ifeq ($(CONFIG_CAN_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+obj-$(CONFIG_PCH_CAN) += pch_can.o
+
+pch_can-objs := pch_can_utils.o pch_can_hal.o pch_can_pci.o pch_can_main.o
diff -urN linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_hal.c topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_hal.c
--- linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_hal.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_hal.c	2010-03-10 20:03:53.000000000 +0900
@@ -0,0 +1,4785 @@
+/*!
+ * @file ioh_can_hal.c
+ * @brief Provides the function definition for CAN HAL APIs.
+ * @version 1.0
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * <hr>
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ *
+ */
+
+/* includes */
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+
+#include "pch_common.h"
+#include "pch_debug.h"
+#include "pch_can_main.h"
+#include "pch_can_hal.h"
+#include "pch_can_utils.h"
+#include "pch_can_pci.h"
+
+#define COUNTER_LIMIT (0xFFFF)
+
+/*! @ingroup    Global
+	@var        ioh_msg_obj_conf
+	@brief      This variable is used to store the configuration
+				(receive /transmit) of the available message
+				 objects.
+	@remarks	This variable is used for storing the message object
+				configuration related information. It includes
+				 the
+				 information about which message object is used
+				 as
+				Receiver and Transmitter.
+	@note		The information is filled during the probe stage of
+				the device.
+
+	@see
+			- ioh_can_probe
+
+	<hr>
+*/
+unsigned int ioh_msg_obj_conf[MAX_MSG_OBJ] = {
+	3, 3, 3, 3,
+	3, 3, 3, 3,
+	3, 3, 3, 3,
+	3, 3, 3, 3,
+	3, 3, 3, 3,
+	3, 3, 3, 3,
+	3, 3, 3, 3,
+	3, 3, 3, 3
+};
+
+/*! @ingroup    HALLayerAPI
+    @fn         static int ioh_can_rx_enable_all(int handle)
+
+	<hr>
+*/
+static int ioh_can_rx_enable_all(int handle);
+
+/*! @ingroup    HALLayerAPI
+    @fn         static int ioh_can_tx_enable_all(int handle)
+
+	<hr>
+*/
+static int ioh_can_tx_enable_all(int handle);
+
+/*! @ingroup    HALLayerFacilitators
+	@var		restartMode
+    @brief      The variable used to store the restart mode.
+
+	<hr>
+*/
+static enum ioh_can_auto_restart restartMode = CAN_MANUAL;
+
+/*! @ingroup	InterfaceLayer
+	@struct		can_hw
+	@brief		This structure defines format for the storage of base
+			 address.
+
+	<hr>
+*/
+struct can_hw {
+	unsigned char *io_base;	/* Device registers  */
+};
+
+/* Array to store the timing settings. */
+/*! @ingroup    Global
+    @var       	can_rec_timing
+    @brief      This variable is used to store the time
+				settings of the CAN device.
+	@remarks	This variable is used for storing the timing
+				related information depending upon the
+				clock rate of the CAN device. It is used for
+				 setting the baud rate of the CAN device.
+
+	@see
+			-	ioh_can_pci_init
+			-	ioh_can_set_baud_simple
+
+	<hr>
+*/
+struct ioh_can_timing can_rec_timing[] = {
+	/*<Baud rate>   <BRP>   <TS1>   <TS2>   <SJW>           */
+	/* settings for 62.5MHz */
+	{0xa, 0x250, 0x7, 0x0, 0x0, 0x0, 0x0},	/**< 10 kbits/s 	*/
+	{0x14, 0x8D, 0xB, 0x5, 0x0, 0x0, 0x0},	/**< 20 kbits/s 	*/
+	{0x32, 0x5C, 0x7, 0x0, 0x0, 0x0, 0x0},	/**< 50 kbits/s 	*/
+	{0x7d, 0x18, 0xC, 0x5, 0x0, 0x0, 0x0},	/**< 125 kbits/s 	*/
+	{0xfa, 0x18, 0x7, 0x0, 0x0, 0x0, 0x0},	/**< 250 kbits/s 	*/
+	{0x1f4, 0x8, 0x9, 0x2, 0x0, 0x0, 0x0},	/**< 500 kbits/s 	*/
+	{0x320, 0x5, 0x8, 0x2, 0x0, 0x0, 0x0},	/**< 800 kbits/s  	*/
+	{0x3e8, 0x2, 0xC, 0x6, 0x0, 0x0, 0x0},	/**< 1000 kbits/s 	*/
+
+	/* settings for 24MHz */
+	{0xa, 0xCF, 0x7, 0x0, 0x0, 0x0, 0x0},	/**< 10 kbits/s 	*/
+	{0x14, 0x57, 0x7, 0x0, 0x0, 0x0, 0x0},	/**< 20 kbits/s 	*/
+	{0x32, 0xF, 0x7, 0x0, 0x0, 0x0, 0x0},	/**< 50 kbits/s 	*/
+	{0x7d, 0xF, 0x8, 0x1, 0x0, 0x0, 0x0},	/**< 125 kbits/s 	*/
+	{0xfa, 0x7, 0x8, 0x1, 0x0, 0x0, 0x0},	/**< 250 kbits/s 	*/
+	{0x1f4, 0x3, 0x8, 0x1, 0x0, 0x0, 0x0},	/**< 500 kbits/s 	*/
+	{0x320, 0x2, 0x7, 0x0, 0x0, 0x0, 0x0},	/**< 800 kbits/s  	*/
+	{0x3e8, 0x1, 0x8, 0x1, 0x0, 0x0, 0x0},	/**< 1000 kbits/s 	*/
+
+	/* settings for 50MHz */
+	{0xa, 0xFA, 0xC, 0x5, 0x1, 0x0, 0x0},	/**< 10 kbits/s 	*/
+	{0x14, 0x7D, 0xC, 0x5, 0x1, 0x0, 0x0},	/**< 20 kbits/s 	*/
+	{0x32, 0x32, 0xF, 0x2, 0x0, 0x0, 0x0},	/**< 50 kbits/s 	*/
+	{0x7d, 0x19, 0xC, 0x1, 0x0, 0x0, 0x0},	/**< 125 kbits/s 	*/
+	{0xfa, 0xA, 0xF, 0x2, 0x0, 0x0, 0x0},	/**< 250 kbits/s 	*/
+	{0x1f4, 0x5, 0xF, 0x2, 0x0, 0x0, 0x0},	/**< 500 kbits/s 	*/
+	{0x320, 0x5, 0x8, 0x2, 0x1, 0x0, 0x0},	/**< 800 kbits/s  	*/
+	{0x3e8, 0x2, 0xF, 0x7, 0x0, 0x0, 0x0}	/**< 1000 kbits/s 	*/
+	/* Add the new clock settings here. */
+};
+
+/*	The offset to the settings array depending on the clock rate entries.*/
+
+/*!	@ingroup	HALLayer
+	@def		IOH_CAN_CLOCK_DEFAULT_OFFSET
+	@brief		The default clock rate offset to the @ref
+			 can_rec_timing array.
+	@see		ioh_can_set_baud_simple
+
+	<hr>
+*/
+#define IOH_CAN_CLOCK_DEFAULT_OFFSET	(0)
+/*!	@ingroup	HALLayer
+	@def		IOH_CAN_CLOCK_62_5_OFFSET
+	@brief		The offset to the @ref can_rec_timing array when the
+				 clock
+				 rate is 62.5MHz.
+	@see		ioh_can_set_baud_simple
+
+	<hr>
+*/
+#define	IOH_CAN_CLOCK_62_5_OFFSET		(0)
+/*!	@ingroup	HALLayer
+	@def		IOH_CAN_CLOCK_24_OFFSET
+	@brief		The offset to the @ref can_rec_timing array when the
+			 clock
+			rate is 24MHz.
+	@see		ioh_can_set_baud_simple
+
+	<hr>
+*/
+#define	IOH_CAN_CLOCK_24_OFFSET			(8)
+
+/*!	@ingroup	HALLayer
+	@def		IOH_CAN_CLOCK_50_OFFSET
+	@brief		The offset to the @ref can_rec_timing array when the
+			 clock
+			rate is 24MHz.
+	@see		ioh_can_set_baud_simple
+
+	<hr>
+*/
+#define	IOH_CAN_CLOCK_50_OFFSET			(16)
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_create(u8 * io_base)
+	@brief		Creates a device handle for the other APIs.
+	@remarks
+				This function creates a device handle that can
+				 be used by
+				 other HAL APIs for accessing the device
+				 specific resources.
+				The main tasks performed by this function are :
+				- Allocates memory for the handle.
+				- Creates the handle and returns it to the
+				 called function.
+
+	@param		io_base		[@ref IN]	The remapped address
+							 for handle creation.
+
+	@retval		int <br>
+				- Handle to the device	--> Handle creation
+								 successful.
+				- @ref IOH_CAN_NULL --> Handle creation failed.
+
+	@see
+				- ioh_can_probe
+
+	<hr>
+*/
+int ioh_can_create(u8 *io_base)
+{
+	struct can_hw *can = NULL;
+	int retval = (int) IOH_CAN_NULL;
+
+	if (io_base == NULL) {
+		IOH_LOG(KERN_ERR, "ioh_can_create -> Invalid IO Base\n");
+	}
+
+	else {
+		/* Allocates memory for the handle. */
+		can = (struct can_hw *) CAN_MEM_ALLOC(sizeof(struct can_hw));
+
+		if (can == NULL) {	/* Allocation failed */
+			IOH_LOG(KERN_ERR,
+				"ioh_can_create -> CAN Memory allocation \
+				failed\n");
+		} else {	/* Allocation successful */
+
+			can->io_base = io_base;
+			retval = (int) can;
+			IOH_DEBUG
+			    ("ioh_can_create -> Handle Creation successful.\n");
+		}
+	}
+
+	IOH_DEBUG("ioh_can_create -> Return value: %x\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			void ioh_can_destroy(int handle)
+	@brief		Destroys (frees) the device handle.
+	@remarks	This function destroys the previously created handle of
+				 the
+				device. It also de-allocates the memory
+				 allocated during the
+				handle creation. The main tasks performed by
+				 this function
+				are :
+				- Verifies whether the passed argument is valid.
+				- If valid frees the allocated memory whose
+					 reference is
+					provided by the passed argument.
+
+	@param		handle		[@ref IN]	The device handle to be
+							 destroyed.
+
+	@retval		None.
+
+	@see
+				- ioh_can_remove
+
+	<hr>
+*/
+void ioh_can_destroy(int handle)
+{
+	struct can_hw *can = (struct can_hw *) handle;
+
+	if (handle != (int) 0) {
+		/*Free the memory for the handle. */
+		CAN_MEM_FREE(can);
+		IOH_DEBUG("ioh_can_destroy -> Free successful.\n");
+	} else {
+		IOH_LOG(KERN_ERR, "ioh_can_destroy -> Invalid handle.\n");
+	}
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_set_run_mode(
+				int handle,enum ioh_can_run_mode mode)
+	@brief      Set run/stop mode of the CAN device.
+	@remarks	This API set the CAN device in RUN/STOP mode. It does
+				 this only if the passed arguments are valid.
+				 The main tasks performed by this function are :
+				- Validates whether the passed arguments are
+					 valid. If invalid
+					error status code is returned.
+				- Depending on the mode to be set, suitably
+					 sets/resets the
+					INIT bit of the CANCONT register.
+					--> RUM Mode :	Resets the INIT bit.
+					--> STOP Mode:	Sets the INIT bit.
+
+	@param	handle		[@ref IN]	Handle to the device.
+	@param	mode		[@ref IN]	The mode to be set.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS --> If the operation is
+							 successful.
+			- @ref 	IOH_CAN_FAIL	--> If the operation fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_suspend
+			- ioh_can_resume
+
+	<hr>
+*/
+int ioh_can_set_run_mode(int handle, enum ioh_can_run_mode mode)
+{
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress = NULL;
+
+	if (handle == (int) 0) {	/* handle invalid */
+		IOH_LOG(KERN_ERR, "ioh_can_set_run_mode -> Invalid Handle \n");
+		retval = IOH_CAN_FAIL;
+	}
+
+	else {
+		/* Retrieving base address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		switch (mode) {
+		case IOH_CAN_RUN:
+			IOH_CAN_BIT_CLEAR((can_baseaddress + CAN_CONT_OFFSET),
+					  CAN_CTRL_INIT);
+			IOH_DEBUG
+			    ("ioh_can_set_run_mode -> Can set to RUN Mode.\n");
+			break;
+
+		case IOH_CAN_STOP:
+			IOH_CAN_BIT_SET((can_baseaddress + CAN_CONT_OFFSET),
+					CAN_CTRL_INIT);
+			IOH_DEBUG
+			    ("ioh_can_set_run_mode -> Can set to STOP Mode.\n");
+			break;
+
+		default:
+			IOH_LOG(KERN_ERR,
+				"ioh_can_set_run_mode -> Invalid run mode.\n");
+			retval = IOH_CAN_FAIL;
+			break;
+		}
+	}
+
+	IOH_DEBUG("ioh_can_set_run_mode -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_get_run_mode(int handle,enum
+				 ioh_can_run_mode *mode)
+	@brief      This function gets current the run/stop mode of the CAN
+				 device.
+	@remarks	Retrieves the current mode(RUN/STOP) of the device
+				 by checking the corresponding settings on the
+				 hardware.
+				The main tasks performed by this function are :
+				- Validates whether the passed arguments are
+					 valid. If invalid
+					returns the error status code.
+				- Depending on the INIT bit value of the CANCONT
+					 register
+					the appropriate mode is copied to the
+					 passed mode
+					reference variable passed as argument.
+
+					 INIT bit value 0:	RUN Mode.
+					 INIT bit value 1:	STOP mode.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	mode		[@ref OUT]	The current mode of the device.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_suspend
+
+	<hr>
+*/
+int ioh_can_get_run_mode(int handle, enum ioh_can_run_mode *mode)
+{
+	u32 reg_val;
+	struct can_hw *can;
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+
+	if ((handle == (int) 0) || (mode == NULL)) {	/* if invalid
+								 parameter. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_get_run_mode -> Invalid parameter.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the remap address for access. */
+		can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		reg_val = IOH_READ_LONG(can_baseaddress + CAN_CONT_OFFSET);
+
+		/* Checking the Init bit of Can Control Register.
+		   Init Bit 1 -> Stop
+		   Init Bit 0 -> Run
+		 */
+		if ((reg_val & CAN_CTRL_INIT) != 0) {
+			*mode = IOH_CAN_STOP;
+			IOH_DEBUG
+			    ("ioh_can_get_run_mode -> Mode is IOH_CAN_STOP\n");
+		} else {
+			*mode = IOH_CAN_RUN;
+			IOH_DEBUG
+			    ("ioh_can_get_run_mode -> Mode is IOH_CAN_RUN\n");
+		}
+	}
+
+	IOH_DEBUG("ioh_can_get_run_mode -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_set_arbiter_mode(
+					int handle,enum ioh_can_arbiter mode)
+	@brief      This function sets the arbiter mode of the CAN device.
+	@remarks	Sets the arbiter mode of the CAN device. The main tasks
+				 performed by this function are :
+				- Validates whether the passed arguments and
+				 mode are valid.
+				If invalid returns the error status code.
+				- Sets the arbiter mode.
+	@note		Only Fixed Priority mode is supported.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	mode		[@ref IN]	The arbiter mode to be set.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+int ioh_can_set_arbiter_mode(int handle, enum ioh_can_arbiter mode)
+{
+	int retval = IOH_CAN_SUCCESS;
+
+	if (handle == (int) 0) {	/* if invalid handle */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_set_arbiter_mode -> Invalid Handle\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/*      IOH CAN Controller supports only IOH_CAN_FIXED_PRIORITY
+		   arbiter mode.
+		 */
+		switch (mode) {
+		case IOH_CAN_FIXED_PRIORITY:
+			IOH_DEBUG("ioh_can_set_arbiter_mode -> FIXED "
+				  "PRIORITY is set for Arbiter mode\n");
+			break;
+
+		case IOH_CAN_ROUND_ROBIN:
+		default:
+			IOH_DEBUG("ioh_can_set_arbiter_mode -> "
+				  "Invalid arbiter mode\n");
+			retval = IOH_CAN_FAIL;
+			break;
+		}
+	}
+
+	IOH_DEBUG("ioh_can_set_arbiter_mode -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_get_arbiter_mode(
+					int handle,enum ioh_can_arbiter *mode
+	@brief      This function gets the arbiter mode of the CAN device.
+	@remarks	Gets the current arbiter mode of the CAN device. The
+				main tasks performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid returns the error status code.
+				- Copies the current arbiter mode to the passed
+				 mode reference variable.
+	@note		Only Fixed Priority mode is supported.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	mode		[@ref OUT]	The current arbiter mode of the
+						 device.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+int ioh_can_get_arbiter_mode(int handle, enum ioh_can_arbiter *mode)
+{
+	int retval = IOH_CAN_SUCCESS;
+
+	if ((handle == (int) 0) || (mode == NULL)) {	/* if invalid
+								 parameter. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_get_arbiter_mode -> Invalid parameter\n");
+		retval = IOH_CAN_FAIL;
+	}
+
+	else {
+		/*      IOH CAN Controller supports only IOH_CAN_FIXED_PRIORITY
+		   arbiter mode.
+		 */
+		*mode = IOH_CAN_FIXED_PRIORITY;
+		IOH_DEBUG("ioh_can_get_arbiter_mode -> Arbiter Mode "
+			  "is IOH_CAN_FIXED_PRIORITY\n");
+	}
+
+	IOH_DEBUG("ioh_can_get_arbiter_mode returns %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_set_restart_mode(int handle,enum
+						 ioh_can_auto_restart mode)
+	@brief		This function sets the restart mode of the CAN device.
+	@remarks	Sets the restart mode of the CAN device. The main
+				tasks performed by this function are :
+				- Validates whether the passed arguments and
+				 mode are valid.
+				If invalid returns the error status code.
+				- Updates the current restart mode variable
+	@ref restartMode
+				to given mode.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	mode		[@ref IN]	The restart mode to be set.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_open
+
+	<hr>
+*/
+int ioh_can_set_restart_mode(int handle,
+			     enum ioh_can_auto_restart mode)
+{
+	int retval = IOH_CAN_SUCCESS;
+
+	if (handle == (int) 0) {	/* if invalid handle. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_set_restart_mode -> Invalid Handle\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		switch (mode) {
+		case CAN_MANUAL:
+			restartMode = CAN_MANUAL;
+			IOH_DEBUG
+			    ("ioh_can_set_restart_mode -> Value of variable "
+			     " restartMode = 0. CAN_MANUAL mode set.\n");
+			break;
+
+		case CAN_AUTO:
+			restartMode = CAN_AUTO;
+			IOH_DEBUG
+			    ("ioh_can_set_restart_mode -> Value of variable "
+			     " restartMode = 1. CAN_AUTO mode set.\n");
+			break;
+
+		default:
+			IOH_DEBUG
+			    ("ioh_can_set_restart_mode -> Invalid restart \
+								mode\n");
+			retval = IOH_CAN_FAIL;
+			break;
+		}
+	}
+
+	IOH_DEBUG("ioh_can_set_restart_mode returns %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_get_restart_mode(
+				int handle,enum ioh_can_auto_restart *mode)
+	@brief      This function gets the restart mode of the CAN device.
+	@remarks	Retrieves the currently set restart mode. The main tasks
+				 performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid returns the error status code.
+				- Copies the current restart mode from the
+				 variable @ref restartMode
+				to the passed mode reference variable.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	mode		[@ref OUT]	Reference to current restart
+						 mode.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_callback
+
+	<hr>
+*/
+int ioh_can_get_restart_mode(int handle,
+				enum ioh_can_auto_restart *mode)
+{
+	int retval = IOH_CAN_SUCCESS;
+
+	if ((handle == (int) 0) || (mode == NULL)) {	/* if invalid
+								 parameter. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_get_restart_mode -> Invalid parameter.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		if (CAN_AUTO == restartMode) {	/* Auto restart mode */
+			*mode = CAN_AUTO;
+			IOH_DEBUG
+			    ("ioh_can_get_restart_mode -> Mode CAN_AUTO. \n");
+		} else {	/* Manual restart mode. */
+
+			*mode = CAN_MANUAL;
+			IOH_DEBUG
+			    ("ioh_can_get_restart_mode -> Mode CAN_MANUAL. \n");
+		}
+	}
+
+	IOH_DEBUG("ioh_can_get_restart_mode returns: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_set_listen_mode(
+				int handle, enum ioh_can_listen_mode mode
+	@brief      This function sets the listen/active mode of the CAN device.
+	@remarks	Sets the listen mode of the CAN device. The main tasks
+				performed by this function are :
+				- Validates whether the passed arguments and
+				 mode are valid.
+				If invalid returns the error status code.
+				- Depending on the obatined mode appropriately
+				 set/reset the
+				Silent bit of the CANOPT register.
+					Active Mode:	Reset Silent bit.
+					Silent Mode:	Set Silent bit.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	mode		[@ref OUT]	The listen mode to be set.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_open
+
+	<hr>
+*/
+int ioh_can_set_listen_mode(int handle, enum ioh_can_listen_mode mode)
+{
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+
+	if (handle == (int) 0) {	/* invalid handle. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_set_listen_mode -> Invalid Handle\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/*      Setting for Bit3 of Can Extended function register for
+			 appropriate mode.
+		   Silent bit = 0 (Active mode)
+		   Silent bit = 1 (Silent mode)
+		 */
+		switch (mode) {
+		case IOH_CAN_LISTEN:
+			IOH_CAN_BIT_SET((can_baseaddress + CAN_CONT_OFFSET),
+					CAN_CTRL_OPT);
+			IOH_CAN_BIT_SET((can_baseaddress + CAN_OPT_OFFSET),
+					CAN_OPT_SILENT);
+			IOH_DEBUG
+			    ("ioh_can_set_listen_mode -> IOH_CAN_LISTEN \
+								mode set.\n");
+			break;
+
+		case IOH_CAN_ACTIVE:
+			IOH_CAN_BIT_SET((can_baseaddress + CAN_CONT_OFFSET),
+					CAN_CTRL_OPT);
+			IOH_CAN_BIT_CLEAR((can_baseaddress + CAN_OPT_OFFSET),
+					  CAN_OPT_SILENT);
+			IOH_DEBUG
+			    ("ioh_can_set_listen_mode ->IOH_CAN_ACTIVE \
+								mode set.\n");
+			break;
+
+		default:
+			IOH_DEBUG
+			    ("ioh_can_set_listen_mode ->Invalid listen mode\n");
+			retval = IOH_CAN_FAIL;
+			break;
+		}
+	}
+
+	IOH_DEBUG("ioh_can_set_listen_mode -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_get_listen_mode(
+				int handle,enum ioh_can_listen_mode *mode)
+	@brief      This function gets the listen/active mode of the CAN device.
+	@remarks	Retrieves the currently set listen mode of the CAN
+				 device.
+				The main tasks performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				- Depending on the Silent bit value of the
+				 CANOPT register
+				appropriately copy the mode to mode reference
+				 variable.
+					Silent bit 0:	Active Mode.
+					Silent bit 1:	Silent mode.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	mode		[@ref OUT]	Reference to the current listen
+						 mode.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_suspend
+
+	<hr>
+*/
+int ioh_can_get_listen_mode(int handle, enum ioh_can_listen_mode *mode)
+{
+	u32 reg_val;
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+
+	if ((handle == (int) 0) || (mode == NULL)) {	/* if invalid
+								 parameters. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_get_listen_mode -> Invalid Parameter\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Attaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		reg_val = IOH_READ_LONG(can_baseaddress + CAN_OPT_OFFSET);
+
+		/*      Checking for Bit3 of Can Extended function register
+			 for silent mode
+		   Silent bit = 0 (Active mode)
+		   Silent bit = 1 (Silent mode)
+		 */
+
+		if ((reg_val & CAN_OPT_SILENT) != 0) {
+			*mode = IOH_CAN_LISTEN;
+			IOH_DEBUG
+			    ("ioh_can_get_listen_mode -> Mode is listen\n");
+		} else {
+			*mode = IOH_CAN_ACTIVE;
+			IOH_DEBUG
+			    ("ioh_can_get_listen_mode -> Mode is active\n");
+		}
+	}
+
+	IOH_DEBUG("ioh_can_get_listen_mode -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_set_int_custom(
+					int handle, u32 interrupts
+	@brief      This function sets which interrupts to enable.
+	@remarks	Sets the specified interrupts. The maisn tasks
+				performed by this funation are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid return the error status code.
+				- Depending on the obtained value set/reset the
+				 IE, SIE
+				and EIE bits of the CANCONT register.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	interrupts	[@ref IN]	The interrupts to be set.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_resume
+
+	<hr>
+*/
+int ioh_can_set_int_custom(int handle, u32 interrupts)
+{
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+
+	if (handle == (int) 0) {	/* invalid handle. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_set_int_custom -> Invalid Handle.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/* Clearing the IE, SIE and EIE bits of Can control register. */
+		IOH_CAN_BIT_CLEAR((can_baseaddress + CAN_CONT_OFFSET),
+				  CAN_CTRL_IE_SIE_EIE);
+
+		/* Appropriately setting them. */
+		IOH_CAN_BIT_SET((can_baseaddress + CAN_CONT_OFFSET),
+				((interrupts & MSK_CTRL_IE_SIE_EIE) <<
+				 BIT_SHIFT_ONE));
+		IOH_DEBUG("ioh_can_set_int_custom -> Interrupts set.\n");
+	}
+
+	IOH_DEBUG("ioh_can_set_int_custom -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_get_int_enables(
+				int handle,u32 *enables)
+	@brief      This function retrieves interrupt enabled for the CAN
+			 device.
+	@remarks	Retrieves the currently enabled interrupts. The main
+				 tasks performed by this function are ..
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid returns the error status code.
+				- Depending on the value of the IE, SIE and EIE
+				 bits
+				of the CANCONT register, determine which
+				 interrupts are
+				enabled and return information accordingly.
+				 The interrupts
+				 are enabled if the corresponding bit is set to
+				 1.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	enables		[@ref OUT]	The currently enabled
+						 interrupts.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_suspend
+
+	<hr>
+*/
+int ioh_can_get_int_enables(int handle, u32 *enables)
+{
+	u32 reg_ctrl_val;
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+
+	if ((handle == (int) 0) || (enables == NULL)) {	/* Invalid
+								 parameters. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_get_int_enables -> Invalid Parameter.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/* Reading the Can control register. */
+		reg_ctrl_val = IOH_READ_LONG(can_baseaddress + CAN_CONT_OFFSET);
+
+		/* Obtaining the status of IE, SIE and EIE interrupt bits. */
+		*enables =
+		    (((reg_ctrl_val & CAN_CTRL_IE_SIE_EIE) >> BIT_SHIFT_ONE));
+		IOH_DEBUG("ioh_can_get_int_enables -> Interrupt enabled "
+			  "value: %d\n", *enables);
+	}
+
+	IOH_DEBUG("ioh_can_get_int_enables -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_set_int_enables(
+				int handle,enum ioh_can_interrupt interrupt)
+	@brief		Sets interrupts.
+	@remarks    This function enables the desired interrupts of the CAN
+				 device.
+				The main tasks performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid returns the error status code.
+				- Depending on the obtained enum constants the
+				 EI, SIE and
+				EIE bits of the CANCONT register are set/reset.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	interrupt	[@ref IN]	The interrupt to be enabled.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_suspend
+			- ioh_can_open
+			- ioh_can_msg_tx
+
+	<hr>
+*/
+int ioh_can_set_int_enables(int handle,
+			    enum ioh_can_interrupt interrupt_no)
+{
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+
+	if (handle == (int) 0) {	/* invalid handle. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_set_int_enables -> Invalid Handle.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+
+		/* Obatining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/*
+		   Appropriately setting the IE, SIE and EIE bits of Can control
+			 register.
+		 */
+		switch (interrupt_no) {
+		case CAN_ENABLE:
+			IOH_CAN_BIT_SET((can_baseaddress + CAN_CONT_OFFSET),
+					CAN_CTRL_IE);
+			IOH_DEBUG
+			    ("ioh_can_set_int_enables -> CAN_ENABLE (IE) \
+							interrupt set.\n");
+			break;
+
+		case CAN_DISABLE:
+			IOH_CAN_BIT_CLEAR((can_baseaddress + CAN_CONT_OFFSET),
+					  CAN_CTRL_IE);
+			IOH_DEBUG
+			    ("ioh_can_set_int_enables -> CAN_DIABLE (IE) \
+							interrupt reset.\n");
+			break;
+
+		case CAN_ALL:
+			IOH_CAN_BIT_SET((can_baseaddress + CAN_CONT_OFFSET),
+					CAN_CTRL_IE_SIE_EIE);
+			IOH_DEBUG
+			    ("ioh_can_set_int_enables -> CAN_ALL (IE,SIE,EIE) \
+							interrupt set.\n");
+			break;
+
+		case CAN_NONE:
+			IOH_CAN_BIT_CLEAR((can_baseaddress + CAN_CONT_OFFSET),
+					  CAN_CTRL_IE_SIE_EIE);
+			IOH_DEBUG
+			    ("ioh_can_set_int_enables -> CAN_NONE (IE,SIE,EIE) \
+							interrupt reset.\n");
+			break;
+
+		default:
+			IOH_DEBUG
+			    ("ioh_can_set_int_enables -> Invalid parameter \
+							interrupt.\n");
+			retval = IOH_CAN_FAIL;
+			break;
+		}
+	}
+
+	IOH_DEBUG("ioh_can_set_int_enables -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			static int ioh_can_rx_enable_all(int handle)
+	@brief      This function enables all receive message objects of the CAN
+				 device.
+	@remarks	Enables all the receive message objects. The main tasks
+				performed by this function are :
+				- Validates whether the passed arguments are
+				 valid. If invalid returns the error status
+				 code.
+				- Enables all the message objects which are
+				 configured as receive objects by invoking
+	@ref ioh_can_set_rx_enable.
+				- If enabling of at least one message object is
+				 successful,
+				it returns success status code.
+
+
+	@param	handle		[@ref IN]	The handle to the device.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_open
+			- ioh_can_callback
+
+	<hr>
+*/
+static int ioh_can_rx_enable_all(int handle)
+{
+	u32 counter = 0;
+	int retval = IOH_CAN_SUCCESS;
+	u32 i;
+
+	if (handle == (int) 0) {	/* invalid handle. */
+		IOH_LOG(KERN_ERR, "ioh_can_rx_enable_all -> Invalid Handle.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Traversing to obtain the object configured as receivers. */
+		for (i = 0; i < (ioh_can_tx_buf_size + ioh_can_rx_buf_size);
+		     i++) {
+			if (ioh_msg_obj_conf[i] == MSG_OBJ_RX) {
+				/* Here i is the index, however (i+1) is object
+								 number. */
+				retval =
+				    ioh_can_set_rx_enable(handle, (i + 1),
+							  ENABLE);
+
+				if (IOH_CAN_FAIL == retval) {
+					IOH_DEBUG
+					    ("ioh_can_rx_enable_all -> Cannot "
+					     "Enable receive object%u\n",
+					     i + 1);
+					counter++;
+				} else {
+					IOH_DEBUG("ioh_can_rx_enable_all -> "
+						"Enabled receive object %u \n",
+						i + 1);
+				}
+			}
+		}
+
+		/* If enabling of all the receive object failed. */
+		if (counter == ioh_can_rx_buf_size) {
+			retval = IOH_CAN_FAIL;
+			IOH_LOG(KERN_ERR, "ioh_can_rx_enable_all failed. \n");
+		}
+	}
+
+	IOH_DEBUG("ioh_can_rx_enable_all -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_rx_disable_all(int handle)
+	@brief      This function disables all receive message objects of the
+		 CAN device.
+	@remarks	Disables all the receive message object. The main tasks
+				performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Disables all the receive message objects by
+				 invoking
+				@ref ioh_can_set_rx_enable.
+
+	@param	handle		[@ref IN]	The handle to the device.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_suspend
+			- ioh_can_callback
+
+	<hr>
+*/
+int ioh_can_rx_disable_all(int handle)
+{
+	u32 counter = 0;
+	int retval = IOH_CAN_SUCCESS;
+	u32 i;
+
+	if (handle == (int) 0) {	/* invalid handle. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_rx_disable_all -> Invalid Handle.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Traversing to obtain the object configured as receivers. */
+		for (i = 0; i < (ioh_can_rx_buf_size + ioh_can_tx_buf_size);
+		     i++) {
+			if (ioh_msg_obj_conf[i] == MSG_OBJ_RX) {
+				/* Here i is the index, however (i+1) is the
+							 object number. */
+				retval =
+				    ioh_can_set_rx_enable(handle, (i + 1),
+							  DISABLE);
+
+				if (IOH_CAN_FAIL == retval) {
+					IOH_DEBUG("ioh_can_rx_disable_all -> \
+						Disabling of Rx " \
+						"buffer %u failed.\n", (i + 1));
+					counter++;
+				} else {
+					IOH_DEBUG("ioh_can_rx_disable_all -> \
+						Disabled receive " \
+						"object %u \n", i + 1);
+				}
+			}
+		}
+
+		/* If disabling of all the receive object failed. */
+		if (counter == ioh_can_rx_buf_size) {
+			retval = IOH_CAN_FAIL;
+			IOH_LOG(KERN_ERR, "ioh_can_rx_disable_all failed. \n");
+		}
+	}
+
+	IOH_DEBUG("ioh_can_rx_disable_all -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			static int ioh_can_tx_enable_all(int handle)
+	@brief      This function enables all transmit buffers of the CAN
+			 device.
+	@remarks	Enables all the transmit message object. The main tasks
+				performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid returns the error status code.
+				- Enables all the message objects configured as
+				 transmit
+				objects by invoking @ref ioh_can_set_tx_enable.
+				- If enabling of at least on message object is
+				 successful,
+				it returns success status code.
+
+	@param	handle		[@ref IN]	The handle to the device.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_open
+			- ioh_can_callback
+
+	<hr>
+*/
+static int ioh_can_tx_enable_all(int handle)
+{
+	u32 counter = 0;
+	int retval = IOH_CAN_SUCCESS;
+	u32 i;
+
+	if (handle == (int) 0) {	/* invalid handle. */
+		IOH_LOG(KERN_ERR, "ioh_can_tx_enable_all -> Invalid Handle.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Traversing to obtain the object configured as transmit
+								 object. */
+		for (i = 0; i < (ioh_can_tx_buf_size + ioh_can_rx_buf_size);
+		     i++) {
+			if (ioh_msg_obj_conf[i] == MSG_OBJ_TX) {
+				/* Here i denotes the index, however (i+1) is
+							 the object number. */
+				retval =
+				    ioh_can_set_tx_enable(handle, (i + 1),
+							  ENABLE);
+
+				if (IOH_CAN_FAIL == retval) {
+					counter++;
+					IOH_DEBUG("ioh_can_tx_enable_all -> \
+					Cannot Enable " \
+					"transmit object %u\n", (i + 1));
+				} else {
+					IOH_DEBUG("ioh_can_tx_enable_all -> \
+					Enabled transmit " \
+					"object %u\n", (i + 1));
+				}
+			}
+		}
+
+		/* If enabling of all transmit object failed. */
+		if (counter == ioh_can_rx_buf_size) {
+			IOH_LOG(KERN_ERR, "ioh_can_tx_enable_all failed.\n");
+			retval = IOH_CAN_FAIL;
+		}
+
+	}
+
+	IOH_DEBUG("ioh_can_tx_enable_all -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_tx_disable_all(int handle)
+	@brief     This function enables all transmit buffers of the CAN device.
+	@remarks	Disables all the transmit message objects. The main
+				 tasks
+				performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Disables all the message object configured as
+				 transmit
+				objects by invoking @ref ioh_can_set_tx_enable.
+
+	@param	handle		[@ref IN]	The handle to the device.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_suspend
+			- ioh_can_callback
+
+	<hr>
+*/
+int ioh_can_tx_disable_all(int handle)
+{
+	u32 counter = 0;
+	int retval = IOH_CAN_SUCCESS;
+	u32 i;
+
+	if (handle == (int) 0) {	/* invalid handle. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_tx_disable_all -> Invalid Handle.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Traversing to obtain the object configured as transmit
+								 object. */
+		for (i = 0; i < (ioh_can_tx_buf_size + ioh_can_tx_buf_size);
+		     i++) {
+			if (ioh_msg_obj_conf[i] == MSG_OBJ_TX) {
+				/* Here i denotes the index, however (i+1) is
+							 the object number. */
+
+				/*Disabling. */
+				retval =
+				    ioh_can_set_tx_enable(handle, (i + 1),
+							  DISABLE);
+
+				if (IOH_CAN_FAIL == retval) {
+					IOH_DEBUG("ioh_can_tx_disable_all -> \
+					Disabling Tx " \
+					"buffer %u failed.\n", (i + 1));
+					counter++;
+				} else {
+					IOH_DEBUG("ioh_can_tx_disable_all -> \
+					Disabled transmit " \
+					"object %u \n", (i + 1));
+				}
+			}
+		}
+
+		/* If disabling of all the transmit object failed. */
+		if (counter == ioh_can_tx_buf_size) {
+			IOH_LOG(KERN_ERR, "ioh_can_tx_disable_all -> \
+				ioh_can_tx_disable_all failed.\n");
+			retval = IOH_CAN_FAIL;
+		}
+	}
+
+	IOH_DEBUG("ioh_can_tx_disable_all -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_rx_init_filter(
+						int handle,u32 buff_num)
+	@brief      This function sets the receive filter for a receive buffer
+			 of the CAN device.
+	@remarks	Initializes the filters for a specific receive message
+				 object.
+				The main tasks performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid returns error status code.
+				- Initializes the default filter settings for
+				 the
+				obtained receive object by invoking @ref
+				 ioh_can_set_rx_filter.
+	@note		The default filter settings is done so that the receive
+				 object can receive frames with any IDs.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	buff_num	[@ref IN]	The message object number.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_open
+
+	<hr>
+*/
+int ioh_can_rx_init_filter(int handle, u32 buff_num)
+{
+	int retval = IOH_CAN_SUCCESS;
+	struct ioh_can_rx_filter filter;
+
+	if (handle == (int) 0) {	/* if invalid handle. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_rx_init_filter -> Invalid Handle.\n");
+		retval = IOH_CAN_FAIL;
+	}
+	/* if invalid buffer number. */
+	else if ((ioh_msg_obj_conf[buff_num - 1] != MSG_OBJ_RX) ||
+		 (buff_num > (ioh_can_tx_buf_size + ioh_can_rx_buf_size))) {
+		IOH_LOG(KERN_ERR,
+			"ioh_can_rx_init_filter -> Invalid buffer no:%d\n",
+			buff_num);
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Set all Rx filters to allow all msgs. */
+		filter.amr.id = (u32) 0;
+		filter.amr.id_ext = (u32) 0;
+
+		filter.aidr.id = (u32) 0;
+		filter.aidr.id_ext = (u32) 0;
+
+		filter.num = buff_num;
+		filter.umask = 1;
+
+		retval = ioh_can_set_rx_filter(handle, &filter);
+	}
+
+	IOH_DEBUG("ioh_can_rx_init_filter -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_set_rx_enable(
+					int handle,u32 buff_num,u32 set)
+	@brief      This function enables or disables a particular receive
+			 buffer of the CAN device.
+	@remarks	Enables/Disables a specific receive message object. The
+				 main
+				tasks performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Depending on whether the message object has to
+				 enabled/disabled
+				the MsgVal and the RxIE bit of the message
+				 object are
+				set/reset.
+					To Enable :Set MsgVal and RxIE bits.
+					To Disable: Reset MsgVal and RxIE bits.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	buff_num	[@ref IN]	Message object number.
+	@param	set			[@ref IN]	Enable/Disable flag.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_rx_enable_all
+			- ioh_can_rx_disable_all
+
+	<hr>
+*/
+int ioh_can_set_rx_enable(int handle, u32 buff_num, u32 set)
+{
+	u32 counter;
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress = NULL;
+	u32 if1_creq;
+
+	if (handle == (int) 0) {	/* invalid handle. */
+		IOH_LOG(KERN_ERR, "ioh_can_set_rx_enable -> Invalid Handle.\n");
+		retval = IOH_CAN_FAIL;
+	}
+	/* if invalid buffer number. */
+	else if ((ioh_msg_obj_conf[buff_num - 1] != MSG_OBJ_RX) ||
+		 (buff_num > (ioh_can_tx_buf_size + ioh_can_rx_buf_size))) {
+		IOH_LOG(KERN_ERR, "ioh_can_set_rx_enable -> Message object %u "
+			"not configured for receive.\n", buff_num);
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/*Reading the receive buffer data from RAM to Interface1
+								 registers */
+		IOH_WRITE_LONG(CAN_CMASK_RX_TX_GET,
+			       (can_baseaddress + CAN_IF1_CMASK_OFFSET));
+		IOH_WRITE_LONG(buff_num,
+			       (can_baseaddress + CAN_IF1_CREQ_OFFSET));
+
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = \
+			(IOH_READ_LONG(can_baseaddress + CAN_IF1_CREQ_OFFSET))
+			& CAN_IF_CREQ_BUSY;
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+
+		if ((counter == 0)) {
+			IOH_LOG(KERN_ERR,
+				"ioh_can_set_rx_enable -> Cannot read "
+				"the message buffer object %u.\n", buff_num);
+			retval = IOH_CAN_FAIL;
+		}
+
+		else {		/*Reading successful */
+
+			/*Setting the IF1MASK1 register to access MsgVal and
+								 RxIE bits */
+			IOH_WRITE_LONG((CAN_CMASK_RDWR | CAN_CMASK_ARB |
+					CAN_CMASK_CTRL),
+				       (can_baseaddress +
+					CAN_IF1_CMASK_OFFSET));
+
+			if (set == ENABLE) {
+				/*Setting the MsgVal and RxIE bits */
+				IOH_CAN_BIT_SET((can_baseaddress +
+						 CAN_IF1_MCONT_OFFSET),
+						CAN_IF_MCONT_RXIE);
+				IOH_CAN_BIT_SET((can_baseaddress +
+						 CAN_IF1_ID2_OFFSET),
+						CAN_ID_MSGVAL);
+
+				IOH_DEBUG
+				    ("ioh_can_set_rx_enable -> Enabled receive "
+				     "message buffer %u.\n", buff_num);
+			} else if (set == DISABLE) {
+				/*Resetting the MsgVal and RxIE bits */
+				IOH_CAN_BIT_CLEAR((can_baseaddress +
+						   CAN_IF1_MCONT_OFFSET),
+						  CAN_IF_MCONT_RXIE);
+				IOH_CAN_BIT_CLEAR((can_baseaddress +
+						   CAN_IF1_ID2_OFFSET),
+						  CAN_ID_MSGVAL);
+
+				IOH_DEBUG
+				("ioh_can_set_rx_enable -> Disabled receive "
+				"message buffer %u", buff_num);
+			}
+
+			/*Updating the changes to the message object. */
+			IOH_WRITE_LONG(buff_num,
+				       (can_baseaddress + CAN_IF1_CREQ_OFFSET));
+
+			/*Confirming the write by checking the busy bit. */
+			counter = COUNTER_LIMIT;
+			while (counter) {
+				if1_creq = \
+					(IOH_READ_LONG(
+						can_baseaddress + \
+						CAN_IF1_CREQ_OFFSET)) \
+					& CAN_IF_CREQ_BUSY;
+				if (if1_creq == 0)
+					break;
+
+				counter--;
+			}
+
+
+			if ((counter == 0)) {
+				IOH_LOG(KERN_ERR,
+				"ioh_can_set_rx_enable -> Write failed.\n");
+				retval = IOH_CAN_FAIL;
+			}
+		}
+	}
+
+	IOH_DEBUG("ioh_can_set_rx_enable -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_get_rx_enable(
+				int handle,u32 buff_num,u32 *enable)
+	@brief      This function gets the enable state of a receive buffer.
+	@remarks	Retrieves the current state(Enabled/disabled) of a
+				 receive message object.
+				The main tasks performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Depending on the value of the MsgVal and the
+				 RxIE bits, the
+				enable/disable status is determined and passed
+				 to the function
+				calling this function.
+					MsgVal and RxIE bits set  :
+					The receive message object is enabled.
+					MsgVal and RxIE bits reset:
+					 The receive message object is disabled.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	buff_num	[@ref IN]	The message object number.
+	@param	enable		[@ref OUT]	The reference to the
+						 enable/disable flag.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_suspend
+
+	<hr>
+*/
+int ioh_can_get_rx_enable(int handle, u32 buff_num, u32 *enable)
+{
+	u8 *can_baseaddress;
+	int retval = IOH_CAN_SUCCESS;
+	u32 counter;
+	u32 if1_creq;
+
+	if ((handle == (int) 0) || (enable == NULL)) {	/* invalid parameter. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_get_rx_enable -> Invalid Parameter.\n");
+		retval = IOH_CAN_FAIL;
+	}
+	/* Invalid buffer number. */
+	else if ((ioh_msg_obj_conf[buff_num - 1] != MSG_OBJ_RX) ||
+		 (buff_num > (ioh_can_tx_buf_size + ioh_can_rx_buf_size))) {
+		IOH_LOG(KERN_ERR, "ioh_can_get_rx_enable -> Message object %u "
+			"not configured for receive.\n", buff_num);
+		retval = IOH_CAN_FAIL;
+	}
+
+	else {
+		/* Obtaining the remap address fro access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		IOH_WRITE_LONG(CAN_CMASK_RX_TX_GET,
+			       (can_baseaddress + CAN_IF1_CMASK_OFFSET));
+		IOH_WRITE_LONG(buff_num,
+			       (can_baseaddress + CAN_IF1_CREQ_OFFSET));
+
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = \
+			(IOH_READ_LONG((can_baseaddress + CAN_IF1_CREQ_OFFSET)))
+			& CAN_IF_CREQ_BUSY;
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		if (counter == 0) {
+			IOH_LOG(KERN_ERR,
+				"ioh_can_get_rx_enable -> Read Failed.\n");
+			retval = IOH_CAN_FAIL;
+		} else {
+			if (((IOH_READ_LONG
+			      (can_baseaddress +
+			       CAN_IF1_ID2_OFFSET)) & CAN_ID_MSGVAL)
+			    &&
+			    ((IOH_READ_LONG
+			      (can_baseaddress +
+			       CAN_IF1_MCONT_OFFSET)) & CAN_IF_MCONT_RXIE)) {
+				*enable = ENABLE;
+
+				IOH_DEBUG
+				    ("ioh_can_get_rx_enable -> Receive message "
+				     "buffer %u is enabled.\n", buff_num);
+			} else {
+				*enable = DISABLE;
+
+				IOH_DEBUG
+				    ("ioh_can_get_rx_enable -> Receive Message "
+				     "buffer %u is disabled.\n", buff_num);
+			}
+		}
+
+	}
+
+	IOH_DEBUG("ioh_can_get_rx_enable -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_set_tx_enable(
+					int handle, u32 buff_num,u32 set)
+	@brief      This function enables/disables a transmit message object.
+	@remarks	Enables/Disables a specific transmit message object. The
+				main tasks performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Depending whether to enable/disable the
+				 transmit object the
+				MsgVal and TxIE bits are set/reset.
+					To Enable :	Set the MsgVal and TxIE
+							 bits.
+					To disable:	Reset the MsgVal and
+							 RxIE bits.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	buff_num	[@ref IN]	The message object number.
+	@param	set			[@ref IN]	Enable/Disable flag.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_tx_enable_all
+			- ioh_can_tx_disable_all
+
+	<hr>
+*/
+int ioh_can_set_tx_enable(int handle, u32 buff_num, u32 set)
+{
+	u8 *can_baseaddress;
+	int retval = IOH_CAN_SUCCESS;
+	u32 counter;
+	u32 if1_creq;
+
+	if (handle == (int) 0) {	/* invalid handle. */
+		IOH_LOG(KERN_ERR, "ioh_can_set_tx_enable -> Invalid Handle");
+		retval = IOH_CAN_FAIL;
+	}
+	/* invalid buffer number. */
+	else if ((ioh_msg_obj_conf[buff_num - 1] != MSG_OBJ_TX) ||
+		 (buff_num > (ioh_can_rx_buf_size + ioh_can_tx_buf_size))) {
+		IOH_LOG(KERN_ERR, "ioh_can_set_tx_enable -> Message object %u "
+			"not configured for transmit.\n", buff_num);
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/*Reading the Message buffer from Message RAM to Interface2
+								 registers. */
+		IOH_WRITE_LONG(CAN_CMASK_RX_TX_GET,
+			       (can_baseaddress + CAN_IF1_CMASK_OFFSET));
+		IOH_WRITE_LONG(buff_num,
+			       (can_baseaddress + CAN_IF1_CREQ_OFFSET));
+
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = \
+			(IOH_READ_LONG(can_baseaddress + CAN_IF1_CREQ_OFFSET)) &
+			CAN_IF_CREQ_BUSY;
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		if ((counter == 0)) {
+			IOH_LOG(KERN_ERR, "ioh_can_set_tx_enable -> Reading "
+				"transmit buffer failed.\n");
+			retval = IOH_CAN_FAIL;
+		} else {	/*Reading successful. */
+
+			/*Setting the IF2CMASK register for accessing the MsgVal
+							 and TxIE bits */
+			IOH_WRITE_LONG((CAN_CMASK_RDWR | CAN_CMASK_ARB |
+					CAN_CMASK_CTRL),
+				       (can_baseaddress +
+					CAN_IF1_CMASK_OFFSET));
+
+			if (set == ENABLE) {
+				/*Setting the MsgVal and TxIE bits */
+				IOH_CAN_BIT_SET((can_baseaddress +
+						 CAN_IF1_MCONT_OFFSET),
+						CAN_IF_MCONT_TXIE);
+				IOH_CAN_BIT_SET((can_baseaddress +
+						 CAN_IF1_ID2_OFFSET),
+						CAN_ID_MSGVAL);
+
+				IOH_DEBUG
+				("ioh_can_set_tx_enable -> Enabled transmit "
+				"message buffer %u\n", buff_num);
+			} else if (set == DISABLE) {
+				/*Resetting the MsgVal and TxIE bits. */
+				IOH_CAN_BIT_CLEAR((can_baseaddress +
+						   CAN_IF1_MCONT_OFFSET),
+						  CAN_IF_MCONT_TXIE);
+				IOH_CAN_BIT_CLEAR((can_baseaddress +
+						   CAN_IF1_ID2_OFFSET),
+						  CAN_ID_MSGVAL);
+
+				IOH_DEBUG
+				("ioh_can_set_tx_enable -> Disabled transmit "
+				"message buffer %u\n", buff_num);
+			}
+
+			/*Updating the changes to the message buffer. */
+			IOH_WRITE_LONG(buff_num,
+				       (can_baseaddress + CAN_IF1_CREQ_OFFSET));
+
+			/*Confirming the updation. */
+			counter = COUNTER_LIMIT;
+			while (counter) {
+				if1_creq = \
+				(IOH_READ_LONG(
+					can_baseaddress + CAN_IF1_CREQ_OFFSET))
+				 & CAN_IF_CREQ_BUSY;
+				if (if1_creq == 0)
+					break;
+
+				counter--;
+			}
+
+			if ((counter == 0)) {	/*Updation failed. */
+				IOH_LOG(KERN_ERR,
+				"ioh_can_set_tx_enable -> Write failed.\n");
+				retval = IOH_CAN_FAIL;
+			}
+		}
+	}
+
+	IOH_DEBUG("ioh_can_set_tx_enable -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_get_tx_enable(
+					int handle,u32 buff_num,u32 *enable)
+	@brief      This function gets the enable/disable status of a transmit
+				 buffer.
+	@remarks	Retrieves the current state(enabled/disabled) of a
+				 transmit message object.
+				The main tasks performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Depending on the value of the MsgVal and the
+				 TxIE bits, the
+				 enable/disable status of the message object is
+				 determined and
+				 passed to the function calling this function.
+					MsgVal and TxIE bits set -->
+					 The transmit object is enabled.
+					MsgVal and TxIE bit reset-->
+					 The transmit object is disabled.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	buff_num	[@ref IN]	The message object number.
+	@param	enable		[@ref OUT]	The reference to the
+						 enable/disable flag.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_suspend
+
+	<hr>
+*/
+int ioh_can_get_tx_enable(int handle, u32 buff_num, u32 *enable)
+{
+	u8 *can_baseaddress;
+	int retval = IOH_CAN_SUCCESS;
+	u32 counter;
+	u32 if1_creq;
+
+	if ((handle == (int) 0) || (enable == NULL)) {	/* invalid
+								 parameters. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_get_tx_enable -> Invalid Parameter.\n");
+		retval = IOH_CAN_FAIL;
+	}
+	/* invalid buffer number. */
+	else if ((ioh_msg_obj_conf[buff_num - 1] != MSG_OBJ_TX) ||
+		 (buff_num > (ioh_can_rx_buf_size + ioh_can_tx_buf_size))) {
+		IOH_LOG(KERN_ERR, "ioh_can_get_tx_enable -> Invalid Message "
+			"object %u.\n", buff_num);
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the buffer number for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		IOH_WRITE_LONG(CAN_CMASK_RX_TX_GET,
+			       (can_baseaddress + CAN_IF1_CMASK_OFFSET));
+		IOH_WRITE_LONG(buff_num,
+			       (can_baseaddress + CAN_IF1_CREQ_OFFSET));
+
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = \
+			(IOH_READ_LONG(can_baseaddress + CAN_IF1_CREQ_OFFSET)) &
+			CAN_IF_CREQ_BUSY;
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		if (counter == 0) {
+			IOH_LOG(KERN_ERR,
+				"ioh_can_get_tx_enable -> Read Failed.\n");
+			retval = IOH_CAN_FAIL;
+		} else {
+			if (((IOH_READ_LONG
+			      (can_baseaddress +
+			       CAN_IF1_ID2_OFFSET)) & CAN_ID_MSGVAL)
+			    &&
+			    ((IOH_READ_LONG
+			      (can_baseaddress +
+			       CAN_IF1_MCONT_OFFSET)) & CAN_IF_MCONT_TXIE)) {
+				*enable = ENABLE;
+
+				IOH_DEBUG
+				("ioh_can_get_rx_enable -> Transmit message "
+				"buffer %u is enabled.\n", buff_num);
+			} else {
+				*enable = DISABLE;
+
+				IOH_DEBUG
+				("ioh_can_get_rx_enable -> Transmit message "
+				"buffer %u is disabled.\n", buff_num);
+			}
+		}
+	}
+
+	IOH_DEBUG("ioh_can_get_tx_enable -> Return value: %d.\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_int_pending(int handle)
+	@brief      This function returns whether or not interrupts are pending
+			 for the CAN device.
+	@remarks	Retrieves the pending interrupts. The main tasks
+				performed by this function are :
+				- Validates whether the passed arguments are
+				 valid. If
+				invalid error status code is returned.
+				- Reads the value of the CANINT register and
+				 returns it to the function calling this
+				 function.
+
+	@param	handle		[@ref IN]	The handle to the device.
+
+	@retval	int
+			- 0			--> No interrupts are pending
+			- >0			--> Interrupts are pending.
+			- @ref IOH_CAN_FAIL		--> Operation failed.
+
+	@see
+			- ioh_can_handler
+
+	<hr>
+*/
+int ioh_can_int_pending(int handle)
+{
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+
+	if (handle == (int) 0) {	/* invalid handle. */
+		IOH_LOG(KERN_ERR, "ioh_can_int_pending -> Invalid Handle.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obatining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		retval = (IOH_READ_LONG(can_baseaddress + CAN_INT_OFFSET) &
+			  MSK_ALL_SIXTEEN);
+	}
+
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_set_baud_simple(
+					int handle, enum ioh_can_baud baud)
+	@brief      This function sets the baud rate of the CAN device.
+	@remarks	Sets the Timing baud settings of the CAN device. The
+				main tasks performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Depending on the baud rate passed and the
+				 clock rate
+				the CANBITT and CANBRPE register values are
+				 determined and written to these registers.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	baud		[@ref IN]	The baud settings to be done.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_open
+
+	<hr>
+*/
+int ioh_can_set_baud_simple(int handle, enum ioh_can_baud baud)
+{
+	u32 reg_val;
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+
+	if (handle == (int) 0) {	/* invalid handle. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_set_baud_simple -> Invalid Handle.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		u32 offset;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/* Setting the CCE bit of Can control register for accessing the
+							 Timing Register. */
+		IOH_CAN_BIT_SET((can_baseaddress + CAN_CONT_OFFSET),
+				CAN_CTRL_CCE);
+
+		/* Calculating the offset of the settings array for the current
+								 clock.  */
+		switch (ioh_can_clock) {
+		case 62500:
+			offset = IOH_CAN_CLOCK_62_5_OFFSET;
+			break;
+
+		case 24000:
+			offset = IOH_CAN_CLOCK_24_OFFSET;
+			break;
+
+		case 50000:
+			offset = IOH_CAN_CLOCK_50_OFFSET;
+			break;
+
+			/*      The default section will not be invoked since
+							 the clock frequency
+			   has been validated at the module init procedure.
+			 */
+		default:
+			offset = IOH_CAN_CLOCK_DEFAULT_OFFSET;
+			break;
+		}
+
+		/* Getting the appropriate register value. */
+		reg_val =
+		    (((can_rec_timing[baud + offset].
+		       cfg_bitrate & MSK_BITT_BRP) << BIT_BITT_BRP) |
+		     (can_rec_timing[baud + offset].
+		      cfg_tseg1 << BIT_BITT_TSEG1) | (can_rec_timing[baud +
+								     offset].
+						      cfg_tseg2 <<
+						      BIT_BITT_TSEG2) |
+		     (can_rec_timing[baud + offset].cfg_sjw << BIT_BITT_SJW));
+
+		/* Writing to Can Timing register. */
+		IOH_WRITE_LONG(reg_val, (can_baseaddress + CAN_BITT_OFFSET));
+		/* Writing to the CAN BRP register. */
+		IOH_WRITE_LONG(((can_rec_timing[baud + offset].
+				 cfg_bitrate & MSK_BRPE_BRPE) >> BIT_BRPE_BRPE),
+			       (can_baseaddress + CAN_BRPE_OFFSET));
+
+		/* Resetting the CCE bit of the Can control register. */
+		IOH_CAN_BIT_CLEAR((can_baseaddress + CAN_CONT_OFFSET),
+				  CAN_CTRL_CCE);
+
+		IOH_DEBUG("ioh_can_set_baud_simple -> Timing Baud set.\n");
+		IOH_DEBUG("cfg_bitrate : %u\n",
+			  can_rec_timing[baud + offset].cfg_bitrate);
+		IOH_DEBUG("cfg_tseg1   : %u\n",
+			  can_rec_timing[baud + offset].cfg_tseg1);
+		IOH_DEBUG("cfg_tseg2   : %u\n",
+			  can_rec_timing[baud + offset].cfg_tseg2);
+		IOH_DEBUG("cfg_sjw     : %u\n",
+			  can_rec_timing[baud + offset].cfg_sjw);
+	}
+
+	IOH_DEBUG("ioh_can_set_baud_simple -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_set_baud_custom(
+				int handle,struct ioh_can_timing *timing)
+	@brief      This function sets a custom baud rate for the CAN device.
+	@remarks	Sets the user specified Timing baud settings. The main
+				 tasks
+				performed by this function are :
+				- Validates whether the passed arguments are
+				 valid. If
+				invalid error status code is returned.
+				- Depending on the user provided settings the
+				 CANBITT and CANBRPE
+				register values are determined and written to
+				 these registers.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	timing		[@ref IN]	The reference to the timing
+						 settings.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_resume
+
+	<hr>
+*/
+int ioh_can_set_baud_custom(int handle, struct ioh_can_timing *timing)
+{
+	u32 reg_val;
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+
+	if ((handle == (int) 0) || (timing == NULL)) {	/* invalid parameter. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_set_baud_custom -> Invalid parameter.\n");
+		retval = IOH_CAN_FAIL;
+	}
+	/* max is MAX_BITRATE */
+	else if (timing->bitrate > MAX_BITRATE) {
+		IOH_LOG(KERN_ERR, "ioh_can_set_baud_custom -> Bit rate %x "
+			"is invalid.\n", timing->bitrate);
+		retval = IOH_CAN_FAIL;
+	}
+
+	else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/* Setting the CCE bit of Can control register for accessing the
+							 Can Timing register. */
+		IOH_CAN_BIT_SET((can_baseaddress + CAN_CONT_OFFSET),
+				CAN_CTRL_CCE);
+
+		/* Obtaining the appropriate register value. */
+		reg_val =
+		    (((timing->
+		       cfg_bitrate & MSK_BITT_BRP) << BIT_BITT_BRP) | (timing->
+								cfg_tseg1
+								<<
+								BIT_BITT_TSEG1)
+		     | (timing->cfg_tseg2 << BIT_BITT_TSEG2) | (timing->
+								cfg_sjw <<
+								BIT_BITT_SJW));
+
+		/* Writing to the timing register. */
+		IOH_WRITE_LONG(reg_val, (can_baseaddress + CAN_BITT_OFFSET));
+		/* Writing to the BRP register. */
+		IOH_WRITE_LONG(((timing->
+				 cfg_bitrate & MSK_BRPE_BRPE) >> BIT_BRPE_BRPE),
+			       (can_baseaddress + CAN_BRPE_OFFSET));
+
+		/* Resetting the CCE bit. */
+		IOH_CAN_BIT_CLEAR((can_baseaddress + CAN_CONT_OFFSET),
+				  CAN_CTRL_CCE);
+
+		IOH_DEBUG("ioh_can_set_baud_custom -> Timing baud set.\n");
+		IOH_DEBUG("cfg_bitrate : %u\n", timing->cfg_bitrate);
+		IOH_DEBUG("cfg_tseg1   : %u\n", timing->cfg_tseg1);
+		IOH_DEBUG("cfg_tseg2   : %u\n", timing->cfg_tseg2);
+		IOH_DEBUG("cfg_sjw     : %u\n", timing->cfg_sjw);
+	}
+
+	IOH_DEBUG("ioh_can_set_baud_custom -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_get_baud(
+				int handle,struct ioh_can_timing *timing)
+	@brief      This function gets the baud rate for the CAN device.
+	@remarks	Retrieves the currently set timing baud settings. The
+				 main tasks
+				performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Depending on the CANBITT and CANBRPE register
+				 values
+				the different fields of the timing structure is
+				 filled
+				and returned to the function calling this
+				 function.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	timing		[@ref OUT]	The reference to the timing baud
+						 settings.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_suspend
+
+	<hr>
+*/
+int ioh_can_get_baud(int handle, struct ioh_can_timing *timing)
+{
+	u32 timing_bitt_reg;
+	u32 timing_brpe_reg;
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+
+	if ((handle == (int) 0) || (timing == NULL)) {	/* invalid
+								 parameters. */
+		IOH_LOG(KERN_ERR, "ioh_can_get_baud -> Invalid Parameter.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		timing_bitt_reg =
+		    IOH_READ_LONG(can_baseaddress + CAN_BITT_OFFSET);
+		timing_brpe_reg =
+		    IOH_READ_LONG(can_baseaddress + CAN_BRPE_OFFSET);
+
+		/* Separating the individual part from the values read. */
+		timing->cfg_bitrate = ((timing_bitt_reg & MSK_BITT_BRP) |
+				       ((timing_brpe_reg & MSK_BRPE_GET) <<
+					BIT_BRPE_BRPE));
+		timing->cfg_tseg1 =
+		    (timing_bitt_reg & MSK_BITT_TSEG1) >> BIT_BITT_TSEG1;
+		timing->cfg_tseg2 =
+		    (timing_bitt_reg & MSK_BITT_TSEG2) >> BIT_BITT_TSEG2;
+		timing->cfg_sjw =
+		    (timing_bitt_reg & MSK_BITT_SJW) >> BIT_BITT_SJW;
+
+		IOH_DEBUG
+		    ("ioh_can_get_baud -> The timing structure filled \
+							successfully.\n");
+		IOH_DEBUG("cfg_bitrate : %u\n", timing->cfg_bitrate);
+		IOH_DEBUG("cfg_tseg1   : %u\n", timing->cfg_tseg1);
+		IOH_DEBUG("cfg_tseg2   : %u\n", timing->cfg_tseg2);
+		IOH_DEBUG("cfg_sjw     : %u\n", timing->cfg_sjw);
+	}
+
+	IOH_DEBUG("ioh_can_get_baud -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_set_rx_filter(
+				int handle,struct ioh_can_rx_filter *filter)
+	@brief      This function sets the receive filter for a receive buffer
+			 of the CAN device.
+	@remarks	Sets the receive filter for a specific receive message
+				 object.
+				The main tasks performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Depending on the obtained filter settings, the
+				 acceptance
+				filter settings of the receive message object is
+				 updated.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	filter		[@ref IN]	the reference to the filter
+						 settings
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_rx_init_filter
+			- ioh_can_resume
+
+	<hr>
+*/
+int ioh_can_set_rx_filter(int handle, struct ioh_can_rx_filter *filter)
+{
+	u32 reg1;
+	u32 reg2;
+	u32 counter;
+	u8 *can_baseaddress = NULL;
+	int retval = IOH_CAN_SUCCESS;
+	u32 if1_creq;
+
+	if ((handle == (int) 0) || (filter == NULL)) {	/* invalid
+								 parameters. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_set_rx_filter -> Invalid Parameter.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		IOH_WRITE_LONG(CAN_CMASK_RX_TX_GET, \
+			(can_baseaddress + CAN_IF1_CMASK_OFFSET));
+				/*Setting the CMASK for reading */
+		IOH_WRITE_LONG(filter->num, \
+				(can_baseaddress + CAN_IF1_CREQ_OFFSET));
+				/*Setting CREQ to specified Msg Obj. */
+
+		/*Confirming the read completion. */
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = \
+			(IOH_READ_LONG(can_baseaddress + CAN_IF1_CREQ_OFFSET)) &
+			CAN_IF_CREQ_BUSY;
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		if ((counter == 0)) {	/*Read Unsuccessful. */
+			IOH_LOG(KERN_ERR, "ioh_can_set_rx_filter -> Reading "
+				"of message buffer %u failed.\n", filter->num);
+			retval = IOH_CAN_FAIL;
+		} else {	/*read successful. */
+
+			IOH_CAN_BIT_CLEAR((can_baseaddress + \
+					CAN_IF1_ID2_OFFSET), \
+					MSK_ALL_THIRTEEN);
+					/*Clearing the bit 0- 12 of ID2 */
+			IOH_CAN_BIT_CLEAR((can_baseaddress + \
+					CAN_IF1_ID2_OFFSET), \
+					CAN_ID2_XTD);
+					/*Clearing XTD bit */
+
+			if ((filter->aidr.id_ext == 1)) {	/*Extended ID */
+				reg1 = filter->aidr.id & MSK_ALL_SIXTEEN;
+								/*ID1 value. */
+				/*ID2 value with XTD bit set. */
+				reg2 =
+				    (((filter->aidr.
+				       id & (MSK_ALL_THIRTEEN <<
+					     BIT_SHIFT_SIXTEEN))
+				      >> BIT_SHIFT_SIXTEEN) | CAN_ID2_XTD);
+			} else {	/*Standard ID */
+
+				reg1 = 0;	/*ID1 value */
+				reg2 = ((filter->aidr.id & MSK_ALL_ELEVEN) << \
+						BIT_SHIFT_TWO);	/*ID2 value */
+			}
+
+			IOH_WRITE_LONG(reg1, (can_baseaddress + \
+					CAN_IF1_ID1_OFFSET));	/*Writing ID1 */
+			IOH_CAN_BIT_SET((can_baseaddress + \
+				CAN_IF1_ID2_OFFSET), reg2);	/*Writing ID2 */
+
+			if (filter->umask == 1) {
+				/*If mask has to be set. */
+				IOH_CAN_BIT_CLEAR((can_baseaddress + \
+				CAN_IF1_MASK2_OFFSET), MSK_ALL_THIRTEEN);
+						/*Clearing bit 0-12 */
+				IOH_CAN_BIT_CLEAR((can_baseaddress + \
+				CAN_IF1_MASK2_OFFSET), CAN_MASK2_MDIR_MXTD);
+						/*Clearing Mdir & MXtd */
+
+				if (filter->amr.id_ext == 1) {
+							/*Extended Mask */
+					reg1 = filter->amr.id & MSK_ALL_SIXTEEN;
+							/*Mask1 value */
+					/*Mask2 value with MXtd set */
+					reg2 =
+					    (((filter->amr.
+					       id & (MSK_ALL_THIRTEEN <<
+						     BIT_SHIFT_SIXTEEN))
+					      >> BIT_SHIFT_SIXTEEN) |
+					     CAN_IF_MASK2_MXTD);
+				} else {
+					reg1 = 0;	/*Mask1 value */
+					reg2 = ((filter->amr.id & \
+					MSK_ALL_ELEVEN) << BIT_SHIFT_TWO);
+								/*Mask2 Value */
+				}
+
+				IOH_WRITE_LONG(reg1, \
+				(can_baseaddress + CAN_IF1_MASK1_OFFSET));
+							/*Writing MASK1 */
+				IOH_CAN_BIT_SET((can_baseaddress + \
+					CAN_IF1_MASK2_OFFSET), reg2);
+							/*Writing MASK2 */
+				IOH_CAN_BIT_SET((can_baseaddress + \
+				CAN_IF1_MCONT_OFFSET), CAN_IF_MCONT_UMASK);
+							/*Setting Umask bit */
+			} else {
+				IOH_CAN_BIT_CLEAR((can_baseaddress + \
+				CAN_IF1_MCONT_OFFSET), CAN_IF_MCONT_UMASK);
+						/*Resetting Umask bit. */
+			}
+
+			/*Setting CMASK for writing */
+			IOH_WRITE_LONG((CAN_CMASK_RDWR | CAN_CMASK_MASK |
+					CAN_CMASK_ARB | CAN_CMASK_CTRL),
+				       (can_baseaddress +
+					CAN_IF1_CMASK_OFFSET));
+			IOH_WRITE_LONG(filter->num, (can_baseaddress + \
+					CAN_IF1_CREQ_OFFSET));
+					/*Setting CREQ for specified sg Obj. */
+
+			/*Confirming the write completion. */
+			counter = COUNTER_LIMIT;
+			while (counter) {
+				if1_creq = \
+				(IOH_READ_LONG
+					(can_baseaddress + CAN_IF1_CREQ_OFFSET))
+				 & CAN_IF_CREQ_BUSY;
+				if (if1_creq == 0)
+					break;
+
+				counter--;
+			}
+
+			if (counter == 0) {	/*Write failed */
+				IOH_LOG(KERN_ERR,
+					"ioh_can_set_rx_filter -> \
+						Write failed.\n");
+				retval = IOH_CAN_FAIL;
+			} else {	/*Write successful. */
+
+				IOH_DEBUG
+				("ioh_can_set_rx_filter -> Filter set \
+				successful "
+				"for message object %u.\n", filter->num);
+			}
+		}
+	}
+
+	IOH_DEBUG("ioh_can_set_rx_filter -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_set_rx_buffer_link(
+					int handle,u32 buffer_num,u32 seti)
+	@brief      This function sets receive buffer linking of the CAN device.
+	@remarks	Enables/disables the buffer link for specific receive
+					 buffer.
+				The main tasks performed by this function are :
+				- Validates whether the passed arguments are
+					 valid.
+				If invalid error status code is returned.
+				- Depending on whether to enable/disable buffer
+					 link the EOB
+				bit of the message object is set/reset.
+					Enable buffer link :	Reset the EOB
+								 bit.
+					Disable buffer link:	Set the EOB bit.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	buffer_num	[@ref IN]	The message object number.
+	@param	set		[@ref IN]	The enable/disable flag.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_resume
+
+	<hr>
+*/
+int ioh_can_set_rx_buffer_link(int handle, u32 buffer_num, u32 set)
+{
+	u32 counter;
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+	u32 if1_creq;
+
+	if (handle == (int) 0) {	/* if invalid handle. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_set_rx_buffer_link -> Invalid handle.\n");
+		retval = IOH_CAN_FAIL;
+	}
+	/* invalid buffer nummber. */
+	else if ((ioh_msg_obj_conf[buffer_num - 1] != MSG_OBJ_RX)
+		 || (buffer_num > (ioh_can_rx_buf_size + \
+		ioh_can_tx_buf_size))) {
+		IOH_LOG(KERN_ERR, "ioh_can_set_rx_buffer_link -> Invalid "
+			"buffer number %u.\n", buffer_num);
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/* Reading the corresponding object. */
+		IOH_WRITE_LONG(CAN_CMASK_RX_TX_GET,
+			       (can_baseaddress + CAN_IF1_CMASK_OFFSET));
+		IOH_WRITE_LONG(buffer_num,
+			       (can_baseaddress + CAN_IF1_CREQ_OFFSET));
+
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = \
+			IOH_READ_LONG((can_baseaddress + CAN_IF1_CREQ_OFFSET)) &
+			CAN_IF_CREQ_BUSY;
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		/* Confirming read. */
+		if ((counter == 0)) {
+			IOH_LOG(KERN_ERR,
+				"ioh_can_set_rx_buffer_link -> Read failed\n");
+			retval = IOH_CAN_FAIL;
+		} else {
+			IOH_WRITE_LONG((CAN_CMASK_RDWR | CAN_CMASK_CTRL),
+				       (can_baseaddress +
+					CAN_IF1_CMASK_OFFSET));
+
+			/*
+			   Setting/Resetting the EOD bit for Buffer link
+			 operation.
+			   EOB bit = 1 -> Buffer link disabled.
+			   EOB bit = 0 -> Biffer link enabled.
+			 */
+			if (set == ENABLE) {
+				IOH_CAN_BIT_CLEAR((can_baseaddress +
+						   CAN_IF1_MCONT_OFFSET),
+						  CAN_IF_MCONT_EOB);
+				IOH_DEBUG
+				    ("ioh_can_set_rx_buffer_link -> \
+					Buffer Link enabled.\n");
+			} else {
+				IOH_CAN_BIT_SET((can_baseaddress +
+						 CAN_IF1_MCONT_OFFSET),
+						CAN_IF_MCONT_EOB);
+				IOH_DEBUG
+				    ("ioh_can_set_rx_buffer_link -> \
+					Buffer Link disabled.\n");
+			}
+
+			IOH_WRITE_LONG(buffer_num,
+				       (can_baseaddress + CAN_IF1_CREQ_OFFSET));
+
+			counter = COUNTER_LIMIT;
+			while (counter) {
+				if1_creq = \
+					IOH_READ_LONG(
+					can_baseaddress + CAN_IF1_CREQ_OFFSET)
+					 & CAN_IF_CREQ_BUSY;
+				if (if1_creq == 0)
+					break;
+
+				counter--;
+			}
+
+			if (counter == 0) {
+				IOH_LOG(KERN_ERR,
+					"ioh_can_set_rx_buffer_link -> \
+					Write failed.\n");
+				retval = IOH_CAN_FAIL;
+			} else {
+				IOH_DEBUG
+				    ("ioh_can_set_rx_buffer_link -> \
+					Write successful.\n");
+				retval = IOH_CAN_SUCCESS;
+			}
+
+		}
+	}
+
+	IOH_DEBUG("ioh_can_set_rx_buffer_link -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_get_rx_buffer_link(
+				int handle,u32 buffer_num,u32 *link)
+	@brief      This function gets receive buffer linking of the CAN device.
+	@remarks	Retrieves the current buffer link state(
+				enabled/disabled) of a receive object.
+				The main tasks performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Depending on the value of the EOB bit, the
+				 enable/disable
+				status of the buffer link of the message object
+				 is determined
+				and returned to the function calling this
+				 function.
+					EOB bit set  :	Buffer link disabled.
+					EOB bit reset:	Buffer link enabled.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	buffer_num	[@ref IN]	The message object number.
+	@param	link		[@ref OUT]	The reference to the buffer link
+						 state.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_suspend
+
+	<hr>
+*/
+int ioh_can_get_rx_buffer_link(int handle, u32 buffer_num,
+			       u32 *link)
+{
+	u32 reg_val;
+	u32 counter;
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+	u32 if1_creq;
+
+	if ((handle == (int) 0) || (link == NULL)) {	/* invalid
+								 parameters. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_get_rx_buffer_link -> Invalid Parameter.\n");
+		retval = IOH_CAN_FAIL;
+	} else if ((ioh_msg_obj_conf[buffer_num - 1] != MSG_OBJ_RX) ||
+		   (buffer_num > (ioh_can_rx_buf_size + ioh_can_tx_buf_size))) {
+		IOH_LOG(KERN_ERR,
+			"ioh_can_get_rx_buffer_link -> Invalid buffer "
+			"number %u.\n", buffer_num);
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obatining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/* Reading the corresponding message object. */
+		IOH_WRITE_LONG(CAN_CMASK_RX_TX_GET,
+			       (can_baseaddress + CAN_IF1_CMASK_OFFSET));
+		IOH_WRITE_LONG(buffer_num,
+			       (can_baseaddress + CAN_IF1_CREQ_OFFSET));
+
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = \
+			(IOH_READ_LONG((can_baseaddress + CAN_IF1_CREQ_OFFSET))
+			 & CAN_IF_CREQ_BUSY);
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		/* Confirming read. */
+		if ((counter == 0)) {
+			IOH_LOG(KERN_ERR,
+				"ioh_can_get_rx_buffer_link -> Read Failed.\n");
+			retval = IOH_CAN_FAIL;
+		} else {
+			/* Checking for the EOB bit.
+			   EOB bit = 1 -> Buffer link disabled.
+			   EOB bit = 0 -> Biffer link enabled.
+			 */
+			reg_val =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF1_MCONT_OFFSET);
+			*link = (reg_val & CAN_IF_MCONT_EOB) ? DISABLE : ENABLE;
+
+			IOH_DEBUG("ioh_can_get_rx_buffer_link -> EOB bit =  "
+				  "%d\n",
+				  (reg_val & CAN_IF_MCONT_EOB) >>
+				  BIT_SHIFT_SEVEN);
+			IOH_DEBUG
+			    ("ioh_can_get_rx_buffer_link -> Buffer Link =  "
+			     "%u (1 - Set ,0 -> not set)\n", *link);
+		}
+	}
+
+	IOH_DEBUG("ioh_can_get_rx_buffer_link -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_get_rx_filter(
+				int handle,struct ioh_can_rx_filter *filter)
+	@brief      This function sets the receive filter for a receive buffer
+			 of the CAN device.
+	@remarks	Retrieves the current receive filter settings of a
+				 receive object.
+				The main tasks performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Depending on the settings of the acceptance
+				 filter the
+				filter structure is filled and returned to the
+				 function calling this function.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	filter		[@ref OUT]	the reference to the filter
+						 settings.
+
+	@retval
+			- @ref 	IOH_CAN_SUCCESS		--> If the operation is
+								 success.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_can_suspend
+	<hr>
+*/
+int ioh_can_get_rx_filter(int handle, struct ioh_can_rx_filter *filter)
+{
+	u32 reg_val1;
+	u32 reg_val2;
+	u32 counter;
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+	u32 if1_creq;
+
+	if ((handle == (int) 0) || (filter == NULL)) {	/* if invalid
+								 parameters. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_get_rx_filter -> Invalid Parameter.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/*Preparing to read the specified Msg Obj. */
+		IOH_WRITE_LONG(CAN_CMASK_RX_TX_GET,
+			       (can_baseaddress + CAN_IF1_CMASK_OFFSET));
+		IOH_WRITE_LONG(filter->num,
+			       (can_baseaddress + CAN_IF1_CREQ_OFFSET));
+
+		/*Confirming the read completion. */
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = \
+			(IOH_READ_LONG(can_baseaddress + CAN_IF1_CREQ_OFFSET)) &
+			CAN_IF_CREQ_BUSY;
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		if ((counter == 0)) {	/*Read unsuccessful. */
+			IOH_LOG(KERN_ERR,
+				"ioh_can_get_rx_filter -> Reading of receive \
+				buffer %u failed.\n",
+				filter->num);
+			retval = IOH_CAN_FAIL;
+		} else {	/*read successful. */
+
+			/*Checking for Umask */
+			reg_val1 =
+			    IOH_READ_LONG((can_baseaddress +
+					   CAN_IF1_MCONT_OFFSET));
+			filter->umask =
+			    ((CAN_IF_MCONT_UMASK & reg_val1) >>
+			     BIT_SHIFT_TWELVE);
+
+			if (1 == filter->umask) {	/*If Umask is set */
+				/* Getting the Mask data. */
+
+				/* Reading MASK2 register. */
+				reg_val1 =
+				    IOH_READ_LONG((can_baseaddress +
+						   CAN_IF1_MASK2_OFFSET));
+
+				if ((CAN_IF_MASK2_MXTD & reg_val1) != 0) {
+					/* Extended Mask set.
+							 Mask ID is 29 bits */
+					reg_val2 =
+					    IOH_READ_LONG((can_baseaddress +
+							CAN_IF1_MASK1_OFFSET));
+
+					/* Extracting the 16 MSB bits of the
+					 29bit ID. */
+					reg_val2 = reg_val2 & MSK_ALL_SIXTEEN;
+					/* Extracting the remaing 13 bits */
+					reg_val1 = reg_val1 & MSK_ALL_THIRTEEN;
+
+					/* Combing them to a single 29bit ID. */
+					reg_val1 =
+					    reg_val1 << BIT_SHIFT_SIXTEEN;
+					reg_val1 = reg_val1 | reg_val2;
+
+					filter->amr.id = reg_val1;
+					filter->amr.id_ext = 1;
+				} else {	/*Standard Mask 11bit Mask ID */
+
+					/* Extracting the 13 bits of MASK2
+								 register. */
+					reg_val1 = reg_val1 & MSK_ALL_THIRTEEN;
+
+					/* Modifying it to represent 11bit Mask
+									 ID */
+					reg_val1 = reg_val1 >> BIT_SHIFT_TWO;
+
+					filter->amr.id = reg_val1;
+					filter->amr.id_ext = 0;
+				}
+			}
+
+			reg_val1 =
+			    IOH_READ_LONG((can_baseaddress +
+					   CAN_IF1_ID2_OFFSET));
+
+			if ((CAN_ID2_XTD & reg_val1) != 0) {	/*Extended ID
+								 29bits */
+				reg_val2 =
+				    IOH_READ_LONG((can_baseaddress +
+						   CAN_IF1_ID1_OFFSET));
+
+				/* Extracting the 16 MSB bits of the 29bit
+									 ID. */
+				reg_val2 = reg_val2 & MSK_ALL_SIXTEEN;
+				/* Extracting the remaining 13 bit. */
+				reg_val1 = reg_val1 & MSK_ALL_THIRTEEN;
+
+				/* Combining them to represent 29bit ID. */
+				reg_val1 = reg_val1 << BIT_SHIFT_SIXTEEN;
+				reg_val1 = reg_val1 | reg_val2;
+
+				filter->aidr.id = reg_val1;
+				filter->aidr.id_ext = 1;
+			} else {	/*Standard Id 11bits. */
+
+				/* Extracting the 13 bits of ID2 register */
+				reg_val1 = reg_val1 & MSK_ALL_THIRTEEN;
+				/* Modifying it to represent the 11 bit ID */
+				reg_val1 = reg_val1 >> BIT_SHIFT_TWO;
+
+				filter->aidr.id = reg_val1;
+				filter->aidr.id_ext = 0;
+			}
+
+			IOH_DEBUG("ioh_can_get_rx_filter -> Successfully read "
+				  "the filter of Msg Obj %u.\n", filter->num);
+		}
+	}
+
+	IOH_DEBUG("ioh_can_get_rx_filter -> Return value: %d.\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_open(
+	int handle,enum ioh_can_listen_mode listen,enum ioh_can_arbiter arbiter)
+	@brief      This function opens the CAN device for read/write.
+	@remarks	Opens and initializes the CAN hardware devices for use.
+				The main tasks performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Configures the Receive and Transmit message
+				 objects.
+				- Initializes the acceptance filter setting of
+				 the
+				Receive message objects.
+				- Enables all the Receive and Transmit message
+				 objects.
+				- Sets the baud rate to 500Kbps.
+				- Sets the restart mode to Auto.
+				- Sets the CAN device to RUN mode.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	listen		[@ref IN]	The listen mode to be set.
+	@param	arbiter		[@ref IN]	The arbiter mode to be set.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_candev_open
+
+	<hr>
+*/
+int ioh_can_open(int handle, enum ioh_can_listen_mode listen,
+		 enum ioh_can_arbiter arbiter)
+{
+	int retval;
+	s32 i;
+
+	if (handle == (int) 0) {	/* invalid handle. */
+		IOH_LOG(KERN_ERR, "ioh_can_open -> Invalid handle.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		do {
+
+			/* Stopping the Can device. */
+			retval = ioh_can_set_run_mode(handle, IOH_CAN_STOP);
+			if (retval == IOH_CAN_FAIL) {
+				IOH_LOG(KERN_ERR,
+					"ioh_can_open -> ioh_can_set_run_mode "
+					"failed(returned %d).\n", retval);
+
+				break;
+			}
+			IOH_DEBUG
+			    ("ioh_can_open -> ioh_can_set_run_mode invoked \
+							successfully.\n");
+
+			/* Clearing all the message object buffers. */
+			retval = ioh_can_clear_buffers(handle);
+			if (retval == IOH_CAN_FAIL) {
+				IOH_LOG(KERN_ERR,
+					"ioh_can_open -> ioh_can_clear_buffers "
+					"failed(returned %d).\n", retval);
+				break;
+			}
+			IOH_DEBUG
+			    ("ioh_can_open -> ioh_can_clear_buffers invoked "
+			     "successfully(returned %d).\n", retval);
+
+			/* Configuring the respective message object as either
+						 receive/transmit object. */
+			ioh_can_config_rx_tx_buffers(handle);
+			IOH_DEBUG
+			    ("ioh_can_open -> ioh_can_config_rx_tx_buffers "
+			     "invoked successfully.\n");
+
+			/* Initializing filters for receive object. */
+			for (i = 0;
+			     i < (ioh_can_tx_buf_size + ioh_can_rx_buf_size);
+			     i++) {
+				if (ioh_msg_obj_conf[i] == MSG_OBJ_RX) {
+					/* Here i denotes the index, however
+						 the object number is (i+1) */
+					retval =
+					    ioh_can_rx_init_filter(handle,
+								   (i + 1));
+
+					if (retval != IOH_CAN_SUCCESS) {
+						IOH_LOG(KERN_ERR,
+						"ioh_can_rx_init_filter "
+						"failed for msg obj:%d\n",
+						(i + 1));
+						break;
+					}
+				}
+			}
+			if (retval != IOH_CAN_SUCCESS)
+				break;
+			IOH_DEBUG("ioh_can_open -> ioh_can_rx_init_filter "
+				  "invoked successfully.\n");
+
+			/* Enabling all receive objects. */
+			retval = ioh_can_rx_enable_all(handle);
+
+			if (retval == IOH_CAN_FAIL) {
+				IOH_LOG(KERN_ERR,
+					"ioh_can_open -> ioh_can_rx_enable_all "
+					"failed(returned %d).\n", retval);
+				break;
+			}
+			IOH_DEBUG("ioh_can_open -> ioh_can_rx_enable_all "
+				  "invoked successfully(returned %d).\n",
+				  retval);
+
+			/* Enabling all transmit objects. */
+			retval = ioh_can_tx_enable_all(handle);
+
+			if (retval == IOH_CAN_FAIL) {
+				IOH_LOG(KERN_ERR,
+					"ioh_can_open -> ioh_can_tx_enable_all "
+					"failed(returned %d).\n", retval);
+				break;
+			}
+			IOH_DEBUG("ioh_can_open -> ioh_can_tx_enable_all "
+				  "invoked successfully(returned %d).\n",
+				  retval);
+
+			/* Setting the Baud Timing. */
+			retval =
+			    ioh_can_set_baud_simple(handle, IOH_CAN_BAUD_500);
+			if (retval == IOH_CAN_FAIL) {
+				IOH_LOG(KERN_ERR,
+				"ioh_can_open -> ioh_can_set_baud_simple "
+				"failed(returned %d).\n", retval);
+				break;
+			}
+			IOH_DEBUG("ioh_can_open -> ioh_can_set_baud_simple "
+				  "invoked successfully(returned %d).\n",
+				  retval);
+
+			/* Setting the arbiter mode. */
+			retval = ioh_can_set_arbiter_mode(handle, arbiter);
+			if (retval == IOH_CAN_FAIL) {
+				IOH_LOG(KERN_ERR,
+				"ioh_can_open -> ioh_can_set_arbiter_mode "
+				"failed(returned %d).\n", retval);
+				break;
+			}
+			IOH_DEBUG
+			    ("ioh_can_open -> ioh_can_set_arbiter_mode invoked "
+			     "successfully(returned %d).\n", retval);
+
+			/* Setting the listen mode. */
+			retval = ioh_can_set_listen_mode(handle, listen);
+			if (retval == IOH_CAN_FAIL) {
+				IOH_LOG(KERN_ERR,
+				"ioh_can_open -> ioh_can_set_listen_mode "
+				"failed(returned %d).\n", retval);
+				break;
+			}
+			IOH_DEBUG("ioh_can_open -> ioh_can_set_listen_mode "
+				  "invoked successfully(returned %d).\n",
+				  retval);
+
+			/* Enabling the interrupts. */
+			retval = ioh_can_set_int_enables(handle, CAN_ALL);
+			if (retval == IOH_CAN_FAIL) {
+				IOH_LOG(KERN_ERR,
+				"ioh_can_open -> ioh_can_set_int_enables "
+				"failed(returned %d).\n", retval);
+				break;
+			}
+			IOH_DEBUG("ioh_can_open -> ioh_can_set_int_enables "
+				  "invoked successfully(returned %d).\n",
+				  retval);
+
+			/* Setting the restart mode. */
+			retval = ioh_can_set_restart_mode(handle, CAN_AUTO);
+			if (retval == IOH_CAN_FAIL) {
+				IOH_LOG(KERN_ERR,
+				"ioh_can_open -> ioh_can_set_restart_mode "
+				"failed(returned %d).\n", retval);
+				break;
+			}
+			IOH_DEBUG("ioh_can_open -> ioh_can_set_restart_mode "
+				  "invoked successfully(returned %d).\n",
+				  retval);
+
+			/* Setting the CAN to run mode. */
+			retval = ioh_can_set_run_mode(handle, IOH_CAN_RUN);
+			if (retval == IOH_CAN_FAIL) {
+				IOH_LOG(KERN_ERR,
+					"ioh_can_open -> ioh_can_set_run_mode "
+					"failed(returned %d).\n", retval);
+				break;
+			}
+			IOH_DEBUG("ioh_can_open -> ioh_can_set_set_run_mode "
+				  "invoked successfully(returned %d).\n",
+				  retval);
+
+		} while (false);
+	}
+
+	IOH_DEBUG("ioh_can_open returns %d.\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_release(int handle)
+	@brief      This function releases (closes) the CAN device. Call to
+			 close an opened CAN device.
+	@remarks	De-initializes the CAN device. The main tasks performed
+				by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Sets the CAN device to STOP mode.
+				- Disables the interrupts.
+				- Disables all the receive message objects.
+				- Disables all the transmit message objects.
+
+	@param	handle		[@ref IN]	The handle to the device.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+							 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+							 fails.
+
+	@see
+			- ioh_candev_close
+
+	<hr>
+*/
+int ioh_can_release(int handle)
+{
+	int retval = IOH_CAN_SUCCESS;
+
+	if (handle == (int) 0) {
+		IOH_LOG(KERN_ERR, "ioh_can_release -> Invalid handle.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		do {
+			/* Stooping the CAN device. */
+			retval = ioh_can_set_run_mode(handle, IOH_CAN_STOP);
+
+			if (IOH_CAN_FAIL == retval) {
+				IOH_LOG(KERN_ERR,
+				"ioh_can_release -> ioh_can_set_run_mode "
+				"failed(returned %d).\n", retval);
+				break;
+			}
+			IOH_DEBUG
+			    ("ioh_can_release -> ioh_can_set_run_mode invoked "
+			     "successfully(returned %d).\n", retval);
+
+			/* Disabling the interrupts. */
+			retval = ioh_can_set_int_enables(handle, CAN_NONE);
+
+			if (IOH_CAN_FAIL == retval) {
+				IOH_LOG(KERN_ERR,
+				"ioh_can_release -> ioh_can_set_int_enables "
+				"failed(returned %d).\n", retval);
+				break;
+			}
+			IOH_DEBUG
+			("ioh_can_release -> ioh_can_set_int_enables invoked "
+			"successfully(returned %d).\n", retval);
+
+			/* Disabling all the receive object. */
+			retval = ioh_can_rx_disable_all(handle);
+			if (IOH_CAN_FAIL == retval) {
+				IOH_LOG(KERN_ERR,
+				"ioh_can_release -> ioh_can_rx_disable_all "
+				"failed(returned %d).\n", retval);
+				break;
+			}
+			IOH_DEBUG
+			("ioh_can_release -> ioh_can_rx_disable_all invoked "
+			"successfully(returned %d).\n", retval);
+
+			/* Disabling all the transmit object. */
+			retval = ioh_can_tx_disable_all(handle);
+			if (IOH_CAN_FAIL == retval) {
+				IOH_LOG(KERN_ERR,
+				"ioh_can_release -> ioh_can_tx_disable_all "
+				"failed(returned %d).\n", retval);
+				break;
+			}
+			IOH_DEBUG
+			("ioh_can_release -> ioh_can_tx_disable_all invoked "
+			"successfully(returned %d).\n", retval);
+
+		} while (false);
+	}
+
+	IOH_DEBUG("ioh_can_release returns %d.\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			void ioh_can_int_clr(int handle,u32 mask)
+	@brief      This function clears interrupt(s) from the CAN device.
+	@remarks	Clears the interrupt. The main tasks performed by this
+				function are :
+				- If the interrupt is status interrupt, clear it
+				 by reading the CANSTAT register.
+				- If the interrupt is message object interrupt
+				 clear it by
+				determining whether it is a transmit/receive
+				 message
+				object and appropriately clearing the IntPnd,
+				 NewDat and
+				TxRqst bits.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	mask		[@ref IN]	The interrupts to be cleared.
+
+	@retval	None.
+
+	@see
+			- ioh_can_callback
+
+	<hr>
+*/
+void ioh_can_int_clr(int handle, u32 mask)
+{
+	u32 counter;
+#ifdef DEBUG
+	u32 rtr;
+#endif
+	u8 *can_baseaddress;
+	u32 if2_creq;
+
+	if ((handle != (int) 0) && (mask != 0)) {	/* if valid
+								 parameters. */
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/* Clearing status interrupt. */
+		if (mask == CAN_STATUS_INT) {
+			IOH_READ_LONG((can_baseaddress + CAN_STAT_OFFSET));
+			IOH_DEBUG
+			    ("ioh_can_int_clr -> Status Interrupt cleared.\n");
+		} else if ((mask > 0) && (mask <= MAX_MSG_OBJ)) {
+			/*Clear interrupt for transmit object */
+			if (ioh_msg_obj_conf[mask - 1] == MSG_OBJ_TX) {
+#ifdef DEBUG
+				/* Checking if the transmission is for remote
+								 frame. */
+				rtr =
+				    ((IOH_READ_LONG
+				      ((can_baseaddress +
+					CAN_IF2_ID2_OFFSET)) & CAN_ID2_DIR) ==
+				     0);
+
+				if (rtr == 1) {
+
+					IOH_DEBUG
+					    ("ioh_can_int_clr -> Remote frame \
+						transmission "
+					     "interrupt cleared for message \
+						object "
+					     "%d.\n", mask);
+				} else {
+					IOH_DEBUG
+					    ("ioh_can_int_clr -> \
+						Data frame transmission "
+					     "interrupt cleared for message \
+						object "
+					     "%d.\n", mask);
+				}
+#endif
+
+				/*Setting CMASK for clearing interrupts for
+							 frame transmission. */
+				IOH_WRITE_LONG((CAN_CMASK_RDWR | CAN_CMASK_CTRL
+						| CAN_CMASK_ARB),
+					       (can_baseaddress +
+						CAN_IF2_CMASK_OFFSET));
+
+				/* Resetting the ID registers. */
+				IOH_CAN_BIT_SET((can_baseaddress +
+						 CAN_IF2_ID2_OFFSET),
+						(CAN_ID2_DIR |
+						 (MSK_ALL_ELEVEN << 2)));
+				IOH_WRITE_LONG(0x0,
+					       (can_baseaddress +
+						CAN_IF2_ID1_OFFSET));
+
+				/*Claring NewDat, TxRqst & IntPnd */
+				IOH_CAN_BIT_CLEAR((can_baseaddress +
+						   CAN_IF2_MCONT_OFFSET),
+						  (CAN_IF_MCONT_NEWDAT |
+						   CAN_IF_MCONT_INTPND |
+						   CAN_IF_MCONT_TXRQXT));
+
+				IOH_WRITE_LONG(mask,
+					       (can_baseaddress +
+						CAN_IF2_CREQ_OFFSET));
+
+				counter = COUNTER_LIMIT;
+				while (counter) {
+					if2_creq = \
+						(IOH_READ_LONG
+							(can_baseaddress
+							 + CAN_IF2_CREQ_OFFSET)
+						& CAN_IF_CREQ_BUSY);
+					if (if2_creq == 0)
+						break;
+
+					counter--;
+				}
+
+
+			}
+			/*Clear interrupt for receive object */
+			else if (ioh_msg_obj_conf[mask - 1] == MSG_OBJ_RX) {
+#ifdef DEBUG
+				/* Checking if the reception is for remote
+								 frame. */
+				rtr =
+				    ((IOH_READ_LONG
+				      ((can_baseaddress +
+					CAN_IF2_ID2_OFFSET)) & CAN_ID2_DIR) !=
+				     0);
+
+				if (rtr == 1) {	/*if remote frame. */
+					IOH_DEBUG
+					("ioh_can_int_clr -> Remote frame \
+						reception "
+						"interrupt cleared for message \
+						object "
+						"%d.\n", mask);
+				} else {
+					IOH_DEBUG
+					("ioh_can_int_clr -> Data frame \
+						reception "
+						"interrupt cleared for message \
+						object "
+						"%d.\n", mask);
+				}
+#endif
+
+				/*Setting CMASK for clearing the reception
+								 interrupts. */
+				IOH_WRITE_LONG((CAN_CMASK_RDWR | CAN_CMASK_CTRL
+						| CAN_CMASK_ARB),
+					       (can_baseaddress +
+						CAN_IF2_CMASK_OFFSET));
+
+				/* Clearing the Dir bit. */
+				IOH_CAN_BIT_CLEAR((can_baseaddress +
+						   CAN_IF2_ID2_OFFSET),
+						  CAN_ID2_DIR);
+
+				/*Clearing NewDat & IntPnd */
+				IOH_CAN_BIT_CLEAR((can_baseaddress +
+						   CAN_IF2_MCONT_OFFSET),
+						  (CAN_IF_MCONT_NEWDAT |
+						   CAN_IF_MCONT_INTPND));
+
+				IOH_WRITE_LONG(mask,
+					       (can_baseaddress +
+						CAN_IF2_CREQ_OFFSET));
+
+				counter = COUNTER_LIMIT;
+				while (counter) {
+					if2_creq = \
+						IOH_READ_LONG
+							(can_baseaddress +
+							CAN_IF2_CREQ_OFFSET)
+							& CAN_IF_CREQ_BUSY;
+					if (if2_creq == 0)
+						break;
+
+					counter--;
+				}
+
+			}
+		}
+	}
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_msg_tx(
+					int handle,struct ioh_can_msg *msg)
+	@brief      This function transmits a CAN message.
+	@remarks	Sends a message object for transmission. The main
+				tasks performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Transmits the obtained message object data by
+				 appropriately
+				filling the currently available transmit message
+				 object.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	msg			[@ref IN]	The message to be
+							 transmitted.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+			- @ref	IOH_CAN_NO_TX_BUFF 	--> No transmit buffer
+							 object is available.
+
+	@see
+			- ioh_can_write
+
+	<hr>
+*/
+int ioh_can_msg_tx(int handle, struct ioh_can_msg *msg)
+{
+	u32 id1 = 0;
+	u32 id2 = 0;
+	u32 data_a1 = 0;
+	u32 data_a2 = 0;
+	u32 data_b1 = 0;
+	u32 data_b2 = 0;
+	u32 tx_disable_counter = 0;
+	u32 buffer_status = 0;
+	u32 tx_buffer_avail = 0;
+	u32 status;
+	u32 i;
+	u32 counter;
+	enum ioh_can_run_mode run_mode;
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+	u32 if1_creq;
+
+	if ((handle == (int) 0) || (msg == NULL)) {	/* If invalid
+								 parameters. */
+		IOH_LOG(KERN_ERR, "ioh_can_msg_tx -> Invalid Parameter.\n");
+		retval = IOH_CAN_FAIL;
+	}
+
+	else {
+		/* Obatining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/*Getting the current CAN mode. */
+		(void)ioh_can_get_run_mode(handle, &run_mode);
+
+		/*If CAN is in STOP mode. */
+		if (run_mode != IOH_CAN_RUN) {
+			IOH_LOG(KERN_ERR,
+				"ioh_can_msg_tx -> CAN stopped on transmit \
+								attempt.\n");
+			retval = IOH_CAN_FAIL;
+		} else {
+			unsigned long flags;
+			/* Attaining the lock. */
+			spin_lock_irqsave(&can_os->tx_spinlock, flags);
+
+			/*Getting the message object status. */
+			buffer_status = (u32) ioh_can_get_buffer_status(handle);
+
+			/*Getting the free transmit message object. */
+			for (i = 0;
+			     i < (ioh_can_rx_buf_size + ioh_can_tx_buf_size);
+			     i++) {
+				if ((ioh_msg_obj_conf[i] == MSG_OBJ_TX)) {
+					/* Checking whether the object is \
+								enabled. */
+					(void)ioh_can_get_tx_enable(handle,
+								    (i + 1),
+								    &status);
+
+					if ((ENABLE == status)) {
+						if ((((buffer_status >> i) & 1)
+						     == 0)) {
+							tx_buffer_avail =
+							    (i + 1);
+							break;
+						}
+					} else {
+						tx_disable_counter++;
+					}
+				}
+			}
+
+			/*If no transmit object available. */
+			if (tx_buffer_avail == 0) {
+				IOH_DEBUG
+				    ("ioh_can_msg_tx -> tx_disable_counter "
+				     "= %d.\n", tx_disable_counter);
+				/* If no object is enabled. */
+				if ((tx_disable_counter == \
+							ioh_can_tx_buf_size)){
+					retval = IOH_CAN_FAIL;
+					IOH_LOG(KERN_ERR,
+						"ioh_can_msg_tx -> \
+						All transmit buffers "
+						"are disabled.\n");
+				} else {
+					IOH_LOG(KERN_ERR,
+						"ioh_can_msg_tx -> \
+						No transmit buffer free.\n");
+					retval = IOH_CAN_NO_TX_BUFF;
+				}
+			} else {
+				IOH_DEBUG
+				    ("ioh_can_msg_tx -> \
+					Transmit buffer obtained.\n");
+
+				/*Reading the message object from the Message
+					 RAM to the Interface register. */
+				IOH_WRITE_LONG(CAN_CMASK_RX_TX_GET,
+					       (can_baseaddress +
+						CAN_IF1_CMASK_OFFSET));
+				IOH_WRITE_LONG(tx_buffer_avail,
+					       (can_baseaddress +
+						CAN_IF1_CREQ_OFFSET));
+
+				/*Confirming the read. */
+				counter = COUNTER_LIMIT;
+				while (counter) {
+					if1_creq = \
+						(IOH_READ_LONG
+							(can_baseaddress +
+							CAN_IF1_CREQ_OFFSET)) &
+						CAN_IF_CREQ_BUSY;
+					if (if1_creq == 0)
+						break;
+
+					counter--;
+				}
+
+				/*If Read not successful. */
+				if (counter == 0) {
+					(void)ioh_can_set_tx_enable(handle,
+								tx_buffer_avail,
+								ENABLE);
+					retval = IOH_CAN_FAIL;
+				} else {
+					/*Setting the CMASK register. */
+					IOH_CAN_BIT_SET((can_baseaddress +
+							 CAN_IF1_CMASK_OFFSET),
+							CAN_CMASK_ALL);
+
+					/*If ID extended is set. */
+					if (msg->ide == 1) {
+						/* Setting 29 bit ID with XTD
+								 bit set. */
+						id1 =
+						    (msg->id & MSK_ALL_SIXTEEN);
+						id2 =
+						    ((msg->
+						      id & (MSK_ALL_THIRTEEN <<
+							    BIT_SHIFT_SIXTEEN))
+						     >> BIT_SHIFT_SIXTEEN);
+
+						id2 |= CAN_ID2_XTD;
+					} else {
+						/* Setting 11bit ID with XTD bit
+								 reset. */
+						id1 = 0;
+						id2 =
+						    ((msg->
+						      id & MSK_ALL_ELEVEN) <<
+						     BIT_SHIFT_TWO);
+					}
+					IOH_CAN_BIT_CLEAR((can_baseaddress +
+							   CAN_IF1_ID1_OFFSET),
+							  MSK_ALL_SIXTEEN);
+					IOH_CAN_BIT_CLEAR((can_baseaddress +
+							   CAN_IF1_ID2_OFFSET),
+							  (MSK_ALL_THIRTEEN |
+							   CAN_ID2_XTD));
+
+					IOH_CAN_BIT_SET((can_baseaddress +
+							 CAN_IF1_ID1_OFFSET),
+							id1);
+					IOH_CAN_BIT_SET((can_baseaddress +
+							 CAN_IF1_ID2_OFFSET),
+							id2);
+
+					/* If remote frame has to be
+							 transmitted.. */
+					if (msg->rtr == 1) {
+						IOH_CAN_BIT_CLEAR(\
+			(can_baseaddress + CAN_IF1_ID2_OFFSET), CAN_ID2_DIR);
+						msg->dlc = 0;
+
+						IOH_DEBUG
+						("ioh_can_msg_tx -> \
+							Transmitting a "
+							"remote frame.\n");
+					} else {	/* Data frame
+							 transmission. */
+
+						msg->dlc &= MSK_ALL_FOUR;
+
+						IOH_DEBUG
+						("ioh_can_msg_tx -> \
+							Transmitting a "
+							"data frame.\n");
+					}
+
+					/*Writing the data and the DLC */
+					switch (msg->dlc) {
+					case 0:
+						break;
+
+					case 1:
+						data_a1 = msg->data[0];
+						break;
+					case 2:
+						data_a1 = msg->data[0];
+						data_a1 |=
+						    (((u32) msg->
+						      data[1]) <<
+						     BIT_SHIFT_EIGHT);
+						break;
+					case 3:
+						data_a1 = msg->data[0];
+						data_a1 |=
+						    (((u32) msg->
+						      data[1]) <<
+						     BIT_SHIFT_EIGHT);
+						data_a2 = msg->data[2];
+						break;
+					case 4:
+						data_a1 = msg->data[0];
+						data_a1 |=
+						    (((u32) msg->
+						      data[1]) <<
+						     BIT_SHIFT_EIGHT);
+						data_a2 = msg->data[2];
+						data_a2 |=
+						    (((u32) msg->
+						      data[3]) <<
+						     BIT_SHIFT_EIGHT);
+						break;
+					case 5:
+						data_a1 = msg->data[0];
+						data_a1 |=
+						    (((u32) msg->
+						      data[1]) <<
+						     BIT_SHIFT_EIGHT);
+						data_a2 = msg->data[2];
+						data_a2 |=
+						    (((u32) msg->
+						      data[3]) <<
+						     BIT_SHIFT_EIGHT);
+						data_b1 = msg->data[4];
+						break;
+					case 6:
+						data_a1 = msg->data[0];
+						data_a1 |=
+						    (((u32) msg->
+						      data[1]) <<
+						     BIT_SHIFT_EIGHT);
+						data_a2 = msg->data[2];
+						data_a2 |=
+						    (((u32) msg->
+						      data[3]) <<
+						     BIT_SHIFT_EIGHT);
+						data_b1 = msg->data[4];
+						data_b1 |=
+						    (((u32) msg->
+						      data[5]) <<
+						     BIT_SHIFT_EIGHT);
+						break;
+					case 7:
+						data_a1 = msg->data[0];
+						data_a1 |=
+						    (((u32) msg->
+						      data[1]) <<
+						     BIT_SHIFT_EIGHT);
+						data_a2 = msg->data[2];
+						data_a2 |=
+						    (((u32) msg->
+						      data[3]) <<
+						     BIT_SHIFT_EIGHT);
+						data_b1 = msg->data[4];
+						data_b1 |=
+						    (((u32) msg->
+						      data[5]) <<
+						     BIT_SHIFT_EIGHT);
+						data_b2 = msg->data[6];
+						break;
+					case 8:
+					default:
+						data_a1 = msg->data[0];
+						data_a1 |=
+						    (((u32) msg->
+						      data[1]) <<
+						     BIT_SHIFT_EIGHT);
+						data_a2 = msg->data[2];
+						data_a2 |=
+						    (((u32) msg->
+						      data[3]) <<
+						     BIT_SHIFT_EIGHT);
+						data_b1 = msg->data[4];
+						data_b1 |=
+						    (((u32) msg->
+						      data[5]) <<
+						     BIT_SHIFT_EIGHT);
+						data_b2 = msg->data[6];
+						data_b2 |=
+						    (((u32) msg->
+						      data[7]) <<
+						     BIT_SHIFT_EIGHT);
+						break;
+
+					}
+
+					/* Writing the DATA registers. */
+					IOH_WRITE_LONG(data_a1,
+						       (can_baseaddress +
+							CAN_IF1_DATAA1_OFFSET));
+					IOH_WRITE_LONG(data_a2,
+						       (can_baseaddress +
+							CAN_IF1_DATAA2_OFFSET));
+					IOH_WRITE_LONG(data_b1,
+						       (can_baseaddress +
+							CAN_IF1_DATAB1_OFFSET));
+					IOH_WRITE_LONG(data_b2,
+						       (can_baseaddress +
+							CAN_IF1_DATAB2_OFFSET));
+
+					/* Updating the size of the data. */
+					IOH_CAN_BIT_CLEAR((can_baseaddress +
+							  CAN_IF1_MCONT_OFFSET),
+							  MSK_ALL_FOUR);
+					IOH_CAN_BIT_SET((can_baseaddress +
+							 CAN_IF1_MCONT_OFFSET),
+							msg->dlc);
+
+					/*Clearing IntPend, NewDat & TxRqst */
+					IOH_CAN_BIT_CLEAR((can_baseaddress + \
+							CAN_IF1_MCONT_OFFSET),\
+							(CAN_IF_MCONT_NEWDAT | \
+							CAN_IF_MCONT_INTPND | \
+							CAN_IF_MCONT_TXRQXT));
+
+					/*Setting NewDat, TxRqst bits */
+					IOH_CAN_BIT_SET((can_baseaddress +
+							 CAN_IF1_MCONT_OFFSET),
+							(CAN_IF_MCONT_NEWDAT |
+							 CAN_IF_MCONT_TXRQXT));
+
+					/*Writing the updation to the Message
+								 object. */
+					IOH_WRITE_LONG(tx_buffer_avail,
+						       (can_baseaddress +
+							CAN_IF1_CREQ_OFFSET));
+
+					/*Confirming the updation. */
+					counter = COUNTER_LIMIT;
+					while (counter) {
+						if1_creq = \
+							(IOH_READ_LONG
+							(can_baseaddress +
+							CAN_IF1_CREQ_OFFSET))
+							& CAN_IF_CREQ_BUSY;
+						if (if1_creq == 0)
+							break;
+
+						counter--;
+					}
+
+					if ((counter == 0)) {
+						retval = IOH_CAN_FAIL;
+					} else {
+						IOH_DEBUG
+						("ioh_can_msg_tx -> \
+							Updation of transmit "
+							"buffer successful.\n");
+						IOH_DEBUG
+						("ioh_can_msg_tx -> \
+							Message object enabled "
+							"for transmission.\n");
+
+					}
+
+				}	/*if message read object successful */
+			}	/* if transmit buffer available */
+
+			/* Releasing the lock. */
+			spin_unlock_irqrestore(&can_os->tx_spinlock, flags);
+		}		/*if device in run mode */
+	}			/* if parameters valid */
+
+	IOH_DEBUG("ioh_can_msg_tx -> Return value: %d.\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_clear_buffers(int handle)
+	@brief		Clears the message objects.
+	@remarks    This function clears all transmit and receive buffers of the
+			 CAN device.
+
+	@param	handle		[@ref IN]	The handle to the device.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_open
+
+	<hr>
+*/
+int ioh_can_clear_buffers(int handle)
+{
+	u32 i;
+	u32 rx_buff_num;
+	u32 tx_buff_num;
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+
+	if (handle == (int) 0) {	/* if handle invalid. */
+		IOH_LOG(KERN_ERR, "ioh_can_clear_buffers -> Invalid Handle.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obatining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		IOH_WRITE_LONG(CAN_CMASK_RX_TX_SET,
+			       (can_baseaddress + CAN_IF1_CMASK_OFFSET));
+		IOH_WRITE_LONG(CAN_CMASK_RX_TX_SET,
+			       (can_baseaddress + CAN_IF2_CMASK_OFFSET));
+
+		IOH_WRITE_LONG(MSK_ALL_SIXTEEN,
+			       (can_baseaddress + CAN_IF1_MASK1_OFFSET));
+		IOH_WRITE_LONG(MSK_ALL_SIXTEEN,
+			       (can_baseaddress + CAN_IF1_MASK2_OFFSET));
+		IOH_WRITE_LONG(MSK_ALL_SIXTEEN,
+			       (can_baseaddress + CAN_IF2_MASK1_OFFSET));
+		IOH_WRITE_LONG(MSK_ALL_SIXTEEN,
+			       (can_baseaddress + CAN_IF2_MASK2_OFFSET));
+
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF1_ID1_OFFSET));
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF1_ID2_OFFSET));
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF2_ID1_OFFSET));
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF2_ID2_OFFSET));
+
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF1_MCONT_OFFSET));
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF2_MCONT_OFFSET));
+
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF1_DATAA1_OFFSET));
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF1_DATAA2_OFFSET));
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF1_DATAB1_OFFSET));
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF1_DATAB2_OFFSET));
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF2_DATAA1_OFFSET));
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF2_DATAA2_OFFSET));
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF2_DATAB1_OFFSET));
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF2_DATAB2_OFFSET));
+
+		for (i = 1; i <= (MAX_MSG_OBJ / 2); i++) {
+			rx_buff_num = 2 * i;
+			tx_buff_num = (2 * i) - 1;
+
+			IOH_WRITE_LONG(rx_buff_num,
+				       (can_baseaddress + CAN_IF1_CREQ_OFFSET));
+			IOH_WRITE_LONG(tx_buff_num,
+				       (can_baseaddress + CAN_IF2_CREQ_OFFSET));
+
+			mdelay(10);
+
+			IOH_DEBUG
+			    ("ioh_can_clear_buffers -> \
+				Cleared receive object %d "
+			     "and tranmit object %d.\n", rx_buff_num,
+			     tx_buff_num);
+		}
+	}
+
+	IOH_DEBUG("ioh_can_clear_buffers returns %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_get_buffer_status(int handle)
+	@brief      This function gets the buffer status of the CAN device.
+	@remarks	Retrieves the message object status. The main tasks
+				 performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Reads the values of the CANTREQ1 and CANTREQ2
+				 registers
+				and returns it to the function calling this
+				 function as
+				32 bit value representing TxRqst bit of each
+				 message object.
+
+	@param	handle		[@ref IN]	The handle to the device.
+
+	@retval	int
+			- 0	--> All transmit buffers available
+			- >0	--> Some transmit buffers are not available.
+			- @ref 	IOH_CAN_FAIL	--> If the operation fails.
+
+	@see
+			ioh_can_msg_tx
+
+	<hr>
+*/
+int ioh_can_get_buffer_status(int handle)
+{
+	u32 reg_treq1;
+	u32 reg_treq2;
+	int retval = IOH_CAN_SUCCESS;
+	u8 *can_baseaddress;
+
+	if (handle == (int) 0) {	/* if handle invalid. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_get_buffer_status -> Invalid Handle.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/* Reading the transmission request registers. */
+		reg_treq1 =
+		    (IOH_READ_LONG(can_baseaddress + CAN_TREQ1_OFFSET) &
+		     MSK_ALL_SIXTEEN);
+		reg_treq2 =
+		    ((IOH_READ_LONG(can_baseaddress + CAN_TREQ2_OFFSET) &
+		      MSK_ALL_SIXTEEN) << BIT_SHIFT_SIXTEEN);
+
+		retval = (reg_treq1 | reg_treq2);
+	}
+
+	IOH_DEBUG("ioh_can_get_buffer_status -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_rx_dequeue(
+				int handle,struct ioh_can_msg *msg,u32 buff_num)
+	@brief      This function gets a pending message from the CAN device.
+	@remarks	Retrieves the message from a received message object.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	msg		[@ref OUT]	Reference to the received
+						 message object.
+	@param	buff_num	[@ref IN]	The message object number.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_callback
+
+	<hr>
+*/
+int ioh_can_rx_dequeue(int handle, struct ioh_can_msg *msg,
+		       u32 buff_num)
+{
+	s32 i;
+	u32 reg;
+	int retval = IOH_CAN_FAIL;
+	u8 *can_baseaddress;
+
+	if ((handle == (int) 0) || (msg == NULL)) {	/* invalid
+								 parameters. */
+		IOH_LOG(KERN_ERR, "ioh_can_rx_dequeue -> Invalid Parameter.\n");
+	}
+	/* invalid buffer number. */
+
+	else if ((ioh_msg_obj_conf[buff_num - 1] != MSG_OBJ_RX) ||
+		 (buff_num > (ioh_can_rx_buf_size + ioh_can_tx_buf_size))) {
+		IOH_LOG(KERN_ERR,
+			"ioh_can_rx_dequeue -> Invalid Buffer number.\n");
+	}
+
+	else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		msg->ide = 0;
+		msg->id = 0;
+		msg->dlc = 0;
+		for (i = 0; i < IOH_CAN_MSG_DATA_LEN; i++)
+			msg->data[i] = 0;
+
+		/* Read the ID type. */
+		msg->ide =
+		    ((IOH_READ_LONG(can_baseaddress + CAN_IF2_ID2_OFFSET)) &
+		     CAN_ID2_XTD)
+		    >> BIT_SHIFT_FOURTEEN;
+
+		/* Extracting the ID. */
+		if (msg->ide == 1) {	/* Extended 29bit ID. */
+			msg->id =
+			    (IOH_READ_LONG(can_baseaddress + CAN_IF2_ID1_OFFSET)
+			     & MSK_ALL_SIXTEEN);
+			msg->id |=
+			    (((IOH_READ_LONG
+			       (can_baseaddress +
+				CAN_IF2_ID2_OFFSET)) & MSK_ALL_THIRTEEN) <<
+			     BIT_SHIFT_SIXTEEN);
+		} else {	/* Standard 11bit ID. */
+
+			msg->id =
+			    (((IOH_READ_LONG
+			       (can_baseaddress +
+				CAN_IF2_ID2_OFFSET)) & (MSK_ALL_ELEVEN <<
+							BIT_SHIFT_TWO)) >>
+			     BIT_SHIFT_TWO);
+		}
+
+		/* Getting the size of the data and the Remote frame bit. */
+		if (msg->rtr == 1) {
+			msg->dlc = 0;
+
+			IOH_DEBUG("ioh_can_rx_dequeue -> Remote frame "
+				  "read with message id: %x.\n", msg->id);
+		} else {
+			msg->dlc =
+			    ((IOH_READ_LONG
+			      (can_baseaddress + CAN_IF2_MCONT_OFFSET))
+			     & MSK_ALL_FOUR);
+
+			IOH_DEBUG("ioh_can_rx_dequeue -> Data frame "
+				  "read with message id: %x.\n", msg->id);
+		}
+
+		/* Reading back the data. */
+		switch (msg->dlc) {
+		case 0:
+			break;
+
+		case 1:
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			break;
+
+		case 2:
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			msg->data[1] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+			break;
+
+		case 3:
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			msg->data[1] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAA2_OFFSET);
+			msg->data[2] = reg & MSK_ALL_EIGHT;
+			break;
+
+		case 4:
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			msg->data[1] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAA2_OFFSET);
+			msg->data[2] = reg & MSK_ALL_EIGHT;
+			msg->data[3] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+			break;
+
+		case 5:
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			msg->data[1] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAA2_OFFSET);
+			msg->data[2] = reg & MSK_ALL_EIGHT;
+			msg->data[3] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAB1_OFFSET);
+			msg->data[4] = reg & MSK_ALL_EIGHT;
+			break;
+
+		case 6:
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			msg->data[1] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAA2_OFFSET);
+			msg->data[2] = reg & MSK_ALL_EIGHT;
+			msg->data[3] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAB1_OFFSET);
+			msg->data[4] = reg & MSK_ALL_EIGHT;
+			msg->data[5] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+			break;
+
+		case 7:
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			msg->data[1] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAA2_OFFSET);
+			msg->data[2] = reg & MSK_ALL_EIGHT;
+			msg->data[3] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAB1_OFFSET);
+			msg->data[4] = reg & MSK_ALL_EIGHT;
+			msg->data[5] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAB2_OFFSET);
+			msg->data[6] = reg & MSK_ALL_EIGHT;
+			break;
+
+		case 8:
+		default:
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			msg->data[1] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAA2_OFFSET);
+			msg->data[2] = reg & MSK_ALL_EIGHT;
+			msg->data[3] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAB1_OFFSET);
+			msg->data[4] = reg & MSK_ALL_EIGHT;
+			msg->data[5] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg =
+			    IOH_READ_LONG(can_baseaddress +
+					  CAN_IF2_DATAB2_OFFSET);
+			msg->data[6] = reg & MSK_ALL_EIGHT;
+			msg->data[7] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			break;
+		}
+		retval = IOH_CAN_SUCCESS;
+	}
+
+	IOH_DEBUG("ioh_can_rx_dequeue -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			void ioh_can_config_rx_tx_buffers(int handle)
+	@brief      This function configures receive and transmit buffers.
+	@remarks	Configures the receive and the transmit buffers.
+
+	@param	handle		[@ref IN]	The handle to the device.
+
+	@retval       None.
+
+	@see
+			- ioh_can_open
+			- ioh_can_resume
+
+	<hr>
+*/
+void ioh_can_config_rx_tx_buffers(int handle)
+{
+	u32 i;
+	u32 counter;
+	u8 *can_baseaddress;
+	u32 if1_creq;
+	u32 if2_creq;
+
+	if (handle != (int) 0) {	/* if handle valid. */
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/*For accssing MsgVal, ID and EOB bit */
+		IOH_WRITE_LONG((CAN_CMASK_RDWR | CAN_CMASK_ARB |
+				CAN_CMASK_CTRL),
+			       (can_baseaddress + CAN_IF1_CMASK_OFFSET));
+		IOH_WRITE_LONG((CAN_CMASK_RDWR | CAN_CMASK_ARB |
+				CAN_CMASK_CTRL),
+			       (can_baseaddress + CAN_IF2_CMASK_OFFSET));
+
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF1_ID1_OFFSET));
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF1_ID2_OFFSET));
+					/*Resetting DIR bit for reception */
+		IOH_WRITE_LONG(0x0, (can_baseaddress + CAN_IF2_ID1_OFFSET));
+		IOH_WRITE_LONG((CAN_ID2_DIR | (MSK_ALL_ELEVEN << 2)), \
+				(can_baseaddress + CAN_IF2_ID2_OFFSET));
+					/*Setting DIR bit for transmission */
+
+		IOH_WRITE_LONG(CAN_IF_MCONT_EOB, \
+				(can_baseaddress + CAN_IF1_MCONT_OFFSET));
+					/*Setting EOB bit for receiver */
+		IOH_WRITE_LONG(CAN_IF_MCONT_EOB, \
+				(can_baseaddress + CAN_IF2_MCONT_OFFSET));
+					/*Setting EOB bit for transmitter */
+
+		for (i = 0; i < (ioh_can_tx_buf_size + ioh_can_rx_buf_size);
+		     i++) {
+			counter = COUNTER_LIMIT;
+			/* Configure the receive message objects */
+			if (ioh_msg_obj_conf[i] == MSG_OBJ_RX) {
+
+				IOH_WRITE_LONG((i + 1),
+					       (can_baseaddress +
+						CAN_IF1_CREQ_OFFSET));
+
+				while (counter) {
+					if1_creq = \
+						(ioread32
+							(can_baseaddress +
+							CAN_IF1_CREQ_OFFSET))
+						 & CAN_IF_CREQ_BUSY;
+					if (if1_creq == 0)
+						break;
+
+					counter--;
+				}
+
+				if ((counter == 0)) {
+					IOH_DEBUG
+					("ioh_can_config_rx_tx_buffers -> \
+					Config failed "
+					"for receive message object %u\n",
+					(i + 1));
+				}
+			}
+			/* Configure the transmit message objects */
+			else if (ioh_msg_obj_conf[i] == MSG_OBJ_TX) {
+				IOH_WRITE_LONG((i + 1),
+					       (can_baseaddress +
+						CAN_IF2_CREQ_OFFSET));
+
+				while (counter) {
+					if2_creq = \
+						(ioread32
+							(can_baseaddress +
+							CAN_IF2_CREQ_OFFSET))
+						 & CAN_IF_CREQ_BUSY;
+					if (if2_creq == 0)
+						break;
+
+					counter--;
+				}
+
+
+
+				if ((counter == 0)) {
+					IOH_DEBUG
+					("ioh_can_config_rx_tx_buffers -> \
+					Config failed "
+					"for transmit message object %u\n",
+					(i + 1));
+				}
+			}
+
+		}
+	}
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_get_error_stats(
+					int handle,struct ioh_can_error *error
+	@brief      This function gets the error statics of the CAN device.
+	@remarks	Retrieves the error status. The main tasks performed by
+				this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- Depending on the value of the CANERRC register
+				 the
+				error status structure is filled and returned to
+				 the function
+				calling this function.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	error		[@ref OUT]	The reference to the error
+						 status.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+int ioh_can_get_error_stats(int handle, struct ioh_can_error *error)
+{
+	u8 *can_baseaddress;
+	u32 reg_val;
+	int retval = IOH_CAN_SUCCESS;
+
+	if ((handle == (int) 0) || (error == NULL)) {	/* invalid
+								 parameters. */
+		IOH_LOG(KERN_ERR,
+			"ioh_can_get_error_stats -> Invalid Parameter.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/* Reading the error count register. */
+		reg_val = IOH_READ_LONG(can_baseaddress + CAN_ERRC_OFFSET);
+
+		error->rxgte96 = 0;
+		error->txgte96 = 0;
+
+		error->rx_err_cnt =
+		    (reg_val & MSK_ES_RXERRCNT) >> BIT_ES_RXERRCNT;
+		error->tx_err_cnt =
+		    (reg_val & MSK_ES_TXERRCNT) >> BIT_ES_TXERRCNT;
+
+		/* receive error count > 96 */
+		if (error->rx_err_cnt >= ERROR_COUNT)
+			error->rxgte96 = 1;
+		/* transmit error count > 96. */
+		if (error->tx_err_cnt >= ERROR_COUNT)
+			error->txgte96 = 1;
+
+		/* Reading the Can status register. */
+		reg_val = IOH_READ_LONG(can_baseaddress + CAN_STAT_OFFSET);
+
+		/* EPass */
+		if ((reg_val & (1 << BIT_SHIFT_FIVE)) != 0)
+			error->error_stat = 1;
+		/* Buss Off */
+		else if ((reg_val & (1 << BIT_SHIFT_SEVEN)) != 0)
+			error->error_stat = 3;
+		else
+			error->error_stat = 0;
+
+		IOH_DEBUG("rxgte96 (Rx > 96) : %u\n", error->rxgte96);
+		IOH_DEBUG("txgte96 (Rx > 96) : %u\n", error->txgte96);
+		IOH_DEBUG("error_stat        : %u\n", error->error_stat);
+		IOH_DEBUG("rx_err_cnt        : %u\n", error->rx_err_cnt);
+		IOH_DEBUG("tx_err_cnt        : %u\n", error->tx_err_cnt);
+	}
+
+	IOH_DEBUG("ioh_can_get_error_stats -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			int ioh_can_reset(struct ioh_can_os *can_os)
+	@brief      Performs soft reset.
+	@remarks	Resets the CAN device. The main tasks
+				performed by this function are :
+				- Validates whether the passed arguments are
+				 valid.
+				If invalid error status code is returned.
+				- The CAN device is reset by setting the SRST
+				 bit of the
+				Soft Reset register.
+
+	@param	can_os		[@ref IN]	Reference to the system
+						 structure.
+
+	@retval	int
+			- @ref	IOH_CAN_SUCCESS		--> If the operation is
+								 successful.
+			- @ref 	IOH_CAN_FAIL		--> If the operation
+								 fails.
+
+	@see
+			- ioh_can_ioctl
+			- ioh_candev_open
+
+	<hr>
+
+*/
+int ioh_can_reset(struct ioh_can_os *can_os)
+{
+	int retval = IOH_CAN_SUCCESS;
+#ifndef	FPGA
+	u8 *can_baseaddress;
+
+	if ((can_os == NULL)) {
+		IOH_LOG(KERN_ERR, "ioh_can_reset -> Invalid parameter.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) can_os->can;
+		can_baseaddress = (u8 *) (can->io_base);
+
+		/* write to sw reset register */
+		IOH_WRITE_LONG(1, (can_baseaddress + CAN_SRST_OFFSET));
+		IOH_WRITE_LONG(0, (can_baseaddress + CAN_SRST_OFFSET));
+
+		IOH_DEBUG("ioh_can_reset -> Reset successful.\n");
+	}
+#endif
+
+	IOH_DEBUG("ioh_can_reset -> Return value: %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			irqreturn_t ioh_can_handler(
+					int irq, void *dev_id
+	@brief      Handles the CAN interrupts.
+	@remarks	Handles the interrupt. the main task perforemd by
+				this function is :
+				- Checks whether an interrupt is encontered.
+				 If encountered
+				the callback function is invoked.
+
+	@param	irq		[@ref IN]	The interrupt number.
+	@param	dev_id		[@ref IN]	Reference to the device
+						 structure.
+
+	@retval	irqreturn_t
+			- IRQ_HANDLED	--> CAN interrupt has been handled.
+			- IRQ_NONE	--> No CAn interrupt source.
+
+	@see
+			- ioh_candev_open
+
+	<hr>
+*/
+irqreturn_t ioh_can_handler(int irq, void *dev_id)
+{
+	irqreturn_t retval = IRQ_NONE;
+
+	struct ioh_can_os *can_os = (struct ioh_can_os *) dev_id;
+	u32 int_stat;
+
+	IOH_DEBUG("ioh_can_handler -> Invoked.\n");
+
+	int_stat = ioh_can_int_pending(can_os->can);
+	IOH_DEBUG("ioh_can_handler -> ioh_can_int_pending "
+		  "returned value: %x\n", int_stat);
+
+	if ((can_os != NULL) && (int_stat > 0)) {
+		can_os->int_stat = int_stat;
+		(*can_os->can_callback) (can_os);
+
+		IOH_DEBUG("ioh_can_handler -> Callback function "
+			  "invoked successfully.\n");
+
+		retval = IRQ_HANDLED;
+	}
+
+	return retval;
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			void ioh_can_log_message(u32 status)
+	@brief      Logs the error messages.
+	@remarks	Logs the error messages according to the error bits set.
+
+	@param	status		[@ref IN]	Error status.
+
+	@retval       None.
+
+	@see
+			- ioh_can_callback
+
+	<hr>
+*/
+void ioh_can_log_message(u32 status)
+{
+
+	switch ((status & MSK_ALL_THREE)) {
+
+	case 0:
+		IOH_DEBUG("ioh_can_log_message ->  No Error\n");
+		break;
+	case 1:
+		IOH_LOG(KERN_ERR, "ioh_can_log_message -> Stuff Error\n");
+		break;
+	case 2:
+		IOH_LOG(KERN_ERR, "ioh_can_log_message -> Form Error.\n");
+		break;
+	case 3:
+		IOH_LOG(KERN_ERR, "ioh_can_log_message -> Ack Error\n");
+		break;
+	case 4:
+		IOH_LOG(KERN_ERR, "ioh_can_log_message -> Bit 1 Error\n");
+		break;
+	case 5:
+		IOH_LOG(KERN_ERR, "ioh_can_log_message -> Bit 0 Error.\n");
+		break;
+	case 6:
+		IOH_LOG(KERN_ERR, "ioh_can_log_message -> Crc Error\n");
+		break;
+	case 7:
+		IOH_LOG(KERN_ERR, "ioh_can_log_message -> Undefined Error\n");
+		break;
+	default:
+		break;
+	}
+}
+
+/*! @ingroup 	HALLayer
+	@fn			void ioh_can_entcb(
+	void(*ioh_can_cb)(struct ioh_can_os *),struct ioh_can_os * p_can_os)
+	@brief      Registers the call back function.
+	@remarks	Registers the callback function for further use.
+
+	@param	ioh_can_cb	[@ref IN]	Reference to the callback
+						 function.
+	@param	p_can_os	[@ref IN]	Reference to the device
+						 structure.
+
+	@retval       None.
+
+	@see
+				- ioh_candev_open
+
+	<hr>
+*/
+void ioh_can_entcb(void (*ioh_can_cb) (struct ioh_can_os *), \
+			struct ioh_can_os *p_can_os)
+{
+	if ((NULL != ioh_can_cb) && (NULL != p_can_os)) {
+		p_can_os->can_callback = ioh_can_cb;
+		IOH_DEBUG("ioh_can_entcb -> Callback function "
+			  "set successful.\n");
+	} else {
+		IOH_LOG(KERN_ERR, "ioh_can_entcb -> Callback function set "
+			"unsuccessful.\n");
+	}
+
+}
+
+/*! @ingroup 	HALLayerAPI
+	@fn			void ioh_can_callback(
+					struct ioh_can_os * can_os)
+	@brief      The callback function.
+	@remarks	The callback function to handle the interrupt.
+
+	@param	can_os		[@ref IN]	Reference to the device
+						 structure.
+
+	@retval       None.
+
+	@see
+			- ioh_candev_open
+
+	<hr>
+*/
+void ioh_can_callback(struct ioh_can_os *can_os)
+{
+	u32 int_stat;
+	u32 reg;
+	u32 reg_stat;
+	u32 counter;
+	u8 *can_baseaddress;
+	struct ioh_can_msg receive_msg;
+	struct can_hw *can = (struct can_hw *) (can_os->can);
+	int retval = IOH_CAN_SUCCESS;
+	u32 if2_creq;
+
+	can_baseaddress = (u8 *) (can->io_base);
+
+	/* Get the interrupt status */
+	int_stat = can_os->int_stat;
+	can_os->int_stat = 0;
+
+	/*Checking for status interrupt */
+	if (CAN_STATUS_INT == int_stat) {
+		/* Reading of the CANSTAT register. */
+		reg_stat = IOH_READ_LONG((can_baseaddress + CAN_STAT_OFFSET));
+		reg_stat = reg_stat & MSK_ALL_EIGHT;
+		IOH_DEBUG("ioh_can_callback -> Status Register: %x.\n",
+			  reg_stat);
+
+		/* If recovered from Bus-Off interrupt. */
+		if ((reg_stat == 0) && (can_os->bus_off_interrupt == 1)) {
+			can_os->bus_off_interrupt = 0;
+			(void)ioh_can_tx_enable_all(can_os->can);
+			(void)ioh_can_rx_enable_all(can_os->can);
+
+			IOH_LOG(KERN_ERR, "ioh_can_callback -> Bus off "
+				"stage recovered.\n");
+		} else {
+			/*Bus off interrupt. */
+			if (reg_stat & ((u32) 1 << BIT_SHIFT_SEVEN)) {
+				if (can_os->bus_off_interrupt == 0) {
+					enum ioh_can_auto_restart restart_mode \
+									= 0;
+
+					IOH_LOG(KERN_ERR,
+						"ioh_can_callback -> Bus off "
+						"interrupt.\n");
+
+					(void)ioh_can_tx_disable_all(can_os->
+								     can);
+					(void)ioh_can_rx_disable_all(can_os->
+								     can);
+
+					(void)ioh_can_get_restart_mode(can_os->
+								can,
+								&restart_mode);
+
+					if (CAN_AUTO == restart_mode) {
+						can_os->bus_off_interrupt = 1;
+
+						(void)
+						    ioh_can_set_run_mode
+						    (can_os->can, IOH_CAN_RUN);
+						IOH_DEBUG("ioh_can_callback -> "
+							"Device restarted.\n");
+					}
+				}
+			}
+			/*EWarn interrupt. */
+			if ((reg_stat & ((u32) 1 << BIT_SHIFT_SIX)) != 0) {
+				IOH_DEBUG
+				    ("ioh_can_callback -> EWarn interrupt.\n");
+			}
+			/*EPass interrupt. */
+			if ((reg_stat & ((u32) 1 << BIT_SHIFT_FIVE)) != 0) {
+				IOH_DEBUG
+				    ("ioh_can_callback -> EPass interrupt.\n");
+			}
+			/*RxOK interrupt. */
+			if ((reg_stat & ((u32) 1 << BIT_SHIFT_FOUR)) != 0) {
+				IOH_DEBUG
+				    ("ioh_can_callback -> RxOK interrupt.\n");
+				reg_stat =
+				    reg_stat & ~((u32) 1 << BIT_SHIFT_FOUR);
+			}
+			/*TxOK interrupt */
+			if ((reg_stat & ((u32) 1 << BIT_SHIFT_THREE)) != 0) {
+				IOH_DEBUG
+				    ("ioh_can_callback -> TxOK interrupt.\n");
+				reg_stat =
+				    reg_stat & ~((u32) 1 << BIT_SHIFT_THREE);
+			}
+			/*Error status */
+			ioh_can_log_message((reg_stat & MSK_ALL_THREE));
+			reg_stat = reg_stat & ~(MSK_ALL_THREE);
+
+			/*Clearing status register interrupt bits. */
+			IOH_WRITE_LONG(reg_stat,
+				       (can_baseaddress + CAN_STAT_OFFSET));
+
+			int_stat = ioh_can_int_pending(can_os->can);
+		}
+	}
+
+	/*Message object interrupt. */
+	if ((int_stat > 0) && (int_stat <= MAX_MSG_OBJ)) {
+		/*Reading the messsage object from the Message RAM to the
+							 interface registers. */
+		IOH_WRITE_LONG(CAN_CMASK_RX_TX_GET,
+			       (can_baseaddress + CAN_IF2_CMASK_OFFSET));
+		IOH_WRITE_LONG((int_stat),
+			       (can_baseaddress + CAN_IF2_CREQ_OFFSET));
+
+		/*Confirming the read. */
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if2_creq = \
+			(IOH_READ_LONG(can_baseaddress + CAN_IF2_CREQ_OFFSET)) &
+			CAN_IF_CREQ_BUSY;
+
+			if (if2_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		if (counter > 0) {	/* If read successful. */
+			/* Reading the MCONT register. */
+			reg =
+			    IOH_READ_LONG((can_baseaddress +
+					   CAN_IF2_MCONT_OFFSET));
+			reg &= MSK_ALL_SIXTEEN;
+
+			/* If MsgLost bit set. */
+			if ((reg & CAN_IF_MCONT_MSGLOST) != 0) {
+				IOH_CAN_BIT_CLEAR((can_baseaddress +
+						   CAN_IF2_MCONT_OFFSET),
+						  CAN_IF_MCONT_MSGLOST);
+
+				IOH_LOG(KERN_ERR,
+					"ioh_can_callback -> \
+					Message object %d has "
+					"been overwritten.\n", int_stat);
+			}
+
+			/* Read the direction bit for determination of remote
+						 frame during reception. */
+			receive_msg.rtr =
+			    ((IOH_READ_LONG
+			      ((can_baseaddress +
+				CAN_IF2_ID2_OFFSET)) & CAN_ID2_DIR) != 0);
+
+			/* Clearing interrupts. */
+			ioh_can_int_clr(can_os->can, int_stat);
+			IOH_DEBUG
+			    ("ioh_can_callback -> \
+				ioh_can_int_clr invoked successfully.\n");
+
+			/*Hanlde reception interrupt */
+			if (MSG_OBJ_RX == ioh_msg_obj_conf[int_stat - 1]) {
+				/*If new data arrived */
+				if ((reg & CAN_IF_MCONT_NEWDAT) != 0) {
+					/*Reading the message object content. */
+					retval =
+					    ioh_can_rx_dequeue(can_os->can,
+							       &receive_msg,
+							       int_stat);
+
+					if ((IOH_CAN_SUCCESS == retval)) {
+						/*Inserting the message object
+							 into the FIFO. */
+						retval =
+						    write_can_fifo(can_os->
+								  rx_fifo,
+								  &receive_msg);
+
+						/*If insertion successful and
+						 if the read call is waiting. */
+						if ((IOH_CAN_SUCCESS == retval)
+						    && (can_os->
+							read_wait_flag == 1)) {
+							can_os->read_wait_flag =
+							    0;
+							wake_up_interruptible
+							    (&can_os->
+							     read_wait_queue);
+						}
+					}
+					IOH_DEBUG
+					("ioh_can_callback -> \
+					Reception interrupt "
+					"handled for receive "
+					"message object %u.\n", int_stat);
+				}
+
+			}
+			/*Hanlde transmission interrupt */
+			else if (MSG_OBJ_TX == ioh_msg_obj_conf[int_stat - 1]) {
+				/*If the write system call is waiting. */
+				if (1 == can_os->write_wait_flag) {
+					can_os->write_wait_flag = 0;
+					wake_up_interruptible(&can_os->
+							      write_wait_queue);
+				}
+
+				IOH_DEBUG
+				("ioh_can_callback -> Transmission interrupt "
+				"handled for transmit "
+				"message object %u.\n", int_stat);
+			}
+		}
+	}
+}
diff -urN linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_hal.h topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_hal.h
--- linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_hal.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_hal.h	2010-03-10 08:57:34.000000000 +0900
@@ -0,0 +1,1407 @@
+/*!
+ * @file ioh_can_hal.h
+ * @brief Provides the macro definitions used by the HAL Layer APIs.
+ * @version 1.0
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * <hr>
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+#ifndef __IOH_CAN_HAL_H__
+#define __IOH_CAN_HAL_H__
+
+/*!	@ingroup	HALLayer
+	@def		MAX_CAN_DEVICES
+	@brief		The maximum number of devices supported by this driver.
+
+	<hr>
+*/
+#define MAX_CAN_DEVICES			(1)
+
+/*!	@ingroup	HALLayer
+	@def		MAX_BITRATE
+	@brief		The maximum bitrate(Kbps) that can be programmed for the
+			 CAN device.
+
+	<hr>
+*/
+#define MAX_BITRATE 			(0x3e8)
+
+/*!	@ingroup	HALLayer
+	@def		NUM_NODES
+	@brief		The maximum number of software FIFO nodes.
+
+	<hr>
+*/
+#define NUM_NODES 				(2000)	/* Maximum number of
+							 Software FIFO nodes. */
+
+/*!	@ingroup	HALLayer
+	@def		MAX_MSG_OBJ
+	@brief		The maximum number of message objects available.
+
+	<hr>
+*/
+#define MAX_MSG_OBJ 			(32)
+
+/*!	@ingroup	HALLayer
+	@def		MSG_OBJ_RX
+	@brief		The receive message object flag.
+
+	<hr>
+*/
+#define MSG_OBJ_RX				(0)
+
+/*!	@ingroup	HALLayer
+	@def		MSG_OBJ_TX
+	@brief		The transmit message object flag.
+
+	<hr>
+*/
+#define MSG_OBJ_TX				(1)
+
+/*!	@ingroup	HALLayer
+	@def		ENABLE
+	@brief		The enable flag.
+
+	<hr>
+*/
+#define ENABLE					(1)
+
+/*!	@ingroup	HALLayer
+	@def		DISABLE
+	@brief		The disable flag.
+
+	<hr>
+*/
+#define DISABLE					(0)
+
+/* bit position of important controller bits. */
+/*!	@ingroup	HALLayer
+	@def		CAN_CTRL_INIT
+	@brief		The INIT bit of CANCONT register.
+
+	<hr>
+*/
+#define CAN_CTRL_INIT			(0x0001)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_CTRL_IE
+	@brief		The IE bit of CANCONT register.
+
+	<hr>
+*/
+#define CAN_CTRL_IE		   		(0x0002)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_CTRL_IE_SIE_EIE
+	@brief		The IE + SIE + EIE bits of CANCONT register.
+
+	<hr>
+*/
+#define CAN_CTRL_IE_SIE_EIE 	(0x000e)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_CTRL_OPT
+	@brief		The OPT bit of CANCONT register.
+
+	<hr>
+*/
+#define CAN_CTRL_OPT       		(0x0080)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_OPT_SILENT
+	@brief		The Silent bit of CANOPT register.
+
+	<hr>
+*/
+#define CAN_OPT_SILENT     		(0x0008)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_CTRL_CCE
+	@brief		The configuration change bit of CANCONT register.
+
+	<hr>
+*/
+#define CAN_CTRL_CCE	   		(0x0040)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_CMASK_RX_TX_SET
+	@brief		The CMASK value used for writing the TX/RX message
+				object to the message RAM.
+
+	<hr>
+*/
+#define CAN_CMASK_RX_TX_SET   	(0x00f3)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_CMASK_RX_TX_GET
+	@brief		The CMASK value used for reading the TX/RX message
+				object from the message RAM.
+
+	<hr>
+*/
+#define CAN_CMASK_RX_TX_GET   	(0x0073)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_CMASK_ALL
+	@brief		The value for setting all the bits
+				of the CMASK register.
+
+	<hr>
+*/
+#define CAN_CMASK_ALL 	   		(0xff)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_CMASK_RDWR
+	@brief		The RD/WR bit of the CMASK register.
+
+	<hr>
+*/
+#define CAN_CMASK_RDWR 	   		(0x80)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_CMASK_ARB
+	@brief		The ARB bit of the CMASK register.
+
+	<hr>
+*/
+#define CAN_CMASK_ARB 	   		(0x20)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_CMASK_CTRL
+	@brief		The CTRL bit of the CMASK register.
+
+	<hr>
+*/
+#define CAN_CMASK_CTRL 	   		(0x10)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_CMASK_MASK
+	@brief		The MASK bit of the CMASK register.
+
+	<hr>
+*/
+#define CAN_CMASK_MASK 	   		(0x40)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_CMASK_CLPNT
+	@brief		The ClrintPnd bit of the CMASK register.
+
+	<hr>
+*/
+#define CAN_CMASK_CLPNT 	   	(0x08)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_CMASK_NEWINT
+	@brief		The TxRqst/NewDat bit for the CMASK register.
+
+	<hr>
+*/
+#define CAN_CMASK_NEWINT 	   	(0x04)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF_MCONT_NEWDAT
+	@brief		The NewDat bit of the MCONT register.
+
+	<hr>
+*/
+#define CAN_IF_MCONT_NEWDAT 	(0x8000)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF_MCONT_INTPND
+	@brief		The IntPnd bit of the MCONT register.
+
+	<hr>
+*/
+#define CAN_IF_MCONT_INTPND 	(0x2000)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF_MCONT_UMASK
+	@brief		The UMask bit of the MCONT register.
+
+	<hr>
+*/
+#define CAN_IF_MCONT_UMASK 		(0x1000)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF_MCONT_TXIE
+	@brief		The TxIE bit of the MCONT register.
+
+	<hr>
+*/
+#define CAN_IF_MCONT_TXIE 		(0x0800)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF_MCONT_RXIE
+	@brief		The RxIE bit of the MCONT register.
+
+	<hr>
+*/
+#define CAN_IF_MCONT_RXIE 		(0x0400)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF_MCONT_RMTEN
+	@brief		The RmtEn bit of the MCONT register.
+
+	<hr>
+*/
+#define CAN_IF_MCONT_RMTEN 		(0x0200)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF_MCONT_TXRQXT
+	@brief		The TxRqst bit of the MCONT register.
+
+	<hr>
+*/
+#define CAN_IF_MCONT_TXRQXT 	(0x0100)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF_MCONT_EOB
+	@brief		The E0B bit of the MCONT register.
+
+	<hr>
+*/
+#define CAN_IF_MCONT_EOB		(0x0080)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF_MCONT_MSGLOST
+	@brief		The MsgLst bit of the MCONT register.
+
+	<hr>
+*/
+#define CAN_IF_MCONT_MSGLOST	(0x4000)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_MASK2_MDIR_MXTD
+	@brief		The MXtd and Mdir bit of the MASK2 register.
+
+	<hr>
+*/
+#define CAN_MASK2_MDIR_MXTD 	(0xc000)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_ID2_MSGVAL_XTD_DIR
+	@brief		The MsgVal, Xtd and Dir bits of the ID2 register.
+
+	<hr>
+*/
+#define CAN_ID2_MSGVAL_XTD_DIR 	(0xe000)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_ID2_MSGVAL_DIR
+	@brief		The MsgVal and Dir bits of the ID2 register.
+
+	<hr>
+*/
+#define CAN_ID2_MSGVAL_DIR 		(0xa000)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_ID2_DIR
+	@brief		The Dir bit of the ID2 register.
+
+	<hr>
+*/
+#define CAN_ID2_DIR 			(0x2000)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_ID_MSGVAL
+	@brief		The MsgVal bit of the ID2 register.
+
+	<hr>
+*/
+#define CAN_ID_MSGVAL 			(0x8000)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF_MASK2_MDIR
+	@brief		The MDir bit of the MASK2 register.
+
+	<hr>
+*/
+#define CAN_IF_MASK2_MDIR		((u32)1 << 14)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF_MASK2_MXTD
+	@brief		The MXtd bit of the MASK2 register.
+
+	<hr>
+*/
+#define CAN_IF_MASK2_MXTD		((u32)1 << 15)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_STATUS_INT
+	@brief		The status interrupt value of the CAN device.
+
+	<hr>
+*/
+#define CAN_STATUS_INT			(0x8000)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF_CREQ_BUSY
+	@brief		The Busy flag bit of the CREQ register.
+
+	<hr>
+*/
+#define CAN_IF_CREQ_BUSY		(0x8000)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_ID2_XTD
+	@brief		The Xtd bit of ID2 register.
+
+	<hr>
+*/
+#define CAN_ID2_XTD				(0x4000)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_SRST_BIT
+	@brief		The SRST bit of the Soft reset register.
+
+	<hr>
+*/
+#define CAN_SRST_BIT			(0x0001)
+
+/* CAN register offset */
+	/* CAN registers */
+/*!	@ingroup	HALLayer
+	@def		CAN_CONT_OFFSET
+	@brief		The offset of CAN control register
+
+	<hr>
+*/
+#define CAN_CONT_OFFSET 		(0x00)	/*Can Control register */
+
+/*!	@ingroup	HALLayer
+	@def		CAN_STAT_OFFSET
+	@brief		The offset of CAN status register.
+
+	<hr>
+*/
+#define CAN_STAT_OFFSET  		(0x04)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_ERRC_OFFSET
+	@brief		The offset of CAN Error counter register
+
+	<hr>
+*/
+#define CAN_ERRC_OFFSET			(0x08)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_BITT_OFFSET
+	@brief		The offset of CAN timing register.
+
+	<hr>
+*/
+#define CAN_BITT_OFFSET 		(0x0c)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_INT_OFFSET
+	@brief		The offset of CAN interrupt register.
+
+	<hr>
+*/
+#define CAN_INT_OFFSET 	 		(0x010)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_OPT_OFFSET
+	@brief		The offset of CAN Option register
+
+	<hr>
+*/
+#define CAN_OPT_OFFSET			(0x14)	/*Extended function register */
+
+/*!	@ingroup	HALLayer
+	@def		CAN_BRPE_OFFSET
+	@brief		The offset of BRPE register.
+
+	<hr>
+*/
+#define CAN_BRPE_OFFSET 		(0x18)
+
+	/* Message interface one (IF1) registers */
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF1_CREQ_OFFSET
+	@brief		The offset of IF1 Command request register.
+
+	<hr>
+*/
+#define CAN_IF1_CREQ_OFFSET 	(0x020)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF1_CMASK_OFFSET
+	@brief		The offset of IF1 Command Mask register.
+
+	<hr>
+*/
+#define CAN_IF1_CMASK_OFFSET 	(0x024)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF1_ID1_OFFSET
+	@brief		The offset of IF1 ID1 register.
+
+	<hr>
+*/
+#define CAN_IF1_ID1_OFFSET 		(0x030)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF1_ID2_OFFSET
+	@brief		The offset of IF1 ID2 register.
+
+	<hr>
+*/
+#define CAN_IF1_ID2_OFFSET 		(0x034)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF1_MCONT_OFFSET
+	@brief		The offset of IF1 Message control register.
+
+	<hr>
+*/
+#define CAN_IF1_MCONT_OFFSET 	(0x038)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF1_DATAA1_OFFSET
+	@brief		The offset of IF1 DATAA1 register.
+
+	<hr>
+*/
+#define CAN_IF1_DATAA1_OFFSET	(0x03C)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF1_DATAA2_OFFSET
+	@brief		The offset of IF1 DATAA2 register.
+
+	<hr>
+*/
+#define CAN_IF1_DATAA2_OFFSET	(0x040)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF1_DATAB1_OFFSET
+	@brief		The offset of IF1 DATAB1 register.
+
+	<hr>
+*/
+#define CAN_IF1_DATAB1_OFFSET	(0x044)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF1_DATAB2_OFFSET
+	@brief		The offset of IF1 DATAB2 register.
+
+	<hr>
+*/
+#define CAN_IF1_DATAB2_OFFSET	(0x048)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF1_MASK1_OFFSET
+	@brief		The offset of IF1 MASK1 register.
+
+	<hr>
+*/
+#define CAN_IF1_MASK1_OFFSET	(0x028)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF1_MASK2_OFFSET
+	@brief		The offset of IF1 MASK2 register.
+
+	<hr>
+*/
+#define CAN_IF1_MASK2_OFFSET	(0x02c)
+
+	/* Message interface two (IF2) registers. */
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF2_CREQ_OFFSET
+	@brief		The offset of IF2 Command request register.
+
+	<hr>
+*/
+#define CAN_IF2_CREQ_OFFSET 	(0x080)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF2_CMASK_OFFSET
+	@brief		The offset of IF2 Command mask register.
+
+	<hr>
+*/
+#define CAN_IF2_CMASK_OFFSET 	(0x084)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF2_ID1_OFFSET
+	@brief		The offset of IF2 ID1 register.
+
+	<hr>
+*/
+#define CAN_IF2_ID1_OFFSET 		(0x090)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF2_ID2_OFFSET
+	@brief		The offset of IF2 ID2 register.
+
+	<hr>
+*/
+#define CAN_IF2_ID2_OFFSET 		(0x094)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF2_MCONT_OFFSET
+	@brief		The offset of IF2 Message control register.
+
+	<hr>
+*/
+#define CAN_IF2_MCONT_OFFSET 	(0x098)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF2_DATAA1_OFFSET
+	@brief		The offset of IF2 DATAA1 register.
+
+	<hr>
+*/
+#define CAN_IF2_DATAA1_OFFSET 	(0x09c)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF2_DATAA2_OFFSET
+	@brief		The offset of IF2 DATAA2 register.
+
+	<hr>
+*/
+#define CAN_IF2_DATAA2_OFFSET 	(0x0a0)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF2_DATAB1_OFFSET
+	@brief		The offset of IF2 DATAB1 register.
+
+	<hr>
+*/
+#define CAN_IF2_DATAB1_OFFSET 	(0x0a4)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF2_DATAB2_OFFSET
+	@brief		The offset of IF2 DATAB2 register.
+
+	<hr>
+*/
+#define CAN_IF2_DATAB2_OFFSET 	(0x0a8)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF2_MASK1_OFFSET
+	@brief		The offset of IF2 MASK1 register.
+
+	<hr>
+*/
+#define CAN_IF2_MASK1_OFFSET	(0x088)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_IF2_MASK2_OFFSET
+	@brief		The offset of IF2 MASK2 register.
+
+	<hr>
+*/
+#define CAN_IF2_MASK2_OFFSET	(0x08c)
+
+	/* Transmission request registers */
+/*!	@ingroup	HALLayer
+	@def		CAN_TREQ1_OFFSET
+	@brief		The offset of the CAN Transmission request register1.
+
+	<hr>
+*/
+#define CAN_TREQ1_OFFSET 		(0x100)
+
+/*!	@ingroup	HALLayer
+	@def		CAN_TREQ2_OFFSET
+	@brief		The offset of the CAN Transmission request register2.
+
+	<hr>
+*/
+#define CAN_TREQ2_OFFSET 		(0x104)
+
+	/* Soft Reset register. */
+/*!	@ingroup	HALLayer
+	@def		CAN_SRST_OFFSET
+	@brief		The offset of the CAN Soft reset register.
+
+	<hr>
+*/
+#define CAN_SRST_OFFSET			(0x1FC)
+
+	/* macros for shift operations. */
+/*!	@ingroup	HALLayer
+	@def		BIT_SHIFT_ONE
+	@brief		Bit shift by one.
+
+	<hr>
+*/
+#define BIT_SHIFT_ONE			(1)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_SHIFT_TWO
+	@brief		Bit shift by two.
+
+	<hr>
+*/
+#define BIT_SHIFT_TWO			(2)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_SHIFT_THREE
+	@brief		Bit shift by three.
+
+	<hr>
+*/
+#define BIT_SHIFT_THREE			(3)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_SHIFT_FOUR
+	@brief		Bit shift by four.
+
+	<hr>
+*/
+#define BIT_SHIFT_FOUR			(4)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_SHIFT_FIVE
+	@brief		Bit shift by five.
+
+	<hr>
+*/
+#define BIT_SHIFT_FIVE			(5)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_SHIFT_SIX
+	@brief		Bit shift by six.
+
+	<hr>
+*/
+#define BIT_SHIFT_SIX			(6)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_SHIFT_SEVEN
+	@brief		Bit shift by seven.
+
+	<hr>
+*/
+#define BIT_SHIFT_SEVEN			(7)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_SHIFT_EIGHT
+	@brief		Bit shift by eight.
+
+	<hr>
+*/
+#define BIT_SHIFT_EIGHT			(8)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_SHIFT_TWELVE
+	@brief		Bit shift by twelve.
+
+	<hr>
+*/
+#define BIT_SHIFT_TWELVE		(12)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_SHIFT_THIRTEEN
+	@brief		Bit shift by thirteen.
+
+	<hr>
+*/
+#define BIT_SHIFT_THIRTEEN		(13)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_SHIFT_FOURTEEN
+	@brief		Bit shift by fourteen.
+
+	<hr>
+*/
+#define BIT_SHIFT_FOURTEEN		(14)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_SHIFT_FIFTEEN
+	@brief		Bit shift by fifteen.
+
+	<hr>
+*/
+#define BIT_SHIFT_FIFTEEN		(15)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_SHIFT_SIXTEEN
+	@brief		Bit shift by sixteen.
+
+	<hr>
+*/
+#define BIT_SHIFT_SIXTEEN		(16)
+
+/* bit position of certain controller bits. */
+
+/*!	@ingroup	HALLayer
+	@def		BIT_BITT_BRP
+	@brief		The Baud Pre-scalar start bit position of the CANBITT
+			 register.
+
+	<hr>
+*/
+#define BIT_BITT_BRP			(0)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_BITT_SJW
+	@brief		The SJW start bit position of the CANBITT register.
+
+	<hr>
+*/
+#define BIT_BITT_SJW			(6)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_BITT_TSEG1
+	@brief		The start bit position of the time segment before a
+				 sampling point
+				of the CANBITT register.
+
+	<hr>
+*/
+#define BIT_BITT_TSEG1			(8)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_BITT_TSEG2
+	@brief		The start bit position of the time segment after a
+				 sampling point
+				of the CANBITT register.
+
+	<hr>
+*/
+#define BIT_BITT_TSEG2			(12)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_IF1_MCONT_RXIE
+	@brief		The RxIE bit position of the MCONT register.
+
+	<hr>
+*/
+#define BIT_IF1_MCONT_RXIE		(10)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_IF2_MCONT_TXIE
+	@brief		The TxIE bit position of the MCONT register.
+
+	<hr>
+*/
+#define BIT_IF2_MCONT_TXIE		(11)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_BRPE_BRPE
+	@brief		The shift value for extracting the extended baud
+				rate prescalar for the CANBRPE register.
+
+	<hr>
+*/
+#define BIT_BRPE_BRPE			(6)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_ES_TXERRCNT
+	@brief		The start bit position of the TX Error counter bits
+				of CANERRC register.
+
+	<hr>
+*/
+#define BIT_ES_TXERRCNT			(0)
+
+/*!	@ingroup	HALLayer
+	@def		BIT_ES_RXERRCNT
+	@brief		The start bit position of the RX Error counter bits
+				of CANERRC register.
+
+	<hr>
+*/
+#define BIT_ES_RXERRCNT			(8)
+
+/* macros used for masking. */
+
+/*!	@ingroup	HALLayer
+	@def		MSK_BITT_BRP
+	@brief		The mask value for extracting Baud Rate prescalar values
+				 for CANBITT register
+				from the user provided value.
+
+	<hr>
+*/
+#define MSK_BITT_BRP			(0x3f)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_BITT_SJW
+	@brief		The mask value for SJW bits.
+
+	<hr>
+*/
+#define MSK_BITT_SJW			(0xc0)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_BITT_TSEG1
+	@brief		The mask value for time segment bits (before a sampling
+			 point).
+
+	<hr>
+*/
+#define MSK_BITT_TSEG1			(0xf00)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_BITT_TSEG2
+	@brief		The mask value for time segment bits (after a sampling
+			 point)
+
+	<hr>
+*/
+#define MSK_BITT_TSEG2			(0x7000)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_BRPE_BRPE
+	@brief		The mask value for extracting Baud Rate prescalar value
+				 for
+				CANBRPE register from user provided value.
+
+	<hr>
+*/
+#define MSK_BRPE_BRPE			(0x3c0)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_BRPE_GET
+	@brief		The mask for Baud Rate prescalar bits of CANBRPE
+			 register.
+
+	<hr>
+*/
+#define MSK_BRPE_GET			(0x0f)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_CTRL_IE_SIE_EIE
+	@brief		The mask value for IE, SIE and EIE bits of the CANCONT
+				register.
+
+	<hr>
+*/
+#define MSK_CTRL_IE_SIE_EIE 	(0x07)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_MCONT_TXIE
+	@brief		The Mask value for TxIE bit of the MCONT register.
+
+	<hr>
+*/
+#define MSK_MCONT_TXIE 			(0x08)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_MCONT_RXIE
+	@brief		The Mask value for RxIE bit of the MCONT register.
+
+	<hr>
+*/
+#define MSK_MCONT_RXIE			(0x10)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_ALL_THREE
+	@brief		The mask value for the first three bits of any register.
+
+	<hr>
+*/
+#define MSK_ALL_THREE			(0x07)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_ALL_FOUR
+	@brief		The mask value for the first four bits of any register.
+
+	<hr>
+*/
+#define MSK_ALL_FOUR			(0x0f)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_ALL_EIGHT
+	@brief		The mask value for the first eight bits of any register.
+
+	<hr>
+*/
+#define MSK_ALL_EIGHT			(0xff)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_ALL_ELEVEN
+	@brief		The mask value for the first eleven bits of any
+			 register.
+
+	<hr>
+*/
+#define MSK_ALL_ELEVEN          (0x7ff)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_ALL_THIRTEEN
+	@brief		The mask value for the first thirteen bits of any
+			 register.
+
+	<hr>
+*/
+#define MSK_ALL_THIRTEEN		(0x1fff)
+
+/*!	@ingroup	HALLayer
+	@def		MSK_ALL_SIXTEEN
+	@brief		The mask value for the first sixteen bits of any
+			 register.
+
+	<hr>
+*/
+#define MSK_ALL_SIXTEEN			(0xffff)
+
+/* Error */
+
+/*!	@ingroup	HALLayer
+	@def		MSK_ES_TXERRCNT
+	@brief		The mask value for the TX Error counter bits of the
+				 CANERRC
+				register.
+
+	<hr>
+*/
+#define MSK_ES_TXERRCNT	((u32)0xff << BIT_ES_TXERRCNT)	/* Tx err count */
+
+/*!	@ingroup	HALLayer
+	@def		MSK_ES_RXERRCNT
+	@brief		The mask value for the RX Error counter bits of the
+				 CANERRC
+				register.
+
+	<hr>
+*/
+#define MSK_ES_RXERRCNT	((u32)0x7f << BIT_ES_RXERRCNT)	/* Rx err count */
+
+#define IOH_CAN_BIT_SET(reg, bitmask) 	\
+	IOH_WRITE_LONG((IOH_READ_LONG((reg)) | ((u32)(bitmask))), (reg))
+#define IOH_CAN_BIT_CLEAR(reg, bitmask) \
+	IOH_WRITE_LONG((IOH_READ_LONG((reg)) & ~((u32)(bitmask))), (reg))
+
+/*!	@ingroup	HALLayer
+	@def		IOH_CAN_NO_TX_BUFF
+	@brief		The flag value for denoting the unavailability of the
+				 transmit message
+				object.
+
+	@see
+			- ioh_can_msg_tx
+			- ioh_can_write
+
+	<hr>
+*/
+#define IOH_CAN_NO_TX_BUFF		(1)
+
+/*!	@ingroup	HALLayer
+	@def		ERROR_COUNT
+	@brief		The maximum error counter value.
+
+	@see
+			- ioh_can_get_error_stats
+
+	<hr>
+*/
+#define ERROR_COUNT				(96)
+
+/*! @ingroup	HALLayer
+	@struct 	ioh_can_os
+	@brief		Defines the fields for maintaining the CAN device
+				specific information.
+	@remarks	This structure is used by the driver for internal uses.
+				It stores the details of the CAN device at a
+				 particular
+				instance and uses this information for
+				 performing
+				operations on it.
+
+	<hr>
+*/
+
+struct ioh_can_os {
+	int can;		/**< CAN: device handle	*/
+	unsigned int opened;		/**< Linux opened device */
+	unsigned int can_num;		/**< Linux: CAN Number         	*/
+	unsigned long pci_remap;	/**< Linux: MMap regs          	*/
+	struct pci_dev *dev;		/**< Linux: PCI Device         	*/
+	unsigned int irq;		/**< Linux: IRQ                	*/
+	int block_mode;			/**< Blocking / non-blocking   	*/
+	int rx_fifo;	/**< Rx FIFO                   	*/
+	wait_queue_head_t read_wait_queue;	/**< Linux: Read wait queue */
+	wait_queue_head_t write_wait_queue;	/**< Linux: Write wait queue */
+	unsigned int write_wait_flag;		/**< Linux: Write wait flag   */
+	unsigned int read_wait_flag;		/**< Linux: Read wait flag    */
+	spinlock_t open_spinlock;	/**< Linux: Open lock variable */
+	unsigned int is_suspending;	/**< Linux: Is suspending state	*/
+	struct inode *inode;		/**< Linux: inode	*/
+	struct ioh_can_timing timing;		/**< CAN: timing              */
+	enum ioh_can_run_mode run_mode;		/**< CAN: run mode            */
+	enum ioh_can_listen_mode listen_mode;	/**< CAN: listen mode         */
+	enum ioh_can_arbiter arbiter_mode;		/**< CAN: arbiter mode        */
+	unsigned int tx_enable[MAX_MSG_OBJ];	/**< CAN: Tx buffer state     */
+	unsigned int rx_enable[MAX_MSG_OBJ];	/**< CAN: Rx buffer state     */
+	unsigned int rx_link[MAX_MSG_OBJ];	/**< CAN: Rx link set         */
+	unsigned int int_enables;		/**< CAN: ints enabled        */
+	unsigned int int_stat;			/**< CAN: int status	     */
+	unsigned int bus_off_interrupt;		/**< CAN: Buss off int flag   */
+	struct ioh_can_rx_filter rx_filter[MAX_MSG_OBJ]; /**< CAN: Rx filters      */
+	void (*can_callback) (struct ioh_can_os *); /**< CAN: callback function
+								 pointer.*/
+	spinlock_t tx_spinlock;		/**< CAN: transmission lock variable.*/
+};
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_create(u8 * io_base)
+
+	<hr>
+*/
+int ioh_can_create(u8 *io_base);
+
+/*! @ingroup	HALlayerAPI
+	@fn			void ioh_can_destroy(int handle
+
+	<hr>
+*/
+void ioh_can_destroy(int handle);
+
+/*! @ingroup	HALlayerAPI
+	@fn	int ioh_can_set_run_mode(
+			int handle,enum ioh_can_run_mode mode)
+
+	<hr>
+*/
+int ioh_can_set_run_mode(int handle, enum ioh_can_run_mode mode);
+
+/*! @ingroup	HALlayerAPI
+	@fn	int ioh_can_get_run_mode(
+			int handle,enum ioh_can_run_mode *mode)
+
+	<hr>
+*/
+int ioh_can_get_run_mode(int handle, enum ioh_can_run_mode *mode);
+
+/*! @ingroup	HALlayerAPI
+	@fn	int ioh_can_set_listen_mode(
+			int handle,enum ioh_can_listen_mode mode)
+
+	<hr>
+*/
+int ioh_can_set_listen_mode(int handle,
+			    enum ioh_can_listen_mode mode);
+
+/*! @ingroup	HALlayerAPI
+	@fn	int ioh_can_get_listen_mode(
+			int handle,enum ioh_can_listen_mode *mode)
+
+	<hr>
+*/
+int ioh_can_get_listen_mode(int handle,
+			    enum ioh_can_listen_mode *mode);
+
+/*! @ingroup	HALlayerAPI
+	@fn	int ioh_can_set_arbiter_mode(
+			int handle,enum ioh_can_arbiter mode)
+
+	<hr>
+*/
+int ioh_can_set_arbiter_mode(int handle, enum ioh_can_arbiter mode);
+
+/*! @ingroup	HALlayerAPI
+	@fn	int ioh_can_get_arbiter_mode(
+			int handle,enum ioh_can_arbiter *mode)
+
+	<hr>
+*/
+int ioh_can_get_arbiter_mode(int handle, enum ioh_can_arbiter *mode);
+
+/*! @ingroup	HALlayerAPI
+	@fn	int ioh_can_set_restart_mode(
+			int handle,enum ioh_can_auto_restart mode)
+
+	<hr>
+*/
+int ioh_can_set_restart_mode(int handle,
+			     enum ioh_can_auto_restart mode);
+
+/*! @ingroup	HALlayerAPI
+	@fn	int ioh_can_get_restart_mode(
+			int handle,enum ioh_can_auto_restart *mode)
+
+	<hr>
+*/
+int ioh_can_get_restart_mode(int handle,
+			     enum ioh_can_auto_restart *mode);
+
+/*! @ingroup	HALlayerAPI
+	@fn	int ioh_can_set_baud_simple(
+				int handle,enum ioh_can_baud baud)
+
+	<hr>
+*/
+int ioh_can_set_baud_simple(int handle, enum ioh_can_baud baud);
+
+/*! @ingroup	HALlayerAPI
+	@fn	int ioh_can_set_baud_custom(
+			int handle, struct ioh_can_timing *timing)
+
+	<hr>
+*/
+int ioh_can_set_baud_custom(int handle, struct ioh_can_timing *timing);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_get_baud(
+			int handle,struct ioh_can_timing *timing)
+
+	<hr>
+*/
+int ioh_can_get_baud(int handle, struct ioh_can_timing *timing);
+
+/*! @ingroup	HALlayerAPI
+	@fn		int ioh_can_set_rx_filter(
+			int handle,struct ioh_can_rx_filter *filter
+
+	<hr>
+*/
+int ioh_can_set_rx_filter(int handle,
+			  struct ioh_can_rx_filter *filter);
+
+/*! @ingroup	HALlayerAPI
+	@fn		int ioh_can_get_rx_filter(
+		int handle,struct ioh_can_rx_filter *filter
+
+	<hr>
+*/
+int ioh_can_get_rx_filter(int handle,
+			  struct ioh_can_rx_filter *filter);
+
+/*! @ingroup	HALlayerAPI
+	@fn	int ioh_can_msg_tx(
+				int handle,struct ioh_can_msg *msg)
+
+	<hr>
+*/
+int ioh_can_msg_tx(int handle, struct ioh_can_msg *msg);
+
+/*! @ingroup	HALlayerAPI
+	@fn	int ioh_can_open(
+int handle,enum ioh_can_listen_mode listen,enum ioh_can_arbiter arbiter)
+
+	<hr>
+*/
+int ioh_can_open(int handle, enum ioh_can_listen_mode listen,
+		 enum ioh_can_arbiter arbiter);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_int_pending(int handle)
+
+	<hr>
+*/
+int ioh_can_int_pending(int handle);
+
+/*! @ingroup	HALlayerAPI
+	@fn			void ioh_can_int_clr(
+					int handle,u32 mask)
+
+	<hr>
+*/
+void ioh_can_int_clr(int handle, u32 mask);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_clear_buffers(
+							int handle)
+
+	<hr>
+*/
+int ioh_can_clear_buffers(int handle);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_rx_dequeue(
+			int handle,struct ioh_can_msg *msg,u32 buff_num)
+*/
+int ioh_can_rx_dequeue(int handle, struct ioh_can_msg *msg,
+		       u32 buff_num);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_set_int_custom(
+					int handle,u32 interrupts)
+
+	<hr>
+*/
+int ioh_can_set_int_custom(int handle, u32 interrupts);
+
+/*! @ingroup	HALlayerAPI
+	@fn		int ioh_can_set_int_enables(
+			int handle,enum ioh_can_interrupt interrupt)
+
+	<hr>
+*/
+int ioh_can_set_int_enables(int handle,
+			    enum ioh_can_interrupt interrupt);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_get_int_enables(
+					int handle,u32 *enables)
+
+	<hr>
+*/
+int ioh_can_get_int_enables(int handle, u32 *enables);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_release(int handle)
+
+	<hr>
+*/
+int ioh_can_release(int handle);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_set_rx_buffer_link(
+				int handle,u32 buffer_num,u32 set)
+
+	<hr>
+*/
+int ioh_can_set_rx_buffer_link(int handle, u32 buffer_num,
+			       u32 set);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_get_rx_buffer_link(
+			int handle,u32 buffer_num,u32 *link)
+
+	<hr>
+*/
+int ioh_can_get_rx_buffer_link(int handle, u32 buffer_num,
+			       u32 *link);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_get_buffer_status(
+							int handle)
+
+	<hr>
+*/
+int ioh_can_get_buffer_status(int handle);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_rx_init_filter(
+					int handle,u32 buff_num)
+
+	<hr>
+*/
+int ioh_can_rx_init_filter(int handle, u32 buff_num);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_rx_disable_all(
+							int handle)
+
+	<hr>
+*/
+int ioh_can_rx_disable_all(int handle);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_tx_disable_all(
+							int handle)
+
+	<hr>
+*/
+int ioh_can_tx_disable_all(int handle);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_set_rx_enable(
+				int handle,u32 buff_num,u32 set)
+
+	<hr>
+*/
+int ioh_can_set_rx_enable(int handle, u32 buff_num, u32 set);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_get_rx_enable(
+			int handle,u32 buff_num,u32 *enable)
+
+	<hr>
+*/
+int ioh_can_get_rx_enable(int handle, u32 buff_num, u32 *enable);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_set_tx_enable(
+				int handle, u32 buff_num,u32 set)
+
+	<hr>
+*/
+int ioh_can_set_tx_enable(int handle, u32 buff_num, u32 set);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_get_tx_enable(
+			int handle,u32 buff_num,u32 *enable)
+
+	<hr>
+*/
+int ioh_can_get_tx_enable(int handle, u32 buff_num, u32 *enable);
+
+/*! @ingroup	HALlayerAPI
+	@fn			void ioh_can_config_rx_tx_buffers(
+							int handle)
+
+	<hr>
+*/
+void ioh_can_config_rx_tx_buffers(int handle);
+
+/*! @ingroup	HALlayerAPI
+	@fn		int ioh_can_get_error_stats(
+				int handle,struct ioh_can_error *error)
+
+	<hr>
+*/
+int ioh_can_get_error_stats(int handle, struct ioh_can_error *error);
+
+/*! @ingroup	HALlayerAPI
+	@fn			irqreturn_t ioh_can_handler(
+							int irq, void *dev_id)
+
+	<hr>
+*/
+irqreturn_t ioh_can_handler(int irq, void *dev_id);
+
+/*! @ingroup	HALlayerAPI
+	@fn			void icp_can_log_message(u32 status)
+
+	<hr>
+*/
+void icp_can_log_message(u32 status);
+
+/*! @ingroup	HALlayerAPI
+	@fn			int ioh_can_reset(struct ioh_can_os *can_os)
+
+	<hr>
+*/
+int ioh_can_reset(struct ioh_can_os *can_os);
+
+/*! @ingroup	HALlayerAPI
+	@fn			void ioh_can_entcb(
+	void(*ioh_can_cb)(struct ioh_can_os *),struct ioh_can_os * p_can_os)
+
+	<hr>
+*/
+void ioh_can_entcb(void (*ioh_can_cb) (struct ioh_can_os *),
+		   struct ioh_can_os *p_can_os);
+
+/*! @ingroup	HALlayerAPI
+	@fn		void ioh_can_callback(struct ioh_can_os * can_os)
+
+	<hr>
+*/
+void ioh_can_callback(struct ioh_can_os *can_os);
+#endif /* __IOH_CAN_HAL_H__ */
diff -urN linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_main.c topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_main.c
--- linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_main.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_main.c	2010-03-10 08:57:34.000000000 +0900
@@ -0,0 +1,1681 @@
+/*!
+ * @file ioh_can_main.c
+ * @brief Provides the function definition for the CAN driver functions.
+ * @version 1.0
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * <hr>
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+/* includes */
+#include <linux/module.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+#include <linux/sched.h>
+
+#include "pch_common.h"
+#include "pch_debug.h"
+#include "pch_can_main.h"
+#include "pch_can_hal.h"
+#include "pch_can_utils.h"
+#include "pch_can_pci.h"
+
+/*** Function prototypes ***/
+static int ioh_candev_open(struct inode *inode, struct file *file);
+static int ioh_candev_close(struct inode *inode, struct file *file);
+static ssize_t ioh_can_read(struct file *filep, char __user * buf, size_t count,
+			    loff_t *f_pos);
+static ssize_t ioh_can_write(struct file *filp, const char __user * buf,
+			     size_t count, loff_t *f_pos);
+static int ioh_can_ioctl(struct inode *inode, struct file *filp,
+			 unsigned int cmd, unsigned long arg);
+static void can_ioctl_buff_size(unsigned int ctl_code, size_t *in_size,
+				size_t *out_size);
+
+/*********/
+
+/*! @ingroup	InterfaceLayerFacilitators
+	@struct		file_ops
+	@brief		Kernel structure for holding references to CAN driver
+				 methods.
+				Used during the CAN driver registeration.
+	@see
+				- ioh_can_probe
+
+	<hr>
+*/
+const struct file_operations file_ops = {
+	.owner = THIS_MODULE,
+	.read = ioh_can_read,
+	.write = ioh_can_write,
+	.ioctl = ioh_can_ioctl,
+	.open = ioh_candev_open,
+	.release = ioh_candev_close
+};
+
+#ifdef DEBUG
+/*!	@ingroup 	Debug
+	@def		IOCTL_CAN_DEBUG
+	@brief		Included for debugging the CAN Driver API.
+	@remarks	It provides an ioctl command through which,
+				the device registers can be read/write.
+				The argument for the command is the structure
+				shown below.
+
+	@note		Can be used only when the DEBUG flag is set during
+				compiling.
+
+	<br>
+*/
+#define IOCTL_CAN_DEBUG			(40)
+
+/*!	@ingroup 	Debug
+	@struct		debug
+	@brief		Included for passing the debug commands to  the
+				 CAN Driver.
+	@remarks	It provides a format for specifying the required
+				debug operation commands and associated
+				 paramters
+				to the Driver.
+	@note		Can be used only when the DEBUG flag is set during
+				compiling.
+
+	<br>
+*/
+struct debug {
+	unsigned char cmd;		/**< (1: Read) (2: Write). 	*/
+	unsigned short offset;		/**< Offset of th register.	*/
+	unsigned long value;		/**< Read Value/Value to be written */
+};
+
+#endif
+
+/*! @ingroup 	InterfaceLayerAPI
+	@fn			static int ioh_candev_open(
+				struct inode *inode, struct file *file)
+	@brief		Implements the open functionalities of the CAN driver.
+	@remarks
+				This function is used as the open function of
+				 the driver. The main
+				 tasks performed by this function are :
+				- Confirms that at a time only one device is
+					 using the CAN device.
+				- Initializes the CAN device to be used by the
+					 driver.
+				- Initializes the driver data structures for
+					 further use.
+	@note		This function is invoked by the kernel subsystem when a
+					 process
+				issues an open system call on the associated
+						 device driver.
+
+	@param	inode		[@ref INOUT]	Reference to the inode structure
+						 of the device file.
+	@param	file		[@ref INOUT]	Reference to the file structure
+						 of the device file.
+
+	@retval	int
+			- @ref IOH_CAN_SUCCESS	--> Operation successful.
+			- EBUSY    	--> Device already opened.
+			- -ENOMEM	--> request_irq error status code.
+			- -EBUSY	--> request_irq error status code.
+			- -ENOSYS 	--> request_irq error status code.
+			- @ref IOH_CAN_FAIL --> ioh_can_open fails/
+						create_can_fifo fails.
+
+	<hr>
+
+*/
+static int ioh_candev_open(struct inode *inode, struct file *file)
+{
+	int retval = IOH_CAN_SUCCESS;
+	struct ioh_can_os *dev_can_os = \
+				(struct ioh_can_os *)&(can_os[iminor(inode)]);
+	unsigned long flags;
+
+	/* Attaining lock for open. */
+	spin_lock_irqsave(&(dev_can_os->open_spinlock), flags);
+
+	/* Check if CAN is already open */
+	if (0 == (dev_can_os->opened)) {
+		/* Resetting the hardware. */
+/*              (void)ioh_can_reset(dev_can_os); */
+/*		IOH_DEBUG("ioh_candev_open -> Function ioh_can_reset invoked " \
+						"successfully.\n");
+*/
+		/* Initializing the CAN hardware. */
+		retval = ioh_can_open(dev_can_os->can,
+				      file->
+				      f_flags & O_RDONLY ? IOH_CAN_LISTEN :
+				      IOH_CAN_ACTIVE, IOH_CAN_FIXED_PRIORITY);
+
+		if (retval != IOH_CAN_SUCCESS) {
+			IOH_LOG(KERN_ERR,
+				"ioh_candev_open -> ioh_can_open failed "
+				"(returned %d).\n", retval);
+		} else {
+			IOH_DEBUG
+			    ("ioh_candev_open -> \
+				ioh_can_open invoked successfully "
+			     "(returned %d).\n", retval);
+
+			dev_can_os->rx_fifo = create_can_fifo(NUM_NODES);
+
+			if (!(dev_can_os->rx_fifo)) {
+				IOH_LOG(KERN_ERR,
+					"ioh_candev_open -> create_can_fifo "
+					"failed.\n");
+
+				(void)ioh_can_release(dev_can_os->can);
+				IOH_DEBUG
+				("ioh_candev_open -> ioh_can_release invoked "
+				"successfully.\n");
+
+				retval = IOH_CAN_FAIL;
+			} else {
+				IOH_DEBUG
+				("ioh_candev_open -> create_can_fifo invoked "
+				"successfully.\n");
+
+				/* Registering the callback function for
+							 interrupt handling. */
+				ioh_can_entcb(ioh_can_callback, dev_can_os);
+				IOH_DEBUG
+				    ("ioh_candev_open -> ioh_can_entcb invoked \
+							successfully.\n");
+
+				/* Regsitering the interrupt. */
+				retval =
+				    request_irq(dev_can_os->irq,
+						ioh_can_handler, IRQF_SHARED,
+						"can", &can_os[iminor(inode)]
+				    );
+
+				if (0 != retval) {
+					(void)ioh_can_release(dev_can_os->can);
+					delete_can_fifo(dev_can_os->rx_fifo);
+					dev_can_os->rx_fifo = 0;
+					dev_can_os->can_callback = NULL;
+
+					IOH_LOG(KERN_ERR,
+						"ioh_candev_open -> \
+						request_irq failed on irq %d"
+						"(returned %d).\n",
+						dev_can_os->irq, retval);
+				} else {
+					IOH_DEBUG
+					    ("ioh_candev_open -> request_irq \
+						invoked "
+					     "successfully(returned %d).\n",
+					     retval);
+
+					/* Assuming that no bus off
+								 interrupt. */
+					dev_can_os->bus_off_interrupt = 0;
+					dev_can_os->write_wait_flag = 0;
+
+					/* Setting the block mode. */
+					dev_can_os->block_mode = 1;
+
+					dev_can_os->inode = inode;
+					dev_can_os->opened = 1;
+
+					/* Storing the can structure for further
+									 use. */
+					file->private_data = dev_can_os;
+
+					retval = IOH_CAN_SUCCESS;
+				}
+			}
+		}
+	} else {
+		retval = -EBUSY;
+		IOH_LOG(KERN_ERR,
+			"ioh_candev_open -> CAN device already open.\n");
+	}
+
+	spin_unlock_irqrestore(&(dev_can_os->open_spinlock), flags);
+
+	IOH_DEBUG("ioh_candev_open returns %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup	InterfaceLayerAPI
+	@fn			static int ioh_candev_close(struct inode *inode,
+				 struct file *file)
+	@brief		Implements the close functionalities of the CAN driver.
+	@remarks	This function is used as the close function of the
+			 driver. The main
+				 tasks performed by this function are :
+				- De-initializes the CAN device hardware so that
+				 the device can be closed.
+				- Releases the resources attained during the
+				 opening of the device.
+				- Re-initializes the data structures so that it
+				 can be used further.
+	@note		This function is invoked by the Kernel subsystem when an
+			 application issues a close system call on the
+			 associated device file.
+
+	@param	inode		[@ref INOUT]	Reference to the inode structure
+						 of the
+						device file.
+	@param	file		[@ref INOUT]	Reference to the file structure
+						 of the
+						device file.
+
+	@retval	int
+				- @ref IOH_CAN_SUCCESS		--> The close
+						 operation was successful.
+
+	<hr>
+*/
+static int ioh_candev_close(struct inode *inode, struct file *file)
+{
+	int retval;
+	struct ioh_can_os *can_os = (struct ioh_can_os *) file->private_data;
+
+	/* Attaining the lock for close. */
+	spin_lock(&(can_os->open_spinlock));
+
+	retval = ioh_can_release(can_os->can);
+	IOH_DEBUG("ioh_candev_close -> ioh_can_release invoked successfully"
+		  "(returned %d).\n", retval);
+
+	(void)ioh_can_set_int_enables(can_os->can, CAN_DISABLE);
+
+	free_irq(can_os->irq, &(can_os[iminor(can_os->inode)]));
+	IOH_DEBUG("ioh_candev_close -> free_irq invoked successfully.\n");
+
+	/* Delete FIFO. */
+	delete_can_fifo(can_os->rx_fifo);
+	IOH_DEBUG
+	    ("ioh_candev_close -> delete_can_fifo invoked successfully.\n");
+
+	/* Resetting the open flag. */
+	can_os->opened = 0;
+	file->private_data = NULL;
+	can_os->rx_fifo = 0;
+	can_os->can_callback = NULL;
+
+	/* Releasing the lock. */
+	spin_unlock(&(can_os->open_spinlock));
+
+	if (retval != IOH_CAN_SUCCESS) {
+		IOH_LOG(KERN_ERR, "ioh_candev_close -> Release failed "
+			"on CAN device %d.\n", iminor(inode));
+
+	}
+
+	IOH_DEBUG("ioh_candev_close returns %d.\n", IOH_CAN_SUCCESS);
+	return IOH_CAN_SUCCESS;
+}
+
+/*! @ingroup	InterfaceLayerAPI
+	@fn			static ssize_t ioh_can_read(
+					struct file *filp, char __user *buf,
+					 size_t count,loff_t *f_pos)
+	@brief		Implements the read functionalities of the CAN driver.
+	@remarks	This function is used as the read function of the
+				 driver. The main tasks of this function are :
+				- Reads the received message data from the
+				 software FIFO if it
+				  is available and copies it to the user process
+				 for further
+				  use.
+				- If the CAN device is in blocking mode and if
+				 no data is
+				  available, this function waits until the
+				 message data is
+				  available within the software FIFO.
+	@note		This function is invoked by the Kernel subsystem when a
+				 process
+				issues read system call on the associated device
+				 file.
+
+	@param	filp		[@ref INOUT]	Reference to the file structure
+						 of the device file.
+	@param	buf			[@ref OUT]		Reference to the
+							 user level buffer for
+							updating the read data.
+	@param	count		[@ref IN]		The size to be read.
+	@param	f_pos		[@ref INOUT]	Not used.
+
+	@retval	ssize_t
+				- Size of the message object
+					--> Read operation successful.
+				- -ENOMEM 	--> copy_to_user fails.
+				- -EAGAIN 	--> Device in suspended
+							 mode/non blocking
+							 read with software FIFO
+							 empty.
+				- -EIO 		--> read_can_fifo fails/read
+							 wait in blocking mode
+							 fails.
+				- -EINVAL 	--> Parameter buf/count is not
+							 valid.
+
+	<hr>
+*/
+static ssize_t ioh_can_read(struct file *filp, char __user * buf, size_t count,
+			    loff_t *f_pos)
+{
+	ssize_t retval = IOH_CAN_SUCCESS;	/* Return status value. */
+	struct ioh_can_msg msg;	/* Msg variable for reading. */
+	struct ioh_can_os *can_os = (struct ioh_can_os *) filp->private_data;
+
+	/* If device susupended */
+	if ((can_os->is_suspending) == 1) {
+		IOH_LOG(KERN_ERR, "ioh_can_read -> Device suspended.\n");
+		retval = -EAGAIN;
+	}
+	/* If invalid parameters. */
+	else if ((buf == NULL) || (count < sizeof(struct ioh_can_msg))) {
+		IOH_LOG(KERN_ERR,
+			"ioh_can_read -> Invalid parameter for read.\n");
+		retval = -EINVAL;
+	}
+	/* If NON_BLOCK mode and FIFO(software) empty. */
+	else if (((can_os->block_mode == 0))
+		 && (check_can_fifo_status(can_os->rx_fifo) ==
+		     IOH_CAN_FIFO_EMPTY)) {
+		IOH_LOG(KERN_ERR,
+			"ioh_can_read -> Buffer empty and device in non-block \
+								mode.\n");
+		retval = -EAGAIN;
+	}
+
+	/* If block mode and FIFO(software) empty. */
+	else if ((can_os->block_mode == 1)
+		 && (check_can_fifo_status(can_os->rx_fifo) ==
+		     IOH_CAN_FIFO_EMPTY)) {
+		IOH_DEBUG
+		    ("ioh_can_read -> \
+				Waiting for FIFO to be filled with data.\n");
+		/* Preparing to wait. */
+		can_os->read_wait_flag = 1;
+		retval = wait_event_interruptible(can_os->read_wait_queue,
+						  (check_can_fifo_status
+						   (can_os->rx_fifo) !=
+						   IOH_CAN_FIFO_EMPTY));
+
+		/* Wait fails. */
+		if (-ERESTARTSYS == retval) {
+			IOH_LOG(KERN_ERR,
+				"ioh_can_read -> \
+				Wait_event_interruptible failed on read.\n");
+			retval = -EIO;
+		}
+	}
+
+	if (IOH_CAN_SUCCESS == retval) {
+		retval = read_can_fifo(can_os->rx_fifo, &msg);
+
+		if (retval) {
+			IOH_LOG(KERN_ERR,
+				"ioh_can_read -> Read from FIFO failed.\n");
+			retval = -EIO;
+		} else {
+			IOH_DEBUG
+			    ("ioh_can_read -> Read from FIFO successful.\n");
+			IOH_DEBUG("ioh_can_read -> The read message is: \n");
+			IOH_DEBUG("Msg ID   : 0x%x\n", msg.id);
+			IOH_DEBUG("EXT ID   : %x\n", msg.ide);
+			IOH_DEBUG("Msg Size : %hu\n", msg.dlc);
+			IOH_DEBUG("Rment    : %hu\n", msg.rtr);
+			IOH_DEBUG("Dat Byt1 : 0x%x\n", msg.data[0]);
+			IOH_DEBUG("Dat Byt2 : 0x%x\n", msg.data[1]);
+			IOH_DEBUG("Dat Byt3 : 0x%x\n", msg.data[2]);
+			IOH_DEBUG("Dat Byt4 : 0x%x\n", msg.data[3]);
+			IOH_DEBUG("Dat Byt5 : 0x%x\n", msg.data[4]);
+			IOH_DEBUG("Dat Byt6 : 0x%x\n", msg.data[5]);
+			IOH_DEBUG("Dat Byt7 : 0x%x\n", msg.data[6]);
+			IOH_DEBUG("Dat Byt8 : 0x%x\n", msg.data[7]);
+
+			retval = copy_to_user(buf, &msg, sizeof(msg));
+
+			if (retval) {
+				IOH_LOG(KERN_ERR,
+					"ioh_can_read -> \
+					Copy to user failed for CAN.\n");
+				retval = -ENOMEM;
+			} else {
+				retval = sizeof(struct ioh_can_msg);
+			}
+		}
+	}
+
+	IOH_DEBUG("ioh_can_read -> Return Value: %d.\n", retval);
+	return retval;
+}
+
+/*! @ingroup	InterfaceLayerAPI
+	@fn			ssize_t ioh_can_write(
+	struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)
+	@brief		Implements the write functionalities of the CAN Driver.
+	@remarks	This function is used as the write function of the
+				 driver.
+				The main tasks performed by this function are :
+				- Obtains the data from the user process and
+				 updates it into the
+				  hardware buffers (if available) for
+				 transmission as message objects.
+				- If the CAN device is in Blocking mode and if
+				 no transmit message
+				  object is available, then this function waits
+				 until a transmit
+				  buffer is available for transmission.
+	@note		This function is invoked by the Kernel subsystem when a
+				 process issues a write system call on the
+				 associated device file.
+
+	@param	filp		[@ref INOUT]	Reference to the file structure
+						 of the device file
+	@param	buf			[@ref IN]		Reference to the
+						 user level buffer containing
+						data to be written(transmitted).
+	@param	count		[@ref IN]		Size of the data to be
+							 written.
+	@param	f_pos		[@ref INOUT]	Not Used.
+
+	@retval	ssize_t
+				- Size of the message object
+							--> Write is successful.
+				- -ENOMEM --> copy_from_user error status code
+				- -EAGAIN --> Device in suspended mode.
+				- -EIO 	--> Non-blocking write fails
+				- -EINVAL --> Size of CAN message not valid.
+				- @ref IOH_CAN_FAIL 	--> Transmit fails.
+
+	<hr>
+*/
+ssize_t ioh_can_write(struct file *filp, const char __user *buf, size_t count,
+		      loff_t *f_pos)
+{
+	struct ioh_can_msg msg;	/* The message object for writing. */
+	int err;		/* error variable. */
+	struct ioh_can_os *can_os = (struct ioh_can_os *) filp->private_data;
+	ssize_t ret;
+
+	/* If device suspended. */
+	if ((can_os->is_suspending) == 1) {
+		IOH_LOG(KERN_ERR,
+			"ioh_can_write -> Device is in suspend mode.\n");
+		IOH_DEBUG("ioh_can_write returns %d\n", -EAGAIN);
+		return -EAGAIN;
+	}
+
+	/* if invalid count. */
+	if (count != sizeof(struct ioh_can_msg)) {
+		IOH_LOG(KERN_ERR,
+			"ioh_can_write -> Write user buffer size invalid "
+			"for CAN.\n");
+		IOH_DEBUG("ioh_can_write returns %d\n", -EINVAL);
+		return -EINVAL;
+	}
+
+	err = copy_from_user(&msg, buf, count);
+
+	if (err) {
+		IOH_LOG(KERN_ERR,
+			"ioh_can_write -> Copy from user failed for CAN in "
+			"write operation.\n");
+		IOH_DEBUG("ioh_can_write returns %d\n", -ENOMEM);
+		return -ENOMEM;
+	}
+
+	/* The wait flag. */
+	can_os->write_wait_flag = 1;
+
+	/* Transmitting the message. */
+	err = ioh_can_msg_tx(can_os->can, &msg);
+
+	if ((err != IOH_CAN_SUCCESS)) {
+		/* Transmission failed due to unavailability of transmit object
+						 and it is block mode. */
+		if ((IOH_CAN_NO_TX_BUFF == err) && (can_os->block_mode == 1)) {
+			IOH_DEBUG
+			    ("ioh_can_write -> Waiting for transmit message "
+			     "object.\n");
+
+			/* Prpearing to wait. */
+			err = wait_event_interruptible(can_os->write_wait_queue,
+						       can_os->
+						       write_wait_flag == 0);
+
+			if (-ERESTARTSYS == err) {
+				IOH_LOG(KERN_ERR,
+					"ioh_can_write -> \
+					Write wait failed.\n");
+				IOH_DEBUG("ioh_can_write returns %d\n",
+					  -EAGAIN);
+				return -EAGAIN;
+			}
+
+			/* Transmitting again. */
+			err = ioh_can_msg_tx(can_os->can, &msg);
+
+			/* If again error. */
+			if (err != IOH_CAN_SUCCESS) {
+				IOH_LOG(KERN_ERR,
+					"ioh_can_write -> Transmit failed "
+					"after 2 attempts.\n");
+				IOH_DEBUG("ioh_can_write returns %d\n",
+					  IOH_CAN_FAIL);
+				return IOH_CAN_FAIL;
+			}
+		} else {	/* If failed due to some other reasons. */
+
+			IOH_LOG(KERN_ERR,
+				"ioh_can_write -> Write from CAN device "
+				"failed %d.\n", -EIO);
+			IOH_DEBUG("ioh_can_write returns %d\n", -EIO);
+			return -EIO;
+		}
+	}
+	IOH_DEBUG
+	    ("ioh_can_write -> Message send for transmission successfully.\n");
+	IOH_DEBUG("The transmitted Message is :\n");
+	IOH_DEBUG("Msg ID   : 0x%x\n", msg.id);
+	IOH_DEBUG("EXT ID   : %hu\n", msg.ide);
+	IOH_DEBUG("Msg Size : %hu\n", msg.dlc);
+	IOH_DEBUG("Rment    : %hu\n", msg.rtr);
+	IOH_DEBUG("Dat Byt1 : 0x%x\n", msg.data[0]);
+	IOH_DEBUG("Dat Byt2 : 0x%x\n", msg.data[1]);
+	IOH_DEBUG("Dat Byt3 : 0x%x\n", msg.data[2]);
+	IOH_DEBUG("Dat Byt4 : 0x%x\n", msg.data[3]);
+	IOH_DEBUG("Dat Byt5 : 0x%x\n", msg.data[4]);
+	IOH_DEBUG("Dat Byt6 : 0x%x\n", msg.data[5]);
+	IOH_DEBUG("Dat Byt7 : 0x%x\n", msg.data[6]);
+	IOH_DEBUG("Dat Byt8 : 0x%x\n", msg.data[7]);
+
+	IOH_DEBUG("ioh_can_write -> Write from CAN device successful "
+		  "( returns %d).", sizeof(struct ioh_can_msg));
+
+	ret = sizeof(struct ioh_can_msg);
+	return ret;
+}
+
+/*! @ingroup	InterfaceLayerAPI
+	@fn			static int ioh_can_ioctl(
+struct inode *inode, struct file *filp, unsigned int cmd,unsigned long arg)
+	@brief		Implements the ioctl functionalities of the CAN driver.
+	@remarks	This function is used as the ioctl function of the
+				 Driver.
+				The main tasks performed by this function are :
+				- Checks for the validity of the obtained IOCTL
+				 command.
+				- Performs the associated operation for the
+				 valid IOCTL
+				  command by invoking the corresponding HAL
+				 APIs.
+				- Copies the data if required back to the user
+				 process.
+	@note		This function is invoked by the Kernel subsystem when
+				a process issues an ioctl system call on the
+				 associated
+				device file.
+
+	@param	inode		[@ref INOUT]		Reference to the inode
+							 structure of the device
+							file.
+	@param	filp		[@ref INOUT]		Reference to the file
+							 structure of the device
+							file.
+	@param	cmd			[@ref IN]	The ioctl command to be
+							 executed.
+	@param	arg			[@ref INOUT]	The argument reference
+							 to be used.
+
+	@retval	int
+				- @ref	IOH_CAN_SUCCESS	--> The operation was
+								 successful.
+				- -ENOMEM --> copy_to_user/copy_from_user fails.
+				- -EAGAIN --> Memory allocation fails for input
+						/output buffer.
+				- @ref	IOH_CAN_FAIL 		--> IOCTL fails.
+
+	<hr>
+*/
+static int ioh_can_ioctl
+    (struct inode *inode, struct file *filp, unsigned int cmd,
+     unsigned long arg) {
+	struct ioh_can_os *can_os;
+	int retval = IOH_CAN_SUCCESS;
+	void *in = NULL;
+	void *out = NULL;
+	size_t in_buff_size = 0;
+	size_t out_buff_size = 0;
+	can_os = (struct ioh_can_os *) filp->private_data;
+
+	can_ioctl_buff_size(cmd, &in_buff_size, &out_buff_size);
+
+	if (can_os->is_suspending == 1) {
+		IOH_LOG(KERN_ERR, "ioh_can_ioctl -> Device suspended.\n");
+		retval = -EAGAIN;
+	}
+
+	if ((in_buff_size != 0) && (retval == IOH_CAN_SUCCESS)) {
+		in = kmalloc(in_buff_size, GFP_KERNEL);
+
+		if (in != NULL) {
+			retval = copy_from_user(in, (void *)arg, in_buff_size);
+			if (retval != 0) {
+				IOH_LOG(KERN_ERR, "ioh_can_ioctl -> Copy from "
+					"user failed.\n");
+				retval = -ENOMEM;
+			}
+		} else {
+			IOH_LOG(KERN_ERR, "ioh_can_ioctl -> Memory allocation "
+				"failed for input argument.\n");
+			retval = -EAGAIN;
+		}
+	}
+
+	if ((out_buff_size != 0) && (IOH_CAN_SUCCESS == retval)) {
+		out = kmalloc(out_buff_size, GFP_KERNEL);
+
+		if (out == NULL) {
+			IOH_LOG(KERN_ERR, "ioh_can_ioctl -> Memory allocation "
+				"failed for output argument.\n");
+			retval = -EAGAIN;
+		}
+	}
+
+	if (IOH_CAN_SUCCESS == retval) {
+		switch (cmd) {
+		case IOCTL_CAN_RESET:
+			IOH_DEBUG("ioh_can_ioctl -> IOCTL_CAN_RESET\n");
+			retval = ioh_can_reset(can_os);
+			break;
+
+		case IOCTL_CAN_RUN:
+			IOH_DEBUG("ioh_can_ioctl -> Command received "
+				  "IOCTL_CAN_RUN\n");
+			retval = ioh_can_set_run_mode(can_os->can, IOH_CAN_RUN);
+			break;
+
+		case IOCTL_CAN_RUN_GET:
+			IOH_DEBUG("ioh_can_ioctl -> Command received "
+				  "IOCTL_CAN_RUN_GET\n");
+			retval =
+			    ioh_can_get_run_mode(can_os->can,
+						 (enum ioh_can_run_mode *) out);
+			break;
+
+		case IOCTL_CAN_STOP:
+			IOH_DEBUG("ioh_can_ioctl -> Command received "
+				  "IOCTL_CAN_STOP:\n");
+			retval =
+			    ioh_can_set_run_mode(can_os->can, IOH_CAN_STOP);
+			break;
+
+		case IOCTL_CAN_SIMPLE:
+			{
+				enum ioh_can_run_mode curr_mode;
+				IOH_DEBUG("ioh_can_ioctl -> Command "
+					  "received IOCTL_CAN_SIMPLE\n");
+
+				(void)ioh_can_get_run_mode(can_os->can,
+							   &curr_mode);
+				if (curr_mode == IOH_CAN_RUN) {
+					(void)ioh_can_set_run_mode(can_os->can,
+								IOH_CAN_STOP);
+				}
+				retval =
+				    ioh_can_set_baud_simple(can_os->can,
+							*((enum ioh_can_baud *)
+							      in));
+				if (curr_mode == IOH_CAN_RUN) {
+					(void)ioh_can_set_run_mode(can_os->can,
+								   IOH_CAN_RUN);
+				}
+			}
+			break;
+
+		case IOCTL_CAN_CUSTOM:
+			{
+				enum ioh_can_run_mode curr_mode;
+
+				IOH_DEBUG("ioh_can_ioctl -> Command "
+					  "received IOCTL_CAN_CUSTOM\n");
+
+				(void)ioh_can_get_run_mode(can_os->can,
+							   &curr_mode);
+				if (curr_mode == IOH_CAN_RUN) {
+					(void)ioh_can_set_run_mode(can_os->can,
+								IOH_CAN_STOP);
+				}
+				retval =
+				    ioh_can_set_baud_custom(can_os->can,
+						(struct ioh_can_timing *)
+						in);
+				if (curr_mode == IOH_CAN_RUN) {
+					(void)ioh_can_set_run_mode(can_os->can,
+								   IOH_CAN_RUN);
+				}
+			}
+			break;
+
+		case IOCTL_CAN_TIMING_GET:
+			IOH_DEBUG("ioh_can_ioctl -> IOCTL_CAN_TIMING_GET\n");
+			retval =
+			    ioh_can_get_baud(can_os->can,
+					     (struct ioh_can_timing *) out);
+			break;
+
+		case IOCTL_CAN_FILTER:
+			{
+				unsigned int buff_num = 0;
+				int i = 0;
+				unsigned int status = 0;
+				struct ioh_can_rx_filter *rx_filter =
+				    (struct ioh_can_rx_filter *) in;
+
+				IOH_DEBUG("ioh_can_ioctl -> Command received "
+					  "IOCTL_CAN_FILTER\n");
+
+				for (i = 0;
+				     i <
+				     (ioh_can_tx_buf_size +
+				      ioh_can_rx_buf_size); i++) {
+					if (ioh_msg_obj_conf[i] == 0) {
+						buff_num++;
+						if (buff_num ==
+						    (rx_filter->num)) {
+							break;
+						}
+					}
+				}
+
+				if (i ==
+				    (ioh_can_tx_buf_size +
+				     ioh_can_rx_buf_size)) {
+					IOH_DEBUG("ioh_can_ioctl -> InValid "
+						  "message buffer.");
+					retval = IOH_CAN_FAIL;
+				} else {
+					/* Here i is the index, however (i+1) is
+							 object number. */
+					rx_filter->num = (i + 1);
+
+					(void)ioh_can_get_rx_enable(can_os->can,
+								    rx_filter->
+								    num,
+								    &status);
+					if (status == ENABLE) {
+						(void)
+						    ioh_can_set_rx_enable
+						    (can_os->can,
+						     rx_filter->num, DISABLE);
+					}
+					retval =
+					    ioh_can_set_rx_filter(can_os->can,
+								  rx_filter);
+					if (status == ENABLE) {
+						(void)
+						    ioh_can_set_rx_enable
+						    (can_os->can,
+						     rx_filter->num, ENABLE);
+					}
+				}
+			}
+			break;
+
+		case IOCTL_CAN_FILTER_GET:
+			{
+				unsigned int buff_num = 0;
+				int i = 0;
+				unsigned int status = 0;
+				struct ioh_can_rx_filter *rx_filter =
+				    (struct ioh_can_rx_filter *) out;
+
+				IOH_DEBUG("ioh_can_ioctl -> Command received "
+					  "IOCTL_CAN_FILTER_GET\n");
+
+				rx_filter->num =
+				    ((struct ioh_can_rx_filter *) in)->num;
+
+				for (i = 0;
+				     i <
+				     (ioh_can_tx_buf_size +
+				      ioh_can_rx_buf_size); i++) {
+					if (ioh_msg_obj_conf[i] == 0) {
+						buff_num++;
+						if (buff_num == rx_filter->num)
+							break;
+					}
+				}
+
+				if (i ==
+				    (ioh_can_tx_buf_size +
+				     ioh_can_rx_buf_size)) {
+					IOH_DEBUG
+					    ("ioh_can_ioctl -> InValid message "
+					     "buffer %x.\n", rx_filter->num);
+					retval = IOH_CAN_FAIL;
+				} else {
+					/* Here i is the index, however (i+1) is
+							 object number. */
+					rx_filter->num = (i + 1);
+
+					(void)ioh_can_get_rx_enable(can_os->can,
+								    rx_filter->
+								    num,
+								    &status);
+
+					if (status == ENABLE) {
+						(void)
+						    ioh_can_set_rx_enable
+						    (can_os->can,
+						     rx_filter->num, DISABLE);
+					}
+
+					retval =
+					    ioh_can_get_rx_filter(can_os->can,
+								  rx_filter);
+
+					if (status == ENABLE) {
+						(void)
+						    ioh_can_set_rx_enable
+						    (can_os->can,
+						     rx_filter->num, ENABLE);
+					}
+
+					rx_filter->num = buff_num;
+
+					IOH_DEBUG("Rx Msg Obj  : %u\n",
+						  rx_filter->num);
+					IOH_DEBUG("ID          : %u\n",
+						  rx_filter->aidr.id);
+					IOH_DEBUG("Extended ID : %u\n",
+						  rx_filter->aidr.id_ext);
+					IOH_DEBUG("Umask       : %u\n",
+						  rx_filter->umask);
+					IOH_DEBUG("Mask Id     : %u\n",
+						  rx_filter->amr.id);
+					IOH_DEBUG("Ext Mask    : %u\n",
+						  rx_filter->amr.id_ext);
+
+				}
+
+			}
+			break;
+
+		case IOCTL_CAN_BLOCK:
+			IOH_DEBUG
+			    ("ioh_can_ioctl -> Command received \
+							IOCTL_CAN_BLOCK\n");
+			can_os->block_mode = 1;
+			retval = IOH_CAN_SUCCESS;
+			IOH_DEBUG
+			    ("ioh_can_ioctl -> Block mode set successfully.\n");
+			break;
+
+		case IOCTL_CAN_NON_BLOCK:
+			IOH_DEBUG
+			    ("ioh_can_ioctl -> Command received \
+							IOCTL_CAN_NON_BLOCK\n");
+			can_os->block_mode = 0;
+			retval = IOH_CAN_SUCCESS;
+			IOH_DEBUG
+			    ("ioh_can_ioctl -> Non-Block mode set \
+							successfully.\n");
+			break;
+
+		case IOCTL_CAN_BLOCK_GET:
+			IOH_DEBUG
+			    ("ioh_can_ioctl -> Command received \
+							IOCTL_CAN_BLOCK_GET\n");
+			*((unsigned int *)out) = can_os->block_mode;
+			retval = IOH_CAN_SUCCESS;
+			IOH_DEBUG("ioh_can_ioctl -> Mode: "
+				  "%s\n",
+				  (((unsigned int)(*(unsigned int *)out) ==
+				    1) ? "BLOCK" : "NON BLOCK"));
+			break;
+
+		case IOCTL_CAN_LISTEN:
+			{
+				enum ioh_can_run_mode curr_mode;
+
+				IOH_DEBUG
+				    ("ioh_can_ioctl -> Command received \
+							IOCTL_CAN_LISTEN\n");
+
+				(void)ioh_can_get_run_mode(can_os->can,
+							   &curr_mode);
+				if (curr_mode == IOH_CAN_RUN) {
+					(void)ioh_can_set_run_mode(can_os->can,
+								IOH_CAN_STOP);
+				}
+
+				retval =
+				    ioh_can_set_listen_mode(can_os->can,
+							    IOH_CAN_LISTEN);
+
+				if (curr_mode == IOH_CAN_RUN) {
+					(void)ioh_can_set_run_mode(can_os->can,
+								   IOH_CAN_RUN);
+				}
+			}
+			break;
+
+		case IOCTL_CAN_ACTIVE:
+			{
+				enum ioh_can_run_mode curr_mode;
+
+				IOH_DEBUG("ioh_can_ioctl -> Command received "
+					  "IOCTL_CAN_ACTIVE\n");
+
+				(void)ioh_can_get_run_mode(can_os->can,
+							   &curr_mode);
+				if (curr_mode == IOH_CAN_RUN) {
+					(void)ioh_can_set_run_mode(can_os->can,
+								IOH_CAN_STOP);
+				}
+
+				retval =
+				    ioh_can_set_listen_mode(can_os->can,
+							    IOH_CAN_ACTIVE);
+
+				if (curr_mode == IOH_CAN_RUN) {
+					(void)ioh_can_set_run_mode(can_os->can,
+								   IOH_CAN_RUN);
+				}
+			}
+			break;
+
+		case IOCTL_CAN_LISTEN_GET:
+			IOH_DEBUG("ioh_can_ioctl -> Command received "
+				  "IOCTL_CAN_LISTEN_GET\n");
+			retval =
+			    ioh_can_get_listen_mode(can_os->can,
+						    (enum ioh_can_listen_mode *)
+						    out);
+			break;
+
+		case IOCTL_CAN_ARBITER_ROUND_ROBIN:
+			IOH_DEBUG("ioh_can_ioctl -> Command received "
+				  "IOCTL_CAN_ARBITER_ROUND_ROBIN\n");
+			retval =
+			    ioh_can_set_arbiter_mode(can_os->can,
+						     IOH_CAN_ROUND_ROBIN);
+			break;
+
+		case IOCTL_CAN_ARBITER_FIXED_PRIORITY:
+			IOH_DEBUG("ioh_can_ioctl -> Command received "
+				  "IOCTL_CAN_ARBITER_FIXED_PRIORITY\n");
+			retval =
+			    ioh_can_set_arbiter_mode(can_os->can,
+						     IOH_CAN_FIXED_PRIORITY);
+			break;
+
+		case IOCTL_CAN_ARBITER_GET:
+			IOH_DEBUG("ioh_can_ioctl -> Command received "
+				  "IOCTL_CAN_ARBITER_GET\n");
+			retval =
+			    ioh_can_get_arbiter_mode(can_os->can,
+						(enum ioh_can_arbiter *) out);
+			break;
+
+		case IOCTL_CAN_ERROR_STATS_GET:
+			IOH_DEBUG("ioh_can_ioctl -> Command received "
+				  "IOCTL_CAN_ERROR_STATS_GET\n");
+			retval =
+			    ioh_can_get_error_stats(can_os->can,
+						(struct ioh_can_error *) out);
+			break;
+
+		case IOCTL_CAN_RESTART_MODE_AUTO:
+			IOH_DEBUG("ioh_can_ioctl -> Command received "
+				  "IOCTL_CAN_RESTART_MODE_AUTO\n");
+			retval =
+			    ioh_can_set_restart_mode(can_os->can, CAN_AUTO);
+			break;
+
+		case IOCTL_CAN_RESTART_MODE_MANUAL:
+			IOH_DEBUG("ioh_can_ioctl -> Command received "
+				  "IOCTL_CAN_RESTART_MODE_MANUAL\n");
+			retval =
+			    ioh_can_set_restart_mode(can_os->can, CAN_MANUAL);
+			break;
+
+		case IOCTL_CAN_RESTART_MODE_GET:
+			IOH_DEBUG("ioh_can_ioctl -> Command received "
+				  "IOCTL_CAN_RESTART_MODE_GET\n");
+			retval =
+			    ioh_can_get_restart_mode(can_os->can,
+						(enum ioh_can_auto_restart *)
+						out);
+			break;
+
+		case IOCTL_CAN_BUFFER_LINK_SET:
+			{
+				unsigned int buff_num = 0, msg_obj = 0;
+				int i = 0;
+				unsigned int status = 0;
+
+				IOH_DEBUG("ioh_can_ioctl -> Command received "
+					  "IOCTL_CAN_BUFFER_LINK_SET\n");
+				for (i = 0;
+				     (i <
+				      (ioh_can_tx_buf_size +
+				       ioh_can_rx_buf_size)); i++) {
+					if (ioh_msg_obj_conf[i] == 0) {
+						buff_num++;
+						if (buff_num ==
+						    (*(unsigned int *)in)) {
+							break;
+						}
+					}
+				}
+
+				if (i ==
+				    (ioh_can_tx_buf_size +
+				     ioh_can_rx_buf_size)) {
+					retval = IOH_CAN_FAIL;
+				} else {
+					/* Here i is the index, however (i+1) is
+							 object number. */
+					msg_obj = (i + 1);
+
+					(void)ioh_can_get_rx_enable(can_os->can,
+								    msg_obj,
+								    &status);
+
+					if (status == ENABLE) {
+						(void)
+						    ioh_can_set_rx_enable
+						    (can_os->can, msg_obj,
+						     DISABLE);
+					}
+
+					IOH_DEBUG
+					    ("ioctl -> Calling \
+						ioh_can_set_rx_buffer_link "
+					     "for Rx buffer %d[%d]\n",
+					     (*(int *)in), msg_obj);
+					retval =
+					    ioh_can_set_rx_buffer_link(can_os->
+								       can,
+								       msg_obj,
+								       ENABLE);
+
+					if (status == ENABLE) {
+						(void)
+						    ioh_can_set_rx_enable
+						    (can_os->can, msg_obj,
+						     ENABLE);
+					}
+				}
+
+			}
+			break;
+
+		case IOCTL_CAN_BUFFER_LINK_CLEAR:
+			{
+				unsigned int buff_num = 0, msg_obj = 0;
+				int i = 0;
+				unsigned status = 0;
+
+				IOH_DEBUG("ioh_can_ioctl -> Command received "
+					  "IOCTL_CAN_BUFFER_LINK_CLEAR\n");
+				for (i = 0;
+				     (i <
+				      (ioh_can_tx_buf_size +
+				       ioh_can_rx_buf_size)); i++) {
+					if (ioh_msg_obj_conf[i] == 0) {
+						buff_num++;
+						if (buff_num ==
+						    (*(unsigned int *)in)) {
+							break;
+						}
+					}
+				}
+
+				if (i ==
+				    (ioh_can_tx_buf_size +
+				     ioh_can_rx_buf_size)) {
+					retval = IOH_CAN_FAIL;
+				} else {
+					/* Here i is the index, however (i+1)
+							 is object number. */
+					msg_obj = (i + 1);
+
+					(void)ioh_can_get_rx_enable(can_os->can,
+								    msg_obj,
+								    &status);
+
+					if (status == ENABLE) {
+						(void)
+						    ioh_can_set_rx_enable
+						    (can_os->can, msg_obj,
+						     DISABLE);
+					}
+
+					IOH_DEBUG
+					    ("ioctl -> Calling \
+						ioh_can_set_rx_buffer_link for "
+					     "Rx buffer %d[%d]\n", (*(int *)in),
+					     msg_obj);
+					retval =
+					    ioh_can_set_rx_buffer_link(can_os->
+								       can,
+								       msg_obj,
+								       DISABLE);
+
+					if (status == ENABLE) {
+						(void)
+						    ioh_can_set_rx_enable
+						    (can_os->can, msg_obj,
+						     ENABLE);
+					}
+				}
+
+			}
+			break;
+
+		case IOCTL_CAN_BUFFER_LINK_GET:
+			{
+				unsigned int buff_num = 0, msg_obj = 0;
+				int i = 0;
+
+				IOH_DEBUG("ioh_can_ioctl -> Command received "
+					  "IOCTL_CAN_BUFFER_LINK_GET\n");
+				for (i = 0;
+				     i <
+				     (ioh_can_tx_buf_size +
+				      ioh_can_rx_buf_size); i++) {
+					if (ioh_msg_obj_conf[i] == 0) {
+						buff_num++;
+						if (buff_num ==
+						    (*(unsigned int *)in)) {
+							break;
+						}
+					}
+				}
+
+				if (i ==
+				    (ioh_can_tx_buf_size +
+				     ioh_can_rx_buf_size)) {
+					retval = IOH_CAN_FAIL;
+				} else {
+					/* Here i is the index, however (i+1) is
+							 object number. */
+					msg_obj = (i + 1);
+
+					IOH_DEBUG
+					("ioctl -> Calling \
+					ioh_can_get_rx_buffer_link for "
+					"Rx buffer %d[%d]\n", (*(int *)in),
+					msg_obj);
+					retval =
+					    ioh_can_get_rx_buffer_link(can_os->
+								       can,
+								       msg_obj,
+								       (unsigned
+									int *)
+								       out);
+
+				}
+			}
+			break;
+
+		case IOCTL_CAN_RX_ENABLE_SET:
+			{
+				unsigned int buff_num = 0, msg_obj = 0;
+				int i = 0;
+				unsigned int status = 0;
+
+				IOH_DEBUG("ioh_can_ioctl -> Command received "
+					  "IOCTL_CAN_RX_ENABLE_SET\n");
+				for (i = 0;
+				     i <
+				     (ioh_can_tx_buf_size +
+				      ioh_can_rx_buf_size); i++) {
+					if (ioh_msg_obj_conf[i] == 0) {
+						buff_num++;
+						if (buff_num == (*(int *)in))
+							break;
+					}
+				}
+
+				if (i ==
+				    (ioh_can_tx_buf_size +
+				     ioh_can_rx_buf_size)) {
+					retval = IOH_CAN_FAIL;
+				} else {
+					/* Here i is the index, however (i+1) is
+							 object number. */
+					msg_obj = (i + 1);
+
+					(void)ioh_can_get_rx_enable(can_os->can,
+								    msg_obj,
+								    &status);
+					if (status == DISABLE) {
+						retval =
+						    ioh_can_set_rx_enable
+						    (can_os->can, msg_obj,
+						     ENABLE);
+					}
+
+				}
+			}
+			break;
+
+		case IOCTL_CAN_RX_ENABLE_CLEAR:
+			{
+				unsigned int buff_num = 0, msg_obj = 0;
+				int i = 0;
+				unsigned int status = 0;
+
+				IOH_DEBUG("ioh_can_ioctl -> Command received "
+					  "IOCTL_CAN_RX_ENABLE_CLEAR\n");
+				for (i = 0;
+				     i <
+				     (ioh_can_tx_buf_size +
+				      ioh_can_rx_buf_size); i++) {
+					if (ioh_msg_obj_conf[i] == 0) {
+						buff_num++;
+						if (buff_num == (*(int *)in))
+							break;
+					}
+				}
+
+				if (i ==
+				    (ioh_can_tx_buf_size +
+				     ioh_can_rx_buf_size)) {
+					retval = IOH_CAN_FAIL;
+				} else {
+					/* Here i is the index, however (i+1) is
+							 object number. */
+					msg_obj = (i + 1);
+
+					(void)ioh_can_get_rx_enable(can_os->can,
+								    msg_obj,
+								    &status);
+					if (status == ENABLE) {
+						retval =
+						    ioh_can_set_rx_enable
+						    (can_os->can, msg_obj,
+						     DISABLE);
+					}
+
+				}
+			}
+			break;
+
+		case IOCTL_CAN_RX_ENABLE_GET:
+			{
+				unsigned int buff_num = 0, msg_obj = 0;
+				int i = 0;
+
+				IOH_DEBUG("ioh_can_ioctl -> Command received "
+					  "IOCTL_CAN_RX_ENABLE_GET\n");
+				for (i = 0;
+				     i <
+				     (ioh_can_tx_buf_size +
+				      ioh_can_rx_buf_size); i++) {
+					if (ioh_msg_obj_conf[i] == 0) {
+						buff_num++;
+						if (buff_num == (*(int *)in))
+							break;
+					}
+				}
+
+				if (i ==
+				    (ioh_can_tx_buf_size +
+				     ioh_can_rx_buf_size)) {
+					retval = IOH_CAN_FAIL;
+				} else {
+					/* Here i is the index, however (i+1) is
+							 object number. */
+					msg_obj = (i + 1);
+
+					retval =
+					    ioh_can_get_rx_enable(can_os->can,
+								  msg_obj,
+								  (unsigned int
+								   *)out);
+
+				}
+			}
+			break;
+
+		case IOCTL_CAN_TX_ENABLE_SET:
+			{
+				unsigned int buff_num = 0, msg_obj = 0;
+				int i = 0;
+				unsigned int status = 0;
+
+				IOH_DEBUG("ioh_can_ioctl -> Command received "
+					  "IOCTL_CAN_TX_ENABLE_SET\n");
+				for (i = 0;
+				     i <
+				     (ioh_can_tx_buf_size +
+				      ioh_can_rx_buf_size); i++) {
+					if (ioh_msg_obj_conf[i] == 1) {
+						buff_num++;
+						if (buff_num == (*(int *)in))
+							break;
+					}
+				}
+
+				if (i ==
+				    (ioh_can_tx_buf_size +
+				     ioh_can_rx_buf_size)) {
+					retval = IOH_CAN_FAIL;
+				} else {
+					/* Here i is the index, however (i+1) is
+							 object number. */
+					msg_obj = (i + 1);
+
+					(void)ioh_can_get_tx_enable(can_os->can,
+								    msg_obj,
+								    &status);
+					if (status == DISABLE) {
+						retval =
+						    ioh_can_set_tx_enable
+						    (can_os->can, msg_obj,
+						     ENABLE);
+					}
+
+				}
+			}
+			break;
+
+		case IOCTL_CAN_TX_ENABLE_CLEAR:
+			{
+				unsigned int buff_num = 0, msg_obj = 0;
+				int i = 0;
+				unsigned int status = 0;
+
+				IOH_DEBUG("ioh_can_ioctl -> Command received "
+					  "IOCTL_CAN_TX_ENABLE_CLEAR\n");
+				for (i = 0;
+				     i <
+				     (ioh_can_tx_buf_size +
+				      ioh_can_rx_buf_size); i++) {
+					if (ioh_msg_obj_conf[i] == 1) {
+						buff_num++;
+						if (buff_num == (*(int *)in))
+							break;
+					}
+				}
+
+				if (i ==
+				    (ioh_can_tx_buf_size +
+				     ioh_can_rx_buf_size)) {
+					retval = IOH_CAN_FAIL;
+				} else {
+					/* Here i is the index, however (i+1) is
+							 object number. */
+					msg_obj = (i + 1);
+
+					(void)ioh_can_get_tx_enable(can_os->can,
+								    msg_obj,
+								    &status);
+					if (status == ENABLE) {
+						retval =
+						    ioh_can_set_tx_enable
+						    (can_os->can, msg_obj,
+						     DISABLE);
+					}
+
+				}
+			}
+			break;
+
+		case IOCTL_CAN_TX_ENABLE_GET:
+			{
+				unsigned int buff_num = 0, msg_obj = 0;
+				int i = 0;
+
+				IOH_DEBUG("ioh_can_ioctl -> Command received "
+					  "IOCTL_CAN_TX_ENABLE_GET\n");
+				for (i = 0;
+				     i <
+				     (ioh_can_tx_buf_size +
+				      ioh_can_rx_buf_size); i++) {
+					if (ioh_msg_obj_conf[i] == 1) {
+						buff_num++;
+						if (buff_num == (*(int *)in))
+							break;
+					}
+				}
+
+				if (i ==
+				    (ioh_can_tx_buf_size +
+				     ioh_can_rx_buf_size)) {
+					retval = IOH_CAN_FAIL;
+				} else {
+					/* Here i is the index, however (i+1) is
+							 object number. */
+					msg_obj = (i + 1);
+
+					retval =
+					    ioh_can_get_tx_enable(can_os->can,
+								  msg_obj,
+								  (unsigned int
+								   *)out);
+
+				}
+			}
+			break;
+
+#ifdef DEBUG
+			/* Inlcuded for debugging. */
+		case IOCTL_CAN_DEBUG:
+			{
+				struct  debug in;
+				retval =
+				    copy_from_user((void *)&in, (void *)arg,
+						   sizeof(struct  debug));
+
+				if (in.cmd == 1) {	/* Read operation. */
+					in.value =
+					    (ioread32
+					     ((void __iomem *)(can_os->
+							       pci_remap +
+							       in.offset))
+					     & MSK_ALL_SIXTEEN);
+					IOH_DEBUG("Offset: 0x%x\nRead value: "
+						  "0x%x\n",
+						  (unsigned int)(in.offset),
+						  (unsigned int)(in.
+							value &
+							MSK_ALL_SIXTEEN));
+
+					retval =
+					    copy_to_user((void *)arg,
+							 (void *)&in,
+							 sizeof(struct  debug));
+
+				}
+
+				else if (in.cmd == 2) {
+					(void)iowrite32(in.value,
+							(void *)(can_os->
+								 pci_remap +
+								 in.offset));
+					if (in.value ==
+					    ((ioread32
+					      ((void *)(can_os->pci_remap +
+							in.offset)))
+					     & MSK_ALL_SIXTEEN)) {
+						retval = IOH_CAN_SUCCESS;
+					} else {
+						retval = IOH_CAN_FAIL;
+					}
+
+				}
+
+				else {
+					retval = IOH_CAN_FAIL;
+				}
+
+			}
+			break;
+#endif
+
+		default:
+			IOH_DEBUG("Unrecognizined IOCTL, skipping 0x%x. \n",
+				  cmd);
+			retval = -EINVAL;
+			break;
+		}
+
+		if ((out_buff_size != 0) && (IOH_CAN_SUCCESS == retval)) {
+			retval = copy_to_user((void *)arg, out, out_buff_size);
+			if (retval != 0) {
+				IOH_LOG(KERN_ERR, "Copy to user failed for "
+					"for CAN in IOCTL operation.\n");
+				retval = -ENOMEM;
+			} else {
+				retval = IOH_CAN_SUCCESS;
+			}
+		}
+
+	}
+
+	if (in != NULL)
+		kfree(in);
+	if (out != NULL)
+		kfree(out);
+
+	IOH_DEBUG("ioh_can_ioctl returns %d.\n", retval);
+	return retval;
+}
+
+/*! @ingroup	InterfaceLayerAPI
+	@fn			static void can_ioctl_buff_size(
+			unsigned int ctl_code,size_t *in_size,size_t *out_size)
+	@brief		Calculates the size of memory required for the IN and
+				 OUT arguments of a
+				specific ioctl command.
+	@remarks	This function is used to obtain the size of the memory
+				space required to store the data for a
+				 particular IOCTL
+				command.
+	@note		For an invalid IOCTL command this function returns IN
+				 and
+				OUT size as 0.
+
+	@param	ctl_code	[@ref IN]	The ioctl command.
+	@param	in_size		[@ref OUT]	The size of the IN argument.
+	@param	out_size	[@ref OUT]	The size of the OUT argument.
+
+	@retval       None
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+static void can_ioctl_buff_size(unsigned int ctl_code, size_t *in_size,
+				size_t *out_size)
+{
+	*in_size = 0;
+	*out_size = 0;
+
+	switch (ctl_code) {
+
+	case IOCTL_CAN_SIMPLE:
+		*in_size = sizeof(enum ioh_can_baud);
+		break;
+
+	case IOCTL_CAN_CUSTOM:
+		*in_size = sizeof(struct ioh_can_timing);
+		break;
+
+	case IOCTL_CAN_FILTER:
+		*in_size = sizeof(struct ioh_can_rx_filter);
+		break;
+
+	case IOCTL_CAN_RUN_GET:
+		*out_size = sizeof(enum ioh_can_run_mode);
+		break;
+
+	case IOCTL_CAN_TIMING_GET:
+		*out_size = sizeof(struct ioh_can_timing);
+		break;
+
+	case IOCTL_CAN_FILTER_GET:
+		*out_size = sizeof(struct ioh_can_rx_filter);
+		*in_size = sizeof(struct ioh_can_rx_filter);
+		break;
+
+	case IOCTL_CAN_BLOCK_GET:
+		*out_size = sizeof(unsigned int);
+		break;
+
+	case IOCTL_CAN_LISTEN_GET:
+		*out_size = sizeof(enum ioh_can_listen_mode);
+		break;
+
+	case IOCTL_CAN_ARBITER_GET:
+		*out_size = sizeof(enum ioh_can_arbiter);
+		break;
+
+	case IOCTL_CAN_ERROR_STATS_GET:
+		*out_size = sizeof(struct ioh_can_error);
+		break;
+
+	case IOCTL_CAN_RESTART_MODE_GET:
+		*out_size = sizeof(enum ioh_can_auto_restart);
+		break;
+
+	case IOCTL_CAN_BUFFER_LINK_SET:
+	case IOCTL_CAN_BUFFER_LINK_CLEAR:
+	case IOCTL_CAN_RX_ENABLE_SET:
+	case IOCTL_CAN_RX_ENABLE_CLEAR:
+	case IOCTL_CAN_TX_ENABLE_SET:
+	case IOCTL_CAN_TX_ENABLE_CLEAR:
+		*in_size = sizeof(unsigned int);
+		break;
+
+	case IOCTL_CAN_BUFFER_LINK_GET:
+	case IOCTL_CAN_RX_ENABLE_GET:
+	case IOCTL_CAN_TX_ENABLE_GET:
+		*in_size = sizeof(unsigned int);
+		*out_size = sizeof(unsigned int);
+		break;
+
+	default:
+		break;
+	}
+
+	IOH_DEBUG("can_ioctl_buff_size -> In size: %u "
+		  "Out Size: %u.\n", *in_size, *out_size);
+	IOH_DEBUG("can_ioctl_buff_size -> Invoked successfully.\n");
+}
diff -urN linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_main.h topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_main.h
--- linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_main.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_main.h	2010-03-10 08:57:34.000000000 +0900
@@ -0,0 +1,826 @@
+/*!
+ * @file ioh_can_main.h
+ * @brief Provides the function declarations for CAN driver methods.
+ * @version 1.0
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * <hr>
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+#ifndef __IOH_CAN_MAIN_H__
+#define __IOH_CAN_MAIN_H__
+
+/*! @defgroup	CAN
+	@brief		Contains the different utilities used for implementing
+				the CAN module.
+*/
+
+/*! @defgroup 	Debug
+	@ingroup 	CAN
+	@brief		Group containing the functionalities for debugging
+				the features of the module.
+	@remarks	This group defines the functionalities that can be
+				used for debugging the different features of the
+				CAN. The main functionalities are of displaying
+				 the
+				debug messages. For normal execution these
+				functionalities are disabled.
+
+	<hr>
+*/
+
+/*! @defgroup 	Global
+	@ingroup 	CAN
+	@brief		This group describes the global entities within
+				the module.
+	@remarks	This group includes all the global data structures
+				used within the modules. These are mainly used
+				 to
+				store the device related information, so that it
+				 can
+				be used by other functions of the modules.
+
+	<hr>
+*/
+/*! @defgroup 	PCILayer
+	@ingroup 	CAN
+	@brief		This group describes the PCI layer interface
+				functionalities.
+	@remarks	This group contains the functions and data structures
+				that are used to interface the module with PCI
+				 Layer
+				subsystem of the Kernel. Most of the data
+				 structures
+				and functions used within this group are Kernel
+				 provided
+				ones.
+
+	<hr>
+*/
+/*! @defgroup 	InterfaceLayer
+	@ingroup 	CAN
+	@brief		This group describes the Driver interface
+			 functionalities.
+	@remarks	This group contains the data structures and functions
+			 used
+				to interface the module driver with the kernel
+				 subsystem.
+
+	<hr>
+*/
+/*! @defgroup 	HALLayer
+	@ingroup 	CAN
+	@brief		This group describes the hardware specific
+				 functionalities.
+	@remarks	This group contains the functions and data structures
+				 used
+				by the module to communicate with the hardware.
+				 These
+				functions are device specific and designed
+				 according to the
+				device specifications.
+
+	<hr>
+*/
+/*! @defgroup 	Utilities
+	@ingroup 	CAN
+	@brief		This group describes the utility functionalities.
+	@remarks	This group contains the functions and data structures
+				 used
+				to assist the other functionalities in their
+				 operations.
+
+	<hr>
+*/
+
+/*! @defgroup 	PCILayerAPI
+	@ingroup 	PCILayer
+	@brief		This group contains the API(functions) used as the PCI
+				interface between the Kernel subsystem and the
+				 module.
+
+	<hr>
+*/
+
+/*! @defgroup 	PCILayerFacilitators
+	@ingroup 	PCILayer
+	@brief		This group contains the data structures used by the PCI
+				Layer APIs for their functionalities.
+
+	<hr>
+*/
+
+/*! @defgroup 	InterfaceLayerAPI
+	@ingroup 	InterfaceLayer
+	@brief		This group contains the API(functions) used as the
+				 Driver
+				interface between the Kernel subsystem and the
+				 module.
+
+	<hr>
+*/
+/*! @defgroup 	InterfaceLayerFacilitators
+	@ingroup 	InterfaceLayer
+	@brief		This group contains the data structures used by the
+				 Driver
+				interface APIs for their functionalities.
+
+	<hr>
+*/
+
+/*! @defgroup 	HALLayerAPI
+	@ingroup 	HALLayer
+	@brief		This group contains the APIs(functions) used to interact
+				 with
+				the hardware. These APIs act as an interface
+				 between the
+				hardware and the other driver functions.
+
+	<hr>
+*/
+
+/*! @defgroup 	UtilitiesAPI
+	@ingroup 	Utilities
+	@brief		This group contains the APIs(functions) used by other
+				 functions
+				in their operations.
+
+	<hr>
+*/
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOH_CAN_MSG_DATA_LEN
+	@brief		The length in bytes of the data part of the
+				CAN message object.
+	@note		The maximum length of data that a message object
+				contains is 8bytes.
+
+	@see
+			- ioh_can_msg
+
+	<hr>
+*/
+#define IOH_CAN_MSG_DATA_LEN		(8)	/* CAN Msg data length */
+
+/*! @ingroup	InterfaceLayer
+    @struct		ioh_can_msg
+    @brief		The structure defining the format of the CAN message.
+	@remarks	This structure is used by the driver/user to specify
+				the message details. It is used during reading
+				 and
+				transmitting of CAN message objects.
+
+	@see
+			- ioh_can_read
+			- ioh_can_write
+			- ioh_can_msg_tx
+			- ioh_can_rx_dequeue
+
+	<hr>
+*/
+struct ioh_can_msg {
+	unsigned short ide;		/**< Standard/extended msg   */
+	unsigned int id;		/**< 11 or 29 bit msg id     */
+	unsigned short dlc;		/**< Size of data            */
+	unsigned char data[IOH_CAN_MSG_DATA_LEN];	/**< Message pay load */
+	unsigned short rtr;		/**< RTR message             */
+};
+
+/*! @ingroup	InterfaceLayer
+    @struct		ioh_can_timing
+    @brief		This structure defines the fields that are
+				used to define the CAN timing.
+	@remarks	This structure is used by the user application
+				to specify the baud timing parameters which are
+				used to calculate the clock rate timing of the
+				CAN device.
+
+	@see
+			- IOCTL_CAN_CUSTOM
+			- IOCTL_CAN_TIMING_GET
+			- ioh_can_set_baud_custom
+			- ioh_can_get_baud
+
+	<hr>
+*/
+struct ioh_can_timing {
+	unsigned int bitrate;		/**< Bitrate (kbps) 	    */
+	unsigned int cfg_bitrate;	/**< Bitrate 		    	*/
+	unsigned int cfg_tseg1;		/**< Tseg1 		    	*/
+	unsigned int cfg_tseg2;		/**< Tseg2 		    	*/
+	unsigned int cfg_sjw;		/**< Sync jump width 	    */
+	unsigned int smpl_mode;		/**< Sampling mode 	    	*/
+	unsigned int edge_mode;		/**< Edge R / D		    	*/
+};
+
+/*! @ingroup	InterfaceLayer
+	@struct		ioh_can_error
+	@brief		This structure defines the format for a
+				CAN error status.
+	@remarks	This structure is used by the driver to
+				specify the CAN device error status to the
+				user.
+
+	@see
+			- IOCTL_CAN_ERROR_STATS_GET
+			- ioh_can_get_error_stats
+	<hr>
+*/
+struct ioh_can_error {
+	unsigned int rxgte96;		/**< Rx err cnt >=96   	   	*/
+	unsigned int txgte96;		/**< Tx err cnt >=96   	   	*/
+	unsigned int error_stat;	/**< Error state of CAN node
+						00=error active (normal)
+						01=error passive
+						1x=bus off              */
+	unsigned int rx_err_cnt;	/**< Rx counter             */
+	unsigned int tx_err_cnt;	/**< Tx counter             */
+};
+
+/*! @ingroup	InterfaceLayer
+	@struct		ioh_can_acc_filter
+	@brief		This structure defines the format for specifying
+				the Mask/ID.
+	@remarks	This structure is used for specifying the type of
+				ID or Mask (standard/extended).
+
+	@see
+			- ioh_can_rx_filter
+
+	<hr>
+*/
+struct ioh_can_acc_filter {
+	unsigned int id;		/**< The id/mask data.		*/
+	unsigned int id_ext;		/**< Standard/extended ID  	*/
+	unsigned int rtr;		/**< RTR message 		*/
+};
+
+/*! @ingroup	InterfaceLayer
+	@struct		ioh_can_rx_filter
+	@brief		This structure describes the ACR and AMR filter
+				for an Rx buffer.
+	@remarks	This driver is used by the driver/user for specifying
+				the acceptance filter details.
+
+	@see
+			- IOCTL_CAN_FILTER
+			- IOCTL_CAN_FILTER_GET
+			- ioh_can_rx_init_filter
+			- ioh_can_set_rx_filter
+
+	<hr>
+*/
+struct ioh_can_rx_filter {
+	unsigned int num;		/**< Filter number 	     	*/
+	unsigned int umask;		/**< UMask value 	     	*/
+	struct ioh_can_acc_filter amr;	/**< Acceptance Mask Reg    */
+	struct ioh_can_acc_filter aidr;	/**< Acceptance Control Reg */
+};
+
+/*! @ingroup	InterfaceLayer
+	@enum		ioh_can_listen_mode
+	@brief		Identities the valid values for the Active/Listen
+				mode.
+	@remarks	These enum constants are used to denote the
+				 Active/Listen
+				mode of the CAN device. It is used both by the
+				 user and
+				driver for specifying the corresponding mode.
+
+	@see
+			- IOCTL_CAN_LISTEN_GET
+			- ioh_can_set_listen_mode
+			- ioh_can_get_listen_mode
+
+	<hr>
+*/
+enum ioh_can_listen_mode {
+	IOH_CAN_ACTIVE = 0,		/**< R/w to/from the CAN     */
+	IOH_CAN_LISTEN			/**< Only read from the CAN  */
+};
+
+/*! @ingroup	InterfaceLayer
+	@enum		ioh_can_run_mode
+	@brief		Identifies the valid values for the Run/Stop mode.
+	@remarks	These enum constants are used by the driver and
+				user level application to specify the current
+				state(STOP/RUN) of the CAN device.
+
+	@see
+			- IOCTL_CAN_RUN_GET
+			- ioh_can_set_run_mode
+			- ioh_can_get_run_mode
+
+	<hr>
+*/
+enum ioh_can_run_mode {
+	IOH_CAN_STOP = 0,		/**< CAN stopped 	     	*/
+	IOH_CAN_RUN			/**< CAN running  	     	*/
+};
+
+/*! @ingroup	InterfaceLayer
+	@enum		ioh_can_arbiter
+	@brief		Identifies the valid values for the arbitration mode.
+	@remarks	These enum constants are used by the driver/user to
+				specify the arbitration/priority mode of the CAN
+				device.
+
+	@see
+			- IOCTL_CAN_ARBITER_GET
+			- ioh_can_set_arbiter_mode
+			- ioh_can_get_arbiter_mode
+
+	<hr>
+*/
+enum ioh_can_arbiter {
+	IOH_CAN_ROUND_ROBIN = 0,	/**< Equal priority 	     */
+	IOH_CAN_FIXED_PRIORITY		/**< Buffer num priority     */
+};
+
+/*! @ingroup	InterfaceLayer
+	@enum		ioh_can_auto_restart
+	@brief		Identifies the valid values for the auto-restart mode.
+	@remarks	These enum constants are used by the driver/user to
+				specify the restart mode of the CAN device.
+	@note		If the restart mode is CAN_AUTO, the CAN device will
+				automatically recover from the BUS-OFF stage.
+				 Else
+				the user would have to manually perform the
+				 required
+				procedures.
+
+	@see
+			- IOCTL_CAN_RESTART_MODE_GET
+			- ioh_can_set_restart_mode
+			- ioh_can_get_restart_mode
+
+	<hr>
+*/
+enum ioh_can_auto_restart {
+	CAN_MANUAL = 0,		/**< Manual restart 	     */
+	CAN_AUTO		/**< Automatic restart       */
+};
+
+/*! @ingroup	InterfaceLayer
+	@enum		ioh_can_baud
+	@brief		Identifies common baud rates.
+	@remarks	These enum constants are used by the driver/user to
+				denote the standard baud rates used by the CAN
+				 device.
+
+	@see
+			- IOCTL_CAN_SIMPLE
+			- ioh_can_set_baud_simple
+
+	<hr>
+*/
+enum ioh_can_baud {
+	IOH_CAN_BAUD_10 = 0,			/**< 10   kbps 	             */
+	IOH_CAN_BAUD_20,			/**< 20   kbps 	             */
+	IOH_CAN_BAUD_50,			/**< 50   kbps 	             */
+	IOH_CAN_BAUD_125,			/**< 125  kbps 	             */
+	IOH_CAN_BAUD_250,			/**< 250  kbps 	             */
+	IOH_CAN_BAUD_500,			/**< 500  kbps 	             */
+	IOH_CAN_BAUD_800,			/**< 800  kbps 	             */
+	IOH_CAN_BAUD_1000			/**< 1000 kbps 	             */
+};
+
+/*! @ingroup	InterfaceLayer
+	@enum		ioh_can_interrupt
+	@brief		Identifies interrupt enables/disables.
+	@remarks	These enum constants are used by the driver
+				to enable/disable the different combination
+				of the interrupts supported by the CAN device.
+
+	@see
+			- ioh_can_set_int_enables
+
+	<hr>
+*/
+enum ioh_can_interrupt {
+	CAN_ENABLE,			/**< Enable IE bit only	     */
+	CAN_DISABLE,			/**< Disable IE bit only	 */
+	CAN_ALL,			/**< All ints		     	 */
+	CAN_NONE			/**< No ints		     	 */
+};
+
+/*!	@ingroup	InterfaceLayer
+	@def		MAGIC
+	@brief		The one byte constant used for the generation
+				of IOCTL commands.
+
+	<hr>
+*/
+#define MAGIC               			(0x88)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_RESET
+	@brief		The IOCTL command for CAN reset.
+
+	@see
+			- ioh_can_ioctl
+	<hr>
+*/
+#define IOCTL_CAN_RESET         		_IO(MAGIC, 0)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_RUN
+	@brief		The IOCTL command for setting the CAN in either RUN
+			 mode.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_RUN           		_IO(MAGIC, 1)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_STOP
+	@brief		The IOCTL command for setting the CAN in either STOP
+			mode.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_STOP          		_IO(MAGIC, 2)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_RUN_GET
+	@brief		The IOCTL command to get the current mode (RUN/STOP) of
+				the CNA device.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_RUN_GET       	_IOR(MAGIC, 3, enum ioh_can_run_mode)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_FILTER
+	@brief		The IOCTL command for setting the filter for a receive
+				buffer.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_FILTER        	_IOW(MAGIC, 4, struct ioh_can_rx_filter)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_FILTER_GET
+	@brief		The IOCTL command for getting the current filter
+				 settings
+				of a receive buffer.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_FILTER_GET    	_IOR(MAGIC, 5, struct ioh_can_rx_filter)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_CUSTOM
+	@brief		The IOCTL command for setting the user specified time
+				settings for the CAN device.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_CUSTOM        	_IOW(MAGIC, 6, struct ioh_can_timing)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_SIMPLE
+	@brief		The IOCTL command for setting the standard time settings
+				for the CAN device.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_SIMPLE        	_IOW(MAGIC, 7, enum ioh_can_baud)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_TIMING_GET
+	@brief		The IOCTL command for getting the current CAN time
+			 settings.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_TIMING_GET    	_IOR(MAGIC, 8, struct ioh_can_timing)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_BLOCK
+	@brief		The IOCTL command for setting the block mode for the CAN
+			 device.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_BLOCK         		_IO(MAGIC, 9)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_NON_BLOCK
+	@brief		The IOCTL command for setting the non-block mode for the
+			 CAN device.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_NON_BLOCK     		_IO(MAGIC, 10)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_BLOCK_GET
+	@brief		The IOCTL command for getting the current block mode
+				 settings
+				for the CAN device operations.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_BLOCK_GET     		_IOR(MAGIC, 11, u32)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_LISTEN
+	@brief		The IOCTL command for setting the CAN device to listen
+			 mode.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_LISTEN        		_IO(MAGIC, 12)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_ACTIVE
+	@brief		The IOCTL command for setting the CAN device to active
+			 mode.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_ACTIVE        		_IO(MAGIC, 13)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_LISTEN_GET
+	@brief		The IOCTL command for getting the current listen mode of
+				 the
+				CAN device.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_LISTEN_GET    _IOR(MAGIC, 14, enum ioh_can_listen_mode)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_ARBITER_ROUND_ROBIN
+	@brief		The IOCTL command to set the arbiter priority mode as
+				 ROUND
+				ROBIN
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_ARBITER_ROUND_ROBIN   	_IO(MAGIC, 15)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_ARBITER_FIXED_PRIORITY
+	@brief		The IOCTL command to set the arbiter priority mode as
+				 FIXED
+				PRIORITY.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_ARBITER_FIXED_PRIORITY 	_IO(MAGIC, 16)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_ARBITER_GET
+	@brief		The IOCTL command for getting the currently set arbiter
+				priority mode.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_ARBITER_GET       	_IOR(MAGIC, 17, enum ioh_can_arbiter)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_ERROR_STATS_GET
+	@brief		The IOCTL command for getting the current error status
+				 of the
+				CAN device.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_ERROR_STATS_GET   	_IOR(MAGIC, 18, struct ioh_can_error)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_BUFFER_LINK_CLEAR
+	@brief		The IOCTL command to clear the link mode of a receive
+			 buffer.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_BUFFER_LINK_CLEAR 		_IOW(MAGIC, 20, u32)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_BUFFER_LINK_GET
+	@brief		The IOCTL command for getting the current link mode
+				 settings
+				of a receive buffer.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_BUFFER_LINK_GET   		_IOWR(MAGIC, 21, u32)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_RX_ENABLE_SET
+	@brief		The IOCTL command for enabling a receive buffer.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_RX_ENABLE_SET     		_IOW(MAGIC, 22, u32)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_RX_ENABLE_CLEAR
+	@brief		The IOCTL command for disabling a receive buffer.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_RX_ENABLE_CLEAR   		_IOW(MAGIC, 23, u32)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_RX_ENABLE_GET
+	@brief		The IOCTL command for getting the current enable status
+				 of
+				a receive buffer.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_RX_ENABLE_GET     		_IOWR(MAGIC, 24, u32)
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_TX_ENABLE_SET
+	@brief		The IOCTL command for enabling a transmit buffer.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_TX_ENABLE_SET     		_IOW(MAGIC, 25, u32)
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_TX_ENABLE_CLEAR
+	@brief		The IOCTL command for disabling a transmit buffer.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_TX_ENABLE_CLEAR   		_IOW(MAGIC, 26, u32)
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_TX_ENABLE_GET
+	@brief		The IOCTL command for getting the current enable status
+				of a transmit buffer.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_TX_ENABLE_GET     		_IOWR(MAGIC, 27, u32)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_RESTART_MODE_AUTO
+	@brief		The IOCTL command to set the restart mode as AUTO.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_RESTART_MODE_AUTO 		_IO(MAGIC, 28)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_RESTART_MODE_MANUAL
+	@brief		The IOCTL command to set the restart mode as MANUAL.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_RESTART_MODE_MANUAL   	_IO(MAGIC, 29)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_RESTART_MODE_GET
+	@brief		The IOCTL command for getting the currently set restart
+				 mode
+				of the CAN device.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_RESTART_MODE_GET  _IOR(MAGIC, 30, enum ioh_can_auto_restart)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOCTL_CAN_BUFFER_LINK_SET
+	@brief		The IOCTL command to set the link mode of a receive
+			 buffer.
+
+	@see
+			- ioh_can_ioctl
+
+	<hr>
+*/
+#define IOCTL_CAN_BUFFER_LINK_SET   		_IOW(MAGIC, 19, u32)
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOH_CAN_SUCCESS
+	@brief		The value returned by certain functions on success.
+
+	<hr>
+*/
+#define IOH_CAN_SUCCESS 		(0)	/* CAN success return value. */
+
+/*!	@ingroup	InterfaceLayer
+	@def		IOH_CAN_FAIL
+	@brief		The value returned by certain functions on failure.
+
+	<hr>
+*/
+#define IOH_CAN_FAIL 			(-1)	/* CAN failure return value. */
+
+#endif /* ifndef __IOH_CAN_H__ */
diff -urN linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_pci.c topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_pci.c
--- linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_pci.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_pci.c	2010-03-12 14:10:54.000000000 +0900
@@ -0,0 +1,1134 @@
+/*!
+ * @file ioh_can_pci.c
+ * @brief Provides the function definition for the PCI Layer APIs.
+ * @version 1.0
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * <hr>
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+/* includes */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/pci.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/wait.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include "pch_common.h"
+#include "pch_debug.h"
+#include "pch_can_main.h"
+#include "pch_can_hal.h"
+#include "pch_can_pci.h"
+
+MODULE_DESCRIPTION("Controller Area Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.94");
+
+/*** Module parameter variables ***/
+
+/*! @ingroup	Global
+	@var		ioh_can_rx_buf_size
+	@brief		The number of message objects that has to be configured
+			 as receive
+				objects.
+	@note		The value can be specified during the loading of the
+				 module. The default value is 16.
+
+	<hr>
+ */
+unsigned int ioh_can_rx_buf_size = 16;
+
+/*! @ingroup	Global
+	@var		ioh_can_tx_buf_size
+	@brief		The number of message objects that has to be configured
+				 as transmit
+				objects.
+	@note		The value can be specified during the loading of the
+				 module. The default value is 16.
+
+	<hr>
+ */
+unsigned int ioh_can_tx_buf_size = 16;
+
+/*! @ingroup	Global
+	@var		ioh_can_clock
+	@brief		The clock rate frequency in KHz.
+	@note		The value can be specified during the loading of the
+			 module. The default value is 62500KHz (62.5MHz).
+	@see
+				- ioh_can_pci_init
+
+	<hr>
+ */
+#ifndef FPGA_BOARD
+int ioh_can_clock = 50000;
+#else
+int ioh_can_clock = 62500;
+#endif
+
+/*! @ingroup	Global
+	@var		major
+	@brief		The major number to be allocated to the device driver.
+	@note		The value can be specified during the loading of the
+			 module. If no value is specified the default value is
+			 0 and the major number would be allocated dynamically.
+	@see
+				- ioh_can_probe
+
+	<hr>
+*/
+static int major;
+/*******/
+
+/*** global variables ***/
+/*! @ingroup	Global
+	@var		MODULE_NAME
+	@brief		The name of the module.
+	@note		This variable denotes the module name which is displayed
+				 along
+				with the debug messages during logging of debug
+				 messages.
+
+	<hr>
+*/
+#define MODULE_NAME "pch_can"
+/*! @ingroup	Global
+	@var		can_os
+	@brief		The global variable used to store the device
+			 information.
+	@note		This variable is used to store the device specific
+				 information,
+				that can be used by other module functions in
+				 their course of operations.
+
+	<hr>
+*/
+struct ioh_can_os can_os[MAX_CAN_DEVICES];
+
+/********/
+
+/*** static variables *****/
+
+/*! @ingroup	Global
+	@var		ioh_can_major
+	@brief		The global variable used to store the major number of
+				 the device driver.
+	@note		This variable is used to store the major number of the
+				device driver. If the major number is allocated
+				 dynamically
+				then the kernel provided major number is stored
+				 in it. During
+				static allocation the unique major number is
+				 calculated with
+				the user provided major number and stored in it.
+
+	@see
+			- ioh_can_probe
+			- ioh_can_remove
+
+	<hr>
+*/
+static dev_t ioh_can_major;	/* Device variable used to calculate the major
+								 number.  */
+
+/*! @ingroup	Global
+	@var		ioh_can_dev
+	@brief		The global variable used to store the device driver
+				 information.
+	@note		This variable is used to store the device driver
+				 specific information.
+				It is used during the registration of the device
+				 driver.
+
+	@see
+			- ioh_can_probe
+			- ioh_can_remove
+
+	<hr>
+*/
+static struct cdev ioh_can_dev;	/* char device reg'd by the driver */
+
+/*******/
+
+/*** Defining as module parameter. ***/
+
+module_param_named(major, major, int, 444);
+module_param_named(ioh_can_rx_buf_size, ioh_can_rx_buf_size, int, 444);
+module_param_named(ioh_can_tx_buf_size, ioh_can_tx_buf_size, int, 444);
+module_param_named(ioh_can_clock, ioh_can_clock, int, 444);
+
+/*****/
+
+/*** Function prototypes. ***/
+
+static int ioh_can_probe(struct pci_dev *dev, const struct pci_device_id *id);
+static void ioh_can_remove(struct pci_dev *dev);
+static int ioh_can_suspend(struct pci_dev *dev, pm_message_t state);
+static int ioh_can_resume(struct pci_dev *dev);
+static void ioh_can_shutdown(struct pci_dev *dev);
+
+/*****/
+
+/*! @ingroup	PCILayerFacilitators
+	@struct		ioh_can_pcidev_id
+	@brief		Instance of Linux Kernel structure pci_device_id for
+				 specifying the Vendor
+				 and deviceID of the supported PCI device.
+	@remarks
+				This structure is the instance of the linux
+				 kernel provided structure
+				 pci_device_id. It is used to register the
+				  vendor and device ID
+				 of the PCI device with the kernel subsystem.
+				This structure is used by the kernel for module
+				 registration for the
+				appropriate device during the device
+				 recognization(probing). In short
+				 it describes the devices for which this module
+				 can be used. It forms
+				 a part of the large structure
+ @ref ioh_can_pcidev used for module registration.
+	@note		This driver is used as a part of another structure
+ @ref ioh_can_pcidev
+    @see
+				- ioh_can_pcidev
+	<hr>
+*/
+static const struct pci_device_id ioh_can_pcidev_id[] __devinitdata = {
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOH1_CAN)},
+	{}
+};
+
+MODULE_DEVICE_TABLE(pci, ioh_can_pcidev_id);
+
+/*! @ingroup	PCILayerFacilitators
+	@struct		ioh_can_pcidev
+	@brief		Instance of the Linux Kernel structure pci_driver for
+				 specifying the PCI Driver features to the
+				 kernel subsystem.
+	@remarks
+				This structure is the instance of the Linux
+				 kernel provided structure
+				pci_driver. It is used to register the PCI
+				 driver features with the kernel subsystem.
+				This structure specifies the PCI driver features
+				 such as the Name
+				of the Module, Entry point, Exit point and Power
+				Management functions for the driver.
+	@note		This structure is used only during the registration and
+				un-registration of the PCI driver.
+	@see
+				- ioh_can_pci_init
+				- ioh_can_pci_exit
+	<hr>
+*/
+static struct pci_driver ioh_can_pcidev = {
+	.name = "ioh_can",
+	.id_table = ioh_can_pcidev_id,
+	.probe = ioh_can_probe,
+	.remove = __devexit_p(ioh_can_remove),
+#ifdef CONFIG_PM
+	.suspend = ioh_can_suspend,
+	.resume = ioh_can_resume,
+#endif
+	.shutdown = ioh_can_shutdown
+};
+
+/*! @ingroup 	PCILayerAPI
+	@fn 		static int ioh_can_pci_init(void)
+	@brief		This function registers the module as a PCI Driver.
+	@remarks
+				This function is invoked during the loading of
+				 the module. The main
+				tasks performed by this function are.
+				- Evaluates the validity of the parameter passed
+				 during loading.
+				- Validates whether the obtained clock frequency
+				 is valid.
+				- Registers the module as PCI driver module.
+
+	@note		This function is called during the loading of the
+				 device.
+	@retval       int
+				- @ref IOH_CAN_SUCCESS	--> The loading of the
+				 module successful.
+				- @ref IOH_CAN_FAIL		--> The loading
+					 of the module failed due to invalid
+				module parameters or invlaid clock frequency.
+				- -EEXIST	--> pci_register_driver failed.
+				- -EINVAL	--> pci_register_driver failed.
+				- -ENOMEM 	--> pci_register_driver failed.
+	<hr>
+*/
+static int __init ioh_can_pci_init(void)
+{
+	int retval;
+
+	IOH_DEBUG("ioh_can_pci_init -> Obtained parameters: \n"
+		  "ioh_can_tx_buf_size = %d\n"
+		  "ioh_can_rx_buf_size = %d\n"
+		  "ioh_can_clock       = %d\n"
+		  "major               = %d\n", ioh_can_tx_buf_size,
+		  ioh_can_rx_buf_size, ioh_can_clock, major);
+
+	/* Checking if the total message objects to be used  exceeds
+	    the supported message object available and whether the obtained
+	    clock frequency is greater than 0. */
+	if (((ioh_can_tx_buf_size + ioh_can_rx_buf_size) <= MAX_MSG_OBJ)
+	    && (ioh_can_clock > 0)) {
+
+		/* Checking the validity of the clock variable. */
+		switch (ioh_can_clock) {
+			/*      List of valid clock frequency
+			   Add new clock frequency here
+			   for validation.
+			 */
+		case 62500:
+		case 24000:
+		case 50000:
+			retval = IOH_CAN_SUCCESS;
+			break;
+
+		default:
+			IOH_LOG(KERN_ERR,
+				"ioh_can_pci_init -> Invalid clock frequency "
+				"%u", ioh_can_clock);
+			retval = IOH_CAN_FAIL;
+		}
+
+		if (IOH_CAN_SUCCESS == retval) {
+
+			/* Register as a PCI driver. */
+			retval = pci_register_driver(&ioh_can_pcidev);
+
+			/* Registeration unsuccessful. */
+			if (0 != retval) {
+				IOH_LOG(KERN_ERR,
+				"ioh_can_pci_init -> \
+				pci_register_driver failed(returned %d).\n",
+				retval);
+			}
+			/* Registeration successful. */
+			else {
+				IOH_DEBUG
+				("ioh_can_pci_init -> pci_register_driver \
+				successful(returned %d).\n",
+				retval);
+
+				IOH_DEBUG
+				("ioh_can_pci_init invoked successfully.\n");
+			}
+		}
+	}
+	/* Message object exceeds the available message object. */
+	else {
+		IOH_LOG(KERN_ERR,
+			"ioh_can_pci_init -> Invalid module parameters.\n\t"
+			"Expected Message objects to be configured <= %d"
+			" and clock frequency expected > 0\n", MAX_MSG_OBJ);
+
+		retval = IOH_CAN_FAIL;
+	}
+
+	IOH_DEBUG("ioh_can_pci_init returns %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	PCILayerAPI
+	@fn 		static int ioh_can_pci_exit(void)
+	@brief		Un-registers the PCI Driver.
+	@note		This function is called by the kernel subsystem during
+				 unloading
+				of the module.
+	@remarks
+				This function is invoked when the module is
+				 unloaded from the
+				 kernel subsystem. The main tasks performed by
+				 this function are.
+				- Un-registers the PCI Driver.
+
+	@retval     None.
+
+	<hr>
+*/
+static void __exit ioh_can_pci_exit(void)
+{
+	/* Unregistering the registered PCI Driver. */
+	pci_unregister_driver(&ioh_can_pcidev);
+	IOH_DEBUG
+	("ioh_can_pci_exit -> pci_unregister_driver invoked successfully.\n");
+
+	IOH_DEBUG("ioh_can_pci_exit invoked successfully. \n");
+}
+
+/*! @ingroup 	PCILayerAPI
+	@fn			static int __devinit ioh_can_probe(
+			struct pci_dev *pdev, const struct pci_device_id *id)
+	@brief		Implements the probe functionalities of the PCI Driver.
+	@remarks
+				This function is used as the probe function of
+				 the PCI Driver.
+				The main tasks performed by this function are:
+				- Enables the PCI device and other associated
+				 features such as interrupts.
+				- Attains the remapped section corresponding to
+				 the device for user interaction.
+				- Registers a character device driver for
+				 accessing the device.
+				- Initializes the driver specific data
+				 structures for use by
+				  other functions of the driver.
+	@note		This function is called by the kernel subsystem only
+				 when a supported PCI device has been detected.
+
+	@param		pdev		[@ref INOUT]	Reference to the PCI
+							 device descriptor.
+	@param		id		[@ref IN]	Reference to the
+						 supported PCI Device IDs
+						 table.
+
+	@retval     int
+				- @ref IOH_CAN_SUCCESS	--> Probe has been
+								 successful.
+				- @ref IOH_CAN_FAIL	--> Probe operation
+								 failed.
+				- -EIO 		--> pci_enable_device error
+							 status code.
+				- -EINVAL 	--> pci_enable_device error
+							 status code.
+				- -EBUSY 	--> pci_request_regions/
+							alloc_chrdev_region/
+				register_chrdev_region error status code.
+				- -ENOMEM 	--> pci_iomap fails/
+							alloc_chrdev_region/
+				register_chrdev_region/cdev_add error status
+				 code.
+				- -ENODEV 	--> pci_iomap error status code.
+
+	@see
+				- ioh_can_pcidev
+
+	<hr>
+*/
+static int __devinit ioh_can_probe(struct pci_dev *pdev,
+				   const struct pci_device_id *id)
+{
+	unsigned int can_num = 0;	/* Variable to denote the CAN
+							 structure index.  */
+	int resources_allocated = false;	/* Flag variables for denting
+							 resource allocation. */
+	int driver_registered = false;	/* Flag variable to denote driver
+							 registration. */
+	int retval = IOH_CAN_SUCCESS;	/* Variable storing the return
+							 status value.    */
+
+	{
+		do {
+			/* Enable the PCI device */
+			retval = pci_enable_device(pdev);
+			if (0 != retval) {
+				IOH_LOG(KERN_ERR,
+				"ioh_can_probe -> pci_enable_device failed"
+				"(returned %d).\n", retval);
+				IOH_DEBUG
+				("ioh_can_probe -> Couldn't enable PCI device "
+				"with Vendor ID:0x%x and Device ID:0x%x. "
+				"Exiting\n", pdev->vendor, pdev->device);
+
+				break;
+			}
+			IOH_DEBUG
+			    ("ioh_can_probe -> Enable PCI device successful"
+			     "(returned %d).\n", retval);
+
+			/* Request the PCI regions. */
+			retval = pci_request_regions(pdev, DRIVER_NAME);
+			if (0 != retval) {
+				IOH_LOG(KERN_ERR,
+					"ioh_can_probe -> pci_request_regions "
+					"failed(returned %d).\n", retval);
+				break;
+			}
+			IOH_DEBUG
+			    ("ioh_can_probe -> pci_request_regions successful"
+			     "(returned %d).\n", retval);
+			resources_allocated = true;
+
+			/* Remap the PCI user space regions to kernel space. */
+			/* Wipro 1/13/2010 Use Mem BAR */
+			can_os[can_num].pci_remap =
+			    (unsigned long)pci_iomap(pdev, 1, 0);
+			if (0 == can_os[can_num].pci_remap) {
+				IOH_LOG(KERN_ERR,
+					"pci_iomap failed(returned 0).\n");
+				retval = -ENOMEM;
+				break;
+			}
+			IOH_DEBUG
+			("ioh_can_probe -> \
+			pci_iomap successful. Remap address: "
+			"%lu\n", can_os[can_num].pci_remap);
+
+			/* If major number is not given as module parameter. */
+			if (major == 0) {
+				/* Registering the driver. */
+				retval = alloc_chrdev_region(
+					&ioh_can_major, 0, 1, DRIVER_NAME);
+				if (0 != retval) {
+
+					IOH_LOG(KERN_ERR,
+					"ioh_can_probe -> alloc_chrdev_region "
+					"failed(returned %d).\n",
+						retval);
+					break;
+				}
+				IOH_DEBUG
+				("ioh_can_probe -> alloc_chrdev_region \
+				successful"
+				"(returned %d).\n", retval);
+			} else {	/* If major number is provided as module
+								 parameter. */
+
+				/* Attaining a device id. */
+				ioh_can_major = MKDEV(major, 0);
+
+				/* Registering the driver. */
+				retval = register_chrdev_region(
+						ioh_can_major, 1, DRIVER_NAME);
+				if (0 != retval) {
+					IOH_LOG(KERN_ERR,
+					"ioh_can_probe -> \
+					register_chrdev_region "
+					"failed(returned %d).\n",
+						retval);
+					break;
+				}
+				IOH_DEBUG
+				("ioh_can_probe -> register_chrdev_region \
+				successful"
+				"(returned %d).\n", retval);
+			}
+
+			/* Initializing the cdev structure. */
+			cdev_init(&ioh_can_dev, &file_ops);
+			ioh_can_dev.owner = THIS_MODULE;
+			ioh_can_dev.ops = &file_ops;
+
+			/* Adding the device to the system. */
+			retval = cdev_add(&ioh_can_dev, ioh_can_major, 1);
+			if (0 != retval) {
+				IOH_LOG(KERN_ERR,
+					"ioh_can_probe -> cdev_add failed"
+					"(returned %d).\n", retval);
+				unregister_chrdev_region(ioh_can_major, 1);
+				IOH_DEBUG
+				("ioh_can_probe -> unregister_chrdev_region \
+				invoked successfully.\n");
+				break;
+			}
+			IOH_DEBUG
+			("ioh_can_probe -> cdev_add successful(returned %d).\n",
+			retval);
+			driver_registered = true;
+
+			/* Filling in the details of the CAN into the can
+								 structure. */
+			can_os[can_num].can_num = can_num;	/* Can number
+						(index to the structure) */
+			can_os[can_num].irq = pdev->irq;	/* IRQ allocated
+						 to this device. */
+
+			/* Creating the device handle denoting the remap base
+								 address. */
+			can_os[can_num].can =
+			    ioh_can_create((void *)can_os[can_num].pci_remap);
+
+			/* If handle creation fails. */
+			if ((int) NULL == can_os[can_num].can) {
+				IOH_LOG(KERN_ERR,
+				"ioh_can_probe -> ioh_can_create failed.\n");
+				retval = IOH_CAN_FAIL;
+				break;
+			}
+			IOH_DEBUG
+			    ("ioh_can_probe -> ioh_can_create successful.\n");
+
+			can_os[can_num].dev = pdev;	/* Reference to
+						 pci_device structure. */
+			can_os[can_num].opened = 0;	/* Open flag denoting
+						 the device usage. */
+			can_os[can_num].is_suspending = 0;	/* Flag denoting
+						 the suspend stage. */
+
+			/* Initializing the wait queues. */
+			init_waitqueue_head(&(can_os[can_num].read_wait_queue));
+			init_waitqueue_head(&
+					    (can_os[can_num].write_wait_queue));
+
+			/* Initailzing the lock variables. */
+			spin_lock_init(&(can_os[can_num].open_spinlock));
+			spin_lock_init(&(can_os[can_num].tx_spinlock));
+							/* OKISEMI 090721 add */
+
+			/* Storing the reference to the structure for
+			   use in other PCI functions.
+			 */
+/*	pdev->dev.driver_data = (void *)&(can_os[can_num]); */
+			dev_set_drvdata(&pdev->dev, (void *)&(can_os[can_num]));
+
+			{
+				/* Initializing the message object array to
+				 identify the
+				   objects used as receive and transmit
+				 object.
+				   According to this logic, the initial
+				 objects will be
+				   configured as receive objects followed by
+				 transmit objects.
+
+				   For example.
+				   1)   Receive Object(R) : 16
+				   Transmit Object(T): 16
+	-----------------------------------------------------------------
+	|R|R|R|R|R|R|R|R|R|R|R|R|R|R|R|R|T|T|T|T|T|T|T|T|T|T|T|T|T|T|T|T|
+	-----------------------------------------------------------------
+
+				   2)   Receive Object(R) : 6
+				   Transmit Object(T): 12
+	-----------------------------------------------------------------
+	|R|R|R|R|R|R|T|T|T|T|T|T|T|T|T|T|T|T|N|N|N|N|N|N|N|N|N|N|N|N|N|N|
+	-----------------------------------------------------------------
+
+				   3)   Receive Object(R) : 18
+				   Transmit Object(T): 5
+	-----------------------------------------------------------------
+	|R|R|R|R|R|R|R|R|R|R|R|R|R|R|R|R|R|R|T|T|T|T|T|N|N|N|N|N|N|N|N|N|
+	-----------------------------------------------------------------
+
+				   The above figure shows 32 message object
+				 starting from message object 1
+				   to object 32, being used according to the
+				 user specified receive and
+				   transmit message object number.
+
+				   Here R -> used as receive object.
+				   T -> used as transmit object.
+				   N -> not used.
+				 */
+
+				int index;
+
+				for (index = 0; index < ioh_can_rx_buf_size;
+				     index++) {
+					ioh_msg_obj_conf[index] = MSG_OBJ_RX;
+				}
+
+				for (index = index;
+				     index <
+				     (ioh_can_rx_buf_size +
+				      ioh_can_tx_buf_size); index++) {
+					ioh_msg_obj_conf[index] = MSG_OBJ_TX;
+				}
+
+			}
+
+			retval = IOH_CAN_SUCCESS;
+			IOH_DEBUG("ioh_can_probe successful.\n");
+		} while (false);
+
+		/* If any of the process fails. */
+		if (IOH_CAN_SUCCESS != retval) {
+			/* If the resources are allocated. */
+			if (true == resources_allocated) {
+				if (0 != can_os[can_num].pci_remap) {
+					pci_iounmap(pdev,
+						    (void *)can_os[can_num].
+						    pci_remap);
+					IOH_DEBUG("ioh_can_probe -> "
+					"pci_iounmap invoked successfully.\n");
+					can_os[can_num].pci_remap = 0;
+				}
+
+				pci_release_regions(pdev);
+				IOH_DEBUG("ioh_can_probe -> "
+				"pci_release_regions invoked successfully.\n");
+			}
+
+			/* If driver has been registered. */
+			if (true == driver_registered) {
+				cdev_del(&ioh_can_dev);
+				IOH_DEBUG("ioh_can_probe -> "
+					"cdev_del invoked successfully.\n");
+				unregister_chrdev_region(ioh_can_major, 1);
+				IOH_DEBUG("ioh_can_probe -> "
+					"unregister_chrdev_region \
+					invoked successfully.\n");
+			}
+
+			pci_disable_device(pdev);
+			IOH_DEBUG("ioh_can_probe -> "
+				  "pci_disable_region invoked successfully.\n");
+
+			IOH_DEBUG("ioh_can_probe failed.\n");
+		}
+
+	}
+
+	/* If probe fails retval contains the status code of the failed API.
+	   If it is successful it contains IOH_CAN_SUCCESS(0).
+	 */
+	IOH_DEBUG("ioh_can_probe returns %d\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	PCILayerAPI
+	@fn			static void __devexit ioh_can_remove(
+				struct pci_dev *pdev)
+	@brief		Implements the remove functionalities of the PCI Driver.
+	@remarks
+				This function is used as the remove function of
+				 the PCI Driver.
+				The main tasks performed by this function
+				 include :
+				- Un-maps the remapped user space from kernel
+				 space.
+				- Releases all the resources attained during
+				 probe.
+				- Un-registers the character device driver
+				 registered during probe.
+	@note		This function is called by the kernel subsystem when the
+				 supported
+				PCI device is removed/unloaded.
+
+	@param		pdev		[@ref INOUT]	Reference to the PCI
+							 device descriptor.
+
+	@retval     None.
+
+	@see
+				- ioh_can_pcidev
+
+	<hr>
+*/
+static void __devexit ioh_can_remove(struct pci_dev *pdev)
+{
+/*      struct ioh_can_os *can_os = pdev->dev.driver_data; */
+	struct ioh_can_os *can_os = \
+			(struct ioh_can_os *) dev_get_drvdata(&pdev->dev);
+
+	/* Unmapping the remmaped user space from kernel space. */
+	pci_iounmap(pdev, (void *)can_os->pci_remap);
+	IOH_DEBUG("ioh_can_remove -> pci_iounmap invoked successfully.\n");
+
+	/* Releasing the driver specific resources. */
+	ioh_can_destroy(can_os->can);
+	IOH_DEBUG("ioh_can_remove -> ioh_can_destroy invoked successfully.\n");
+
+	/* Releasing the acquired resources. */
+	pci_release_regions(pdev);
+	IOH_DEBUG
+	    ("ioh_can_remove -> pci_release_regions invoked successfully.\n");
+
+	/* Removing the device */
+	cdev_del(&ioh_can_dev);
+	IOH_DEBUG("ioh_can_remove -> cdev_del invoked successfully.\n");
+
+	/* Unregistering the driver. */
+	unregister_chrdev_region(ioh_can_major, 1);
+	IOH_DEBUG
+	("ioh_can_remove -> unregister_chrdev_region invoked successfully.\n");
+
+	/* disabling the device. */
+	pci_disable_device(pdev);
+	IOH_DEBUG
+	    ("ioh_can_remove -> pci_disable_device invoked successfully.\n");
+}
+
+#ifdef CONFIG_PM
+/*! @ingroup 	PCILayerAPI
+	@fn			static int ioh_can_suspend(struct pci_dev *pdev,
+				 pm_message_t state)
+	@brief		Implements the suspend functionalities of the PCI
+				 Driver.
+	@remarks
+				This function is used as the suspend function of
+				 the PCI driver.
+				The main tasks performed by this function are :
+				- Manipulates the power management of the
+				 supported device during
+				  system suspension.
+				- Maintains the crucial device data, so that the
+				 state of the system
+				  can be maintained during resumption.
+	@note		This function is called by the Kernel Power Management
+				 subsystem during system suspend operation.
+
+	@param		pdev		[@ref INOUT]	Reference to the PCI
+				 Device descriptor.
+	@param		state		[@ref IN]		The state of the
+				 PCI Device.
+
+	@retval     int
+				- @ref IOH_CAN_SUCCESS		--> The suspend
+				 process was successful.
+				- -ENOMEM --> pci_save_state error status code
+
+	@see
+				- ioh_can_pci_dev
+
+	<hr>
+*/
+static int ioh_can_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int i;			/* Counter variable. */
+	int retval;		/* Return value. */
+/*      struct ioh_can_os *can_os = pdev->dev.driver_data; */
+	struct ioh_can_os *can_os = \
+			(struct ioh_can_os *) dev_get_drvdata(&pdev->dev);
+
+	/* If the device is opened get the current run mode. */
+	if (1 == can_os->opened) {
+		/* Save the Run Mode. */
+		(void)ioh_can_get_run_mode(can_os->can, &(can_os->run_mode));
+	}
+
+	/* Stop the CAN controller */
+	(void)ioh_can_set_run_mode(can_os->can, IOH_CAN_STOP);
+
+	/* Indicate that we are aboutto/in suspend */
+	can_os->is_suspending = 1;
+
+	if (1 == can_os->opened) {
+		u32 buf_stat;	/* Variable for reading the transmit buffer
+								 status. */
+		u32 counter = 0xFFFFFF;
+
+		/*
+		   Waiting for all transmission to complete.
+		   This is done by checking the TXQST pending
+		    register. The loop teriminates when no
+		    transmission is pending.
+		 */
+		while (counter) {
+			buf_stat = ioh_can_get_buffer_status(can_os->can);
+			if (buf_stat == 0)
+				break;
+
+			counter--;
+		}
+
+		if (counter > 0) {
+			IOH_DEBUG
+			("ioh_can_suspend -> No transmission is pending.\n");
+		} else {
+			IOH_LOG(KERN_ERR,
+				"ioh_can_suspend -> Transmission time "
+				"out.\n");
+		}
+
+		/* Free any waiting write threads */
+		can_os->write_wait_flag = 1;
+		wake_up_interruptible(&(can_os->write_wait_queue));
+
+		/* Save interrupt configuration and then disable them */
+		(void)ioh_can_get_int_enables(can_os->can,
+					      &(can_os->int_enables));
+		(void)ioh_can_set_int_enables(can_os->can, CAN_DISABLE);
+
+		/* Save Tx buffer enable state */
+		for (i = 0; i < (ioh_can_tx_buf_size + ioh_can_rx_buf_size);
+		     i++) {
+			if (ioh_msg_obj_conf[i] == MSG_OBJ_TX) {
+				/* Here i is the index, however (i+1) is object
+								 number. */
+				(void)ioh_can_get_tx_enable(can_os->can,
+							    (i + 1),
+							    &(can_os->
+							      tx_enable[i]));
+			}
+		}
+
+		/* Disable all Transmit buffers */
+		(void)ioh_can_tx_disable_all(can_os->can);
+
+		/* Save Rx buffer enable state */
+		for (i = 0; i < (ioh_can_tx_buf_size + ioh_can_rx_buf_size);
+		     i++) {
+			if (ioh_msg_obj_conf[i] == MSG_OBJ_RX) {
+				/* Here i is the index, however (i+1) is object
+								 number. */
+
+				(void)ioh_can_get_rx_enable(can_os->can,
+							    (i + 1),
+							    &(can_os->
+							      rx_enable[i]));
+				(void)ioh_can_get_rx_buffer_link(can_os->can,
+								 (i + 1),
+								 &(can_os->
+								   rx_link[i]));
+
+				/* Save Rx Filters */
+				can_os->rx_filter[i].num = (i + 1);
+				(void)ioh_can_get_rx_filter(can_os->can,
+							    &(can_os->
+							      rx_filter[i]));
+			}
+		}
+
+		/* Disable all Receive buffers */
+		(void)ioh_can_rx_disable_all(can_os->can);
+
+		/* Save Context */
+		(void)ioh_can_get_baud(can_os->can, &(can_os->timing));
+								/* Timing. */
+		(void)ioh_can_get_listen_mode(can_os->can, \
+					&(can_os->listen_mode));
+							/* Listen mode  */
+		(void)ioh_can_get_arbiter_mode(can_os->can, \
+						&(can_os->arbiter_mode));
+							/* Arbiter mode */
+
+	}
+
+	retval = pci_save_state(pdev);
+
+	if (0 != retval) {
+		/* Indicate that we have not suspended */
+		can_os->is_suspending = 0;
+
+		IOH_LOG(KERN_ERR,
+			"ioh_can_suspend -> pci_save_state \
+			failed(returned %d).\n",
+			retval);
+	} else {
+		IOH_DEBUG
+		("ioh_can_suspend -> pci_save_state successful(returned %d).\n",
+		retval);
+
+		(void)pci_enable_wake(pdev, PCI_D3hot, 0);
+		IOH_DEBUG
+		("ioh_can_suspend -> pci_enable_wake invoked successfully.\n");
+
+		pci_disable_device(pdev);
+		IOH_DEBUG
+		("ioh_can_suspend -> pci_disable_device invoked \
+							successfully.\n");
+
+		(void)pci_set_power_state(pdev, pci_choose_state(pdev, state));
+		IOH_DEBUG
+		("ioh_can_suspend -> pci_set_power_state invoked \
+							successfully.\n");
+	}
+
+	IOH_DEBUG("ioh_can_suspend returns %d.\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	PCILayerAPI
+	@fn			static int ioh_can_resume(struct pci_dev *pdev)
+	@brief		Implements the resume functionalities of the PCI Driver.
+	@remarks
+				This function is used as the resume function of
+				 the PCI Driver.
+				The main tasks performed by this function
+				 includes :
+				- Restores the regular power state of the device
+				 to D0.
+				- Restores the same state of the device as that
+				 was before
+				  suspension.
+	@note		This function is invoked by the Kernel Power Management
+				 subsystem
+				during system resume operation.
+
+	@param		pdev		[@ref INOUT]	Reference to the PCI
+							 device descriptor.
+
+	@retval     int
+				- @ref IOH_CAN_SUCCESS		--> The resume
+				 operation was successful.
+				- -EIO	--> pci_enable_device error status code.
+				- -EINVAL --> pci_enable_device error status
+						 code.
+	@see
+				- ioh_can_pci_dev
+
+	<hr>
+*/
+static int ioh_can_resume(struct pci_dev *pdev)
+{
+	int i;			/* Counter variable. */
+	int retval;		/* Return variable. */
+/*      struct ioh_can_os *can_os = pdev->dev.driver_data; */
+	struct ioh_can_os *can_os = \
+			(struct ioh_can_os *) dev_get_drvdata(&pdev->dev);
+
+	(void)pci_set_power_state(pdev, PCI_D0);
+	IOH_DEBUG
+	    ("ioh_can_resume -> pci_set_power_state invoked successfully.\n");
+
+	(void)pci_restore_state(pdev);
+	IOH_DEBUG
+	    ("ioh_can_resume -> pci_restore_state invoked successfully.\n");
+
+	retval = pci_enable_device(pdev);
+	if (0 != retval) {
+		IOH_LOG(KERN_ERR,
+		"ioh_can_resume -> pci_enable_device failed(returned %d).\n",
+		retval);
+	}
+
+	else {
+		IOH_DEBUG
+		    ("ioh_can_resume -> pci_enable_device invoked successfully"
+		     "(returned %d)\n", retval);
+		(void)pci_enable_wake(pdev, PCI_D3hot, 0);
+
+		/* Disabling all interrupts. */
+		(void)ioh_can_set_int_enables(can_os->can, CAN_DISABLE);
+
+		/* Setting the CAN device in Stop Mode. */
+		(void)ioh_can_set_run_mode(can_os->can, IOH_CAN_STOP);
+
+		/* Configuring the transmit and receive buffers. */
+		ioh_can_config_rx_tx_buffers(can_os->can);
+		IOH_DEBUG
+		    ("ioh_can_resume -> ioh_can_config_rx_tx_buffers invoked "
+		     "successfully.\n");
+
+		if (1 == can_os->opened) {
+			/* Reset write file operation wait flag */
+			can_os->write_wait_flag = 0;
+
+			/* Restore the CAN state */
+			(void)ioh_can_set_baud_custom(\
+				can_os->can, &(can_os->timing));
+								/*Timing */
+			(void)ioh_can_set_listen_mode(\
+				can_os->can, can_os->listen_mode);
+							/*Listen/Active */
+			(void)ioh_can_set_arbiter_mode(\
+				can_os->can, can_os->arbiter_mode);
+							/*Arbiter mode */
+
+			/* Enabling the transmit buffer. */
+			for (i = 0;
+			     i < (ioh_can_tx_buf_size + ioh_can_rx_buf_size);
+			     i++) {
+				if (ioh_msg_obj_conf[i] == MSG_OBJ_TX) {
+					/* Here i is the index, however (i+1) is
+							 object number. */
+					(void)ioh_can_set_tx_enable(can_os->can,
+								    (i + 1),
+								    can_os->
+								    tx_enable
+								    [i]);
+				}
+			}
+
+			/* Configuring the receive buffer and enabling them. */
+			for (i = 0;
+			     i < (ioh_can_tx_buf_size + ioh_can_rx_buf_size);
+			     i++) {
+				if (ioh_msg_obj_conf[i] == MSG_OBJ_RX) {
+					/* Here i is the index, however (i+1) is
+							 object number. */
+
+					/* Restore buffer link */
+					(void)
+					    ioh_can_set_rx_buffer_link(can_os->
+								       can,
+								       (i + 1),
+								       can_os->
+								       rx_link
+								       [i]);
+
+					/* Restore Rx Filters */
+					can_os->rx_filter[i].num = (i + 1);
+					(void)ioh_can_set_rx_filter(can_os->can,
+								    &(can_os->
+								      rx_filter
+								      [i]));
+
+					/* Restore buffer enables */
+					(void)ioh_can_set_rx_enable(can_os->can,
+								    (i + 1),
+								    can_os->
+								    rx_enable
+								    [i]);
+				}
+			}
+
+			/* Enable CAN Interrupts */
+			(void)ioh_can_set_int_custom(can_os->can,
+						     can_os->int_enables);
+
+			/* Restore Run Mode */
+			(void)ioh_can_set_run_mode(can_os->can,
+						   can_os->run_mode);
+		}
+		/*if opened */
+		can_os->is_suspending = 0;
+	}			/*else */
+
+	IOH_DEBUG("ioh_can_resume returns %d\n", retval);
+	return retval;
+}
+#endif
+
+/*! @ingroup 	PCILayerAPI
+	@fn			static void ioh_can_shutdown(
+					struct pci_dev * pdev)
+	@brief		Implements the shutdown functionalities of the PCI
+			 Driver.
+	@remarks
+				This function is used as the shutdown function
+				 of the PCI Driver.
+				The main tasks performed by this function
+				 include :
+				- Prepare the system to enter the shutdown
+				 state.
+	@note		This function is called by the kernel subsystem during
+				 system shutdown.
+
+	@param		pdev		[@ref INOUT]	Reference to the PCI
+							 device descriptor.
+
+	@retval     None.
+
+	<hr>
+*/
+static void ioh_can_shutdown(struct pci_dev *pdev)
+{
+	(void)ioh_can_suspend(pdev, PMSG_SUSPEND);
+}
+
+module_init(ioh_can_pci_init);
+module_exit(ioh_can_pci_exit);
diff -urN linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_pci.h topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_pci.h
--- linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_pci.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_pci.h	2010-03-10 08:57:34.000000000 +0900
@@ -0,0 +1,105 @@
+/*!
+ * @file ioh_can_pci.h
+ * @brief Provides the macro definitions used by the PCI Layer APIs.
+ * @version 1.0
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * <hr>
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+#ifndef __IOH_CAN_PCI_H__
+#define __IOH_CAN_PCI_H__
+
+/* The PCI vendor ID for the CAN device. */
+#ifdef PCI_VENDOR_ID_INTEL
+#undef PCI_VENDOR_ID_INTEL
+#endif
+
+/*! @ingroup	PCILayer
+	@def		PCI_VENDOR_ID_INTEL
+	@brief		The Vendor ID of the supported device.
+	@remarks	This ID is used during the registration of the
+				PCI Driver, so that whenever a PCI device with
+				specified Vendor ID is detected the
+				 corresponding
+				registered functionalities are invoked.
+	@see
+				- ioh_can_pcidev_id
+
+	<hr>
+*/
+#ifndef FPGA_BOARD
+#define PCI_VENDOR_ID_INTEL       	(0x8086)
+#else
+#define PCI_VENDOR_ID_INTEL       	(0x10DB)
+#endif
+
+/* The PCI device ID for the CAN device . */
+/*! @ingroup	PCILayer
+	@def		PCI_DEVICE_ID_INTEL_IOH1_CAN
+	@brief		The Device ID of the supported device.
+	@remarks	This ID is used during the registration of the
+				PCI Driver, so that whenever a PCI device with
+				specified Device ID is detected the
+				 corresponding
+				registered functionalities are invoked.
+	@see
+				- ioh_can_pcidev_id
+
+	<hr>
+*/
+#ifndef FPGA_BOARD
+#define PCI_DEVICE_ID_INTEL_IOH1_CAN		(0x8818)
+#else
+#define PCI_DEVICE_ID_INTEL_IOH1_CAN		(0x800A)
+#endif
+
+/* The driver name. */
+/*! @ingroup	InterfaceLayer
+	@def		DRIVER_NAME
+	@brief		The Driver name
+	@see
+				- ioh_can_probe
+
+	<hr>
+*/
+#define DRIVER_NAME            		"can"
+
+/* external linkage */
+extern unsigned int ioh_msg_obj_conf[MAX_MSG_OBJ];	/* Array denoting the
+				 usage of the respective message object.   */
+extern struct ioh_can_timing can_rec_timing[];	/* Structure array for different
+					 supported timing settings.     */
+extern unsigned int ioh_can_rx_buf_size;	/* The receive buffer size. */
+extern unsigned int ioh_can_tx_buf_size;	/* The transmit buffer size. */
+extern int ioh_can_clock;	/* The clock rate.	*/
+extern struct ioh_can_os can_os[MAX_CAN_DEVICES];
+		/* Structure to store the details of the CAN controller. */
+
+extern const struct file_operations file_ops;	/* Structure to register the
+						 character device driver. */
+#endif
diff -urN linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_utils.c topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_utils.c
--- linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_utils.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_utils.c	2010-03-10 08:57:34.000000000 +0900
@@ -0,0 +1,397 @@
+/*!
+ * @file ioh_can_utils.c
+ * @brief Provides the function definition for FIFO utility functions.
+ * @version 1.0
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * <hr>
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+/* includes */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+#include "pch_common.h"
+#include "pch_debug.h"
+#include "pch_can_utils.h"
+
+/*! @ingroup	Utilities
+	@struct		can_fifo_item
+	@brief		This structure describes the FIFO node items.
+	@remarks	This structure is used to implement the
+				 software FIFO. It describes a particular
+				node within the FIFO chain.
+
+	<hr>
+*/
+struct can_fifo_item {
+	struct ioh_can_msg msg;		/**< The msg object */
+	struct can_fifo_item *next;	/**< The next pointer. */
+};
+
+/*! @ingroup	Utilities
+	@struct		can_fifo
+	@brief		This structure is used for maintaining the software
+				 FIFO chain.
+	@remarks	This structure maintains the reference to the FIFO
+				chain. It specifies which node within the FIFO
+				 has to be read and written.
+
+	<hr>
+*/
+struct can_fifo {
+	struct can_fifo_item *head;	/**< The node where insertion
+							 can be done. 	*/
+	struct can_fifo_item *tail;	/**< The node where reading can
+							 be done.	*/
+	unsigned int size;		/**< The number of FIFO nodes.	*/
+};
+
+/*! @ingroup 	UtilitiesAPI
+	@fn			int check_can_fifo_status(int handle)
+	@brief      Checks the status (Empty/Full/Non-Empty) of the software
+		 fifo.
+	@remarks	Checks the status (Empty/Full/Non-Empty) of the software
+				 fifo.
+				The main tasks performed by this API are :
+				- Checks the software FIFO status and returns
+					 the values denoting
+					the status.
+				- The return values along with the specified
+					 meaning is described
+					 in the Return values Section.
+
+	@param	handle		[@ref IN]	The handle to the device.
+
+	@retval	int
+	- @ref IOH_CAN_FIFO_NOT_EMPTY		--> FIFO is not empty.
+	- @ref IOH_CAN_FIFO_EMPTY			--> FIFO is empty.
+	- @ref IOH_CAN_FIFO_FULL			--> FIFO is full.
+
+	@see
+			- ioh_can_read
+
+	<hr>
+
+*/
+int check_can_fifo_status(int handle)
+{
+	int ret_val;
+	struct can_fifo *f = (struct can_fifo *) handle;
+
+	if (f->head == f->tail) {
+		ret_val = IOH_CAN_FIFO_EMPTY;	/*FIFO empty */
+		IOH_DEBUG("check_can_fifo_status -> FIFO empty.\n");
+	} else if (f->head->next == f->tail) {
+		ret_val = IOH_CAN_FIFO_FULL;	/*FIFO full */
+		IOH_DEBUG("check_can_fifo_status -> FIFO full.\n");
+	} else {
+		ret_val = IOH_CAN_FIFO_NOT_EMPTY;	/* FIFO non empty. */
+		IOH_DEBUG("check_can_fifo_status -> FIFO non-empty.\n");
+	}
+
+	IOH_DEBUG("check_can_fifo_status returns %d\n", ret_val);
+	return ret_val;
+}
+
+/*! @ingroup 	UtilitiesAPI
+	@fn			int create_can_fifo(unsigned int fifo_entries)
+	@brief      Creates the CAN FIFO.
+	@remarks	Creates the CAN FIFO depending on the argument value
+				 passed.
+				The main tasks performed by this API are :
+				- Depending on obtained argument value allocates
+					 memory for
+					the software FIFO nodes.
+				- If any of the memory allocation fails,
+					 releases the allocated
+					memory.
+				- Updates the software FIFO related structures
+					 with the
+					reference values so that the FIFO can
+					 be accessed by other
+					APIs
+
+	@param		fifo_entries	[@ref IN]	The number of FIFO nodes
+							 to be created.
+
+	@retval	int
+			- >0				--> Creation successful.
+			- @ref IOH_CAN_NULL 		--> Creation failed.
+
+	@see
+			- ioh_candev_open
+
+	<hr>
+
+*/
+int create_can_fifo(unsigned int fifo_entries)
+{
+	unsigned int i;
+	struct can_fifo_item *curr;
+	struct can_fifo *f;
+	int retval;
+
+	/* Allocating the Main start node. */
+	f = (struct can_fifo *) CAN_MEM_ALLOC(sizeof(struct can_fifo));
+
+	if (f == NULL) {
+		IOH_LOG(KERN_ERR,
+			"create_can_fifo -> msg queue allocation failed.\n");
+		retval = (int) IOH_CAN_NULL;
+	} else {
+		/* Allocating the first node. */
+		f->head =
+		(struct can_fifo_item *) CAN_MEM_ALLOC(\
+						sizeof(struct can_fifo_item));
+
+		if ((f->head == NULL)) {	/* Failed. */
+			CAN_MEM_FREE(f);
+			retval = (int) IOH_CAN_NULL;
+		} else {
+			/* Initially empty. */
+			f->tail = f->head;
+			curr = f->head;
+
+			/* Rest of the nod ecreation Node creation. */
+			for (i = 1; i <= fifo_entries; i++) {
+				curr->next =
+				    (struct can_fifo_item *)
+				    CAN_MEM_ALLOC(sizeof(struct can_fifo_item));
+
+				/* If allocation failed. */
+				if ((curr->next == NULL)) {
+					IOH_LOG(KERN_ERR,
+						"create_can_fifo -> \
+						Allocation failed.\n");
+					i = (i - 1);
+					/* Freeing the already allocated
+								 nodes. */
+					while (i > 0) {
+						curr = f->head;
+						f->head = curr->next;
+						CAN_MEM_FREE(curr);
+
+						i--;
+					}
+
+					/* Freeing the main start node. */
+					CAN_MEM_FREE(f);
+					f = NULL;
+					retval =
+					    (int) IOH_CAN_NULL;
+					break;
+				}
+
+				curr = curr->next;
+			}
+
+			if (NULL != f) {
+				/*Making it circular. */
+				curr->next = f->head;
+				f->size = fifo_entries;
+
+				retval = (int) f;
+				IOH_DEBUG("create_can_fifo sucessful.\n");
+			}
+		}
+	}
+
+	IOH_DEBUG("create_can_fifo returns %u.\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	UtilitiesAPI
+	@fn			void delete_can_fifo(int handle)
+	@brief      Deletes the software FIFO.
+	@remarks	Deletes the previously created software FIFO nodes.
+				The main task performed by this API is :
+				- Releases all the memory allocated for FIFO
+				 nodes.
+
+	@param	handle		[@ref IN]	The handle to the device.
+
+	@retval       None.
+
+	@see
+			- ioh_candev_close
+
+	<hr>
+*/
+void delete_can_fifo(int handle)
+{
+	unsigned int i;
+	struct can_fifo_item *curr = NULL;
+	struct can_fifo_item *next = NULL;
+	struct can_fifo *f = (struct can_fifo *) handle;
+
+	if (handle != (int) 0) {	/* valid handle */
+		curr = f->head;
+
+		if (f->head != NULL) {
+			next = curr->next;
+
+			/* Freeing individual node. */
+			for (i = 0; i < f->size; i++) {
+				CAN_MEM_FREE(curr);
+				curr = next;
+				next = (struct can_fifo_item *) curr->next;
+			}
+		}
+
+		/* Free the START node. */
+		CAN_MEM_FREE(f);
+	} else {
+		IOH_LOG(KERN_ERR, "delete_can_fifo -> Invalid handle.\n");
+	}
+
+	IOH_DEBUG("delete_can_fifo successful.\n");
+}
+
+/*! @ingroup 	UtilitiesAPI
+	@fn			int read_can_fifo(
+				int handle,struct ioh_can_msg *msg)
+	@brief      Reads data from the software FIFO.
+	@remarks	Reads data from the software FIFO when read system call
+				 is issued. The main tasks performed by this API
+				 are :
+				- Reads the node from the FIFO under the Read
+				 reference locator.
+				- Advances the Read reference locator to the
+				 next node to be
+					read.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	msg			[@ref OUT]	Reference to the read
+							 message.
+
+	@retval	int
+		- @ref IOH_CAN_SUCCESS		--> Operation successful.
+		- @ref IOH_CAN_FAIL			--> Operation failed.
+
+	@see
+				- ioh_can_read
+
+	<hr>
+*/
+int read_can_fifo(int handle, struct ioh_can_msg *msg)
+{
+	int i;
+	int retval = IOH_CAN_SUCCESS;
+	struct can_fifo *f = (struct can_fifo *) handle;
+	struct ioh_can_msg msg_tmp;
+
+	if ((handle == (int) 0) || (msg == NULL)) {	/* invalid parameters.*/
+		IOH_LOG(KERN_ERR, "read_can_fifo -> Invalid parameter.\n");
+		retval = IOH_CAN_FAIL;
+	} else if (f->head == f->tail) {	/* Buffer Empty */
+		IOH_DEBUG("read_can_fifo -> FIFO empty.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Accessing the msg object in the FIFO. */
+		msg_tmp = f->tail->msg;
+
+		/* Filling in the msg object. */
+		msg->ide = msg_tmp.ide;
+		msg->id = msg_tmp.id;
+		msg->dlc = msg_tmp.dlc;
+		msg->rtr = msg_tmp.rtr;
+
+		for (i = 0; i < IOH_CAN_MSG_DATA_LEN; i++)
+			msg->data[i] = msg_tmp.data[i];
+
+		/* Proceeding the FIFO read pointer. */
+		f->tail = f->tail->next;
+		IOH_DEBUG("read_can_fifo successful.\n");
+	}
+
+	IOH_DEBUG("read_can_fifo returns %d.\n", retval);
+	return retval;
+}
+
+/*! @ingroup 	UtilitiesAPI
+	@fn			int write_can_fifo(
+				int handle,struct ioh_can_msg *msg)
+	@brief      Write data to the software FIFO.
+	@remarks	Write data to the software FIFO when a message is
+				 received.
+				The main tasks performed by this API are :
+				- Writes the obtained data to the FIFO node
+					 under the Write
+					Reference locator.
+				- Advances the Write reference locator to the
+					 next node to be written.
+
+	@param	handle		[@ref IN]	The handle to the device.
+	@param	msg			[@ref IN]	Reference to the  data
+							 to be written
+
+	@retval	int
+		- @ref IOH_CAN_SUCCESS		--> Operation successful.
+		- @ref IOH_CAN_FAIL			--> Operation failed.
+
+	@see
+				- ioh_can_callback
+
+	<hr>
+
+*/
+int write_can_fifo(int handle, struct ioh_can_msg *msg)
+{
+	int i;
+	int retval = IOH_CAN_SUCCESS;
+	struct can_fifo *f = (struct can_fifo *) handle;
+	struct ioh_can_msg *msg_tmp;
+
+	if ((handle == (int) 0) || (msg == NULL)) {	/* invalid parameters.*/
+		IOH_LOG(KERN_ERR, "write_can_fifo -> Invalid parameters.\n");
+		retval = IOH_CAN_FAIL;
+	} else if (f->head->next == f->tail) {
+		IOH_DEBUG("write_can_fifo -> FIFO Full.\n");
+		retval = IOH_CAN_FAIL;
+	} else {
+		/* Accessing the write node in the FIFO */
+		msg_tmp = &(f->head->msg);
+
+		/* Filling in the FIFO node. */
+		msg_tmp->ide = msg->ide;
+		msg_tmp->rtr = msg->rtr;
+		msg_tmp->id = msg->id;
+		msg_tmp->dlc = msg->dlc;
+
+		for (i = 0; i < IOH_CAN_MSG_DATA_LEN; i++)
+			msg_tmp->data[i] = msg->data[i];
+
+		/* Proceeding the write node. */
+		f->head = f->head->next;
+		IOH_DEBUG("write_can_fifo successful.\n");
+	}
+
+	IOH_DEBUG("write_can_fifo returns %d.\n", retval);
+	return retval;
+}
diff -urN linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_utils.h topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_utils.h
--- linux-2.6.33-rc3/drivers/net/can/pch_can/pch_can_utils.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_can_utils.h	2010-03-10 08:57:34.000000000 +0900
@@ -0,0 +1,127 @@
+/*!
+ * @file ioh_can_utils.h
+ * @brief Provides the function prototype of the Utilis Layer APIs.
+ * @version 1.0
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * <hr>
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+#ifndef __IOH_CAN_FIFO_H__
+#define __IOH_CAN_FIFO_H__
+
+#include "pch_can_main.h"
+
+#define CAN_MEM_ALLOC(size)		(kmalloc((size), GFP_KERNEL))
+#define CAN_MEM_FREE(ptr)		(kfree((ptr)))
+
+/*! @ingroup 	Utilities
+	@def 		IOH_CAN_FIFO_NOT_EMPTY
+	@brief		Flag value denoting that the software fifo is not empty.
+	@see
+			- check_can_fifo_status
+			- ioh_can_read
+
+	<hr>
+*/
+#define IOH_CAN_FIFO_NOT_EMPTY	(0)
+
+/*! @ingroup 	Utilities
+	@def 		IOH_CAN_FIFO_EMPTY
+	@brief		Flag value denoting that the software fifo is empty.
+	@see
+			- check_can_fifo_status
+			- ioh_can_read
+
+	<hr>
+*/
+#define IOH_CAN_FIFO_EMPTY		(1)
+
+/*! @ingroup 	Utilities
+	@def 		IOH_CAN_FIFO_FULL
+	@brief		Flag value denoting that the software fifo is full.
+	@see
+			- check_can_fifo_status
+			- ioh_can_read
+
+	<hr>
+*/
+#define IOH_CAN_FIFO_FULL		(2)
+
+/*!	@ingroup	Utilities
+	@def		IOH_CAN_NULL
+	@brief		Denoting NULL value.
+
+	@see
+			- ioh_can_create
+			- create_can_fifo
+	<hr>
+*/
+#define IOH_CAN_NULL			(NULL)
+
+/*! @ingroup	UtilitiesAPI
+	@fn		int check_can_fifo_status(int handle)
+	@brief		Checks the status (Empty/Full/Non-Empty) of the software
+			 fifo.
+
+	<hr>
+*/
+int check_can_fifo_status(int handle);
+
+/*! @ingroup	UtilitiesAPI
+	@fn		int create_can_fifo(unsigned int num_nodes)
+	@brief		Creates the CAN FIFO.
+
+	<hr>
+*/
+int create_can_fifo(unsigned int num_nodes);
+
+/*! @ingroup	UtilitiesAPI
+	@fn			void delete_can_fifo(int handle)
+	@brief		Deletes the software FIFO.
+
+	<hr>
+*/
+void delete_can_fifo(int handle);
+
+/*! @ingroup	UtilitiesAPI
+	@fn	int read_can_fifo(int  handle, struct ioh_can_msg *msg)
+	@brief		Reads data from the software FIFO.
+
+	<hr>
+*/
+int read_can_fifo(int handle, struct ioh_can_msg *msg);
+
+/*! @ingroup	UtilitiesAPI
+	@fn	int write_can_fifo(int handle, struct ioh_can_msg *msg)
+	@brief		Write data to the software FIFO.
+
+	<hr>
+*/
+int write_can_fifo(int handle, struct ioh_can_msg *msg);
+
+#endif /* __IOH_CAN_FIFO_H__ */
diff -urN linux-2.6.33-rc3/drivers/net/can/pch_can/pch_common.h topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_common.h
--- linux-2.6.33-rc3/drivers/net/can/pch_can/pch_common.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_common.h	2010-03-09 05:56:11.000000000 +0900
@@ -0,0 +1,146 @@
+/*!
+ * @file ioh_common.h
+ * @brief Provides the macro definitions used by all files.
+ * @version 1.0.0.0
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+#ifndef __IOH_COMMON_H__
+#define __IOH_COMMON_H__
+
+/*! @ingroup	Global
+@def		    IOH_WRITE8
+@brief			Macro for writing 8 bit data to an io/mem address
+*/
+#define IOH_WRITE8(val, addr)   iowrite8((val), (void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_LOG
+@brief			Macro for writing 16 bit data to an io/mem address
+*/
+#define IOH_WRITE16(val, addr)  iowrite16((val), (void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_LOG
+@brief			Macro for writing 32 bit data to an io/mem address
+*/
+#define IOH_WRITE32(val, addr)  iowrite32((val), (void __iomem *)(addr))
+
+/*! @ingroup	Global
+@def		    IOH_READ8
+@brief			Macro for reading 8 bit data from an io/mem address
+*/
+#define IOH_READ8(addr)   ioread8((void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_READ16
+@brief			Macro for reading 16 bit data from an io/mem address
+*/
+#define IOH_READ16(addr)  ioread16((void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_READ32
+@brief			Macro for reading 32 bit data from an io/mem address
+*/
+#define IOH_READ32(addr)  ioread32((void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_WRITE32_F
+@brief			Macro for writing 32 bit data to an io/mem address
+*/
+#define IOH_WRITE32_F(val, addr) do \
+	{ IOH_WRITE32((val), (addr)); (void)IOH_READ32((addr)); } while (0);
+
+/*! @ingroup	Global
+@def		    IOH_WRITE_BYTE
+@brief			Macro for writing 1 byte data to an io/mem address
+*/
+#define IOH_WRITE_BYTE IOH_WRITE8
+/*! @ingroup	Global
+@def		    IOH_WRITE_WORD
+@brief			Macro for writing 1 word data to an io/mem address
+*/
+#define IOH_WRITE_WORD IOH_WRITE16
+/*! @ingroup	Global
+@def		    IOH_WRITE_LONG
+@brief			Macro for writing long data to an io/mem address
+*/
+#define IOH_WRITE_LONG IOH_WRITE32
+
+/*! @ingroup	Global
+@def		    IOH_READ_BYTE
+@brief			Macro for reading 1 byte data from an io/mem address
+*/
+#define IOH_READ_BYTE  IOH_READ8
+/*! @ingroup	Global
+@def		    IOH_READ_WORD
+@brief			Macro for reading 1 word data from an io/mem address
+*/
+#define IOH_READ_WORD  IOH_READ16
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			Macro for reading long data from an io/mem address
+*/
+#define IOH_READ_LONG  IOH_READ32
+
+/* Bit Manipulation Macros */
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to set a specified bit(mask) at the
+			specified address
+*/
+#define IOH_SET_ADDR_BIT(addr, bitmask) IOH_WRITE_LONG((IOH_READ_LONG(addr) |\
+							 (bitmask)), (addr))
+
+/*! @ingroup	Global
+@def	    IOH_READ_LONG
+@brief		macro to clear a specified bit(mask) at the specified address
+*/
+#define IOH_CLR_ADDR_BIT(addr, bitmask) IOH_WRITE_LONG((IOH_READ_LONG(addr) &\
+							 ~(bitmask)), (addr))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to set a specified bitmask for a variable
+*/
+#define IOH_SET_BITMSK(var, bitmask) ((var) |= (bitmask))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to clear a specified bitmask for a variable
+*/
+#define IOH_CLR_BITMSK(var, bitmask) ((var) &= (~(bitmask)))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to set a specified bit for a variable
+*/
+#define IOH_SET_BIT(var, bit) ((var) |= (1<<(bit)))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to clear a specified bit for a variable
+*/
+#define IOH_CLR_BIT(var, bit) ((var) &= ~(1<<(bit)))
+
+#endif
diff -urN linux-2.6.33-rc3/drivers/net/can/pch_can/pch_debug.h topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_debug.h
--- linux-2.6.33-rc3/drivers/net/can/pch_can/pch_debug.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33-rc3/drivers/net/can/pch_can/pch_debug.h	2010-03-09 05:37:47.000000000 +0900
@@ -0,0 +1,60 @@
+/*!
+ * @file ioh_debug.h
+ * @brief Provides the macro definitions used for debugging.
+ * @version 1.0.0.0
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+#ifndef __IOH_DEBUG_H__
+#define __IOH_DEBUG_H__
+
+#ifdef MODULE
+#define IOH_LOG(level, fmt, args...) printk(level "%s:" fmt "\n",\
+						 THIS_MODULE->name, ##args)
+#else
+#define IOH_LOG(level, fmt, args...) printk(level "%s:" fmt "\n" ,\
+							 __FILE__, ##args)
+#endif
+
+
+#ifdef DEBUG
+	#define IOH_DEBUG(fmt, args...) IOH_LOG(KERN_DEBUG, fmt, ##args)
+#else
+	#define IOH_DEBUG(fmt, args...)
+#endif
+
+#ifdef IOH_TRACE_ENABLED
+	#define IOH_TRACE IOH_DEBUG
+#else
+	#define IOH_TRACE(fmt, args...)
+#endif
+
+#define IOH_TRACE_ENTER IOH_TRACE("Enter %s", __func__)
+#define IOH_TRACE_EXIT 	IOH_TRACE("Exit %s", __func__)
+
+
+#endif
