• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         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(const struct I3cCntlr * cntlr,uint16_t addr)94 static int32_t GetAddrStatus(const 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 
I3cGetDeviceByAddr(const struct I3cCntlr * cntlr,uint16_t addr)206 struct I3cDevice *I3cGetDeviceByAddr(const 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;
249     int32_t addr;
250 
251     ret = SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_I3C_DEVICE);
252     if (ret != HDF_SUCCESS) {
253         addr = GetFreeAddr(device->cntlr);
254         if (addr <= 0) {
255             HDF_LOGE("%s: No free addresses left!", __func__);
256             return HDF_ERR_DEVICE_BUSY;
257         }
258         ret = SetAddrStatus(device->cntlr, (uint16_t)addr, I3C_ADDR_I3C_DEVICE);
259         if (ret != HDF_SUCCESS) {
260             HDF_LOGE("%s: Add I3C device failed!", __func__);
261             return ret;
262         }
263     }
264 
265     return HDF_SUCCESS;
266 }
267 
I3cDeviceAdd(struct I3cDevice * device)268 int32_t I3cDeviceAdd(struct I3cDevice *device)
269 {
270     struct DListHead *head = NULL;
271     struct I3cDevice *pos = NULL;
272     struct I3cDevice *tmp = NULL;
273     int32_t ret;
274 
275     if ((device == NULL) || (GetAddrStatus(device->cntlr, device->addr) != I3C_ADDR_FREE)) {
276         HDF_LOGE("%s: device or addr is unavailable", __func__);
277         return HDF_ERR_INVALID_OBJECT;
278     }
279     if (device->type == I3C_CNTLR_I2C_DEVICE || device->type == I3C_CNTLR_I2C_LEGACY_DEVICE) {
280         ret = SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_I2C_DEVICE);
281         if (ret != HDF_SUCCESS) {
282             HDF_LOGE("%s: Add I2C device failed!", __func__);
283             return ret;
284         }
285     } else {
286         ret = I3cDeviceDefineI3cDevices(device);
287         if (ret != HDF_SUCCESS) {
288             HDF_LOGE("%s: I3c DEFSLVS error!", __func__);
289             return ret;
290         }
291     }
292     head = I3cDeviceListGet();
293     DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, head, struct I3cDevice, list) {
294         if (pos == NULL) { // empty list
295             break;
296         }
297         if ((pos->pid == device->pid) && (pos->cntlr == device->cntlr)) {
298             I3cDeviceListPut();
299             HDF_LOGE("%s: device already existed!: 0x%llx", __func__, device->pid);
300             (void)SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_RESERVED);
301             return HDF_ERR_IO;
302         }
303     }
304     DListHeadInit(&device->list);
305     DListInsertTail(&device->list, head);
306     I3cDeviceListPut();
307     HDF_LOGI("%s: done!", __func__);
308 
309     return HDF_SUCCESS;
310 }
311 
I3cDeviceRemove(struct I3cDevice * device)312 void I3cDeviceRemove(struct I3cDevice *device)
313 {
314     int32_t ret;
315     if (device == NULL) {
316         return;
317     }
318 
319     ret = SetAddrStatus(device->cntlr, device->addr, I3C_ADDR_RESERVED);
320     if (ret != HDF_SUCCESS) {
321         return;
322     }
323     (void)I3cDeviceListGet();
324     DListRemove(&device->list);
325     I3cDeviceListPut();
326 }
327 
I3cManagerAddCntlr(struct I3cCntlr * cntlr)328 static int32_t I3cManagerAddCntlr(struct I3cCntlr *cntlr)
329 {
330     int32_t ret;
331     struct I3cManager *manager = g_i3cManager;
332 
333     if (cntlr->busId >= I3C_CNTLR_MAX) {
334         HDF_LOGE("%s: busId:%d exceed!", __func__, cntlr->busId);
335         return HDF_ERR_INVALID_PARAM;
336     }
337 
338     if (manager == NULL) {
339         HDF_LOGE("%s: get i3c manager fail!", __func__);
340         return HDF_ERR_NOT_SUPPORT;
341     }
342 
343     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
344         HDF_LOGE("%s: lock i3c manager fail!", __func__);
345         return HDF_ERR_DEVICE_BUSY;
346     }
347 
348     if (manager->cntlrs[cntlr->busId] != NULL) {
349         HDF_LOGE("%s: cntlr of bus:%hd already exits!", __func__, cntlr->busId);
350         ret = HDF_FAILURE;
351     } else {
352         manager->cntlrs[cntlr->busId] = cntlr;
353         ret = HDF_SUCCESS;
354     }
355     (void)OsalMutexUnlock(&manager->lock);
356 
357     return ret;
358 }
359 
I3cManagerRemoveCntlr(struct I3cCntlr * cntlr)360 static void I3cManagerRemoveCntlr(struct I3cCntlr *cntlr)
361 {
362     struct I3cManager *manager = g_i3cManager;
363 
364     if (cntlr->busId < 0 || cntlr->busId >= I3C_CNTLR_MAX) {
365         HDF_LOGE("%s: invalid busId:%hd!", __func__, cntlr->busId);
366         return;
367     }
368 
369     if (manager == NULL) {
370         HDF_LOGE("%s: get i3c manager fail!", __func__);
371         return;
372     }
373     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
374         HDF_LOGE("%s: lock i3c manager fail!", __func__);
375         return;
376     }
377 
378     if (manager->cntlrs[cntlr->busId] != cntlr) {
379         HDF_LOGE("%s: cntlr(%hd) not in manager!", __func__, cntlr->busId);
380     } else {
381         manager->cntlrs[cntlr->busId] = NULL;
382     }
383 
384     (void)OsalMutexUnlock(&manager->lock);
385 }
386 
I3cCntlrGet(int16_t number)387 struct I3cCntlr *I3cCntlrGet(int16_t number)
388 {
389     struct I3cCntlr *cntlr = NULL;
390     struct I3cManager *manager = g_i3cManager;
391 
392     if (number < 0 || number >= I3C_CNTLR_MAX) {
393         HDF_LOGE("%s: invalid busId:%hd!", __func__, number);
394         return NULL;
395     }
396 
397     if (manager == NULL) {
398         HDF_LOGE("%s: get i3c manager fail!", __func__);
399         return NULL;
400     }
401 
402     if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
403         HDF_LOGE("%s: lock i3c manager fail!", __func__);
404         return NULL;
405     }
406     cntlr = manager->cntlrs[number];
407     (void)OsalMutexUnlock(&manager->lock);
408 
409     return cntlr;
410 }
411 
I3cCntlrPut(struct I3cCntlr * cntlr)412 void I3cCntlrPut(struct I3cCntlr *cntlr)
413 {
414     (void)cntlr;
415 }
416 
I3cCntlrAdd(struct I3cCntlr * cntlr)417 int32_t I3cCntlrAdd(struct I3cCntlr *cntlr)
418 {
419     int32_t ret;
420 
421     if (cntlr == NULL) {
422         HDF_LOGE("%s: cntlr is NULL!", __func__);
423         return HDF_ERR_INVALID_OBJECT;
424     }
425 
426     if (cntlr->ops == NULL) {
427         HDF_LOGE("%s: no ops supplied!", __func__);
428         return HDF_ERR_INVALID_OBJECT;
429     }
430 
431     if (cntlr->lockOps == NULL) {
432         HDF_LOGI("%s: use default lock methods!", __func__);
433         cntlr->lockOps = &g_i3cLockOpsDefault;
434     }
435 
436     if (OsalSpinInit(&cntlr->lock) != HDF_SUCCESS) {
437         HDF_LOGE("%s: init lock fail!", __func__);
438         return HDF_FAILURE;
439     }
440 
441     I3cInitAddrStatus(cntlr);
442     ret = I3cManagerAddCntlr(cntlr);
443     if (ret != HDF_SUCCESS) {
444         (void)OsalSpinDestroy(&cntlr->lock);
445         return ret;
446     }
447 
448     return HDF_SUCCESS;
449 }
450 
I3cCntlrRemove(struct I3cCntlr * cntlr)451 void I3cCntlrRemove(struct I3cCntlr *cntlr)
452 {
453     if (cntlr == NULL) {
454         return;
455     }
456     I3cManagerRemoveCntlr(cntlr);
457     (void)OsalSpinDestroy(&cntlr->lock);
458 }
459 
I3cCntlrTransfer(struct I3cCntlr * cntlr,struct I3cMsg * msgs,int16_t count)460 int32_t I3cCntlrTransfer(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count)
461 {
462     int32_t ret;
463 
464     if (cntlr == NULL) {
465         HDF_LOGE("%s: cntlr is NULL!", __func__);
466         return HDF_ERR_INVALID_OBJECT;
467     }
468 
469     if (cntlr->ops == NULL || cntlr->ops->Transfer == NULL) {
470         HDF_LOGE("%s: ops or i3transfer is null", __func__);
471         return HDF_ERR_NOT_SUPPORT;
472     }
473 
474     if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
475         HDF_LOGE("%s: lock controller fail!", __func__);
476         return HDF_ERR_DEVICE_BUSY;
477     }
478 
479     ret = cntlr->ops->Transfer(cntlr, msgs, count);
480     I3cCntlrUnlock(cntlr);
481 
482     return ret;
483 }
484 
I3cCntlrI2cTransfer(struct I3cCntlr * cntlr,struct I3cMsg * msgs,int16_t count)485 int32_t I3cCntlrI2cTransfer(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count)
486 {
487     int32_t ret;
488 
489     if (cntlr == NULL) {
490         HDF_LOGE("%s: cntlr is NULL!", __func__);
491         return HDF_ERR_INVALID_OBJECT;
492     }
493 
494     if (cntlr->ops == NULL || cntlr->ops->i2cTransfer == NULL) {
495         HDF_LOGE("%s: ops or i2ctransfer is null", __func__);
496         return HDF_ERR_NOT_SUPPORT;
497     }
498 
499     if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
500         HDF_LOGE("%s: lock controller fail!", __func__);
501         return HDF_ERR_DEVICE_BUSY;
502     }
503     ret = cntlr->ops->i2cTransfer(cntlr, msgs, count);
504     I3cCntlrUnlock(cntlr);
505 
506     return ret;
507 }
508 
I3cCntlrSetConfig(struct I3cCntlr * cntlr,struct I3cConfig * config)509 int32_t I3cCntlrSetConfig(struct I3cCntlr *cntlr, struct I3cConfig *config)
510 {
511     int32_t ret;
512 
513     if (cntlr == NULL) {
514         HDF_LOGE("%s: cntlr is NULL!", __func__);
515         return HDF_ERR_INVALID_OBJECT;
516     }
517 
518     if (config == NULL) {
519         HDF_LOGE("%s: config is NULL!", __func__);
520         return HDF_ERR_INVALID_PARAM;
521     }
522 
523     if (cntlr->ops == NULL || cntlr->ops->setConfig == NULL) {
524         HDF_LOGE("%s: ops or setConfig is NULL!", __func__);
525         return HDF_ERR_NOT_SUPPORT;
526     }
527 
528     if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
529         HDF_LOGE("%s: lock controller fail!", __func__);
530         return HDF_ERR_DEVICE_BUSY;
531     }
532 
533     ret = cntlr->ops->setConfig(cntlr, config);
534     cntlr->config = *config;
535     I3cCntlrUnlock(cntlr);
536 
537     return ret;
538 }
539 
I3cCntlrGetConfig(struct I3cCntlr * cntlr,struct I3cConfig * config)540 int32_t I3cCntlrGetConfig(struct I3cCntlr *cntlr, struct I3cConfig *config)
541 {
542     int32_t ret;
543 
544     if (cntlr == NULL) {
545         HDF_LOGE("%s: cntlr is NULL!", __func__);
546         return HDF_ERR_INVALID_OBJECT;
547     }
548 
549     if (config == NULL) {
550         HDF_LOGE("%s: config is NULL!", __func__);
551         return HDF_ERR_INVALID_PARAM;
552     }
553 
554     if (cntlr->ops == NULL || cntlr->ops->getConfig == NULL) {
555         HDF_LOGE("%s: ops or getConfig is NULL!", __func__);
556         return HDF_ERR_NOT_SUPPORT;
557     }
558 
559     if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
560         HDF_LOGE("%s: lock controller fail!", __func__);
561         return HDF_ERR_DEVICE_BUSY;
562     }
563 
564     ret = cntlr->ops->getConfig(cntlr, config);
565     cntlr->config = *config;
566     I3cCntlrUnlock(cntlr);
567 
568     return ret;
569 }
570 
I3cCntlrRequestIbi(struct I3cCntlr * cntlr,uint16_t addr,I3cIbiFunc func,uint32_t payload)571 int32_t I3cCntlrRequestIbi(struct I3cCntlr *cntlr, uint16_t addr, I3cIbiFunc func, uint32_t payload)
572 {
573     struct I3cDevice *device = NULL;
574     struct I3cIbiInfo *ibi = NULL;
575     uint16_t ptr;
576     int32_t ret;
577 
578     if (cntlr == NULL) {
579         HDF_LOGE("%s: cntlr is NULL!", __func__);
580         return HDF_ERR_INVALID_OBJECT;
581     }
582     if (cntlr->ops == NULL || cntlr->ops->requestIbi == NULL) {
583         HDF_LOGE("%s: Not support!", __func__);
584         return HDF_ERR_NOT_SUPPORT;
585     }
586     if ((func == NULL) || (addr >= I3C_ADDR_MAX)) {
587         HDF_LOGE("%s: invalid func or addr!", __func__);
588         return HDF_ERR_INVALID_PARAM;
589     }
590     device = I3cGetDeviceByAddr(cntlr, addr);
591     if (device == NULL) {
592         HDF_LOGE("%s: Get device failed!", __func__);
593         return HDF_ERR_INVALID_OBJECT;
594     }
595     if (device->supportIbi != I3C_DEVICE_SUPPORT_IBI) {
596         HDF_LOGE("%s: not support!", __func__);
597         return HDF_ERR_NOT_SUPPORT;
598     }
599     if (I3cCntlrLock(cntlr) != HDF_SUCCESS) {
600         HDF_LOGE("%s: lock controller fail!", __func__);
601         return HDF_ERR_DEVICE_BUSY;
602     }
603 
604     for (ptr = 0; ptr < I3C_IBI_MAX; ptr++) {
605         if (cntlr->ibiSlot[ptr] != NULL) {
606             continue;
607         }
608         ibi = (struct I3cIbiInfo *)OsalMemCalloc(sizeof(*ibi));
609         if (ibi == NULL) {
610             HDF_LOGE("func:%s ibi is NULL!", __func__);
611             return HDF_ERR_MALLOC_FAIL;
612         }
613         ibi->ibiFunc = func;
614         ibi->payload = payload;
615         ibi->data = (uint8_t *)OsalMemCalloc(sizeof(uint8_t) * payload);
616         device->ibi = ibi;
617         cntlr->ibiSlot[ptr] = device->ibi;
618         ret = cntlr->ops->requestIbi(device);
619         I3cCntlrUnlock(cntlr);
620         return ret;
621     }
622     I3cCntlrUnlock(cntlr);
623 
624     return HDF_ERR_DEVICE_BUSY;
625 }
626 
I3cCntlrFreeIbi(struct I3cCntlr * cntlr,uint16_t addr)627 int32_t I3cCntlrFreeIbi(struct I3cCntlr *cntlr, uint16_t addr)
628 {
629     struct I3cDevice *device = NULL;
630     uint16_t ptr;
631 
632     if (cntlr == NULL) {
633         HDF_LOGE("%s: cntlr is NULL!", __func__);
634         return HDF_ERR_INVALID_OBJECT;
635     }
636 
637     if (addr >= I3C_ADDR_MAX) {
638         HDF_LOGE("%s: Invalid addr: %x", __func__, addr);
639         return HDF_ERR_INVALID_PARAM;
640     }
641 
642     device = I3cGetDeviceByAddr(cntlr, addr);
643     if (device == NULL || device->ibi == NULL) {
644         HDF_LOGE("%s: invaild device!", __func__);
645         return HDF_ERR_INVALID_OBJECT;
646     }
647 
648     for (ptr = 0; ptr < I3C_IBI_MAX; ptr++) {
649         if (cntlr->ibiSlot[ptr] == NULL || cntlr->ibiSlot[ptr] != device->ibi) {
650             continue;
651         }
652         cntlr->ibiSlot[ptr] = NULL;
653         if (device->ibi->data != NULL) {
654             OsalMemFree(device->ibi->data);
655         }
656         OsalMemFree(device->ibi);
657         device->ibi = NULL;
658         break;
659     }
660 
661     return HDF_SUCCESS;
662 }
663 
I3cCntlrIbiCallback(struct I3cDevice * device)664 int32_t I3cCntlrIbiCallback(struct I3cDevice *device)
665 {
666     struct I3cIbiData *ibiData = NULL;
667 
668     if (device == NULL) {
669         HDF_LOGW("%s: invalid device!", __func__);
670         return HDF_ERR_INVALID_PARAM;
671     }
672 
673     ibiData = (struct I3cIbiData *)OsalMemCalloc(sizeof(*ibiData));
674     if (ibiData == NULL) {
675         HDF_LOGE("%s: Memcalloc failed", __func__);
676         return HDF_ERR_MALLOC_FAIL;
677     }
678 
679     ibiData->buf = device->ibi->data;
680     ibiData->payload = device->ibi->payload;
681 
682     if (device->ibi->ibiFunc == NULL) {
683         HDF_LOGW("%s: device->ibi or ibiFunc is NULL!", __func__);
684         OsalMemFree(ibiData);
685         return HDF_ERR_NOT_SUPPORT;
686     }
687 
688     if (device->dynaAddr != 0) {
689         (void)device->ibi->ibiFunc(device->cntlr, device->dynaAddr, *ibiData);
690         OsalMemFree(ibiData);
691     } else {
692         (void)device->ibi->ibiFunc(device->cntlr, device->addr, *ibiData);
693         OsalMemFree(ibiData);
694     }
695 
696     return HDF_SUCCESS;
697 }
698 
I3cManagerBind(struct HdfDeviceObject * device)699 static int32_t I3cManagerBind(struct HdfDeviceObject *device)
700 {
701     (void)device;
702     HDF_LOGI("%s:Enter!", __func__);
703     return HDF_SUCCESS;
704 }
705 
I3cManagerInit(struct HdfDeviceObject * device)706 static int32_t I3cManagerInit(struct HdfDeviceObject *device)
707 {
708     int32_t ret;
709     struct I3cManager *manager = NULL;
710 
711     HDF_LOGI("%s: Enter!", __func__);
712     if (device == NULL) {
713         HDF_LOGE("%s: device is NULL", __func__);
714         return HDF_ERR_INVALID_OBJECT;
715     }
716 
717     manager = (struct I3cManager *)OsalMemCalloc(sizeof(*manager));
718     if (manager == NULL) {
719         HDF_LOGE("%s: malloc manager fail!", __func__);
720         return HDF_ERR_MALLOC_FAIL;
721     }
722 
723     ret = OsalMutexInit(&manager->lock);
724     if (ret != HDF_SUCCESS) {
725         HDF_LOGE("%s: mutex init fail:%d", __func__, ret);
726         OsalMemFree(manager);
727         return HDF_FAILURE;
728     }
729     manager->device = device;
730     g_i3cManager = manager;
731     DListHeadInit(&g_i3cDeviceList);
732     OsalSpinInit(&g_listLock);
733 
734     return HDF_SUCCESS;
735 }
736 
I3cManagerRelease(struct HdfDeviceObject * device)737 static void I3cManagerRelease(struct HdfDeviceObject *device)
738 {
739     struct I3cManager *manager = NULL;
740 
741     HDF_LOGI("%s: enter", __func__);
742     if (device == NULL) {
743         HDF_LOGI("%s: device is null", __func__);
744         return;
745     }
746     manager = (struct I3cManager *)device->service;
747     if (manager == NULL) {
748         HDF_LOGI("%s: no service binded!", __func__);
749         return;
750     }
751     g_i3cManager = NULL;
752     OsalMemFree(manager);
753 }
754 
755 struct HdfDriverEntry g_i3cManagerEntry = {
756     .moduleVersion = 1,
757     .Bind = I3cManagerBind,
758     .Init = I3cManagerInit,
759     .Release = I3cManagerRelease,
760     .moduleName = "HDF_PLATFORM_I3C_MANAGER",
761 };
762 HDF_INIT(g_i3cManagerEntry);
763