浅析/dev/hidraw0对应的fops操作集-hid设备控制的唯一入口
对于hid设备的完全裸露控制,节点/dev/hidraw0是唯一的入口[luther.gliethttp].
hidraw_init
==> alloc_chrdev_region(&dev_id, HIDRAW_FIRST_MINOR, HIDRAW_MAX_DEVICES, "hidraw"); // 动态获取一个major主设备号[luther.gliethttp]
==> cdev_init(&hidraw_cdev, &hidraw_ops); // /dev/hidraw0...对应的fops方法集
==> cdev_add(&hidraw_cdev, dev_id, HIDRAW_MAX_DEVICES); // 添加到chr数组中,等待open引用
static const struct file_operations hidraw_ops = {
.owner = THIS_MODULE,
.read = hidraw_read, // 获取hid设备的raw数据[luther.gliethttp]
.write = hidraw_write, // 向hid设备直接写入raw数据[luther.gliethttp]
.poll = hidraw_poll,
.open = hidraw_open,
.release = hidraw_release,
.ioctl = hidraw_ioctl,
};
usb_hid_configure
==> hid->hid_output_raw_report = usbhid_output_raw_report; // 向hid设备提交一个out类型的report.[luther.gliethttp]
static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count)
{
struct usbhid_device *usbhid = hid->driver_data;
struct usb_device *dev = hid_to_usb_dev(hid);
struct usb_interface *intf = usbhid->intf;
struct usb_host_interface *interface = intf->cur_altsetting;
int ret;
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
HID_REQ_SET_REPORT,
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
cpu_to_le16(((HID_OUTPUT_REPORT + 1) << 8) | *buf), // buf[0]对应报告描述符report_id值[luther.gliethttp]
interface->desc.bInterfaceNumber, buf + 1, count - 1,
USB_CTRL_SET_TIMEOUT); // 默认5秒超时[luther.gliethttp]
/* count also the report id */
if (ret > 0)
ret++;
return ret;
}
阅读(10564) | 评论(0) | 转发(0) |