1 /*
2  * Copyright (c) 2021-2023 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 "i3c_core.h"
10 #include "hdf_device_desc.h"
11 #include "hdf_log.h"
12 #include "osal_mem.h"
13 #include "osal_mutex.h"
14 
15 #define I3C_SERVICE_NAME "HDF_PLATFORM_I3C_MANAGER"
16 
17 struct I3cManager {
18     struct IDeviceIoService service;
19     struct HdfDeviceObject *device;
20     struct I3cCntlr *cntlrs[I3C_CNTLR_MAX];
21     struct OsalMutex lock;
22 };
23 
24 static struct I3cManager *g_i3cManager = NULL;
25 static struct DListHead g_i3cDeviceList;
26 static OsalSpinlock g_listLock;
27 
I3cCheckReservedAddr(uint16_t addr)28 int I3cCheckReservedAddr(uint16_t addr)
29 {
30     if ((addr == I3C_RESERVED_ADDR_7H00) || (addr == I3C_RESERVED_ADDR_7H01) ||
31         (addr == I3C_RESERVED_ADDR_7H02) || (addr == I3C_RESERVED_ADDR_7H3E) ||
32         (addr == I3C_RESERVED_ADDR_7H5E) || (addr == I3C_RESERVED_ADDR_7H6E) ||
33         (addr == I3C_RESERVED_ADDR_7H76) || (addr == I3C_RESERVED_ADDR_7H78) ||
34         (addr == I3C_RESERVED_ADDR_7H79) || (addr == I3C_RESERVED_ADDR_7H7A) ||
35         (addr == I3C_RESERVED_ADDR_7H7B) || (addr == I3C_RESERVED_ADDR_7H7C) ||
36         (addr == I3C_RESERVED_ADDR_7H7D) || (addr == I3C_RESERVED_ADDR_7H7E) ||
37         (addr == I3C_RESERVED_ADDR_7H7F)) {
38         return I3C_ADDR_RESERVED;
39     }
40     return I3C_ADDR_FREE;
41 }
42 
I3cCntlrLockDefault(struct I3cCntlr * cntlr)43 static inline int32_t I3cCntlrLockDefault(struct I3cCntlr *cntlr)
44 {
45     if (cntlr == NULL) {
46         HDF_LOGE("I3cCntlrLockDefault: cntlr is null!");
47         return HDF_ERR_DEVICE_BUSY;
48     }
49     return OsalSpinLock(&cntlr->lock);
50 }
51 
I3cCntlrUnlockDefault(struct I3cCntlr * cntlr)52 static inline void I3cCntlrUnlockDefault(struct I3cCntlr *cntlr)
53 {
54     if (cntlr == NULL) {
55         HDF_LOGE("I3cCntlrUnlockDefault: cntlr is null!");
56         return;
57     }
58     (void)OsalSpinUnlock(&cntlr->lock);
59 }
60 
61 static const struct I3cLockMethod g_i3cLockOpsDefault = {
62     .lock = I3cCntlrLockDefault,
63     .unlock = I3cCntlrUnlockDefault,
64 };
65 
I3cCntlrLock(struct I3cCntlr * cntlr)66 static inline int32_t I3cCntlrLock(struct I3cCntlr *cntlr)
67 {
68     if (cntlr->lockOps == NULL || cntlr->lockOps->lock == NULL) {
69         HDF_LOGE("I3cCntlrLock: lockOps or lock is null!");
70         return HDF_ERR_NOT_SUPPORT;
71     }
72     return cntlr->lockOps->lock(cntlr);
73 }
74 
I3cCntlrUnlock(struct I3cCntlr * cntlr)75 static inline void I3cCntlrUnlock(struct I3cCntlr *cntlr)
76 {
77     if (cntlr->lockOps != NULL && cntlr->lockOps->unlock != NULL) {
78         cntlr->lockOps->unlock(cntlr);
79     }
80 }
81 
I3cDeviceListGet(void)82 static struct DListHead *I3cDeviceListGet(void)
83 {
84     static struct DListHead *head = NULL;
85 
86     head = &g_i3cDeviceList;
87     while (OsalSpinLock(&g_listLock)) { }
88 
89     return head;
90 }
91 
I3cDeviceListPut(void)92 static void I3cDeviceListPut(void)
93 {
94     (void)OsalSpinUnlock(&g_listLock);
95 }
96 
GetAddrStatus(const struct I3cCntlr * cntlr,uint16_t addr)97 static int32_t GetAddrStatus(const struct I3cCntlr *cntlr, uint16_t addr)
98 {
99     int32_t status;
100 
101     if (addr > I3C_ADDR_MAX) {
102         HDF_LOGE("GetAddrStatus: The address 0x%x exceeds the maximum address!", addr);
103         return HDF_ERR_INVALID_PARAM;
104     }
105 
106     status = ADDR_STATUS_MASK & ((cntlr->addrSlot[addr / ADDRS_PER_UINT16]) >>
107         ((addr % ADDRS_PER_UINT16) * ADDRS_STATUS_BITS));
108 
109     return status;
110 }
111 
SetAddrStatus(struct I3cCntlr * cntlr,uint16_t addr,enum I3cAddrStatus status)112 static int32_t SetAddrStatus(struct I3cCntlr *cntlr, uint16_t addr, enum I3cAddrStatus status)
113 {
114     uint16_t temp;
115     int32_t ret;
116     uint16_t statusMask;
117 
118     if (addr > I3C_ADDR_MAX) {
119         HDF_LOGE("SetAddrStatus: The address 0x%x exceeds the maximum address!", addr);
120         return HDF_ERR_INVALID_PARAM;
121     }
122 
123     if (cntlr == NULL) {
124         HDF_LOGE("SetAddrStatus: cntlr is null!");
125         return HDF_ERR_INVALID_PARAM;
126     }
127 
128     ret = I3cCntlrLock(cntlr);
129     if (ret != HDF_SUCCESS) {
130         HDF_LOGE("SetAddrStatus: lock cntlr fail!");
131         return ret;
132     }
133 
134     statusMask = ADDR_STATUS_MASK << ((addr % ADDRS_PER_UINT16) * ADDRS_STATUS_BITS);
135     temp = (cntlr->addrSlot[addr / (uint16_t)ADDRS_PER_UINT16]) & (uint16_t)~statusMask;
136     temp |= (uint16_t)(((uint16_t)status) << ((addr % ADDRS_PER_UINT16) * ADDRS_STATUS_BITS));
137     cntlr->addrSlot[addr / ADDRS_PER_UINT16] = temp;
138 
139     I3cCntlrUnlock(cntlr);
140 
141     return HDF_SUCCESS;
142 }
143 
I3cInitAddrStatus(struct I3cCntlr * cntlr)144 static void inline I3cInitAddrStatus(struct I3cCntlr *cntlr)
145 {
146     uint16_t addr;
147 
148     for (addr = 0; addr <= I3C_ADDR_MAX; addr++) {
149         if (I3cCheckReservedAddr(addr) == I3C_ADDR_RESERVED) {
150             (void)SetAddrStatus(cntlr, addr, I3C_ADDR_RESERVED);
151         }
152     }
153 }
154 
GetFreeAddr(struct I3cCntlr * cntlr)155 static int32_t GetFreeAddr(struct I3cCntlr *cntlr)
156 {
157     enum I3cAddrStatus status;
158     int16_t count;
159     int32_t ret;
160 
161     if (cntlr == NULL) {
162         HDF_LOGE("GetFreeAddr: cntlr is null!");
163         return HDF_ERR_INVALID_PARAM;
164     }
165 
166     ret = I3cCntlrLock(cntlr);
167     if (ret != HDF_SUCCESS) {
168         HDF_LOGE("GetFreeAddr: lock cntlr fail!");
169         return ret;
170     }
171 
172     for (count = 0; count <= I3C_ADDR_MAX; count++) {
173         status = (enum I3cAddrStatus)GetAddrStatus(cntlr, count);
174         if (status == I3C_ADDR_FREE) {
175             return (int32_t)count;
176         }
177     }
178     I3cCntlrUnlock(cntlr);
179     HDF_LOGE("GetFreeAddr: no free addresses left!");
180 
181     return HDF_FAILURE;
182 }
183 
I3cCntlrSendCccCmd(struct I3cCntlr * cntlr,struct I3cCccCmd * ccc)184 int32_t I3cCntlrSendCccCmd(struct I3cCntlr *cntlr, struct I3cCccCmd *ccc)
185 {
186     int32_t ret;
187 
188     if (ccc == NULL) {
189         HDF_LOGE("I3cCntlrSendCccCmd: ccc is null!");
190         return HDF_ERR_INVALID_PARAM;
191     }
192 
193     if (cntlr->ops == NULL || cntlr->ops->sendCccCmd == NULL) {
194         HDF_LOGE("I3cCntlrSendCccCmd: ops or sendCccCmd is null!");
195         return HDF_ERR_NOT_SUPPORT;
196     }
197 
198     if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
199         HDF_LOGE("I3cCntlrSendCccCmd: lock cntlr fail!");
200         return HDF_ERR_DEVICE_BUSY;
201     }
202 
203     ret = cntlr->ops->sendCccCmd(cntlr, ccc);
204     I3cCntlrUnlock(cntlr);
205 
206     return ret;
207 }
208 
I3cGetDeviceByAddr(const struct I3cCntlr * cntlr,uint16_t addr)209 struct I3cDevice *I3cGetDeviceByAddr(const struct I3cCntlr *cntlr, uint16_t addr)
210 {
211     struct DListHead *head = NULL;
212     struct I3cDevice *pos = NULL;
213     struct I3cDevice *tmp = NULL;
214     enum I3cAddrStatus addrStatus;
215 
216     if (addr > I3C_ADDR_MAX) {
217         HDF_LOGE("I3cGetDeviceByAddr: The address 0x%x exceeds the maximum address!", addr);
218         return NULL;
219     }
220     addrStatus = GetAddrStatus(cntlr, addr);
221     if (addrStatus == I3C_ADDR_FREE) {
222         HDF_LOGE("I3cGetDeviceByAddr: The addr 0x%x is unavailable!", addr);
223         return NULL;
224     }
225     if (addrStatus == I3C_ADDR_RESERVED) {
226         HDF_LOGE("I3cGetDeviceByAddr: The addr 0x%x is reserved!", addr);
227         return NULL;
228     }
229 
230     if (addrStatus == I3C_ADDR_I2C_DEVICE || addrStatus == I3C_ADDR_I3C_DEVICE) {
231         head = I3cDeviceListGet();
232         DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, head, struct I3cDevice, list) {
233             if ((pos->dynaAddr == addr) && (pos->cntlr == cntlr)) {
234                 I3cDeviceListPut();
235                 HDF_LOGI("I3cGetDeviceByAddr: found by dynaAddr, done!");
236                 return pos;
237             } else if ((!pos->dynaAddr) && (pos->addr == addr) && (pos->cntlr == cntlr)) {
238                 HDF_LOGI("I3cGetDeviceByAddr: found by Addr, done!");
239                 I3cDeviceListPut();
240                 return pos;
241             }
242         }
243     }
244     HDF_LOGE("I3cGetDeviceByAddr: No such device found! addr: 0x%x!", addr);
245 
246     return NULL;
247 }
248 
I3cDeviceDefineI3cDevices(struct I3cDevice * device)249 static int32_t I3cDeviceDefineI3cDevices(struct I3cDevice *device)
250 {
251     int32_t ret;
252     int32_t addr;
253 
254     ret = SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_I3C_DEVICE);
255     if (ret != HDF_SUCCESS) {
256         addr = GetFreeAddr(device->cntlr);
257         if (addr <= 0) {
258             HDF_LOGE("I3cDeviceDefineI3cDevices: no free addresses left!");
259             return HDF_ERR_DEVICE_BUSY;
260         }
261         ret = SetAddrStatus(device->cntlr, (uint16_t)addr, I3C_ADDR_I3C_DEVICE);
262         if (ret != HDF_SUCCESS) {
263             HDF_LOGE("I3cDeviceDefineI3cDevices: add i3c device fail!");
264             return ret;
265         }
266     }
267 
268     return HDF_SUCCESS;
269 }
270 
I3cDeviceAdd(struct I3cDevice * device)271 int32_t I3cDeviceAdd(struct I3cDevice *device)
272 {
273     struct DListHead *head = NULL;
274     struct I3cDevice *pos = NULL;
275     struct I3cDevice *tmp = NULL;
276     int32_t ret;
277 
278     if ((device == NULL) || (GetAddrStatus(device->cntlr, device->addr) != I3C_ADDR_FREE)) {
279         HDF_LOGE("I3cDeviceAdd: device or addr is unavailable!");
280         return HDF_ERR_INVALID_OBJECT;
281     }
282     if (device->type == I3C_CNTLR_I2C_DEVICE || device->type == I3C_CNTLR_I2C_LEGACY_DEVICE) {
283         ret = SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_I2C_DEVICE);
284         if (ret != HDF_SUCCESS) {
285             HDF_LOGE("I3cDeviceAdd: add i2c device fail!");
286             return ret;
287         }
288     } else {
289         ret = I3cDeviceDefineI3cDevices(device);
290         if (ret != HDF_SUCCESS) {
291             HDF_LOGE("I3cDeviceAdd: i3c DEFSLVS error!");
292             return ret;
293         }
294     }
295     head = I3cDeviceListGet();
296     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, head, struct I3cDevice, list) {
297         if (pos == NULL) { // empty list
298             break;
299         }
300         if ((pos->pid == device->pid) && (pos->cntlr == device->cntlr)) {
301             I3cDeviceListPut();
302             HDF_LOGE("I3cDeviceAdd: device already existed!: 0x%llx!", device->pid);
303             (void)SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_RESERVED);
304             return HDF_ERR_IO;
305         }
306     }
307     DListHeadInit(&device->list);
308     DListInsertTail(&device->list, head);
309     I3cDeviceListPut();
310     HDF_LOGI("I3cDeviceAdd: done!");
311 
312     return HDF_SUCCESS;
313 }
314 
I3cDeviceRemove(struct I3cDevice * device)315 void I3cDeviceRemove(struct I3cDevice *device)
316 {
317     int32_t ret;
318 
319     if (device == NULL) {
320         HDF_LOGE("I3cDeviceRemove: device is null!");
321         return;
322     }
323 
324     ret = SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_RESERVED);
325     if (ret != HDF_SUCCESS) {
326         HDF_LOGE("I3cDeviceRemove: set addr status fail!");
327         return;
328     }
329     (void)I3cDeviceListGet();
330     DListRemove(&device->list);
331     I3cDeviceListPut();
332 }
333 
I3cManagerAddCntlr(struct I3cCntlr * cntlr)334 static int32_t I3cManagerAddCntlr(struct I3cCntlr *cntlr)
335 {
336     int32_t ret;
337     struct I3cManager *manager = g_i3cManager;
338 
339     if (cntlr->busId >= I3C_CNTLR_MAX) {
340         HDF_LOGE("I3cManagerAddCntlr: busId:%d exceed!", cntlr->busId);
341         return HDF_ERR_INVALID_PARAM;
342     }
343 
344     if (manager == NULL) {
345         HDF_LOGE("I3cManagerAddCntlr: get i3c manager fail!");
346         return HDF_ERR_NOT_SUPPORT;
347     }
348 
349     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
350         HDF_LOGE("I3cManagerAddCntlr: lock i3c manager fail!");
351         return HDF_ERR_DEVICE_BUSY;
352     }
353 
354     if (manager->cntlrs[cntlr->busId] != NULL) {
355         HDF_LOGE("I3cManagerAddCntlr: cntlr of bus:%hd already exits!", cntlr->busId);
356         ret = HDF_FAILURE;
357     } else {
358         manager->cntlrs[cntlr->busId] = cntlr;
359         ret = HDF_SUCCESS;
360     }
361     (void)OsalMutexUnlock(&manager->lock);
362 
363     return ret;
364 }
365 
I3cManagerRemoveCntlr(struct I3cCntlr * cntlr)366 static void I3cManagerRemoveCntlr(struct I3cCntlr *cntlr)
367 {
368     struct I3cManager *manager = g_i3cManager;
369 
370     if (cntlr->busId < 0 || cntlr->busId >= I3C_CNTLR_MAX) {
371         HDF_LOGE("I3cManagerRemoveCntlr: invalid busId:%hd!", cntlr->busId);
372         return;
373     }
374 
375     if (manager == NULL) {
376         HDF_LOGE("I3cManagerRemoveCntlr: get i3c manager fail!");
377         return;
378     }
379     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
380         HDF_LOGE("I3cManagerRemoveCntlr: lock i3c manager fail!");
381         return;
382     }
383 
384     if (manager->cntlrs[cntlr->busId] != cntlr) {
385         HDF_LOGE("I3cManagerRemoveCntlr: cntlr(%hd) not in manager!", cntlr->busId);
386     } else {
387         manager->cntlrs[cntlr->busId] = NULL;
388     }
389 
390     (void)OsalMutexUnlock(&manager->lock);
391 }
392 
I3cCntlrGet(int16_t number)393 struct I3cCntlr *I3cCntlrGet(int16_t number)
394 {
395     struct I3cCntlr *cntlr = NULL;
396     struct I3cManager *manager = g_i3cManager;
397 
398     if (number < 0 || number >= I3C_CNTLR_MAX) {
399         HDF_LOGE("I3cCntlrGet: invalid busId:%hd!", number);
400         return NULL;
401     }
402 
403     if (manager == NULL) {
404         HDF_LOGE("I3cCntlrGet: get i3c manager fail!");
405         return NULL;
406     }
407 
408     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
409         HDF_LOGE("I3cCntlrGet: lock i3c manager fail!");
410         return NULL;
411     }
412     cntlr = manager->cntlrs[number];
413     (void)OsalMutexUnlock(&manager->lock);
414 
415     return cntlr;
416 }
417 
I3cCntlrPut(struct I3cCntlr * cntlr)418 void I3cCntlrPut(struct I3cCntlr *cntlr)
419 {
420     (void)cntlr;
421 }
422 
I3cCntlrAdd(struct I3cCntlr * cntlr)423 int32_t I3cCntlrAdd(struct I3cCntlr *cntlr)
424 {
425     int32_t ret;
426 
427     if (cntlr == NULL) {
428         HDF_LOGE("I3cCntlrAdd: cntlr is null!");
429         return HDF_ERR_INVALID_OBJECT;
430     }
431 
432     if (cntlr->ops == NULL) {
433         HDF_LOGE("I3cCntlrAdd: no ops supplied!");
434         return HDF_ERR_INVALID_OBJECT;
435     }
436 
437     if (cntlr->lockOps == NULL) {
438         HDF_LOGI("I3cCntlrAdd: use default lock methods!");
439         cntlr->lockOps = &g_i3cLockOpsDefault;
440     }
441 
442     if (OsalSpinInit(&cntlr->lock) != HDF_SUCCESS) {
443         HDF_LOGE("I3cCntlrAdd: init lock fail!");
444         return HDF_FAILURE;
445     }
446 
447     I3cInitAddrStatus(cntlr);
448     ret = I3cManagerAddCntlr(cntlr);
449     if (ret != HDF_SUCCESS) {
450         HDF_LOGE("I3cCntlrAdd: i3c manager add cntlr fail!");
451         (void)OsalSpinDestroy(&cntlr->lock);
452         return ret;
453     }
454 
455     return HDF_SUCCESS;
456 }
457 
I3cCntlrRemove(struct I3cCntlr * cntlr)458 void I3cCntlrRemove(struct I3cCntlr *cntlr)
459 {
460     if (cntlr == NULL) {
461         HDF_LOGE("I3cCntlrRemove: cntlr is null!");
462         return;
463     }
464     I3cManagerRemoveCntlr(cntlr);
465     (void)OsalSpinDestroy(&cntlr->lock);
466 }
467 
I3cCntlrTransfer(struct I3cCntlr * cntlr,struct I3cMsg * msgs,int16_t count)468 int32_t I3cCntlrTransfer(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count)
469 {
470     int32_t ret;
471 
472     if (cntlr == NULL) {
473         HDF_LOGE("I3cCntlrTransfer: cntlr is null!");
474         return HDF_ERR_INVALID_OBJECT;
475     }
476 
477     if (cntlr->ops == NULL || cntlr->ops->Transfer == NULL) {
478         HDF_LOGE("I3cCntlrTransfer: ops or i3transfer is null!");
479         return HDF_ERR_NOT_SUPPORT;
480     }
481 
482     if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
483         HDF_LOGE("I3cCntlrTransfer: lock cntlr fail!");
484         return HDF_ERR_DEVICE_BUSY;
485     }
486 
487     ret = cntlr->ops->Transfer(cntlr, msgs, count);
488     I3cCntlrUnlock(cntlr);
489 
490     return ret;
491 }
492 
I3cCntlrI2cTransfer(struct I3cCntlr * cntlr,struct I3cMsg * msgs,int16_t count)493 int32_t I3cCntlrI2cTransfer(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count)
494 {
495     int32_t ret;
496 
497     if (cntlr == NULL) {
498         HDF_LOGE("I3cCntlrI2cTransfer: cntlr is null!");
499         return HDF_ERR_INVALID_OBJECT;
500     }
501 
502     if (cntlr->ops == NULL || cntlr->ops->i2cTransfer == NULL) {
503         HDF_LOGE("I3cCntlrI2cTransfer: ops or i2ctransfer is null!");
504         return HDF_ERR_NOT_SUPPORT;
505     }
506 
507     if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
508         HDF_LOGE("I3cCntlrI2cTransfer: lock cntlr fail!");
509         return HDF_ERR_DEVICE_BUSY;
510     }
511     ret = cntlr->ops->i2cTransfer(cntlr, msgs, count);
512     I3cCntlrUnlock(cntlr);
513 
514     return ret;
515 }
516 
I3cCntlrSetConfig(struct I3cCntlr * cntlr,struct I3cConfig * config)517 int32_t I3cCntlrSetConfig(struct I3cCntlr *cntlr, struct I3cConfig *config)
518 {
519     int32_t ret;
520 
521     if (cntlr == NULL) {
522         HDF_LOGE("I3cCntlrSetConfig: cntlr is null!");
523         return HDF_ERR_INVALID_OBJECT;
524     }
525 
526     if (config == NULL) {
527         HDF_LOGE("I3cCntlrSetConfig: config is null!");
528         return HDF_ERR_INVALID_PARAM;
529     }
530 
531     if (cntlr->ops == NULL || cntlr->ops->setConfig == NULL) {
532         HDF_LOGE("I3cCntlrSetConfig: ops or setConfig is null!");
533         return HDF_ERR_NOT_SUPPORT;
534     }
535 
536     if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
537         HDF_LOGE("I3cCntlrSetConfig: lock cntlr fail!");
538         return HDF_ERR_DEVICE_BUSY;
539     }
540 
541     ret = cntlr->ops->setConfig(cntlr, config);
542     cntlr->config = *config;
543     I3cCntlrUnlock(cntlr);
544 
545     return ret;
546 }
547 
I3cCntlrGetConfig(struct I3cCntlr * cntlr,struct I3cConfig * config)548 int32_t I3cCntlrGetConfig(struct I3cCntlr *cntlr, struct I3cConfig *config)
549 {
550     int32_t ret;
551 
552     if (cntlr == NULL) {
553         HDF_LOGE("I3cCntlrGetConfig: cntlr is null!");
554         return HDF_ERR_INVALID_OBJECT;
555     }
556 
557     if (config == NULL) {
558         HDF_LOGE("I3cCntlrGetConfig: config is null!");
559         return HDF_ERR_INVALID_PARAM;
560     }
561 
562     if (cntlr->ops == NULL || cntlr->ops->getConfig == NULL) {
563         HDF_LOGE("I3cCntlrGetConfig: ops or getConfig is null!");
564         return HDF_ERR_NOT_SUPPORT;
565     }
566 
567     if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
568         HDF_LOGE("I3cCntlrGetConfig: lock controller fail!");
569         return HDF_ERR_DEVICE_BUSY;
570     }
571 
572     ret = cntlr->ops->getConfig(cntlr, config);
573     cntlr->config = *config;
574     I3cCntlrUnlock(cntlr);
575 
576     return ret;
577 }
578 
I3cCntlrRequestIbi(struct I3cCntlr * cntlr,uint16_t addr,I3cIbiFunc func,uint32_t payload)579 int32_t I3cCntlrRequestIbi(struct I3cCntlr *cntlr, uint16_t addr, I3cIbiFunc func, uint32_t payload)
580 {
581     struct I3cDevice *device = NULL;
582     struct I3cIbiInfo *ibi = NULL;
583     uint16_t ptr;
584 
585     if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->requestIbi == NULL) {
586         HDF_LOGE("I3cCntlrRequestIbi: cntlr or ops or requestIbi is null!");
587         return HDF_ERR_NOT_SUPPORT;
588     }
589     if ((func == NULL) || (addr >= I3C_ADDR_MAX)) {
590         HDF_LOGE("I3cCntlrRequestIbi: invalid func or addr!");
591         return HDF_ERR_INVALID_PARAM;
592     }
593     device = I3cGetDeviceByAddr(cntlr, addr);
594     if (device == NULL) {
595         HDF_LOGE("I3cCntlrRequestIbi: get device fail!");
596         return HDF_ERR_INVALID_OBJECT;
597     }
598     if (device->supportIbi != I3C_DEVICE_SUPPORT_IBI) {
599         HDF_LOGE("I3cCntlrRequestIbi: not support!");
600         return HDF_ERR_NOT_SUPPORT;
601     }
602     if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
603         HDF_LOGE("I3cCntlrRequestIbi: lock controller fail!");
604         return HDF_ERR_DEVICE_BUSY;
605     }
606 
607     for (ptr = 0; ptr < I3C_IBI_MAX; ptr++) {
608         if (cntlr->ibiSlot[ptr] != NULL) {
609             continue;
610         }
611         ibi = (struct I3cIbiInfo *)OsalMemCalloc(sizeof(*ibi));
612         if (ibi == NULL) {
613             HDF_LOGE("I3cCntlrRequestIbi: ibi is null!");
614             I3cCntlrUnlock(cntlr);
615             return HDF_ERR_MALLOC_FAIL;
616         }
617         ibi->ibiFunc = func;
618         ibi->payload = payload;
619         ibi->data = (uint8_t *)OsalMemCalloc(sizeof(uint8_t) * payload);
620         device->ibi = ibi;
621         cntlr->ibiSlot[ptr] = device->ibi;
622         int32_t ret = cntlr->ops->requestIbi(device);
623         I3cCntlrUnlock(cntlr);
624         return ret;
625     }
626     I3cCntlrUnlock(cntlr);
627 
628     return HDF_ERR_DEVICE_BUSY;
629 }
630 
I3cCntlrFreeIbi(struct I3cCntlr * cntlr,uint16_t addr)631 int32_t I3cCntlrFreeIbi(struct I3cCntlr *cntlr, uint16_t addr)
632 {
633     struct I3cDevice *device = NULL;
634     uint16_t ptr;
635 
636     if (cntlr == NULL) {
637         HDF_LOGE("I3cCntlrFreeIbi: cntlr is null!");
638         return HDF_ERR_INVALID_OBJECT;
639     }
640 
641     if (addr >= I3C_ADDR_MAX) {
642         HDF_LOGE("I3cCntlrFreeIbi: Invalid addr: %x!", addr);
643         return HDF_ERR_INVALID_PARAM;
644     }
645 
646     device = I3cGetDeviceByAddr(cntlr, addr);
647     if (device == NULL || device->ibi == NULL) {
648         HDF_LOGE("I3cCntlrFreeIbi: invaild device!");
649         return HDF_ERR_INVALID_OBJECT;
650     }
651 
652     for (ptr = 0; ptr < I3C_IBI_MAX; ptr++) {
653         if (cntlr->ibiSlot[ptr] == NULL || cntlr->ibiSlot[ptr] != device->ibi) {
654             continue;
655         }
656         cntlr->ibiSlot[ptr] = NULL;
657         if (device->ibi->data != NULL) {
658             OsalMemFree(device->ibi->data);
659         }
660         OsalMemFree(device->ibi);
661         device->ibi = NULL;
662         break;
663     }
664 
665     return HDF_SUCCESS;
666 }
667 
I3cCntlrIbiCallback(struct I3cDevice * device)668 int32_t I3cCntlrIbiCallback(struct I3cDevice *device)
669 {
670     struct I3cIbiData *ibiData = NULL;
671 
672     if (device == NULL) {
673         HDF_LOGW("I3cCntlrIbiCallback: device is null!");
674         return HDF_ERR_INVALID_PARAM;
675     }
676 
677     ibiData = (struct I3cIbiData *)OsalMemCalloc(sizeof(*ibiData));
678     if (ibiData == NULL) {
679         HDF_LOGE("I3cCntlrIbiCallback: memcalloc ibiData fail!");
680         return HDF_ERR_MALLOC_FAIL;
681     }
682 
683     ibiData->buf = device->ibi->data;
684     ibiData->payload = device->ibi->payload;
685 
686     if (device->ibi->ibiFunc == NULL) {
687         HDF_LOGW("I3cCntlrIbiCallback: device->ibi or ibiFunc is null!");
688         OsalMemFree(ibiData);
689         return HDF_ERR_NOT_SUPPORT;
690     }
691 
692     if (device->dynaAddr != 0) {
693         (void)device->ibi->ibiFunc(device->cntlr, device->dynaAddr, *ibiData);
694         OsalMemFree(ibiData);
695     } else {
696         (void)device->ibi->ibiFunc(device->cntlr, device->addr, *ibiData);
697         OsalMemFree(ibiData);
698     }
699 
700     return HDF_SUCCESS;
701 }
702 
I3cManagerBind(struct HdfDeviceObject * device)703 static int32_t I3cManagerBind(struct HdfDeviceObject *device)
704 {
705     (void)device;
706     HDF_LOGI("I3cManagerBind: enter!");
707     return HDF_SUCCESS;
708 }
709 
I3cManagerInit(struct HdfDeviceObject * device)710 static int32_t I3cManagerInit(struct HdfDeviceObject *device)
711 {
712     int32_t ret;
713     struct I3cManager *manager = NULL;
714 
715     HDF_LOGI("I3cManagerInit: enter!");
716     if (device == NULL) {
717         HDF_LOGE("I3cManagerInit: device is null!");
718         return HDF_ERR_INVALID_OBJECT;
719     }
720 
721     manager = (struct I3cManager *)OsalMemCalloc(sizeof(*manager));
722     if (manager == NULL) {
723         HDF_LOGE("I3cManagerInit: malloc manager fail!");
724         return HDF_ERR_MALLOC_FAIL;
725     }
726 
727     ret = OsalMutexInit(&manager->lock);
728     if (ret != HDF_SUCCESS) {
729         HDF_LOGE("I3cManagerInit: mutex init fail, ret: %d!", ret);
730         OsalMemFree(manager);
731         return HDF_FAILURE;
732     }
733     manager->device = device;
734     g_i3cManager = manager;
735     DListHeadInit(&g_i3cDeviceList);
736     OsalSpinInit(&g_listLock);
737 
738     return HDF_SUCCESS;
739 }
740 
I3cManagerRelease(struct HdfDeviceObject * device)741 static void I3cManagerRelease(struct HdfDeviceObject *device)
742 {
743     struct I3cManager *manager = NULL;
744 
745     HDF_LOGI("I3cManagerRelease: enter");
746     if (device == NULL) {
747         HDF_LOGI("I3cManagerRelease: device is null!");
748         return;
749     }
750     manager = (struct I3cManager *)device->service;
751     if (manager == NULL) {
752         HDF_LOGI("I3cManagerRelease: no service binded!");
753         return;
754     }
755     g_i3cManager = NULL;
756     (void)OsalMutexDestroy(&manager->lock);
757     OsalMemFree(manager);
758 }
759 
760 struct HdfDriverEntry g_i3cManagerEntry = {
761     .moduleVersion = 1,
762     .Bind = I3cManagerBind,
763     .Init = I3cManagerInit,
764     .Release = I3cManagerRelease,
765     .moduleName = "HDF_PLATFORM_I3C_MANAGER",
766 };
767 HDF_INIT(g_i3cManagerEntry);
768