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