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