Commit 505a8e65 authored by Robert Sprowson's avatar Robert Sprowson

Stop the endpoint when software's finished with it

Tell the controller when a pipe is closed, so it doesn't need to schedule time to look at endpoints we're not using any more. Also guards against packets arriving which USBDriver isn't expecting to receive.
From NetBSD revision 1.28.2.19.

Version 0.15. Tagged as 'XHCIDriver-0_15'
parent 3a3d343d
/* (0.14)
/* (0.15)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.14
#define Module_MajorVersion_CMHG 0.15
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 03 Jun 2016
#define Module_Date_CMHG 06 Jun 2016
#define Module_MajorVersion "0.14"
#define Module_Version 14
#define Module_MajorVersion "0.15"
#define Module_Version 15
#define Module_MinorVersion ""
#define Module_Date "03 Jun 2016"
#define Module_Date "06 Jun 2016"
#define Module_ApplicationDate "03-Jun-16"
#define Module_ApplicationDate "06-Jun-16"
#define Module_ComponentName "XHCIDriver"
#define Module_ComponentPath "mixed/RiscOS/Sources/HWSupport/USB/Controllers/XHCIDriver"
#define Module_FullVersion "0.14"
#define Module_HelpVersion "0.14 (03 Jun 2016)"
#define Module_LibraryVersionInfo "0:14"
#define Module_FullVersion "0.15"
#define Module_HelpVersion "0.15 (06 Jun 2016)"
#define Module_LibraryVersionInfo "0:15"
......@@ -144,6 +144,7 @@ struct xhci_pipe {
#define XHCI_TRB_3_ED_BIT XHCI_TRB_3_ISP_BIT /* Event data */
static usbd_status xhci_open(usbd_pipe_handle);
static void xhci_close_pipe(usbd_pipe_handle);
static int xhci_intr1(struct xhci_softc * const);
static void xhci_softintr(void *);
static void xhci_poll(struct usbd_bus *);
......@@ -165,7 +166,7 @@ static usbd_status xhci_new_device(device_t, usbd_bus_handle, int, int, int,
static usbd_status xhci_configure_endpoint(usbd_pipe_handle);
static usbd_status xhci_unconfigure_endpoint(usbd_pipe_handle);
static usbd_status xhci_reset_endpoint(usbd_pipe_handle);
//static usbd_status xhci_stop_endpoint(usbd_pipe_handle);
static usbd_status xhci_stop_endpoint(usbd_pipe_handle);
static usbd_status xhci_set_dequeue(usbd_pipe_handle);
......@@ -1177,6 +1178,7 @@ xhci_configure_endpoint(usbd_pipe_handle pipe)
return err;
}
#ifndef BRANCH_NHUSB /* unused */
static usbd_status
xhci_unconfigure_endpoint(usbd_pipe_handle pipe)
{
......@@ -1189,6 +1191,7 @@ xhci_unconfigure_endpoint(usbd_pipe_handle pipe)
return USBD_NORMAL_COMPLETION;
}
#endif
static usbd_status
xhci_reset_endpoint(usbd_pipe_handle pipe)
......@@ -1213,7 +1216,7 @@ xhci_reset_endpoint(usbd_pipe_handle pipe)
return err;
}
#if 0
#ifdef BRANCH_NHUSB
static usbd_status
xhci_stop_endpoint(usbd_pipe_handle pipe)
{
......@@ -1336,6 +1339,77 @@ xhci_open(usbd_pipe_handle pipe)
}
#ifdef BRANCH_NHUSB
/*
* Closes pipe, called from usbd_kill_pipe via close methods.
* If the endpoint to be closed is ep0, disable_slot.
* Should be called with sc_lock held.
*/
static void
xhci_close_pipe(usbd_pipe_handle pipe)
{
struct xhci_softc * const sc = pipe->device->bus->hci_private;
struct xhci_slot * const xs = pipe->device->hci_private;
usb_endpoint_descriptor_t * const ed = pipe->endpoint->edesc;
const u_int dci = xhci_ep_get_dci(ed);
struct xhci_trb trb;
uint32_t *cp;
XHCIHIST_FUNC(); XHCIHIST_CALLED();
if (sc->sc_dying)
return;
/* xs is uninitialized before xhci_init_slot */
if (xs == NULL || xs->xs_idx == 0)
return;
DPRINTFN(4, "pipe %p slot %u dci %u", pipe, xs->xs_idx, dci, 0);
KASSERTMSG(!cpu_intr_p() && !cpu_softintr_p(), "called from intr ctx");
KASSERT(mutex_owned(&sc->sc_lock));
if (pipe->device->depth == 0)
return;
if (dci == XHCI_DCI_EP_CONTROL) {
DPRINTFN(4, "closing ep0", 0, 0, 0, 0);
#ifndef RISCOS
xhci_disable_slot(sc, xs->xs_idx);
#endif
return;
}
/*
* This may fail in the case that xhci_close_pipe is called after
* xhci_abort_xfer e.g. usbd_kill_pipe.
*/
(void)xhci_stop_endpoint(pipe);
/*
* set appropriate bit to be dropped.
* don't set DC bit to 1, otherwise all endpoints
* would be deconfigured.
*/
cp = xhci_slot_get_icv(sc, xs, XHCI_ICI_INPUT_CONTROL);
cp[0] = htole32(XHCI_INCTX_0_DROP_MASK(dci));
cp[1] = htole32(0);
/* XXX should be most significant one, not dci? */
cp = xhci_slot_get_icv(sc, xs, xhci_dci_to_ici(XHCI_DCI_SLOT));
cp[0] = htole32(XHCI_SCTX_0_CTX_NUM_SET(dci));
/* sync input contexts before they are read from memory */
usb_syncmem(&xs->xs_ic_dma, 0, sc->sc_pgsz, BUS_DMASYNC_PREWRITE);
trb.trb_0 = xhci_slot_get_icp(sc, xs, XHCI_ICI_INPUT_CONTROL);
trb.trb_2 = 0;
trb.trb_3 = XHCI_TRB_3_SLOT_SET(xs->xs_idx) |
XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_CONFIGURE_EP);
(void)xhci_do_command(sc, &trb, USBD_DEFAULT_TIMEOUT);
usb_syncmem(&xs->xs_dc_dma, 0, sc->sc_pgsz, BUS_DMASYNC_POSTREAD);
}
/*
* Recover STALLed endpoint.
* xHCI 1.1 sect 4.10.2.1
......@@ -3289,6 +3363,10 @@ static void
xhci_device_ctrl_close(usbd_pipe_handle pipe)
{
XHCIHIST_FUNC(); XHCIHIST_CALLED();
#ifdef BRANCH_NHUSB
xhci_close_pipe(pipe);
#endif
}
/* ----------------- */
......@@ -3409,6 +3487,10 @@ static void
xhci_device_bulk_close(usbd_pipe_handle pipe)
{
XHCIHIST_FUNC(); XHCIHIST_CALLED();
#ifdef BRANCH_NHUSB
xhci_close_pipe(pipe);
#endif
}
/* --------------- */
......@@ -3543,7 +3625,11 @@ xhci_device_intr_close(usbd_pipe_handle pipe)
XHCIHIST_FUNC(); XHCIHIST_CALLED();
DPRINTFN(15, "%p", pipe, 0, 0, 0);
#ifdef BRANCH_NHUSB
xhci_close_pipe(pipe);
#else
xhci_unconfigure_endpoint(pipe);
#endif
}
/* ------------ */
......
......@@ -37,6 +37,7 @@ typedef int pmf_qual_t; /* No power management functions */
/* Porting definitions */
#define KASSERT(k) /* Nothing */
#define KASSERTMSG(k,m) /* Nothing */
#define UNUSED(k) (k)=(k)
#define USBHIST_FUNC() /* Nothing */
#define USBHIST_CALLED(a) /* Nothing */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment