Module Name:    src
Committed By:   skrll
Date:           Sun Apr 10 20:48:56 UTC 2016

Modified Files:
        src/sys/dev/usb [nick-nhusb]: xhci.c

Log Message:
Free DMA buffer after disabling slot.
Fix bug DCBA was not cleared after disabling slot.

>From Takahiro HAYASHI


To generate a diff of this commit:
cvs rdiff -u -r1.28.2.62 -r1.28.2.63 src/sys/dev/usb/xhci.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/xhci.c
diff -u src/sys/dev/usb/xhci.c:1.28.2.62 src/sys/dev/usb/xhci.c:1.28.2.63
--- src/sys/dev/usb/xhci.c:1.28.2.62	Sun Apr 10 15:51:32 2016
+++ src/sys/dev/usb/xhci.c	Sun Apr 10 20:48:56 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: xhci.c,v 1.28.2.62 2016/04/10 15:51:32 skrll Exp $	*/
+/*	$NetBSD: xhci.c,v 1.28.2.63 2016/04/10 20:48:56 skrll Exp $	*/
 
 /*
  * Copyright (c) 2013 Jonathan A. Kollasch
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.62 2016/04/10 15:51:32 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.63 2016/04/10 20:48:56 skrll Exp $");
 
 #include "opt_usb.h"
 
@@ -156,6 +156,7 @@ static usbd_status xhci_enable_slot(stru
 static usbd_status xhci_disable_slot(struct xhci_softc * const, uint8_t);
 static usbd_status xhci_address_device(struct xhci_softc * const,
     uint64_t, uint8_t, bool);
+static void xhci_set_dcba(struct xhci_softc * const, uint64_t, int);
 static usbd_status xhci_update_ep0_mps(struct xhci_softc * const,
     struct xhci_slot * const, u_int);
 static usbd_status xhci_ring_init(struct xhci_softc * const,
@@ -2582,29 +2583,36 @@ xhci_disable_slot(struct xhci_softc * co
 {
 	struct xhci_trb trb;
 	struct xhci_slot *xs;
+	usbd_status err;
 
 	XHCIHIST_FUNC(); XHCIHIST_CALLED();
 
 	if (sc->sc_dying)
 		return USBD_IOERROR;
 
-	xs = &sc->sc_slots[slot];
-	if (xs->xs_idx != 0) {
-		for (int i = XHCI_DCI_SLOT + 1; i < 32; i++) {
-			xhci_ring_free(sc, &xs->xs_ep[i].xe_tr);
-			memset(&xs->xs_ep[i], 0, sizeof(xs->xs_ep[i]));
-		}
-		usb_freemem(&sc->sc_bus, &xs->xs_ic_dma);
-		usb_freemem(&sc->sc_bus, &xs->xs_dc_dma);
-	}
-
 	trb.trb_0 = 0;
 	trb.trb_2 = 0;
 	trb.trb_3 = htole32(
 		XHCI_TRB_3_SLOT_SET(slot) |
 		XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_DISABLE_SLOT));
 
-	return xhci_do_command_locked(sc, &trb, USBD_DEFAULT_TIMEOUT);
+	err = xhci_do_command_locked(sc, &trb, USBD_DEFAULT_TIMEOUT);
+
+	if (!err) {
+		xs = &sc->sc_slots[slot];
+		if (xs->xs_idx != 0) {
+			for (int i = XHCI_DCI_SLOT + 1; i < 32; i++) {
+				xhci_ring_free(sc, &xs->xs_ep[i].xe_tr);
+				memset(&xs->xs_ep[i], 0, sizeof(xs->xs_ep[i]));
+			}
+			usb_freemem(&sc->sc_bus, &xs->xs_ic_dma);
+			usb_freemem(&sc->sc_bus, &xs->xs_dc_dma);
+			xhci_set_dcba(sc, 0, slot);
+			memset(xs, 0, sizeof(*xs));
+		}
+	}
+
+	return err;
 }
 
 /*

Reply via email to