Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Anmärkning
Den här artikeln gäller för utvecklare av enhetsdrivrutiner. Om du har problem med en USB-enhet kan du läsa Åtgärda USB-C problem i Windows
Den här artikeln innehåller information om steg som du kan prova när en dataöverföring till ett USB-rör misslyckas. De mekanismer som nämns i den här artikeln beskriver operationer för att avbryta, återställa och låta cykla portar på bulk-, avbrotts- och isokrona rör.
En USB-klientdrivrutin kommunicerar med sin enhet genom att skicka kontrollöverföringar till standardslutpunkten och dataöverföringar till mass-, avbrotts- och isokrona slutpunkter på enheten. Ibland kan dessa överföringar misslyckas av olika anledningar, till exempel ett blockeringstillstånd i slutpunkten. Om överföringen misslyckas kan det associerade röret inte bearbeta förfrågningar förrän feltillståndet är åtgärdat.
För kontrollöverföringar rensar USB-drivrutinsstacken felförhållandena automatiskt. För dataöverföringar måste klienten vidta lämpliga åtgärder för att återställa från felvillkoret. När en dataöverföring misslyckas rapporterar USB-drivrutinsstacken felet till klientdrivrutinen via misslyckade USBD-statuskoder. Baserat på statuskoden kan drivrutinen sedan tillhandahålla en mekanism för felåterställning.
Den här artikeln innehåller riktlinjer för felåterställning genom dessa åtgärder.
- Återställa USB-röret
 - Återställa USB-porten som enheten är ansluten till
 - Växla USB-porten för att räkna upp enhetsstacken igen för klientdrivrutinen
 
Om du vill rensa ett feltillstånd börjar du med åtgärden reset-pipe och utför mer komplexa åtgärder, till exempel återställningsport och cykelport, endast om det är nödvändigt.
Om att samordna olika återställningsmekanismer:
Klientdrivrutinen måste samordna de olika åtgärderna för återställning och se till att endast en metod används vid en viss tidpunkt. Tänk dig till exempel en enhet med två slutpunkter: en bulk och ett avbrott. När man har skickat några dataöverföringsbegäranden till enheten märker drivrutinen att begäranden misslyckas på bulköverföringskanalen. För att återhämta sig från dessa fel återställer drivrutinen bulkkanalen. Den åtgärden löser dock inte överföringsfelen och massöverföringarna fortsätter att misslyckas. Därför utfärdar drivrutinen en begäran om att återställa USB-porten. Under tiden börjar överföringarna att misslyckas på interrupt pipeline och sedan en begäran om att återställa enheten. För att återhämta sig från avbrott i överföringen utfärdar drivrutinen en reset-pipe-begäran för interrupt-pipen. Om dessa två åtgärder inte samordnas kan drivrutinen starta två återställningsenheter samtidigt på grund av fel i båda rören. Dessa samtidiga åtgärder kan vara problematiska.
Klientdrivrutinen måste se till att drivrutinen vid en viss tidpunkt endast utför en återställning av porten eller en cykelportoperation. Under dessa operationer bör ingen röråterställning pågå och drivrutinen får inte utfärda en ny begäran om röråterställning.
Vad du behöver veta
Den här artikeln använder Kernel-Mode Driver Framework (KMDF).
Förutsättningar
Klientdrivrutinen måste ha skapat ramverkets USB-målenhetsobjekt.
Om du använder DE USB-mallar som tillhandahålls med Microsoft Visual Studio Professional 2012 utför mallkoden dessa uppgifter. Mallkoden hämtar handtaget till målenhetsobjektet och lagrar i enhetskontexten.
En KMDF-klientdrivrutin måste hämta ett WDFUSBDEVICE-handle genom att anropa metoden WdfUsbTargetDeviceCreateWithParameters. Mer information finns i "Enhetens källkod" i Förstå USB-klientdrivrutinens kodstruktur (KMDF).
Klientdrivrutinen måste ha en referens till målpipsobjektet för ramverket. Mer information finns i Så här räknar du upp USB-rör.
Steg 1: Fastställa orsaken till feltillståndet
Klientdrivrutinen initierar en dataöverföring med hjälp av ett USB-begärandeblock (URB). När begäran har slutförts returnerar USB-drivrutinsstacken en USBD-statuskod som anger om överföringen lyckades eller om den misslyckades. Vid ett fel anger USBD-koden orsaken till felet.
- Om du har skickat URB genom att anropa metoden WdfUsbTargetDeviceSendUrbSynchronously, kontrollerar du Hdr.Status medlem i URB--struktur efter att metoden har returnerat.
 - Om du har skickat URB asynkront genom att anropa metoden WdfRequestSend kontrollerar du URB-statusen i EVT_WDF_REQUEST_COMPLETION_ROUTINE. Parametern Params pekar på en WDF_REQUEST_COMPLETION_PARAMS struktur. För att kontrollera USBD-statuskoden, inspektera Usb->UsbdStatus- medlemmen. Information om koden finns i USBD_STATUS.
 
Överföringsfel kan bero på ett enhetsfel, till exempel USBD_STATUS_STALL_PID eller USBD_STATUS_BABBLE_DETECTED. De kan också uppstå på grund av ett fel som rapporterats av värdstyrenheten, till exempel USBD_STATUS_XACT_ERROR.
Steg 2: Avgör om enheten är ansluten till porten
Innan du skickar en begäran som återställer röret eller enheten kontrollerar du att enheten är ansluten. Du kan fastställa enhetens anslutna tillstånd genom att anropa metoden WdfUsbTargetDeviceIsConnectedSynchronous.
Steg 3: Avbryt alla väntande överföringar till röret
Innan du skickar begäranden som återställer röret eller porten avbryter du alla väntande överföringsbegäranden till röret, som USB-drivrutinsstacken ännu inte har slutfört. Du kan avbryta begäranden på något av följande sätt:
Stoppa I/O-målet genom att anropa metoden WdfIoTargetStop.
Om du vill stoppa I/O-målet hämtar du först WDFIOTARGET-referensen som är associerad med ramverkspipeobjektet genom att anropa metoden WdfUsbTargetPipeGetIoTarget. Genom att använda handtaget anropar du WdfIoTargetStop. I anropet anger du åtgärden till WdfIoTargetCancelSentIo (se WDF_IO_TARGET_SENT_IO_ACTION)** för att instruera ramverket att avbryta alla begäranden som USB-drivrutinsstacken inte har slutfört. För begäranden som har slutförts måste klientdrivrutinen vänta på att återanropet anropas av ramverket.
Skicka en begäran om avbrutet rör. Du kan skicka begäran genom att anropa någon av följande metoder:
Anropa metoden WdfUsbTargetPipeAbortSynchronously.
Anropet är synkront och returnerar endast när alla kvarstående begäranden har avbokats. WdfUsbTargetPipeAbortSynchronously tar en valfri Request Parameter. Vi rekommenderar att du skickar en WDFREQUEST-referens till ett förallokerat ramverksbegärandeobjekt. Parametern aktiverar ramverket för användning av det angivna begärandeobjektet i stället för ett internt begärandeobjekt som drivrutinen inte kan komma åt. Det här parametervärdet säkerställer att WdfUsbTargetPipeAbortSynchronously inte misslyckas på grund av otillräckligt minne.
Anropa metoden WdfUsbTargetPipeFormatRequestForAbort för att formatera ett begärandeobjekt för en abort-pipe-begäran och skicka sedan begäran genom att anropa WdfRequestSend-metoden.
Om drivrutinen skickar begäran asynkront måste den ange en pekare till drivrutinens EVT_WDF_REQUEST_COMPLETION_ROUTINE som drivrutinen implementerar. Om du vill ange pekaren anropar du metoden WdfRequestSetCompletionRoutine.
Drivrutinen kan skicka begäran synkront genom att ange WDF_REQUEST_SEND_OPTION_SYNCHRONOUS som ett av begärandealternativen i WdfRequestSend. Om du skickar begäran synkront anropar du WdfUsbTargetPipeAbortSynchronously i stället.
Steg 4: Återställ USB-röret
Starta felåterställningen genom att återställa röret. Du kan skicka en begäran om återställningsrör genom att anropa någon av följande metoder:
Anropa WdfUsbTargetPipeResetSynchronously för att synkront skicka en begäran om att återställa röret.
Anropa metoden WdfUsbTargetPipeFormatRequestForReset för att formatera ett begärandeobjekt för en begäran om återställningsrör och skicka sedan begäran genom att anropa WdfRequestSend-metoden. Dessa anrop liknar dem för begäran om abort-pipe enligt beskrivningen i steg 3.
Anmärkning
Skicka inga nya överföringsförfrågningar förrän reset-pipe-operationen är fullbordad.
Begäran om återställningsrör rensar feltillståndet i enheten och värdstyrenhetens maskinvara. För att rensa enhetsfel skickar USB-drivrutinsstacken en CLEAR_FEATURE-kontrollbegäran till enheten med hjälp av funktionsväljaren ENDPOINT_HALT. Mottagaren för begäran är slutpunkten som är associerad med röret. Om feltillståndet inträffade i ett isochront rör vidtar drivrutinsstacken ingen åtgärd för att rensa enheten eftersom isochrona slutpunkter rensas automatiskt vid fel.
För att rensa värdstyrenhetsfelet tar drivrutinsstacken bort HALT-läget för röret och återställer dataväxlingen för röret till 0.
Steg 5: Återställa USB-porten
Om en reset-pipe-åtgärd inte rensar feltillståndet och dataöverföringarna fortsätter att misslyckas skickar du en begäran om återställningsport.
Avbryt alla överföringar till enheten. Det gör du genom att räkna upp alla rör i den aktuella konfigurationen och avbryta väntande begäranden som schemalagts för varje rör.
Stoppa I/O-målpunkt för enheten.
Anropa metoden WdfUsbTargetDeviceGetIoTarget för att hämta en WDFIOTARGET-referens som är associerad med ramverkets målenhetsobjekt. Anropa sedan WdfIoTargetStop och ange WDFIOTARGET-handtaget. I anrop, ange åtgärden som WdfIoTargetCancelSentIo (WDF_IO_TARGET_SENT_IO_ACTION).
Skicka en begäran om att återställa porten genom att anropa metoden WdfUsbTargetDeviceResetPortSynchronously.
En åtgärd för att återställa porten gör att enheten omidentifieras på USB-bussen. USB-drivrutinsstacken bevarar enhetskonfigurationen efter uppräkningen. Klientdrivrutinen kan använda de tidigare erhållna rörhandtagen eftersom drivrutinsstacken säkerställer att befintliga rörhandtag förblir giltiga.
Du kan inte återställa en enskild funktion för en sammansatt enhet. För en sammansatt enhet återställs hela enheten när klientdrivrutinen för en viss funktion skickar en begäran om återställningsport. Om USB-enheten behåller tillståndet kan begäran om återställningsport påverka klientdrivrutinerna för andra funktioner. Därför är det viktigt att klientdrivrutinen försöker återställa röret innan porten återställs.
Steg 6: Starta om USB-porten
En cykelportåtgärd liknar den enhet som är urkopplad och ansluten tillbaka till porten, förutom att enheten inte är frånkopplad elektriskt. Enheten är frånkopplad och återansluten i programvara. Den här åtgärden leder till enhetsåterställning och uppräkning. Därför återskapar PnP Manager enhetsnoden.
Om en återställningsport inte rensar feltillståndet och dataöverföringarna fortsätter att misslyckas skickar du en begäran om cykelport.
Avbryt alla överföringar till enheten. Se till att du avbryter pågående förfrågningar som schemalagts för varje ledning i den aktuella konfigurationen (se steg 3).
Stoppa I/O-målet för enheten.
Anropa metoden WdfUsbTargetDeviceGetIoTarget för att hämta en WDFIOTARGET-referens som är associerad med ramverkets målenhetsobjekt. Anropa sedan WdfIoTargetStop och ange WDFIOTARGET-handtaget. I anrop anger du åtgärden till WdfIoTargetCancelSentIo (WDF_IO_TARGET_SENT_IO_ACTION).
Skicka en begäran om cykelport genom att anropa någon av följande metoder:
- Anropa WdfUsbTargetDeviceCyclePortSynchronously för att skicka en begäran om cykelport synkront.
 - Anropa metoden WdfUsbTargetDeviceFormatRequestForCyclePort för att formatera ett begärandeobjekt för en cycle-port-begäran och skicka sedan begäran genom att anropa WdfRequestSend-metoden. Dessa anrop liknar de som görs för begäran om abort-pipe, enligt beskrivningen i steg 3.
 
Klientdrivrutinen kan skicka överföringsbegäranden till enheten endast efter att cykelportbegäran har slutförts. Det beror på att enhetsnoden tas bort medan USB-drivrutinsstacken bearbetar begäran om cykelport.
Begäran om cykelport gör att enheten omräknas. USB-drivrutinsstacken informerar PnP Manager om att enheten har kopplats från. PnP Manager river ned enhetsstacken som är associerad med klientdrivrutinen. Drivrutinsstacken återställer enheten, återenumererar den på USB-bussen och informerar PnP-hanteraren om att en enhet har anslutits. PnP Manager återskapar sedan enhetsstacken för USB-enheten.
Som en följd av en cykelportsoperation får alla applikationer med ett öppet handtag till enheten ett meddelande om enhetsborttagning (om applikationen har registrerat sig för ett sådant meddelande). Som svar kan programmet rapportera ett enhetsfrånkopplat meddelande till användaren. Eftersom det påverkar användarens upplevelse bör klientdrivrutinen välja en cykelportbegäran endast om andra återställningsmetoder inte löser feltillståndet.
På samma sätt som återställningsporten (beskrivs i steg 6) påverkar cykelportåtgärden hela enheten och inte enhetens enskilda funktioner för en sammansatt enhet.