summaryrefslogtreecommitdiff
path: root/drivers/usb/host/xhci-mtk.h
diff options
context:
space:
mode:
authorChunfeng Yun <chunfeng.yun@mediatek.com>2021-08-26 10:51:43 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-08-26 13:40:33 +0200
commit4ce186665e7c3e9edde648dfb373ca0d213fb312 (patch)
tree71c09d69a540aa587169c2f601dda10087bb69b6 /drivers/usb/host/xhci-mtk.h
parent926d60ae64a623db3c1afcc524c23709615893d7 (diff)
downloadlinux-4ce186665e7c3e9edde648dfb373ca0d213fb312.tar.gz
usb: xhci-mtk: Do not use xhci's virt_dev in drop_endpoint
xhci-mtk depends on xhci's internal virt_dev when it retrieves its internal data from usb_host_endpoint both in add_endpoint and drop_endpoint callbacks. But when setup packet was retired by transaction errors in xhci_setup_device() path, a virt_dev for the slot is newly created with real_port 0. This leads to xhci-mtks's NULL pointer dereference from drop_endpoint callback as xhci-mtk assumes that virt_dev's real_port is always started from one. The similar problems were addressed by [1] but that can't cover the failure cases from setup_device. This patch drops the usages of xhci's virt_dev in xhci-mtk's drop_endpoint callback by adopting hashtable for searching mtk's schedule entity from a given usb_host_endpoint pointer instead of searching a linked list. So mtk's drop_endpoint callback doesn't have to rely on virt_dev at all. [1] f351f4b63dac ("usb: xhci-mtk: fix oops when unbind driver") Signed-off-by: Ikjoon Jang <ikjn@chromium.org> Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> Link: https://lore.kernel.org/r/20210826025144.51992-5-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/xhci-mtk.h')
-rw-r--r--drivers/usb/host/xhci-mtk.h11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index 56dc348349af..9c54a597e66b 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -10,11 +10,15 @@
#define _XHCI_MTK_H_
#include <linux/clk.h>
+#include <linux/hashtable.h>
#include "xhci.h"
#define BULK_CLKS_NUM 5
+/* support at most 64 ep, use 32 size hash table */
+#define SCH_EP_HASH_BITS 5
+
/**
* To simplify scheduler algorithm, set a upper limit for ESIT,
* if a synchromous ep's ESIT is larger than @XHCI_MTK_MAX_ESIT,
@@ -36,14 +40,12 @@ struct mu3h_sch_tt {
* struct mu3h_sch_bw_info: schedule information for bandwidth domain
*
* @bus_bw: array to keep track of bandwidth already used at each uframes
- * @bw_ep_list: eps in the bandwidth domain
*
* treat a HS root port as a bandwidth domain, but treat a SS root port as
* two bandwidth domains, one for IN eps and another for OUT eps.
*/
struct mu3h_sch_bw_info {
u32 bus_bw[XHCI_MTK_MAX_ESIT];
- struct list_head bw_ep_list;
};
/**
@@ -54,8 +56,10 @@ struct mu3h_sch_bw_info {
* @num_budget_microframes: number of continuous uframes
* (@repeat==1) scheduled within the interval
* @bw_cost_per_microframe: bandwidth cost per microframe
+ * @hentry: hash table entry
* @endpoint: linked into bandwidth domain which it belongs to
* @tt_endpoint: linked into mu3h_sch_tt's list which it belongs to
+ * @bw_info: bandwidth domain which this endpoint belongs
* @sch_tt: mu3h_sch_tt linked into
* @ep_type: endpoint type
* @maxpkt: max packet size of endpoint
@@ -84,7 +88,9 @@ struct mu3h_sch_ep_info {
u32 num_budget_microframes;
u32 bw_cost_per_microframe;
struct list_head endpoint;
+ struct hlist_node hentry;
struct list_head tt_endpoint;
+ struct mu3h_sch_bw_info *bw_info;
struct mu3h_sch_tt *sch_tt;
u32 ep_type;
u32 maxpkt;
@@ -137,6 +143,7 @@ struct xhci_hcd_mtk {
struct usb_hcd *hcd;
struct mu3h_sch_bw_info *sch_array;
struct list_head bw_ep_chk_list;
+ DECLARE_HASHTABLE(sch_ep_hash, SCH_EP_HASH_BITS);
struct mu3c_ippc_regs __iomem *ippc_regs;
int num_u2_ports;
int num_u3_ports;