⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbstring.c

📁 LINUX2.4.18内核下的usb GADGET驱动程序
💻 C
字号:
/* * Copyright (C) 2003 David Brownell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. */#include <linux/errno.h>#include <linux/kernel.h>#include <linux/list.h>#include <linux/string.h>#include <linux/init.h>#include <linux/usb_ch9.h>#include <linux/usb_gadget.h>#include <asm/byteorder.h>#include <asm/unaligned.h>static int utf8_to_utf16le(const char *s, u16 *cp, unsigned len){	int	count = 0;	u8	c;	u16	uchar;	/* this insists on correct encodings, though not minimal ones.	 * BUT it currently rejects legit 4-byte UTF-8 code points,	 * which need surrogate pairs.  (Unicode 3.1 can use them.)	 */	while (len != 0 && (c = (u8) *s++) != 0) {		if (unlikely(c & 0x80)) {			// 2-byte sequence:			// 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx			if ((c & 0xe0) == 0xc0) {				uchar = (c & 0x1f) << 6;				c = (u8) *s++;				if ((c & 0xc0) != 0xc0)					goto fail;				c &= 0x3f;				uchar |= c;			// 3-byte sequence (most CJKV characters):			// zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx			} else if ((c & 0xf0) == 0xe0) {				uchar = (c & 0x0f) << 12;				c = (u8) *s++;				if ((c & 0xc0) != 0xc0)					goto fail;				c &= 0x3f;				uchar |= c << 6;				c = (u8) *s++;				if ((c & 0xc0) != 0xc0)					goto fail;				c &= 0x3f;				uchar |= c;				/* no bogus surrogates */				if (0xd800 <= uchar && uchar <= 0xdfff)					goto fail;			// 4-byte sequence (surrogate pairs, currently rare):			// 11101110wwwwzzzzyy + 110111yyyyxxxxxx			//     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx			// (uuuuu = wwww + 1)			// FIXME accept the surrogate code points (only)			} else				goto fail;		} else			uchar = c;		put_unaligned (cpu_to_le16 (uchar), cp++);		count++;		len--;	}	return count;fail:	return -1;}/** * usb_gadget_get_string - fill out a string descriptor  * @table: of c strings encoded using UTF-8 * @id: string id, from low byte of wValue in get string descriptor * @buf: at least 256 bytes * * Finds the UTF-8 string matching the ID, and converts it into a * string descriptor in utf16-le. * Returns length of descriptor (always even) or negative errno * * If your driver needs stings in multiple languages, you'll probably * "switch (wIndex) { ... }"  in your ep0 string descriptor logic, * using this routine after choosing which set of UTF-8 strings to use. * Note that US-ASCII is a strict subset of UTF-8; any string bytes with * the eighth bit set will be multibyte UTF-8 characters, not ISO-8859/1 * characters (which are also widely used in C strings). */intusb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf){	struct usb_string	*s;	int			len;	/* descriptor 0 has the language id */	if (id == 0) {		buf [0] = 4;		buf [1] = USB_DT_STRING;		buf [2] = (u8) table->language;		buf [3] = (u8) (table->language >> 8);		return 4;	}	for (s = table->strings; s && s->s; s++)		if (s->id == id)			break;	/* unrecognized: stall. */	if (!s || !s->s)		return -EINVAL;	/* string descriptors have length, tag, then UTF16-LE text */	len = min ((size_t) 126, strlen (s->s));	memset (buf + 2, 0, 2 * len);	/* zero all the bytes */	len = utf8_to_utf16le(s->s, (u16 *)&buf[2], len);	if (len < 0)		return -EINVAL;	buf [0] = (len + 1) * 2;	buf [1] = USB_DT_STRING;	return buf [0];}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -