USB核心回撥¶
usbcore會進行哪些回撥?¶
Usbcore將透過驅動程式結構中定義的回撥和驅動程式提交的URB的完成處理程式來呼叫驅動程式。只有前者在本檔案的範圍之內。這兩種回撥是完全獨立的。關於完成回撥的資訊可以在USB請求塊(URB)中找到。
驅動程式結構中定義的回撥有:
熱插拔回調
- @probe
呼叫以檢視驅動程式是否願意管理裝置上的特定介面。
- @disconnect
當介面不再可訪問時呼叫,通常是因為其裝置已(或正在)斷開連線或驅動程式模組正在解除安裝。
透過usbfs的奇怪後門
- @ioctl
用於希望透過“usbfs”檔案系統與使用者空間通訊的驅動程式。這使裝置能夠提供向用戶空間公開資訊的方式,而不管它們是否以其他方式出現在檔案系統中。
電源管理(PM)回撥
- @suspend
當裝置即將掛起時呼叫。
- @resume
當裝置正在恢復時呼叫。
- @reset_resume
當掛起的裝置已重置而不是恢復時呼叫。
裝置級操作
- @pre_reset
在裝置即將重置時呼叫。
- @post_reset
裝置重置後呼叫
只有在您有非常好的理由時才應使用ioctl介面(2)。現在首選Sysfs。PM回撥在USB電源管理中單獨介紹。
呼叫約定¶
所有回撥都是互斥的。無需針對其他USB回撥進行鎖定。所有回撥都從任務上下文中呼叫。您可以睡眠。但是,重要的是所有睡眠都具有較小的固定時間上限。特別是,您不得呼叫使用者空間並等待結果。
熱插拔回調¶
這些回撥旨在將驅動程式與介面關聯和分離。驅動程式與介面的繫結是獨佔的。
probe()回撥¶
int (*probe) (struct usb_interface *intf,
const struct usb_device_id *id);
接受或拒絕介面。如果您接受裝置,則返回0,否則返回-ENODEV或-ENXIO。僅當初始化期間發生真正的錯誤,阻止驅動程式接受否則會被接受的裝置時,才應使用其他錯誤程式碼。強烈建議您使用usbcore的工具usb_set_intfdata(),將資料結構與介面關聯,以便您知道將哪個內部狀態和標識與特定介面關聯。裝置不會被掛起,您可以對您呼叫的介面和裝置的端點0執行IO。時間不長的裝置初始化在這裡是個好主意。
disconnect()回撥¶
void (*disconnect) (struct usb_interface *intf);
此回撥是斷開與介面的任何連線的訊號。從此回撥返回後,您不得對裝置進行任何IO。您也不得執行任何可能干擾繫結到該介面的另一個驅動程式的操作,例如電源管理操作。必須在此回撥返回之前完成或中止裝置上的未完成操作。
如果您是由於物理斷開連線而被呼叫的,則您的所有URB都將被usbcore殺死。請注意,在這種情況下,disconnect將在物理斷開連線後的一段時間呼叫。因此,即使在回撥之前,您的驅動程式也必須準備好處理失敗的IO。
裝置級回撥¶
pre_reset¶
int (*pre_reset)(struct usb_interface *intf);
驅動程式或使用者空間正在觸發裝置上的重置,該裝置包含作為引數傳遞的介面。停止IO,等待所有未完成的URB完成,並儲存您需要恢復的任何裝置狀態。在呼叫post_reset方法之前,不得提交更多URB。
如果您需要在此處分配記憶體,請使用GFP_NOIO或GFP_ATOMIC(如果您處於原子上下文中)。
post_reset¶
int (*post_reset)(struct usb_interface *intf);
重置已完成。恢復任何已儲存的裝置狀態並再次開始使用該裝置。
如果您需要在此處分配記憶體,請使用GFP_NOIO或GFP_ATOMIC(如果您處於原子上下文中)。
呼叫序列¶
對於未繫結到您的驅動程式的介面,不會呼叫除probe之外的任何回撥。
永遠不會為繫結到驅動程式的介面呼叫Probe。因此,在成功探測之後,在對同一介面進行另一次探測之前,將呼叫disconnect。
一旦您的驅動程式繫結到介面,就可以隨時呼叫disconnect,除非在pre_reset和post_reset之間。pre_reset始終後跟post_reset,即使重置失敗或裝置已拔下。
suspend始終後跟以下之一:resume,reset_resume或disconnect。