Cara memulihkan dari kesalahan pipa USB

Catatan

Artikel ini untuk pengembang driver perangkat. Jika Anda mengalami kesulitan dengan perangkat USB, silakan lihat Memecahkan masalah USB umum

Artikel ini menyediakan informasi tentang langkah-langkah yang dapat Anda coba saat transfer data ke pipa USB gagal. Mekanisme yang dijelaskan dalam artikel ini mencakup operasi pembatalan, reset, dan port siklus pada pipa massal, interupsi, dan isochronous.

Driver klien USB berkomunikasi dengan perangkatnya dengan mengirim transfer kontrol ke titik akhir default; transfer data ke titik akhir perangkat secara massal, interupsi, dan isochronous. Terkadang, transfer tersebut dapat gagal karena berbagai alasan, seperti kondisi kios di titik akhir. Jika transfer gagal, pipa terkait tidak dapat memproses permintaan hingga kondisi kesalahan dibersihkan.

Untuk transfer kontrol, tumpukan driver USB menghapus kondisi kesalahan secara otomatis. Untuk transfer data, klien harus mengambil langkah-langkah yang tepat untuk pulih dari kondisi kesalahan. Ketika transfer data gagal, tumpukan driver USB melaporkan kesalahan ke driver klien melalui kode status USBD yang gagal. Berdasarkan kode status, driver kemudian dapat memberikan mekanisme pemulihan kesalahan.

Artikel ini menyediakan panduan tentang pemulihan kesalahan melalui operasi ini.

  • Mengatur ulang pipa USB
  • Mengatur ulang port USB tempat perangkat tersambung
  • Siklus port USB untuk menghitung ulang tumpukan perangkat untuk driver klien

Untuk menghapus kondisi kesalahan, mulailah dengan operasi reset-pipe dan lakukan operasi yang lebih kompleks, seperti reset-port dan cycle-port, hanya jika diperlukan.

Tentang mengoordinasikan berbagai mekanisme pemulihan:

Driver klien harus mengoordinasikan berbagai operasi untuk pemulihan dan memastikan bahwa hanya satu metode yang digunakan pada waktu tertentu. Misalnya, pertimbangkan perangkat dengan dua titik akhir: massal dan interupsi. Setelah mengirim beberapa permintaan transfer data ke perangkat, driver melihat bahwa permintaan gagal pada pipa massal. Untuk memulihkan dari kesalahan tersebut, driver mengatur ulang pipa massal. Namun, operasi tersebut tidak menyelesaikan kesalahan transfer dan transfer massal terus gagal. Oleh karena itu, driver mengeluarkan permintaan untuk mengatur ulang port USB. Sementara itu, transfer mulai gagal pada pipa interupsi, dan kemudian permintaan perangkat reset. Untuk memulihkan dari kegagalan transfer interupsi, driver mengeluarkan permintaan reset-pipe pada pipa interupsi. Jika kedua operasi tersebut tidak dikoordinasikan, driver dapat memulai dua operasi perangkat reset secara bersamaan, karena kegagalan pada kedua pipa. Operasi simultan tersebut bisa bermasalah.

Driver klien harus memastikan bahwa pada waktu tertentu, driver hanya melakukan satu operasi port reset atau port siklus. Selama operasi tersebut, operasi reset-pipe tidak boleh berlangsung pada pipa apa pun dan driver tidak boleh mengeluarkan permintaan reset-pipe baru.

Apa yang perlu Anda ketahui

Artikel ini menggunakan Kerangka Kerja Driver Mode Kernel (KMDF).

Prasyarat

  • Driver klien harus telah membuat objek perangkat target USB kerangka kerja.

    Jika Anda menggunakan templat USB yang disediakan dengan Microsoft Visual Studio Professional 2012, kode templat melakukan tugas tersebut. Kode templat mendapatkan handel ke objek perangkat target dan disimpan dalam konteks perangkat.

    Driver klien KMDF harus mendapatkan handel WDFUSBDEVICE dengan memanggil metode WdfUsbTargetDeviceCreateWithParameters . Untuk informasi selengkapnya, lihat "Kode sumber perangkat" dalam Memahami struktur kode driver klien USB (KMDF).

  • Driver klien harus memiliki handel ke objek pipa target kerangka kerja. Untuk informasi selengkapnya, lihat Cara menghitung pipa USB.

Langkah 1: Tentukan penyebab kondisi kesalahan

Driver klien memulai transfer data dengan menggunakan Blok Permintaan USB (URB). Setelah permintaan selesai, tumpukan driver USB mengembalikan kode status USBD yang menunjukkan apakah transfer berhasil atau gagal. Dalam kegagalan, kode USBD menunjukkan alasan kegagalan.

Kegagalan transfer dapat disebabkan oleh kesalahan perangkat, seperti USBD_STATUS_STALL_PID atau USBD_STATUS_BABBLE_DETECTED. Ini juga dapat diakibatkan karena kesalahan yang dilaporkan oleh pengontrol host, seperti USBD_STATUS_XACT_ERROR.

Langkah 2: Tentukan apakah perangkat tersambung ke port

Sebelum mengeluarkan permintaan apa pun yang mengatur ulang pipa atau perangkat, pastikan perangkat tersambung. Anda dapat menentukan status perangkat yang terhubung dengan memanggil metode WdfUsbTargetDeviceIsConnectedSynchronous .

Langkah 3: Batalkan semua transfer yang tertunda ke pipa

Sebelum mengirim permintaan apa pun yang mengatur ulang pipa atau port, batalkan semua permintaan transfer yang tertunda ke pipa, yang belum diselesaikan oleh tumpukan driver USB. Anda dapat membatalkan permintaan dengan salah satu cara berikut:

  • Hentikan target I/O dengan memanggil metode WdfIoTargetStop .

    Untuk menghentikan target I/O, pertama-tama, dapatkan handel WDFIOTARGET yang terkait dengan objek pipa kerangka kerja dengan memanggil metode WdfUsbTargetPipeGetIoTarget . Dengan menggunakan handel, panggil WdfIoTargetStop. Dalam panggilan, atur tindakan ke WdfIoTargetCancelSentIo (lihat WDF_IO_TARGET_SENT_IO_ACTION)** untuk menginstruksikan kerangka kerja untuk membatalkan semua permintaan yang belum diselesaikan tumpukan driver USB. Untuk permintaan yang telah selesai, driver klien harus menunggu panggilan balik penyelesaiannya dipanggil oleh kerangka kerja.

  • Kirim permintaan abort-pipe. Anda dapat mengirim permintaan dengan memanggil salah satu metode berikut:

Langkah 4: Reset pipa USB

Mulai pemulihan kesalahan dengan mengatur ulang pipa. Anda dapat mengirim permintaan reset-pipe dengan memanggil salah satu metode berikut:

Catatan

Jangan mengirim permintaan transfer baru hingga operasi reset-pipe selesai.

Permintaan reset-pipe menghapus kondisi kesalahan di perangkat dan perangkat keras pengontrol host. Untuk menghapus kesalahan perangkat, tumpukan driver USB mengirimkan permintaan kontrol CLEAR_FEATURE ke perangkat dengan menggunakan pemilih fitur ENDPOINT_HALT. Penerima untuk permintaan adalah titik akhir yang terkait dengan pipa. Jika kondisi kesalahan terjadi pada pipa isochronous, tumpukan driver tidak mengambil tindakan untuk menghapus perangkat karena, jika terjadi kesalahan, titik akhir isochronous dihapus secara otomatis.

Untuk menghapus kesalahan pengontrol host, tumpukan driver menghapus status HALT pipa dan mengatur ulang pengalih data pipa ke 0.

Langkah 5: Reset port USB

Jika operasi reset-pipe tidak menghapus kondisi kesalahan dan transfer data terus gagal, kirim permintaan reset-port.

  1. Batalkan semua transfer ke perangkat. Untuk melakukannya, hitung semua pipa dalam konfigurasi saat ini dan batalkan permintaan tertunda yang dijadwalkan untuk setiap pipa.

  2. Hentikan target I/O untuk perangkat.

    Panggil metode WdfUsbTargetDeviceGetIoTarget untuk mendapatkan handel WDFIOTARGET yang terkait dengan objek perangkat target kerangka kerja. Kemudian, panggil WdfIoTargetStop dan tentukan handel WDFIOTARGET. Dalam panggilan, atur tindakan ke WdfIoTargetCancelSentIo (WDF_IO_TARGET_SENT_IO_ACTION).

  3. Kirim permintaan reset-port dengan memanggil metode WdfUsbTargetDeviceResetPortSynchronously .

Operasi reset-port menyebabkan perangkat dijumlahkan kembali pada bus USB. Tumpukan driver USB mempertahankan konfigurasi perangkat setelah enumerasi. Driver klien dapat menggunakan handel pipa yang diperoleh sebelumnya karena tumpukan driver memastikan bahwa handel pipa yang ada tetap valid.

Anda tidak dapat mengatur ulang fungsi individual perangkat komposit. Untuk perangkat komposit, ketika driver klien dari fungsi tertentu mengirim permintaan reset-port, seluruh perangkat diatur ulang. Jika perangkat USB mempertahankan status, permintaan reset-port tersebut dapat memengaruhi driver klien fungsi lain. Oleh karena itu, penting bahwa driver klien mencoba mengatur ulang pipa sebelum mengatur ulang port.

Langkah 6: Siklus port USB

Operasi port siklus mirip dengan perangkat yang dicabut dan dicolokkan kembali ke port, kecuali perangkat tidak terputus secara listrik. Perangkat terputus dan tersambung kembali dalam perangkat lunak. Operasi ini mengarah pada reset dan enumerasi perangkat. Akibatnya, Manajer PnP membangun kembali simpul perangkat.

Jika operasi reset-port tidak menghapus kondisi kesalahan dan transfer data terus gagal, kirim permintaan port siklus.

  1. Batalkan semua transfer ke perangkat. Pastikan Anda membatalkan permintaan tertunda yang dijadwalkan untuk setiap pipa dalam konfigurasi saat ini (lihat langkah 3).

  2. Hentikan target I/O untuk perangkat.

    Panggil metode WdfUsbTargetDeviceGetIoTarget untuk mendapatkan handel WDFIOTARGET yang terkait dengan objek perangkat target kerangka kerja. Kemudian, panggil WdfIoTargetStop dan tentukan handel WDFIOTARGET. Dalam panggilan, atur tindakan ke WdfIoTargetCancelSentIo (WDF_IO_TARGET_SENT_IO_ACTION).

  3. Kirim permintaan port siklus dengan memanggil salah satu metode berikut:

Driver klien dapat mengirim permintaan transfer ke perangkat hanya setelah permintaan port siklus selesai. Itu karena simpul perangkat dihapus saat tumpukan driver USB memproses permintaan port siklus.

Permintaan port siklus menyebabkan perangkat dijumlahkan kembali. Tumpukan driver USB memberi tahu Manajer PnP bahwa perangkat telah terputus. Manajer PnP merobek tumpukan perangkat yang terkait dengan driver klien. Tumpukan driver mengatur ulang perangkat, menghitungnya kembali di bus USB, dan memberi tahu Manajer PnP bahwa perangkat telah terhubung. PnP Manager kemudian membangun kembali tumpukan perangkat untuk perangkat USB.

Sebagai hasil dari operasi port siklus, aplikasi apa pun yang memiliki handel terbuka untuk perangkat mendapatkan pemberitahuan penghapusan perangkat (jika aplikasi terdaftar untuk pemberitahuan seperti itu). Sebagai respons, aplikasi mungkin melaporkan pesan yang terputus dari perangkat kepada pengguna. Karena berdampak pada pengalaman pengguna, driver klien harus memilih permintaan port siklus hanya jika mekanisme pemulihan lain tidak menyelesaikan kondisi kesalahan.

Mirip dengan operasi reset-port (dijelaskan di langkah 6), untuk perangkat komposit, operasi port siklus memengaruhi seluruh perangkat dan bukan fungsi individual perangkat.