void chkkbd(void) { register WORD achar, kstat; /* poll keybd */ if (!gl_play) { kstat = gsx_kstate(); achar = gsx_char(); if (achar && (gl_mowner->p_cda->c_q.c_cnt >= KBD_SIZE)) { achar = 0x0; /* buffer overrun */ sound(TRUE, 880, 2); } if ( (achar) || (kstat != kstate) ) { cli(); forkq( (void (*)())kchange, (((LONG)achar<<16)|kstat) ); sti(); } } }
int __noreturn kern_init(void) { extern char edata[], end[]; memset(edata, 0, end - edata); cons_init(); // init the console const char *message = "(THU.CST) os is loading ..."; cprintf("%s\n\n", message); print_kerninfo(); pic_init(); // init interrupt controller idt_init(); // init interrupt descriptor table clock_init(); // init clock interrupt sti(); // enable irq interrupt /* do nothing */ while (1); }
static int bpq_get_info(char *buffer, char **start, off_t offset, int length) { struct bpqdev *bpqdev; int len = 0; off_t pos = 0; off_t begin = 0; cli(); len += sprintf(buffer, "dev ether destination accept from\n"); for (bpqdev = bpq_devices; bpqdev != NULL; bpqdev = bpqdev->next) { len += sprintf(buffer + len, "%-5s %-10s %s ", bpqdev->axdev.name, bpqdev->ethname, bpq_print_ethaddr(bpqdev->dest_addr)); len += sprintf(buffer + len, "%s\n", (bpqdev->acpt_addr[0] & 0x01) ? "*" : bpq_print_ethaddr(bpqdev->acpt_addr)); pos = begin + len; if (pos < offset) { len = 0; begin = pos; } if (pos > offset + length) break; } sti(); *start = buffer + (offset - begin); len -= (offset - begin); if (len > length) len = length; return len; }
static int ps2ev_release(struct inode *inode, struct file *file) { struct ps2ev_data *data, **p; data = (struct ps2ev_data *)file->private_data; ps2ev_fasync(-1, file, 0); cli(); data->intr_mask = 0; register_intr_handler(); p = &ps2ev_data; while (*p != NULL) { if (*p == data) { *p = data->next; break; } p = &(*p)->next; } sti(); kfree(data); return 0; }
void do_timer() //0x20 { ++ticks; outb(0x20,0x60); /* master PIC */ if(ticks >= buoy->time && buoy != &last_timer) { fifo_write(&global_fifo,TIMER_STA+buoy->id); list_del(&buoy->list); buoy = (struct TIMER *)first_timer.list.next; } cli(); if(current != &TASK0 && current) current->counter -= 10; if (! (ticks%1)) scheduler(); //printk("%d ",ticks); sti(); }
void DMA_setup (unsigned channel, uchar mask, void *address, size_t size) { assert(channel < 8); assert(size > 0); cli(); outb(0x0D, 0); DMA_disable(channel); DMA_clearflip(channel); outb(page_port[channel], (u32)address >> 16); (u32)address &= 0xffff; outb(address_port[channel], (u32)address & 0xff); outb(address_port[channel], ((u32)address >> 8) & 0xff); size--; outb(count_port[channel], size & 0xff); outb(count_port[channel], size >> 8); outb(mode_port[channel], (channel & 0xF) | mask); sti(); DMA_enable(channel); }
void die_if_kernel(char *str, struct pt_regs *regs, long err) { if (user_mode(regs)) { #ifdef PRINT_USER_FAULTS if (err == 0) return; /* STFU */ /* XXX for debugging only */ printk(KERN_DEBUG "%s (pid %d): %s (code %ld)\n", current->comm, current->pid, str, err); show_regs(regs); #endif return; } /* unlock the pdc lock if necessary */ pdc_emergency_unlock(); /* maybe the kernel hasn't booted very far yet and hasn't been able * to initialize the serial or STI console. In that case we should * re-enable the pdc console, so that the user will be able to * identify the problem. */ if (!console_drivers) pdc_console_restart(); printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n", current->comm, current->pid, str, err); show_regs(regs); /* Wot's wrong wif bein' racy? */ if (current->thread.flags & PARISC_KERNEL_DEATH) { printk(KERN_CRIT "%s() recursion detected.\n", __FUNCTION__); sti(); while (1); } current->thread.flags |= PARISC_KERNEL_DEATH; do_exit(SIGSEGV); }
/* * pollchar: check if we have an input character pending * * Returns 1 if character pending. */ int bios_pollchar(void) { com32sys_t ireg, oreg; uint8_t data = 0; memset(&ireg, 0, sizeof(ireg)); ireg.eax.b[1] = 0x11; /* Poll keyboard */ __intcall(0x16, &ireg, &oreg); if (!(oreg.eflags.l & EFLAGS_ZF)) return 1; if (SerialPort) { cli(); /* Already-queued input? */ if (SerialTail == SerialHead) { /* LSR */ data = inb(SerialPort + 5) & 1; if (data) { /* MSR */ data = inb(SerialPort + 6); /* Required status bits */ data &= FlowIgnore; if (data == FlowIgnore) data = 1; else data = 0; } } else data = 1; sti(); } return data; }
static int saphir_reset(struct IsdnCardState *cs) { long flags; u_char irq_val; switch(cs->irq) { case 5: irq_val = 0; break; case 3: irq_val = 1; break; case 11: irq_val = 2; break; case 12: irq_val = 3; break; case 15: irq_val = 4; break; default: printk(KERN_WARNING "HiSax: saphir wrong IRQ %d\n", cs->irq); return (1); } byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val); save_flags(flags); sti(); byteout(cs->hw.saphir.cfg_reg + RESET_REG, 1); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((30*HZ)/1000); /* Timeout 30ms */ byteout(cs->hw.saphir.cfg_reg + RESET_REG, 0); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((30*HZ)/1000); /* Timeout 30ms */ restore_flags(flags); byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val); byteout(cs->hw.saphir.cfg_reg + SPARE_REG, 0x02); return (0); }
//PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p; struct proc *hp; for(;;){ // Enable interrupts on this processor. sti(); // Loop over process table looking for process to run. acquire(&ptable.lock); hp = ptable.proc; for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if(p->state != RUNNABLE) continue; if(hp->state != RUNNABLE) //garantiza que tenga runnable hp = p; if(hp->priority < p->priority) hp = p; } p = hp; // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; //para matar un proceso tenemos que matar a proc switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; release(&ptable.lock); } }
void kernel_init(struct multiboot *mboot_ptr) { //Reprogram PICs cli(); init_pics(0x20, 0x28); sti(); //Initialize Terminal terminal_initialize(); kinfo("Enable A20 Gate (if not already done)\n"); //Enable A20 Gate if it is not already enabled. if (checkA20() = 0) enableA20(); //Check if A20 is REALLY enabled if (checkA20() = 0) panic("Enabling A20 Gate"); //Enable the timer and setting it to 50hz kinfo("Enable Timer (50hz)"); init_timer(50); //Initiate the descriptor tables (gdt and idt) init_descriptor_tables(); //Enter the protected mode kinfo("Enter protected mode"); enterProtected(); //Spawning the init process with argument *mboot_ptr kinfo("Spawning Init process..."); init(*mboot_ptr); //The init process should NEVER die. //If it dies kerror("Init Process terminated... make a kernel panic..."); panic("Unendable Process ended."); }
static int t163c_card_msg(struct IsdnCardState *cs, int mt, void *arg) { long flags; char tmp[32]; if (cs->debug & L1_DEB_ISAC) { sprintf(tmp, "teles3c: card_msg %x", mt); debugl1(cs, tmp); } switch (mt) { case CARD_RESET: reset_t163c(cs); return(0); case CARD_RELEASE: release_io_t163c(cs); return(0); case CARD_SETIRQ: cs->hw.hfcD.timer.expires = jiffies + 75; add_timer(&cs->hw.hfcD.timer); return(request_irq(cs->irq, &t163c_interrupt, I4L_IRQ_FLAG, "HiSax", cs)); case CARD_INIT: init2bds0(cs); save_flags(flags); sti(); current->state = TASK_INTERRUPTIBLE; schedule_timeout((80*HZ)/1000); cs->hw.hfcD.ctmt |= HFCD_TIM800; cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt); cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_MST_MODE, cs->hw.hfcD.mst_m); restore_flags(flags); return(0); case CARD_TEST: return(0); } return(0); }
/* * floppy-change is never called from an interrupt, so we can relax a bit * here, sleep etc. Note that floppy-on tries to set current_DOR to point * to the desired drive, but it will probably not survive the sleep if * several floppies are used at the same time: thus the loop. */ int floppy_change(struct buffer_head * bh) { unsigned int mask = 1 << (bh->b_dev & 0x03); if (MAJOR(bh->b_dev) != 2) { printk("floppy_changed: not a floppy\r\n"); return 0; } if (fake_change & mask) { fake_change &= ~mask; /* omitting the next line breaks formatting in a horrible way ... */ changed_floppies &= ~mask; return 1; } if (changed_floppies & mask) { changed_floppies &= ~mask; recalibrate = 1; return 1; } if (!bh) return 0; if (bh->b_dirt) ll_rw_block(WRITE,bh); else { buffer_track = -1; bh->b_uptodate = 0; ll_rw_block(READ,bh); } cli(); while (bh->b_lock) sleep_on(&bh->b_wait); sti(); if (changed_floppies & mask) { changed_floppies &= ~mask; recalibrate = 1; return 1; } return 0; }
void gusintr (int unit) { unsigned char src; #ifdef linux sti(); #endif while (1) { if (!(src = INB (u_IrqStatus))) return; if (src & DMA_TC_IRQ) { guswave_dma_irq (); } if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ)) { #ifndef EXCLUDE_MIDI gus_midi_interrupt (0); #endif } if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ)) { printk ("T"); gus_write8 (0x45, 0); /* Timer control */ } if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ)) { gus_voice_irq (); } } }
/* * nk_join * * join (wait) on the given thread * * t: the thread to wait on * retval: where the waited-on thread should * put its output * * returns -EINVAL on error, 0 on success * */ int nk_join (nk_thread_id_t t, void ** retval) #ifndef NAUT_CONFIG_USE_RT_SCHEDULER { nk_thread_t *thethread = (nk_thread_t*)t; uint8_t flags; ASSERT(thethread->parent == get_cur_thread()); flags = irq_disable_save(); while (__sync_lock_test_and_set(&thethread->lock, 1)); if (thethread->status == NK_THR_EXITED) { if (thethread->output) { *retval = thethread->output; } goto out; } else { while (*(volatile int*)&thethread->status != NK_THR_EXITED) { __sync_lock_release(&thethread->lock); cli(); nk_wait(t); sti(); while (__sync_lock_test_and_set(&thethread->lock, 1)); } } if (retval) { *retval = thethread->output; } out: __sync_lock_release(&thethread->lock); thread_detach(thethread); irq_enable_restore(flags); return 0; }
int play_cd ( dword base, byte id, byte min_xx, word fr_sec ) { int i = 0; byte ret; word param; for ( i = 0; i < 1; i++ ) { atapi ( base, id ); cli(); outw ( 0x0047, base ); param = ( min_xx << 8 ) + 0x01; outw ( param, base ); outw ( fr_sec, base ); outw ( 256 + 99, base ); outw ( 0x0001, base ); outw ( 0x0000, base ); delay ( MICRO(200000L) ); sti(); ret = inb ( base+7 ); if ( ret == 0xC0 || ret == 0x50 || ret == 0xD0 ) { #ifdef DEBUG imprimir ( "anduvo todo bien: 0x%xb!!\n", ret); #endif return 0; } else { #ifdef DEBUG imprimir ("Fallo: 0x%xb!!!, reintentando...\n", ret); #endif } } return -1; }
static void reset_bkm(struct IsdnCardState *cs) { long flags; if (cs->typ == ISDN_CTYPE_BKM_A4T) { I20_REGISTER_FILE *pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); save_flags(flags); sti(); /* Issue the I20 soft reset */ pI20_Regs->i20SysControl = 0xFF; /* all in */ set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10 * HZ) / 1000); /* Remove the soft reset */ pI20_Regs->i20SysControl = sysRESET | 0xFF; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10 * HZ) / 1000); /* Set our configuration */ pI20_Regs->i20SysControl = sysRESET | sysCFG; /* Issue ISDN reset */ pI20_Regs->i20GuestControl = guestWAIT_CFG | g_A4T_JADE_RES | g_A4T_ISAR_RES | g_A4T_ISAC_RES | g_A4T_JADE_BOOTR | g_A4T_ISAR_BOOTR; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10 * HZ) / 1000); /* Remove RESET state from ISDN */ pI20_Regs->i20GuestControl &= ~(g_A4T_ISAC_RES | g_A4T_JADE_RES | g_A4T_ISAR_RES); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10 * HZ) / 1000); restore_flags(flags); } }
/************************************************ rtc_write - change the clock frequency Probably make a function call in kernel to show that frequency can be changed *************************************************/ int32_t rtc_write(file_t* file, const uint8_t* buf, int32_t nbytes) { if(nbytes != RTC_READ_BYTES) return RET_FAILURE; uint32_t flags; cli_and_save(flags); //save all the flags and stop interrupts uint32_t frequency = *(uint32_t*)buf; if((frequency > HIGHEST_FREQ)||(frequency < LOWEST_FREQ)) //if frequency is out of bounds then return -1 { restore_flags(flags); //restore the flags even if we are returning -1 return RET_FAILURE; } //printf("inside rtc_write\n"); int rate = LOWEST_FREQ; // rate must be above 2 and not over 15 while(frequency != HIGH_16_BIT >> (rate-1)) //rate calculation formula on OS DEV { rate++; } rate--; outb(VAL_1, PORT_1); // set index to register A, disable NMI char prev = inb(PORT_2); // get initial value of register A outb(VAL_1, PORT_1); // reset index to A outb((prev & FIRST_4_BITS) | rate, PORT_2); //write only our rate to A. Note, rate is the bottom 4 bits. outb(VAL_2, PORT_1); // select register B, and disable NMI prev = inb(PORT_2); // read the current value of register B outb(VAL_2, PORT_1); // set the index again (a read will reset the index to register D) outb(prev | BIT_6, PORT_2); // write the previous value ORed with 0x40. This turns on bit 6 of register B //the offset of the RTC is IRQ1 sti(); restore_flags(flags); return RET_SUCCESS; }
void OptionsDialog::_buildFrameUser() { Input* i; SmallSelect* ss; Checkbox* c; int y = 0; mFrameUser->mSortable = false; new Label(mFrameUser, "", rect(0,y), "Nickname"); i = new Input(mFrameUser, "nick", rect(95, y, 150, 20), "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\\_-^`[]{}|", 32, true, NULL); i->SetText( game->mPlayer->GetName() ); y += 25; new Label(mFrameUser, "", rect(0,y), "Alerts"); ss = new SmallSelect(mFrameUser, "alerts", rect(95, y, 150, 20), NULL); ss->AddItem("Off"); ss->AddItem("Always"); ss->AddItem("Only When Inactive"); ss->mSelectedIndex = gui->mSystemAlertType; ss->mHoverText = "Controls when to flash the title bar for a new message"; y += 25; /* c = new Checkbox(mFrameUser, "names", rect(0,y), "Show Player Names", 0); c->SetState( game->mPlayerData.GetParamInt("map", "shownames") ); y += 25; c = new Checkbox(mFrameUser, "trading", rect(0,y), "Allow Trade Requests", 0); c->SetState( game->mPlayerData.GetParamInt("map", "trading") ); y += 25; */ c = new Checkbox(mFrameUser, "stamps", rect(0,y), "Show Timestamps", 0); c->SetState( sti(game->mUserData.GetValue("MapSettings", "Timestamps")) ); y += 25; }
void kmain(){ cli("kmain()"); clear_screen(); kprintln("KERNEL STARTED"); if(mb_magic != 0x2BADB002){ /* Something went not according to specs. Print an error */ /* message and halt, but do *not* rely on the multiboot */ /* data structure. */ kprint("ERROR: Invalid multiboot magic number: "); kprintln_uint32(mb_magic); return; } kutil_init(); kprintln("kutil initialised"); memory_init(); kprintln("memory initialised"); interrupts_init(); add_interrupt_handler(0x80, (uint32_t) interrupt_handler); kprintln("interrupts initialised"); processes_init(); kprintln("processes initialised"); clear_screen(); add_process(&print_A); add_process(&print_B); //check_process_stack(); sti("kmain()"); halt(); }
void init_8259A(){ outb(0x20,0x11); iodelay(); outb(0xa0,0x11); iodelay(); outb(0x21,0x20); iodelay(); outb(0xa1,0x28); iodelay(); outb(0x21,0x04); iodelay(); outb(0xa1,0x02); iodelay(); outb(0x21,0x01); iodelay(); outb(0xa1,0x01); iodelay(); outb(0x21,0xfe); iodelay(); outb(0xa1,0xff); iodelay(); idt[TIMER] = IDT_ENTRY(0x8e00,cs(),(u32)p); sti(); }
/* * This routine is the bottom half of the keyboard interrupt * routine, and runs with all interrupts enabled. It does * console changing, led setting and copy_to_cooked, which can * take a reasonably long time. * * Aside from timing (which isn't really that important for * keyboard interrupts as they happen often), using the software * interrupt routines for this thing allows us to easily mask * this when we don't want any of the above to happen. Not yet * used, but this allows for easy and efficient race-condition * prevention later on. */ static void kbd_bh(void * unused) { static unsigned char old_leds = 0xff; unsigned char leds = kbd_table[fg_console].ledstate; if (leds != old_leds) { old_leds = leds; if (!send_data(0xed) || !send_data(leds)) send_data(0xf4); /* re-enable kbd if any errors */ } if (want_console >= 0) { if (want_console != fg_console) { last_console = fg_console; change_console(want_console); } want_console = -1; } poke_blanked_console(); cli(); if ((inb_p(0x64) & kbd_read_mask) == 0x01) fake_keyboard_interrupt(); sti(); }
static void el_reset(struct device *dev) { if (el_debug> 2) printk("3c501 reset..."); outb(AX_RESET, AX_CMD); /* Reset the chip */ outb(AX_LOOP, AX_CMD); /* Aux control, irq and loopback enabled */ { int i; for (i = 0; i < 6; i++) /* Set the station address. */ outb(dev->dev_addr[i], el_base + i); } outb(0, RX_BUF_CLR); /* Set rx packet area to 0. */ cli(); /* Avoid glitch on writes to CMD regs */ outb(TX_NORM, TX_CMD); /* tx irq on done, collision */ outb(RX_NORM, RX_CMD); /* Set Rx commands. */ inb(RX_STATUS); /* Clear status. */ inb(TX_STATUS); dev->interrupt = 0; dev->tbusy = 0; sti(); }
static int serial_read(struct dev *dev, void *buffer, size_t count, blkno_t blkno, int flags) { struct serial_port *sp = (struct serial_port *) dev->privdata; unsigned int n; unsigned char *bufp; if (wait_for_object(&sp->rx_lock, sp->cfg.rx_timeout) < 0) return -ETIMEOUT; bufp = (unsigned char *) buffer; for (n = 0; n < count; n++) { // Wait until rx queue is not empty if (wait_for_object(&sp->rx_sem, n == 0 ? sp->cfg.rx_timeout : 0) < 0) break; // Remove next char from receive queue cli(); *bufp++ = fifo_get(&sp->rxq); sti(); //kprintf("serial: read %02X\n", bufp[-1]); } release_mutex(&sp->rx_lock); return n; }
void do_syscall(TrapFrame *tf) { switch(tf->eax) { /* The ``add_irq_handle'' system call is artificial. We use it to * let user program register its interrupt handlers. But this is * very dangerous in a real operating system. Therefore such a * system call never exists in GNU/Linux. */ case 0: cli(); add_irq_handle(tf->ebx, (void*)tf->ecx); sti(); break; case SYS_brk: sys_brk(tf); break; /* system write */ case 4: sys_write(tf); break; /* TODO: Add more system calls. */ default: panic("Unhandled system call: id = %d", tf->eax); } }
void kernel_start(void) { fill_interrupt(49, KERNEL_CS, int49, 3); // Usermode syscalls /* Protection faults etc */ fill_interrupt(0x0d, KERNEL_CS, pfault, 0); fill_interrupt(0x0e, KERNEL_CS, pfault, 0); call_debugger(); INIT(console); INIT(sem); //INIT(floppy); INIT(vfs); INIT(context); INIT(timer); sti(); for(;;); return; }
static void reset_netjet_s(struct IsdnCardState *cs) { long flags; save_flags(flags); sti(); cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ cs->hw.njet.ctrl_reg = 0x40; /* Reset Off and status read clear */ /* now edge triggered for TJ320 GE 13/07/00 */ byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ restore_flags(flags); cs->hw.njet.auxd = 0; cs->hw.njet.dmactrl = 0; byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ); byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); }
void * sock_rmalloc(volatile struct sock *sk, unsigned long size, int force) { struct mem *tmp; if (sk ) { if (sk->rmem_alloc + size >= SK_RMEM_MAX && !force) { MPRINTK ("sock_rmalloc(%X,%d,%d) returning NULL\n",sk,size,force); return (NULL); } cli(); sk->rmem_alloc+= size; sti(); } if (sk) tmp = smalloc (size); else tmp = malloc (size); MPRINTK ("sock_rmalloc(%X,%d,%d) returning %X\n",sk, size, force, tmp); return (tmp); }
static void acpi_cpu_mwait_ipi_check_wakeup(void *arg) { volatile uint32_t *mcpu_mwait = (volatile uint32_t *)arg; ASSERT(arg != NULL); if (*mcpu_mwait != MWAIT_WAKEUP_IPI) { /* * CPU has been awakened, notify CPU idle notification system. */ cpu_idle_exit(CPU_IDLE_CB_FLAG_IDLE); } else { /* * Toggle interrupt flag to detect pending interrupts. * If interrupt happened, do_interrupt() will notify CPU idle * notification framework so no need to call cpu_idle_exit() * here. */ sti(); SMT_PAUSE(); cli(); } }
int init_virtio_net() { virtio_dev_t dev = to_virtio_dev_t(&pci_vn); if (virtio_setup_device(dev, VIRTIO_NET_SUBID, 1)) { virtio_net_read_config(&pci_vn); /* virtio-net has at least 2 queues */ int queues = 2; if (pci_vn._ctrl_vq) { queues++; } int ret = virtio_alloc_queues(dev, queues); pci_d("virtio_alloc_queues ret:%d\n", ret); if (virtio_net_alloc_bufs() != OK) panic("%s: Buffer allocation failed", name); pci_d("virtio_net_alloc_bufs:%d\n", ret); virtio_net_init_queues(); pci_d("virtio_net_init_queues:%d\n", ret); /* Add packets to the receive queue. */ virtio_net_refill_rx_queue(); pci_d("virtio_net_refill_rx_queue:%d\n", ret); virtio_device_ready(to_virtio_dev_t(&pci_vn)); pci_d("virtio_device_ready:%d\n", ret); // virtio_irq_enable(to_virtio_dev_t(&pci_vn)); bool virtio_had_irq(struct virtio_device *dev); pci_d("had_irq:%d\n", virtio_had_irq(to_virtio_dev_t(&pci_vn))); set_timeout(1000, vn_timeout); sti(); } return OK; }