LINUX usb-skeleton断开函数skel_disconnect
2024-03-08
128
0
skel_disconnect函数很有特点,之所以这么说是我们达到了共鸣。
在之前skel_probe函数中,其使用如下代码:
struct usb_skel *dev;
/* allocate memory for our device state and initialize it */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
...
usb_set_intfdata(interface, dev);
存储了私有数据usb_skel结构体。那么当要断开设备时,需要对在prob中申请的资源进行释放。
static void skel_disconnect(struct usb_interface *interface)
{
struct usb_skel *dev;
int minor = interface->minor;
dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
...
}
可见,interface作为通用的参数在各个函数中来传递,但实际在函数内部需要使用usb_get_intfdata函数获取私有数据。
这就和Windows驱动中,通用数据结构使用的是PDEVICE_OBJECT指针,但私有数据结构又在DeviceExtension成员中。故在函数中都有类似的操作:
NTSTATUS
FdoStartDevice(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PFDO_DEVICE_EXTENSION FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
}
对于其它的回调函数:
static struct usb_driver skel_driver = {
.name = "skeleton",
.probe = skel_probe,
.disconnect = skel_disconnect,
.suspend = skel_suspend,
.resume = skel_resume,
.pre_reset = skel_pre_reset,
.post_reset = skel_post_reset,
.id_table = skel_table,
.supports_autosuspend = 1,
};
我们可以一一查看其函数原型:
static int skel_suspend(struct usb_interface *intf, pm_message_t message)
{
struct usb_skel *dev = usb_get_intfdata(intf);
if (!dev)
return 0;
skel_draw_down(dev);
return 0;
}
static int skel_resume(struct usb_interface *intf)
{
return 0;
}
static int skel_pre_reset(struct usb_interface *intf)
{
struct usb_skel *dev = usb_get_intfdata(intf);
mutex_lock(&dev->io_mutex);
skel_draw_down(dev);
return 0;
}
static int skel_post_reset(struct usb_interface *intf)
{
struct usb_skel *dev = usb_get_intfdata(intf);
/* we are sure no URBs are active - no locking needed */
dev->errors = -EPIPE;
mutex_unlock(&dev->io_mutex);
return 0;
}
可见,函数具有一统的入参struct usb_interface *intf
,它就是我们Windows驱动中的PDEVICE_OBJECT 对象。