usb: host: move EH SINGLE_STEP_SET_FEATURE implementation to core
Subsystems (3)
PATCH v3 1/3 usb: host: move EH SINGLE_STEP_SET_FEATURE implementation to core
From: Peter Chen <[email protected]>
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.
---
Change for v3:
- Add Alan's A-b tag.
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(-)
drivers/usb/core/hcd.c +134 -0
@@ -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
drivers/usb/host/ehci-hcd.c +4 -0
@@ -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,
drivers/usb/host/ehci-hub.c +0 -139
145 lines not on this page · raw message
drivers/usb/host/ehci-q.c +1 -1
@@ -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
include/linux/usb/hcd.h +12 -1
@@ -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 ;
Signature · 1 line
2.25.1
PATCH v3 2/3 usb: host: xhci: add EH SINGLE_STEP_SET_FEATURE Test for USB2
From: Peter Chen <[email protected]>
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.
---
Change for v3:
- No change.
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(+)
drivers/usb/host/xhci-hub.c +10 -0
@@ -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;
drivers/usb/host/xhci-ring.c +123 -0
129 lines not on this page · raw message
drivers/usb/host/xhci.c +1 -0
@@ -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,
drivers/usb/host/xhci.h +10 -0
@@ -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);
Signature · 1 line
2.25.1
RE: [PATCH v3 2/3] usb: host: xhci: add EH SINGLE_STEP_SET_FEATURE Test for USB2
Quoted 226 lines
-----Original Message-----
From: Jun Li <[email protected]>
Sent: Friday, May 7, 2021 2:58 PM
To: [email protected]; [email protected]; [email protected]
Cc: [email protected]; Jun Li <[email protected]>; [email protected]; [email protected]; dl-linux-imx <[email protected]>
Subject: [PATCH v3 2/3] usb: host: xhci: add EHSINGLE_STEP_SET_FEATURETest for USB2From: Peter Chen <[email protected]>
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 <[email protected]>Signed-off-by Li Jun <[email protected]>---
Change for v3:
- No change.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(+)drivers/usb/host/xhci-hub.c +10
-0@@ -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 )drivers/usb/host/xhci-hub.c +0
-0goto error;drivers/usb/host/xhci-ring.c +124
-0@@ -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 SuperSpeeddrivers/usb/host/xhci.c index renamed from drivers/usb/host/xhci.c +0
-0
ca9385d22f68..a27616775845100644drivers/usb/host/xhci.c +1
-0@@ -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 --gita/drivers/usb/host/xhci.hb/drivers/usb/host/xhci.hindex2595a8f057c4..f93fc8f59af6100644drivers/usb/host/xhci.h +10
-0@@ -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
Quoted 3 lines
int
xhci_bus_suspend(struct usb_hcd *hcd);
--
2.25.1
A gentle ping.
Li Jun
RE: [PATCH v3 2/3] usb: host: xhci: add EH SINGLE_STEP_SET_FEATURE Test for USB2
Hi Mathias,
Quoted 240 lines
-----Original Message-----
From: Jun Li
Sent: Friday, June 11, 2021 5:19 PM
To: [email protected]
Cc: [email protected]; [email protected]; [email protected]; dl-linux-imx <[email protected]>; [email protected]; [email protected]
Subject: RE: [PATCH v3 2/3] usb: host: xhci: add EHSINGLE_STEP_SET_FEATURETest for USB2Quoted 228 lines
-----Original Message-----
From: Jun Li <[email protected]>
Sent: Friday, May 7, 2021 2:58 PM
To: [email protected]; [email protected]; [email protected]
Cc: [email protected]; Jun Li <[email protected]>; [email protected]; [email protected]; dl-linux-imx <[email protected]>
Subject: [PATCH v3 2/3] usb: host: xhci: add EHSINGLE_STEP_SET_FEATURETest for USB2From: Peter Chen <[email protected]>
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 <[email protected]>Signed-off-by Li Jun <[email protected]>---
Change for v3:
- No change.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(+)drivers/usb/host/xhci-hub.c +10
-0@@ -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 ||drivers/usb/host/xhci-hub.c +0
-0test_mode < USB_TEST_J) goto error;(quoted diff) +0
-0
b/drivers/usb/host/xhci-ring.cindex05c38dd3ee36..87a9c1e3325a100644drivers/usb/host/xhci-ring.c +125
-0@@ -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 --gita/drivers/usb/host/xhci.cb/drivers/usb/host/xhci.cindexca9385d22f68..a27616775845100644drivers/usb/host/xhci.c +1
-0@@ -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 --gita/drivers/usb/host/xhci.hb/drivers/usb/host/xhci.hindex2595a8f057c4..f93fc8f59af6100644drivers/usb/host/xhci.h +10
-0@@ -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
Quoted 6 lines
Quoted 4 lines
#ifdef
CONFIG_PM
intxhci_bus_suspend(struct usb_hcd *hcd);
--
2.25.1A gentle ping.
Could you please take a look this patch?
Thanks
Quoted 1 line
Li Jun
Re: [PATCH v3 2/3] usb: host: xhci: add EH SINGLE_STEP_SET_FEATURE Test for USB2
Hi
Quoted 14 lines · Jun Li
Hi Mathias,
Quoted 12 lines
-----Original Message-----
From: Jun Li
Sent: Friday, June 11, 2021 5:19 PM
To: [email protected]
Cc: [email protected]; [email protected]; [email protected]; dl-linux-imx <[email protected]>; [email protected]; [email protected]
Subject: RE: [PATCH v3 2/3] usb: host: xhci: add EHSINGLE_STEP_SET_FEATURETest for USB2
Quoted 3 lines
Quoted 1 line
Quoted 1 line
A gentle ping.
Could you please take a look this patch?
This somehow fell through the cracks, sorry.
I'll be away for two weeks so this will unfortunately be delayed even more. Sorry about this.
-Mathias
RE: [PATCH v3 2/3] usb: host: xhci: add EH SINGLE_STEP_SET_FEATURE Test for USB2
Hi Mathias,
Quoted 27 lines
-----Original Message-----
From: Mathias Nyman <[email protected]>
Sent: Friday, July 16, 2021 10:35 PM
To: Jun Li <[email protected]>; [email protected]
Cc: [email protected]; [email protected]; [email protected]; dl-linux-imx <[email protected]>; [email protected]; [email protected]
Subject: Re: [PATCH v3 2/3] usb: host: xhci: add EHSINGLE_STEP_SET_FEATURETest for USB2Hi
Quoted 14 lines · Jun Li
Hi Mathias,
Quoted 12 lines
-----Original Message-----
From: Jun Li
Sent: Friday, June 11, 2021 5:19 PM
To: [email protected]
Cc: [email protected]; [email protected]; [email protected]; dl-linux-imx <[email protected]>; [email protected]; [email protected]
Subject: RE: [PATCH v3 2/3] usb: host: xhci: add EHSINGLE_STEP_SET_FEATURETest for USB2
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line
A gentle ping.
Could you please take a look this patch?
This somehow fell through the cracks, sorry.
I'll be away for two weeks so this will unfortunately be delayed even more. Sorry about this.
Seems this patch is still missed, ping again.
Li Jun
Quoted 3 lines
-Mathias
PATCH v3 3/3 usb: core: hcd: use map_urb_for_dma for single step set feature urb
In reply to Li JunUse map_urb_for_dma() to improve the dma map code for single step set feature request urb in test mode.
---
Change for v3:
- Correct the error handling if map_urb_for_dma() fails.
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 | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
drivers/usb/core/hcd.c +5 -10
@@ -2159,16 +2159,11 @@ 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 )) { +usb_put_urb (urb); +return NULL ; + } + urb->context = done;return urb; }
Signature · 1 line
2.25.1
Alan Stern
maintainerRe: [PATCH v3 3/3] usb: core: hcd: use map_urb_for_dma for single step set feature urb
Quoted 26 lines · Li Jun
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 <[email protected]>---
Change for v3:
- Correct the error handling ifmap_urb_for_dma()fails.change for v2:
- Add this new patch to usemap_urb_for_dmaAPI to replace both ofdma_map_single()calls, suggested by Jack Pham.drivers/usb/core/hcd.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)drivers/usb/core/hcd.c +0
-2@@ -2159,16 +2159,11 @@ 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,
drivers/usb/core/hcd.c static struct urb *request_single_step_set_feature_urb( · line 2163
Quoted 10 lines
drivers/usb/core/hcd.c +2
-8- 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 )) { +usb_put_urb (urb);
You need to call usb_free_urb() here.
Alan Stern
Quoted 9 lines
drivers/usb/core/hcd.c +3
-0+return NULL ; + } + urb->context = done;return urb; }Signature · 1 line
2.25.1
Re: [PATCH v3 3/3] usb: core: hcd: use map_urb_for_dma for single step set feature urb
Quoted 31 lines · Alan Stern
Quoted 30 lines · Li Jun
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 <[email protected]>---
Change for v3:
- Correct the error handling ifmap_urb_for_dma()fails.change for v2:
- Add this new patch to usemap_urb_for_dmaAPI to replace both ofdma_map_single()calls, suggested by Jack Pham.drivers/usb/core/hcd.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)drivers/usb/core/hcd.c +0
-6@@ -2159,16 +2159,11 @@ 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(
Quoted 8 lines
drivers/usb/core/hcd.c static struct urb *request_single_step_set_feature_urb( · line 2163
Quoted 6 lines
drivers/usb/core/hcd.c +2
-4- hcd->self.sysdev, - urb->transfer_buffer, - urb->transfer_buffer_length, - DMA_FROM_DEVICE); +if (map_urb_for_dma (hcd, urb,GFP_KERNEL )) { +usb_put_urb (urb);You need to call
usb_free_urb()here.
Hi Alan,
Aren't usb_put_urb() and usb_free_urb() identical? The former appears to just be a macro subsitution of the latter.
Jack
Quoted 9 lines
Quoted 9 lines
drivers/usb/core/hcd.c +3
-0+return NULL ; + } + urb->context = done;return urb; }Signature · 1 line
2.25.1
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Alan Stern
maintainerRe: [PATCH v3 3/3] usb: core: hcd: use map_urb_for_dma for single step set feature urb
Quoted 41 lines · Jack Pham
Quoted 31 lines · Alan Stern
Quoted 30 lines · Li Jun
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 <[email protected]>---
Change for v3:
- Correct the error handling ifmap_urb_for_dma()fails.change for v2:
- Add this new patch to usemap_urb_for_dmaAPI to replace both ofdma_map_single()calls, suggested by Jack Pham.drivers/usb/core/hcd.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)drivers/usb/core/hcd.c +0
-6@@ -2159,16 +2159,11 @@ 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(Quoted 8 lines
drivers/usb/core/hcd.c static struct urb *request_single_step_set_feature_urb( · line 2163
Quoted 6 lines
drivers/usb/core/hcd.c +2
-4- hcd->self.sysdev, - urb->transfer_buffer, - urb->transfer_buffer_length, - DMA_FROM_DEVICE); +if (map_urb_for_dma (hcd, urb,GFP_KERNEL )) { +usb_put_urb (urb);You need to call
usb_free_urb()here.
Quoted 4 lines
Hi Alan,
Aren't
usb_put_urb()andusb_free_urb()identical? The former appears to just be a macro subsitution of the latter.
Yes, they are identical, although that's more or less an historical accident. usb_free_urb was written before the refcount API came along.
The usb_put_urb() call here undoes the usb_get_urb() call at the top of the patch. You still need one more call to decrease the refcount to 0.
Alan Stern