usb储存之BOT/UAS内核驱动
usb储存驱动
概览
BOT和UAS(UASP)的区别:
Windows NT内核/Linux内核都是如此的设计:
用一个标志表示UAS启用与否,用4EP支持UAS,用2EP支持BOT,判断主控是否支持STREAM,如果支持就会尝试ALT模式来使用UAS协议。
Windows NT内核驱动判断只有在高于全速2.0的情况下才会尝试UAS。
BOT仅单线程,使用2个EP:Data-In/Data-Out管道,是单工等待的,所以在高速下有瓶颈,这也是USB储存没跑满的原因。

UAS多管道(ITr/ITc/OTr/Otc)四路传输管道+USB2/USB3管道+UAS信息单元管道
一般是4个EP:datain dataout cmd status



UAS基于SCSI

声明
drivers/usb/storage/usb.c
static struct usb_driver usb_storage_driver = {
.name = DRV_NAME,
.probe = storage_probe, //这里是挂载
.disconnect = usb_stor_disconnect,
.suspend = usb_stor_suspend,
.resume = usb_stor_resume,
.reset_resume = usb_stor_reset_resume,
.pre_reset = usb_stor_pre_reset,
.post_reset = usb_stor_post_reset,
.id_table = usb_storage_usb_ids,
.supports_autosuspend = 1,
.soft_unbind = 1,
};
// 这里是usb主机储存控制器的驱动模板挂载
module_usb_stor_driver(usb_storage_driver, usb_stor_host_template, DRV_NAME);
普通BOT挂载流程
如果为UAS或非常规设备,则退出storage_probe。
drivers/usb/storage/usual-tables.c 的两个数组列表
- 非规设备 ignore_ids[]
- UAS列表 usb_storage_usb_ids[]
UAS判断:uas_use_uas_driver
/* If uas is enabled and this device can do uas then ignore it. */
#if IS_ENABLED(CONFIG_USB_UAS)
if (uas_use_uas_driver(intf, id, NULL))
return -ENXIO;
#endif
非规设备判断:
/*
* If the device isn't standard (is handled by a subdriver
* module) then don't accept it.
*/
if (usb_usual_ignore_device(intf))
return -ENXIO;
然后就会走usb_stor_probe1和usb_stor_probe2流程
在usb_stor_probe1里面会有协议选择,根据协议切换读写处理函数
/* Get standard transport and protocol settings */
get_transport(us);
get_protocol(us);
流式UAS挂载
drivers/usb/storage/uas.c

XHCI驱动重载
主要用于重写公版驱动行为
static const struct xhci_driver_overrides xhci_pci_overrides __initconst = {
.reset = xhci_pci_setup,
.update_hub_device = xhci_pci_update_hub_device,
};
//init
xhci_init_driver(&xhci_pci_hc_driver, &xhci_pci_overrides);
原理:非null时重新赋值函数指针

XHCI协议spec
USB储存 BOT(Bulk-Only Transport)CBW-UFI命令数据流
例子:https://www.usbzh.com/tool/bot-cbw-ufi-csw.html
SCSI协议
希捷:https://www.seagate.com/files/staticfiles/support/docs/manual/Interface manuals/100293068j.pdf
其模型称为 SCSI architectural model (SAM)
CHIP 之 UASP IP
https://www.synopsys.com/blogs/chip-design/uasp-faster-usb-mass-storage.html
Others
sd 1:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
- FUA: Force Unit Access
- DPO: Disable Page Out
编写kprobe/kretprobe钩子
查看当前内核里相关的函数符号
grep uas /proc/kallsyms <
uas开头的符号有
0000000000000000 t uas_probe
0000000000000000 t uas_disconnect
0000000000000000 t uas_suspend
0000000000000000 t uas_resume
0000000000000000 t uas_reset_resume
0000000000000000 t uas_pre_reset
0000000000000000 t uas_post_reset
0000000000000000 t uas_shutdown
0000000000000000 t uas_do_work
0000000000000000 t uas_scan_work
0000000000000000 t uas_configure_endpoints
0000000000000000 t uas_queuecommand
0000000000000000 t uas_eh_abort_handler
0000000000000000 t uas_eh_device_reset_handler
0000000000000000 t uas_slave_alloc
0000000000000000 t uas_slave_configure
0000000000000000 t uas_target_alloc
0000000000000000 t uas_submit_urbs
0000000000000000 t uas_log_cmd_state
0000000000000000 t uas_stat_cmplt
0000000000000000 t uas_sense
0000000000000000 t uas_try_complete
0000000000000000 t uas_xfer_data
0000000000000000 t uas_evaluate_response_iu
0000000000000000 t uas_data_cmplt
0000000000000000 t uas_cmd_cmplt
0000000000000000 t uas_zap_pending
0000000000000000 t uas_wait_for_pending_cmnds
0000000000000000 t uas_init
0000000000000000 t uas_exit
0000000000000000 d __initcall__kmod_uas__452_1275_uas_init6
0000000000000000 d uas_driver
0000000000000000 d uas_usb_ids
0000000000000000 d uas_host_template
console:/data #
一般
查看驱动
# 看drivers段Driver=usb-storage或者uas
lsusb -t
cat /sys/kernel/usb/devices
Ref
国内现行标准:
ISO/IEC 14776-251:2014

浙公网安备 33010602011771号