标签:counter 空间 cmd 处理 传输 class cond dir 通过
本文转载自:http://www.360doc.com/content/12/0321/14/8363527_196286673.shtml
1 /* 2 * USB Skeleton driver - 0.6 3 * 4 * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * 12 * This driver is to be used as a skeleton driver to be able to create a 13 * USB driver quickly. The design of it is based on the usb-serial and 14 * dc2xx drivers. 15 * 16 * Thanks to Oliver Neukum and David Brownell for their help in debugging 17 * this driver. 18 * 19 * TODO: 20 * - fix urb->status race condition in write sequence 21 * - move minor_table to a dynamic list. 22 * 23 * History: 24 * 25 * 2001_11_05 - 0.6 - fix minor locking problem in skel_disconnect. 26 * Thanks to Pete Zaitcev for the fix. 27 * 2001_09_04 - 0.5 - fix devfs bug in skel_disconnect. Thanks to wim delvaux 28 * 2001_08_21 - 0.4 - more small bug fixes. 29 * 2001_05_29 - 0.3 - more bug fixes based on review from linux-usb-devel 30 * 2001_05_24 - 0.2 - bug fixes based on review from linux-usb-devel people 31 * 2001_05_01 - 0.1 - first version 32 * 33 */ 34 #include <linux/config.h> 35 #include <linux/kernel.h> 36 #include <linux/sched.h> 37 #include <linux/signal.h> 38 #include <linux/errno.h> 39 #include <linux/poll.h> 40 #include <linux/init.h> 41 #include <linux/slab.h> 42 #include <linux/fcntl.h> 43 #include <linux/module.h> 44 #include <linux/spinlock.h> 45 #include <linux/list.h> 46 #include <linux/smp_lock.h> 47 #include <linux/devfs_fs_kernel.h> 48 #include <linux/usb.h> 49 #ifdef CONFIG_USB_DEBUG 50 static int debug = 1; 51 #else 52 static int debug; 53 #endif 54 //一个宏,用来调试时使用 55 /* Use our own dbg macro */ 56 #undef dbg 57 #define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0) 58 59 /* Version Information */ 60 #define DRIVER_VERSION "v0.4" 61 #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com" 62 #define DRIVER_DESC "USB Skeleton Driver" 63 //参量,可以在lsmod中更改 64 /* Module paramaters */ 65 MODULE_PARM(debug, "i"); 66 MODULE_PARM_DESC(debug, "Debug enabled or not"); 67 //分别是厂商id和产品id 68 /* Define these values to match your device */ 69 #define USB_SKEL_VENDOR_ID 0xfff0 70 #define USB_SKEL_PRODUCT_ID 0xfff0 71 //根据厂商和芯片id创建usb_device_id结构体 72 /* table of devices that work with this driver */ 73 static struct usb_device_id skel_table [] = { 74 { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, 75 { } /* Terminating entry */ 76 }; 77 //将此结构体注册,提供给用户区空间的工具使用 78 MODULE_DEVICE_TABLE (usb, skel_table); 79 80 //主设备号的起始值 81 /* Get a minor range for your devices from the usb maintainer */ 82 #define USB_SKEL_MINOR_BASE 200 83 //设备数目 84 /* we can have up to this number of device plugged in at once */ 85 #define MAX_DEVICES 16 86 //一个自定义的结构体,用来存储驱动的相关信息 87 //分别是设备,接口,设备句柄,主设备号的起始值,设备个数,中断端点数,批量输入端点数,批量输出端点数, 88 //输入缓冲区首指针,大小,usb的端点地址 89 //输出缓冲区首指针,大小,urb数组,usb的端点地址 90 //工作队列,设备使用计数,信号量 91 /* Structure to hold all of our device specific stuff */ 92 struct usb_skel { 93 struct usb_device * udev; /* save off the usb device pointer */ 94 struct usb_interface * interface; /* the interface for this device */ 95 devfs_handle_t devfs; /* devfs device node */ 96 unsigned char minor; /* the starting minor number for this device */ 97 unsigned char num_ports; /* the number of ports this device has */ 98 char num_interrupt_in; /* number of interrupt in endpoints we have */ 99 char num_bulk_in; /* number of bulk in endpoints we have */ 100 char num_bulk_out; /* number of bulk out endpoints we have */ 101 unsigned char * bulk_in_buffer; /* the buffer to receive data */ 102 int bulk_in_size; /* the size of the receive buffer */ 103 __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ 104 unsigned char * bulk_out_buffer; /* the buffer to send data */ 105 int bulk_out_size; /* the size of the send buffer */ 106 struct urb * write_urb; /* the urb used to send data */ 107 __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ 108 struct tq_struct tqueue; /* task queue for line discipline waking up */ 109 int open_count; /* number of times this port has been opened */ 110 struct semaphore sem; /* locks this structure */ 111 }; 112 //设备句柄 113 /* the global usb devfs handle */ 114 extern devfs_handle_t usb_devfs_handle; 115 //用来注册file_operations结构体的一些函数 116 /* local function prototypes */ 117 static ssize_t skel_read (struct file *file, char *buffer, size_t count, loff_t *ppos); 118 static ssize_t skel_write (struct file *file, const char *buffer, size_t count, loff_t *ppos); 119 static int skel_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); 120 static int skel_open (struct inode *inode, struct file *file); 121 static int skel_release (struct inode *inode, struct file *file); 122 123 static void * skel_probe (struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id); 124 static void skel_disconnect (struct usb_device *dev, void *ptr); 125 static void skel_write_bulk_callback (struct urb *urb); 126 //保存usb设备信息的结构体 127 /* array of pointers to our devices that are currently connected */ 128 static struct usb_skel *minor_table[MAX_DEVICES]; 129 //初始化信号量 130 /* lock to protect the minor_table structure */ 131 static DECLARE_MUTEX (minor_table_mutex); 132 /* 133 * File operations needed when we register this driver. 134 * This assumes that this driver NEEDS file operations, 135 * of course, which means that the driver is expected 136 * to have a node in the /dev directory. If the USB 137 * device were for a network interface then the driver 138 * would use "struct net_driver" instead, and a serial 139 * device would use "struct tty_driver". 140 */ 141 //字符串型设备所必须的结构体 142 //依次为所有者,读函数,写函数,控制函数,打开函数,关闭函数 143 static struct file_operations skel_fops = { 144 /* 145 * The owner field is part of the module-locking 146 * mechanism. The idea is that the kernel knows 147 * which module to increment the use-counter of 148 * BEFORE it calls the device‘s open() function. 149 * This also means that the kernel can decrement 150 * the use-counter again before calling release() 151 * or should the open() function fail. 152 * 153 * Not all device structures have an "owner" field 154 * yet. "struct file_operations" and "struct net_device" 155 * do, while "struct tty_driver" does not. If the struct 156 * has an "owner" field, then initialize it to the value 157 * THIS_MODULE and the kernel will handle all module 158 * locking for you automatically. Otherwise, you must 159 * increment the use-counter in the open() function 160 * and decrement it again in the release() function 161 * yourself. 162 */ 163 owner: THIS_MODULE, 164 read: skel_read, 165 write: skel_write, 166 ioctl: skel_ioctl, 167 open: skel_open, 168 release: skel_release, 169 }; 170 //usb设备注册所必需的一个结构体,但只有name, probe, disconnect, idtable, owner五个是必须的 171 /* usb specific object needed to register this driver with the usb subsystem */ 172 static struct usb_driver skel_driver = { 173 owner: THIS_MODULE, 174 name: "skeleton", 175 probe: skel_probe, 176 disconnect: skel_disconnect, 177 fops: &skel_fops, 178 minor: USB_SKEL_MINOR_BASE, 179 id_table: skel_table, 180 }; 181 /** 182 * usb_skel_debug_data 183 */ 184 //用来debug的函数 185 static inline void usb_skel_debug_data (const char *function, int size, const unsigned char *data) 186 { 187 int i; 188 if (!debug) 189 return; 190 191 printk (KERN_DEBUG __FILE__": %s - length = %d, data = ", 192 function, size); 193 for (i = 0; i < size; ++i) { 194 printk ("%.2x ", data[i]); 195 } 196 printk ("\n"); 197 } 198 199 /** 200 * skel_delete 201 */ 202 //usb驱动程序卸载时将调用的函数 203 static inline void skel_delete (struct usb_skel *dev) 204 { 205 minor_table[dev->minor] = NULL; 206 //回收输入缓冲区内存 207 if (dev->bulk_in_buffer != NULL) 208 kfree (dev->bulk_in_buffer); 209 //回收输出缓冲区内存 210 if (dev->bulk_out_buffer != NULL) 211 kfree (dev->bulk_out_buffer); 212 //释放写入urb内存 213 if (dev->write_urb != NULL) 214 usb_free_urb (dev->write_urb); 215 //释放整个结构体 216 kfree (dev); 217 } 218 219 /** 220 * skel_open 221 */ 222 //打开设备函数,主要是用来初始化usb_skel结构体 223 static int skel_open (struct inode *inode, struct file *file) 224 { 225 struct usb_skel *dev = NULL; 226 int subminor; 227 int retval = 0; 228 229 dbg(__FUNCTION__); 230 //检测从设备号是否有问题 231 subminor = MINOR (inode->i_rdev) - USB_SKEL_MINOR_BASE; 232 if ((subminor < 0) || 233 (subminor >= MAX_DEVICES)) { 234 return -ENODEV; 235 } 236 /* Increment our usage count for the module. 237 * This is redundant here, because "struct file_operations" 238 * has an "owner" field. This line is included here soley as 239 * a reference for drivers using lesser structures... ;-) 240 */ 241 MOD_INC_USE_COUNT; 242 //占有全局信号量,进入临界区域 243 /* lock our minor table and get our local data for this minor */ 244 down (&minor_table_mutex); 245 //得到当前设备的第subminor个usb_skel结构体 246 dev = minor_table[subminor]; 247 if (dev == NULL) { 248 //该设备不可用 249 up (&minor_table_mutex); 250 MOD_DEC_USE_COUNT; 251 return -ENODEV; 252 } 253 //占有当前设备的信号量 254 /* lock this device */ 255 down (&dev->sem); 256 //释放全局信号量 257 /* unlock the minor table */ 258 up (&minor_table_mutex); 259 //打开设备计数加一 260 /* increment our usage count for the driver */ 261 ++dev->open_count; 262 //把当前设备的信心保存到设备驱动的结构体中 263 /* save our object in the file‘s private structure */ 264 file->private_data = dev; 265 //释放信号量 266 /* unlock this device */ 267 up (&dev->sem); 268 return retval; 269 } 270 271 /** 272 * skel_release 273 */ 274 //关闭函数 275 static int skel_release (struct inode *inode, struct file *file) 276 { 277 struct usb_skel *dev; 278 int retval = 0; 279 dev = (struct usb_skel *)file->private_data; 280 if (dev == NULL) { 281 dbg (__FUNCTION__ " - object is NULL"); 282 return -ENODEV; 283 } 284 dbg(__FUNCTION__ " - minor %d", dev->minor); 285 //占有全局信号量 286 /* lock our minor table */ 287 down (&minor_table_mutex); 288 //占有局部信号量 289 /* lock our device */ 290 down (&dev->sem); 291 //设备引用计数小于0,说明目前没有打开设备 292 if (dev->open_count <= 0) { 293 dbg (__FUNCTION__ " - device not opened"); 294 retval = -ENODEV; 295 goto exit_not_opened; 296 } 297 //检测到设备已经拔出 298 if (dev->udev == NULL) { 299 /* the device was unplugged before the file was released */ 300 up (&dev->sem); 301 skel_delete (dev); 302 up (&minor_table_mutex); 303 MOD_DEC_USE_COUNT; 304 return 0; 305 } 306 //设备打开计数减一 307 /* decrement our usage count for the device */ 308 --dev->open_count; 309 if (dev->open_count <= 0) { 310 //没有任何人在使用该设备,则取消目前所有的数据传输 311 /* shutdown any bulk writes that might be going on */ 312 usb_unlink_urb (dev->write_urb); 313 dev->open_count = 0; 314 } 315 //bookmark 316 /* decrement our usage count for the module */ 317 MOD_DEC_USE_COUNT; 318 //没有执行open就执行close 319 exit_not_opened: 320 up (&dev->sem); 321 up (&minor_table_mutex); 322 return retval; 323 } 324 325 /** 326 * skel_read 327 */ 328 //注意这里的数据传输并没有利用urb,而是用了一种简单的方式 329 static ssize_t skel_read (struct file *file, char *buffer, size_t count, loff_t *ppos) 330 { 331 struct usb_skel *dev; 332 int retval = 0; 333 dev = (struct usb_skel *)file->private_data; 334 335 dbg(__FUNCTION__ " - minor %d, count = %d", dev->minor, count); 336 //锁定信号量 337 /* lock this object */ 338 down (&dev->sem); 339 //该设备是否可用 340 /* verify that the device wasn‘t unplugged */ 341 if (dev->udev == NULL) { 342 up (&dev->sem); 343 return -ENODEV; 344 } 345 //接收批量数据,同时指定了设备信息,批量输入的端点(通过usb_rcvbulkpipe构造),缓冲区地址和大小,所需要数据的大小,超时时间 346 /* do an immediate bulk read to get data from the device */ 347 retval = usb_bulk_msg (dev->udev, 348 usb_rcvbulkpipe (dev->udev, 349 dev->bulk_in_endpointAddr), 350 dev->bulk_in_buffer, dev->bulk_in_size, 351 &count, HZ*10); 352 //数据正常接收 353 //则把数据复制供给用户 354 /* if the read was successful, copy the data to userspace */ 355 if (!retval) { 356 if (copy_to_user (buffer, dev->bulk_in_buffer, count)) 357 retval = -EFAULT; 358 else 359 retval = count; 360 } 361 362 /* unlock the device */ 363 up (&dev->sem); 364 return retval; 365 } 366 367 /** 368 * skel_write 369 */ 370 static ssize_t skel_write (struct file *file, const char *buffer, size_t count, loff_t *ppos) 371 { 372 struct usb_skel *dev; 373 ssize_t bytes_written = 0; 374 int retval = 0; 375 dev = (struct usb_skel *)file->private_data; 376 dbg(__FUNCTION__ " - minor %d, count = %d", dev->minor, count); 377 /* lock this object */ 378 down (&dev->sem); 379 /* verify that the device wasn‘t unplugged */ 380 if (dev->udev == NULL) { 381 retval = -ENODEV; 382 goto exit; 383 } 384 //无效操作 385 /* verify that we actually have some data to write */ 386 if (count == 0) { 387 dbg(__FUNCTION__ " - write request of 0 bytes"); 388 goto exit; 389 } 390 //设备正在忙碌 391 /* see if we are already in the middle of a write */ 392 if (dev->write_urb->status == -EINPROGRESS) { 393 dbg (__FUNCTION__ " - already writing"); 394 goto exit; 395 } 396 //计算写入的数据大小 397 /* we can only write as much as 1 urb will hold */ 398 bytes_written = (count > dev->bulk_out_size) ? 399 dev->bulk_out_size : count; 400 /* copy the data from userspace into our urb */ 401 if (copy_from_user(dev->write_urb->transfer_buffer, buffer, 402 bytes_written)) { 403 retval = -EFAULT; 404 goto exit; 405 } 406 usb_skel_debug_data (__FUNCTION__, bytes_written, 407 dev->write_urb->transfer_buffer); 408 //填充批量urb 409 //目标urb,usb设备,目标端点(通过usb_sndbulkpipe创建),数据首地址,已写入数据的返回值,回调函数,提供给回调函数的数据 410 /* set up our urb */ 411 FILL_BULK_URB(dev->write_urb, dev->udev, 412 usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), 413 dev->write_urb->transfer_buffer, bytes_written, 414 skel_write_bulk_callback, dev); 415 //正是发送urb 416 /* send the data out the bulk port */ 417 retval = usb_submit_urb(dev->write_urb); 418 if (retval) { 419 err(__FUNCTION__ " - failed submitting write urb, error %d", 420 retval); 421 } else { 422 retval = bytes_written; 423 } 424 //释放信号量 425 exit: 426 /* unlock the device */ 427 up (&dev->sem); 428 return retval; 429 } 430 431 /** 432 * skel_ioctl 433 */ 434 //控制函数,并没有实质的功能 435 static int skel_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 436 { 437 struct usb_skel *dev; 438 dev = (struct usb_skel *)file->private_data; 439 /* lock this object */ 440 down (&dev->sem); 441 /* verify that the device wasn‘t unplugged */ 442 if (dev->udev == NULL) { 443 up (&dev->sem); 444 return -ENODEV; 445 } 446 dbg(__FUNCTION__ " - minor %d, cmd 0x%.4x, arg %ld", 447 dev->minor, cmd, arg); 448 449 /* fill in your device specific stuff here */ 450 451 /* unlock the device */ 452 up (&dev->sem); 453 454 /* return that we did not understand this ioctl call */ 455 return -ENOTTY; 456 } 457 458 /** 459 * skel_write_bulk_callback 460 */ 461 //skel_write的回调函数 462 static void skel_write_bulk_callback (struct urb *urb) 463 { 464 //用来获取skel_write失败时的设备信息 465 struct usb_skel *dev = (struct usb_skel *)urb->context; 466 //提供给debug函数的信息 467 dbg(__FUNCTION__ " - minor %d", dev->minor); 468 if ((urb->status != -ENOENT) && 469 (urb->status != -ECONNRESET)) { 470 dbg(__FUNCTION__ " - nonzero write bulk status received: %d", 471 urb->status); 472 return; 473 } 474 return; 475 } 476 477 /** 478 * skel_probe 479 * 480 * Called by the usb core when a new device is connected that it thinks 481 * this driver might be interested in. 482 */ 483 //设备的试探函数 484 static void * skel_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) 485 { 486 //设备信息 487 struct usb_skel *dev = NULL; 488 //接口函数 489 struct usb_interface *interface; 490 //接口描述符 491 struct usb_interface_descriptor *iface_desc; 492 //端点结构体 493 struct usb_endpoint_descriptor *endpoint; 494 //从设备号 495 int minor; 496 //缓冲区大小 497 int buffer_size; 498 int i; 499 char name[10]; 500 //验证厂商和芯片id 501 /* See if the device offered us matches what we can accept */ 502 if ((udev->descriptor.idVendor != USB_SKEL_VENDOR_ID) || 503 (udev->descriptor.idProduct != USB_SKEL_PRODUCT_ID)) { 504 return NULL; 505 } 506 //临界区 507 /* select a "subminor" number (part of a minor number) */ 508 down (&minor_table_mutex); 509 //取得一个合适的从设备号 510 for (minor = 0; minor < MAX_DEVICES; ++minor) { 511 if (minor_table[minor] == NULL) 512 break; 513 } 514 //该从设备号不可用 515 if (minor >= MAX_DEVICES) { 516 info ("Too many devices plugged in, can not handle this device."); 517 goto exit; 518 } 519 //申请内存 520 /* allocate memory for our device state and intialize it */ 521 dev = kmalloc (sizeof(struct usb_skel), GFP_KERNEL); 522 if (dev == NULL) { 523 err ("Out of memory"); 524 goto exit; 525 } 526 minor_table[minor] = dev; 527 //特定设备特定配置的特定接口 528 interface = &udev->actconfig->interface[ifnum]; 529 //初始化从设备的信号量 530 init_MUTEX (&dev->sem); 531 //保存设备,配置以及接口方面的信息 532 dev->udev = udev; 533 dev->interface = interface; 534 dev->minor = minor; 535 /* set up the endpoint information */ 536 /* check out the endpoints */ 537 //搜索设备中可用的端点 538 iface_desc = &interface->altsetting[0]; 539 for (i = 0; i < iface_desc->bNumEndpoints; ++i) { 540 endpoint = &iface_desc->endpoint[i]; 541 //找到一个批量入端点,并配置相关信息:缓冲区大小,端点地址,缓冲区地址 542 //由于采用简单方式,因此不需要在接收区使用urb 543 if ((endpoint->bEndpointAddress & 0x80) && 544 ((endpoint->bmAttributes & 3) == 0x02)) { 545 /* we found a bulk in endpoint */ 546 buffer_size = endpoint->wMaxPacketSize; 547 dev->bulk_in_size = buffer_size; 548 dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; 549 dev->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL); 550 if (!dev->bulk_in_buffer) { 551 err("Couldn‘t allocate bulk_in_buffer"); 552 goto error; 553 } 554 } 555 //找到一个批量出端点,除前面的信息外还需要一个urb,并初始化该urb 556 if (((endpoint->bEndpointAddress & 0x80) == 0x00) && 557 ((endpoint->bmAttributes & 3) == 0x02)) { 558 /* we found a bulk out endpoint */ 559 dev->write_urb = usb_alloc_urb(0); 560 if (!dev->write_urb) { 561 err("No free urbs available"); 562 goto error; 563 } 564 buffer_size = endpoint->wMaxPacketSize; 565 dev->bulk_out_size = buffer_size; 566 dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; 567 dev->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL); 568 if (!dev->bulk_out_buffer) { 569 err("Couldn‘t allocate bulk_out_buffer"); 570 goto error; 571 } 572 //初始化该urbbookmark 573 FILL_BULK_URB(dev->write_urb, udev, 574 usb_sndbulkpipe(udev, 575 endpoint->bEndpointAddress), 576 dev->bulk_out_buffer, buffer_size, 577 skel_write_bulk_callback, dev); 578 } 579 } 580 /* initialize the devfs node for this device and register it */ 581 sprintf(name, "skel%d", dev->minor); 582 //初始化该设备文件,参数依次是: 583 //设备句柄,驱动名称,名称长度(采用了默认值),主设备号,从设备号,权限(mode,gid,uid),file_operations结构体,额外的信息 584 dev->devfs = devfs_register (usb_devfs_handle, name, 585 DEVFS_FL_DEFAULT, USB_MAJOR, 586 USB_SKEL_MINOR_BASE + dev->minor, 587 S_IFCHR | S_IRUSR | S_IWUSR | 588 S_IRGRP | S_IWGRP | S_IROTH, 589 &skel_fops, NULL); 590 //提供给用户访问该文件系统时的信息 591 /* let the user know what node this device is now attached to */ 592 info ("USB Skeleton device now attached to USBSkel%d", dev->minor); 593 goto exit; 594 //出错处理 595 error: 596 skel_delete (dev); 597 dev = NULL; 598 exit: 599 up (&minor_table_mutex); 600 return dev; 601 } 602 603 /** 604 * skel_disconnect 605 * 606 * Called by the usb core when the device is removed from the system. 607 */ 608 //设备移除时调用的函数 609 static void skel_disconnect(struct usb_device *udev, void *ptr) 610 { 611 struct usb_skel *dev; 612 int minor; 613 //获取从设备信息 614 dev = (struct usb_skel *)ptr; 615 616 down (&minor_table_mutex); 617 down (&dev->sem); 618 619 minor = dev->minor; 620 //设备文件注销 621 /* remove our devfs node */ 622 devfs_unregister(dev->devfs); 623 //当前设备没有被使用 624 /* if the device is not opened, then we clean up right now */ 625 if (!dev->open_count) { 626 up (&dev->sem); 627 skel_delete (dev); 628 } else { 629 dev->udev = NULL; 630 up (&dev->sem); 631 } 632 info("USB Skeleton #%d now disconnected", minor); 633 up (&minor_table_mutex); 634 } 635 /** 636 * usb_skel_init 637 */ 638 //设备的初始化 639 static int __init usb_skel_init(void) 640 { 641 int result; 642 //设备注册 643 /* register this driver with the USB subsystem */ 644 result = usb_register(&skel_driver); 645 if (result < 0) { 646 err("usb_register failed for the "__FILE__" driver. Error number %d", 647 result); 648 return -1; 649 } 650 info(DRIVER_DESC " " DRIVER_VERSION); 651 return 0; 652 } 653 654 /** 655 * usb_skel_exit 656 */ 657 //设备的注销,注意用的是usb_deregister而不是usb_unregister 658 static void __exit usb_skel_exit(void) 659 { 660 /* deregister this driver with the USB subsystem */ 661 usb_deregister(&skel_driver); 662 } 663 //采用默认的函数进行驱动模块的初始化和注销 664 module_init (usb_skel_init); 665 module_exit (usb_skel_exit); 666 MODULE_AUTHOR(DRIVER_AUTHOR); 667 MODULE_DESCRIPTION(DRIVER_DESC); 668 MODULE_LICENSE("GPL");
标签:counter 空间 cmd 处理 传输 class cond dir 通过
原文地址:http://www.cnblogs.com/zzb-Dream-90Time/p/6256699.html