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