From 97ef0faf575e03b352553f92c9430cb4c0431436 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Thu, 8 Mar 2018 17:17:14 +0200 Subject: xhci: fix endpoint context tracer output Fix incorrent values showed for max Primary stream and Linear stream array (LSA) values in the endpoint context decoder. Fixes: 19a7d0d65c4a ("usb: host: xhci: add Slot and EP Context tracers") Cc: # v4.12+ Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e4d7d3d..d20e57b 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -718,11 +718,12 @@ struct xhci_ep_ctx { /* bits 10:14 are Max Primary Streams */ /* bit 15 is Linear Stream Array */ /* Interval - period between requests to an endpoint - 125u increments. */ -#define EP_INTERVAL(p) (((p) & 0xff) << 16) -#define EP_INTERVAL_TO_UFRAMES(p) (1 << (((p) >> 16) & 0xff)) -#define CTX_TO_EP_INTERVAL(p) (((p) >> 16) & 0xff) -#define EP_MAXPSTREAMS_MASK (0x1f << 10) -#define EP_MAXPSTREAMS(p) (((p) << 10) & EP_MAXPSTREAMS_MASK) +#define EP_INTERVAL(p) (((p) & 0xff) << 16) +#define EP_INTERVAL_TO_UFRAMES(p) (1 << (((p) >> 16) & 0xff)) +#define CTX_TO_EP_INTERVAL(p) (((p) >> 16) & 0xff) +#define EP_MAXPSTREAMS_MASK (0x1f << 10) +#define EP_MAXPSTREAMS(p) (((p) << 10) & EP_MAXPSTREAMS_MASK) +#define CTX_TO_EP_MAXPSTREAMS(p) (((p) & EP_MAXPSTREAMS_MASK) >> 10) /* Endpoint is set up with a Linear Stream Array (vs. Secondary Stream Array) */ #define EP_HAS_LSA (1 << 15) /* hosts with LEC=1 use bits 31:24 as ESIT high bits. */ @@ -2549,21 +2550,22 @@ static inline const char *xhci_decode_ep_context(u32 info, u32 info2, u64 deq, u8 burst; u8 cerr; u8 mult; - u8 lsa; - u8 hid; + + bool lsa; + bool hid; esit = CTX_TO_MAX_ESIT_PAYLOAD_HI(info) << 16 | CTX_TO_MAX_ESIT_PAYLOAD(tx_info); ep_state = info & EP_STATE_MASK; - max_pstr = info & EP_MAXPSTREAMS_MASK; + max_pstr = CTX_TO_EP_MAXPSTREAMS(info); interval = CTX_TO_EP_INTERVAL(info); mult = CTX_TO_EP_MULT(info) + 1; - lsa = info & EP_HAS_LSA; + lsa = !!(info & EP_HAS_LSA); cerr = (info2 & (3 << 1)) >> 1; ep_type = CTX_TO_EP_TYPE(info2); - hid = info2 & (1 << 7); + hid = !!(info2 & (1 << 7)); burst = CTX_TO_MAX_BURST(info2); maxp = MAX_PACKET_DECODED(info2); -- cgit v1.1 From a098dc8b03d1c7284ed98d921224fffa15b13ece Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Thu, 8 Mar 2018 17:17:15 +0200 Subject: usb: xhci: dbc: Fix lockdep warning The xHCI DbC implementation might enter a deadlock situation because there is no sufficient protection against the shared data between process and softirq contexts. This can lead to the following lockdep warnings. This patch changes to use spin_{,un}lock_irq{save,restore} to avoid potential deadlock. [ 528.248084] ================================ [ 528.252914] WARNING: inconsistent lock state [ 528.257756] 4.15.0-rc1+ #1630 Not tainted [ 528.262305] -------------------------------- [ 528.267145] inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. [ 528.273953] ksoftirqd/1/17 [HC0[0]:SC1[1]:HE0:SE0] takes: [ 528.280075] (&(&port->port_lock)->rlock){+.?.}, at: [] dbc_rx_push+0x38/0x1c0 [ 528.290043] {SOFTIRQ-ON-W} state was registered at: [ 528.295570] _raw_spin_lock+0x2f/0x40 [ 528.299818] dbc_write_complete+0x27/0xa0 [ 528.304458] xhci_dbc_giveback+0xd1/0x200 [ 528.309098] xhci_dbc_flush_endpoint_requests+0x50/0x70 [ 528.315116] xhci_dbc_handle_events+0x696/0x7b0 [ 528.320349] process_one_work+0x1ee/0x6e0 [ 528.324988] worker_thread+0x4a/0x430 [ 528.329236] kthread+0x13e/0x170 [ 528.332992] ret_from_fork+0x24/0x30 [ 528.337141] irq event stamp: 2861 [ 528.340897] hardirqs last enabled at (2860): [] tasklet_action+0x6a/0x250 [ 528.350460] hardirqs last disabled at (2861): [] _raw_spin_lock_irq+0xf/0x40 [ 528.360219] softirqs last enabled at (2852): [] __do_softirq+0x3dc/0x4f9 [ 528.369683] softirqs last disabled at (2857): [] run_ksoftirqd+0x1b/0x60 [ 528.379048] [ 528.379048] other info that might help us debug this: [ 528.386443] Possible unsafe locking scenario: [ 528.386443] [ 528.393150] CPU0 [ 528.395917] ---- [ 528.398687] lock(&(&port->port_lock)->rlock); [ 528.403821] [ 528.406786] lock(&(&port->port_lock)->rlock); [ 528.412116] [ 528.412116] *** DEADLOCK *** [ 528.412116] [ 528.418825] no locks held by ksoftirqd/1/17. [ 528.423662] [ 528.423662] stack backtrace: [ 528.428598] CPU: 1 PID: 17 Comm: ksoftirqd/1 Not tainted 4.15.0-rc1+ #1630 [ 528.436387] Call Trace: [ 528.439158] dump_stack+0x5e/0x8e [ 528.442914] print_usage_bug+0x1fc/0x220 [ 528.447357] mark_lock+0x4db/0x5a0 [ 528.451210] __lock_acquire+0x726/0x1130 [ 528.455655] ? __lock_acquire+0x557/0x1130 [ 528.460296] lock_acquire+0xa2/0x200 [ 528.464347] ? dbc_rx_push+0x38/0x1c0 [ 528.468496] _raw_spin_lock_irq+0x35/0x40 [ 528.473038] ? dbc_rx_push+0x38/0x1c0 [ 528.477186] dbc_rx_push+0x38/0x1c0 [ 528.481139] tasklet_action+0x1d2/0x250 [ 528.485483] __do_softirq+0x1dc/0x4f9 [ 528.489630] run_ksoftirqd+0x1b/0x60 [ 528.493682] smpboot_thread_fn+0x179/0x270 [ 528.498324] kthread+0x13e/0x170 [ 528.501981] ? sort_range+0x20/0x20 [ 528.505933] ? kthread_delayed_work_timer_fn+0x80/0x80 [ 528.511755] ret_from_fork+0x24/0x30 Fixes: dfba2174dc42 ("usb: xhci: Add DbC support in xHCI driver") Signed-off-by: Lu Baolu Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-dbgcap.c | 20 ++++++++++++-------- drivers/usb/host/xhci-dbgtty.c | 20 ++++++++++++-------- 2 files changed, 24 insertions(+), 16 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c index a1ab8ac..c359bae 100644 --- a/drivers/usb/host/xhci-dbgcap.c +++ b/drivers/usb/host/xhci-dbgcap.c @@ -328,13 +328,14 @@ dbc_ep_do_queue(struct dbc_ep *dep, struct dbc_request *req) int dbc_ep_queue(struct dbc_ep *dep, struct dbc_request *req, gfp_t gfp_flags) { + unsigned long flags; struct xhci_dbc *dbc = dep->dbc; int ret = -ESHUTDOWN; - spin_lock(&dbc->lock); + spin_lock_irqsave(&dbc->lock, flags); if (dbc->state == DS_CONFIGURED) ret = dbc_ep_do_queue(dep, req); - spin_unlock(&dbc->lock); + spin_unlock_irqrestore(&dbc->lock, flags); mod_delayed_work(system_wq, &dbc->event_work, 0); @@ -521,15 +522,16 @@ static void xhci_do_dbc_stop(struct xhci_hcd *xhci) static int xhci_dbc_start(struct xhci_hcd *xhci) { int ret; + unsigned long flags; struct xhci_dbc *dbc = xhci->dbc; WARN_ON(!dbc); pm_runtime_get_sync(xhci_to_hcd(xhci)->self.controller); - spin_lock(&dbc->lock); + spin_lock_irqsave(&dbc->lock, flags); ret = xhci_do_dbc_start(xhci); - spin_unlock(&dbc->lock); + spin_unlock_irqrestore(&dbc->lock, flags); if (ret) { pm_runtime_put(xhci_to_hcd(xhci)->self.controller); @@ -541,6 +543,7 @@ static int xhci_dbc_start(struct xhci_hcd *xhci) static void xhci_dbc_stop(struct xhci_hcd *xhci) { + unsigned long flags; struct xhci_dbc *dbc = xhci->dbc; struct dbc_port *port = &dbc->port; @@ -551,9 +554,9 @@ static void xhci_dbc_stop(struct xhci_hcd *xhci) if (port->registered) xhci_dbc_tty_unregister_device(xhci); - spin_lock(&dbc->lock); + spin_lock_irqsave(&dbc->lock, flags); xhci_do_dbc_stop(xhci); - spin_unlock(&dbc->lock); + spin_unlock_irqrestore(&dbc->lock, flags); pm_runtime_put_sync(xhci_to_hcd(xhci)->self.controller); } @@ -779,14 +782,15 @@ static void xhci_dbc_handle_events(struct work_struct *work) int ret; enum evtreturn evtr; struct xhci_dbc *dbc; + unsigned long flags; struct xhci_hcd *xhci; dbc = container_of(to_delayed_work(work), struct xhci_dbc, event_work); xhci = dbc->xhci; - spin_lock(&dbc->lock); + spin_lock_irqsave(&dbc->lock, flags); evtr = xhci_dbc_do_handle_events(dbc); - spin_unlock(&dbc->lock); + spin_unlock_irqrestore(&dbc->lock, flags); switch (evtr) { case EVT_GSER: diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index 8d47b6f..75f0b92 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -92,21 +92,23 @@ static void dbc_start_rx(struct dbc_port *port) static void dbc_read_complete(struct xhci_hcd *xhci, struct dbc_request *req) { + unsigned long flags; struct xhci_dbc *dbc = xhci->dbc; struct dbc_port *port = &dbc->port; - spin_lock(&port->port_lock); + spin_lock_irqsave(&port->port_lock, flags); list_add_tail(&req->list_pool, &port->read_queue); tasklet_schedule(&port->push); - spin_unlock(&port->port_lock); + spin_unlock_irqrestore(&port->port_lock, flags); } static void dbc_write_complete(struct xhci_hcd *xhci, struct dbc_request *req) { + unsigned long flags; struct xhci_dbc *dbc = xhci->dbc; struct dbc_port *port = &dbc->port; - spin_lock(&port->port_lock); + spin_lock_irqsave(&port->port_lock, flags); list_add(&req->list_pool, &port->write_pool); switch (req->status) { case 0: @@ -119,7 +121,7 @@ static void dbc_write_complete(struct xhci_hcd *xhci, struct dbc_request *req) req->status); break; } - spin_unlock(&port->port_lock); + spin_unlock_irqrestore(&port->port_lock, flags); } static void xhci_dbc_free_req(struct dbc_ep *dep, struct dbc_request *req) @@ -327,12 +329,13 @@ static void dbc_rx_push(unsigned long _port) { struct dbc_request *req; struct tty_struct *tty; + unsigned long flags; bool do_push = false; bool disconnect = false; struct dbc_port *port = (void *)_port; struct list_head *queue = &port->read_queue; - spin_lock_irq(&port->port_lock); + spin_lock_irqsave(&port->port_lock, flags); tty = port->port.tty; while (!list_empty(queue)) { req = list_first_entry(queue, struct dbc_request, list_pool); @@ -392,16 +395,17 @@ static void dbc_rx_push(unsigned long _port) if (!disconnect) dbc_start_rx(port); - spin_unlock_irq(&port->port_lock); + spin_unlock_irqrestore(&port->port_lock, flags); } static int dbc_port_activate(struct tty_port *_port, struct tty_struct *tty) { + unsigned long flags; struct dbc_port *port = container_of(_port, struct dbc_port, port); - spin_lock_irq(&port->port_lock); + spin_lock_irqsave(&port->port_lock, flags); dbc_start_rx(port); - spin_unlock_irq(&port->port_lock); + spin_unlock_irqrestore(&port->port_lock, flags); return 0; } -- cgit v1.1 From 015dbeb2282030bf56762e21d25f09422edfd750 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 27 Feb 2018 17:15:20 +0900 Subject: usb: host: xhci-rcar: add support for r8a77965 This patch adds support for r8a77965 (R-Car M3-N). Signed-off-by: Yoshihiro Shimoda Reviewed-by: Simon Horman Reviewed-by: Rob Herring Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-rcar.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index f0b5596..f33ffc2 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -83,6 +83,10 @@ static const struct soc_device_attribute rcar_quirks_match[] = { .soc_id = "r8a7796", .data = (void *)RCAR_XHCI_FIRMWARE_V3, }, + { + .soc_id = "r8a77965", + .data = (void *)RCAR_XHCI_FIRMWARE_V3, + }, { /* sentinel */ }, }; -- cgit v1.1 From d56e57ca030c8b4296944a2ae61ac167bf979c07 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 8 Mar 2018 17:17:16 +0200 Subject: usb: host: xhci-plat: revert "usb: host: xhci-plat: enable clk in resume timing" This patch reverts the commit 835e4241e714 ("usb: host: xhci-plat: enable clk in resume timing") because this driver also has runtime PM and the commit 560869100b99 ("clk: renesas: cpg-mssr: Restore module clocks during resume") will restore the clock on R-Car H3 environment. If the xhci_plat_suspend() disables the clk, the system cannot enable the clk in resume like the following behavior: < In resume > - genpd_resume_noirq() runs and enable the clk (enable_count = 1) - cpg_mssr_resume_noirq() restores the clk register. -- Since the clk was disabled in suspend, cpg_mssr_resume_noirq() will disable the clk and keep the enable_count. - Even if xhci_plat_resume() calls clk_prepare_enable(), since the enable_count is 1, the clk will be not enabled. After this patch is applied, the cpg-mssr driver will save the clk as enable, so the clk will be enabled in resume. Fixes: 835e4241e714 ("usb: host: xhci-plat: enable clk in resume timing") Signed-off-by: Yoshihiro Shimoda Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-plat.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 6f03830..6652e2d 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -360,7 +360,6 @@ static int __maybe_unused xhci_plat_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); - int ret; /* * xhci_suspend() needs `do_wakeup` to know whether host is allowed @@ -370,12 +369,7 @@ static int __maybe_unused xhci_plat_suspend(struct device *dev) * reconsider this when xhci_plat_suspend enlarges its scope, e.g., * also applies to runtime suspend. */ - ret = xhci_suspend(xhci, device_may_wakeup(dev)); - - if (!device_may_wakeup(dev) && !IS_ERR(xhci->clk)) - clk_disable_unprepare(xhci->clk); - - return ret; + return xhci_suspend(xhci, device_may_wakeup(dev)); } static int __maybe_unused xhci_plat_resume(struct device *dev) @@ -384,9 +378,6 @@ static int __maybe_unused xhci_plat_resume(struct device *dev) struct xhci_hcd *xhci = hcd_to_xhci(hcd); int ret; - if (!device_may_wakeup(dev) && !IS_ERR(xhci->clk)) - clk_prepare_enable(xhci->clk); - ret = xhci_priv_resume_quirk(hcd); if (ret) return ret; -- cgit v1.1 From 191edc5e2e515aab1075a3f0ef23599e80be5f59 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Thu, 8 Mar 2018 17:17:17 +0200 Subject: xhci: Fix front USB ports on ASUS PRIME B350M-A When a USB device gets plugged on ASUS PRIME B350M-A's front ports, the xHC stops working: [ 549.114587] xhci_hcd 0000:02:00.0: WARN: xHC CMD_RUN timeout [ 549.114608] suspend_common(): xhci_pci_suspend+0x0/0xc0 returns -110 [ 549.114638] xhci_hcd 0000:02:00.0: can't suspend (hcd_pci_runtime_suspend returned -110) Delay before running xHC command CMD_RUN can workaround the issue. Use a new quirk to make the delay only targets to the affected xHC. Signed-off-by: Kai-Heng Feng Signed-off-by: Mathias Nyman Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 3 +++ drivers/usb/host/xhci.c | 3 +++ drivers/usb/host/xhci.h | 1 + 3 files changed, 7 insertions(+) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 5262fa5..d9f831b 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -126,6 +126,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) xhci->quirks |= XHCI_AMD_PLL_FIX; + if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x43bb) + xhci->quirks |= XHCI_SUSPEND_DELAY; + if (pdev->vendor == PCI_VENDOR_ID_AMD) xhci->quirks |= XHCI_TRUST_TX_LENGTH; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 25d4b748..5d37700 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -877,6 +877,9 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); del_timer_sync(&xhci->shared_hcd->rh_timer); + if (xhci->quirks & XHCI_SUSPEND_DELAY) + usleep_range(1000, 1500); + spin_lock_irq(&xhci->lock); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index d20e57b..866e141 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1826,6 +1826,7 @@ struct xhci_hcd { #define XHCI_U2_DISABLE_WAKE (1 << 27) #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28) #define XHCI_HW_LPM_DISABLE (1 << 29) +#define XHCI_SUSPEND_DELAY (1 << 30) unsigned int num_active_eps; unsigned int limit_active_eps; -- cgit v1.1 From d6c931ea32dc08ac2665bb5f009f9c40ad1bbdb3 Mon Sep 17 00:00:00 2001 From: Fredrik Noring Date: Fri, 9 Mar 2018 18:34:34 +0100 Subject: USB: OHCI: Fix NULL dereference in HCDs using HCD_LOCAL_MEM Scatter-gather needs to be disabled when using dma_declare_coherent_memory and HCD_LOCAL_MEM. Andrea Righi made the equivalent fix for EHCI drivers in commit 4307a28eb01284 "USB: EHCI: fix NULL pointer dererence in HCDs that use HCD_LOCAL_MEM". The following NULL pointer WARN_ON_ONCE triggered with OHCI drivers: ------------[ cut here ]------------ WARNING: CPU: 0 PID: 49 at drivers/usb/core/hcd.c:1379 hcd_alloc_coherent+0x4c/0xc8 Modules linked in: CPU: 0 PID: 49 Comm: usb-storage Not tainted 4.15.0+ #1014 Stack : 00000000 00000000 805a78d2 0000003a 81f5c2cc 8053d367 804d77fc 00000031 805a3a08 00000563 81ee9400 805a0000 00000000 10058c00 81f61b10 805c0000 00000000 00000000 805a0000 00d9038e 00000004 803ee818 00000006 312e3420 805c0000 00000000 00000073 81f61958 00000000 00000000 802eb380 804fd538 00000009 00000563 81ee9400 805a0000 00000002 80056148 00000000 805a0000 ... Call Trace: [<578af360>] show_stack+0x74/0x104 [<2f3702c6>] __warn+0x118/0x120 [] warn_slowpath_null+0x44/0x58 [] hcd_alloc_coherent+0x4c/0xc8 [<3578fa36>] usb_hcd_map_urb_for_dma+0x4d8/0x534 [<110bc94c>] usb_hcd_submit_urb+0x82c/0x834 [<02eb5baf>] usb_sg_wait+0x14c/0x1a0 [] usb_stor_bulk_transfer_sglist.part.1+0xac/0x124 [<87a5c34c>] usb_stor_bulk_srb+0x40/0x60 [] usb_stor_Bulk_transport+0x160/0x37c [] usb_stor_invoke_transport+0x3c/0x500 [<004754f4>] usb_stor_control_thread+0x258/0x28c [<22edf42e>] kthread+0x134/0x13c [] ret_from_kernel_thread+0x14/0x1c ---[ end trace bcdb825805eefdcc ]--- Signed-off-by: Fredrik Noring Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hcd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/usb/host') diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 84f88fa..d088c34 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -447,7 +447,8 @@ static int ohci_init (struct ohci_hcd *ohci) struct usb_hcd *hcd = ohci_to_hcd(ohci); /* Accept arbitrarily long scatter-gather lists */ - hcd->self.sg_tablesize = ~0; + if (!(hcd->driver->flags & HCD_LOCAL_MEM)) + hcd->self.sg_tablesize = ~0; if (distrust_firmware) ohci->flags |= OHCI_QUIRK_HUB_POWER; -- cgit v1.1