Page MenuHomeFreeBSD

D52122.diff
No OneTemporary

D52122.diff

diff --git a/lib/libusb/Makefile b/lib/libusb/Makefile
--- a/lib/libusb/Makefile
+++ b/lib/libusb/Makefile
@@ -225,6 +225,7 @@
MLINKS += libusb20.3 libusb20_dev_get_stats.3
MLINKS += libusb20.3 libusb20_dev_close.3
MLINKS += libusb20.3 libusb20_dev_detach_kernel_driver.3
+MLINKS += libusb20.3 libusb20_dev_attach_kernel_driver.3
MLINKS += libusb20.3 libusb20_dev_set_config_index.3
MLINKS += libusb20.3 libusb20_dev_get_debug.3
MLINKS += libusb20.3 libusb20_dev_get_fd.3
diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h
--- a/lib/libusb/libusb.h
+++ b/lib/libusb/libusb.h
@@ -202,8 +202,8 @@
LIBUSB_CAP_HAS_HID_ACCESS,
/*
- * Supports detaching of the default USB driver with
- * libusb_detach_kernel_driver().
+ * Supports detaching and attaching of the default USB driver with
+ * libusb_detach_kernel_driver() and libusb_attach_kernel_driver().
*/
LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER,
};
diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3
--- a/lib/libusb/libusb.3
+++ b/lib/libusb/libusb.3
@@ -95,8 +95,10 @@
can access HID devices without requiring user intervention.
.It Va LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER
.Nm
-supports detaching of the default USB driver with
-.Fn libusb_detach_kernel_driver .
+supports detaching and attaching of the default USB driver with
+.Fn libusb_detach_kernel_driver
+and
+.Fn libusb_attach_kernel_driver .
.El
.Pp
.Ft const char *
@@ -869,6 +871,7 @@
.Fn usb_check_connected
.Fn usb_get_driver_np
.Fn usb_detach_kernel_driver_np
+.Fn usb_attach_kernel_driver_np
.Sh SEE ALSO
.Xr libusb20 3 ,
.Xr usb 4 ,
diff --git a/lib/libusb/libusb01.c b/lib/libusb/libusb01.c
--- a/lib/libusb/libusb01.c
+++ b/lib/libusb/libusb01.c
@@ -1023,3 +1023,21 @@
return (0);
}
+
+int
+usb_attach_kernel_driver_np(usb_dev_handle *dev, int interface)
+{
+ struct libusb20_device *pdev;
+ int err;
+
+ pdev = (void *)dev;
+
+ if (pdev == NULL)
+ return (-1);
+
+ err = libusb20_dev_attach_kernel_driver(pdev, interface);
+ if (err != 0)
+ return (-1);
+
+ return (0);
+}
diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c
--- a/lib/libusb/libusb10.c
+++ b/lib/libusb/libusb10.c
@@ -1052,10 +1052,14 @@
int
libusb_attach_kernel_driver(struct libusb20_device *pdev, int interface)
{
+ int err;
+
if (pdev == NULL)
return (LIBUSB_ERROR_INVALID_PARAM);
- /* stub - currently not supported by libusb20 */
- return (0);
+
+ err = libusb20_dev_attach_kernel_driver(pdev, interface);
+
+ return (err ? LIBUSB_ERROR_OTHER : 0);
}
int
diff --git a/lib/libusb/libusb20.h b/lib/libusb/libusb20.h
--- a/lib/libusb/libusb20.h
+++ b/lib/libusb/libusb20.h
@@ -246,6 +246,8 @@
const char *libusb20_dev_get_desc(struct libusb20_device *pdev);
int libusb20_dev_close(struct libusb20_device *pdev);
int libusb20_dev_detach_kernel_driver(struct libusb20_device *pdev, uint8_t iface_index);
+int libusb20_dev_attach_kernel_driver(struct libusb20_device *pdev,
+ uint8_t iface_index);
int libusb20_dev_set_config_index(struct libusb20_device *pdev, uint8_t configIndex);
int libusb20_dev_get_debug(struct libusb20_device *pdev);
int libusb20_dev_get_fd(struct libusb20_device *pdev);
diff --git a/lib/libusb/libusb20.3 b/lib/libusb/libusb20.3
--- a/lib/libusb/libusb20.3
+++ b/lib/libusb/libusb20.3
@@ -126,6 +126,8 @@
.Ft int
.Fn libusb20_dev_detach_kernel_driver "struct libusb20_device *pdev" "uint8_t iface_index"
.Ft int
+.Fn libusb20_dev_attach_kernel_driver "struct libusb20_device *pdev" "uint8_t iface_index"
+.Ft int
.Fn libusb20_dev_set_config_index "struct libusb20_device *pdev" "uint8_t configIndex"
.Ft int
.Fn libusb20_dev_get_debug "struct libusb20_device *pdev"
@@ -623,6 +625,15 @@
.
.Pp
.
+.Fn libusb20_dev_attach_kernel_driver
+will try to attach the kernel driver for the USB interface given by
+.Fa iface_index .
+.
+This function returns zero on success else a LIBUSB20_ERROR value is
+returned.
+.
+.Pp
+.
.Fn libusb20_dev_set_config_index
will try to set the configuration index on an USB
device.
diff --git a/lib/libusb/libusb20.c b/lib/libusb/libusb20.c
--- a/lib/libusb/libusb20.c
+++ b/lib/libusb/libusb20.c
@@ -80,6 +80,7 @@
#define dummy_get_stats (void *)dummy_int
#define dummy_kernel_driver_active (void *)dummy_int
#define dummy_detach_kernel_driver (void *)dummy_int
+#define dummy_attach_kernel_driver (void *)dummy_int
#define dummy_do_request_sync (void *)dummy_int
#define dummy_tr_open (void *)dummy_int
#define dummy_tr_close (void *)dummy_int
@@ -636,6 +637,16 @@
return (error);
}
+int
+libusb20_dev_attach_kernel_driver(struct libusb20_device *pdev,
+ uint8_t ifaceIndex)
+{
+ int error;
+
+ error = pdev->methods->attach_kernel_driver(pdev, ifaceIndex);
+ return (error);
+}
+
struct LIBUSB20_DEVICE_DESC_DECODED *
libusb20_dev_get_device_desc(struct libusb20_device *pdev)
{
diff --git a/lib/libusb/libusb20_int.h b/lib/libusb/libusb20_int.h
--- a/lib/libusb/libusb20_int.h
+++ b/lib/libusb/libusb20_int.h
@@ -92,6 +92,7 @@
/* USB device specific */
typedef int (libusb20_detach_kernel_driver_t)(struct libusb20_device *pdev, uint8_t iface_index);
+typedef int (libusb20_attach_kernel_driver_t)(struct libusb20_device *pdev, uint8_t iface_index);
typedef int (libusb20_do_request_sync_t)(struct libusb20_device *pdev, struct LIBUSB20_CONTROL_SETUP_DECODED *setup, void *data, uint16_t *pactlen, uint32_t timeout, uint8_t flags);
typedef int (libusb20_get_config_desc_full_t)(struct libusb20_device *pdev, uint8_t **ppbuf, uint16_t *plen, uint8_t index);
typedef int (libusb20_get_config_index_t)(struct libusb20_device *pdev, uint8_t *pindex);
@@ -116,6 +117,7 @@
#define LIBUSB20_DEVICE(m,n) \
m(n, detach_kernel_driver) \
+ m(n, attach_kernel_driver) \
m(n, do_request_sync) \
m(n, get_config_desc_full) \
m(n, get_config_index) \
diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c
--- a/lib/libusb/libusb20_ugen20.c
+++ b/lib/libusb/libusb20_ugen20.c
@@ -82,6 +82,7 @@
static libusb20_get_stats_t ugen20_get_stats;
static libusb20_kernel_driver_active_t ugen20_kernel_driver_active;
static libusb20_detach_kernel_driver_t ugen20_detach_kernel_driver;
+static libusb20_attach_kernel_driver_t ugen20_attach_kernel_driver;
static libusb20_do_request_sync_t ugen20_do_request_sync;
static libusb20_process_t ugen20_process;
@@ -716,6 +717,17 @@
return (0); /* kernel driver is detached */
}
+static int
+ugen20_attach_kernel_driver(struct libusb20_device *pdev, uint8_t iface_index)
+{
+ int temp = iface_index;
+
+ if (ioctl(pdev->file_ctrl, IOUSB(USB_IFACE_DRIVER_ATTACH), &temp)) {
+ return (LIBUSB20_ERROR_OTHER);
+ }
+ return (0); /* kernel driver is attached */
+}
+
static int
ugen20_do_request_sync(struct libusb20_device *pdev,
struct LIBUSB20_CONTROL_SETUP_DECODED *setup,
diff --git a/lib/libusb/usb.h b/lib/libusb/usb.h
--- a/lib/libusb/usb.h
+++ b/lib/libusb/usb.h
@@ -303,6 +303,7 @@
struct usb_bus *usb_get_busses(void);
int usb_get_driver_np(usb_dev_handle * dev, int interface, char *name, int namelen);
int usb_detach_kernel_driver_np(usb_dev_handle * dev, int interface);
+int usb_attach_kernel_driver_np(usb_dev_handle *dev, int interface);
#if 0
{ /* style */
diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c
--- a/sys/dev/usb/usb_generic.c
+++ b/sys/dev/usb/usb_generic.c
@@ -2376,6 +2376,28 @@
*/
usbd_set_parent_iface(f->udev, n, n);
break;
+ case USB_IFACE_DRIVER_ATTACH:
+
+ error = priv_check(curthread, PRIV_DRIVER);
+
+ if (error)
+ break;
+
+ n = *u.pint & 0xFF;
+
+ if (n == USB_IFACE_INDEX_ANY) {
+ error = EINVAL;
+ break;
+ }
+
+ /*
+ * Attach the currently detached driver.
+ */
+ usbd_set_parent_iface(f->udev, n, USB_IFACE_INDEX_ANY);
+
+ usb_probe_and_attach(f->udev, n);
+
+ break;
case USB_SET_POWER_MODE:
error = ugen_set_power_mode(f, *u.pint);
diff --git a/sys/dev/usb/usb_ioctl.h b/sys/dev/usb/usb_ioctl.h
--- a/sys/dev/usb/usb_ioctl.h
+++ b/sys/dev/usb/usb_ioctl.h
@@ -273,7 +273,8 @@
#define USB_IFACE_DRIVER_DETACH _IOW ('U', 125, int)
#define USB_GET_PLUGTIME _IOR ('U', 126, uint32_t)
#define USB_READ_DIR _IOW ('U', 127, struct usb_read_dir)
-/* 128 - 133 unused */
+#define USB_IFACE_DRIVER_ATTACH _IOW('U', 128, int)
+/* 129 - 133 unused */
#define USB_GET_DEV_PORT_PATH _IOR ('U', 134, struct usb_device_port_path)
#define USB_GET_POWER_USAGE _IOR ('U', 135, int)
#define USB_SET_TX_FORCE_SHORT _IOW ('U', 136, int)
diff --git a/usr.sbin/usbconfig/usbconfig.8 b/usr.sbin/usbconfig/usbconfig.8
--- a/usr.sbin/usbconfig/usbconfig.8
+++ b/usr.sbin/usbconfig/usbconfig.8
@@ -159,6 +159,11 @@
This command uses the
.Fl i Ar interface_index
option.
+.It Cm attach_kernel_driver
+Attach kernel driver for the selected interface and USB device.
+This command uses the
+.Fl i Ar interface_index
+option.
.It Cm suspend
Force the device to suspend.
.It Cm resume
diff --git a/usr.sbin/usbconfig/usbconfig.c b/usr.sbin/usbconfig/usbconfig.c
--- a/usr.sbin/usbconfig/usbconfig.c
+++ b/usr.sbin/usbconfig/usbconfig.c
@@ -93,6 +93,7 @@
uint8_t got_do_request:1;
uint8_t got_detach_kernel_driver:1;
uint8_t opt_dump_in_list_mode:1;
+ uint8_t got_attach_kernel_driver:1;
};
struct token {
@@ -129,6 +130,7 @@
T_RESET,
T_LIST,
T_DO_REQUEST,
+ T_ATTACH_KERNEL_DRIVER,
};
static struct options options;
@@ -143,6 +145,7 @@
{"add_quirk", T_ADD_QUIRK, 1},
{"remove_quirk", T_REMOVE_QUIRK, 1},
{"detach_kernel_driver", T_DETACH_KERNEL_DRIVER, 0},
+ {"attach_kernel_driver", T_ATTACH_KERNEL_DRIVER, 0},
{"dump_quirk_names", T_DUMP_QUIRK_NAMES, 0},
{"dump_device_quirks", T_DUMP_DEVICE_QUIRKS, 0},
{"dump_all_desc", T_DUMP_ALL_DESC, 0},
@@ -283,6 +286,7 @@
" add_quirk <quirk>" "\n"
" remove_quirk <quirk>" "\n"
" detach_kernel_driver" "\n"
+ " attach_kernel_driver" "\n"
" dump_quirk_names" "\n"
" dump_device_quirks" "\n"
" dump_all_desc" "\n"
@@ -496,6 +500,11 @@
err(1, "could not detach kernel driver");
}
}
+ if (opt->got_attach_kernel_driver) {
+ if (libusb20_dev_attach_kernel_driver(pdev, opt->iface)) {
+ err(1, "could not attach kernel driver");
+ }
+ }
dump_any =
(opt->got_dump_all_desc ||
opt->got_dump_device_desc ||
@@ -688,6 +697,13 @@
opt->got_any++;
break;
+ case T_ATTACH_KERNEL_DRIVER:
+ if (opt->got_attach_kernel_driver)
+ duplicate_option(argv[n]);
+ opt->got_attach_kernel_driver = 1;
+ opt->got_any++;
+ break;
+
case T_DUMP_QUIRK_NAMES:
if (opt->got_dump_quirk_names)
duplicate_option(argv[n]);

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 15, 10:54 AM (58 m, 24 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27647002
Default Alt Text
D52122.diff (10 KB)

Event Timeline