相关文章:USB Gadget设备端驱动架构(Based on Linux 4.x)
USB Gadget设备端驱动架构总目录
其他参考:本文源代码基于 Linux Kernel 4.9
以UVC设备为例,系统加载UVC驱动后首先进入uvc_init, 这个接口直接调用了usb_function_register(&uvcusb_func); 在层次上这个函数明显是属于Gadget Function API中间层。因此系统中所有的USB设备在注册时都会调用这个函数的流程。
一、源码流程
(1)输入参数newf : 代表调用注册函数的Gadget设备,如UVC,MTP等
(2)实现功能:新增设备调用时,将该设备通过list_add_tail添加到全局的Gadget设备列表中(func_list),如果当前需要注册的设备在列表中已经存在则直接退出,防止重复注册。其中list_for_each_entry是一个遍历函数,相当于一个for循环,从fun_list依次取出链表项在代码中与当前输入的newf进行比对。
int usb_function_register(struct usb_function_driver *newf)
{
struct usb_function_driver *fd;
int ret;
pr_err("SOLEN Enter %s",__func__);
pr_err("SOLEN newf->name = %s",newf->name);
ret = -EEXIST;
mutex_lock(&func_lock);
list_for_each_entry(fd, &func_list, list) {
pr_err("SOLEN fd->name = %s\n",fd->name);
if (!strcmp(fd->name, newf->name))
{
pr_err("SOLEN in %s go to out",__func__);
goto out;
}
}
ret = 0;
list_add_tail(&newf->list, &func_list);
pr_err("SOLEN in list_add_tail \n");
out:
mutex_unlock(&func_lock);
return ret;
}
打印的Log如下:
[ 10.855143] SOLEN Enter usb_function_register
[ 10.859471] SOLEN newf->name = ncm
[ 10.874261] SOLEN in list_add_tail
[ 10.877852] SOLEN Enter usb_function_register
[ 10.882173] SOLEN newf->name = mass_storage
[ 10.897885] SOLEN fd->name = ncm
[ 10.901229] SOLEN in list_add_tail
[ 10.904821] SOLEN Enter usb_function_register
[ 10.909210] SOLEN newf->name = ffs
[ 10.924001] SOLEN fd->name = ncm
[ 10.927328] SOLEN fd->name = mass_storage
[ 10.931489] SOLEN in list_add_tail
[ 10.935080] SOLEN Enter usb_function_register
[ 10.939394] SOLEN newf->name = uac2
[ 10.954291] SOLEN fd->name = ncm
[ 10.957620] SOLEN fd->name = mass_storage
[ 10.961763] SOLEN fd->name = ffs
[ 10.965090] SOLEN in list_add_tail
[ 10.968712] SOLEN Enter usb_function_register
[ 10.973012] SOLEN newf->name = uac2
[ 10.987892] SOLEN fd->name = ncm
[ 10.991249] SOLEN fd->name = mass_storage
[ 10.995379] SOLEN fd->name = ffs
[ 10.998719] SOLEN fd->name = uac2
[ 11.002139] SOLEN in usb_function_register go to out
[ 11.007071] SOLEN enter uvc_init
[ 11.021740] SOLEN Enter usb_function_register
[ 11.026040] SOLEN newf->name = uvc
[ 11.040860] SOLEN fd->name = ncm
[ 11.044187] SOLEN fd->name = mass_storage
[ 11.048372] SOLEN fd->name = ffs
[ 11.051700] SOLEN fd->name = uac2
[ 11.055119] SOLEN in list_add_tail
[ 11.058724] SOLEN Enter usb_function_register
[ 11.063023] SOLEN newf->name = uvc
[ 11.077829] SOLEN fd->name = ncm
[ 11.081170] SOLEN fd->name = mass_storage
[ 11.085300] SOLEN fd->name = ffs
[ 11.088656] SOLEN fd->name = uac2
[ 11.092064] SOLEN fd->name = uvc
[ 11.095391] SOLEN in usb_function_register go to out
[ 11.100336] SOLEN Enter usb_function_register
[ 11.116125] SOLEN newf->name = midi
[ 11.118203] SOLEN fd->name = ncm
[ 11.132869] SOLEN fd->name = mass_storage
[ 11.136999] SOLEN fd->name = ffs
[ 11.140340] SOLEN fd->name = uac2
[ 11.143758] SOLEN fd->name = uvc
[ 11.147087] SOLEN in list_add_tail
[ 11.150706] SOLEN Enter usb_function_register
[ 11.155006] SOLEN newf->name = hid
[ 11.169823] SOLEN fd->name = ncm
[ 11.173150] SOLEN fd->name = mass_storage
[ 11.177280] SOLEN fd->name = ffs
[ 11.180623] SOLEN fd->name = uac2
[ 11.184042] SOLEN fd->name = uvc
[ 11.187369] SOLEN fd->name = midi
[ 11.190816] SOLEN in list_add_tail
[ 11.194408] SOLEN Enter usb_function_register
[ 11.198720] SOLEN newf->name = mtp
[ 11.213526] SOLEN fd->name = ncm
[ 11.216854] SOLEN fd->name = mass_storage
[ 11.220997] SOLEN fd->name = ffs
[ 11.224325] SOLEN fd->name = uac2
[ 11.227734] SOLEN fd->name = uvc
[ 11.231124] SOLEN fd->name = midi
[ 11.234533] SOLEN fd->name = hid
[ 11.237861] SOLEN in list_add_tail
[ 11.241466] SOLEN Enter usb_function_register
[ 11.245766] SOLEN newf->name = ptp
[ 11.260583] SOLEN fd->name = ncm
[ 11.263912] SOLEN fd->name = mass_storage
[ 11.268041] SOLEN fd->name = ffs
[ 11.271397] SOLEN fd->name = uac2
[ 11.274817] SOLEN fd->name = uvc
[ 11.278144] SOLEN fd->name = midi
[ 11.281575] SOLEN fd->name = hid
[ 11.284903] SOLEN fd->name = mtp
[ 11.288258] SOLEN in list_add_tail
[ 11.291850] SOLEN Enter usb_function_register
[ 11.296150] SOLEN newf->name = audio_source
[ 11.311770] SOLEN fd->name = ncm
[ 11.315099] SOLEN fd->name = mass_storage
[ 11.319240] SOLEN fd->name = ffs
[ 11.322568] SOLEN fd->name = uac2
[ 11.325986] SOLEN fd->name = uvc
[ 11.329376] SOLEN fd->name = midi
[ 11.332794] SOLEN fd->name = hid
[ 11.336122] SOLEN fd->name = mtp
[ 11.339464] SOLEN fd->name = ptp
[ 11.342791] SOLEN in list_add_tail
[ 11.346383] SOLEN Enter usb_function_register
[ 11.350712] SOLEN newf->name = accessory
[ 11.366041] SOLEN fd->name = ncm
[ 11.369397] SOLEN fd->name = mass_storage
[ 11.373527] SOLEN fd->name = ffs
[ 11.376855] SOLEN fd->name = uac2
[ 11.380286] SOLEN fd->name = uvc
[ 11.383614] SOLEN fd->name = midi
[ 11.387033] SOLEN fd->name = hid
[ 11.390389] SOLEN fd->name = mtp
[ 11.393717] SOLEN fd->name = ptp
[ 11.397045] SOLEN fd->name = audio_source
[ 11.401187] SOLEN in list_add_tail
[ 11.404870] SOLEN Enter usb_function_register
[ 11.409203] SOLEN newf->name = diag
[ 11.424084] SOLEN fd->name = ncm
[ 11.427413] SOLEN fd->name = mass_storage
[ 11.431607] SOLEN fd->name = ffs
[ 11.434936] SOLEN fd->name = uac2
[ 11.438372] SOLEN fd->name = uvc
[ 11.441699] SOLEN fd->name = midi
[ 11.445118] SOLEN fd->name = hid
[ 11.448475] SOLEN fd->name = mtp
[ 11.451802] SOLEN fd->name = ptp
[ 11.455130] SOLEN fd->name = audio_source
[ 11.459274] SOLEN fd->name = accessory
[ 11.463128] SOLEN in list_add_tail
[ 11.467197] SOLEN Enter usb_function_register
[ 11.471534] SOLEN newf->name = cser
[ 11.486415] SOLEN fd->name = ncm
[ 11.489774] SOLEN fd->name = mass_storage
[ 11.493905] SOLEN fd->name = ffs
[ 11.497234] SOLEN fd->name = uac2
[ 11.500667] SOLEN fd->name = uvc
[ 11.503996] SOLEN fd->name = midi
[ 11.507415] SOLEN fd->name = hid
[ 11.510776] SOLEN fd->name = mtp
[ 11.514104] SOLEN fd->name = ptp
[ 11.517433] SOLEN fd->name = audio_source
[ 11.521576] SOLEN fd->name = accessory
[ 11.525441] SOLEN fd->name = diag
[ 11.528928] SOLEN in list_add_tail
[ 11.532520] SOLEN Enter usb_function_register
[ 11.536820] SOLEN newf->name = ccid
[ 11.551731] SOLEN fd->name = ncm
[ 11.555059] SOLEN fd->name = mass_storage
[ 11.559201] SOLEN fd->name = ffs
[ 11.562529] SOLEN fd->name = uac2
[ 11.565948] SOLEN fd->name = uvc
[ 11.569309] SOLEN fd->name = midi
[ 11.572728] SOLEN fd->name = hid
[ 11.576056] SOLEN fd->name = mtp
[ 11.579397] SOLEN fd->name = ptp
[ 11.582724] SOLEN fd->name = audio_source
[ 11.586853] SOLEN fd->name = accessory
[ 11.590736] SOLEN fd->name = diag
[ 11.594156] SOLEN fd->name = cser
[ 11.597574] SOLEN in list_add_tail
[ 11.602062] SOLEN Enter usb_function_register
[ 11.606366] SOLEN newf->name = gsi
[ 11.621191] SOLEN fd->name = ncm
[ 11.624519] SOLEN fd->name = mass_storage
[ 11.628724] SOLEN fd->name = ffs
[ 11.632053] SOLEN fd->name = uac2
[ 11.635472] SOLEN fd->name = uvc
[ 11.638815] SOLEN fd->name = midi
[ 11.642235] SOLEN fd->name = hid
[ 11.645563] SOLEN fd->name = mtp
[ 11.648920] SOLEN fd->name = ptp
[ 11.652247] SOLEN fd->name = audio_source
[ 11.656378] SOLEN fd->name = accessory
[ 11.660244] SOLEN fd->name = diag
[ 11.663664] SOLEN fd->name = cser
[ 11.667084] SOLEN fd->name = ccid
[ 11.670532] SOLEN in list_add_tail
[ 11.674124] SOLEN Enter usb_function_register
[ 11.678436] SOLEN newf->name = qdss
[ 11.693332] SOLEN fd->name = ncm
[ 11.696660] SOLEN fd->name = mass_storage
[ 11.700804] SOLEN fd->name = ffs
[ 11.704133] SOLEN fd->name = uac2
[ 11.707552] SOLEN fd->name = uvc
[ 11.710910] SOLEN fd->name = midi
[ 11.714329] SOLEN fd->name = hid
[ 11.717656] SOLEN fd->name = mtp
[ 11.720995] SOLEN fd->name = ptp
[ 11.724323] SOLEN fd->name = audio_source
[ 11.728516] SOLEN fd->name = accessory
[ 11.732380] SOLEN fd->name = diag
[ 11.735799] SOLEN fd->name = cser
[ 11.739232] SOLEN fd->name = ccid
[ 11.742651] SOLEN fd->name = gsi
[ 11.745978] SOLEN in list_add_tail
可以简要分析概况如下:
(1)注册ncm,列表更新为 ncm
(2)注册mass_storage,列表更新为 ncm,mass_storage
(3)注册ffs,列表更新为 ncm,mass_storage ,ffs
(4)注册uac2, 列表更新为 ncm,mass_storage ,ffs,uac2
(5)注册uac2, 列表中已存在uac2退出
(6)注册uvc,列表更新为 ncm,mass_storage ,ffs,uac2,uvc
(7)注册uvc,列表中已经存在uvc,退出
(8)注册midi ,列表更新为ncm,mass_storage ,ffs,uac2,uvc,midi
(9)注册hid,列表更新为ncm,mass_storage ,ffs,uac2,uvc,midi,hid
........
继续注册 mtp,ptp,audio_source,accessory,diag,cser,ccid,gsi,qdss
可以在 adb shell config/usb_gadget/g1/functions目录下看到注册的各个设备情况:
accessory.gs2 cser.dun.0 diag.diag gsi.dpl mass_storage.0 ncm.0 qdss.qdss_mdm
audio_source.gs3 cser.dun.2 diag.diag_mdm gsi.rmnet midi.gs5 ptp.gs1 uac2.0
ccid.ccid cser.nmea.1 ffs.adb gsi.rndis mtp.gs0 qdss.qdss uvc.0