文章目录
任务1:编写USB设备驱动程序(40min)
任务要求
- 参考内核源码中的drivers/usb/usb-skeleton.c文件,编写一个USB探测驱动程序,能够实现以下基本功能:
(1)在插入U盘时能够探测到;
(2)在拔出U盘时能够探测到; - 加载、卸载模块并查看模块打印信息。
任务代码
usb_detect.c
/*
* USB Detect driver
*
* This driver is based on the 2.6.3 version of drivers/usb/usb-skeleton.c
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kref.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/mutex.h>
/* Define these values to match your devices */
#define USB_DETECT_VENDOR_ID 0x0951
#define USB_DETECT_PRODUCT_ID 0x160b
/* table of devices that work with this driver */
static const struct usb_device_id usbdetect_table[] = {
{
USB_DEVICE(USB_DETECT_VENDOR_ID, USB_DETECT_PRODUCT_ID) },
{
} /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, usbdetect_table);
/* Get a minor range for your devices from the usb maintainer */
#define USB_DETECT_MINOR_BASE 192
#define WRITES_IN_FLIGHT 8
/* arbitrarily chosen */
/* Structure to hold all of our device specific stuff */
struct usb_detect {
struct usb_device *udev; /* the usb device for this device */
struct usb_interface *interface; /* the interface for this device */
struct semaphore limit_sem; /* limiting the number of writes in progress */
struct usb_anchor submitted; /* in case we need to retract our submissions */
struct urb *bulk_in_urb; /* the urb to read data with */
unsigned char *bulk_in_buffer; /* the buffer to receive data */
size_t bulk_in_size; /* the size of the receive buffer */
size_t bulk_in_filled; /* number of bytes in the buffer */
size_t bulk_in_copied; /* already copied to user space */
__u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
__u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
int errors; /* the last request tanked */
bool ongoing_read; /* a read is going on */
spinlock_t err_lock; /* lock for errors */
struct kref kref;
struct mutex io_mutex; /* synchronize I/O with disconnect */
unsigned long disconnected:1;
wait_queue_head_t bulk_in_wait; /* to wait for an ongoing read */
};
#define to_detect_dev(d) container_of(d, struct usb_detect, kref)
static struct usb_driver usbdetect_driver;
static void usbdetect_delete(struct kref *kref)
{
struct usb_detect *dev = to_detect_dev(kref);
usb_free_urb(dev->bulk_in_urb);
usb_put_intf(dev->interface);
usb_put_dev(dev->udev);
kfree(dev->bulk_in_buffer);
kfree(dev);
}
static const struct file_operations usbdetect_fops = {
};
/*
* usb class driver info in order to get a minor number from