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