//------------------------------------------------------------------------------ static void SYSRAM_FreeUser(SYSRAM_USER_ENUM const User) { SYSRAM_MEM_BANK_ENUM const MemBankNo = SYSRAM_GetMemBankNo(User); // switch(MemBankNo) { case SYSRAM_MEM_BANK_BAD: case SYSRAM_MEM_BANK_AMOUNT: { // Do nothing. break; } default: { if(SYSRAM_FreeUserPhy(User, MemBankNo)) { SYSRAM_UnlockUser(User); } else { LOG_ERR("Cannot free User(%d)",User); SYSRAM_DumpLayout(); } break; } } }
/* ------------------------------------------------------------------------------ */ static MBOOL SYSRAM_IsLegalSizeToAlloc(SYSRAM_MEM_BANK_ENUM const MemBankNo, SYSRAM_USER_ENUM const User, MUINT32 const Size) { MUINT32 MaxSize = 0; /* (1) Check the memory pool. */ switch (MemBankNo) { case SYSRAM_MEM_BANK_BAD: case SYSRAM_MEM_BANK_AMOUNT: { /* Illegal Memory Pool: return "illegal" */ /* Shouldn't happen. */ goto EXIT; } default: { break; } } /* (2) */ /* Here we use the dynamic memory pools. */ MaxSize = SysramUserSize[User]; /* */ EXIT: if (MaxSize < Size) { LOG_ERR("[User:%s]requested size(0x%lX) > max size(0x%lX)", SysramUserName[User], Size, MaxSize); SYSRAM_DumpLayout(); return MFALSE; } return MTRUE; }
/* ------------------------------------------------------------------------------ */ static int SYSRAM_Release(struct inode *pInode, struct file *pFile) { MUINT32 Index = 0; MUINT32 Sec = 0, USec = 0; MUINT64 Time64 = 0; SYSRAM_PROC_STRUCT *pProc; /* */ SYSRAM_GetTime(&Time64, &Sec, &USec); /* */ LOG_MSG("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)", current->comm, current->pid, current->tgid, Sec, USec); /* */ if (pFile->private_data != NULL) { pProc = (SYSRAM_PROC_STRUCT *) (pFile->private_data); /* */ if (pProc->Pid != 0 || pProc->Tgid != 0 || pProc->Table != 0) { /* */ LOG_WRN("Proc:Name(%s),pid(%d),tgid(%d),Table(0x%08lX),Time(%ld.%06ld)", pProc->ProcName, pProc->Pid, pProc->Tgid, pProc->Table, pProc->TimeS, pProc->TimeUS); /* */ if (pProc->Table) { LOG_WRN("Force to release"); /* LOG_WRN("Proc:Name(%s),pid(%d),tgid(%d),Table(0x%08lX),Time(%ld.%06ld)", pProc->ProcName, pProc->Pid, pProc->Tgid, pProc->Table, pProc->TimeS, pProc->TimeUS); */ SYSRAM_DumpLayout(); /* */ for (Index = 0; Index < SYSRAM_USER_AMOUNT; Index++) { if (pProc->Table & (1 << Index)) { SYSRAM_IOC_Free((SYSRAM_USER_ENUM) Index); } } } } /* */ kfree(pFile->private_data); pFile->private_data = NULL; } else { LOG_WRN("private_data is NULL"); /* LOG_WRN("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)", current->comm, current->pid, current->tgid, Sec, USec); */ } /* */ return 0; }
/* ------------------------------------------------------------------------------ */ static MUINT32 SYSRAM_IOC_Alloc(SYSRAM_USER_ENUM const User, MUINT32 const Size, MUINT32 Alignment, MUINT32 const TimeoutMS) { MUINT32 Addr = 0; MINT32 TimeOut = 0; /* */ if (SYSRAM_IsBadOwner(User)) { LOG_ERR("User(%d) out of range(%d)", User, SYSRAM_USER_AMOUNT); return 0; } /* */ if (0 == Size) { LOG_ERR("[User:%s]allocates 0 size!", SysramUserName[User]); return 0; } /* */ Addr = SYSRAM_TryAllocUser(User, Size, Alignment); if (0 != Addr /* success */ || 0 == TimeoutMS /* failure without a timeout specified */ ) { goto EXIT; } /* */ TimeOut = wait_event_interruptible_timeout(Sysram.WaitQueueHead, 0 != (Addr = SYSRAM_TryAllocUser(User, Size, Alignment)), SYSRAM_MsToJiffies(TimeoutMS)); /* */ if (0 == TimeOut && 0 == Addr) { LOG_ERR("[User:%s]allocate timeout", SysramUserName[User]); } /* */ EXIT: if (0 == Addr) { /* Failure */ LOG_ERR("[User:%s]fails to allocate.Size(%lu),Alignment(%lu),TimeoutMS(%lu)", SysramUserName[User], Size, Alignment, TimeoutMS); SYSRAM_DumpLayout(); } else { /* Success */ if ((1 << User) & SysramLogUserMask) { LOG_MSG("[User:%s]%lu bytes OK", SysramUserName[User], Size); } } /* */ return Addr; }
//------------------------------------------------------------------------------ static long SYSRAM_Ioctl( struct file* pFile, unsigned int Cmd, unsigned long Param) { MINT32 Ret = 0; MUINT32 Sec = 0,USec = 0; MUINT64 Time64 = 0; SYSRAM_PROC_STRUCT* pProc = (SYSRAM_PROC_STRUCT*)pFile->private_data; SYSRAM_ALLOC_STRUCT Alloc; SYSRAM_USER_ENUM User; // SYSRAM_GetTime(&Time64, &Sec, &USec); /* LOG_MSG("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)", current->comm, current->pid, current->tgid, Sec, USec); */ if(pFile->private_data == NULL) { LOG_WRN("private_data is NULL."); Ret = -EFAULT; goto EXIT; } // switch(Cmd) { case SYSRAM_ALLOC: { if(copy_from_user(&Alloc, (void*)Param, sizeof(SYSRAM_ALLOC_STRUCT)) == 0) { if(SYSRAM_IsBadOwner(Alloc.User)) { LOG_ERR("User(%d) out of range(%d)",Alloc.User,SYSRAM_USER_AMOUNT); Ret = -EFAULT; goto EXIT; } // Alloc.Addr = SYSRAM_IOC_Alloc( Alloc.User, Alloc.Size, Alloc.Alignment, Alloc.TimeoutMS); if(Alloc.Addr != 0) { SYSRAM_SpinLock(); pProc->Table |= (1 << Alloc.User); if(pProc->Tgid == 0) { pProc->Pid = current->pid; pProc->Tgid = current->tgid; strcpy(pProc->ProcName,current->comm); SYSRAM_SpinUnlock(); } else { SYSRAM_SpinUnlock(); if(pProc->Tgid != current->tgid) { LOG_ERR("Tgid is inconsistent"); Ret = -EFAULT; } } } else { Ret = -EFAULT; } // if(copy_to_user((void*)Param, &Alloc, sizeof(SYSRAM_ALLOC_STRUCT)) ) { LOG_ERR("copy to user failed"); Ret = -EFAULT; } } else { LOG_ERR("copy_from_user fail"); Ret = -EFAULT; } break; } // case SYSRAM_FREE: { if(copy_from_user(&User, (void*)Param, sizeof(SYSRAM_USER_ENUM)) == 0) { if(SYSRAM_IsBadOwner(User)) { LOG_ERR("User(%d) out of range(%d)",User,SYSRAM_USER_AMOUNT); Ret = -EFAULT; goto EXIT; } // SYSRAM_SpinLock(); if((pProc->Table) & (1 << User)) { SYSRAM_SpinUnlock(); SYSRAM_IOC_Free(User); SYSRAM_SpinLock(); // pProc->Table &= (~(1 << User)); if(pProc->Table == 0) { pProc->Pid = 0; pProc->Tgid = 0; strcpy(pProc->ProcName,SYSRAM_PROC_NAME); } SYSRAM_SpinUnlock(); } else { SYSRAM_SpinUnlock(); LOG_WRN("Freeing unallocated buffer user(%d)",User); Ret = -EFAULT; } } else { LOG_ERR("copy_from_user fail"); Ret = -EFAULT; } break; } case SYSRAM_DUMP: { SYSRAM_DumpLayout(); break; } default: { LOG_WRN("No such command"); Ret = -EINVAL; break; } } // EXIT: if(Ret != 0) { LOG_ERR("Fail"); LOG_ERR("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)", current->comm, current->pid, current->tgid, Sec, USec); if(pFile->private_data != NULL) { LOG_ERR("Proc:Name(%s),pid(%d),tgid(%d),Table(0x%08lX),Time(%ld.%06ld)", pProc->ProcName, pProc->Pid, pProc->Tgid, pProc->Table, Sec, USec); } } // return Ret; }
//------------------------------------------------------------------------------ static int SYSRAM_Flush( struct file* pFile, fl_owner_t Id) { MUINT32 Index = 0; MUINT32 Sec = 0,USec = 0; MUINT64 Time64 = 0; SYSRAM_PROC_STRUCT* pProc; // SYSRAM_GetTime(&Time64, &Sec, &USec); // LOG_MSG("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)", current->comm, current->pid, current->tgid, Sec, USec); // if(pFile->private_data != NULL) { pProc = (SYSRAM_PROC_STRUCT *)pFile->private_data; // if( pProc->Pid != 0 || pProc->Tgid != 0 || pProc->Table != 0) { // LOG_WRN("Proc:Name(%s),pid(%d),tgid(%d),Table(0x%08lX),Time(%ld.%06ld)", pProc->ProcName, pProc->Pid, pProc->Tgid, pProc->Table, pProc->TimeS, pProc->TimeUS); // if( pProc->Tgid == 0 && pProc->Table != 0) { LOG_ERR("No Tgid info"); /* LOG_ERR("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)", current->comm, current->pid, current->tgid, Sec, USec); LOG_ERR("Proc:Name(%s),pid(%d),tgid(%d),Table(0x%08lX),Time(%ld.%06ld)", pProc->ProcName, pProc->Pid, pProc->Tgid, pProc->Table, pProc->TimeS, pProc->TimeUS); */ } else if( (pProc->Tgid == current->tgid) || ((pProc->Tgid != current->tgid) && (strcmp(current->comm, "binder") == 0))) { if(pProc->Table) { LOG_WRN("Force to release"); /* LOG_WRN("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)", current->comm, current->pid, current->tgid, Sec, USec); */ SYSRAM_DumpLayout(); // for(Index = 0 ; Index < SYSRAM_USER_AMOUNT; Index++) { if(pProc->Table & (1 << Index)) { SYSRAM_IOC_Free((SYSRAM_USER_ENUM)Index); } } // pProc->Table= 0; } } } } else { LOG_WRN("private_data is NULL"); /* LOG_WRN("Cur:Name(%s),pid(%d),tgid(%d),Time(%ld.%06ld)", current->comm, current->pid, current->tgid, Sec, USec); */ } // return 0; }