static int MIXCOM_exit(struct net_device *dev) { struct comx_channel *ch = dev->priv; struct mixcom_privdata *hw = ch->HW_privdata; if(hw->channel==0 && TWIN(dev)) { return -EBUSY; } if(hw->channel==1 && TWIN(dev)) { TWIN(TWIN(dev))=NULL; } kfree(ch->HW_privdata); remove_proc_entry(FILENAME_IO, ch->procdir); remove_proc_entry(FILENAME_IRQ, ch->procdir); #if 0 remove_proc_entry(FILENAME_CLOCK, ch->procdir); #endif remove_proc_entry(FILENAME_CHANNEL, ch->procdir); remove_proc_entry(FILENAME_TWIN, ch->procdir); MOD_DEC_USE_COUNT; return 0; }
static struct net_device *mixcom_twin_check(struct net_device *dev) { struct comx_channel *ch = dev->priv; struct proc_dir_entry *procfile = ch->procdir->parent->subdir; struct mixcom_privdata *hw = ch->HW_privdata; struct net_device *twin; struct comx_channel *ch_twin; struct mixcom_privdata *hw_twin; for ( ; procfile ; procfile = procfile->next) { if(!S_ISDIR(procfile->mode)) continue; twin = procfile->data; ch_twin = twin->priv; hw_twin = ch_twin->HW_privdata; if (twin != dev && dev->irq && dev->base_addr && dev->irq == twin->irq && ch->hardware == ch_twin->hardware && dev->base_addr == twin->base_addr + (1-2*hw->channel)*MIXCOM_CHANNEL_OFFSET && hw->channel == (1 - hw_twin->channel)) { if (!TWIN(twin) || TWIN(twin)==dev) { return twin; } } } return NULL; }
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hParent,LPSTR CmdA,int CmdShow) { WCHAR Cmd[2048]; mbstowcs(Cmd,CmdA,sizeof(Cmd)/sizeof(WCHAR)); //!!! #else int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hParent,TCHAR* Cmd,int CmdShow) { #endif #ifndef NDEBUG // DLLTest(); // just to help debugging plugins. comment out if not needed Context(); #endif #if defined(TARGET_WINCE) && defined(ARM) if (ProgramId == 2) { OSVERSIONINFO Ver; Ver.dwOSVersionInfoSize = sizeof(Ver); GetVersionEx(&Ver); if (Ver.dwMajorVersion*100 + Ver.dwMinorVersion >= 421) { // old shell menu not supported after WM2003SE MessageBox(NULL,T("This ARM_CE3 version of the player is not compatible with this device. Please install ARM_CE3 version."),NULL,MB_OK|MB_ICONERROR); return 1; } } #endif #ifdef NDEBUG if (!FindRunning(Cmd)) { HANDLE Handle = CreateMutex(NULL,FALSE,ProgramName); if (GetLastError() != ERROR_ALREADY_EXISTS) #endif { #ifndef NO_PLUGINS HMODULE Module; SetCursor(LoadCursor(NULL, IDC_WAIT)); Module = Load(T("interface.plg")); if (Module) { void (*Main)(const tchar_t* Name,const tchar_t* Version,int Id,const tchar_t* CmdLine); *(FARPROC*)&Main = GetProcAddress(Module,TWIN("Main")); if (!Main) *(FARPROC*)&Main = GetProcAddress(Module,TWIN("_Main@16")); if (Main) Main(ProgramName,ProgramVersion,ProgramId,Cmd); FreeLibrary(Module); } #else Main(ProgramName,ProgramVersion,ProgramId,Cmd); #endif #ifdef NDEBUG CloseHandle(Handle); #endif SetCursor(LoadCursor(NULL, IDC_ARROW)); } #ifdef NDEBUG } #endif return 0; }
static void setup_twin(struct net_device* dev) { if(TWIN(dev) && TWIN(TWIN(dev))) { TWIN(TWIN(dev))=NULL; } if ((TWIN(dev) = mixcom_twin_check(dev)) != NULL) { if (TWIN(TWIN(dev)) && TWIN(TWIN(dev)) != dev) { TWIN(dev)=NULL; } else { TWIN(TWIN(dev))=dev; } } }
static int MIXCOM_close(struct net_device *dev) { struct comx_channel *ch = dev->priv; struct mixcom_privdata *hw = ch->HW_privdata; struct proc_dir_entry *procfile = ch->procdir->subdir; unsigned long flags; save_flags(flags); cli(); mixcom_off(dev); /* This is channel 0, twin is not open, we can safely turn off everything */ if(hw->channel==0 && (!(TWIN(dev)) || !(COMX_CHANNEL(TWIN(dev))->init_status & HW_OPEN))) { mixcom_board_off(dev); free_irq(dev->irq, dev); release_region(dev->base_addr, MIXCOM_IO_EXTENT); ch->init_status &= ~IRQ_ALLOCATED; } /* This is channel 1, channel 0 has already been shutdown, we can release this one too */ if(hw->channel==1 && !(COMX_CHANNEL(TWIN(dev))->init_status & HW_OPEN)) { if(COMX_CHANNEL(TWIN(dev))->init_status & IRQ_ALLOCATED) { mixcom_board_off(TWIN(dev)); free_irq(TWIN(dev)->irq, TWIN(dev)); release_region(TWIN(dev)->base_addr, MIXCOM_IO_EXTENT); COMX_CHANNEL(TWIN(dev))->init_status &= ~IRQ_ALLOCATED; } } /* the ioports for channel 1 can be safely released */ if(hw->channel==1) { release_region(dev->base_addr, MIXCOM_IO_EXTENT); } restore_flags(flags); /* If we don't hold any hardware open */ if(!(ch->init_status & IRQ_ALLOCATED)) { for (; procfile ; procfile = procfile->next) { if (strcmp(procfile->name, FILENAME_IO) == 0 || strcmp(procfile->name, FILENAME_CHANNEL) == 0 || strcmp(procfile->name, FILENAME_CLOCK) == 0 || strcmp(procfile->name, FILENAME_IRQ) == 0) { procfile->mode = S_IFREG | 0644; } } } /* channel 0 was only waiting for us to close channel 1 close it completely */ if(hw->channel==1 && !(COMX_CHANNEL(TWIN(dev))->init_status & HW_OPEN)) { for (procfile=COMX_CHANNEL(TWIN(dev))->procdir->subdir; procfile ; procfile = procfile->next) { if (strcmp(procfile->name, FILENAME_IO) == 0 || strcmp(procfile->name, FILENAME_CHANNEL) == 0 || strcmp(procfile->name, FILENAME_CLOCK) == 0 || strcmp(procfile->name, FILENAME_IRQ) == 0) { procfile->mode = S_IFREG | 0644; } } } ch->init_status &= ~HW_OPEN; return 0; }
static int MIXCOM_open(struct net_device *dev) { struct comx_channel *ch = dev->priv; struct mixcom_privdata *hw = ch->HW_privdata; struct proc_dir_entry *procfile = ch->procdir->subdir; unsigned long flags; int ret = -ENODEV; if (!dev->base_addr || !dev->irq) goto err_ret; if(hw->channel==1) { if(!TWIN(dev) || !(COMX_CHANNEL(TWIN(dev))->init_status & IRQ_ALLOCATED)) { printk(KERN_ERR "%s: channel 0 not yet initialized\n",dev->name); ret = -EAGAIN; goto err_ret; } } /* Is our hw present at all ? Not checking for channel 0 if it is already open */ if(hw->channel!=0 || !(ch->init_status & IRQ_ALLOCATED)) { if (!request_region(dev->base_addr, MIXCOM_IO_EXTENT, dev->name)) { ret = -EAGAIN; goto err_ret; } if (mixcom_probe(dev)) { ret = -ENODEV; goto err_release_region; } } if(hw->channel==0 && !(ch->init_status & IRQ_ALLOCATED)) { if (request_irq(dev->irq, MIXCOM_interrupt, 0, dev->name, (void *)dev)) { printk(KERN_ERR "MIXCOM: unable to obtain irq %d\n", dev->irq); ret = -EAGAIN; goto err_release_region; } } save_flags(flags); cli(); if(hw->channel==0 && !(ch->init_status & IRQ_ALLOCATED)) { ch->init_status|=IRQ_ALLOCATED; mixcom_board_on(dev); } mixcom_on(dev); hw->status=inb(MIXCOM_BOARD_BASE(dev) + MIXCOM_STATUS_OFFSET); if(hw->status != 0xff) { printk(KERN_DEBUG "%s: board has status register, good\n", dev->name); hw->card_has_status=1; } hw->txbusy = 0; ch->init_status |= HW_OPEN; if (rd_hscx(dev, HSCX_STAR) & HSCX_CTS) { ch->line_status |= LINE_UP; } else { ch->line_status &= ~LINE_UP; } restore_flags(flags); ch->LINE_status(dev, ch->line_status); for (; procfile ; procfile = procfile->next) { if (strcmp(procfile->name, FILENAME_IO) == 0 || strcmp(procfile->name, FILENAME_CHANNEL) == 0 || strcmp(procfile->name, FILENAME_CLOCK) == 0 || strcmp(procfile->name, FILENAME_IRQ) == 0) { procfile->mode = S_IFREG | 0444; } } return 0; err_restore_flags: restore_flags(flags); err_release_region: release_region(dev->base_addr, MIXCOM_IO_EXTENT); err_ret: return ret; }