Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
那么什么时候我们需要调用这个函数呢?先不说我们这里的上下文,实际上usb spec 规定了,对于设备的<br />
bulk 端点,每当设备在reset 之后,需要清除halt 这个feature 然后端点才能正常工作.所以之后我们会<br />
看<br />
到,在reset 相关的函数里我们会调用这个函数,那么我们此刻所遇到的这个函数是处于什么情景呢?如果<br />
不<br />
看注释你就能看懂,那么我只能说,你他妈的太有才了!开源社区需要你这样伟大的自由主义战士!注释里说<br />
得很清楚,有些变态的设备,它就是不跟你按常理出牌,人家能正常响应GetMaxLUN 这个request,它偏要<br />
耍个性,就是不认spec,你发送GetMaxLUN 请求过来,它不予回复,它出现STALL 的特点,什么是STALL?<br />
其实就是Halt,端点挂起,或者通俗一点理解,就是死机了.所以,毫无疑问,我们要把这个halt 给清掉,否则设<br />
别没有办法工作了.<br />
Ok,是时候该看看函数内部了,这是一个定义于drivers/usb/storage/transport.c 中的函<br />
数.usb_stor_clear_halt():<br />
243 /* This is a version <strong>of</strong> usb_clear_halt() that allows early termination and<br />
244 * doesn't read the status from the device -- this is because some devices<br />
245 * crash their internal firmware when the status is requested after a halt.<br />
246 *<br />
247 * A definitive list <strong>of</strong> these 'bad' devices is too difficult to maintain or<br />
248 * make complete enough to be useful. This problem was first observed on the<br />
249 * Hagiwara FlashGate DUAL unit. However, bus traces reveal that neither<br />
250 * MacOS nor Windows checks the status after clearing a halt.<br />
251 *<br />
252 * Since many vendors in this space limit their testing to interoperability<br />
253 * with these two OSes, specification violations like this one are common.<br />
254 */<br />
255 int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)<br />
256 {<br />
257 int result;<br />
258 int endp = usb_pipeendpoint(pipe);<br />
259<br />
260 if (usb_pipein (pipe))<br />
261 endp |= USB_DIR_IN;<br />
262<br />
263 result = usb_stor_control_msg(us, us->send_ctrl_pipe,<br />
264 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,<br />
265 USB_ENDPOINT_HALT, endp,<br />
266 NULL, 0, 3*HZ);<br />
267<br />
268 /* reset the endpoint toggle */<br />
269 usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe),<br />
270 usb_pipeout(pipe), 0);<br />
271<br />
272 US_DEBUGP("%s: result = %d\n", __FUNCTION__, result);<br />
273 return result;<br />
274 }