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