c26bb35843
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
371 lines
14 KiB
C
371 lines
14 KiB
C
/****************************************************************************
|
|
* arch/arm/src/samd5e5/sam_usbhost.c
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership. The
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <assert.h>
|
|
|
|
#include <nuttx/usb/usbhost_trace.h>
|
|
|
|
#include "sam_usbhost.h"
|
|
|
|
#ifdef HAVE_USBHOST_TRACE
|
|
|
|
/****************************************************************************
|
|
* Pre-processor Definitions
|
|
****************************************************************************/
|
|
#define TR_FMT1 false
|
|
#define TR_FMT2 true
|
|
|
|
#define TRENTRY(id,fmt1,string) {string}
|
|
|
|
/****************************************************************************
|
|
* Private Types
|
|
****************************************************************************/
|
|
|
|
struct sam_usbhost_trace_s
|
|
{
|
|
const char *string;
|
|
};
|
|
|
|
/****************************************************************************
|
|
* Private Data
|
|
****************************************************************************/
|
|
|
|
static const struct sam_usbhost_trace_s g_trace1[TRACE1_NSTRINGS] =
|
|
{
|
|
TRENTRY(SAM_TRACE1_ALLOC_FAIL, TR_FMT1,
|
|
"INIT: Failed to allocate state structure: %u\n"),
|
|
|
|
#ifdef CONFIG_USBHOST_ASYNCH
|
|
TRENTRY(SAM_TRACE1_ASYNCHSETUP_FAIL1, TR_FMT1,
|
|
"OUT: Asynch setup failed: %u\n"),
|
|
TRENTRY(SAM_TRACE1_ASYNCHSETUP_FAIL2, TR_FMT1,
|
|
"IN: Asynch setup failed: %u\n"),
|
|
#endif
|
|
|
|
TRENTRY(SAM_TRACE1_BAD_JKSTATE, TR_FMT1,
|
|
"CONNECT: Bad JK state: %02x\n"),
|
|
TRENTRY(SAM_TRACE1_BADREVISION, TR_FMT1,
|
|
"INIT: Bad revision number: %02x\n"),
|
|
TRENTRY(SAM_TRACE1_PIPEALLOC_FAIL, TR_FMT1,
|
|
"EPALLOC: Pipe allocation failed: %u\n"),
|
|
TRENTRY(SAM_TRACE1_PIPEWAIT_FAIL, TR_FMT1,
|
|
"OUT: Pipe wait failure: %u\n"),
|
|
TRENTRY(SAM_TRACE1_DEVDISCONN1, TR_FMT1,
|
|
"OUT: Disconnected during wait: %u\n"),
|
|
TRENTRY(SAM_TRACE1_DEVDISCONN2, TR_FMT1,
|
|
"CTRL: Disconnected during SETUP phase: %u\n"),
|
|
TRENTRY(SAM_TRACE1_DEVDISCONN3, TR_FMT1,
|
|
"CTRL OUT: Disconnected during DATA phase: %u\n"),
|
|
TRENTRY(SAM_TRACE1_DEVDISCONN4, TR_FMT1,
|
|
"CTRL IN: Disconnected during DATA phase: %u"),
|
|
TRENTRY(SAM_TRACE1_DEVDISCONN5, TR_FMT1,
|
|
"IN: Disconnected during wait: %u\n"),
|
|
TRENTRY(SAM_TRACE1_DEVDISCONN6, TR_FMT1,
|
|
"CONNECT: Device disconnect #1: %u\n"),
|
|
TRENTRY(SAM_TRACE1_DEVDISCONN7, TR_FMT1,
|
|
"CONNECT: Device disconnect #2: %u\n"),
|
|
TRENTRY(SAM_TRACE1_DEVDISCONN8, TR_FMT1,
|
|
"CONNECT: Device disconnect #3: %u\n"),
|
|
TRENTRY(SAM_TRACE1_ENUMERATE_FAIL, TR_FMT1,
|
|
"CONNECT: Enumeration failed: %u\n"),
|
|
TRENTRY(SAM_TRACE1_INSETUP_FAIL1, TR_FMT1,
|
|
"CTRL IN: SETUP phase failure: %u\n"),
|
|
|
|
#ifdef CONFIG_USBHOST_ASYNCH
|
|
TRENTRY(SAM_TRACE1_INSETUP_FAIL2, TR_FMT1,
|
|
"CTRL IN: Asynch SETUP phase failure #1: %u\n"),
|
|
TRENTRY(SAM_TRACE1_INSETUP_FAIL3, TR_FMT1,
|
|
"CTRL IN: Asynch SETUP phase failure #2: %u\n"),
|
|
#endif
|
|
|
|
TRENTRY(SAM_TRACE1_IRQATTACH_FAIL, TR_FMT1,
|
|
"INIT: Failed to attach interrupt: %u\n"),
|
|
TRENTRY(SAM_TRACE1_OUTSETUP_FAIL1, TR_FMT1,
|
|
"CTRL OUT: SETUP phase failure: %u\n"),
|
|
|
|
#ifdef CONFIG_USBHOST_ASYNCH
|
|
TRENTRY(SAM_TRACE1_OUTSETUP_FAIL2, TR_FMT1,
|
|
"CTRL OUT: Asynch SETUP phase failure #1: %u\n"),
|
|
TRENTRY(SAM_TRACE1_OUTSETUP_FAIL3, TR_FMT1,
|
|
"CTRL OUT: Asynch SETUP phase failure #2: %u\n"),
|
|
#endif
|
|
|
|
TRENTRY(SAM_TRACE1_RECVDATA_FAIL, TR_FMT1,
|
|
"CTRL IN: Data phase failure: %u\n"),
|
|
TRENTRY(SAM_TRACE1_RECVSTATUS_FAIL, TR_FMT1,
|
|
"CTRL OUT: Status phase failure: %u\n"),
|
|
TRENTRY(SAM_TRACE1_SENDDATA_FAIL, TR_FMT1,
|
|
"CTRL OUT: Data phase failure: %u\n"),
|
|
TRENTRY(SAM_TRACE1_SENDSETUP_FAIL1, TR_FMT1,
|
|
"CTRL OUT: SETUP phase failure: %u\n"),
|
|
TRENTRY(SAM_TRACE1_SENDSETUP_FAIL2, TR_FMT1,
|
|
"CTRL IN: SETUP phase failure: %u\n"),
|
|
TRENTRY(SAM_TRACE1_SENDSTATUS_FAIL, TR_FMT1,
|
|
"CTRL IN: Status phase failure: %u\n"),
|
|
TRENTRY(SAM_TRACE1_TRANSFER_FAILED1, TR_FMT1,
|
|
"OUT: Transfer wait returned failure: %u\n"),
|
|
TRENTRY(SAM_TRACE1_TRANSFER_FAILED2, TR_FMT1,
|
|
"CTRL: SETUP wait returned failure: %u\n"),
|
|
TRENTRY(SAM_TRACE1_TRANSFER_FAILED3, TR_FMT1,
|
|
"IN: Transfer wait returned failure: %u\n"),
|
|
|
|
#ifdef HAVE_USBHOST_TRACE_VERBOSE
|
|
TRENTRY(SAM_VTRACE1_CANCEL, TR_FMT1,
|
|
"Transfer canceled: EP%u\n"),
|
|
TRENTRY(SAM_VTRACE1_CONNECTED1, TR_FMT1,
|
|
"CONNECT: Connection event: %u\n"),
|
|
TRENTRY(SAM_VTRACE1_CONNECTED2, TR_FMT1,
|
|
"CONNECT: Connection change detected: %u\n"),
|
|
TRENTRY(SAM_VTRACE1_CONNECTED3, TR_FMT1,
|
|
"CONNECT: Connected: %u\n"),
|
|
TRENTRY(SAM_VTRACE1_DISCONNECTED1, TR_FMT1,
|
|
"CONNECT: Disconnected: %u\n"),
|
|
TRENTRY(SAM_VTRACE1_DISCONNECTED2, TR_FMT1,
|
|
"CONNECT: Disconnect detected: %u\n"),
|
|
TRENTRY(SAM_VTRACE1_ENUMERATE, TR_FMT1,
|
|
"ENUMERATE: Start: %u\n"),
|
|
|
|
#ifdef CONFIG_USBHOST_HUB
|
|
TRENTRY(SAM_VTRACE1_HUB_CONNECTED, TR_FMT1,
|
|
"CONNECT: Hub connected: %u\n"),
|
|
#endif
|
|
TRENTRY(SAM_VTRACE1_INITIALIZED, TR_FMT1,
|
|
"INIT: Hardware initialized: %u\n"),
|
|
#ifdef CONFIG_USBHOST_ASYNCH
|
|
TRENTRY(SAM_VTRACE1_TRANSFER_COMPLETE, TR_FMT1,
|
|
"OUT: Asynch transfer complete: %u\n"),
|
|
#endif
|
|
#endif
|
|
|
|
TRENTRY(TRACE1_DEVDISCONN, TR_FMT1,
|
|
"ERROR: RHport%d Device disconnected\n"),
|
|
TRENTRY(TRACE1_INTRUNRECOVERABLE, TR_FMT1,
|
|
"ERROR: Unrecoverable error. pending: %06x\n"),
|
|
TRENTRY(TRACE1_INTRUNHANDLED, TR_FMT1,
|
|
"ERROR: Unhandled interrupts pending: %06x\n"),
|
|
TRENTRY(TRACE1_EPLISTALLOC_FAILED, TR_FMT1,
|
|
"ERROR: Failed to allocate EP list\n"),
|
|
TRENTRY(TRACE1_EDALLOC_FAILED, TR_FMT1,
|
|
"ERROR: Failed to allocate ED\n"),
|
|
TRENTRY(TRACE1_TDALLOC_FAILED, TR_FMT1,
|
|
"ERROR: Failed to allocate TD\n"),
|
|
TRENTRY(TRACE1_IRQATTACH, TR_FMT1,
|
|
"ERROR: Failed to attach IRQ%d\n"),
|
|
#ifdef CONFIG_USBHOST_ASYNCH
|
|
TRENTRY(TRACE1_BADTDSTATUS, TR_FMT1,
|
|
"ERROR: Bad asynch TD completion status: %d\n"),
|
|
#endif
|
|
|
|
#ifdef HAVE_USBHOST_TRACE_VERBOSE
|
|
TRENTRY(VTRACE1_PHYSED, TR_FMT1,
|
|
"physed: %06x\n"),
|
|
TRENTRY(VTRACE1_VIRTED, TR_FMT1,
|
|
"ed: %06x\n"),
|
|
TRENTRY(VTRACE1_CSC, TR_FMT1,
|
|
"Connect Status Change, RHSTATUS: %06x\n"),
|
|
TRENTRY(VTRACE1_DRWE, TR_FMT1,
|
|
"DRWE: Remote wake-up, RHSTATUS: %06x\n"),
|
|
TRENTRY(VTRACE1_ALREADYCONN, TR_FMT1,
|
|
"Already connected, RHPORTST: %06x\n"),
|
|
TRENTRY(VTRACE1_SPEED, TR_FMT1,
|
|
"Port speed: %d\n"),
|
|
TRENTRY(VTRACE1_ALREADYDISCONN, TR_FMT1,
|
|
"Already disconnected, RHPORTST: %06x\n"),
|
|
TRENTRY(VTRACE1_RHSC, TR_FMT1,
|
|
"Root Hub Status Change. Pending: %06x\n"),
|
|
TRENTRY(VTRACE1_WDHINTR, TR_FMT1,
|
|
"Writeback Done Head interrupt. Pending: %06x\n"),
|
|
TRENTRY(VTRACE1_CLASSENUM, TR_FMT1,
|
|
"Hub port %d: Enumerate device\n"),
|
|
TRENTRY(VTRACE1_ENUMDISCONN, TR_FMT1,
|
|
"RHport%dNot connected\n"),
|
|
TRENTRY(VTRACE1_INITIALIZING, TR_FMT1,
|
|
"Initializing Stack\n"),
|
|
TRENTRY(VTRACE1_INITIALIZED, TR_FMT1,
|
|
"Initialized\n"),
|
|
TRENTRY(VTRACE1_INTRPENDING, TR_FMT1,
|
|
"Interrupts pending: %06x\n"),
|
|
#endif
|
|
};
|
|
|
|
static const struct sam_usbhost_trace_s g_trace2[TRACE2_NSTRINGS] =
|
|
{
|
|
#ifdef HAVE_USBHOST_TRACE_VERBOSE
|
|
#ifdef CONFIG_USBHOST_ASYNCH
|
|
TRENTRY(SAM_VTRACE2_ASYNCH, TR_FMT2,
|
|
"ASYNCH: Transfer started: EP%u len=%u\n"),
|
|
#endif
|
|
TRENTRY(SAM_VTRACE2_BULKIN, TR_FMT2,
|
|
"BULK IN: SETUP: pipe%u len=%u\n"),
|
|
TRENTRY(SAM_VTRACE2_BULKOUT, TR_FMT2,
|
|
"BULK OUT: SETUP: pipe%u len=%u\n"),
|
|
TRENTRY(SAM_VTRACE2_PIPEWAKEUP_IN, TR_FMT2,
|
|
"IN: Pipe Wakeup: pipe%u, result=%u\n"),
|
|
TRENTRY(SAM_VTRACE2_PIPEWAKEUP_OUT, TR_FMT2,
|
|
"OUT: Pipe Wakeup: pipe%u result=%u\n"),
|
|
TRENTRY(SAM_VTRACE2_CTRLIN, TR_FMT2,
|
|
"CTRL IN: Start: type=%u req=%u\n"),
|
|
TRENTRY(SAM_VTRACE2_CTRLOUT, TR_FMT2,
|
|
"CTRL OUT: Start: type=%u req=%u\n"),
|
|
#ifdef CONFIG_USBHOST_HUB
|
|
TRENTRY(SAM_VTRACE2_HUB_CONNECTED, TR_FMT2,
|
|
"CONNECT: Hub connected: port=%u, connected=%u\n"),
|
|
#endif
|
|
TRENTRY(SAM_VTRACE2_INTRIN, TR_FMT2,
|
|
"INTR IN: SETUP: pipe%u len=%u\n"),
|
|
TRENTRY(SAM_VTRACE2_INTROUT, TR_FMT2,
|
|
"INTR OUT: SETUP: pipe%u len=%u\n"),
|
|
TRENTRY(SAM_VTRACE2_ISOCIN, TR_FMT2,
|
|
"ISOC IN: SETUP: pipe%u len=%u\n"),
|
|
TRENTRY(SAM_VTRACE2_ISOCOUT, TR_FMT2,
|
|
"ISOC OUT: SETUP: pipe%u len=%u\n"),
|
|
TRENTRY(SAM_VTRACE2_RECVSTATUS, TR_FMT2,
|
|
"CTRL OUT: Receive status: pipe%u len=%u\n"),
|
|
TRENTRY(SAM_VTRACE2_SENDSTATUS, TR_FMT2,
|
|
"CTRL IN: Send status: pipe%u len=%u\n"),
|
|
TRENTRY(SAM_VTRACE2_STARTTRANSFER1, TR_FMT2,
|
|
"OUT: Send start: pipe%u len=%u\n"),
|
|
TRENTRY(SAM_VTRACE2_STARTTRANSFER2, TR_FMT2,
|
|
"IN: Receive start: pipe%u len=%u\n"),
|
|
TRENTRY(SAM_VTRACE2_TRANSFER, TR_FMT2,
|
|
"Transfer start: EP%u len=%u\n"),
|
|
TRENTRY(SAM_VTRACE2_PIPECONF_CTRL_IN, TR_FMT2,
|
|
"Pipe%d configured (EP%d,IN ,CTRL)\n"),
|
|
TRENTRY(SAM_VTRACE2_PIPECONF_CTRL_OUT, TR_FMT2,
|
|
"Pipe%d configured (EP%d,OUT,CTRL)\n"),
|
|
TRENTRY(SAM_VTRACE2_PIPECONF_INTR_IN, TR_FMT2,
|
|
"Pipe%d configured (EP%d,IN ,INTR)\n"),
|
|
TRENTRY(SAM_VTRACE2_PIPECONF_INTR_OUT, TR_FMT2,
|
|
"Pipe%d configured (EP%d,OUT,INTR)\n"),
|
|
TRENTRY(SAM_VTRACE2_PIPECONF_BULK_IN, TR_FMT2,
|
|
"Pipe%d configured (EP%d,IN ,BULK)\n"),
|
|
TRENTRY(SAM_VTRACE2_PIPECONF_BULK_OUT, TR_FMT2,
|
|
"Pipe%d configured (EP%d,OUT,BULK)\n"),
|
|
TRENTRY(SAM_VTRACE2_PIPECONF_ISOC_IN, TR_FMT2,
|
|
"Pipe%d configured (EP%d,IN ,ISOC)\n"),
|
|
TRENTRY(SAM_VTRACE2_PIPECONF_ISOC_OUT, TR_FMT2,
|
|
"Pipe%d configured (EP%d,OUT,ISOC)\n"),
|
|
|
|
#ifdef CONFIG_USBHOST_ASYNCH
|
|
TRENTRY(SAM_VTRACE2_XFRCOMPLETE, TR_FMT2,
|
|
"ASYNCH: Transfer complete: EP%u len=%u\n"),
|
|
#endif
|
|
#endif
|
|
|
|
TRENTRY(TRACE2_BADTDSTATUS, TR_FMT2,
|
|
"ERROR: RHport%d Bad TD completion status: %d\n"),
|
|
TRENTRY(TRACE2_WHDTDSTATUS, TR_FMT2,
|
|
"ERROR: WHD Bad TD completion status: %d xfrtype: %d\n"),
|
|
TRENTRY(TRACE2_EP0ENQUEUE_FAILED, TR_FMT2,
|
|
"ERROR: RHport%d Failed to enqueue EP0: %d\n"),
|
|
TRENTRY(TRACE2_EDENQUEUE_FAILED, TR_FMT2,
|
|
"ERROR: Failed to queue ED for transfer type %d: %d\n"),
|
|
TRENTRY(TRACE2_CLASSENUM_FAILED, TR_FMT2,
|
|
"Hub port %d usbhost_enumerate() failed: %d\n"),
|
|
|
|
#ifdef HAVE_USBHOST_TRACE_VERBOSE
|
|
TRENTRY(VTRACE2_EP0CONFIG, TR_FMT2,
|
|
"EP0 configure speed=%d funcaddr=%d\n"),
|
|
TRENTRY(VTRACE2_INTERVAL, TR_FMT2,
|
|
"interval: %d->%d\n"),
|
|
TRENTRY(VTRACE2_MININTERVAL, TR_FMT2,
|
|
"MIN interval: %d offset: %d\n"),
|
|
TRENTRY(VTRACE2_RHPORTST, TR_FMT2,
|
|
"RHPORTST%d: %04x\n"),
|
|
TRENTRY(VTRACE2_CONNECTED, TR_FMT2,
|
|
"RHPort%d connected, rhswait: %d\n"),
|
|
TRENTRY(VTRACE2_DISCONNECTED, TR_FMT2,
|
|
"RHPort%d disconnected, rhswait: %d\n"),
|
|
TRENTRY(VTRACE2_WAKEUP, TR_FMT2,
|
|
"RHPort%d connected: %d\n"),
|
|
TRENTRY(VTRACE2_EP0CTRLED, TR_FMT2,
|
|
"RHPort%d EP0 CTRL: %04x\n"),
|
|
TRENTRY(VTRACE2_EPALLOC, TR_FMT2,
|
|
"EP%d CTRL: %04x\n"),
|
|
TRENTRY(VTRACE2_CTRLIN, TR_FMT2,
|
|
"CTRLIN RHPort%d req: %02x\n"),
|
|
TRENTRY(VTRACE2_CTRLOUT, TR_FMT2,
|
|
"CTRLOUT RHPort%d req: %02x\n"),
|
|
TRENTRY(VTRACE2_TRANSFER, TR_FMT2,
|
|
"EP%d buflen: %d\n"),
|
|
TRENTRY(VTRACE2_INITCONNECTED, TR_FMT2,
|
|
"RHPort%d Device connected: %d\n"),
|
|
#ifdef CONFIG_USBHOST_HUB
|
|
TRENTRY(VTRACE2_HUBWAKEUP, TR_FMT2,
|
|
"Hub Port%d connected: %d\n"),
|
|
#endif
|
|
#endif
|
|
};
|
|
|
|
/****************************************************************************
|
|
* Private Function Prototypes
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Public Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: usbhost_trformat1 and usbhost_trformat2
|
|
*
|
|
* Description:
|
|
* This interface must be provided by platform specific logic that knows
|
|
* the HCDs encoding of USB trace data.
|
|
*
|
|
* Given an 9-bit index, return a format string suitable for use with, say,
|
|
* printf. The returned format is expected to handle two unsigned integer
|
|
* values.
|
|
*
|
|
****************************************************************************/
|
|
|
|
const char *usbhost_trformat1(uint16_t id)
|
|
{
|
|
int ndx = TRACE1_INDEX(id);
|
|
|
|
if (ndx < TRACE1_NSTRINGS)
|
|
{
|
|
return g_trace1[ndx].string;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const char *usbhost_trformat2(uint16_t id)
|
|
{
|
|
int ndx = TRACE2_INDEX(id);
|
|
|
|
if (ndx < TRACE2_NSTRINGS)
|
|
{
|
|
return g_trace2[ndx].string;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
#endif /* HAVE_USBHOST_TRACE */
|