• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "can/can_manager.h"
10 #include "can/can_core.h"
11 
12 #define HDF_LOG_TAG can_manager
13 
14 #define CAN_NUMBER_MAX 32
15 #define CAN_MSG_POOL_SIZE_DFT 8
16 
17 static struct PlatformManager *g_manager;
18 
CanManagerGet(void)19 static struct PlatformManager *CanManagerGet(void)
20 {
21     int32_t ret;
22 
23     if (g_manager == NULL) {
24         ret = PlatformManagerCreate("CAN_BUS_MANAGER", &g_manager);
25         if (ret != HDF_SUCCESS) {
26             HDF_LOGE("CanManagerGet: careate can manager failed:%d", ret);
27         }
28     }
29     return g_manager;
30 }
31 
CanManagerDestroyIfNeed(void)32 static void CanManagerDestroyIfNeed(void)
33 {
34     if (g_manager != NULL && DListIsEmpty(&g_manager->devices)) {
35         PlatformManagerDestroy(g_manager);
36         g_manager = NULL;
37     }
38 }
39 
CanCntlrCheckAndInit(struct CanCntlr * cntlr)40 static int32_t CanCntlrCheckAndInit(struct CanCntlr *cntlr)
41 {
42     if (cntlr == NULL || cntlr->ops == NULL) {
43         return HDF_ERR_INVALID_OBJECT;
44     }
45 
46     if (cntlr->number < 0 || cntlr->number >= CAN_NUMBER_MAX) {
47         HDF_LOGE("CanCntlrCheckAndInit: invlaid can num:%d", cntlr->number);
48         return HDF_ERR_INVALID_OBJECT;
49     }
50 
51     DListHeadInit(&cntlr->rxBoxList);
52 
53     if (OsalMutexInit(&cntlr->lock) != HDF_SUCCESS) {
54         HDF_LOGE("CanCntlrCheckAndInit: init lock failed");
55         return HDF_FAILURE;
56     }
57 
58     if (OsalMutexInit(&cntlr->rboxListLock) != HDF_SUCCESS) {
59         HDF_LOGE("CanCntlrCheckAndInit: init rx box list lock failed");
60         (void)OsalMutexDestroy(&cntlr->lock);
61         return HDF_FAILURE;
62     }
63 
64     if (cntlr->msgPoolSize <= 0) {
65         cntlr->msgPoolSize = CAN_MSG_POOL_SIZE_DFT;
66     }
67 
68     cntlr->msgPool = CanMsgPoolCreate(cntlr->msgPoolSize);
69     if (cntlr->msgPool == NULL) {
70         HDF_LOGE("CanCntlrCheckAndInit: create can msg pool failed");
71         (void)OsalMutexDestroy(&cntlr->rboxListLock);
72         (void)OsalMutexDestroy(&cntlr->lock);
73         return HDF_FAILURE;
74     }
75 
76     return HDF_SUCCESS;
77 }
78 
CanCntlrDeInit(struct CanCntlr * cntlr)79 static void CanCntlrDeInit(struct CanCntlr *cntlr)
80 {
81     HDF_LOGD("CanCntlrDeInit: enter");
82     CanMsgPoolDestroy(cntlr->msgPool);
83     cntlr->msgPool = NULL;
84     (void)OsalMutexDestroy(&cntlr->rboxListLock);
85     (void)OsalMutexDestroy(&cntlr->lock);
86     HDF_LOGD("CanCntlrDeInit: exit");
87 }
88 
CanCntlrAdd(struct CanCntlr * cntlr)89 int32_t CanCntlrAdd(struct CanCntlr *cntlr)
90 {
91     int32_t ret;
92 
93     ret = CanCntlrCheckAndInit(cntlr);
94     if (ret != HDF_SUCCESS) {
95         return ret;
96     }
97 
98     cntlr->device.number = cntlr->number;
99     ret = PlatformDeviceSetName(&cntlr->device, "CAN%d", cntlr->number);
100     if (ret != HDF_SUCCESS) {
101         CanCntlrDeInit(cntlr);
102         return ret;
103     }
104 
105     cntlr->device.manager = CanManagerGet();
106     if (cntlr->device.manager == NULL) {
107         PlatformDeviceClearName(&cntlr->device);
108         CanCntlrDeInit(cntlr);
109         return HDF_PLT_ERR_DEV_GET;
110     }
111 
112     if ((ret = PlatformDeviceAdd(&cntlr->device)) != HDF_SUCCESS) {
113         PlatformDeviceClearName(&cntlr->device);
114         CanCntlrDeInit(cntlr);
115         return ret;
116     }
117 
118     HDF_LOGI("CanCntlrAdd: add controller %d success", cntlr->number);
119     return HDF_SUCCESS;
120 }
121 
CanCntlrDel(struct CanCntlr * cntlr)122 int32_t CanCntlrDel(struct CanCntlr *cntlr)
123 {
124     if (cntlr == NULL) {
125         return HDF_ERR_INVALID_OBJECT;
126     }
127 
128     PlatformDeviceDel(&cntlr->device);
129     PlatformDeviceClearName(&cntlr->device);
130 
131     CanCntlrDeInit(cntlr);
132 
133     CanManagerDestroyIfNeed();
134     HDF_LOGI("CanCntlrDel: del controller %d success", cntlr->number);
135     return HDF_SUCCESS;
136 }
137 
CanCntlrFromPlatformDevice(const struct PlatformDevice * pdevice)138 static struct CanCntlr *CanCntlrFromPlatformDevice(const struct PlatformDevice *pdevice)
139 {
140     return CONTAINER_OF(pdevice, struct CanCntlr, device);
141 }
142 
CanCntlrGetByName(const char * name)143 struct CanCntlr *CanCntlrGetByName(const char *name)
144 {
145     static struct PlatformManager *manager = NULL;
146     struct PlatformDevice *pdevice = NULL;
147 
148     manager = CanManagerGet();
149     if (manager == NULL) {
150         return NULL;
151     }
152 
153     pdevice = PlatformManagerGetDeviceByName(manager, name);
154     if (pdevice == NULL) {
155         return NULL;
156     }
157 
158     return CanCntlrFromPlatformDevice(pdevice);
159 }
160 
CanCntlrGetByNumber(int32_t number)161 struct CanCntlr *CanCntlrGetByNumber(int32_t number)
162 {
163     static struct PlatformManager *manager = NULL;
164     struct PlatformDevice *pdevice = NULL;
165 
166     manager = CanManagerGet();
167     if (manager == NULL) {
168         return NULL;
169     }
170 
171     pdevice = PlatformManagerGetDeviceByNumber(manager, number);
172     if (pdevice == NULL) {
173         return NULL;
174     }
175 
176     return CanCntlrFromPlatformDevice(pdevice);
177 }
178 
CanCntlrPut(struct CanCntlr * cntlr)179 void CanCntlrPut(struct CanCntlr *cntlr)
180 {
181     if (cntlr != NULL) {
182         PlatformDevicePut(&cntlr->device);
183     }
184 }
185