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 "hdf_base.h"
17 #include "hdf_device_desc.h"
18 #include "hdf_device_object.h"
19 #include "device_resource_if.h"
20 #include "hdf_log.h"
21 #include "osal_mem.h"
22 #include "osal_time.h"
23 #include "securec.h"
24 #include "usbfn_device.h"
25 #include "usbfn_interface.h"
26 #include "usbfn_request.h"
27 #include "default_config.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 = CpuToLe16(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 = CpuToLe32(0),
110 .wMaxSegmentSize = CpuToLe16(0x05ea),
111 .wNumberMCFilters = CpuToLe16(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 = CpuToLe16(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 = CpuToLe16(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 = CpuToLe16(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 = CpuToLe16(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 = CpuToLe16(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 = CpuToLe16(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 = CpuToLe16(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 = CpuToLe16(SS_MAX_PACKET_SIZE),
273 };
274
275 static struct UsbSsEpCompDescriptor g_ssEcmBulkCompDesc = {
276 .bLength = sizeof(g_ssEcmBulkCompDesc),
277 .bDescriptorType = USB_DDK_DT_SS_ENDPOINT_COMP,
278
279 /* the following 2 values can be tweaked if necessary */
280 /* .bMaxBurst = 0, */
281 /* .bmAttributes = 0, */
282 };
283
284 static struct UsbDescriptorHeader *g_ecmSsFunction[] = {
285 /* CDC ECM control descriptors */
286 (struct UsbDescriptorHeader *) &g_ecmIadDescriptor,
287 (struct UsbDescriptorHeader *) &g_ecmControlIntf,
288 (struct UsbDescriptorHeader *) &g_ecmHeaderDesc,
289 (struct UsbDescriptorHeader *) &g_ecmUnionDesc,
290 (struct UsbDescriptorHeader *) &g_ecmDesc,
291
292 /* NOTE: status endpoint might need to be removed */
293 (struct UsbDescriptorHeader *) &g_ssEcmNotifyDesc,
294 (struct UsbDescriptorHeader *) &g_ssEcmIntrCompDesc,
295
296 /* data interface, altsettings 0 and 1 */
297 (struct UsbDescriptorHeader *) &g_ecmDataNopIntf,
298 (struct UsbDescriptorHeader *) &g_ecmDataIntf,
299 (struct UsbDescriptorHeader *) &g_ssEcmInDesc,
300 (struct UsbDescriptorHeader *) &g_ssEcmBulkCompDesc,
301 (struct UsbDescriptorHeader *) &g_ssEcmOutDesc,
302 (struct UsbDescriptorHeader *) &g_ssEcmBulkCompDesc,
303 NULL,
304 };
305
306 /* string descriptors: */
307 static struct UsbString g_ecmStringDefs[] = {
308 [0].s = "CDC Ethernet Control Model (ECM)",
309 [0x01].s = "0ac75ae91c79",
310 [0x02].s = "CDC Ethernet Data",
311 [0x03].s = "CDC ECM",
312 { } /* end of list */
313 };
314
315 static struct UsbFnStrings g_ecmStringTable = {
316 .language = 0x0409, /* en-us */
317 .strings = g_ecmStringDefs,
318 };
319
320 static struct UsbFnStrings *g_ecmStrings[] = {
321 &g_ecmStringTable,
322 NULL,
323 };
324
325 static struct UsbFnFunction g_ecmFunction = {
326 .enable = true,
327 .funcName = "f_generic.e",
328 .strings = g_ecmStrings,
329 .fsDescriptors = g_ecmFsFunction,
330 .hsDescriptors = g_ecmHsFunction,
331 .ssDescriptors = g_ecmSsFunction,
332 .sspDescriptors = NULL,
333 };
334 #endif
335
336 #ifdef CDC_ACM
337 #define ACM_NOTIFY_INTERVAL 32 /* ms */
338 #define ACM_HS_NOTIFY_INTERVAL 9 /* ms */
339 #define ACM_NOTIFY_MAXPACKET 10 /* notification + 2 bytes */
340
341 #define ACM_CTRL_IDX 1
342 #define ACM_DATA_IDX 2
343 #define ACM_IAD_IDX 3
344
345 static struct UsbInterfaceAssocDescriptor g_acmIadDescriptor = {
346 .bLength = sizeof(g_acmIadDescriptor),
347 .bDescriptorType = USB_DDK_DT_INTERFACE_ASSOCIATION,
348 #ifdef CDC_ECM
349 .bFirstInterface = 0x02,
350 #else
351 .bFirstInterface = 0,
352 #endif
353 .bInterfaceCount = INTF_COUNT,
354 .bFunctionClass = USB_DDK_CLASS_COMM,
355 .bFunctionSubClass = USB_DDK_CDC_SUBCLASS_ACM,
356 .bFunctionProtocol = USB_DDK_CDC_ACM_PROTO_AT_V25TER,
357 .iFunction = ACM_IAD_IDX,
358 };
359
360 static struct UsbInterfaceDescriptor g_acmControlInterfaceDesc = {
361 .bLength = USB_DDK_DT_INTERFACE_SIZE,
362 .bDescriptorType = USB_DDK_DT_INTERFACE,
363 #ifdef CDC_ECM
364 .bInterfaceNumber = 0x02,
365 #else
366 .bInterfaceNumber = 0,
367 #endif
368 .bAlternateSetting = 0,
369 .bNumEndpoints = NOTIFY_EP_NUM,
370 .bInterfaceClass = USB_DDK_CLASS_COMM,
371 .bInterfaceSubClass = USB_DDK_CDC_SUBCLASS_ACM,
372 .bInterfaceProtocol = USB_DDK_CDC_ACM_PROTO_AT_V25TER,
373 .iInterface = ACM_CTRL_IDX,
374 };
375
376 static struct UsbInterfaceDescriptor g_acmDataInterfaceDesc = {
377 .bLength = USB_DDK_DT_INTERFACE_SIZE,
378 .bDescriptorType = USB_DDK_DT_INTERFACE,
379 #ifdef CDC_ECM
380 .bInterfaceNumber = 0x03,
381 #else
382 .bInterfaceNumber = 1,
383 #endif
384 .bAlternateSetting = 0,
385 .bNumEndpoints = DATA_EP_NUM,
386 .bInterfaceClass = USB_DDK_CLASS_CDC_DATA,
387 .bInterfaceSubClass = 0,
388 .bInterfaceProtocol = 2,
389 .iInterface = ACM_DATA_IDX,
390 };
391
392 static struct UsbCdcHeaderDesc g_acmHeaderDesc = {
393 .bLength = sizeof(g_acmHeaderDesc),
394 .bDescriptorType = USB_DDK_DT_CS_INTERFACE,
395 .bDescriptorSubType = USB_DDK_CDC_HEADER_TYPE,
396 .bcdCDC = CpuToLe16(0x0110),
397 };
398
399 static struct UsbCdcCallMgmtDescriptor g_acmCallMgmtDescriptor = {
400 .bLength = sizeof(g_acmCallMgmtDescriptor),
401 .bDescriptorType = USB_DDK_DT_CS_INTERFACE,
402 .bDescriptorSubType = USB_DDK_CDC_CALL_MANAGEMENT_TYPE,
403 .bmCapabilities = 0,
404 .bDataInterface = 1,
405 };
406
407 static struct UsbCdcAcmDescriptor g_acmDescriptor = {
408 .bLength = sizeof(g_acmDescriptor),
409 .bDescriptorType = USB_DDK_DT_CS_INTERFACE,
410 .bDescriptorSubType = USB_DDK_CDC_ACM_TYPE,
411 .bmCapabilities = USB_DDK_CDC_CAP_LINE,
412 };
413
414 static struct UsbCdcUnionDesc g_acmUnionDesc = {
415 .bLength = sizeof(g_acmUnionDesc),
416 .bDescriptorType = USB_DDK_DT_CS_INTERFACE,
417 .bDescriptorSubType = USB_DDK_CDC_UNION_TYPE,
418 #ifdef CDC_ECM
419 .bMasterInterface0 = 0x02,
420 .bSlaveInterface0 = 0x03,
421 #else
422 .bMasterInterface0 = 0,
423 .bSlaveInterface0 = 1,
424 #endif
425 };
426
427 static struct UsbEndpointDescriptor g_acmFsNotifyDesc = {
428 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
429 .bDescriptorType = USB_DDK_DT_ENDPOINT,
430 .bEndpointAddress = EP_ADD_NOTIFY | USB_DDK_DIR_IN,
431 .bmAttributes = USB_DDK_ENDPOINT_XFER_INT,
432 .wMaxPacketSize = CpuToLe16(ACM_NOTIFY_MAXPACKET),
433 .bInterval = ACM_NOTIFY_INTERVAL,
434 };
435
436 static struct UsbEndpointDescriptor g_acmFsInDesc = {
437 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
438 .bDescriptorType = USB_DDK_DT_ENDPOINT,
439 .bEndpointAddress = EP_ADD_DATA_IN | USB_DDK_DIR_IN,
440 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
441 };
442
443 static struct UsbEndpointDescriptor g_acmFsOutDesc = {
444 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
445 .bDescriptorType = USB_DDK_DT_ENDPOINT,
446 .bEndpointAddress = EP_ADD_DATA_OUT | USB_DDK_DIR_OUT,
447 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
448 };
449
450 static struct UsbDescriptorHeader *g_acmFsFunction[] = {
451 (struct UsbDescriptorHeader *) &g_acmIadDescriptor,
452 (struct UsbDescriptorHeader *) &g_acmControlInterfaceDesc,
453 (struct UsbDescriptorHeader *) &g_acmHeaderDesc,
454 (struct UsbDescriptorHeader *) &g_acmCallMgmtDescriptor,
455 (struct UsbDescriptorHeader *) &g_acmDescriptor,
456 (struct UsbDescriptorHeader *) &g_acmUnionDesc,
457 (struct UsbDescriptorHeader *) &g_acmFsNotifyDesc,
458 (struct UsbDescriptorHeader *) &g_acmDataInterfaceDesc,
459 (struct UsbDescriptorHeader *) &g_acmFsInDesc,
460 (struct UsbDescriptorHeader *) &g_acmFsOutDesc,
461 NULL,
462 };
463
464 static struct UsbEndpointDescriptor g_acmHsNotifyDesc = {
465 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
466 .bDescriptorType = USB_DDK_DT_ENDPOINT,
467 .bEndpointAddress = EP_ADD_NOTIFY | USB_DDK_DIR_IN,
468 .bmAttributes = USB_DDK_ENDPOINT_XFER_INT,
469 .wMaxPacketSize = CpuToLe16(ACM_NOTIFY_MAXPACKET),
470 .bInterval = ACM_HS_NOTIFY_INTERVAL,
471 };
472
473 static struct UsbEndpointDescriptor g_acmHsInDesc = {
474 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
475 .bDescriptorType = USB_DDK_DT_ENDPOINT,
476 .bEndpointAddress = EP_ADD_DATA_IN | USB_DDK_DIR_IN,
477 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
478 .wMaxPacketSize = CpuToLe16(MAX_PACKET_SIZE),
479 };
480
481 static struct UsbEndpointDescriptor g_acmHsOutDesc = {
482 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
483 .bDescriptorType = USB_DDK_DT_ENDPOINT,
484 .bEndpointAddress = EP_ADD_DATA_OUT | USB_DDK_DIR_OUT,
485 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
486 .wMaxPacketSize = CpuToLe16(MAX_PACKET_SIZE),
487 };
488
489 static struct UsbDescriptorHeader *g_acmHsFunction[] = {
490 (struct UsbDescriptorHeader *) &g_acmIadDescriptor,
491 (struct UsbDescriptorHeader *) &g_acmControlInterfaceDesc,
492 (struct UsbDescriptorHeader *) &g_acmHeaderDesc,
493 (struct UsbDescriptorHeader *) &g_acmCallMgmtDescriptor,
494 (struct UsbDescriptorHeader *) &g_acmDescriptor,
495 (struct UsbDescriptorHeader *) &g_acmUnionDesc,
496 (struct UsbDescriptorHeader *) &g_acmHsNotifyDesc,
497 (struct UsbDescriptorHeader *) &g_acmDataInterfaceDesc,
498 (struct UsbDescriptorHeader *) &g_acmHsInDesc,
499 (struct UsbDescriptorHeader *) &g_acmHsOutDesc,
500 NULL,
501 };
502
503 static struct UsbEndpointDescriptor g_acmSsInDesc = {
504 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
505 .bDescriptorType = USB_DDK_DT_ENDPOINT,
506 .bEndpointAddress = EP_ADD_DATA_IN | USB_DDK_DIR_IN,
507 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
508 .wMaxPacketSize = CpuToLe16(SS_MAX_PACKET_SIZE),
509 };
510
511 static struct UsbEndpointDescriptor g_acmSsOutDesc = {
512 .bLength = USB_DDK_DT_ENDPOINT_SIZE,
513 .bDescriptorType = USB_DDK_DT_ENDPOINT,
514 .bEndpointAddress = EP_ADD_DATA_OUT | USB_DDK_DIR_OUT,
515 .bmAttributes = USB_DDK_ENDPOINT_XFER_BULK,
516 .wMaxPacketSize = CpuToLe16(SS_MAX_PACKET_SIZE),
517 };
518
519 static struct UsbSsEpCompDescriptor g_acmSsBulkCompDesc = {
520 .bLength = sizeof(g_acmSsBulkCompDesc),
521 .bDescriptorType = USB_DDK_DT_SS_ENDPOINT_COMP,
522 };
523
524 static struct UsbDescriptorHeader *g_acmSsFunction[] = {
525 (struct UsbDescriptorHeader *) &g_acmIadDescriptor,
526 (struct UsbDescriptorHeader *) &g_acmControlInterfaceDesc,
527 (struct UsbDescriptorHeader *) &g_acmHeaderDesc,
528 (struct UsbDescriptorHeader *) &g_acmCallMgmtDescriptor,
529 (struct UsbDescriptorHeader *) &g_acmDescriptor,
530 (struct UsbDescriptorHeader *) &g_acmUnionDesc,
531 (struct UsbDescriptorHeader *) &g_acmHsNotifyDesc,
532 (struct UsbDescriptorHeader *) &g_acmSsBulkCompDesc,
533 (struct UsbDescriptorHeader *) &g_acmDataInterfaceDesc,
534 (struct UsbDescriptorHeader *) &g_acmSsInDesc,
535 (struct UsbDescriptorHeader *) &g_acmSsBulkCompDesc,
536 (struct UsbDescriptorHeader *) &g_acmSsOutDesc,
537 (struct UsbDescriptorHeader *) &g_acmSsBulkCompDesc,
538 NULL,
539 };
540
541 static struct UsbString g_acmStringDefs[] = {
542 [0].s = "CDC Abstract Control Model (ACM)",
543 [0x01].s = "CDC ACM Data",
544 [0x02].s = "CDC Serial",
545 { } /* end of list */
546 };
547
548 static struct UsbFnStrings g_acmStringTable = {
549 .language = 0x0409, /* en-us */
550 .strings = g_acmStringDefs,
551 };
552
553 static struct UsbFnStrings *g_acmStrings[] = {
554 &g_acmStringTable,
555 NULL,
556 };
557
558 static struct UsbFnFunction g_acmFunction = {
559 .enable = true,
560 .funcName = "f_generic.a",
561 .strings = g_acmStrings,
562 .fsDescriptors = g_acmFsFunction,
563 .hsDescriptors = g_acmHsFunction,
564 .ssDescriptors = g_acmSsFunction,
565 .sspDescriptors = NULL,
566 };
567 #endif
568 /** device **/
569 #define BCD_USB 0x0200
570 #define DEVICE_VENDOR_ID 0x12D1
571 #define DEVICE_PRODUCT_ID 0x5000
572 #define DEVICE_VERSION 0x0223
573
574 #define USB_MAX_PACKET_SIZE 0x40
575 #define POWER 500
576
577 #define USB_FUNC_CONFIG_IDX USB_FUNC_FIRST_AVAIL_IDX
578 #define DRIVER_DESC "HDC Device"
579 #define CONFIG_DESC "hdc"
580
581 static struct UsbDeviceDescriptor g_cdcMasterDeviceDesc = {
582 .bLength = sizeof(g_cdcMasterDeviceDesc),
583 .bDescriptorType = USB_DDK_DT_DEVICE,
584 .bcdUSB = CpuToLe16(BCD_USB),
585 .bDeviceClass = 0,
586 .bDeviceSubClass = 0,
587 .bDeviceProtocol = 0,
588 .bMaxPacketSize0 = USB_MAX_PACKET_SIZE,
589 .idVendor = CpuToLe16(DEVICE_VENDOR_ID),
590 .idProduct = CpuToLe16(DEVICE_PRODUCT_ID),
591 .bcdDevice = CpuToLe16(DEVICE_VERSION),
592 .iManufacturer = USB_FUNC_MANUFACTURER_IDX,
593 .iProduct = USB_FUNC_PRODUCT_IDX,
594 .iSerialNumber = USB_FUNC_SERIAL_IDX,
595 .bNumConfigurations = 1,
596 };
597
598 static struct UsbString g_stringsDev[] = {
599 {USB_FUNC_MANUFACTURER_IDX, "HISILICON"},
600 {USB_FUNC_PRODUCT_IDX, DRIVER_DESC},
601 {USB_FUNC_SERIAL_IDX, "0123456789POPLAR"},
602 {USB_FUNC_CONFIG_IDX, CONFIG_DESC},
603 { } /* end of list */
604 };
605
606 static struct UsbFnStrings g_stringTabDev = {
607 .language = 0x0409, /* en-us */
608 .strings = g_stringsDev,
609 };
610
611 static struct UsbFnStrings *g_devStrings[] = {
612 &g_stringTabDev,
613 NULL,
614 };
615
616 struct UsbFnFunction *g_functions[] = {
617 #ifdef CDC_ECM
618 &g_ecmFunction,
619 #endif
620 #ifdef CDC_ACM
621 &g_acmFunction,
622 #endif
623 NULL
624 };
625
626 static struct UsbFnConfiguration g_masterConfig = {
627 .configurationValue = 1,
628 .iConfiguration = USB_FUNC_CONFIG_IDX,
629 .attributes = USB_CFG_BUS_POWERED,
630 .maxPower = POWER,
631 .functions = g_functions,
632 };
633
634 static struct UsbFnConfiguration *g_configs[] = {
635 &g_masterConfig,
636 NULL,
637 };
638
639 static struct UsbFnDeviceDesc g_masterFuncDevice = {
640 .deviceDesc = &g_cdcMasterDeviceDesc,
641 .deviceStrings = g_devStrings,
642 .configs = g_configs,
643 };
644
645 struct UsbFnDevice *g_fnDev = NULL;
MasterReleaseFuncDevice()646 static int32_t MasterReleaseFuncDevice()
647 {
648 int32_t ret;
649 if (g_fnDev == NULL) {
650 HDF_LOGE("%s: fnDev is null", __func__);
651 return HDF_FAILURE;
652 }
653 ret = UsbFnRemoveDevice(g_fnDev);
654 if (ret == HDF_SUCCESS) {
655 g_fnDev = NULL;
656 } else {
657 HDF_LOGE("%{public}s: remove usb function device failed", __func__);
658 }
659
660 return ret;
661 }
662
UsbFnRegistUsbfnDevice(struct HdfDeviceIoClient * client,struct HdfSBuf * data,struct HdfSBuf * reply)663 static int32_t UsbFnRegistUsbfnDevice(struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply)
664 {
665 struct HdfDeviceObject *device = client->device;
666 struct DevMasterMgr *devMgr = NULL;
667 struct UsbFnDevice *fnDev = NULL;
668 uint8_t value;
669 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
670
671 if (iface == NULL || iface->GetUint32 == NULL || device == NULL) {
672 HDF_LOGE("%s: face is invalid", __func__);
673 return HDF_FAILURE;
674 }
675 devMgr = (struct DevMasterMgr *)device->service;
676 if (HdfSbufReadUint8(data, &value) != true) {
677 HDF_LOGE("%s: read sbuf failed", __func__);
678 return HDF_FAILURE;
679 }
680 devMgr->descData.functionMask = value;
681 fnDev = (struct UsbFnDevice *)UsbFnCreateDevice(devMgr->udcName, &devMgr->descData);
682 if (fnDev == NULL) {
683 HDF_LOGE("%s: create usb function device failed", __func__);
684 if (!HdfSbufWriteInt8(reply, 0)) {
685 HDF_LOGE("UsbEcmRead HdfSbufWriteInt8 error");
686 }
687 return HDF_FAILURE;
688 }
689 g_fnDev = fnDev;
690 if (!HdfSbufWriteInt8(reply, value)) {
691 HDF_LOGE("UsbEcmRead HdfSbufWriteInt8 error");
692 return HDF_FAILURE;
693 }
694 return 0;
695 }
696
MasterDispatch(struct HdfDeviceIoClient * client,int32_t cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)697 int32_t MasterDispatch(struct HdfDeviceIoClient *client, int32_t cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
698 {
699 int32_t ret;
700 if (client == NULL) {
701 HDF_LOGE("%s: client is NULL", __func__);
702 return HDF_FAILURE;
703 }
704
705 if (HdfDeviceObjectCheckInterfaceDesc(client->device, data) == false) {
706 HDF_LOGE("%{public}s:%{public}d check interface desc fail", __func__, __LINE__);
707 return HDF_ERR_INVALID_PARAM;
708 }
709
710 switch (cmdId) {
711 case DEV_MASTER_INIT:
712 ret = UsbFnRegistUsbfnDevice(client, data, reply);
713 if (ret != HDF_SUCCESS) {
714 HDF_LOGE("%s: create usbfn device failed", __func__);
715 }
716 break;
717 case DEV_MASTER_RELEASE:
718 ret = MasterReleaseFuncDevice();
719 break;
720 default:
721 ret = HDF_ERR_INVALID_OBJECT;
722 HDF_LOGE("%s: unknown cmd id %d", __func__, cmdId);
723 break;
724 }
725 return ret;
726 }
727
728 /* HdfDriverEntry implementations */
MasterDriverBind(struct HdfDeviceObject * device)729 static int32_t MasterDriverBind(struct HdfDeviceObject *device)
730 {
731 struct DevMasterMgr *devMgr = NULL;
732 if (device == NULL) {
733 HDF_LOGE("%s:%d device is null\n", __func__, __LINE__);
734 return HDF_FAILURE;
735 }
736 devMgr = (struct DevMasterMgr *)OsalMemCalloc(sizeof(*devMgr));
737 if (devMgr == NULL) {
738 HDF_LOGE("%s: usbfn Alloc usb devMgr failed", __func__);
739 return HDF_FAILURE;
740 }
741
742 if (HdfDeviceObjectSetInterfaceDesc(device, "hdf.usb.usbfn") != HDF_SUCCESS) {
743 HDF_LOGE(" Set Desc fail!");
744 OsalMemFree(devMgr);
745 return HDF_FAILURE;
746 }
747
748 devMgr->device = device;
749 device->service = &(devMgr->service);
750 devMgr->device->service->Dispatch = MasterDispatch;
751 return HDF_SUCCESS;
752 }
753
MasterDriverInit(struct HdfDeviceObject * device)754 static int32_t MasterDriverInit(struct HdfDeviceObject *device)
755 {
756 struct DevMasterMgr *devMgr = NULL;
757 uint8_t useHcs;
758
759 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
760 if (iface == NULL || iface->GetUint32 == NULL || device == NULL) {
761 HDF_LOGE("%s: face is invalid", __func__);
762 return HDF_FAILURE;
763 }
764 devMgr = (struct DevMasterMgr *)device->service;
765 if (iface->GetString(device->property, "udc_name",
766 &devMgr->udcName, UDC_NAME) != HDF_SUCCESS) {
767 HDF_LOGE("%s: read udc_name failed, use default", __func__);
768 }
769 if (iface->GetUint8(device->property, "use_hcs", &useHcs, 0) != HDF_SUCCESS) {
770 HDF_LOGE("%s: read use_hcs fail, use default", __func__);
771 }
772 if (useHcs == 0) {
773 devMgr->descData.type = USBFN_DESC_DATA_TYPE_DESC;
774 devMgr->descData.descriptor = &g_masterFuncDevice;
775 } else {
776 devMgr->descData.type = USBFN_DESC_DATA_TYPE_PROP;
777 devMgr->descData.property = device->property;
778 }
779 return HDF_SUCCESS;
780 }
781
MasterDriverRelease(struct HdfDeviceObject * device)782 static void MasterDriverRelease(struct HdfDeviceObject *device)
783 {
784 struct DevMasterMgr *devMgr = NULL;
785 devMgr = (struct DevMasterMgr *)device->service;
786 if (devMgr == NULL) {
787 HDF_LOGE("%s: descriptor is NULL", __func__);
788 return;
789 }
790 OsalMemFree(devMgr);
791 }
792
793 struct HdfDriverEntry g_masterDriverEntry = {
794 .moduleVersion = 1,
795 .moduleName = "usbfn_master",
796 .Bind = MasterDriverBind,
797 .Init = MasterDriverInit,
798 .Release = MasterDriverRelease,
799 };
800
801 HDF_INIT(g_masterDriverEntry);
802