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>