forked from ni/usb3vision
-
Notifications
You must be signed in to change notification settings - Fork 2
/
u3v.h
182 lines (161 loc) · 5.28 KB
/
u3v.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*
* u3v.h: Driver for USB3 Vision(TM) class devices
*
* (C) Copyright 2014 National Instruments Corp.
* Authors: Katie Ensign <[email protected]>,
* Jared Jenson <[email protected]>
*
* The "USB3 Vision" name and logo are trademarks of the AIA and may not
* be used without the authorization of the AIA <www.visiononline.org>
*
* Anyone wishing to develop, manufacture, or sell private labeled
* compliant product for commercial purposes or to develop compliant
* software for distribution must obtain a license to use the USB3
* Vision standard and the USB3 Vision name and logo from the AIA.
* All products (including software) must be registered with the AIA and
* must be tested for compliancy with the standard.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License, or (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef _U3V_H_
#define _U3V_H_
/*
* pr_fmt has to be redefined prior to including linux/kernel.h to prevent
* a compiler warning for its redefinition
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/ioctl.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/kernel.h>
#include <linux/kref.h>
/* General device info */
#define DRIVER_DESC "USB3 Vision Driver"
#define U3V_DEVICE_CLASS 0xEF
#define U3V_DEVICE_SUBCLASS 0x02
#define U3V_DEVICE_PROTOCOL 0x01
#define U3V_INTERFACE_CLASS 0xEF
#define U3V_INTERFACE_SUBCLASS 0x05
#define U3V_INTERFACE_PROTOCOL_CONTROL 0x00
#define U3V_INTERFACE_PROTOCOL_EVENT 0x01
#define U3V_INTERFACE_PROTOCOL_STREAM 0x02
#define U3V_INTERFACE 0x24
#define U3V_DEVICEINFO 0x01
#define MIN_U3V_INFO_LENGTH 20
#define U3V_MINOR_BASE 208
#define U3V_MAX_STR 64
#define U3V_REQUEST_ACK 0x4000
#define U3V_TIMEOUT 5000
#define U3V_DEV_DISCONNECTED 1
struct u3v_interface_info {
u8 idx;
struct usb_endpoint_descriptor *bulk_in;
struct usb_endpoint_descriptor *bulk_out;
struct mutex interface_lock;
struct mutex ioctl_count_lock;
int ioctl_count;
struct completion ioctl_complete;
void *interface_ptr;
};
/*
* A copy of this structure exists for each U3V device to contain its
* private data.
*/
struct u3v_device {
struct usb_device *udev;
struct usb_interface *intf;
struct device *device;
struct kref kref;
struct u3v_device_info *u3v_info; /* device attributes */
struct usb_driver *u3v_driver;
int device_state;
atomic_t device_available;
bool stalling_disabled;
bool device_connected;
struct u3v_interface_info control_info;
struct u3v_interface_info event_info;
struct u3v_interface_info stream_info;
};
#define to_u3v_device(d) container_of(d, struct u3v_device, kref)
/*
* Each u3v_device contains a u3v_device_info struct to store
* device attributes
*/
struct u3v_device_info {
u32 gen_cp_version;
u32 u3v_version;
char device_guid[U3V_MAX_STR];
char vendor_name[U3V_MAX_STR];
char model_name[U3V_MAX_STR];
char family_name[U3V_MAX_STR];
char device_version[U3V_MAX_STR];
char manufacturer_info[U3V_MAX_STR];
char serial_number_u3v[U3V_MAX_STR];
char user_defined_name[U3V_MAX_STR];
u8 speed_support;
u8 previously_initialized;
u32 host_byte_alignment;
u32 os_max_transfer_size;
u64 sirm_addr;
u32 transfer_alignment;
u32 segmented_xfer_supported;
u32 segmented_xfer_enabled;
u32 legacy_ctrl_ep_stall_enabled;
};
/* Helper functions for interfaces */
int reset_pipe(struct u3v_device *u3v, struct u3v_interface_info *iface_info);
static inline void u3v_reinit_completion(struct completion *x)
{
#ifdef INIT_COMPLETION
INIT_COMPLETION(*x);
#else
reinit_completion(x);
#endif
}
/* Helper function for sysfs attributes */
static inline struct u3v_device *u3v_get_driver_data(struct device *dev)
{
struct usb_interface *intf;
if (dev == NULL)
return NULL;
intf = to_usb_interface(dev);
return intf ? usb_get_intfdata(intf) : NULL;
}
/* Helper function for checking hcd */
static inline bool hcd_is_xhci(struct usb_device *udev)
{
const char *hcd = bus_to_hcd(udev->bus)->driver->description;
return (strncmp(hcd, "xhci_hcd", 8) == 0 ||
strncmp(hcd, "xhci-hcd", 8) == 0);
}
#define GET_INTERFACE(ptr_type, ptr, interface_info) \
do { \
mutex_lock(&interface_info.interface_lock); \
mutex_lock(&interface_info.ioctl_count_lock); \
ptr = (ptr_type)(interface_info.interface_ptr); \
if (interface_info.ioctl_count++ == 0) \
u3v_reinit_completion(&interface_info.ioctl_complete); \
mutex_unlock(&interface_info.ioctl_count_lock); \
mutex_unlock(&interface_info.interface_lock); \
} while (0)
#define PUT_INTERFACE(interface_info) \
do { \
mutex_lock(&interface_info.ioctl_count_lock); \
if (--interface_info.ioctl_count == 0) \
complete_all(&interface_info.ioctl_complete); \
mutex_unlock(&interface_info.ioctl_count_lock); \
} while (0)
#endif /* _U3V_H_ */