Netdev List
 help / color / mirror / Atom feed
* [PATCH V3 1/2] cpc-usb: Removed driver from staging tree
From: Sebastian Haas @ 2009-09-16 12:04 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	greg-U8xfFu+wG4EAvxtiuMwx3w, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	wg-5Yr1BZd7O62+XT7JhA+gdA
In-Reply-To: <20090916120409.30391.22292.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>

This patch prepares replacing the staging driver cpc-usb with the new
developed ems_usb CAN driver.

Signed-off-by: Sebastian Haas <haas-zsNKPWJ8Pib6hrUXjxyGrA@public.gmane.org>
Acked-by: Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org>
---

 drivers/staging/Kconfig               |    2 
 drivers/staging/Makefile              |    1 
 drivers/staging/cpc-usb/Kconfig       |    4 
 drivers/staging/cpc-usb/Makefile      |    3 
 drivers/staging/cpc-usb/TODO          |    9 
 drivers/staging/cpc-usb/cpc-usb_drv.c | 1185 ---------------------------------
 drivers/staging/cpc-usb/cpc.h         |  440 ------------
 drivers/staging/cpc-usb/cpc_int.h     |   83 --
 drivers/staging/cpc-usb/cpcusb.h      |   86 --
 drivers/staging/cpc-usb/sja2m16c.h    |   41 -
 drivers/staging/cpc-usb/sja2m16c_2.c  |  452 -------------
 11 files changed, 0 insertions(+), 2306 deletions(-)
 delete mode 100644 drivers/staging/cpc-usb/Kconfig
 delete mode 100644 drivers/staging/cpc-usb/Makefile
 delete mode 100644 drivers/staging/cpc-usb/TODO
 delete mode 100644 drivers/staging/cpc-usb/cpc-usb_drv.c
 delete mode 100644 drivers/staging/cpc-usb/cpc.h
 delete mode 100644 drivers/staging/cpc-usb/cpc_int.h
 delete mode 100644 drivers/staging/cpc-usb/cpcusb.h
 delete mode 100644 drivers/staging/cpc-usb/sja2m16c.h
 delete mode 100644 drivers/staging/cpc-usb/sja2m16c_2.c

diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 975ecdd..5e4b865 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -121,8 +121,6 @@ source "drivers/staging/serqt_usb2/Kconfig"
 
 source "drivers/staging/vt6655/Kconfig"
 
-source "drivers/staging/cpc-usb/Kconfig"
-
 source "drivers/staging/pata_rdc/Kconfig"
 
 source "drivers/staging/udlfb/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 2241ae1..ede1599 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -42,6 +42,5 @@ obj-$(CONFIG_LINE6_USB)		+= line6/
 obj-$(CONFIG_USB_SERIAL_QUATECH2)	+= serqt_usb2/
 obj-$(CONFIG_OCTEON_ETHERNET)	+= octeon/
 obj-$(CONFIG_VT6655)		+= vt6655/
-obj-$(CONFIG_USB_CPC)		+= cpc-usb/
 obj-$(CONFIG_RDC_17F3101X)	+= pata_rdc/
 obj-$(CONFIG_FB_UDL)		+= udlfb/
diff --git a/drivers/staging/cpc-usb/Kconfig b/drivers/staging/cpc-usb/Kconfig
deleted file mode 100644
index 2be0bc9..0000000
--- a/drivers/staging/cpc-usb/Kconfig
+++ /dev/null
@@ -1,4 +0,0 @@
-config USB_CPC
-	tristate "CPC CAN USB driver"
-	depends on USB && PROC_FS
-	default n
diff --git a/drivers/staging/cpc-usb/Makefile b/drivers/staging/cpc-usb/Makefile
deleted file mode 100644
index 3f83170..0000000
--- a/drivers/staging/cpc-usb/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_USB_CPC)	+= cpc-usb.o
-
-cpc-usb-y := cpc-usb_drv.o sja2m16c_2.o
diff --git a/drivers/staging/cpc-usb/TODO b/drivers/staging/cpc-usb/TODO
deleted file mode 100644
index 000e8bb..0000000
--- a/drivers/staging/cpc-usb/TODO
+++ /dev/null
@@ -1,9 +0,0 @@
-Things to do for this driver to get merged into the main portion of the
-kernel:
-	- checkpatch cleanups
-	- sparse clean
-	- remove proc code
-	- tie into CAN socket interfaces if possible
-	- figure out sane userspace api
-
-Send patches to Greg Kroah-Hartman <greg-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
diff --git a/drivers/staging/cpc-usb/cpc-usb_drv.c b/drivers/staging/cpc-usb/cpc-usb_drv.c
deleted file mode 100644
index 9bf3f98..0000000
--- a/drivers/staging/cpc-usb/cpc-usb_drv.c
+++ /dev/null
@@ -1,1185 +0,0 @@
-/*
- * CPC-USB CAN Interface Kernel Driver
- *
- * Copyright (C) 2004-2009 EMS Dr. Thomas Wuensche
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-#include <linux/poll.h>
-#include <linux/smp_lock.h>
-#include <linux/completion.h>
-#include <asm/uaccess.h>
-#include <linux/usb.h>
-
-#include <linux/version.h>
-
-#include <linux/proc_fs.h>
-
-#include "cpc.h"
-
-#include "cpc_int.h"
-#include "cpcusb.h"
-
-#include "sja2m16c.h"
-
-/* Version Information */
-#define DRIVER_AUTHOR  "Sebastian Haas <haas-zsNKPWJ8Pib6hrUXjxyGrA@public.gmane.org>"
-#define DRIVER_DESC    "CPC-USB Driver for Linux Kernel 2.6"
-#define DRIVER_VERSION CPC_DRIVER_VERSION
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL v2");
-
-/* Define these values to match your devices */
-#define USB_CPCUSB_VENDOR_ID	0x12D6
-
-#define USB_CPCUSB_M16C_PRODUCT_ID    0x0888
-#define USB_CPCUSB_LPC2119_PRODUCT_ID 0x0444
-
-#define CPC_USB_PROC_DIR     CPC_PROC_DIR "cpc-usb"
-
-static struct proc_dir_entry *procDir;
-static struct proc_dir_entry *procEntry;
-
-/* Module parameters */
-static int debug;
-module_param(debug, int, S_IRUGO);
-
-/* table of devices that work with this driver */
-static struct usb_device_id cpcusb_table[] = {
-	{USB_DEVICE(USB_CPCUSB_VENDOR_ID, USB_CPCUSB_M16C_PRODUCT_ID)},
-	{USB_DEVICE(USB_CPCUSB_VENDOR_ID, USB_CPCUSB_LPC2119_PRODUCT_ID)},
-	{}			/* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, cpcusb_table);
-
-/* use to prevent kernel panic if driver is unloaded
- * while a programm has still open the device
- */
-DECLARE_WAIT_QUEUE_HEAD(rmmodWq);
-atomic_t useCount;
-
-static CPC_USB_T *CPCUSB_Table[CPC_USB_CARD_CNT] = { 0 };
-static unsigned int CPCUsbCnt;
-
-/* prevent races between open() and disconnect() */
-static DECLARE_MUTEX(disconnect_sem);
-
-/* local function prototypes */
-static ssize_t cpcusb_read(struct file *file, char *buffer, size_t count,
-			   loff_t *ppos);
-static ssize_t cpcusb_write(struct file *file, const char *buffer,
-			    size_t count, loff_t *ppos);
-static unsigned int cpcusb_poll(struct file *file, poll_table * wait);
-static int cpcusb_open(struct inode *inode, struct file *file);
-static int cpcusb_release(struct inode *inode, struct file *file);
-
-static int cpcusb_probe(struct usb_interface *interface,
-			const struct usb_device_id *id);
-static void cpcusb_disconnect(struct usb_interface *interface);
-
-static void cpcusb_read_bulk_callback(struct urb *urb);
-static void cpcusb_write_bulk_callback(struct urb *urb);
-static void cpcusb_read_interrupt_callback(struct urb *urb);
-
-static int cpcusb_setup_intrep(CPC_USB_T *card);
-
-static struct file_operations cpcusb_fops = {
-	/*
-	 * The owner field is part of the module-locking
-	 * mechanism. The idea is that the kernel knows
-	 * which module to increment the use-counter of
-	 * BEFORE it calls the device's open() function.
-	 * This also means that the kernel can decrement
-	 * the use-counter again before calling release()
-	 * or should the open() function fail.
-	 */
-	.owner = THIS_MODULE,
-
-	.read = cpcusb_read,
-	.write = cpcusb_write,
-	.poll = cpcusb_poll,
-	.open = cpcusb_open,
-	.release = cpcusb_release,
-};
-
-/*
- * usb class driver info in order to get a minor number from the usb core,
- * and to have the device registered with devfs and the driver core
- */
-static struct usb_class_driver cpcusb_class = {
-	.name = "usb/cpc_usb%d",
-	.fops = &cpcusb_fops,
-	.minor_base = CPC_USB_BASE_MNR,
-};
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver cpcusb_driver = {
-	.name = "cpc-usb",
-	.probe = cpcusb_probe,
-	.disconnect = cpcusb_disconnect,
-	.id_table = cpcusb_table,
-};
-
-static int cpcusb_create_info_output(char *buf)
-{
-	int i = 0, j;
-
-	for (j = 0; j < CPC_USB_CARD_CNT; j++) {
-		if (CPCUSB_Table[j]) {
-			CPC_USB_T *card = CPCUSB_Table[j];
-			CPC_CHAN_T *chan = card->chan;
-
-			/* MINOR CHANNELNO BUSNO SLOTNO */
-			i += sprintf(&buf[i], "%d %s\n", chan->minor,
-				     card->serialNumber);
-		}
-	}
-
-	return i;
-}
-
-static int cpcusb_proc_read_info(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
-{
-	int len = cpcusb_create_info_output(page);
-
-	if (len <= off + count)
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len > count)
-		len = count;
-	if (len < 0)
-		len = 0;
-
-	return len;
-}
-
-/*
- * Remove CPC-USB and cleanup
- */
-static inline void cpcusb_delete(CPC_USB_T *card)
-{
-	if (card) {
-		if (card->chan) {
-			if (card->chan->buf)
-				vfree(card->chan->buf);
-
-			if (card->chan->CPCWait_q)
-				kfree(card->chan->CPCWait_q);
-
-			kfree(card->chan);
-		}
-
-		CPCUSB_Table[card->idx] = NULL;
-		kfree(card);
-	}
-}
-
-/*
- * setup the interrupt IN endpoint of a specific CPC-USB device
- */
-static int cpcusb_setup_intrep(CPC_USB_T *card)
-{
-	int retval = 0;
-	struct usb_endpoint_descriptor *ep;
-
-	ep = &card->interface->altsetting[0].endpoint[card->num_intr_in].desc;
-
-	card->intr_in_buffer[0] = 0;
-	card->free_slots = 15;	/* initial size */
-
-	/* setup the urb */
-	usb_fill_int_urb(card->intr_in_urb, card->udev,
-			 usb_rcvintpipe(card->udev, card->num_intr_in),
-			 card->intr_in_buffer,
-			 sizeof(card->intr_in_buffer),
-			 cpcusb_read_interrupt_callback,
-			 card,
-			 ep->bInterval);
-
-	card->intr_in_urb->status = 0;	/* needed! */
-
-	/* submit the urb */
-	retval = usb_submit_urb(card->intr_in_urb, GFP_KERNEL);
-
-	if (retval)
-		err("%s - failed submitting intr urb, error %d", __func__,
-		    retval);
-
-	return retval;
-}
-
-static int cpcusb_open(struct inode *inode, struct file *file)
-{
-	CPC_USB_T *card = NULL;
-	struct usb_interface *interface;
-	int subminor;
-	int j, retval = 0;
-
-	subminor = iminor(inode);
-
-	/* prevent disconnects */
-	down(&disconnect_sem);
-
-	interface = usb_find_interface(&cpcusb_driver, subminor);
-	if (!interface) {
-		err("%s - error, can't find device for minor %d",
-				__func__, subminor);
-		retval = CPC_ERR_NO_INTERFACE_PRESENT;
-		goto exit_no_device;
-	}
-
-	card = usb_get_intfdata(interface);
-	if (!card) {
-		retval = CPC_ERR_NO_INTERFACE_PRESENT;
-		goto exit_no_device;
-	}
-
-	/* lock this device */
-	down(&card->sem);
-
-	/* increment our usage count for the driver */
-	if (card->open) {
-		dbg("device already opened");
-		retval = CPC_ERR_CHANNEL_ALREADY_OPEN;
-		goto exit_on_error;
-	}
-
-	/* save our object in the file's private structure */
-	file->private_data = card;
-	for (j = 0; j < CPC_USB_URB_CNT; j++) {
-		usb_fill_bulk_urb(card->urbs[j].urb, card->udev,
-				  usb_rcvbulkpipe(card->udev, card->num_bulk_in),
-				  card->urbs[j].buffer, card->urbs[j].size,
-				  cpcusb_read_bulk_callback, card);
-
-		retval = usb_submit_urb(card->urbs[j].urb, GFP_KERNEL);
-
-		if (retval) {
-			err("%s - failed submitting read urb, error %d",
-			    __func__, retval);
-			retval = CPC_ERR_TRANSMISSION_FAILED;
-			goto exit_on_error;
-		}
-	}
-
-	info("%s - %d URB's submitted", __func__, j);
-
-	ResetBuffer(card->chan);
-
-	cpcusb_setup_intrep(card);
-	card->open = 1;
-
-	atomic_inc(&useCount);
-
-exit_on_error:
-	/* unlock this device */
-	up(&card->sem);
-
-exit_no_device:
-	up(&disconnect_sem);
-
-	return retval;
-}
-
-static unsigned int cpcusb_poll(struct file *file, poll_table * wait)
-{
-	CPC_USB_T *card = (CPC_USB_T *) file->private_data;
-	unsigned int retval = 0;
-
-	if (!card) {
-		err("%s - device object lost", __func__);
-		return -EIO;
-	}
-
-	poll_wait(file, card->chan->CPCWait_q, wait);
-
-	if (IsBufferNotEmpty(card->chan) || !(card->present))
-		retval |= (POLLIN | POLLRDNORM);
-
-	if (card->free_slots)
-		retval |= (POLLOUT | POLLWRNORM);
-
-	return retval;
-}
-
-static int cpcusb_release(struct inode *inode, struct file *file)
-{
-	CPC_USB_T *card = (CPC_USB_T *) file->private_data;
-	int j, retval = 0;
-
-	if (card == NULL) {
-		dbg("%s - object is NULL", __func__);
-		return CPC_ERR_NO_INTERFACE_PRESENT;
-	}
-
-	/* lock our device */
-	down(&card->sem);
-
-	if (!card->open) {
-		dbg("%s - device not opened", __func__);
-		retval = CPC_ERR_NO_INTERFACE_PRESENT;
-		goto exit_not_opened;
-	}
-
-	/* if device wasn't unplugged kill all urbs */
-	if (card->present) {
-		/* kill read urbs */
-		for (j = 0; j < CPC_USB_URB_CNT; j++) {
-			usb_kill_urb(card->urbs[j].urb);
-		}
-
-		/* kill irq urb */
-		usb_kill_urb(card->intr_in_urb);
-
-		/* kill write urbs */
-		for (j = 0; j < CPC_USB_URB_CNT; j++) {
-			if (atomic_read(&card->wrUrbs[j].busy)) {
-				usb_kill_urb(card->wrUrbs[j].urb);
-				wait_for_completion(&card->wrUrbs[j].finished);
-			}
-		}
-	}
-
-	atomic_dec(&useCount);
-
-	/* last process detached */
-	if (atomic_read(&useCount) == 0) {
-		wake_up(&rmmodWq);
-	}
-
-	if (!card->present && card->open) {
-		/* the device was unplugged before the file was released */
-		up(&card->sem);
-		cpcusb_delete(card);
-		return 0;
-	}
-
-	card->open = 0;
-
-exit_not_opened:
-	up(&card->sem);
-
-	return 0;
-}
-
-static ssize_t cpcusb_read(struct file *file, char *buffer, size_t count,
-			   loff_t *ppos)
-{
-	CPC_USB_T *card = (CPC_USB_T *) file->private_data;
-	CPC_CHAN_T *chan;
-	int retval = 0;
-
-	if (count < sizeof(CPC_MSG_T))
-		return CPC_ERR_UNKNOWN;
-
-	/* check if can read from the given address */
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return CPC_ERR_UNKNOWN;
-
-	/* lock this object */
-	down(&card->sem);
-
-	/* verify that the device wasn't unplugged */
-	if (!card->present) {
-		up(&card->sem);
-		return CPC_ERR_NO_INTERFACE_PRESENT;
-	}
-
-	if (IsBufferEmpty(card->chan)) {
-		retval = 0;
-	} else {
-		chan = card->chan;
-
-#if 0
-		/* convert LPC2119 params back to SJA1000 params */
-		if (card->deviceRevision >= 0x0200
-		    && chan->buf[chan->oidx].type == CPC_MSG_T_CAN_PRMS) {
-			LPC2119_TO_SJA1000_Params(&chan->buf[chan->oidx]);
-		}
-#endif
-
-		if (copy_to_user(buffer, &chan->buf[chan->oidx], count) != 0) {
-			retval = CPC_ERR_IO_TRANSFER;
-		} else {
-			chan->oidx = (chan->oidx + 1) % CPC_MSG_BUF_CNT;
-			chan->WnR = 1;
-			retval = sizeof(CPC_MSG_T);
-		}
-	}
-/*	spin_unlock_irqrestore(&card->slock, flags); */
-
-	/* unlock the device */
-	up(&card->sem);
-
-	return retval;
-}
-
-#define SHIFT  1
-static inline void cpcusb_align_buffer_alignment(unsigned char *buf)
-{
-	/* CPC-USB uploads packed bytes. */
-	CPC_MSG_T *cpc = (CPC_MSG_T *) buf;
-	unsigned int i;
-
-	for (i = 0; i < cpc->length + (2 * sizeof(unsigned long)); i++) {
-		((unsigned char *) &cpc->msgid)[1 + i] =
-		    ((unsigned char *) &cpc->msgid)[1 + SHIFT + i];
-	}
-}
-
-static int cpc_get_buffer_count(CPC_CHAN_T *chan)
-{
-	/* check the buffer parameters */
-	if (chan->iidx == chan->oidx)
-		return !chan->WnR ? CPC_MSG_BUF_CNT : 0;
-	else if (chan->iidx >= chan->oidx)
-		return (chan->iidx - chan->oidx) % CPC_MSG_BUF_CNT;
-
-	return (chan->iidx + CPC_MSG_BUF_CNT - chan->oidx) % CPC_MSG_BUF_CNT;
-}
-
-static ssize_t cpcusb_write(struct file *file, const char *buffer,
-			    size_t count, loff_t *ppos)
-{
-	CPC_USB_T *card = (CPC_USB_T *) file->private_data;
-	CPC_USB_WRITE_URB_T *wrUrb = NULL;
-
-	ssize_t bytes_written = 0;
-	int retval = 0;
-	int j;
-
-	unsigned char *obuf = NULL;
-	unsigned char type = 0;
-	CPC_MSG_T *info = NULL;
-
-	dbg("%s - entered minor %d, count = %zu, present = %d",
-	    __func__, card->minor, count, card->present);
-
-	if (count > sizeof(CPC_MSG_T))
-		return CPC_ERR_UNKNOWN;
-
-	/* check if can read from the given address */
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return CPC_ERR_UNKNOWN;
-
-	/* lock this object */
-	down(&card->sem);
-
-	/* verify that the device wasn't unplugged */
-	if (!card->present) {
-		retval = CPC_ERR_NO_INTERFACE_PRESENT;
-		goto exit;
-	}
-
-	/* verify that we actually have some data to write */
-	if (count == 0) {
-		dbg("%s - write request of 0 bytes", __func__);
-		goto exit;
-	}
-
-	if (card->free_slots <= 5) {
-		info = (CPC_MSG_T *) buffer;
-
-		if (info->type != CPC_CMD_T_CLEAR_CMD_QUEUE
-		    || card->free_slots <= 0) {
-			dbg("%s - send buffer full please try again %d",
-			    __func__, card->free_slots);
-			retval = CPC_ERR_CAN_NO_TRANSMIT_BUF;
-			goto exit;
-		}
-	}
-
-	/* Find a free write urb */
-	for (j = 0; j < CPC_USB_URB_CNT; j++) {
-		if (!atomic_read(&card->wrUrbs[j].busy)) {
-			wrUrb = &card->wrUrbs[j];	/* remember found URB */
-			atomic_set(&wrUrb->busy, 1);	/* lock this URB      */
-			init_completion(&wrUrb->finished);	/* init completion    */
-			dbg("WR URB no. %d started", j);
-			break;
-		}
-	}
-
-	/* don't found write urb say error */
-	if (!wrUrb) {
-		dbg("%s - no free send urb available", __func__);
-		retval = CPC_ERR_CAN_NO_TRANSMIT_BUF;
-		goto exit;
-	}
-	dbg("URB write req");
-
-	obuf = (unsigned char *) wrUrb->urb->transfer_buffer;
-
-	/* copy the data from userspace into our transfer buffer;
-	 * this is the only copy required.
-	 */
-	if (copy_from_user(&obuf[4], buffer, count) != 0) {
-		atomic_set(&wrUrb->busy, 0);	/* release urb */
-		retval = CPC_ERR_IO_TRANSFER;
-		goto exit;
-	}
-
-	/* check if it is a DRIVER information message, so we can
-	 * response to that message and not the USB
-	 */
-	info = (CPC_MSG_T *) &obuf[4];
-
-	bytes_written = 11 + info->length;
-	if (bytes_written >= wrUrb->size) {
-		retval = CPC_ERR_IO_TRANSFER;
-		goto exit;
-	}
-
-	switch (info->type) {
-	case CPC_CMD_T_CLEAR_MSG_QUEUE:
-		ResetBuffer(card->chan);
-		break;
-
-	case CPC_CMD_T_INQ_MSG_QUEUE_CNT:
-		retval = cpc_get_buffer_count(card->chan);
-		atomic_set(&wrUrb->busy, 0);
-
-		goto exit;
-
-	case CPC_CMD_T_INQ_INFO:
-		if (info->msg.info.source == CPC_INFOMSG_T_DRIVER) {
-			/* release urb cause we'll use it for driver
-			 * information
-			 */
-			atomic_set(&wrUrb->busy, 0);
-			if (IsBufferFull(card->chan)) {
-				retval = CPC_ERR_IO_TRANSFER;
-				goto exit;
-			}
-
-			/* it is a driver information request message and we have
-			 * free rx slots to store the response
-			 */
-			type = info->msg.info.type;
-			info = &card->chan->buf[card->chan->iidx];
-
-			info->type = CPC_MSG_T_INFO;
-			info->msg.info.source = CPC_INFOMSG_T_DRIVER;
-			info->msg.info.type = type;
-
-			switch (type) {
-			case CPC_INFOMSG_T_VERSION:
-				info->length = strlen(CPC_DRIVER_VERSION) + 2;
-				sprintf(info->msg.info.msg, "%s\n",
-					CPC_DRIVER_VERSION);
-				break;
-
-			case CPC_INFOMSG_T_SERIAL:
-				info->length = strlen(CPC_DRIVER_SERIAL) + 2;
-				sprintf(info->msg.info.msg, "%s\n",
-					CPC_DRIVER_SERIAL);
-				break;
-
-			default:
-				info->length = 2;
-				info->msg.info.type =
-				    CPC_INFOMSG_T_UNKNOWN_TYPE;
-			}
-
-			card->chan->WnR = 0;
-			card->chan->iidx =
-			    (card->chan->iidx + 1) % CPC_MSG_BUF_CNT;
-
-			retval = info->length;
-			goto exit;
-		}
-		break;
-	case CPC_CMD_T_CAN_PRMS:
-		/* Check the controller type. If it's the new CPC-USB, make sure if these are SJA1000 params */
-		if (info->msg.canparams.cc_type != SJA1000
-		    && info->msg.canparams.cc_type != M16C_BASIC
-		    && (card->productId == USB_CPCUSB_LPC2119_PRODUCT_ID
-			&& info->msg.canparams.cc_type != SJA1000)) {
-			/* don't forget to release the urb */
-			atomic_set(&wrUrb->busy, 0);
-			retval = CPC_ERR_WRONG_CONTROLLER_TYPE;
-			goto exit;
-		}
-		break;
-	}
-
-	/* just convert the params if it is an old CPC-USB with M16C controller */
-	if (card->productId == USB_CPCUSB_M16C_PRODUCT_ID) {
-		/* if it is a parameter message convert it from SJA1000 controller
-		 * settings to M16C Basic controller settings
-		 */
-		SJA1000_TO_M16C_BASIC_Params((CPC_MSG_T *) &obuf[4]);
-	}
-
-	/* don't forget the byte alignment */
-	cpcusb_align_buffer_alignment(&obuf[4]);
-
-	/* setup a the 4 byte header */
-	obuf[0] = obuf[1] = obuf[2] = obuf[3] = 0;
-
-	/* this urb was already set up, except for this write size */
-	wrUrb->urb->transfer_buffer_length = bytes_written + 4;
-
-	/* send the data out the bulk port */
-	/* a character device write uses GFP_KERNEL,
-	   unless a spinlock is held */
-	retval = usb_submit_urb(wrUrb->urb, GFP_KERNEL);
-	if (retval) {
-		atomic_set(&wrUrb->busy, 0);	/* release urb */
-		err("%s - failed submitting write urb, error %d",
-		    __func__, retval);
-	} else {
-		retval = bytes_written;
-	}
-
-exit:
-	/* unlock the device */
-	up(&card->sem);
-
-	dbg("%s - leaved", __func__);
-
-	return retval;
-}
-
-/*
- * callback for interrupt IN urb
- */
-static void cpcusb_read_interrupt_callback(struct urb *urb)
-{
-	CPC_USB_T *card = (CPC_USB_T *) urb->context;
-	int retval;
-	unsigned long flags;
-
-	spin_lock_irqsave(&card->slock, flags);
-
-	if (!card->present) {
-		spin_unlock_irqrestore(&card->slock, flags);
-		info("%s - no such device", __func__);
-		return;
-	}
-
-	switch (urb->status) {
-	case 0: /* success */
-		card->free_slots = card->intr_in_buffer[1];
-		break;
-	case -ECONNRESET:
-	case -ENOENT:
-	case -ESHUTDOWN:
-		/* urb was killed */
-		spin_unlock_irqrestore(&card->slock, flags);
-		dbg("%s - intr urb killed", __func__);
-		return;
-	default:
-		info("%s - nonzero urb status %d", __func__, urb->status);
-		break;
-	}
-
-	retval = usb_submit_urb(urb, GFP_ATOMIC);
-	if (retval) {
-		err("%s - failed resubmitting intr urb, error %d",
-		    __func__, retval);
-	}
-
-	spin_unlock_irqrestore(&card->slock, flags);
-	wake_up_interruptible(card->chan->CPCWait_q);
-
-	return;
-}
-
-#define UN_SHIFT  1
-#define CPCMSG_HEADER_LEN_FIRMWARE   11
-static inline int cpcusb_unalign_and_copy_buffy(unsigned char *out,
-						unsigned char *in)
-{
-	unsigned int i, j;
-
-	for (i = 0; i < 3; i++)
-		out[i] = in[i];
-
-	for (j = 0; j < (in[1] + (CPCMSG_HEADER_LEN_FIRMWARE - 3)); j++)
-		out[j + i + UN_SHIFT] = in[j + i];
-
-	return i + j;
-}
-
-/*
- * callback for bulk IN urb
- */
-static void cpcusb_read_bulk_callback(struct urb *urb)
-{
-	CPC_USB_T *card = (CPC_USB_T *) urb->context;
-	CPC_CHAN_T *chan;
-	unsigned char *ibuf = urb->transfer_buffer;
-	int retval, msgCnt, start, again = 0;
-	unsigned long flags;
-
-	if (!card) {
-		err("%s - device object lost", __func__);
-		return;
-	}
-
-	spin_lock_irqsave(&card->slock, flags);
-
-	if (!card->present) {
-		spin_unlock_irqrestore(&card->slock, flags);
-		info("%s - no such device", __func__);
-		return;
-	}
-
-	switch (urb->status) {
-	case 0:		/* success */
-		break;
-	case -ECONNRESET:
-	case -ENOENT:
-	case -ESHUTDOWN:
-		/* urb was killed */
-		spin_unlock_irqrestore(&card->slock, flags);
-		dbg("%s - read urb killed", __func__);
-		return;
-	default:
-		info("%s - nonzero urb status %d", __func__, urb->status);
-		break;
-	}
-
-	if (urb->actual_length) {
-		msgCnt = ibuf[0] & ~0x80;
-		again = ibuf[0] & 0x80;
-
-		/* we have a 4 byte header */
-		start = 4;
-		chan = card->chan;
-		while (msgCnt) {
-			if (!(IsBufferFull(card->chan))) {
-				start +=
-				    cpcusb_unalign_and_copy_buffy((unsigned char *)
-							  &chan->buf[chan->iidx], &ibuf[start]);
-
-				if (start > urb->transfer_buffer_length) {
-					err("%d > %d", start, urb->transfer_buffer_length);
-					break;
-				}
-
-				chan->WnR = 0;
-				chan->iidx = (chan->iidx + 1) % CPC_MSG_BUF_CNT;
-				msgCnt--;
-			} else {
-				break;
-			}
-		}
-	}
-
-	usb_fill_bulk_urb(urb, card->udev,
-			  usb_rcvbulkpipe(card->udev, card->num_bulk_in),
-			  urb->transfer_buffer,
-			  urb->transfer_buffer_length,
-			  cpcusb_read_bulk_callback, card);
-
-	retval = usb_submit_urb(urb, GFP_ATOMIC);
-
-	if (retval) {
-		err("%s - failed resubmitting read urb, error %d", __func__, retval);
-	}
-
-	spin_unlock_irqrestore(&card->slock, flags);
-
-	wake_up_interruptible(card->chan->CPCWait_q);
-}
-
-/*
- * callback for bulk IN urb
- */
-static void cpcusb_write_bulk_callback(struct urb *urb)
-{
-	CPC_USB_T *card = (CPC_USB_T *) urb->context;
-	unsigned long flags;
-	int j;
-
-	spin_lock_irqsave(&card->slock, flags);
-
-	/* find this urb */
-	for (j = 0; j < CPC_USB_URB_CNT; j++) {
-		if (card->wrUrbs[j].urb == urb) {
-			dbg("URB found no. %d", j);
-			/* notify anyone waiting that the write has finished */
-			complete(&card->wrUrbs[j].finished);
-			atomic_set(&card->wrUrbs[j].busy, 0);
-			break;
-		}
-	}
-
-	switch (urb->status) {
-	case 0:		/* success */
-		break;
-	case -ECONNRESET:
-	case -ENOENT:
-	case -ESHUTDOWN:
-		/* urb was killed */
-		spin_unlock_irqrestore(&card->slock, flags);
-		dbg("%s - write urb no. %d killed", __func__, j);
-		return;
-	default:
-		info("%s - nonzero urb status %d", __func__, urb->status);
-		break;
-	}
-
-	spin_unlock_irqrestore(&card->slock, flags);
-
-	wake_up_interruptible(card->chan->CPCWait_q);
-}
-
-static inline int cpcusb_get_free_slot(void)
-{
-	int i;
-
-	for (i = 0; i < CPC_USB_CARD_CNT; i++) {
-		if (!CPCUSB_Table[i])
-			return i;
-	}
-
-	return -1;
-}
-
-/*
- * probe function for new CPC-USB devices
- */
-static int cpcusb_probe(struct usb_interface *interface,
-			const struct usb_device_id *id)
-{
-	CPC_USB_T *card = NULL;
-	CPC_CHAN_T *chan = NULL;
-
-	struct usb_device *udev = interface_to_usbdev(interface);
-	struct usb_host_interface *iface_desc;
-	struct usb_endpoint_descriptor *endpoint;
-
-	int i, j, retval = -ENOMEM, slot;
-
-	slot = cpcusb_get_free_slot();
-	if (slot < 0) {
-		info("No more devices supported");
-		return -ENOMEM;
-	}
-
-	/* allocate memory for our device state and initialize it */
-	card = kzalloc(sizeof(CPC_USB_T), GFP_KERNEL);
-	if (!card) {
-		err("Out of memory");
-		return -ENOMEM;
-	}
-	CPCUSB_Table[slot] = card;
-
-	/* allocate and initialize the channel struct */
-	card->chan = kmalloc(sizeof(CPC_CHAN_T), GFP_KERNEL);
-	if (!card->chan) {
-		kfree(card);
-		err("Out of memory");
-		return -ENOMEM;
-	}
-
-	chan = card->chan;
-	memset(chan, 0, sizeof(CPC_CHAN_T));
-	ResetBuffer(chan);
-
-	init_MUTEX(&card->sem);
-	spin_lock_init(&card->slock);
-
-	card->udev = udev;
-	card->interface = interface;
-	if (udev->descriptor.iSerialNumber) {
-		usb_string(udev, udev->descriptor.iSerialNumber, card->serialNumber,
-				   128);
-		info("Serial %s", card->serialNumber);
-	}
-
-	card->productId = udev->descriptor.idProduct;
-	info("Product %s",
-	     card->productId == USB_CPCUSB_LPC2119_PRODUCT_ID ?
-			 "CPC-USB/ARM7" : "CPC-USB/M16C");
-
-	/* set up the endpoint information */
-	/* check out the endpoints */
-	/* use only the first bulk-in and bulk-out endpoints */
-	iface_desc = &interface->altsetting[0];
-	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
-		endpoint = &iface_desc->endpoint[i].desc;
-
-		if (!card->num_intr_in &&
-		    (endpoint->bEndpointAddress & USB_DIR_IN) &&
-		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-		     == USB_ENDPOINT_XFER_INT)) {
-			card->intr_in_urb = usb_alloc_urb(0, GFP_KERNEL);
-			card->num_intr_in = 1;
-
-			if (!card->intr_in_urb) {
-				err("No free urbs available");
-				goto error;
-			}
-
-			dbg("intr_in urb %d", card->num_intr_in);
-		}
-
-		if (!card->num_bulk_in &&
-		    (endpoint->bEndpointAddress & USB_DIR_IN) &&
-		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-		     == USB_ENDPOINT_XFER_BULK)) {
-			card->num_bulk_in = 2;
-			for (j = 0; j < CPC_USB_URB_CNT; j++) {
-				card->urbs[j].size = endpoint->wMaxPacketSize;
-				card->urbs[j].urb = usb_alloc_urb(0, GFP_KERNEL);
-				if (!card->urbs[j].urb) {
-					err("No free urbs available");
-					goto error;
-				}
-				card->urbs[j].buffer =
-				    usb_buffer_alloc(udev,
-						     card->urbs[j].size,
-						     GFP_KERNEL,
-						     &card->urbs[j].urb->transfer_dma);
-				if (!card->urbs[j].buffer) {
-					err("Couldn't allocate bulk_in_buffer");
-					goto error;
-				}
-			}
-			info("%s - %d reading URB's allocated",
-			     __func__, CPC_USB_URB_CNT);
-		}
-
-		if (!card->num_bulk_out &&
-		    !(endpoint->bEndpointAddress & USB_DIR_IN) &&
-		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-		     == USB_ENDPOINT_XFER_BULK)) {
-
-			card->num_bulk_out = 2;
-
-			for (j = 0; j < CPC_USB_URB_CNT; j++) {
-				card->wrUrbs[j].size =
-				    endpoint->wMaxPacketSize;
-				card->wrUrbs[j].urb =
-				    usb_alloc_urb(0, GFP_KERNEL);
-				if (!card->wrUrbs[j].urb) {
-					err("No free urbs available");
-					goto error;
-				}
-				card->wrUrbs[j].buffer = usb_buffer_alloc(udev,
-							       card->wrUrbs[j].size, GFP_KERNEL,
-							       &card->wrUrbs[j].urb->transfer_dma);
-
-				if (!card->wrUrbs[j].buffer) {
-					err("Couldn't allocate bulk_out_buffer");
-					goto error;
-				}
-
-				usb_fill_bulk_urb(card->wrUrbs[j].urb, udev,
-						usb_sndbulkpipe(udev, endpoint->bEndpointAddress),
-						card->wrUrbs[j].buffer,
-						card->wrUrbs[j].size,
-						cpcusb_write_bulk_callback,
-						card);
-			}
-
-			info("%s - %d writing URB's allocated", __func__, CPC_USB_URB_CNT);
-		}
-	}
-
-	if (!(card->num_bulk_in && card->num_bulk_out)) {
-		err("Couldn't find both bulk-in and bulk-out endpoints");
-		goto error;
-	}
-
-	/* allow device read, write and ioctl */
-	card->present = 1;
-
-	/* we can register the device now, as it is ready */
-	usb_set_intfdata(interface, card);
-	retval = usb_register_dev(interface, &cpcusb_class);
-
-	if (retval) {
-		/* something prevented us from registering this driver */
-		err("Not able to get a minor for this device.");
-		usb_set_intfdata(interface, NULL);
-		goto error;
-	}
-
-	card->chan->minor = card->minor = interface->minor;
-
-	chan->buf = vmalloc(sizeof(CPC_MSG_T) * CPC_MSG_BUF_CNT);
-	if (chan->buf == NULL) {
-		err("Out of memory");
-		retval = -ENOMEM;
-		goto error;
-	}
-	info("Allocated memory for %d messages (%lu kbytes)",
-	     CPC_MSG_BUF_CNT, (long unsigned int)(sizeof(CPC_MSG_T) * CPC_MSG_BUF_CNT) / 1000);
-	memset(chan->buf, 0, sizeof(CPC_MSG_T) * CPC_MSG_BUF_CNT);
-
-	ResetBuffer(chan);
-
-	card->chan->CPCWait_q = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL);
-	if (!card->chan->CPCWait_q) {
-		err("Out of memory");
-		retval = -ENOMEM;
-		goto error;
-	}
-	init_waitqueue_head(card->chan->CPCWait_q);
-
-	CPCUSB_Table[slot] = card;
-	card->idx = slot;
-	CPCUsbCnt++;
-
-	/* let the user know what node this device is now attached to */
-	info("Device now attached to USB-%d", card->minor);
-	return 0;
-
-error:
-	for (j = 0; j < CPC_USB_URB_CNT; j++) {
-		if (card->urbs[j].buffer) {
-			usb_buffer_free(card->udev, card->urbs[j].size,
-					card->urbs[j].buffer,
-					card->urbs[j].urb->transfer_dma);
-			card->urbs[j].buffer = NULL;
-		}
-		if (card->urbs[j].urb) {
-			usb_free_urb(card->urbs[j].urb);
-			card->urbs[j].urb = NULL;
-		}
-	}
-
-	cpcusb_delete(card);
-	return retval;
-}
-
-/*
- * called by the usb core when the device is removed from the system
- */
-static void cpcusb_disconnect(struct usb_interface *interface)
-{
-	CPC_USB_T *card = NULL;
-	int minor, j;
-
-	/* prevent races with open() */
-	down(&disconnect_sem);
-
-	card = usb_get_intfdata(interface);
-	usb_set_intfdata(interface, NULL);
-
-	down(&card->sem);
-
-	/* prevent device read, write and ioctl */
-	card->present = 0;
-
-	minor = card->minor;
-
-	/* free all urbs and their buffers */
-	for (j = 0; j < CPC_USB_URB_CNT; j++) {
-		/* terminate an ongoing write */
-		if (atomic_read(&card->wrUrbs[j].busy)) {
-			usb_kill_urb(card->wrUrbs[j].urb);
-			wait_for_completion(&card->wrUrbs[j].finished);
-		}
-		usb_buffer_free(card->udev, card->wrUrbs[j].size,
-				card->wrUrbs[j].buffer,
-				card->wrUrbs[j].urb->transfer_dma);
-		usb_free_urb(card->wrUrbs[j].urb);
-	}
-	info("%d write URBs freed", CPC_USB_URB_CNT);
-
-	/* free all urbs and their buffers */
-	for (j = 0; j < CPC_USB_URB_CNT; j++) {
-		usb_buffer_free(card->udev, card->urbs[j].size,
-				card->urbs[j].buffer,
-				card->urbs[j].urb->transfer_dma);
-		usb_free_urb(card->urbs[j].urb);
-	}
-	info("%d read URBs freed", CPC_USB_URB_CNT);
-	usb_free_urb(card->intr_in_urb);
-
-	/* give back our minor */
-	usb_deregister_dev(interface, &cpcusb_class);
-
-	up(&card->sem);
-
-	/* if the device is opened, cpcusb_release will clean this up */
-	if (!card->open)
-		cpcusb_delete(card);
-	else
-		wake_up_interruptible(card->chan->CPCWait_q);
-
-	up(&disconnect_sem);
-
-	CPCUsbCnt--;
-	info("USB-%d now disconnected", minor);
-}
-
-static int __init CPCUsb_Init(void)
-{
-	int result, i;
-
-	info(DRIVER_DESC " v" DRIVER_VERSION);
-	info("Build on " __DATE__ " at " __TIME__);
-
-	for (i = 0; i < CPC_USB_CARD_CNT; i++)
-		CPCUSB_Table[i] = 0;
-
-	/* register this driver with the USB subsystem */
-	result = usb_register(&cpcusb_driver);
-	if (result) {
-		err("usb_register failed. Error number %d", result);
-		return result;
-	}
-
-	procDir = proc_mkdir(CPC_USB_PROC_DIR, NULL);
-	if (!procDir) {
-		err("Could not create proc entry");
-	} else {
-		procEntry = create_proc_read_entry("info", 0444, procDir,
-						   cpcusb_proc_read_info,
-						   NULL);
-		if (!procEntry) {
-			err("Could not create proc entry %s", CPC_USB_PROC_DIR "/info");
-			remove_proc_entry(CPC_USB_PROC_DIR, NULL);
-			procDir = NULL;
-		}
-	}
-
-	return 0;
-}
-
-static void __exit CPCUsb_Exit(void)
-{
-	wait_event(rmmodWq, !atomic_read(&useCount));
-
-	/* deregister this driver with the USB subsystem */
-	usb_deregister(&cpcusb_driver);
-
-	if (procDir) {
-		if (procEntry)
-			remove_proc_entry("info", procDir);
-		remove_proc_entry(CPC_USB_PROC_DIR, NULL);
-	}
-}
-
-module_init(CPCUsb_Init);
-module_exit(CPCUsb_Exit);
diff --git a/drivers/staging/cpc-usb/cpc.h b/drivers/staging/cpc-usb/cpc.h
deleted file mode 100644
index ed8cb34..0000000
--- a/drivers/staging/cpc-usb/cpc.h
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * CPC CAN Interface Definitions
- *
- * Copyright (C) 2000-2008 EMS Dr. Thomas Wuensche
- *
- * 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.
- */
-#ifndef CPC_HEADER
-#define CPC_HEADER
-
-// the maximum length of the union members within a CPC_MSG
-// this value can be defined by the customer, but has to be
-// >= 64 bytes
-// however, if not defined before, we set a length of 64 byte
-#if !defined(CPC_MSG_LEN) || (CPC_MSG_LEN < 64)
-#undef CPC_MSG_LEN
-#define CPC_MSG_LEN 64
-#endif
-
-// check the operating system used
-#ifdef _WIN32 // running a Windows OS
-
-// define basic types on Windows platforms
-#ifdef _MSC_VER // Visual Studio
-	typedef unsigned __int8 u8;
-	typedef unsigned __int16 u16;
-	typedef unsigned __int32 u32;
-#else // Borland Compiler
-	typedef unsigned char u8;
-	typedef unsigned short u16;
-	typedef unsigned int u32;
-#endif
-	// on Windows OS we use a byte alignment of 1
-	#pragma pack(push, 1)
-
-	// set the calling conventions for the library function calls
-	#define CALL_CONV __stdcall
-#else
-	// Kernel headers already define this types
-	#ifndef __KERNEL__
-		// define basic types
-		typedef unsigned char u8;
-		typedef unsigned short u16;
-		typedef unsigned int u32;
-	#endif
-
-	// Linux does not use this calling convention
-	#define CALL_CONV
-#endif
-
-// Transmission of events from CPC interfaces to PC can be individually
-// controlled per event type. Default state is: don't transmit
-// Control values are constructed by bit-or of Subject and Action
-// and passed to CPC_Control()
-
-// Control-Values for CPC_Control() Command Subject Selection
-#define CONTR_CAN_Message 0x04
-#define CONTR_Busload	  0x08
-#define	CONTR_CAN_State	  0x0C
-#define	CONTR_SendAck	  0x10
-#define	CONTR_Filter	  0x14
-#define CONTR_CmdQueue    0x18	// reserved, do not use
-#define CONTR_BusError    0x1C
-
-// Control Command Actions
-#define CONTR_CONT_OFF    0
-#define CONTR_CONT_ON     1
-#define CONTR_SING_ON     2
-// CONTR_SING_ON doesn't change CONTR_CONT_ON state, so it should be
-// read as: transmit at least once
-
-// defines for confirmed request
-#define DO_NOT_CONFIRM 0
-#define DO_CONFIRM     1
-
-// event flags
-#define EVENT_READ 0x01
-#define EVENT_WRITE 0x02
-
-// Messages from CPC to PC contain a message object type field.
-// The following message types are sent by CPC and can be used in
-// handlers, others should be ignored.
-#define CPC_MSG_T_RESYNC        0 // Normally to be ignored
-#define CPC_MSG_T_CAN           1 // CAN data frame
-#define CPC_MSG_T_BUSLOAD       2 // Busload message
-#define CPC_MSG_T_STRING        3 // Normally to be ignored
-#define CPC_MSG_T_CONTI         4 // Normally to be ignored
-#define CPC_MSG_T_MEM           7 // Normally not to be handled
-#define	CPC_MSG_T_RTR           8 // CAN remote frame
-#define CPC_MSG_T_TXACK	        9 // Send acknowledge
-#define CPC_MSG_T_POWERUP      10 // Power-up message
-#define	CPC_MSG_T_CMD_NO       11 // Normally to be ignored
-#define	CPC_MSG_T_CAN_PRMS     12 // Actual CAN parameters
-#define	CPC_MSG_T_ABORTED      13 // Command aborted message
-#define	CPC_MSG_T_CANSTATE     14 // CAN state message
-#define CPC_MSG_T_RESET        15 // used to reset CAN-Controller
-#define	CPC_MSG_T_XCAN         16 // XCAN data frame
-#define CPC_MSG_T_XRTR         17 // XCAN remote frame
-#define CPC_MSG_T_INFO         18 // information strings
-#define CPC_MSG_T_CONTROL      19 // used for control of interface/driver behaviour
-#define CPC_MSG_T_CONFIRM      20 // response type for confirmed requests
-#define CPC_MSG_T_OVERRUN      21 // response type for overrun conditions
-#define CPC_MSG_T_KEEPALIVE    22 // response type for keep alive conditions
-#define CPC_MSG_T_CANERROR     23 // response type for bus error conditions
-#define CPC_MSG_T_DISCONNECTED 24 // response type for a disconnected interface
-#define CPC_MSG_T_ERR_COUNTER  25 // RX/TX error counter of CAN controller
-
-#define CPC_MSG_T_FIRMWARE    100 // response type for USB firmware download
-
-// Messages from the PC to the CPC interface contain a command field
-// Most of the command types are wrapped by the library functions and have therefore
-// normally not to be used.
-// However, programmers who wish to circumvent the library and talk directly
-// to the drivers (mainly Linux programmers) can use the following
-// command types:
-
-#define CPC_CMD_T_CAN                 1	// CAN data frame
-#define CPC_CMD_T_CONTROL             3	// used for control of interface/driver behaviour
-#define	CPC_CMD_T_CAN_PRMS            6	// set CAN parameters
-#define	CPC_CMD_T_CLEARBUF            8	// clears input queue; this is depricated, use CPC_CMD_T_CLEAR_MSG_QUEUE instead
-#define	CPC_CMD_T_INQ_CAN_PARMS      11	// inquire actual CAN parameters
-#define	CPC_CMD_T_FILTER_PRMS        12	// set filter parameter
-#define	CPC_CMD_T_RTR                13	// CAN remote frame
-#define	CPC_CMD_T_CANSTATE           14	// CAN state message
-#define	CPC_CMD_T_XCAN               15	// XCAN data frame
-#define CPC_CMD_T_XRTR               16	// XCAN remote frame
-#define CPC_CMD_T_RESET              17	// used to reset CAN-Controller
-#define CPC_CMD_T_INQ_INFO           18	// miscellanous information strings
-#define CPC_CMD_T_OPEN_CHAN          19	// open a channel
-#define CPC_CMD_T_CLOSE_CHAN         20	// close a channel
-#define CPC_CMD_T_CNTBUF             21	// this is depricated, use CPC_CMD_T_INQ_MSG_QUEUE_CNT instead
-#define CPC_CMD_T_CAN_EXIT          200 // exit the CAN (disable interrupts; reset bootrate; reset output_cntr; mode = 1)
-
-#define CPC_CMD_T_INQ_MSG_QUEUE_CNT  CPC_CMD_T_CNTBUF   // inquires the count of elements in the message queue
-#define CPC_CMD_T_INQ_ERR_COUNTER    25	                // request the CAN controllers error counter
-#define	CPC_CMD_T_CLEAR_MSG_QUEUE    CPC_CMD_T_CLEARBUF // clear CPC_MSG queue
-#define	CPC_CMD_T_CLEAR_CMD_QUEUE    28	                // clear CPC_CMD queue
-#define CPC_CMD_T_FIRMWARE          100                 // reserved, must not be used
-#define CPC_CMD_T_USB_RESET         101                 // reserved, must not be used
-#define CPC_CMD_T_WAIT_NOTIFY       102                 // reserved, must not be used
-#define CPC_CMD_T_WAIT_SETUP        103                 // reserved, must not be used
-#define	CPC_CMD_T_ABORT             255                 // Normally not to be used
-
-// definitions for CPC_MSG_T_INFO
-// information sources
-#define CPC_INFOMSG_T_UNKNOWN_SOURCE 0
-#define CPC_INFOMSG_T_INTERFACE      1
-#define CPC_INFOMSG_T_DRIVER         2
-#define CPC_INFOMSG_T_LIBRARY        3
-
-// information types
-#define CPC_INFOMSG_T_UNKNOWN_TYPE   0
-#define CPC_INFOMSG_T_VERSION        1
-#define CPC_INFOMSG_T_SERIAL         2
-
-// definitions for controller types
-#define PCA82C200   1 // Philips basic CAN controller, replaced by SJA1000
-#define SJA1000     2 // Philips basic CAN controller
-#define AN82527     3 // Intel full CAN controller
-#define M16C_BASIC  4 // M16C controller running in basic CAN (not full CAN) mode
-
-// channel open error codes
-#define CPC_ERR_NO_FREE_CHANNEL            -1	// no more free space within the channel array
-#define CPC_ERR_CHANNEL_ALREADY_OPEN       -2	// the channel is already open
-#define CPC_ERR_CHANNEL_NOT_ACTIVE         -3	// access to a channel not active failed
-#define CPC_ERR_NO_DRIVER_PRESENT          -4	// no driver at the location searched by the library
-#define CPC_ERR_NO_INIFILE_PRESENT         -5	// the library could not find the inifile
-#define CPC_ERR_WRONG_PARAMETERS           -6	// wrong parameters in the inifile
-#define CPC_ERR_NO_INTERFACE_PRESENT       -7	// 1. The specified interface is not connected
-						// 2. The interface (mostly CPC-USB) was disconnected upon operation
-#define CPC_ERR_NO_MATCHING_CHANNEL        -8	// the driver couldn't find a matching channel
-#define CPC_ERR_NO_BUFFER_AVAILABLE        -9	// the driver couldn't allocate buffer for messages
-#define CPC_ERR_NO_INTERRUPT               -10	// the requested interrupt couldn't be claimed
-#define CPC_ERR_NO_MATCHING_INTERFACE      -11	// no interface type related to this channel was found
-#define CPC_ERR_NO_RESOURCES               -12	// the requested resources could not be claimed
-#define CPC_ERR_SOCKET                     -13	// error concerning TCP sockets
-
-// init error codes
-#define CPC_ERR_WRONG_CONTROLLER_TYPE      -14	// wrong CAN controller type within initialization
-#define CPC_ERR_NO_RESET_MODE              -15	// the controller could not be set into reset mode
-#define CPC_ERR_NO_CAN_ACCESS              -16	// the CAN controller could not be accessed
-
-// transmit error codes
-#define CPC_ERR_CAN_WRONG_ID               -20	// the provided CAN id is too big
-#define CPC_ERR_CAN_WRONG_LENGTH           -21	// the provided CAN length is too long
-#define CPC_ERR_CAN_NO_TRANSMIT_BUF        -22	// the transmit buffer was occupied
-#define CPC_ERR_CAN_TRANSMIT_TIMEOUT       -23	// The message could not be sent within a
-						// specified time
-
-// other error codes
-#define CPC_ERR_SERVICE_NOT_SUPPORTED      -30	// the requested service is not supported by the interface
-#define CPC_ERR_IO_TRANSFER                -31	// a transmission error down to the driver occurred
-#define CPC_ERR_TRANSMISSION_FAILED        -32	// a transmission error down to the interface occurred
-#define CPC_ERR_TRANSMISSION_TIMEOUT       -33	// a timeout occurred within transmission to the interface
-#define CPC_ERR_OP_SYS_NOT_SUPPORTED       -35	// the operating system is not supported
-#define CPC_ERR_UNKNOWN                    -40	// an unknown error ocurred (mostly IOCTL errors)
-
-#define CPC_ERR_LOADING_DLL                -50	// the library 'cpcwin.dll' could not be loaded
-#define CPC_ERR_ASSIGNING_FUNCTION         -51	// the specified function could not be assigned
-#define CPC_ERR_DLL_INITIALIZATION         -52	// the DLL was not initialized correctly
-#define CPC_ERR_MISSING_LICFILE            -55	// the file containing the licenses does not exist
-#define CPC_ERR_MISSING_LICENSE            -56	// a required license was not found
-
-// CAN state bit values. Ignore any bits not listed
-#define CPC_CAN_STATE_BUSOFF     0x80
-#define CPC_CAN_STATE_ERROR      0x40
-
-// Mask to help ignore undefined bits
-#define CPC_CAN_STATE_MASK       0xc0
-
-// CAN-Message representation in a CPC_MSG
-// Message object type is CPC_MSG_T_CAN or CPC_MSG_T_RTR
-// or CPC_MSG_T_XCAN or CPC_MSG_T_XRTR
-typedef struct CPC_CAN_MSG {
-	u32 id;
-	u8 length;
-	u8 msg[8];
-} CPC_CAN_MSG_T;
-
-
-// representation of the CAN parameters for the PCA82C200 controller
-typedef struct CPC_PCA82C200_PARAMS {
-	u8 acc_code;	// Acceptance-code for receive, Standard: 0
-	u8 acc_mask;	// Acceptance-mask for receive, Standard: 0xff (everything)
-	u8 btr0;	// Bus-timing register 0
-	u8 btr1;	// Bus-timing register 1
-	u8 outp_contr;	// Output-control register
-} CPC_PCA82C200_PARAMS_T;
-
-// representation of the CAN parameters for the SJA1000 controller
-typedef struct CPC_SJA1000_PARAMS {
-	u8 mode;	// enables single or dual acceptance filtering
-	u8 acc_code0;	// Acceptance-code for receive, Standard: 0
-	u8 acc_code1;
-	u8 acc_code2;
-	u8 acc_code3;
-	u8 acc_mask0;	// Acceptance-mask for receive, Standard: 0xff (everything)
-	u8 acc_mask1;
-	u8 acc_mask2;
-	u8 acc_mask3;
-	u8 btr0;	// Bus-timing register 0
-	u8 btr1;	// Bus-timing register 1
-	u8 outp_contr;	// Output-control register
-} CPC_SJA1000_PARAMS_T;
-
-// representation of the CAN parameters for the M16C controller
-// in basic CAN mode (means no full CAN)
-typedef struct CPC_M16C_BASIC_PARAMS {
-	u8 con0;
-	u8 con1;
-	u8 ctlr0;
-	u8 ctlr1;
-	u8 clk;
-	u8 acc_std_code0;
-	u8 acc_std_code1;
-	u8 acc_ext_code0;
-	u8 acc_ext_code1;
-	u8 acc_ext_code2;
-	u8 acc_ext_code3;
-	u8 acc_std_mask0;
-	u8 acc_std_mask1;
-	u8 acc_ext_mask0;
-	u8 acc_ext_mask1;
-	u8 acc_ext_mask2;
-	u8 acc_ext_mask3;
-} CPC_M16C_BASIC_PARAMS_T;
-
-// CAN params message representation
-typedef struct CPC_CAN_PARAMS {
-	u8 cc_type;	// represents the controller type
-	union {
-		CPC_M16C_BASIC_PARAMS_T m16c_basic;
-		CPC_SJA1000_PARAMS_T sja1000;
-		CPC_PCA82C200_PARAMS_T pca82c200;
-	} cc_params;
-} CPC_CAN_PARAMS_T;
-
-// the following structures are slightly different for Windows and Linux
-// To be able to use the 'Select' mechanism with Linux the application
-// needs to know the devices file desciptor.
-// This mechanism is not implemented within Windows and the file descriptor
-// is therefore not needed
-#ifdef _WIN32
-
-// CAN init params message representation
-typedef struct CPC_INIT_PARAMS {
-	CPC_CAN_PARAMS_T canparams;
-} CPC_INIT_PARAMS_T;
-
-#else// Linux
-
-// CHAN init params representation
-typedef struct CPC_CHAN_PARAMS {
-	int fd;
-} CPC_CHAN_PARAMS_T;
-
-// CAN init params message representation
-typedef struct CPC_INIT_PARAMS {
-	CPC_CHAN_PARAMS_T chanparams;
-	CPC_CAN_PARAMS_T canparams;
-} CPC_INIT_PARAMS_T;
-
-#endif
-
-// structure for confirmed message handling
-typedef struct CPC_CONFIRM {
-	u8 result; // error code
-} CPC_CONFIRM_T;
-
-// structure for information requests
-typedef struct CPC_INFO {
-	u8 source;                 // interface, driver or library
-	u8 type;                   // version or serial number
-	char msg[CPC_MSG_LEN - 2]; // string holding the requested information
-} CPC_INFO_T;
-
-// OVERRUN ///////////////////////////////////////
-// In general two types of overrun may occur.
-// A hardware overrun, where the CAN controller
-// lost a message, because the interrupt was
-// not handled before the next messgae comes in.
-// Or a software overrun, where i.e. a received
-// message could not be stored in the CPC_MSG
-// buffer.
-
-// After a software overrun has occurred
-// we wait until we have CPC_OVR_GAP slots
-// free in the CPC_MSG buffer.
-#define CPC_OVR_GAP               10
-
-// Two types of software overrun may occur.
-// A received CAN message or a CAN state event
-// can cause an overrun.
-// Note: A CPC_CMD which would normally store
-// its result immediately in the CPC_MSG
-// queue may fail, because the message queue is full.
-// This will not generate an overrun message, but
-// will halt command execution, until this command
-// is able to store its message in the message queue.
-#define CPC_OVR_EVENT_CAN       0x01
-#define CPC_OVR_EVENT_CANSTATE  0x02
-#define CPC_OVR_EVENT_BUSERROR  0x04
-
-// If the CAN controller lost a message
-// we indicate it with the highest bit
-// set in the count field.
-#define CPC_OVR_HW              0x80
-
-// structure for overrun conditions
-typedef struct {
-	u8 event;
-	u8 count;
-} CPC_OVERRUN_T;
-
-// CAN errors ////////////////////////////////////
-// Each CAN controller type has different
-// registers to record errors.
-// Therefor a structure containing the specific
-// errors is set up for each controller here
-
-// SJA1000 error structure
-// see the SJA1000 datasheet for detailed
-// explanation of the registers
-typedef struct CPC_SJA1000_CAN_ERROR {
-	u8 ecc;   // error capture code register
-	u8 rxerr; // RX error counter register
-	u8 txerr; // TX error counter register
-} CPC_SJA1000_CAN_ERROR_T;
-
-// M16C error structure
-// see the M16C datasheet for detailed
-// explanation of the registers
-typedef struct CPC_M16C_CAN_ERROR {
-	u8 tbd;	// to be defined
-} CPC_M16C_CAN_ERROR_T;
-
-// structure for CAN error conditions
-#define  CPC_CAN_ECODE_ERRFRAME   0x01
-typedef struct CPC_CAN_ERROR {
-	u8 ecode;
-	struct {
-		u8 cc_type; // CAN controller type
-		union {
-			CPC_SJA1000_CAN_ERROR_T sja1000;
-			CPC_M16C_CAN_ERROR_T m16c;
-		} regs;
-	} cc;
-} CPC_CAN_ERROR_T;
-
-// Structure containing RX/TX error counter.
-// This structure is used to request the
-// values of the CAN controllers TX and RX
-// error counter.
-typedef struct CPC_CAN_ERR_COUNTER {
-	u8 rx;
-	u8 tx;
-} CPC_CAN_ERR_COUNTER_T;
-
-// If this flag is set, transmissions from PC to CPC are protected against loss
-#define CPC_SECURE_TO_CPC	0x01
-
-// If this flag is set, transmissions from CPC to PC are protected against loss
-#define CPC_SECURE_TO_PC	0x02
-
-// If this flag is set, the CAN-transmit buffer is checked to be free before sending a message
-#define CPC_SECURE_SEND		0x04
-
-// If this flag is set, the transmission complete flag is checked
-// after sending a message
-// THIS IS CURRENTLY ONLY IMPLEMENTED IN THE PASSIVE INTERFACE DRIVERS
-#define CPC_SECURE_TRANSMIT	0x08
-
-// main message type used between library and application
-typedef struct CPC_MSG {
-	u8 type;	// type of message
-	u8 length;	// length of data within union 'msg'
-	u8 msgid;	// confirmation handle
-	u32 ts_sec;	// timestamp in seconds
-	u32 ts_nsec;	// timestamp in nano seconds
-	union {
-		u8 generic[CPC_MSG_LEN];
-		CPC_CAN_MSG_T canmsg;
-		CPC_CAN_PARAMS_T canparams;
-		CPC_CONFIRM_T confirmation;
-		CPC_INFO_T info;
-		CPC_OVERRUN_T overrun;
-		CPC_CAN_ERROR_T error;
-		CPC_CAN_ERR_COUNTER_T err_counter;
-		u8 busload;
-		u8 canstate;
-	} msg;
-} CPC_MSG_T;
-
-#ifdef _WIN32
-#pragma pack(pop)		// reset the byte alignment
-#endif
-
-#endif				// CPC_HEADER
diff --git a/drivers/staging/cpc-usb/cpc_int.h b/drivers/staging/cpc-usb/cpc_int.h
deleted file mode 100644
index a0d60c0..0000000
--- a/drivers/staging/cpc-usb/cpc_int.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * CPCLIB
- *
- * Copyright (C) 2000-2008 EMS Dr. Thomas Wuensche
- *
- * 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.
- *
- */
-#ifndef CPC_INT_H
-#define CPC_INT_H
-
-#include <linux/wait.h>
-
-#define CPC_MSG_BUF_CNT	1500
-
-#define CPC_PROC_DIR "driver/"
-
-#undef dbg
-#undef err
-#undef info
-
-/* Use our own dbg macro */
-#define dbg(format, arg...) do { if (debug) printk( KERN_INFO format "\n" , ## arg); } while (0)
-#define err(format, arg...) do { printk( KERN_INFO "ERROR " format "\n" , ## arg); } while (0)
-#define info(format, arg...) do { printk( KERN_INFO format "\n" , ## arg); } while (0)
-
-/* Macros help using of our buffers */
-#define IsBufferFull(x)     (!(x)->WnR) && ((x)->iidx == (x)->oidx)
-#define IsBufferEmpty(x)    ((x)->WnR) && ((x)->iidx == (x)->oidx)
-#define IsBufferNotEmpty(x) (!(x)->WnR) || ((x)->iidx != (x)->oidx)
-#define ResetBuffer(x)      do { (x)->oidx = (x)->iidx=0; (x)->WnR = 1; } while(0);
-
-#define CPC_BufWriteAllowed ((chan->oidx != chan->iidx) || chan->WnR)
-
-typedef void (*chan_write_byte_t) (void *chan, unsigned int reg,
-				   unsigned char val);
-typedef unsigned char (*chan_read_byte_t) (void *chan, unsigned int reg);
-
-typedef struct CPC_CHAN {
-	void __iomem * canBase;	// base address of SJA1000
-	chan_read_byte_t read_byte;	// CAN controller read access routine
-	chan_write_byte_t write_byte;	// CAN controller write access routine
-	CPC_MSG_T *buf;		// buffer for CPC msg
-	unsigned int iidx;
-	unsigned int oidx;
-	unsigned int WnR;
-	unsigned int minor;
-	unsigned int locked;
-	unsigned int irqDisabled;
-
-	unsigned char cpcCtrlCANMessage;
-	unsigned char cpcCtrlCANState;
-	unsigned char cpcCtrlBUSState;
-
-	unsigned char controllerType;
-
-	unsigned long ovrTimeSec;
-	unsigned long ovrTimeNSec;
-	unsigned long ovrLockedBuffer;
-	CPC_OVERRUN_T ovr;
-
-	/* for debugging only */
-	unsigned int handledIrqs;
-	unsigned int lostMessages;
-
-	unsigned int sentStdCan;
-	unsigned int sentExtCan;
-	unsigned int sentStdRtr;
-	unsigned int sentExtRtr;
-
-	unsigned int recvStdCan;
-	unsigned int recvExtCan;
-	unsigned int recvStdRtr;
-	unsigned int recvExtRtr;
-
-	wait_queue_head_t *CPCWait_q;
-
-	void *private;
-} CPC_CHAN_T;
-
-#endif
diff --git a/drivers/staging/cpc-usb/cpcusb.h b/drivers/staging/cpc-usb/cpcusb.h
deleted file mode 100644
index e5273dd..0000000
--- a/drivers/staging/cpc-usb/cpcusb.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Header for CPC-USB Driver ********************
- * Copyright 1999, 2000, 2001
- *
- * Company:  EMS Dr. Thomas Wuensche
- *           Sonnenhang 3
- *           85304 Ilmmuenster
- *           Phone: +49-8441-490260
- *           Fax:   +49-8441-81860
- *           email: support-zsNKPWJ8Pib6hrUXjxyGrA@public.gmane.org
- *           WWW:   www.ems-wuensche.com
- */
-
-#ifndef CPCUSB_H
-#define CPCUSB_H
-
-#undef err
-#undef dbg
-#undef info
-
-/* Use our own dbg macro */
-#define dbg(format, arg...) do { if (debug) printk(KERN_INFO "CPC-USB: " format "\n" , ## arg); } while (0)
-#define info(format, arg...) do { printk(KERN_INFO "CPC-USB: " format "\n" , ## arg); } while (0)
-#define err(format, arg...) do { printk(KERN_INFO "CPC-USB(ERROR): " format "\n" , ## arg); } while (0)
-
-#define CPC_USB_CARD_CNT      4
-
-typedef struct CPC_USB_READ_URB {
-	unsigned char *buffer;	/* the buffer to send data */
-	size_t size;		/* the size of the send buffer */
-	struct urb *urb;	/* the urb used to send data */
-} CPC_USB_READ_URB_T;
-
-typedef struct CPC_USB_WRITE_URB {
-	unsigned char *buffer;	/* the buffer to send data */
-	size_t size;		/* the size of the send buffer */
-	struct urb *urb;	/* the urb used to send data */
-	atomic_t busy;		/* true if write urb is busy */
-	struct completion finished;	/* wait for the write to finish */
-} CPC_USB_WRITE_URB_T;
-
-#define CPC_USB_URB_CNT  10
-
-typedef struct CPC_USB {
-	struct usb_device *udev;	/* save off the usb device pointer */
-	struct usb_interface *interface;	/* the interface for this device */
-	unsigned char minor;	/* the starting minor number for this device */
-	unsigned char num_ports;	/* the number of ports this device has */
-	int num_intr_in;	/* number of interrupt in endpoints we have */
-	int num_bulk_in;	/* number of bulk in endpoints we have */
-	int num_bulk_out;	/* number of bulk out endpoints we have */
-
-	CPC_USB_READ_URB_T urbs[CPC_USB_URB_CNT];
-
-	unsigned char intr_in_buffer[4];	/* interrupt transfer buffer */
-	struct urb *intr_in_urb;	/* interrupt transfer urb */
-
-	CPC_USB_WRITE_URB_T wrUrbs[CPC_USB_URB_CNT];
-
-	int open;		/* if the port is open or not */
-	int present;		/* if the device is not disconnected */
-	struct semaphore sem;	/* locks this structure */
-
-	int free_slots;		/* free send slots of CPC-USB */
-	int idx;
-
-	spinlock_t slock;
-
-	char serialNumber[128];	/* serial number */
-	int productId;		/* product id to differ between M16C and LPC2119 */
-	CPC_CHAN_T *chan;
-} CPC_USB_T;
-
-#define CPCTable               CPCUSB_Table
-
-#define CPC_DRIVER_VERSION "0.724"
-#define CPC_DRIVER_SERIAL  "not applicable"
-
-#define OBUF_SIZE 255		// 4096
-
-/* read timeouts -- RD_NAK_TIMEOUT * RD_EXPIRE = Number of seconds */
-#define RD_NAK_TIMEOUT (10*HZ)	/* Default number of X seconds to wait */
-#define RD_EXPIRE 12		/* Number of attempts to wait X seconds */
-
-#define CPC_USB_BASE_MNR 0	/* CPC-USB start at minor 0  */
-
-#endif
diff --git a/drivers/staging/cpc-usb/sja2m16c.h b/drivers/staging/cpc-usb/sja2m16c.h
deleted file mode 100644
index 654bd3f..0000000
--- a/drivers/staging/cpc-usb/sja2m16c.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef _SJA2M16C_H
-#define _SJA2M16C_H
-
-#include "cpc.h"
-
-#define BAUDRATE_TOLERANCE_PERCENT	1
-#define SAMPLEPOINT_TOLERANCE_PERCENT	5
-#define SAMPLEPOINT_UPPER_LIMIT		88
-
-/* M16C parameters */
-struct FIELD_C0CONR {
-	unsigned int brp:4;
-	unsigned int sam:1;
-	unsigned int pr:3;
-	unsigned int dummy:8;
-};
-struct FIELD_C1CONR {
-	unsigned int ph1:3;
-	unsigned int ph2:3;
-	unsigned int sjw:2;
-	unsigned int dummy:8;
-};
-typedef union C0CONR {
-	unsigned char c0con;
-	struct FIELD_C0CONR bc0con;
-} C0CONR_T;
-typedef union C1CONR {
-	unsigned char c1con;
-	struct FIELD_C1CONR bc1con;
-} C1CONR_T;
-
-#define SJA_TSEG1	((pParams->btr1 & 0x0f)+1)
-#define SJA_TSEG2	(((pParams->btr1 & 0x70)>>4)+1)
-#define SJA_BRP		((pParams->btr0 & 0x3f)+1)
-#define SJA_SJW		((pParams->btr0 & 0xc0)>>6)
-#define SJA_SAM		((pParams->btr1 & 0x80)>>7)
-int baudrate_m16c(int clk, int brp, int pr, int ph1, int ph2);
-int samplepoint_m16c(int brp, int pr, int ph1, int ph2);
-int SJA1000_TO_M16C_BASIC_Params(CPC_MSG_T *pMsg);
-
-#endif
diff --git a/drivers/staging/cpc-usb/sja2m16c_2.c b/drivers/staging/cpc-usb/sja2m16c_2.c
deleted file mode 100644
index bf0230f..0000000
--- a/drivers/staging/cpc-usb/sja2m16c_2.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/****************************************************************************
-*
-*      Copyright (c) 2003,2004 by EMS Dr. Thomas Wuensche
-*
-*                  - All rights reserved -
-*
-* This code is provided "as is" without warranty of any kind, either
-* expressed or implied, including but not limited to the liability
-* concerning the freedom from material defects, the fitness for parti-
-* cular purposes or the freedom of proprietary rights of third parties.
-*
-*****************************************************************************
-* Module name.: cpcusb
-*****************************************************************************
-* Include file: cpc.h
-*****************************************************************************
-* Project.....: Windows Driver Development Kit
-* Filename....: sja2m16c.cpp
-* Authors.....: (GU) Gerhard Uttenthaler
-*               (CS) Christian Schoett
-*****************************************************************************
-* Short descr.: converts baudrate between SJA1000 and M16C
-*****************************************************************************
-* Description.: handles the baudrate conversion from SJA1000 parameters to
-*               M16C parameters
-*****************************************************************************
-* Address     : EMS Dr. Thomas Wuensche
-*               Sonnenhang 3
-*               D-85304 Ilmmuenster
-*               Tel. : +49-8441-490260
-*               Fax. : +49-8441-81860
-*               email: support-zsNKPWJ8Pib6hrUXjxyGrA@public.gmane.org
-*****************************************************************************
-*                            History
-*****************************************************************************
-* Version  Date        Auth Remark
-*
-* 01.00    ??          GU   - initial release
-* 01.10    ??????????  CS   - adapted to fit into the USB Windows driver
-* 02.00    18.08.2004  GU   - improved the baudrate calculating algorithm
-*                           - implemented acceptance filtering
-* 02.10    10.09.2004  CS   - adapted to fit into the USB Windows driver
-*****************************************************************************
-*                            ToDo's
-*****************************************************************************
-*/
-
-/****************************************************************************/
-/*     I N C L U D E S
-*/
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-#include <linux/poll.h>
-#include <linux/smp_lock.h>
-#include <linux/completion.h>
-#include <asm/uaccess.h>
-#include <linux/usb.h>
-
-#include "cpc.h"
-#include "cpc_int.h"
-#include "cpcusb.h"
-
-#include "sja2m16c.h"
-
-/*********************************************************************/
-int baudrate_m16c(int clk, int brp, int pr, int ph1, int ph2)
-{
-	return (16000000 / (1 << clk)) / 2 / (brp + 1) / (1 + pr + 1 +
-							    ph1 + 1 + ph2 +
-							    1);
-}
-
-
-/*********************************************************************/
-int samplepoint_m16c(int brp, int pr, int ph1, int ph2)
-{
-	return (100 * (1 + pr + 1 + ph1 + 1)) / (1 + pr + 1 + ph1 + 1 +
-						  ph2 + 1);
-}
-
-
-/****************************************************************************
-* Function.....: SJA1000_TO_M16C_BASIC_Params
-*
-* Task.........: This routine converts SJA1000 CAN btr parameters into M16C
-*                parameters based on the sample point and the error. In
-*                addition it converts the acceptance filter parameters to
-*                suit the M16C parameters
-*
-* Parameters...: None
-*
-* Return values: None
-*
-* Comments.....:
-*****************************************************************************
-*                History
-*****************************************************************************
-* 19.01.2005  CS   - modifed the conversion of SJA1000 filter params into
-*                    M16C params. Due to compatibility reasons with the
-*                    older 82C200 CAN controller the SJA1000
-****************************************************************************/
-int SJA1000_TO_M16C_BASIC_Params(CPC_MSG_T * in)
-{
-	int sjaBaudrate;
-	int sjaSamplepoint;
-	int *baudrate_error;	// BRP[0..15], PR[0..7], PH1[0..7], PH2[0..7]
-	int *samplepoint_error;	// BRP[0..15], PR[0..7], PH1[0..7], PH2[0..7]
-	int baudrate_error_merk;
-	int clk, brp, pr, ph1, ph2;
-	int clk_merk, brp_merk, pr_merk, ph1_merk, ph2_merk;
-	int index;
-	unsigned char acc_code0, acc_code1, acc_code2, acc_code3;
-	unsigned char acc_mask0, acc_mask1, acc_mask2, acc_mask3;
-	CPC_MSG_T * out;
-	C0CONR_T c0con;
-	C1CONR_T c1con;
-	int tmpAccCode;
-	int tmpAccMask;
-
-	    // we have to convert the parameters into M16C parameters
-	    CPC_SJA1000_PARAMS_T * pParams;
-
-	    // check if the type is CAN parameters and if we have to convert the given params
-	    if (in->type != CPC_CMD_T_CAN_PRMS
-		|| in->msg.canparams.cc_type != SJA1000)
-		return 0;
-	pParams =
-	    (CPC_SJA1000_PARAMS_T *) & in->msg.canparams.cc_params.sja1000;
-	acc_code0 = pParams->acc_code0;
-	acc_code1 = pParams->acc_code1;
-	acc_code2 = pParams->acc_code2;
-	acc_code3 = pParams->acc_code3;
-	acc_mask0 = pParams->acc_mask0;
-	acc_mask1 = pParams->acc_mask1;
-	acc_mask2 = pParams->acc_mask2;
-	acc_mask3 = pParams->acc_mask3;
-
-#ifdef _DEBUG_OUTPUT_CAN_PARAMS
-	    info("acc_code0: %2.2Xh\n", acc_code0);
-	info("acc_code1: %2.2Xh\n", acc_code1);
-	info("acc_code2: %2.2Xh\n", acc_code2);
-	info("acc_code3: %2.2Xh\n", acc_code3);
-	info("acc_mask0: %2.2Xh\n", acc_mask0);
-	info("acc_mask1: %2.2Xh\n", acc_mask1);
-	info("acc_mask2: %2.2Xh\n", acc_mask2);
-	info("acc_mask3: %2.2Xh\n", acc_mask3);
-
-#endif	/*  */
-	    if (!
-		 (baudrate_error =
-		  (int *) vmalloc(sizeof(int) * 16 * 8 * 8 * 8 * 5))) {
-		err("Could not allocate memory\n");
-		return -3;
-	}
-	if (!
-	      (samplepoint_error =
-	       (int *) vmalloc(sizeof(int) * 16 * 8 * 8 * 8 * 5))) {
-		err("Could not allocate memory\n");
-		vfree(baudrate_error);
-		return -3;
-	}
-	memset(baudrate_error, 0xff, sizeof(baudrate_error));
-	memset(samplepoint_error, 0xff, sizeof(baudrate_error));
-	sjaBaudrate =
-	    16000000 / 2 / SJA_BRP / (1 + SJA_TSEG1 + SJA_TSEG2);
-	sjaSamplepoint =
-	    100 * (1 + SJA_TSEG1) / (1 + SJA_TSEG1 + SJA_TSEG2);
-	if (sjaBaudrate == 0) {
-		vfree(baudrate_error);
-		vfree(samplepoint_error);
-		return -2;
-	}
-
-#ifdef _DEBUG_OUTPUT_CAN_PARAMS
-	    info("\nStarting SJA CAN params\n");
-	info("-------------------------\n");
-	info("TS1     : %2.2Xh TS2 : %2.2Xh\n", SJA_TSEG1, SJA_TSEG2);
-	info("BTR0    : %2.2Xh BTR1: %2.2Xh\n", pParams->btr0,
-	      pParams->btr1);
-	info("Baudrate: %d.%dkBaud\n", sjaBaudrate / 1000,
-	      sjaBaudrate % 1000);
-	info("Sample P: 0.%d\n", sjaSamplepoint);
-	info("\n");
-
-#endif	/*  */
-	    c0con.bc0con.sam = SJA_SAM;
-	c1con.bc1con.sjw = SJA_SJW;
-
-	    // calculate errors for all baudrates
-	    index = 0;
-	for (clk = 0; clk < 5; clk++) {
-		for (brp = 0; brp < 16; brp++) {
-			for (pr = 0; pr < 8; pr++) {
-				for (ph1 = 0; ph1 < 8; ph1++) {
-					for (ph2 = 0; ph2 < 8; ph2++) {
-						baudrate_error[index] =
-						    100 *
-						    abs(baudrate_m16c
-							(clk, brp, pr, ph1,
-							 ph2) -
-							sjaBaudrate) /
-						    sjaBaudrate;
-						samplepoint_error[index] =
-						    abs(samplepoint_m16c
-							(brp, pr, ph1,
-							 ph2) -
-							sjaSamplepoint);
-
-#if 0
-						    info
-						    ("Baudrate      : %d kBaud\n",
-						     baudrate_m16c(clk,
-								   brp, pr,
-								   ph1,
-								   ph2));
-						info
-						    ("Baudrate Error: %d\n",
-						     baudrate_error
-						     [index]);
-						info
-						    ("Sample P Error: %d\n",
-						     samplepoint_error
-						     [index]);
-						info
-						    ("clk           : %d\n",
-						     clk);
-
-#endif	/*  */
-						    index++;
-					}
-				}
-			}
-		}
-	}
-
-	    // mark all baudrate_error entries which are outer limits
-	    index = 0;
-	for (clk = 0; clk < 5; clk++) {
-		for (brp = 0; brp < 16; brp++) {
-			for (pr = 0; pr < 8; pr++) {
-				for (ph1 = 0; ph1 < 8; ph1++) {
-					for (ph2 = 0; ph2 < 8; ph2++) {
-						if ((baudrate_error[index]
-						      >
-						      BAUDRATE_TOLERANCE_PERCENT)
-						     ||
-						     (samplepoint_error
-						       [index] >
-						       SAMPLEPOINT_TOLERANCE_PERCENT)
-						     ||
-						     (samplepoint_m16c
-						       (brp, pr, ph1,
-							ph2) >
-						       SAMPLEPOINT_UPPER_LIMIT))
-						{
-							baudrate_error
-							    [index] = -1;
-						} else
-						    if (((1 + pr + 1 +
-							  ph1 + 1 + ph2 +
-							  1) < 8)
-							||
-							((1 + pr + 1 +
-							  ph1 + 1 + ph2 +
-							  1) > 25)) {
-							baudrate_error
-							    [index] = -1;
-						}
-
-#if 0
-						    else {
-							info
-							    ("Baudrate      : %d kBaud\n",
-							     baudrate_m16c
-							     (clk, brp, pr,
-							      ph1, ph2));
-							info
-							    ("Baudrate Error: %d\n",
-							     baudrate_error
-							     [index]);
-							info
-							    ("Sample P Error: %d\n",
-							     samplepoint_error
-							     [index]);
-						}
-
-#endif	/*  */
-						    index++;
-					}
-				}
-			}
-		}
-	}
-
-	    // find list of minimum of baudrate_error within unmarked entries
-	    clk_merk = brp_merk = pr_merk = ph1_merk = ph2_merk = 0;
-	baudrate_error_merk = 100;
-	index = 0;
-	for (clk = 0; clk < 5; clk++) {
-		for (brp = 0; brp < 16; brp++) {
-			for (pr = 0; pr < 8; pr++) {
-				for (ph1 = 0; ph1 < 8; ph1++) {
-					for (ph2 = 0; ph2 < 8; ph2++) {
-						if (baudrate_error[index]
-						     != -1) {
-							if (baudrate_error
-							     [index] <
-							     baudrate_error_merk)
-							{
-								baudrate_error_merk
-								    =
-								    baudrate_error
-								    [index];
-								brp_merk =
-								    brp;
-								pr_merk =
-								    pr;
-								ph1_merk =
-								    ph1;
-								ph2_merk =
-								    ph2;
-								clk_merk =
-								    clk;
-
-#if 0
-								    info
-								    ("brp: %2.2Xh pr: %2.2Xh ph1: %2.2Xh ph2: %2.2Xh\n",
-								     brp,
-								     pr,
-								     ph1,
-								     ph2);
-								info
-								    ("Baudrate      : %d kBaud\n",
-								     baudrate_m16c
-								     (clk,
-								      brp,
-								      pr,
-								      ph1,
-								      ph2));
-								info
-								    ("Baudrate Error: %d\n",
-								     baudrate_error
-								     [index]);
-								info
-								    ("Sample P Error: %d\n",
-								     samplepoint_error
-								     [index]);
-
-#endif	/*  */
-							}
-						}
-						index++;
-					}
-				}
-			}
-		}
-	}
-	if (baudrate_error_merk == 100) {
-		info("ERROR: Could not convert CAN init parameter\n");
-		vfree(baudrate_error);
-		vfree(samplepoint_error);
-		return -1;
-	}
-
-	    // setting m16c CAN parameter
-	    c0con.bc0con.brp = brp_merk;
-	c0con.bc0con.pr = pr_merk;
-	c1con.bc1con.ph1 = ph1_merk;
-	c1con.bc1con.ph2 = ph2_merk;
-
-#ifdef _DEBUG_OUTPUT_CAN_PARAMS
-	    info("\nResulting M16C CAN params\n");
-	info("-------------------------\n");
-	info("clk     : %2.2Xh\n", clk_merk);
-	info("ph1     : %2.2Xh ph2: %2.2Xh\n", c1con.bc1con.ph1 + 1,
-	      c1con.bc1con.ph2 + 1);
-	info("pr      : %2.2Xh brp: %2.2Xh\n", c0con.bc0con.pr + 1,
-	      c0con.bc0con.brp + 1);
-	info("sjw     : %2.2Xh sam: %2.2Xh\n", c1con.bc1con.sjw,
-	      c0con.bc0con.sam);
-	info("co1     : %2.2Xh co0: %2.2Xh\n", c1con.c1con, c0con.c0con);
-	info("Baudrate: %d.%dBaud\n",
-	       baudrate_m16c(clk_merk, c0con.bc0con.brp, c0con.bc0con.pr,
-			     c1con.bc1con.ph1, c1con.bc1con.ph2) / 1000,
-	       baudrate_m16c(clk_merk, c0con.bc0con.brp, c0con.bc0con.pr,
-			      c1con.bc1con.ph1, c1con.bc1con.ph2) % 1000);
-	info("Sample P: 0.%d\n",
-	      samplepoint_m16c(c0con.bc0con.brp, c0con.bc0con.pr,
-			       c1con.bc1con.ph1, c1con.bc1con.ph2));
-	info("\n");
-
-#endif	/*  */
-	    out = in;
-	out->type = 6;
-	out->length = sizeof(CPC_M16C_BASIC_PARAMS_T) + 1;
-	out->msg.canparams.cc_type = M16C_BASIC;
-	out->msg.canparams.cc_params.m16c_basic.con0 = c0con.c0con;
-	out->msg.canparams.cc_params.m16c_basic.con1 = c1con.c1con;
-	out->msg.canparams.cc_params.m16c_basic.ctlr0 = 0x4C;
-	out->msg.canparams.cc_params.m16c_basic.ctlr1 = 0x00;
-	out->msg.canparams.cc_params.m16c_basic.clk = clk_merk;
-	out->msg.canparams.cc_params.m16c_basic.acc_std_code0 =
-	    acc_code0;
-	out->msg.canparams.cc_params.m16c_basic.acc_std_code1 = acc_code1;
-
-//      info("code0: 0x%2.2X, code1: 0x%2.2X\n", out->msg.canparams.cc_params.m16c_basic.acc_std_code0, out->msg.canparams.cc_params.m16c_basic.acc_std_code1);
-	    tmpAccCode = (acc_code1 >> 5) + (acc_code0 << 3);
-	out->msg.canparams.cc_params.m16c_basic.acc_std_code0 =
-	    (unsigned char) tmpAccCode;
-	out->msg.canparams.cc_params.m16c_basic.acc_std_code1 =
-	    (unsigned char) (tmpAccCode >> 8);
-
-//      info("code0: 0x%2.2X, code1: 0x%2.2X\n", out->msg.canparams.cc_params.m16c_basic.acc_std_code0, out->msg.canparams.cc_params.m16c_basic.acc_std_code1);
-	    out->msg.canparams.cc_params.m16c_basic.acc_std_mask0 =
-	    ~acc_mask0;
-	out->msg.canparams.cc_params.m16c_basic.acc_std_mask1 =
-	    ~acc_mask1;
-
-//      info("mask0: 0x%2.2X, mask1: 0x%2.2X\n", out->msg.canparams.cc_params.m16c_basic.acc_std_mask0, out->msg.canparams.cc_params.m16c_basic.acc_std_mask1);
-	    tmpAccMask = ((acc_mask1) >> 5) + ((acc_mask0) << 3);
-
-//      info("tmpAccMask: 0x%4.4X\n", tmpAccMask);
-	    out->msg.canparams.cc_params.m16c_basic.acc_std_mask0 =
-	    (unsigned char) ~tmpAccMask;
-	out->msg.canparams.cc_params.m16c_basic.acc_std_mask1 =
-	    (unsigned char) ~(tmpAccMask >> 8);
-
-//      info("mask0: 0x%2.2X, mask1: 0x%2.2X\n", out->msg.canparams.cc_params.m16c_basic.acc_std_mask0, out->msg.canparams.cc_params.m16c_basic.acc_std_mask1);
-	    out->msg.canparams.cc_params.m16c_basic.acc_ext_code0 =
-	    (unsigned char) tmpAccCode;
-	out->msg.canparams.cc_params.m16c_basic.acc_ext_code1 =
-	    (unsigned char) (tmpAccCode >> 8);
-	out->msg.canparams.cc_params.m16c_basic.acc_ext_code2 = acc_code2;
-	out->msg.canparams.cc_params.m16c_basic.acc_ext_code3 = acc_code3;
-	out->msg.canparams.cc_params.m16c_basic.acc_ext_mask0 =
-	    (unsigned char) ~tmpAccMask;
-	out->msg.canparams.cc_params.m16c_basic.acc_ext_mask1 =
-	    (unsigned char) ~(tmpAccMask >> 8);
-	out->msg.canparams.cc_params.m16c_basic.acc_ext_mask2 =
-	    ~acc_mask2;
-	out->msg.canparams.cc_params.m16c_basic.acc_ext_mask3 =
-	    ~acc_mask3;
-	vfree(baudrate_error);
-	vfree(samplepoint_error);
-	return 0;
-}
-
-

-- 
EMS Dr. Thomas Wuensche e.K.
Sonnenhang 3
85304 Ilmmuenster
HRA Neuburg a.d. Donau, HR-Nr. 70.106
Phone: +49-8441-490260
Fax  : +49-8441-81860
http://www.ems-wuensche.com

^ permalink raw reply related

* [PATCH V3 0/2 -next] ems_usb: Added support for EMS CPC-USB/ARM7 CAN interface
From: Sebastian Haas @ 2009-09-16 12:04 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	greg-U8xfFu+wG4EAvxtiuMwx3w, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	wg-5Yr1BZd7O62+XT7JhA+gdA

The following series replaces the staging driver cpc-usb with the newly written
ems_usb CAN driver.

---

Sebastian Haas (2):
      ems_usb: Added support for EMS CPC-USB/ARM7 CAN/USB interface
      cpc-usb: Removed driver from staging tree


 drivers/net/can/Kconfig               |    7 
 drivers/net/can/Makefile              |    2 
 drivers/net/can/usb/Makefile          |    5 
 drivers/net/can/usb/ems_usb.c         | 1151 ++++++++++++++++++++++++++++++++
 drivers/staging/Kconfig               |    2 
 drivers/staging/Makefile              |    1 
 drivers/staging/cpc-usb/Kconfig       |    4 
 drivers/staging/cpc-usb/Makefile      |    3 
 drivers/staging/cpc-usb/TODO          |    9 
 drivers/staging/cpc-usb/cpc-usb_drv.c | 1185 ---------------------------------
 drivers/staging/cpc-usb/cpc.h         |  440 ------------
 drivers/staging/cpc-usb/cpc_int.h     |   83 --
 drivers/staging/cpc-usb/cpcusb.h      |   86 --
 drivers/staging/cpc-usb/sja2m16c.h    |   41 -
 drivers/staging/cpc-usb/sja2m16c_2.c  |  452 -------------
 15 files changed, 1165 insertions(+), 2306 deletions(-)
 create mode 100644 drivers/net/can/usb/Makefile
 create mode 100644 drivers/net/can/usb/ems_usb.c
 delete mode 100644 drivers/staging/cpc-usb/Kconfig
 delete mode 100644 drivers/staging/cpc-usb/Makefile
 delete mode 100644 drivers/staging/cpc-usb/TODO
 delete mode 100644 drivers/staging/cpc-usb/cpc-usb_drv.c
 delete mode 100644 drivers/staging/cpc-usb/cpc.h
 delete mode 100644 drivers/staging/cpc-usb/cpc_int.h
 delete mode 100644 drivers/staging/cpc-usb/cpcusb.h
 delete mode 100644 drivers/staging/cpc-usb/sja2m16c.h
 delete mode 100644 drivers/staging/cpc-usb/sja2m16c_2.c

-- 
Cheers, Sebastian
-- 
EMS Dr. Thomas Wuensche e.K.
Sonnenhang 3
85304 Ilmmuenster
HRA Neuburg a.d. Donau, HR-Nr. 70.106
Phone: +49-8441-490260
Fax  : +49-8441-81860
http://www.ems-wuensche.com

^ permalink raw reply

* Re: fanotify as syscalls
From: Alan Cox @ 2009-09-16 12:01 UTC (permalink / raw)
  To: Jamie Lokier
  Cc: Alan Cox, Eric Paris, Linus Torvalds, Evgeniy Polyakov,
	David Miller, linux-kernel, linux-fsdevel, netdev, viro, hch
In-Reply-To: <20090916114107.GB29359@shareable.org>

> You can't rely on the name being non-racy, but you _can_ reliably
> invalidate application-level caches from the sequence of events
> including file writes, creates, renames, links, unlinks, mounts.  And
> revalidate such caches by the absence of pending events.

You can't however create the caches reliably because you've no idea if
you are referencing the right object in the first place - which is why
you want a handle in these cases. I see fanotify as a handle producing
addition to inotify, not as a replacement (plus some other bits around
open blocking for HSM etc)

> Clearly, I'm going to have to explain with working code :-)

Always a good demo

> > but it is somewhat inadequate for indexers
> 
> For indexers, the real inadequacy is the need to attach inotify
> watches to every directory at system startup, and to stat() everything
> to check it hasn't changed since the indexer was last running.  Both

stat doesn't help you - inode numbers are only guaranteed unqiue (and
constant) while a reference to the object is held.

> Descriptors don't tell you which subtree a file is in any better than
> inotify watches.  I.e. they do, if you track them and their containing
> directories all individually.

Don't get me wrong - I don't think fanotify is sufficient on its own -
and this is one reason. Some things care about the namespace, some about
getting the exact content.

> > chroot isn't a security model. You can already do this with AF_UNIX
> > sockets (and there are apps that intentionally use fchdir that way)
> 
> Ah, no.  AF_UNIX works with explicit sender cooperation.
> 
> fanotify gives you access to files without sender cooperation, as it
> intercepts every open().

and is currently not general user accessible for this reason.

> > Inside of containers - unlikely.
> 
> Why not?  Some people run entire distributions in containiners, and
> present them as VMs to the world for other people to admin.

In a word - performance. In two words performance and security. It isn't
a sensible setup because you want to scan the most efficient way possible
and you want to keep your malware scan as far away from attackers, so it
makes sense to keep it outside of the containers and do the job once
- one scan, one database of things to keep current.

Alan

^ permalink raw reply

* Re: Fwd: [RFC v3] net: Introduce recvmmsg socket syscall
From: Arnaldo Carvalho de Melo @ 2009-09-16 11:52 UTC (permalink / raw)
  To: Simon Horman
  Cc: Arnaldo Carvalho de Melo, Nir Tzachar,
	Linux Networking Development Mailing List, Ziv Ayalon
In-Reply-To: <20090916045333.GA18325@verge.net.au>

Em Wed, Sep 16, 2009 at 02:53:44PM +1000, Simon Horman escreveu:
> On Tue, Sep 15, 2009 at 05:52:07PM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Tue, Sep 15, 2009 at 09:20:13PM +0300, Nir Tzachar escreveu:
> > > >> Setup:
> > > >> linux 2.6.29.2 with the third version of the patch, running on an
> > > >> Intel Xeon X3220 2.4GHz quad core, with 4Gbyte of ram, running Ubuntu
> > > >> 9.04
> > > >
> > > > Which NIC? 10 Gbit/s?
> > > 
> > > 1G. We do not care as much for throughput as we do about latency...
> > 
> > OK, but anyway the 10 Gbit/s cards I've briefly played with all
> > exhibited lower latencies than all 1 gbit/s ones, in fact I've heard
> > about people moving to 10 Gbit/s not for the bw, but for the lower
> > latencies :-)
> 
> Hi Arnaldo,
> 
> Out of curiosity, is that using a 10Gbit card with
> a 10Gbit link or a 1Gbit link?

Its been a while, but most details should be publicly available here:

http://www.stacresearch.com/node/4211

- Arnaldo

^ permalink raw reply

* [PATCH] ipv6: Log the affected address when DAD failure occurs
From: Jens Rosenboom @ 2009-09-16 11:44 UTC (permalink / raw)
  To: Linux Network Developers

From: Jens Rosenboom <me@jayr.de>

If an interface has multiple addresses, the current message for DAD
failure isn't really helpful, so this patch adds the address itself to
the printk.

Signed-off-by: Jens Rosenboom <me@jayr.de>

---
This is a resubmit of http://patchwork.ozlabs.org/patch/31196/ which
erroneously was marked as superseded, but using the new compact output format.

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index c9b3690..907a6f7 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1405,8 +1405,8 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
 	struct inet6_dev *idev = ifp->idev;
 
 	if (net_ratelimit())
-		printk(KERN_INFO "%s: IPv6 duplicate address detected!\n",
-			ifp->idev->dev->name);
+		printk(KERN_INFO "%s: IPv6 duplicate address %pI6c detected!\n",
+			ifp->idev->dev->name, &ifp->addr);
 
 	if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6) {
 		struct in6_addr addr;



^ permalink raw reply related

* Re: [PATCHv5 3/3] vhost_net: a kernel-level virtio server
From: Gregory Haskins @ 2009-09-16 11:44 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Michael S. Tsirkin, Ira W. Snyder, netdev, virtualization, kvm,
	linux-kernel, mingo, linux-mm, akpm, hpa, Rusty Russell, s.hetze,
	alacrityvm-devel
In-Reply-To: <4AB0A070.1050400@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 5873 bytes --]

Avi Kivity wrote:
> On 09/15/2009 11:08 PM, Gregory Haskins wrote:
>>
>>> There's virtio-console, virtio-blk etc.  None of these have kernel-mode
>>> servers, but these could be implemented if/when needed.
>>>      
>> IIUC, Ira already needs at least ethernet and console capability.
>>
>>    
> 
> He's welcome to pick up the necessary code from qemu.

The problem isn't where to find the models...the problem is how to
aggregate multiple models to the guest.

> 
>>>> b) what do you suppose this protocol to aggregate the connections would
>>>> look like? (hint: this is what a vbus-connector does).
>>>>
>>>>        
>>> You mean multilink?  You expose the device as a multiqueue.
>>>      
>> No, what I mean is how do you surface multiple ethernet and consoles to
>> the guests?  For Ira's case, I think he needs at minimum at least one of
>> each, and he mentioned possibly having two unique ethernets at one point.
>>    
> 
> You instantiate multiple vhost-nets.  Multiple ethernet NICs is a
> supported configuration for kvm.

But this is not KVM.

> 
>> His slave boards surface themselves as PCI devices to the x86
>> host.  So how do you use that to make multiple vhost-based devices (say
>> two virtio-nets, and a virtio-console) communicate across the transport?
>>    
> 
> I don't really see the difference between 1 and N here.

A KVM surfaces N virtio-devices as N pci-devices to the guest.  What do
we do in Ira's case where the entire guest represents itself as a PCI
device to the host, and nothing the other way around?


> 
>> There are multiple ways to do this, but what I am saying is that
>> whatever is conceived will start to look eerily like a vbus-connector,
>> since this is one of its primary purposes ;)
>>    
> 
> I'm not sure if you're talking about the configuration interface or data
> path here.

I am talking about how we would tunnel the config space for N devices
across his transport.

As an aside, the vbus-kvm connector makes them one and the same, but
they do not have to be.  Its all in the connector design.

> 
>>>> c) how do you manage the configuration, especially on a per-board
>>>> basis?
>>>>
>>>>        
>>> pci (for kvm/x86).
>>>      
>> Ok, for kvm understood (and I would also add "qemu" to that mix).  But
>> we are talking about vhost's application in a non-kvm environment here,
>> right?.
>>
>> So if the vhost-X devices are in the "guest",
> 
> They aren't in the "guest".  The best way to look at it is
> 
> - a device side, with a dma engine: vhost-net
> - a driver side, only accessing its own memory: virtio-net
> 
> Given that Ira's config has the dma engine in the ppc boards, that's
> where vhost-net would live (the ppc boards acting as NICs to the x86
> board, essentially).

That sounds convenient given his hardware, but it has its own set of
problems.  For one, the configuration/inventory of these boards is now
driven by the wrong side and has to be addressed.  Second, the role
reversal will likely not work for many models other than ethernet (e.g.
virtio-console or virtio-blk drivers running on the x86 board would be
naturally consuming services from the slave boards...virtio-net is an
exception because 802.x is generally symmetrical).

IIUC, vbus would support having the device models live properly on the
x86 side, solving both of these problems.  It would be impossible to
reverse vhost given its current design.

> 
>> and the x86 board is just
>> a slave...How do you tell each ppc board how many devices and what
>> config (e.g. MACs, etc) to instantiate?  Do you assume that they should
>> all be symmetric and based on positional (e.g. slot) data?  What if you
>> want asymmetric configurations (if not here, perhaps in a different
>> environment)?
>>    
> 
> I have no idea, that's for Ira to solve.

Bingo.  Thus my statement that the vhost proposal is incomplete.  You
have the virtio-net and vhost-net pieces covering the fast-path
end-points, but nothing in the middle (transport, aggregation,
config-space), and nothing on the management-side.  vbus provides most
of the other pieces, and can even support the same virtio-net protocol
on top.  The remaining part would be something like a udev script to
populate the vbus with devices on board-insert events.

> If he could fake the PCI
> config space as seen by the x86 board, he would just show the normal pci
> config and use virtio-pci (multiple channels would show up as a
> multifunction device).  Given he can't, he needs to tunnel the virtio
> config space some other way.

Right, and note that vbus was designed to solve this.  This tunneling
can, of course, be done without vbus using some other design.  However,
whatever solution is created will look incredibly close to what I've
already done, so my point is "why reinvent it"?

> 
>>> Yes.  virtio is really virtualization oriented.
>>>      
>> I would say that its vhost in particular that is virtualization
>> oriented.  virtio, as a concept, generally should work in physical
>> systems, if perhaps with some minor modifications.  The biggest "limit"
>> is having "virt" in its name ;)
>>    
> 
> Let me rephrase.  The virtio developers are virtualization oriented.  If
> it works for non-virt applications, that's good, but not a design goal.
> 

Fair enough.  Vbus was designed to support both HW and virt (as well as
other models, like containers), including tunneling virtio within those
environments.  That is probably why IMO vbus is a better fit than vhost
here.  (FWIW: I would love to see vhost use the vbus framework, then we
all win.  You can do this and still retain virtio-pci compatiblity (at
least theoretically).  I am still open to working with the team on this).

Kind Regards,
-Greg


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 267 bytes --]

^ permalink raw reply

* Re: fanotify as syscalls
From: Jamie Lokier @ 2009-09-16 11:41 UTC (permalink / raw)
  To: Alan Cox
  Cc: Eric Paris, Linus Torvalds, Evgeniy Polyakov, David Miller,
	linux-kernel, linux-fsdevel, netdev, viro, hch
In-Reply-To: <20090916114111.2228f0fc@linux.intel.com>

Alan Cox wrote:
> > - fanotify does not provide subtree notification in it's
> >   present form.  When it is extended to do that, why wouldn't
> >   inotify be as well?  That's an fsnotify feature, common to both.
> 
> Because inotify gives you no reliable access to the object monitored as
> the name passed back is not an object reference and is racy. Inotify is
> fine for making pretty icons pop up on desktops and making file
> selectors update, but it is somewhat inadequate for indexers and
> completely useless for stuff like HSM.

That was my point.  (Why do people keep not getting it?)

You can't rely on the name being non-racy, but you _can_ reliably
invalidate application-level caches from the sequence of events
including file writes, creates, renames, links, unlinks, mounts.  And
revalidate such caches by the absence of pending events.

(There is one obscure case which inotify is missing, though, which
means it cannot detect file changes in certain cases with hard links.
I intend to fix that one.)

For that, an inode isn't useful, a descriptor isn't useful, a
directory descriptor/inode and pathname isn't useful, and file write
events by themselves aren't useful.  None of them quite do it by
themselves.

But with the correct combination of events, you can maintain very
efficient application-level caching of file data / directory listing
and lookups / stat results you have previously read from the
filesystem.  That's because the information you have previously
depended upon, including path lookups, are all notified as one sort of
inotify event or another when changed.

Which doesn't sound all that special until you realise you can very
quickly revalidate application-caches of any data structure calculated
from reading things from the filesystem, no matter how many
prerequisites or how complex the data structures, in a single system
call.  Amortised over many revalidations if you have them in parallel.

That can apply to things like git, make, ccache, samba, rsync, httpd
path walks, and virtually any "web templating" framework.  Of course
it takes userspace support as well, but that's where I'm coming from
regarding "acceleration" and the essential kernel infrastructure.

Clearly, I'm going to have to explain with working code :-)

> but it is somewhat inadequate for indexers

For indexers, the real inadequacy is the need to attach inotify
watches to every directory at system startup, and to stat() everything
to check it hasn't changed since the indexer was last running.  Both
are very slow on a large directory tree.  The former can be dealt with
using subtree watches (yes, even with hard links - I have proposed an
algorithm for this but I think nobody understood it ;-).  The latter
needs filesystem support for a persistent change attribute.

> > - fanotify requires you call readlink(/proc/fd/N) for every event to
> >   get the path.  It's not a particularly efficient way to get it,
> 
> IFF you want the path, but the path isn't usually the most valuable bit.
> Plus you'll find the readlink is extremely quick anyway.

I agree, you don't usually want the whole path.

So what was the point about fanotify making subtree tracking possible
with it's file descriptor, if not by readlink(/proc/fd/N)?
Descriptors don't tell you which subtree a file is in any better than
inotify watches.  I.e. they do, if you track them and their containing
directories all individually.

> > People who want to break out of chroot/namespace jails using the
> > conveniently provided open file descriptor? :-)
> 
> chroot isn't a security model. You can already do this with AF_UNIX
> sockets (and there are apps that intentionally use fchdir that way)

Ah, no.  AF_UNIX works with explicit sender cooperation.

fanotify gives you access to files without sender cooperation, as it
intercepts every open().

> > I'd expect anti-malware to want to be run inside VMs quite often...
> 
> Inside of containers - unlikely.

Why not?  Some people run entire distributions in containiners, and
present them as VMs to the world for other people to admin.

> > the accessing process until acked), that's ok with me.  It makes
> > sense.  But then it's messy that neither offers a superset of the
> > other regarding which files and events are tracked.
> 
> Agreed.

In the end this is my main gripe.

-- Jamie


^ permalink raw reply

* Re: fanotify as syscalls
From: Arnd Bergmann @ 2009-09-16 11:30 UTC (permalink / raw)
  To: Eric Paris
  Cc: Evgeniy Polyakov, Jamie Lokier, David Miller, linux-kernel,
	linux-fsdevel, netdev, viro, alan, hch, torvalds
In-Reply-To: <1253051699.5213.18.camel@dhcp231-106.rdu.redhat.com>

On Tuesday 15 September 2009, Eric Paris wrote:
> fanotify_modify_mark_at() --- like inotify_add_watch and rm_watch
> fanotify_modify_mark_fd() --- same but with an fd instead of a path

I think these two can be merged into one without adding complexity,
in the same way that sys_utimensat can take a file descriptor or
a path or both.

> fanotify_response() --- userspace tells the kernel what to do if requested/allowed
>    (could probably be done using write() to the fanotify fd)
> fanotify_exclude() --- a horrid syscall which might be better as an ioctl since it isn't strongly typed....

Please don't use an ioctl here. While ioctl is fine for character devices
and sort of fine for sockets, I think it would be very bad style to use
it on file descriptors that you get back from specialized syscalls like
fanotify_init. Do one or the other, but do it consistently.

Why is it not strongly typed anyway? Something like

int fanotify_ignore_sb(int fanotify_fd, unsigned int flag,
                       long f_type, fsid_t f_fsid);

would be type safe, although I think it would be better to only handle
one of the two cases. Can you think of a case that you can't handle if
you have to decide between them and only do one interface (f_type or fsid)?

	Arnd <><

^ permalink raw reply

