1. usb-storage 驱动注册过程. module_init(usb_stor_init);
- usb_stor_init(void) <drivers/usb/storage/usb.c>
- usb_register(&usb_storage_driver);
- usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
- driver_register(&new_driver->drvwrap.driver);
- driver_find(drv->name, drv->bus);
- bus_add_driver(drv);
- kobject_init_and_add
- driver_attach(drv);
- bus_for_each_dev
- __driver_attach
- driver_probe_device(drv, dev);
- really_probe(dev, drv);
- drv->probe(dev);
- kobject_uevent(&priv->kobj, KOBJ_ADD);
2. storage_probe 函数的处理过程.
在 usb-stroage 驱动程序注册的过程中, 由于 bus_usb_type 没有定义 probe 函数,所以会执行代码 usb_storage_driver 中定义的 probe 函数.
- storage_probe(struct usb_interface *intf, const struct usb_device_id *id)
- usb_stor_probe1(&us, intf, id, (id - usb_storage_usb_ids) + us_unusual_dev_list);
- scsi_host_alloc(&usb_stor_host_template, sizeof(*us)); //alloc us->host
- associate_dev(us, intf);
- interface_to_usbdev(intf);
- usb_set_intfdata(intf, us);
- usb_buffer_alloc(us->pusb_dev, sizeof(*us->cr), GFP_KERNEL, &us->cr_dma); //set us->cr
- usb_buffer_alloc(us->pusb_dev, US_IOBUF_SIZE, GFP_KERNEL, &us->iobuf_dma);//set us->iobuf
- get_device_info(us, id, unusual_dev);
- get_transport(us); //set us->transport = usb_stor_CB_transport; us->transport_reset = usb_stor_CB_reset;
- get_protocol(us); //set us->proto_handler = usb_stor_transparent_scsi_command;
- usb_stor_probe2(us);
- get_pipes(us); //get bulk in/out endpoint.and get contrl in/out endpoint.
- usb_stor_acquire_resources(us); //Acquire all the other resources and add the host
- usb_alloc_urb(0, GFP_KERNEL); //set us->current_urb.
- kthread_run(usb_stor_control_thread, us, "usb-storage"); //set to us->ctl_thread. struct task_struct.sleep at the beginning.
- scsi_add_host(us_to_host(us), &us->pusb_intf->dev);//add us->host into scsi-core.
- kthread_create(usb_stor_scan_thread, us, "usb-stor-scan"); //Start up the thread for delayed SCSI-device scanning
- wake_up_process(th); // wake up kthread usb_stor_scan_thread, which create above.
- set_freezable(); // usb_stor_scan_thread run as below flow. begin this line.
- usb_stor_Bulk_max_lun(us); //set us->max_lun. lun<logical unit number>
- usb_stor_control_msg(...); //args doesn't show as too long.
- usb_fill_control_urb(...); //fill urb with args.
- usb_stor_msg_common(us, timeout);
- init_completion(&urb_done);
- usb_submit_urb(us->current_urb, GFP_NOIO); //submit urb to the usb-core.
- wait_for_completion_interruptible_timeout(...);//wait urb to be done.
- scsi_scan_host(us_to_host(us));
3. usb_stor_host_template 数据结构.
- struct scsi_host_template usb_stor_host_template = {
- .name = "usb-storage",
- .proc_name = "usb-storage",
- .proc_info = proc_info,
- .info = host_info,
- .queuecommand = queuecommand, //called by scsi_dispatch_cmd() in scsi.c, dispatch srb.
- .eh_abort_handler = command_abort, //abort command.
- .eh_device_reset_handler = device_reset, //reset device.
- .eh_bus_reset_handler = bus_reset, //reset all, include usb scsi host, bus, driver.
- .can_queue = 1,
- .cmd_per_lun = 1,
- .this_id = -1,
- .slave_alloc = slave_alloc,
- .slave_configure = slave_configure,
- .sg_tablesize = SG_ALL,
- .max_sectors = 240,
- .use_clustering = 1,
- .emulated = 1,
- .skip_settle_delay = 1,
- .sdev_attrs = sysfs_device_attr_list,
- .module = THIS_MODULE
- }
4. usb_storage_driver 数据结构.
usb-storage 驱动的核心结构.
- static struct usb_driver usb_storage_driver = {
- .name = "usb-storage",
- .probe = storage_probe, //注册驱动或者有设备插入时被调用.
- .disconnect = usb_stor_disconnect,//移除设备或者移除驱动时调用.
- .suspend = usb_stor_suspend, //系统挂起时调用
- .resume = usb_stor_resume, //系统从挂起恢复执行时调用.
- .reset_resume = usb_stor_reset_resume,//系统从挂起恢复执行时,用reset替代resume.
- .pre_reset = usb_stor_pre_reset, //USB设备reset之前调用.
- .post_reset = usb_stor_post_reset,//USB设备reset之后调用.
- .id_table = usb_storage_usb_ids,
- .soft_unbind = 1,
- };
5. USB 读写.
(1) 当用户需要访问 USB 设备时, scsi-core 会调用 scsi_dispatch_cmd(), 而 scsi_dispatch_cmd()
会进一步调用 scsi_host_template 中的 queuecommand, 也就是 usb_stor_host_template 中的 queuecommand() 函数.
- queuecommand(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *))
- host_to_us(srb->device->host) //get us.
- complete(&us->cmnd_ready); //this would wake up usb-storage kthread, execute func usb_stor_control_thread.
(2) usb_stor_control_thread 线程的处理过程.
- usb_stor_control_thread(void * __us)
- if (wait_for_completion_interruptible(&us->cmnd_ready)) //wake up by queuecommand(). see 4 lines above.
- us->proto_handler(us->srb, us); //see storage_probe() -> get_protocol(us). called usb_stor_transparent_scsi_command actually.
- us->srb->scsi_done(us->srb); //transfer already done.
(3) usb_stor_transparent_scsi_command() 函数的处理过程.
USB 的数据传输分为三个过程: 命令传输, 数据传输, 状态传输.
- usb_stor_transparent_scsi_command(struct scsi_cmnd *srb, struct us_data *us)
- usb_stor_invoke_transport(srb, us); //send the command to the transport layer
- scsi_set_resid(srb, 0);
- us->transport(srb, us); //see storage_probe() -> get_transport(us), called usb_stor_CB_transport() acctually.
- usb_stor_ctrl_transfer(...); //send command.
- usb_fill_control_urb(...); //fill urb with args.
- usb_stor_msg_common(us, 0); //submit urb.
- init_completion(&urb_done);
- usb_submit_urb(us->current_urb, GFP_NOIO); //submit urb to the usb-core.
- wait_for_completion_interruptible_timeout(...);//wait urb to be done.
- interpret_urb_result(...); //translate result of usb_stor_msg_common().
- usb_stor_bulk_srb(us, pipe, srb); //transfer data.
- usb_stor_bulk_transfer_sglist(...); //use scatter/gather.
- usb_sg_init(...); //init scatter/gather.
- usb_sg_wait(&us->current_sg); //wait for the completion of the transfer .
- interpret_urb_result(...);
- scsi_set_resid(srb, scsi_bufflen(srb) - partial);
- usb_stor_intr_transfer(us, us->iobuf, 2);// get transfer status.
- usb_fill_int_urb(...);
- usb_stor_msg_common(us, 0);
- interpret_urb_result(...);
6. 移除 USB 设备. usb_stor_disconnect() 函数的处理过程. 基本都是释放资源, 释放锁.
- usb_stor_disconnect(struct usb_interface *intf)
- usb_get_intfdata(intf); // get usb-data.
- quiesce_and_remove_host(us);
- wake_up(&us->delay_wait);
- wait_for_completion(&us->scanning_done);
- scsi_remove_host(host);
- wake_up(&us->delay_wait);
- release_everything(us);
- usb_stor_release_resources(us);
- complete(&us->cmnd_ready);
- kthread_stop(us->ctl_thread);
- kfree(us->extra);
- usb_free_urb(us->current_urb);
- dissociate_dev(us);
- usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr, us->cr_dma);
- usb_buffer_free(us->pusb_dev, US_IOBUF_SIZE, us->iobuf, us->iobuf_dma);
- usb_set_intfdata(us->pusb_intf, NULL);
- scsi_host_put(us_to_host(us));
阅读(4853) | 评论(0) | 转发(2) |