summaryrefslogtreecommitdiff
path: root/drivers/usb/usbip/usbip_common.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-10-07 16:48:26 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-10-07 16:48:26 -0700
commitd3dcbe24a0fc6373ce7e4a65acd5c785aa8e2396 (patch)
tree2072b4977f2e22f0b51bd7e48f131c48c14e896d /drivers/usb/usbip/usbip_common.c
parent6181073dd6a7e5deafc60e7981bd765b6c93da8c (diff)
parent00988f70a0763f14c97c4c0df76fb9aa4959e953 (diff)
downloadlinux-d3dcbe24a0fc6373ce7e4a65acd5c785aa8e2396.tar.gz
linux-d3dcbe24a0fc6373ce7e4a65acd5c785aa8e2396.tar.bz2
linux-d3dcbe24a0fc6373ce7e4a65acd5c785aa8e2396.zip
Merge tag 'usb-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB / Thunderbolt updates from Greg KH: "Here is the big set of USB and Thunderbolt driver changes for 6.1-rc1. Nothing major in here, lots of little things with new devices supported and updates for a few drivers. Highlights include: - thunderbolt/USB4 devices supported a bit better than before, and some new ids to enable new hardware devices - USB gadget uvc updates for newer video formats and better v4l integration (the v4l portions were acked by those maintainers) - typec updates for tiny issues and more typec drivers for new chips. - xhci tiny updates for minor issues - big usb-serial ftdi_sio driver update to handle new devices better - lots of tiny dwc3 fixes and updates for the IP block that is showing up everywhere these days - dts updates for new devices being supported - other tiny janitorial and cleanups fixes for lots of different USB drivers. Full details are in the shortlog. All of these have been in linux-next for a while with no reported issues" * tag 'usb-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (169 commits) usb: gadget: uvc: don't put item still in use usb: gadget: uvc: Fix argument to sizeof() in uvc_register_video() usb: host: ehci-exynos: switch to using gpiod API Revert "usb: dwc3: Don't switch OTG -> peripheral if extcon is present" Revert "USB: fixup for merge issue with "usb: dwc3: Don't switch OTG -> peripheral if extcon is present"" dt-bindings: usb: Convert FOTG210 to dt schema usb: mtu3: fix failed runtime suspend in host only mode USB: omap_udc: Fix spelling mistake: "tranceiver_ctrl" -> "transceiver_ctrl" usb: typec: ucsi_ccg: Disable UCSI ALT support on Tegra usb: typec: Replace custom implementation of device_match_fwnode() usb: typec: ucsi: Don't warn on probe deferral usb: add quirks for Lenovo OneLink+ Dock MAINTAINERS: switch dwc3 to Thinh usb: idmouse: fix an uninit-value in idmouse_open USB: PHY: JZ4770: Switch to use dev_err_probe() helper usb: phy: generic: Switch to use dev_err_probe() helper usb: ulpi: use DEFINE_SHOW_ATTRIBUTE to simplify ulpi_regs usb: cdns3: remove dead code usb: cdc-wdm: Use skb_put_data() instead of skb_put/memcpy pair usb: musb: sunxi: Switch to use dev_err_probe() helper ...
Diffstat (limited to 'drivers/usb/usbip/usbip_common.c')
-rw-r--r--drivers/usb/usbip/usbip_common.c91
1 files changed, 88 insertions, 3 deletions
diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c
index 2ab99244bc31..053a2bca4c47 100644
--- a/drivers/usb/usbip/usbip_common.c
+++ b/drivers/usb/usbip/usbip_common.c
@@ -344,6 +344,91 @@ static unsigned int tweak_transfer_flags(unsigned int flags)
return flags;
}
+/*
+ * USBIP driver packs URB transfer flags in PDUs that are exchanged
+ * between Server (usbip_host) and Client (vhci_hcd). URB_* flags
+ * are internal to kernel and could change. Where as USBIP URB flags
+ * exchanged in PDUs are USBIP user API must not change.
+ *
+ * USBIP_URB* flags are exported as explicit API and client and server
+ * do mapping from kernel flags to USBIP_URB*. Details as follows:
+ *
+ * Client tx path (USBIP_CMD_SUBMIT):
+ * - Maps URB_* to USBIP_URB_* when it sends USBIP_CMD_SUBMIT packet.
+ *
+ * Server rx path (USBIP_CMD_SUBMIT):
+ * - Maps USBIP_URB_* to URB_* when it receives USBIP_CMD_SUBMIT packet.
+ *
+ * Flags aren't included in USBIP_CMD_UNLINK and USBIP_RET_SUBMIT packets
+ * and no special handling is needed for them in the following cases:
+ * - Server rx path (USBIP_CMD_UNLINK)
+ * - Client rx path & Server tx path (USBIP_RET_SUBMIT)
+ *
+ * Code paths:
+ * usbip_pack_pdu() is the common routine that handles packing pdu from
+ * urb and unpack pdu to an urb.
+ *
+ * usbip_pack_cmd_submit() and usbip_pack_ret_submit() handle
+ * USBIP_CMD_SUBMIT and USBIP_RET_SUBMIT respectively.
+ *
+ * usbip_map_urb_to_usbip() and usbip_map_usbip_to_urb() are used
+ * by usbip_pack_cmd_submit() and usbip_pack_ret_submit() to map
+ * flags.
+ */
+
+struct urb_to_usbip_flags {
+ u32 urb_flag;
+ u32 usbip_flag;
+};
+
+#define NUM_USBIP_FLAGS 17
+
+static const struct urb_to_usbip_flags flag_map[NUM_USBIP_FLAGS] = {
+ {URB_SHORT_NOT_OK, USBIP_URB_SHORT_NOT_OK},
+ {URB_ISO_ASAP, USBIP_URB_ISO_ASAP},
+ {URB_NO_TRANSFER_DMA_MAP, USBIP_URB_NO_TRANSFER_DMA_MAP},
+ {URB_ZERO_PACKET, USBIP_URB_ZERO_PACKET},
+ {URB_NO_INTERRUPT, USBIP_URB_NO_INTERRUPT},
+ {URB_FREE_BUFFER, USBIP_URB_FREE_BUFFER},
+ {URB_DIR_IN, USBIP_URB_DIR_IN},
+ {URB_DIR_OUT, USBIP_URB_DIR_OUT},
+ {URB_DIR_MASK, USBIP_URB_DIR_MASK},
+ {URB_DMA_MAP_SINGLE, USBIP_URB_DMA_MAP_SINGLE},
+ {URB_DMA_MAP_PAGE, USBIP_URB_DMA_MAP_PAGE},
+ {URB_DMA_MAP_SG, USBIP_URB_DMA_MAP_SG},
+ {URB_MAP_LOCAL, USBIP_URB_MAP_LOCAL},
+ {URB_SETUP_MAP_SINGLE, USBIP_URB_SETUP_MAP_SINGLE},
+ {URB_SETUP_MAP_LOCAL, USBIP_URB_SETUP_MAP_LOCAL},
+ {URB_DMA_SG_COMBINED, USBIP_URB_DMA_SG_COMBINED},
+ {URB_ALIGNED_TEMP_BUFFER, USBIP_URB_ALIGNED_TEMP_BUFFER},
+};
+
+static unsigned int urb_to_usbip(unsigned int flags)
+{
+ unsigned int map_flags = 0;
+ int loop;
+
+ for (loop = 0; loop < NUM_USBIP_FLAGS; loop++) {
+ if (flags & flag_map[loop].urb_flag)
+ map_flags |= flag_map[loop].usbip_flag;
+ }
+
+ return map_flags;
+}
+
+static unsigned int usbip_to_urb(unsigned int flags)
+{
+ unsigned int map_flags = 0;
+ int loop;
+
+ for (loop = 0; loop < NUM_USBIP_FLAGS; loop++) {
+ if (flags & flag_map[loop].usbip_flag)
+ map_flags |= flag_map[loop].urb_flag;
+ }
+
+ return map_flags;
+}
+
static void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb,
int pack)
{
@@ -354,14 +439,14 @@ static void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb,
* will be discussed when usbip is ported to other operating systems.
*/
if (pack) {
- spdu->transfer_flags =
- tweak_transfer_flags(urb->transfer_flags);
+ /* map after tweaking the urb flags */
+ spdu->transfer_flags = urb_to_usbip(tweak_transfer_flags(urb->transfer_flags));
spdu->transfer_buffer_length = urb->transfer_buffer_length;
spdu->start_frame = urb->start_frame;
spdu->number_of_packets = urb->number_of_packets;
spdu->interval = urb->interval;
} else {
- urb->transfer_flags = spdu->transfer_flags;
+ urb->transfer_flags = usbip_to_urb(spdu->transfer_flags);
urb->transfer_buffer_length = spdu->transfer_buffer_length;
urb->start_frame = spdu->start_frame;
urb->number_of_packets = spdu->number_of_packets;