|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/3] usbback: Add new features
Add new_vport and remove_vport.
Ported from patch Noboru Iwamatsu: PVUSB: backend driver.
Signed-off-by: Alexander Savchenko <oleksandr.savchenko@xxxxxxxxxxxxxxx>
---
drivers/usb/host/xen-usbback/usbdev.c | 93 +++++++++++++++++++++++++++++++--
1 file changed, 88 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/host/xen-usbback/usbdev.c
b/drivers/usb/host/xen-usbback/usbdev.c
index 53a14b4..05709f2 100644
--- a/drivers/usb/host/xen-usbback/usbdev.c
+++ b/drivers/usb/host/xen-usbback/usbdev.c
@@ -276,6 +276,73 @@ static ssize_t usbdev_show_ports(struct device_driver
*driver, char *buf)
DRIVER_ATTR(port_ids, S_IRUSR, usbdev_show_ports, NULL);
+static inline int str_to_vport(const char *buf, char *phys_bus, int *dom_id,
+ int *dev_id, int *port)
+{
+ char *p;
+ int len;
+ int err;
+
+ /* no physical bus */
+ if (!(p = strchr(buf, ':')))
+ return -EINVAL;
+
+ len = p - buf;
+
+ /* bad physical bus */
+ if (len + 1 > XEN_USB_BUS_ID_SIZE)
+ return -EINVAL;
+
+ strlcpy(phys_bus, buf, len + 1);
+ err = sscanf(p + 1, "%d:%d:%d", dom_id, dev_id, port);
+ if (err == 3)
+ return 0;
+ else
+ return -EINVAL;
+}
+
+static ssize_t usbstub_vport_add(struct device_driver *driver,
+ const char *buf, size_t count)
+{
+ char bus_id[XEN_USB_BUS_ID_SIZE];
+ int err = 0, dom_id, dev_id, portnum;
+
+ err = str_to_vport(buf, &bus_id[0], &dom_id, &dev_id, &portnum);
+ if (err)
+ goto out;
+
+ err = xen_usbport_add(&bus_id[0], dom_id, dev_id, portnum);
+
+out:
+ if (!err)
+ err = count;
+
+ return err;
+}
+
+DRIVER_ATTR(new_vport, S_IWUSR, NULL, usbstub_vport_add);
+
+static ssize_t usbstub_vport_remove(struct device_driver *driver,
+ const char *buf, size_t count)
+{
+ char bus_id[XEN_USB_BUS_ID_SIZE];
+ int err = 0, dom_id, dev_id, portnum;
+
+ err = str_to_vport(buf, &bus_id[0], &dom_id, &dev_id, &portnum);
+ if (err)
+ goto out;
+
+ err = xen_usbport_remove(dom_id, dev_id, portnum);
+
+out:
+ if (!err)
+ err = count;
+
+ return err;
+}
+
+DRIVER_ATTR(remove_vport, S_IWUSR, NULL, usbstub_vport_remove);
+
/* table of devices that matches any usbdevice */
static const struct usb_device_id usbdev_table[] = {
{ .driver_info = 1 }, /* wildcard, see usb_match_id() */
@@ -293,27 +360,43 @@ static struct usb_driver xen_usbdev_driver = {
int __init xen_usbdev_init(void)
{
- int err;
+ int err = 0;
err = usb_register(&xen_usbdev_driver);
if (err < 0) {
pr_alert(DRV_PFX "usb_register failed (error %d)\n",
err);
- goto out;
+ return err;
}
err = driver_create_file(&xen_usbdev_driver.drvwrap.driver,
&driver_attr_port_ids);
if (err)
- usb_deregister(&xen_usbdev_driver);
+ goto err;
+ err = driver_create_file(&xen_usbdev_driver.drvwrap.driver,
+ &driver_attr_remove_vport);
+ if (err)
+ goto err;
+ err = driver_create_file(&xen_usbdev_driver.drvwrap.driver,
+ &driver_attr_new_vport);
+ if (err)
+ goto err;
+
+ return err;
+
+err:
+ usb_deregister(&xen_usbdev_driver);
-out:
return err;
}
void xen_usbdev_exit(void)
{
driver_remove_file(&xen_usbdev_driver.drvwrap.driver,
- &driver_attr_port_ids);
+ &driver_attr_port_ids);
+ driver_remove_file(&xen_usbdev_driver.drvwrap.driver,
+ &driver_attr_remove_vport);
+ driver_remove_file(&xen_usbdev_driver.drvwrap.driver,
+ &driver_attr_new_vport);
usb_deregister(&xen_usbdev_driver);
}
--
1.7.9.5
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |