Created
December 27, 2018 09:38
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <linux/kernel.h> | |
#include <linux/module.h> | |
#include <linux/usb.h> | |
MODULE_LICENSE("GPL"); | |
#define USB_VENDOR_ID 0x18ec | |
#define USB_PRODUCT_ID 0x3299 | |
#define MYUSB_MINOR_BASE 250 | |
#define DUMP_USB_INTERFACE_DESCRIPTOR( i ) \ | |
{\ | |
pr_info("USB_INTERFACE_DESCRIPTOR:\n"); \ | |
pr_info("-----------------------------\n"); \ | |
pr_info("bLength: 0x%x\n", i.bLength); \ | |
pr_info("bDescriptorType: 0x%x\n", i.bDescriptorType); \ | |
pr_info("bInterfaceNumber: 0x%x\n", i.bInterfaceNumber); \ | |
pr_info("bAlternateSetting: 0x%x\n", i.bAlternateSetting); \ | |
pr_info("bNumEndpoints: 0x%x\n", i.bNumEndpoints); \ | |
pr_info("bInterfaceClass: 0x%x\n", i.bInterfaceClass); \ | |
pr_info("bInterfaceSubClass: 0x%x\n", i.bInterfaceSubClass); \ | |
pr_info("bInterfaceProtocol: 0x%x\n", i.bInterfaceProtocol); \ | |
pr_info("iInterface: 0x%x\n", i.iInterface); \ | |
pr_info("\n"); \ | |
} | |
#define DUMP_USB_ENDPOINT_DESCRIPTOR( e ) \ | |
{\ | |
pr_info("USB_ENDPOINT_DESCRIPTOR:\n"); \ | |
pr_info("------------------------\n"); \ | |
pr_info("bLength: 0x%x\n", e.bLength); \ | |
pr_info("bDescriptorType: 0x%x\n", e.bDescriptorType); \ | |
pr_info("bEndPointAddress: 0x%x\n", e.bEndpointAddress); \ | |
pr_info("bmAttributes: 0x%x\n", e.bmAttributes); \ | |
pr_info("wMaxPacketSize: 0x%x\n", e.wMaxPacketSize); \ | |
pr_info("bInterval: 0x%x\n", e.bInterval); \ | |
pr_info("\n"); \ | |
} | |
const struct usb_device_id usb_table[] = { | |
{ USB_DEVICE(USB_VENDOR_ID, USB_PRODUCT_ID) }, | |
{ } | |
}; | |
MODULE_DEVICE_TABLE(usb, usb_table); | |
static int myusb_open(struct inode *inode, struct file *file) | |
{ | |
pr_info("%s\n", __func__); | |
return 0; | |
} | |
static int myusb_release(struct inode *inode, struct file *file) | |
{ | |
pr_info("%s\n", __func__); | |
return 0; | |
} | |
static ssize_t myusb_write(struct file *file, const char *user_buffer, | |
size_t count, loff_t *ppos) | |
{ | |
pr_info("%s\n", __func__); | |
return count; | |
} | |
static ssize_t myusb_read(struct file *file, char *buffer, size_t count, | |
loff_t *ppos) | |
{ | |
pr_info("%s\n", __func__); | |
return 0; | |
} | |
static const struct file_operations myusb_fops = { | |
.owner = THIS_MODULE, | |
.open = myusb_open, | |
.release = myusb_release, | |
.read = myusb_read, | |
.write = myusb_write, | |
}; | |
static struct usb_class_driver myusb_class = { | |
.name = "mydevice%d", | |
.fops = &myusb_fops, | |
.minor_base = MYUSB_MINOR_BASE, | |
}; | |
static int usb_probe(struct usb_interface *interface, | |
const struct usb_device_id *id) | |
{ | |
unsigned int i; | |
unsigned int num_endpoints; | |
struct usb_host_interface *iface_desc = interface->cur_altsetting; | |
dev_info(&interface->dev, "USB Driver Probed: Vendor ID:%02x\t" | |
"Product ID:%02x\n", id->idVendor, id->idProduct); | |
num_endpoints = iface_desc->desc.bNumEndpoints; | |
DUMP_USB_INTERFACE_DESCRIPTOR(iface_desc->desc); | |
for (i = 0; i < num_endpoints; i++) { | |
DUMP_USB_ENDPOINT_DESCRIPTOR(iface_desc->endpoint[i].desc); | |
} | |
return usb_register_dev(interface, &myusb_class);; | |
} | |
static void usb_disconnect(struct usb_interface *interface) | |
{ | |
usb_deregister_dev(interface, &myusb_class); | |
dev_info(&interface->dev, "USB Driver Disconected\n"); | |
} | |
static struct usb_driver usb_hello_driver = { | |
.name = "hello", | |
.probe = usb_probe, | |
.disconnect = usb_disconnect, | |
.id_table = usb_table, | |
}; | |
module_usb_driver(usb_hello_driver); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment