Commit 6080cd0e authored by Valentina Manea's avatar Valentina Manea Committed by Greg Kroah-Hartman

staging: usbip: claim ports used by shared devices

A device should not be able to be used concurrently both by
the server and the client. Claiming the port used by the
shared device ensures no interface drivers bind to it and
that it is not usable from the server.
Signed-off-by: default avatarValentina Manea <valentina.manea.m@gmail.com>
Acked-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a46034ca
...@@ -339,6 +339,7 @@ static int stub_probe(struct usb_device *udev) ...@@ -339,6 +339,7 @@ static int stub_probe(struct usb_device *udev)
const char *udev_busid = dev_name(&udev->dev); const char *udev_busid = dev_name(&udev->dev);
int err = 0; int err = 0;
struct bus_id_priv *busid_priv; struct bus_id_priv *busid_priv;
int rc;
dev_dbg(&udev->dev, "Enter\n"); dev_dbg(&udev->dev, "Enter\n");
...@@ -388,6 +389,18 @@ static int stub_probe(struct usb_device *udev) ...@@ -388,6 +389,18 @@ static int stub_probe(struct usb_device *udev)
busid_priv->sdev = sdev; busid_priv->sdev = sdev;
busid_priv->udev = udev; busid_priv->udev = udev;
/*
* Claim this hub port.
* It doesn't matter what value we pass as owner
* (struct dev_state) as long as it is unique.
*/
rc = usb_hub_claim_port(udev->parent, udev->portnum,
(struct dev_state *) udev);
if (rc) {
dev_dbg(&udev->dev, "unable to claim port\n");
return rc;
}
err = stub_add_files(&udev->dev); err = stub_add_files(&udev->dev);
if (err) { if (err) {
dev_err(&udev->dev, "stub_add_files for %s\n", udev_busid); dev_err(&udev->dev, "stub_add_files for %s\n", udev_busid);
...@@ -424,6 +437,7 @@ static void stub_disconnect(struct usb_device *udev) ...@@ -424,6 +437,7 @@ static void stub_disconnect(struct usb_device *udev)
struct stub_device *sdev; struct stub_device *sdev;
const char *udev_busid = dev_name(&udev->dev); const char *udev_busid = dev_name(&udev->dev);
struct bus_id_priv *busid_priv; struct bus_id_priv *busid_priv;
int rc;
dev_dbg(&udev->dev, "Enter\n"); dev_dbg(&udev->dev, "Enter\n");
...@@ -448,6 +462,14 @@ static void stub_disconnect(struct usb_device *udev) ...@@ -448,6 +462,14 @@ static void stub_disconnect(struct usb_device *udev)
*/ */
stub_remove_files(&udev->dev); stub_remove_files(&udev->dev);
/* release port */
rc = usb_hub_release_port(udev->parent, udev->portnum,
(struct dev_state *) udev);
if (rc) {
dev_dbg(&udev->dev, "unable to release port\n");
return;
}
/* If usb reset is called from event handler */ /* If usb reset is called from event handler */
if (busid_priv->sdev->ud.eh == current) if (busid_priv->sdev->ud.eh == current)
return; return;
......
...@@ -1819,6 +1819,7 @@ int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, ...@@ -1819,6 +1819,7 @@ int usb_hub_claim_port(struct usb_device *hdev, unsigned port1,
*powner = owner; *powner = owner;
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(usb_hub_claim_port);
int usb_hub_release_port(struct usb_device *hdev, unsigned port1, int usb_hub_release_port(struct usb_device *hdev, unsigned port1,
struct dev_state *owner) struct dev_state *owner)
...@@ -1834,6 +1835,7 @@ int usb_hub_release_port(struct usb_device *hdev, unsigned port1, ...@@ -1834,6 +1835,7 @@ int usb_hub_release_port(struct usb_device *hdev, unsigned port1,
*powner = NULL; *powner = NULL;
return rc; return rc;
} }
EXPORT_SYMBOL_GPL(usb_hub_release_port);
void usb_hub_release_all_ports(struct usb_device *hdev, struct dev_state *owner) void usb_hub_release_all_ports(struct usb_device *hdev, struct dev_state *owner)
{ {
......
...@@ -57,10 +57,6 @@ extern int usb_match_device(struct usb_device *dev, ...@@ -57,10 +57,6 @@ extern int usb_match_device(struct usb_device *dev,
extern void usb_forced_unbind_intf(struct usb_interface *intf); extern void usb_forced_unbind_intf(struct usb_interface *intf);
extern void usb_rebind_intf(struct usb_interface *intf); extern void usb_rebind_intf(struct usb_interface *intf);
extern int usb_hub_claim_port(struct usb_device *hdev, unsigned port,
struct dev_state *owner);
extern int usb_hub_release_port(struct usb_device *hdev, unsigned port,
struct dev_state *owner);
extern void usb_hub_release_all_ports(struct usb_device *hdev, extern void usb_hub_release_all_ports(struct usb_device *hdev,
struct dev_state *owner); struct dev_state *owner);
extern bool usb_device_is_owned(struct usb_device *udev); extern bool usb_device_is_owned(struct usb_device *udev);
......
...@@ -366,6 +366,8 @@ struct usb_bus { ...@@ -366,6 +366,8 @@ struct usb_bus {
#endif #endif
}; };
struct dev_state;
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
struct usb_tt; struct usb_tt;
...@@ -749,6 +751,11 @@ extern struct usb_host_interface *usb_find_alt_setting( ...@@ -749,6 +751,11 @@ extern struct usb_host_interface *usb_find_alt_setting(
unsigned int iface_num, unsigned int iface_num,
unsigned int alt_num); unsigned int alt_num);
/* port claiming functions */
int usb_hub_claim_port(struct usb_device *hdev, unsigned port1,
struct dev_state *owner);
int usb_hub_release_port(struct usb_device *hdev, unsigned port1,
struct dev_state *owner);
/** /**
* usb_make_path - returns stable device path in the usb tree * usb_make_path - returns stable device path in the usb tree
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment