1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "usb_ddk_pnp_loader.h"
10 #include "devhost_service_clnt.h"
11 #include "device_resource_if.h"
12 #include "hcs_tree_if.h"
13 #include "hdf_attribute_manager.h"
14 #include "hdf_base.h"
15 #include "hdf_log.h"
16 #include "hdf_sbuf.h"
17 #include "osal_mem.h"
18 #include "osal_time.h"
19 #include "securec.h"
20 #include "usb_pnp_manager.h"
21
22 #define HDF_LOG_TAG USB_DDK_PNP_LOADER
23
24 #define USB_DDK_PNP_CLASS_VENDOR_SPEC 0xFF
25
26 static struct DListHead g_usbPnpDeviceTableListHead;
27 static struct UsbPnpMatchIdTable **g_usbPnpMatchIdTable = NULL;
28
UsbDdkPnpLoaderBufCreate(const char * moduleName,const char * serviceName,const char * deviceMatchAttr,struct UsbPnpNotifyServiceInfo serviceInfo)29 static struct HdfSBuf *UsbDdkPnpLoaderBufCreate(const char *moduleName,
30 const char *serviceName, const char *deviceMatchAttr, struct UsbPnpNotifyServiceInfo serviceInfo)
31 {
32 struct HdfSBuf *pnpData = NULL;
33
34 pnpData = HdfSBufObtainDefaultSize();
35 if (pnpData == NULL) {
36 HDF_LOGE("%s: HdfSBufTypedObtain pnpData fail", __func__);
37 return NULL;
38 }
39
40 if (!UsbPnpManagerWriteModuleName(pnpData, moduleName)) {
41 HDF_LOGE("%s: write moduleName failed!", __func__);
42 goto out;
43 }
44
45 if (!HdfSbufWriteString(pnpData, serviceName)) {
46 HDF_LOGE("%s: write service name failed!", __func__);
47 goto out;
48 }
49
50 if (!HdfSbufWriteString(pnpData, deviceMatchAttr)) {
51 HDF_LOGE("%s: write deviceMatchAttr failed!", __func__);
52 goto out;
53 }
54
55 if (!HdfSbufWriteBuffer(pnpData, (const void *)(&serviceInfo), serviceInfo.length)) {
56 HDF_LOGE("%s: write privateData failed!", __func__);
57 goto out;
58 }
59
60 return pnpData;
61
62 out:
63 HdfSBufRecycle(pnpData);
64
65 return NULL;
66 }
67
UsbDdkPnpLoaderMatchDevice(const struct UsbPnpNotifyMatchInfoTable * dev,const struct UsbPnpMatchIdTable * id)68 static bool UsbDdkPnpLoaderMatchDevice(const struct UsbPnpNotifyMatchInfoTable *dev,
69 const struct UsbPnpMatchIdTable *id)
70 {
71 if ((id->matchFlag & USB_PNP_NOTIFY_MATCH_VENDOR) &&
72 (id->vendorId != dev->deviceInfo.vendorId)) {
73 return false;
74 }
75
76 if ((id->matchFlag & USB_PNP_NOTIFY_MATCH_PRODUCT) &&
77 (id->productId != dev->deviceInfo.productId)) {
78 return false;
79 }
80
81 if ((id->matchFlag & USB_PNP_NOTIFY_MATCH_DEV_LOW) &&
82 (id->bcdDeviceLow > dev->deviceInfo.bcdDeviceLow)) {
83 return false;
84 }
85
86 if ((id->matchFlag & USB_PNP_NOTIFY_MATCH_DEV_HIGH) &&
87 (id->bcdDeviceHigh < dev->deviceInfo.bcdDeviceHigh)) {
88 return false;
89 }
90
91 if ((id->matchFlag & USB_PNP_NOTIFY_MATCH_DEV_CLASS) &&
92 (id->deviceClass != dev->deviceInfo.deviceClass)) {
93 return false;
94 }
95
96 if ((id->matchFlag & USB_PNP_NOTIFY_MATCH_DEV_SUBCLASS) &&
97 (id->deviceSubClass != dev->deviceInfo.deviceSubClass)) {
98 return false;
99 }
100
101 if ((id->matchFlag & USB_PNP_NOTIFY_MATCH_DEV_PROTOCOL) &&
102 (id->deviceProtocol != dev->deviceInfo.deviceProtocol)) {
103 return false;
104 }
105
106 return true;
107 }
108
UsbDdkPnpLoaderMatchHandle(const struct UsbPnpNotifyMatchInfoTable * dev,int8_t index,struct UsbPnpMatchIdTable * id,bool flag)109 static void UsbDdkPnpLoaderMatchHandle(const struct UsbPnpNotifyMatchInfoTable *dev,
110 int8_t index, struct UsbPnpMatchIdTable *id, bool flag)
111 {
112 if ((id->pnpMatchFlag == false) && (flag == true)) {
113 if (!(id->matchFlag & USB_PNP_NOTIFY_MATCH_INT_CLASS)) {
114 id->interfaceClass[id->interfaceClassLength++] = dev->interfaceInfo[index].interfaceClass;
115 }
116 if (!(id->matchFlag & USB_PNP_NOTIFY_MATCH_INT_SUBCLASS)) {
117 id->interfaceSubClass[id->interfaceSubClassLength++] = dev->interfaceInfo[index].interfaceSubClass;
118 }
119 if (!(id->matchFlag & USB_PNP_NOTIFY_MATCH_INT_PROTOCOL)) {
120 id->interfaceProtocol[id->interfaceProtocolLength++] = dev->interfaceInfo[index].interfaceProtocol;
121 }
122 if (!(id->matchFlag & USB_PNP_NOTIFY_MATCH_INT_NUMBER)) {
123 id->interfaceNumber[id->interfaceLength++] = dev->interfaceInfo[index].interfaceNumber;
124 }
125 }
126 }
127
UsbDdkPnpLoaderMatchFlag(const struct UsbPnpNotifyMatchInfoTable * dev,int8_t index,struct UsbPnpMatchIdTable * id,bool flag)128 static bool UsbDdkPnpLoaderMatchFlag(const struct UsbPnpNotifyMatchInfoTable *dev,
129 int8_t index, struct UsbPnpMatchIdTable *id, bool flag)
130 {
131 int32_t i;
132 bool ret = true;
133
134 if (id->matchFlag & USB_PNP_NOTIFY_MATCH_INT_CLASS) {
135 for (i = 0; i < id->interfaceClassLength; i++) {
136 if (!((id->interfaceClassMask >> i) & 0x01)) {
137 break;
138 }
139 }
140 if (i < id->interfaceClassLength) {
141 ret = false;
142 goto out;
143 }
144 }
145
146 if (id->matchFlag & USB_PNP_NOTIFY_MATCH_INT_SUBCLASS) {
147 for (i = 0; i < id->interfaceSubClassLength; i++) {
148 if (!((id->interfaceSubClassMask >> i) & 0x01)) {
149 break;
150 }
151 }
152 if (i < id->interfaceSubClassLength) {
153 ret = false;
154 goto out;
155 }
156 }
157
158 if (id->matchFlag & USB_PNP_NOTIFY_MATCH_INT_PROTOCOL) {
159 for (i = 0; i < id->interfaceProtocolLength; i++) {
160 if (!((id->interfaceProtocolMask >> i) & 0x01)) {
161 break;
162 }
163 }
164 if (i < id->interfaceProtocolLength) {
165 ret = false;
166 goto out;
167 }
168 }
169
170 if (id->matchFlag & USB_PNP_NOTIFY_MATCH_INT_NUMBER) {
171 for (i = 0; i < id->interfaceLength; i++) {
172 if (!((id->interfaceMask >> i) & 0x01)) {
173 break;
174 }
175 }
176 if (i < id->interfaceLength) {
177 ret = false;
178 goto out;
179 }
180 }
181
182 ret = true;
183
184 out:
185 UsbDdkPnpLoaderMatchHandle(dev, index, id, flag);
186
187 return ret;
188 }
189
UsbDdkPnpLoaderMatchInterface(const struct UsbPnpNotifyMatchInfoTable * dev,int8_t index,struct UsbPnpMatchIdTable * id)190 static bool UsbDdkPnpLoaderMatchInterface(const struct UsbPnpNotifyMatchInfoTable *dev,
191 int8_t index, struct UsbPnpMatchIdTable *id)
192 {
193 uint32_t i;
194 bool maskFlag = true;
195
196 if (id->matchFlag & USB_PNP_NOTIFY_MATCH_INT_CLASS) {
197 for (i = 0; i < id->interfaceClassLength; i++) {
198 if (id->interfaceClass[i] == dev->interfaceInfo[index].interfaceClass) {
199 id->interfaceClassMask |= (1 << i);
200 break;
201 }
202 }
203
204 if (i >= id->interfaceClassLength) {
205 maskFlag = false;
206 }
207 }
208
209 if (id->matchFlag & USB_PNP_NOTIFY_MATCH_INT_SUBCLASS) {
210 for (i = 0; i < id->interfaceSubClassLength; i++) {
211 if (id->interfaceSubClass[i] == dev->interfaceInfo[index].interfaceSubClass) {
212 id->interfaceSubClassMask |= (1 << i);
213 break;
214 }
215 }
216
217 if (i >= id->interfaceSubClassLength) {
218 maskFlag = false;
219 }
220 }
221
222 if (id->matchFlag & USB_PNP_NOTIFY_MATCH_INT_PROTOCOL) {
223 for (i = 0; i < id->interfaceProtocolLength; i++) {
224 if (id->interfaceProtocol[i] == dev->interfaceInfo[index].interfaceProtocol) {
225 id->interfaceProtocolMask |= (1 << i);
226 break;
227 }
228 }
229
230 if (i >= id->interfaceProtocolLength) {
231 maskFlag = false;
232 }
233 }
234
235 if (id->matchFlag & USB_PNP_NOTIFY_MATCH_INT_NUMBER) {
236 for (i = 0; i < id->interfaceLength; i++) {
237 if (id->interfaceNumber[i] == dev->interfaceInfo[index].interfaceNumber) {
238 id->interfaceMask |= (1 << i);
239 break;
240 }
241 }
242
243 if (i >= id->interfaceLength) {
244 maskFlag = false;
245 }
246 }
247
248 return maskFlag;
249 }
250
UsbDdkPnpLoaderMatchOneIdIntf(const struct UsbPnpNotifyMatchInfoTable * dev,int8_t index,struct UsbPnpMatchIdTable * id)251 static bool UsbDdkPnpLoaderMatchOneIdIntf(const struct UsbPnpNotifyMatchInfoTable *dev,
252 int8_t index, struct UsbPnpMatchIdTable *id)
253 {
254 bool maskFlag = true;
255
256 if (dev->deviceInfo.deviceClass == USB_DDK_PNP_CLASS_VENDOR_SPEC &&
257 !(id->matchFlag & USB_PNP_NOTIFY_MATCH_VENDOR) &&
258 (id->matchFlag & (USB_PNP_NOTIFY_MATCH_INT_CLASS | USB_PNP_NOTIFY_MATCH_INT_SUBCLASS |
259 USB_PNP_NOTIFY_MATCH_INT_PROTOCOL | USB_PNP_NOTIFY_MATCH_INT_NUMBER))) {
260 return false;
261 }
262
263 maskFlag = UsbDdkPnpLoaderMatchInterface(dev, index, id);
264 if (UsbDdkPnpLoaderMatchFlag(dev, index, id, maskFlag) != true) {
265 return false;
266 }
267
268 if (id->pnpMatchFlag == false) {
269 id->pnpMatchFlag = true;
270 } else {
271 return false;
272 }
273
274 return true;
275 }
276
UsbDdkPnpLoaderParseIdInfClass(const struct DeviceResourceNode * node,const struct DeviceResourceIface * devResIface,struct UsbPnpMatchIdTable * table)277 static int32_t UsbDdkPnpLoaderParseIdInfClass(const struct DeviceResourceNode *node,
278 const struct DeviceResourceIface *devResIface, struct UsbPnpMatchIdTable *table)
279 {
280 table->interfaceClassMask = 0;
281 table->interfaceClassLength = devResIface->GetElemNum(node, "interfaceClass");
282 if (table->interfaceClassLength <= 0) {
283 HDF_LOGE("%s: read interfaceClass length=%d fail!", __func__, table->interfaceClassLength);
284 return HDF_FAILURE;
285 }
286 if (devResIface->GetUint8Array(node, "interfaceClass", table->interfaceClass, \
287 table->interfaceClassLength, 0) != HDF_SUCCESS) {
288 HDF_LOGE("%s: read interfaceClass fail!", __func__);
289 return HDF_FAILURE;
290 }
291 if (!(table->matchFlag & USB_PNP_NOTIFY_MATCH_INT_CLASS)) {
292 table->interfaceClassLength = 0;
293 }
294
295 table->interfaceSubClassMask = 0;
296 table->interfaceSubClassLength = devResIface->GetElemNum(node, "interfaceSubClass");
297 if (table->interfaceSubClassLength <= 0) {
298 HDF_LOGE("%s: read interfaceSubClass length=%d fail!",
299 __func__, table->interfaceSubClassLength);
300 return HDF_FAILURE;
301 }
302 if (devResIface->GetUint8Array(node, "interfaceSubClass", table->interfaceSubClass, \
303 table->interfaceSubClassLength, 0) != HDF_SUCCESS) {
304 HDF_LOGE("%s: read interfaceSubClass fail!", __func__);
305 return HDF_FAILURE;
306 }
307 if (!(table->matchFlag & USB_PNP_NOTIFY_MATCH_INT_SUBCLASS)) {
308 table->interfaceSubClassLength = 0;
309 }
310
311 return HDF_SUCCESS;
312 }
313
314
UsbDdkPnpLoaderParseIdInferface(const struct DeviceResourceNode * node,const struct DeviceResourceIface * devResIface,struct UsbPnpMatchIdTable * table)315 static int32_t UsbDdkPnpLoaderParseIdInferface(const struct DeviceResourceNode *node,
316 const struct DeviceResourceIface *devResIface, struct UsbPnpMatchIdTable *table)
317 {
318 if (UsbDdkPnpLoaderParseIdInfClass(node, devResIface, table) != HDF_SUCCESS) {
319 return HDF_FAILURE;
320 }
321
322 table->interfaceProtocolMask = 0;
323 table->interfaceProtocolLength = devResIface->GetElemNum(node, "interfaceProtocol");
324 if (table->interfaceProtocolLength <= 0) {
325 HDF_LOGE("%s: read interfaceProtocol length=%d fail!",
326 __func__, table->interfaceProtocolLength);
327 return HDF_FAILURE;
328 }
329 if (devResIface->GetUint8Array(node, "interfaceProtocol", table->interfaceProtocol, \
330 table->interfaceProtocolLength, 0) != HDF_SUCCESS) {
331 HDF_LOGE("%s: read interfaceProtocol fail!", __func__);
332 return HDF_FAILURE;
333 }
334 if (!(table->matchFlag & USB_PNP_NOTIFY_MATCH_INT_PROTOCOL)) {
335 table->interfaceProtocolLength = 0;
336 }
337
338 table->interfaceMask = 0;
339 table->interfaceLength = devResIface->GetElemNum(node, "interfaceNumber");
340 if (table->interfaceLength <= 0) {
341 HDF_LOGE("%s: read interfaceNumber length=%d fail!", __func__, table->interfaceLength);
342 return HDF_FAILURE;
343 }
344 if (devResIface->GetUint8Array(node, "interfaceNumber", table->interfaceNumber, \
345 table->interfaceLength, 0) != HDF_SUCCESS) {
346 HDF_LOGE("%s: read interfaceNumber fail!", __func__);
347 return HDF_FAILURE;
348 }
349 if (!(table->matchFlag & USB_PNP_NOTIFY_MATCH_INT_NUMBER)) {
350 table->interfaceLength = 0;
351 }
352
353 return HDF_SUCCESS;
354 }
355
UsbDdkPnpLoaderParseIdDevice(const struct DeviceResourceNode * node,const struct DeviceResourceIface * devResIface,struct UsbPnpMatchIdTable * table)356 static int32_t UsbDdkPnpLoaderParseIdDevice(const struct DeviceResourceNode *node,
357 const struct DeviceResourceIface *devResIface, struct UsbPnpMatchIdTable *table)
358 {
359 if (devResIface->GetUint16(node, "vendorId", &table->vendorId, 0) != HDF_SUCCESS) {
360 HDF_LOGE("%s: read vendorId fail!", __func__);
361 return HDF_FAILURE;
362 }
363
364 if (devResIface->GetUint16(node, "productId", &table->productId, 0) != HDF_SUCCESS) {
365 HDF_LOGE("%s: read productId fail!", __func__);
366 return HDF_FAILURE;
367 }
368
369 if (devResIface->GetUint16(node, "bcdDeviceLow", &table->bcdDeviceLow, 0) != HDF_SUCCESS) {
370 HDF_LOGE("%s: read bcdDeviceLow fail!", __func__);
371 return HDF_FAILURE;
372 }
373
374 if (devResIface->GetUint16(node, "bcdDeviceHigh", &table->bcdDeviceHigh, 0) != HDF_SUCCESS) {
375 HDF_LOGE("%s: read bcdDeviceHigh fail!", __func__);
376 return HDF_FAILURE;
377 }
378
379 if (devResIface->GetUint8(node, "deviceClass", &table->deviceClass, 0) != HDF_SUCCESS) {
380 HDF_LOGE("%s: read deviceClass fail!", __func__);
381 return HDF_FAILURE;
382 }
383
384 if (devResIface->GetUint8(node, "deviceSubClass", &table->deviceSubClass, 0) != HDF_SUCCESS) {
385 HDF_LOGE("%s: read deviceSubClass fail!", __func__);
386 return HDF_FAILURE;
387 }
388
389 if (devResIface->GetUint8(node, "deviceProtocol", &table->deviceProtocol, 0) != HDF_SUCCESS) {
390 HDF_LOGE("%s: read deviceProtocol fail!", __func__);
391 return HDF_FAILURE;
392 }
393
394 return HDF_SUCCESS;
395 }
396
UsbDdkPnpLoaderParseIdTable(const struct DeviceResourceNode * node,const struct DeviceResourceIface * devResIface,struct UsbPnpMatchIdTable * table)397 static int32_t UsbDdkPnpLoaderParseIdTable(const struct DeviceResourceNode *node,
398 const struct DeviceResourceIface *devResIface, struct UsbPnpMatchIdTable *table)
399 {
400 if (node == NULL || table == NULL || devResIface == NULL) {
401 HDF_LOGE("%s: node or table or devResIface is NULL!", __func__);
402 return HDF_FAILURE;
403 }
404
405 if (devResIface->GetString(node, "moduleName", &table->moduleName, "") != HDF_SUCCESS) {
406 HDF_LOGE("%s: read moduleName fail!", __func__);
407 return HDF_FAILURE;
408 }
409
410 if (devResIface->GetString(node, "serviceName", &table->serviceName, "") != HDF_SUCCESS) {
411 HDF_LOGE("%s: read serviceName fail!", __func__);
412 return HDF_FAILURE;
413 }
414
415 if (devResIface->GetString(node, "deviceMatchAttr", &table->deviceMatchAttr, "") != HDF_SUCCESS) {
416 HDF_LOGE("%s: read deviceMatchAttr fail!", __func__);
417 return HDF_FAILURE;
418 }
419
420 if (devResIface->GetUint8(node, "length", &table->length, 0) != HDF_SUCCESS) {
421 HDF_LOGE("%s: read length fail!", __func__);
422 return HDF_FAILURE;
423 }
424
425 if (devResIface->GetUint16(node, "matchFlag", &table->matchFlag, 0) != HDF_SUCCESS) {
426 HDF_LOGE("%s: read matchFlag fail!", __func__);
427 return HDF_FAILURE;
428 }
429
430 if (UsbDdkPnpLoaderParseIdDevice(node, devResIface, table) != HDF_SUCCESS) {
431 return HDF_FAILURE;
432 }
433
434 return UsbDdkPnpLoaderParseIdInferface(node, devResIface, table);
435 }
436
UsbDdkPnpLoaderParseTableList(const struct DeviceResourceNode * node,int32_t idTabCount,const struct DeviceResourceIface * devResIface)437 static struct UsbPnpMatchIdTable **UsbDdkPnpLoaderParseTableList(
438 const struct DeviceResourceNode *node, int32_t idTabCount, const struct DeviceResourceIface *devResIface)
439 {
440 int32_t ret;
441 int32_t count;
442 const char *idTableName = NULL;
443 struct UsbPnpMatchIdTable **idTable = NULL;
444 const struct DeviceResourceNode *tableNode = NULL;
445
446 idTable = (struct UsbPnpMatchIdTable **)OsalMemCalloc((idTabCount + 1) * sizeof(struct UsbPnpMatchIdTable *));
447 if (idTable == NULL) {
448 HDF_LOGE("%s: OsalMemCalloc failure!", __func__);
449 return NULL;
450 }
451 idTable[idTabCount] = NULL;
452 for (count = 0; count < idTabCount; count++) {
453 idTable[count] = (struct UsbPnpMatchIdTable *)OsalMemCalloc(sizeof(struct UsbPnpMatchIdTable));
454 if (idTable[count] == NULL) {
455 HDF_LOGE("%s: OsalMemCalloc failure!", __func__);
456 goto out;
457 }
458 ret = devResIface->GetStringArrayElem(node, "idTableList", count, &idTableName, NULL);
459 if (ret != HDF_SUCCESS) {
460 goto out;
461 }
462 tableNode = devResIface->GetChildNode(node, idTableName);
463 if (tableNode == NULL) {
464 HDF_LOGE("%s: tableNode is NULL!", __func__);
465 goto out;
466 }
467 if (UsbDdkPnpLoaderParseIdTable(tableNode, devResIface, idTable[count]) != HDF_SUCCESS) {
468 HDF_LOGE("%s: UsbDdkPnpLoaderParseIdTable failure!", __func__);
469 goto out;
470 }
471 }
472
473 return idTable;
474
475 out:
476 while ((--count) >= 0) {
477 OsalMemFree(idTable[count]);
478 }
479 OsalMemFree(idTable);
480
481 return NULL;
482 }
483
UsbDdkPnpLoaderParseTable(const struct DeviceResourceNode * node)484 static struct UsbPnpMatchIdTable **UsbDdkPnpLoaderParseTable(const struct DeviceResourceNode *node)
485 {
486 struct DeviceResourceIface *devResIface = NULL;
487 int32_t idTabCount;
488
489 if (node == NULL) {
490 HDF_LOGE("%s: node is NULL!", __func__);
491 return NULL;
492 }
493
494 devResIface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
495 if (devResIface == NULL) {
496 HDF_LOGE("%s: devResIface is NULL!", __func__);
497 return NULL;
498 }
499 idTabCount = devResIface->GetElemNum(node, "idTableList");
500 if (idTabCount <= 0) {
501 HDF_LOGE("%s: idTableList not found!", __func__);
502 return NULL;
503 }
504
505 return UsbDdkPnpLoaderParseTableList(node, idTabCount, devResIface);
506 }
507
UsbDdkPnpLoaderParseDeviceId(const struct DeviceResourceNode * node)508 static struct UsbPnpMatchIdTable **UsbDdkPnpLoaderParseDeviceId(const struct DeviceResourceNode *node)
509 {
510 const char *deviceIdName = NULL;
511 struct DeviceResourceIface *devResIface = NULL;
512 const struct DeviceResourceNode *deviceIdNode = NULL;
513
514 if (node == NULL) {
515 HDF_LOGE("%s: node is NULL!", __func__);
516 return NULL;
517 }
518
519 devResIface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
520 if (devResIface == NULL) {
521 HDF_LOGE("%s: devResIface is NULL!", __func__);
522 return NULL;
523 }
524
525 if (devResIface->GetString(node, "usb_pnp_device_id", &deviceIdName, NULL) != HDF_SUCCESS) {
526 HDF_LOGE("%s: get usb_pnp_device_id name failure!", __func__);
527 return NULL;
528 }
529
530 deviceIdNode = devResIface->GetChildNode(node, deviceIdName);
531 if (deviceIdNode == NULL) {
532 HDF_LOGE("%s: deviceIdNode is NULL!", __func__);
533 return NULL;
534 }
535
536 return UsbDdkPnpLoaderParseTable(deviceIdNode);
537 }
538
UsbDdkPnpLoaderPnpMatch(void)539 static struct UsbPnpMatchIdTable **UsbDdkPnpLoaderPnpMatch(void)
540 {
541 struct DeviceResourceIface *devResInstance = NULL;
542 const struct DeviceResourceNode *rootNode = NULL;
543 const struct DeviceResourceNode *usbPnpNode = NULL;
544
545 devResInstance = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
546 if (devResInstance == NULL) {
547 HDF_LOGE("%s: devResInstance is NULL!", __func__);
548 return NULL;
549 }
550
551 rootNode = devResInstance->GetRootNode();
552 if (rootNode == NULL) {
553 HDF_LOGE("%s: devResNode is NULL!", __func__);
554 return NULL;
555 }
556
557 usbPnpNode = devResInstance->GetNodeByMatchAttr(rootNode, "usb_pnp_match");
558 if (usbPnpNode == NULL) {
559 HDF_LOGE("%s: usbPnpNode is NULL!", __func__);
560 return NULL;
561 }
562
563 return UsbDdkPnpLoaderParseDeviceId(usbPnpNode);
564 }
565
UsbDdkPnpLoaderDispatchPnpDevice(const struct IDevmgrService * devmgrSvc,struct HdfSBuf * data,bool isReg)566 static int32_t UsbDdkPnpLoaderDispatchPnpDevice(
567 const struct IDevmgrService *devmgrSvc, struct HdfSBuf *data, bool isReg)
568 {
569 uint32_t infoSize = 0;
570 struct UsbPnpNotifyServiceInfo *privateData = NULL;
571 struct UsbPnpManagerDeviceInfo managerInfo;
572
573 const char *moduleName = HdfSbufReadString(data);
574 if (moduleName == NULL) {
575 return HDF_ERR_INVALID_PARAM;
576 }
577 const char *serviceName = HdfSbufReadString(data);
578 if (serviceName == NULL) {
579 return HDF_ERR_INVALID_PARAM;
580 }
581
582 const char *deviceMatchAttr = HdfSbufReadString(data);
583 if (deviceMatchAttr == NULL) {
584 return HDF_ERR_INVALID_PARAM;
585 }
586
587 if (!HdfSbufReadBuffer(data, (const void **)(&privateData), &infoSize)) {
588 HDF_LOGW("%s: HdfSbufReadBuffer privateData error!", __func__);
589 privateData = NULL;
590 }
591
592 managerInfo.devmgrSvc = (struct IDevmgrService *)devmgrSvc;
593 managerInfo.moduleName = moduleName;
594 managerInfo.serviceName = serviceName;
595 managerInfo.deviceMatchAttr = deviceMatchAttr;
596 managerInfo.privateData = privateData;
597 managerInfo.isReg = isReg;
598
599 return UsbPnpManagerRegisterOrUnregisterDevice(managerInfo);
600 }
601
UsbDdkPnpLoaderDeviceListAdd(const struct UsbPnpNotifyMatchInfoTable * info,const struct UsbPnpMatchIdTable * idTable)602 static int UsbDdkPnpLoaderDeviceListAdd(const struct UsbPnpNotifyMatchInfoTable *info,
603 const struct UsbPnpMatchIdTable *idTable)
604 {
605 int ret;
606 unsigned char *ptr = NULL;
607 struct UsbPnpDeviceListTable *deviceTableListTemp = NULL;
608
609 ptr = OsalMemAlloc(sizeof(struct UsbPnpDeviceListTable));
610 if (ptr == NULL) {
611 ret = HDF_ERR_MALLOC_FAIL;
612 HDF_LOGE("%s:%d OsalMemAlloc faile, ret=%d ", __func__, __LINE__, ret);
613 } else {
614 deviceTableListTemp = (struct UsbPnpDeviceListTable *)ptr;
615
616 DListHeadInit(&deviceTableListTemp->list);
617 deviceTableListTemp->moduleName = idTable->moduleName;
618 deviceTableListTemp->serviceName = idTable->serviceName;
619 deviceTableListTemp->deviceMatchAttr = idTable->deviceMatchAttr;
620 deviceTableListTemp->status = USB_PNP_ADD_STATUS;
621 deviceTableListTemp->usbDevAddr = info->usbDevAddr;
622 deviceTableListTemp->devNum = info->devNum;
623 deviceTableListTemp->busNum = info->busNum;
624 deviceTableListTemp->interfaceLength = idTable->interfaceLength;
625 memcpy_s(deviceTableListTemp->interfaceNumber, USB_PNP_INFO_MAX_INTERFACES, \
626 idTable->interfaceNumber, USB_PNP_INFO_MAX_INTERFACES);
627
628 DListInsertTail(&deviceTableListTemp->list, &g_usbPnpDeviceTableListHead);
629
630 ret = HDF_SUCCESS;
631 }
632
633 return ret;
634 }
635
UsbDdkPnpLoaderAddInterface(const struct UsbPnpNotifyMatchInfoTable * info,const struct UsbPnpMatchIdTable * idTable)636 static struct UsbPnpDeviceListTable *UsbDdkPnpLoaderAddInterface(
637 const struct UsbPnpNotifyMatchInfoTable *info, const struct UsbPnpMatchIdTable *idTable)
638 {
639 struct UsbPnpDeviceListTable *deviceListTablePos = NULL;
640 struct UsbPnpDeviceListTable *deviceListTableTemp = NULL;
641
642 if (DListIsEmpty(&g_usbPnpDeviceTableListHead)) {
643 HDF_LOGE("%s:%d g_usbPnpDeviceTableListHead is empty. ", __func__, __LINE__);
644 return NULL;
645 }
646
647 DLIST_FOR_EACH_ENTRY_SAFE(deviceListTablePos, deviceListTableTemp, &g_usbPnpDeviceTableListHead,
648 struct UsbPnpDeviceListTable, list) {
649 if ((strcmp(deviceListTablePos->moduleName, idTable->moduleName) == 0) && \
650 (strcmp(deviceListTablePos->serviceName, idTable->serviceName) == 0) && \
651 (strcmp(deviceListTablePos->deviceMatchAttr, idTable->deviceMatchAttr) == 0) && \
652 (deviceListTablePos->usbDevAddr == info->usbDevAddr) && \
653 (deviceListTablePos->devNum = info->devNum) && \
654 (deviceListTablePos->busNum = info->busNum)) {
655 return deviceListTablePos;
656 }
657 }
658
659 HDF_LOGE("%s:%d usbDevAddr=0x%x, interface=%d-%d-%d to \
660 be add but not exist. ",
661 __func__, __LINE__, (uint32_t)info->usbDevAddr, info->devNum, info->busNum, info->numInfos);
662
663 return NULL;
664 }
665
UsbDdkPnpLoaderrAddPnpDevice(const struct IDevmgrService * devmgrSvc,const struct UsbPnpNotifyMatchInfoTable * infoTable,const struct UsbPnpMatchIdTable * idTable,uint32_t cmdId)666 static int UsbDdkPnpLoaderrAddPnpDevice(const struct IDevmgrService *devmgrSvc,
667 const struct UsbPnpNotifyMatchInfoTable *infoTable, const struct UsbPnpMatchIdTable *idTable, uint32_t cmdId)
668 {
669 int ret;
670 struct HdfSBuf *pnpData = NULL;
671 struct UsbPnpNotifyServiceInfo serviceInfo;
672 struct UsbPnpDeviceListTable *deviceListTable = NULL;
673
674 deviceListTable = UsbDdkPnpLoaderAddInterface(infoTable, idTable);
675 if ((deviceListTable != NULL) && (deviceListTable->status != USB_PNP_REMOVE_STATUS)) {
676 HDF_LOGI("%s:%d %s-%s is already exist!",
677 __func__, __LINE__, idTable->moduleName, idTable->serviceName);
678 return HDF_SUCCESS;
679 }
680
681 serviceInfo.length = sizeof(struct UsbPnpNotifyServiceInfo) - (USB_PNP_INFO_MAX_INTERFACES
682 - idTable->interfaceLength);
683 serviceInfo.devNum = infoTable->devNum;
684 serviceInfo.busNum = infoTable->busNum;
685 serviceInfo.interfaceLength = idTable->interfaceLength;
686 memcpy_s(serviceInfo.interfaceNumber, USB_PNP_INFO_MAX_INTERFACES, \
687 idTable->interfaceNumber, USB_PNP_INFO_MAX_INTERFACES);
688 pnpData = UsbDdkPnpLoaderBufCreate(idTable->moduleName, idTable->serviceName,
689 idTable->deviceMatchAttr, serviceInfo);
690 if (pnpData == NULL) {
691 ret = HDF_FAILURE;
692 HDF_LOGE("%s: UsbDdkPnpLoaderBufCreate faile", __func__);
693 goto error;
694 }
695
696 ret = UsbDdkPnpLoaderDispatchPnpDevice(devmgrSvc, pnpData, true);
697 if (ret != HDF_SUCCESS) {
698 HDF_LOGE("%s:%d handle failed, %s-%s cmdId is %d, ret=%d",
699 __func__, __LINE__, idTable->moduleName, idTable->serviceName, cmdId, ret);
700 } else {
701 if (cmdId == USB_PNP_NOTIFY_ADD_INTERFACE) {
702 if (deviceListTable == NULL) {
703 ret = HDF_ERR_INVALID_OBJECT;
704 HDF_LOGE("%s:%d UsbDdkPnpLoaderAddInterface faile", __func__, __LINE__);
705 goto error;
706 }
707 deviceListTable->status = USB_PNP_ADD_STATUS;
708 } else {
709 ret = UsbDdkPnpLoaderDeviceListAdd(infoTable, idTable);
710 if (ret != HDF_SUCCESS) {
711 HDF_LOGE("%s:%d UsbDdkPnpLoaderDeviceListAdd faile", __func__, __LINE__);
712 goto error;
713 }
714 }
715 }
716 error:
717 HdfSBufRecycle(pnpData);
718 return ret;
719 }
720
UsbDdkPnpLoaderAddDevice(uint32_t cmdId,uint8_t index,const struct IDevmgrService * devmgrSvc,const struct UsbPnpNotifyMatchInfoTable * infoTable,struct UsbPnpMatchIdTable ** matchIdTable)721 static void UsbDdkPnpLoaderAddDevice(uint32_t cmdId, uint8_t index, const struct IDevmgrService *devmgrSvc,
722 const struct UsbPnpNotifyMatchInfoTable *infoTable, struct UsbPnpMatchIdTable **matchIdTable)
723 {
724 int ret = HDF_FAILURE;
725 struct UsbPnpMatchIdTable *idTable = NULL;
726 int32_t tableCount;
727
728 for (tableCount = 0, idTable = matchIdTable[0]; idTable != NULL; idTable = matchIdTable[++tableCount]) {
729 if (!UsbDdkPnpLoaderMatchDevice(infoTable, idTable)) {
730 continue;
731 }
732
733 if (!UsbDdkPnpLoaderMatchOneIdIntf(infoTable, index, idTable)) {
734 continue;
735 }
736
737 HDF_LOGD("%s:%d matchDevice end, index=%d tableCount=%d is match \
738 idTable=%p, moduleName=%s, serviceName=%s",
739 __func__, __LINE__, index, tableCount, idTable, idTable->moduleName, idTable->serviceName);
740
741 ret = UsbDdkPnpLoaderrAddPnpDevice(devmgrSvc, infoTable, idTable, cmdId);
742 if (ret != HDF_SUCCESS) {
743 continue;
744 }
745 }
746
747 HDF_LOGD("%s:%d AddDevice end, index=%d, ret=%d", __func__, __LINE__, index, ret);
748 }
749
UsbDdkPnpLoaderRemoveHandle(const struct IDevmgrService * devmgrSvc,struct UsbPnpDeviceListTable * deviceListTablePos)750 static int UsbDdkPnpLoaderRemoveHandle(const struct IDevmgrService *devmgrSvc,
751 struct UsbPnpDeviceListTable *deviceListTablePos)
752 {
753 struct UsbPnpNotifyServiceInfo serviceInfo;
754 struct HdfSBuf *pnpData = NULL;
755 int ret = HDF_SUCCESS;
756
757 serviceInfo.length = sizeof(struct UsbPnpNotifyServiceInfo) - (USB_PNP_INFO_MAX_INTERFACES \
758 - deviceListTablePos->interfaceLength);
759 serviceInfo.devNum = deviceListTablePos->devNum;
760 serviceInfo.busNum = deviceListTablePos->busNum;
761 serviceInfo.interfaceLength = deviceListTablePos->interfaceLength;
762 memcpy_s(serviceInfo.interfaceNumber, USB_PNP_INFO_MAX_INTERFACES, \
763 deviceListTablePos->interfaceNumber, USB_PNP_INFO_MAX_INTERFACES);
764 pnpData = UsbDdkPnpLoaderBufCreate(deviceListTablePos->moduleName, deviceListTablePos->serviceName, \
765 deviceListTablePos->deviceMatchAttr, serviceInfo);
766 if (pnpData == NULL) {
767 HDF_LOGE("%s: UsbDdkPnpLoaderBufCreate faile", __func__);
768 return HDF_FAILURE;
769 }
770
771 if (deviceListTablePos->status != USB_PNP_REMOVE_STATUS) {
772 ret = UsbDdkPnpLoaderDispatchPnpDevice(devmgrSvc, pnpData, false);
773 if (ret != HDF_SUCCESS) {
774 HDF_LOGE("%s:%d UsbDdkPnpLoaderDispatchPnpDevice faile ret=%d",
775 __func__, __LINE__, ret);
776 goto error;
777 }
778 deviceListTablePos->status = USB_PNP_REMOVE_STATUS;
779 }
780
781 error:
782 HdfSBufRecycle(pnpData);
783 return ret;
784 }
785
UsbDdkPnpLoaderRemoveDevice(const struct IDevmgrService * devmgrSvc,struct UsbPnpRemoveInfo removeInfo,uint32_t cmdId)786 static int UsbDdkPnpLoaderRemoveDevice(const struct IDevmgrService *devmgrSvc,
787 struct UsbPnpRemoveInfo removeInfo, uint32_t cmdId)
788 {
789 int ret = HDF_SUCCESS;
790 struct UsbPnpDeviceListTable *deviceListTablePos = NULL;
791 struct UsbPnpDeviceListTable *deviceListTableTemp = NULL;
792 bool findFlag = false;
793 int32_t i;
794
795 if (DListIsEmpty(&g_usbPnpDeviceTableListHead)) {
796 HDF_LOGE("%s:%d g_usbPnpDeviceTableListHead is empty. ", __func__, __LINE__);
797 return HDF_SUCCESS;
798 }
799
800 DLIST_FOR_EACH_ENTRY_SAFE(deviceListTablePos, deviceListTableTemp, &g_usbPnpDeviceTableListHead,
801 struct UsbPnpDeviceListTable, list) {
802 if (deviceListTablePos->usbDevAddr == removeInfo.usbDevAddr) {
803 if (removeInfo.removeType == USB_PNP_NOTIFY_REMOVE_INTERFACE_NUM) {
804 for (i = 0; i < deviceListTablePos->interfaceLength; i++) {
805 if (deviceListTablePos->interfaceNumber[i] == removeInfo.interfaceNum) {
806 break;
807 }
808 }
809
810 if (i >= deviceListTablePos->interfaceLength) {
811 continue;
812 }
813 }
814 findFlag = true;
815
816 ret = UsbDdkPnpLoaderRemoveHandle(devmgrSvc, deviceListTablePos);
817 if (ret != HDF_SUCCESS) {
818 break;
819 }
820
821 if (cmdId != USB_PNP_NOTIFY_REMOVE_INTERFACE) {
822 DListRemove(&deviceListTablePos->list);
823 OsalMemFree(deviceListTablePos);
824 deviceListTablePos = NULL;
825 }
826 }
827 }
828
829 if (findFlag == false) {
830 HDF_LOGE("%s:%d removeType=%d, usbDevAddr=0x%x, to be remove but not exist.",
831 __func__, __LINE__, removeInfo.removeType, (uint32_t)removeInfo.usbDevAddr);
832 ret = HDF_FAILURE;
833 }
834
835 return ret;
836 }
837
UsbDdkPnpLoaderDevice(const struct UsbPnpNotifyMatchInfoTable * infoTable,const struct IDevmgrService * super,uint32_t id)838 static int UsbDdkPnpLoaderDevice(const struct UsbPnpNotifyMatchInfoTable *infoTable,
839 const struct IDevmgrService *super, uint32_t id)
840 {
841 int8_t i;
842 int32_t tableCount;
843 struct UsbPnpMatchIdTable *idTable = NULL;
844
845 if ((infoTable == NULL) || (g_usbPnpMatchIdTable == NULL) || (g_usbPnpMatchIdTable[0] == NULL)) {
846 HDF_LOGE("%s:%d infoTable or super or g_usbPnpMatchIdTable is NULL!", __func__, __LINE__);
847 return HDF_ERR_INVALID_PARAM;
848 }
849
850 for (i = 0; i < infoTable->numInfos; i++) {
851 UsbDdkPnpLoaderAddDevice(id, i, super, infoTable, g_usbPnpMatchIdTable);
852 }
853
854 for (tableCount = 0, idTable = g_usbPnpMatchIdTable[0]; idTable != NULL;
855 idTable = g_usbPnpMatchIdTable[++tableCount]) {
856 idTable->interfaceClassMask = 0;
857 if (!(idTable->matchFlag & USB_PNP_NOTIFY_MATCH_INT_CLASS)) {
858 idTable->interfaceClassLength = 0;
859 }
860 idTable->interfaceSubClassMask = 0;
861 if (!(idTable->matchFlag & USB_PNP_NOTIFY_MATCH_INT_SUBCLASS)) {
862 idTable->interfaceSubClassLength = 0;
863 }
864 idTable->interfaceProtocolMask = 0;
865 if (!(idTable->matchFlag & USB_PNP_NOTIFY_MATCH_INT_PROTOCOL)) {
866 idTable->interfaceProtocolLength = 0;
867 }
868 idTable->interfaceMask = 0;
869 if (!(idTable->matchFlag & USB_PNP_NOTIFY_MATCH_INT_NUMBER)) {
870 idTable->interfaceLength = 0;
871 }
872 idTable->pnpMatchFlag = false;
873 }
874
875 return HDF_SUCCESS;
876 }
877
UsbDdkPnpLoaderEventSend(const struct HdfIoService * serv,const char * eventData)878 static int UsbDdkPnpLoaderEventSend(const struct HdfIoService *serv, const char *eventData)
879 {
880 int ret;
881 int replyData = 0;
882 struct HdfSBuf *data = NULL;
883
884 data = HdfSBufObtainDefaultSize();
885 if (data == NULL) {
886 ret = HDF_DEV_ERR_NO_MEMORY;
887 HDF_LOGE("%s: fail to obtain sbuf data", __func__);
888 return ret;
889 }
890
891 struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
892 if (reply == NULL) {
893 ret = HDF_DEV_ERR_NO_MEMORY;
894 HDF_LOGE("%s: fail to obtain sbuf reply", __func__);
895 goto out;
896 }
897
898 if (!HdfSbufWriteString(data, eventData)) {
899 ret = HDF_FAILURE;
900 HDF_LOGE("%s: fail to write sbuf", __func__);
901 goto out;
902 }
903
904 ret = serv->dispatcher->Dispatch((struct HdfObject *)&serv->object, USB_PNP_NOTIFY_REPORT_INTERFACE, data, reply);
905 if (ret != HDF_SUCCESS) {
906 HDF_LOGE("%s: fail to send serivice call, ret=%d", __func__, ret);
907 goto out;
908 }
909
910 if (!HdfSbufReadInt32(reply, &replyData)) {
911 ret = HDF_ERR_INVALID_OBJECT;
912 HDF_LOGE("%s: fail to get service call reply", __func__);
913 goto out;
914 }
915
916 HDF_LOGI("%s:%d get reply is 0x%x", __func__, __LINE__, replyData);
917
918 out:
919 HdfSBufRecycle(data);
920 HdfSBufRecycle(reply);
921
922 return ret;
923 }
924
UsbDdkPnpLoaderEventReceived(void * priv,uint32_t id,struct HdfSBuf * data)925 int UsbDdkPnpLoaderEventReceived(void *priv, uint32_t id, struct HdfSBuf *data)
926 {
927 int ret;
928 bool flag = false;
929 uint32_t infoSize;
930 struct UsbPnpNotifyMatchInfoTable *infoTable = NULL;
931 struct IDevmgrService *super = (struct IDevmgrService *)priv;
932 struct UsbPnpRemoveInfo removeInfo;
933
934 flag = HdfSbufReadBuffer(data, (const void **)(&infoTable), &infoSize);
935 if ((flag == false) || (infoTable == NULL)) {
936 ret = HDF_ERR_INVALID_PARAM;
937 HDF_LOGE("%s: fail to read infoTable in event data, flag=%d, infoTable=%p", \
938 __func__, flag, infoTable);
939 return ret;
940 }
941
942 HDF_LOGI("%s:%d id=%d infoSize=%d, usbDevAddr=0x%x, devNum=%d, \
943 busNum=%d, infoTable=0x%x-0x%x success",
944 __func__, __LINE__, id, infoSize, (uint32_t)infoTable->usbDevAddr, infoTable->devNum,
945 infoTable->busNum, infoTable->deviceInfo.vendorId, infoTable->deviceInfo.productId);
946
947 switch (id) {
948 case USB_PNP_NOTIFY_ADD_INTERFACE:
949 case USB_PNP_NOTIFY_ADD_DEVICE:
950 case USB_PNP_NOTIFY_REPORT_INTERFACE:
951 #if USB_PNP_NOTIFY_TEST_MODE == true
952 case USB_PNP_NOTIFY_ADD_TEST:
953 #endif
954 ret = UsbDdkPnpLoaderDevice(infoTable, super, id);
955 break;
956 case USB_PNP_NOTIFY_REMOVE_INTERFACE:
957 case USB_PNP_NOTIFY_REMOVE_DEVICE:
958 #if USB_PNP_NOTIFY_TEST_MODE == true
959 case USB_PNP_NOTIFY_REMOVE_TEST:
960 #endif
961 removeInfo.removeType = infoTable->removeType;
962 removeInfo.usbDevAddr = infoTable->usbDevAddr;
963 removeInfo.devNum = infoTable->devNum;
964 removeInfo.busNum = infoTable->busNum;
965 removeInfo.interfaceNum = infoTable->interfaceInfo[0].interfaceNumber;
966 ret = UsbDdkPnpLoaderRemoveDevice(super, removeInfo, id);
967 break;
968 default:
969 ret = HDF_ERR_INVALID_PARAM;
970 break;
971 }
972
973 HDF_LOGI("%s:%d ret=%d DONE", __func__, __LINE__, ret);
974
975 return ret;
976 }
977
UsbDdkPnpLoaderEventHandle(void)978 int UsbDdkPnpLoaderEventHandle(void)
979 {
980 int status;
981 int32_t tableCount = 0;
982 static bool firstInitFlag = true;
983 const struct UsbPnpMatchIdTable *idTable = NULL;
984 struct HdfIoService *usbPnpServ = HdfIoServiceBind(USB_PNP_NOTIFY_SERVICE_NAME);
985
986 if (usbPnpServ == NULL) {
987 HDF_LOGE("%s: HdfIoServiceBind faile.", __func__);
988 return HDF_ERR_INVALID_OBJECT;
989 }
990
991 if (firstInitFlag == true) {
992 firstInitFlag = false;
993
994 DListHeadInit(&g_usbPnpDeviceTableListHead);
995 }
996
997 g_usbPnpMatchIdTable = UsbDdkPnpLoaderPnpMatch();
998 if ((g_usbPnpMatchIdTable == NULL) || (g_usbPnpMatchIdTable[0] == NULL)) {
999 status = HDF_ERR_INVALID_PARAM;
1000 HDF_LOGE("%s: g_usbPnpMatchIdTable or g_usbPnpMatchIdTable[0] is NULL!", __func__);
1001 return status;
1002 }
1003
1004 status = UsbDdkPnpLoaderEventSend(usbPnpServ, "USB PNP Handle Info");
1005 if (status != HDF_SUCCESS) {
1006 HDF_LOGE("UsbDdkPnpLoaderEventSend faile status=%d", status);
1007 goto error;
1008 }
1009 return status;
1010 error:
1011 for (idTable = g_usbPnpMatchIdTable[0]; idTable != NULL; ) {
1012 tableCount++;
1013 idTable = g_usbPnpMatchIdTable[tableCount];
1014 }
1015 while ((--tableCount) >= 0) {
1016 OsalMemFree(g_usbPnpMatchIdTable[tableCount]);
1017 g_usbPnpMatchIdTable[tableCount] = NULL;
1018 }
1019 OsalMemFree(g_usbPnpMatchIdTable);
1020 g_usbPnpMatchIdTable = NULL;
1021
1022 return status;
1023 }
1024