Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Oct 2008 10:10:12 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 151943 for review
Message-ID:  <200810261010.m9QAACHZ035849@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=151943

Change 151943 by hselasky@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 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810261010.m9QAACHZ035849>