summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-mem.c
diff options
context:
space:
mode:
authorNiklas Neronin <niklas.neronin@linux.intel.com>2024-04-29 17:02:30 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-05-01 08:47:14 +0200
commitdb4460b6ecf07574d580f01cd88054a62607068c (patch)
tree9c0fb329333ee53feafcdca52333936303fbce94 /drivers/usb/host/xhci-mem.c
parent6d3bc5e941bf94947937281b20c17cc80202de8b (diff)
downloadlinux-stable-db4460b6ecf07574d580f01cd88054a62607068c.tar.gz
linux-stable-db4460b6ecf07574d580f01cd88054a62607068c.tar.bz2
linux-stable-db4460b6ecf07574d580f01cd88054a62607068c.zip
usb: xhci: check if 'requested segments' exceeds ERST capacity
Check if requested segments ('segs' or 'ERST_DEFAULT_SEGS') exceeds the maximum amount ERST supports. When 'segs' is '0', 'ERST_DEFAULT_SEGS' is used instead. But both values may not exceed ERST max. Macro 'ERST_MAX_SEGS' is renamed to 'ERST_DEFAULT_SEGS'. The new name better represents the macros, which is the number of Event Ring segments to allocate, when the amount is not specified. Additionally, rename and change xhci_create_secondary_interrupter()'s argument 'int num_segs' to 'unsigned int segs'. This makes it the same as its counter part in xhci_alloc_interrupter(). Fixes: c99b38c41234 ("xhci: add support to allocate several interrupters") Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://lore.kernel.org/r/20240429140245.3955523-4-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r--drivers/usb/host/xhci-mem.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 7ff2ff29b48e..1a16b44506da 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -2259,24 +2259,24 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
}
static struct xhci_interrupter *
-xhci_alloc_interrupter(struct xhci_hcd *xhci, int segs, gfp_t flags)
+xhci_alloc_interrupter(struct xhci_hcd *xhci, unsigned int segs, gfp_t flags)
{
struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
struct xhci_interrupter *ir;
- unsigned int num_segs = segs;
+ unsigned int max_segs;
int ret;
+ if (!segs)
+ segs = ERST_DEFAULT_SEGS;
+
+ max_segs = BIT(HCS_ERST_MAX(xhci->hcs_params2));
+ segs = min(segs, max_segs);
+
ir = kzalloc_node(sizeof(*ir), flags, dev_to_node(dev));
if (!ir)
return NULL;
- /* number of ring segments should be greater than 0 */
- if (segs <= 0)
- num_segs = min_t(unsigned int, 1 << HCS_ERST_MAX(xhci->hcs_params2),
- ERST_MAX_SEGS);
-
- ir->event_ring = xhci_ring_alloc(xhci, num_segs, 1, TYPE_EVENT, 0,
- flags);
+ ir->event_ring = xhci_ring_alloc(xhci, segs, 1, TYPE_EVENT, 0, flags);
if (!ir->event_ring) {
xhci_warn(xhci, "Failed to allocate interrupter event ring\n");
kfree(ir);
@@ -2334,7 +2334,7 @@ xhci_add_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir,
}
struct xhci_interrupter *
-xhci_create_secondary_interrupter(struct usb_hcd *hcd, int num_seg)
+xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
struct xhci_interrupter *ir;
@@ -2344,7 +2344,7 @@ xhci_create_secondary_interrupter(struct usb_hcd *hcd, int num_seg)
if (!xhci->interrupters || xhci->max_interrupters <= 1)
return NULL;
- ir = xhci_alloc_interrupter(xhci, num_seg, GFP_KERNEL);
+ ir = xhci_alloc_interrupter(xhci, segs, GFP_KERNEL);
if (!ir)
return NULL;