31#include <sys/stdint.h>
32#include <sys/stddef.h>
37#include <sys/kernel.h>
39#include <sys/module.h>
42#include <sys/condvar.h>
43#include <sys/sysctl.h>
45#include <sys/unistd.h>
46#include <sys/callout.h>
47#include <sys/malloc.h>
55#define USB_DEBUG_VAR usb_debug
64#define USB_DEV_QUIRKS_MAX 384
65#define USB_SUB_QUIRKS_MAX 8
66#define USB_QUIRK_ENVROOT "hw.usb.quirk."
78#define USB_QUIRK_VP(v,p,l,h,...) \
79 { .vid = (v), .pid = (p), .lo_rev = (l), .hi_rev = (h), \
80 .quirks = { __VA_ARGS__ } }
81#define USB_QUIRK(v,p,l,h,...) \
82 USB_QUIRK_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, l, h, __VA_ARGS__)
251 USB_QUIRK(GENESYS, GL641USB2IDE_2, 0x0000, 0xffff,
264 USB_QUIRK(HITACHI, DVDCAM_DZ_MV100A, 0x0000, 0xffff,
361 USB_QUIRK(ONSPEC, CFSM_READER2, 0x0000, 0xffff,
363 USB_QUIRK(ONSPEC, MDCFE_B_CF_READER, 0x0000, 0xffff,
365 USB_QUIRK(ONSPEC, MDSM_B_READER, 0x0000, 0xffff,
370 USB_QUIRK(ONSPEC2, IMAGEMATE_SDDR55, 0x0000, 0xffff,
384 USB_QUIRK(PROLIFIC, PL2506, 0x0000, 0xffff,
410 USB_QUIRK(SANDISK, IMAGEMATE_SDDR289, 0x0000, 0xffff,
698 if (strncmp(str, quirk,
len) == 0 &&
814 int fflag,
struct thread *td)
856 err = priv_check(curthread, PRIV_DRIVER);
894 err = priv_check(curthread, PRIV_DRIVER);
918 if (pqe->
quirks[x] == y) {
934 memset(pqe, 0,
sizeof(*pqe));
957 if (
value > 65535 || *
pptr == end || (*end !=
' ' && *end !=
'\t')) {
958 printf(
"%s: %s 16-bit %s value set to zero\n",
959 name, what, *end == 0 ?
"incomplete" :
"invalid");
963 return ((uint16_t)
value);
982 if (
name == NULL || env == NULL)
986 printf(
"Adding USB QUIRK '%s' = '%s'\n",
name, env);
998 while (*env ==
' ' || *env ==
'\t')
1002 end = strchr(env,
',');
1004 end = env + strlen(env);
1009 entry.
quirks[quirk_idx++] = quirk;
1011 printf(
"%s: unknown USB quirk '%.*s' (skipped)\n",
1012 name, (
int)(end - env), env);
1022 if (quirk_idx != 0) {
1024 printf(
"%s: Too many USB quirks, only %d allowed!\n",
1031 printf(
"%s: USB quirks table is full!\n",
name);
1033 memcpy(new->quirks, entry.
quirks,
sizeof(entry.
quirks));
1036 printf(
"%s: No USB quirks found!\n",
name);
1050 for (i = 0; i != 100; i++) {
1054 if (!testenv(envkey))
uint16_t quirks[USB_SUB_QUIRKS_MAX]
usb_quirk_ioctl_t * usb_quirk_ioctl_p
void usb_quirk_unload(void *arg)
usb_test_quirk_t * usb_test_quirk_p
#define USB_QUIRK_NAME_GET
#define USB_DEV_QUIRK_ADD
#define USB_DEV_QUIRK_REMOVE
#define USB_DEV_QUIRK_GET
static int usb_quirk_ioctl(unsigned long cmd, caddr_t data, int fflag, struct thread *td)
static void usb_quirk_add_entry_from_str(const char *name, const char *env)
MODULE_DEPEND(usb_quirk, usb, 1, 1, 1)
#define USB_DEV_QUIRKS_MAX
#define USB_QUIRK_ENVROOT
static void usb_quirk_uninit(void *arg)
static uint8_t usb_test_quirk_by_info(const struct usbd_lookup_info *info, uint16_t quirk)
static uint16_t usb_quirk_strtou16(const char **pptr, const char *name, const char *what)
#define USB_QUIRK_VP(v, p, l, h,...)
static struct usb_quirk_entry * usb_quirk_get_entry(uint16_t vid, uint16_t pid, uint16_t lo_rev, uint16_t hi_rev, uint8_t do_alloc)
SYSUNINIT(usb_quirk_uninit, SI_SUB_LOCK, SI_ORDER_ANY, usb_quirk_uninit, NULL)
static struct mtx usb_quirk_mtx
static uint16_t usb_strquirk(const char *str, size_t len)
static const char * usb_quirk_str[USB_QUIRK_MAX]
SYSINIT(usb_quirk_init, SI_SUB_LOCK, SI_ORDER_FIRST, usb_quirk_init, NULL)
static const char * usb_quirkstr(uint16_t quirk)
MODULE_VERSION(usb_quirk, 1)
static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX]
#define USB_SUB_QUIRKS_MAX
static void usb_quirk_init(void *arg)
#define USB_QUIRK(v, p, l, h,...)
@ UQ_MSC_FORCE_PROTO_ATAPI
@ UQ_MSC_NO_TEST_UNIT_READY
@ UQ_MSC_FORCE_PROTO_SCSI
@ UQ_MSC_NO_PREVENT_ALLOW
@ UQ_MSC_FORCE_WIRE_CBI_I
@ UQ_MSC_EJECT_HUAWEISCSI
@ UQ_MSC_EJECT_HUAWEISCSI2
#define USB_MTX_UNLOCK(_m)
#define USB_MTX_ASSERT(_m, _t)