• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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