View | Details | Raw Unified | Return to bug 203249 | Differences between
and this patch

Collapse All | Expand All

(-)dev/usb/quirk/usb_quirk.c (+134 lines)
Lines 62-67 Link Here
62
#define	USB_DEV_QUIRKS_MAX 384
62
#define	USB_DEV_QUIRKS_MAX 384
63
#define	USB_SUB_QUIRKS_MAX 8
63
#define	USB_SUB_QUIRKS_MAX 8
64
64
65
#define ENVNAMEROOT "usb.quirk."
66
65
struct usb_quirk_entry {
67
struct usb_quirk_entry {
66
	uint16_t vid;
68
	uint16_t vid;
67
	uint16_t pid;
69
	uint16_t pid;
Lines 612-617 Link Here
612
}
614
}
613
615
614
/*------------------------------------------------------------------------*
616
/*------------------------------------------------------------------------*
617
 *	usb_quirk_str2num
618
 *
619
 * This function converts an USB quirk string into its code.
620
 *
621
 * Returns:
622
 * -1: Quirk not found
623
 * Else: Quirk code
624
 *------------------------------------------------------------------------*/
625
static int32_t
626
usb_quirk_str2num(char *name, int32_t namelen)
627
{
628
	int i;
629
630
	for (i = 0; i < USB_QUIRK_MAX; i++) {
631
		if (usb_quirk_str[i] != NULL
632
		    && strncmp(name, usb_quirk_str[i], namelen) == 0
633
		    && usb_quirk_str[i][namelen] == '\0')
634
			return i;
635
	}
636
637
	return -1;
638
}
639
640
/*------------------------------------------------------------------------*
615
 *	usb_test_quirk_by_info
641
 *	usb_test_quirk_by_info
616
 *
642
 *
617
 * Returns:
643
 * Returns:
Lines 853-867 Link Here
853
	return (ENOIOCTL);
879
	return (ENOIOCTL);
854
}
880
}
855
881
882
/*------------------------------------------------------------------------*
883
 *	usb_quirk_add_entry_from_str
884
 *
885
 * Add a USB quirk entry from string.
886
 *     "VENDOR PRODUCT LO_REV HI_REV QUIRK[,QUIRK[,...]]"
887
 *------------------------------------------------------------------------*/
888
static void
889
usb_quirk_add_entry_from_str(char *name, char *env)
890
{
891
	struct usb_quirk_entry entry = { 0 }, *new;
892
	int32_t quirk;
893
	uint32_t quirk_idx;
894
	char *end;
895
896
	entry.vid = (uint16_t)strtoul(env, &end, 0);
897
	if (env == end || *end != ' ') {
898
		if (*end == '\0')
899
			goto too_short;
900
		printf("%s: invalid USB quirk vendor ID at \"%s\"\n",
901
		    name, env);
902
		return;
903
	}
904
905
	env = end + 1;
906
	entry.pid = (uint16_t)strtoul(env, &end, 0);
907
	if (env == end || *end != ' ') {
908
		if (*end == '\0')
909
			goto too_short;
910
		printf("%s: invalid USB quirk product ID at \"%s\"\n",
911
		    name, env);
912
		return;
913
	}
914
915
	env = end + 1;
916
	entry.lo_rev = (uint16_t)strtoul(env, &end, 0);
917
	if (env == end || *end != ' ') {
918
		if (*end == '\0')
919
			goto too_short;
920
		printf("%s: invalid USB quirk low revision at \"%s\"\n",
921
		    name, env);
922
		return;
923
	}
924
925
	env = end + 1;
926
	entry.hi_rev = (uint16_t)strtoul(env, &end, 0);
927
	if (env == end || *end != ' ') {
928
		if (*end == '\0')
929
			goto too_short;
930
		printf("%s: invalid USB quirk high revision at \"%s\"\n",
931
		    name, env);
932
		return;
933
	}
934
935
	for (env = end; *++env == ' '; )
936
		;		/* nothing */
937
	if (*env == '\0') {
938
      too_short:
939
		printf("%s: USB quirk definition not complete!\n", name);
940
		return;
941
	}
942
943
	for (quirk_idx = 0; quirk_idx < USB_SUB_QUIRKS_MAX; quirk_idx++) {
944
		end = strchr(env, ',');
945
		if (end == NULL)
946
			end = env + strlen(env);
947
948
		quirk = usb_quirk_str2num(env, end - env);
949
		if (quirk < 0) {
950
			printf("%s: unknown USB quirk \"%.*s\"\n",
951
			    name, (int)(end - env), env);
952
			return;
953
		}
954
955
		entry.quirks[quirk_idx] = quirk;
956
957
		if (*end == '\0') {
958
			mtx_lock(&usb_quirk_mtx);
959
			new = usb_quirk_get_entry(entry.vid, entry.pid,
960
			    entry.lo_rev, entry.hi_rev, 1);
961
			if (new == NULL) {
962
				mtx_unlock(&usb_quirk_mtx);
963
				printf("%s: USB quirks table full!\n", name);
964
				return;
965
			}
966
			bcopy(entry.quirks, new->quirks, sizeof(entry.quirks));
967
			mtx_unlock(&usb_quirk_mtx);
968
			return;
969
		}
970
971
		env = end + 1;
972
	}
973
974
	printf("%s: too many usb quirks, only %d allowed!\n",
975
	    name, USB_SUB_QUIRKS_MAX);
976
}
977
856
static void
978
static void
857
usb_quirk_init(void *arg)
979
usb_quirk_init(void *arg)
858
{
980
{
981
	char envkey[sizeof(ENVNAMEROOT) + 2]; /* 2 digits max, 0 to 99 */
982
	int i;
983
859
	/* initialize mutex */
984
	/* initialize mutex */
860
	mtx_init(&usb_quirk_mtx, "USB quirk", NULL, MTX_DEF);
985
	mtx_init(&usb_quirk_mtx, "USB quirk", NULL, MTX_DEF);
861
986
862
	/* register our function */
987
	/* register our function */
863
	usb_test_quirk_p = &usb_test_quirk_by_info;
988
	usb_test_quirk_p = &usb_test_quirk_by_info;
864
	usb_quirk_ioctl_p = &usb_quirk_ioctl;
989
	usb_quirk_ioctl_p = &usb_quirk_ioctl;
990
991
	for (i = 0; i < 100; i++) {
992
		snprintf(envkey, sizeof(envkey), ENVNAMEROOT "%d", i);
993
994
		if (!testenv(envkey))
995
			break;	/* Stop at first undefined var */
996
997
		usb_quirk_add_entry_from_str(envkey, getenv(envkey));
998
	}
865
}
999
}
866
1000
867
static void
1001
static void

Return to bug 203249