⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 krua.c

📁 Sigma SMP8634 Mrua v. 2.8.2.0
💻 C
📖 第 1 页 / 共 4 页
字号:
	}		return RM_OK;}RMstatus krua_register_sendcomplete_callback(void *pE, Alsa_callback callback){	struct em8xxxprivate *real_pE = (struct em8xxxprivate *) pE;	real_pE->data_callback = callback;	return RM_OK;}RMstatus krua_unregister_sendcomplete_callback(void *pE){	struct em8xxxprivate *real_pE = (struct em8xxxprivate *) pE;	real_pE->data_callback = NULL;	return RM_OK;}/* ran from tasklet */RMstatus EMhwlibSendBufferComplete (void *context, RMuint32 bus_address){	RMuint32 minor = ((RMuint32) context) >> 16;	RMuint32 poolId = ((RMuint32) context) & 0xffff;	struct em8xxxprivate *pE;	int err;		if (minor >= MAXLLAD) return -EINVAL; 	pE= &(Etable[minor]);	if (pE->pllad == NULL) return -EINVAL;		poolId --;	if (poolId == MAXDMAPOOL) {		if (pE->data_callback != NULL) {			pE->data_callback(pE, bus_address);			return RM_OK;		}		else			return RM_ERROR;	}	/* make sure the dmapool is valid before accessing it */	err = kdmapool_check_opened(pE->pllad, poolId);	if (err != 0)		return RM_ERROR;		PE_RMDBGLOG((LOCALDBG,"release bus address 0x%08x in pool ID %lu\n", bus_address, poolId));	err = kdmapool_release(pE->pllad, poolId, bus_address);	if (err != 0) {		RMDBGLOG((ENABLE, "ERROR: %d, EMhwlibSendBufferComplete() dmapool_release(pool = %lu, phys_addr = 0x%08lx)\n", err, poolId,bus_address));		return RM_ERROR;	}	return RM_OK;} /* ran from tasklet */RMstatus EMhwlibEventComplete(void *context, RMuint32 ModuleID, RMuint32 *Status){	RMuint32 i;	struct em8xxxprivate *pE = (struct em8xxxprivate *) context;	RMuint32 kernel_processed_interrupts=0;	RMstatus err=RM_OK;	for (i=0; i<MAX_EVENT_CALLBACKS ;i++) {		struct em8xxx_event_callback_entry * entry = &(pE->event_callback_array[i]);		if ((ModuleID==entry->ModuleID) && (entry->mask & *Status) && (entry->callback != NULL)) {			RMDBGLOG((EVENTDBG,"Processing event callback for module %lu and mask 0x%08x\n",entry->ModuleID,entry->mask & *Status));			kernel_processed_interrupts |= entry->callback(pE,ModuleID,*Status & entry->mask);		}	}	for (i=0; i<MAX_EVENT_TASKLETS ;i++) {		struct em8xxx_event_tasklet_entry * entry = &(pE->event_tasklet_array[i]);		if ((ModuleID==entry->module_id) && (entry->mask & *Status) && (entry->used)) {			tasklet_schedule(&(entry->tasklet));			/* store interrupts processed in kernel space */			kernel_processed_interrupts |= *Status & entry->mask;		}	}	/* The interrupts processed by registered kernel event	 * callbacks will be cleared by the waiter, otherwise the Hardware	 * librayr is reeentrant	 * Do not propagate those interrupts to user space 	 */	*Status &= ~kernel_processed_interrupts;	if (*Status == 0)		return err;	for (i=0 ; i<pE->event_count ; i++) {		if (pE->event_array[i].module_id == ModuleID) {			RMuint32 new_events, old_events;			old_events = pE->event_array[i].event_mask;			new_events =  (old_events | *Status) ^ (old_events);			kc_atomic_set_mask(&(pE->event_array[i].event_mask), new_events);			*Status &= ~(new_events);			if (new_events)				kc_wake_up_interruptible(pE->wq);				PE_RMDBGLOG((EVENTDBG, "Adding event 0x%lx to module %lu in array index (%lu)\n", new_events, ModuleID, i));			return RM_OK;		}	}	if (i < MAX_WAITERS) {		/* non atomicity is OK here since we validate the index only after event_count is incremented */		pE->event_array[i].module_id = ModuleID;		pE->event_array[i].event_mask = *Status;		PE_RMDBGLOG((EVENTDBG, "Adding event 0x%lx to module %lu in array index (%lu)\n", *Status, ModuleID, i));		*Status = 0;		pE->event_count ++;		kc_wake_up_interruptible(pE->wq);		return RM_OK;	}	RMDBGLOG((ENABLE, "Not enough space to store all modules generating events (%lu)\n", i));	return RM_ERROR;}RMstatus EMhwlibRegisterCleanable(struct EMhwlib *pemhwlib, RMuint32 ModuleID, RMuint32 PropertyID, RMuint32 value){	RMuint32 i;	RMuint32 em8xxx_id;	struct em8xxxprivate *pE;	for (i=0;i<MAXLLAD;i++) 		if (Etable[i].pemhwlib==pemhwlib) break;	if (i==MAXLLAD) {		RMDBGLOG((ENABLE, "Cannot find emhwlib 0x%p\n", pemhwlib));		return RM_ERROR;	}	pE=&Etable[i];	for (i=0;i<MAX_OPENERS;i++) if (pE->openers[i].em8xxx_id==CURRENT_EM8XXX_ID) break;	em8xxx_id = (i==MAX_OPENERS) ? 0 : CURRENT_EM8XXX_ID; 		if (PropertyID == RMMMPropertyID_Free) {		for (i=0 ; i<MAX_MEMORY_AREA ; i++) 			if (pE->mem_area[i].PropertyID==0) break;				if (i==MAX_MEMORY_AREA) {			PE_RMDBGLOG((ENABLE, "EMhwlibRegisterCleanable: no room left for address 0x%08lx in mem_area\n", value));			return RM_ERROR;		}					pE->mem_area[i].em8xxx_id=em8xxx_id;		pE->mem_area[i].refcount = 0;		pE->mem_area[i].ModuleID=ModuleID;		pE->mem_area[i].PropertyID=PropertyID;		pE->mem_area[i].address_start=value;		pE->mem_area[i].address_end=0;		pE->mem_area[i].id = 0;	}	else {		// empty entries are found by PropertyID=0		for (i=0;i<MAX_CLEANABLE;i++) 			if (pE->cl[i].PropertyID==0) break;				if (i==MAX_CLEANABLE) {			PE_RMDBGLOG((ENABLE, "EMhwlibRegisterCleanable: no room left for ModuleID %lu PropertyID %lu.\n", ModuleID, PropertyID));			return RM_ERROR;		}						pE->cl[i].em8xxx_id=em8xxx_id;		pE->cl[i].ModuleID=ModuleID;		pE->cl[i].PropertyID=PropertyID;		pE->cl[i].value=value;			}	PE_RMDBGLOG((CLEANDBG,"EMhwlibRegisterCleanable: #%d %d-%d-%d-0x%08lx\n",		     i,		     em8xxx_id,		     ModuleID,		     PropertyID,		     value));		return RM_OK;}RMstatus EMhwlibUnregisterCleanable(struct EMhwlib *pemhwlib, RMuint32 ModuleID, RMuint32 PropertyID, RMuint32 value){ 	RMuint32 i;	struct em8xxxprivate *pE;		for (i=0;i<MAXLLAD;i++) 		if (Etable[i].pemhwlib==pemhwlib) break;	if (i==MAXLLAD) {		RMDBGLOG((ENABLE, "Cannot find emhwlib 0x%p\n", pemhwlib));		return RM_ERROR;	}	pE=&Etable[i];	if (PropertyID == RMMMPropertyID_Free) {		for (i=0 ; i<MAX_MEMORY_AREA ; i++) {			if ((pE->mem_area[i].ModuleID == ModuleID) 			    && 			    (pE->mem_area[i].PropertyID == PropertyID)			    &&			    (pE->mem_area[i].address_start == value)			    &&			    ((pE->mem_area[i].em8xxx_id == 0) || (pE->mem_area[i].em8xxx_id == CURRENT_EM8XXX_ID))) 				break;		}				if (i==MAX_MEMORY_AREA) {			PE_RMDBGLOG((ENABLE,"EMhwlibUnregisterCleanable mem_area (0x%08x) (from rmmod em8xxx_id %d): not found\n",value, CURRENT_EM8XXX_ID));			return RM_ERROR;		}			if (pE->mem_area[i].refcount > 0) {			PE_RMDBGLOG((LOCALDBG,"EMhwlibUnregisterCleanable mem_area (0x%08x) (from rmmod em8xxx_id %d): refcount %d.\n",value, CURRENT_EM8XXX_ID, pE->mem_area[i].refcount));			return RM_ERROR;		}		else {			pE->mem_area[i].PropertyID=0; // mark entry as empty			pE->mem_area[i].id=0; // mark custom id entry as empty		}	}	else {		for (i=0;i<MAX_CLEANABLE;i++) {			if ((pE->cl[i].ModuleID == ModuleID) 			    && 			    (pE->cl[i].PropertyID == PropertyID)			    &&			    (pE->cl[i].value == value)			    &&			    ((pE->cl[i].em8xxx_id == 0) || (pE->cl[i].em8xxx_id == CURRENT_EM8XXX_ID))) 				break;		}				if (i==MAX_CLEANABLE) {			// hack should we really call cleanup_module -> Exit -> CRCExit -> _Close unconditionally?			PE_RMDBGLOG((ENABLE,"EMhwlibUnregisterCleanable module %lu, prop %lu (from rmmod em8xxx_id %d): not found\n", ModuleID, PropertyID, CURRENT_EM8XXX_ID));			return RM_ERROR;		}				pE->cl[i].PropertyID=0; // mark entry as empty		pE->mem_area[i].id=0; // mark custom id entry as empty	}	PE_RMDBGLOG((CLEANDBG,"EMhwlibUnregisterCleanable: #%d\n",i));	return RM_OK;}static int mem_area_add_refcount(struct em8xxxprivate *pE, RMuint32 address, int incr){	RMuint32 i;	for (i=0 ; i<MAX_MEMORY_AREA ; i++) {		if (pE->mem_area[i].PropertyID == 0)			continue;				if (pE->mem_area[i].address_end == 0) {			struct MM_AreaSize_in_type valueIn;			struct MM_AreaSize_out_type valueOut;			RMstatus status;						valueIn.Address = (void *) pE->mem_area[i].address_start;			status = EMhwlibExchangeProperty(pE->pemhwlib, pE->mem_area[i].ModuleID, RMMMPropertyID_AreaSize, 							 &valueIn, sizeof(valueIn), &valueOut, sizeof(valueOut));			if (status == RM_OK)				pE->mem_area[i].address_end = pE->mem_area[i].address_start + valueOut.Size;			}				if ((address >= pE->mem_area[i].address_start) && (address < pE->mem_area[i].address_end)) {			pE->mem_area[i].refcount += incr;			if (pE->mem_area[i].refcount < 0) { 				PE_RMDBGLOG((ENABLE,"!!!! ERROR !!!!: mem_area_add_refcount address 0x%08x, is negative\n",address));				pE->mem_area[i].refcount = 0;			}			PE_RMDBGLOG((CLEANDBG,"mem_area_add_refcount address 0x%08x, incr %d, refcount %lu\n",address, incr, pE->mem_area[i].refcount));			break;		}	}		if (i==MAX_MEMORY_AREA) {		return -1;	}			return 0;}/* EMhwlib callback so do not spinlock */RMstatus EMhwlibAcquireAddress(struct EMhwlib *pEMhwlib, RMuint32 address){	RMuint32 i;	struct em8xxxprivate *pE;		for (i=0;i<MAXLLAD;i++) 		if (Etable[i].pemhwlib==pEMhwlib) break;	if (i==MAXLLAD) {		RMDBGLOG((ENABLE, "Cannot find emhwlib 0x%p\n", pEMhwlib));		return RM_ERROR;	}		pE=&Etable[i];	if (mem_area_add_refcount(pE, address, 1) < 0) {		PE_RMDBGLOG((ENABLE,"EMhwlibAcquireAddress address 0x%08x not found\n",address));		return RM_ERROR;	}			PE_RMDBGLOG((CLEANDBG,"EMhwlibAcquireAddress address 0x%08x\n",address));	return RM_OK;}/* EMhwlib callback so do not spinlock */RMstatus EMhwlibReleaseAddress(struct EMhwlib *pEMhwlib, RMuint32 address){	RMuint32 i;	struct em8xxxprivate *pE;		for (i=0;i<MAXLLAD;i++) 		if (Etable[i].pemhwlib==pEMhwlib) break;		if (i==MAXLLAD) {		RMDBGLOG((ENABLE, "Cannot find emhwlib 0x%p\n", pEMhwlib));		return RM_ERROR;	}		pE=&Etable[i];	if (mem_area_add_refcount(pE, address, -1) < 0) {		PE_RMDBGLOG((ENABLE,"EMhwlibReleaseAddress address 0x%08x not found\n",address));		return RM_ERROR;	}			return RM_OK;}struct file_operations em8xxx_fops = {	// this replaces MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT pain	owner: THIS_MODULE,		ioctl:em8xxx_ioctl, 	open:em8xxx_open, 	release:em8xxx_release, 	poll: em8xxx_poll};/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// hack this must be related to smallapps/burnsflash/config-* and mambo_project/loader/config.h line 38static inline void patch_pci_config(RMascii *str){  RMascii a1[3], a2[3], a3[2], a4[7], a5[5], a6[5], a7[5], a8[5], a9[3];  sscanf(str, "%2s:%2s.%1s %6s %4s:%4s %4s:%4s %2s\n", a1, a2, a3, a4, a5, a6, a7, a8, a9);  sprintf(str, "0%s:0%s.0%s 0%s 0%s:0%s 0%s:0%s 0%s\n", a1, a2, a3, a4, a5, a6, a7, a8, a9);}/*  Differenciate between the signature of the serial flash (cannot be reread it at 0x40000000)  and the MAMB signature coming shortly after */#define MAMBO_CONFIGSIGN_OFFSET     0xc#define MAMBO_CONFIGSIGN            0x424d414d#define MAMBO_FLASH_OFFSET          0x06000000static int identify(struct em8xxxprivate *pE){	RMuint32 device,subid;	RMascii pci_config[256];	int tmp, ret, revid;#if (EM86XX_CHIP==EM86XX_CHIPID_TANGO2)	// hack: no verification#else	if (gbus_read_uint32(pE->pgbus,MEM_BASE_host_interface+MAMBO_CONFIGSIGN_OFFSET)!=MAMBO_CONFIGSIGN) {		PE_RMDBGLOG((ENABLE,"identify: board has no valid serial flash signature. Skipping.\n"));		if (gbus_read_uint32(pE->pgbus,MEM_BASE_host_interface+MAMBO_CONFIGSIGN_OFFSET + MAMBO_FLASH_OFFSET)!=MAMBO_CONFIGSIGN) {			PE_RMDBGLOG((ENABLE,"identify: board has no valid parallel flash signature. Skipping.\n"));			return -1;		}	}#endif	llad_get_config(pE->pllad, pci_config, 256);	/* some 2.4 kernels have a buggy sscanf, numbers have to start with a decimal digit :-( */	patch_pci_config(pci_config);	ret = kc_sscanf(pci_config, "%x:%x.%x %x %x:%x %x:%x %x",		     &tmp, &tmp, &tmp, &tmp, &tmp, &device, &tmp, &subid, &revid);	if (ret != 9) {		PE_RMDBGLOG((ENABLE,"cannot parse llad pci configuration: %s on item %d\n", pci_config, ret));		return -1;	}	switch (subid) {	case 0:		PE_RMDBGLOG((ENABLE,"identify: board is design #711 (odyssey)\n"));		break;	case 1:		PE_RMDBGLOG((ENABLE,"identify: board is design #706 (mstv)\n"));		break;	case 2:		PE_RMDBGLOG((ENABLE,"identify: board is design #716 (no name) (ONLY ONE DRAM CHIP!!!)\n"));		break;	default:		PE_RMDBGLOG((ENABLE,"identify: board as unknown subid\n"));		break;	}	#if ( (EM86XX_CHIP==EM86XX_CHIPID_MAMBOLIGHT) || (EM86XX_CHIP==EM86XX_CHIPID_MAMBO) )	if ( ! ( ((device & 0xf0) == 0x00) || ((device & 0xf0) == 0x10) ) ) {		RMDBGLOG((ENABLE,"identify: " S_EM86XX_CHIPID " software inserted on other hardware (0x%04x)\n",device));		return -1;	}	// e.m. do not weaken this to a warning#if (EM86XX_REVISION=='C')	if (revid!=3) {		RMDBGLOG((ENABLE,"identify: " S_EM86XX_CHIPID S_EM86XX_REVISION " software on older revid=0x%x\n",revid));		return -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -