Menulis driver klien pengontrol fungsi

Artikel ini menjelaskan berbagai tugas yang dilakukan driver klien pengontrol fungsi saat berinteraksi dengan ekstensi pengontrol fungsi USB (UFX).

API penting

Menjelaskan berbagai tugas yang dilakukan driver klien pengontrol fungsi saat berinteraksi dengan ekstensi pengontrol fungsi USB (UFX). UFX dan driver klien berkomunikasi satu sama lain dengan menggunakan metode ekspor dan fungsi panggilan balik peristiwa. Metode ekspor (bernama UfxDeviceXxx atau UfxEndpointXxx) diekspor oleh UFX dan dipanggil oleh driver klien. Fungsi panggilan balik (bernama EVT_UFX_Xxx)diimplementasikan dalam driver klien dan dipanggil oleh UFX.

UFX memanggil semua fungsi panggilan balik driver klien secara asinkron, dan satu panggilan balik pada satu waktu per objek. Misalnya, ada objek perangkat USB dan tiga objek titik akhir. Paling banyak empat fungsi panggilan balik (satu untuk perangkat dan satu untuk setiap titik akhir) dapat dipanggil pada satu waktu. Untuk setiap metode panggilan balik, UFX menunggu hingga driver klien memanggil UfxDeviceEventComplete untuk menunjukkan bahwa driver telah menyelesaikan permintaan. Satu-satunya metode ekspor lain yang didengarkan UFX saat menunggu ekspor ini adalah UfxDeviceNotifyHardwareFailure. Banyak fungsi panggilan balik klien bersifat opsional. Fungsi yang diperlukan adalah sebagai berikut:

Inisialisasi

  1. Driver klien pengontrol fungsi memulai proses inisialisasi ketika Windows Driver Foundation (WDF) memanggil implementasi driver klien dari panggilan balik EVT_WDF_DRIVER_DEVICE_ADD . Dalam implementasi itu, driver klien diharapkan untuk memanggil UfxFdoInit dan kemudian membuat objek perangkat dengan memanggil WdfDeviceCreate.
  2. Driver klien memanggil UfxDeviceCreate untuk membuat objek perangkat USB dan mengambil handel UFXDEVICE.
  3. Driver klien memanggil UfxDeviceNotifyHardwareReady untuk menunjukkan kepada UFX bahwa sekarang dapat memanggil fungsi panggilan balik driver klien.
  4. UFX melakukan tugas inisialisasi seperti:

Pemberitahuan driver kelas

Untuk diberi tahu tentang paket penyiapan dan status bus, pengemudi kelas harus mengirim permintaan IOCTL_INTERNAL_USBFN_ACTIVATE_USB_BUS . UFX mengantrekan permintaan ini ke dalam antrean pemberitahuan khusus driver kelas. Saat menerima pemberitahuan tentang peristiwa bus dari driver klien, UFX muncul dari setiap antrean yang sesuai dan menyelesaikan permintaan. Untuk mencegah driver kelas kehilangan pemberitahuan, UFX menyimpan antrean pemberitahuan ukuran tetap untuk driver kelas.

Kejadian lampirkan dan lepas perangkat

UFX mengasumsikan bahwa perangkat dilepas hingga driver klien pengontrol fungsi memanggil UfxDeviceNotifyAttach.

Setelah panggilan itu, UFX mengatur status perangkat ke Didukung seperti yang didefinisikan dalam spesifikasi USB. Untuk memberi tahu driver klien tentang perubahan status, UFX memanggil implementasi EVT_UFX_DEVICE_USB_STATE_CHANGE driver klien.

UFX memberi tahu driver pengisi daya (Cad.sys) untuk membantu pengisian daya perangkat. UFX juga memberi tahu driver kelas dengan menyelesaikan permintaan IOCTL_INTERNAL_USBFN_BUS_EVENT_NOTIFICATION yang dikirim sebelumnya oleh driver kelas.

Driver klien harus memanggil UfxDeviceNotifyDetach ketika bus dilepas. Klien hanya boleh memanggil lepaskan sekali setelah setiap panggilan ke UfxDeviceNotifyAttach. Setelah panggilan UfxDeviceNotifyDetach , UFX memanggil EVT_UFX_DEVICE_HOST_DISCONNECT (jika ini bukan perubahan antarmuka). UFX kemudian melanjutkan dengan semua tugas pembersihan seperti membersihkan semua antrean titik akhir dan memulai antrean titik akhir default. UFX memanggil EVT_UFX_DEVICE_USB_STATE_CHANGE dan memberi tahu driver kelas dengan menyelesaikan permintaan IOCTL_INTERNAL_USBFN_BUS_EVENT_NOTIFICATION .

Kegagalan perangkat keras

Jika terjadi kesalahan perangkat keras, driver klien diharapkan memanggil UfxDeviceNotifyHardwareFailure. Sebagai tanggapan, UFX akan merobek tumpukan perangkat dan mungkin mencoba pulih dari situasi ini dengan memanggil EVT_UFX_DEVICE_CONTROLLER_RESET driver klien. Klien harus mengatur ulang pengontrol ke status awalnya. Jika kegagalan perangkat keras lain terjadi, klien harus memanggil UfxDeviceNotifyHardwareFailure lagi. Pada panggilan kedua, UFX akan merekam status dan pemeriksaan bug-nya.

Deteksi port

Deteksi port dilakukan oleh UFX. Ini memanggil fungsi fungsi pengontrol klien driver EVT_UFX_DEVICE_PORT_DETECT fungsi panggilan balik untuk menentukan jenis port tempat perangkat terpasang. Klien merespons dengan memanggil UfxDevicePortDetectComplete atau UfxDevicePortDetectCompleteEx dengan salah satu jenis port yang ditentukan dalam USBFN_PORT_TYPE.

Jika klien tidak dapat menentukan jenis port, klien harus melaporkan UsbfnUnknownPort. Jika port tidak diketahui atau port hilir, maka UFX memanggil fungsi EVT_UFX_DEVICE_HOST_CONNECT driver klien. UFX mendengarkan bus untuk beberapa waktu. Jika port tidak diketahui, tetapi ada lalu lintas, seperti paket penyiapan, maka UFX akan mengasumsikan UsbfnStandardDownstreamPort. Jika tidak, UFX menetapkan port menjadi UsbfnInvalidDedicatedChargingPort. Setelah jenis port ditentukan, UFX memberi tahu Cad.sys dan memanggil fungsi EVT_UFX_DEVICE_PORT_CHANGE driver klien. Dalam fungsi, driver klien diharapkan untuk mengubah status perangkat keras agar sesuai dengan jenis port UFX.

Pembuatan titik akhir

UFX membuat titik akhir default (titik akhir 0) dengan memanggil EVT_UFX_DEVICE_DEFAULT_ENDPOINT_ADD driver klien sehingga dapat menangani paket penyiapan yang dikirim oleh host. UFX membuat titik akhir lain dengan memanggil EVT_UFX_DEVICE_ENDPOINT_ADD. UFX hanya membuat titik akhir setelah driver klien memanggil UfxDeviceNotifyHardwareReady. Dalam fungsi panggilan balik ini, driver klien diharapkan untuk memanggil UfxEndpointCreate ke objek titik akhir dan mendapatkan handel UFXENDPOINT-nya. UFX mengatur induk ke PDO driver kelas yang terkait dengan antarmuka tempat titik akhir berada. Induk dari titik akhir default adalah objek perangkat USB. Titik akhir berisi dua objek antrean kerangka kerja: antrean transfer, dan Antrean perintah, yang keduanya hanya dapat diakses ketika perangkat dalam status Dikonfigurasi (dengan pengecualian Titik Akhir 0, yang dapat diakses setelah panggilan UFX EVT_UFX_DEVICE_HOST_CONNECT).

Enumerasi perangkat

Driver klien tidak boleh mengizinkan koneksi ke host sebelum UFX memanggil EVT_UFX_DEVICE_HOST_CONNECT driver. Enumerasi perangkat dimulai ketika driver klien memanggil UfxDeviceNotifyReset. Dalam status Default , UFX menangani paket penyiapan standar.

Mengatur ulang

UFX menghapus menyeluruh semua antrean titik akhir dan mengirim permintaan IOCTL_INTERNAL_USBFN_DESCRIPTOR_UPDATE ke driver klien untuk memperbarui wMaxPacketSize titik akhir 0. UFX memulai antrean titik akhir default dan mengatur status ke Default.

Default

UFX memanggil fungsi EVT_UFX_DEVICE_USB_STATE_CHANGE driver klien. Ini juga memberi tahu driver kelas negara bagian. Setelah UFX menerima paket penyiapan standar SET_ADDRESS, UFX mengatur status ke Ditangani.

Ditujukan

UFX memanggil fungsi EVT_UFX_DEVICE_ADDRESSED driver klien untuk menunjukkan kepada klien alamat mana yang harus digunakannya. - Jika alamatnya adalah 0, UFX mengatur status kembali ke Default dan memanggil EVT_UFX_DEVICE_USB_STATE_CHANGE dan memberi tahu driver kelas. Saat menerima paket penyiapan standar SET_CONFIGURATION, UFX mengatur status ke Dikonfigurasi.

Dikonfigurasi

Jika konfigurasi yang dipilih adalah 0, UFX menghapus menyeluruh titik akhir antarmuka dan mengatur status ke Ditangani. UFX mengirimkan permintaan IOCTL_INTERNAL_USBFN_DESCRIPTOR_UPDATE ke driver klien untuk memperbarui wMaxPacketSize dari titik akhir antarmuka. UFX memastikan semua antrean titik akhir antarmuka telah selesai membersihkan dan memulai antrean titik akhir antarmuka. Jika jenis port bukan UsbfnStandardDownstreamPort atau UsbfnChargingDownstreamPort, UFX mengubah jenis port menjadi UsbfnStandardDownstreamPort dan menginformasikan Cad.sys; driver klien dengan memanggil EVT_UFX_DEVICE_PORT_CHANGE dan EVT_UFX_DEVICE_USB_STATE_CHANGE untuk memperbarui status; driver kelas dari status yang dikonfigurasi.

Transfer kontrol standar

UFX dapat menangani transfer kontrol pada titik akhir default kapan saja setelah memanggil EVT_UFX_DEVICE_DEFAULT_ENDPOINT_ADD, di mana driver klien membuat titik akhir default menggunakan. Semua transfer kontrol dimulai dengan paket penyiapan 8-byte. Untuk mengirim paket penyiapan ke host, driver klien harus memanggil UfxEndpointNotifySetup. Transfer kontrol standar diselesaikan oleh UFX. Jika ada data yang terkait dengan transfer kontrol, UFX membaca dari dan menulis ke titik akhir kontrol default yang sesuai.

Transfer kontrol non-Standar

Jika UFX tidak dapat menangani transfer kontrol, transfer diteruskan ke driver kelas yang sesuai dengan menyelesaikan permintaan IOCTL_INTERNAL_USBFN_BUS_EVENT_NOTIFICATION . Transfer kontrol dapat terjadi pada titik akhir apa pun yang didefinisikan sebagai titik akhir kontrol di deskriptor titik akhir. Transfer kontrol pada titik akhir selain titik akhir kontrol default selalu merupakan transfer kontrol non-standar. Jika titik akhir kontrol adalah titik akhir kontrol default, UFX akan memberi tahu driver kelas tentang paket penyiapan yang ditandai sebagai permintaan kelas untuk driver kelas tersebut. Jika titik akhir kontrol milik antarmuka, maka UFX memberi tahu driver kelas yang terkait dengan antarmuka tersebut. Jika perlu, driver kelas diharapkan membaca dari dan menulis ke titik akhir kontrol.

Transfer data

Transfer data dimulai oleh driver kelas dengan mengirim permintaan IOCTL_INTERNAL_USBFN_TRANSFER_IN, IOCTL_INTERNAL_USBFN_TRANSFER_IN_APPEND_ZERO_PKT, atau IOCTL_INTERNAL_USBFN_TRANSFER_OUT . Setelah memvalidasi setiap permintaan tersebut, UFX meneruskannya ke antrean titik akhir yang sesuai untuk ditangani oleh driver klien. Driver klien diharapkan untuk melakukan validasi tambahan. Driver klien menerima permintaan transfer pada antrean titik akhir. Driver klien dapat mengambil permintaan sebanyak mungkin dari antrean ini karena perlu memaksimalkan pemanfaatan bus. Driver klien harus menyelesaikan permintaan yang berhasil dengan STATUS_SUCCESS. Pengemudi harus berusaha sebaik mungkin untuk membatalkan permintaan, dan menyelesaikan permintaan yang dibatalkan dengan STATUS_CANCELLED jika dibatalkan. Jika parameter yang tidak valid diteruskan, driver klien menyelesaikan permintaan dengan STATUS_INVALID_PARAMETER.

Transfer kontrol

Transfer kontrol dimulai dengan paket penyiapan 8 byte. Untuk mengirim paket penyiapan ke host, driver klien harus memanggil UfxEndpointNotifySetup. UFX memberi tahu driver kelas tentang transfer kontrol non-standar dengan menyelesaikan permintaan pemberitahuan. Klien dan UFX menggunakan IOCTL_INTERNAL_USBFN_TRANSFER_IN, IOCTL_INTERNAL_USBFN_TRANSFER_IN_APPEND_ZERO_PKT, atau IOCTL_INTERNAL_USBFN_TRANSFER_OUT untuk membaca dari dan menulis ke titik akhir kontrol default. Namun, antarmuka dapat menentukan titik akhir kontrol lainnya, yang hanya dapat digunakan oleh driver kelas yang sesuai. Titik akhir kontrol dapat terhenti sebagai respons terhadap paket penyiapan. Driver kelas mengirim permintaan IOCTL_INTERNAL_USBFN_SET_PIPE_STATE untuk mengulur titik akhir. Perangkat keras atau driver klien diharapkan untuk segera melanjutkan lalu lintas di titik akhir setelah kios dikirim. Titik akhir kontrol juga dapat mengirim dan menerima paket panjang nol (ZLP) tanpa data sebelumnya. Driver klien dan UFX dapat melakukan ini dengan menggunakan IOCTL_INTERNAL_USBFN_CONTROL_STATUS_HANDSHAKE_IN dan IOCTL_INTERNAL_USBFN_CONTROL_STATUS_HANDSHAKE_OUT.

Transfer massal dan interupsi

Transfer massal menjamin pengiriman data dan digunakan untuk mengirim data dalam jumlah besar. Transfer dapat dikirim pada titik akhir massal menggunakan IOCTL_INTERNAL_USBFN_TRANSFER_IN, IOCTL_INTERNAL_USBFN_TRANSFER_IN_APPEND_ZERO_PKT, atau IOCTL_INTERNAL_USBFN_TRANSFER_OUT. Titik akhir massal dapat dihentikan mirip dengan titik akhir kontrol menggunakan IOCTL_INTERNAL_USBFN_SET_PIPE_STATE. Driver klien diharapkan untuk mengirim paket STALL sebagai respons terhadap semua permintaan host dan menyimpan permintaan IOCTL. Tidak seperti titik akhir kontrol, titik akhir massal yang terhenti tetap terhenti sampai status kios dihapus secara eksplisit.

Transfer Interupsi Transfer Mengganggu seperti transfer massal, tetapi memiliki latensi yang dijamin. Transfer interupsi memiliki antarmuka yang sama dengan transfer massal, tetapi tidak memiliki kemampuan streaming.

Transfer isochronous

Driver klien tidak diharapkan untuk mendukung transfer isochronous dalam versi ini.

Manajemen daya

Driver klien memiliki semua aspek manajemen daya. Karena fungsi panggilan balik tidak sinkron, driver klien diharapkan untuk kembali ke status daya yang sesuai dan menyelesaikan permintaan sebelum memanggil fungsi ekspor lengkap peristiwa yang sesuai, seperti UfxDeviceEventComplete.

UFX dalam status Bekerja jika status perangkat (ditentukan dalam USBFN_DEVICE_STATE) adalah UsbfnDeviceStateSuspended dan UsbfnDeviceStateAttached, dan belum melaporkan jenis port. Secara bergantian, UFX telah melaporkan jenis port (ditentukan dalam USBFN_PORT_TYPE) UsbfnStandardDownstreamPort atau UsbfnChargingDownstreamPort.

UFX memasuki dan keluar dari status Kerja dengan memanggil implementasi EVT_UFX_DEVICE_USB_STATE_CHANGE atau EVT_UFX_DEVICE_PORT_CHANGE . Transisi ke atau dari status Kerja selesai ketika driver klien memanggil UfxDeviceEventComplete.

Dalam status Bekerja, UFX dapat memanggil panggilan balik apa pun. Meskipun tidak dalam status Bekerja, UFX hanya memanggil EVT_UFX_DEVICE_USB_STATE_CHANGE untuk memasuki status kerja; EVT_UFX_DEVICE_REMOTE_WAKEUP_SIGNAL untuk mengeluarkan bangun jarak jauh selama penangguhan (jika didukung).

Perangkat ditangguhkan

Penangguhan perangkat terjadi ketika tidak ada lalu lintas di bus selama 3 milidetik. Dalam hal ini, driver klien harus menginformasikan UFX ketika mendeteksi menangguhkan dan melanjutkan dengan memanggil UfxDeviceNotifySuspend dan UfxDeviceNotifyResume. Saat menerima panggilan tersebut, UFX memanggil EVT_UFX_DEVICE_USB_STATE_CHANGE dan memberi tahu driver kelas dengan menyelesaikan permintaan IOCTL_INTERNAL_USBFN_BUS_EVENT_NOTIFICATION . Jika bangun jarak jauh didukung oleh perangkat dan diaktifkan oleh host, UFX dapat memanggil panggilan EVT_UFX_DEVICE_USB_STATE_CHANGE saat ditangguhkan untuk mengeluarkan sinyal bangun jarak jauh.