* [PATCH v2 1/3] usb: host: move EH SINGLE_STEP_SET_FEATURE implementation to core
@ 2021-04-30 6:16 Li Jun
2021-04-30 6:16 ` [PATCH v2 2/3] usb: host: xhci: add EH SINGLE_STEP_SET_FEATURE Test for USB2 Li Jun
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Li Jun @ 2021-04-30 6:16 UTC (permalink / raw)
To: gregkh, stern, mathias.nyman
Cc: peter.chen, jun.li, jackp, linux-usb, linux-imx
From: Peter Chen <peter.chen@nxp.com>
It is needed at USB Certification test for Embedded Host 2.0, and
the detail is at CH6.4.1.1 of On-The-Go and Embedded Host Supplement
to the USB Revision 2.0 Specification. Since other USB 2.0 capable
host like XHCI also need it, so move it to HCD core.
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Li Jun <jun.li@nxp.com>
---
Change for v2:
- No change.
drivers/usb/core/hcd.c | 134 ++++++++++++++++++++++++++++++++++
drivers/usb/host/ehci-hcd.c | 4 ++
drivers/usb/host/ehci-hub.c | 139 ------------------------------------
drivers/usb/host/ehci-q.c | 2 +-
include/linux/usb/hcd.h | 13 +++-
5 files changed, 151 insertions(+), 141 deletions(-)
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 6119fb41d736..d7eb9f179ca6 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2110,6 +2110,140 @@ int usb_hcd_get_frame_number (struct usb_device *udev)
return hcd->driver->get_frame_number (hcd);
}
+/*-------------------------------------------------------------------------*/
+#ifdef CONFIG_USB_HCD_TEST_MODE
+
+static void usb_ehset_completion(struct urb *urb)
+{
+ struct completion *done = urb->context;
+
+ complete(done);
+}
+/*
+ * Allocate and initialize a control URB. This request will be used by the
+ * EHSET SINGLE_STEP_SET_FEATURE test in which the DATA and STATUS stages
+ * of the GetDescriptor request are sent 15 seconds after the SETUP stage.
+ * Return NULL if failed.
+ */
+static struct urb *request_single_step_set_feature_urb(
+ struct usb_device *udev,
+ void *dr,
+ void *buf,
+ struct completion *done)
+{
+ struct urb *urb;
+ struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+ struct usb_host_endpoint *ep;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb)
+ return NULL;
+
+ urb->pipe = usb_rcvctrlpipe(udev, 0);
+ ep = (usb_pipein(urb->pipe) ? udev->ep_in : udev->ep_out)
+ [usb_pipeendpoint(urb->pipe)];
+ if (!ep) {
+ usb_free_urb(urb);
+ return NULL;
+ }
+
+ urb->ep = ep;
+ urb->dev = udev;
+ urb->setup_packet = (void *)dr;
+ urb->transfer_buffer = buf;
+ urb->transfer_buffer_length = USB_DT_DEVICE_SIZE;
+ urb->complete = usb_ehset_completion;
+ urb->status = -EINPROGRESS;
+ urb->actual_length = 0;
+ urb->transfer_flags = URB_DIR_IN;
+ usb_get_urb(urb);
+ atomic_inc(&urb->use_count);
+ atomic_inc(&urb->dev->urbnum);
+ urb->setup_dma = dma_map_single(
+ hcd->self.sysdev,
+ urb->setup_packet,
+ sizeof(struct usb_ctrlrequest),
+ DMA_TO_DEVICE);
+ urb->transfer_dma = dma_map_single(
+ hcd->self.sysdev,
+ urb->transfer_buffer,
+ urb->transfer_buffer_length,
+ DMA_FROM_DEVICE);
+ urb->context = done;
+ return urb;
+}
+
+int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
+{
+ int retval = -ENOMEM;
+ struct usb_ctrlrequest *dr;
+ struct urb *urb;
+ struct usb_device *udev;
+ struct usb_device_descriptor *buf;
+ DECLARE_COMPLETION_ONSTACK(done);
+
+ /* Obtain udev of the rhub's child port */
+ udev = usb_hub_find_child(hcd->self.root_hub, port);
+ if (!udev) {
+ dev_err(hcd->self.controller, "No device attached to the RootHub\n");
+ return -ENODEV;
+ }
+ buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
+ if (!dr) {
+ kfree(buf);
+ return -ENOMEM;
+ }
+
+ /* Fill Setup packet for GetDescriptor */
+ dr->bRequestType = USB_DIR_IN;
+ dr->bRequest = USB_REQ_GET_DESCRIPTOR;
+ dr->wValue = cpu_to_le16(USB_DT_DEVICE << 8);
+ dr->wIndex = 0;
+ dr->wLength = cpu_to_le16(USB_DT_DEVICE_SIZE);
+ urb = request_single_step_set_feature_urb(udev, dr, buf, &done);
+ if (!urb)
+ goto cleanup;
+
+ /* Submit just the SETUP stage */
+ retval = hcd->driver->submit_single_step_set_feature(hcd, urb, 1);
+ if (retval)
+ goto out1;
+ if (!wait_for_completion_timeout(&done, msecs_to_jiffies(2000))) {
+ usb_kill_urb(urb);
+ retval = -ETIMEDOUT;
+ dev_err(hcd->self.controller,
+ "%s SETUP stage timed out on ep0\n", __func__);
+ goto out1;
+ }
+ msleep(15 * 1000);
+
+ /* Complete remaining DATA and STATUS stages using the same URB */
+ urb->status = -EINPROGRESS;
+ usb_get_urb(urb);
+ atomic_inc(&urb->use_count);
+ atomic_inc(&urb->dev->urbnum);
+ retval = hcd->driver->submit_single_step_set_feature(hcd, urb, 0);
+ if (!retval && !wait_for_completion_timeout(&done,
+ msecs_to_jiffies(2000))) {
+ usb_kill_urb(urb);
+ retval = -ETIMEDOUT;
+ dev_err(hcd->self.controller,
+ "%s IN stage timed out on ep0\n", __func__);
+ }
+out1:
+ usb_free_urb(urb);
+cleanup:
+ kfree(dr);
+ kfree(buf);
+ return retval;
+}
+EXPORT_SYMBOL_GPL(ehset_single_step_set_feature);
+#endif /* CONFIG_USB_HCD_TEST_MODE */
+
/*-------------------------------------------------------------------------*/
#ifdef CONFIG_PM
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 94b5e64ae9a2..35eec0c0edcd 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1238,6 +1238,10 @@ static const struct hc_driver ehci_hc_driver = {
* device support
*/
.free_dev = ehci_remove_device,
+#ifdef CONFIG_USB_HCD_TEST_MODE
+ /* EH SINGLE_STEP_SET_FEATURE test support */
+ .submit_single_step_set_feature = ehci_submit_single_step_set_feature,
+#endif
};
void ehci_init_driver(struct hc_driver *drv,
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 159cc27b1a36..c4f6a2559a98 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -726,145 +726,6 @@ ehci_hub_descriptor (
desc->wHubCharacteristics = cpu_to_le16(temp);
}
-/*-------------------------------------------------------------------------*/
-#ifdef CONFIG_USB_HCD_TEST_MODE
-
-#define EHSET_TEST_SINGLE_STEP_SET_FEATURE 0x06
-
-static void usb_ehset_completion(struct urb *urb)
-{
- struct completion *done = urb->context;
-
- complete(done);
-}
-static int submit_single_step_set_feature(
- struct usb_hcd *hcd,
- struct urb *urb,
- int is_setup
-);
-
-/*
- * Allocate and initialize a control URB. This request will be used by the
- * EHSET SINGLE_STEP_SET_FEATURE test in which the DATA and STATUS stages
- * of the GetDescriptor request are sent 15 seconds after the SETUP stage.
- * Return NULL if failed.
- */
-static struct urb *request_single_step_set_feature_urb(
- struct usb_device *udev,
- void *dr,
- void *buf,
- struct completion *done
-) {
- struct urb *urb;
- struct usb_hcd *hcd = bus_to_hcd(udev->bus);
- struct usb_host_endpoint *ep;
-
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb)
- return NULL;
-
- urb->pipe = usb_rcvctrlpipe(udev, 0);
- ep = (usb_pipein(urb->pipe) ? udev->ep_in : udev->ep_out)
- [usb_pipeendpoint(urb->pipe)];
- if (!ep) {
- usb_free_urb(urb);
- return NULL;
- }
-
- urb->ep = ep;
- urb->dev = udev;
- urb->setup_packet = (void *)dr;
- urb->transfer_buffer = buf;
- urb->transfer_buffer_length = USB_DT_DEVICE_SIZE;
- urb->complete = usb_ehset_completion;
- urb->status = -EINPROGRESS;
- urb->actual_length = 0;
- urb->transfer_flags = URB_DIR_IN;
- usb_get_urb(urb);
- atomic_inc(&urb->use_count);
- atomic_inc(&urb->dev->urbnum);
- urb->setup_dma = dma_map_single(
- hcd->self.sysdev,
- urb->setup_packet,
- sizeof(struct usb_ctrlrequest),
- DMA_TO_DEVICE);
- urb->transfer_dma = dma_map_single(
- hcd->self.sysdev,
- urb->transfer_buffer,
- urb->transfer_buffer_length,
- DMA_FROM_DEVICE);
- urb->context = done;
- return urb;
-}
-
-static int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
-{
- int retval = -ENOMEM;
- struct usb_ctrlrequest *dr;
- struct urb *urb;
- struct usb_device *udev;
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- struct usb_device_descriptor *buf;
- DECLARE_COMPLETION_ONSTACK(done);
-
- /* Obtain udev of the rhub's child port */
- udev = usb_hub_find_child(hcd->self.root_hub, port);
- if (!udev) {
- ehci_err(ehci, "No device attached to the RootHub\n");
- return -ENODEV;
- }
- buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
- if (!dr) {
- kfree(buf);
- return -ENOMEM;
- }
-
- /* Fill Setup packet for GetDescriptor */
- dr->bRequestType = USB_DIR_IN;
- dr->bRequest = USB_REQ_GET_DESCRIPTOR;
- dr->wValue = cpu_to_le16(USB_DT_DEVICE << 8);
- dr->wIndex = 0;
- dr->wLength = cpu_to_le16(USB_DT_DEVICE_SIZE);
- urb = request_single_step_set_feature_urb(udev, dr, buf, &done);
- if (!urb)
- goto cleanup;
-
- /* Submit just the SETUP stage */
- retval = submit_single_step_set_feature(hcd, urb, 1);
- if (retval)
- goto out1;
- if (!wait_for_completion_timeout(&done, msecs_to_jiffies(2000))) {
- usb_kill_urb(urb);
- retval = -ETIMEDOUT;
- ehci_err(ehci, "%s SETUP stage timed out on ep0\n", __func__);
- goto out1;
- }
- msleep(15 * 1000);
-
- /* Complete remaining DATA and STATUS stages using the same URB */
- urb->status = -EINPROGRESS;
- usb_get_urb(urb);
- atomic_inc(&urb->use_count);
- atomic_inc(&urb->dev->urbnum);
- retval = submit_single_step_set_feature(hcd, urb, 0);
- if (!retval && !wait_for_completion_timeout(&done,
- msecs_to_jiffies(2000))) {
- usb_kill_urb(urb);
- retval = -ETIMEDOUT;
- ehci_err(ehci, "%s IN stage timed out on ep0\n", __func__);
- }
-out1:
- usb_free_urb(urb);
-cleanup:
- kfree(dr);
- kfree(buf);
- return retval;
-}
-#endif /* CONFIG_USB_HCD_TEST_MODE */
/*-------------------------------------------------------------------------*/
int ehci_hub_control(
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index a826715ae9bd..2cbf4f85bff3 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -1165,7 +1165,7 @@ submit_async (
* performed; TRUE - SETUP and FALSE - IN+STATUS
* Returns 0 if success
*/
-static int submit_single_step_set_feature(
+static int ehci_submit_single_step_set_feature(
struct usb_hcd *hcd,
struct urb *urb,
int is_setup
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 96281cd50ff6..22c5d1c0acf3 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -409,7 +409,10 @@ struct hc_driver {
int (*find_raw_port_number)(struct usb_hcd *, int);
/* Call for power on/off the port if necessary */
int (*port_power)(struct usb_hcd *hcd, int portnum, bool enable);
-
+ /* Call for SINGLE_STEP_SET_FEATURE Test for USB2 EH certification */
+#define EHSET_TEST_SINGLE_STEP_SET_FEATURE 0x06
+ int (*submit_single_step_set_feature)(struct usb_hcd *,
+ struct urb *, int);
};
static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd)
@@ -474,6 +477,14 @@ int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr,
struct platform_device;
extern void usb_hcd_platform_shutdown(struct platform_device *dev);
+#ifdef CONFIG_USB_HCD_TEST_MODE
+extern int ehset_single_step_set_feature(struct usb_hcd *hcd, int port);
+#else
+static inline int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
+{
+ return 0;
+}
+#endif /* CONFIG_USB_HCD_TEST_MODE */
#ifdef CONFIG_USB_PCI
struct pci_dev;
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/3] usb: host: xhci: add EH SINGLE_STEP_SET_FEATURE Test for USB2
2021-04-30 6:16 [PATCH v2 1/3] usb: host: move EH SINGLE_STEP_SET_FEATURE implementation to core Li Jun
@ 2021-04-30 6:16 ` Li Jun
2021-04-30 6:16 ` [PATCH v2 3/3] usb: core: hcd: use map_urb_for_dma for single step set feature urb Li Jun
2021-04-30 14:47 ` [PATCH v2 1/3] usb: host: move EH SINGLE_STEP_SET_FEATURE implementation to core Alan Stern
2 siblings, 0 replies; 6+ messages in thread
From: Li Jun @ 2021-04-30 6:16 UTC (permalink / raw)
To: gregkh, stern, mathias.nyman
Cc: peter.chen, jun.li, jackp, linux-usb, linux-imx
From: Peter Chen <peter.chen@nxp.com>
This function is similar with EHCI's, but implemented using XHCI.
The USB2 host needs to send SETUP packet first, then wait 15
seconds before DATA (IN) + STATUS stage.
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Li Jun <jun.li@nxp.com>
---
Change for v2:
- No change.
drivers/usb/host/xhci-hub.c | 10 +++
drivers/usb/host/xhci-ring.c | 123 +++++++++++++++++++++++++++++++++++
drivers/usb/host/xhci.c | 1 +
drivers/usb/host/xhci.h | 10 +++
4 files changed, 144 insertions(+)
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index e9b18fc17617..c64ee95cc89b 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -1511,6 +1511,16 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
/* 4.19.6 Port Test Modes (USB2 Test Mode) */
if (hcd->speed != HCD_USB2)
goto error;
+
+#ifdef CONFIG_USB_HCD_TEST_MODE
+ if (test_mode == EHSET_TEST_SINGLE_STEP_SET_FEATURE) {
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ retval = ehset_single_step_set_feature(hcd,
+ wIndex + 1);
+ spin_lock_irqsave(&xhci->lock, flags);
+ break;
+ }
+#endif
if (test_mode > USB_TEST_FORCE_ENABLE ||
test_mode < USB_TEST_J)
goto error;
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 05c38dd3ee36..87a9c1e3325a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3793,6 +3793,129 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
return 0;
}
+#ifdef CONFIG_USB_HCD_TEST_MODE
+/*
+ * This function prepare TRBs and submits them for the
+ * SINGLE_STEP_SET_FEATURE Test.
+ * This is done in two parts: first SETUP req for GetDesc is sent then
+ * 15 seconds later, the IN stage for GetDesc starts to req data from dev
+ *
+ * is_setup : argument decides which of the two stage needs to be
+ * performed; TRUE - SETUP and FALSE - IN+STATUS
+ * Returns 0 if success
+ */
+int xhci_submit_single_step_set_feature(struct usb_hcd *hcd,
+ struct urb *urb, int is_setup)
+{
+ int slot_id;
+ unsigned int ep_index;
+ struct xhci_ring *ep_ring;
+ int ret;
+ struct usb_ctrlrequest *setup;
+ struct xhci_generic_trb *start_trb;
+ int start_cycle;
+ u32 field, length_field, remainder;
+ struct urb_priv *urb_priv;
+ struct xhci_td *td;
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+
+ /* urb_priv will be free after transcation has completed */
+ urb_priv = kzalloc(sizeof(struct urb_priv) +
+ sizeof(struct xhci_td), GFP_KERNEL);
+ if (!urb_priv)
+ return -ENOMEM;
+
+ td = &urb_priv->td[0];
+ urb_priv->num_tds = 1;
+ urb_priv->num_tds_done = 0;
+ urb->hcpriv = urb_priv;
+
+ ep_ring = xhci_urb_to_transfer_ring(xhci, urb);
+ if (!ep_ring) {
+ ret = -EINVAL;
+ goto free_priv;
+ }
+
+ slot_id = urb->dev->slot_id;
+ ep_index = xhci_get_endpoint_index(&urb->ep->desc);
+
+ setup = (struct usb_ctrlrequest *) urb->setup_packet;
+ if (is_setup) {
+ ret = prepare_transfer(xhci, xhci->devs[slot_id],
+ ep_index, urb->stream_id,
+ 1, urb, 0, GFP_KERNEL);
+ if (ret < 0)
+ goto free_priv;
+
+ start_trb = &ep_ring->enqueue->generic;
+ start_cycle = ep_ring->cycle_state;
+ /* Save the DMA address of the last TRB in the TD */
+ td->last_trb = ep_ring->enqueue;
+ field = TRB_IOC | TRB_IDT | TRB_TYPE(TRB_SETUP) | start_cycle;
+ /* xHCI 1.0/1.1 6.4.1.2.1: Transfer Type field */
+ if ((xhci->hci_version >= 0x100) ||
+ (xhci->quirks & XHCI_MTK_HOST))
+ field |= TRB_TX_TYPE(TRB_DATA_IN);
+
+ queue_trb(xhci, ep_ring, false,
+ setup->bRequestType | setup->bRequest << 8 |
+ le16_to_cpu(setup->wValue) << 16,
+ le16_to_cpu(setup->wIndex) |
+ le16_to_cpu(setup->wLength) << 16,
+ TRB_LEN(8) | TRB_INTR_TARGET(0),
+ /* Immediate data in pointer */
+ field);
+ giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
+ start_cycle, start_trb);
+ return 0;
+ }
+
+ ret = prepare_transfer(xhci, xhci->devs[slot_id],
+ ep_index, urb->stream_id,
+ 2, urb, 0, GFP_KERNEL);
+ if (ret < 0)
+ goto free_priv;
+
+ start_trb = &ep_ring->enqueue->generic;
+ start_cycle = ep_ring->cycle_state;
+ field = TRB_ISP | TRB_TYPE(TRB_DATA);
+
+ remainder = xhci_td_remainder(xhci, 0,
+ urb->transfer_buffer_length,
+ urb->transfer_buffer_length,
+ urb, 1);
+
+ length_field = TRB_LEN(urb->transfer_buffer_length) |
+ TRB_TD_SIZE(remainder) |
+ TRB_INTR_TARGET(0);
+
+ if (urb->transfer_buffer_length > 0) {
+ field |= TRB_DIR_IN;
+ queue_trb(xhci, ep_ring, true,
+ lower_32_bits(urb->transfer_dma),
+ upper_32_bits(urb->transfer_dma),
+ length_field,
+ field | ep_ring->cycle_state);
+ }
+
+ td->last_trb = ep_ring->enqueue;
+ field = TRB_IOC | TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state;
+ queue_trb(xhci, ep_ring, false,
+ 0,
+ 0,
+ TRB_INTR_TARGET(0),
+ field);
+
+ giveback_first_trb(xhci, slot_id, ep_index, 0,
+ start_cycle, start_trb);
+
+ return 0;
+free_priv:
+ xhci_urb_free_priv(urb_priv);
+ return ret;
+}
+#endif /* CONFIG_USB_HCD_TEST_MODE */
+
/*
* The transfer burst count field of the isochronous TRB defines the number of
* bursts that are required to move all packets in this TD. Only SuperSpeed
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ca9385d22f68..a27616775845 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -5426,6 +5426,7 @@ static const struct hc_driver xhci_hc_driver = {
.disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout,
.find_raw_port_number = xhci_find_raw_port_number,
.clear_tt_buffer_complete = xhci_clear_tt_buffer_complete,
+ .submit_single_step_set_feature = xhci_submit_single_step_set_feature,
};
void xhci_init_driver(struct hc_driver *drv,
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 2595a8f057c4..f93fc8f59af6 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -2165,6 +2165,16 @@ int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1);
struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd);
void xhci_hc_died(struct xhci_hcd *xhci);
+#ifdef CONFIG_USB_HCD_TEST_MODE
+int xhci_submit_single_step_set_feature(struct usb_hcd *hcd,
+ struct urb *urb, int is_setup);
+#else
+static inline int xhci_submit_single_step_set_feature(struct usb_hcd *hcd,
+ struct urb *urb, int is_setup)
+{
+ return 0;
+}
+#endif
#ifdef CONFIG_PM
int xhci_bus_suspend(struct usb_hcd *hcd);
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 3/3] usb: core: hcd: use map_urb_for_dma for single step set feature urb
2021-04-30 6:16 [PATCH v2 1/3] usb: host: move EH SINGLE_STEP_SET_FEATURE implementation to core Li Jun
2021-04-30 6:16 ` [PATCH v2 2/3] usb: host: xhci: add EH SINGLE_STEP_SET_FEATURE Test for USB2 Li Jun
@ 2021-04-30 6:16 ` Li Jun
2021-04-30 14:49 ` Alan Stern
2021-04-30 14:47 ` [PATCH v2 1/3] usb: host: move EH SINGLE_STEP_SET_FEATURE implementation to core Alan Stern
2 siblings, 1 reply; 6+ messages in thread
From: Li Jun @ 2021-04-30 6:16 UTC (permalink / raw)
To: gregkh, stern, mathias.nyman
Cc: peter.chen, jun.li, jackp, linux-usb, linux-imx
Use map_urb_for_dma() to improve the dma map code for single step
set feature request urb in test mode.
Signed-off-by: Li Jun <jun.li@nxp.com>
---
change for v2:
- Add this new patch to use map_urb_for_dma API to
replace both of dma_map_single() calls, suggested by
Jack Pham.
drivers/usb/core/hcd.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index d7eb9f179ca6..0b89a3dc99a3 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2159,16 +2159,8 @@ static struct urb *request_single_step_set_feature_urb(
usb_get_urb(urb);
atomic_inc(&urb->use_count);
atomic_inc(&urb->dev->urbnum);
- urb->setup_dma = dma_map_single(
- hcd->self.sysdev,
- urb->setup_packet,
- sizeof(struct usb_ctrlrequest),
- DMA_TO_DEVICE);
- urb->transfer_dma = dma_map_single(
- hcd->self.sysdev,
- urb->transfer_buffer,
- urb->transfer_buffer_length,
- DMA_FROM_DEVICE);
+ if (map_urb_for_dma(hcd, urb, GFP_KERNEL))
+ unmap_urb_for_dma(hcd, urb);
urb->context = done;
return urb;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/3] usb: host: move EH SINGLE_STEP_SET_FEATURE implementation to core
2021-04-30 6:16 [PATCH v2 1/3] usb: host: move EH SINGLE_STEP_SET_FEATURE implementation to core Li Jun
2021-04-30 6:16 ` [PATCH v2 2/3] usb: host: xhci: add EH SINGLE_STEP_SET_FEATURE Test for USB2 Li Jun
2021-04-30 6:16 ` [PATCH v2 3/3] usb: core: hcd: use map_urb_for_dma for single step set feature urb Li Jun
@ 2021-04-30 14:47 ` Alan Stern
2 siblings, 0 replies; 6+ messages in thread
From: Alan Stern @ 2021-04-30 14:47 UTC (permalink / raw)
To: Li Jun; +Cc: gregkh, mathias.nyman, peter.chen, jackp, linux-usb, linux-imx
On Fri, Apr 30, 2021 at 02:16:31PM +0800, Li Jun wrote:
> From: Peter Chen <peter.chen@nxp.com>
>
> It is needed at USB Certification test for Embedded Host 2.0, and
> the detail is at CH6.4.1.1 of On-The-Go and Embedded Host Supplement
> to the USB Revision 2.0 Specification. Since other USB 2.0 capable
> host like XHCI also need it, so move it to HCD core.
>
> Signed-off-by: Peter Chen <peter.chen@nxp.com>
> Signed-off-by: Li Jun <jun.li@nxp.com>
> ---
Acked-by: Alan Stern <stern@rowland.harvard.edu>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 3/3] usb: core: hcd: use map_urb_for_dma for single step set feature urb
2021-04-30 6:16 ` [PATCH v2 3/3] usb: core: hcd: use map_urb_for_dma for single step set feature urb Li Jun
@ 2021-04-30 14:49 ` Alan Stern
2021-05-06 11:51 ` Jun Li
0 siblings, 1 reply; 6+ messages in thread
From: Alan Stern @ 2021-04-30 14:49 UTC (permalink / raw)
To: Li Jun; +Cc: gregkh, mathias.nyman, peter.chen, jackp, linux-usb, linux-imx
On Fri, Apr 30, 2021 at 02:16:33PM +0800, Li Jun wrote:
> Use map_urb_for_dma() to improve the dma map code for single step
> set feature request urb in test mode.
>
> Signed-off-by: Li Jun <jun.li@nxp.com>
> ---
> change for v2:
> - Add this new patch to use map_urb_for_dma API to
> replace both of dma_map_single() calls, suggested by
> Jack Pham.
>
> drivers/usb/core/hcd.c | 12 ++----------
> 1 file changed, 2 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
> index d7eb9f179ca6..0b89a3dc99a3 100644
> --- a/drivers/usb/core/hcd.c
> +++ b/drivers/usb/core/hcd.c
> @@ -2159,16 +2159,8 @@ static struct urb *request_single_step_set_feature_urb(
> usb_get_urb(urb);
> atomic_inc(&urb->use_count);
> atomic_inc(&urb->dev->urbnum);
> - urb->setup_dma = dma_map_single(
> - hcd->self.sysdev,
> - urb->setup_packet,
> - sizeof(struct usb_ctrlrequest),
> - DMA_TO_DEVICE);
> - urb->transfer_dma = dma_map_single(
> - hcd->self.sysdev,
> - urb->transfer_buffer,
> - urb->transfer_buffer_length,
> - DMA_FROM_DEVICE);
> + if (map_urb_for_dma(hcd, urb, GFP_KERNEL))
> + unmap_urb_for_dma(hcd, urb);
That looks awfully weird. Are you sure about it?
Alan Stern
> urb->context = done;
> return urb;
> }
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: [PATCH v2 3/3] usb: core: hcd: use map_urb_for_dma for single step set feature urb
2021-04-30 14:49 ` Alan Stern
@ 2021-05-06 11:51 ` Jun Li
0 siblings, 0 replies; 6+ messages in thread
From: Jun Li @ 2021-05-06 11:51 UTC (permalink / raw)
To: Alan Stern
Cc: gregkh, mathias.nyman, peter.chen, jackp, linux-usb, dl-linux-imx
> -----Original Message-----
> From: Alan Stern <stern@rowland.harvard.edu>
> Sent: Friday, April 30, 2021 10:49 PM
> To: Jun Li <jun.li@nxp.com>
> Cc: gregkh@linuxfoundation.org; mathias.nyman@intel.com;
> peter.chen@kernel.org; jackp@codeaurora.org; linux-usb@vger.kernel.org;
> dl-linux-imx <linux-imx@nxp.com>
> Subject: Re: [PATCH v2 3/3] usb: core: hcd: use map_urb_for_dma for single
> step set feature urb
>
> On Fri, Apr 30, 2021 at 02:16:33PM +0800, Li Jun wrote:
> > Use map_urb_for_dma() to improve the dma map code for single step set
> > feature request urb in test mode.
> >
> > Signed-off-by: Li Jun <jun.li@nxp.com>
> > ---
> > change for v2:
> > - Add this new patch to use map_urb_for_dma API to
> > replace both of dma_map_single() calls, suggested by
> > Jack Pham.
> >
> > drivers/usb/core/hcd.c | 12 ++----------
> > 1 file changed, 2 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index
> > d7eb9f179ca6..0b89a3dc99a3 100644
> > --- a/drivers/usb/core/hcd.c
> > +++ b/drivers/usb/core/hcd.c
> > @@ -2159,16 +2159,8 @@ static struct urb
> *request_single_step_set_feature_urb(
> > usb_get_urb(urb);
> > atomic_inc(&urb->use_count);
> > atomic_inc(&urb->dev->urbnum);
> > - urb->setup_dma = dma_map_single(
> > - hcd->self.sysdev,
> > - urb->setup_packet,
> > - sizeof(struct usb_ctrlrequest),
> > - DMA_TO_DEVICE);
> > - urb->transfer_dma = dma_map_single(
> > - hcd->self.sysdev,
> > - urb->transfer_buffer,
> > - urb->transfer_buffer_length,
> > - DMA_FROM_DEVICE);
> > + if (map_urb_for_dma(hcd, urb, GFP_KERNEL))
> > + unmap_urb_for_dma(hcd, urb);
>
> That looks awfully weird. Are you sure about it?
Oops, will update the "awfully weird" error handling in v3.
Thanks
Li Jun
>
> Alan Stern
>
> > urb->context = done;
> > return urb;
> > }
> > --
> > 2.25.1
> >
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-05-06 11:51 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-30 6:16 [PATCH v2 1/3] usb: host: move EH SINGLE_STEP_SET_FEATURE implementation to core Li Jun
2021-04-30 6:16 ` [PATCH v2 2/3] usb: host: xhci: add EH SINGLE_STEP_SET_FEATURE Test for USB2 Li Jun
2021-04-30 6:16 ` [PATCH v2 3/3] usb: core: hcd: use map_urb_for_dma for single step set feature urb Li Jun
2021-04-30 14:49 ` Alan Stern
2021-05-06 11:51 ` Jun Li
2021-04-30 14:47 ` [PATCH v2 1/3] usb: host: move EH SINGLE_STEP_SET_FEATURE implementation to core Alan Stern
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).