1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "default_config.h"
17 #include "device_resource_if.h"
18 #include "hdf_base.h"
19 #include "hdf_device_desc.h"
20 #include "hdf_device_object.h"
21 #include "hdf_log.h"
22 #include "osal_mem.h"
23 #include "osal_time.h"
24 #include "securec.h"
25 #include "usbfn_device.h"
26 #include "usbfn_interface.h"
27 #include "usbfn_request.h"
28
29 #define HDF_LOG_TAG dev_master
30
31 #define CDC_ACM
32 #define CDC_ECM
33
34 #define SS_MAX_PACKET_SIZE 1024
35 #define MAX_PACKET_SIZE 512
36 #define EP_ADD_NOTIFY 1
37 #define EP_ADD_DATA_IN 2
38 #define EP_ADD_DATA_OUT 3
39 #define DATA_EP_NUM 2
40 #define NOTIFY_EP_NUM 1
41 #define INTF_COUNT 2
42
43 #ifdef CDC_ECM
44 #define ECM_HS_INTERVAL 9
45 #define ECM_STATUS_INTERVAL_MS 32
46 #define ECM_STATUS_BYTECOUNT 16 /* 8 byte header + data */
47
48 #define ECM_CTRL_IDX 1
49 #define ECM_DATA_IDX 2
50 #define ECM_IAD_IDX 3
51
52 enum DevMasterCmd {
53 DEV_MASTER_INIT = 0x1,
54 DEV_MASTER_RELEASE,
55 };
56
57 struct DevMasterMgr {
58 struct IDeviceIoService service;
59 struct UsbFnDescriptorData descData;
60 struct HdfDeviceObject *device;
61 const char *udcName;
62 };
63
64 /* interface descriptor: */
65 static struct UsbInterfaceAssocDescriptor g_ecmIadDescriptor = {
66 .bLength = sizeof(g_ecmIadDescriptor),
67 .bDescriptorType = USB_DDK_DT_INTERFACE_ASSOCIATION,
68 .bFirstInterface = 0,
69 .bInterfaceCount = INTF_COUNT,
70 .bFunctionClass = USB_DDK_CLASS_COMM,
71 .bFunctionSubClass = USB_DDK_CDC_SUBCLASS_ETHERNET,
72 .bFunctionProtocol = USB_DDK_CDC_PROTO_NONE,
73 .iFunction = ECM_IAD_IDX,
74 };
75
76 static struct UsbInterfaceDescriptor g_ecmControlIntf = {
77 .bLength = sizeof(g_ecmControlIntf),
78 .bDescriptorType = USB_DDK_DT_INTERFACE,
79 .bInterfaceNumber = 0,
80 .bNumEndpoints = NOTIFY_EP_NUM,
81 .bInterfaceClass = USB_DDK_CLASS_COMM,
82 .bInterfaceSubClass = USB_DDK_CDC_SUBCLASS_ETHERNET,
83 .bInterfaceProtocol = USB_DDK_CDC_PROTO_NONE,
84 .iInterface = ECM_CTRL_IDX,
85 };
86
87 static struct UsbCdcHeaderDesc g_ecmHeaderDesc = {
88 .bLength = sizeof(g_ecmHeaderDesc),
89 .bDescriptorType = USB_DDK_DT_CS_INTERFACE,
90 .bDescriptorSubType = USB_DDK_CDC_HEADER_TYPE,
91
92 .bcdCDC = CPU_TO_LE16(0x0110),
93 };
94
95 static struct UsbCdcUnionDesc g_ecmUnionDesc = {
96 .bLength = sizeof(g_ecmUnionDesc),
97 .bDescriptorType = USB_DDK_DT_CS_INTERFACE,
98 .bDescriptorSubType = USB_DDK_CDC_UNION_TYPE,
99 .bMasterInterface0 = 0,
100 .bSlaveInterface0 = 1,
101 };
102
103 #define MAC_ADDR 6
104 static struct UsbCdcEtherDesc g_ecmDesc = {
105 .bLength = sizeof(g_ecmDesc),
106 .bDescriptorType = USB_DDK_DT_CS_INTERFACE,
107 .bDescriptorSubType = USB_DDK_CDC_ETHERNET_TYPE,
108 .iMACAddress = MAC_ADDR,
109 .bmEthernetStatistics = CPU_TO_LE32(0),
110 .wMaxSegmentSize = CPU_TO_LE16(0x05ea),
111 .wNumberMCFilters = CPU_TO_LE16(0),
112 .bNumberPowerFilters = 0,
113 };
114
115 /* the default data interface has no endpoints ... */
116 static struct UsbInterfaceDescriptor g_ecmDataNopIntf = {
117 .bLength = sizeof(g_ecmDataNopIntf),
118 .bDescriptorType = USB_DDK_DT_INTERFACE,
119
120 .bInterfaceNumber = 1,
121 .bAlternateSetting = 0,
122 .bNumEndpoints = 0,
123 .bInterfaceClass = USB_DDK_CLASS_CDC_DATA,
124 .bInterfaceSubClass = 0,
125 .bInterfaceProtocol = 6,
126 };
127
128 /* ... but the "real" data interface has two bulk endpoints */
129 static struct UsbInterfaceDescriptor g_ecmDataIntf = {
130 .bLength = sizeof(g_ecmDataIntf),
131 .bDescriptorType = USB_DDK_DT_INTERFACE,
132
133 .bInterfaceNumber = 1,
134 .bAlternateSetting = 1,
135 .bNumEndpoints = DATA_EP_NUM,
136 .bInterfaceClass = USB_DDK_CLASS_CDC_DATA,
137 .bInterfaceSubClass = 0,
138 .bInterfaceProtocol = 6,
139 .iInterface = ECM_DATA_IDX,
140 };
141
142 /* full speed support: */
143 static struct UsbEndpointDescriptor g_fsEcmNotifyDesc = {
144 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
145 .bDescriptorType = USB_DDK_DT_ENDPOINT,
146
147 .bEndpointAddress = EP_ADD_NOTIFY | USB_DDK_DIR_IN,
148 .bmAttributes = USB_DDK_ENDPOINT_XFER_INT,
149 .wMaxPacketSize = CPU_TO_LE16(ECM_STATUS_BYTECOUNT),
150 .bInterval = ECM_STATUS_INTERVAL_MS,
151 };
152
153 static struct UsbEndpointDescriptor g_fsEcmInDesc = {
154 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
155 .bDescriptorType = USB_DDK_DT_ENDPOINT,
156
157 .bEndpointAddress = EP_ADD_DATA_IN | USB_DDK_DIR_IN,
158 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
159 };
160
161 static struct UsbEndpointDescriptor g_fsEcmOutDesc = {
162 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
163 .bDescriptorType = USB_DDK_DT_ENDPOINT,
164
165 .bEndpointAddress = EP_ADD_DATA_OUT | USB_DDK_DIR_OUT,
166 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
167 };
168
169 static struct UsbDescriptorHeader *g_ecmFsFunction[] = {
170 /* CDC ECM control descriptors */
171 (struct UsbDescriptorHeader *)&g_ecmIadDescriptor,
172 (struct UsbDescriptorHeader *)&g_ecmControlIntf,
173 (struct UsbDescriptorHeader *)&g_ecmHeaderDesc,
174 (struct UsbDescriptorHeader *)&g_ecmUnionDesc,
175 (struct UsbDescriptorHeader *)&g_ecmDesc,
176
177 /* NOTE: status endpoint might need to be removed */
178 (struct UsbDescriptorHeader *)&g_fsEcmNotifyDesc,
179
180 /* data interface, altsettings 0 and 1 */
181 (struct UsbDescriptorHeader *)&g_ecmDataNopIntf,
182 (struct UsbDescriptorHeader *)&g_ecmDataIntf,
183 (struct UsbDescriptorHeader *)&g_fsEcmInDesc,
184 (struct UsbDescriptorHeader *)&g_fsEcmOutDesc,
185 NULL,
186 };
187
188 /* high speed support: */
189 static struct UsbEndpointDescriptor g_hsEcmNotifyDesc = {
190 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
191 .bDescriptorType = USB_DDK_DT_ENDPOINT,
192
193 .bEndpointAddress = EP_ADD_NOTIFY | USB_DDK_DIR_IN,
194 .bmAttributes = USB_DDK_ENDPOINT_XFER_INT,
195 .wMaxPacketSize = CPU_TO_LE16(ECM_STATUS_BYTECOUNT),
196 .bInterval = ECM_HS_INTERVAL,
197 };
198
199 static struct UsbEndpointDescriptor g_hsEcmInDesc = {
200 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
201 .bDescriptorType = USB_DDK_DT_ENDPOINT,
202
203 .bEndpointAddress = EP_ADD_DATA_IN | USB_DDK_DIR_IN,
204 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
205 .wMaxPacketSize = CPU_TO_LE16(MAX_PACKET_SIZE),
206 };
207
208 static struct UsbEndpointDescriptor g_hsEcmOutDesc = {
209 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
210 .bDescriptorType = USB_DDK_DT_ENDPOINT,
211
212 .bEndpointAddress = EP_ADD_DATA_OUT | USB_DDK_DIR_OUT,
213 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
214 .wMaxPacketSize = CPU_TO_LE16(MAX_PACKET_SIZE),
215 };
216
217 static struct UsbDescriptorHeader *g_ecmHsFunction[] = {
218 /* CDC ECM control descriptors */
219 (struct UsbDescriptorHeader *)&g_ecmIadDescriptor,
220 (struct UsbDescriptorHeader *)&g_ecmControlIntf,
221 (struct UsbDescriptorHeader *)&g_ecmHeaderDesc,
222 (struct UsbDescriptorHeader *)&g_ecmUnionDesc,
223 (struct UsbDescriptorHeader *)&g_ecmDesc,
224
225 /* NOTE: status endpoint might need to be removed */
226 (struct UsbDescriptorHeader *)&g_hsEcmNotifyDesc,
227
228 /* data interface, altsettings 0 and 1 */
229 (struct UsbDescriptorHeader *)&g_ecmDataNopIntf,
230 (struct UsbDescriptorHeader *)&g_ecmDataIntf,
231 (struct UsbDescriptorHeader *)&g_hsEcmInDesc,
232 (struct UsbDescriptorHeader *)&g_hsEcmOutDesc,
233 NULL,
234 };
235
236 /* super speed support: */
237 static struct UsbEndpointDescriptor g_ssEcmNotifyDesc = {
238 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
239 .bDescriptorType = USB_DDK_DT_ENDPOINT,
240
241 .bEndpointAddress = EP_ADD_NOTIFY | USB_DDK_DIR_IN,
242 .bmAttributes = USB_DDK_ENDPOINT_XFER_INT,
243 .wMaxPacketSize = CPU_TO_LE16(ECM_STATUS_BYTECOUNT),
244 .bInterval = ECM_HS_INTERVAL,
245 };
246
247 static struct UsbSsEpCompDescriptor g_ssEcmIntrCompDesc = {
248 .bLength = sizeof(g_ssEcmIntrCompDesc),
249 .bDescriptorType = USB_DDK_DT_SS_ENDPOINT_COMP,
250
251 /* the following 3 values can be tweaked if necessary */
252 /* .bMaxBurst = 0, */
253 /* .bmAttributes = 0, */
254 .wBytesPerInterval = CPU_TO_LE16(ECM_STATUS_BYTECOUNT),
255 };
256
257 static struct UsbEndpointDescriptor g_ssEcmInDesc = {
258 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
259 .bDescriptorType = USB_DDK_DT_ENDPOINT,
260
261 .bEndpointAddress = EP_ADD_DATA_IN | USB_DDK_DIR_IN,
262 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
263 .wMaxPacketSize = CPU_TO_LE16(SS_MAX_PACKET_SIZE),
264 };
265
266 static struct UsbEndpointDescriptor g_ssEcmOutDesc = {
267 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
268 .bDescriptorType = USB_DDK_DT_ENDPOINT,
269
270 .bEndpointAddress = EP_ADD_DATA_OUT | USB_DDK_DIR_OUT,
271 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
272 .wMaxPacketSize = CPU_TO_LE16(SS_MAX_PACKET_SIZE),
273 };
274
275 static struct UsbSsEpCompDescriptor g_ssEcmBulkCompDesc = {
276 .bLength = sizeof(g_ssEcmBulkCompDesc), .bDescriptorType = USB_DDK_DT_SS_ENDPOINT_COMP,
277
278 /* the following 2 values can be tweaked if necessary */
279 /* .bMaxBurst = 0, */
280 /* .bmAttributes = 0, */
281 };
282
283 static struct UsbDescriptorHeader *g_ecmSsFunction[] = {
284 /* CDC ECM control descriptors */
285 (struct UsbDescriptorHeader *)&g_ecmIadDescriptor,
286 (struct UsbDescriptorHeader *)&g_ecmControlIntf,
287 (struct UsbDescriptorHeader *)&g_ecmHeaderDesc,
288 (struct UsbDescriptorHeader *)&g_ecmUnionDesc,
289 (struct UsbDescriptorHeader *)&g_ecmDesc,
290
291 /* NOTE: status endpoint might need to be removed */
292 (struct UsbDescriptorHeader *)&g_ssEcmNotifyDesc,
293 (struct UsbDescriptorHeader *)&g_ssEcmIntrCompDesc,
294
295 /* data interface, altsettings 0 and 1 */
296 (struct UsbDescriptorHeader *)&g_ecmDataNopIntf,
297 (struct UsbDescriptorHeader *)&g_ecmDataIntf,
298 (struct UsbDescriptorHeader *)&g_ssEcmInDesc,
299 (struct UsbDescriptorHeader *)&g_ssEcmBulkCompDesc,
300 (struct UsbDescriptorHeader *)&g_ssEcmOutDesc,
301 (struct UsbDescriptorHeader *)&g_ssEcmBulkCompDesc,
302 NULL,
303 };
304
305 /* string descriptors: */
306 static struct UsbString g_ecmStringDefs[] = {
307 [0].s = "CDC Ethernet Control Model (ECM)",
308 [0x01].s = "0ac75ae91c79",
309 [0x02].s = "CDC Ethernet Data",
310 [0x03].s = "CDC ECM",
311 {} /* end of list */
312 };
313
314 static struct UsbFnStrings g_ecmStringTable = {
315 .language = 0x0409, /* en-us */
316 .strings = g_ecmStringDefs,
317 };
318
319 static struct UsbFnStrings *g_ecmStrings[] = {
320 &g_ecmStringTable,
321 NULL,
322 };
323
324 static struct UsbFnFunction g_ecmFunction = {
325 .enable = true,
326 .funcName = "f_generic.e",
327 .strings = g_ecmStrings,
328 .fsDescriptors = g_ecmFsFunction,
329 .hsDescriptors = g_ecmHsFunction,
330 .ssDescriptors = g_ecmSsFunction,
331 .sspDescriptors = NULL,
332 };
333 #endif
334
335 #ifdef CDC_ACM
336 #define ACM_NOTIFY_INTERVAL 32 /* ms */
337 #define ACM_HS_NOTIFY_INTERVAL 9 /* ms */
338 #define ACM_NOTIFY_MAXPACKET 10 /* notification + 2 bytes */
339
340 #define ACM_CTRL_IDX 1
341 #define ACM_DATA_IDX 2
342 #define ACM_IAD_IDX 3
343
344 static struct UsbInterfaceAssocDescriptor g_acmIadDescriptor = {
345 .bLength = sizeof(g_acmIadDescriptor),
346 .bDescriptorType = USB_DDK_DT_INTERFACE_ASSOCIATION,
347 #ifdef CDC_ECM
348 .bFirstInterface = 0x02,
349 #else
350 .bFirstInterface = 0,
351 #endif
352 .bInterfaceCount = INTF_COUNT,
353 .bFunctionClass = USB_DDK_CLASS_COMM,
354 .bFunctionSubClass = USB_DDK_CDC_SUBCLASS_ACM,
355 .bFunctionProtocol = USB_DDK_CDC_ACM_PROTO_AT_V25TER,
356 .iFunction = ACM_IAD_IDX,
357 };
358
359 static struct UsbInterfaceDescriptor g_acmControlInterfaceDesc = {
360 .bLength = USB_DDK_DT_INTERFACE_SIZE,
361 .bDescriptorType = USB_DDK_DT_INTERFACE,
362 #ifdef CDC_ECM
363 .bInterfaceNumber = 0x02,
364 #else
365 .bInterfaceNumber = 0,
366 #endif
367 .bAlternateSetting = 0,
368 .bNumEndpoints = NOTIFY_EP_NUM,
369 .bInterfaceClass = USB_DDK_CLASS_COMM,
370 .bInterfaceSubClass = USB_DDK_CDC_SUBCLASS_ACM,
371 .bInterfaceProtocol = USB_DDK_CDC_ACM_PROTO_AT_V25TER,
372 .iInterface = ACM_CTRL_IDX,
373 };
374
375 static struct UsbInterfaceDescriptor g_acmDataInterfaceDesc = {
376 .bLength = USB_DDK_DT_INTERFACE_SIZE,
377 .bDescriptorType = USB_DDK_DT_INTERFACE,
378 #ifdef CDC_ECM
379 .bInterfaceNumber = 0x03,
380 #else
381 .bInterfaceNumber = 1,
382 #endif
383 .bAlternateSetting = 0,
384 .bNumEndpoints = DATA_EP_NUM,
385 .bInterfaceClass = USB_DDK_CLASS_CDC_DATA,
386 .bInterfaceSubClass = 0,
387 .bInterfaceProtocol = 2,
388 .iInterface = ACM_DATA_IDX,
389 };
390
391 static struct UsbCdcHeaderDesc g_acmHeaderDesc = {
392 .bLength = sizeof(g_acmHeaderDesc),
393 .bDescriptorType = USB_DDK_DT_CS_INTERFACE,
394 .bDescriptorSubType = USB_DDK_CDC_HEADER_TYPE,
395 .bcdCDC = CPU_TO_LE16(0x0110),
396 };
397
398 static struct UsbCdcCallMgmtDescriptor g_acmCallMgmtDescriptor = {
399 .bLength = sizeof(g_acmCallMgmtDescriptor),
400 .bDescriptorType = USB_DDK_DT_CS_INTERFACE,
401 .bDescriptorSubType = USB_DDK_CDC_CALL_MANAGEMENT_TYPE,
402 .bmCapabilities = 0,
403 .bDataInterface = 1,
404 };
405
406 static struct UsbCdcAcmDescriptor g_acmDescriptor = {
407 .bLength = sizeof(g_acmDescriptor),
408 .bDescriptorType = USB_DDK_DT_CS_INTERFACE,
409 .bDescriptorSubType = USB_DDK_CDC_ACM_TYPE,
410 .bmCapabilities = USB_DDK_CDC_CAP_LINE,
411 };
412
413 static struct UsbCdcUnionDesc g_acmUnionDesc = {
414 .bLength = sizeof(g_acmUnionDesc),
415 .bDescriptorType = USB_DDK_DT_CS_INTERFACE,
416 .bDescriptorSubType = USB_DDK_CDC_UNION_TYPE,
417 #ifdef CDC_ECM
418 .bMasterInterface0 = 0x02,
419 .bSlaveInterface0 = 0x03,
420 #else
421 .bMasterInterface0 = 0,
422 .bSlaveInterface0 = 1,
423 #endif
424 };
425
426 static struct UsbEndpointDescriptor g_acmFsNotifyDesc = {
427 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
428 .bDescriptorType = USB_DDK_DT_ENDPOINT,
429 .bEndpointAddress = EP_ADD_NOTIFY | USB_DDK_DIR_IN,
430 .bmAttributes = USB_DDK_ENDPOINT_XFER_INT,
431 .wMaxPacketSize = CPU_TO_LE16(ACM_NOTIFY_MAXPACKET),
432 .bInterval = ACM_NOTIFY_INTERVAL,
433 };
434
435 static struct UsbEndpointDescriptor g_acmFsInDesc = {
436 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
437 .bDescriptorType = USB_DDK_DT_ENDPOINT,
438 .bEndpointAddress = EP_ADD_DATA_IN | USB_DDK_DIR_IN,
439 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
440 };
441
442 static struct UsbEndpointDescriptor g_acmFsOutDesc = {
443 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
444 .bDescriptorType = USB_DDK_DT_ENDPOINT,
445 .bEndpointAddress = EP_ADD_DATA_OUT | USB_DDK_DIR_OUT,
446 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
447 };
448
449 static struct UsbDescriptorHeader *g_acmFsFunction[] = {
450 (struct UsbDescriptorHeader *)&g_acmIadDescriptor,
451 (struct UsbDescriptorHeader *)&g_acmControlInterfaceDesc,
452 (struct UsbDescriptorHeader *)&g_acmHeaderDesc,
453 (struct UsbDescriptorHeader *)&g_acmCallMgmtDescriptor,
454 (struct UsbDescriptorHeader *)&g_acmDescriptor,
455 (struct UsbDescriptorHeader *)&g_acmUnionDesc,
456 (struct UsbDescriptorHeader *)&g_acmFsNotifyDesc,
457 (struct UsbDescriptorHeader *)&g_acmDataInterfaceDesc,
458 (struct UsbDescriptorHeader *)&g_acmFsInDesc,
459 (struct UsbDescriptorHeader *)&g_acmFsOutDesc,
460 NULL,
461 };
462
463 static struct UsbEndpointDescriptor g_acmHsNotifyDesc = {
464 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
465 .bDescriptorType = USB_DDK_DT_ENDPOINT,
466 .bEndpointAddress = EP_ADD_NOTIFY | USB_DDK_DIR_IN,
467 .bmAttributes = USB_DDK_ENDPOINT_XFER_INT,
468 .wMaxPacketSize = CPU_TO_LE16(ACM_NOTIFY_MAXPACKET),
469 .bInterval = ACM_HS_NOTIFY_INTERVAL,
470 };
471
472 static struct UsbEndpointDescriptor g_acmHsInDesc = {
473 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
474 .bDescriptorType = USB_DDK_DT_ENDPOINT,
475 .bEndpointAddress = EP_ADD_DATA_IN | USB_DDK_DIR_IN,
476 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
477 .wMaxPacketSize = CPU_TO_LE16(MAX_PACKET_SIZE),
478 };
479
480 static struct UsbEndpointDescriptor g_acmHsOutDesc = {
481 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
482 .bDescriptorType = USB_DDK_DT_ENDPOINT,
483 .bEndpointAddress = EP_ADD_DATA_OUT | USB_DDK_DIR_OUT,
484 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
485 .wMaxPacketSize = CPU_TO_LE16(MAX_PACKET_SIZE),
486 };
487
488 static struct UsbDescriptorHeader *g_acmHsFunction[] = {
489 (struct UsbDescriptorHeader *)&g_acmIadDescriptor,
490 (struct UsbDescriptorHeader *)&g_acmControlInterfaceDesc,
491 (struct UsbDescriptorHeader *)&g_acmHeaderDesc,
492 (struct UsbDescriptorHeader *)&g_acmCallMgmtDescriptor,
493 (struct UsbDescriptorHeader *)&g_acmDescriptor,
494 (struct UsbDescriptorHeader *)&g_acmUnionDesc,
495 (struct UsbDescriptorHeader *)&g_acmHsNotifyDesc,
496 (struct UsbDescriptorHeader *)&g_acmDataInterfaceDesc,
497 (struct UsbDescriptorHeader *)&g_acmHsInDesc,
498 (struct UsbDescriptorHeader *)&g_acmHsOutDesc,
499 NULL,
500 };
501
502 static struct UsbEndpointDescriptor g_acmSsInDesc = {
503 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
504 .bDescriptorType = USB_DDK_DT_ENDPOINT,
505 .bEndpointAddress = EP_ADD_DATA_IN | USB_DDK_DIR_IN,
506 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
507 .wMaxPacketSize = CPU_TO_LE16(SS_MAX_PACKET_SIZE),
508 };
509
510 static struct UsbEndpointDescriptor g_acmSsOutDesc = {
511 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
512 .bDescriptorType = USB_DDK_DT_ENDPOINT,
513 .bEndpointAddress = EP_ADD_DATA_OUT | USB_DDK_DIR_OUT,
514 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
515 .wMaxPacketSize = CPU_TO_LE16(SS_MAX_PACKET_SIZE),
516 };
517
518 static struct UsbSsEpCompDescriptor g_acmSsBulkCompDesc = {
519 .bLength = sizeof(g_acmSsBulkCompDesc),
520 .bDescriptorType = USB_DDK_DT_SS_ENDPOINT_COMP,
521 };
522
523 static struct UsbDescriptorHeader *g_acmSsFunction[] = {
524 (struct UsbDescriptorHeader *)&g_acmIadDescriptor,
525 (struct UsbDescriptorHeader *)&g_acmControlInterfaceDesc,
526 (struct UsbDescriptorHeader *)&g_acmHeaderDesc,
527 (struct UsbDescriptorHeader *)&g_acmCallMgmtDescriptor,
528 (struct UsbDescriptorHeader *)&g_acmDescriptor,
529 (struct UsbDescriptorHeader *)&g_acmUnionDesc,
530 (struct UsbDescriptorHeader *)&g_acmHsNotifyDesc,
531 (struct UsbDescriptorHeader *)&g_acmSsBulkCompDesc,
532 (struct UsbDescriptorHeader *)&g_acmDataInterfaceDesc,
533 (struct UsbDescriptorHeader *)&g_acmSsInDesc,
534 (struct UsbDescriptorHeader *)&g_acmSsBulkCompDesc,
535 (struct UsbDescriptorHeader *)&g_acmSsOutDesc,
536 (struct UsbDescriptorHeader *)&g_acmSsBulkCompDesc,
537 NULL,
538 };
539
540 static struct UsbString g_acmStringDefs[] = {
541 [0].s = "CDC Abstract Control Model (ACM)", [0x01].s = "CDC ACM Data", [0x02].s = "CDC Serial", {} /* end of list */
542 };
543
544 static struct UsbFnStrings g_acmStringTable = {
545 .language = 0x0409, /* en-us */
546 .strings = g_acmStringDefs,
547 };
548
549 static struct UsbFnStrings *g_acmStrings[] = {
550 &g_acmStringTable,
551 NULL,
552 };
553
554 static struct UsbFnFunction g_acmFunction = {
555 .enable = true,
556 .funcName = "f_generic.a",
557 .strings = g_acmStrings,
558 .fsDescriptors = g_acmFsFunction,
559 .hsDescriptors = g_acmHsFunction,
560 .ssDescriptors = g_acmSsFunction,
561 .sspDescriptors = NULL,
562 };
563 #endif
564 /** device **/
565 #define BCD_USB 0x0200
566 #define DEVICE_VENDOR_ID 0x12D1
567 #define DEVICE_PRODUCT_ID 0x5000
568 #define DEVICE_VERSION 0x0223
569
570 #define USB_MAX_PACKET_SIZE 0x40
571 #define POWER 500
572
573 #define USB_FUNC_CONFIG_IDX USB_FUNC_FIRST_AVAIL_IDX
574 #define DRIVER_DESC "HDC Device"
575 #define CONFIG_DESC "hdc"
576
577 static struct UsbDeviceDescriptor g_cdcMasterDeviceDesc = {
578 .bLength = sizeof(g_cdcMasterDeviceDesc),
579 .bDescriptorType = USB_DDK_DT_DEVICE,
580 .bcdUSB = CPU_TO_LE16(BCD_USB),
581 .bDeviceClass = 0,
582 .bDeviceSubClass = 0,
583 .bDeviceProtocol = 0,
584 .bMaxPacketSize0 = USB_MAX_PACKET_SIZE,
585 .idVendor = CPU_TO_LE16(DEVICE_VENDOR_ID),
586 .idProduct = CPU_TO_LE16(DEVICE_PRODUCT_ID),
587 .bcdDevice = CPU_TO_LE16(DEVICE_VERSION),
588 .iManufacturer = USB_FUNC_MANUFACTURER_IDX,
589 .iProduct = USB_FUNC_PRODUCT_IDX,
590 .iSerialNumber = USB_FUNC_SERIAL_IDX,
591 .bNumConfigurations = 1,
592 };
593
594 static struct UsbString g_stringsDev[] = {
595 {USB_FUNC_MANUFACTURER_IDX, "HISILICON"},
596 {USB_FUNC_PRODUCT_IDX, DRIVER_DESC},
597 {USB_FUNC_SERIAL_IDX, "0123456789POPLAR"},
598 {USB_FUNC_CONFIG_IDX, CONFIG_DESC},
599 { } /* end of list */
600 };
601
602 static struct UsbFnStrings g_stringTabDev = {
603 .language = 0x0409, /* en-us */
604 .strings = g_stringsDev,
605 };
606
607 static struct UsbFnStrings *g_devStrings[] = {
608 &g_stringTabDev,
609 NULL,
610 };
611
612 struct UsbFnFunction *g_functions[] = {
613 #ifdef CDC_ECM
614 &g_ecmFunction,
615 #endif
616 #ifdef CDC_ACM
617 &g_acmFunction,
618 #endif
619 NULL};
620
621 static struct UsbFnConfiguration g_masterConfig = {
622 .configurationValue = 1,
623 .iConfiguration = USB_FUNC_CONFIG_IDX,
624 .attributes = USB_CFG_BUS_POWERED,
625 .maxPower = POWER,
626 .functions = g_functions,
627 };
628
629 static struct UsbFnConfiguration *g_configs[] = {
630 &g_masterConfig,
631 NULL,
632 };
633
634 static struct UsbFnDeviceDesc g_masterFuncDevice = {
635 .deviceDesc = &g_cdcMasterDeviceDesc,
636 .deviceStrings = g_devStrings,
637 .configs = g_configs,
638 };
639
640 struct UsbFnDevice *g_fnDev = NULL;
MasterReleaseFuncDevice(void)641 static int32_t MasterReleaseFuncDevice(void)
642 {
643 int32_t ret;
644 if (g_fnDev == NULL) {
645 HDF_LOGE("%s: fnDev is null", __func__);
646 return HDF_FAILURE;
647 }
648 ret = UsbFnRemoveDevice(g_fnDev);
649 if (ret == HDF_SUCCESS) {
650 g_fnDev = NULL;
651 } else {
652 HDF_LOGE("%{public}s: remove usb function device failed", __func__);
653 }
654
655 return ret;
656 }
657
UsbFnRegistUsbfnDevice(struct HdfDeviceIoClient * client,struct HdfSBuf * data,struct HdfSBuf * reply)658 static int32_t UsbFnRegistUsbfnDevice(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
659 {
660 struct HdfDeviceObject *device = client->device;
661 struct DevMasterMgr *devMgr = NULL;
662 struct UsbFnDevice *fnDev = NULL;
663 uint8_t value;
664 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
665
666 if (iface == NULL || iface->GetUint32 == NULL || device == NULL) {
667 HDF_LOGE("%s: face is invalid", __func__);
668 return HDF_FAILURE;
669 }
670 devMgr = (struct DevMasterMgr *)device->service;
671 if (HdfSbufReadUint8(data, &value) != true) {
672 HDF_LOGE("%s: read sbuf failed", __func__);
673 return HDF_FAILURE;
674 }
675 devMgr->descData.functionMask = value;
676 fnDev = (struct UsbFnDevice *)UsbFnCreateDevice(devMgr->udcName, &devMgr->descData);
677 if (fnDev == NULL) {
678 HDF_LOGE("%s: create usb function device failed", __func__);
679 if (!HdfSbufWriteInt8(reply, 0)) {
680 HDF_LOGE("UsbEcmRead HdfSbufWriteInt8 error");
681 }
682 return HDF_FAILURE;
683 }
684 g_fnDev = fnDev;
685 if (!HdfSbufWriteInt8(reply, value)) {
686 HDF_LOGE("UsbEcmRead HdfSbufWriteInt8 error");
687 return HDF_FAILURE;
688 }
689 return 0;
690 }
691
MasterDispatch(struct HdfDeviceIoClient * client,int32_t cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)692 static int32_t MasterDispatch(
693 struct HdfDeviceIoClient *client, int32_t cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
694 {
695 int32_t ret;
696 if (client == NULL) {
697 HDF_LOGE("%s: client is NULL", __func__);
698 return HDF_FAILURE;
699 }
700
701 if (HdfDeviceObjectCheckInterfaceDesc(client->device, data) == false) {
702 HDF_LOGE("%{public}s:%{public}d check interface desc fail", __func__, __LINE__);
703 return HDF_ERR_INVALID_PARAM;
704 }
705
706 switch (cmdId) {
707 case DEV_MASTER_INIT:
708 ret = UsbFnRegistUsbfnDevice(client, data, reply);
709 if (ret != HDF_SUCCESS) {
710 HDF_LOGE("%s: create usbfn device failed", __func__);
711 }
712 break;
713 case DEV_MASTER_RELEASE:
714 ret = MasterReleaseFuncDevice();
715 break;
716 default:
717 ret = HDF_ERR_INVALID_OBJECT;
718 HDF_LOGE("%s: unknown cmd id %d", __func__, cmdId);
719 break;
720 }
721 return ret;
722 }
723
724 /* HdfDriverEntry implementations */
MasterDriverBind(struct HdfDeviceObject * device)725 static int32_t MasterDriverBind(struct HdfDeviceObject *device)
726 {
727 struct DevMasterMgr *devMgr = NULL;
728 if (device == NULL) {
729 HDF_LOGE("%s:%d device is null\n", __func__, __LINE__);
730 return HDF_FAILURE;
731 }
732 devMgr = (struct DevMasterMgr *)OsalMemCalloc(sizeof(*devMgr));
733 if (devMgr == NULL) {
734 HDF_LOGE("%s: usbfn Alloc usb devMgr failed", __func__);
735 return HDF_FAILURE;
736 }
737
738 if (HdfDeviceObjectSetInterfaceDesc(device, "hdf.usb.usbfn") != HDF_SUCCESS) {
739 HDF_LOGE(" Set Desc fail!");
740 OsalMemFree(devMgr);
741 return HDF_FAILURE;
742 }
743
744 devMgr->device = device;
745 device->service = &(devMgr->service);
746 devMgr->device->service->Dispatch = MasterDispatch;
747 return HDF_SUCCESS;
748 }
749
MasterDriverInit(struct HdfDeviceObject * device)750 static int32_t MasterDriverInit(struct HdfDeviceObject *device)
751 {
752 struct DevMasterMgr *devMgr = NULL;
753 uint8_t useHcs;
754
755 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
756 if (iface == NULL || iface->GetUint32 == NULL || device == NULL) {
757 HDF_LOGE("%s: face is invalid", __func__);
758 return HDF_FAILURE;
759 }
760 devMgr = (struct DevMasterMgr *)device->service;
761 if (iface->GetString(device->property, "udc_name", &devMgr->udcName, UDC_NAME) != HDF_SUCCESS) {
762 HDF_LOGE("%s: read udc_name failed, use default", __func__);
763 }
764 if (iface->GetUint8(device->property, "use_hcs", &useHcs, 0) != HDF_SUCCESS) {
765 HDF_LOGE("%s: read use_hcs fail, use default", __func__);
766 }
767 if (useHcs == 0) {
768 devMgr->descData.type = USBFN_DESC_DATA_TYPE_DESC;
769 devMgr->descData.descriptor = &g_masterFuncDevice;
770 } else {
771 devMgr->descData.type = USBFN_DESC_DATA_TYPE_PROP;
772 devMgr->descData.property = device->property;
773 }
774 return HDF_SUCCESS;
775 }
776
MasterDriverRelease(struct HdfDeviceObject * device)777 static void MasterDriverRelease(struct HdfDeviceObject *device)
778 {
779 struct DevMasterMgr *devMgr = NULL;
780 devMgr = (struct DevMasterMgr *)device->service;
781 if (devMgr == NULL) {
782 HDF_LOGE("%s: descriptor is NULL", __func__);
783 return;
784 }
785 OsalMemFree(devMgr);
786 }
787
788 struct HdfDriverEntry g_masterDriverEntry = {
789 .moduleVersion = 1,
790 .moduleName = "usbfn_master",
791 .Bind = MasterDriverBind,
792 .Init = MasterDriverInit,
793 .Release = MasterDriverRelease,
794 };
795
796 HDF_INIT(g_masterDriverEntry);
797