diff options
author | Johan Hovold <johan@kernel.org> | 2014-09-15 12:40:45 -0400 |
---|---|---|
committer | Johan Hovold <johan@kernel.org> | 2014-09-15 12:43:08 -0400 |
commit | f8c0e057b4898055b24b44d03b837a15d8b93b37 (patch) | |
tree | d3998d35f8917010562abbee6e7d8ede4b73c232 | |
parent | 4b7154ba70bb20a3c024faabdd2bc207b550a813 (diff) |
USB: serial: remove zte_ev driver
The zte_ev driver is based on code (once) distributed by ZTE that still
appears to originally have been reverse-engineered and bolted onto the
generic driver.
A closer analysis of the zte_ev setup code reveals that it consists of
standard CDC requests (SET/GET_LINE_CODING and SET_CONTROL_LINE_STATE)
but unfortunately fails to get some of those right. In particular, as
reported by Lei Liu, it fails to lower DTR/RTS on close. It also appears
that the control requests lack the interface argument.
Since line control is already handled properly by the option driver, and
the SET/GET_LINE_CODING requests appears to be redundant (amounts to a
SET 9600 8N1) let's remove the redundant zte_ev driver.
Also move the remaining ZTE PIDs to the generic option modem driver.
Reported-by: Lei Liu <liu.lei78@zte.com.cn>
Signed-off-by: Johan Hovold <johan@kernel.org>
-rw-r--r-- | drivers/usb/serial/Kconfig | 8 | ||||
-rw-r--r-- | drivers/usb/serial/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/serial/option.c | 11 | ||||
-rw-r--r-- | drivers/usb/serial/zte_ev.c | 305 |
4 files changed, 10 insertions, 315 deletions
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index c3119eb251bc..a69f7cd9d0bf 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -684,14 +684,6 @@ config USB_SERIAL_WISHBONE | |||
684 | To compile this driver as a module, choose M here: the | 684 | To compile this driver as a module, choose M here: the |
685 | module will be called wishbone-serial. | 685 | module will be called wishbone-serial. |
686 | 686 | ||
687 | config USB_SERIAL_ZTE | ||
688 | tristate "ZTE USB serial driver" | ||
689 | help | ||
690 | Say Y here if you want to use a ZTE USB to serial device. | ||
691 | |||
692 | To compile this driver as a module, choose M here: the | ||
693 | module will be called zte. | ||
694 | |||
695 | config USB_SERIAL_SSU100 | 687 | config USB_SERIAL_SSU100 |
696 | tristate "USB Quatech SSU-100 Single Port Serial Driver" | 688 | tristate "USB Quatech SSU-100 Single Port Serial Driver" |
697 | help | 689 | help |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index bfdafd349441..349d9df0895f 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -60,4 +60,3 @@ obj-$(CONFIG_USB_SERIAL_WISHBONE) += wishbone-serial.o | |||
60 | obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o | 60 | obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o |
61 | obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o | 61 | obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o |
62 | obj-$(CONFIG_USB_SERIAL_XSENS_MT) += xsens_mt.o | 62 | obj-$(CONFIG_USB_SERIAL_XSENS_MT) += xsens_mt.o |
63 | obj-$(CONFIG_USB_SERIAL_ZTE) += zte_ev.o | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 54a8120897a6..d1a3f6044c8a 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -276,6 +276,7 @@ static void option_instat_callback(struct urb *urb); | |||
276 | #define ZTE_PRODUCT_MF628 0x0015 | 276 | #define ZTE_PRODUCT_MF628 0x0015 |
277 | #define ZTE_PRODUCT_MF626 0x0031 | 277 | #define ZTE_PRODUCT_MF626 0x0031 |
278 | #define ZTE_PRODUCT_AC2726 0xfff1 | 278 | #define ZTE_PRODUCT_AC2726 0xfff1 |
279 | #define ZTE_PRODUCT_MG880 0xfffd | ||
279 | #define ZTE_PRODUCT_CDMA_TECH 0xfffe | 280 | #define ZTE_PRODUCT_CDMA_TECH 0xfffe |
280 | #define ZTE_PRODUCT_AC8710T 0xffff | 281 | #define ZTE_PRODUCT_AC8710T 0xffff |
281 | #define ZTE_PRODUCT_MC2718 0xffe8 | 282 | #define ZTE_PRODUCT_MC2718 0xffe8 |
@@ -1560,7 +1561,15 @@ static const struct usb_device_id option_ids[] = { | |||
1560 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff92, 0xff, 0xff, 0xff) }, | 1561 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff92, 0xff, 0xff, 0xff) }, |
1561 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) }, | 1562 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) }, |
1562 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) }, | 1563 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) }, |
1563 | 1564 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffec, 0xff, 0xff, 0xff) }, | |
1565 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffee, 0xff, 0xff, 0xff) }, | ||
1566 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xfff6, 0xff, 0xff, 0xff) }, | ||
1567 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xfff7, 0xff, 0xff, 0xff) }, | ||
1568 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xfff8, 0xff, 0xff, 0xff) }, | ||
1569 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xfff9, 0xff, 0xff, 0xff) }, | ||
1570 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xfffb, 0xff, 0xff, 0xff) }, | ||
1571 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xfffc, 0xff, 0xff, 0xff) }, | ||
1572 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MG880, 0xff, 0xff, 0xff) }, | ||
1564 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, | 1573 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, |
1565 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, | 1574 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, |
1566 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, | 1575 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, |
diff --git a/drivers/usb/serial/zte_ev.c b/drivers/usb/serial/zte_ev.c deleted file mode 100644 index c9bb107d5e5c..000000000000 --- a/drivers/usb/serial/zte_ev.c +++ /dev/null | |||
@@ -1,305 +0,0 @@ | |||
1 | /* | ||
2 | * ZTE_EV USB serial driver | ||
3 | * | ||
4 | * Copyright (C) 2012 Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||
5 | * Copyright (C) 2012 Linux Foundation | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This driver is based on code found in a ZTE_ENV patch that modified | ||
12 | * the usb-serial generic driver. Comments were left in that I think | ||
13 | * show the commands used to talk to the device, but I am not sure. | ||
14 | */ | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/tty.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/usb.h> | ||
20 | #include <linux/usb/serial.h> | ||
21 | #include <linux/uaccess.h> | ||
22 | |||
23 | #define MAX_SETUP_DATA_SIZE 32 | ||
24 | |||
25 | static void debug_data(struct device *dev, const char *function, int len, | ||
26 | const unsigned char *data, int result) | ||
27 | { | ||
28 | dev_dbg(dev, "result = %d\n", result); | ||
29 | if (result == len) | ||
30 | dev_dbg(dev, "%s - length = %d, data = %*ph\n", function, | ||
31 | len, len, data); | ||
32 | } | ||
33 | |||
34 | static int zte_ev_usb_serial_open(struct tty_struct *tty, | ||
35 | struct usb_serial_port *port) | ||
36 | { | ||
37 | struct usb_device *udev = port->serial->dev; | ||
38 | struct device *dev = &port->dev; | ||
39 | int result = 0; | ||
40 | int len; | ||
41 | unsigned char *buf; | ||
42 | |||
43 | buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL); | ||
44 | if (!buf) | ||
45 | return -ENOMEM; | ||
46 | |||
47 | /* send 1st ctl cmd(CTL 21 22 01 00 00 00 00 00) */ | ||
48 | len = 0; | ||
49 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
50 | 0x22, 0x21, | ||
51 | 0x0001, 0x0000, NULL, len, | ||
52 | USB_CTRL_GET_TIMEOUT); | ||
53 | dev_dbg(dev, "result = %d\n", result); | ||
54 | |||
55 | /* send 2st cmd and receive data */ | ||
56 | /* | ||
57 | * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 25.1.0(5) | ||
58 | * 16.0 DI 00 96 00 00 00 00 08 | ||
59 | */ | ||
60 | len = 0x0007; | ||
61 | result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
62 | 0x21, 0xa1, | ||
63 | 0x0000, 0x0000, buf, len, | ||
64 | USB_CTRL_GET_TIMEOUT); | ||
65 | debug_data(dev, __func__, len, buf, result); | ||
66 | |||
67 | /* send 3rd cmd */ | ||
68 | /* | ||
69 | * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 30.1.0 | ||
70 | * 16.0 DO 80 25 00 00 00 00 08 .%..... 30.2.0 | ||
71 | */ | ||
72 | len = 0x0007; | ||
73 | buf[0] = 0x80; | ||
74 | buf[1] = 0x25; | ||
75 | buf[2] = 0x00; | ||
76 | buf[3] = 0x00; | ||
77 | buf[4] = 0x00; | ||
78 | buf[5] = 0x00; | ||
79 | buf[6] = 0x08; | ||
80 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
81 | 0x20, 0x21, | ||
82 | 0x0000, 0x0000, buf, len, | ||
83 | USB_CTRL_GET_TIMEOUT); | ||
84 | debug_data(dev, __func__, len, buf, result); | ||
85 | |||
86 | /* send 4th cmd */ | ||
87 | /* | ||
88 | * 16.0 CTL 21 22 03 00 00 00 00 00 | ||
89 | */ | ||
90 | len = 0; | ||
91 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
92 | 0x22, 0x21, | ||
93 | 0x0003, 0x0000, NULL, len, | ||
94 | USB_CTRL_GET_TIMEOUT); | ||
95 | dev_dbg(dev, "result = %d\n", result); | ||
96 | |||
97 | /* send 5th cmd */ | ||
98 | /* | ||
99 | * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 33.1.0 | ||
100 | * 16.0 DI 80 25 00 00 00 00 08 | ||
101 | */ | ||
102 | len = 0x0007; | ||
103 | result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
104 | 0x21, 0xa1, | ||
105 | 0x0000, 0x0000, buf, len, | ||
106 | USB_CTRL_GET_TIMEOUT); | ||
107 | debug_data(dev, __func__, len, buf, result); | ||
108 | |||
109 | /* send 6th cmd */ | ||
110 | /* | ||
111 | * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 34.1.0 | ||
112 | * 16.0 DO 80 25 00 00 00 00 08 | ||
113 | */ | ||
114 | len = 0x0007; | ||
115 | buf[0] = 0x80; | ||
116 | buf[1] = 0x25; | ||
117 | buf[2] = 0x00; | ||
118 | buf[3] = 0x00; | ||
119 | buf[4] = 0x00; | ||
120 | buf[5] = 0x00; | ||
121 | buf[6] = 0x08; | ||
122 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
123 | 0x20, 0x21, | ||
124 | 0x0000, 0x0000, buf, len, | ||
125 | USB_CTRL_GET_TIMEOUT); | ||
126 | debug_data(dev, __func__, len, buf, result); | ||
127 | kfree(buf); | ||
128 | |||
129 | return usb_serial_generic_open(tty, port); | ||
130 | } | ||
131 | |||
132 | /* | ||
133 | * CTL 21 22 02 00 00 00 00 00 CLASS 338.1.0 | ||
134 | * | ||
135 | * 16.1 DI a1 20 00 00 00 00 02 00 02 00 . ........ 340.1.0 | ||
136 | * 16.0 CTL 21 22 03 00 00 00 00 00 CLASS 341.1.0 | ||
137 | * | ||
138 | * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 346.1.0(3) | ||
139 | * 16.0 DI 00 08 07 00 00 00 08 ....... 346.2.0 | ||
140 | * | ||
141 | * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 349.1.0 | ||
142 | * 16.0 DO 00 c2 01 00 00 00 08 ....... 349.2.0 | ||
143 | * | ||
144 | * 16.0 CTL 21 22 03 00 00 00 00 00 CLASS 350.1.0(2) | ||
145 | * | ||
146 | * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 352.1.0 | ||
147 | * 16.0 DI 00 c2 01 00 00 00 08 ....... 352.2.0 | ||
148 | * | ||
149 | * 16.1 DI a1 20 00 00 00 00 02 00 02 00 . ........ 353.1.0 | ||
150 | * | ||
151 | * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 354.1.0 | ||
152 | * 16.0 DO 00 c2 01 00 00 00 08 ....... 354.2.0 | ||
153 | * | ||
154 | * 16.0 CTL 21 22 03 00 00 00 00 00 | ||
155 | */ | ||
156 | |||
157 | static void zte_ev_usb_serial_close(struct usb_serial_port *port) | ||
158 | { | ||
159 | struct usb_device *udev = port->serial->dev; | ||
160 | struct device *dev = &port->dev; | ||
161 | int result = 0; | ||
162 | int len; | ||
163 | unsigned char *buf; | ||
164 | |||
165 | buf = kmalloc(MAX_SETUP_DATA_SIZE, GFP_KERNEL); | ||
166 | if (!buf) | ||
167 | return; | ||
168 | |||
169 | /* send 1st ctl cmd(CTL 21 22 02 00 00 00 00 00) */ | ||
170 | len = 0; | ||
171 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
172 | 0x22, 0x21, | ||
173 | 0x0002, 0x0000, NULL, len, | ||
174 | USB_CTRL_GET_TIMEOUT); | ||
175 | dev_dbg(dev, "result = %d\n", result); | ||
176 | |||
177 | /* send 2st ctl cmd(CTL 21 22 03 00 00 00 00 00 ) */ | ||
178 | len = 0; | ||
179 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
180 | 0x22, 0x21, | ||
181 | 0x0003, 0x0000, NULL, len, | ||
182 | USB_CTRL_GET_TIMEOUT); | ||
183 | dev_dbg(dev, "result = %d\n", result); | ||
184 | |||
185 | /* send 3st cmd and recieve data */ | ||
186 | /* | ||
187 | * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 25.1.0(5) | ||
188 | * 16.0 DI 00 08 07 00 00 00 08 | ||
189 | */ | ||
190 | len = 0x0007; | ||
191 | result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
192 | 0x21, 0xa1, | ||
193 | 0x0000, 0x0000, buf, len, | ||
194 | USB_CTRL_GET_TIMEOUT); | ||
195 | debug_data(dev, __func__, len, buf, result); | ||
196 | |||
197 | /* send 4th cmd */ | ||
198 | /* | ||
199 | * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 30.1.0 | ||
200 | * 16.0 DO 00 c2 01 00 00 00 08 .%..... 30.2.0 | ||
201 | */ | ||
202 | len = 0x0007; | ||
203 | buf[0] = 0x00; | ||
204 | buf[1] = 0xc2; | ||
205 | buf[2] = 0x01; | ||
206 | buf[3] = 0x00; | ||
207 | buf[4] = 0x00; | ||
208 | buf[5] = 0x00; | ||
209 | buf[6] = 0x08; | ||
210 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
211 | 0x20, 0x21, | ||
212 | 0x0000, 0x0000, buf, len, | ||
213 | USB_CTRL_GET_TIMEOUT); | ||
214 | debug_data(dev, __func__, len, buf, result); | ||
215 | |||
216 | /* send 5th cmd */ | ||
217 | /* | ||
218 | * 16.0 CTL 21 22 03 00 00 00 00 00 | ||
219 | */ | ||
220 | len = 0; | ||
221 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
222 | 0x22, 0x21, | ||
223 | 0x0003, 0x0000, NULL, len, | ||
224 | USB_CTRL_GET_TIMEOUT); | ||
225 | dev_dbg(dev, "result = %d\n", result); | ||
226 | |||
227 | /* send 6th cmd */ | ||
228 | /* | ||
229 | * 16.0 CTL a1 21 00 00 00 00 07 00 CLASS 33.1.0 | ||
230 | * 16.0 DI 00 c2 01 00 00 00 08 | ||
231 | */ | ||
232 | len = 0x0007; | ||
233 | result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
234 | 0x21, 0xa1, | ||
235 | 0x0000, 0x0000, buf, len, | ||
236 | USB_CTRL_GET_TIMEOUT); | ||
237 | debug_data(dev, __func__, len, buf, result); | ||
238 | |||
239 | /* send 7th cmd */ | ||
240 | /* | ||
241 | * 16.0 CTL 21 20 00 00 00 00 07 00 CLASS 354.1.0 | ||
242 | * 16.0 DO 00 c2 01 00 00 00 08 ....... 354.2.0 | ||
243 | */ | ||
244 | len = 0x0007; | ||
245 | buf[0] = 0x00; | ||
246 | buf[1] = 0xc2; | ||
247 | buf[2] = 0x01; | ||
248 | buf[3] = 0x00; | ||
249 | buf[4] = 0x00; | ||
250 | buf[5] = 0x00; | ||
251 | buf[6] = 0x08; | ||
252 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
253 | 0x20, 0x21, | ||
254 | 0x0000, 0x0000, buf, len, | ||
255 | USB_CTRL_GET_TIMEOUT); | ||
256 | debug_data(dev, __func__, len, buf, result); | ||
257 | |||
258 | /* send 8th cmd */ | ||
259 | /* | ||
260 | * 16.0 CTL 21 22 03 00 00 00 00 00 | ||
261 | */ | ||
262 | len = 0; | ||
263 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
264 | 0x22, 0x21, | ||
265 | 0x0003, 0x0000, NULL, len, | ||
266 | USB_CTRL_GET_TIMEOUT); | ||
267 | dev_dbg(dev, "result = %d\n", result); | ||
268 | |||
269 | kfree(buf); | ||
270 | |||
271 | usb_serial_generic_close(port); | ||
272 | } | ||
273 | |||
274 | static const struct usb_device_id id_table[] = { | ||
275 | { USB_DEVICE(0x19d2, 0xffec) }, | ||
276 | { USB_DEVICE(0x19d2, 0xffee) }, | ||
277 | { USB_DEVICE(0x19d2, 0xfff6) }, | ||
278 | { USB_DEVICE(0x19d2, 0xfff7) }, | ||
279 | { USB_DEVICE(0x19d2, 0xfff8) }, | ||
280 | { USB_DEVICE(0x19d2, 0xfff9) }, | ||
281 | { USB_DEVICE(0x19d2, 0xfffb) }, | ||
282 | { USB_DEVICE(0x19d2, 0xfffc) }, | ||
283 | /* MG880 */ | ||
284 | { USB_DEVICE(0x19d2, 0xfffd) }, | ||
285 | { }, | ||
286 | }; | ||
287 | MODULE_DEVICE_TABLE(usb, id_table); | ||
288 | |||
289 | static struct usb_serial_driver zio_device = { | ||
290 | .driver = { | ||
291 | .owner = THIS_MODULE, | ||
292 | .name = "zte_ev", | ||
293 | }, | ||
294 | .id_table = id_table, | ||
295 | .num_ports = 1, | ||
296 | .open = zte_ev_usb_serial_open, | ||
297 | .close = zte_ev_usb_serial_close, | ||
298 | }; | ||
299 | |||
300 | static struct usb_serial_driver * const serial_drivers[] = { | ||
301 | &zio_device, NULL | ||
302 | }; | ||
303 | |||
304 | module_usb_serial_driver(serial_drivers, id_table); | ||
305 | MODULE_LICENSE("GPL v2"); | ||