* Re: [PATCH 3/3] at91_can: add driver for Atmel's CAN controller on AT91SAM9263
From: Marc Kleine-Budde @ 2009-09-16 10:45 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: netdev, Socketcan-core, linux-arm-kernel
In-Reply-To: <4AB0B8F4.50301@grandegger.com>

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Wolfgang Grandegger wrote:
> Marc Kleine-Budde wrote:
>> This patch add the driver for the SoC CAN controller in Atmel's AT91SAM9263.
>>
>> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
> 
> I already reviewed at91_can.c on the Socket-CAN ML and it's almost OK
> from the Socket-CAN point of view. I just realized two minor issues:
> 
>> ---
>>  drivers/net/can/Kconfig    |    6 +
>>  drivers/net/can/Makefile   |    1 +
>>  drivers/net/can/at91_can.c | 1177 ++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 1184 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/net/can/at91_can.c
>>
>> diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
>> index 0900743..b6d2af1 100644
>> --- a/drivers/net/can/Kconfig
>> +++ b/drivers/net/can/Kconfig
>> @@ -82,6 +82,12 @@ config CAN_KVASER_PCI
>>  	  This driver is for the the PCIcanx and PCIcan cards (1, 2 or
>>  	  4 channel) from Kvaser (http://www.kvaser.com).
>>  
>> +config CAN_AT91
>> +	tristate "Atmel AT91 onchip CAN controller"
>> +	depends on CAN && ARCH_AT91SAM9263
> 
> It should depend on CAN_DEV because it used the CAN device driver interface.

will fix

> 
>> +	---help---
>> +	  This is a driver for the SoC CAN controller in Atmel's AT91SAM9263.
>> +
>>  config CAN_DEBUG_DEVICES
>>  	bool "CAN devices debugging messages"
>>  	depends on CAN
>> diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
>> index 523a941..3a54a12 100644
>> --- a/drivers/net/can/Makefile
>> +++ b/drivers/net/can/Makefile
>> @@ -8,5 +8,6 @@ obj-$(CONFIG_CAN_DEV)		+= can-dev.o
>>  can-dev-y			:= dev.o
>>  
>>  obj-$(CONFIG_CAN_SJA1000)	+= sja1000/
>> +obj-$(CONFIG_CAN_AT91)		+= at91_can.o
>>  
>>  ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
>> diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
>> new file mode 100644
>> index 0000000..cd1e8cb
>> --- /dev/null
>> +++ b/drivers/net/can/at91_can.c
>> @@ -0,0 +1,1177 @@
>> +/*
>> + * at91_can.c - CAN network driver for AT91 SoC CAN controller
>> + *
>> + * (C) 2007 by Hans J. Koch <hjk@linutronix.de>
>> + * (C) 2008, 2009 by Marc Kleine-Budde <kernel@pengutronix.de>
>> + *
>> + * This software may be distributed under the terms of the GNU General
>> + * Public License ("GPL") version 2 as distributed in the 'COPYING'
>> + * file from the main directory of the linux kernel source.
>> + *
>> + * Send feedback to <socketcan-users@lists.berlios.de>
> 
> This driver uses platform data. Could you please add some description on
> how they should be used, e.g. like for the MCP251x:
> 
>  * Your platform definition file should specify something like:
>  *
>  * static struct mcp251x_platform_data mcp251x_info = {
>  *         .oscillator_frequency = 8000000,
>  *         .board_specific_setup = &mcp251x_setup,
>  *         .model = CAN_MCP251X_MCP2510,
>  *         .power_enable = mcp251x_power_enable,
>  *         .transceiver_enable = NULL,
>  * };
>  *
>  * static struct spi_board_info spi_board_info[] = {
>  *         {
>  *                 .modalias      = "mcp251x",
>  *                 .platform_data = &mcp251x_info,
>  *                 .irq           = IRQ_EINT13,
>  *                 .max_speed_hz  = 2*1000*1000,
>  *                 .chip_select   = 2,
>  *         },
>  * };
>  *
>  * Please see mcp251x.h for a description of the fields in
>  * struct mcp251x_platform_data.
> 
> I find that really useful.

good point, I'll add a help text

tnx for the review,
Marc

- --
Pengutronix e.K.                         | Marc Kleine-Budde           |
Linux Solutions for Science and Industry | Phone: +49-231-2826-924     |
Vertretung West/Dortmund                 | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686         | http://www.pengutronix.de   |
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkqwwecACgkQjTAFq1RaXHNb9wCfTQ18W790/Bqsk8gEVWYnxsL6
sTkAmgNF3KzD8ics9UwemxHEi/HE4jIM
=pyRS
-----END PGP SIGNATURE-----

^ permalink raw reply

* Re: [PATCH 3/3] at91_can: add driver for Atmel's CAN controller on AT91SAM9263
From: Marc Kleine-Budde @ 2009-09-16 10:47 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: netdev, Socketcan-core, linux-arm-kernel
In-Reply-To: <4AB0B8F4.50301@grandegger.com>

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Wolfgang Grandegger wrote:
> Marc Kleine-Budde wrote:
>> This patch add the driver for the SoC CAN controller in Atmel's AT91SAM9263.
>>
>> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
> 
> I already reviewed at91_can.c on the Socket-CAN ML and it's almost OK
> from the Socket-CAN point of view. I just realized two minor issues:
> 
>> ---
>>  drivers/net/can/Kconfig    |    6 +
>>  drivers/net/can/Makefile   |    1 +
>>  drivers/net/can/at91_can.c | 1177 ++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 1184 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/net/can/at91_can.c
>>
>> diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
>> index 0900743..b6d2af1 100644
>> --- a/drivers/net/can/Kconfig
>> +++ b/drivers/net/can/Kconfig
>> @@ -82,6 +82,12 @@ config CAN_KVASER_PCI
>>  	  This driver is for the the PCIcanx and PCIcan cards (1, 2 or
>>  	  4 channel) from Kvaser (http://www.kvaser.com).
>>  
>> +config CAN_AT91
>> +	tristate "Atmel AT91 onchip CAN controller"
>> +	depends on CAN && ARCH_AT91SAM9263
> 
> It should depend on CAN_DEV because it used the CAN device driver interface.

will fix

> 
>> +	---help---
>> +	  This is a driver for the SoC CAN controller in Atmel's AT91SAM9263.
>> +
>>  config CAN_DEBUG_DEVICES
>>  	bool "CAN devices debugging messages"
>>  	depends on CAN
>> diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
>> index 523a941..3a54a12 100644
>> --- a/drivers/net/can/Makefile
>> +++ b/drivers/net/can/Makefile
>> @@ -8,5 +8,6 @@ obj-$(CONFIG_CAN_DEV)		+= can-dev.o
>>  can-dev-y			:= dev.o
>>  
>>  obj-$(CONFIG_CAN_SJA1000)	+= sja1000/
>> +obj-$(CONFIG_CAN_AT91)		+= at91_can.o
>>  
>>  ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
>> diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
>> new file mode 100644
>> index 0000000..cd1e8cb
>> --- /dev/null
>> +++ b/drivers/net/can/at91_can.c
>> @@ -0,0 +1,1177 @@
>> +/*
>> + * at91_can.c - CAN network driver for AT91 SoC CAN controller
>> + *
>> + * (C) 2007 by Hans J. Koch <hjk@linutronix.de>
>> + * (C) 2008, 2009 by Marc Kleine-Budde <kernel@pengutronix.de>
>> + *
>> + * This software may be distributed under the terms of the GNU General
>> + * Public License ("GPL") version 2 as distributed in the 'COPYING'
>> + * file from the main directory of the linux kernel source.
>> + *
>> + * Send feedback to <socketcan-users@lists.berlios.de>
> 
> This driver uses platform data. Could you please add some description on
> how they should be used, e.g. like for the MCP251x:
> 
>  * Your platform definition file should specify something like:
>  *
>  * static struct mcp251x_platform_data mcp251x_info = {
>  *         .oscillator_frequency = 8000000,
>  *         .board_specific_setup = &mcp251x_setup,
>  *         .model = CAN_MCP251X_MCP2510,
>  *         .power_enable = mcp251x_power_enable,
>  *         .transceiver_enable = NULL,
>  * };
>  *
>  * static struct spi_board_info spi_board_info[] = {
>  *         {
>  *                 .modalias      = "mcp251x",
>  *                 .platform_data = &mcp251x_info,
>  *                 .irq           = IRQ_EINT13,
>  *                 .max_speed_hz  = 2*1000*1000,
>  *                 .chip_select   = 2,
>  *         },
>  * };
>  *
>  * Please see mcp251x.h for a description of the fields in
>  * struct mcp251x_platform_data.
> 
> I find that really useful.

good point, I'll add a help text

tnx for the review,
Marc

- --
Pengutronix e.K.                         | Marc Kleine-Budde           |
Linux Solutions for Science and Industry | Phone: +49-231-2826-924     |
Vertretung West/Dortmund                 | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686         | http://www.pengutronix.de   |
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkqwwecACgkQjTAFq1RaXHNb9wCfTQ18W790/Bqsk8gEVWYnxsL6
sTkAmgNF3KzD8ics9UwemxHEi/HE4jIM
=pyRS
-----END PGP SIGNATURE-----

^ permalink raw reply

* Re: fanotify as syscalls
From: Alan Cox @ 2009-09-16 10:41 UTC (permalink / raw)
  To: Jamie Lokier
  Cc: Eric Paris, Linus Torvalds, Evgeniy Polyakov, David Miller,
	linux-kernel, linux-fsdevel, netdev, viro, hch
In-Reply-To: <20090916075219.GA22024@shareable.org>

> - fanotify does not provide subtree notification in it's
>   present form.  When it is extended to do that, why wouldn't
>   inotify be as well?  That's an fsnotify feature, common to both.

Because inotify gives you no reliable access to the object monitored as
the name passed back is not an object reference and is racy. Inotify is
fine for making pretty icons pop up on desktops and making file
selectors update, but it is somewhat inadequate for indexers and
completely useless for stuff like HSM.

> - fanotify requires you call readlink(/proc/fd/N) for every event to
>   get the path.  It's not a particularly efficient way to get it,

IFF you want the path, but the path isn't usually the most valuable bit.
Plus you'll find the readlink is extremely quick anyway.

> People who want to break out of chroot/namespace jails using the
> conveniently provided open file descriptor? :-)

chroot isn't a security model. You can already do this with AF_UNIX
sockets (and there are apps that intentionally use fchdir that way)

> I'd expect anti-malware to want to be run inside VMs quite often...

Inside of containers - unlikely. Inside of guests sure but thats not
going to relevant to fanotify()

> the accessing process until acked), that's ok with me.  It makes
> sense.  But then it's messy that neither offers a superset of the
> other regarding which files and events are tracked.

Agreed.


^ permalink raw reply

* [PATCH] pkt_sched: Fix qstats.qlen updating in dump_stats
From: Jarek Poplawski @ 2009-09-16 10:38 UTC (permalink / raw)
  To: David Miller; +Cc: Patrick McHardy, netdev

Some classful qdiscs miss qstats.qlen updating with q.qlen of their
child qdiscs in dump_stats methods.

Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
---

 net/sched/sch_drr.c    |    4 +++-
 net/sched/sch_mq.c     |    1 +
 net/sched/sch_multiq.c |    1 +
 net/sched/sch_prio.c   |    1 +
 4 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index 12b2fb0..5a888af 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -274,8 +274,10 @@ static int drr_dump_class_stats(struct Qdisc *sch, unsigned long arg,
 	struct tc_drr_stats xstats;
 
 	memset(&xstats, 0, sizeof(xstats));
-	if (cl->qdisc->q.qlen)
+	if (cl->qdisc->q.qlen) {
 		xstats.deficit = cl->deficit;
+		cl->qdisc->qstats.qlen = cl->qdisc->q.qlen;
+	}
 
 	if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
 	    gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index dd5ee02..d44eddd 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -188,6 +188,7 @@ static int mq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
 	struct netdev_queue *dev_queue = mq_queue_get(sch, cl);
 
 	sch = dev_queue->qdisc_sleeping;
+	sch->qstats.qlen = sch->q.qlen;
 	if (gnet_stats_copy_basic(d, &sch->bstats) < 0 ||
 	    gnet_stats_copy_queue(d, &sch->qstats) < 0)
 		return -1;
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 069f81c..7db2c88 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -359,6 +359,7 @@ static int multiq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
 	struct Qdisc *cl_q;
 
 	cl_q = q->queues[cl - 1];
+	cl_q->qstats.qlen = cl_q->q.qlen;
 	if (gnet_stats_copy_basic(d, &cl_q->bstats) < 0 ||
 	    gnet_stats_copy_queue(d, &cl_q->qstats) < 0)
 		return -1;
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 0f73c41..93285ce 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -322,6 +322,7 @@ static int prio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
 	struct Qdisc *cl_q;
 
 	cl_q = q->queues[cl - 1];
+	cl_q->qstats.qlen = cl_q->q.qlen;
 	if (gnet_stats_copy_basic(d, &cl_q->bstats) < 0 ||
 	    gnet_stats_copy_queue(d, &cl_q->qstats) < 0)
 		return -1;

^ permalink raw reply related

* Re: [PATCH 3/3] at91_can: add driver for Atmel's CAN controller on AT91SAM9263
From: Wolfgang Grandegger @ 2009-09-16 10:07 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: Socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1253094405-3216-4-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

Marc Kleine-Budde wrote:
> This patch add the driver for the SoC CAN controller in Atmel's AT91SAM9263.
> 
> Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

I already reviewed at91_can.c on the Socket-CAN ML and it's almost OK
from the Socket-CAN point of view. I just realized two minor issues:

> ---
>  drivers/net/can/Kconfig    |    6 +
>  drivers/net/can/Makefile   |    1 +
>  drivers/net/can/at91_can.c | 1177 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 1184 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/net/can/at91_can.c
> 
> diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
> index 0900743..b6d2af1 100644
> --- a/drivers/net/can/Kconfig
> +++ b/drivers/net/can/Kconfig
> @@ -82,6 +82,12 @@ config CAN_KVASER_PCI
>  	  This driver is for the the PCIcanx and PCIcan cards (1, 2 or
>  	  4 channel) from Kvaser (http://www.kvaser.com).
>  
> +config CAN_AT91
> +	tristate "Atmel AT91 onchip CAN controller"
> +	depends on CAN && ARCH_AT91SAM9263

It should depend on CAN_DEV because it used the CAN device driver interface.

> +	---help---
> +	  This is a driver for the SoC CAN controller in Atmel's AT91SAM9263.
> +
>  config CAN_DEBUG_DEVICES
>  	bool "CAN devices debugging messages"
>  	depends on CAN
> diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
> index 523a941..3a54a12 100644
> --- a/drivers/net/can/Makefile
> +++ b/drivers/net/can/Makefile
> @@ -8,5 +8,6 @@ obj-$(CONFIG_CAN_DEV)		+= can-dev.o
>  can-dev-y			:= dev.o
>  
>  obj-$(CONFIG_CAN_SJA1000)	+= sja1000/
> +obj-$(CONFIG_CAN_AT91)		+= at91_can.o
>  
>  ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
> diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
> new file mode 100644
> index 0000000..cd1e8cb
> --- /dev/null
> +++ b/drivers/net/can/at91_can.c
> @@ -0,0 +1,1177 @@
> +/*
> + * at91_can.c - CAN network driver for AT91 SoC CAN controller
> + *
> + * (C) 2007 by Hans J. Koch <hjk-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
> + * (C) 2008, 2009 by Marc Kleine-Budde <kernel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> + *
> + * This software may be distributed under the terms of the GNU General
> + * Public License ("GPL") version 2 as distributed in the 'COPYING'
> + * file from the main directory of the linux kernel source.
> + *
> + * Send feedback to <socketcan-users-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org>

This driver uses platform data. Could you please add some description on
how they should be used, e.g. like for the MCP251x:

 * Your platform definition file should specify something like:
 *
 * static struct mcp251x_platform_data mcp251x_info = {
 *         .oscillator_frequency = 8000000,
 *         .board_specific_setup = &mcp251x_setup,
 *         .model = CAN_MCP251X_MCP2510,
 *         .power_enable = mcp251x_power_enable,
 *         .transceiver_enable = NULL,
 * };
 *
 * static struct spi_board_info spi_board_info[] = {
 *         {
 *                 .modalias      = "mcp251x",
 *                 .platform_data = &mcp251x_info,
 *                 .irq           = IRQ_EINT13,
 *                 .max_speed_hz  = 2*1000*1000,
 *                 .chip_select   = 2,
 *         },
 * };
 *
 * Please see mcp251x.h for a description of the fields in
 * struct mcp251x_platform_data.

I find that really useful.

Wolfgang.

^ permalink raw reply

* RE: [Patch net-next]atl1e:fix 2.6.31-git4 -- ATL1E 0000:03:00.0: DMA-API: device driver frees DMA
From: Jie Yang @ 2009-09-16  9:54 UTC (permalink / raw)
  To: Cyrill Gorcunov, David Miller
  Cc: dwalker@fifo99.com, miles.lane@gmail.com, chris.snook@gmail.com,
	jcliburn@gmail.com, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <20090916095138.GH5094@lenovo>

On Wednesday, September 16, 2009 5:52 PM
Cyrill Gorcunov <gorcunov@gmail.com>  wrote:

> [David Miller - Wed, Sep 16, 2009 at 02:47:59AM -0700]
> | From: Daniel Walker <dwalker@fifo99.com>
> | Date: Wed, 16 Sep 2009 02:10:51 -0700
> |
> | > On Wed, 2009-09-16 at 14:21 +0800, jie.yang@atheros.com wrote:
> | >> -           pci_unmap_page(pdev, tx_buffer->dma,
> | >> +           if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
> | >> +               pci_unmap_single(pdev, tx_buffer->dma,
> | >> +                   tx_buffer->length, PCI_DMA_TODEVICE);
> | >> +           else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
> | >> +               pci_unmap_page(pdev, tx_buffer->dma,
> | >
> | > Could you run this through checkpatch, and fix any errors
> if find?
> | > It looks like you uses spaces for tabs in the code above,
> maybe in
> | > the other block too..
> | >
> |
> | It's because of his email client, it corrupted the whole patch like
> | that.
>
> well, client seems to be
>
> | X-Mailer: git-send-email 1.5.2.2
>
> more probably the text editor is the reason.
>
>         -- Cyrill
>

yes, the editor 'vi' have configed "set expandtab".

^ permalink raw reply

* Re: [Patch net-next]atl1e:fix 2.6.31-git4 -- ATL1E 0000:03:00.0: DMA-API: device driver frees DMA
From: Cyrill Gorcunov @ 2009-09-16  9:51 UTC (permalink / raw)
  To: David Miller
  Cc: dwalker, jie.yang, miles.lane, chris.snook, jcliburn, netdev,
	linux-kernel
In-Reply-To: <20090916.024759.51103835.davem@davemloft.net>

[David Miller - Wed, Sep 16, 2009 at 02:47:59AM -0700]
| From: Daniel Walker <dwalker@fifo99.com>
| Date: Wed, 16 Sep 2009 02:10:51 -0700
| 
| > On Wed, 2009-09-16 at 14:21 +0800, jie.yang@atheros.com wrote:
| >> -           pci_unmap_page(pdev, tx_buffer->dma,
| >> +           if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
| >> +               pci_unmap_single(pdev, tx_buffer->dma,
| >> +                   tx_buffer->length, PCI_DMA_TODEVICE);
| >> +           else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
| >> +               pci_unmap_page(pdev, tx_buffer->dma,
| > 
| > Could you run this through checkpatch, and fix any errors if find? It
| > looks like you uses spaces for tabs in the code above, maybe in the
| > other block too..
| > 
| 
| It's because of his email client, it corrupted the whole patch
| like that.

well, client seems to be

| X-Mailer: git-send-email 1.5.2.2

more probably the text editor is the reason.

	-- Cyrill

^ permalink raw reply

* Re: fanotify as syscalls
From: Eric Paris @ 2009-09-16  9:48 UTC (permalink / raw)
  To: Jamie Lokier
  Cc: Linus Torvalds, Evgeniy Polyakov, David Miller, linux-kernel,
	linux-fsdevel, netdev, viro, alan, hch
In-Reply-To: <20090916075219.GA22024@shareable.org>

On Wed, 2009-09-16 at 08:52 +0100, Jamie Lokier wrote:
> Eric Paris wrote:
> > On Tue, 2009-09-15 at 16:49 -0700, Linus Torvalds wrote:
> > > And btw, I still want to know what's so wonderful about fanotify that we 
> > > would actually want yet-another-filesystem-notification-interface. So I'm 
> > > not sayying that I'll take a system call interface.
> > 
> > The real thing that fanotify provides is an open fd with the event
> > rather than some arbitrary 'watch descriptor' that userspace must
> > somehow magically map back to data on disk.  This means that it could be
> > used to provide subtree notification, which inotify is completely
> > incapable of doing.
> 
> That's a bit of a spurious claim.

My claim that a watch descriptor plus pathname segment sucks is
spurious?  You've got to be kidding me.  You think that a number which
represents the pathname of an object at some point in the past is a
reasonable piece of information?  If a watch descriptor actually
provided any information about the object on which an event just
happened it would be useful.  Sadly, it doesn't.

> - fanotify does not provide subtree notification in it's
>   present form.  When it is extended to do that, why wouldn't
>   inotify be as well?  That's an fsnotify feature, common to both.

Because I don't believe inotify can be reasonably extended in this way.
It's already clear that an arbitrary watch descriptor which userspace
has to somehow know how to correctly map back to an object (impossible
task) is difficult to use and I personally don't see how watch
descriptor + long path name component is somehow better or even
reasonable.  Path names are such crap and passing a pathname to
userspace is really just telling userspace, something happened to
something that used to be at this location but is possibly long since
gone.  I don't believe that's a good interface or one we should be
allowing to be {ab,}used.

> - fanotify does not provide notification at all for some events that
>   you get with inotify.  It is not a superset, so you can't use
>   fanotify to provide a subtree-capable equivalent to inotify.  What
>   a mess when you need the combination of both features!

This is true, although where possible I plan to rectify this situation
on an ongoing basis.  Absolutely nothing preventing that from happening.

> - fanotify requires you call readlink(/proc/fd/N) for every event to
>   get the path.

And inotify requires magic.  Which one sounds better?

>   It's not a particularly efficient way to get it,

What is?

>   especially when an apps wants to know if it's something in it's
>   region of interest but doesn't care about the actual path.
>   When an apps knows it needs the map back to to path, why make it
>   slow to get it?  That "extensible data format" is being
>   underutilised...

You convince Al Viro that the vfs should give us a path name for an
arbitrary object that honestly might not have one and I'll consider
giving it to userspace in the event notification.  Probably should read
some of the AppArmour arguments before you do though.  You're asking for
something that's impossible and is at best incredibly race prone crap.
At worst is a total lie.

> - fanotify's descriptor may be race-prone as a way to get the subtree
>   used for access, because any of the parent directories could have
>   moved and even been deleted before the app calls
>   readlink(/proc/fd/N).  I don't know if a _reliable_ way to track
>   changes in a subtree can be built on it.  Maybe it can but it
>   appears this hasn't been analysed.  It depends on
>   readlink(/proc/fd/N)'s behaviour when the dentry's have been
>   changed, among other things.

Huh?  Your saying that by the time userspace deals with an event it
might have moved?  True.  So what?  Spurious and irrelevant.  You got an
event that happened to this object.  If subtree notification is added at
some later point you may get an event for an object that was in the
subtree and is now not in the subtree.  That sounds fine to me....

> - Does the descriptor cause umount to fail when user does "do some
>   stuff in baz; umount baz", or does it serialise nicely?  That's one
>   of inotify's nice features - it doesn't cause umounts to fail.

Ah yes, you didn't read the code.  Seeing as how that's an fsnotify
property and fanotify notify is built on fsnotify....

> Seriously, what does system-wide fanotify do when run from a
> chroot/namespace/cgroup, and a file outside them is accessed?

At the moment an fanotify global listener is system wide.  Truely system
wide.  A gentleman from suse is looking rectify the problem so that if
run inside a namespace it stays inside the namespace.  Note that this
particular little tidbit is not in the 8 patches I proposed.  At the
moment those just include the UI and basic notification.

> If the event is delivered with file desciptor, that's a security hole.
> If it's not delivered, that sounds like working subtree support?

What?

> I'd expect anti-malware to want to be run inside VMs quite often...

What?

> Answer questions about use-cases that you're not interested in?  Why
> block them?  What about Evigny's request for an event without an open
> fd - because he needs the pid information (inotify doesn't provide)
> but not the fd?

It's not blocked, it's on the list of things to look at.  It's a
relatively simple change to have the mark add code return a watch
descriptor and use that value instead of an fd.  I believe I already
said that.  It certainly doesn't seem like a merge blocker that some
other feature might come along one day.  There's nothing preventing it
from coming out.  "Here is a patch which implements TCP."  "No, don't
merge that, it doesn't implement UDP as well."  "WTF?"

> I'd like to be able to use it from some applications to accelerate
> userspace caching of things (faster Make, faster Samba) without
> penalising all other applications touching unrelated parts of the
> filesystem.  The attitude "you can live with 10% slowdown" worries me.
> I'm sure that can be fixed with a bit of care.

I've said that using ANYTHING which allows userspace to arbitrate access
decisions for an entries system is going to eat performance.  If you
can't handle that, don't build that damn userspace decision making
portion into your kernel!  Don't buy anti-malware snake oil.  

fanotify as a notification system isn't some performance monster here to
eat your babies.  fanotify as an access control system is, and I can't
really do anything about that, it's the nature of that part of the
horrible beast.  Lets not confuse things...

> If the intention is to maintain fanotify and inotify side-by-side for
> different uses (because fanotify returns open descriptors and blocks
> the accessing process until acked)

I know I've told you this before.  fanotify provides TWO separate
things.  Notification with a fd.  A method to provide access control and
blocking.  Lets not lead people to believe you can't you one without the
other.  They are very distinct.

> , that's ok with me.  It makes
> sense.  But then it's messy that neither offers a superset of the
> other regarding which files and events are tracked.

inotify isn't going away any time soon....

> If it's right that inotify has no room for extensibility (I'm not sure
> about this), than it appears we already made a mess with dnotify and
> inotify, so it would be a shame to repeat the same mistakes again.
> Let's get the next one right, even it takes a bit longer, ok?

Calling inotify a "mess" or "completely inextensible" would probably be
too harsh.  There are ways with inotify_init1() that we could provide a
better or more forward looking data format.  But you are still left with
inotify's fatal flaw: userspace is required to map a random number to an
object in the filesystem.  inotify starts with a reasonably impossible
premise and builds from there.

You show me anything about my proposal that limits any use case you have
in mind and I'll fix it.  I'll fix it today.  My proposal does what it
does very well and leaves the door open to build upon it for whatever
has been mentioned over the last 1.25 years I've been trying to get
comments.  I'm certainly not going to wait until fanotify can leap out
of my computer and make a pot of coffee before I ask for it to be merged
(and no, it doesn't have that forward looking extensibility, I'll add a
syscall flag for it right now, O_COFFEE)

-Eric

^ permalink raw reply

* Re: [Patch net-next]atl1e:fix 2.6.31-git4 -- ATL1E 0000:03:00.0: DMA-API: device driver frees DMA
From: David Miller @ 2009-09-16  9:47 UTC (permalink / raw)
  To: dwalker; +Cc: jie.yang, miles.lane, chris.snook, jcliburn, netdev, linux-kernel
In-Reply-To: <1253092251.11643.569.camel@desktop>

From: Daniel Walker <dwalker@fifo99.com>
Date: Wed, 16 Sep 2009 02:10:51 -0700

> On Wed, 2009-09-16 at 14:21 +0800, jie.yang@atheros.com wrote:
>> -           pci_unmap_page(pdev, tx_buffer->dma,
>> +           if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
>> +               pci_unmap_single(pdev, tx_buffer->dma,
>> +                   tx_buffer->length, PCI_DMA_TODEVICE);
>> +           else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
>> +               pci_unmap_page(pdev, tx_buffer->dma,
> 
> Could you run this through checkpatch, and fix any errors if find? It
> looks like you uses spaces for tabs in the code above, maybe in the
> other block too..
> 

It's because of his email client, it corrupted the whole patch
like that.

^ permalink raw reply

* [PATCH 3/3] at91_can: add driver for Atmel's CAN controller on AT91SAM9263
From: Marc Kleine-Budde @ 2009-09-16  9:46 UTC (permalink / raw)
  To: netdev; +Cc: linux-arm-kernel, Socketcan-core, Marc Kleine-Budde
In-Reply-To: <1253094405-3216-3-git-send-email-mkl@pengutronix.de>

This patch add the driver for the SoC CAN controller in Atmel's AT91SAM9263.

Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/Kconfig    |    6 +
 drivers/net/can/Makefile   |    1 +
 drivers/net/can/at91_can.c | 1177 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1184 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/can/at91_can.c

diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 0900743..b6d2af1 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -82,6 +82,12 @@ config CAN_KVASER_PCI
 	  This driver is for the the PCIcanx and PCIcan cards (1, 2 or
 	  4 channel) from Kvaser (http://www.kvaser.com).
 
+config CAN_AT91
+	tristate "Atmel AT91 onchip CAN controller"
+	depends on CAN && ARCH_AT91SAM9263
+	---help---
+	  This is a driver for the SoC CAN controller in Atmel's AT91SAM9263.
+
 config CAN_DEBUG_DEVICES
 	bool "CAN devices debugging messages"
 	depends on CAN
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 523a941..3a54a12 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -8,5 +8,6 @@ obj-$(CONFIG_CAN_DEV)		+= can-dev.o
 can-dev-y			:= dev.o
 
 obj-$(CONFIG_CAN_SJA1000)	+= sja1000/
+obj-$(CONFIG_CAN_AT91)		+= at91_can.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
new file mode 100644
index 0000000..cd1e8cb
--- /dev/null
+++ b/drivers/net/can/at91_can.c
@@ -0,0 +1,1177 @@
+/*
+ * at91_can.c - CAN network driver for AT91 SoC CAN controller
+ *
+ * (C) 2007 by Hans J. Koch <hjk@linutronix.de>
+ * (C) 2008, 2009 by Marc Kleine-Budde <kernel@pengutronix.de>
+ *
+ * This software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2 as distributed in the 'COPYING'
+ * file from the main directory of the linux kernel source.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/if_arp.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+
+#include <mach/board.h>
+
+#define DRV_NAME		"at91_can"
+#define AT91_NAPI_WEIGHT	12
+
+/*
+ * RX/TX Mailbox split
+ * don't dare to touch
+ */
+#define AT91_MB_RX_NUM		12
+#define AT91_MB_TX_SHIFT	2
+
+#define AT91_MB_RX_FIRST	0
+#define AT91_MB_RX_LAST		(AT91_MB_RX_FIRST + AT91_MB_RX_NUM - 1)
+
+#define AT91_MB_RX_MASK(i)	((1 << (i)) - 1)
+#define AT91_MB_RX_SPLIT	8
+#define AT91_MB_RX_LOW_LAST	(AT91_MB_RX_SPLIT - 1)
+#define AT91_MB_RX_LOW_MASK	(AT91_MB_RX_MASK(AT91_MB_RX_SPLIT))
+
+#define AT91_MB_TX_NUM		(1 << AT91_MB_TX_SHIFT)
+#define AT91_MB_TX_FIRST	(AT91_MB_RX_LAST + 1)
+#define AT91_MB_TX_LAST		(AT91_MB_TX_FIRST + AT91_MB_TX_NUM - 1)
+
+#define AT91_NEXT_PRIO_SHIFT	(AT91_MB_TX_SHIFT)
+#define AT91_NEXT_PRIO_MASK	(0xf << AT91_MB_TX_SHIFT)
+#define AT91_NEXT_MB_MASK	(AT91_MB_TX_NUM - 1)
+#define AT91_NEXT_MASK		((AT91_MB_TX_NUM - 1) | AT91_NEXT_PRIO_MASK)
+
+/* Common registers */
+enum at91_reg {
+	AT91_MR		= 0x000,
+	AT91_IER	= 0x004,
+	AT91_IDR	= 0x008,
+	AT91_IMR	= 0x00C,
+	AT91_SR		= 0x010,
+	AT91_BR		= 0x014,
+	AT91_TIM	= 0x018,
+	AT91_TIMESTP	= 0x01C,
+	AT91_ECR	= 0x020,
+	AT91_TCR	= 0x024,
+	AT91_ACR	= 0x028,
+};
+
+/* Mailbox registers (0 <= i <= 15) */
+#define AT91_MMR(i)		(enum at91_reg)(0x200 + ((i) * 0x20))
+#define AT91_MAM(i)		(enum at91_reg)(0x204 + ((i) * 0x20))
+#define AT91_MID(i)		(enum at91_reg)(0x208 + ((i) * 0x20))
+#define AT91_MFID(i)		(enum at91_reg)(0x20C + ((i) * 0x20))
+#define AT91_MSR(i)		(enum at91_reg)(0x210 + ((i) * 0x20))
+#define AT91_MDL(i)		(enum at91_reg)(0x214 + ((i) * 0x20))
+#define AT91_MDH(i)		(enum at91_reg)(0x218 + ((i) * 0x20))
+#define AT91_MCR(i)		(enum at91_reg)(0x21C + ((i) * 0x20))
+
+/* Register bits */
+#define AT91_MR_CANEN		BIT(0)
+#define AT91_MR_LPM		BIT(1)
+#define AT91_MR_ABM		BIT(2)
+#define AT91_MR_OVL		BIT(3)
+#define AT91_MR_TEOF		BIT(4)
+#define AT91_MR_TTM		BIT(5)
+#define AT91_MR_TIMFRZ		BIT(6)
+#define AT91_MR_DRPT		BIT(7)
+
+#define AT91_SR_RBSY		BIT(29)
+
+#define AT91_MMR_PRIO_SHIFT	(16)
+
+#define AT91_MID_MIDE		BIT(29)
+
+#define AT91_MSR_MRTR		BIT(20)
+#define AT91_MSR_MABT		BIT(22)
+#define AT91_MSR_MRDY		BIT(23)
+#define AT91_MSR_MMI		BIT(24)
+
+#define AT91_MCR_MRTR		BIT(20)
+#define AT91_MCR_MTCR		BIT(23)
+
+/* Mailbox Modes */
+enum at91_mb_mode {
+	AT91_MB_MODE_DISABLED	= 0,
+	AT91_MB_MODE_RX		= 1,
+	AT91_MB_MODE_RX_OVRWR	= 2,
+	AT91_MB_MODE_TX		= 3,
+	AT91_MB_MODE_CONSUMER	= 4,
+	AT91_MB_MODE_PRODUCER	= 5,
+};
+
+/* Interrupt mask bits */
+#define AT91_IRQ_MB_RX		((1 << (AT91_MB_RX_LAST + 1)) \
+				 - (1 << AT91_MB_RX_FIRST))
+#define AT91_IRQ_MB_TX		((1 << (AT91_MB_TX_LAST + 1)) \
+				 - (1 << AT91_MB_TX_FIRST))
+#define AT91_IRQ_MB_ALL		(AT91_IRQ_MB_RX | AT91_IRQ_MB_TX)
+
+#define AT91_IRQ_ERRA		(1 << 16)
+#define AT91_IRQ_WARN		(1 << 17)
+#define AT91_IRQ_ERRP		(1 << 18)
+#define AT91_IRQ_BOFF		(1 << 19)
+#define AT91_IRQ_SLEEP		(1 << 20)
+#define AT91_IRQ_WAKEUP		(1 << 21)
+#define AT91_IRQ_TOVF		(1 << 22)
+#define AT91_IRQ_TSTP		(1 << 23)
+#define AT91_IRQ_CERR		(1 << 24)
+#define AT91_IRQ_SERR		(1 << 25)
+#define AT91_IRQ_AERR		(1 << 26)
+#define AT91_IRQ_FERR		(1 << 27)
+#define AT91_IRQ_BERR		(1 << 28)
+
+#define AT91_IRQ_ERR_ALL	(0x1fff0000)
+#define AT91_IRQ_ERR_FRAME	(AT91_IRQ_CERR | AT91_IRQ_SERR | \
+				 AT91_IRQ_AERR | AT91_IRQ_FERR | AT91_IRQ_BERR)
+#define AT91_IRQ_ERR_LINE	(AT91_IRQ_ERRA | AT91_IRQ_WARN | \
+				 AT91_IRQ_ERRP | AT91_IRQ_BOFF)
+
+#define AT91_IRQ_ALL		(0x1fffffff)
+
+struct at91_priv {
+	struct can_priv		can;	   /* must be the first member! */
+	struct net_device	*dev;
+	struct napi_struct	napi;
+
+	void __iomem		*reg_base;
+
+	u32			reg_sr;
+	unsigned int		tx_next;
+	unsigned int		tx_echo;
+	unsigned int		rx_next;
+
+	struct clk		*clk;
+	struct at91_can_data	*pdata;
+};
+
+static struct can_bittiming_const at91_bittiming_const = {
+	.tseg1_min	= 4,
+	.tseg1_max	= 16,
+	.tseg2_min	= 2,
+	.tseg2_max	= 8,
+	.sjw_max	= 4,
+	.brp_min 	= 2,
+	.brp_max	= 128,
+	.brp_inc	= 1,
+};
+
+static inline int get_tx_next_mb(const struct at91_priv *priv)
+{
+	return (priv->tx_next & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST;
+}
+
+static inline int get_tx_next_prio(const struct at91_priv *priv)
+{
+	return (priv->tx_next >> AT91_NEXT_PRIO_SHIFT) & 0xf;
+}
+
+static inline int get_tx_echo_mb(const struct at91_priv *priv)
+{
+	return (priv->tx_echo & AT91_NEXT_MB_MASK) + AT91_MB_TX_FIRST;
+}
+
+static inline u32 at91_read(const struct at91_priv *priv, enum at91_reg reg)
+{
+	return readl(priv->reg_base + reg);
+}
+
+static inline void at91_write(const struct at91_priv *priv, enum at91_reg reg,
+		u32 value)
+{
+	writel(value, priv->reg_base + reg);
+}
+
+static inline void set_mb_mode_prio(const struct at91_priv *priv,
+		unsigned int mb, enum at91_mb_mode mode, int prio)
+{
+	at91_write(priv, AT91_MMR(mb), (mode << 24) | (prio << 16));
+}
+
+static inline void set_mb_mode(const struct at91_priv *priv, unsigned int mb,
+		enum at91_mb_mode mode)
+{
+	set_mb_mode_prio(priv, mb, mode, 0);
+}
+
+static struct sk_buff *alloc_can_skb(struct net_device *dev,
+		struct can_frame **cf)
+{
+	struct sk_buff *skb;
+
+	skb = netdev_alloc_skb(dev, sizeof(struct can_frame));
+	if (unlikely(!skb))
+		return NULL;
+
+	skb->protocol = htons(ETH_P_CAN);
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+	*cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
+
+	return skb;
+}
+
+static struct sk_buff *alloc_can_err_skb(struct net_device *dev,
+		struct can_frame **cf)
+{
+	struct sk_buff *skb;
+
+	skb = alloc_can_skb(dev, cf);
+	if (unlikely(!skb))
+		return NULL;
+
+	memset(*cf, 0, sizeof(struct can_frame));
+	(*cf)->can_id = CAN_ERR_FLAG;
+	(*cf)->can_dlc = CAN_ERR_DLC;
+
+	return skb;
+}
+
+/*
+ * Swtich transceiver on or off
+ */
+static void at91_transceiver_switch(const struct at91_priv *priv, int on)
+{
+	if (priv->pdata && priv->pdata->transceiver_switch)
+		priv->pdata->transceiver_switch(on);
+}
+
+static void at91_setup_mailboxes(struct net_device *dev)
+{
+	struct at91_priv *priv = netdev_priv(dev);
+	unsigned int i;
+
+	/*
+	 * The first 12 mailboxes are used as a reception FIFO. The
+	 * last mailbox is configured with overwrite option. The
+	 * overwrite flag indicates a FIFO overflow.
+	 */
+	for (i = AT91_MB_RX_FIRST; i < AT91_MB_RX_LAST; i++)
+		set_mb_mode(priv, i, AT91_MB_MODE_RX);
+	set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR);
+
+	/* The last 4 mailboxes are used for transmitting. */
+	for (i = AT91_MB_TX_FIRST; i <= AT91_MB_TX_LAST; i++)
+		set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0);
+
+	/* Reset tx and rx helper pointers */
+	priv->tx_next = priv->tx_echo = priv->rx_next = 0;
+}
+
+static int at91_set_bittiming(struct net_device *dev)
+{
+	const struct at91_priv *priv = netdev_priv(dev);
+	const struct can_bittiming *bt = &priv->can.bittiming;
+	u32 reg_br;
+
+	reg_br = ((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) << 24) |
+		((bt->brp - 1) << 16) |	((bt->sjw - 1) << 12) |
+		((bt->prop_seg - 1) << 8) | ((bt->phase_seg1 - 1) << 4) |
+		((bt->phase_seg2 - 1) << 0);
+
+	dev_info(dev->dev.parent, "writing AT91_BR: 0x%08x\n", reg_br);
+
+	at91_write(priv, AT91_BR, reg_br);
+
+	return 0;
+}
+
+static void at91_chip_start(struct net_device *dev)
+{
+	struct at91_priv *priv = netdev_priv(dev);
+	u32 reg_mr, reg_ier;
+
+	/* disable interrupts */
+	at91_write(priv, AT91_IDR, AT91_IRQ_ALL);
+
+	/* disable chip */
+	reg_mr = at91_read(priv, AT91_MR);
+	at91_write(priv, AT91_MR, reg_mr & ~AT91_MR_CANEN);
+
+	at91_setup_mailboxes(dev);
+	at91_transceiver_switch(priv, 1);
+
+	/* enable chip */
+	at91_write(priv, AT91_MR, AT91_MR_CANEN);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	/* Enable interrupts */
+	reg_ier = AT91_IRQ_MB_RX | AT91_IRQ_ERRP | AT91_IRQ_ERR_FRAME;
+	at91_write(priv, AT91_IDR, AT91_IRQ_ALL);
+	at91_write(priv, AT91_IER, reg_ier);
+}
+
+static void at91_chip_stop(struct net_device *dev, enum can_state state)
+{
+	struct at91_priv *priv = netdev_priv(dev);
+	u32 reg_mr;
+
+	/* disable interrupts */
+	at91_write(priv, AT91_IDR, AT91_IRQ_ALL);
+
+	reg_mr = at91_read(priv, AT91_MR);
+	at91_write(priv, AT91_MR, reg_mr & ~AT91_MR_CANEN);
+
+	at91_transceiver_switch(priv, 0);
+	priv->can.state = state;
+}
+
+/*
+ * theory of operation:
+ *
+ * According to the datasheet priority 0 is the highest priority, 15
+ * is the lowest. If two mailboxes have the same priority level the
+ * message of the mailbox with the lowest number is sent first.
+ *
+ * We use the first TX mailbox (AT91_MB_TX_FIRST) with prio 0, then
+ * the next mailbox with prio 0, and so on, until all mailboxes are
+ * used. Then we start from the beginning with mailbox
+ * AT91_MB_TX_FIRST, but with prio 1, mailbox AT91_MB_TX_FIRST + 1
+ * prio 1. When we reach the last mailbox with prio 15, we have to
+ * stop sending, waiting for all messages to be delivered, then start
+ * again with mailbox AT91_MB_TX_FIRST prio 0.
+ *
+ * We use the priv->tx_next as counter for the next transmission
+ * mailbox, but without the offset AT91_MB_TX_FIRST. The lower bits
+ * encode the mailbox number, the upper 4 bits the mailbox priority:
+ *
+ * priv->tx_next = (prio << AT91_NEXT_PRIO_SHIFT) ||
+ *                 (mb - AT91_MB_TX_FIRST);
+ *
+ */
+static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct at91_priv *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf = (struct can_frame *)skb->data;
+	unsigned int mb, prio;
+	u32 reg_mid, reg_mcr;
+
+	mb = get_tx_next_mb(priv);
+	prio = get_tx_next_prio(priv);
+
+	if (unlikely(!(at91_read(priv, AT91_MSR(mb)) & AT91_MSR_MRDY))) {
+		netif_stop_queue(dev);
+
+		dev_err(dev->dev.parent,
+			"BUG! TX buffer full when queue awake!\n");
+		return NETDEV_TX_BUSY;
+	}
+
+	if (cf->can_id & CAN_EFF_FLAG)
+		reg_mid = (cf->can_id & CAN_EFF_MASK) | AT91_MID_MIDE;
+	else
+		reg_mid = (cf->can_id & CAN_SFF_MASK) << 18;
+
+	reg_mcr = ((cf->can_id & CAN_RTR_FLAG) ? AT91_MCR_MRTR : 0) |
+		(cf->can_dlc << 16) | AT91_MCR_MTCR;
+
+	/* disable MB while writing ID (see datasheet) */
+	set_mb_mode(priv, mb, AT91_MB_MODE_DISABLED);
+	at91_write(priv, AT91_MID(mb), reg_mid);
+	set_mb_mode_prio(priv, mb, AT91_MB_MODE_TX, prio);
+
+	at91_write(priv, AT91_MDL(mb), *(u32 *)(cf->data + 0));
+	at91_write(priv, AT91_MDH(mb), *(u32 *)(cf->data + 4));
+
+	/* This triggers transmission */
+	at91_write(priv, AT91_MCR(mb), reg_mcr);
+
+	stats->tx_bytes += cf->can_dlc;
+	dev->trans_start = jiffies;
+
+	/* _NOTE_: substract AT91_MB_TX_FIRST offset from mb! */
+	can_put_echo_skb(skb, dev, mb - AT91_MB_TX_FIRST);
+
+	/*
+	 * we have to stop the queue and deliver all messages in case
+	 * of a prio+mb counter wrap around. This is the case if
+	 * tx_next buffer prio and mailbox equals 0.
+	 *
+	 * also stop the queue if next buffer is still in use
+	 * (== not ready)
+	 */
+	priv->tx_next++;
+	if (!(at91_read(priv, AT91_MSR(get_tx_next_mb(priv))) &
+	      AT91_MSR_MRDY) ||
+	    (priv->tx_next & AT91_NEXT_MASK) == 0)
+		netif_stop_queue(dev);
+
+	/* Enable interrupt for this mailbox */
+	at91_write(priv, AT91_IER, 1 << mb);
+
+	return NETDEV_TX_OK;
+}
+
+/**
+ * at91_activate_rx_low - activate lower rx mailboxes
+ * @priv: a91 context
+ *
+ * Reenables the lower mailboxes for reception of new CAN messages
+ */
+static inline void at91_activate_rx_low(const struct at91_priv *priv)
+{
+	u32 mask = AT91_MB_RX_LOW_MASK;
+	at91_write(priv, AT91_TCR, mask);
+}
+
+/**
+ * at91_activate_rx_mb - reactive single rx mailbox
+ * @priv: a91 context
+ * @mb: mailbox to reactivate
+ *
+ * Reenables given mailbox for reception of new CAN messages
+ */
+static inline void at91_activate_rx_mb(const struct at91_priv *priv,
+		unsigned int mb)
+{
+	u32 mask = 1 << mb;
+	at91_write(priv, AT91_TCR, mask);
+}
+
+/**
+ * at91_rx_overflow_err - send error frame due to rx overflow
+ * @dev: net device
+ */
+static void at91_rx_overflow_err(struct net_device *dev)
+{
+	struct net_device_stats *stats = &dev->stats;
+	struct sk_buff *skb;
+	struct can_frame *cf;
+
+	dev_dbg(dev->dev.parent, "RX buffer overflow\n");
+	stats->rx_over_errors++;
+	stats->rx_errors++;
+
+	skb = alloc_can_err_skb(dev, &cf);
+	if (unlikely(!skb))
+		return;
+
+	cf->can_id |= CAN_ERR_CRTL;
+	cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+	netif_receive_skb(skb);
+
+	stats->rx_packets++;
+	stats->rx_bytes += cf->can_dlc;
+}
+
+/**
+ * at91_read_mb - read CAN msg from mailbox (lowlevel impl)
+ * @dev: net device
+ * @mb: mailbox number to read from
+ * @cf: can frame where to store message
+ *
+ * Reads a CAN message from the given mailbox and stores data into
+ * given can frame. "mb" and "cf" must be valid.
+ */
+static void at91_read_mb(struct net_device *dev, unsigned int mb,
+		struct can_frame *cf)
+{
+	const struct at91_priv *priv = netdev_priv(dev);
+	u32 reg_msr, reg_mid;
+
+	reg_mid = at91_read(priv, AT91_MID(mb));
+	if (reg_mid & AT91_MID_MIDE)
+		cf->can_id = ((reg_mid >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
+	else
+		cf->can_id = (reg_mid >> 18) & CAN_SFF_MASK;
+
+	reg_msr = at91_read(priv, AT91_MSR(mb));
+	if (reg_msr & AT91_MSR_MRTR)
+		cf->can_id |= CAN_RTR_FLAG;
+	cf->can_dlc = min_t(__u8, (reg_msr >> 16) & 0xf, 8);
+
+	*(u32 *)(cf->data + 0) = at91_read(priv, AT91_MDL(mb));
+	*(u32 *)(cf->data + 4) = at91_read(priv, AT91_MDH(mb));
+
+	if (unlikely(mb == AT91_MB_RX_LAST && reg_msr & AT91_MSR_MMI))
+		at91_rx_overflow_err(dev);
+}
+
+/**
+ * at91_read_msg - read CAN message from mailbox
+ * @dev: net device
+ * @mb: mail box to read from
+ *
+ * Reads a CAN message from given mailbox, and put into linux network
+ * RX queue, does all housekeeping chores (stats, ...)
+ */
+static void at91_read_msg(struct net_device *dev, unsigned int mb)
+{
+	struct net_device_stats *stats = &dev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+
+	skb = alloc_can_skb(dev, &cf);
+	if (unlikely(!skb)) {
+		stats->rx_dropped++;
+		return;
+	}
+
+	at91_read_mb(dev, mb, cf);
+	netif_receive_skb(skb);
+
+	stats->rx_packets++;
+	stats->rx_bytes += cf->can_dlc;
+}
+
+/**
+ * at91_poll_rx - read multiple CAN messages from mailboxes
+ * @dev: net device
+ * @quota: max number of pkgs we're allowed to receive
+ *
+ * Theory of Operation:
+ *
+ * 12 of the 16 mailboxes on the chip are reserved for RX. we split
+ * them into 2 groups. The lower group holds 8 and upper 4 mailboxes.
+ *
+ * Like it or not, but the chip always saves a received CAN message
+ * into the first free mailbox it finds (starting with the
+ * lowest). This makes it very difficult to read the messages in the
+ * right order from the chip. This is how we work around that problem:
+ *
+ * The first message goes into mb nr. 0 and issues an interrupt. All
+ * rx ints are disabled in the interrupt handler and a napi poll is
+ * scheduled. We read the mailbox, but do _not_ reenable the mb (to
+ * receive another message).
+ *
+ *    lower mbxs      upper
+ *   ______^______    __^__
+ *  /             \  /     \
+ * +-+-+-+-+-+-+-+-++-+-+-+-+
+ * |x|x|x|x|x|x|x|x|| | | | |
+ * +-+-+-+-+-+-+-+-++-+-+-+-+
+ *  0 0 0 0 0 0  0 0 0 0 1 1  \ mail
+ *  0 1 2 3 4 5  6 7 8 9 0 1  / box
+ *
+ * The variable priv->rx_next points to the next mailbox to read a
+ * message from. As long we're in the lower mailboxes we just read the
+ * mailbox but not reenable it.
+ *
+ * With completion of the last of the lower mailboxes, we reenable the
+ * whole first group, but continue to look for filled mailboxes in the
+ * upper mailboxes. Imagine the second group like overflow mailboxes,
+ * which takes CAN messages if the lower goup is full. While in the
+ * upper group we reenable the mailbox right after reading it. Giving
+ * the chip more room to store messages.
+ *
+ * After finishing we look again in the lower group if we've still
+ * quota.
+ *
+ */
+static int at91_poll_rx(struct net_device *dev, int quota)
+{
+	struct at91_priv *priv = netdev_priv(dev);
+	u32 reg_sr = at91_read(priv, AT91_SR);
+	const unsigned long *addr = (unsigned long *)&reg_sr;
+	unsigned int mb;
+	int received = 0;
+
+	if (priv->rx_next > AT91_MB_RX_LOW_LAST &&
+	    reg_sr & AT91_MB_RX_LOW_MASK)
+		dev_info(dev->dev.parent,
+			 "order of incoming frames cannot be guaranteed\n");
+
+ again:
+	for (mb = find_next_bit(addr, AT91_MB_RX_NUM, priv->rx_next);
+	     mb < AT91_MB_RX_NUM && quota > 0;
+	     reg_sr = at91_read(priv, AT91_SR),
+	     mb = find_next_bit(addr, AT91_MB_RX_NUM, ++priv->rx_next)) {
+		at91_read_msg(dev, mb);
+
+		/* reactivate mailboxes */
+		if (mb == AT91_MB_RX_LOW_LAST)
+			/* all lower mailboxed, if just finished it */
+			at91_activate_rx_low(priv);
+		else if (mb > AT91_MB_RX_LOW_LAST)
+			/* only the mailbox we read */
+			at91_activate_rx_mb(priv, mb);
+
+		received++;
+		quota--;
+	}
+
+	/* upper group completed, look again in lower */
+	if (priv->rx_next > AT91_MB_RX_LOW_LAST &&
+	    quota > 0 && mb >= AT91_MB_RX_NUM) {
+		priv->rx_next = 0;
+		goto again;
+	}
+
+	return received;
+}
+
+static void at91_poll_err_frame(struct net_device *dev,
+		struct can_frame *cf, u32 reg_sr)
+{
+	struct at91_priv *priv = netdev_priv(dev);
+
+	/* CRC error */
+	if (reg_sr & AT91_IRQ_CERR) {
+		dev_dbg(dev->dev.parent, "CERR irq\n");
+		dev->stats.rx_errors++;
+		priv->can.can_stats.bus_error++;
+		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+	}
+
+	/* Stuffing Error */
+	if (reg_sr & AT91_IRQ_SERR) {
+		dev_dbg(dev->dev.parent, "SERR irq\n");
+		dev->stats.rx_errors++;
+		priv->can.can_stats.bus_error++;
+		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+		cf->data[2] |= CAN_ERR_PROT_STUFF;
+	}
+
+	/* Acknowledgement Error */
+	if (reg_sr & AT91_IRQ_AERR) {
+		dev_dbg(dev->dev.parent, "AERR irq\n");
+		dev->stats.tx_errors++;
+		cf->can_id |= CAN_ERR_ACK;
+	}
+
+	/* Form error */
+	if (reg_sr & AT91_IRQ_FERR) {
+		dev_dbg(dev->dev.parent, "FERR irq\n");
+		dev->stats.rx_errors++;
+		priv->can.can_stats.bus_error++;
+		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+		cf->data[2] |= CAN_ERR_PROT_FORM;
+	}
+
+	/* Bit Error */
+	if (reg_sr & AT91_IRQ_BERR) {
+		dev_dbg(dev->dev.parent, "BERR irq\n");
+		dev->stats.tx_errors++;
+		priv->can.can_stats.bus_error++;
+		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+		cf->data[2] |= CAN_ERR_PROT_BIT;
+	}
+}
+
+static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
+{
+	struct sk_buff *skb;
+	struct can_frame *cf;
+
+	if (quota == 0)
+		return 0;
+
+	skb = alloc_can_err_skb(dev, &cf);
+	if (unlikely(!skb))
+		return 0;
+
+	at91_poll_err_frame(dev, cf, reg_sr);
+	netif_receive_skb(skb);
+
+	dev->last_rx = jiffies;
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += cf->can_dlc;
+
+	return 1;
+}
+
+static int at91_poll(struct napi_struct *napi, int quota)
+{
+	struct net_device *dev = napi->dev;
+	const struct at91_priv *priv = netdev_priv(dev);
+	u32 reg_sr = at91_read(priv, AT91_SR);
+	int work_done = 0;
+
+	if (reg_sr & AT91_IRQ_MB_RX)
+		work_done += at91_poll_rx(dev, quota - work_done);
+
+	/*
+	 * The error bits are clear on read,
+	 * so use saved value from irq handler.
+	 */
+	reg_sr |= priv->reg_sr;
+	if (reg_sr & AT91_IRQ_ERR_FRAME)
+		work_done += at91_poll_err(dev, quota - work_done, reg_sr);
+
+	if (work_done < quota) {
+		/* enable IRQs for frame errors and all mailboxes >= rx_next */
+		u32 reg_ier = AT91_IRQ_ERR_FRAME;
+		reg_ier |= AT91_IRQ_MB_RX & ~AT91_MB_RX_MASK(priv->rx_next);
+
+		napi_complete(napi);
+		at91_write(priv, AT91_IER, reg_ier);
+	}
+
+	return work_done;
+}
+
+/*
+ * theory of operation:
+ *
+ * priv->tx_echo holds the number of the oldest can_frame put for
+ * transmission into the hardware, but not yet ACKed by the CAN tx
+ * complete IRQ.
+ *
+ * We iterate from priv->tx_echo to priv->tx_next and check if the
+ * packet has been transmitted, echo it back to the CAN framework. If
+ * we discover a not yet transmitted package, stop looking for more.
+ *
+ */
+static void at91_irq_tx(struct net_device *dev, u32 reg_sr)
+{
+	struct at91_priv *priv = netdev_priv(dev);
+	u32 reg_msr;
+	unsigned int mb;
+
+	/* masking of reg_sr not needed, already done by at91_irq */
+
+	for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) {
+		mb = get_tx_echo_mb(priv);
+
+		/* no event in mailbox? */
+		if (!(reg_sr & (1 << mb)))
+			break;
+
+		/* Disable irq for this TX mailbox */
+		at91_write(priv, AT91_IDR, 1 << mb);
+
+		/*
+		 * only echo if mailbox signals us a transfer
+		 * complete (MSR_MRDY). Otherwise it's a tansfer
+		 * abort. "can_bus_off()" takes care about the skbs
+		 * parked in the echo queue.
+		 */
+		reg_msr = at91_read(priv, AT91_MSR(mb));
+		if (likely(reg_msr & AT91_MSR_MRDY &&
+			   ~reg_msr & AT91_MSR_MABT)) {
+			/* _NOTE_: substract AT91_MB_TX_FIRST offset from mb! */
+			can_get_echo_skb(dev, mb - AT91_MB_TX_FIRST);
+			dev->stats.tx_packets++;
+		}
+	}
+
+	/*
+	 * restart queue if we don't have a wrap around but restart if
+	 * we get a TX int for the last can frame directly before a
+	 * wrap around.
+	 */
+	if ((priv->tx_next & AT91_NEXT_MASK) != 0 ||
+	    (priv->tx_echo & AT91_NEXT_MASK) == 0)
+		netif_wake_queue(dev);
+}
+
+static void at91_irq_err_state(struct net_device *dev,
+		struct can_frame *cf, enum can_state new_state)
+{
+	struct at91_priv *priv = netdev_priv(dev);
+	u32 reg_idr, reg_ier, reg_ecr;
+	u8 tec, rec;
+
+	reg_ecr = at91_read(priv, AT91_ECR);
+	rec = reg_ecr & 0xff;
+	tec = reg_ecr >> 16;
+
+	switch (priv->can.state) {
+	case CAN_STATE_ERROR_ACTIVE:
+		/*
+		 * from: ERROR_ACTIVE
+		 * to  : ERROR_WARNING, ERROR_PASSIVE, BUS_OFF
+		 * =>  : there was a warning int
+		 */
+		if (new_state >= CAN_STATE_ERROR_WARNING &&
+		    new_state <= CAN_STATE_BUS_OFF) {
+			dev_dbg(dev->dev.parent, "Error Warning IRQ\n");
+			priv->can.can_stats.error_warning++;
+
+			cf->can_id |= CAN_ERR_CRTL;
+			cf->data[1] = (tec > rec) ?
+				CAN_ERR_CRTL_TX_WARNING :
+				CAN_ERR_CRTL_RX_WARNING;
+		}
+	case CAN_STATE_ERROR_WARNING:	/* fallthrough */
+		/*
+		 * from: ERROR_ACTIVE, ERROR_WARNING
+		 * to  : ERROR_PASSIVE, BUS_OFF
+		 * =>  : error passive int
+		 */
+		if (new_state >= CAN_STATE_ERROR_PASSIVE &&
+		    new_state <= CAN_STATE_BUS_OFF) {
+			dev_dbg(dev->dev.parent, "Error Passive IRQ\n");
+			priv->can.can_stats.error_passive++;
+
+			cf->can_id |= CAN_ERR_CRTL;
+			cf->data[1] = (tec > rec) ?
+				CAN_ERR_CRTL_TX_PASSIVE :
+				CAN_ERR_CRTL_RX_PASSIVE;
+		}
+		break;
+	case CAN_STATE_BUS_OFF:
+		/*
+		 * from: BUS_OFF
+		 * to  : ERROR_ACTIVE, ERROR_WARNING, ERROR_PASSIVE
+		 */
+		if (new_state <= CAN_STATE_ERROR_PASSIVE) {
+			cf->can_id |= CAN_ERR_RESTARTED;
+
+			dev_dbg(dev->dev.parent, "restarted\n");
+			priv->can.can_stats.restarts++;
+
+			netif_carrier_on(dev);
+			netif_wake_queue(dev);
+		}
+		break;
+	default:
+		break;
+	}
+
+
+	/* process state changes depending on the new state */
+	switch (new_state) {
+	case CAN_STATE_ERROR_ACTIVE:
+		/*
+		 * actually we want to enable AT91_IRQ_WARN here, but
+		 * it screws up the system under certain
+		 * circumstances. so just enable AT91_IRQ_ERRP, thus
+		 * the "fallthrough"
+		 */
+		dev_dbg(dev->dev.parent, "Error Active\n");
+		cf->can_id |= CAN_ERR_PROT;
+		cf->data[2] = CAN_ERR_PROT_ACTIVE;
+	case CAN_STATE_ERROR_WARNING:	/* fallthrough */
+		reg_idr = AT91_IRQ_ERRA | AT91_IRQ_WARN | AT91_IRQ_BOFF;
+		reg_ier = AT91_IRQ_ERRP;
+		break;
+	case CAN_STATE_ERROR_PASSIVE:
+		reg_idr = AT91_IRQ_ERRA | AT91_IRQ_WARN | AT91_IRQ_ERRP;
+		reg_ier = AT91_IRQ_BOFF;
+		break;
+	case CAN_STATE_BUS_OFF:
+		reg_idr = AT91_IRQ_ERRA | AT91_IRQ_ERRP |
+			AT91_IRQ_WARN | AT91_IRQ_BOFF;
+		reg_ier = 0;
+
+		cf->can_id |= CAN_ERR_BUSOFF;
+
+		dev_dbg(dev->dev.parent, "bus-off\n");
+		netif_carrier_off(dev);
+		priv->can.can_stats.bus_off++;
+
+		/* turn off chip, if restart is disabled */
+		if (!priv->can.restart_ms) {
+			at91_chip_stop(dev, CAN_STATE_BUS_OFF);
+			return;
+		}
+		break;
+	default:
+		break;
+	}
+
+	at91_write(priv, AT91_IDR, reg_idr);
+	at91_write(priv, AT91_IER, reg_ier);
+}
+
+static void at91_irq_err(struct net_device *dev)
+{
+	struct at91_priv *priv = netdev_priv(dev);
+	struct sk_buff *skb;
+	struct can_frame *cf;
+	enum can_state new_state;
+	u32 reg_sr;
+
+	reg_sr = at91_read(priv, AT91_SR);
+
+	/* we need to look at the unmasked reg_sr */
+	if (unlikely(reg_sr & AT91_IRQ_BOFF))
+		new_state = CAN_STATE_BUS_OFF;
+	else if (unlikely(reg_sr & AT91_IRQ_ERRP))
+		new_state = CAN_STATE_ERROR_PASSIVE;
+	else if (unlikely(reg_sr & AT91_IRQ_WARN))
+		new_state = CAN_STATE_ERROR_WARNING;
+	else if (likely(reg_sr & AT91_IRQ_ERRA))
+		new_state = CAN_STATE_ERROR_ACTIVE;
+	else {
+		dev_err(dev->dev.parent, "BUG! hardware in undefined state\n");
+		return;
+	}
+
+	/* state hasn't changed */
+	if (likely(new_state == priv->can.state))
+		return;
+
+	skb = alloc_can_err_skb(dev, &cf);
+	if (unlikely(!skb))
+		return;
+
+	at91_irq_err_state(dev, cf, new_state);
+	netif_rx(skb);
+
+	dev->last_rx = jiffies;
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += cf->can_dlc;
+
+	priv->can.state = new_state;
+}
+
+/*
+ * interrupt handler
+ */
+static irqreturn_t at91_irq(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct at91_priv *priv = netdev_priv(dev);
+	irqreturn_t handled = IRQ_NONE;
+	u32 reg_sr, reg_imr;
+
+	reg_sr = at91_read(priv, AT91_SR);
+	reg_imr = at91_read(priv, AT91_IMR);
+
+	/* Ignore masked interrupts */
+	reg_sr &= reg_imr;
+	if (!reg_sr)
+		goto exit;
+
+	handled = IRQ_HANDLED;
+
+	/* Receive or error interrupt? -> napi */
+	if (reg_sr & (AT91_IRQ_MB_RX | AT91_IRQ_ERR_FRAME)) {
+		/*
+		 * The error bits are clear on read,
+		 * save for later use.
+		 */
+		priv->reg_sr = reg_sr;
+		at91_write(priv, AT91_IDR,
+			   AT91_IRQ_MB_RX | AT91_IRQ_ERR_FRAME);
+		napi_schedule(&priv->napi);
+	}
+
+	/* Transmission complete interrupt */
+	if (reg_sr & AT91_IRQ_MB_TX)
+		at91_irq_tx(dev, reg_sr);
+
+	at91_irq_err(dev);
+
+ exit:
+	return handled;
+}
+
+static int at91_open(struct net_device *dev)
+{
+	struct at91_priv *priv = netdev_priv(dev);
+	int err;
+
+	clk_enable(priv->clk);
+
+	/* check or determine and set bittime */
+	err = open_candev(dev);
+	if (err)
+		goto out;
+
+	/* register interrupt handler */
+	if (request_irq(dev->irq, at91_irq, IRQF_SHARED,
+			dev->name, dev)) {
+		err = -EAGAIN;
+		goto out_close;
+	}
+
+	/* start chip and queuing */
+	at91_chip_start(dev);
+	napi_enable(&priv->napi);
+	netif_start_queue(dev);
+
+	return 0;
+
+ out_close:
+	close_candev(dev);
+ out:
+	clk_disable(priv->clk);
+
+	return err;
+}
+
+/*
+ * stop CAN bus activity
+ */
+static int at91_close(struct net_device *dev)
+{
+	struct at91_priv *priv = netdev_priv(dev);
+
+	netif_stop_queue(dev);
+	napi_disable(&priv->napi);
+	at91_chip_stop(dev, CAN_STATE_STOPPED);
+
+	free_irq(dev->irq, dev);
+	clk_disable(priv->clk);
+
+	close_candev(dev);
+
+	return 0;
+}
+
+static int at91_set_mode(struct net_device *dev, enum can_mode mode)
+{
+	switch (mode) {
+	case CAN_MODE_START:
+		at91_chip_start(dev);
+		netif_wake_queue(dev);
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static const struct net_device_ops at91_netdev_ops = {
+	.ndo_open	= at91_open,
+	.ndo_stop	= at91_close,
+	.ndo_start_xmit	= at91_start_xmit,
+};
+
+static int __init at91_can_probe(struct platform_device *pdev)
+{
+	struct net_device *dev;
+	struct at91_priv *priv;
+	struct resource *res;
+	struct clk *clk;
+	void __iomem *addr;
+	int err, irq;
+
+	clk = clk_get(&pdev->dev, "can_clk");
+	if (IS_ERR(clk)) {
+		dev_err(&pdev->dev, "no clock defined\n");
+		err = -ENODEV;
+		goto exit;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	if (!res || !irq) {
+		err = -ENODEV;
+		goto exit_put;
+	}
+
+	if (!request_mem_region(res->start,
+				resource_size(res),
+				pdev->name)) {
+		err = -EBUSY;
+		goto exit_put;
+	}
+
+	addr = ioremap_nocache(res->start, resource_size(res));
+	if (!addr) {
+		err = -ENOMEM;
+		goto exit_release;
+	}
+
+	dev = alloc_candev(sizeof(struct at91_priv));
+	if (!dev) {
+		err = -ENOMEM;
+		goto exit_iounmap;
+	}
+
+	dev->netdev_ops	= &at91_netdev_ops;
+	dev->irq = irq;
+	dev->flags |= IFF_ECHO;
+
+	priv = netdev_priv(dev);
+	priv->can.clock.freq = clk_get_rate(clk);
+	priv->can.bittiming_const = &at91_bittiming_const;
+	priv->can.do_set_bittiming = at91_set_bittiming;
+	priv->can.do_set_mode = at91_set_mode;
+	priv->reg_base = addr;
+	priv->dev = dev;
+	priv->clk = clk;
+	priv->pdata = pdev->dev.platform_data;
+
+	netif_napi_add(dev, &priv->napi, at91_poll, AT91_NAPI_WEIGHT);
+
+	dev_set_drvdata(&pdev->dev, dev);
+	SET_NETDEV_DEV(dev, &pdev->dev);
+
+	err = register_candev(dev);
+	if (err) {
+		dev_err(&pdev->dev, "registering netdev failed\n");
+		goto exit_free;
+	}
+
+	dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n",
+		 priv->reg_base, dev->irq);
+
+	return 0;
+
+ exit_free:
+	free_netdev(dev);
+ exit_iounmap:
+	iounmap(addr);
+ exit_release:
+	release_mem_region(res->start, resource_size(res));
+ exit_put:
+	clk_put(clk);
+ exit:
+	return err;
+}
+
+static int __devexit at91_can_remove(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+	struct at91_priv *priv = netdev_priv(dev);
+	struct resource *res;
+
+	unregister_netdev(dev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	free_netdev(dev);
+
+	iounmap(priv->reg_base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, resource_size(res));
+
+	clk_put(priv->clk);
+
+	return 0;
+}
+
+static struct platform_driver at91_can_driver = {
+	.probe		= at91_can_probe,
+	.remove		= __devexit_p(at91_can_remove),
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init at91_can_module_init(void)
+{
+	printk(KERN_INFO "%s netdevice driver\n", DRV_NAME);
+	return platform_driver_register(&at91_can_driver);
+}
+
+static void __exit at91_can_module_exit(void)
+{
+	platform_driver_unregister(&at91_can_driver);
+	printk(KERN_INFO "%s: driver removed\n", DRV_NAME);
+}
+
+module_init(at91_can_module_init);
+module_exit(at91_can_module_exit);
+
+MODULE_AUTHOR("Marc Kleine-Budde <mkl@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION(DRV_NAME " CAN netdevice driver");
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 1/3] at91sam9263: add at91_can device to generic device definition
From: Marc Kleine-Budde @ 2009-09-16  9:46 UTC (permalink / raw)
  To: netdev; +Cc: linux-arm-kernel, Socketcan-core, Marc Kleine-Budde, Hans J. Koch
In-Reply-To: <1253094405-3216-1-git-send-email-mkl@pengutronix.de>

This patch adds the device definition for the at91_can device to
the generic device definiton file for the at91sam9263.

Signed-off-by: Hans J. Koch <hjk@linutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 arch/arm/mach-at91/at91sam9263_devices.c |   36 ++++++++++++++++++++++++++++++
 arch/arm/mach-at91/include/mach/board.h  |    6 +++++
 2 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index b7f2332..6026c2e 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -757,6 +757,42 @@ void __init at91_add_device_ac97(struct atmel_ac97_data *data)
 void __init at91_add_device_ac97(struct atmel_ac97_data *data) {}
 #endif
 
+/* --------------------------------------------------------------------
+ *  CAN Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_CAN_AT91) || defined(CONFIG_CAN_AT91_MODULE)
+static struct resource can_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_CAN,
+		.end	= AT91SAM9263_BASE_CAN + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_CAN,
+		.end	= AT91SAM9263_ID_CAN,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9263_can_device = {
+	.name		= "at91_can",
+	.id		= -1,
+	.resource	= can_resources,
+	.num_resources	= ARRAY_SIZE(can_resources),
+};
+
+void __init at91_add_device_can(struct at91_can_data *data)
+{
+	at91_set_A_periph(AT91_PIN_PA13, 0);	/* CANTX */
+	at91_set_A_periph(AT91_PIN_PA14, 0);	/* CANRX */
+	at91sam9263_can_device.dev.platform_data = data;
+
+	platform_device_register(&at91sam9263_can_device);
+}
+#else
+void __init at91_add_device_can(struct at91_can_data *data) {}
+#endif
 
 /* --------------------------------------------------------------------
  *  LCD Controller
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index e6afff8..134731c 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -179,6 +179,12 @@ extern void __init at91_add_device_isi(void);
  /* Touchscreen Controller */
 extern void __init at91_add_device_tsadcc(void);
 
+/* CAN */
+struct at91_can_data {
+	void (*transceiver_switch)(int on);
+};
+extern void __init at91_add_device_can(struct at91_can_data *data);
+
  /* LEDs */
 extern void __init at91_init_leds(u8 cpu_led, u8 timer_led);
 extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 2/3] at91sam9263ek: activate at91 CAN controller
From: Marc Kleine-Budde @ 2009-09-16  9:46 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: Socketcan-core-0fE9KPoRgkgATYTw5x5z8w, Marc Kleine-Budde,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1253094405-3216-2-git-send-email-mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

This patch activates the at91 CAN controller for the at91sam9263ek
development board.

Signed-off-by: Hans J. Koch <hjk-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 arch/arm/mach-at91/board-sam9263ek.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index 57d5252..e6268b3 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -400,6 +400,23 @@ static struct gpio_led ek_pwm_led[] = {
 	}
 };
 
+/*
+ * CAN
+ */
+static void sam9263ek_transceiver_switch(int on)
+{
+	if (on) {
+		at91_set_gpio_output(AT91_PIN_PA18, 1); /* CANRXEN */
+		at91_set_gpio_output(AT91_PIN_PA19, 0); /* CANRS */
+	} else {
+		at91_set_gpio_output(AT91_PIN_PA18, 0); /* CANRXEN */
+		at91_set_gpio_output(AT91_PIN_PA19, 1); /* CANRS */
+	}
+}
+
+static struct at91_can_data ek_can_data = {
+	.transceiver_switch = sam9263ek_transceiver_switch,
+};
 
 static void __init ek_board_init(void)
 {
@@ -431,6 +448,8 @@ static void __init ek_board_init(void)
 	/* LEDs */
 	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
 	at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
+	/* CAN */
+	at91_add_device_can(&ek_can_data);
 }
 
 MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH 0/3] at91_can: add support for Atmel's CAN controller on AT91SAM9263
From: Marc Kleine-Budde @ 2009-09-16  9:46 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: Socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

This patch series add support for Atmels's CAN controller as found
on the AT91SAM9263.

Marc Kleine-Budde (3):
      at91sam9263: add at91_can device to generic device definition
      at91sam9263ek: activate at91 CAN controller
      at91_can: add driver for Atmel's CAN controller on AT91SAM9263

 arch/arm/mach-at91/at91sam9263_devices.c |   36 +
 arch/arm/mach-at91/board-sam9263ek.c     |   19 +
 arch/arm/mach-at91/include/mach/board.h  |    6 +
 drivers/net/can/Kconfig                  |    6 +
 drivers/net/can/Makefile                 |    1 +
 drivers/net/can/at91_can.c               | 1177 ++++++++++++++++++++++++++++++
 6 files changed, 1245 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/can/at91_can.c

^ permalink raw reply

* RE: [Patch net-next]atl1e:fix 2.6.31-git4 -- ATL1E 0000:03:00.0: DMA-API: device driver frees DMA
From: Jie Yang @ 2009-09-16  9:31 UTC (permalink / raw)
  To: Daniel Walker
  Cc: davem@davemloft.net, miles.lane@gmail.com, chris.snook@gmail.com,
	jcliburn@gmail.com, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <1253092251.11643.569.camel@desktop>

On Wednesday, September 16, 2009 5:11 PM
Daniel Walker <dwalker@fifo99.com> wrote:

> On Wed, 2009-09-16 at 14:21 +0800, jie.yang@atheros.com wrote:
> > -           pci_unmap_page(pdev, tx_buffer->dma,
> > +           if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
> > +               pci_unmap_single(pdev, tx_buffer->dma,
> > +                   tx_buffer->length, PCI_DMA_TODEVICE);
> > +           else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
> > +               pci_unmap_page(pdev, tx_buffer->dma,
>
> Could you run this through checkpatch, and fix any errors if
> find? It looks like you uses spaces for tabs in the code
> above, maybe in the other block too..
>
> Daniel
>
>

ou, my mistake, just resend.

Best  wishes
jie

^ permalink raw reply

* [Patch net-next]atl1e:fix 2.6.31-git4 -- ATL1E 0000:03:00.0: DMA-API: device driver frees DMA
From: jie.yang @ 2009-09-16  9:28 UTC (permalink / raw)
  To: davem; +Cc: miles.lane, chris.snook, jcliburn, netdev, linux-kernel, Jie Yang

use the wrong API when free dma. So when map dma use a flag to demostrate whether it is 'pci_map_single' or 'pci_map_page'. When free the dma, check the flags to select the right APIs('pci_unmap_single' or 'pci_unmap_page').

set the flags type to u16  instead of unsigned long  on David's comments.

Signed-off-by: Jie Yang <jie.yang@atheros.com>
---

diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h
index ba48220..490d3b3 100644
--- a/drivers/net/atl1e/atl1e.h
+++ b/drivers/net/atl1e/atl1e.h
@@ -377,10 +377,19 @@ struct atl1e_hw {
  */
 struct atl1e_tx_buffer {
 	struct sk_buff *skb;
+	u16 flags;
+#define ATL1E_TX_PCIMAP_SINGLE		0x0001
+#define ATL1E_TX_PCIMAP_PAGE		0x0002
+#define ATL1E_TX_PCIMAP_TYPE_MASK	0x0003
 	u16 length;
 	dma_addr_t dma;
 };
 
+#define ATL1E_SET_PCIMAP_TYPE(tx_buff, type) do {		\
+	((tx_buff)->flags) &= ~ATL1E_TX_PCIMAP_TYPE_MASK;	\
+	((tx_buff)->flags) |= (type);				\
+	} while (0)
+
 struct atl1e_rx_page {
 	dma_addr_t	dma;    /* receive rage DMA address */
 	u8		*addr;   /* receive rage virtual address */
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index 69b830f..955da73 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -635,7 +635,11 @@ static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter)
 	for (index = 0; index < ring_count; index++) {
 		tx_buffer = &tx_ring->tx_buffer[index];
 		if (tx_buffer->dma) {
-			pci_unmap_page(pdev, tx_buffer->dma,
+			if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
+				pci_unmap_single(pdev, tx_buffer->dma,
+					tx_buffer->length, PCI_DMA_TODEVICE);
+			else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
+				pci_unmap_page(pdev, tx_buffer->dma,
 					tx_buffer->length, PCI_DMA_TODEVICE);
 			tx_buffer->dma = 0;
 		}
@@ -1220,7 +1224,11 @@ static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter)
 	while (next_to_clean != hw_next_to_clean) {
 		tx_buffer = &tx_ring->tx_buffer[next_to_clean];
 		if (tx_buffer->dma) {
-			pci_unmap_page(adapter->pdev, tx_buffer->dma,
+			if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
+				pci_unmap_single(adapter->pdev, tx_buffer->dma,
+					tx_buffer->length, PCI_DMA_TODEVICE);
+			else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
+				pci_unmap_page(adapter->pdev, tx_buffer->dma,
 					tx_buffer->length, PCI_DMA_TODEVICE);
 			tx_buffer->dma = 0;
 		}
@@ -1741,6 +1749,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
 		tx_buffer->length = map_len;
 		tx_buffer->dma = pci_map_single(adapter->pdev,
 					skb->data, hdr_len, PCI_DMA_TODEVICE);
+		ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
 		mapped_len += map_len;
 		use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
 		use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
@@ -1766,6 +1775,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
 		tx_buffer->dma =
 			pci_map_single(adapter->pdev, skb->data + mapped_len,
 					map_len, PCI_DMA_TODEVICE);
+		ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
 		mapped_len  += map_len;
 		use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
 		use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
@@ -1801,6 +1811,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
 						(i * MAX_TX_BUF_LEN),
 						tx_buffer->length,
 						PCI_DMA_TODEVICE);
+			ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_PAGE);
 			use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
 			use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
 					((cpu_to_le32(tx_buffer->length) &

^ permalink raw reply related

* Re: [PATCH V2 2/2] ems_usb: Added support for EMS CPC-USB/ARM7 CAN/USB interface
From: Wolfgang Grandegger @ 2009-09-16  9:26 UTC (permalink / raw)
  To: Sebastian Haas
  Cc: eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
	netdev-u79uwXL29TY76Z2rM5mHXA, oliver-GvhC2dPhHPQdnm+yROfE0A,
	socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	oliver-fJ+pQTUTwRTk1uMJSBkQmQ, greg-U8xfFu+wG4EAvxtiuMwx3w,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <20090916090418.12370.16510.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>

Sebastian Haas wrote:
> This patch adds support for one channel CAN/USB interace CPC-USB/ARM7 from
> EMS Dr. Thomas Wuensche (http://www.ems-wuensche.com).
> 
> Signed-off-by: Sebastian Haas <haas-zsNKPWJ8Pib6hrUXjxyGrA@public.gmane.org>

The cleanup in the probe function is still not OK :-(.

> ---
> 
>  drivers/net/can/Kconfig       |    7 
>  drivers/net/can/Makefile      |    2 
>  drivers/net/can/usb/Makefile  |    5 
>  drivers/net/can/usb/ems_usb.c | 1151 +++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 1165 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/net/can/usb/Makefile
>  create mode 100644 drivers/net/can/usb/ems_usb.c
> 
> diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
> index 0900743..6ac5aa5 100644
> --- a/drivers/net/can/Kconfig
> +++ b/drivers/net/can/Kconfig
> @@ -75,6 +75,13 @@ config CAN_EMS_PCI
>  	  CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche
>  	  (http://www.ems-wuensche.de).
>  
> +config CAN_EMS_USB
> +	tristate "EMS CPC-USB/ARM7 CAN/USB interface"
> +	depends on USB && CAN_DEV
> +	---help---
> +	  This driver is for the one channel CPC-USB/ARM7 CAN/USB interface
> +	  from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
> +
>  config CAN_KVASER_PCI
>  	tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards"
>  	depends on PCI && CAN_SJA1000
> diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
> index 523a941..9b035ec 100644
> --- a/drivers/net/can/Makefile
> +++ b/drivers/net/can/Makefile
> @@ -7,6 +7,8 @@ obj-$(CONFIG_CAN_VCAN)		+= vcan.o
>  obj-$(CONFIG_CAN_DEV)		+= can-dev.o
>  can-dev-y			:= dev.o
>  
> +obj-y				+= usb/
> +
>  obj-$(CONFIG_CAN_SJA1000)	+= sja1000/
>  
>  ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
> diff --git a/drivers/net/can/usb/Makefile b/drivers/net/can/usb/Makefile
> new file mode 100644
> index 0000000..c3f75ba
> --- /dev/null
> +++ b/drivers/net/can/usb/Makefile
> @@ -0,0 +1,5 @@
> +#
> +#  Makefile for the Linux Controller Area Network USB drivers.
> +#
> +
> +obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o
> diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
[snip]
> +/*
> + * probe function for new CPC-USB devices
> + */
> +static int ems_usb_probe(struct usb_interface *intf,
> +			 const struct usb_device_id *id)
> +{
> +	struct net_device *netdev;
> +	struct ems_usb *dev;
> +	int i, err;
> +	int retval = -ENOMEM;

Why do you need an extra variable here.

	int err = -ENOMEM;

Should work fine!?

> +
> +	netdev = alloc_candev(sizeof(struct ems_usb));
> +	if (!netdev) {
> +		dev_err(netdev->dev.parent, "Couldn't alloc candev\n");
> +		return -ENOMEM;
> +	}
> +
> +	dev = netdev_priv(netdev);
> +
> +	dev->udev = interface_to_usbdev(intf);
> +	dev->netdev = netdev;
> +
> +	dev->can.state = CAN_STATE_STOPPED;
> +	dev->can.clock.freq = EMS_USB_ARM7_CLOCK;
> +	dev->can.bittiming_const = &ems_usb_bittiming_const;
> +	dev->can.do_set_bittiming = ems_usb_set_bittiming;
> +	dev->can.do_set_mode = ems_usb_set_mode;
> +
> +	netdev->flags |= IFF_ECHO; /* we support local echo */
> +
> +	/*
> +	 * The device actually uses a 16MHz clock to generate the CAN clock
> +	 * but it expects SJA1000 bit settings based on 8MHz (is internally
> +	 * converted).
> +	 */
> +
> +	netdev->netdev_ops = &ems_usb_netdev_ops;
> +
> +	netdev->flags |= IFF_ECHO; /* we support local echo */
> +
> +	init_usb_anchor(&dev->rx_submitted);
> +
> +	init_usb_anchor(&dev->tx_submitted);
> +	atomic_set(&dev->active_tx_urbs, 0);
> +
> +	for (i = 0; i < MAX_TX_URBS; i++)
> +		dev->tx_contexts[i].echo_index = MAX_TX_URBS;
> +
> +	dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
> +	if (!dev->intr_urb) {
> +		dev_err(netdev->dev.parent, "Couldn't alloc intr URB\n");
> +		goto cleanup_candev;
> +	}
> +
> +	dev->intr_in_buffer = kzalloc(INTR_IN_BUFFER_SIZE, GFP_KERNEL);
> +	if (!dev->intr_in_buffer) {
> +		dev_err(netdev->dev.parent, "Couldn't alloc Intr buffer\n");
> +		goto cleanup_intr_urb;
> +	}
> +
> +	dev->tx_msg_buffer = kzalloc(CPC_HEADER_SIZE +
> +				     sizeof(struct ems_cpc_msg), GFP_KERNEL);
> +	if (!dev->tx_msg_buffer) {
> +		dev_err(netdev->dev.parent, "Couldn't alloc Tx buffer\n");
> +		goto cleanup_intr_in_buffer;
> +	}
> +
> +	usb_set_intfdata(intf, dev);
> +
> +	SET_NETDEV_DEV(netdev, &intf->dev);
> +
> +	init_params_sja1000(&dev->active_params);
> +
> +	err = ems_usb_command_msg(dev, &dev->active_params);
> +	if (err) {
> +		dev_err(netdev->dev.parent,
> +			"couldn't initialize controller: %d\n", err);
> +		retval = err;

Could be removed then.

> +		goto cleanup_tx_msg_buffer;
> +	}
> +
> +	return register_candev(netdev);

Cleanup is missing if register_candev() fails!

> +
> +cleanup_tx_msg_buffer:
> +	kfree(dev->tx_msg_buffer);
> +
> +cleanup_intr_in_buffer:
> +	kfree(dev->intr_in_buffer);
> +
> +cleanup_intr_urb:
> +	usb_free_urb(dev->intr_urb);
> +
> +cleanup_candev:
> +	free_candev(netdev);
> +
> +	return retval;
> +}

Wolfgang.

^ permalink raw reply

* Re: [E1000-devel] [BUG 2.6.30+] e100 sometimes causes oops during resume
From: Karol Lewandowski @ 2009-09-16  9:19 UTC (permalink / raw)
  To: Karol Lewandowski
  Cc: Graham, David, Rafael J. Wysocki, linux-kernel@vger.kernel.org,
	e1000-devel@lists.sourceforge.net, netdev@vger.kernel.org
In-Reply-To: <20090916014448.GA1070@bizet.domek.prywatny>

On Wed, Sep 16, 2009 at 03:44:48AM +0200, Karol Lewandowski wrote:
> On Tue, Sep 15, 2009 at 03:54:20PM -0700, Graham, David wrote:
> 
> > A v2.6.30..v2.6.31 diff shows that this is probably exposed by
> > Rafael Wysocki's commit 6905b1f1, which now allows systems with e100
> > to sleep. If I understand correctly, it looks like these systems
> > simply couldn't sleep before. Is that right Rafael?.
> 
> Probably true, but that wasn't the case for my (I guess
> ACPI-controlled) system.
> 
> 
> > I don't think its likely that the commit is a direct cause of the
> > problem, but that the suspend/resume cycle now allows us to see
> > another issue.
> 
> From my (very limited) understanding commit message is at least in
> conflict with patch body.

No, it isn't, I must just go to bed earlier than 4AM. :/

Sorry for noise.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox