usb Mass Strorage分析(1)

本文详细介绍了Linux内核中USB Mass Storage驱动的工作原理,包括注册过程、存储设备信息获取、传输层与协议层的配置,以及如何与SCSI层交互。分析了`storage_probe`函数中的`get_transport`、`get_protocol`和`get_pipes`函数,展示了如何根据设备特性设置相应的传输协议和端点。此外,还讨论了控制线程`usb_stor_control_thread`的角色,它是如何接收上层命令并调用相应处理函数的。
摘要由CSDN通过智能技术生成


接上一篇: usb-skeleton.c到 usb core层的分析

对于存储设备的USB,Linux源码中有关于USB MASS Storage 的驱动程序(/drivers/usb/storage下),其中/drivers/usb/storage/usb.c 实现了驱动初始化,和usb-skeleton.c 例子以一样,调用    retval = usb_register(&usb_storage_driver); 注册usb设备,

static struct usb_driver usb_storage_driver = {
    .name =        "usb-storage",
    .probe =    storage_probe,
    .disconnect =    storage_disconnect,
#ifdef CONFIG_PM
    .suspend =    storage_suspend,
    .resume =    storage_resume,
    .reset_resume =    storage_reset_resume,
#endif
    .pre_reset =    storage_pre_reset,
    .post_reset =    storage_post_reset,
    .id_table =    storage_usb_ids,
    .soft_unbind =    1,
};

static int storage_probe(struct usb_interface *intf,
             const struct usb_device_id *id)
{


.....................

    /*
     * Ask the SCSI layer to allocate a host structure, with extra
     * space at the end for our private us_data structure.
     */
    host = scsi_host_alloc(&usb_stor_host_template, sizeof(*us));
    if (!host) {
        printk(KERN_WARNING USB_STORAGE
            "Unable to allocate the scsi host\n");
        return -ENOMEM;
    }

 
    result = get_device_info(us, id);
    if (result)
        goto BadDevice;

    result = get_transport(us);   //获得usb设备端的的数据,并进行相应设置,见下面
    if (result)
        goto BadDevice;
    result = get_protocol(us);   //获得usb设备端协议的数据,并进行相应设置,见下面
    if (result)
        goto BadDevice;
    result = get_pipes(us);    //获得endpoint管道的数据,并进行相应设置,见下面
    if (result)
        goto BadDevice;
.........................

    result = usb_stor_acquire_resources(us);   //获得资源,开启了一个控制内核的线程static int usb_stor_control_thread(void * __us),用于接收上层命令,该线程会在有命令的时候(休眠等待),调用struct us_data(在storage中定义的数据)中的proto_handler方法,从而调用transport,向usbcore发送命令。非常重要,见下面代码
    if (result)
        goto BadDevice;
    result = scsi_add_host(host, &intf->dev);    增加到SCSI host
    if (result) {
        printk(KERN_WARNING USB_STORAGE
            "Unable to add the scsi host\n");
        goto BadDevice;
    }

    /* Start up the thread for delayed SCSI-device scanning */
    th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan");
   
}

流程结构图:

以下是进行usb设备端信息获取,同时设置us参数的函数get_transport()、get_protocal()、getPipes(),对应着上图中的Protocal Layer 和 Transfer Layer,分别在/drivers/usb/storage/protocal.c、transport.c中实现。初始化完成了交给SCSI层的接口后就由上层处理。




static int get_transport(struct us_data *us)
{
    switch (us->protocol) {
    case US_PR_CB:
        us->transport_name = "Control/Bulk";
        us->transport = usb_stor_CB_transport;
        us->transport_reset = <

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值