📄 krua.c
字号:
}#else#error unsupported revision#endif#elif (EM86XX_CHIP==EM86XX_CHIPID_TANGOLIGHT) if ( ! (((device & 0xff) == 0x20) || ((device & 0xff) == 0x21)) ) { 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!=0x82) { RMDBGLOG((ENABLE,"identify: " S_EM86XX_CHIPID S_EM86XX_REVISION " software on older revid=0x%x\n",revid)); return -1; }#else#error unsupported revision#endif#elif (EM86XX_CHIP==EM86XX_CHIPID_TANGO15) if ( ! (((device & 0xff) == 0x22) || ((device & 0xff) == 0x23) || ((device & 0xff) == 0x24) || ((device & 0xff) == 0x25)) ) { 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<='A') if ((revid!=0x81) && (revid!=0x82)) { RMDBGLOG((ENABLE,"identify: " S_EM86XX_CHIPID S_EM86XX_REVISION " software on revid=0x%x\n",revid)); return -1; }#elif ((EM86XX_REVISION=='B') || (EM86XX_REVISION=='C')) // adding rev.C support if ((revid!=0x82) && (revid!=0x83)) { RMDBGLOG((ENABLE,"identify: " S_EM86XX_CHIPID S_EM86XX_REVISION " software on revid=0x%x\n",revid)); return -1; }#else#error unsupported revision#endif#elif (EM86XX_CHIP==EM86XX_CHIPID_TANGO2) if ( ! ((device & 0xf0) == 0x30) ) { 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<=3) if (revid!=0x81) { RMDBGLOG((ENABLE,"identify: " S_EM86XX_CHIPID S_EM86XX_REVISION " software on revid=%#x\n",revid)); return -1; }#elif (EM86XX_REVISION==4) if ((revid!=0x82) || !isES4(pE->pgbus)) { RMDBGLOG((ENABLE,"identify: " S_EM86XX_CHIPID S_EM86XX_REVISION " software on revid %#x\n",revid)); return -1; }#elif (EM86XX_REVISION==5) if ((revid!=0x82) || isES4(pE->pgbus)) { RMDBGLOG((ENABLE,"identify: " S_EM86XX_CHIPID S_EM86XX_REVISION " software on revid %#x\n",revid)); return -1; }#elif ((EM86XX_REVISION==6)||(EM86XX_REVISION==7)||(EM86XX_REVISION=='A')||(EM86XX_REVISION=='B')||(EM86XX_REVISION==8)||(EM86XX_REVISION==9)||(EM86XX_REVISION=='C')) /* 2006dec5: accept to load the driver build for ES6 and ES7 on ES4, ES5, ES6, ES7, ES8. See bug #4472 */ if (revid<0x82) { /* 0x85 for ES8, 0x86 for ES9/RevC */ RMDBGLOG((ENABLE,"identify: " S_EM86XX_CHIPID S_EM86XX_REVISION " software on revid %#x\n",revid)); return -1; }#else#error unsupported revision#endif #else#error EM86XX_CHIP is not set in RMCFLAGS: refer to emhwlib/include/emhwlib_chips.h.#endif RMDBGLOG((ENABLE, "identify: device 0x%04x 0x%x accepted with software " S_EM86XX_CHIPID S_EM86XX_REVISION "\n",device,revid)); return 0;}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int init_module(void){ char dev[3]; RMuint32 number_of_probed_em8xxx = 0, minor = 0; RMuint32 InterruptEnableMask; RMDBGLOG((ENABLE,"init_module: begun\n")); /* add the em8xxx driver entry */ add_driver_proc_entry(); while (minor < MAXLLAD) { memset(&Etable[minor],0,sizeof(struct em8xxxprivate)); kc_spin_lock_init(&Etable[minor].lock); kc_sprintf(dev, "%d", minor); Etable[minor].pllad = llad_open(dev); if (Etable[minor].pllad == NULL) break; Etable[minor].pgbus = gbus_open(Etable[minor].pllad); if (Etable[minor].pgbus == NULL) { RMDBGLOG((ENABLE,"Cannot open gbus\n")); goto clean_llad; } if (identify(&Etable[minor]) != 0) { RMDBGLOG((ENABLE,"software/hardware conflict --- cannot go on\n")); goto clean_gbus; } Etable[minor].pemhwlib = (struct EMhwlib *) kc_vmalloc(EMhwlibGetSize()); if (Etable[minor].pemhwlib == NULL) { RMDBGLOG((ENABLE,"Cannot allocate %lu bytes for emhwlib\n", EMhwlibGetSize())); goto clean_gbus; } Etable[minor].insmod_em8xxx_id = CURRENT_EM8XXX_ID; kc_init_waitqueue_head(&Etable[minor].wq); if (EMhwlibCreate(Etable[minor].pgbus, Etable[minor].pemhwlib) != RM_OK) { RMDBGLOG((ENABLE,"Cannot create emhwlib for device %lu\n", minor)); goto clean_emhwlib_allocation; } // Enable the PCI interrupts (They are disabled by default) InterruptEnableMask = 0xFFFFFFFF; EMhwlibSetProperty(Etable[minor].pemhwlib, CPUBlock, RMCPUBlockPropertyID_PCIEnableInterrupt, &InterruptEnableMask, sizeof(InterruptEnableMask)); /* some interrupts may have already be sent */ EMhwlibProcessInterrupt(Etable[minor].pemhwlib, LLAD_SOFT_INTERRUPT, (void *) &(Etable[minor])); Etable[minor].buf1 = (RMuint8 *) kc_vmalloc(2 * MAX_PROPSIZE); if (Etable[minor].buf1 == NULL) { RMDBGLOG((ENABLE,"Cannot allocate ioctl temporary buffers\n")); goto clean_emhwlib_creation; } Etable[minor].buf2 = Etable[minor].buf1 + MAX_PROPSIZE; kc_tasklet_init(&(Etable[minor].tasklet), em8xxx_tasklet, (unsigned long) &(Etable[minor])); mumk_register_tasklet(Etable[minor].pgbus, Etable[minor].tasklet, &(Etable[minor].tasklet_irq_status), LLAD_SOFT_INTERRUPT | LLAD_WAIT_WRITE_COMPLETE); // Add the /proc/driver/em8xxx/[minor] where [minor] is 0.. add_board_proc_entry(minor); // Add the /proc/driver/em8xxx/[minor]/resources add_board_proc_files(minor, &(Etable[minor])); number_of_probed_em8xxx ++; goto next_device; clean_emhwlib_creation: EMhwlibDestroy(Etable[minor].pemhwlib); clean_emhwlib_allocation: kc_vfree(Etable[minor].pemhwlib); Etable[minor].pemhwlib = NULL; clean_gbus: gbus_close(Etable[minor].pgbus); Etable[minor].pgbus = NULL; clean_llad: llad_close(Etable[minor].pllad); Etable[minor].pllad = NULL; next_device: minor++; } if (number_of_probed_em8xxx==0) goto wayout; if (register_chrdev(major, EM8XXX_DEVICE_NAME, &em8xxx_fops)<0) { RMDBGLOG((ENABLE,"init_module: Can't register module!\n")); goto wayout; }#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) { char devfs_name[64]; /* call will return -1 if CONFIG_DEVFS_FS is undefined */ devfs_major = devfs_alloc_major(DEVFS_SPECIAL_CHR); /* does nothing if CONFIG_DEVFS_FS is undefined */ for (minor=0 ; minor<MAXLLAD; minor++) { if (Etable[minor].pllad == NULL) continue; sprintf(devfs_name, "%s%lu", EM8XXX_DEVICE_NAME, minor); Etable[minor].devfs_handle = kc_devfs_register(NULL, devfs_name, DEVFS_FL_DEFAULT, (devfs_major>0) ? devfs_major : major, minor, S_IFCHR | S_IRUGO | S_IWUGO, &em8xxx_fops, Etable + minor); if (Etable[minor].devfs_handle == NULL) RMDBGLOG((ENABLE,"init_module: cannot register devfs for device %s\n", devfs_name)); } }#else // see post-halloween document: devfs will be obsoleted in favour of udev (E.M.)#endif RMDBGLOG((ENABLE,"init_module: done. Found %lu em8xxx\n", number_of_probed_em8xxx)); return 0; wayout: RMDBGLOG((ENABLE,"init_module: no valid board found\n")); return -EINVAL;}void cleanup_module(void){ RMuint32 minor; RMDBGLOG((ENABLE,"cleanup_module: begun\n"));#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) /* does nothing if CONFIG_DEVFS_FS is undefined */ for (minor=0 ; minor<MAXLLAD ; minor++) { if (Etable[minor].devfs_handle != NULL) { kc_devfs_unregister(Etable[minor].devfs_handle); } } /* does nothing if CONFIG_DEVFS_FS is undefined */ if (devfs_major > 0) devfs_dealloc_major(DEVFS_SPECIAL_CHR, devfs_major); #endif unregister_chrdev(major, EM8XXX_DEVICE_NAME); for (minor=0 ; minor<MAXLLAD ; minor++) { if (Etable[minor].pllad != NULL) { RMstatus err; kc_tasklet_disable(Etable[minor].tasklet); mumk_unregister_tasklet(Etable[minor].pgbus, Etable[minor].tasklet); kc_tasklet_deinit(Etable[minor].tasklet); kc_deinit_waitqueue_head(Etable[minor].wq); kc_vfree(Etable[minor].buf1); // remove the /proc/driver/em8xxx/[minor]/... rm_board_proc_files(minor); // remove the /proc/driver/em8xxx/[minor] rm_board_proc_entry(minor); err = EMhwlibDestroy(Etable[minor].pemhwlib); if(RMFAILED(err)){ RMDBGLOG((ENABLE, "ERROR: EMhwlibDestroy failed\n")); } Etable[minor].insmod_em8xxx_id = 0; kc_vfree(Etable[minor].pemhwlib); gbus_close(Etable[minor].pgbus); llad_close(Etable[minor].pllad); kc_spin_lock_deinit(Etable[minor].lock); } } // remove the /proc/driver/em8xxx rm_driver_proc_entry(); RMDBGLOG((ENABLE,"cleanup_module: done\n"));} RMstatus krua_get_pointers(RMuint32 chip_id, RMuint32 *pe, RMuint32 *pem){ if(chip_id>=MAXLLAD){ return RM_ERROR; } *pe = (RMuint32)&Etable[chip_id]; *pem = (RMuint32)Etable[chip_id].pemhwlib; RMDBGLOG((ENABLE, "I have pe %ld and pem %ld\n", pe, pem)); return RM_OK;}RMstatus krua_set_property(void*pE,RMuint32 ModuleID, RMuint32 PropertyID, void *pValue,RMuint32 ValueSize){ RMstatus rc; struct em8xxxprivate *pe= (struct em8xxxprivate *)pE; //RMDBGLOG((ENABLE,"krua_set_property: enable BH spinlock\n")); kc_spin_lock_bh(pe->lock); rc = EMhwlibSetProperty(pe->pemhwlib, ModuleID, PropertyID, pValue, ValueSize); kc_spin_unlock_bh(pe->lock); //RMDBGLOG((ENABLE,"krua_set_property: disable BH spinlock\n")); return rc;}RMstatus krua_get_property(void*pE,RMuint32 ModuleID, RMuint32 PropertyID, void *pValue,RMuint32 ValueSize){ RMstatus rc; struct em8xxxprivate *pe= (struct em8xxxprivate *)pE; //RMDBGLOG((ENABLE,"krua_get_property: enable BH spinlock\n")); kc_spin_lock_bh(pe->lock); rc = EMhwlibGetProperty(pe->pemhwlib, ModuleID, PropertyID, pValue, ValueSize); kc_spin_unlock_bh(pe->lock); //RMDBGLOG((ENABLE,"krua_get_property: disable BH spinlock\n")); return rc;}RMstatus krua_exchange_property(void*pE,RMuint32 ModuleID, RMuint32 PropertyID, void *pValueIn,RMuint32 ValueInSize,void *pValueOut,RMuint32 ValueOutSize){ RMstatus rc; struct em8xxxprivate *pe= (struct em8xxxprivate *)pE; //RMDBGLOG((ENABLE,"krua_exchange_property: enable BH spinlock\n")); kc_spin_lock_bh(pe->lock); rc=EMhwlibExchangeProperty(pe->pemhwlib, ModuleID, PropertyID, pValueIn, ValueInSize,pValueOut, ValueOutSize); kc_spin_unlock_bh(pe->lock); //RMDBGLOG((ENABLE,"krua_exchange_property: disable BH spinlock\n")); return rc; }RMstatus krua_set_property_from_bh(void*pE,RMuint32 ModuleID, RMuint32 PropertyID, void *pValue,RMuint32 ValueSize){ RMstatus rc; struct em8xxxprivate *pe= (struct em8xxxprivate *)pE; //RMDBGLOG((ENABLE,"krua_set_property_from_bh: enable spinlock\n")); kc_spin_lock(pe->lock); rc = EMhwlibSetProperty(pe->pemhwlib, ModuleID, PropertyID, pValue, ValueSize); kc_spin_unlock(pe->lock); //RMDBGLOG((ENABLE,"krua_set_property_from_bh: disable spinlock\n")); return rc;}RMstatus krua_get_property_from_bh(void*pE,RMuint32 ModuleID, RMuint32 PropertyID, void *pValue,RMuint32 ValueSize){ RMstatus rc; struct em8xxxprivate *pe= (struct em8xxxprivate *)pE; //RMDBGLOG((ENABLE,"krua_get_property_from_bh: enable spinlock\n")); kc_spin_lock(pe->lock); rc = EMhwlibGetProperty(pe->pemhwlib, ModuleID, PropertyID, pValue, ValueSize); kc_spin_unlock(pe->lock); //RMDBGLOG((ENABLE,"krua_get_property_from_bh: disable spinlock\n")); return rc;}RMstatus krua_exchange_property_from_bh(void*pE,RMuint32 ModuleID, RMuint32 PropertyID, void *pValueIn,RMuint32 ValueInSize,void *pValueOut,RMuint32 ValueOutSize){ struct em8xxxprivate *pe= (struct em8xxxprivate *)pE; RMstatus rc; //RMDBGLOG((ENABLE,"krua_exchange_property_from_bh: enable spinlock\n")); kc_spin_lock(pe->lock); rc=EMhwlibExchangeProperty(pe->pemhwlib, ModuleID, PropertyID, pValueIn, ValueInSize,pValueOut, ValueOutSize); kc_spin_unlock(pe->lock); // RMDBGLOG((ENABLE,"krua_exchange_property_from_bh: disable spinlock\n")); return rc;}EXPORT_SYMBOL(Etable);EXPORT_SYMBOL(EMhwlibExchangeProperty);EXPORT_SYMBOL(EMhwlibSendBuffer);EXPORT_SYMBOL(EMhwlibReceiveBuffer);EXPORT_SYMBOL(EMhwlibSetProperty);EXPORT_SYMBOL(EMhwlibGetProperty);EXPORT_SYMBOL(RMDBGLOG_implementation);EXPORT_SYMBOL(EMhwlibReleaseAddress);EXPORT_SYMBOL(RMDBGPRINT_implementation);EXPORT_SYMBOL(EMhwlibUnregisterCleanable);EXPORT_SYMBOL(EMhwlibAcquireAddress);EXPORT_SYMBOL(EMhwlibSendBufferComplete);EXPORT_SYMBOL(EMhwlibRegisterCleanable);EXPORT_SYMBOL(krua_register_sendcomplete_callback);EXPORT_SYMBOL(krua_unregister_sendcomplete_callback);EXPORT_SYMBOL(krua_register_event_callback);EXPORT_SYMBOL(krua_unregister_event_callback);EXPORT_SYMBOL(krua_register_event_callback_as_tasklet);EXPORT_SYMBOL(krua_unregister_event_callback_as_tasklet);EXPORT_SYMBOL(krua_get_pointers);EXPORT_SYMBOL(EMhwlibEventComplete);EXPORT_SYMBOL(krua_set_property);EXPORT_SYMBOL(krua_exchange_property);EXPORT_SYMBOL(krua_set_property_from_bh);EXPORT_SYMBOL(krua_exchange_property_from_bh);/* HACK : There is a problem when EXPORT_SYMBOL_NOVERS are done on 8624 (too many exports? kernel memory full?). For now, since they are not used anywhere yet, following symbols are not exported.*/ /* EXPORT_SYMBOL(krua_get_property_from_bh);EXPORT_SYMBOL(krua_get_property);*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -