• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  *    conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *    of conditions and the following disclaimer in the documentation and/or other materials
12  *    provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15  *    to endorse or promote products derived from this software without specific prior written
16  *    permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "usb_pnp_notify.h"
32 #include <unistd.h>
33 #include <los_queue.h>
34 #include <osal_thread.h>
35 #include "osal_file.h"
36 #include "osal_mem.h"
37 #include "osal_mutex.h"
38 #include "osal_time.h"
39 #include "devsvc_manager_clnt.h"
40 #include "hdf_log.h"
41 #include "hdf_device_object.h"
42 #include "implementation/global_implementation.h"
43 #include "fs/fs.h"
44 #include "usbdi.h"
45 #include "linux_usb.h"
46 #include "usb_debug.h"
47 
48 #define HDF_LOG_TAG LITEOS_USB_PNP_NOTIFY
49 
50 static wait_queue_head_t g_usbPnpNotifyReportWait;
51 static struct OsalThread g_usbPnpNotifyReportThread;
52 static bool g_usbPnpThreadRunningFlag = false;
53 static enum UsbPnpNotifyServiceCmd g_usbPnpNotifyCmdType = USB_PNP_NOTIFY_ADD_INTERFACE;
54 static enum UsbPnpNotifyRemoveType g_usbPnpNotifyRemoveType = USB_PNP_NOTIFY_REMOVE_BUS_DEV_NUM;
55 struct OsalMutex g_usbSendEventLock;
56 struct usb_device *g_usbDevice = NULL;
57 struct UsbPnpAddRemoveInfo g_usbPnpInfo;
58 struct DListHead g_usbPnpInfoListHead;
59 #if USB_PNP_NOTIFY_TEST_MODE == true
60 struct UsbPnpNotifyMatchInfoTable *g_testUsbPnpInfo = NULL;
61 #endif
62 
63 /* USB universal driver matching code in LiteOS */
64 struct DListHead g_usbPnpDeviceListHead;
65 struct OsalMutex g_usbPnpNotifyDevicelistLock;
66 
UsbPnpNotifyFindDeviceList(struct usb_device * deviceObj,bool freeFlag)67 static bool UsbPnpNotifyFindDeviceList(struct usb_device *deviceObj, bool freeFlag)
68 {
69     struct UsbPnpNotifyDeviceList *pnpNotifyDevicePos = NULL;
70     struct UsbPnpNotifyDeviceList *pnpNotifyDeviceTemp = NULL;
71     bool findFlag = false;
72 
73     if (DListIsEmpty(&g_usbPnpDeviceListHead)) {
74         PRINTK("%s:%d device list is empty\n", __func__, __LINE__);
75         return false;
76     }
77 
78     OsalMutexLock(&g_usbPnpNotifyDevicelistLock);
79     DLIST_FOR_EACH_ENTRY_SAFE(pnpNotifyDevicePos, pnpNotifyDeviceTemp, &g_usbPnpDeviceListHead,
80         struct UsbPnpNotifyDeviceList, deviceList) {
81         if (pnpNotifyDevicePos->device == deviceObj) {
82             findFlag = true;
83             if (freeFlag == true) {
84                 DListRemove(&pnpNotifyDevicePos->deviceList);
85                 OsalMemFree(&pnpNotifyDevicePos);
86             }
87             break;
88         }
89     }
90     OsalMutexUnlock(&g_usbPnpNotifyDevicelistLock);
91 
92     return findFlag;
93 }
94 
95 /* HDF driver framework code */
UsbPnpNotifyCreateInfo(void)96 static struct UsbPnpDeviceInfo *UsbPnpNotifyCreateInfo(void)
97 {
98     struct UsbPnpDeviceInfo *infoTemp = NULL;
99     unsigned char *ptr = NULL;
100     static int32_t idNum = 0;
101     int32_t ret;
102 
103     ptr = OsalMemCalloc(sizeof(struct UsbPnpDeviceInfo));
104     if (ptr == NULL) {
105         HDF_LOGE("%s:%d OsalMemAlloc faile ", __func__, __LINE__);
106         return NULL;
107     }
108     infoTemp = (struct UsbPnpDeviceInfo *)ptr;
109 
110     if (idNum++ >= INT32_MAX) {
111         idNum = 0;
112     }
113     infoTemp->id = idNum;
114     OsalMutexInit(&infoTemp->lock);
115     infoTemp->status = USB_PNP_DEVICE_INIT_STATUS;
116     DListHeadInit(&infoTemp->list);
117     ret = memset_s(infoTemp->interfaceRemoveStatus, USB_PNP_INFO_MAX_INTERFACES,
118         0, sizeof(infoTemp->interfaceRemoveStatus));
119     if (ret != HDF_SUCCESS) {
120         HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
121         OsalMemFree(ptr);
122         return NULL;
123     }
124 
125     DListInsertTail(&infoTemp->list, &g_usbPnpInfoListHead);
126     return infoTemp;
127 }
128 
UsbPnpNotifyFindInfo(struct UsbInfoQueryPara queryPara)129 static struct UsbPnpDeviceInfo *UsbPnpNotifyFindInfo(struct UsbInfoQueryPara queryPara)
130 {
131     struct UsbPnpDeviceInfo *infoPos = NULL;
132     struct UsbPnpDeviceInfo *infoTemp = NULL;
133     bool findFlag = false;
134 
135     if (DListIsEmpty(&g_usbPnpInfoListHead)) {
136         HDF_LOGE("%s:%d usb pnp list head is empty. ", __func__, __LINE__);
137         return NULL;
138     }
139 
140     DLIST_FOR_EACH_ENTRY_SAFE(infoPos, infoTemp, &g_usbPnpInfoListHead, struct UsbPnpDeviceInfo, list) {
141         switch (queryPara.type) {
142             case USB_INFO_NORMAL_TYPE:
143                 if ((infoPos->info.devNum == queryPara.devNum) && (infoPos->info.busNum == queryPara.busNum)) {
144                     findFlag = true;
145                 }
146                 break;
147             case USB_INFO_ID_TYPE:
148                 if (infoPos->id == queryPara.id) {
149                     findFlag = true;
150                 }
151                 break;
152             case USB_INFO_DEVICE_ADDRESS_TYPE:
153                 if (infoPos->info.usbDevAddr == queryPara.usbDevAddr) {
154                     findFlag = true;
155                 }
156                 break;
157             default:
158                 break;
159         }
160 
161         if (findFlag == true) {
162             break;
163         }
164     }
165 
166     if (findFlag == false) {
167         HDF_LOGE("%s:%d the usb pnp info to be find does not exist. ", __func__, __LINE__);
168         return NULL;
169     } else {
170         return infoPos;
171     }
172 }
173 
UsbPnpNotifyDestroyInfo(struct UsbPnpDeviceInfo * deviceInfo)174 static HDF_STATUS UsbPnpNotifyDestroyInfo(struct UsbPnpDeviceInfo *deviceInfo)
175 {
176     HDF_STATUS ret = HDF_SUCCESS;
177     struct UsbPnpDeviceInfo *infoPos = NULL;
178     struct UsbPnpDeviceInfo *infoTemp = NULL;
179     bool findFlag = false;
180 
181     if (deviceInfo == NULL) {
182         ret = HDF_FAILURE;
183         HDF_LOGE("%s:%d the deviceInfo is NULL, ret=%d ", __func__, __LINE__, ret);
184         return ret;
185     }
186 
187     if (DListIsEmpty(&g_usbPnpInfoListHead)) {
188         HDF_LOGI("%s:%d the g_usbPnpInfoListHead is empty.", __func__, __LINE__);
189         return HDF_SUCCESS;
190     }
191 
192     DLIST_FOR_EACH_ENTRY_SAFE(infoPos, infoTemp, &g_usbPnpInfoListHead, struct UsbPnpDeviceInfo, list) {
193         if (infoPos->id == deviceInfo->id) {
194             findFlag = true;
195             DListRemove(&infoPos->list);
196             OsalMemFree((void *)infoPos);
197             infoPos = NULL;
198             break;
199         }
200     }
201 
202     if (findFlag == false) {
203         ret = HDF_FAILURE;
204         HDF_LOGE("%s:%d the deviceInfoto be destroyed does not exist, ret=%d ", __func__, __LINE__, ret);
205     }
206 
207     return ret;
208 }
209 
UsbPnpNotifyAddInitInfo(struct UsbPnpDeviceInfo * deviceInfo,union UsbPnpDeviceInfoData infoData)210 static int32_t UsbPnpNotifyAddInitInfo(struct UsbPnpDeviceInfo *deviceInfo, union UsbPnpDeviceInfoData infoData)
211 {
212     int32_t ret = HDF_SUCCESS;
213 
214     deviceInfo->info.usbDevAddr = (uint64_t)infoData.usbDev;
215     deviceInfo->info.devNum = infoData.usbDev->address;
216     deviceInfo->info.busNum = (int32_t)infoData.usbDev->port_no;
217 
218     deviceInfo->info.deviceInfo.vendorId = UGETW(infoData.usbDev->ddesc.idVendor);
219     deviceInfo->info.deviceInfo.productId = UGETW(infoData.usbDev->ddesc.idProduct);
220     deviceInfo->info.deviceInfo.bcdDeviceLow = UGETW(infoData.usbDev->ddesc.bcdDevice);
221     deviceInfo->info.deviceInfo.bcdDeviceHigh = UGETW(infoData.usbDev->ddesc.bcdDevice);
222     deviceInfo->info.deviceInfo.deviceClass = infoData.usbDev->ddesc.bDeviceClass;
223     deviceInfo->info.deviceInfo.deviceSubClass = infoData.usbDev->ddesc.bDeviceSubClass;
224     deviceInfo->info.deviceInfo.deviceProtocol = infoData.usbDev->ddesc.bDeviceProtocol;
225 
226     if (infoData.usbDev->cdesc == NULL) {
227         DPRINTFN(0, "%s infoData.usbDev->cdesc=%p is NULL", __func__, infoData.usbDev->cdesc);
228         ret = HDF_ERR_INVALID_PARAM;
229         goto OUT;
230     }
231     deviceInfo->info.numInfos = infoData.usbDev->cdesc->bNumInterface;
232     for (uint8_t i = 0; i < deviceInfo->info.numInfos; i++) {
233         if (infoData.usbDev->ifaces[i].idesc == NULL) {
234             HDF_LOGE("%s:%d interface[%d].idesc is NULL",
235                 __func__, __LINE__, i);
236             ret = HDF_ERR_INVALID_PARAM;
237             goto OUT;
238         }
239         deviceInfo->info.interfaceInfo[i].interfaceClass =
240             infoData.usbDev->ifaces[i].idesc->bInterfaceClass;
241         deviceInfo->info.interfaceInfo[i].interfaceSubClass =
242             infoData.usbDev->ifaces[i].idesc->bInterfaceSubClass;
243         deviceInfo->info.interfaceInfo[i].interfaceProtocol =
244             infoData.usbDev->ifaces[i].idesc->bInterfaceProtocol;
245         deviceInfo->info.interfaceInfo[i].interfaceNumber =
246             infoData.usbDev->ifaces[i].idesc->bInterfaceNumber;
247 
248         HDF_LOGI("%s:%d i=%d, interfaceInfo=0x%x-0x%x-0x%x-0x%x",
249             __func__, __LINE__, i, deviceInfo->info.interfaceInfo[i].interfaceClass,
250             deviceInfo->info.interfaceInfo[i].interfaceSubClass,
251             deviceInfo->info.interfaceInfo[i].interfaceProtocol,
252             deviceInfo->info.interfaceInfo[i].interfaceNumber);
253     }
254 
255 OUT:
256     return ret;
257 }
258 
UsbPnpNotifyAddInterfaceInitInfo(struct UsbPnpDeviceInfo * deviceInfo,union UsbPnpDeviceInfoData infoData,struct UsbPnpNotifyMatchInfoTable * infoTable)259 static void UsbPnpNotifyAddInterfaceInitInfo(struct UsbPnpDeviceInfo *deviceInfo,
260     union UsbPnpDeviceInfoData infoData, struct UsbPnpNotifyMatchInfoTable *infoTable)
261 {
262     uint8_t i;
263     uint8_t j;
264 
265     for (i = 0; i < deviceInfo->info.numInfos; i++) {
266         if ((infoData.infoData->interfaceClass == deviceInfo->info.interfaceInfo[i].interfaceClass)
267             && (infoData.infoData->interfaceSubClass == deviceInfo->info.interfaceInfo[i].interfaceSubClass)
268             && (infoData.infoData->interfaceProtocol == deviceInfo->info.interfaceInfo[i].interfaceProtocol)
269             && (infoData.infoData->interfaceNumber == deviceInfo->info.interfaceInfo[i].interfaceNumber)) {
270             if (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_INTERFACE) {
271                 deviceInfo->interfaceRemoveStatus[i] = true;
272             } else if (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_ADD_INTERFACE) {
273                 deviceInfo->interfaceRemoveStatus[i] = false;
274             }
275         }
276     }
277 
278     if (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_INTERFACE) {
279         infoTable->numInfos = 1;
280         infoTable->interfaceInfo[0].interfaceClass = infoData.infoData->interfaceClass;
281         infoTable->interfaceInfo[0].interfaceSubClass = infoData.infoData->interfaceSubClass;
282         infoTable->interfaceInfo[0].interfaceProtocol = infoData.infoData->interfaceProtocol;
283         infoTable->interfaceInfo[0].interfaceNumber = infoData.infoData->interfaceNumber;
284     } else {
285         for (i = 0, j = 0; i < deviceInfo->info.numInfos; i++) {
286             if (deviceInfo->interfaceRemoveStatus[i] == true) {
287                 HDF_LOGI("%s:%d j=%d deviceInfo->interfaceRemoveStatus[%d] is true!", __func__, __LINE__, j, i);
288                 continue;
289             }
290             infoTable->interfaceInfo[j].interfaceClass = deviceInfo->info.interfaceInfo[i].interfaceClass;
291             infoTable->interfaceInfo[j].interfaceSubClass = deviceInfo->info.interfaceInfo[i].interfaceSubClass;
292             infoTable->interfaceInfo[j].interfaceProtocol = deviceInfo->info.interfaceInfo[i].interfaceProtocol;
293             infoTable->interfaceInfo[j].interfaceNumber = deviceInfo->info.interfaceInfo[i].interfaceNumber;
294             j++;
295 
296             HDF_LOGI("%s:%d i=%d, j=%d, interfaceInfo=0x%x-0x%x-0x%x-0x%x",
297                 __func__, __LINE__, i, j - 1, infoTable->interfaceInfo[j - 1].interfaceClass,
298                 infoTable->interfaceInfo[j - 1].interfaceSubClass,
299                 infoTable->interfaceInfo[j - 1].interfaceProtocol,
300                 infoTable->interfaceInfo[j - 1].interfaceNumber);
301         }
302         infoTable->numInfos = j;
303     }
304 }
305 
UsbPnpNotifyInitInfo(struct HdfSBuf * sbuf,struct UsbPnpDeviceInfo * deviceInfo,union UsbPnpDeviceInfoData infoData)306 static int32_t UsbPnpNotifyInitInfo(
307     struct HdfSBuf *sbuf, struct UsbPnpDeviceInfo *deviceInfo, union UsbPnpDeviceInfoData infoData)
308 {
309     int32_t ret = HDF_SUCCESS;
310     const void *data = NULL;
311 
312     if ((g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_ADD_INTERFACE)
313         || (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_INTERFACE)) {
314         static struct UsbPnpNotifyMatchInfoTable infoTable;
315 
316         infoTable.usbDevAddr = deviceInfo->info.usbDevAddr;
317         infoTable.devNum = deviceInfo->info.devNum;
318         infoTable.busNum = deviceInfo->info.busNum;
319         infoTable.deviceInfo.vendorId = deviceInfo->info.deviceInfo.vendorId;
320         infoTable.deviceInfo.productId = deviceInfo->info.deviceInfo.productId;
321         infoTable.deviceInfo.bcdDeviceLow = deviceInfo->info.deviceInfo.bcdDeviceLow;
322         infoTable.deviceInfo.bcdDeviceHigh = deviceInfo->info.deviceInfo.bcdDeviceHigh;
323         infoTable.deviceInfo.deviceClass = deviceInfo->info.deviceInfo.deviceClass;
324         infoTable.deviceInfo.deviceSubClass = deviceInfo->info.deviceInfo.deviceSubClass;
325         infoTable.deviceInfo.deviceProtocol = deviceInfo->info.deviceInfo.deviceProtocol;
326         infoTable.removeType = g_usbPnpNotifyRemoveType;
327 
328         UsbPnpNotifyAddInterfaceInitInfo(deviceInfo, infoData, &infoTable);
329 
330         data = (const void *)(&infoTable);
331     } else if (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REPORT_INTERFACE) {
332         ret = UsbPnpNotifyAddInitInfo(deviceInfo, infoData);
333         if (ret != HDF_SUCCESS) {
334             goto OUT;
335         }
336 
337         data = (const void *)(&deviceInfo->info);
338     } else {
339         data = (const void *)(&deviceInfo->info);
340     }
341 
342     if (!HdfSbufWriteBuffer(sbuf, data, sizeof(struct UsbPnpNotifyMatchInfoTable))) {
343         HDF_LOGE("%s:%d sbuf write data failed", __func__, __LINE__);
344         ret = HDF_FAILURE;
345         goto OUT;
346     }
347 
348 OUT:
349     return ret;
350 }
351 
UsbPnpNotifySendEventLoader(struct HdfSBuf * data)352 static int32_t UsbPnpNotifySendEventLoader(struct HdfSBuf *data)
353 {
354     int32_t ret;
355 
356     struct HdfIoService *loaderService = HdfIoServiceBind(USB_PNP_LOADER_SERVICE_NAME);
357     if (loaderService == NULL) {
358         HDF_LOGE("%s:%d fail to get service %s", __func__, __LINE__, USB_PNP_LOADER_SERVICE_NAME);
359         return HDF_FAILURE;
360     }
361 
362     ret = loaderService->dispatcher->Dispatch(&loaderService->object, g_usbPnpNotifyCmdType, data, NULL);
363     if (ret != HDF_SUCCESS) {
364         HDF_LOGE("%s:%d Dispatch USB_PNP_DRIVER_REGISTER_DEVICE err", __func__, __LINE__);
365         goto OUT;
366     }
367 
368 OUT:
369     HdfIoServiceRecycle(loaderService);
370 
371     return HDF_SUCCESS;
372 }
373 
UsbPnpNotifyGetDeviceInfo(void * eventData,union UsbPnpDeviceInfoData * pnpInfoData,struct UsbPnpDeviceInfo ** deviceInfo)374 static int32_t UsbPnpNotifyGetDeviceInfo(void *eventData, union UsbPnpDeviceInfoData *pnpInfoData,
375     struct UsbPnpDeviceInfo **deviceInfo)
376 {
377     struct UsbInfoQueryPara infoQueryPara;
378 
379     if ((g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_ADD_INTERFACE)
380         || (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_INTERFACE)) {
381         pnpInfoData->infoData = (struct UsbPnpAddRemoveInfo *)eventData;
382     } else {
383         pnpInfoData->usbDev = (struct usb_device *)eventData;
384     }
385 
386     if ((g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_ADD_INTERFACE)
387         || (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_INTERFACE)) {
388         infoQueryPara.type = USB_INFO_NORMAL_TYPE;
389         infoQueryPara.devNum = pnpInfoData->infoData->devNum;
390         infoQueryPara.busNum = pnpInfoData->infoData->busNum;
391         *deviceInfo = UsbPnpNotifyFindInfo(infoQueryPara);
392     } else if ((g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_ADD_DEVICE)
393         || (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_DEVICE)) {
394         infoQueryPara.type = USB_INFO_DEVICE_ADDRESS_TYPE;
395         infoQueryPara.usbDevAddr = (uint64_t)pnpInfoData->usbDev;
396         *deviceInfo = UsbPnpNotifyFindInfo(infoQueryPara);
397     } else {
398         *deviceInfo = UsbPnpNotifyCreateInfo();
399     }
400 
401     if (*deviceInfo == NULL) {
402         HDF_LOGE("%s:%d create or find info failed", __func__, __LINE__);
403         return HDF_FAILURE;
404     }
405 
406     (*deviceInfo)->info.removeType = g_usbPnpNotifyRemoveType;
407 
408     return HDF_SUCCESS;
409 }
410 
UsbPnpNotifyHdfSendEvent(const struct HdfDeviceObject * deviceObject,void * eventData)411 static int32_t UsbPnpNotifyHdfSendEvent(const struct HdfDeviceObject *deviceObject,
412     void *eventData)
413 {
414     int32_t ret;
415     struct UsbPnpDeviceInfo *deviceInfo = NULL;
416     struct HdfSBuf *data = NULL;
417     union UsbPnpDeviceInfoData pnpInfoData;
418 
419     if ((deviceObject == NULL) || (eventData == NULL)) {
420         HDF_LOGE("%s:%d deviceObject and eventData is NULL", __func__, __LINE__);
421         return HDF_ERR_INVALID_PARAM;
422     }
423 
424     data = HdfSbufObtainDefaultSize();
425     if (data == NULL) {
426         HDF_LOGE("%s:%d InitDataBlock failed", __func__, __LINE__);
427         return HDF_FAILURE;
428     }
429 
430     ret = UsbPnpNotifyGetDeviceInfo(eventData, &pnpInfoData, &deviceInfo);
431     if (ret != HDF_SUCCESS) {
432         HDF_LOGE("%s:%d UsbPnpNotifyGetDeviceInfo failed, ret=%d", __func__, __LINE__, ret);
433         goto ERROR_DEVICE_INFO;
434     }
435 
436     ret = UsbPnpNotifyInitInfo(data, deviceInfo, pnpInfoData);
437     if (ret != HDF_SUCCESS) {
438         HDF_LOGE("%s:%d UsbPnpNotifyInitInfo failed, ret=%d", __func__, __LINE__, ret);
439         goto OUT;
440     }
441 
442     HDF_LOGI("%s:%d report one device information, devNum=%d, busNum=%d, infoTable=%d-0x%x-0x%x!",
443         __func__, __LINE__, deviceInfo->info.devNum, deviceInfo->info.busNum, deviceInfo->info.numInfos,
444         deviceInfo->info.deviceInfo.vendorId, deviceInfo->info.deviceInfo.productId);
445 
446     OsalMutexLock(&deviceInfo->lock);
447     if (deviceInfo->status == USB_PNP_DEVICE_INIT_STATUS) {
448         ret = UsbPnpNotifySendEventLoader(data);
449         if (ret != HDF_SUCCESS) {
450             OsalMutexUnlock(&deviceInfo->lock);
451             HDF_LOGE("%s:%d UsbPnpNotifySendEventLoader ret=%d", __func__, __LINE__, ret);
452             goto OUT;
453         }
454         deviceInfo->status = USB_PNP_DEVICE_ADD_STATUS;
455     } else {
456         ret = HDF_ERR_INVALID_OBJECT;
457     }
458     OsalMutexUnlock(&deviceInfo->lock);
459 
460 OUT:
461     if ((ret != HDF_SUCCESS) || (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_DEVICE)) {
462         if (UsbPnpNotifyDestroyInfo(deviceInfo) != HDF_SUCCESS) {
463             HDF_LOGE("%s:%d UsbPnpNotifyDestroyInfo fail", __func__, __LINE__);
464         }
465     }
466 ERROR_DEVICE_INFO:
467     HdfSbufRecycle(data);
468     return ret;
469 }
470 
471 #if USB_PNP_NOTIFY_TEST_MODE == true
TestReadPnpInfo(struct HdfSBuf * data)472 static void TestReadPnpInfo(struct HdfSBuf *data)
473 {
474     uint32_t infoSize;
475     bool flag;
476 
477     flag = HdfSbufReadBuffer(data, (const void **)(&g_testUsbPnpInfo), &infoSize);
478     if ((flag == false) || (g_testUsbPnpInfo == NULL)) {
479         HDF_LOGE("%s: fail to read g_testUsbPnpInfo, flag=%d, g_testUsbPnpInfo=%px", \
480             __func__, flag, g_testUsbPnpInfo);
481         return;
482     }
483 
484     HDF_LOGI("%s:%d infoSize=%d g_testUsbPnpInfo=%px read success!", __func__, __LINE__, infoSize, g_testUsbPnpInfo);
485 }
486 
TestPnpNotifyFillInfoTable(struct UsbPnpNotifyMatchInfoTable * infoTable)487 static void TestPnpNotifyFillInfoTable(struct UsbPnpNotifyMatchInfoTable *infoTable)
488 {
489     int8_t i;
490 
491     infoTable->usbDevAddr = g_testUsbPnpInfo->usbDevAddr;
492     infoTable->devNum = g_testUsbPnpInfo->devNum;
493     if (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_TEST) {
494         infoTable->busNum = -1;
495     } else {
496         infoTable->busNum = g_testUsbPnpInfo->busNum;
497     }
498 
499     infoTable->deviceInfo.vendorId = g_testUsbPnpInfo->deviceInfo.vendorId;
500     infoTable->deviceInfo.productId = g_testUsbPnpInfo->deviceInfo.productId;
501     infoTable->deviceInfo.bcdDeviceLow = g_testUsbPnpInfo->deviceInfo.bcdDeviceLow;
502     infoTable->deviceInfo.bcdDeviceHigh = g_testUsbPnpInfo->deviceInfo.bcdDeviceHigh;
503     infoTable->deviceInfo.deviceClass = g_testUsbPnpInfo->deviceInfo.deviceClass;
504     infoTable->deviceInfo.deviceSubClass = g_testUsbPnpInfo->deviceInfo.deviceSubClass;
505     infoTable->deviceInfo.deviceProtocol = g_testUsbPnpInfo->deviceInfo.deviceProtocol;
506 
507     infoTable->removeType = g_usbPnpNotifyRemoveType;
508 
509     if (g_usbPnpNotifyCmdType != USB_PNP_NOTIFY_REMOVE_TEST) {
510         infoTable->numInfos = g_testUsbPnpInfo->numInfos;
511         for (i = 0; i < infoTable->numInfos; i++) {
512             infoTable->interfaceInfo[i].interfaceClass = g_testUsbPnpInfo->interfaceInfo[i].interfaceClass;
513             infoTable->interfaceInfo[i].interfaceSubClass = g_testUsbPnpInfo->interfaceInfo[i].interfaceSubClass;
514             infoTable->interfaceInfo[i].interfaceProtocol = g_testUsbPnpInfo->interfaceInfo[i].interfaceProtocol;
515             infoTable->interfaceInfo[i].interfaceNumber = g_testUsbPnpInfo->interfaceInfo[i].interfaceNumber;
516         }
517     }
518 }
519 
TestPnpNotifyHdfSendEvent(const struct HdfDeviceObject * deviceObject)520 static int32_t TestPnpNotifyHdfSendEvent(const struct HdfDeviceObject *deviceObject)
521 {
522     int32_t ret;
523     struct UsbPnpNotifyMatchInfoTable infoTable;
524     struct HdfSBuf *data = NULL;
525 
526     if ((deviceObject == NULL) || (g_testUsbPnpInfo == NULL)) {
527         HDF_LOGE("%s deviceObject=%px or g_testUsbPnpInfo=%px is NULL", __func__, deviceObject, g_testUsbPnpInfo);
528         return HDF_ERR_INVALID_PARAM;
529     }
530 
531     data = HdfSbufObtainDefaultSize();
532     if (data == NULL) {
533         HDF_LOGE("%s InitDataBlock failed", __func__);
534         return HDF_FAILURE;
535     }
536 
537     TestPnpNotifyFillInfoTable(&infoTable);
538 
539     if (!HdfSbufWriteBuffer(data, (const void *)(&infoTable), sizeof(struct UsbPnpNotifyMatchInfoTable))) {
540         HDF_LOGE("%s: sbuf write infoTable failed", __func__);
541         goto OUT;
542     }
543 
544     HDF_LOGI("%s: report one device information, %d usbDev=%llu, devNum=%d, busNum=%d, infoTable=%d-0x%x-0x%x!", \
545         __func__, g_usbPnpNotifyCmdType, infoTable.usbDevAddr, infoTable.devNum, infoTable.busNum, \
546         infoTable.numInfos, infoTable.deviceInfo.vendorId, infoTable.deviceInfo.productId);
547 
548     ret = UsbPnpNotifySendEventLoader(data);
549     if (ret != HDF_SUCCESS) {
550         HDF_LOGE("%s: UsbPnpNotifySendEventLoader error=%d", __func__, ret);
551         goto OUT;
552     }
553 
554     HdfSbufRecycle(data);
555     return ret;
556 
557 OUT:
558     HdfSbufRecycle(data);
559     return HDF_FAILURE;
560 }
561 #endif
562 
UsbPnpNotifyFirstReportDevice(struct HdfDeviceIoClient * client)563 static int32_t UsbPnpNotifyFirstReportDevice(struct HdfDeviceIoClient *client)
564 {
565     struct UsbPnpNotifyDeviceList *pnpNotifyDevicePos = NULL;
566     struct UsbPnpNotifyDeviceList *pnpNotifyDeviceTemp = NULL;
567 
568     dprintf("%s:%d Enter!\n", __func__, __LINE__);
569 
570     if (DListIsEmpty(&g_usbPnpDeviceListHead)) {
571         dprintf("%s:%d device list is empty\n", __func__, __LINE__);
572         return HDF_SUCCESS;
573     }
574 
575     OsalMutexLock(&g_usbPnpNotifyDevicelistLock);
576     DLIST_FOR_EACH_ENTRY_SAFE(pnpNotifyDevicePos, pnpNotifyDeviceTemp, &g_usbPnpDeviceListHead,
577         struct UsbPnpNotifyDeviceList, deviceList) {
578         UsbPnpNotifyHdfSendEvent(client->device, pnpNotifyDevicePos->device);
579     }
580     OsalMutexUnlock(&g_usbPnpNotifyDevicelistLock);
581 
582     dprintf("%s:%d report all device information!", __func__, __LINE__);
583 
584     return HDF_SUCCESS;
585 }
586 
UsbPnpNotifyReportThread(void * arg)587 static int32_t UsbPnpNotifyReportThread(void* arg)
588 {
589     int32_t ret;
590     struct HdfDeviceObject *deviceObject = (struct HdfDeviceObject *)arg;
591 
592     while (g_usbPnpThreadRunningFlag) {
593 #if USB_PNP_NOTIFY_TEST_MODE == false
594         ret = wait_event_interruptible(g_usbPnpNotifyReportWait, g_usbDevice != NULL);
595 #else
596         ret = wait_event_interruptible(g_usbPnpNotifyReportWait,
597             ((g_usbDevice != NULL) || (g_testUsbPnpInfo != NULL)));
598 #endif
599         if (!ret) {
600             HDF_LOGI("%s: UsbPnpNotifyReportThread start!", __func__);
601         }
602 
603         OsalMutexLock(&g_usbSendEventLock);
604 #if USB_PNP_NOTIFY_TEST_MODE == true
605         if ((g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_ADD_TEST) || \
606             (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_TEST)) {
607             ret = TestPnpNotifyHdfSendEvent(deviceObject);
608         } else {
609 #endif
610             if ((g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_ADD_INTERFACE)
611                 || (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_INTERFACE)) {
612                 OsalMSleep(USB_PNP_INTERFACE_MSLEEP_TIME);
613                 ret = UsbPnpNotifyHdfSendEvent(deviceObject, &g_usbPnpInfo);
614             } else {
615                 ret = UsbPnpNotifyHdfSendEvent(deviceObject, g_usbDevice);
616             }
617 #if USB_PNP_NOTIFY_TEST_MODE == true
618         }
619 #endif
620         if (ret != HDF_SUCCESS) {
621             HDF_LOGI("%s: UsbPnpNotifyHdfSendEvent error=%d!", __func__, ret);
622         }
623 
624         g_usbDevice = NULL;
625 #if USB_PNP_NOTIFY_TEST_MODE == true
626         g_testUsbPnpInfo = NULL;
627 #endif
628         OsalMutexUnlock(&g_usbSendEventLock);
629 
630         OsalMSleep(USB_PNP_NOTIFY_MSLEEP_TIME);
631     }
632 
633     HDF_LOGI("%s: usb pnp notify handle kthread exiting!", __func__);
634 
635     return 0;
636 }
637 
UsbPnpNotifyCreateDeviceList(struct usb_device * udev)638 static void UsbPnpNotifyCreateDeviceList(struct usb_device *udev)
639 {
640     struct UsbPnpNotifyDeviceList *deviceListTemp = NULL;
641 
642     deviceListTemp = (struct UsbPnpNotifyDeviceList *)OsalMemCalloc(sizeof(struct UsbPnpNotifyDeviceList));
643     if (deviceListTemp == NULL) {
644         HDF_LOGE("%s:%d deviceListTemp is NULL!", __func__, __LINE__);
645         return;
646     }
647 
648     deviceListTemp->device = udev;
649     DListHeadInit(&deviceListTemp->deviceList);
650 
651     OsalMutexLock(&g_usbPnpNotifyDevicelistLock);
652     DListInsertTail(&deviceListTemp->deviceList, &g_usbPnpDeviceListHead);
653     OsalMutexUnlock(&g_usbPnpNotifyDevicelistLock);
654 }
655 
UsbPnpNotifyAddDevice(struct usb_device * udev)656 static void UsbPnpNotifyAddDevice(struct usb_device *udev)
657 {
658     int32_t ret;
659     struct UsbPnpDeviceInfo *deviceInfo = NULL;
660     union UsbPnpDeviceInfoData pnpInfoData;
661 
662     pnpInfoData.usbDev = udev;
663     deviceInfo = UsbPnpNotifyCreateInfo();
664     if (deviceInfo == NULL) {
665         DPRINTFN(0, "%s:%d USB_DEVICE_ADD create info failed\n", __func__, __LINE__);
666     } else {
667         ret = UsbPnpNotifyAddInitInfo(deviceInfo, pnpInfoData);
668         if (ret != HDF_SUCCESS) {
669             PRINTK("%s:%d USB_DEVICE_ADD UsbPnpNotifyAddInitInfo error\n", __func__, __LINE__);
670         } else {
671             OsalMutexLock(&g_usbSendEventLock);
672             g_usbDevice = udev;
673             g_usbPnpNotifyCmdType = USB_PNP_NOTIFY_ADD_DEVICE;
674             OsalMutexUnlock(&g_usbSendEventLock);
675             wake_up_interruptible(&g_usbPnpNotifyReportWait);
676         }
677     }
678 }
679 
UsbPnpNotifyAttachDevice(struct usb_device * udev)680 static void UsbPnpNotifyAttachDevice(struct usb_device *udev)
681 {
682     int32_t error;
683     static int32_t listLockInit = 0;
684 
685     if ((udev->ddesc.bDeviceClass == UICLASS_HUB) || UsbPnpNotifyFindDeviceList(udev, false) == true) {
686         PRINTK("%s:%d findDeviceList is true!\n", __func__, __LINE__);
687         return;
688     }
689 
690     if (0 == listLockInit) {
691         error = OsalMutexInit(&g_usbPnpNotifyDevicelistLock);
692         if (error != HDF_SUCCESS) {
693             HDF_LOGE("%s:%d error=%d!", __func__, __LINE__, error);
694             return;
695         }
696         listLockInit = 1;
697     }
698 
699     error = usb_create_usb_device(udev);
700     if (error != HDF_SUCCESS) {
701         PRINTK("%s:%d usb_create_usb_device error\n", __func__, __LINE__);
702         return;
703     }
704 
705     UsbPnpNotifyCreateDeviceList(udev);
706     UsbPnpNotifyAddDevice(udev);
707 
708     return;
709 }
710 
UsbPnpNotifyDetachDevice(struct usb_device * udev)711 static void UsbPnpNotifyDetachDevice(struct usb_device *udev)
712 {
713     struct UsbInfoQueryPara infoQueryPara;
714     struct UsbPnpDeviceInfo *deviceInfo = NULL;
715 
716     if (UsbPnpNotifyFindDeviceList(udev, true) == true) {
717         infoQueryPara.type = USB_INFO_DEVICE_ADDRESS_TYPE;
718         infoQueryPara.usbDevAddr = (uint64_t)udev;
719         deviceInfo = UsbPnpNotifyFindInfo(infoQueryPara);
720         if (deviceInfo == NULL) {
721             PRINTK("%s:%d USB_DEVICE_REMOVE find info failed", __func__, __LINE__);
722         } else {
723             OsalMutexLock(&deviceInfo->lock);
724             if (deviceInfo->status != USB_PNP_DEVICE_INIT_STATUS) {
725                 deviceInfo->status = USB_PNP_DEVICE_INIT_STATUS;
726             } else {
727                 deviceInfo->status = USB_PNP_DEVICE_REMOVE_STATUS;
728             }
729             OsalMutexUnlock(&deviceInfo->lock);
730             OsalMutexLock(&g_usbSendEventLock);
731             g_usbDevice = udev;
732             g_usbPnpNotifyCmdType = USB_PNP_NOTIFY_REMOVE_DEVICE;
733             g_usbPnpNotifyRemoveType = USB_PNP_NOTIFY_REMOVE_BUS_DEV_NUM;
734             OsalMutexUnlock(&g_usbSendEventLock);
735             wake_up_interruptible(&g_usbPnpNotifyReportWait);
736         }
737     }
738 }
739 
UsbPnpNotifyDevice(const char * type,struct usb_device * udev)740 void UsbPnpNotifyDevice(const char *type, struct usb_device *udev)
741 {
742     if (strcmp(type, "ATTACH") == 0) {
743         UsbPnpNotifyAttachDevice(udev);
744     } else if (strcmp(type, "DETACH") == 0) {
745         UsbPnpNotifyDetachDevice(udev);
746     } else {
747         PRINTK("%s:%d type=%s is not define!\n", __func__, __LINE__, type);
748     }
749 }
750 
UsbPnpNotifyGetUsbDevice(struct UsbGetDevicePara paraData)751 struct usb_device *UsbPnpNotifyGetUsbDevice(struct UsbGetDevicePara paraData)
752 {
753     bool findFlag = false;
754     struct usb_device *usbPnpDevice = NULL;
755     struct UsbPnpNotifyDeviceList *pnpNotifyDevicePos = NULL;
756 
757     OsalMutexLock(&g_usbPnpNotifyDevicelistLock);
758     DLIST_FOR_EACH_ENTRY(pnpNotifyDevicePos, &g_usbPnpDeviceListHead,
759         struct UsbPnpNotifyDeviceList, deviceList) {
760         switch (paraData.type) {
761             case USB_PNP_DEVICE_ADDRESS_TYPE:
762                 if ((pnpNotifyDevicePos->device->address == paraData.devNum)
763                     && (pnpNotifyDevicePos->device->port_no == paraData.busNum)) {
764                     findFlag = true;
765                 }
766                 break;
767             case USB_PNP_DEVICE_VENDOR_PRODUCT_TYPE:
768                 if ((UGETW(pnpNotifyDevicePos->device->ddesc.idVendor) == paraData.vendorId)
769                     && (UGETW(pnpNotifyDevicePos->device->ddesc.idProduct) == paraData.productId)) {
770                     findFlag = true;
771                 }
772                 break;
773             default:
774                 findFlag = false;
775                 break;
776         }
777 
778         if (findFlag == true) {
779             usbPnpDevice = pnpNotifyDevicePos->device;
780             break;
781         }
782     }
783     OsalMutexUnlock(&g_usbPnpNotifyDevicelistLock);
784 
785     return usbPnpDevice;
786 }
787 
UsbPnpNotifyReadPnpInfo(struct HdfSBuf * data)788 static void UsbPnpNotifyReadPnpInfo(struct HdfSBuf *data)
789 {
790     struct UsbInfoQueryPara infoQueryPara;
791     struct UsbPnpDeviceInfo *deviceInfo = NULL;
792     struct UsbPnpAddRemoveInfo *usbPnpInfo = NULL;
793     uint32_t infoSize;
794     bool flag;
795 
796     flag = HdfSbufReadBuffer(data, (const void **)(&usbPnpInfo), &infoSize);
797     if ((flag == false) || (usbPnpInfo == NULL)) {
798         HDF_LOGE("%s:%d fail to read g_usbPnpInfo, flag=%d", __func__, __LINE__, flag);
799         return;
800     }
801 
802     g_usbPnpInfo.devNum = usbPnpInfo->devNum;
803     g_usbPnpInfo.busNum = usbPnpInfo->busNum;
804     g_usbPnpInfo.interfaceNumber = usbPnpInfo->interfaceNumber;
805     g_usbPnpInfo.interfaceClass = usbPnpInfo->interfaceClass;
806     g_usbPnpInfo.interfaceSubClass = usbPnpInfo->interfaceSubClass;
807     g_usbPnpInfo.interfaceProtocol = usbPnpInfo->interfaceProtocol;
808 
809     g_usbDevice = (struct usb_device *)&g_usbPnpInfo;
810 
811     infoQueryPara.type = USB_INFO_NORMAL_TYPE;
812     infoQueryPara.devNum = usbPnpInfo->devNum;
813     infoQueryPara.busNum = usbPnpInfo->busNum;
814     deviceInfo = UsbPnpNotifyFindInfo(infoQueryPara);
815     if (deviceInfo == NULL) {
816         HDF_LOGE("%s:%d add or remove interface find info failed", __func__, __LINE__);
817     } else {
818         OsalMutexLock(&deviceInfo->lock);
819         if (deviceInfo->status != USB_PNP_DEVICE_INIT_STATUS) {
820             deviceInfo->status = USB_PNP_DEVICE_INIT_STATUS;
821         } else {
822             deviceInfo->status = USB_PNP_DEVICE_INTERFACE_STATUS;
823         }
824         OsalMutexUnlock(&deviceInfo->lock);
825     }
826 
827     HDF_LOGI("%s:%d infoSize=%d g_usbPnpInfo=%d-%d-%d-%d-%d-%d read success!",
828         __func__, __LINE__, infoSize, g_usbPnpInfo.devNum, g_usbPnpInfo.busNum,
829         g_usbPnpInfo.interfaceNumber, g_usbPnpInfo.interfaceClass, g_usbPnpInfo.interfaceSubClass,
830         g_usbPnpInfo.interfaceProtocol);
831 }
832 
UsbPnpNotifyDriverRegisterDevice(struct HdfDeviceObject * device,struct HdfSBuf * data)833 static int32_t UsbPnpNotifyDriverRegisterDevice(struct HdfDeviceObject *device, struct HdfSBuf *data)
834 {
835     if (data == NULL) {
836         return HDF_FAILURE;
837     }
838 
839     const char *moduleName = HdfSbufReadString(data);
840     if (moduleName == NULL) {
841         return HDF_FAILURE;
842     }
843     const char *serviceName = HdfSbufReadString(data);
844     if (serviceName == NULL) {
845         return HDF_FAILURE;
846     }
847 
848     int32_t ret;
849     struct HdfDeviceObject *devObj = HdfDeviceObjectAlloc(device, moduleName);
850     if (devObj == NULL) {
851         HDF_LOGE("%s: failed to alloc device object", __func__);
852         return HDF_DEV_ERR_NO_MEMORY;
853     }
854 
855     ret = HdfDeviceObjectRegister(devObj);
856     if (ret != HDF_SUCCESS) {
857         HDF_LOGE("%s: failed to regitst device %s", __func__, moduleName);
858         HdfDeviceObjectRelease(devObj);
859         return ret;
860     }
861 
862     ret = HdfDeviceObjectPublishService(devObj, serviceName, SERVICE_POLICY_CAPACITY,
863         OSAL_S_IREAD | OSAL_S_IWRITE | OSAL_S_IRGRP | OSAL_S_IWGRP | OSAL_S_IROTH);
864     if (ret != HDF_SUCCESS) {
865         HDF_LOGE("%s: failed to regitst device %s", __func__, serviceName);
866         HdfDeviceObjectRelease(devObj);
867     }
868 
869     return ret;
870 }
871 
UsbPnpNotifyDriverUnregisterDevice(struct HdfSBuf * data)872 static int32_t UsbPnpNotifyDriverUnregisterDevice(struct HdfSBuf *data)
873 {
874     if (data == NULL) {
875         return HDF_FAILURE;
876     }
877 
878     const char *moduleName = HdfSbufReadString(data);
879     if (moduleName == NULL) {
880         return HDF_FAILURE;
881     }
882     const char *serviceName = HdfSbufReadString(data);
883     if (serviceName == NULL) {
884         return HDF_FAILURE;
885     }
886 
887     struct HdfDeviceObject *devObj = DevSvcManagerClntGetDeviceObject(serviceName);
888     if (devObj == NULL) {
889         return HDF_DEV_ERR_NO_DEVICE;
890     }
891     HdfDeviceObjectRelease(devObj);
892     return HDF_SUCCESS;
893 }
894 
UsbPnpNotifyDispatch(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)895 static int32_t UsbPnpNotifyDispatch(struct HdfDeviceIoClient *client, int32_t cmd,
896     struct HdfSBuf *data, struct HdfSBuf *reply)
897 {
898     int32_t ret = HDF_SUCCESS;
899 
900     if (reply == NULL || client == NULL) {
901         HDF_LOGE("%s:%d reply or client is NULL, cmd = %d", __func__, __LINE__, cmd);
902         return HDF_FAILURE;
903     }
904 
905     dprintf("%s:%d dispatch success, cmd = %d\n", __func__, __LINE__, cmd);
906 
907     OsalMutexLock(&g_usbSendEventLock);
908     g_usbPnpNotifyCmdType = cmd;
909 
910     switch (cmd) {
911         case USB_PNP_NOTIFY_ADD_INTERFACE:
912             UsbPnpNotifyReadPnpInfo(data);
913             wake_up_interruptible(&g_usbPnpNotifyReportWait);
914             break;
915         case USB_PNP_NOTIFY_REMOVE_INTERFACE:
916             UsbPnpNotifyReadPnpInfo(data);
917             g_usbPnpNotifyRemoveType = USB_PNP_NOTIFY_REMOVE_INTERFACE_NUM;
918             wake_up_interruptible(&g_usbPnpNotifyReportWait);
919             break;
920         case USB_PNP_NOTIFY_REPORT_INTERFACE:
921             UsbPnpNotifyFirstReportDevice(client);
922             break;
923 #if USB_PNP_NOTIFY_TEST_MODE == true
924         case USB_PNP_NOTIFY_ADD_TEST:
925             TestReadPnpInfo(data);
926             wake_up_interruptible(&g_usbPnpNotifyReportWait);
927             break;
928         case USB_PNP_NOTIFY_REMOVE_TEST:
929             TestReadPnpInfo(data);
930             g_usbPnpNotifyRemoveType = g_testUsbPnpInfo->removeType;
931             wake_up_interruptible(&g_usbPnpNotifyReportWait);
932             break;
933 #endif
934         case USB_PNP_DRIVER_REGISTER_DEVICE:
935             ret = UsbPnpNotifyDriverRegisterDevice(client->device, data);
936             break;
937         case USB_PNP_DRIVER_UNREGISTER_DEVICE:
938             ret = UsbPnpNotifyDriverUnregisterDevice(data);
939             break;
940         default:
941             ret = HDF_ERR_NOT_SUPPORT;
942             break;
943     }
944     OsalMutexUnlock(&g_usbSendEventLock);
945 
946     if (!HdfSbufWriteInt32(reply, INT32_MAX)) {
947         dprintf("%s: reply int32 fail\n", __func__);
948     }
949 
950     return ret;
951 }
952 
UsbPnpNotifyBind(struct HdfDeviceObject * device)953 static int32_t UsbPnpNotifyBind(struct HdfDeviceObject *device)
954 {
955     static struct IDeviceIoService pnpNotifyService = {
956         .Dispatch = UsbPnpNotifyDispatch,
957     };
958 
959     dprintf("%s:%d enter!\n", __func__, __LINE__);
960 
961     if (device == NULL) {
962         HDF_LOGE("%s: device is NULL!", __func__);
963         return HDF_ERR_INVALID_OBJECT;
964     }
965 
966     device->service = &pnpNotifyService;
967     dprintf("%s:%d bind success\n", __func__, __LINE__);
968 
969     return HDF_SUCCESS;
970 }
971 
UsbPnpNotifyInit(struct HdfDeviceObject * device)972 static int32_t UsbPnpNotifyInit(struct HdfDeviceObject *device)
973 {
974     static bool firstInitFlag = true;
975     int32_t ret;
976     struct OsalThreadParam threadCfg;
977 
978     dprintf("%s:%d enter!\n", __func__, __LINE__);
979 
980     if (device == NULL) {
981         HDF_LOGE("%s: device is NULL", __func__);
982         return HDF_ERR_INVALID_OBJECT;
983     }
984 
985     if (firstInitFlag == true) {
986         firstInitFlag = false;
987 
988         DListHeadInit(&g_usbPnpInfoListHead);
989         DListHeadInit(&g_usbPnpDeviceListHead);
990     }
991 
992     init_waitqueue_head(&g_usbPnpNotifyReportWait);
993 
994     OsalMutexInit(&g_usbSendEventLock);
995 
996     /* Creat thread to handle send usb interface information. */
997     ret = memset_s(&threadCfg, sizeof(threadCfg), 0, sizeof(threadCfg));
998     if (ret != HDF_SUCCESS) {
999         HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
1000         return ret;
1001     }
1002 
1003     g_usbPnpThreadRunningFlag = true;
1004     threadCfg.name = "LiteOS usb pnp notify handle kthread";
1005     threadCfg.priority = OSAL_THREAD_PRI_HIGH;
1006     threadCfg.stackSize = USB_PNP_NOTIFY_REPORT_STACK_SIZE;
1007 
1008     ret = OsalThreadCreate(&g_usbPnpNotifyReportThread, (OsalThreadEntry)UsbPnpNotifyReportThread, (void *)device);
1009     if (HDF_SUCCESS != ret) {
1010         HDF_LOGE("%s:%d OsalThreadCreate faile, ret=%d ", __func__, __LINE__, ret);
1011         return ret;
1012     }
1013 
1014     ret = OsalThreadStart(&g_usbPnpNotifyReportThread, &threadCfg);
1015     if (HDF_SUCCESS != ret) {
1016         HDF_LOGE("%s:%d OsalThreadStart faile, ret=%d ", __func__, __LINE__, ret);
1017         return ret;
1018     }
1019 
1020     dprintf("%s:%d Init success\n", __func__, __LINE__);
1021 
1022     return HDF_SUCCESS;
1023 }
1024 
UsbPnpNotifyRelease(struct HdfDeviceObject * device)1025 static void UsbPnpNotifyRelease(struct HdfDeviceObject *device)
1026 {
1027     HDF_STATUS ret;
1028 
1029     if (device == NULL) {
1030         HDF_LOGI("%s: device is null", __func__);
1031         return;
1032     }
1033 
1034     g_usbPnpThreadRunningFlag = false;
1035 
1036     ret = OsalThreadDestroy(&g_usbPnpNotifyReportThread);
1037     if (HDF_SUCCESS != ret) {
1038         HDF_LOGE("%s:%d OsalThreadDestroy faile, ret=%d ", __func__, __LINE__, ret);
1039         return;
1040     }
1041 
1042     OsalMutexDestroy(&g_usbSendEventLock);
1043 
1044     dprintf("%s:%d release success\n", __func__, __LINE__);
1045 
1046     return;
1047 }
1048 
1049 struct HdfDriverEntry g_usbPnpNotifyEntry = {
1050     .moduleVersion = 1,
1051     .Bind = UsbPnpNotifyBind,
1052     .Init = UsbPnpNotifyInit,
1053     .Release = UsbPnpNotifyRelease,
1054     .moduleName = "HDF_USB_PNP_NOTIFY",
1055 };
1056 
1057 HDF_INIT(g_usbPnpNotifyEntry);
1058