📄 krua.c
字号:
rc = (rc == RM_OK) ? 0 : -EINVAL; if ((RMuint32) context != (((pE-Etable) << 16) | (param.poolId + 1))) { PE_RMDBGLOG((LOCALDBG,"Receive data error. bufferpool %lu is not correct, moduleId %lu\n", param.poolId, param.moduleId)); rc = -EINVAL; } if (kc_logging_copy_to_user(param.info, info, param.infoSize) > 0) rc = -EFAULT; if (kc_logging_copy_to_user((char *)arg, ¶m, sizeof(param)) > 0) rc = -EFAULT; if (param.infoSize > MAX_PROPSIZE) kc_vfree(info); } break; case EM8XXX_IOCTL_PREPARE_DATA: { struct em8xxx_data param; struct ReadBufferInfo prop; if (kc_logging_copy_from_user(¶m, (char *)arg, sizeof(param)) > 0) return -EFAULT; prop.address = param.bus_addr; prop.size = param.dataSize; prop.context = (void *) (((pE-Etable) << 16) | (param.poolId + 1)); kc_spin_lock_bh(pE->lock); rc = EMhwlibSetProperty(pE->pemhwlib, param.moduleId, RMGenericPropertyID_AddReadBuffer, &prop, sizeof(prop)); kc_spin_unlock_bh(pE->lock); rc = (rc == RM_OK) ? 0 : -EINVAL; } break; case EM8XXX_IOCTL_WAIT: { struct condition_cookie_type cookie; struct em8xxx_wait param; if (kc_logging_copy_from_user(¶m, (char *)arg, sizeof(struct em8xxx_wait)) > 0) return -EFAULT; RMDBGLOG((EVENTDBG, "Wait Event\n")); cookie.pE = pE; cookie.event_count = param.EventCount; cookie.pEvents = param.pEvents; kc_wait_event_interruptible_timeout(pE->wq, wait_condition, US_TO_JIFFIES(param.TimeOut_us), &cookie); param.EventNum = cookie.event_num; if (kc_logging_copy_to_user((char *)arg, ¶m, sizeof(struct em8xxx_wait)) > 0) return -EFAULT; rc=0; // proper handling of return codes is done in user_src/rua.c } break; case EM8XXX_IOCTL_RESET_EVENT: { struct em8xxx_event param; if (kc_logging_copy_from_user(¶m, (char *)arg, sizeof(struct em8xxx_event)) > 0) return -EFAULT; RMDBGLOG((EVENTDBG, "Reset Event\n")); find_and_clear_event(pE, 1, ¶m); /* reset event cannot fails */ rc = 0; } break; case EM8XXX_IOCTL_SET_EVENT: { RMuint32 mask; if (kc_logging_copy_from_user(&mask, (char *)arg, sizeof(mask)) > 0) return -EFAULT; kc_spin_lock_bh(pE->lock); rc = EMhwlibEventComplete((void *) pE, 0, &mask); kc_spin_unlock_bh(pE->lock); kc_wake_up_interruptible(pE->wq); rc = (rc == RM_OK) ? 0 : -EINVAL; } break; case EM8XXX_IOCTL_ACQUIRE_ADDRESS: { RMuint32 address; if (kc_logging_copy_from_user(&address, (char *)arg, sizeof(address)) > 0) return -EFAULT; kc_spin_lock_bh(pE->lock); rc = EMhwlibAcquireAddress(pE->pemhwlib, address); kc_spin_unlock_bh(pE->lock); rc = (rc == RM_OK) ? 0 : -EINVAL; } break; case EM8XXX_IOCTL_RELEASE_ADDRESS: { RMuint32 address; if (kc_logging_copy_from_user(&address, (char *)arg, sizeof(address)) > 0) return -EFAULT; kc_spin_lock_bh(pE->lock); rc = EMhwlibReleaseAddress(pE->pemhwlib, address); kc_spin_unlock_bh(pE->lock); rc = (rc == RM_OK) ? 0 : -EINVAL; } break; case EM8XXX_IOCTL_SET_ADDRESS_ID: { struct em8xxx_address_id param; RMuint32 i; RMuint32 ID_already_found=0; if (kc_logging_copy_from_user(¶m, (char *)arg, sizeof(param)) > 0) return -EFAULT; rc = 0; for (i=0 ; i<MAX_MEMORY_AREA ; i++) { if (pE->mem_area[i].PropertyID == 0) continue; if (pE->mem_area[i].id==param.id && param.id!=0) { //when id=0, ruasetaddressid resets id of mem_area with corresponding address_start ID_already_found=1; break; } } if (ID_already_found==1){ PE_RMDBGLOG((LOCALDBG,"id %u already found for address address 0x%08lx\n", param.id, pE->mem_area[i].address_start)); rc=-EINVAL; } else { for (i=0 ; i<MAX_MEMORY_AREA ; i++) { if (pE->mem_area[i].PropertyID == 0) continue; if (param.address == pE->mem_area[i].address_start) { pE->mem_area[i].id = param.id; break; } } if (i==MAX_MEMORY_AREA) { rc = -EINVAL; } } } break; case EM8XXX_IOCTL_GET_ADDRESS_ID: { struct em8xxx_address_id param; RMuint32 i; if (kc_logging_copy_from_user(¶m, (char *)arg, sizeof(param)) > 0) return -EFAULT; rc = 0; if (param.id==0) rc=-EINVAL; else { for (i=0 ; i<MAX_MEMORY_AREA ; i++) { if (pE->mem_area[i].PropertyID == 0) continue; if (param.id == pE->mem_area[i].id) { param.address = pE->mem_area[i].address_start; PE_RMDBGLOG((LOCALDBG,"get id %lu from address 0x%08lx\n", param.id, param.address)); break; } } if (i==MAX_MEMORY_AREA) { rc = -EINVAL; } else { if (kc_logging_copy_to_user((char *)arg, ¶m, sizeof(param)) > 0) return -EFAULT; } } } break; default: rc = -EINVAL; } return rc;}static unsigned int em8xxx_poll(struct file *filp, struct poll_table_struct *wait){ struct em8xxxprivate *pE = (struct em8xxxprivate *) filp->private_data; unsigned int mask = 0; kc_poll_wait(filp, pE->wq, wait); if (pE->event_count > 0) mask = POLLPRI; return mask;}static int em8xxx_open(struct inode *i_node, struct file *filp){ struct em8xxxprivate *pE; int rc=-EINVAL; RMuint32 i; /* in case we do not use devfs, fills private_data here */ if (filp->private_data == NULL) { int minor=MINOR(i_node->i_rdev); if (minor >= MAXLLAD) return -EINVAL; filp->private_data = Etable + minor; } pE = (struct em8xxxprivate *) filp->private_data; if (pE->pllad == NULL) return -EINVAL; kc_spin_lock_bh(pE->lock);#if (RMPLATFORM!=RMPLATFORMID_AOE6_SH4) // find em8xxx_id in the table for (i=0;i<MAX_OPENERS;i++) if (pE->openers[i].em8xxx_id==CURRENT_EM8XXX_ID) break; if (i==MAX_OPENERS) { // find empty entry for (i=0;i<MAX_OPENERS;i++) if (pE->openers[i].em8xxx_id==0) break; if (i==MAX_OPENERS) { PE_RMDBGLOG((ENABLE,"em8xxx_open: too many openers (increase MAX_OPENERS)\n")); goto over; } pE->openers[i].em8xxx_id=CURRENT_EM8XXX_ID; PE_RMDBGLOG((LOCALDBG,"em8xxx_open: #%d new em8xxx_id %d\n", i,pE->openers[i].em8xxx_id)); } pE->openers[i].open_count++;#endif pE->total_open_count++; rc=0;#if (RMPLATFORM!=RMPLATFORMID_AOE6_SH4) PE_RMDBGLOG((LOCALDBG,"em8xxx_open: #%d em8xxx_id %d open_count=%d\n", i,pE->openers[i].em8xxx_id,pE->openers[i].open_count));#endif over: kc_spin_unlock_bh(pE->lock); return rc;}static int em8xxx_release(struct inode *i_node, struct file *filp){ struct em8xxxprivate *pE = (struct em8xxxprivate *) filp->private_data; RMuint32 i; if (pE->pllad == NULL) return -EINVAL; kc_spin_lock_bh(pE->lock); #if (RMPLATFORM!=RMPLATFORMID_AOE6_SH4) // find em8xxx_id in the table for (i=0 ; i<MAX_OPENERS ; i++) if (pE->openers[i].em8xxx_id==CURRENT_EM8XXX_ID) break; if (i>=MAX_OPENERS) { PE_RMDBGLOG((ENABLE,"em8xxx_release: too many openers (increase MAX_OPENERS)\n")); kc_spin_unlock_bh(pE->lock); return -EINVAL; } pE->openers[i].open_count--; PE_RMDBGLOG((LOCALDBG,"em8xxx_release: #%d em8xxx_id %d open_count=%d\n", i,pE->openers[i].em8xxx_id,pE->openers[i].open_count)); if (pE->openers[i].open_count==0) { // free entry PE_RMDBGLOG((LOCALDBG,"em8xxx_release: #%d em8xxx_id %d disappears\n",i,pE->openers[i].em8xxx_id)); pE->openers[i].em8xxx_id=0; if (emergency_exit(pE)>0) PE_RMDBGLOG((ENABLE,"em8xxx_release: unclean exit\n")); }#endif pE->total_open_count--; if (pE->total_open_count == 0) { /* if no process accesses the driver clear the event array */ for (i=0 ; i<pE->event_count ; i++) { /* clear mask inside emhwlib */ EMhwlibSetProperty(pE->pemhwlib, pE->event_array[i].module_id, RMGenericPropertyID_ClearEventMask, &(pE->event_array[i].event_mask), sizeof(pE->event_array[i].event_mask)); } pE->event_count = 0; } kc_spin_unlock_bh(pE->lock); return 0;}static void em8xxx_tasklet(unsigned long data){ struct em8xxxprivate *pE = (struct em8xxxprivate *) data; RMuint32 irq_status; unsigned long flags; /* Get the status and clear it atomically. If the same event comes during EMhwlibProcessInterrupt, we do not lose it. */ kc_spin_lock_irqsave(pE->lock, &flags); irq_status = pE->tasklet_irq_status; pE->tasklet_irq_status = 0; kc_spin_unlock_irqrestore(pE->lock, flags); PE_RMDBGLOG((LOCALDBG,"irq_status = 0x%08lx\n", irq_status)); kc_spin_lock(pE->lock); EMhwlibProcessInterrupt(pE->pemhwlib, irq_status, (void *) pE); kc_spin_unlock(pE->lock);}RMstatus krua_register_event_callback_as_tasklet(void *pE, RMuint32 module_id, RMuint32 mask, void (*callback)(RMuint32), RMuint32 callback_data, RMuint32 *tasklet_id){ RMuint32 i; struct em8xxxprivate *real_pE = (struct em8xxxprivate *) pE; for (i=0;i<MAX_EVENT_TASKLETS;i++) { struct em8xxx_event_tasklet_entry * entry = &(real_pE->event_tasklet_array[i]); if (entry->used == 0) break; } if (i == MAX_EVENT_TASKLETS) { RMDBGLOG((ENABLE,"Cannot register event tasklet : event callback array is full !\n")); return RM_ERROR; } RMDBGLOG((ENABLE,"Registering event callback with module_id %lu and mask 0x%08x \n",module_id,mask)); real_pE->event_tasklet_array[i].used = 1; real_pE->event_tasklet_array[i].module_id = module_id; real_pE->event_tasklet_array[i].mask = mask; tasklet_init(&(real_pE->event_tasklet_array[i].tasklet), callback, callback_data); *tasklet_id = i; return RM_OK;}RMstatus krua_unregister_event_callback_as_tasklet(void *pE, RMuint32 tasklet_id){ struct em8xxxprivate *real_pE = (struct em8xxxprivate *) pE; if (tasklet_id >= MAX_EVENT_CALLBACKS) { RMDBGLOG((ENABLE,"Wrong tasklet_id, cannot unregister tasklet\n")); return RM_ERROR; } real_pE->event_tasklet_array[tasklet_id].used = 0; return RM_OK;}RMstatus krua_register_event_callback(void *pE, RMuint32 ModuleID, RMuint32 mask, Event_callback callback){ RMuint32 i; struct em8xxxprivate *real_pE = (struct em8xxxprivate *) pE; for (i=0;i<MAX_EVENT_CALLBACKS;i++) { struct em8xxx_event_callback_entry * entry = &(real_pE->event_callback_array[i]); if (entry->callback == NULL) break; } if (i == MAX_EVENT_CALLBACKS) { RMDBGLOG((ENABLE,"Cannot register event callback : event callback array is full !\n")); return RM_ERROR; } else { RMDBGLOG((ENABLE,"Registering event callback with module_id %lu and mask 0x%08x \n",ModuleID,mask)); real_pE->event_callback_array[i] = (struct em8xxx_event_callback_entry) { ModuleID , mask , callback }; } return RM_OK;}RMstatus krua_unregister_event_callback(void *pE, RMuint32 ModuleID, Event_callback callback){ RMuint32 i; RMbool found=FALSE; struct em8xxxprivate *real_pE = (struct em8xxxprivate *) pE; for (i=0;i<MAX_EVENT_CALLBACKS;i++) { struct em8xxx_event_callback_entry * entry = &(real_pE->event_callback_array[i]); if ((entry->callback == callback) && (entry->ModuleID == ModuleID)) { RMDBGLOG((ENABLE,"Unregistering callback for module_id %lu and mask 0x%08x \n",entry->ModuleID,entry->mask)); found = TRUE; real_pE->event_callback_array[i].ModuleID = 0; real_pE->event_callback_array[i].mask = 0; real_pE->event_callback_array[i].callback = NULL; break; } } if (!found) { RMDBGLOG((ENABLE,"Cannot find event callback to unregister for moduleID %lu\n",ModuleID)); return RM_ERROR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -