USB大容量存储设备浅析
一 USB 設備類
SB 引入了設備類的概念,根據每一類驅動程序的功能將USB設備分為幾大類,標準的幾大類包括:
大容量存儲類 網絡類 集線器類 串行轉換器 音頻類 視頻類 圖像類 調制解調器 打印機 HID(Human Interface Device 人機接口設備)每一大類的驅動程序對屬于這類的所有設備通用,不需要另外再開發和安裝驅動程序就可以使用。Linux-USB子系統支持主要的幾類設備驅動程序。
每個USB設備都有類代碼和子類代碼。如 大容量存儲設備類(0x08)就包含 光盤存儲器(0x02)、磁帶(0x03)、固態存儲器(0x06)。設備驅動程序的 usb_device_id結構體包含類代碼成員和子類代碼成員。
也可以從 /proc/bus/usb/devices 輸出結果的"I:"行看到設備的類代碼和子類代碼信息。
存儲設備的接口有五大類
IDE、SCSI、USB,并行口,串口,其中并行口與串口的速度非常慢,不提也罷,最主要的就是IDE,usb, SCSI。IDE。
二 USB大容量存儲設備
通常來講USB大容量存儲設備(Mass Storage) 主要是指 U盤,USB硬盤,筆驅動器,CD-ROM,軟驅以及類似的存儲設備。USB大容量存儲設備利用 SCSI(Small Computer System Interface 小型計算機系統接口)協議和主機系統通信。
SCSI 接口
SCSI是“Small Computer System Interface”的縮寫,即小型計算機系統接口。同IDE(ATA)完全不同的接口, IDE接口是普通PC的標準接口,而SCSI并不是專門為硬盤設計的接口,是一種廣泛應用于小型機上的高速數據傳輸技術。
SCSI 協議
Scsi 協議是U盤,讀卡器這些大容量存儲所使用的協議。整個協議是工作在批量傳輸,分為IN、OUT兩個方向。當插入U盤,USB主機控制器會識別到該設備是一個海量存儲設備,然就就會根據SCSI協議,先發送CBW命令塊包,U盤收到后根據SCSI協議解析該報,并回復命令執行狀態包(CSW),就是應答,作為對前一個CBW命令塊包處理結果的回應。Host 根據 CSW 來決定是否繼續發 送下一個CBW 或是數據。
當一個U盤插入主體后,主機會拿到USB設備的描述符,從而識別到該USB設備是一個支持 Bulk-Only傳輸協議的海量存儲設備。并使用Bulk-Only傳輸協議,即進入Bulk-Only傳輸方式,主機與USB設備間的所有數據都是通過Bulk input(批量輸入端點)、 Bulk ouput(批量輸出端點) 進行傳輸。不再通過控制端點傳輸任何數據。在這種傳輸方式下,有三種類型數據在主機和usb設備之間傳輸:命令塊包(CBW)、命令執行狀態包(CSW)、普通數據包。
Bulk-Only傳輸協議:Bulk-Only協議是USB組織針對大容量存儲設備制定的一種塊存儲類協議,是USB大容量數據存儲的基礎協議,BOT協議用于主機和USB設備之間進行大容量數據傳輸。,U盤屬于海量存儲類。USB定義了海量存儲存儲設備類的規范。主要是指USB總線上的傳輸方法與存儲介質的操作命令。海量存儲設備只支持一個接口,即數據接口,此接口有三個端點, Bulk input(批量輸入端點)、 Bulk ouput(批量輸出端點)、中斷端點。
大容量存儲設備驅動程序把自己注冊成一個虛擬的SCSI適配器。該虛擬適配器在上行方向上通過SCSI命令和上層通信,在下行方向通過URB與塊存儲器減緩數據。
在USB集線器枚舉過后,USB系統發現插入設備是大容量設備 U盤,就會調用 storage_probe()。目前分析的主要工作就是,申請一個 SCSI適配器,并綁定USB接口 與 該適配器的關系,最后注冊該SCSI適配器到 SCSI總線。SCSI總線掃描到該設備后,調用 sd_prob(),即sd驅動, sd驅動為該U盤在系統中生成 /dev/sd* 節點,從這以后,應用程序就可以用該接口訪問這個U盤了。SCSI子系統把發向虛擬適配器的磁盤操作命令排隊,在虛擬適配器這端,排隊的命令以URB的形式傳遞給設備。
drivers\usb\storage\usb.c
static int storage_probe(struct usb_interface *intf,const struct usb_device_id *id) {struct us_unusual_dev *unusual_dev;//私有數據結構struct us_data *us;int result;int size;.../*//私有數據結構struct us_data *us;USB設備接口struct usb_interface *intfstruct usb_device_id *idstruct us_unusual_dev *unusual_dev;scsi協議主機信息模板 ??struct scsi_host_template usb_stor_host_template*/result = usb_stor_probe1(&us, intf, id, unusual_dev,&usb_stor_host_template);if (result)return result;/* No special transport or protocol settings in the main module */result = usb_stor_probe2(us);return result; }static struct usb_driver usb_storage_driver = {.name = DRV_NAME,.probe = storage_probe,.disconnect = usb_stor_disconnect,.suspend = usb_stor_suspend, ... };/* First part of general USB mass-storage probing */ /* //私有數據結構 struct us_data *us;USB設備接口 struct usb_interface *intfstruct usb_device_id *idstruct us_unusual_dev *unusual_dev;scsi協議主機信息模板 ?? struct scsi_host_template usb_stor_host_template暫時分析的工作申請 SCSI 主機控制器綁定 SCSI 主機控制器 和 私有數據綁定 私有數據 和 usb接口信息*/int usb_stor_probe1(struct us_data **pus,struct usb_interface *intf,const struct usb_device_id *id,struct us_unusual_dev *unusual_dev,struct scsi_host_template *sht) {//SCSI 主機控制器struct Scsi_Host *host;struct us_data *us;int result;dev_info(&intf->dev, "USB Mass Storage device detected\n");host = scsi_host_alloc(sht, sizeof(*us));if (!host) {dev_warn(&intf->dev, "Unable to allocate the scsi host\n");return -ENOMEM;} ...*pus = us = host_to_us(host); ...INIT_DELAYED_WORK(&us->scan_dwork, usb_stor_scan_dwork);/* Associate the us_data structure with the USB device *///us_data結構與USB設備關聯sresult = associate_dev(us, intf);if (result)goto BadDevice;... }/* Associate our private data with the USB device */ static int associate_dev(struct us_data *us, struct usb_interface *intf) {/* Fill in the device-related fields */us->pusb_dev = interface_to_usbdev(intf);us->pusb_intf = intf;us->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; .../* Store our private data in the interface *///在接口中存儲我們的私有數據usb_set_intfdata(intf, us);...return 0; }/* Second part of general USB mass-storage probing */ int usb_stor_probe2(struct us_data *us) {int result;struct device *dev = &us->pusb_intf->dev; .../*1 關聯 USB設備 -- SCSI主機控制器2 注冊 SCSI主機控制器到 SCSI總線*/result = scsi_add_host(us_to_host(us), dev);if (result) {dev_warn(dev,"Unable to add the scsi host\n");goto HostAddErr;}.../*調用 usb_stor_scan_dwork() ,請求SCSI系統掃描總線來發現插入的SCSI設備*/queue_delayed_work(system_freezable_wq, &us->scan_dwork,delay_use * HZ);return 0;...return result; } EXPORT_SYMBOL_GPL(usb_stor_probe2);總結
以上是生活随笔為你收集整理的USB大容量存储设备浅析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 企业大数据价值你只发掘了1%!
- 下一篇: 学习笔记61—兴趣阅读之经济学