60. struct usb_mouse *mouse = urb->context;
61. signed char *data = mouse->data;
62. struct input_dev *dev = mouse->dev;
63. int status;
64. /*
65. * status 值为 0 表示 urb 成功返回,直接跳出循环把鼠标事件报告给输入子系统。
66. * ECONNRESET 出错信息表示 urb 被 usb_unlink_urb 函数给 unlink 了,ENOENT 出错信息表示 urb 被
67. * usb_kill_urb 函数给 kill 了。usb_kill_urb 表示彻底结束 urb 的生命周期,而 usb_unlink_urb 则
68. * 是停止 urb,这个函数不等 urb 完全终止就会返回给回调函数。这在运行中断处理程序时或者等待某自旋锁
69. * 时非常有用,在这两种情况下是不能睡眠的,而等待一个 urb 完全停止很可能会出现睡眠的情况。
70. * ESHUTDOWN 这种错误表示 USB 主控制器驱动程序发生了严重的错误,或者提交完 urb 的一瞬间设备被拔出。
71. * 遇见除了以上三种错误以外的错误,将申请重传 urb。
72. */
73. switch (urb->status)
74. {
75. case 0: /* success */
76. break;
77. case -ECONNRESET: /* unlink */
78. case -ENOENT:
79. case -ESHUTDOWN:
80. return;
81. /* -EPIPE: should clear the halt */
82. default: /* error */
83. goto resubmit;
84. }
85. /*
86. * 向输入子系统汇报鼠标事件情况,以便作出反应。
87. * data 数组的第0个字节:bit 0、1、2、3、4分别代表左、右、中、SIDE、EXTRA键的按下情况;
88. * data 数组的第1个字节:表示鼠标的水平位移;
89. * data 数组的第2个字节:表示鼠标的垂直位移;
90. * data 数组的第3个字节:REL_WHEEL位移。
91. */
92. input_report_key(dev, BTN_LEFT, data[0] & 0x01);
93. input_report_key(dev, BTN_RIGHT, data[0] & 0x02);
94. input_report_key(dev, BTN_MIDDLE, data[0] & 0x04);
95. input_report_key(dev, BTN_SIDE, data[0] & 0x08);
96. input_report_key(dev, BTN_EXTRA, data[0] & 0x10);
97. input_report_rel(dev, REL_X, data[1]);
98. input_report_rel(dev, REL_Y, data[2]);
99. input_report_rel(dev, REL_WHEEL, data[3]);
100. /*
101. * 这里是用于事件同步。上面几行是一次完整的鼠标事件,包括按键信息、绝对坐标信息和滚轮信息,输入子
102. * 系统正是通过这个同步信号来在多个完整事件报告中区分每一次完整事件报告。示意如下:
103. * 按键信息 坐标位移信息 滚轮信息 EV_SYC | 按键信息 坐标位移信息 滚轮信息 EV_SYC ...
104. */
105. input_sync(dev);
106. /*
107. * 系统需要周期性不断地获取鼠标的事件信息,因此在 urb 回调函数的末尾再次提交 urb 请求块,这样又会
108. * 调用新的回调函数,周而复始。
109. * 在回调函数中提交 urb 一定只能是 GFP_ATOMIC 优先级的,因为 urb 回调函数运行于中断上下文中,在提
110. * 交 urb 过程中可能会需要申请内存、保持信号量,这些操作或许会导致 USB core 睡眠,一切导致睡眠的行
111. * 为都是不允许的。
112. */
113. resubmit:
114. status = usb_submit_urb (urb, GFP_ATOMIC);
115. if (status)
116. err ("can't resubmit intr, %s-%s/input0, status %d",
117. mouse->usbdev->bus->bus_name,
118. mouse->usbdev->devpath, status);
119. }
责任编辑:小草