USB fixes for 5.11-rc7
Here are some small, last-minute, USB driver fixes for 5.11-rc7 They all resolve issues reported, or are a few new device ids for some drivers. They include: - new device ids for some usb-serial drivers - xhci fixes for a variety of reported problems - dwc3 driver bugfixes - dwc2 driver bugfixes - usblp driver bugfix - thunderbolt bugfix - few other tiny fixes All have been in linux-next with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCYB6mPw8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+yk7QgCcC948UTZcM6GtJK7BZtVStNENRqsAn3pvFR3Y m7Qv7knWxULL6UNWVsTw =83YY -----END PGP SIGNATURE----- Merge tag 'usb-5.11-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb Pull USB fixes from Greg KH: "Here are some small, last-minute, USB driver fixes for 5.11-rc7 They all resolve issues reported, or are a few new device ids for some drivers. They include: - new device ids for some usb-serial drivers - xhci fixes for a variety of reported problems - dwc3 driver bugfixes - dwc2 driver bugfixes - usblp driver bugfix - thunderbolt bugfix - few other tiny fixes All have been in linux-next with no reported issues" * tag 'usb-5.11-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: usb: dwc2: Fix endpoint direction check in ep_from_windex usb: dwc3: fix clock issue during resume in OTG mode xhci: fix bounce buffer usage for non-sg list case usb: host: xhci: mvebu: make USB 3.0 PHY optional for Armada 3720 usb: xhci-mtk: break loop when find the endpoint to drop usb: xhci-mtk: skip dropping bandwidth of unchecked endpoints usb: renesas_usbhs: Clear pipe running flag in usbhs_pkt_pop() USB: gadget: legacy: fix an error code in eth_bind() thunderbolt: Fix possible NULL pointer dereference in tb_acpi_add_link() USB: serial: option: Adding support for Cinterion MV31 usb: xhci-mtk: fix unreleased bandwidth data usb: gadget: aspeed: add missing of_node_put USB: usblp: don't call usb_set_interface if there's a single alt USB: serial: cp210x: add pid/vid for WSDA-200-USB USB: serial: cp210x: add new VID/PID for supporting Teraoka AD2000
This commit is contained in:
Коммит
368afecbfb
|
@ -56,7 +56,7 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data,
|
|||
* managed with the xHCI and the SuperSpeed hub so we create the
|
||||
* link from xHCI instead.
|
||||
*/
|
||||
while (!dev_is_pci(dev))
|
||||
while (dev && !dev_is_pci(dev))
|
||||
dev = dev->parent;
|
||||
|
||||
if (!dev)
|
||||
|
|
|
@ -1329,14 +1329,17 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
|
|||
if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL)
|
||||
return -EINVAL;
|
||||
|
||||
alts = usblp->protocol[protocol].alt_setting;
|
||||
if (alts < 0)
|
||||
return -EINVAL;
|
||||
r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
|
||||
if (r < 0) {
|
||||
printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n",
|
||||
alts, usblp->ifnum);
|
||||
return r;
|
||||
/* Don't unnecessarily set the interface if there's a single alt. */
|
||||
if (usblp->intf->num_altsetting > 1) {
|
||||
alts = usblp->protocol[protocol].alt_setting;
|
||||
if (alts < 0)
|
||||
return -EINVAL;
|
||||
r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
|
||||
if (r < 0) {
|
||||
printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n",
|
||||
alts, usblp->ifnum);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
usblp->bidir = (usblp->protocol[protocol].epread != NULL);
|
||||
|
|
|
@ -1543,7 +1543,6 @@ static void dwc2_hsotg_complete_oursetup(struct usb_ep *ep,
|
|||
static struct dwc2_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg,
|
||||
u32 windex)
|
||||
{
|
||||
struct dwc2_hsotg_ep *ep;
|
||||
int dir = (windex & USB_DIR_IN) ? 1 : 0;
|
||||
int idx = windex & 0x7F;
|
||||
|
||||
|
@ -1553,12 +1552,7 @@ static struct dwc2_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg,
|
|||
if (idx > hsotg->num_of_eps)
|
||||
return NULL;
|
||||
|
||||
ep = index_to_ep(hsotg, idx, dir);
|
||||
|
||||
if (idx && ep->dir_in != dir)
|
||||
return NULL;
|
||||
|
||||
return ep;
|
||||
return index_to_ep(hsotg, idx, dir);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1758,7 +1758,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
|
|||
if (PMSG_IS_AUTO(msg))
|
||||
break;
|
||||
|
||||
ret = dwc3_core_init(dwc);
|
||||
ret = dwc3_core_init_for_resume(dwc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -403,8 +403,10 @@ static int eth_bind(struct usb_composite_dev *cdev)
|
|||
struct usb_descriptor_header *usb_desc;
|
||||
|
||||
usb_desc = usb_otg_descriptor_alloc(gadget);
|
||||
if (!usb_desc)
|
||||
if (!usb_desc) {
|
||||
status = -ENOMEM;
|
||||
goto fail1;
|
||||
}
|
||||
usb_otg_descriptor_init(gadget, usb_desc);
|
||||
otg_desc[0] = usb_desc;
|
||||
otg_desc[1] = NULL;
|
||||
|
|
|
@ -999,8 +999,10 @@ static int ast_vhub_of_parse_str_desc(struct ast_vhub *vhub,
|
|||
str_array[offset].s = NULL;
|
||||
|
||||
ret = ast_vhub_str_alloc_add(vhub, &lang_str);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
of_node_put(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -200,6 +200,8 @@ static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev,
|
|||
|
||||
sch_ep->sch_tt = tt;
|
||||
sch_ep->ep = ep;
|
||||
INIT_LIST_HEAD(&sch_ep->endpoint);
|
||||
INIT_LIST_HEAD(&sch_ep->tt_endpoint);
|
||||
|
||||
return sch_ep;
|
||||
}
|
||||
|
@ -373,6 +375,7 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
|
|||
sch_ep->bw_budget_table[j];
|
||||
}
|
||||
}
|
||||
sch_ep->allocated = used;
|
||||
}
|
||||
|
||||
static int check_sch_tt(struct usb_device *udev,
|
||||
|
@ -541,6 +544,22 @@ static int check_sch_bw(struct usb_device *udev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void destroy_sch_ep(struct usb_device *udev,
|
||||
struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
|
||||
{
|
||||
/* only release ep bw check passed by check_sch_bw() */
|
||||
if (sch_ep->allocated)
|
||||
update_bus_bw(sch_bw, sch_ep, 0);
|
||||
|
||||
list_del(&sch_ep->endpoint);
|
||||
|
||||
if (sch_ep->sch_tt) {
|
||||
list_del(&sch_ep->tt_endpoint);
|
||||
drop_tt(udev);
|
||||
}
|
||||
kfree(sch_ep);
|
||||
}
|
||||
|
||||
static bool need_bw_sch(struct usb_host_endpoint *ep,
|
||||
enum usb_device_speed speed, int has_tt)
|
||||
{
|
||||
|
@ -583,6 +602,8 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
|
|||
|
||||
mtk->sch_array = sch_array;
|
||||
|
||||
INIT_LIST_HEAD(&mtk->bw_ep_chk_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xhci_mtk_sch_init);
|
||||
|
@ -601,19 +622,14 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
|
|||
struct xhci_ep_ctx *ep_ctx;
|
||||
struct xhci_slot_ctx *slot_ctx;
|
||||
struct xhci_virt_device *virt_dev;
|
||||
struct mu3h_sch_bw_info *sch_bw;
|
||||
struct mu3h_sch_ep_info *sch_ep;
|
||||
struct mu3h_sch_bw_info *sch_array;
|
||||
unsigned int ep_index;
|
||||
int bw_index;
|
||||
int ret = 0;
|
||||
|
||||
xhci = hcd_to_xhci(hcd);
|
||||
virt_dev = xhci->devs[udev->slot_id];
|
||||
ep_index = xhci_get_endpoint_index(&ep->desc);
|
||||
slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
|
||||
ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
|
||||
sch_array = mtk->sch_array;
|
||||
|
||||
xhci_dbg(xhci, "%s() type:%d, speed:%d, mpkt:%d, dir:%d, ep:%p\n",
|
||||
__func__, usb_endpoint_type(&ep->desc), udev->speed,
|
||||
|
@ -632,35 +648,13 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
bw_index = get_bw_index(xhci, udev, ep);
|
||||
sch_bw = &sch_array[bw_index];
|
||||
|
||||
sch_ep = create_sch_ep(udev, ep, ep_ctx);
|
||||
if (IS_ERR_OR_NULL(sch_ep))
|
||||
return -ENOMEM;
|
||||
|
||||
setup_sch_info(udev, ep_ctx, sch_ep);
|
||||
|
||||
ret = check_sch_bw(udev, sch_bw, sch_ep);
|
||||
if (ret) {
|
||||
xhci_err(xhci, "Not enough bandwidth!\n");
|
||||
if (is_fs_or_ls(udev->speed))
|
||||
drop_tt(udev);
|
||||
|
||||
kfree(sch_ep);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
|
||||
|
||||
ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts)
|
||||
| EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode));
|
||||
ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset)
|
||||
| EP_BREPEAT(sch_ep->repeat));
|
||||
|
||||
xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n",
|
||||
sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode,
|
||||
sch_ep->offset, sch_ep->repeat);
|
||||
list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_chk_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -675,7 +669,7 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
|
|||
struct xhci_virt_device *virt_dev;
|
||||
struct mu3h_sch_bw_info *sch_array;
|
||||
struct mu3h_sch_bw_info *sch_bw;
|
||||
struct mu3h_sch_ep_info *sch_ep;
|
||||
struct mu3h_sch_ep_info *sch_ep, *tmp;
|
||||
int bw_index;
|
||||
|
||||
xhci = hcd_to_xhci(hcd);
|
||||
|
@ -694,17 +688,79 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
|
|||
bw_index = get_bw_index(xhci, udev, ep);
|
||||
sch_bw = &sch_array[bw_index];
|
||||
|
||||
list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) {
|
||||
list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) {
|
||||
if (sch_ep->ep == ep) {
|
||||
update_bus_bw(sch_bw, sch_ep, 0);
|
||||
list_del(&sch_ep->endpoint);
|
||||
if (is_fs_or_ls(udev->speed)) {
|
||||
list_del(&sch_ep->tt_endpoint);
|
||||
drop_tt(udev);
|
||||
}
|
||||
kfree(sch_ep);
|
||||
destroy_sch_ep(udev, sch_bw, sch_ep);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk);
|
||||
|
||||
int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
{
|
||||
struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id];
|
||||
struct mu3h_sch_bw_info *sch_bw;
|
||||
struct mu3h_sch_ep_info *sch_ep, *tmp;
|
||||
int bw_index, ret;
|
||||
|
||||
xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev));
|
||||
|
||||
list_for_each_entry(sch_ep, &mtk->bw_ep_chk_list, endpoint) {
|
||||
bw_index = get_bw_index(xhci, udev, sch_ep->ep);
|
||||
sch_bw = &mtk->sch_array[bw_index];
|
||||
|
||||
ret = check_sch_bw(udev, sch_bw, sch_ep);
|
||||
if (ret) {
|
||||
xhci_err(xhci, "Not enough bandwidth!\n");
|
||||
return -ENOSPC;
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) {
|
||||
struct xhci_ep_ctx *ep_ctx;
|
||||
struct usb_host_endpoint *ep = sch_ep->ep;
|
||||
unsigned int ep_index = xhci_get_endpoint_index(&ep->desc);
|
||||
|
||||
bw_index = get_bw_index(xhci, udev, ep);
|
||||
sch_bw = &mtk->sch_array[bw_index];
|
||||
|
||||
list_move_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
|
||||
|
||||
ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
|
||||
ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts)
|
||||
| EP_BCSCOUNT(sch_ep->cs_count)
|
||||
| EP_BBM(sch_ep->burst_mode));
|
||||
ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset)
|
||||
| EP_BREPEAT(sch_ep->repeat));
|
||||
|
||||
xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n",
|
||||
sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode,
|
||||
sch_ep->offset, sch_ep->repeat);
|
||||
}
|
||||
|
||||
return xhci_check_bandwidth(hcd, udev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xhci_mtk_check_bandwidth);
|
||||
|
||||
void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
{
|
||||
struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
struct mu3h_sch_bw_info *sch_bw;
|
||||
struct mu3h_sch_ep_info *sch_ep, *tmp;
|
||||
int bw_index;
|
||||
|
||||
xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev));
|
||||
|
||||
list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) {
|
||||
bw_index = get_bw_index(xhci, udev, sch_ep->ep);
|
||||
sch_bw = &mtk->sch_array[bw_index];
|
||||
destroy_sch_ep(udev, sch_bw, sch_ep);
|
||||
}
|
||||
|
||||
xhci_reset_bandwidth(hcd, udev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xhci_mtk_reset_bandwidth);
|
||||
|
|
|
@ -347,6 +347,8 @@ static void usb_wakeup_set(struct xhci_hcd_mtk *mtk, bool enable)
|
|||
static int xhci_mtk_setup(struct usb_hcd *hcd);
|
||||
static const struct xhci_driver_overrides xhci_mtk_overrides __initconst = {
|
||||
.reset = xhci_mtk_setup,
|
||||
.check_bandwidth = xhci_mtk_check_bandwidth,
|
||||
.reset_bandwidth = xhci_mtk_reset_bandwidth,
|
||||
};
|
||||
|
||||
static struct hc_driver __read_mostly xhci_mtk_hc_driver;
|
||||
|
|
|
@ -59,6 +59,7 @@ struct mu3h_sch_bw_info {
|
|||
* @ep_type: endpoint type
|
||||
* @maxpkt: max packet size of endpoint
|
||||
* @ep: address of usb_host_endpoint struct
|
||||
* @allocated: the bandwidth is aready allocated from bus_bw
|
||||
* @offset: which uframe of the interval that transfer should be
|
||||
* scheduled first time within the interval
|
||||
* @repeat: the time gap between two uframes that transfers are
|
||||
|
@ -86,6 +87,7 @@ struct mu3h_sch_ep_info {
|
|||
u32 ep_type;
|
||||
u32 maxpkt;
|
||||
void *ep;
|
||||
bool allocated;
|
||||
/*
|
||||
* mtk xHCI scheduling information put into reserved DWs
|
||||
* in ep context
|
||||
|
@ -131,6 +133,7 @@ struct xhci_hcd_mtk {
|
|||
struct device *dev;
|
||||
struct usb_hcd *hcd;
|
||||
struct mu3h_sch_bw_info *sch_array;
|
||||
struct list_head bw_ep_chk_list;
|
||||
struct mu3c_ippc_regs __iomem *ippc_regs;
|
||||
bool has_ippc;
|
||||
int num_u2_ports;
|
||||
|
@ -166,6 +169,8 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
|
|||
struct usb_host_endpoint *ep);
|
||||
void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep);
|
||||
int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
|
||||
void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
|
||||
|
||||
#else
|
||||
static inline int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd,
|
||||
|
@ -179,6 +184,16 @@ static inline void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd,
|
|||
{
|
||||
}
|
||||
|
||||
static inline int xhci_mtk_check_bandwidth(struct usb_hcd *hcd,
|
||||
struct usb_device *udev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd,
|
||||
struct usb_device *udev)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _XHCI_MTK_H_ */
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/mbus.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/phy/phy.h>
|
||||
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/hcd.h>
|
||||
|
@ -74,6 +75,47 @@ int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd)
|
||||
{
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
struct device *dev = hcd->self.controller;
|
||||
struct phy *phy;
|
||||
int ret;
|
||||
|
||||
/* Old bindings miss the PHY handle */
|
||||
phy = of_phy_get(dev->of_node, "usb3-phy");
|
||||
if (IS_ERR(phy) && PTR_ERR(phy) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
else if (IS_ERR(phy))
|
||||
goto phy_out;
|
||||
|
||||
ret = phy_init(phy);
|
||||
if (ret)
|
||||
goto phy_put;
|
||||
|
||||
ret = phy_set_mode(phy, PHY_MODE_USB_HOST_SS);
|
||||
if (ret)
|
||||
goto phy_exit;
|
||||
|
||||
ret = phy_power_on(phy);
|
||||
if (ret == -EOPNOTSUPP) {
|
||||
/* Skip initializatin of XHCI PHY when it is unsupported by firmware */
|
||||
dev_warn(dev, "PHY unsupported by firmware\n");
|
||||
xhci->quirks |= XHCI_SKIP_PHY_INIT;
|
||||
}
|
||||
if (ret)
|
||||
goto phy_exit;
|
||||
|
||||
phy_power_off(phy);
|
||||
phy_exit:
|
||||
phy_exit(phy);
|
||||
phy_put:
|
||||
of_phy_put(phy);
|
||||
phy_out:
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
|
||||
{
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
|
|
|
@ -12,6 +12,7 @@ struct usb_hcd;
|
|||
|
||||
#if IS_ENABLED(CONFIG_USB_XHCI_MVEBU)
|
||||
int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd);
|
||||
int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd);
|
||||
int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd);
|
||||
#else
|
||||
static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
|
||||
|
@ -19,6 +20,11 @@ static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -44,6 +44,16 @@ static void xhci_priv_plat_start(struct usb_hcd *hcd)
|
|||
priv->plat_start(hcd);
|
||||
}
|
||||
|
||||
static int xhci_priv_plat_setup(struct usb_hcd *hcd)
|
||||
{
|
||||
struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
|
||||
|
||||
if (!priv->plat_setup)
|
||||
return 0;
|
||||
|
||||
return priv->plat_setup(hcd);
|
||||
}
|
||||
|
||||
static int xhci_priv_init_quirk(struct usb_hcd *hcd)
|
||||
{
|
||||
struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
|
||||
|
@ -111,6 +121,7 @@ static const struct xhci_plat_priv xhci_plat_marvell_armada = {
|
|||
};
|
||||
|
||||
static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = {
|
||||
.plat_setup = xhci_mvebu_a3700_plat_setup,
|
||||
.init_quirk = xhci_mvebu_a3700_init_quirk,
|
||||
};
|
||||
|
||||
|
@ -330,7 +341,14 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
|||
|
||||
hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node);
|
||||
xhci->shared_hcd->tpl_support = hcd->tpl_support;
|
||||
if (priv && (priv->quirks & XHCI_SKIP_PHY_INIT))
|
||||
|
||||
if (priv) {
|
||||
ret = xhci_priv_plat_setup(hcd);
|
||||
if (ret)
|
||||
goto disable_usb_phy;
|
||||
}
|
||||
|
||||
if ((xhci->quirks & XHCI_SKIP_PHY_INIT) || (priv && (priv->quirks & XHCI_SKIP_PHY_INIT)))
|
||||
hcd->skip_phy_initialization = 1;
|
||||
|
||||
if (priv && (priv->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK))
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
struct xhci_plat_priv {
|
||||
const char *firmware_name;
|
||||
unsigned long long quirks;
|
||||
int (*plat_setup)(struct usb_hcd *);
|
||||
void (*plat_start)(struct usb_hcd *);
|
||||
int (*init_quirk)(struct usb_hcd *);
|
||||
int (*suspend_quirk)(struct usb_hcd *);
|
||||
|
|
|
@ -699,11 +699,16 @@ static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci,
|
|||
dma_unmap_single(dev, seg->bounce_dma, ring->bounce_buf_len,
|
||||
DMA_FROM_DEVICE);
|
||||
/* for in tranfers we need to copy the data from bounce to sg */
|
||||
len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, seg->bounce_buf,
|
||||
seg->bounce_len, seg->bounce_offs);
|
||||
if (len != seg->bounce_len)
|
||||
xhci_warn(xhci, "WARN Wrong bounce buffer read length: %zu != %d\n",
|
||||
len, seg->bounce_len);
|
||||
if (urb->num_sgs) {
|
||||
len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, seg->bounce_buf,
|
||||
seg->bounce_len, seg->bounce_offs);
|
||||
if (len != seg->bounce_len)
|
||||
xhci_warn(xhci, "WARN Wrong bounce buffer read length: %zu != %d\n",
|
||||
len, seg->bounce_len);
|
||||
} else {
|
||||
memcpy(urb->transfer_buffer + seg->bounce_offs, seg->bounce_buf,
|
||||
seg->bounce_len);
|
||||
}
|
||||
seg->bounce_len = 0;
|
||||
seg->bounce_offs = 0;
|
||||
}
|
||||
|
@ -3277,12 +3282,16 @@ static int xhci_align_td(struct xhci_hcd *xhci, struct urb *urb, u32 enqd_len,
|
|||
|
||||
/* create a max max_pkt sized bounce buffer pointed to by last trb */
|
||||
if (usb_urb_dir_out(urb)) {
|
||||
len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs,
|
||||
seg->bounce_buf, new_buff_len, enqd_len);
|
||||
if (len != new_buff_len)
|
||||
xhci_warn(xhci,
|
||||
"WARN Wrong bounce buffer write length: %zu != %d\n",
|
||||
len, new_buff_len);
|
||||
if (urb->num_sgs) {
|
||||
len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs,
|
||||
seg->bounce_buf, new_buff_len, enqd_len);
|
||||
if (len != new_buff_len)
|
||||
xhci_warn(xhci, "WARN Wrong bounce buffer write length: %zu != %d\n",
|
||||
len, new_buff_len);
|
||||
} else {
|
||||
memcpy(seg->bounce_buf, urb->transfer_buffer + enqd_len, new_buff_len);
|
||||
}
|
||||
|
||||
seg->bounce_dma = dma_map_single(dev, seg->bounce_buf,
|
||||
max_pkt, DMA_TO_DEVICE);
|
||||
} else {
|
||||
|
|
|
@ -2985,7 +2985,7 @@ static void xhci_check_bw_drop_ep_streams(struct xhci_hcd *xhci,
|
|||
* else should be touching the xhci->devs[slot_id] structure, so we
|
||||
* don't need to take the xhci->lock for manipulating that.
|
||||
*/
|
||||
static int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
@ -3083,7 +3083,7 @@ command_cleanup:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
{
|
||||
struct xhci_hcd *xhci;
|
||||
struct xhci_virt_device *virt_dev;
|
||||
|
@ -5510,6 +5510,10 @@ void xhci_init_driver(struct hc_driver *drv,
|
|||
drv->reset = over->reset;
|
||||
if (over->start)
|
||||
drv->start = over->start;
|
||||
if (over->check_bandwidth)
|
||||
drv->check_bandwidth = over->check_bandwidth;
|
||||
if (over->reset_bandwidth)
|
||||
drv->reset_bandwidth = over->reset_bandwidth;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xhci_init_driver);
|
||||
|
|
|
@ -1920,6 +1920,8 @@ struct xhci_driver_overrides {
|
|||
size_t extra_priv_size;
|
||||
int (*reset)(struct usb_hcd *hcd);
|
||||
int (*start)(struct usb_hcd *hcd);
|
||||
int (*check_bandwidth)(struct usb_hcd *, struct usb_device *);
|
||||
void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *);
|
||||
};
|
||||
|
||||
#define XHCI_CFC_DELAY 10
|
||||
|
@ -2074,6 +2076,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks);
|
|||
void xhci_shutdown(struct usb_hcd *hcd);
|
||||
void xhci_init_driver(struct hc_driver *drv,
|
||||
const struct xhci_driver_overrides *over);
|
||||
int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
|
||||
void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
|
||||
int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
|
||||
int xhci_ext_cap_init(struct xhci_hcd *xhci);
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt)
|
|||
}
|
||||
|
||||
usbhs_pipe_clear_without_sequence(pipe, 0, 0);
|
||||
usbhs_pipe_running(pipe, 0);
|
||||
|
||||
__usbhsf_pkt_del(pkt);
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ static const struct usb_device_id id_table[] = {
|
|||
{ USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */
|
||||
{ USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */
|
||||
{ USB_DEVICE(0x0908, 0x01FF) }, /* Siemens RUGGEDCOM USB Serial Console */
|
||||
{ USB_DEVICE(0x0988, 0x0578) }, /* Teraoka AD2000 */
|
||||
{ USB_DEVICE(0x0B00, 0x3070) }, /* Ingenico 3070 */
|
||||
{ USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher Acceptor */
|
||||
{ USB_DEVICE(0x0BED, 0x1101) }, /* MEI series 2000 Combo Acceptor */
|
||||
|
@ -201,6 +202,7 @@ static const struct usb_device_id id_table[] = {
|
|||
{ USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */
|
||||
{ USB_DEVICE(0x1901, 0x0195) }, /* GE B850/B650/B450 CP2104 DP UART interface */
|
||||
{ USB_DEVICE(0x1901, 0x0196) }, /* GE B850 CP2105 DP UART interface */
|
||||
{ USB_DEVICE(0x199B, 0xBA30) }, /* LORD WSDA-200-USB */
|
||||
{ USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
|
||||
{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
|
||||
{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
|
||||
|
|
|
@ -425,6 +425,8 @@ static void option_instat_callback(struct urb *urb);
|
|||
#define CINTERION_PRODUCT_AHXX_2RMNET 0x0084
|
||||
#define CINTERION_PRODUCT_AHXX_AUDIO 0x0085
|
||||
#define CINTERION_PRODUCT_CLS8 0x00b0
|
||||
#define CINTERION_PRODUCT_MV31_MBIM 0x00b3
|
||||
#define CINTERION_PRODUCT_MV31_RMNET 0x00b7
|
||||
|
||||
/* Olivetti products */
|
||||
#define OLIVETTI_VENDOR_ID 0x0b3c
|
||||
|
@ -1914,6 +1916,10 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) },
|
||||
{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 enumerates with Siemens or Cinterion VID depending on FW revision */
|
||||
{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_MBIM, 0xff),
|
||||
.driver_info = RSVD(3)},
|
||||
{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_RMNET, 0xff),
|
||||
.driver_info = RSVD(0)},
|
||||
{ USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100),
|
||||
.driver_info = RSVD(4) },
|
||||
{ USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120),
|
||||
|
|
Загрузка…
Ссылка в новой задаче