Chinaunix首页 | 论坛 | 博客
  • 博客访问: 243108
  • 博文数量: 33
  • 博客积分: 246
  • 博客等级: 二等列兵
  • 技术积分: 918
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-31 16:37
文章分类

全部博文(33)

文章存档

2014年(4)

2013年(7)

2012年(22)

分类: LINUX

2012-09-07 20:31:52


1. usb-storage 驱动注册过程.  module_init(usb_stor_init);

  1. usb_stor_init(void) <drivers/usb/storage/usb.c>
  2.     usb_register(&usb_storage_driver);
  3.         usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
  4.             driver_register(&new_driver->drvwrap.driver);
  5.                 driver_find(drv->name, drv->bus);
  6.                 bus_add_driver(drv);
  7.                     kobject_init_and_add
  8.                     driver_attach(drv);
  9.                         bus_for_each_dev
  10.                             __driver_attach
  11.                                 driver_probe_device(drv, dev);
  12.                                     really_probe(dev, drv);
  13.                                         drv->probe(dev);
  14.                 kobject_uevent(&priv->kobj, KOBJ_ADD);

2. storage_probe 函数的处理过程.
 
在 usb-stroage 驱动程序注册的过程中, 由于 bus_usb_type 没有定义 probe 函数,所以会执行代码 usb_storage_driver 中定义的 probe 函数.
 

  1. storage_probe(struct usb_interface *intf, const struct usb_device_id *id)
  2.     usb_stor_probe1(&us, intf, id, (id - usb_storage_usb_ids) + us_unusual_dev_list);
  3.         scsi_host_alloc(&usb_stor_host_template, sizeof(*us)); //alloc us->host
  4.         associate_dev(us, intf);
  5.             interface_to_usbdev(intf);
  6.             usb_set_intfdata(intf, us);
  7.             usb_buffer_alloc(us->pusb_dev, sizeof(*us->cr),    GFP_KERNEL, &us->cr_dma); //set us->cr
  8.             usb_buffer_alloc(us->pusb_dev, US_IOBUF_SIZE, GFP_KERNEL, &us->iobuf_dma);//set us->iobuf
  9.         get_device_info(us, id, unusual_dev);
  10.         get_transport(us); //set us->transport = usb_stor_CB_transport; us->transport_reset = usb_stor_CB_reset;
  11.         get_protocol(us); //set us->proto_handler = usb_stor_transparent_scsi_command;        
  12.     usb_stor_probe2(us);
  13.         get_pipes(us); //get bulk in/out endpoint.and get contrl in/out endpoint.
  14.         usb_stor_acquire_resources(us); //Acquire all the other resources and add the host
  15.             usb_alloc_urb(0, GFP_KERNEL); //set us->current_urb.
  16.             kthread_run(usb_stor_control_thread, us, "usb-storage"); //set to us->ctl_thread. struct task_struct.sleep at the beginning.
  17.         scsi_add_host(us_to_host(us), &us->pusb_intf->dev);//add us->host into scsi-core.
  18.         kthread_create(usb_stor_scan_thread, us, "usb-stor-scan"); //Start up the thread for delayed SCSI-device scanning
  19.         wake_up_process(th); // wake up kthread usb_stor_scan_thread, which create above.
  20.             set_freezable(); // usb_stor_scan_thread run as below flow. begin this line.
  21.             usb_stor_Bulk_max_lun(us); //set us->max_lun. lun<logical unit number>
  22.                 usb_stor_control_msg(...); //args doesn't show as too long.
  23.                     usb_fill_control_urb(...); //fill urb with args.
  24.                     usb_stor_msg_common(us, timeout);
  25.                         init_completion(&urb_done);
  26.                         usb_submit_urb(us->current_urb, GFP_NOIO); //submit urb to the usb-core.
  27.                         wait_for_completion_interruptible_timeout(...);//wait urb to be done.
  28.             scsi_scan_host(us_to_host(us));

3. usb_stor_host_template 数据结构.
 

  1. struct scsi_host_template usb_stor_host_template = {
  2.     .name =                "usb-storage",
  3.     .proc_name =            "usb-storage",
  4.     .proc_info =            proc_info,
  5.     .info =                host_info,
  6.     .queuecommand =            queuecommand, //called by scsi_dispatch_cmd() in scsi.c, dispatch srb.
  7.     .eh_abort_handler =        command_abort, //abort command.
  8.     .eh_device_reset_handler =    device_reset, //reset device.
  9.     .eh_bus_reset_handler =        bus_reset, //reset all, include usb scsi host, bus, driver.
  10.     .can_queue =            1,
  11.     .cmd_per_lun =            1,
  12.     .this_id =            -1,
  13.     .slave_alloc =            slave_alloc,
  14.     .slave_configure =        slave_configure,
  15.     .sg_tablesize =            SG_ALL,
  16.     .max_sectors = 240,
  17.     .use_clustering =        1,
  18.     .emulated =            1,
  19.     .skip_settle_delay =        1,
  20.     .sdev_attrs =            sysfs_device_attr_list,
  21.     .module =            THIS_MODULE
  22. }
 
4. usb_storage_driver 数据结构.
 
usb-storage 驱动的核心结构.

  1. static struct usb_driver usb_storage_driver = {
  2.     .name =        "usb-storage",
  3.     .probe =    storage_probe, //注册驱动或者有设备插入时被调用.
  4.     .disconnect =    usb_stor_disconnect,//移除设备或者移除驱动时调用.
  5.     .suspend =    usb_stor_suspend, //系统挂起时调用
  6.     .resume =    usb_stor_resume, //系统从挂起恢复执行时调用.
  7.     .reset_resume =    usb_stor_reset_resume,//系统从挂起恢复执行时,用reset替代resume.
  8.     .pre_reset =    usb_stor_pre_reset, //USB设备reset之前调用.
  9.     .post_reset =    usb_stor_post_reset,//USB设备reset之后调用.
  10.     .id_table =    usb_storage_usb_ids,
  11.     .soft_unbind =    1,
  12. };
 
5. USB 读写.
 
(1) 当用户需要访问 USB 设备时, scsi-core 会调用 scsi_dispatch_cmd(), 而 scsi_dispatch_cmd()
会进一步调用 scsi_host_template 中的 queuecommand, 也就是 usb_stor_host_template 中的 queuecommand() 函数.
  1. queuecommand(struct scsi_cmnd *srb,    void (*done)(struct scsi_cmnd *))
  2.     host_to_us(srb->device->host) //get us.
  3.     complete(&us->cmnd_ready); //this would wake up usb-storage kthread, execute func usb_stor_control_thread.
(2) usb_stor_control_thread 线程的处理过程.

  1. usb_stor_control_thread(void * __us)
  2.     if (wait_for_completion_interruptible(&us->cmnd_ready)) //wake up by queuecommand(). see 4 lines above.
  3.     us->proto_handler(us->srb, us); //see storage_probe() -> get_protocol(us). called usb_stor_transparent_scsi_command actually.
  4.     us->srb->scsi_done(us->srb); //transfer already done.


(3) usb_stor_transparent_scsi_command() 函数的处理过程.
USB 的数据传输分为三个过程: 命令传输, 数据传输, 状态传输.

  1. usb_stor_transparent_scsi_command(struct scsi_cmnd *srb, struct us_data *us)
  2.     usb_stor_invoke_transport(srb, us); //send the command to the transport layer
  3.         scsi_set_resid(srb, 0);
  4.         us->transport(srb, us); //see storage_probe() -> get_transport(us), called usb_stor_CB_transport() acctually.
  5.         usb_stor_ctrl_transfer(...); //send command.
  6.             usb_fill_control_urb(...); //fill urb with args.
  7.             usb_stor_msg_common(us, 0); //submit urb.
  8.                 init_completion(&urb_done);
  9.                 usb_submit_urb(us->current_urb, GFP_NOIO); //submit urb to the usb-core.
  10.                 wait_for_completion_interruptible_timeout(...);//wait urb to be done.
  11.             interpret_urb_result(...); //translate result of usb_stor_msg_common().    
  12.         usb_stor_bulk_srb(us, pipe, srb); //transfer data.
  13.             usb_stor_bulk_transfer_sglist(...); //use scatter/gather.
  14.                 usb_sg_init(...); //init scatter/gather.
  15.                 usb_sg_wait(&us->current_sg); //wait for the completion of the transfer .
  16.                 interpret_urb_result(...);
  17.             scsi_set_resid(srb, scsi_bufflen(srb) - partial);
  18.         usb_stor_intr_transfer(us, us->iobuf, 2);// get transfer status.
  19.             usb_fill_int_urb(...);
  20.             usb_stor_msg_common(us, 0);
  21.             interpret_urb_result(...);
6. 移除 USB 设备. usb_stor_disconnect() 函数的处理过程. 基本都是释放资源, 释放锁.
 
 

  1. usb_stor_disconnect(struct usb_interface *intf)
  2.     usb_get_intfdata(intf); // get usb-data.
  3.     quiesce_and_remove_host(us);
  4.         wake_up(&us->delay_wait);
  5.         wait_for_completion(&us->scanning_done);
  6.         scsi_remove_host(host);
  7.         wake_up(&us->delay_wait);
  8.     release_everything(us);
  9.         usb_stor_release_resources(us);
  10.             complete(&us->cmnd_ready);
  11.             kthread_stop(us->ctl_thread);
  12.             kfree(us->extra);
  13.             usb_free_urb(us->current_urb);
  14.         dissociate_dev(us);
  15.             usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr, us->cr_dma);        
  16.             usb_buffer_free(us->pusb_dev, US_IOBUF_SIZE, us->iobuf,    us->iobuf_dma);    
  17.             usb_set_intfdata(us->pusb_intf, NULL);
  18.         scsi_host_put(us_to_host(us));


阅读(4689) | 评论(0) | 转发(2) |
0

上一篇:没有了

下一篇:USB详解

给主人留下些什么吧!~~