USB Core je subsystém linuxového jádra navržený pro podporu zařízení USB a řadičů sběrnice USB. Účelem jeho vytvoření je abstrahovat od hardwarové implementace standardu USB (resp. hardwarově závislých funkcí) definováním sady datových struktur, maker a funkcí.
Podpora USB byla do linuxového jádra přidána krátce po větvi jádra 2.2 a krátce před spuštěním řady 2.3. Vývoj z řady 2.3 byl pravidelně převáděn na řadu 2.2, čímž byly přidávány nové funkce, jako je podpora hot plug, nové ovladače a optimalizace práce. Řada jádra 2.5 zdědila všechna tato vylepšení a přidala podporu pro práci s USB 2.0 a v důsledku toho vyšší výkon, stabilnější provoz mezi zařízeními, zjednodušení aplikačního rozhraní (stalo se obtížnější dělat chyby v kódu) a také vedení interní dokumentace.
Vzhledem k tomu, že se schopnost spouštět Linux v průběhu času objevila na mnoha mediálních zařízeních, během svého vývoje byla podpora USB v Linuxu rozdělena na dvě části. Linux lze na jedné straně spouštět z USB zařízení připojených k zařízení (například flash disky), na druhé straně lze Linux spustit i na hlavním počítači, ke kterému jsou USB zařízení připojena. Použité USB ovladače jsou velmi odlišné, takže pro rozlišení mezi nimi byl zaveden vhodný název pro ovladače zařízení . ovladače gadgetu [1] .
V jádře mají ovladače hostitelského OS přístup k rozhraním USB Core API. Existují dva typy veřejných rozhraní API USB Core, které se zaměřují na dvě různé úrovně ovladače USB: ovladače pro obecné účely , které jsou dostupné prostřednictvím rámců ovladačů , jako jsou bloková, znaková nebo síťová zařízení, a ovladače, které jsou součástí jádra a jsou zapojeny do správa sběrnice USB. Mezi takové ovladače jádra patří ovladač rozbočovače, který spravuje strom zařízení USB, a také několik různých typů ovladačů hostitelského řadiče ( angl. host controller driver , zkr. HCD), které řídí jednotlivé sběrnice.
Metoda pro určení nejlepšího způsobu práce ovladačů se zařízením USB je poměrně komplikovaná:
Jediné ovladače hostitelského OS, které skutečně přistupují k zařízení (čtení/zápis do registrů, zpracování přerušení atd.), jsou ovladače hostitelského řadiče. Teoreticky všechny ovladače hostitelského řadiče podporují podobnou funkcionalitu prostřednictvím použití jediného aplikačního rozhraní. V praxi to začalo být podporováno až v jádře verze 2.5, ale existují rozdíly ve zpracování chyb [2] .
Níže jsou uvedena standardní aplikační programová rozhraní (API), která jsou součástí USB Core [3] .
název | Funkce |
---|---|
usb_init_urb | Inicializuje URB pro pozdější použití ovladačem USB |
usb_alloc_urb | Vytvoří nový URB pro pozdější použití ovladačem USB |
usb_free_urb | Uvolní paměť obsazenou URB, když ji všichni uživatelé přestanou používat. |
usb_get_urb | Zvyšuje počet odkazů URB |
usb_submit_urb | Odešle požadavek na asynchronní přenos na koncové zařízení |
usb_unlink_urb | Přeruší/zruší požadavek na přenos na koncové zařízení |
usb_kill_urb | Zruší požadavek na přenos a čeká na jeho dokončení |
usb_control_msg | Vytvoří řídicí zprávu URB, odešle ji a čeká na provedení |
usb_bulk_msg | Vytvoří obecnou zprávu URB, odešle ji a čeká na provedení |
usb_sg_init | Inicializuje obecný I/O nebo požadavek na přerušení na základě distribuovaného seznamu |
usb_sg_wait | Synchronně provádí dotaz rozdělení/připojení |
usb_sg_cancel | Zastaví I/O rozdělení/sloučení iniciované usb_sg_wait |
usb_get_descriptor | Odešle obecný požadavek deskriptoru get (GET_DESCRIPTOR) |
usb_string | Vrátí deskriptor řetězce ve formátu ISO 8859-1 |
usb_get_status | Odešle volání GET_STATUS |
usb_clear_halt | Oznámí zařízení, aby resetovalo nevyřízený stav pro koncové zařízení |
rozhraní usb_set_interface | Aktivuje alternativní předvolbu |
usb_reset_configuration | Softwarový restart zařízení |
usb_register_dev | Zaregistruje zařízení USB a požádá o vedlejší číslo |
usb_deregister_dev | Zruší registraci dynamického vedlejšího čísla zařízení USB |
usb_match_id | Najde první odpovídající usb_device_id pro zařízení nebo rozhraní |
usb_register_driver | Registruje ovladač USB |
usb_deregister | Zruší registraci ovladače USB |
usb_ifnum_to_if | Získá objekt rozhraní pro dané číslo rozhraní |
usb_altnum_to_altsetting | Získá alternativní strukturu nastavení pro dané číslo rozhraní |
rozhraní usb_driver_claim_interface | Spojí ovladač s rozhraním |
rozhraní usb_driver_release_interface | Odpojí ovladač od rozhraní |
rozhraní usb_find_interface | Vyhledá ukazatel usb_interface pro ovladač a zařízení |
usb_get_dev | Zvyšuje počet odkazů struktury zařízení USB |
usb_put_dev | Uvolní použitou strukturu USB zařízení |
usb_get_intf | Zvyšuje počet odkazů struktury rozhraní USB |
usb_put_intf | Uvolní použitou strukturu rozhraní USB |
usb_lock_device_for_reset | Správně zablokuje zařízení pro následné restartování |
usb_find_device | Vyhledá požadované zařízení USB v systému |
usb_get_current_frame_number | Vrátí číslo aktuálního rámce sběrnice |
usb_buffer_alloc | Přiděluje vyrovnávací paměť kompatibilní s DMA pro umístění URB_NO_xxx_DMA_MAP |
usb_buffer_free | Uvolňuje paměť přidělenou pomocí usb_buffer_alloc |
usb_buffer_map | Vytvoří vazby DMA na URB |
usb_buffer_dmasync | Synchronizuje procházení vyrovnávacích pamětí DMA a CPU |
usb_buffer_unmap | Přeruší vazby DMA na URB |
usb_buffer_map_sg | Vytváří distribuované vazby DMA na koncové body |
usb_buffer_dmasync_sg | Synchronizuje zobrazení distribuovaných vyrovnávacích pamětí DMA a CPU |
usb_buffer_unmap_sg | Přeruší distribuované vazby DMA |
usb_hub_tt_clear_buffer | Resetuje ovládání/hromadný režim ve vysokorychlostním rozbočovači |
usb_root_hub_lost_power | Volá HCD, když kořenový rozbočovač ztratí napájení Vbus. |
usb_reset_device | Restartuje port USB, aby se zařízení znovu inicializovalo |
V rozhraní USB API jsou dva hlavní modely I/O. Nejjednodušší model je asynchronní: ovladače odešlou požadavek jako URB a pak zpětné volání URB v dalším kroku dokončí operaci. Všechny typy USB přenosů podporují tento model, existují však speciální modely pro řídicí URB (které mají vždy svá vlastní nastavení a stavy, ale ne vždy mají možnost datové fáze ) a izochronní URB (umožňují přenos velkých paketů). a zahrnují hlášení o každém chybném paketu.) Takové modely jsou založeny na podpoře synchronního API, ve kterém ovladač volá rutinu, která alokuje jeden nebo více URB v paměti, odešle je a čeká na jejich dokončení. Existují také synchronní obaly pro řízení s jednou vyrovnávací pamětí a hromadné přenosy (které jsou nepohodlné pro použití v některých scénářích vypnutí ovladače), stejně jako pro streamování založené na distribuovaných seznamech (streamování nebo přerušování).
Ovladače USB vyžadují vyrovnávací paměti, které lze použít pro přímý přístup do paměti (DMA), i když nemusejí provádět vlastní vazbu DMA. Existují rozhraní API, která lze použít při přidělování vyrovnávacích pamětí DMA, protože mohou zabránit použití nesprávných vyrovnávacích pamětí na některých systémech. V některých případech mohou ovladače používat 64bitový režim DMA k překonání jiných typů omezení vyrovnávací paměti [3] .