#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/mutex.h>
+#include <linux/netdevice.h>
+#include <linux/version.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
#define CTU_USBCAN_VENDOR_ID 0x1669
#define CTU_USBCAN_PRODUCT_ID 0x1011
+MODULE_LICENSE("GPL");
/* table of devices that work with this driver */
static struct usb_device_id ctu_usbcan_table [] = {
static struct usb_driver ctu_usbcan_driver;
+/* Structure to hold all of our device specific stuff */
+struct ctu_usbcan_usb {
+
+ struct can_priv can; /* must be the first member */
+
+ struct usb_device *udev; /* the usb device for this device */
+ struct net_device *netdev;
+};
+
+static int ctu_usbcan_open(struct net_device *netdev)
+{
+ return 0;
+}
+
+static int ctu_usbcan_close(struct net_device *netdev)
+{
+ return 0;
+}
+
+static const struct net_device_ops ctu_usbcan_netdev_ops = {
+ .ndo_open = ctu_usbcan_open,
+ .ndo_stop = ctu_usbcan_close,
+};
-static int ctu_usbcan_probe(struct usb_interface *interface, const struct usb_device_id *id)
+static int ctu_usbcan_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
+ struct net_device *netdev;
+ struct ctu_usbcan_usb *dev;
+ int err = -ENOMEM;
printk(KERN_INFO "CTU USBCAN device now attached\n");
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
+ netdev = alloc_candev(sizeof(struct ctu_usbcan_usb), MAX_TX_URBS);
+#else
+ netdev = alloc_candev(sizeof(struct ctu_usbcan_usb));
+#endif
+
+ if (!netdev) {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32)
+ dev_err(&intf->dev, "ems_usb: Couldn't alloc candev\n");
+#else
+ dev_err(netdev->dev.parent, "Couldn't alloc candev\n");
+#endif
+ return -ENOMEM;
+ }
+
+ dev = netdev_priv(netdev);
+
+ dev->udev = interface_to_usbdev(intf);
+ dev->netdev = netdev;
+
+
+ netdev->netdev_ops = &ctu_usbcan_netdev_ops;
+ netdev->flags |= IFF_ECHO;
+
+ usb_set_intfdata(intf, dev);
+ SET_NETDEV_DEV(netdev, &intf->dev);
+
+
+ err = register_candev(netdev);
+ if (err) {
+ dev_err(netdev->dev.parent,
+ "couldn't register CAN device: %d\n", err);
+ }
+
return 0;
}
/* called by the usb core when the device is removed from the system */
-static void ctu_usbcan_disconnect(struct usb_interface *interface)
+static void ctu_usbcan_disconnect(struct usb_interface *intf)
{
+ struct ctu_usbcan_usb *dev = usb_get_intfdata(intf);
+
printk(KERN_INFO "CTU USBCAN device now disconnected\n");
+ usb_set_intfdata(intf, NULL);
+
+ if (dev) {
+ unregister_netdev(dev->netdev);
+ free_candev(dev->netdev);
+ }
+
}
/* usb specific object needed to register this driver with the usb subsystem */
module_init(ctu_usbcan_init);
module_exit(ctu_usbcan_exit);
-MODULE_LICENSE("GPL");