dde_linux: delete orphaned files

Fix genodelabs/genode#4998
This commit is contained in:
Stefan Kalkowski 2023-09-14 11:22:29 +02:00 committed by Christian Helmuth
parent cfab4e74a9
commit 17a140db3d
18 changed files with 0 additions and 1299 deletions

View File

@ -1,34 +0,0 @@
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 74664a6..38cc18a 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -944,7 +944,10 @@ EXPORT_SYMBOL(phy_attached_print);
int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
u32 flags, phy_interface_t interface)
{
+#if 0
+ /* 'driver' has not been set yet on Genode */
struct module *ndev_owner = dev->dev.parent->driver->owner;
+#endif
struct mii_bus *bus = phydev->mdio.bus;
struct device *d = &phydev->mdio.dev;
bool using_genphy = false;
@@ -955,7 +958,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
* our own module->refcnt here, otherwise we would not be able to
* unload later on.
*/
- if (ndev_owner != bus->owner && !try_module_get(bus->owner)) {
+ if (/*ndev_owner != bus->owner &&*/ !try_module_get(bus->owner)) {
dev_err(&dev->dev, "failed to get the bus module\n");
return -EIO;
}
@@ -1060,7 +1063,9 @@ error_module_put:
module_put(d->driver->owner);
error_put_device:
put_device(d);
+#if 0
if (ndev_owner != bus->owner)
+#endif
module_put(bus->owner);
return err;
}

View File

@ -1,13 +0,0 @@
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 9147f9f..c63ee5c 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -3281,7 +3281,7 @@ static inline void skb_remcsum_process(struct sk_buff *skb, void *ptr,
if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) {
__skb_checksum_complete(skb);
- skb_postpull_rcsum(skb, skb->data, ptr - (void *)skb->data);
+ skb_postpull_rcsum(skb, skb->data, (unsigned char*)ptr - skb->data);
}
delta = remcsum_adjust(ptr, skb->csum, start, offset);

View File

@ -1,13 +0,0 @@
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index d4604bc..3f72629 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2798,7 +2798,7 @@ fec_enet_alloc_txq_buffers(struct net_device *ndev, unsigned int queue)
txq = fep->tx_queue[queue];
bdp = txq->bd.base;
for (i = 0; i < txq->bd.ring_size; i++) {
- txq->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
+ txq->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL | GFP_LX_DMA);
if (!txq->tx_bounce[i])
goto err_alloc;

View File

@ -1,43 +0,0 @@
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 3f72629..2b54f2b 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -428,7 +428,7 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
{
struct fec_enet_private *fep = netdev_priv(ndev);
int nr_frags = skb_shinfo(skb)->nr_frags;
- struct bufdesc *bdp, *last_bdp;
+ struct bufdesc *bdp, *last_bdp, *dummy_bdp;
void *bufaddr;
dma_addr_t addr;
unsigned short status;
@@ -532,6 +532,7 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
*/
status |= (BD_ENET_TX_READY | BD_ENET_TX_TC);
bdp->cbd_sc = cpu_to_fec16(status);
+ dummy_bdp = bdp;
/* If this was the last BD in the ring, start at the beginning again. */
bdp = fec_enet_get_nextdesc(last_bdp, &txq->bd);
@@ -542,6 +543,21 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
* txq->bd.cur.
*/
wmb();
+
+ /*
+ * Unfortunately, our current implementation of 'wmb()' doesn't seem
+ * to do what we want it to do. On base-hw + imx6q_sabrelite, the
+ * write of bdp->cbd_sc seems to get re-ordered after the write to
+ * txq->bd.reg_desc_active and, therefore, the transmission of the packet
+ * would only be triggered the next time we reach this point,
+ * i.e. when the next packet is sent. However, we only quick-fix it by
+ * enforcing the write with this volatile global read as we will
+ * soon update the FEC NIC port with a new DDE approach anyway
+ * (See Genode Github issue #4010).
+ */
+ static unsigned long volatile dummy_cbd_sc;
+ dummy_cbd_sc = *(unsigned long volatile *)&dummy_bdp->cbd_sc;
+
txq->bd.cur = bdp;
/* Trigger transmission start */

View File

@ -1,10 +0,0 @@
+++ src/linux/drivers/gpu/drm/i915/i915_pci.c
@@ -954,7 +954,7 @@
XE_LPD_FEATURES,
PLATFORM(INTEL_ALDERLAKE_P),
.has_cdclk_crawl = 1,
- .require_force_probe = 1,
+ .require_force_probe = 0,
.display.has_modular_fia = 1,
.platform_engine_mask =
BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0) | BIT(VCS2),

View File

@ -1,66 +0,0 @@
From 52a9dab6d892763b2a8334a568bd4e2c1a6fde66 Mon Sep 17 00:00:00 2001
From: Kees Cook <keescook@chromium.org>
Date: Sun, 13 Feb 2022 10:24:43 -0800
Subject: [PATCH] libsubcmd: Fix use-after-free for realloc(..., 0)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
GCC 12 correctly reports a potential use-after-free condition in the
xrealloc helper. Fix the warning by avoiding an implicit "free(ptr)"
when size == 0:
In file included from help.c:12:
In function 'xrealloc',
inlined from 'add_cmdname' at help.c:24:2: subcmd-util.h:56:23: error: pointer may be used after 'realloc' [-Werror=use-after-free]
56 | ret = realloc(ptr, size);
| ^~~~~~~~~~~~~~~~~~
subcmd-util.h:52:21: note: call to 'realloc' here
52 | void *ret = realloc(ptr, size);
| ^~~~~~~~~~~~~~~~~~
subcmd-util.h:58:31: error: pointer may be used after 'realloc' [-Werror=use-after-free]
58 | ret = realloc(ptr, 1);
| ^~~~~~~~~~~~~~~
subcmd-util.h:52:21: note: call to 'realloc' here
52 | void *ret = realloc(ptr, size);
| ^~~~~~~~~~~~~~~~~~
Fixes: 2f4ce5ec1d447beb ("perf tools: Finalize subcmd independence")
Reported-by: Valdis Klētnieks <valdis.kletnieks@vt.edu>
Signed-off-by: Kees Kook <keescook@chromium.org>
Tested-by: Valdis Klētnieks <valdis.kletnieks@vt.edu>
Tested-by: Justin M. Forbes <jforbes@fedoraproject.org>
Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: linux-hardening@vger.kernel.org
Cc: Valdis Klētnieks <valdis.kletnieks@vt.edu>
Link: http://lore.kernel.org/lkml/20220213182443.4037039-1-keescook@chromium.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/lib/subcmd/subcmd-util.h | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/tools/lib/subcmd/subcmd-util.h b/tools/lib/subcmd/subcmd-util.h
index 794a375dad36..b2aec04fce8f 100644
--- src/linux/tools/lib/subcmd/subcmd-util.h
+++ src/linux/tools/lib/subcmd/subcmd-util.h
@@ -50,15 +50,8 @@ static NORETURN inline void die(const char *err, ...)
static inline void *xrealloc(void *ptr, size_t size)
{
void *ret = realloc(ptr, size);
- if (!ret && !size)
- ret = realloc(ptr, 1);
- if (!ret) {
- ret = realloc(ptr, size);
- if (!ret && !size)
- ret = realloc(ptr, 1);
- if (!ret)
- die("Out of memory, realloc failed");
- }
+ if (!ret)
+ die("Out of memory, realloc failed");
return ret;
}
--
2.39.0

View File

@ -1,14 +0,0 @@
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 5bd400f..044c17c 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -841,7 +841,8 @@ int usb_hub_clear_tt_buffer(struct urb *urb)
clear->tt = tt->multi ? udev->ttport : 1;
clear->devinfo = usb_pipeendpoint (pipe);
clear->devinfo |= udev->devnum << 4;
- clear->devinfo |= usb_pipecontrol(pipe)
+ /* usb_pipeint(pipe) is only relevant for the 'dwc_otg' driver */
+ clear->devinfo |= (usb_pipecontrol(pipe) || usb_pipeint(pipe))
? (USB_ENDPOINT_XFER_CONTROL << 11)
: (USB_ENDPOINT_XFER_BULK << 11);
if (usb_pipein(pipe))

View File

@ -1,107 +0,0 @@
For Intel host controllers an interrupt is raised for every isochronous packet,
because of the "AVOID_BEI" quirk. The reasoning for this is found in the
following commit:
commit 227a4fd801c8a9fa2c4700ab98ec1aec06e3b44d
Author: Lu Baolu <baolu.lu@linux.intel.com>
Date: Mon Mar 23 18:27:42 2015 +0200
usb: xhci: apply XHCI_AVOID_BEI quirk to all Intel xHCI controllers
When a device with an isochronous endpoint is plugged into the Intel
xHCI host controller, and the driver submits multiple frames per URB,
the xHCI driver will set the Block Event Interrupt (BEI) flag on all
but the last TD for the URB. This causes the host controller to place
an event on the event ring, but not send an interrupt. When the last
TD for the URB completes, BEI is cleared, and we get an interrupt for
the whole URB.
However, under Intel xHCI host controllers, if the event ring is full
of events from transfers with BEI set, an "Event Ring is Full" event
will be posted to the last entry of the event ring, but no interrupt
is generated. Host will cease all transfer and command executions and
wait until software completes handling the pending events in the event
ring. That means xHC stops, but event of "event ring is full" is not
notified. As the result, the xHC looks like dead to user.
This patch is to apply XHCI_AVOID_BEI quirk to Intel xHC devices. And
it should be backported to kernels as old as 3.0, that contains the
commit 69e848c2090a ("Intel xhci: Support EHCI/xHCI port switching.").
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Tested-by: Alistair Grant <akgrant0710@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Because this behavior up to 8000 interrupts/s can be raised by the host
controller during isochronous transfer. Since 2020 there exists a patch that
relaxes this burden and which we will apply.
Author: Mathias Nyman <mathias.nyman@linux.intel.com>
Date: Fr Sep 18 2020 13:17:24 2020 +0200
xhci: Tune interrupt blocking for isochronous transfers
controllers with XHCI_AVOID_BEI quirk cause too frequent interrupts
and affect power management.
To avoid interrupting on every isochronous interval the BEI (Block
Event Interrupt) flag is set for all except the last Isoch TRB in a URB.
This lead to event ring filling up in case several isoc URB were
queued and cancelled rapidly, which some controllers didn't
handle well, and thus the XHCI_AVOID_BEI quirk was introduced.
see commit 227a4fd801c8 ("usb: xhci: apply XHCI_AVOID_BEI quirk to all
Intel xHCI controllers")
With the XHCI_AVOID_BEI quirk each Isoch TRB will trigger an interrupt.
This can cause up to 8000 interrupts per second for isochronous transfers
with HD USB3 cameras, affecting power saving.
The event ring fits 256 events, instead of interrupting on every
isochronous TRB if XHCI_AVOID_BEI is set we make sure at least every
8th Isochronous TRB asserts an interrupt, clearing the event ring.
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 028891a..31f6bd3 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3608,6 +3608,24 @@ static int xhci_get_isoc_frame_id(struct xhci_hcd *xhci,
return start_frame;
}
+/* Check if we should generate event interrupt for a TD in an isoc URB */
+static bool trb_block_event_intr(struct xhci_hcd *xhci, int num_tds, int i)
+{
+ if (xhci->hci_version < 0x100)
+ return false;
+ /* always generate an event interrupt for the last TD */
+ if (i == num_tds - 1)
+ return false;
+ /*
+ * If AVOID_BEI is set the host handles full event rings poorly,
+ * generate an event at least every 8th TD to clear the event ring
+ */
+ if (i && xhci->quirks & XHCI_AVOID_BEI)
+ return !!(i % 8);
+
+ return true;
+}
+
/* This is for isoc transfer */
static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
struct urb *urb, int slot_id, unsigned int ep_index)
@@ -3715,10 +3733,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
more_trbs_coming = false;
td->last_trb = ep_ring->enqueue;
field |= TRB_IOC;
- /* set BEI, except for the last TD */
- if (xhci->hci_version >= 0x100 &&
- !(xhci->quirks & XHCI_AVOID_BEI) &&
- i < num_tds - 1)
+ if (trb_block_event_intr(xhci, num_tds, i))
field |= TRB_BEI;
}
/* Calculate TRB length */

View File

@ -1,548 +0,0 @@
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index c821b4b..5accd4d 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -706,7 +706,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx,
}
len = sizeof(*intfc) + sizeof(struct usb_host_interface) * j;
- config->intf_cache[i] = intfc = kzalloc(len, GFP_KERNEL);
+ config->intf_cache[i] = intfc = kzalloc(len, GFP_LX_DMA);
if (!intfc)
return -ENOMEM;
kref_init(&intfc->ref);
@@ -817,16 +817,16 @@ int usb_get_configuration(struct usb_device *dev)
}
length = ncfg * sizeof(struct usb_host_config);
- dev->config = kzalloc(length, GFP_KERNEL);
+ dev->config = kzalloc(length, GFP_LX_DMA);
if (!dev->config)
goto err2;
length = ncfg * sizeof(char *);
- dev->rawdescriptors = kzalloc(length, GFP_KERNEL);
+ dev->rawdescriptors = kzalloc(length, GFP_LX_DMA);
if (!dev->rawdescriptors)
goto err2;
- desc = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL);
+ desc = kmalloc(USB_DT_CONFIG_SIZE, GFP_LX_DMA);
if (!desc)
goto err2;
@@ -855,7 +855,7 @@ int usb_get_configuration(struct usb_device *dev)
USB_DT_CONFIG_SIZE);
/* Now that we know the length, get the whole thing */
- bigbuffer = kmalloc(length, GFP_KERNEL);
+ bigbuffer = kmalloc(length, GFP_LX_DMA);
if (!bigbuffer) {
result = -ENOMEM;
goto err;
@@ -928,7 +928,7 @@ int usb_get_bos_descriptor(struct usb_device *dev)
__u8 cap_type;
int ret;
- bos = kzalloc(sizeof(struct usb_bos_descriptor), GFP_KERNEL);
+ bos = kzalloc(sizeof(struct usb_bos_descriptor), GFP_LX_DMA);
if (!bos)
return -ENOMEM;
@@ -949,12 +949,12 @@ int usb_get_bos_descriptor(struct usb_device *dev)
if (total_len < length)
return -EINVAL;
- dev->bos = kzalloc(sizeof(struct usb_host_bos), GFP_KERNEL);
+ dev->bos = kzalloc(sizeof(struct usb_host_bos), GFP_LX_DMA);
if (!dev->bos)
return -ENOMEM;
/* Now let's get the whole BOS descriptor set */
- buffer = kzalloc(total_len, GFP_KERNEL);
+ buffer = kzalloc(total_len, GFP_LX_DMA);
if (!buffer) {
ret = -ENOMEM;
goto err;
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index fc32391..919c9e9 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -507,7 +507,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
* USB hub descriptor.
*/
tbuf_size = max_t(u16, sizeof(struct usb_hub_descriptor), wLength);
- tbuf = kzalloc(tbuf_size, GFP_KERNEL);
+ tbuf = kzalloc(tbuf_size, GFP_LX_DMA);
if (!tbuf) {
status = -ENOMEM;
goto err_alloc;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index c5c1f6c..5bd400f 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -706,7 +706,7 @@ resubmit:
if (hub->quiescing)
return;
- status = usb_submit_urb(hub->urb, GFP_ATOMIC);
+ status = usb_submit_urb(hub->urb, GFP_LX_DMA);
if (status != 0 && status != -ENODEV && status != -EPERM)
dev_err(hub->intfdev, "resubmit --> %d\n", status);
}
@@ -1310,20 +1310,20 @@ static int hub_configure(struct usb_hub *hub,
unsigned full_load;
unsigned maxchild;
- hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL);
+ hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_LX_DMA);
if (!hub->buffer) {
ret = -ENOMEM;
goto fail;
}
- hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL);
+ hub->status = kmalloc(sizeof(*hub->status), GFP_LX_DMA);
if (!hub->status) {
ret = -ENOMEM;
goto fail;
}
mutex_init(&hub->status_mutex);
- hub->descriptor = kzalloc(sizeof(*hub->descriptor), GFP_KERNEL);
+ hub->descriptor = kzalloc(sizeof(*hub->descriptor), GFP_LX_DMA);
if (!hub->descriptor) {
ret = -ENOMEM;
goto fail;
@@ -1565,7 +1565,7 @@ static int hub_configure(struct usb_hub *hub,
if (maxp > sizeof(*hub->buffer))
maxp = sizeof(*hub->buffer);
- hub->urb = usb_alloc_urb(0, GFP_KERNEL);
+ hub->urb = usb_alloc_urb(0, GFP_LX_DMA);
if (!hub->urb) {
ret = -ENOMEM;
goto fail;
@@ -4713,7 +4713,7 @@ check_highspeed(struct usb_hub *hub, struct usb_device *udev, int port1)
if (udev->quirks & USB_QUIRK_DEVICE_QUALIFIER)
return;
- qual = kmalloc(sizeof *qual, GFP_KERNEL);
+ qual = kmalloc(sizeof *qual, GFP_LX_DMA);
if (qual == NULL)
return;
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index b3f98e0..3442858 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -237,7 +237,7 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
if (!ep || len < 0)
return -EINVAL;
- urb = usb_alloc_urb(0, GFP_KERNEL);
+ urb = usb_alloc_urb(0, GFP_LX_DMA);
if (!urb)
return -ENOMEM;
@@ -990,7 +989,7 @@ int usb_get_status(struct usb_device *dev, int recip, int type, int target,
return -EINVAL;
}
- status = kmalloc(length, GFP_KERNEL);
+ status = kmalloc(length, GFP_LX_DMA);
if (!status)
return -ENOMEM;
@@ -2084,7 +2083,7 @@ int usb_driver_set_configuration(struct usb_device *udev, int config)
{
struct set_config_request *req;
- req = kmalloc(sizeof(*req), GFP_KERNEL);
+ req = kmalloc(sizeof(*req), GFP_LX_DMA);
if (!req)
return -ENOMEM;
req->udev = udev;
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 0a84661..f427b75 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -749,7 +749,7 @@ static struct urb *request_single_step_set_feature_urb(
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
struct usb_host_endpoint *ep;
- urb = usb_alloc_urb(0, GFP_KERNEL);
+ urb = usb_alloc_urb(0, GFP_LX_DMA);
if (!urb)
return NULL;
@@ -804,11 +803,11 @@ static int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
ehci_err(ehci, "No device attached to the RootHub\n");
return -ENODEV;
}
- buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL);
+ buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_LX_DMA);
if (!buf)
return -ENOMEM;
- dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
+ dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_LX_DMA);
if (!dr) {
kfree(buf);
return -ENOMEM;
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 3276304..8b9e337 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -1020,7 +1020,7 @@ static struct ehci_qh *qh_append_tds (
qh = (struct ehci_qh *) *ptr;
if (unlikely (qh == NULL)) {
/* can't sleep here, we have ehci->lock... */
- qh = qh_make (ehci, urb, GFP_ATOMIC);
+ qh = qh_make (ehci, urb, GFP_LX_DMA);
*ptr = qh;
}
if (likely (qh != NULL)) {
@@ -1172,7 +1172,7 @@ static int submit_single_step_set_feature(
head = &qtd_list;
/* URBs map to sequences of QTDs: one logical transaction */
- qtd = ehci_qtd_alloc(ehci, GFP_KERNEL);
+ qtd = ehci_qtd_alloc(ehci, GFP_LX_DMA);
if (unlikely(!qtd))
return -1;
list_add_tail(&qtd->qtd_list, head);
@@ -1193,7 +1193,7 @@ static int submit_single_step_set_feature(
sizeof(struct usb_ctrlrequest),
QTD_IOC | token | (2 /* "setup" */ << 8), 8);
- submit_async(ehci, urb, &qtd_list, GFP_ATOMIC);
+ submit_async(ehci, urb, &qtd_list, GFP_LX_DMA);
return 0; /*Return now; we shall come back after 15 seconds*/
}
@@ -1221,7 +1221,7 @@ static int submit_single_step_set_feature(
token |= QTD_TOGGLE; /* force DATA1 */
qtd_prev = qtd;
- qtd = ehci_qtd_alloc(ehci, GFP_ATOMIC);
+ qtd = ehci_qtd_alloc(ehci, GFP_LX_DMA);
if (unlikely(!qtd))
goto cleanup;
qtd->urb = urb;
@@ -1231,7 +1231,7 @@ static int submit_single_step_set_feature(
/* Interrupt after STATUS completion */
qtd_fill(ehci, qtd, 0, 0, token | QTD_IOC, 0);
- submit_async(ehci, urb, &qtd_list, GFP_KERNEL);
+ submit_async(ehci, urb, &qtd_list, GFP_LX_DMA);
return 0;
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index ac7d4ac..1eb1fc7 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -683,7 +683,7 @@ static int fill_buffer(struct debug_buffer *buf)
int ret = 0;
if (!buf->page)
- buf->page = (char *)get_zeroed_page(GFP_KERNEL);
+ buf->page = (char *)get_zeroed_page(GFP_LX_DMA);
if (!buf->page) {
ret = -ENOMEM;
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index d088c34..2211b20 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -506,7 +506,7 @@ static int ohci_init (struct ohci_hcd *ohci)
ohci->prev_frame_no = IO_WATCHDOG_OFF;
ohci->hcca = dma_alloc_coherent (hcd->self.controller,
- sizeof(*ohci->hcca), &ohci->hcca_dma, GFP_KERNEL);
+ sizeof(*ohci->hcca), &ohci->hcca_dma, GFP_LX_DMA);
if (!ohci->hcca)
return -ENOMEM;
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index f9c3947..99a1696 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -602,7 +602,7 @@ static int uhci_start(struct usb_hcd *hcd)
uhci->frame = dma_zalloc_coherent(uhci_dev(uhci),
UHCI_NUMFRAMES * sizeof(*uhci->frame),
- &uhci->frame_dma_handle, GFP_KERNEL);
+ &uhci->frame_dma_handle, GFP_LX_DMA);
if (!uhci->frame) {
dev_err(uhci_dev(uhci),
"unable to allocate consistent memory for frame list\n");
@@ -610,7 +610,7 @@ static int uhci_start(struct usb_hcd *hcd)
}
uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu),
- GFP_KERNEL);
+ GFP_LX_DMA);
if (!uhci->frame_cpu)
goto err_alloc_frame_cpu;
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 35fcb82..3a0cff5 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -108,7 +108,7 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci)
dma_addr_t dma_handle;
struct uhci_td *td;
- td = dma_pool_alloc(uhci->td_pool, GFP_ATOMIC, &dma_handle);
+ td = dma_pool_alloc(uhci->td_pool, GFP_LX_DMA, &dma_handle);
if (!td)
return NULL;
@@ -248,7 +248,7 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
dma_addr_t dma_handle;
struct uhci_qh *qh;
- qh = dma_pool_zalloc(uhci->qh_pool, GFP_ATOMIC, &dma_handle);
+ qh = dma_pool_zalloc(uhci->qh_pool, GFP_LX_DMA, &dma_handle);
if (!qh)
return NULL;
@@ -724,7 +724,7 @@ static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci,
{
struct urb_priv *urbp;
- urbp = kmem_cache_zalloc(uhci_up_cachep, GFP_ATOMIC);
+ urbp = kmem_cache_zalloc(uhci_up_cachep, GFP_LX_DMA);
if (!urbp)
return NULL;
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 72ebbc9..0e815a8 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -404,7 +404,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
if (GET_EP_CTX_STATE(ep_ctx) != EP_STATE_RUNNING)
continue;
- command = xhci_alloc_command(xhci, false, GFP_NOWAIT);
+ command = xhci_alloc_command(xhci, false, GFP_LX_DMA);
if (!command) {
spin_unlock_irqrestore(&xhci->lock, flags);
ret = -ENOMEM;
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 332420d..e037aaf 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -2135,7 +2135,7 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
rhub->psi_count = XHCI_EXT_PORT_PSIC(temp);
if (rhub->psi_count) {
rhub->psi = kcalloc(rhub->psi_count, sizeof(*rhub->psi),
- GFP_KERNEL);
+ GFP_LX_DMA);
if (!rhub->psi)
rhub->psi_count = 0;
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index daa94c3..028891a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -656,6 +656,7 @@
struct device *dev = xhci_to_hcd(xhci)->self.controller;
struct xhci_segment *seg = td->bounce_seg;
struct urb *urb = td->urb;
+ size_t len;
if (!ring || !seg || !urb)
return;
@@ -667,8 +668,16 @@
}
/* for in tranfers we need to copy the data from bounce to sg */
- sg_pcopy_from_buffer(urb->sg, urb->num_mapped_sgs, seg->bounce_buf,
- seg->bounce_len, seg->bounce_offs);
+ if (urb->num_sgs) {
+ len = sg_pcopy_from_buffer(urb->sg, urb->num_mapped_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);
+ }
dma_unmap_single(dev, seg->bounce_dma, ring->bounce_buf_len,
DMA_FROM_DEVICE);
seg->bounce_len = 0;
@@ -1141,7 +1150,7 @@
if (xhci->quirks & XHCI_RESET_EP_QUIRK) {
struct xhci_command *command;
- command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
+ command = xhci_alloc_command(xhci, false, GFP_LX_DMA);
if (!command)
return;
@@ -1821,7 +1830,7 @@
{
struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index];
struct xhci_command *command;
- command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
+ command = xhci_alloc_command(xhci, false, GFP_LX_DMA);
if (!command)
return;
@@ -3136,6 +3145,7 @@
unsigned int unalign;
unsigned int max_pkt;
u32 new_buff_len;
+ size_t len;
max_pkt = usb_endpoint_maxp(&urb->ep->desc);
unalign = (enqd_len + *trb_buff_len) % max_pkt;
@@ -3166,8 +3176,17 @@
/* create a max max_pkt sized bounce buffer pointed to by last trb */
if (usb_urb_dir_out(urb)) {
- sg_pcopy_to_buffer(urb->sg, urb->num_mapped_sgs,
- seg->bounce_buf, new_buff_len, enqd_len);
+ if (urb->num_sgs) {
+ len = sg_pcopy_to_buffer(urb->sg, urb->num_mapped_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 {
@@ -3906,7 +3925,7 @@
reserved_trbs++;
ret = prepare_ring(xhci, xhci->cmd_ring, EP_STATE_RUNNING,
- reserved_trbs, GFP_ATOMIC);
+ reserved_trbs, GFP_LX_DMA);
if (ret < 0) {
xhci_err(xhci, "ERR: No room for command on command ring\n");
if (command_must_succeed)
@@ -4040,7 +4059,7 @@
}
/* This function gets called from contexts where it cannot sleep */
- cmd = xhci_alloc_command(xhci, false, GFP_ATOMIC);
+ cmd = xhci_alloc_command(xhci, false, GFP_LX_DMA);
if (!cmd)
return;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 5d37700..1945abb 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -602,7 +604,7 @@ int xhci_run(struct usb_hcd *hcd)
if (xhci->quirks & XHCI_NEC_HOST) {
struct xhci_command *command;
- command = xhci_alloc_command(xhci, false, GFP_KERNEL);
+ command = xhci_alloc_command(xhci, false, GFP_LX_DMA);
if (!command)
return -ENOMEM;
@@ -1244,7 +1246,7 @@ static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,
* changes max packet sizes.
*/
- command = xhci_alloc_command(xhci, true, GFP_KERNEL);
+ command = xhci_alloc_command(xhci, true, GFP_LX_DMA);
if (!command)
return -ENOMEM;
@@ -1355,7 +1357,7 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
switch (usb_endpoint_type(&urb->ep->desc)) {
case USB_ENDPOINT_XFER_CONTROL:
- ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
+ ret = xhci_queue_ctrl_tx(xhci, GFP_LX_DMA, urb,
slot_id, ep_index);
break;
case USB_ENDPOINT_XFER_BULK:
@@ -1366,18 +1368,18 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
ret = -EINVAL;
break;
}
- ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
+ ret = xhci_queue_bulk_tx(xhci, GFP_LX_DMA, urb,
slot_id, ep_index);
break;
case USB_ENDPOINT_XFER_INT:
- ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb,
+ ret = xhci_queue_intr_tx(xhci, GFP_LX_DMA, urb,
slot_id, ep_index);
break;
case USB_ENDPOINT_XFER_ISOC:
- ret = xhci_queue_isoc_tx_prepare(xhci, GFP_ATOMIC, urb,
+ ret = xhci_queue_isoc_tx_prepare(xhci, GFP_LX_DMA, urb,
slot_id, ep_index);
}
@@ -1499,7 +1501,7 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
* the first cancellation to be handled.
*/
if (!(ep->ep_state & EP_STOP_CMD_PENDING)) {
- command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
+ command = xhci_alloc_command(xhci, false, GFP_LX_DMA);
if (!command) {
ret = -ENOMEM;
goto done;
@@ -2684,7 +2686,7 @@ static int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
virt_dev = xhci->devs[udev->slot_id];
- command = xhci_alloc_command(xhci, true, GFP_KERNEL);
+ command = xhci_alloc_command(xhci, true, GFP_LX_DMA);
if (!command)
return -ENOMEM;
@@ -3560,7 +3562,7 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id)
u32 state;
int ret = 0;
- command = xhci_alloc_command(xhci, false, GFP_KERNEL);
+ command = xhci_alloc_command(xhci, false, GFP_LX_DMA);
if (!command)
return -ENOMEM;
@@ -3622,7 +3624,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
int ret, slot_id;
struct xhci_command *command;
- command = xhci_alloc_command(xhci, true, GFP_KERNEL);
+ command = xhci_alloc_command(xhci, true, GFP_LX_DMA);
if (!command)
return 0;
@@ -3755,7 +3757,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
}
}
- command = xhci_alloc_command(xhci, true, GFP_KERNEL);
+ command = xhci_alloc_command(xhci, true, GFP_LX_DMA);
if (!command) {
ret = -ENOMEM;
goto out;
@@ -4688,7 +4690,7 @@ static int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
spin_lock_irqsave(&xhci->lock, flags);
if (hdev->speed == USB_SPEED_HIGH &&
- xhci_alloc_tt_info(xhci, vdev, hdev, tt, GFP_ATOMIC)) {
+ xhci_alloc_tt_info(xhci, vdev, hdev, tt, GFP_LX_DMA)) {
xhci_dbg(xhci, "Could not allocate xHCI TT structure.\n");
xhci_free_command(xhci, config_cmd);
spin_unlock_irqrestore(&xhci->lock, flags);

View File

@ -1,12 +0,0 @@
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 8d8bafc..3c3f71c 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -28,6 +28,7 @@
#include <linux/clk.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
+#include <linux/usb/phy.h>
#include <linux/of.h>
#include <linux/dma-mapping.h>

View File

@ -1,105 +0,0 @@
This is a backport of commit dc0ffbea5729a3abafa577ebfce87f18b79e294b:
Subject: [PATCH] usb: host: xhci: update event ring dequeue pointer on purpose
On some situations, the software handles TRB events slower
than adding TRBs, then xhci_handle_event can't return zero
long time, the xHC will consider the event ring is full,
and trigger "Event Ring Full" error, but in fact, the software
has already finished lots of events, just no chance to
update ERDP (event ring dequeue pointer).
In this commit, we force update ERDP if half of TRBS_PER_SEGMENT
events have handled to avoid "Event Ring Full" error.
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/1573836603-10871-2-git-send-email-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2717,6 +2717,42 @@
}
/*
+ * Update Event Ring Dequeue Pointer:
+ * - When all events have finished
+ * - To avoid "Event Ring Full Error" condition
+ */
+static void xhci_update_erst_dequeue(struct xhci_hcd *xhci,
+ union xhci_trb *event_ring_deq)
+{
+ u64 temp_64;
+ dma_addr_t deq;
+
+ temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+ /* If necessary, update the HW's version of the event ring deq ptr. */
+ if (event_ring_deq != xhci->event_ring->dequeue) {
+ deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg,
+ xhci->event_ring->dequeue);
+ if (deq == 0)
+ xhci_warn(xhci, "WARN something wrong with SW event ring dequeue ptr\n");
+ /*
+ * Per 4.9.4, Software writes to the ERDP register shall
+ * always advance the Event Ring Dequeue Pointer value.
+ */
+ if ((temp_64 & (u64) ~ERST_PTR_MASK) ==
+ ((u64) deq & (u64) ~ERST_PTR_MASK))
+ return;
+
+ /* Update HC event ring dequeue pointer */
+ temp_64 &= ERST_PTR_MASK;
+ temp_64 |= ((u64) deq & (u64) ~ERST_PTR_MASK);
+ }
+
+ /* Clear the event handler busy flag (RW1C) */
+ temp_64 |= ERST_EHB;
+ xhci_write_64(xhci, temp_64, &xhci->ir_set->erst_dequeue);
+}
+
+/*
* xHCI spec says we can get an interrupt, and if the HC has an error condition,
* we might get bad data out of the event ring. Section 4.10.2.7 has a list of
* indicators of an event TRB error, but we check the status *first* to be safe.
@@ -2727,9 +2763,9 @@
union xhci_trb *event_ring_deq;
irqreturn_t ret = IRQ_NONE;
unsigned long flags;
- dma_addr_t deq;
u64 temp_64;
u32 status;
+ int event_loop = 0;
spin_lock_irqsave(&xhci->lock, flags);
/* Check if the xHC generated the interrupt, or the irq is shared */
@@ -2783,24 +2819,14 @@
/* FIXME this should be a delayed service routine
* that clears the EHB.
*/
- while (xhci_handle_event(xhci) > 0) {}
-
- temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
- /* If necessary, update the HW's version of the event ring deq ptr. */
- if (event_ring_deq != xhci->event_ring->dequeue) {
- deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg,
- xhci->event_ring->dequeue);
- if (deq == 0)
- xhci_warn(xhci, "WARN something wrong with SW event "
- "ring dequeue ptr.\n");
- /* Update HC event ring dequeue pointer */
- temp_64 &= ERST_PTR_MASK;
- temp_64 |= ((u64) deq & (u64) ~ERST_PTR_MASK);
+ while (xhci_handle_event(xhci) > 0) {
+ if (event_loop++ < TRBS_PER_SEGMENT / 2)
+ continue;
+ xhci_update_erst_dequeue(xhci, event_ring_deq);
+ event_loop = 0;
}
- /* Clear the event handler busy flag (RW1C); event ring is empty. */
- temp_64 |= ERST_EHB;
- xhci_write_64(xhci, temp_64, &xhci->ir_set->erst_dequeue);
+ xhci_update_erst_dequeue(xhci, event_ring_deq);
ret = IRQ_HANDLED;
out:

View File

@ -1,71 +0,0 @@
From 09f736aa95476631227d2dc0e6b9aeee1ad7ed58 Mon Sep 17 00:00:00 2001
From: Mathias Nyman <mathias.nyman@linux.intel.com>
Date: Fri, 26 Nov 2021 14:23:40 +0200
Subject: xhci: Fix commad ring abort, write all 64 bits to CRCR register.
Turns out some xHC controllers require all 64 bits in the CRCR register
to be written to execute a command abort.
The lower 32 bits containing the command abort bit is written first.
In case the command ring stops before we write the upper 32 bits then
hardware may use these upper bits to set the commnd ring dequeue pointer.
Solve this by making sure the upper 32 bits contain a valid command
ring dequeue pointer.
The original patch that only wrote the first 32 to stop the ring went
to stable, so this fix should go there as well.
Fixes: ff0e50d3564f ("xhci: Fix command ring pointer corruption while aborting a command")
Cc: stable@vger.kernel.org
Tested-by: Pavankumar Kondeti <quic_pkondeti@quicinc.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20211126122340.1193239-2-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/host/xhci-ring.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 311597bba80e2..eaa49aef29352 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -366,7 +366,9 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci,
/* Must be called with xhci->lock held, releases and aquires lock back */
static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
{
- u32 temp_32;
+ struct xhci_segment *new_seg = xhci->cmd_ring->deq_seg;
+ union xhci_trb *new_deq = xhci->cmd_ring->dequeue;
+ u64 crcr;
int ret;
xhci_dbg(xhci, "Abort command ring\n");
@@ -375,13 +377,18 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
/*
* The control bits like command stop, abort are located in lower
- * dword of the command ring control register. Limit the write
- * to the lower dword to avoid corrupting the command ring pointer
- * in case if the command ring is stopped by the time upper dword
- * is written.
+ * dword of the command ring control register.
+ * Some controllers require all 64 bits to be written to abort the ring.
+ * Make sure the upper dword is valid, pointing to the next command,
+ * avoiding corrupting the command ring pointer in case the command ring
+ * is stopped by the time the upper dword is written.
*/
- temp_32 = readl(&xhci->op_regs->cmd_ring);
- writel(temp_32 | CMD_RING_ABORT, &xhci->op_regs->cmd_ring);
+ next_trb(xhci, NULL, &new_seg, &new_deq);
+ if (trb_is_link(new_deq))
+ next_trb(xhci, NULL, &new_seg, &new_deq);
+
+ crcr = xhci_trb_virt_to_dma(new_seg, new_deq);
+ xhci_write_64(xhci, crcr | CMD_RING_ABORT, &xhci->op_regs->cmd_ring);
/* Section 4.6.1.2 of xHCI 1.0 spec says software should also time the
* completion of the Command Abort operation. If CRR is not negated in 5
--
cgit

View File

@ -1,59 +0,0 @@
From e91ac20889d1a26d077cc511365cd7ff4346a6f3 Mon Sep 17 00:00:00 2001
From: Weitao Wang <WeitaoWang-oc@zhaoxin.com>
Date: Fri, 8 Apr 2022 16:48:21 +0300
Subject: [PATCH] USB: Fix xhci event ring dequeue pointer ERDP update issue
In some situations software handles TRB events slower than adding TRBs.
If the number of TRB events to be processed in a given interrupt is exactly
the same as the event ring size 256, then the local variable
"event_ring_deq" that holds the initial dequeue position is equal to
software_dequeue after handling all 256 interrupts.
It will cause driver to not update ERDP to hardware,
Software dequeue pointer is out of sync with ERDP on interrupt exit.
On the next interrupt, the event ring may full but driver will not
update ERDP as software_dequeue is equal to ERDP.
[ 536.377115] xhci_hcd 0000:00:12.0: ERROR unknown event type 37
[ 566.933173] sd 8:0:0:0: [sdb] tag#27 uas_eh_abort_handler 0 uas-tag 7 inflight: CMD OUT
[ 566.933181] sd 8:0:0:0: [sdb] tag#27 CDB: Write(10) 2a 00 17 71 e6 78 00 00 08 00
[ 572.041186] xhci_hcd On some situataions,the0000:00:12.0: xHCI host not responding to stop endpoint command.
[ 572.057193] xhci_hcd 0000:00:12.0: Host halt failed, -110
[ 572.057196] xhci_hcd 0000:00:12.0: xHCI host controller not responding, assume dead
[ 572.057236] sd 8:0:0:0: [sdb] tag#26 uas_eh_abort_handler 0 uas-tag 6 inflight: CMD
[ 572.057240] sd 8:0:0:0: [sdb] tag#26 CDB: Write(10) 2a 00 38 eb cc d8 00 00 08 00
[ 572.057244] sd 8:0:0:0: [sdb] tag#25 uas_eh_abort_handler 0 uas-tag 5 inflight: CMD
Hardware ERDP is updated mid event handling if there are more than 128
events in an interrupt (half of ring size).
Fix this by updating the software local variable at the same time as
hardware ERDP.
[commit message rewording -Mathias]
Fixes: dc0ffbea5729 ("usb: host: xhci: update event ring dequeue pointer on purpose")
Reviewed-by: Peter Chen <peter.chen@kernel.org>
Signed-off-by: Weitao Wang <WeitaoWang-oc@zhaoxin.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20220408134823.2527272-2-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/host/xhci-ring.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index d0b6806275e0..f9707997969d 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3141,6 +3141,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
if (event_loop++ < TRBS_PER_SEGMENT / 2)
continue;
xhci_update_erst_dequeue(xhci, event_ring_deq);
+ event_ring_deq = xhci->event_ring->dequeue;
/* ring is half-full, force isoc trbs to interrupt more often */
if (xhci->isoc_bei_interval > AVOID_BEI_INTERVAL_MIN)
--
2.25.1

View File

@ -1,28 +0,0 @@
LIB_MK := lib/mk/usb_host_include.mk lib/import/import-usb_arch_include.mk \
$(foreach SPEC,arm arm_64 x86_32 x86_64,lib/mk/spec/$(SPEC)/lx_kit_setjmp.mk)
PORT_DIR := $(call port_dir,$(REP_DIR)/ports/dde_linux)
MIRROR_FROM_REP_DIR := $(LIB_MK) \
lib/import/import-usb_host_include.mk \
src/include/legacy src/lib/legacy/lx_kit \
src/lib/lx_kit/spec \
$(foreach SPEC,arm arm_64 arm_v6 arm_v7 x86 x86_32 x86_64,src/include/spec/$(SPEC)) \
$(shell cd $(REP_DIR); find src/drivers/usb_host -type f)
MIRROR_FROM_PORT_DIR := $(shell cd $(PORT_DIR); find src/drivers/usb_host -type f | grep -v ".git")
MIRROR_FROM_PORT_DIR := $(filter-out $(MIRROR_FROM_REP_DIR),$(MIRROR_FROM_PORT_DIR))
content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_PORT_DIR)
$(MIRROR_FROM_REP_DIR):
$(mirror_from_rep_dir)
$(MIRROR_FROM_PORT_DIR):
mkdir -p $(dir $@)
cp $(PORT_DIR)/$@ $@
content: LICENSE
LICENSE:
( echo "GNU General Public License version 2, see:"; \
echo "https://www.kernel.org/pub/linux/kernel/COPYING" ) > $@

View File

@ -1 +0,0 @@
2023-08-21 0db2afb6d236762f066a30556c1c765800d6ed85

View File

@ -1,8 +0,0 @@
base
os
format
usb_session
gpio_session
platform_session
timer_session
report_session

View File

@ -1,89 +0,0 @@
/*
* \brief Generic base of a network session using a DDE Linux back end
* \author Martin Stein
* \date 2020-12-13
*/
/*
* Copyright (C) 2020 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <linux_network_session_base.h>
#include <legacy/lx_kit/scheduler.h>
#include <lx_emul.h>
void Linux_network_session_base::_run_tx_task(void * args)
{
Tx_data *data = static_cast<Tx_data*>(args);
while (1) {
Lx::scheduler().current()->block_and_schedule();
net_device * ndev = data->ndev;
struct sk_buff * skb = data->skb;
ndev->netdev_ops->ndo_start_xmit(skb, ndev);
}
}
void Linux_network_session_base::_run_rx_task(void * args)
{
Rx_data *data = static_cast<Rx_data*>(args);
while (1) {
Lx::scheduler().current()->block_and_schedule();
int ret = 0;
struct napi_struct * n = data->napi;
for (;;) {
/* This NAPI_STATE_SCHED test is for avoiding a race
* with netpoll's poll_napi(). Only the entity which
* obtains the lock and sees NAPI_STATE_SCHED set will
* actually make the ->poll() call. Therefore we avoid
* accidentally calling ->poll() when NAPI is not scheduled.
*/
if (!test_bit(NAPI_STATE_SCHED, &n->state)) break;
int weight = n->weight;
int work = n->poll(n, weight);
ret += work;
if (work < weight) break;
Genode::warning("Too much incoming traffic, we should "
"schedule RX more intelligent");
}
}
}
Linux_network_session_base::
Linux_network_session_base(Genode::Session_label const &label)
:
_ndev { _register_session(*this, label) }
{
if (!_ndev) {
error("failed to register session with label \"", label, "\"");
throw Genode::Service_denied();
}
}
bool Linux_network_session_base::_read_link_state_from_ndev() const
{
return !(_ndev->state & (1UL << __LINK_STATE_NOCARRIER));
}
void Linux_network_session_base::unblock_rx_task(napi_struct * n)
{
_rx_data.napi = n;
_rx_task.unblock();
}

View File

@ -1,78 +0,0 @@
/*
* \brief Virtual interface of a network session connected to the driver
* \author Martin Stein
* \date 2020-12-13
*/
/*
* Copyright (C) 2020 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _SRC__DRIVERS__NIC__LINUX_NETWORK_SESSION_BASE_H_
#define _SRC__DRIVERS__NIC__LINUX_NETWORK_SESSION_BASE_H_
#include <legacy/lx_kit/scheduler.h>
/* forward declarations */
extern "C" {
struct net_device;
struct napi_struct;
struct sk_buff;
}
class Linux_network_session_base
{
protected:
enum { HEAD_ROOM = 8 };
struct Tx_data
{
net_device * ndev;
sk_buff * skb;
};
struct Rx_data
{
struct napi_struct * napi;
};
net_device * _ndev = nullptr;
Tx_data _tx_data;
Rx_data _rx_data;
Lx::Task _tx_task { _run_tx_task, &_tx_data, "tx_task",
Lx::Task::PRIORITY_1, Lx::scheduler() };
Lx::Task _rx_task { _run_rx_task, &_rx_data, "rx_task",
Lx::Task::PRIORITY_1, Lx::scheduler() };
static void _run_tx_task(void * args);
static void _run_rx_task(void * args);
static net_device *
_register_session(Linux_network_session_base &session,
Genode::Session_label label);
bool _read_link_state_from_ndev() const;
public:
Linux_network_session_base(Genode::Session_label const &label);
void unblock_rx_task(napi_struct * n);
/***********************
** Virtual interface **
***********************/
virtual void receive(struct sk_buff *skb) = 0;
virtual void link_state(bool state) = 0;
};
#endif /* _SRC__DRIVERS__NIC__LINUX_NETWORK_SESSION_BASE_H_ */