Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'usb-v5.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb into usb-linus

Peter writes:

4 bug fixes for Cadence 3 driver.
The biggest fix is changing endpoint configuration method to
avoid FIFO overflow at multiple endpoints situation.

* tag 'usb-v5.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb:
usb: cdns3: gadget: own the lock wrongly at the suspend routine
usb: cdns3: Fix on-chip memory overflow issue
usb: cdns3: gadget: suspicious implicit sign extension
usb: cdns3: Variable 'length' set but not used

+102 -83
+35 -30
drivers/usb/cdns3/ep0.c
··· 137 137 struct usb_ctrlrequest *ctrl_req) 138 138 { 139 139 enum usb_device_state device_state = priv_dev->gadget.state; 140 - struct cdns3_endpoint *priv_ep; 141 140 u32 config = le16_to_cpu(ctrl_req->wValue); 142 141 int result = 0; 143 - int i; 144 142 145 143 switch (device_state) { 146 144 case USB_STATE_ADDRESS: 147 - /* Configure non-control EPs */ 148 - for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++) { 149 - priv_ep = priv_dev->eps[i]; 150 - if (!priv_ep) 151 - continue; 152 - 153 - if (priv_ep->flags & EP_CLAIMED) 154 - cdns3_ep_config(priv_ep); 155 - } 156 - 157 145 result = cdns3_ep0_delegate_req(priv_dev, ctrl_req); 158 146 159 - if (result) 160 - return result; 161 - 162 - if (!config) { 163 - cdns3_hw_reset_eps_config(priv_dev); 164 - usb_gadget_set_state(&priv_dev->gadget, 165 - USB_STATE_ADDRESS); 166 - } 147 + if (result || !config) 148 + goto reset_config; 167 149 168 150 break; 169 151 case USB_STATE_CONFIGURED: 170 152 result = cdns3_ep0_delegate_req(priv_dev, ctrl_req); 153 + if (!config && !result) 154 + goto reset_config; 171 155 172 - if (!config && !result) { 173 - cdns3_hw_reset_eps_config(priv_dev); 174 - usb_gadget_set_state(&priv_dev->gadget, 175 - USB_STATE_ADDRESS); 176 - } 177 156 break; 178 157 default: 179 - result = -EINVAL; 158 + return -EINVAL; 180 159 } 160 + 161 + return 0; 162 + 163 + reset_config: 164 + if (result != USB_GADGET_DELAYED_STATUS) 165 + cdns3_hw_reset_eps_config(priv_dev); 166 + 167 + usb_gadget_set_state(&priv_dev->gadget, 168 + USB_STATE_ADDRESS); 181 169 182 170 return result; 183 171 } ··· 693 705 unsigned long flags; 694 706 int ret = 0; 695 707 u8 zlp = 0; 708 + int i; 696 709 697 710 spin_lock_irqsave(&priv_dev->lock, flags); 698 711 trace_cdns3_ep0_queue(priv_dev, request); ··· 709 720 u32 val; 710 721 711 722 cdns3_select_ep(priv_dev, 0x00); 723 + 724 + /* 725 + * Configure all non-control EPs which are not enabled by class driver 726 + */ 727 + for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++) { 728 + priv_ep = priv_dev->eps[i]; 729 + if (priv_ep && priv_ep->flags & EP_CLAIMED && 730 + !(priv_ep->flags & EP_ENABLED)) 731 + cdns3_ep_config(priv_ep, 0); 732 + } 733 + 712 734 cdns3_set_hw_configuration(priv_dev); 713 735 cdns3_ep0_complete_setup(priv_dev, 0, 1); 714 736 /* wait until configuration set */ ··· 811 811 struct cdns3_usb_regs __iomem *regs; 812 812 struct cdns3_endpoint *priv_ep; 813 813 u32 max_packet_size = 64; 814 + u32 ep_cfg; 814 815 815 816 regs = priv_dev->regs; 816 817 ··· 843 842 BIT(0) | BIT(16)); 844 843 } 845 844 846 - writel(EP_CFG_ENABLE | EP_CFG_MAXPKTSIZE(max_packet_size), 847 - &regs->ep_cfg); 845 + ep_cfg = EP_CFG_ENABLE | EP_CFG_MAXPKTSIZE(max_packet_size); 846 + 847 + if (!(priv_ep->flags & EP_CONFIGURED)) 848 + writel(ep_cfg, &regs->ep_cfg); 848 849 849 850 writel(EP_STS_EN_SETUPEN | EP_STS_EN_DESCMISEN | EP_STS_EN_TRBERREN, 850 851 &regs->ep_sts_en); ··· 854 851 /* init ep in */ 855 852 cdns3_select_ep(priv_dev, USB_DIR_IN); 856 853 857 - writel(EP_CFG_ENABLE | EP_CFG_MAXPKTSIZE(max_packet_size), 858 - &regs->ep_cfg); 854 + if (!(priv_ep->flags & EP_CONFIGURED)) 855 + writel(ep_cfg, &regs->ep_cfg); 856 + 857 + priv_ep->flags |= EP_CONFIGURED; 859 858 860 859 writel(EP_STS_EN_SETUPEN | EP_STS_EN_TRBERREN, &regs->ep_sts_en); 861 860
+64 -51
drivers/usb/cdns3/gadget.c
··· 296 296 */ 297 297 void cdns3_hw_reset_eps_config(struct cdns3_device *priv_dev) 298 298 { 299 + int i; 300 + 299 301 writel(USB_CONF_CFGRST, &priv_dev->regs->usb_conf); 300 302 301 303 cdns3_allow_enable_l1(priv_dev, 0); ··· 306 304 priv_dev->out_mem_is_allocated = 0; 307 305 priv_dev->wait_for_setup = 0; 308 306 priv_dev->using_streams = 0; 307 + 308 + for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++) 309 + if (priv_dev->eps[i]) 310 + priv_dev->eps[i]->flags &= ~EP_CONFIGURED; 309 311 } 310 312 311 313 /** ··· 512 506 513 507 while (!list_empty(&priv_ep->wa2_descmiss_req_list)) { 514 508 int chunk_end; 515 - int length; 516 509 517 510 descmiss_priv_req = 518 511 cdns3_next_priv_request(&priv_ep->wa2_descmiss_req_list); ··· 522 517 break; 523 518 524 519 chunk_end = descmiss_priv_req->flags & REQUEST_INTERNAL_CH; 525 - length = request->actual + descmiss_req->actual; 526 520 request->status = descmiss_req->status; 527 521 __cdns3_descmiss_copy_data(request, descmiss_req); 528 522 list_del_init(&descmiss_priv_req->list); ··· 1750 1746 1751 1747 static void cdns3_disconnect_gadget(struct cdns3_device *priv_dev) 1752 1748 { 1753 - if (priv_dev->gadget_driver && priv_dev->gadget_driver->disconnect) { 1754 - spin_unlock(&priv_dev->lock); 1749 + if (priv_dev->gadget_driver && priv_dev->gadget_driver->disconnect) 1755 1750 priv_dev->gadget_driver->disconnect(&priv_dev->gadget); 1756 - spin_lock(&priv_dev->lock); 1757 - } 1758 1751 } 1759 1752 1760 1753 /** ··· 1762 1761 */ 1763 1762 static void cdns3_check_usb_interrupt_proceed(struct cdns3_device *priv_dev, 1764 1763 u32 usb_ists) 1764 + __must_hold(&priv_dev->lock) 1765 1765 { 1766 1766 int speed = 0; 1767 1767 ··· 1787 1785 1788 1786 /* Disconnection detected */ 1789 1787 if (usb_ists & (USB_ISTS_DIS2I | USB_ISTS_DISI)) { 1788 + spin_unlock(&priv_dev->lock); 1790 1789 cdns3_disconnect_gadget(priv_dev); 1790 + spin_lock(&priv_dev->lock); 1791 1791 priv_dev->gadget.speed = USB_SPEED_UNKNOWN; 1792 1792 usb_gadget_set_state(&priv_dev->gadget, USB_STATE_NOTATTACHED); 1793 1793 cdns3_hw_reset_eps_config(priv_dev); ··· 1983 1979 return 0; 1984 1980 } 1985 1981 1986 - static void cdns3_stream_ep_reconfig(struct cdns3_device *priv_dev, 1987 - struct cdns3_endpoint *priv_ep) 1988 - { 1989 - if (!priv_ep->use_streams || priv_dev->gadget.speed < USB_SPEED_SUPER) 1990 - return; 1991 - 1992 - if (priv_dev->dev_ver >= DEV_VER_V3) { 1993 - u32 mask = BIT(priv_ep->num + (priv_ep->dir ? 16 : 0)); 1994 - 1995 - /* 1996 - * Stream capable endpoints are handled by using ep_tdl 1997 - * register. Other endpoints use TDL from TRB feature. 1998 - */ 1999 - cdns3_clear_register_bit(&priv_dev->regs->tdl_from_trb, mask); 2000 - } 2001 - 2002 - /* Enable Stream Bit TDL chk and SID chk */ 2003 - cdns3_set_register_bit(&priv_dev->regs->ep_cfg, EP_CFG_STREAM_EN | 2004 - EP_CFG_TDL_CHK | EP_CFG_SID_CHK); 2005 - } 2006 - 2007 1982 static void cdns3_configure_dmult(struct cdns3_device *priv_dev, 2008 1983 struct cdns3_endpoint *priv_ep) 2009 1984 { ··· 2020 2037 /** 2021 2038 * cdns3_ep_config Configure hardware endpoint 2022 2039 * @priv_ep: extended endpoint object 2040 + * @enable: set EP_CFG_ENABLE bit in ep_cfg register. 2023 2041 */ 2024 - void cdns3_ep_config(struct cdns3_endpoint *priv_ep) 2042 + int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) 2025 2043 { 2026 2044 bool is_iso_ep = (priv_ep->type == USB_ENDPOINT_XFER_ISOC); 2027 2045 struct cdns3_device *priv_dev = priv_ep->cdns3_dev; ··· 2083 2099 break; 2084 2100 default: 2085 2101 /* all other speed are not supported */ 2086 - return; 2102 + return -EINVAL; 2087 2103 } 2088 2104 2089 2105 if (max_packet_size == 1024) ··· 2093 2109 else 2094 2110 priv_ep->trb_burst_size = 16; 2095 2111 2096 - ret = cdns3_ep_onchip_buffer_reserve(priv_dev, buffering + 1, 2097 - !!priv_ep->dir); 2098 - if (ret) { 2099 - dev_err(priv_dev->dev, "onchip mem is full, ep is invalid\n"); 2100 - return; 2112 + /* onchip buffer is only allocated before configuration */ 2113 + if (!priv_dev->hw_configured_flag) { 2114 + ret = cdns3_ep_onchip_buffer_reserve(priv_dev, buffering + 1, 2115 + !!priv_ep->dir); 2116 + if (ret) { 2117 + dev_err(priv_dev->dev, "onchip mem is full, ep is invalid\n"); 2118 + return ret; 2119 + } 2120 + } 2121 + 2122 + if (enable) 2123 + ep_cfg |= EP_CFG_ENABLE; 2124 + 2125 + if (priv_ep->use_streams && priv_dev->gadget.speed >= USB_SPEED_SUPER) { 2126 + if (priv_dev->dev_ver >= DEV_VER_V3) { 2127 + u32 mask = BIT(priv_ep->num + (priv_ep->dir ? 16 : 0)); 2128 + 2129 + /* 2130 + * Stream capable endpoints are handled by using ep_tdl 2131 + * register. Other endpoints use TDL from TRB feature. 2132 + */ 2133 + cdns3_clear_register_bit(&priv_dev->regs->tdl_from_trb, 2134 + mask); 2135 + } 2136 + 2137 + /* Enable Stream Bit TDL chk and SID chk */ 2138 + ep_cfg |= EP_CFG_STREAM_EN | EP_CFG_TDL_CHK | EP_CFG_SID_CHK; 2101 2139 } 2102 2140 2103 2141 ep_cfg |= EP_CFG_MAXPKTSIZE(max_packet_size) | ··· 2129 2123 2130 2124 cdns3_select_ep(priv_dev, bEndpointAddress); 2131 2125 writel(ep_cfg, &priv_dev->regs->ep_cfg); 2126 + priv_ep->flags |= EP_CONFIGURED; 2132 2127 2133 2128 dev_dbg(priv_dev->dev, "Configure %s: with val %08x\n", 2134 2129 priv_ep->name, ep_cfg); 2130 + 2131 + return 0; 2135 2132 } 2136 2133 2137 2134 /* Find correct direction for HW endpoint according to description */ ··· 2275 2266 u32 bEndpointAddress; 2276 2267 unsigned long flags; 2277 2268 int enable = 1; 2278 - int ret; 2269 + int ret = 0; 2279 2270 int val; 2280 2271 2281 2272 priv_ep = ep_to_cdns3_ep(ep); ··· 2314 2305 bEndpointAddress = priv_ep->num | priv_ep->dir; 2315 2306 cdns3_select_ep(priv_dev, bEndpointAddress); 2316 2307 2308 + /* 2309 + * For some versions of controller at some point during ISO OUT traffic 2310 + * DMA reads Transfer Ring for the EP which has never got doorbell. 2311 + * This issue was detected only on simulation, but to avoid this issue 2312 + * driver add protection against it. To fix it driver enable ISO OUT 2313 + * endpoint before setting DRBL. This special treatment of ISO OUT 2314 + * endpoints are recommended by controller specification. 2315 + */ 2316 + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && !priv_ep->dir) 2317 + enable = 0; 2318 + 2317 2319 if (usb_ss_max_streams(comp_desc) && usb_endpoint_xfer_bulk(desc)) { 2318 2320 /* 2319 2321 * Enable stream support (SS mode) related interrupts ··· 2335 2315 EP_STS_EN_SIDERREN | EP_STS_EN_MD_EXITEN | 2336 2316 EP_STS_EN_STREAMREN; 2337 2317 priv_ep->use_streams = true; 2338 - cdns3_stream_ep_reconfig(priv_dev, priv_ep); 2318 + ret = cdns3_ep_config(priv_ep, enable); 2339 2319 priv_dev->using_streams |= true; 2340 2320 } 2321 + } else { 2322 + ret = cdns3_ep_config(priv_ep, enable); 2341 2323 } 2342 2324 2343 - ret = cdns3_allocate_trb_pool(priv_ep); 2325 + if (ret) 2326 + goto exit; 2344 2327 2328 + ret = cdns3_allocate_trb_pool(priv_ep); 2345 2329 if (ret) 2346 2330 goto exit; 2347 2331 ··· 2374 2350 cdns3_wa2_enable_detection(priv_dev, priv_ep, reg); 2375 2351 2376 2352 writel(reg, &priv_dev->regs->ep_sts_en); 2377 - 2378 - /* 2379 - * For some versions of controller at some point during ISO OUT traffic 2380 - * DMA reads Transfer Ring for the EP which has never got doorbell. 2381 - * This issue was detected only on simulation, but to avoid this issue 2382 - * driver add protection against it. To fix it driver enable ISO OUT 2383 - * endpoint before setting DRBL. This special treatment of ISO OUT 2384 - * endpoints are recommended by controller specification. 2385 - */ 2386 - if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && !priv_ep->dir) 2387 - enable = 0; 2388 - 2389 - if (enable) 2390 - cdns3_set_register_bit(&priv_dev->regs->ep_cfg, EP_CFG_ENABLE); 2391 2353 2392 2354 ep->desc = desc; 2393 2355 priv_ep->flags &= ~(EP_PENDING_REQUEST | EP_STALLED | EP_STALL_PENDING | ··· 3275 3265 } 3276 3266 3277 3267 static int cdns3_gadget_suspend(struct cdns3 *cdns, bool do_wakeup) 3268 + __must_hold(&cdns->lock) 3278 3269 { 3279 3270 struct cdns3_device *priv_dev = cdns->gadget_dev; 3280 3271 3272 + spin_unlock(&cdns->lock); 3281 3273 cdns3_disconnect_gadget(priv_dev); 3274 + spin_lock(&cdns->lock); 3282 3275 3283 3276 priv_dev->gadget.speed = USB_SPEED_UNKNOWN; 3284 3277 usb_gadget_set_state(&priv_dev->gadget, USB_STATE_NOTATTACHED);
+3 -2
drivers/usb/cdns3/gadget.h
··· 1072 1072 #define TRB_TDL_SS_SIZE_GET(p) (((p) & GENMASK(23, 17)) >> 17) 1073 1073 1074 1074 /* transfer_len bitmasks - bits 31:24 */ 1075 - #define TRB_BURST_LEN(p) (((p) << 24) & GENMASK(31, 24)) 1075 + #define TRB_BURST_LEN(p) ((unsigned int)((p) << 24) & GENMASK(31, 24)) 1076 1076 #define TRB_BURST_LEN_GET(p) (((p) & GENMASK(31, 24)) >> 24) 1077 1077 1078 1078 /* Data buffer pointer bitmasks*/ ··· 1159 1159 #define EP_QUIRK_EXTRA_BUF_DET BIT(12) 1160 1160 #define EP_QUIRK_EXTRA_BUF_EN BIT(13) 1161 1161 #define EP_TDLCHK_EN BIT(15) 1162 + #define EP_CONFIGURED BIT(16) 1162 1163 u32 flags; 1163 1164 1164 1165 struct cdns3_request *descmis_req; ··· 1361 1360 int cdns3_init_ep0(struct cdns3_device *priv_dev, 1362 1361 struct cdns3_endpoint *priv_ep); 1363 1362 void cdns3_ep0_config(struct cdns3_device *priv_dev); 1364 - void cdns3_ep_config(struct cdns3_endpoint *priv_ep); 1363 + int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable); 1365 1364 void cdns3_check_ep0_interrupt_proceed(struct cdns3_device *priv_dev, int dir); 1366 1365 int __cdns3_gadget_wakeup(struct cdns3_device *priv_dev); 1367 1366