• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * usb_pnp_notify.c
3  *
4  * usb pnp notify adapter of linux
5  *
6  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
7  *
8  * This software is licensed under the terms of the GNU General Public
9  * License version 2, as published by the Free Software Foundation, and
10  * may be copied, distributed, and modified under those terms.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  */
18 
19 #include "usb_pnp_notify.h"
20 #include <linux/delay.h>
21 #include <linux/kthread.h>
22 #include <linux/notifier.h>
23 #include <linux/usb.h>
24 #include "hdf_device_desc.h"
25 #include "hdf_log.h"
26 #include "osal_mem.h"
27 #include "securec.h"
28 
29 #define HDF_LOG_TAG USB_PNP_NOTIFY
30 #ifndef USB_GADGET_ADD
31 #define USB_GADGET_ADD 0x0005
32 #endif
33 #ifndef USB_GADGET_REMOVE
34 #define USB_GADGET_REMOVE 0x0006
35 #endif
36 
37 static wait_queue_head_t g_usbPnpNotifyReportWait;
38 static wait_queue_head_t g_gadgetPnpNotifyReportWait;
39 static struct task_struct *g_usbPnpNotifyReportThread = NULL;
40 static struct task_struct *g_gadgetPnpNotifyReportThread = NULL;
41 static enum UsbPnpNotifyServiceCmd g_usbPnpNotifyCmdType = USB_PNP_NOTIFY_ADD_INTERFACE;
42 static enum UsbPnpNotifyRemoveType g_usbPnpNotifyRemoveType = USB_PNP_NOTIFY_REMOVE_BUS_DEV_NUM;
43 static uint8_t g_gadgetPnpNotifyType = 0;
44 static unsigned long g_preAcion = 0;
45 struct OsalMutex g_usbSendEventLock;
46 struct OsalMutex g_gadgetSendEventLock;
47 struct usb_device *g_usbDevice = NULL;
48 struct UsbPnpAddRemoveInfo g_usbPnpInfo;
49 struct DListHead g_usbPnpInfoListHead;
50 #if USB_PNP_NOTIFY_TEST_MODE == true
51 struct UsbPnpNotifyMatchInfoTable *g_testUsbPnpInfo = NULL;
52 #endif
53 
UsbPnpNotifyCreateInfo(void)54 static struct UsbPnpDeviceInfo *UsbPnpNotifyCreateInfo(void)
55 {
56     struct UsbPnpDeviceInfo *infoTemp = NULL;
57     unsigned char *ptr = NULL;
58     static int32_t idNum = 0;
59     int32_t ret;
60 
61     ptr = OsalMemCalloc(sizeof(struct UsbPnpDeviceInfo));
62     if (ptr == NULL) {
63         HDF_LOGE("%s:%d OsalMemAlloc faile ", __func__, __LINE__);
64         return NULL;
65     }
66     infoTemp = (struct UsbPnpDeviceInfo *)ptr;
67 
68     if (idNum++ >= INT32_MAX) {
69         idNum = 0;
70     }
71     infoTemp->id = idNum;
72     OsalMutexInit(&infoTemp->lock);
73     infoTemp->status = USB_PNP_DEVICE_INIT_STATUS;
74     DListHeadInit(&infoTemp->list);
75     ret = memset_s(infoTemp->interfaceRemoveStatus, USB_PNP_INFO_MAX_INTERFACES, 0, sizeof(infoTemp->interfaceRemoveStatus));
76     if (ret != HDF_SUCCESS) {
77         HDF_LOGE("%{public}s:%{public}d memset_s failed", __func__, __LINE__);
78         OsalMemFree(ptr);
79         return NULL;
80     }
81 
82     DListInsertTail(&infoTemp->list, &g_usbPnpInfoListHead);
83     return infoTemp;
84 }
85 
UsbPnpNotifyFindInfo(struct UsbInfoQueryPara queryPara)86 static struct UsbPnpDeviceInfo *UsbPnpNotifyFindInfo(struct UsbInfoQueryPara queryPara)
87 {
88     struct UsbPnpDeviceInfo *infoPos = NULL;
89     struct UsbPnpDeviceInfo *infoTemp = NULL;
90     bool findFlag = false;
91 
92     if (DListIsEmpty(&g_usbPnpInfoListHead)) {
93         HDF_LOGE("%s:%d usb pnp list head is empty. ", __func__, __LINE__);
94         return NULL;
95     }
96 
97     DLIST_FOR_EACH_ENTRY_SAFE(infoPos, infoTemp, &g_usbPnpInfoListHead, struct UsbPnpDeviceInfo, list) {
98         switch (queryPara.type) {
99             case USB_INFO_NORMAL_TYPE:
100                 if ((infoPos->info.devNum == queryPara.devNum) && (infoPos->info.busNum == queryPara.busNum)) {
101                     findFlag = true;
102                 }
103                 break;
104             case USB_INFO_ID_TYPE:
105                 if (infoPos->id == queryPara.id) {
106                     findFlag = true;
107                 }
108                 break;
109             case USB_INFO_DEVICE_ADDRESS_TYPE:
110                 if (infoPos->info.usbDevAddr == queryPara.usbDevAddr) {
111                     findFlag = true;
112                 }
113                 break;
114             default:
115                 break;
116         }
117 
118         if (findFlag == true) {
119             break;
120         }
121     }
122 
123     if (findFlag == false) {
124         HDF_LOGE("%s:%d the usb pnp info to be find does not exist. ", __func__, __LINE__);
125         return NULL;
126     } else {
127         return infoPos;
128     }
129 }
130 
UsbPnpNotifyDestroyInfo(struct UsbPnpDeviceInfo * deviceInfo)131 static HDF_STATUS UsbPnpNotifyDestroyInfo(struct UsbPnpDeviceInfo *deviceInfo)
132 {
133     HDF_STATUS ret = HDF_SUCCESS;
134     struct UsbPnpDeviceInfo *infoPos = NULL;
135     struct UsbPnpDeviceInfo *infoTemp = NULL;
136     bool findFlag = false;
137 
138     if (deviceInfo == NULL) {
139         ret = HDF_FAILURE;
140         HDF_LOGE("%s:%d the deviceInfo is NULL, ret=%d ", __func__, __LINE__, ret);
141         return ret;
142     }
143 
144     if (DListIsEmpty(&g_usbPnpInfoListHead)) {
145         HDF_LOGI("%s:%d the g_usbPnpInfoListHead is empty.", __func__, __LINE__);
146         return HDF_SUCCESS;
147     }
148 
149     DLIST_FOR_EACH_ENTRY_SAFE(infoPos, infoTemp, &g_usbPnpInfoListHead, struct UsbPnpDeviceInfo, list) {
150         if (infoPos->id == deviceInfo->id) {
151             findFlag = true;
152             DListRemove(&infoPos->list);
153             OsalMemFree((void *)infoPos);
154             infoPos = NULL;
155             break;
156         }
157     }
158 
159     if (findFlag == false) {
160         ret = HDF_FAILURE;
161         HDF_LOGE("%s:%d the deviceInfoto be destroyed does not exist, ret=%d ", __func__, __LINE__, ret);
162     }
163 
164     return ret;
165 }
166 
UsbPnpNotifyAddInitInfo(struct UsbPnpDeviceInfo * deviceInfo,union UsbPnpDeviceInfoData infoData)167 static int32_t UsbPnpNotifyAddInitInfo(struct UsbPnpDeviceInfo *deviceInfo, union UsbPnpDeviceInfoData infoData)
168 {
169     int32_t ret = HDF_SUCCESS;
170     uint8_t i;
171 
172     deviceInfo->info.usbDevAddr = (uint64_t)infoData.usbDev;
173     deviceInfo->info.devNum = infoData.usbDev->devnum;
174     if (infoData.usbDev->bus == NULL) {
175         HDF_LOGE("%s infoData.usbDev->bus=%px is NULL", __func__, infoData.usbDev->bus);
176         ret = HDF_ERR_INVALID_PARAM;
177         goto OUT;
178     }
179     deviceInfo->info.busNum = infoData.usbDev->bus->busnum;
180 
181     deviceInfo->info.deviceInfo.vendorId = le16_to_cpu(infoData.usbDev->descriptor.idVendor);
182     deviceInfo->info.deviceInfo.productId = le16_to_cpu(infoData.usbDev->descriptor.idProduct);
183     deviceInfo->info.deviceInfo.bcdDeviceLow = le16_to_cpu(infoData.usbDev->descriptor.bcdDevice);
184     deviceInfo->info.deviceInfo.bcdDeviceHigh = le16_to_cpu(infoData.usbDev->descriptor.bcdDevice);
185     deviceInfo->info.deviceInfo.deviceClass = infoData.usbDev->descriptor.bDeviceClass;
186     deviceInfo->info.deviceInfo.deviceSubClass = infoData.usbDev->descriptor.bDeviceSubClass;
187     deviceInfo->info.deviceInfo.deviceProtocol = infoData.usbDev->descriptor.bDeviceProtocol;
188 
189     if (infoData.usbDev->actconfig == NULL) {
190         HDF_LOGE("%s infoData.usbDev->actconfig=%p is NULL", __func__, infoData.usbDev->actconfig);
191         ret = HDF_ERR_INVALID_PARAM;
192         goto OUT;
193     }
194     deviceInfo->info.numInfos = infoData.usbDev->actconfig->desc.bNumInterfaces;
195     for (i = 0; i < deviceInfo->info.numInfos; i++) {
196         if ((infoData.usbDev->actconfig->interface[i] == NULL) ||
197             (infoData.usbDev->actconfig->interface[i]->cur_altsetting == NULL)) {
198             HDF_LOGE("%{public}s interface[%{public}d] or interface[%{public}d]->cur_altsetting is NULL",
199                 __func__, i, i);
200             ret = HDF_ERR_INVALID_PARAM;
201             goto OUT;
202         }
203         deviceInfo->info.interfaceInfo[i].interfaceClass =
204         infoData.usbDev->actconfig->interface[i]->cur_altsetting->desc.bInterfaceClass;
205         deviceInfo->info.interfaceInfo[i].interfaceSubClass =
206         infoData.usbDev->actconfig->interface[i]->cur_altsetting->desc.bInterfaceSubClass;
207         deviceInfo->info.interfaceInfo[i].interfaceProtocol =
208         infoData.usbDev->actconfig->interface[i]->cur_altsetting->desc.bInterfaceProtocol;
209         deviceInfo->info.interfaceInfo[i].interfaceNumber =
210         infoData.usbDev->actconfig->interface[i]->cur_altsetting->desc.bInterfaceNumber;
211 
212         HDF_LOGI("%s:%d i=%d, interfaceInfo=0x%x-0x%x-0x%x-0x%x",
213             __func__, __LINE__, i, deviceInfo->info.interfaceInfo[i].interfaceClass,
214             deviceInfo->info.interfaceInfo[i].interfaceSubClass,
215             deviceInfo->info.interfaceInfo[i].interfaceProtocol,
216             deviceInfo->info.interfaceInfo[i].interfaceNumber);
217     }
218 
219 OUT:
220     return ret;
221 }
222 
UsbPnpNotifyAddInterfaceInitInfo(struct UsbPnpDeviceInfo * deviceInfo,union UsbPnpDeviceInfoData infoData,struct UsbPnpNotifyMatchInfoTable * infoTable)223 static void UsbPnpNotifyAddInterfaceInitInfo(struct UsbPnpDeviceInfo *deviceInfo,
224     union UsbPnpDeviceInfoData infoData, struct UsbPnpNotifyMatchInfoTable *infoTable)
225 {
226     uint8_t i;
227     uint8_t j;
228 
229     for (i = 0; i < deviceInfo->info.numInfos; i++) {
230         if ((infoData.infoData->interfaceClass == deviceInfo->info.interfaceInfo[i].interfaceClass)
231             && (infoData.infoData->interfaceSubClass == deviceInfo->info.interfaceInfo[i].interfaceSubClass)
232             && (infoData.infoData->interfaceProtocol == deviceInfo->info.interfaceInfo[i].interfaceProtocol)
233             && (infoData.infoData->interfaceNumber == deviceInfo->info.interfaceInfo[i].interfaceNumber)) {
234             if (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_INTERFACE) {
235                 deviceInfo->interfaceRemoveStatus[i] = true;
236             } else if (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_ADD_INTERFACE) {
237                 deviceInfo->interfaceRemoveStatus[i] = false;
238             }
239         }
240     }
241 
242     if (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_INTERFACE) {
243         infoTable->numInfos = 1;
244         infoTable->interfaceInfo[0].interfaceClass = infoData.infoData->interfaceClass;
245         infoTable->interfaceInfo[0].interfaceSubClass = infoData.infoData->interfaceSubClass;
246         infoTable->interfaceInfo[0].interfaceProtocol = infoData.infoData->interfaceProtocol;
247         infoTable->interfaceInfo[0].interfaceNumber = infoData.infoData->interfaceNumber;
248     } else {
249         for (i = 0, j = 0; i < deviceInfo->info.numInfos; i++) {
250             if (deviceInfo->interfaceRemoveStatus[i] == true) {
251                 HDF_LOGI("%s:%d j=%d deviceInfo->interfaceRemoveStatus[%d] is true!", __func__, __LINE__, j, i);
252                 continue;
253             }
254             infoTable->interfaceInfo[j].interfaceClass = deviceInfo->info.interfaceInfo[i].interfaceClass;
255             infoTable->interfaceInfo[j].interfaceSubClass = deviceInfo->info.interfaceInfo[i].interfaceSubClass;
256             infoTable->interfaceInfo[j].interfaceProtocol = deviceInfo->info.interfaceInfo[i].interfaceProtocol;
257             infoTable->interfaceInfo[j].interfaceNumber = deviceInfo->info.interfaceInfo[i].interfaceNumber;
258             j++;
259 
260             HDF_LOGI("%s:%d i=%d, j=%d, interfaceInfo=0x%x-0x%x-0x%x-0x%x",
261                 __func__, __LINE__, i, j - 1, infoTable->interfaceInfo[j - 1].interfaceClass,
262                 infoTable->interfaceInfo[j - 1].interfaceSubClass,
263                 infoTable->interfaceInfo[j - 1].interfaceProtocol,
264                 infoTable->interfaceInfo[j - 1].interfaceNumber);
265         }
266         infoTable->numInfos = j;
267     }
268 }
269 
UsbPnpNotifyInitInfo(struct HdfSBuf * sbuf,struct UsbPnpDeviceInfo * deviceInfo,union UsbPnpDeviceInfoData infoData)270 static int32_t UsbPnpNotifyInitInfo(
271     struct HdfSBuf *sbuf, struct UsbPnpDeviceInfo *deviceInfo, union UsbPnpDeviceInfoData infoData)
272 {
273     int32_t ret = HDF_SUCCESS;
274     const void *data = NULL;
275 
276     if ((g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_ADD_INTERFACE)
277         || (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_INTERFACE)) {
278         static struct UsbPnpNotifyMatchInfoTable infoTable;
279 
280         infoTable.usbDevAddr = deviceInfo->info.usbDevAddr;
281         infoTable.devNum = deviceInfo->info.devNum;
282         infoTable.busNum = deviceInfo->info.busNum;
283         infoTable.deviceInfo.vendorId = deviceInfo->info.deviceInfo.vendorId;
284         infoTable.deviceInfo.productId = deviceInfo->info.deviceInfo.productId;
285         infoTable.deviceInfo.bcdDeviceLow = deviceInfo->info.deviceInfo.bcdDeviceLow;
286         infoTable.deviceInfo.bcdDeviceHigh = deviceInfo->info.deviceInfo.bcdDeviceHigh;
287         infoTable.deviceInfo.deviceClass = deviceInfo->info.deviceInfo.deviceClass;
288         infoTable.deviceInfo.deviceSubClass = deviceInfo->info.deviceInfo.deviceSubClass;
289         infoTable.deviceInfo.deviceProtocol = deviceInfo->info.deviceInfo.deviceProtocol;
290         infoTable.removeType = g_usbPnpNotifyRemoveType;
291 
292         UsbPnpNotifyAddInterfaceInitInfo(deviceInfo, infoData, &infoTable);
293 
294         data = (const void *)(&infoTable);
295     } else if (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REPORT_INTERFACE) {
296         ret = UsbPnpNotifyAddInitInfo(deviceInfo, infoData);
297         if (ret != HDF_SUCCESS) {
298             goto OUT;
299         }
300 
301         data = (const void *)(&deviceInfo->info);
302     } else {
303         data = (const void *)(&deviceInfo->info);
304     }
305 
306     if (!HdfSbufWriteBuffer(sbuf, data, sizeof(struct UsbPnpNotifyMatchInfoTable))) {
307         HDF_LOGE("%s:%d sbuf write data failed", __func__, __LINE__);
308         ret = HDF_FAILURE;
309         goto OUT;
310     }
311 
312 OUT:
313     return ret;
314 }
315 
UsbPnpNotifyGetDeviceInfo(void * eventData,union UsbPnpDeviceInfoData * pnpInfoData,struct UsbPnpDeviceInfo ** deviceInfo)316 static int32_t UsbPnpNotifyGetDeviceInfo(void *eventData, union UsbPnpDeviceInfoData *pnpInfoData,
317     struct UsbPnpDeviceInfo **deviceInfo)
318 {
319     struct UsbInfoQueryPara infoQueryPara;
320 
321     if ((g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_ADD_INTERFACE)
322         || (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_INTERFACE)) {
323         pnpInfoData->infoData = (struct UsbPnpAddRemoveInfo *)eventData;
324     } else {
325         pnpInfoData->usbDev = (struct usb_device *)eventData;
326     }
327 
328     if ((g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_ADD_INTERFACE)
329         || (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_INTERFACE)) {
330         infoQueryPara.type = USB_INFO_NORMAL_TYPE;
331         infoQueryPara.devNum = pnpInfoData->infoData->devNum;
332         infoQueryPara.busNum = pnpInfoData->infoData->busNum;
333         *deviceInfo = UsbPnpNotifyFindInfo(infoQueryPara);
334     } else if ((g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_ADD_DEVICE)
335         || (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_DEVICE)) {
336         infoQueryPara.type = USB_INFO_DEVICE_ADDRESS_TYPE;
337         infoQueryPara.usbDevAddr = (uint64_t)pnpInfoData->usbDev;
338         *deviceInfo = UsbPnpNotifyFindInfo(infoQueryPara);
339     } else {
340         *deviceInfo = UsbPnpNotifyCreateInfo();
341     }
342 
343     if (*deviceInfo == NULL) {
344         HDF_LOGE("%s:%d create or find info failed", __func__, __LINE__);
345         return HDF_FAILURE;
346     }
347 
348     (*deviceInfo)->info.removeType = g_usbPnpNotifyRemoveType;
349 
350     return HDF_SUCCESS;
351 }
352 
UsbPnpNotifyHdfSendEvent(const struct HdfDeviceObject * deviceObject,void * eventData)353 static int32_t UsbPnpNotifyHdfSendEvent(const struct HdfDeviceObject *deviceObject,
354     void *eventData)
355 {
356     int32_t ret;
357     struct UsbPnpDeviceInfo *deviceInfo = NULL;
358     struct HdfSBuf *data = NULL;
359     union UsbPnpDeviceInfoData pnpInfoData;
360 
361     if ((deviceObject == NULL) || (eventData == NULL)) {
362         HDF_LOGE("%s deviceObject=%p or eventData=%p is NULL", __func__, deviceObject, eventData);
363         return HDF_ERR_INVALID_PARAM;
364     }
365 
366     data = HdfSbufObtainDefaultSize();
367     if (data == NULL) {
368         HDF_LOGE("%s:%d InitDataBlock failed", __func__, __LINE__);
369         return HDF_FAILURE;
370     }
371 
372     ret = UsbPnpNotifyGetDeviceInfo(eventData, &pnpInfoData, &deviceInfo);
373     if (ret != HDF_SUCCESS) {
374         HDF_LOGE("%s:%d UsbPnpNotifyGetDeviceInfo failed, ret=%d", __func__, __LINE__, ret);
375         goto ERROR_DEVICE_INFO;
376     }
377 
378     ret = UsbPnpNotifyInitInfo(data, deviceInfo, pnpInfoData);
379     if (ret != HDF_SUCCESS) {
380         HDF_LOGE("%s:%d UsbPnpNotifyInitInfo failed, ret=%d", __func__, __LINE__, ret);
381         goto OUT;
382     }
383 
384     HDF_LOGI("%s:%d report one device information, %d usbDevAddr=%llu, devNum=%d, busNum=%d, infoTable=%d-0x%x-0x%x!",
385         __func__, __LINE__, g_usbPnpNotifyCmdType, deviceInfo->info.usbDevAddr, deviceInfo->info.devNum,
386         deviceInfo->info.busNum, deviceInfo->info.numInfos, deviceInfo->info.deviceInfo.vendorId,
387         deviceInfo->info.deviceInfo.productId);
388 
389     OsalMutexLock(&deviceInfo->lock);
390     if (deviceInfo->status == USB_PNP_DEVICE_INIT_STATUS) {
391         ret = HdfDeviceSendEvent(deviceObject, g_usbPnpNotifyCmdType, data);
392         if (ret != HDF_SUCCESS) {
393             OsalMutexUnlock(&deviceInfo->lock);
394             HDF_LOGE("%s:%d HdfDeviceSendEvent ret=%d", __func__, __LINE__, ret);
395             goto OUT;
396         }
397         deviceInfo->status = USB_PNP_DEVICE_ADD_STATUS;
398     } else {
399         ret = HDF_ERR_INVALID_OBJECT;
400     }
401     OsalMutexUnlock(&deviceInfo->lock);
402 
403 OUT:
404     if ((ret != HDF_SUCCESS) || (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_DEVICE)) {
405         if (UsbPnpNotifyDestroyInfo(deviceInfo) != HDF_SUCCESS) {
406             HDF_LOGE("%s:%d UsbPnpNotifyDestroyInfo fail", __func__, __LINE__);
407         }
408     }
409 ERROR_DEVICE_INFO:
410     HdfSbufRecycle(data);
411     return ret;
412 }
413 
414 #if USB_PNP_NOTIFY_TEST_MODE == true
TestReadPnpInfo(struct HdfSBuf * data)415 static void TestReadPnpInfo(struct HdfSBuf *data)
416 {
417     uint32_t infoSize;
418     bool flag;
419 
420     flag = HdfSbufReadBuffer(data, (const void **)(&g_testUsbPnpInfo), &infoSize);
421     if ((flag == false) || (g_testUsbPnpInfo == NULL)) {
422         HDF_LOGE("%s: fail to read g_testUsbPnpInfo, flag=%d, g_testUsbPnpInfo=%px", \
423             __func__, flag, g_testUsbPnpInfo);
424         return;
425     }
426 
427     HDF_LOGI("%s:%d infoSize=%d g_testUsbPnpInfo=%px read success!", __func__, __LINE__, infoSize, g_testUsbPnpInfo);
428 }
429 
TestPnpNotifyFillInfoTable(struct UsbPnpNotifyMatchInfoTable * infoTable)430 static void TestPnpNotifyFillInfoTable(struct UsbPnpNotifyMatchInfoTable *infoTable)
431 {
432     int8_t i;
433 
434     infoTable->usbDevAddr = g_testUsbPnpInfo->usbDevAddr;
435     infoTable->devNum = g_testUsbPnpInfo->devNum;
436     if (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_TEST) {
437         infoTable->busNum = -1;
438     } else {
439         infoTable->busNum = g_testUsbPnpInfo->busNum;
440     }
441 
442     infoTable->deviceInfo.vendorId = g_testUsbPnpInfo->deviceInfo.vendorId;
443     infoTable->deviceInfo.productId = g_testUsbPnpInfo->deviceInfo.productId;
444     infoTable->deviceInfo.bcdDeviceLow = g_testUsbPnpInfo->deviceInfo.bcdDeviceLow;
445     infoTable->deviceInfo.bcdDeviceHigh = g_testUsbPnpInfo->deviceInfo.bcdDeviceHigh;
446     infoTable->deviceInfo.deviceClass = g_testUsbPnpInfo->deviceInfo.deviceClass;
447     infoTable->deviceInfo.deviceSubClass = g_testUsbPnpInfo->deviceInfo.deviceSubClass;
448     infoTable->deviceInfo.deviceProtocol = g_testUsbPnpInfo->deviceInfo.deviceProtocol;
449 
450     infoTable->removeType = g_usbPnpNotifyRemoveType;
451 
452     if (g_usbPnpNotifyCmdType != USB_PNP_NOTIFY_REMOVE_TEST) {
453         infoTable->numInfos = g_testUsbPnpInfo->numInfos;
454         for (i = 0; i < infoTable->numInfos; i++) {
455             infoTable->interfaceInfo[i].interfaceClass = g_testUsbPnpInfo->interfaceInfo[i].interfaceClass;
456             infoTable->interfaceInfo[i].interfaceSubClass = g_testUsbPnpInfo->interfaceInfo[i].interfaceSubClass;
457             infoTable->interfaceInfo[i].interfaceProtocol = g_testUsbPnpInfo->interfaceInfo[i].interfaceProtocol;
458             infoTable->interfaceInfo[i].interfaceNumber = g_testUsbPnpInfo->interfaceInfo[i].interfaceNumber;
459         }
460     }
461 }
462 
TestPnpNotifyHdfSendEvent(const struct HdfDeviceObject * deviceObject)463 static int32_t TestPnpNotifyHdfSendEvent(const struct HdfDeviceObject *deviceObject)
464 {
465     struct UsbPnpNotifyMatchInfoTable infoTable;
466     struct HdfSBuf *data = NULL;
467 
468     if ((deviceObject == NULL) || (g_testUsbPnpInfo == NULL)) {
469         HDF_LOGE("%s deviceObject=%px or g_testUsbPnpInfo=%px is NULL", __func__, deviceObject, g_testUsbPnpInfo);
470         return HDF_ERR_INVALID_PARAM;
471     }
472 
473     data = HdfSbufObtainDefaultSize();
474     if (data == NULL) {
475         HDF_LOGE("%s InitDataBlock failed", __func__);
476         return HDF_FAILURE;
477     }
478 
479     TestPnpNotifyFillInfoTable(&infoTable);
480 
481     if (!HdfSbufWriteBuffer(data, (const void *)(&infoTable), sizeof(struct UsbPnpNotifyMatchInfoTable))) {
482         HDF_LOGE("%s: sbuf write infoTable failed", __func__);
483         goto OUT;
484     }
485 
486     HDF_LOGI("%s: report one device information, %d usbDev=%llu, devNum=%d, busNum=%d, infoTable=%d-0x%x-0x%x!", \
487         __func__, g_usbPnpNotifyCmdType, infoTable.usbDevAddr, infoTable.devNum, infoTable.busNum, \
488         infoTable.numInfos, infoTable.deviceInfo.vendorId, infoTable.deviceInfo.productId);
489 
490     int32_t ret = HdfDeviceSendEvent(deviceObject, g_usbPnpNotifyCmdType, data);
491     if (ret != HDF_SUCCESS) {
492         HDF_LOGE("%s: HdfDeviceSendEvent error=%d", __func__, ret);
493         goto OUT;
494     }
495 
496     HdfSbufRecycle(data);
497     return ret;
498 
499 OUT:
500     HdfSbufRecycle(data);
501     return HDF_FAILURE;
502 }
503 #endif
504 
GadgetPnpNotifyHdfSendEvent(const struct HdfDeviceObject * deviceObject)505 static int32_t GadgetPnpNotifyHdfSendEvent(const struct HdfDeviceObject *deviceObject)
506 {
507     if (deviceObject == NULL) {
508         HDF_LOGE("%s deviceObject=%p", __func__, deviceObject);
509         return HDF_ERR_INVALID_PARAM;
510     }
511 
512     struct HdfSBuf *data = NULL;
513     data = HdfSbufObtainDefaultSize();
514     if (data == NULL) {
515         HDF_LOGE("%s:%d InitDataBlock failed", __func__, __LINE__);
516         return HDF_FAILURE;
517     }
518     if (!HdfSbufWriteUint8(data, g_gadgetPnpNotifyType)) {
519         HDF_LOGE("%s, UsbEcmRead HdfSbufWriteInt8 error", __func__);
520         HdfSbufRecycle(data);
521         return HDF_FAILURE;
522     }
523     int32_t ret = HdfDeviceSendEvent(deviceObject, g_gadgetPnpNotifyType, data);
524     if (ret != HDF_SUCCESS) {
525         HDF_LOGE("%s:%d HdfDeviceSendEvent ret=%d", __func__, __LINE__, ret);
526     }
527 
528     HdfSbufRecycle(data);
529     return ret;
530 }
531 
UsbPnpNotifyFirstReport(struct usb_device * usbDev,void * data)532 static int32_t UsbPnpNotifyFirstReport(struct usb_device *usbDev, void *data)
533 {
534     int32_t ret;
535     struct HdfDeviceIoClient *client = (struct HdfDeviceIoClient *)data;
536 
537     ret = UsbPnpNotifyHdfSendEvent(client->device, usbDev);
538 
539     HDF_LOGI("%s: report all device information!", __func__);
540 
541     return ret;
542 }
543 
UsbPnpNotifyReportThread(void * arg)544 static int32_t UsbPnpNotifyReportThread(void* arg)
545 {
546     int32_t ret;
547     struct HdfDeviceObject *deviceObject = (struct HdfDeviceObject *)arg;
548 
549     while (!kthread_should_stop()) {
550 #if USB_PNP_NOTIFY_TEST_MODE == false
551         ret = wait_event_interruptible(g_usbPnpNotifyReportWait, g_usbDevice != NULL);
552 #else
553         ret = wait_event_interruptible(g_usbPnpNotifyReportWait,
554             ((g_usbDevice != NULL) || (g_testUsbPnpInfo != NULL)));
555 #endif
556         if (!ret) {
557             HDF_LOGI("%s: UsbPnpNotifyReportThread start!", __func__);
558         }
559 
560         OsalMutexLock(&g_usbSendEventLock);
561 #if USB_PNP_NOTIFY_TEST_MODE == true
562         if ((g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_ADD_TEST) || \
563             (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_TEST)) {
564             ret = TestPnpNotifyHdfSendEvent(deviceObject);
565         } else {
566 #endif
567             if ((g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_ADD_INTERFACE)
568                 || (g_usbPnpNotifyCmdType == USB_PNP_NOTIFY_REMOVE_INTERFACE)) {
569                 ret = UsbPnpNotifyHdfSendEvent(deviceObject, &g_usbPnpInfo);
570             } else {
571                 ret = UsbPnpNotifyHdfSendEvent(deviceObject, g_usbDevice);
572             }
573 #if USB_PNP_NOTIFY_TEST_MODE == true
574         }
575 #endif
576         if (ret != HDF_SUCCESS) {
577             HDF_LOGI("%s: UsbPnpNotifyHdfSendEvent error=%d!", __func__, ret);
578         }
579 
580         g_usbDevice = NULL;
581 #if USB_PNP_NOTIFY_TEST_MODE == true
582         g_testUsbPnpInfo = NULL;
583 #endif
584         OsalMutexUnlock(&g_usbSendEventLock);
585 
586         msleep(USB_PNP_NOTIFY_MSLEEP_TIME);
587     }
588 
589     HDF_LOGI("%s: usb pnp notify handle kthread exiting!", __func__);
590 
591     return 0;
592 }
593 
GadgetPnpNotifyReportThread(void * arg)594 static int32_t GadgetPnpNotifyReportThread(void* arg)
595 {
596     int32_t ret;
597     struct HdfDeviceObject *deviceObject = (struct HdfDeviceObject *)arg;
598 
599     while (!kthread_should_stop()) {
600         ret = wait_event_interruptible(g_gadgetPnpNotifyReportWait,
601             (g_gadgetPnpNotifyType != 0));
602         if (!ret) {
603             HDF_LOGI("%s: GadgetPnpNotifyReportThread start!", __func__);
604         }
605         OsalMutexLock(&g_gadgetSendEventLock);
606         ret = GadgetPnpNotifyHdfSendEvent(deviceObject);
607         if (ret != HDF_SUCCESS) {
608             HDF_LOGI("%s: UsbPnpNotifyHdfSendEvent error=%d!", __func__, ret);
609         }
610         g_gadgetPnpNotifyType = 0;
611         OsalMutexUnlock(&g_gadgetSendEventLock);
612         msleep(USB_PNP_NOTIFY_MSLEEP_TIME);
613     }
614 
615     HDF_LOGI("%s: gadget pnp notify handle kthread exiting!", __func__);
616 
617     return 0;
618 }
619 
UsbPnpNotifyCallback(struct notifier_block * self,unsigned long action,void * dev)620 static int32_t UsbPnpNotifyCallback(struct notifier_block *self, unsigned long action, void *dev)
621 {
622     int32_t ret;
623     struct UsbInfoQueryPara infoQueryPara;
624     struct UsbPnpDeviceInfo *deviceInfo = NULL;
625     union UsbPnpDeviceInfoData pnpInfoData;
626 
627     HDF_LOGI("%s: action=0x%lx", __func__, action);
628 
629     switch (action) {
630         case USB_DEVICE_ADD:
631             pnpInfoData.usbDev = dev;
632             deviceInfo = UsbPnpNotifyCreateInfo();
633             if (deviceInfo == NULL) {
634                 HDF_LOGE("%s:%d USB_DEVICE_ADD create info failed", __func__, __LINE__);
635             } else {
636                 ret = UsbPnpNotifyAddInitInfo(deviceInfo, pnpInfoData);
637                 if (ret != HDF_SUCCESS) {
638                     HDF_LOGE("%s:%d USB_DEVICE_ADD UsbPnpNotifyAddInitInfo error", __func__, __LINE__);
639                 } else {
640                     OsalMutexLock(&g_usbSendEventLock);
641                     g_usbDevice = dev;
642                     g_usbPnpNotifyCmdType = USB_PNP_NOTIFY_ADD_DEVICE;
643                     OsalMutexUnlock(&g_usbSendEventLock);
644                     wake_up_interruptible(&g_usbPnpNotifyReportWait);
645                 }
646             }
647             break;
648         case USB_DEVICE_REMOVE:
649             infoQueryPara.type = USB_INFO_DEVICE_ADDRESS_TYPE;
650             infoQueryPara.usbDevAddr = (uint64_t)dev;
651             deviceInfo = UsbPnpNotifyFindInfo(infoQueryPara);
652             if (deviceInfo == NULL) {
653                 HDF_LOGE("%s:%d USB_DEVICE_REMOVE find info failed", __func__, __LINE__);
654             } else {
655                 OsalMutexLock(&deviceInfo->lock);
656                 if (deviceInfo->status != USB_PNP_DEVICE_INIT_STATUS) {
657                     deviceInfo->status = USB_PNP_DEVICE_INIT_STATUS;
658                 } else {
659                     deviceInfo->status = USB_PNP_DEVICE_REMOVE_STATUS;
660                 }
661                 OsalMutexUnlock(&deviceInfo->lock);
662                 OsalMutexLock(&g_usbSendEventLock);
663                 g_usbDevice = dev;
664                 g_usbPnpNotifyCmdType = USB_PNP_NOTIFY_REMOVE_DEVICE;
665                 g_usbPnpNotifyRemoveType = USB_PNP_NOTIFY_REMOVE_BUS_DEV_NUM;
666                 OsalMutexUnlock(&g_usbSendEventLock);
667                 wake_up_interruptible(&g_usbPnpNotifyReportWait);
668             }
669             break;
670         case USB_GADGET_ADD:
671         case USB_GADGET_REMOVE:
672             OsalMutexLock(&g_gadgetSendEventLock);
673             if (g_preAcion == action) {
674                 OsalMutexUnlock(&g_gadgetSendEventLock);
675                 break;
676             }
677             if (action == USB_GADGET_ADD) {
678                 g_gadgetPnpNotifyType  = USB_PNP_DRIVER_GADGET_ADD;
679             } else {
680                 g_gadgetPnpNotifyType = USB_PNP_DRIVER_GADGET_REMOVE;
681             }
682             OsalMutexUnlock(&g_gadgetSendEventLock);
683             HDF_LOGI("%s:%d g_gadgetPnpNotifyType = %d", __func__, __LINE__, g_gadgetPnpNotifyType);
684             wake_up_interruptible(&g_gadgetPnpNotifyReportWait);
685             g_preAcion = action;
686             break;
687         default:
688             HDF_LOGI("%s: the action = 0x%lx is not defined!", __func__, action);
689             break;
690     }
691 
692     return NOTIFY_OK;
693 }
694 
695 static struct notifier_block g_usbPnpNotifyNb = {
696     .notifier_call =    UsbPnpNotifyCallback,
697 };
698 
UsbPnpNotifyReadPnpInfo(struct HdfSBuf * data)699 static void UsbPnpNotifyReadPnpInfo(struct HdfSBuf *data)
700 {
701     struct UsbInfoQueryPara infoQueryPara;
702     struct UsbPnpDeviceInfo *deviceInfo = NULL;
703     struct UsbPnpAddRemoveInfo *usbPnpInfo = NULL;
704     uint32_t infoSize;
705     bool flag;
706 
707     flag = HdfSbufReadBuffer(data, (const void **)(&usbPnpInfo), &infoSize);
708     if ((flag == false) || (usbPnpInfo == NULL)) {
709         HDF_LOGE("%s: fail to read g_usbPnpInfo, flag=%d, usbPnpInfo=%px", \
710             __func__, flag, usbPnpInfo);
711         return;
712     }
713 
714     g_usbPnpInfo.devNum = usbPnpInfo->devNum;
715     g_usbPnpInfo.busNum = usbPnpInfo->busNum;
716     g_usbPnpInfo.interfaceNumber = usbPnpInfo->interfaceNumber;
717     g_usbPnpInfo.interfaceClass = usbPnpInfo->interfaceClass;
718     g_usbPnpInfo.interfaceSubClass = usbPnpInfo->interfaceSubClass;
719     g_usbPnpInfo.interfaceProtocol = usbPnpInfo->interfaceProtocol;
720 
721     g_usbDevice = (struct usb_device *)&g_usbPnpInfo;
722 
723     infoQueryPara.type = USB_INFO_NORMAL_TYPE;
724     infoQueryPara.devNum = usbPnpInfo->devNum;
725     infoQueryPara.busNum = usbPnpInfo->busNum;
726     deviceInfo = UsbPnpNotifyFindInfo(infoQueryPara);
727     if (deviceInfo == NULL) {
728         HDF_LOGE("%s:%d add or remove interface find info failed", __func__, __LINE__);
729     } else {
730         OsalMutexLock(&deviceInfo->lock);
731         if (deviceInfo->status != USB_PNP_DEVICE_INIT_STATUS) {
732             deviceInfo->status = USB_PNP_DEVICE_INIT_STATUS;
733         } else {
734             deviceInfo->status = USB_PNP_DEVICE_INTERFACE_STATUS;
735         }
736         OsalMutexUnlock(&deviceInfo->lock);
737     }
738 
739     HDF_LOGI("%s:%d infoSize=%d g_usbPnpInfo=%px-%d-%d-%d-%d-%d-%d read success!",
740         __func__, __LINE__, infoSize, &g_usbPnpInfo, g_usbPnpInfo.devNum, g_usbPnpInfo.busNum,
741         g_usbPnpInfo.interfaceNumber, g_usbPnpInfo.interfaceClass, g_usbPnpInfo.interfaceSubClass,
742         g_usbPnpInfo.interfaceProtocol);
743 }
744 
UsbPnpGetDevices(struct HdfSBuf * reply)745 static int32_t UsbPnpGetDevices(struct HdfSBuf *reply)
746 {
747     int32_t ret = HDF_SUCCESS;
748     struct UsbPnpDeviceInfo *infoPos = NULL;
749     struct UsbPnpDeviceInfo *infoTemp = NULL;
750 
751     if (DListIsEmpty(&g_usbPnpInfoListHead)) {
752         return ret;
753     }
754     DLIST_FOR_EACH_ENTRY_SAFE(infoPos, infoTemp, &g_usbPnpInfoListHead, struct UsbPnpDeviceInfo, list){
755         if (!HdfSbufWriteInt32(reply, infoPos->info.busNum)) {
756             break;
757         }
758         if (!HdfSbufWriteInt32(reply, infoPos->info.devNum)) {
759             break;
760         }
761         if (!HdfSbufWriteUint8(reply, infoPos->info.deviceInfo.deviceClass)) {
762             break;
763         }
764         if (!HdfSbufWriteUint8(reply, infoPos->info.deviceInfo.deviceSubClass)) {
765             break;
766         }
767         if (!HdfSbufWriteUint8(reply, infoPos->info.deviceInfo.deviceProtocol)) {
768             break;
769         }
770         if (!HdfSbufWriteUint8(reply, infoPos->status)) {
771             break;
772         }
773     }
774     return ret;
775 }
776 
UsbPnpNotifyDispatch(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)777 static int32_t UsbPnpNotifyDispatch(struct HdfDeviceIoClient *client, int32_t cmd,
778     struct HdfSBuf *data, struct HdfSBuf *reply)
779 {
780     int32_t ret = HDF_SUCCESS;
781 
782     HDF_LOGI("%s: received cmd = %d", __func__, cmd);
783 
784     OsalMutexLock(&g_usbSendEventLock);
785     if (USB_PNP_DRIVER_GETDEVICES != cmd) {
786         g_usbPnpNotifyCmdType = cmd;
787     }
788 
789     switch (cmd) {
790         case USB_PNP_NOTIFY_ADD_INTERFACE:
791             UsbPnpNotifyReadPnpInfo(data);
792             wake_up_interruptible(&g_usbPnpNotifyReportWait);
793             break;
794         case USB_PNP_NOTIFY_REMOVE_INTERFACE:
795             UsbPnpNotifyReadPnpInfo(data);
796             g_usbPnpNotifyRemoveType = USB_PNP_NOTIFY_REMOVE_INTERFACE_NUM;
797             wake_up_interruptible(&g_usbPnpNotifyReportWait);
798             break;
799         case USB_PNP_NOTIFY_REPORT_INTERFACE:
800             usb_for_each_dev((void *)client, UsbPnpNotifyFirstReport);
801             break;
802 #if USB_PNP_NOTIFY_TEST_MODE == true
803         case USB_PNP_NOTIFY_ADD_TEST:
804             TestReadPnpInfo(data);
805             wake_up_interruptible(&g_usbPnpNotifyReportWait);
806             break;
807         case USB_PNP_NOTIFY_REMOVE_TEST:
808             TestReadPnpInfo(data);
809             g_usbPnpNotifyRemoveType = g_testUsbPnpInfo->removeType;
810             wake_up_interruptible(&g_usbPnpNotifyReportWait);
811             break;
812 #endif
813         case USB_PNP_DRIVER_GETDEVICES:
814             UsbPnpGetDevices(reply);
815             break;
816         default:
817             ret = HDF_ERR_NOT_SUPPORT;
818             break;
819     }
820     OsalMutexUnlock(&g_usbSendEventLock);
821 
822     if (!HdfSbufWriteInt32(reply, INT32_MAX)) {
823         HDF_LOGE("%s: reply int32 fail", __func__);
824     }
825 
826     return ret;
827 }
828 
UsbPnpNotifyBind(struct HdfDeviceObject * device)829 static int32_t UsbPnpNotifyBind(struct HdfDeviceObject *device)
830 {
831     static struct IDeviceIoService pnpNotifyService = {
832         .Dispatch = UsbPnpNotifyDispatch,
833     };
834 
835     HDF_LOGI("%s: Enter!", __func__);
836 
837     if (device == NULL) {
838         HDF_LOGE("%s: device is NULL!", __func__);
839         return HDF_ERR_INVALID_OBJECT;
840     }
841 
842     device->service = &pnpNotifyService;
843 
844     return HDF_SUCCESS;
845 }
846 
UsbPnpNotifyInit(struct HdfDeviceObject * device)847 static int32_t UsbPnpNotifyInit(struct HdfDeviceObject *device)
848 {
849     static bool firstInitFlag = true;
850 
851     HDF_LOGI("%s: Enter!", __func__);
852 
853     if (device == NULL) {
854         HDF_LOGE("%s: device is NULL", __func__);
855         return HDF_ERR_INVALID_OBJECT;
856     }
857 
858     if (firstInitFlag == true) {
859         firstInitFlag = false;
860 
861         DListHeadInit(&g_usbPnpInfoListHead);
862     }
863 
864     init_waitqueue_head(&g_usbPnpNotifyReportWait);
865     init_waitqueue_head(&g_gadgetPnpNotifyReportWait);
866 
867     OsalMutexInit(&g_usbSendEventLock);
868     OsalMutexInit(&g_gadgetSendEventLock);
869 
870     /* Add a new notify for usb pnp notify module. */
871     usb_register_notify(&g_usbPnpNotifyNb);
872 
873     /* Creat thread to handle send usb interface information. */
874     if (NULL == g_usbPnpNotifyReportThread) {
875         g_usbPnpNotifyReportThread = kthread_run(UsbPnpNotifyReportThread,
876             (void *)device, "usb pnp notify handle kthread");
877         if (g_usbPnpNotifyReportThread == NULL) {
878             HDF_LOGE("%s: kthread_run g_usbPnpNotifyReportThread is NULL", __func__);
879         }
880     } else {
881         HDF_LOGI("%s: g_usbPnpNotifyReportThread is already running!", __func__);
882     }
883 
884     /* Creat thread to handle gadeget information. */
885     if (NULL == g_gadgetPnpNotifyReportThread) {
886         g_gadgetPnpNotifyReportThread = kthread_run(GadgetPnpNotifyReportThread,
887             (void *)device, "gadget pnp notify handle kthread");
888         if (g_usbPnpNotifyReportThread == NULL) {
889             HDF_LOGE("%s: kthread_run g_usbPnpNotifyReportThread is NULL", __func__);
890         }
891     } else {
892         HDF_LOGI("%s: g_devPnpNotifyReportThread is already running!", __func__);
893     }
894 
895     return HDF_SUCCESS;
896 }
897 
UsbPnpNotifyRelease(struct HdfDeviceObject * device)898 static void UsbPnpNotifyRelease(struct HdfDeviceObject *device)
899 {
900     if (device == NULL) {
901         HDF_LOGI("%s: device is null", __func__);
902         return;
903     }
904 
905     if (g_usbPnpNotifyReportThread == NULL) {
906         HDF_LOGI("%s: g_usbPnpNotifyReportThread is not running!", __func__);
907     } else {
908         kthread_stop(g_usbPnpNotifyReportThread);
909     }
910     if (g_gadgetPnpNotifyReportThread == NULL) {
911         HDF_LOGI("%s: g_usbPnpNotifyReportThread is not running!", __func__);
912     } else {
913         kthread_stop(g_gadgetPnpNotifyReportThread);
914     }
915 
916     usb_unregister_notify(&g_usbPnpNotifyNb);
917 
918     OsalMutexDestroy(&g_usbSendEventLock);
919     OsalMutexDestroy(&g_gadgetSendEventLock);
920 
921     HDF_LOGI("%s: release done!", __func__);
922 
923     return;
924 }
925 
926 struct HdfDriverEntry g_usbPnpNotifyEntry = {
927     .moduleVersion = 1,
928     .Bind = UsbPnpNotifyBind,
929     .Init = UsbPnpNotifyInit,
930     .Release = UsbPnpNotifyRelease,
931     .moduleName = "HDF_USB_PNP_NOTIFY",
932 };
933 
934 HDF_INIT(g_usbPnpNotifyEntry);
935