Linux usb子系统(二)(3)

skel_open()
--90-->从inode中获取次设备号
--92-->根据skel_driver对象和次设备号获取usb_interface对象,至此就找到了设备
--100-->从interface->dev->p->driver_data中获取资源对象的地址,这个地址是在probe--555--中藏到这的
--110-->引用计数加一
--114-->关键,将之前获得的资源对象的地址藏在file->private_data中,这样在所有的cdev接口之间都可以使用资源对象了,和将资源对象地址藏到interface中以便在usb_driver的接口函数之间流动的思想是一样的。

read

打开了设备,接下来就可以读写了,skeleton中对于读操作的关键函数调用关系如下,我们依照这个调用树依次分析

skel_read()
skel_do_read_io(dev, count)
usb_fill_bulk_urb(...);
usb_submit_urb(dev->bulk_in_urb, GFP_KERNEL);

首先是skel_read(),这个函数是应用层读设备时回调的函数,它试图实现这样一个功能: 如果内核缓冲区有数据就将适当的数据拷贝给应用层, 如果没有就调用skel_do_read_io来向设备请求数据

226 static ssize_t skel_read(struct file *file, char *buffer, size_t count, 227 loff_t *ppos) 228 { 229 struct usb_skel *dev; 230 int rv; 231 bool ongoing_io; 232 233 dev = file->private_data; 255 if (ongoing_io) { 256 /* nonblocking IO shall not wait */ 257 if (file->f_flags & O_NONBLOCK) { 258 rv = -EAGAIN; 259 goto exit; 260 } 265 rv = wait_event_interruptible(dev->bulk_in_wait, (!dev->ongoing_read)); 266 if (rv < 0) 267 goto exit; 268 } 269 270 /* errors must be reported */ 271 rv = dev->errors; 272 if (rv < 0) { 273 /* any error is reported once */ 274 dev->errors = 0; 275 /* to preserve notifications about reset */ 276 rv = (rv == -EPIPE) ? rv : -EIO; 277 /* report it */ 278 goto exit; 279 } 286 if (dev->bulk_in_filled) { 287 /* we had read data */ 288 size_t available = dev->bulk_in_filled - dev->bulk_in_copied; 289 size_t chunk = min(available, count); 290 291 if (!available) { 296 rv = skel_do_read_io(dev, count); 297 if (rv < 0) 298 goto exit; 299 else 300 goto retry; 301 } 307 if (copy_to_user(buffer, 308 dev->bulk_in_buffer + dev->bulk_in_copied, 309 chunk)) 310 rv = -EFAULT; 311 else 312 rv = chunk; 313 314 dev->bulk_in_copied += chunk; 320 if (available < count) 321 skel_do_read_io(dev, count - chunk); 322 } else { 323 /* no data in the buffer */ 324 rv = skel_do_read_io(dev, count); 325 if (rv < 0) 326 goto exit; 327 else 328 goto retry; 329 } 330 exit: 331 mutex_unlock(&dev->io_mutex); 332 return rv; 333 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/b6145cb911cf25495391e7483184a16b.html