PERFORCE change 151943 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sun Oct 26 10:10:13 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=151943
Change 151943 by hselasky at hselasky_laptop001 on 2008/10/26 10:09:56
Add support for dynamic USB quirks - step one.
Affected files ...
.. //depot/projects/usb/src/lib/libusb20/libusb20.3#3 edit
.. //depot/projects/usb/src/lib/libusb20/libusb20.c#6 edit
.. //depot/projects/usb/src/lib/libusb20/libusb20.h#5 edit
.. //depot/projects/usb/src/lib/libusb20/libusb20_int.h#5 edit
.. //depot/projects/usb/src/lib/libusb20/libusb20_ugen20.c#5 edit
.. //depot/projects/usb/src/usr.sbin/usbconfig/dump.c#5 edit
.. //depot/projects/usb/src/usr.sbin/usbconfig/dump.h#3 edit
.. //depot/projects/usb/src/usr.sbin/usbconfig/usbconfig.c#2 edit
Differences ...
==== //depot/projects/usb/src/lib/libusb20/libusb20.3#3 (text+ko) ====
@@ -674,6 +674,58 @@
.
.Sh USB BACKEND OPERATIONS
.
+.Fn libusb20_be_get_dev_quirk
+This function will return the device quirk according to
+.Fa index
+into the libusb20_quirk structure pointed to by
+.Fa pq .
+This function returns zero on success else a LIBUSB20_ERROR value is
+returned.
+.
+If the given quirk does not exist LIBUSB20_ERROR_NOT_FOUND is
+returned.
+.
+.Pp
+.
+.Fn libusb20_be_get_quirk_name
+This function will return the quirk name according to
+.Fa index
+into the libusb20_quirk structure pointed to by
+.Fa pq .
+This function returns zero on success else a LIBUSB20_ERROR value is
+returned.
+.
+If the given quirk does not exist LIBUSB20_ERROR_NOT_FOUND is
+returned.
+.
+.Pp
+.
+.Fn libusb20_be_add_dev_quirk
+This function will add the libusb20_quirk structure pointed to by the
+.Fa pq
+argument into the device quirk list.
+.
+This function returns zero on success else a LIBUSB20_ERROR value is
+returned.
+.
+If the given quirk cannot be added LIBUSB20_ERROR_NO_MEM is
+returned.
+.
+.Pp
+.
+.Fn libusb20_be_remove_dev_quirk
+This function will remove the quirk matching the libusb20_quirk structure pointed to by the
+.Fa pq
+argument from the device quirk list.
+.
+This function returns zero on success else a LIBUSB20_ERROR value is
+returned.
+.
+If the given quirk does not exist LIBUSB20_ERROR_NOT_FOUND is
+returned.
+.
+.Pp
+.
.Fn libusb20_be_set_owner
This function will set the ownership for the given backend.
.
==== //depot/projects/usb/src/lib/libusb20/libusb20.c#6 (text+ko) ====
@@ -1070,6 +1070,34 @@
/* USB backend operations */
int
+libusb20_be_get_dev_quirk(struct libusb20_backend *pbe,
+ uint16_t index, struct libusb20_quirk *pq)
+{
+ return ((pbe->methods->root_get_dev_quirk) (pbe, index, pq));
+}
+
+int
+libusb20_be_get_quirk_name(struct libusb20_backend *pbe,
+ uint16_t index, struct libusb20_quirk *pq)
+{
+ return ((pbe->methods->root_get_quirk_name) (pbe, index, pq));
+}
+
+int
+libusb20_be_add_dev_quirk(struct libusb20_backend *pbe,
+ struct libusb20_quirk *pq)
+{
+ return ((pbe->methods->root_add_dev_quirk) (pbe, pq));
+}
+
+int
+libusb20_be_remove_dev_quirk(struct libusb20_backend *pbe,
+ struct libusb20_quirk *pq)
+{
+ return ((pbe->methods->root_remove_dev_quirk) (pbe, pq));
+}
+
+int
libusb20_be_set_owner(struct libusb20_backend *pbe, uid_t user, gid_t group)
{
return ((pbe->methods->root_set_owner) (pbe, user, group));
==== //depot/projects/usb/src/lib/libusb20/libusb20.h#5 (text+ko) ====
@@ -186,6 +186,14 @@
typedef void (libusb20_tr_callback_t)(struct libusb20_transfer *xfer);
+struct libusb20_quirk {
+ uint16_t vid; /* vendor ID */
+ uint16_t pid; /* product ID */
+ uint16_t reserved[2]; /* for the future */
+ char quirkname[64 - 8]; /* quirk name including terminating
+ * zero */
+};
+
/* USB transfer operations */
int libusb20_tr_close(struct libusb20_transfer *xfer);
@@ -272,6 +280,10 @@
/* USB global operations */
+int libusb20_be_get_dev_quirk(struct libusb20_backend *pbe, uint16_t index, struct libusb20_quirk *pq);
+int libusb20_be_get_quirk_name(struct libusb20_backend *pbe, uint16_t index, struct libusb20_quirk *pq);
+int libusb20_be_add_dev_quirk(struct libusb20_backend *pbe, struct libusb20_quirk *pq);
+int libusb20_be_remove_dev_quirk(struct libusb20_backend *pbe, struct libusb20_quirk *pq);
int libusb20_be_set_owner(struct libusb20_backend *be, uid_t user, gid_t group);
int libusb20_be_set_perm(struct libusb20_backend *be, mode_t mode);
int libusb20_be_get_owner(struct libusb20_backend *be, uid_t *user, gid_t *group);
==== //depot/projects/usb/src/lib/libusb20/libusb20_int.h#5 (text+ko) ====
@@ -34,6 +34,7 @@
struct libusb20_device;
struct libusb20_backend;
struct libusb20_transfer;
+struct libusb20_quirk;
union libusb20_session_data {
unsigned long session_data;
@@ -43,6 +44,10 @@
/* USB backend specific */
typedef const char *(libusb20_get_backend_name_t)(void);
+typedef int (libusb20_root_get_dev_quirk_t)(struct libusb20_backend *pbe, uint16_t index, struct libusb20_quirk *pq);
+typedef int (libusb20_root_get_quirk_name_t)(struct libusb20_backend *pbe, uint16_t index, struct libusb20_quirk *pq);
+typedef int (libusb20_root_add_dev_quirk_t)(struct libusb20_backend *pbe, struct libusb20_quirk *pq);
+typedef int (libusb20_root_remove_dev_quirk_t)(struct libusb20_backend *pbe, struct libusb20_quirk *pq);
typedef int (libusb20_bus_get_owner_t)(struct libusb20_backend *pbe, uint8_t bus, uid_t *user, gid_t *group);
typedef int (libusb20_bus_get_perm_t)(struct libusb20_backend *pbe, uint8_t bus, mode_t *mode);
typedef int (libusb20_bus_set_owner_t)(struct libusb20_backend *pbe, uint8_t bus, uid_t user, gid_t group);
@@ -88,6 +93,10 @@
m(n, dev_set_iface_perm) \
m(n, dev_set_owner) \
m(n, dev_set_perm) \
+ m(n, root_get_dev_quirk) \
+ m(n, root_get_quirk_name) \
+ m(n, root_add_dev_quirk) \
+ m(n, root_remove_dev_quirk) \
m(n, root_set_owner) \
m(n, root_get_owner) \
m(n, root_set_perm) \
==== //depot/projects/usb/src/lib/libusb20/libusb20_ugen20.c#5 (text+ko) ====
@@ -62,6 +62,10 @@
static libusb20_dev_set_iface_perm_t ugen20_dev_set_iface_perm;
static libusb20_dev_set_owner_t ugen20_dev_set_owner;
static libusb20_dev_set_perm_t ugen20_dev_set_perm;
+static libusb20_root_get_dev_quirk_t ugen20_root_get_dev_quirk;
+static libusb20_root_get_quirk_name_t ugen20_root_get_quirk_name;
+static libusb20_root_add_dev_quirk_t ugen20_root_add_dev_quirk;
+static libusb20_root_remove_dev_quirk_t ugen20_root_remove_dev_quirk;
static libusb20_root_set_owner_t ugen20_root_set_owner;
static libusb20_root_get_owner_t ugen20_root_get_owner;
static libusb20_root_set_perm_t ugen20_root_set_perm;
@@ -929,6 +933,34 @@
}
static int
+ugen20_root_get_dev_quirk(struct libusb20_backend *pbe,
+ uint16_t index, struct libusb20_quirk *pq)
+{
+ return (LIBUSB20_ERROR_NOT_SUPPORTED);
+}
+
+static int
+ugen20_root_get_quirk_name(struct libusb20_backend *pbe, uint16_t index,
+ struct libusb20_quirk *pq)
+{
+ return (LIBUSB20_ERROR_NOT_SUPPORTED);
+}
+
+static int
+ugen20_root_add_dev_quirk(struct libusb20_backend *pbe,
+ struct libusb20_quirk *pq)
+{
+ return (LIBUSB20_ERROR_NOT_SUPPORTED);
+}
+
+static int
+ugen20_root_remove_dev_quirk(struct libusb20_backend *pbe,
+ struct libusb20_quirk *pq)
+{
+ return (LIBUSB20_ERROR_NOT_SUPPORTED);
+}
+
+static int
ugen20_dev_set_owner(struct libusb20_device *pdev,
uid_t user, gid_t group)
{
==== //depot/projects/usb/src/usr.sbin/usbconfig/dump.c#5 (text+ko) ====
@@ -240,6 +240,63 @@
}
void
+dump_be_quirk_names(struct libusb20_backend *pbe)
+{
+ struct libusb20_quirk q;
+ uint16_t x;
+ int err;
+
+ memset(&q, 0, sizeof(q));
+
+ printf("\nDumping list of supported quirks:\n\n");
+
+ for (x = 0; x != 0xFFFF; x++) {
+
+ err = libusb20_be_get_quirk_name(pbe, x, &q);
+ if (err) {
+ if (x == 0) {
+ printf("No quirk names - maybe the USB quirk "
+ "module has not been loaded.\n");
+ }
+ break;
+ }
+ printf("%s\n", q.quirkname);
+ }
+ printf("\n");
+ return;
+}
+
+void
+dump_be_dev_quirks(struct libusb20_backend *pbe)
+{
+ struct libusb20_quirk q;
+ uint16_t x;
+ int err;
+
+ memset(&q, 0, sizeof(q));
+
+ printf("\nDumping current device quirks:\n\n");
+
+ for (x = 0; x != 0xFFFF; x++) {
+
+ err = libusb20_be_get_dev_quirk(pbe, x, &q);
+ if (err == LIBUSB20_ERROR_NOT_FOUND) {
+ continue;
+ } else if (err) {
+ if (x == 0) {
+ printf("No device quirks - maybe the USB quirk "
+ "module has not been loaded.\n");
+ }
+ break;
+ }
+ printf("VID=0x%04x PID=0x%04x QUIRK=%s\n",
+ q.vid, q.pid, q.quirkname);
+ }
+ printf("\n");
+ return;
+}
+
+void
dump_be_access(struct libusb20_backend *pbe)
{
struct group *gr;
==== //depot/projects/usb/src/usr.sbin/usbconfig/dump.h#3 (text+ko) ====
@@ -29,6 +29,8 @@
const char *dump_power_mode(uint8_t value);
void dump_device_info(struct libusb20_device *pdev);
void dump_be_access(struct libusb20_backend *pbe);
+void dump_be_quirk_names(struct libusb20_backend *pbe);
+void dump_be_dev_quirks(struct libusb20_backend *pbe);
void dump_device_access(struct libusb20_device *pdev, uint8_t iface);
int dump_device_iface_access(struct libusb20_device *pdev, uint8_t iface);
void dump_device_desc(struct libusb20_device *pdev);
==== //depot/projects/usb/src/usr.sbin/usbconfig/usbconfig.c#2 (text+ko) ====
@@ -39,17 +39,19 @@
#include "dump.h"
struct options {
+ const char *quirkname;
gid_t gid;
uid_t uid;
mode_t mode;
+ uint32_t got_any;
uint16_t bus;
uint16_t addr;
uint16_t iface;
+ uint16_t vid;
+ uint16_t pid;
uint8_t config_index;
uint8_t alt_index;
-
uint8_t got_list:1;
- uint8_t got_any:1;
uint8_t got_bus:1;
uint8_t got_addr:1;
uint8_t got_iface:1;
@@ -63,11 +65,15 @@
uint8_t got_power_off:1;
uint8_t got_power_save:1;
uint8_t got_power_on:1;
+ uint8_t got_dump_device_quirks:1;
+ uint8_t got_dump_quirk_names:1;
uint8_t got_dump_device_desc:1;
uint8_t got_dump_curr_config:1;
uint8_t got_dump_all_config:1;
uint8_t got_dump_info:1;
uint8_t got_dump_access:1;
+ uint8_t got_remove_device_quirk:1;
+ uint8_t got_add_device_quirk:1;
};
struct token {
@@ -84,6 +90,10 @@
T_SET_ALT,
T_SET_OWNER,
T_SET_PERM,
+ T_ADD_DEVICE_QUIRK,
+ T_REMOVE_DEVICE_QUIRK,
+ T_DUMP_QUIRK_NAMES,
+ T_DUMP_DEVICE_QUIRKS,
T_DUMP_DEVICE_DESC,
T_DUMP_CURR_CONFIG_DESC,
T_DUMP_ALL_CONFIG_DESC,
@@ -108,6 +118,10 @@
{"set_alt", T_SET_ALT, 1},
{"set_owner", T_SET_OWNER, 1},
{"set_perm", T_SET_PERM, 1},
+ {"add_dev_quirk", T_ADD_DEVICE_QUIRK, 3},
+ {"remove_dev_quirk", T_REMOVE_DEVICE_QUIRK, 3},
+ {"dump_quirk_names", T_DUMP_QUIRK_NAMES, 0},
+ {"dump_device_quirks", T_DUMP_DEVICE_QUIRKS, 0},
{"dump_device_desc", T_DUMP_DEVICE_DESC, 0},
{"dump_curr_config_desc", T_DUMP_CURR_CONFIG_DESC, 0},
{"dump_all_config_desc", T_DUMP_ALL_CONFIG_DESC, 0},
@@ -122,6 +136,44 @@
{"list", T_LIST, 0},
};
+static void
+be_dev_remove_quirk(struct libusb20_backend *pbe, uint16_t vid, uint16_t pid, const char *str)
+{
+ struct libusb20_quirk q;
+ int err;
+
+ memset(&q, 0, sizeof(q));
+
+ q.vid = vid;
+ q.pid = pid;
+ strlcpy(q.quirkname, str, sizeof(q.quirkname));
+
+ err = libusb20_be_remove_dev_quirk(pbe, &q);
+ if (err) {
+ printf("Removing quirk '%s' failed, continuing.\n", str);
+ }
+ return;
+}
+
+static void
+be_dev_add_quirk(struct libusb20_backend *pbe, uint16_t vid, uint16_t pid, const char *str)
+{
+ struct libusb20_quirk q;
+ int err;
+
+ memset(&q, 0, sizeof(q));
+
+ q.vid = vid;
+ q.pid = pid;
+ strlcpy(q.quirkname, str, sizeof(q.quirkname));
+
+ err = libusb20_be_add_dev_quirk(pbe, &q);
+ if (err) {
+ printf("Adding quirk '%s' failed, continuing.\n", str);
+ }
+ return;
+}
+
static uint8_t
get_token(const char *str, uint8_t narg)
{
@@ -146,7 +198,7 @@
char *ep;
errno = 0;
- val = strtoul(name, &ep, 10);
+ val = strtoul(name, &ep, 0);
if (errno) {
err(1, "%s", name);
}
@@ -208,6 +260,10 @@
" set_alt <altno>" "\n"
" set_owner <user:group>" "\n"
" set_perm <mode>" "\n"
+ " add_dev_quirk <vid> <pid> <quirk>" "\n"
+ " remove_dev_quirk <vid> <pid> <quirk>" "\n"
+ " dump_quirk_names" "\n"
+ " dump_device_quirks" "\n"
" dump_device_desc" "\n"
" dump_curr_config_desc" "\n"
" dump_all_config_desc" "\n"
@@ -253,8 +309,32 @@
"at the same time!");
}
if (opt->got_dump_access) {
+ opt->got_any--;
dump_be_access(pbe);
}
+ if (opt->got_dump_quirk_names) {
+ opt->got_any--;
+ dump_be_quirk_names(pbe);
+ }
+ if (opt->got_dump_device_quirks) {
+ opt->got_any--;
+ dump_be_dev_quirks(pbe);
+ }
+ if (opt->got_remove_device_quirk) {
+ opt->got_any--;
+ be_dev_remove_quirk(pbe, opt->vid, opt->pid, opt->quirkname);
+ }
+ if (opt->got_add_device_quirk) {
+ opt->got_any--;
+ be_dev_add_quirk(pbe, opt->vid, opt->pid, opt->quirkname);
+ }
+ if (opt->got_any == 0) {
+ /*
+ * do not scan through all the devices if there are no valid
+ * options
+ */
+ goto done;
+ }
while ((pdev = libusb20_be_device_foreach(pbe, pdev))) {
if (opt->got_bus &&
@@ -404,6 +484,7 @@
if (matches == 0) {
printf("No device match\n");
}
+done:
reset_options(opt);
return;
@@ -432,6 +513,42 @@
if (t > 255)
t = 255;
switch (get_token(argv[n], t)) {
+ case T_ADD_DEVICE_QUIRK:
+ if (opt->got_add_device_quirk) {
+ flush_command(pbe, opt);
+ }
+ opt->vid = num_id(argv[n + 1], "Vendor ID");
+ opt->pid = num_id(argv[n + 2], "Product ID");
+ opt->quirkname = argv[n + 3];
+ n += 3;
+
+ opt->got_add_device_quirk = 1;
+ opt->got_any++;
+ break;
+
+ case T_REMOVE_DEVICE_QUIRK:
+ if (opt->got_remove_device_quirk) {
+ flush_command(pbe, opt);
+ }
+ opt->vid = num_id(argv[n + 1], "Vendor ID");
+ opt->pid = num_id(argv[n + 2], "Product ID");
+ opt->quirkname = argv[n + 3];
+ n += 3;
+
+ opt->got_remove_device_quirk = 1;
+ opt->got_any++;
+ break;
+
+ case T_DUMP_QUIRK_NAMES:
+ opt->got_dump_quirk_names = 1;
+ opt->got_any++;
+ break;
+
+ case T_DUMP_DEVICE_QUIRKS:
+ opt->got_dump_device_quirks = 1;
+ opt->got_any++;
+ break;
+
case T_UNIT:
if (opt->got_any) {
/* allow multiple commands on the same line */
@@ -454,13 +571,13 @@
case T_SET_CONFIG:
opt->config_index = num_id(argv[n + 1], "confindex");
opt->got_set_config = 1;
- opt->got_any = 1;
+ opt->got_any++;
n++;
break;
case T_SET_ALT:
opt->alt_index = num_id(argv[n + 1], "confindex");
opt->got_set_alt = 1;
- opt->got_any = 1;
+ opt->got_any++;
n++;
break;
case T_SET_OWNER:
@@ -473,62 +590,62 @@
opt->gid = a_gid(cp);
opt->uid = a_uid(argv[n + 1]);
opt->got_set_owner = 1;
- opt->got_any = 1;
+ opt->got_any++;
n++;
break;
case T_SET_PERM:
opt->mode = a_mode(argv[n + 1]);
opt->got_set_perm = 1;
- opt->got_any = 1;
+ opt->got_any++;
n++;
break;
case T_DUMP_DEVICE_DESC:
opt->got_dump_device_desc = 1;
- opt->got_any = 1;
+ opt->got_any++;
break;
case T_DUMP_CURR_CONFIG_DESC:
opt->got_dump_curr_config = 1;
- opt->got_any = 1;
+ opt->got_any++;
break;
case T_DUMP_ALL_CONFIG_DESC:
opt->got_dump_all_config = 1;
- opt->got_any = 1;
+ opt->got_any++;
break;
case T_DUMP_INFO:
opt->got_dump_info = 1;
- opt->got_any = 1;
+ opt->got_any++;
break;
case T_DUMP_ACCESS:
opt->got_dump_access = 1;
- opt->got_any = 1;
+ opt->got_any++;
break;
case T_SUSPEND:
opt->got_suspend = 1;
- opt->got_any = 1;
+ opt->got_any++;
break;
case T_RESUME:
opt->got_resume = 1;
- opt->got_any = 1;
+ opt->got_any++;
break;
case T_POWER_OFF:
opt->got_power_off = 1;
- opt->got_any = 1;
+ opt->got_any++;
break;
case T_POWER_SAVE:
opt->got_power_save = 1;
- opt->got_any = 1;
+ opt->got_any++;
break;
case T_POWER_ON:
opt->got_power_on = 1;
- opt->got_any = 1;
+ opt->got_any++;
break;
case T_RESET:
opt->got_reset = 1;
- opt->got_any = 1;
+ opt->got_any++;
break;
case T_LIST:
opt->got_list = 1;
- opt->got_any = 1;
+ opt->got_any++;
break;
default:
usage();
@@ -541,6 +658,7 @@
} else {
/* list all the devices */
opt->got_list = 1;
+ opt->got_any++;
flush_command(pbe, opt);
}
/* release data */
More information about the p4-projects
mailing list