Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F141977181
D52122.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D52122.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D52122: usb: implement attach kernel driver
Attached
Detach File
Event Timeline
Log In to Comment