• 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 "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