diff --git a/arch/arm/src/kinetis/hardware/kinetis_k28memorymap.h b/arch/arm/src/kinetis/hardware/kinetis_k28memorymap.h index 49e4294860d..78b73e36e43 100644 --- a/arch/arm/src/kinetis/hardware/kinetis_k28memorymap.h +++ b/arch/arm/src/kinetis/hardware/kinetis_k28memorymap.h @@ -1,35 +1,20 @@ /****************************************************************************************** * arch/arm/src/kinetis/hardware/kinetis_k28memorymap.h * - * Copyright (C) 2018 Gregory Nutt. All rights reserved. - * Authors: Gregory Nutt + * 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 * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * 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. * ******************************************************************************************/ @@ -102,7 +87,7 @@ # define KINETIS_FLEXBUSWT_BASE 0x98000000 /* FlexBus * (External Memory - Write-through) */ # define KINETIS_FLEXBUSEP_BASE 0xa0000000 /* FlexBus - * External Peripheral - Not executable)*/ + * External Peripheral - Not executable) */ # define KINETIS_PERIPH_BASE 0xe0000000 /* Private peripherals */ /* Peripheral Bridge 0 Memory Map *********************************************************/ diff --git a/arch/arm/src/kinetis/hardware/kinetis_usbhs.h b/arch/arm/src/kinetis/hardware/kinetis_usbhs.h index 4af1c3afa70..1fc1191ad50 100644 --- a/arch/arm/src/kinetis/hardware/kinetis_usbhs.h +++ b/arch/arm/src/kinetis/hardware/kinetis_usbhs.h @@ -32,23 +32,23 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ******************************************************************************************************************* */ + ********************************************************************************************************************/ #ifndef __ARCH_ARM_SRC_KINETIS_HARDWARE_KINETIS_USBHS_H #define __ARCH_ARM_SRC_KINETIS_HARDWARE_KINETIS_USBHS_H /******************************************************************************************************************** * Included Files - ******************************************************************************************************************* */ + ********************************************************************************************************************/ #include #include "chip.h" /******************************************************************************************************************** * Pre-processor Definitions - ******************************************************************************************************************* */ + ********************************************************************************************************************/ -/* Register Offsets ************************************************************************************************ */ +/* Register Offsets *************************************************************************************************/ #define KINETIS_USBHS_ID_OFFSET 0x0000 /* Identification Register */ #define KINETIS_USBHS_HWGENERAL_OFFSET 0x0004 /* General Hardware Parameters */ @@ -158,7 +158,7 @@ #define KINETIS_USBHSDCD_TIMER2_BC11_OFFSET 0x0018 /* TIMER2_BC11 register */ #define KINETIS_USBHSDCD_TIMER2_BC12_OFFSET 0x001c /* TIMER2_BC12 register */ -/* Register Addresses ********************************************************************************************** */ +/* Register Addresses ***********************************************************************************************/ #define KINETIS_USBHS_ID (KINETIS_USBHS_BASE + KINETIS_USBHS_ID_OFFSET) #define KINETIS_USBHS_HWGENERAL (KINETIS_USBHS_BASE + KINETIS_USBHS_HWGENERAL_OFFSET) @@ -268,7 +268,8 @@ #define KINETIS_USBHSDCD_TIMER2_BC11 (KINETIS_USBHSDCD_BASE + KINETIS_USBHSDCD_TIMER2_BC11_OFFSET) #define KINETIS_USBHSDCD_TIMER2_BC12 (KINETIS_USBHSDCD_BASE + KINETIS_USBHSDCD_TIMER2_BC12_OFFSET) -/* Register Bit-Field Definitions ********************************************************************************** */ +/* Register Bit-Field Definitions ***********************************************************************************/ + /* Identification Register */ #define USBHS_ID_VERSIONID_SHIFT (29) /* Bits 29-31: Version ID */ @@ -336,8 +337,8 @@ /* General Purpose Timer n Load Register */ - /* Bits 24-31: Reserved */ -#define USBHS_GPTIMERnLD_GPTLD_SHIFT (0) /* Bits 0-23: Value to be loaded into the countdown timer on reset */ + /* Bits 24-31: Reserved */ +#define USBHS_GPTIMERnLD_GPTLD_SHIFT (0) /* Bits 0-23: Value to be loaded into the countdown timer on reset */ #define USBHS_GPTIMERnLD_GPTLD_MASK (0xffffff << USBHS_GPTIMERnLD_GPTLD_SHIFT) /* General Purpose Timer n Control Register */ @@ -798,7 +799,7 @@ #define USBPHY_DEBUGn_SQUELCHRESETLENGTH_MASK (0xf << USBPHY_DEBUGn_SQUELCHRESETLENGTH_SHIFT) #define USBPHY_DEBUGn_ENSQUELCHRESET (1 << 24) /* Bit 24: Set bit to allow squelch to reset high-speed receive */ /* Bits 21-23: Reserved */ -#define USBPHY_DEBUGn_SQUELCHRESETCOUNT_SHIFT (16) /* Bits 16-20: Delay in between the detection of squelch to the reset of high-speed RX */ +#define USBPHY_DEBUGn_SQUELCHRESETCOUNT_SHIFT (16) /* Bits 16-20: Delay in between the detection of squelch to the reset of high-speed RX */ #define USBPHY_DEBUGn_SQUELCHRESETCOUNT_MASK (0x1f << USBPHY_DEBUGn_SQUELCHRESETCOUNT_SHIFT) /* Bits 13-15: Reserved */ #define USBPHY_DEBUGn_ENTX2RXCOUNT (1 << 12) /* Bit 12: Allow a countdown to transition in between TX and RX */ @@ -830,9 +831,9 @@ /* UTMI RTL Version */ -#define USBPHY_VERSION_MAJOR_SHIFT (24) /* Bits 24-31: Fixed read-only value reflecting the MAJOR field of the RTL version */ +#define USBPHY_VERSION_MAJOR_SHIFT (24) /* Bits 24-31: Fixed read-only value reflecting the MAJOR field of the RTL version */ #define USBPHY_VERSION_MAJOR_MASK (0xff << USBPHY_VERSION_MAJOR_SHIFT) -#define USBPHY_VERSION_MINOR_SHIFT (16) /* Bits 16-23: Fixed read-only value reflecting the MINOR field of the RTL version */ +#define USBPHY_VERSION_MINOR_SHIFT (16) /* Bits 16-23: Fixed read-only value reflecting the MINOR field of the RTL version */ #define USBPHY_VERSION_MINOR_MASK (0xff << USBPHY_VERSION_MINOR_SHIFT) #define USBPHY_VERSION_STEP_SHIFT (0) /* Bits 0-15: Fixed read-only value reflecting the stepping of the RTL version */ #define USBPHY_VERSION_STEP_MASK (0xffff << USBPHY_VERSION_STEP_SHIFT) @@ -927,9 +928,9 @@ /* USB PHY Loopback Packet Number Select Register */ -#define USBPHY_USB1_LOOPBACK_HSFSCNTn_TSTI_FS_NUMBER_SHIFT (16) /* Bits 16-31: Full speed packet number */ +#define USBPHY_USB1_LOOPBACK_HSFSCNTn_TSTI_FS_NUMBER_SHIFT (16) /* Bits 16-31: Full speed packet number */ #define USBPHY_USB1_LOOPBACK_HSFSCNTn_TSTI_FS_NUMBER_MASK (0xffff << USBPHY_USB1_LOOPBACK_HSFSCNTn_TSTI_FS_NUMBER_SHIFT) -#define USBPHY_USB1_LOOPBACK_HSFSCNTn_TSTI_HS_NUMBER_SHIFT (0) /* Bits 0-15: High speed packet number */ +#define USBPHY_USB1_LOOPBACK_HSFSCNTn_TSTI_HS_NUMBER_SHIFT (0) /* Bits 0-15: High speed packet number */ #define USBPHY_USB1_LOOPBACK_HSFSCNTn_TSTI_HS_NUMBER_MASK (0xffff << USBPHY_USB1_LOOPBACK_HSFSCNTn_TSTI_HS_NUMBER_SHIFT) /* USB PHY Trim Override Enable Register */ diff --git a/arch/arm/src/kinetis/kinetis_usbdev.c b/arch/arm/src/kinetis/kinetis_usbdev.c index 64a3d359f1b..77a3cb131a8 100644 --- a/arch/arm/src/kinetis/kinetis_usbdev.c +++ b/arch/arm/src/kinetis/kinetis_usbdev.c @@ -1,9 +1,20 @@ -/**************************************************************************** +/****************************************************************************************** * arch/arm/src/kinetis/kinetis_usbdev.c * - * Copyright (C) 2011-2014, 2016-2017 Gregory Nutt. All rights reserved. - * Authors: Gregory Nutt - * David Sidrane + * 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. * * References: * This file derives from the STM32 USB device driver with modifications @@ -16,38 +27,11 @@ * K66 Sub-Family Reference Manual, Rev. 2, May 2015 * How to Implement USB Suspend/Resume - Document Number: AN5385 * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ + ******************************************************************************************/ -/**************************************************************************** +/****************************************************************************************** * Included Files - ****************************************************************************/ + ******************************************************************************************/ #include @@ -76,16 +60,20 @@ #if defined(CONFIG_USBDEV) -/**************************************************************************** +/****************************************************************************************** * Pre-processor Definitions - ****************************************************************************/ + ******************************************************************************************/ -/* Configuration ************************************************************/ +/* Configuration **************************************************************************/ #ifndef CONFIG_USBDEV_EP0_MAXSIZE # define CONFIG_USBDEV_EP0_MAXSIZE 64 #endif +#ifndef CONFIG_USBDEV_SETUP_MAXDATASIZE +# define CONFIG_USBDEV_SETUP_MAXDATASIZE (CONFIG_USBDEV_EP0_MAXSIZE * 4) +#endif + /* Extremely detailed register/BDT debug that you would normally never want * enabled. */ @@ -103,9 +91,10 @@ #undef CONFIG_USBDEV_NOREADAHEAD /* Makes no difference */ #undef CONFIG_USBDEV_NOWRITEAHEAD -#define CONFIG_USBDEV_NOWRITEAHEAD 1 /* Fixes some problems with IN transfers */ +#define CONFIG_USBDEV_NOWRITEAHEAD /* Fixes some problems with IN transfers */ + +/* Interrupts *****************************************************************************/ -/* Interrupts ***************************************************************/ /* Initial interrupt sets */ #ifdef CONFIG_USB_SOFINTS @@ -121,7 +110,7 @@ #define NORMAL_INTERRUPTS (USB_INT_USBRST | USB_INT_ERROR | USB_SOF_INTERRUPT | \ USB_INT_TOKDNE | USB_INT_SLEEP | USB_INT_STALL) -/* Endpoints ****************************************************************/ +/* Endpoints ******************************************************************************/ #define USB_STAT_ENDPT(n) ((n) << USB_STAT_ENDP_SHIFT) /* Endpoint n, n=0..15 */ @@ -186,7 +175,7 @@ #define REQRECIPIENT_MASK (USB_REQ_TYPE_MASK | USB_REQ_RECIPIENT_MASK) -/* Request queue operations *************************************************/ +/* Request queue operations ***************************************************************/ #define khci_rqempty(q) ((q)->head == NULL) #define khci_rqhead(q) ((q)->head) @@ -198,7 +187,8 @@ * Kinetis lib */ -/* USB trace ****************************************************************/ +/* USB trace ******************************************************************************/ + /* Trace error codes */ #define KHCI_TRACEERR_ALLOCFAIL 0x0001 @@ -267,47 +257,51 @@ #define KHCI_TRACEINTID_SUSPENDED 0x0023 #define KHCI_TRACEINTID_RESUME 0x0024 #define KHCI_TRACEINTID_WAITRESET 0x0025 +#define KHCI_TRACEINTID_EP0SETUPOUT 0x0026 +#define KHCI_TRACEINTID_EP0SETUPOUTDATA 0x0027 #ifdef CONFIG_USBDEV_TRACE_STRINGS const struct trace_msg_t g_usb_trace_strings_intdecode[] = { - TRACE_STR(KHCI_TRACEINTID_CLEARFEATURE ), /* 0x0001 */ - TRACE_STR(KHCI_TRACEINTID_DEVGETSTATUS ), /* 0x0002 */ - TRACE_STR(KHCI_TRACEINTID_DISPATCH ), /* 0x0003 */ - TRACE_STR(KHCI_TRACEINTID_EP0IN ), /* 0x0004 */ - TRACE_STR(KHCI_TRACEINTID_EP0INDONE ), /* 0x0005 */ - TRACE_STR(KHCI_TRACEINTID_EP0OUTDONE ), /* 0x0006 */ - TRACE_STR(KHCI_TRACEINTID_EP0SETUPDONE ), /* 0x0007 */ - TRACE_STR(KHCI_TRACEINTID_EP0SETUPSETADDRESS ), /* 0x0008 */ - TRACE_STR(KHCI_TRACEINTID_EP0ADDRESSSET ), /* 0x0009 */ - TRACE_STR(KHCI_TRACEINTID_EPGETSTATUS ), /* 0x000a */ - TRACE_STR(KHCI_TRACEINTID_EPINDONE ), /* 0x000b */ - TRACE_STR(KHCI_TRACEINTID_EPINQEMPTY ), /* 0x000c */ - TRACE_STR(KHCI_TRACEINTID_EPOUTDONE ), /* 0x000d */ - TRACE_STR(KHCI_TRACEINTID_EPOUTQEMPTY ), /* 0x000e */ - TRACE_STR(KHCI_TRACEINTID_SOF ), /* 0x000f */ - TRACE_STR(KHCI_TRACEINTID_GETCONFIG ), /* 0x0010 */ - TRACE_STR(KHCI_TRACEINTID_GETSETDESC ), /* 0x0011 */ - TRACE_STR(KHCI_TRACEINTID_GETSETIF ), /* 0x0012 */ - TRACE_STR(KHCI_TRACEINTID_GETSTATUS ), /* 0x0013 */ - TRACE_STR(KHCI_TRACEINTID_IFGETSTATUS ), /* 0x0014 */ - TRACE_STR(KHCI_TRACEINTID_TRNC ), /* 0x0015 */ - TRACE_STR(KHCI_TRACEINTID_TRNCS ), /* 0x0016 */ - TRACE_STR(KHCI_TRACEINTID_INTERRUPT ), /* 0x0017 */ - TRACE_STR(KHCI_TRACEINTID_NOSTDREQ ), /* 0x0018 */ - TRACE_STR(KHCI_TRACEINTID_RESET ), /* 0x0019 */ - TRACE_STR(KHCI_TRACEINTID_SETCONFIG ), /* 0x001a */ - TRACE_STR(KHCI_TRACEINTID_SETFEATURE ), /* 0x001b */ - TRACE_STR(KHCI_TRACEINTID_IDLE ), /* 0x001c */ - TRACE_STR(KHCI_TRACEINTID_SYNCHFRAME ), /* 0x001d */ - TRACE_STR(KHCI_TRACEINTID_WKUP ), /* 0x001e */ - TRACE_STR(KHCI_TRACEINTID_T1MSEC ), /* 0x001f */ - TRACE_STR(KHCI_TRACEINTID_OTGID ), /* 0x0020 */ - TRACE_STR(KHCI_TRACEINTID_STALL ), /* 0x0021 */ - TRACE_STR(KHCI_TRACEINTID_UERR ), /* 0x0022 */ - TRACE_STR(KHCI_TRACEINTID_SUSPENDED ), /* 0x0023 */ - TRACE_STR(KHCI_TRACEINTID_RESUME ), /* 0x0024 */ - TRACE_STR(KHCI_TRACEINTID_WAITRESET ), /* 0x0025 */ + TRACE_STR(KHCI_TRACEINTID_CLEARFEATURE), /* 0x0001 */ + TRACE_STR(KHCI_TRACEINTID_DEVGETSTATUS), /* 0x0002 */ + TRACE_STR(KHCI_TRACEINTID_DISPATCH), /* 0x0003 */ + TRACE_STR(KHCI_TRACEINTID_EP0IN), /* 0x0004 */ + TRACE_STR(KHCI_TRACEINTID_EP0INDONE), /* 0x0005 */ + TRACE_STR(KHCI_TRACEINTID_EP0OUTDONE), /* 0x0006 */ + TRACE_STR(KHCI_TRACEINTID_EP0SETUPDONE), /* 0x0007 */ + TRACE_STR(KHCI_TRACEINTID_EP0SETUPSETADDRESS), /* 0x0008 */ + TRACE_STR(KHCI_TRACEINTID_EP0ADDRESSSET), /* 0x0009 */ + TRACE_STR(KHCI_TRACEINTID_EPGETSTATUS), /* 0x000a */ + TRACE_STR(KHCI_TRACEINTID_EPINDONE), /* 0x000b */ + TRACE_STR(KHCI_TRACEINTID_EPINQEMPTY), /* 0x000c */ + TRACE_STR(KHCI_TRACEINTID_EPOUTDONE), /* 0x000d */ + TRACE_STR(KHCI_TRACEINTID_EPOUTQEMPTY), /* 0x000e */ + TRACE_STR(KHCI_TRACEINTID_SOF), /* 0x000f */ + TRACE_STR(KHCI_TRACEINTID_GETCONFIG), /* 0x0010 */ + TRACE_STR(KHCI_TRACEINTID_GETSETDESC), /* 0x0011 */ + TRACE_STR(KHCI_TRACEINTID_GETSETIF), /* 0x0012 */ + TRACE_STR(KHCI_TRACEINTID_GETSTATUS), /* 0x0013 */ + TRACE_STR(KHCI_TRACEINTID_IFGETSTATUS), /* 0x0014 */ + TRACE_STR(KHCI_TRACEINTID_TRNC), /* 0x0015 */ + TRACE_STR(KHCI_TRACEINTID_TRNCS), /* 0x0016 */ + TRACE_STR(KHCI_TRACEINTID_INTERRUPT), /* 0x0017 */ + TRACE_STR(KHCI_TRACEINTID_NOSTDREQ), /* 0x0018 */ + TRACE_STR(KHCI_TRACEINTID_RESET), /* 0x0019 */ + TRACE_STR(KHCI_TRACEINTID_SETCONFIG), /* 0x001a */ + TRACE_STR(KHCI_TRACEINTID_SETFEATURE), /* 0x001b */ + TRACE_STR(KHCI_TRACEINTID_IDLE), /* 0x001c */ + TRACE_STR(KHCI_TRACEINTID_SYNCHFRAME), /* 0x001d */ + TRACE_STR(KHCI_TRACEINTID_WKUP), /* 0x001e */ + TRACE_STR(KHCI_TRACEINTID_T1MSEC), /* 0x001f */ + TRACE_STR(KHCI_TRACEINTID_OTGID), /* 0x0020 */ + TRACE_STR(KHCI_TRACEINTID_STALL), /* 0x0021 */ + TRACE_STR(KHCI_TRACEINTID_UERR), /* 0x0022 */ + TRACE_STR(KHCI_TRACEINTID_SUSPENDED), /* 0x0023 */ + TRACE_STR(KHCI_TRACEINTID_RESUME), /* 0x0024 */ + TRACE_STR(KHCI_TRACEINTID_WAITRESET), /* 0x0025 */ + TRACE_STR(KHCI_TRACEINTID_EP0SETUPOUT), /* 0x0026 */ + TRACE_STR(KHCI_TRACEINTID_EP0SETUPOUTDATA), /* 0x0027 */ TRACE_STR_END }; #endif @@ -315,37 +309,37 @@ const struct trace_msg_t g_usb_trace_strings_intdecode[] = #ifdef CONFIG_USBDEV_TRACE_STRINGS const struct trace_msg_t g_usb_trace_strings_deverror[] = { - TRACE_STR(KHCI_TRACEERR_ALLOCFAIL ), /* 0x0001 */ - TRACE_STR(KHCI_TRACEERR_BADCLEARFEATURE ), /* 0x0002 */ - TRACE_STR(KHCI_TRACEERR_BADDEVGETSTATUS ), /* 0x0003 */ - TRACE_STR(KHCI_TRACEERR_BADEPGETSTATUS ), /* 0x0004 */ - TRACE_STR(KHCI_TRACEERR_BADEPNO ), /* 0x0005 */ - TRACE_STR(KHCI_TRACEERR_BADEPTYPE ), /* 0x0006 */ - TRACE_STR(KHCI_TRACEERR_BADGETCONFIG ), /* 0x0007 */ - TRACE_STR(KHCI_TRACEERR_BADGETSETDESC ), /* 0x0008 */ - TRACE_STR(KHCI_TRACEERR_BADGETSTATUS ), /* 0x0009 */ - TRACE_STR(KHCI_TRACEERR_BADSETADDRESS ), /* 0x000a */ - TRACE_STR(KHCI_TRACEERR_BADSETCONFIG ), /* 0x000b */ - TRACE_STR(KHCI_TRACEERR_BADSETFEATURE ), /* 0x000c */ - TRACE_STR(KHCI_TRACEERR_BINDFAILED ), /* 0x000d */ - TRACE_STR(KHCI_TRACEERR_DISPATCHSTALL ), /* 0x000e */ - TRACE_STR(KHCI_TRACEERR_DRIVER ), /* 0x000f */ - TRACE_STR(KHCI_TRACEERR_DRIVERREGISTERED ), /* 0x0010 */ - TRACE_STR(KHCI_TRACEERR_EP0SETUPSTALLED ), /* 0x0011 */ - TRACE_STR(KHCI_TRACEERR_EPDISABLED ), /* 0x0012 */ - TRACE_STR(KHCI_TRACEERR_EPOUTNULLPACKET ), /* 0x0013 */ - TRACE_STR(KHCI_TRACEERR_EPRESERVE ), /* 0x0014 */ - TRACE_STR(KHCI_TRACEERR_INVALIDCTRLREQ ), /* 0x0015 */ - TRACE_STR(KHCI_TRACEERR_INVALIDPARMS ), /* 0x0016 */ - TRACE_STR(KHCI_TRACEERR_IRQREGISTRATION ), /* 0x0017 */ - TRACE_STR(KHCI_TRACEERR_NOTCONFIGURED ), /* 0x0018 */ - TRACE_STR(KHCI_TRACEERR_REQABORTED ), /* 0x0019 */ - TRACE_STR(KHCI_TRACEERR_INVALIDSTATE ), /* 0x001a */ + TRACE_STR(KHCI_TRACEERR_ALLOCFAIL), /* 0x0001 */ + TRACE_STR(KHCI_TRACEERR_BADCLEARFEATURE), /* 0x0002 */ + TRACE_STR(KHCI_TRACEERR_BADDEVGETSTATUS), /* 0x0003 */ + TRACE_STR(KHCI_TRACEERR_BADEPGETSTATUS), /* 0x0004 */ + TRACE_STR(KHCI_TRACEERR_BADEPNO), /* 0x0005 */ + TRACE_STR(KHCI_TRACEERR_BADEPTYPE), /* 0x0006 */ + TRACE_STR(KHCI_TRACEERR_BADGETCONFIG), /* 0x0007 */ + TRACE_STR(KHCI_TRACEERR_BADGETSETDESC), /* 0x0008 */ + TRACE_STR(KHCI_TRACEERR_BADGETSTATUS), /* 0x0009 */ + TRACE_STR(KHCI_TRACEERR_BADSETADDRESS), /* 0x000a */ + TRACE_STR(KHCI_TRACEERR_BADSETCONFIG), /* 0x000b */ + TRACE_STR(KHCI_TRACEERR_BADSETFEATURE), /* 0x000c */ + TRACE_STR(KHCI_TRACEERR_BINDFAILED), /* 0x000d */ + TRACE_STR(KHCI_TRACEERR_DISPATCHSTALL), /* 0x000e */ + TRACE_STR(KHCI_TRACEERR_DRIVER), /* 0x000f */ + TRACE_STR(KHCI_TRACEERR_DRIVERREGISTERED), /* 0x0010 */ + TRACE_STR(KHCI_TRACEERR_EP0SETUPSTALLED), /* 0x0011 */ + TRACE_STR(KHCI_TRACEERR_EPDISABLED), /* 0x0012 */ + TRACE_STR(KHCI_TRACEERR_EPOUTNULLPACKET), /* 0x0013 */ + TRACE_STR(KHCI_TRACEERR_EPRESERVE), /* 0x0014 */ + TRACE_STR(KHCI_TRACEERR_INVALIDCTRLREQ), /* 0x0015 */ + TRACE_STR(KHCI_TRACEERR_INVALIDPARMS), /* 0x0016 */ + TRACE_STR(KHCI_TRACEERR_IRQREGISTRATION), /* 0x0017 */ + TRACE_STR(KHCI_TRACEERR_NOTCONFIGURED), /* 0x0018 */ + TRACE_STR(KHCI_TRACEERR_REQABORTED), /* 0x0019 */ + TRACE_STR(KHCI_TRACEERR_INVALIDSTATE), /* 0x001a */ TRACE_STR_END }; #endif -/* Misc Helper Macros *******************************************************/ +/* Misc Helper Macros *********************************************************************/ /* Ever-present MIN and MAX macros */ @@ -367,7 +361,8 @@ const struct trace_msg_t g_usb_trace_strings_deverror[] = # define MSB 1 #endif -/* Debug ********************************************************************/ +/* Debug **********************************************************************************/ + /* CONFIG_KHCI_USBDEV_REGDEBUG enables dumping of all low-level register * access and BDT accesses. Normally, this generates so much debug output * that USB may not even be functional. @@ -391,9 +386,9 @@ const struct trace_msg_t g_usb_trace_strings_deverror[] = # define bdtinfo(x...) #endif -/**************************************************************************** +/****************************************************************************************** * Private Type Definitions - ****************************************************************************/ + ******************************************************************************************/ /* Overvall device state */ @@ -413,6 +408,9 @@ enum khci_devstate_e enum khci_ctrlstate_e { CTRLSTATE_WAITSETUP = 0, /* No request in progress, waiting for setup */ + CTRLSTATE_SETUP_OUT, /* Set up received with data for device OUT in progress */ + CTRLSTATE_SETUP_READY, /* Set up was received prior and is in ctrl, + * now the data has arrived */ CTRLSTATE_RDREQUEST, /* Read request (OUT) in progress */ CTRLSTATE_WRREQUEST, /* Write request (IN) in progress */ CTRLSTATE_STALL, /* EP0 stall requested */ @@ -469,6 +467,7 @@ struct khci_ep_s uint8_t txnullpkt:1; /* Null packet needed at end of TX transfer */ uint8_t txdata1:1; /* Data0/1 of next TX transfer */ uint8_t rxdata1:1; /* Data0/1 of next RX transfer */ + volatile struct usbotg_bdtentry_s *bdtin; /* BDT entry for the IN transaction */ volatile struct usbotg_bdtentry_s *bdtout; /* BDT entry for the OUT transaction */ }; @@ -499,23 +498,28 @@ struct khci_usbdev_s uint16_t epstalled; /* Bitset of stalled endpoints */ WDOG_ID wdog; /* Supports the restart delay */ + uint8_t out0data[2][CONFIG_USBDEV_EP0_MAXSIZE]; + uint8_t ep0data[CONFIG_USBDEV_SETUP_MAXDATASIZE]; + uint16_t ep0datlen; + uint16_t ep0datreq; + /* The endpoint list */ struct khci_ep_s eplist[KHCI_NENDPOINTS]; }; -/**************************************************************************** +/****************************************************************************************** * Private Function Prototypes - ****************************************************************************/ + ******************************************************************************************/ -/* Register operations ******************************************************/ +/* Register operations ********************************************************************/ #ifdef CONFIG_KHCI_USBDEV_REGDEBUG static uint16_t khci_getreg(uint32_t addr); static void khci_putreg(uint32_t val, uint32_t addr); #endif -/* Suspend/Resume Helpers ***************************************************/ +/* Suspend/Resume Helpers *****************************************************************/ #ifndef CONFIG_KINETIS_USBOTG static void khci_suspend(struct khci_usbdev_s *priv); @@ -523,7 +527,7 @@ static void khci_suspend(struct khci_usbdev_s *priv); static void khci_remote_resume(struct khci_usbdev_s *priv); static void khci_resume(struct khci_usbdev_s *priv); -/* Request Queue Management *************************************************/ +/* Request Queue Management ***************************************************************/ static struct khci_req_s *khci_remfirst(struct khci_queue_s *queue); static struct khci_req_s *khci_remlast(struct khci_queue_s *queue); @@ -532,7 +536,7 @@ static void khci_addlast(struct khci_queue_s *queue, static void khci_addfirst(struct khci_queue_s *queue, struct khci_req_s *req); -/* Request Helpers **********************************************************/ +/* Request Helpers ************************************************************************/ static void khci_reqreturn(struct khci_ep_s *privep, struct khci_req_s *privreq, int16_t result); @@ -562,7 +566,7 @@ static int khci_rdrequest(struct khci_usbdev_s *priv, static void khci_cancelrequests(struct khci_ep_s *privep, int16_t result); -/* Interrupt level processing ***********************************************/ +/* Interrupt level processing *************************************************************/ static void khci_dispatchrequest(struct khci_usbdev_s *priv); static void khci_ep0stall(struct khci_usbdev_s *priv); @@ -577,7 +581,7 @@ static void khci_ep0transfer(struct khci_usbdev_s *priv, uint16_t ustat); static int khci_interrupt(int irq, void *context, FAR void *arg); -/* Endpoint helpers *********************************************************/ +/* Endpoint helpers ***********************************************************************/ static inline struct khci_ep_s * khci_epreserve(struct khci_usbdev_s *priv, uint8_t epset); @@ -588,7 +592,7 @@ static inline bool khci_epreserved(struct khci_usbdev_s *priv, int epno); static void khci_ep0configure(struct khci_usbdev_s *priv); -/* Endpoint operations ******************************************************/ +/* Endpoint operations ********************************************************************/ static int khci_epconfigure(struct usbdev_ep_s *ep, const struct usb_epdesc_s *desc, bool last); @@ -605,7 +609,7 @@ static int khci_epbdtstall(struct usbdev_ep_s *ep, bool resume, bool epin); static int khci_epstall(struct usbdev_ep_s *ep, bool resume); -/* USB device controller operations *****************************************/ +/* USB device controller operations *******************************************************/ static struct usbdev_ep_s * khci_allocep(struct usbdev_s *dev, uint8_t epno, bool in, @@ -615,7 +619,7 @@ static int khci_getframe(struct usbdev_s *dev); static int khci_wakeup(struct usbdev_s *dev); static int khci_selfpowered(struct usbdev_s *dev, bool selfpowered); -/* Initialization/Reset *****************************************************/ +/* Initialization/Reset *******************************************************************/ static void khci_reset(struct khci_usbdev_s *priv); static void khci_attach(struct khci_usbdev_s *priv); @@ -625,9 +629,9 @@ static void khci_swinitialize(struct khci_usbdev_s *priv); static void khci_hwinitialize(struct khci_usbdev_s *priv); static void khci_hwshutdown(struct khci_usbdev_s *priv); -/**************************************************************************** +/****************************************************************************************** * Private Data - ****************************************************************************/ + ******************************************************************************************/ /* Since there is only a single USB interface, all status information can be * be simply retained in a single global instance. @@ -671,17 +675,17 @@ static const struct usbdev_ops_s g_devops = static volatile struct usbotg_bdtentry_s g_bdt[4*KHCI_NENDPOINTS] __attribute__ ((aligned(512))); -/**************************************************************************** +/****************************************************************************************** * Private Private Functions - ****************************************************************************/ + ******************************************************************************************/ -/**************************************************************************** +/****************************************************************************************** * Register Operations - ****************************************************************************/ + ******************************************************************************************/ - /**************************************************************************** +/****************************************************************************************** * Name: khci_getreg - ****************************************************************************/ + ******************************************************************************************/ #ifdef CONFIG_KHCI_USBDEV_REGDEBUG static uint16_t khci_getreg(uint32_t addr) @@ -702,10 +706,10 @@ static uint16_t khci_getreg(uint32_t addr) { if (count == 0xffffffff || ++count > 3) { - if (count == 4) - { - uinfo("...\n"); - } + if (count == 4) + { + uinfo("...\n"); + } return val; } } @@ -714,20 +718,20 @@ static uint16_t khci_getreg(uint32_t addr) else { - /* Did we print "..." for the previous value? */ + /* Did we print "..." for the previous value? */ - if (count > 3) - { - /* Yes.. then show how many times the value repeated */ + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ - uinfo("[repeats %d more times]\n", count-3); - } + uinfo("[repeats %d more times]\n", count - 3); + } - /* Save the new address, value, and count */ + /* Save the new address, value, and count */ - prevaddr = addr; - preval = val; - count = 1; + prevaddr = addr; + preval = val; + count = 1; } /* Show the register value read */ @@ -737,9 +741,9 @@ static uint16_t khci_getreg(uint32_t addr) } #endif -/**************************************************************************** +/****************************************************************************************** * Name: khci_putreg - ****************************************************************************/ + ******************************************************************************************/ #ifdef CONFIG_KHCI_USBDEV_REGDEBUG static void khci_putreg(uint32_t val, uint32_t addr) @@ -754,13 +758,13 @@ static void khci_putreg(uint32_t val, uint32_t addr) } #endif -/**************************************************************************** +/****************************************************************************************** * Request Helpers - ****************************************************************************/ + ******************************************************************************************/ -/**************************************************************************** +/****************************************************************************************** * Name: khci_remfirst - ****************************************************************************/ + ******************************************************************************************/ static struct khci_req_s *khci_remfirst(struct khci_queue_s *queue) { @@ -780,9 +784,9 @@ static struct khci_req_s *khci_remfirst(struct khci_queue_s *queue) return ret; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_remlast - ****************************************************************************/ + ******************************************************************************************/ static struct khci_req_s *khci_remlast(struct khci_queue_s *queue) { @@ -816,9 +820,9 @@ static struct khci_req_s *khci_remlast(struct khci_queue_s *queue) return ret; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_addlast - ****************************************************************************/ + ******************************************************************************************/ static void khci_addlast(struct khci_queue_s *queue, struct khci_req_s *req) { @@ -835,9 +839,9 @@ static void khci_addlast(struct khci_queue_s *queue, struct khci_req_s *req) } } -/**************************************************************************** +/****************************************************************************************** * Name: khci_addfirst - ****************************************************************************/ + ******************************************************************************************/ static void khci_addfirst(struct khci_queue_s *queue, struct khci_req_s *req) { @@ -850,9 +854,9 @@ static void khci_addfirst(struct khci_queue_s *queue, struct khci_req_s *req) queue->head = req; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_reqreturn - ****************************************************************************/ + ******************************************************************************************/ static void khci_reqreturn(struct khci_ep_s *privep, struct khci_req_s *privreq, int16_t result) @@ -881,9 +885,9 @@ static void khci_reqreturn(struct khci_ep_s *privep, privep->stalled = stalled; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_reqcomplete - ****************************************************************************/ + ******************************************************************************************/ static void khci_reqcomplete(struct khci_ep_s *privep, int16_t result) { @@ -906,9 +910,9 @@ static void khci_reqcomplete(struct khci_ep_s *privep, int16_t result) } } -/**************************************************************************** +/****************************************************************************************** * Name: khci_epwrite - ****************************************************************************/ + ******************************************************************************************/ static void khci_epwrite(struct khci_ep_s *privep, volatile struct usbotg_bdtentry_s *bdt, @@ -948,9 +952,9 @@ static void khci_epwrite(struct khci_ep_s *privep, bdt->status = status; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_wrcomplete - ****************************************************************************/ + ******************************************************************************************/ static void khci_wrcomplete(struct khci_usbdev_s *priv, struct khci_ep_s *privep) @@ -1042,9 +1046,9 @@ static void khci_wrcomplete(struct khci_usbdev_s *priv, } } -/**************************************************************************** +/****************************************************************************************** * Name: khci_rqrestart - ****************************************************************************/ + ******************************************************************************************/ static void khci_rqrestart(int argc, uint32_t arg1, ...) { @@ -1102,9 +1106,9 @@ static void khci_rqrestart(int argc, uint32_t arg1, ...) } } -/**************************************************************************** +/****************************************************************************************** * Name: khci_delayedrestart - ****************************************************************************/ + ******************************************************************************************/ static void khci_delayedrestart(struct khci_usbdev_s *priv, uint8_t epno) { @@ -1118,9 +1122,9 @@ static void khci_delayedrestart(struct khci_usbdev_s *priv, uint8_t epno) (uint32_t)priv); } -/**************************************************************************** +/****************************************************************************************** * Name: khci_rqstop - ****************************************************************************/ + ******************************************************************************************/ static void khci_rqstop(struct khci_ep_s *privep) { @@ -1136,9 +1140,9 @@ static void khci_rqstop(struct khci_ep_s *privep) } } -/**************************************************************************** +/****************************************************************************************** * Name: khci_wrstart - ****************************************************************************/ + ******************************************************************************************/ static int khci_wrstart(struct khci_usbdev_s *priv, struct khci_ep_s *privep) @@ -1346,9 +1350,9 @@ static int khci_wrstart(struct khci_usbdev_s *priv, return OK; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_wrrequest - ****************************************************************************/ + ******************************************************************************************/ static int khci_wrrequest(struct khci_usbdev_s *priv, struct khci_ep_s *privep) { @@ -1377,9 +1381,9 @@ static int khci_wrrequest(struct khci_usbdev_s *priv, struct khci_ep_s *privep) return khci_rqhead(&privep->active) == NULL ? -ENODATA : OK; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_rdcomplete - ****************************************************************************/ + ******************************************************************************************/ static int khci_rdcomplete(struct khci_usbdev_s *priv, struct khci_ep_s *privep) @@ -1449,9 +1453,9 @@ static int khci_rdcomplete(struct khci_usbdev_s *priv, return khci_rdrequest(priv, privep); } -/**************************************************************************** +/****************************************************************************************** * Name: khci_ep0rdsetup - ****************************************************************************/ + ******************************************************************************************/ static int khci_ep0rdsetup(struct khci_usbdev_s *priv, uint8_t *dest, int readlen) @@ -1546,7 +1550,7 @@ static int khci_ep0rdsetup(struct khci_usbdev_s *priv, uint8_t *dest, privep->rxdata1 = 1; } - /* Set the data pointer, data length, and enable the endpoint */ + /* Set the data pointer, data length, and enable the endpoint */ bdtout->addr = (uint8_t *)dest; status |= ((uint32_t)readlen << USB_BDT_BYTECOUNT_SHIFT); @@ -1561,9 +1565,9 @@ static int khci_ep0rdsetup(struct khci_usbdev_s *priv, uint8_t *dest, return OK; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_rdsetup - ****************************************************************************/ + ******************************************************************************************/ static int khci_rdsetup(struct khci_ep_s *privep, uint8_t *dest, int readlen) { @@ -1661,9 +1665,9 @@ static int khci_rdsetup(struct khci_ep_s *privep, uint8_t *dest, int readlen) return OK; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_rdrequest - ****************************************************************************/ + ******************************************************************************************/ static int khci_rdrequest(struct khci_usbdev_s *priv, struct khci_ep_s *privep) @@ -1739,9 +1743,9 @@ static int khci_rdrequest(struct khci_usbdev_s *priv, return ret; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_cancelrequests - ****************************************************************************/ + ******************************************************************************************/ static void khci_cancelrequests(struct khci_ep_s *privep, int16_t result) { @@ -1760,13 +1764,13 @@ static void khci_cancelrequests(struct khci_ep_s *privep, int16_t result) } } -/**************************************************************************** +/****************************************************************************************** * Interrupt Level Processing - ****************************************************************************/ + ******************************************************************************************/ -/**************************************************************************** +/****************************************************************************************** * Name: khci_dispatchrequest - ****************************************************************************/ + ******************************************************************************************/ static void khci_dispatchrequest(struct khci_usbdev_s *priv) { @@ -1777,7 +1781,8 @@ static void khci_dispatchrequest(struct khci_usbdev_s *priv) { /* Forward to the control request to the class driver implementation */ - ret = CLASS_SETUP(priv->driver, &priv->usbdev, &priv->ctrl, NULL, 0); + ret = CLASS_SETUP(priv->driver, &priv->usbdev, &priv->ctrl, + priv->ep0data, priv->ep0datlen); if (ret < 0) { /* Stall on failure */ @@ -1788,9 +1793,9 @@ static void khci_dispatchrequest(struct khci_usbdev_s *priv) } } -/**************************************************************************** +/****************************************************************************************** * Name: khci_ep0stall - ****************************************************************************/ + ******************************************************************************************/ static void khci_ep0stall(struct khci_usbdev_s *priv) { @@ -1808,9 +1813,9 @@ static void khci_ep0stall(struct khci_usbdev_s *priv) } } -/**************************************************************************** +/****************************************************************************************** * Name: khci_eptransfer - ****************************************************************************/ + ******************************************************************************************/ static void khci_eptransfer(struct khci_usbdev_s *priv, uint8_t epno, uint16_t ustat) @@ -1864,7 +1869,7 @@ static void khci_eptransfer(struct khci_usbdev_s *priv, uint8_t epno, } } -/**************************************************************************** +/****************************************************************************************** * Name: khci_ep0nextsetup * * Description: @@ -1873,7 +1878,7 @@ static void khci_eptransfer(struct khci_usbdev_s *priv, uint8_t epno, * transfers). It simply sets up the single BDT to accept the next * SETUP command. * - ****************************************************************************/ + ******************************************************************************************/ static void khci_ep0nextsetup(struct khci_usbdev_s *priv) { @@ -1888,14 +1893,22 @@ static void khci_ep0nextsetup(struct khci_usbdev_s *priv) if (!priv->ep0done) { - bytecount = (USB_SIZEOF_CTRLREQ << USB_BDT_BYTECOUNT_SHIFT); - bdt->addr = (uint8_t *)&priv->ctrl; + if (bdt == &g_bdt[EP0_OUT_EVEN]) + { + bdt->addr = priv->out0data[EP0_OUT_EVEN]; + } + else + { + bdt->addr = priv->out0data[EP0_OUT_ODD]; + } + + bytecount = (CONFIG_USBDEV_EP0_MAXSIZE << USB_BDT_BYTECOUNT_SHIFT); bdt->status = (USB_BDT_UOWN | bytecount); priv->ep0done = 1; } } -/**************************************************************************** +/****************************************************************************************** * Name: khci_ep0rdcomplete * * Description: @@ -1903,13 +1916,12 @@ static void khci_ep0nextsetup(struct khci_usbdev_s *priv) * context, only one BDT is used. Both BDTs must be prepared to receive * SETUP packets. * - ****************************************************************************/ + ******************************************************************************************/ static void khci_ep0rdcomplete(struct khci_usbdev_s *priv) { volatile struct usbotg_bdtentry_s *bdt; struct khci_ep_s *ep0; - uint32_t physaddr; uint32_t bytecount; /* This operation should be performed no more than once per OUT transaction. @@ -1920,15 +1932,14 @@ static void khci_ep0rdcomplete(struct khci_usbdev_s *priv) if (!priv->ep0done) { - bytecount = (USB_SIZEOF_CTRLREQ << USB_BDT_BYTECOUNT_SHIFT); - physaddr = (uint32_t)&priv->ctrl; + bytecount = (CONFIG_USBDEV_EP0_MAXSIZE << USB_BDT_BYTECOUNT_SHIFT); bdt = &g_bdt[EP0_OUT_EVEN]; - bdt->addr = (uint8_t *)physaddr; + bdt->addr = priv->out0data[EP0_OUT_EVEN]; bdt->status = (USB_BDT_UOWN | bytecount); bdt = &g_bdt[EP0_OUT_ODD]; - bdt->addr = (uint8_t *)physaddr; + bdt->addr = priv->out0data[EP0_OUT_ODD]; bdt->status = (USB_BDT_UOWN | bytecount); priv->ep0done = 1; @@ -1943,9 +1954,9 @@ static void khci_ep0rdcomplete(struct khci_usbdev_s *priv) } } -/**************************************************************************** +/****************************************************************************************** * Name: khci_ep0setup - ****************************************************************************/ + ******************************************************************************************/ static void khci_ep0setup(struct khci_usbdev_s *priv) { @@ -1976,453 +1987,487 @@ static void khci_ep0setup(struct khci_usbdev_s *priv) ep0->rxdata1 = 0; ep0->txdata1 = 1; - /* Initialize for the SETUP */ - - priv->ctrlstate = CTRLSTATE_WAITSETUP; - - /* And extract the little-endian 16-bit values to host order */ + /* Extract the little-endian 16-bit values to host order */ value.w = GETUINT16(priv->ctrl.value); index.w = GETUINT16(priv->ctrl.index); len.w = GETUINT16(priv->ctrl.len); + response.w = 0; - uinfo("SETUP: type=%02x req=%02x value=%04x index=%04x len=%04x\n", - priv->ctrl.type, priv->ctrl.req, value.w, index.w, len.w); + /* Check to see if called from the DATA phase of a SETUP Transfer */ - /* Dispatch any non-standard requests */ - - if ((priv->ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + if (priv->ctrlstate != CTRLSTATE_SETUP_READY && + priv->ctrlstate != CTRLSTATE_SETUP_OUT) { - usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_NOSTDREQ), priv->ctrl.type); + /* Not the data phase */ - /* Let the class implementation handle all non-standar requests */ + uinfo("SETUP: type=%02x req=%02x value=%04x index=%04x len=%04x\n", + priv->ctrl.type, priv->ctrl.req, value.w, index.w, len.w); - khci_dispatchrequest(priv); - dispatched = true; - goto resume_packet_processing; /* Sorry about the goto */ + /* Is this an setup with OUT and data of length > 0 */ + + if (USB_REQ_ISOUT(priv->ctrl.type) && len.w > 0) + { + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_EP0SETUPOUT), len.w); + + priv->ep0datlen = 0; + priv->ep0datreq = len.w; + + /* At this point priv->ctrl is the setup packet. */ + + khci_ep0nextsetup(priv); + priv->ctrlstate = CTRLSTATE_SETUP_OUT; + } + else + { + priv->ctrlstate = CTRLSTATE_SETUP_READY; + } } - /* Handle standard request. Pick off the things of interest to the - * USB device controller driver; pass what is left to the class driver - */ - - switch (priv->ctrl.req) + if (priv->ctrlstate == CTRLSTATE_SETUP_READY) { - case USB_REQ_GETSTATUS: - { - /* type: device-to-host; recipient = device, interface, endpoint - * value: 0 - * index: zero interface endpoint - * len: 2; data = status - */ + /* Dispatch any non-standard requests */ - usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_GETSTATUS), priv->ctrl.type); - if (len.w != 2 || (priv->ctrl.type & USB_REQ_DIR_IN) == 0 || - index.b[MSB] != 0 || value.w != 0) - { - usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADEPGETSTATUS), 0); - priv->ctrlstate = CTRLSTATE_STALL; - } - else - { - switch (priv->ctrl.type & USB_REQ_RECIPIENT_MASK) + if ((priv->ctrl.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_NOSTDREQ), priv->ctrl.type); + + /* Let the class implementation handle all non-standard requests */ + + khci_dispatchrequest(priv); + dispatched = true; + } + else + { + /* Handle standard request. Pick off the things of interest to the + * USB device controller driver; pass what is left to the class driver + */ + + switch (priv->ctrl.req) + { + case USB_REQ_GETSTATUS: { - case USB_REQ_RECIPIENT_ENDPOINT: - { - epno = USB_EPNO(index.b[LSB]); - usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_EPGETSTATUS), epno); - if (epno >= KHCI_NENDPOINTS) - { - usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADEPGETSTATUS), epno); - priv->ctrlstate = CTRLSTATE_STALL; - } - else - { - privep = &priv->eplist[epno]; - response.w = 0; /* Not stalled */ - nbytes = 2; /* Response size: 2 bytes */ + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ - if (USB_ISEPIN(index.b[LSB])) + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_GETSTATUS), priv->ctrl.type); + if (len.w != 2 || (priv->ctrl.type & USB_REQ_DIR_IN) == 0 || + index.b[MSB] != 0 || value.w != 0) + { + usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADEPGETSTATUS), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + else + { + switch (priv->ctrl.type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: { - /* IN endpoint */ + epno = USB_EPNO(index.b[LSB]); + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_EPGETSTATUS), epno); + if (epno >= KHCI_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADEPGETSTATUS), epno); + priv->ctrlstate = CTRLSTATE_STALL; + } + else + { + privep = &priv->eplist[epno]; + response.w = 0; /* Not stalled */ + nbytes = 2; /* Response size: 2 bytes */ - bdt = privep->bdtin; + if (USB_ISEPIN(index.b[LSB])) + { + /* IN endpoint */ + + bdt = privep->bdtin; + } + else + { + /* OUT endpoint */ + + bdt = privep->bdtout; + } + + /* BSTALL set if stalled */ + + if ((bdt->status & USB_BDT_BSTALL) != 0) + { + response.b[LSB] = 1; /* Stalled, set bit 0 */ + } + } } - else + break; + + case USB_REQ_RECIPIENT_DEVICE: { - /* OUT endpoint */ + if (index.w == 0) + { + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_DEVGETSTATUS), 0); - bdt = privep->bdtout; + /* Features: Remote Wakeup=YES; selfpowered=? */ + + response.w = 0; + response.b[LSB] = + (priv->selfpowered << USB_FEATURE_SELFPOWERED) | + (priv->rwakeup << USB_FEATURE_REMOTEWAKEUP); + nbytes = 2; /* Response size: 2 bytes */ + } + else + { + usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADDEVGETSTATUS), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } } + break; - /* BSTALL set if stalled */ - - if ((bdt->status & USB_BDT_BSTALL) != 0) + case USB_REQ_RECIPIENT_INTERFACE: { - response.b[LSB] = 1; /* Stalled, set bit 0 */ + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_IFGETSTATUS), 0); + response.w = 0; + nbytes = 2; /* Response size: 2 bytes */ } - } - } - break; + break; - case USB_REQ_RECIPIENT_DEVICE: - { - if (index.w == 0) - { - usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_DEVGETSTATUS), 0); - - /* Features: Remote Wakeup=YES; selfpowered=? */ - - response.w = 0; - response.b[LSB] = (priv->selfpowered << USB_FEATURE_SELFPOWERED) | - (priv->rwakeup << USB_FEATURE_REMOTEWAKEUP); - nbytes = 2; /* Response size: 2 bytes */ - } - else - { - usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADDEVGETSTATUS), 0); - priv->ctrlstate = CTRLSTATE_STALL; - } - } - break; - - case USB_REQ_RECIPIENT_INTERFACE: - { - usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_IFGETSTATUS), 0); - response.w = 0; - nbytes = 2; /* Response size: 2 bytes */ - } - break; - - default: - { - usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADGETSTATUS), 0); - priv->ctrlstate = CTRLSTATE_STALL; - } - break; + default: + { + usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADGETSTATUS), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + break; + } + } } - } - } - break; + break; - case USB_REQ_CLEARFEATURE: - { - /* type: host-to-device; recipient = device, interface or endpoint - * value: feature selector - * index: zero interface endpoint; - * len: zero, data = none - */ - - usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_CLEARFEATURE), priv->ctrl.type); - if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) - { - /* Disable B device from performing HNP */ - -#ifdef CONFIG_KINETIS_USBOTG - if (value.w == USBOTG_FEATURE_B_HNP_ENABLE) + case USB_REQ_CLEARFEATURE: { - /* Disable HNP */ -#warning Missing Logic + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_CLEARFEATURE), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + /* Disable B device from performing HNP */ + + #ifdef CONFIG_KINETIS_USBOTG + if (value.w == USBOTG_FEATURE_B_HNP_ENABLE) + { + /* Disable HNP */ + #warning Missing Logic + } + + /* Disable A device HNP support */ + + else if (value.w == USBOTG_FEATURE_A_HNP_SUPPORT) + { + /* Disable HNP support */ + #warning Missing Logic + } + + /* Disable alternate HNP support */ + + else if (value.w == USBOTG_FEATURE_A_ALT_HNP_SUPPORT) + { + /* Disable alternate HNP */ + #warning Missing Logic + } + else + #endif + /* Disable remote wakeup */ + + if (value.w == USB_FEATURE_REMOTEWAKEUP) + { + priv->rwakeup = 0; + } + else + { + /* Let the class implementation handle all other device features */ + + khci_dispatchrequest(priv); + dispatched = true; + } + } + else if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_ENDPOINT) + { + epno = USB_EPNO(index.b[LSB]); + if (epno > 0 && epno < KHCI_NENDPOINTS && index.b[MSB] == 0 && + value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) + { + privep = &priv->eplist[epno]; + privep->halted = false; + ret = khci_epstall(&privep->ep, true); + UNUSED(ret); + } + else + { + usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADCLEARFEATURE), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + } + else + { + /* Let the class implementation handle all other recipients. */ + + khci_dispatchrequest(priv); + dispatched = true; + } } + break; - /* Disable A device HNP support */ - - else if (value.w == USBOTG_FEATURE_A_HNP_SUPPORT) + case USB_REQ_SETFEATURE: { - /* Disable HNP support */ -#warning Missing Logic + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_SETFEATURE), priv->ctrl.type); + + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + /* Enable B device to perform HNP */ + + #ifdef CONFIG_KINETIS_USBOTG + if (value.w == USBOTG_FEATURE_B_HNP_ENABLE) + { + /* Enable HNP */ + #warning "Missing logic" + } + + /* Enable A device HNP supports */ + + else if (value.w == USBOTG_FEATURE_A_HNP_SUPPORT) + { + /* Enable HNP support */ + #warning "Missing logic" + } + + /* Another port on the A device supports HNP */ + + else if (value.w == USBOTG_FEATURE_A_ALT_HNP_SUPPORT) + { + /* Enable alternate HNP */ + #warning "Missing logic" + } + else + #endif + + if (value.w == USB_FEATURE_REMOTEWAKEUP) + { + priv->rwakeup = 0; + } + else if (value.w == USB_FEATURE_TESTMODE) + { + /* Special case recipient=device test mode */ + + uinfo("test mode: %d\n", index.w); + } + else + { + /* Let the class implementation handle all other device features */ + + khci_dispatchrequest(priv); + dispatched = true; + } + } + else if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_ENDPOINT) + { + /* Handler recipient=endpoint */ + + epno = USB_EPNO(index.b[LSB]); + if (epno < KHCI_NENDPOINTS && index.b[MSB] == 0 && + value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) + { + privep = &priv->eplist[epno]; + privep->halted = true; + ret = khci_epstall(&privep->ep, false); + UNUSED(ret); + } + else + { + usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADSETFEATURE), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + } + else + { + /* The class driver handles all recipients except recipient=endpoint */ + + khci_dispatchrequest(priv); + dispatched = true; + } } + break; - /* Disable alternate HNP support */ - - else if (value.w == USBOTG_FEATURE_A_ALT_HNP_SUPPORT) + case USB_REQ_SETADDRESS: { - /* Disable alternate HNP */ -#warning Missing Logic + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_EP0SETUPSETADDRESS), value.w); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != + USB_REQ_RECIPIENT_DEVICE || + index.w != 0 || len.w != 0 || value.w > 127) + { + usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADSETADDRESS), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + else + { + /* Note that setting of the device address will be deferred. + * A zero-length packet will be sent and the device address will + * be set when the zerolength packet transfer completes. + */ + + priv->devstate = DEVSTATE_ADDRPENDING; + } } - else -#endif - /* Disable remote wakeup */ + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ - if (value.w == USB_FEATURE_REMOTEWAKEUP) { - priv->rwakeup = 0; + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_GETSETDESC), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE) + { + /* The request seems valid... let the class implementation handle it */ + + khci_dispatchrequest(priv); + dispatched = true; + } + else + { + usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADGETSETDESC), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } } - else - { - /* Let the class implementation handle all other device features */ + break; + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + + { + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_GETCONFIG), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && value.w == 0 && index.w == 0 && len.w == 1) + { + /* The request seems valid... let the class implementation handle it */ + + khci_dispatchrequest(priv); + dispatched = true; + } + else + { + usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADGETCONFIG), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_SETCONFIG), priv->ctrl.type); + if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == + USB_REQ_RECIPIENT_DEVICE && index.w == 0 && len.w == 0) + { + /* The request seems valid. Let the class implementation handle it */ + + khci_dispatchrequest(priv); + dispatched = true; + } + else + { + usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADSETCONFIG), 0); + priv->ctrlstate = CTRLSTATE_STALL; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + + { + /* Let the class implementation handle the request */ + + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_GETSETIF), priv->ctrl.type); khci_dispatchrequest(priv); dispatched = true; } - } - else if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_ENDPOINT) - { - epno = USB_EPNO(index.b[LSB]); - if (epno > 0 && epno < KHCI_NENDPOINTS && index.b[MSB] == 0 && - value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + { - privep = &priv->eplist[epno]; - privep->halted = false; - ret = khci_epstall(&privep->ep, true); - UNUSED(ret); + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_SYNCHFRAME), 0); } - else + break; + + default: { - usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADCLEARFEATURE), 0); + usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_INVALIDCTRLREQ), priv->ctrl.req); priv->ctrlstate = CTRLSTATE_STALL; } - } - else - { - /* Let the class implementation handle all other recipients. */ - - khci_dispatchrequest(priv); - dispatched = true; - } - } - break; - - case USB_REQ_SETFEATURE: - { - /* type: host-to-device; recipient = device, interface, endpoint - * value: feature selector - * index: zero interface endpoint; - * len: 0; data = none - */ - - usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_SETFEATURE), priv->ctrl.type); - - if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) - { - /* Enable B device to perform HNP */ - -#ifdef CONFIG_KINETIS_USBOTG - if (value.w == USBOTG_FEATURE_B_HNP_ENABLE) - { - /* Enable HNP */ -#warning "Missing logic" - } - - /* Enable A device HNP supports */ - - else if (value.w == USBOTG_FEATURE_A_HNP_SUPPORT) - { - /* Enable HNP support */ -#warning "Missing logic" - } - - /* Another port on the A device supports HNP */ - - else if (value.w == USBOTG_FEATURE_A_ALT_HNP_SUPPORT) - { - /* Enable alternate HNP */ -#warning "Missing logic" - } - else -#endif - - if (value.w == USB_FEATURE_REMOTEWAKEUP) - { - priv->rwakeup = 0; - } - else if (value.w == USB_FEATURE_TESTMODE) - { - /* Special case recipient=device test mode */ - - uinfo("test mode: %d\n", index.w); - } - else - { - /* Let the class implementation handle all other device features */ - - khci_dispatchrequest(priv); - dispatched = true; - } - } - else if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_ENDPOINT) - { - /* Handler recipient=endpoint */ - - epno = USB_EPNO(index.b[LSB]); - if (epno < KHCI_NENDPOINTS && index.b[MSB] == 0 && - value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) - { - privep = &priv->eplist[epno]; - privep->halted = true; - ret = khci_epstall(&privep->ep, false); - UNUSED(ret); - } - else - { - usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADSETFEATURE), 0); - priv->ctrlstate = CTRLSTATE_STALL; - } - } - else - { - /* The class driver handles all recipients except recipient=endpoint */ - - khci_dispatchrequest(priv); - dispatched = true; - } - } - break; - - case USB_REQ_SETADDRESS: - { - /* type: host-to-device; recipient = device - * value: device address - * index: 0 - * len: 0; data = none - */ - - usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_EP0SETUPSETADDRESS), value.w); - if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) != USB_REQ_RECIPIENT_DEVICE || - index.w != 0 || len.w != 0 || value.w > 127) - { - usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADSETADDRESS), 0); - priv->ctrlstate = CTRLSTATE_STALL; - } - else - { - /* Note that setting of the device address will be deferred. A zero-length - * packet will be sent and the device address will be set when the zero- - * length packet transfer completes. - */ - - priv->devstate = DEVSTATE_ADDRPENDING; - } - } - break; - - case USB_REQ_GETDESCRIPTOR: - /* type: device-to-host; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ - case USB_REQ_SETDESCRIPTOR: - /* type: host-to-device; recipient = device - * value: descriptor type and index - * index: 0 or language ID; - * len: descriptor len; data = descriptor - */ - - { - usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_GETSETDESC), priv->ctrl.type); - if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) - { - /* The request seems valid... let the class implementation handle it */ - - khci_dispatchrequest(priv); - dispatched = true; - } - else - { - usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADGETSETDESC), 0); - priv->ctrlstate = CTRLSTATE_STALL; - } - } - break; - - case USB_REQ_GETCONFIGURATION: - /* type: device-to-host; recipient = device - * value: 0; - * index: 0; - * len: 1; data = configuration value - */ - - { - usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_GETCONFIG), priv->ctrl.type); - if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && - value.w == 0 && index.w == 0 && len.w == 1) - { - /* The request seems valid... let the class implementation handle it */ - - khci_dispatchrequest(priv); - dispatched = true; - } - else - { - usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADGETCONFIG), 0); - priv->ctrlstate = CTRLSTATE_STALL; - } - } - break; - - case USB_REQ_SETCONFIGURATION: - /* type: host-to-device; recipient = device - * value: configuration value - * index: 0; - * len: 0; data = none - */ - - { - usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_SETCONFIG), priv->ctrl.type); - if ((priv->ctrl.type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && - index.w == 0 && len.w == 0) - { - /* The request seems valid... let the class implementation handle it */ - - khci_dispatchrequest(priv); - dispatched = true; - } - else - { - usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADSETCONFIG), 0); - priv->ctrlstate = CTRLSTATE_STALL; - } - } - break; - - case USB_REQ_GETINTERFACE: - /* type: device-to-host; recipient = interface - * value: 0 - * index: interface; - * len: 1; data = alt interface - */ - case USB_REQ_SETINTERFACE: - /* type: host-to-device; recipient = interface - * value: alternate setting - * index: interface; - * len: 0; data = none - */ - - { - /* Let the class implementation handle the request */ - - usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_GETSETIF), priv->ctrl.type); - khci_dispatchrequest(priv); - dispatched = true; - } - break; - - case USB_REQ_SYNCHFRAME: - /* type: device-to-host; recipient = endpoint - * value: 0 - * index: endpoint; - * len: 2; data = frame number - */ - - { - usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_SYNCHFRAME), 0); - } - break; - - default: - { - usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_INVALIDCTRLREQ), priv->ctrl.req); - priv->ctrlstate = CTRLSTATE_STALL; - } - break; + break; + } + } } /* PKTDIS bit is set when a Setup Transaction is received. Clear to resume * packet processing. */ -resume_packet_processing: regval = khci_getreg(KINETIS_USB0_CTL); regval &= ~USB_CTL_TXSUSPENDTOKENBUSY; khci_putreg(regval, KINETIS_USB0_CTL); @@ -2444,43 +2489,50 @@ resume_packet_processing: * logic altogether. */ - if (!dispatched && (priv->ctrlstate != CTRLSTATE_STALL)) + if (priv->ctrlstate == CTRLSTATE_SETUP_READY) { - /* The SETUP command was not dispatched to the class driver and the SETUP - * command did not cause a stall. We will respond. First, restrict the - * data length to the length requested in the setup packet - */ - - if (nbytes > len.w) + if (!dispatched) { - nbytes = len.w; + /* The SETUP command was not dispatched to the class driver and the SETUP + * command did not cause a stall. We will respond. First, restrict the + * data length to the length requested in the setup packet + */ + + if (nbytes > len.w) + { + nbytes = len.w; + } + + /* Send the EP0 SETUP response (might be a zero-length packet) */ + + khci_epwrite(ep0, ep0->bdtin, response.b, nbytes); } - /* Send the EP0 SETUP response (might be a zero-length packet) */ + priv->ctrlstate = CTRLSTATE_WAITSETUP; + } + else if (priv->ctrlstate == CTRLSTATE_STALL) + { + /* Did we stall? This might have occurred from the above logic OR the stall + * condition may have been set less obviously in khci_dispatchrequest(). + * In either case, we handle the stall condition the same. + * + * However, bad things happen if we try to stall a SETUP packet. So lets + * not. If we wait a bit, things will recover. Hmmm.. If we completed + * the data phase (perhaps by sending a NULL packet), then I think we + * could stall the endpoint and perhaps speed things up a bit???. + */ - khci_epwrite(ep0, ep0->bdtin, response.b, nbytes); priv->ctrlstate = CTRLSTATE_WAITSETUP; } - /* Did we stall? This might have occurred from the above logic OR the stall - * condition may have been set less obviously in khci_dispatchrequest(). - * In either case, we handle the stall condition the same. - * - * However, bad things happen if we try to stall a SETUP packet. So lets - * not. If we wait a bit, things will recover. Hmmm.. If we completed - * the data phase (perhaps by sending a NULL packet), then I think we - * could stall the endpoint and perhaps speed things up a bit???. - */ + /* Set up the BDT to accept the next setup command. */ - /* Set up the BDT to accept the next setup command. */ - - khci_ep0nextsetup(priv); - priv->ctrlstate = CTRLSTATE_WAITSETUP; + khci_ep0nextsetup(priv); } -/**************************************************************************** +/****************************************************************************************** * Name: khci_ep0incomplete - ****************************************************************************/ + ******************************************************************************************/ static void khci_ep0incomplete(struct khci_usbdev_s *priv) { @@ -2544,7 +2596,7 @@ static void khci_ep0incomplete(struct khci_usbdev_s *priv) { DEBUGASSERT(bdtlast == &g_bdt[EP0_IN_ODD]); ep0->bdtin = &g_bdt[EP0_IN_EVEN]; - } + } /* Look at the saved SETUP command. Was it a SET ADDRESS request? * If so, then now is the time to set the address. @@ -2584,9 +2636,9 @@ static void khci_ep0incomplete(struct khci_usbdev_s *priv) } } -/**************************************************************************** +/****************************************************************************************** * Name: khci_ep0outcomplete - ****************************************************************************/ + ******************************************************************************************/ static void khci_ep0outcomplete(struct khci_usbdev_s *priv) { @@ -2638,9 +2690,9 @@ static void khci_ep0outcomplete(struct khci_usbdev_s *priv) } } -/**************************************************************************** +/****************************************************************************************** * Name: khci_ep0transfer - ****************************************************************************/ + ******************************************************************************************/ static void khci_ep0transfer(struct khci_usbdev_s *priv, uint16_t ustat) { @@ -2673,23 +2725,50 @@ static void khci_ep0transfer(struct khci_usbdev_s *priv, uint16_t ustat) if (((bdt->status & USB_BDT_PID_MASK) >> USB_BDT_PID_SHIFT) == USB_PID_SETUP_TOKEN) { - /* Check if the SETUP transaction data went into the priv->ctrl - * buffer. If not, then we will need to copy it. - */ + void *src = (void *)bdt->addr; + void *dest = &priv->ctrl; - if (bdt->addr != (uint8_t *)&priv->ctrl) - { - void *src = (void *)bdt->addr; - void *dest = &priv->ctrl; - - memcpy(dest, src, USB_SIZEOF_CTRLREQ); - bdt->addr = (uint8_t *)&priv->ctrl; - } + memcpy(dest, src, USB_SIZEOF_CTRLREQ); /* Handle the control OUT transfer */ - usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_EP0SETUPDONE), bdt->status); khci_ep0setup(priv); + + if (priv->ctrlstate == CTRLSTATE_WAITSETUP) + { + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_EP0SETUPDONE), bdt->status); + } + else + { + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_EP0SETUPOUT), bdt->status); + } + } + else if (priv->ctrlstate == CTRLSTATE_SETUP_OUT) + { + void *src = (void *)bdt->addr; + void *dest = (void *)&priv->ep0data[priv->ep0datlen]; + uint16_t readlen = MIN((priv->ep0datreq - priv->ep0datlen), + priv->eplist[0].ep.maxpacket); + + memcpy(dest, src, readlen); + + priv->ep0datlen += readlen; + + if (priv->ep0datlen == priv->ep0datreq) + { + priv->ctrlstate = CTRLSTATE_SETUP_READY; + } + + khci_ep0setup(priv); + + if (priv->ctrlstate == CTRLSTATE_WAITSETUP) + { + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_EP0SETUPDONE), bdt->status); + } + else + { + usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_EP0SETUPOUTDATA), bdt->status); + } } else { @@ -2722,9 +2801,9 @@ static void khci_ep0transfer(struct khci_usbdev_s *priv, uint16_t ustat) } } -/**************************************************************************** +/****************************************************************************************** * Name: khci_interrupt - ****************************************************************************/ + ******************************************************************************************/ static int khci_interrupt(int irq, void *context, FAR void *arg) { @@ -2777,13 +2856,12 @@ static int khci_interrupt(int irq, void *context, FAR void *arg) if (priv->devstate == DEVSTATE_ATTACHED) { - /* Now were are in the powered state */ priv->devstate = DEVSTATE_POWERED; } - /* Service error interrupts */ + /* Service error interrupts */ if ((usbir & USB_INT_ERROR) != 0) { @@ -2946,9 +3024,9 @@ static int khci_interrupt(int irq, void *context, FAR void *arg) } #endif - /* Service stall interrupts */ + /* Service stall interrupts */ - if ((usbir & USB_INT_STALL) != 0) + if ((usbir & USB_INT_STALL) != 0) { usbtrace(TRACE_INTDECODE(KHCI_TRACEINTID_STALL), usbir); @@ -2960,7 +3038,7 @@ static int khci_interrupt(int irq, void *context, FAR void *arg) } /* Clear the pending USB interrupt. Goto is used in the above to assure - * that all interrupt exists pass through this logic. + * that all interrupt exits pass through this logic. */ interrupt_exit: @@ -2973,12 +3051,13 @@ interrupt_exit: return OK; } -/**************************************************************************** +/****************************************************************************************** * Suspend/Resume Helpers - ****************************************************************************/ -/**************************************************************************** + ******************************************************************************************/ + +/****************************************************************************************** * Name: khci_suspend - ****************************************************************************/ + ******************************************************************************************/ #ifndef CONFIG_KINETIS_USBOTG static void khci_suspend(struct khci_usbdev_s *priv) @@ -3016,13 +3095,12 @@ static void khci_suspend(struct khci_usbdev_s *priv) */ kinetis_usbsuspend((struct usbdev_s *)priv, false); - } #endif -/**************************************************************************** +/****************************************************************************************** * Name: khci_remote_resume - ****************************************************************************/ + ******************************************************************************************/ static void khci_remote_resume(struct khci_usbdev_s *priv) { @@ -3042,9 +3120,9 @@ static void khci_remote_resume(struct khci_usbdev_s *priv) khci_putreg(regval, KINETIS_USB0_CTL); } -/**************************************************************************** +/****************************************************************************************** * Name: khci_resume - ****************************************************************************/ + ******************************************************************************************/ static void khci_resume(struct khci_usbdev_s *priv) { @@ -3068,20 +3146,20 @@ static void khci_resume(struct khci_usbdev_s *priv) /* Enable the IDLE interrupt */ - regval = khci_getreg(KINETIS_USB0_INTEN); - regval |= USB_INT_SLEEP; - khci_putreg(regval, KINETIS_USB0_INTEN); + regval = khci_getreg(KINETIS_USB0_INTEN); + regval |= USB_INT_SLEEP; + khci_putreg(regval, KINETIS_USB0_INTEN); - /* Disable the RESUME interrupt */ + /* Disable the RESUME interrupt */ - regval &= ~USB_INT_RESUME; - khci_putreg(regval, KINETIS_USB0_INTEN); + regval &= ~USB_INT_RESUME; + khci_putreg(regval, KINETIS_USB0_INTEN); - /* Disable the the async resume interrupt */ + /* Disable the the async resume interrupt */ - regval = khci_getreg(KINETIS_USB0_USBTRC0); - regval &= ~USB_USBTRC0_USBRESMEN; - khci_putreg(regval, KINETIS_USB0_USBTRC0); + regval = khci_getreg(KINETIS_USB0_USBTRC0); + regval &= ~USB_USBTRC0_USBRESMEN; + khci_putreg(regval, KINETIS_USB0_USBTRC0); khci_putreg(USB_INT_RESUME, KINETIS_USB0_ISTAT); @@ -3095,12 +3173,13 @@ static void khci_resume(struct khci_usbdev_s *priv) leave_critical_section(flags); } -/**************************************************************************** +/****************************************************************************************** * Endpoint Helpers - ****************************************************************************/ -/**************************************************************************** + ******************************************************************************************/ + +/****************************************************************************************** * Name: khci_epreserve - ****************************************************************************/ + ******************************************************************************************/ static inline struct khci_ep_s * khci_epreserve(struct khci_usbdev_s *priv, uint8_t epset) @@ -3138,9 +3217,9 @@ khci_epreserve(struct khci_usbdev_s *priv, uint8_t epset) return privep; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_epunreserve - ****************************************************************************/ + ******************************************************************************************/ static inline void khci_epunreserve(struct khci_usbdev_s *priv, struct khci_ep_s *privep) @@ -3150,9 +3229,9 @@ khci_epunreserve(struct khci_usbdev_s *priv, struct khci_ep_s *privep) leave_critical_section(flags); } -/**************************************************************************** +/****************************************************************************************** * Name: khci_epreserved - ****************************************************************************/ + ******************************************************************************************/ static inline bool khci_epreserved(struct khci_usbdev_s *priv, int epno) @@ -3160,9 +3239,9 @@ khci_epreserved(struct khci_usbdev_s *priv, int epno) return ((priv->epavail & KHCI_ENDP_BIT(epno)) == 0); } -/**************************************************************************** +/****************************************************************************************** * Name: khci_ep0configure - ****************************************************************************/ + ******************************************************************************************/ static void khci_ep0configure(struct khci_usbdev_s *priv) { @@ -3180,16 +3259,16 @@ static void khci_ep0configure(struct khci_usbdev_s *priv) khci_putreg(KHCI_EP_DISABLED, KINETIS_USB0_ENDPT0); ep0 = &priv->eplist[EP0]; - bytecount = (USB_SIZEOF_CTRLREQ << USB_BDT_BYTECOUNT_SHIFT); + bytecount = (CONFIG_USBDEV_EP0_MAXSIZE << USB_BDT_BYTECOUNT_SHIFT); bdt = &g_bdt[EP0_OUT_EVEN]; - bdt->addr = (uint8_t *)&priv->ctrl; + bdt->addr = priv->out0data[EP0_OUT_EVEN]; bdt->status = (USB_BDT_UOWN | bytecount); ep0->bdtout = bdt; - bdt++; + bdt = &g_bdt[EP0_OUT_ODD]; + bdt->addr = priv->out0data[EP0_OUT_ODD]; bdt->status = (USB_BDT_UOWN | bytecount); - bdt->addr = (uint8_t *)&priv->ctrl; /* Configure the IN BDTs. */ @@ -3198,7 +3277,7 @@ static void khci_ep0configure(struct khci_usbdev_s *priv) bdt->addr = 0; ep0->bdtin = bdt; - bdt++; + bdt = &g_bdt[EP0_IN_ODD]; bdt->status = 0; bdt->addr = 0; @@ -3214,16 +3293,15 @@ static void khci_ep0configure(struct khci_usbdev_s *priv) khci_putreg(KHCI_EP_CONTROL, KINETIS_USB0_ENDPT0); } -/**************************************************************************** +/****************************************************************************************** * Endpoint operations - ****************************************************************************/ + ******************************************************************************************/ -/**************************************************************************** +/****************************************************************************************** * Name: khci_epconfigure - ****************************************************************************/ + ******************************************************************************************/ -static int khci_epconfigure(struct usbdev_ep_s *ep, - const struct usb_epdesc_s *desc, +static int khci_epconfigure(struct usbdev_ep_s *ep, const struct usb_epdesc_s *desc, bool last) { struct khci_ep_s *privep = (struct khci_ep_s *)ep; @@ -3255,7 +3333,7 @@ static int khci_epconfigure(struct usbdev_ep_s *ep, /* Set the requested type */ switch (desc->attr & USB_EP_ATTR_XFERTYPE_MASK) - { + { case USB_EP_ATTR_XFER_INT: /* Interrupt endpoint */ regval = epin ? KHCI_EP_INTIN : KHCI_EP_INTOUT; break; @@ -3276,7 +3354,7 @@ static int khci_epconfigure(struct usbdev_ep_s *ep, default: usbtrace(TRACE_DEVERROR(KHCI_TRACEERR_BADEPTYPE), (uint16_t)desc->type); return -EINVAL; - } + } /* First disable the endpoint */ @@ -3356,9 +3434,9 @@ static int khci_epconfigure(struct usbdev_ep_s *ep, return OK; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_epdisable - ****************************************************************************/ + ******************************************************************************************/ static int khci_epdisable(struct usbdev_ep_s *ep) { @@ -3404,9 +3482,9 @@ static int khci_epdisable(struct usbdev_ep_s *ep) return OK; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_epallocreq - ****************************************************************************/ + ******************************************************************************************/ static struct usbdev_req_s *khci_epallocreq(struct usbdev_ep_s *ep) { @@ -3433,9 +3511,9 @@ static struct usbdev_req_s *khci_epallocreq(struct usbdev_ep_s *ep) return &privreq->req; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_epfreereq - ****************************************************************************/ + ******************************************************************************************/ static void khci_epfreereq(struct usbdev_ep_s *ep, struct usbdev_req_s *req) { @@ -3454,9 +3532,9 @@ static void khci_epfreereq(struct usbdev_ep_s *ep, struct usbdev_req_s *req) kmm_free(privreq); } -/**************************************************************************** +/****************************************************************************************** * Name: khci_epsubmit - ****************************************************************************/ + ******************************************************************************************/ static int khci_epsubmit(struct usbdev_ep_s *ep, struct usbdev_req_s *req) { @@ -3546,9 +3624,9 @@ static int khci_epsubmit(struct usbdev_ep_s *ep, struct usbdev_req_s *req) return ret; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_epcancel - ****************************************************************************/ + ******************************************************************************************/ static int khci_epcancel(struct usbdev_ep_s *ep, struct usbdev_req_s *req) { @@ -3571,9 +3649,9 @@ static int khci_epcancel(struct usbdev_ep_s *ep, struct usbdev_req_s *req) return OK; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_epbdtstall - ****************************************************************************/ + ******************************************************************************************/ static int khci_epbdtstall(struct usbdev_ep_s *ep, bool resume, bool epin) { @@ -3658,17 +3736,32 @@ static int khci_epbdtstall(struct usbdev_ep_s *ep, bool resume, bool epin) if (epno == 0 && !epin) { - uint32_t bytecount = (USB_SIZEOF_CTRLREQ << USB_BDT_BYTECOUNT_SHIFT); - uint32_t physaddr = (uint32_t)&priv->ctrl; + uint32_t bytecount = (CONFIG_USBDEV_EP0_MAXSIZE << USB_BDT_BYTECOUNT_SHIFT); /* Configure the other BDT to receive a SETUP command. */ - otherbdt->addr = (uint8_t *)physaddr; + if (otherbdt == &g_bdt[EP0_OUT_EVEN]) + { + otherbdt->addr = priv->out0data[EP0_OUT_EVEN]; + } + else + { + otherbdt->addr = priv->out0data[EP0_OUT_ODD]; + } + otherbdt->status = (USB_BDT_UOWN | bytecount); /* Configure the current BDT to receive a SETUP command. */ - bdt->addr = (uint8_t *)physaddr; + if (bdt == &g_bdt[EP0_OUT_EVEN]) + { + bdt->addr = priv->out0data[EP0_OUT_EVEN]; + } + else + { + bdt->addr = priv->out0data[EP0_OUT_ODD]; + } + bdt->status = (USB_BDT_UOWN | bytecount); bdtinfo("EP0 BDT IN [%p] {%08x, %08x}\n", @@ -3732,9 +3825,9 @@ static int khci_epbdtstall(struct usbdev_ep_s *ep, bool resume, bool epin) return OK; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_epstall - ****************************************************************************/ + ******************************************************************************************/ static int khci_epstall(struct usbdev_ep_s *ep, bool resume) { @@ -3788,12 +3881,13 @@ static int khci_epstall(struct usbdev_ep_s *ep, bool resume) return ret; } -/**************************************************************************** +/****************************************************************************************** * Device Controller Operations - ****************************************************************************/ -/**************************************************************************** + ******************************************************************************************/ + +/****************************************************************************************** * Name: khci_allocep - ****************************************************************************/ + ******************************************************************************************/ static struct usbdev_ep_s *khci_allocep(struct usbdev_s *dev, uint8_t epno, bool epin, uint8_t eptype) @@ -3852,9 +3946,9 @@ static struct usbdev_ep_s *khci_allocep(struct usbdev_s *dev, uint8_t epno, return &privep->ep; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_freeep - ****************************************************************************/ + ******************************************************************************************/ static void khci_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep) { @@ -3883,9 +3977,9 @@ static void khci_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep) khci_epunreserve(priv, privep); } -/**************************************************************************** +/****************************************************************************************** * Name: khci_getframe - ****************************************************************************/ + ******************************************************************************************/ static int khci_getframe(struct usbdev_s *dev) { @@ -3925,9 +4019,9 @@ static int khci_getframe(struct usbdev_s *dev) return tmp; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_wakeup - ****************************************************************************/ + ******************************************************************************************/ static int khci_wakeup(struct usbdev_s *dev) { @@ -3948,9 +4042,9 @@ static int khci_wakeup(struct usbdev_s *dev) return OK; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_selfpowered - ****************************************************************************/ + ******************************************************************************************/ static int khci_selfpowered(struct usbdev_s *dev, bool selfpowered) { @@ -3970,18 +4064,18 @@ static int khci_selfpowered(struct usbdev_s *dev, bool selfpowered) return OK; } -/**************************************************************************** +/****************************************************************************************** * Initialization/Reset - ****************************************************************************/ + ******************************************************************************************/ -/**************************************************************************** +/****************************************************************************************** * Name: khci_reset * * Description: * Reset the software and hardware states. At the end of this reset, the * hardware should be in the full up, ready-to-run state. * - ****************************************************************************/ + ******************************************************************************************/ static void khci_reset(struct khci_usbdev_s *priv) { @@ -3998,9 +4092,9 @@ static void khci_reset(struct khci_usbdev_s *priv) khci_attach(priv); } -/**************************************************************************** +/****************************************************************************************** * Name: khci_attach - ****************************************************************************/ + ******************************************************************************************/ static void khci_attach(struct khci_usbdev_s *priv) { @@ -4084,9 +4178,9 @@ static void khci_attach(struct khci_usbdev_s *priv) } } -/**************************************************************************** +/****************************************************************************************** * Name: khci_swreset - ****************************************************************************/ + ******************************************************************************************/ static void khci_swreset(struct khci_usbdev_s *priv) { @@ -4132,13 +4226,13 @@ static void khci_swreset(struct khci_usbdev_s *priv) priv->rxbusy = 0; } -/**************************************************************************** +/****************************************************************************************** * Name: khci_hwreset * * Description: * Reset the hardware and leave it in a known, unready state. * - ****************************************************************************/ + ******************************************************************************************/ static void khci_hwreset(struct khci_usbdev_s *priv) { @@ -4174,7 +4268,7 @@ static void khci_hwreset(struct khci_usbdev_s *priv) /* Bring the ping pong buffer pointers out of reset */ regval &= ~USB_CTL_ODDRST; - khci_putreg(regval, KINETIS_USB0_CTL); + khci_putreg(regval, KINETIS_USB0_CTL); /* Enable interrupts at the USB controller */ @@ -4182,13 +4276,13 @@ static void khci_hwreset(struct khci_usbdev_s *priv) khci_putreg(NORMAL_INTERRUPTS, KINETIS_USB0_INTEN); } -/**************************************************************************** +/****************************************************************************************** * Name: khci_hwinitialize * * Description: * Reset the hardware and leave it in a known, unready state. * - ****************************************************************************/ + ******************************************************************************************/ static void khci_hwinitialize(struct khci_usbdev_s *priv) { @@ -4225,26 +4319,26 @@ static void khci_hwinitialize(struct khci_usbdev_s *priv) khci_putreg((uint8_t)((uint32_t)g_bdt >> 24), KINETIS_USB0_BDTPAGE3); khci_putreg((uint8_t)((uint32_t)g_bdt >> 16), KINETIS_USB0_BDTPAGE2); - khci_putreg((uint8_t)(((uint32_t)g_bdt >> 8) & USB_BDTPAGE1_MASK), KINETIS_USB0_BDTPAGE1); + khci_putreg((uint8_t)(((uint32_t)g_bdt >> 8) & USB_BDTPAGE1_MASK), + KINETIS_USB0_BDTPAGE1); - uinfo("BDT Address %hhx \n" ,&g_bdt); - uinfo("BDTPAGE3 %hhx\n",khci_getreg(KINETIS_USB0_BDTPAGE3)); - uinfo("BDTPAGE2 %hhx\n",khci_getreg(KINETIS_USB0_BDTPAGE2)); - uinfo("BDTPAGE1 %hhx\n",khci_getreg(KINETIS_USB0_BDTPAGE1)); + uinfo("BDT Address %hhx \n", &g_bdt); + uinfo("BDTPAGE3 %hhx\n", khci_getreg(KINETIS_USB0_BDTPAGE3)); + uinfo("BDTPAGE2 %hhx\n", khci_getreg(KINETIS_USB0_BDTPAGE2)); + uinfo("BDTPAGE1 %hhx\n", khci_getreg(KINETIS_USB0_BDTPAGE1)); #if defined(USB0_USBTRC0_BIT6) /* Undocumented bit */ regval = khci_getreg(KINETIS_USB0_USBTRC0); regval |= USB0_USBTRC0_BIT6; - khci_putreg(regval,KINETIS_USB0_USBTRC0); + khci_putreg(regval, KINETIS_USB0_USBTRC0); #endif - } -/**************************************************************************** +/****************************************************************************************** * Name: khci_swinitialize - ****************************************************************************/ + ******************************************************************************************/ static void khci_swinitialize(struct khci_usbdev_s *priv) { @@ -4299,13 +4393,12 @@ static void khci_swinitialize(struct khci_usbdev_s *priv) #endif } -/**************************************************************************** +/****************************************************************************************** * Name: khci_hwshutdown - ****************************************************************************/ + ******************************************************************************************/ static void khci_hwshutdown(struct khci_usbdev_s *priv) { - /* Disable all interrupts and force the USB controller into reset */ khci_putreg(0, KINETIS_USB0_ERREN); @@ -4319,11 +4412,11 @@ static void khci_hwshutdown(struct khci_usbdev_s *priv) kinetis_clrpend(KINETIS_IRQ_USBOTG); } -/**************************************************************************** +/****************************************************************************************** * Public Functions - ****************************************************************************/ + ******************************************************************************************/ -/**************************************************************************** +/****************************************************************************************** * Name: arm_usbinitialize * * Description: @@ -4342,7 +4435,7 @@ static void khci_hwshutdown(struct khci_usbdev_s *priv) * Returned Value: * None * - ****************************************************************************/ + ******************************************************************************************/ void arm_usbinitialize(void) { @@ -4407,7 +4500,7 @@ void arm_usbinitialize(void) khci_hwinitialize(priv); } -/**************************************************************************** +/****************************************************************************************** * Name: arm_usbuninitialize * Description: * Initialize the USB driver @@ -4417,7 +4510,7 @@ void arm_usbinitialize(void) * Returned Value: * None * - ****************************************************************************/ + ******************************************************************************************/ void arm_usbuninitialize(void) { @@ -4461,14 +4554,14 @@ void arm_usbuninitialize(void) leave_critical_section(flags); } -/**************************************************************************** +/****************************************************************************************** * Name: usbdev_register * * Description: * Register a USB device class driver. The class driver's bind() method * will be called to bind it to a USB device driver. * - ****************************************************************************/ + ******************************************************************************************/ int usbdev_register(struct usbdevclass_driver_s *driver) { @@ -4518,12 +4611,12 @@ int usbdev_register(struct usbdevclass_driver_s *driver) DEBUGASSERT(priv->devstate == DEVSTATE_DETACHED); khci_reset(priv); - } + } return ret; } -/**************************************************************************** +/****************************************************************************************** * Name: usbdev_unregister * * Description: @@ -4532,7 +4625,7 @@ int usbdev_register(struct usbdevclass_driver_s *driver) * unbind() and clean up any device state, before this procedure finally * returns. * - ****************************************************************************/ + ******************************************************************************************/ int usbdev_unregister(struct usbdevclass_driver_s *driver) { diff --git a/boards/arm/kinetis/freedom-k28f/configs/nshsdusb/defconfig b/boards/arm/kinetis/freedom-k28f/configs/nshsdusb/defconfig new file mode 100644 index 00000000000..3297dc6f71d --- /dev/null +++ b/boards/arm/kinetis/freedom-k28f/configs/nshsdusb/defconfig @@ -0,0 +1,93 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_MMCSD_HAVE_WRITEPROTECT is not set +# CONFIG_MMCSD_MMCSUPPORT is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +# CONFIG_NSH_CMDPARMS is not set +# CONFIG_SPI_CALLBACK is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="freedom-k28f" +CONFIG_ARCH_BOARD_FREEDOM_K28F=y +CONFIG_ARCH_CHIP="kinetis" +CONFIG_ARCH_CHIP_KINETIS=y +CONFIG_ARCH_CHIP_MK28FN2M0VMI15=y +CONFIG_ARCH_IRQPRIO=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARDCTL_USBDEVCTRL=y +CONFIG_BOARD_LOOPSPERMSEC=10401 +CONFIG_BUILTIN=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_TASK_STACKSIZE=4096 +CONFIG_FAT_LFN=y +CONFIG_FAT_MAXFNAME=128 +CONFIG_FRDMK28F_SDHC_AUTOMOUNT=y +CONFIG_FS_AUTOMOUNTER=y +CONFIG_FS_FAT=y +CONFIG_FS_PROCFS=y +CONFIG_INTELHEX_BINARY=y +CONFIG_KINETIS_GPIOIRQ=y +CONFIG_KINETIS_LPUART0=y +CONFIG_KINETIS_PORTBINTS=y +CONFIG_KINETIS_SDHC=y +CONFIG_KINETIS_SERIALBRK_BSDCOMPAT=y +CONFIG_KINETIS_UART_BREAKS=y +CONFIG_KINETIS_USBDCD=y +CONFIG_KINETIS_USBOTG=y +CONFIG_LPUART0_SERIAL_CONSOLE=y +CONFIG_MAX_TASKS=16 +CONFIG_MAX_WDOGPARMS=2 +CONFIG_MMCSD=y +CONFIG_MMCSD_SDIO=y +CONFIG_NET=y +CONFIG_NETDB_BUFSIZE=128 +CONFIG_NETDEVICES=y +CONFIG_NETINIT_NOMAC=y +CONFIG_NETINIT_THREAD=y +CONFIG_NETUTILS_TELNETD=y +CONFIG_NET_ARP_SEND=y +CONFIG_NET_BROADCAST=y +CONFIG_NET_ICMP=y +CONFIG_NET_LOOPBACK=y +CONFIG_NET_SOCKOPTS=y +CONFIG_NET_STATISTICS=y +CONFIG_NET_TCP=y +CONFIG_NET_TCP_WRITE_BUFFERS=y +CONFIG_NET_UDP=y +CONFIG_NFILE_DESCRIPTORS=8 +CONFIG_NFILE_STREAMS=8 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_MQ_MSGS=4 +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PREALLOC_WDOGS=16 +CONFIG_PRIORITY_INHERITANCE=y +CONFIG_PTHREAD_STACK_DEFAULT=2048 +CONFIG_RAM_SIZE=524288 +CONFIG_RAM_START=0x34000000 +CONFIG_RAW_BINARY=y +CONFIG_RNDIS=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SDCLONE_DISABLE=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_SPI=y +CONFIG_START_DAY=2 +CONFIG_START_MONTH=5 +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_NSH_STACKSIZE=2048 +CONFIG_TASK_NAME_SIZE=0 +CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048 +CONFIG_USBDEV=y +CONFIG_USERMAIN_STACKSIZE=2048 +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/boards/arm/kinetis/freedom-k28f/src/k28_bringup.c b/boards/arm/kinetis/freedom-k28f/src/k28_bringup.c index 8f9b8c7fd95..e4a31192adb 100644 --- a/boards/arm/kinetis/freedom-k28f/src/k28_bringup.c +++ b/boards/arm/kinetis/freedom-k28f/src/k28_bringup.c @@ -1,35 +1,20 @@ /**************************************************************************** * boards/arm/kinetis/freedom-k28f/src/k28_bringup.c * - * Copyright (C) 2018 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * 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 * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * 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. * ****************************************************************************/ @@ -51,6 +36,11 @@ # include #endif +#ifdef CONFIG_RNDIS +# include +# include +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -145,6 +135,24 @@ int k28_bringup(void) usbdev_serialinitialize(0); #endif +#ifdef CONFIG_RNDIS + /* Register USB RNDIS Driver */ + + uint8_t mac[6]; + mac[0] = (CONFIG_NETINIT_MACADDR_2 >> (8 * 1)) & 0xff; + mac[1] = (CONFIG_NETINIT_MACADDR_2 >> (8 * 0)) & 0xff; + mac[2] = (CONFIG_NETINIT_MACADDR_1 >> (8 * 3)) & 0xff; + mac[3] = (CONFIG_NETINIT_MACADDR_1 >> (8 * 2)) & 0xff; + mac[4] = (CONFIG_NETINIT_MACADDR_1 >> (8 * 1)) & 0xff; + mac[5] = (CONFIG_NETINIT_MACADDR_1 >> (8 * 0)) & 0xff; + + ret = usbdev_rndis_initialize(mac); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: usbdev_rndis_initialize() failed %d\n", ret); + } +#endif + UNUSED(ret); return OK; } diff --git a/drivers/usbdev/pl2303.c b/drivers/usbdev/pl2303.c index 0b8ff9cdb2c..04c17e9f0bc 100644 --- a/drivers/usbdev/pl2303.c +++ b/drivers/usbdev/pl2303.c @@ -1,43 +1,28 @@ -/**************************************************************************** +/****************************************************************************************** * drivers/usbdev/pl2303.c * - * Copyright (C) 2008-2013, 2015-2016 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * 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. * * This logic emulates the Prolific PL2303 serial/USB converter * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ + ******************************************************************************************/ -/**************************************************************************** +/****************************************************************************************** * Included Files - ****************************************************************************/ + ******************************************************************************************/ #include @@ -60,11 +45,11 @@ #include #include -/**************************************************************************** +/****************************************************************************************** * Pre-processor Definitions - ****************************************************************************/ + ******************************************************************************************/ -/* Configuration ************************************************************/ +/* Configuration **************************************************************************/ /* Number of requests in the write queue */ @@ -155,7 +140,7 @@ # define CONFIG_USBDEV_MAXPOWER 100 #endif -/* Descriptors ****************************************************************/ +/* Descriptors ****************************************************************************/ /* These settings are not modifiable via the NuttX configuration */ @@ -196,7 +181,7 @@ #define PL2303_MXDESCLEN (64) #define PL2303_MAXSTRLEN (PL2303_MXDESCLEN-2) -/* Vendor specific control requests *******************************************/ +/* Vendor specific control requests *******************************************************/ #define PL2303_CONTROL_TYPE (0x20) #define PL2303_SETLINEREQUEST (0x20) /* OUT, Recipient interface */ @@ -209,7 +194,7 @@ #define PL2303_RWREQUEST_TYPE (0x40) #define PL2303_RWREQUEST (0x01) /* IN/OUT, Recipient device */ -/* Misc Macros ****************************************************************/ +/* Misc Macros ****************************************************************************/ /* min/max macros */ @@ -221,7 +206,7 @@ # define max(a,b) ((a)>(b)?(a):(b)) #endif -/* Trace values *************************************************************/ +/* Trace values ***************************************************************************/ #define PL2303_CLASSAPI_SETUP TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_SETUP) #define PL2303_CLASSAPI_SHUTDOWN TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_SHUTDOWN) @@ -236,9 +221,9 @@ #define PL2303_CLASSAPI_TXREADY TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_TXREADY) #define PL2303_CLASSAPI_TXEMPTY TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_TXEMPTY) -/**************************************************************************** +/****************************************************************************************** * Private Types - ****************************************************************************/ + ******************************************************************************************/ /* Container to support a list of requests */ @@ -298,11 +283,11 @@ struct pl2303_alloc_s struct pl2303_driver_s drvr; }; -/**************************************************************************** +/****************************************************************************************** * Private Function Prototypes - ****************************************************************************/ + ******************************************************************************************/ -/* Transfer helpers *********************************************************/ +/* Transfer helpers ***********************************************************************/ static uint16_t usbclass_fillrequest(FAR struct pl2303_dev_s *priv, uint8_t *reqbuf, uint16_t reqlen); @@ -310,14 +295,14 @@ static int usbclass_sndpacket(FAR struct pl2303_dev_s *priv); static inline int usbclass_recvpacket(FAR struct pl2303_dev_s *priv, uint8_t *reqbuf, uint16_t reqlen); -/* Request helpers *********************************************************/ +/* Request helpers ************************************************************************/ static struct usbdev_req_s *usbclass_allocreq(FAR struct usbdev_ep_s *ep, uint16_t len); static void usbclass_freereq(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req); -/* Configuration ***********************************************************/ +/* Configuration **************************************************************************/ static int usbclass_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc); #ifdef CONFIG_USBDEV_DUALSPEED @@ -331,7 +316,7 @@ static void usbclass_resetconfig(FAR struct pl2303_dev_s *priv); static int usbclass_setconfig(FAR struct pl2303_dev_s *priv, uint8_t config); -/* Completion event handlers ***********************************************/ +/* Completion event handlers **************************************************************/ static void usbclass_ep0incomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req); @@ -340,7 +325,7 @@ static void usbclass_rdcomplete(FAR struct usbdev_ep_s *ep, static void usbclass_wrcomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req); -/* USB class device ********************************************************/ +/* USB class device ***********************************************************************/ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); @@ -359,7 +344,7 @@ static void usbclass_resume(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev); #endif -/* Serial port *************************************************************/ +/* Serial port ****************************************************************************/ static int usbser_setup(FAR struct uart_dev_s *dev); static void usbser_shutdown(FAR struct uart_dev_s *dev); @@ -369,11 +354,11 @@ static void usbser_rxint(FAR struct uart_dev_s *dev, bool enable); static void usbser_txint(FAR struct uart_dev_s *dev, bool enable); static bool usbser_txempty(FAR struct uart_dev_s *dev); -/**************************************************************************** +/****************************************************************************************** * Private Data - ****************************************************************************/ + ******************************************************************************************/ -/* USB class device ********************************************************/ +/* USB class device ***********************************************************************/ static const struct usbdevclass_driverops_s g_driverops = { @@ -390,7 +375,7 @@ static const struct usbdevclass_driverops_s g_driverops = #endif }; -/* Serial port *************************************************************/ +/* Serial port ****************************************************************************/ static const struct uart_ops_s g_uartops = { @@ -411,7 +396,7 @@ static const struct uart_ops_s g_uartops = usbser_txempty /* txempty */ }; -/* USB descriptor templates these will be copied and modified **************/ +/* USB descriptor templates these will be copied and modified *****************************/ static const struct usb_devdesc_s g_devdesc = { @@ -507,11 +492,11 @@ static const struct usb_qualdesc_s g_qualdesc = }; #endif -/**************************************************************************** +/****************************************************************************************** * Private Functions - ****************************************************************************/ + ******************************************************************************************/ -/************************************************************************************ +/****************************************************************************************** * Name: usbclass_fillrequest * * Description: @@ -525,7 +510,7 @@ static const struct usb_qualdesc_s g_qualdesc = * Unfortunately, that decision also exposes some internals of the serial driver * in the following. * - ************************************************************************************/ + ******************************************************************************************/ static uint16_t usbclass_fillrequest(FAR struct pl2303_dev_s *priv, uint8_t *reqbuf, uint16_t reqlen) @@ -576,7 +561,7 @@ static uint16_t usbclass_fillrequest(FAR struct pl2303_dev_s *priv, uint8_t *req return nbytes; } -/************************************************************************************ +/****************************************************************************************** * Name: usbclass_sndpacket * * Description: @@ -585,7 +570,7 @@ static uint16_t usbclass_fillrequest(FAR struct pl2303_dev_s *priv, uint8_t *req * (1) there are no further packets available, or (2) there is not further data * to send. * - ************************************************************************************/ + ******************************************************************************************/ static int usbclass_sndpacket(FAR struct pl2303_dev_s *priv) { @@ -663,7 +648,7 @@ static int usbclass_sndpacket(FAR struct pl2303_dev_s *priv) return ret; } -/************************************************************************************ +/****************************************************************************************** * Name: usbclass_recvpacket * * Description: @@ -674,7 +659,7 @@ static int usbclass_sndpacket(FAR struct pl2303_dev_s *priv) * Assumptions: * Called from the USB interrupt handler with interrupts disabled. * - ************************************************************************************/ + ******************************************************************************************/ static inline int usbclass_recvpacket(FAR struct pl2303_dev_s *priv, uint8_t *reqbuf, uint16_t reqlen) @@ -768,16 +753,17 @@ static inline int usbclass_recvpacket(FAR struct pl2303_dev_s *priv, usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RXOVERRUN), 0); return -ENOSPC; } + return OK; } -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_allocreq * * Description: * Allocate a request instance along with its buffer * - ****************************************************************************/ + ******************************************************************************************/ static struct usbdev_req_s *usbclass_allocreq(FAR struct usbdev_ep_s *ep, uint16_t len) @@ -795,16 +781,17 @@ static struct usbdev_req_s *usbclass_allocreq(FAR struct usbdev_ep_s *ep, req = NULL; } } + return req; } -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_freereq * * Description: * Free a request instance along with its buffer * - ****************************************************************************/ + ******************************************************************************************/ static void usbclass_freereq(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) @@ -815,17 +802,18 @@ static void usbclass_freereq(FAR struct usbdev_ep_s *ep, { EP_FREEBUFFER(ep, req->buf); } + EP_FREEREQ(ep, req); } } -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_mkstrdesc * * Description: * Construct a string descriptor * - ****************************************************************************/ + ******************************************************************************************/ static int usbclass_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc) { @@ -867,34 +855,34 @@ static int usbclass_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc) return -EINVAL; } - /* The string is utf16-le. The poor man's utf-8 to utf16-le - * conversion below will only handle 7-bit en-us ascii - */ + /* The string is utf16-le. The poor man's utf-8 to utf16-le + * conversion below will only handle 7-bit en-us ascii + */ - len = strlen(str); - if (len > (PL2303_MAXSTRLEN / 2)) - { - len = (PL2303_MAXSTRLEN / 2); - } + len = strlen(str); + if (len > (PL2303_MAXSTRLEN / 2)) + { + len = (PL2303_MAXSTRLEN / 2); + } - for (i = 0, ndata = 0; i < len; i++, ndata += 2) - { - strdesc->data[ndata] = str[i]; - strdesc->data[ndata+1] = 0; - } + for (i = 0, ndata = 0; i < len; i++, ndata += 2) + { + strdesc->data[ndata] = str[i]; + strdesc->data[ndata + 1] = 0; + } - strdesc->len = ndata+2; - strdesc->type = USB_DESC_TYPE_STRING; - return strdesc->len; + strdesc->len = ndata + 2; + strdesc->type = USB_DESC_TYPE_STRING; + return strdesc->len; } -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_mkepbulkdesc * * Description: * Construct the endpoint descriptor * - ****************************************************************************/ + ******************************************************************************************/ #ifdef CONFIG_USBDEV_DUALSPEED static inline void usbclass_mkepbulkdesc(const FAR struct usb_epdesc_s *indesc, @@ -912,13 +900,13 @@ static inline void usbclass_mkepbulkdesc(const FAR struct usb_epdesc_s *indesc, } #endif -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_mkcfgdesc * * Description: * Construct the configuration descriptor * - ****************************************************************************/ + ******************************************************************************************/ #ifdef CONFIG_USBDEV_DUALSPEED static int16_t usbclass_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type) @@ -937,7 +925,8 @@ static int16_t usbclass_mkcfgdesc(uint8_t *buf) * size that we will be sending now. */ - totallen = USB_SIZEOF_CFGDESC + USB_SIZEOF_IFDESC + PL2303_NENDPOINTS * USB_SIZEOF_EPDESC; + totallen = USB_SIZEOF_CFGDESC + USB_SIZEOF_IFDESC + + PL2303_NENDPOINTS * USB_SIZEOF_EPDESC; /* Configuration descriptor -- Copy the canned descriptor and fill in the * type (we'll also need to update the size below @@ -991,13 +980,13 @@ static int16_t usbclass_mkcfgdesc(uint8_t *buf) return totallen; } -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_resetconfig * * Description: * Mark the device as not configured and disable all endpoints. * - ****************************************************************************/ + ******************************************************************************************/ static void usbclass_resetconfig(FAR struct pl2303_dev_s *priv) { @@ -1027,14 +1016,14 @@ static void usbclass_resetconfig(FAR struct pl2303_dev_s *priv) } } -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_setconfig * * Description: * Set the device configuration by allocating and configuring endpoints and * by allocating and queue read and write requests. * - ****************************************************************************/ + ******************************************************************************************/ static int usbclass_setconfig(FAR struct pl2303_dev_s *priv, uint8_t config) { @@ -1090,6 +1079,7 @@ static int usbclass_setconfig(FAR struct pl2303_dev_s *priv, uint8_t config) usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPINTINCONFIGFAIL), 0); goto errout; } + priv->epintin->priv = priv; /* Configure the IN bulk endpoint */ @@ -1167,13 +1157,13 @@ errout: return ret; } -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_ep0incomplete * * Description: * Handle completion of EP0 control operations * - ****************************************************************************/ + ******************************************************************************************/ static void usbclass_ep0incomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) @@ -1184,14 +1174,14 @@ static void usbclass_ep0incomplete(FAR struct usbdev_ep_s *ep, } } -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_rdcomplete * * Description: * Handle completion of read request on the bulk OUT endpoint. This * is handled like the receipt of serial data on the "UART" * - ****************************************************************************/ + ******************************************************************************************/ static void usbclass_rdcomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) @@ -1207,7 +1197,7 @@ static void usbclass_rdcomplete(FAR struct usbdev_ep_s *ep, { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); return; - } + } #endif /* Extract references to private data */ @@ -1243,17 +1233,18 @@ static void usbclass_rdcomplete(FAR struct usbdev_ep_s *ep, { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT), (uint16_t)-req->result); } + leave_critical_section(flags); } -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_wrcomplete * * Description: * Handle completion of write request. This function probably executes * in the context of an interrupt handler. * - ****************************************************************************/ + ******************************************************************************************/ static void usbclass_wrcomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) @@ -1269,7 +1260,7 @@ static void usbclass_wrcomplete(FAR struct usbdev_ep_s *ep, { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); return; - } + } #endif /* Extract references to our private data */ @@ -1305,17 +1296,17 @@ static void usbclass_wrcomplete(FAR struct usbdev_ep_s *ep, } } -/**************************************************************************** +/****************************************************************************************** * USB Class Driver Methods - ****************************************************************************/ + ******************************************************************************************/ -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_bind * * Description: * Invoked when the driver is bound to a USB device driver * - ****************************************************************************/ + ******************************************************************************************/ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) @@ -1350,6 +1341,7 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver, ret = -ENOMEM; goto errout; } + priv->ctrlreq->callback = usbclass_ep0incomplete; /* Pre-allocate all endpoints... the endpoints will not be functional @@ -1368,6 +1360,7 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver, ret = -ENODEV; goto errout; } + priv->epintin->priv = priv; /* Pre-allocate the IN bulk endpoint */ @@ -1379,6 +1372,7 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver, ret = -ENODEV; goto errout; } + priv->epbulkin->priv = priv; /* Pre-allocate the OUT bulk endpoint */ @@ -1390,6 +1384,7 @@ static int usbclass_bind(FAR struct usbdevclass_driver_s *driver, ret = -ENODEV; goto errout; } + priv->epbulkout->priv = priv; /* Pre-allocate read requests. The buffer size is one full packet. */ @@ -1470,13 +1465,13 @@ errout: return ret; } -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_unbind * * Description: * Invoked when the driver is unbound from a USB device driver * - ****************************************************************************/ + ******************************************************************************************/ static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) @@ -1493,7 +1488,7 @@ static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver, { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); return; - } + } #endif /* Extract reference to private data */ @@ -1584,6 +1579,7 @@ static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver, priv->nwrq--; /* Number of write requests queued */ } } + DEBUGASSERT(priv->nwrq == 0); leave_critical_section(flags); } @@ -1594,14 +1590,14 @@ static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver, priv->serdev.xmit.tail = 0; } -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_setup * * Description: * Invoked for ep0 control requests. This function probably executes * in the context of an interrupt handler. * - ****************************************************************************/ + ******************************************************************************************/ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev, @@ -1620,7 +1616,7 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); return -EIO; - } + } #endif /* Extract reference to private data */ @@ -1635,6 +1631,7 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, return -ENODEV; } #endif + ctrlreq = priv->ctrlreq; /* Extract the little-endian 16-bit values to host order */ @@ -1648,9 +1645,7 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, switch (ctrl->type & USB_REQ_TYPE_MASK) { - /*********************************************************************** - * Standard Requests - ***********************************************************************/ + /* Standard Requests */ case USB_REQ_TYPE_STANDARD: { @@ -1696,7 +1691,8 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, { /* index == language code. */ - ret = usbclass_mkstrdesc(ctrl->value[0], (struct usb_strdesc_s *)ctrlreq->buf); + ret = usbclass_mkstrdesc(ctrl->value[0], + (struct usb_strdesc_s *)ctrlreq->buf); } break; @@ -1769,9 +1765,7 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, } break; - /*********************************************************************** - * PL2303 Vendor-Specific Requests - ***********************************************************************/ + /* PL2303 Vendor-Specific Requests */ case PL2303_CONTROL_TYPE: { @@ -1786,7 +1780,6 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, } break; - case PL2303_GETLINEREQUEST: { memcpy(ctrlreq->buf, priv->linest, 7); @@ -1817,8 +1810,31 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, { if ((ctrl->type & USB_DIR_IN) != 0) { - *(FAR uint32_t *)ctrlreq->buf = 0xdeadbeef; - ret = 4; + if (ctrl->value[0] == 0x84) + { + *ctrlreq->buf = 0x02; + ret = 1; + } + else if (ctrl->value[0] == 0x94) + { + *ctrlreq->buf = 0x00; + ret = 1; + } + else if (ctrl->value[0] == 0x83) + { + *ctrlreq->buf = 0xff; + ret = 1; + } + else if (ctrl->value[0] == 0x86) + { + *ctrlreq->buf = 0xaa; + ret = 1; + } + else + { + *(FAR uint32_t *)ctrlreq->buf = 0xdeadbe02; + ret = 4; + } } else { @@ -1858,7 +1874,7 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, return ret; } -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_disconnect * * Description: @@ -1866,7 +1882,7 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver, * disconnected. This function is probably called from the context of an * interrupt handler. * - ****************************************************************************/ + ******************************************************************************************/ static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev) @@ -1881,7 +1897,7 @@ static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver, { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); return; - } + } #endif /* Extract reference to private data */ @@ -1923,13 +1939,13 @@ static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver, DEV_CONNECT(dev); } -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_suspend * * Description: * Handle the USB suspend event. * - ****************************************************************************/ + ******************************************************************************************/ #ifdef CONFIG_SERIAL_REMOVABLE static void usbclass_suspend(FAR struct usbdevclass_driver_s *driver, @@ -1944,7 +1960,7 @@ static void usbclass_suspend(FAR struct usbdevclass_driver_s *driver, { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); return; - } + } #endif /* Extract reference to private data */ @@ -1957,13 +1973,13 @@ static void usbclass_suspend(FAR struct usbdevclass_driver_s *driver, } #endif -/**************************************************************************** +/****************************************************************************************** * Name: usbclass_resume * * Description: * Handle the USB resume event. * - ****************************************************************************/ + ******************************************************************************************/ #ifdef CONFIG_SERIAL_REMOVABLE static void usbclass_resume(FAR struct usbdevclass_driver_s *driver, @@ -1978,7 +1994,7 @@ static void usbclass_resume(FAR struct usbdevclass_driver_s *driver, { usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0); return; - } + } #endif /* Extract reference to private data */ @@ -1996,17 +2012,17 @@ static void usbclass_resume(FAR struct usbdevclass_driver_s *driver, } #endif -/**************************************************************************** +/****************************************************************************************** * Serial Device Methods - ****************************************************************************/ + ******************************************************************************************/ -/**************************************************************************** +/****************************************************************************************** * Name: usbser_setup * * Description: * This method is called the first time that the serial port is opened. * - ****************************************************************************/ + ******************************************************************************************/ static int usbser_setup(FAR struct uart_dev_s *dev) { @@ -2039,7 +2055,7 @@ static int usbser_setup(FAR struct uart_dev_s *dev) return OK; } -/**************************************************************************** +/****************************************************************************************** * Name: usbser_shutdown * * Description: @@ -2049,7 +2065,7 @@ static int usbser_setup(FAR struct uart_dev_s *dev) * usbser_txempty() until that function returns true before calling this * function. * - ****************************************************************************/ + ******************************************************************************************/ static void usbser_shutdown(FAR struct uart_dev_s *dev) { @@ -2065,13 +2081,13 @@ static void usbser_shutdown(FAR struct uart_dev_s *dev) #endif } -/**************************************************************************** +/****************************************************************************************** * Name: usbser_attach * * Description: * Does not apply to the USB serial class device * - ****************************************************************************/ + ******************************************************************************************/ static int usbser_attach(FAR struct uart_dev_s *dev) { @@ -2079,20 +2095,20 @@ static int usbser_attach(FAR struct uart_dev_s *dev) return OK; } -/**************************************************************************** +/****************************************************************************************** * Name: usbser_detach * * Description: * Does not apply to the USB serial class device * - ****************************************************************************/ + ******************************************************************************************/ static void usbser_detach(FAR struct uart_dev_s *dev) { usbtrace(PL2303_CLASSAPI_DETACH, 0); } -/**************************************************************************** +/****************************************************************************************** * Name: usbser_rxint * * Description: @@ -2107,7 +2123,7 @@ static void usbser_detach(FAR struct uart_dev_s *dev) * 3. With enable==false when the port is closed (just before usbser_detach * and usbser_shutdown are called). * - ****************************************************************************/ + ******************************************************************************************/ static void usbser_rxint(FAR struct uart_dev_s *dev, bool enable) { @@ -2185,10 +2201,11 @@ static void usbser_rxint(FAR struct uart_dev_s *dev, bool enable) priv->rxhead = serdev->recv.head; priv->rxenabled = false; } + leave_critical_section(flags); } -/**************************************************************************** +/****************************************************************************************** * Name: usbser_txint * * Description: @@ -2200,7 +2217,7 @@ static void usbser_rxint(FAR struct uart_dev_s *dev, bool enable) * 2. With enable==true when data may be taken from the buffer. * 3. With enable==false when the TX buffer is empty * - ****************************************************************************/ + ******************************************************************************************/ static void usbser_txint(FAR struct uart_dev_s *dev, bool enable) { @@ -2235,7 +2252,7 @@ static void usbser_txint(FAR struct uart_dev_s *dev, bool enable) } } -/**************************************************************************** +/****************************************************************************************** * Name: usbser_txempty * * Description: @@ -2245,7 +2262,7 @@ static void usbser_txint(FAR struct uart_dev_s *dev, bool enable) * responsibility for flushing TX data through the hardware so we can be * a bit sloppy about that. * - ****************************************************************************/ + ******************************************************************************************/ static bool usbser_txempty(FAR struct uart_dev_s *dev) { @@ -2268,17 +2285,17 @@ static bool usbser_txempty(FAR struct uart_dev_s *dev) return priv->nwrq >= CONFIG_PL2303_NWRREQS; } -/**************************************************************************** +/****************************************************************************************** * Public Functions - ****************************************************************************/ + ******************************************************************************************/ -/**************************************************************************** +/****************************************************************************************** * Name: usbdev_serialinitialize * * Description: * Register USB serial port (and USB serial console if so configured). * - ****************************************************************************/ + ******************************************************************************************/ int usbdev_serialinitialize(int minor) { @@ -2369,6 +2386,7 @@ int usbdev_serialinitialize(int minor) usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UARTREGISTER), (uint16_t)-ret); goto errout_with_class; } + return OK; errout_with_class: