590 lines
19 KiB
Diff
590 lines
19 KiB
Diff
diff --git a/drivers/usb/gadget/function/ci13xxx_udc.h b/drivers/usb/gadget/function/ci13xxx_udc.h
|
|
new file mode 100644
|
|
index 0000000..7983bfd
|
|
--- /dev/null
|
|
+++ b/drivers/usb/gadget/function/ci13xxx_udc.h
|
|
@@ -0,0 +1,280 @@
|
|
+/*
|
|
+ * ci13xxx_udc.h - structures, registers, and macros MIPS USB IP core
|
|
+ *
|
|
+ * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
|
|
+ *
|
|
+ * Author: David Lopo
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License version 2 as
|
|
+ * published by the Free Software Foundation.
|
|
+ *
|
|
+ * Description: MIPS USB IP core family device controller
|
|
+ * Structures, registers and logging macros
|
|
+ */
|
|
+
|
|
+#ifndef _CI13XXX_h_
|
|
+#define _CI13XXX_h_
|
|
+
|
|
+/******************************************************************************
|
|
+ * DEFINE
|
|
+ *****************************************************************************/
|
|
+#define CI13XXX_PAGE_SIZE 4096ul /* page size for TD's */
|
|
+#define ENDPT_MAX (32)
|
|
+#define CTRL_PAYLOAD_MAX (64)
|
|
+#define RX (0) /* similar to USB_DIR_OUT but can be used as an index */
|
|
+#define TX (1) /* similar to USB_DIR_IN but can be used as an index */
|
|
+
|
|
+/* UDC private data:
|
|
+ * 16MSb - Vendor ID | 16 LSb Vendor private data
|
|
+ */
|
|
+#define CI13XX_REQ_VENDOR_ID(id) (id & 0xFFFF0000UL)
|
|
+
|
|
+#define MSM_ETD_TYPE BIT(1)
|
|
+#define MSM_EP_PIPE_ID_RESET_VAL 0x1F001F
|
|
+
|
|
+/******************************************************************************
|
|
+ * STRUCTURES
|
|
+ *****************************************************************************/
|
|
+/* DMA layout of transfer descriptors */
|
|
+struct ci13xxx_td {
|
|
+ /* 0 */
|
|
+ u32 next;
|
|
+#define TD_TERMINATE BIT(0)
|
|
+#define TD_ADDR_MASK (0xFFFFFFEUL << 5)
|
|
+ /* 1 */
|
|
+ u32 token;
|
|
+#define TD_STATUS (0x00FFUL << 0)
|
|
+#define TD_STATUS_TR_ERR BIT(3)
|
|
+#define TD_STATUS_DT_ERR BIT(5)
|
|
+#define TD_STATUS_HALTED BIT(6)
|
|
+#define TD_STATUS_ACTIVE BIT(7)
|
|
+#define TD_MULTO (0x0003UL << 10)
|
|
+#define TD_IOC BIT(15)
|
|
+#define TD_TOTAL_BYTES (0x7FFFUL << 16)
|
|
+ /* 2 */
|
|
+ u32 page[5];
|
|
+#define TD_CURR_OFFSET (0x0FFFUL << 0)
|
|
+#define TD_FRAME_NUM (0x07FFUL << 0)
|
|
+#define TD_RESERVED_MASK (0x0FFFUL << 0)
|
|
+} __attribute__ ((packed, aligned(4)));
|
|
+
|
|
+/* DMA layout of queue heads */
|
|
+struct ci13xxx_qh {
|
|
+ /* 0 */
|
|
+ u32 cap;
|
|
+#define QH_IOS BIT(15)
|
|
+#define QH_MAX_PKT (0x07FFUL << 16)
|
|
+#define QH_ZLT BIT(29)
|
|
+#define QH_MULT (0x0003UL << 30)
|
|
+#define QH_MULT_SHIFT 11
|
|
+ /* 1 */
|
|
+ u32 curr;
|
|
+ /* 2 - 8 */
|
|
+ struct ci13xxx_td td;
|
|
+ /* 9 */
|
|
+ u32 RESERVED;
|
|
+ struct usb_ctrlrequest setup;
|
|
+} __attribute__ ((packed, aligned(4)));
|
|
+
|
|
+/* cache of larger request's original attributes */
|
|
+struct ci13xxx_multi_req {
|
|
+ unsigned len;
|
|
+ unsigned actual;
|
|
+ void *buf;
|
|
+};
|
|
+
|
|
+/* Extension of usb_request */
|
|
+struct ci13xxx_req {
|
|
+ struct usb_request req;
|
|
+ unsigned map;
|
|
+ struct list_head queue;
|
|
+ struct ci13xxx_td *ptr;
|
|
+ dma_addr_t dma;
|
|
+ struct ci13xxx_td *zptr;
|
|
+ dma_addr_t zdma;
|
|
+ struct ci13xxx_multi_req multi;
|
|
+};
|
|
+
|
|
+/* Extension of usb_ep */
|
|
+struct ci13xxx_ep {
|
|
+ struct usb_ep ep;
|
|
+ const struct usb_endpoint_descriptor *desc;
|
|
+ u8 dir;
|
|
+ u8 num;
|
|
+ u8 type;
|
|
+ char name[16];
|
|
+ struct {
|
|
+ struct list_head queue;
|
|
+ struct ci13xxx_qh *ptr;
|
|
+ dma_addr_t dma;
|
|
+ } qh;
|
|
+ struct list_head rw_queue;
|
|
+ int wedge;
|
|
+
|
|
+ /* global resources */
|
|
+ spinlock_t *lock;
|
|
+ struct device *device;
|
|
+ struct dma_pool *td_pool;
|
|
+ struct ci13xxx_td *last_zptr;
|
|
+ dma_addr_t last_zdma;
|
|
+ unsigned long dTD_update_fail_count;
|
|
+ unsigned long dTD_active_re_q_count;
|
|
+ unsigned long prime_fail_count;
|
|
+ int prime_timer_count;
|
|
+ struct timer_list prime_timer;
|
|
+
|
|
+ bool multi_req;
|
|
+};
|
|
+
|
|
+struct ci13xxx;
|
|
+struct ci13xxx_udc_driver {
|
|
+ const char *name;
|
|
+ unsigned long flags;
|
|
+ unsigned int nz_itc;
|
|
+#define CI13XXX_REGS_SHARED BIT(0)
|
|
+#define CI13XXX_REQUIRE_TRANSCEIVER BIT(1)
|
|
+#define CI13XXX_PULLUP_ON_VBUS BIT(2)
|
|
+#define CI13XXX_DISABLE_STREAMING BIT(3)
|
|
+#define CI13XXX_ZERO_ITC BIT(4)
|
|
+#define CI13XXX_ENABLE_AHB2AHB_BYPASS BIT(6)
|
|
+
|
|
+#define CI13XXX_CONTROLLER_RESET_EVENT 0
|
|
+#define CI13XXX_CONTROLLER_CONNECT_EVENT 1
|
|
+#define CI13XXX_CONTROLLER_SUSPEND_EVENT 2
|
|
+#define CI13XXX_CONTROLLER_REMOTE_WAKEUP_EVENT 3
|
|
+#define CI13XXX_CONTROLLER_RESUME_EVENT 4
|
|
+#define CI13XXX_CONTROLLER_DISCONNECT_EVENT 5
|
|
+#define CI13XXX_CONTROLLER_UDC_STARTED_EVENT 6
|
|
+#define CI13XXX_CONTROLLER_ERROR_EVENT 7
|
|
+
|
|
+ void (*notify_event)(struct ci13xxx *udc, unsigned event);
|
|
+ bool (*in_lpm)(struct ci13xxx *udc);
|
|
+};
|
|
+
|
|
+/* CI13XXX UDC descriptor & global resources */
|
|
+struct ci13xxx {
|
|
+ spinlock_t *lock; /* ctrl register bank access */
|
|
+ void __iomem *regs; /* registers address space */
|
|
+
|
|
+ struct dma_pool *qh_pool; /* DMA pool for queue heads */
|
|
+ struct dma_pool *td_pool; /* DMA pool for transfer descs */
|
|
+ struct usb_request *status; /* ep0 status request */
|
|
+ void *status_buf;/* GET_STATUS buffer */
|
|
+
|
|
+ struct usb_gadget gadget; /* USB slave device */
|
|
+ struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */
|
|
+ u32 ep0_dir; /* ep0 direction */
|
|
+#define ep0out ci13xxx_ep[0]
|
|
+#define ep0in ci13xxx_ep[hw_ep_max / 2]
|
|
+ u8 suspended; /* suspended by the host */
|
|
+ u8 configured; /* is device configured */
|
|
+ u8 test_mode; /* the selected test mode */
|
|
+ bool rw_pending; /* Remote wakeup pending flag */
|
|
+ struct delayed_work rw_work; /* remote wakeup delayed work */
|
|
+ struct usb_gadget_driver *driver; /* 3rd party gadget driver */
|
|
+ struct ci13xxx_udc_driver *udc_driver; /* device controller driver */
|
|
+ int vbus_active; /* is VBUS active */
|
|
+ int softconnect; /* is pull-up enable allowed */
|
|
+ unsigned long dTD_update_fail_count;
|
|
+ struct usb_phy *transceiver; /* Transceiver struct */
|
|
+ bool skip_flush; /* skip flushing remaining EP
|
|
+ upon flush timeout for the
|
|
+ first EP. */
|
|
+};
|
|
+
|
|
+/******************************************************************************
|
|
+ * REGISTERS
|
|
+ *****************************************************************************/
|
|
+/* register size */
|
|
+#define REG_BITS (32)
|
|
+
|
|
+/* HCCPARAMS */
|
|
+#define HCCPARAMS_LEN BIT(17)
|
|
+
|
|
+/* DCCPARAMS */
|
|
+#define DCCPARAMS_DEN (0x1F << 0)
|
|
+#define DCCPARAMS_DC BIT(7)
|
|
+
|
|
+/* TESTMODE */
|
|
+#define TESTMODE_FORCE BIT(0)
|
|
+
|
|
+/* AHB_MODE */
|
|
+#define AHB2AHB_BYPASS BIT(31)
|
|
+
|
|
+/* USBCMD */
|
|
+#define USBCMD_RS BIT(0)
|
|
+#define USBCMD_RST BIT(1)
|
|
+#define USBCMD_SUTW BIT(13)
|
|
+#define USBCMD_ATDTW BIT(14)
|
|
+
|
|
+/* USBSTS & USBINTR */
|
|
+#define USBi_UI BIT(0)
|
|
+#define USBi_UEI BIT(1)
|
|
+#define USBi_PCI BIT(2)
|
|
+#define USBi_URI BIT(6)
|
|
+#define USBi_SLI BIT(8)
|
|
+
|
|
+/* DEVICEADDR */
|
|
+#define DEVICEADDR_USBADRA BIT(24)
|
|
+#define DEVICEADDR_USBADR (0x7FUL << 25)
|
|
+
|
|
+/* PORTSC */
|
|
+#define PORTSC_FPR BIT(6)
|
|
+#define PORTSC_SUSP BIT(7)
|
|
+#define PORTSC_PR BIT(8)
|
|
+#define PORTSC_HSP BIT(9)
|
|
+#define PORTSC_PTC (0x0FUL << 16)
|
|
+
|
|
+/* DEVLC */
|
|
+#define DEVLC_PSPD (0x03UL << 25)
|
|
+#define DEVLC_PSPD_HS (0x02UL << 25)
|
|
+
|
|
+/* USBMODE */
|
|
+#define USBMODE_CM (0x03UL << 0)
|
|
+#define USBMODE_CM_IDLE (0x00UL << 0)
|
|
+#define USBMODE_CM_DEVICE (0x02UL << 0)
|
|
+#define USBMODE_CM_HOST (0x03UL << 0)
|
|
+#define USBMODE_SLOM BIT(3)
|
|
+#define USBMODE_SDIS BIT(4)
|
|
+#define USBCMD_ITC(n) (n << 16) /* n = 0, 1, 2, 4, 8, 16, 32, 64 */
|
|
+#define USBCMD_ITC_MASK (0xFF << 16)
|
|
+
|
|
+/* ENDPTCTRL */
|
|
+#define ENDPTCTRL_RXS BIT(0)
|
|
+#define ENDPTCTRL_RXT (0x03UL << 2)
|
|
+#define ENDPTCTRL_RXR BIT(6) /* reserved for port 0 */
|
|
+#define ENDPTCTRL_RXE BIT(7)
|
|
+#define ENDPTCTRL_TXS BIT(16)
|
|
+#define ENDPTCTRL_TXT (0x03UL << 18)
|
|
+#define ENDPTCTRL_TXR BIT(22) /* reserved for port 0 */
|
|
+#define ENDPTCTRL_TXE BIT(23)
|
|
+
|
|
+/******************************************************************************
|
|
+ * LOGGING
|
|
+ *****************************************************************************/
|
|
+#define ci13xxx_printk(level, format, args...) \
|
|
+do { \
|
|
+ if (_udc == NULL) \
|
|
+ printk(level "[%s] " format "\n", __func__, ## args); \
|
|
+ else \
|
|
+ dev_printk(level, _udc->gadget.dev.parent, \
|
|
+ "[%s] " format "\n", __func__, ## args); \
|
|
+} while (0)
|
|
+
|
|
+#ifndef err
|
|
+#define err(format, args...) ci13xxx_printk(KERN_ERR, format, ## args)
|
|
+#endif
|
|
+
|
|
+#define warn(format, args...) ci13xxx_printk(KERN_WARNING, format, ## args)
|
|
+#define info(format, args...) ci13xxx_printk(KERN_INFO, format, ## args)
|
|
+
|
|
+#ifdef TRACE
|
|
+#define trace(format, args...) ci13xxx_printk(KERN_DEBUG, format, ## args)
|
|
+#define dbg_trace(format, args...) dev_dbg(dev, format, ##args)
|
|
+#else
|
|
+#define trace(format, args...) do {} while (0)
|
|
+#define dbg_trace(format, args...) do {} while (0)
|
|
+#endif
|
|
+
|
|
+#endif /* _CI13XXX_h_ */
|
|
diff --git a/drivers/usb/gadget/function/configfs.h b/drivers/usb/gadget/function/configfs.h
|
|
new file mode 100644
|
|
index 0000000..36c468c
|
|
--- /dev/null
|
|
+++ b/drivers/usb/gadget/function/configfs.h
|
|
@@ -0,0 +1,19 @@
|
|
+#ifndef USB__GADGET__CONFIGFS__H
|
|
+#define USB__GADGET__CONFIGFS__H
|
|
+
|
|
+#include <linux/configfs.h>
|
|
+
|
|
+void unregister_gadget_item(struct config_item *item);
|
|
+
|
|
+int usb_os_desc_prepare_interf_dir(struct config_group *parent,
|
|
+ int n_interf,
|
|
+ struct usb_os_desc **desc,
|
|
+ char **names,
|
|
+ struct module *owner);
|
|
+
|
|
+static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item)
|
|
+{
|
|
+ return container_of(to_config_group(item), struct usb_os_desc, group);
|
|
+}
|
|
+
|
|
+#endif /* USB__GADGET__CONFIGFS__H */
|
|
diff --git a/drivers/usb/gadget/function/debug.h b/drivers/usb/gadget/function/debug.h
|
|
new file mode 100644
|
|
index 0000000..8729aca
|
|
--- /dev/null
|
|
+++ b/drivers/usb/gadget/function/debug.h
|
|
@@ -0,0 +1,55 @@
|
|
+/*
|
|
+ * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License version 2 and
|
|
+ * only version 2 as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef __DEBUG_H_
|
|
+#define __DEBUG_H_
|
|
+
|
|
+#define DBG_MAX_MSG 1024UL
|
|
+#define DBG_MSG_LEN 80UL
|
|
+#define TIME_BUF_LEN 17
|
|
+#define DBG_EVENT_LEN (DBG_MSG_LEN - TIME_BUF_LEN)
|
|
+
|
|
+extern unsigned int enable_event_log;
|
|
+extern void put_timestamp(char *tbuf);
|
|
+extern void add_event_to_buf(char *tbuf);
|
|
+extern int debug_debugfs_init(void);
|
|
+extern void debug_debugfs_exit(void);
|
|
+
|
|
+#define LOGLEVEL_NONE 8
|
|
+#define LOGLEVEL_DEBUG 7
|
|
+#define LOGLEVEL_INFO 6
|
|
+#define LOGLEVEL_ERR 3
|
|
+
|
|
+#define log_event(log_level, x...) \
|
|
+do { \
|
|
+ char buf[DBG_MSG_LEN]; \
|
|
+ if (log_level == LOGLEVEL_DEBUG) \
|
|
+ pr_debug(x); \
|
|
+ else if (log_level == LOGLEVEL_ERR) \
|
|
+ pr_err(x); \
|
|
+ else if (log_level == LOGLEVEL_INFO) \
|
|
+ pr_info(x); \
|
|
+ if (enable_event_log) { \
|
|
+ put_timestamp(buf); \
|
|
+ snprintf(&buf[TIME_BUF_LEN - 1], DBG_EVENT_LEN, x); \
|
|
+ add_event_to_buf(buf); \
|
|
+ } \
|
|
+} while (0)
|
|
+
|
|
+#define log_event_none(x, ...) log_event(LOGLEVEL_NONE, x, ##__VA_ARGS__)
|
|
+#define log_event_dbg(x, ...) log_event(LOGLEVEL_DEBUG, x, ##__VA_ARGS__)
|
|
+#define log_event_err(x, ...) log_event(LOGLEVEL_ERR, x, ##__VA_ARGS__)
|
|
+#define log_event_info(x, ...) log_event(LOGLEVEL_INFO, x, ##__VA_ARGS__)
|
|
+
|
|
+#endif /* __DEBUG_H_ */
|
|
diff --git a/drivers/usb/gadget/function/f_ccid.h b/drivers/usb/gadget/function/f_ccid.h
|
|
new file mode 100644
|
|
index 0000000..d899044
|
|
--- /dev/null
|
|
+++ b/drivers/usb/gadget/function/f_ccid.h
|
|
@@ -0,0 +1,83 @@
|
|
+/*
|
|
+ * Copyright (c) 2011, The Linux Foundation. All rights reserved.
|
|
+
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License version 2 and
|
|
+ * only version 2 as published by the Free Software Foundation.
|
|
+
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details
|
|
+ */
|
|
+
|
|
+#ifndef __F_CCID_H
|
|
+#define __F_CCID_H
|
|
+
|
|
+#define PROTOCOL_TO 0x01
|
|
+#define PROTOCOL_T1 0x02
|
|
+#define ABDATA_SIZE 512
|
|
+
|
|
+/* define for dwFeatures for Smart Card Device Class Descriptors */
|
|
+/* No special characteristics */
|
|
+#define CCID_FEATURES_NADA 0x00000000
|
|
+/* Automatic parameter configuration based on ATR data */
|
|
+#define CCID_FEATURES_AUTO_PCONF 0x00000002
|
|
+/* Automatic activation of ICC on inserting */
|
|
+#define CCID_FEATURES_AUTO_ACTIV 0x00000004
|
|
+/* Automatic ICC voltage selection */
|
|
+#define CCID_FEATURES_AUTO_VOLT 0x00000008
|
|
+/* Automatic ICC clock frequency change */
|
|
+#define CCID_FEATURES_AUTO_CLOCK 0x00000010
|
|
+/* Automatic baud rate change */
|
|
+#define CCID_FEATURES_AUTO_BAUD 0x00000020
|
|
+/*Automatic parameters negotiation made by the CCID */
|
|
+#define CCID_FEATURES_AUTO_PNEGO 0x00000040
|
|
+/* Automatic PPS made by the CCID according to the active parameters */
|
|
+#define CCID_FEATURES_AUTO_PPS 0x00000080
|
|
+/* CCID can set ICC in clock stop mode */
|
|
+#define CCID_FEATURES_ICCSTOP 0x00000100
|
|
+/* NAD value other than 00 accepted (T=1 protocol in use) */
|
|
+#define CCID_FEATURES_NAD 0x00000200
|
|
+/* Automatic IFSD exchange as first exchange (T=1 protocol in use) */
|
|
+#define CCID_FEATURES_AUTO_IFSD 0x00000400
|
|
+/* TPDU level exchanges with CCID */
|
|
+#define CCID_FEATURES_EXC_TPDU 0x00010000
|
|
+/* Short APDU level exchange with CCID */
|
|
+#define CCID_FEATURES_EXC_SAPDU 0x00020000
|
|
+/* Short and Extended APDU level exchange with CCID */
|
|
+#define CCID_FEATURES_EXC_APDU 0x00040000
|
|
+/* USB Wake up signaling supported on card insertion and removal */
|
|
+#define CCID_FEATURES_WAKEUP 0x00100000
|
|
+
|
|
+#define CCID_NOTIFY_CARD _IOW('C', 1, struct usb_ccid_notification)
|
|
+#define CCID_NOTIFY_HWERROR _IOW('C', 2, struct usb_ccid_notification)
|
|
+#define CCID_READ_DTR _IOR('C', 3, int)
|
|
+
|
|
+struct usb_ccid_notification {
|
|
+ unsigned char buf[4];
|
|
+} __packed;
|
|
+
|
|
+struct ccid_bulk_in_header {
|
|
+ unsigned char bMessageType;
|
|
+ unsigned long wLength;
|
|
+ unsigned char bSlot;
|
|
+ unsigned char bSeq;
|
|
+ unsigned char bStatus;
|
|
+ unsigned char bError;
|
|
+ unsigned char bSpecific;
|
|
+ unsigned char abData[ABDATA_SIZE];
|
|
+ unsigned char bSizeToSend;
|
|
+} __packed;
|
|
+
|
|
+struct ccid_bulk_out_header {
|
|
+ unsigned char bMessageType;
|
|
+ unsigned long wLength;
|
|
+ unsigned char bSlot;
|
|
+ unsigned char bSeq;
|
|
+ unsigned char bSpecific_0;
|
|
+ unsigned char bSpecific_1;
|
|
+ unsigned char bSpecific_2;
|
|
+ unsigned char APDU[ABDATA_SIZE];
|
|
+} __packed;
|
|
+#endif
|
|
diff --git a/drivers/usb/gadget/function/u_os_desc.h b/drivers/usb/gadget/function/u_os_desc.h
|
|
new file mode 100644
|
|
index 0000000..947b7dd
|
|
--- /dev/null
|
|
+++ b/drivers/usb/gadget/function/u_os_desc.h
|
|
@@ -0,0 +1,123 @@
|
|
+/*
|
|
+ * u_os_desc.h
|
|
+ *
|
|
+ * Utility definitions for "OS Descriptors" support
|
|
+ *
|
|
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
|
|
+ * http://www.samsung.com
|
|
+ *
|
|
+ * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License version 2 as
|
|
+ * published by the Free Software Foundation.
|
|
+ */
|
|
+
|
|
+#ifndef __U_OS_DESC_H__
|
|
+#define __U_OS_DESC_H__
|
|
+
|
|
+#include <asm/unaligned.h>
|
|
+#include <linux/nls.h>
|
|
+
|
|
+#define USB_EXT_PROP_DW_SIZE 0
|
|
+#define USB_EXT_PROP_DW_PROPERTY_DATA_TYPE 4
|
|
+#define USB_EXT_PROP_W_PROPERTY_NAME_LENGTH 8
|
|
+#define USB_EXT_PROP_B_PROPERTY_NAME 10
|
|
+#define USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH 10
|
|
+#define USB_EXT_PROP_B_PROPERTY_DATA 14
|
|
+
|
|
+#define USB_EXT_PROP_RESERVED 0
|
|
+#define USB_EXT_PROP_UNICODE 1
|
|
+#define USB_EXT_PROP_UNICODE_ENV 2
|
|
+#define USB_EXT_PROP_BINARY 3
|
|
+#define USB_EXT_PROP_LE32 4
|
|
+#define USB_EXT_PROP_BE32 5
|
|
+#define USB_EXT_PROP_UNICODE_LINK 6
|
|
+#define USB_EXT_PROP_UNICODE_MULTI 7
|
|
+
|
|
+static inline u8 *__usb_ext_prop_ptr(u8 *buf, size_t offset)
|
|
+{
|
|
+ return buf + offset;
|
|
+}
|
|
+
|
|
+static inline u8 *usb_ext_prop_size_ptr(u8 *buf)
|
|
+{
|
|
+ return __usb_ext_prop_ptr(buf, USB_EXT_PROP_DW_SIZE);
|
|
+}
|
|
+
|
|
+static inline u8 *usb_ext_prop_type_ptr(u8 *buf)
|
|
+{
|
|
+ return __usb_ext_prop_ptr(buf, USB_EXT_PROP_DW_PROPERTY_DATA_TYPE);
|
|
+}
|
|
+
|
|
+static inline u8 *usb_ext_prop_name_len_ptr(u8 *buf)
|
|
+{
|
|
+ return __usb_ext_prop_ptr(buf, USB_EXT_PROP_W_PROPERTY_NAME_LENGTH);
|
|
+}
|
|
+
|
|
+static inline u8 *usb_ext_prop_name_ptr(u8 *buf)
|
|
+{
|
|
+ return __usb_ext_prop_ptr(buf, USB_EXT_PROP_B_PROPERTY_NAME);
|
|
+}
|
|
+
|
|
+static inline u8 *usb_ext_prop_data_len_ptr(u8 *buf, size_t off)
|
|
+{
|
|
+ return __usb_ext_prop_ptr(buf,
|
|
+ USB_EXT_PROP_DW_PROPERTY_DATA_LENGTH + off);
|
|
+}
|
|
+
|
|
+static inline u8 *usb_ext_prop_data_ptr(u8 *buf, size_t off)
|
|
+{
|
|
+ return __usb_ext_prop_ptr(buf, USB_EXT_PROP_B_PROPERTY_DATA + off);
|
|
+}
|
|
+
|
|
+static inline void usb_ext_prop_put_size(u8 *buf, int dw_size)
|
|
+{
|
|
+ put_unaligned_le32(dw_size, usb_ext_prop_size_ptr(buf));
|
|
+}
|
|
+
|
|
+static inline void usb_ext_prop_put_type(u8 *buf, int type)
|
|
+{
|
|
+ put_unaligned_le32(type, usb_ext_prop_type_ptr(buf));
|
|
+}
|
|
+
|
|
+static inline int usb_ext_prop_put_name(u8 *buf, const char *name, int pnl)
|
|
+{
|
|
+ int result;
|
|
+
|
|
+ put_unaligned_le16(pnl, usb_ext_prop_name_len_ptr(buf));
|
|
+ result = utf8s_to_utf16s(name, strlen(name), UTF16_LITTLE_ENDIAN,
|
|
+ (wchar_t *) usb_ext_prop_name_ptr(buf), pnl - 2);
|
|
+ if (result < 0)
|
|
+ return result;
|
|
+
|
|
+ put_unaligned_le16(0, &buf[USB_EXT_PROP_B_PROPERTY_NAME + pnl - 2]);
|
|
+
|
|
+ return pnl;
|
|
+}
|
|
+
|
|
+static inline void usb_ext_prop_put_binary(u8 *buf, int pnl, const u8 *data,
|
|
+ int data_len)
|
|
+{
|
|
+ put_unaligned_le32(data_len, usb_ext_prop_data_len_ptr(buf, pnl));
|
|
+ memcpy(usb_ext_prop_data_ptr(buf, pnl), data, data_len);
|
|
+}
|
|
+
|
|
+static inline int usb_ext_prop_put_unicode(u8 *buf, int pnl, const char *string,
|
|
+ int data_len)
|
|
+{
|
|
+ int result;
|
|
+ put_unaligned_le32(data_len, usb_ext_prop_data_len_ptr(buf, pnl));
|
|
+ result = utf8s_to_utf16s(string, data_len >> 1, UTF16_LITTLE_ENDIAN,
|
|
+ (wchar_t *) usb_ext_prop_data_ptr(buf, pnl),
|
|
+ data_len - 2);
|
|
+ if (result < 0)
|
|
+ return result;
|
|
+
|
|
+ put_unaligned_le16(0,
|
|
+ &buf[USB_EXT_PROP_B_PROPERTY_DATA + pnl + data_len - 2]);
|
|
+
|
|
+ return data_len;
|
|
+}
|
|
+
|
|
+#endif /* __U_OS_DESC_H__ */
|