int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action) { int status; int cpu = smp_processor_id(); kstat.irqs[cpu][irq]++; irq_enter(cpu, irq); status = 1; /* Force the "do bottom halves" bit */ do { if (!(action->flags & SA_INTERRUPT)) __sti(); else __cli(); status |= action->flags; action->handler(irq, action->dev_id, regs); action = action->next; } while (action); if (status & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); __cli(); irq_exit(cpu, irq); return status; }
/* * do_IRQ handles IRQ's that have been installed without the * SA_INTERRUPT flag: it uses the full signal-handling return * and runs with other interrupts enabled. All relatively slow * IRQ's should use this format: notably the keyboard/timer * routines. */ static void do_IRQ(int irq, struct pt_regs * regs) { struct irqaction *action; int do_random, cpu; cpu = smp_processor_id(); irq_enter(cpu); kstat.irqs[cpu][irq]++; mask_irq(irq); action = *(irq + irq_action); if (action) { if (!(action->flags & SA_INTERRUPT)) __sti(); action = *(irq + irq_action); do_random = 0; do { do_random |= action->flags; action->handler(irq, action->dev_id, regs); action = action->next; } while (action); if (do_random & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); __cli(); } else { printk("do_IRQ: Unregistered IRQ (0x%X) occured\n", irq); } unmask_irq(irq); irq_exit(cpu); /* unmasking and bottom half handling is done magically for us. */ }
void printk(const char *text, ...) { va_list args; char text_buf[1024]; int len; u32 flags; int i; if (!term_init) return; save_flags(flags); __cli(); memset(text_buf, 0, 1024); va_start(args, text); len = vsnprintf(text_buf, 1024, text, args); va_end(args); /* printk to all terminals */ for (i = 0; i < MAX_TERMINALS; i++) { if (term_sys[i].ops && term_sys[i].ops->write) term_sys[i].ops->write(&term_sys[i], text_buf); } restore_flags(flags); }
static void flat_send_IPI_mask(unsigned long cpumask, int vector) { unsigned long mask = cpumask; unsigned long cfg; unsigned long flags; __save_flags(flags); __cli(); /* * Wait for idle. */ apic_wait_icr_idle(); /* * prepare target chip field */ cfg = __prepare_ICR2(mask); apic_write_around(APIC_ICR2, cfg); /* * program the ICR */ cfg = __prepare_ICR(0, vector, APIC_DEST_LOGICAL); /* * Send the IPI. The write to APIC_ICR fires this off. */ apic_write_around(APIC_ICR, cfg); __restore_flags(flags); }
void do_IRQ (int irq /* gets currently not passed: , struct pt_regs * regs*/) /* * Note: the code in "interrupt-entry.s" that calls this function * does leave IRQs disabled until return from this function. * This function gets entered with the IRQ still disabled. You * may enable it here. */ { struct irqdesc * desc; struct irqaction * action; if (irq >= NR_IRQS) { // spurious intr return; } desc = irq_desc + irq; if (desc->mask_ack) { desc->mask_ack(irq); action = desc->action; if (action) { if (desc->nomask) { desc->unmask(irq); } __sti(); // enable IRQs do { action->handler(irq, action->dev_id, 0); action = action->next; } while (action); __cli(); // disable IRQs so that unmask() can be called safely if (!desc->nomask && desc->enabled) { desc->unmask(irq); } } } }
/* * This routine is invoked from ide.c to prepare for access to a given drive. */ static void ht6560b_selectproc (ide_drive_t *drive) { byte t; unsigned long flags; static byte current_select = 0; static byte current_timing = 0; byte select = ht6560b_selects[HWIF(drive)->index][drive->select.b.unit]; byte timing = ht6560b_timings[HWIF(drive)->index][drive->select.b.unit]; if (select != current_select || timing != current_timing) { current_select = select; current_timing = timing; __save_flags (flags); /* local CPU only */ __cli(); /* local CPU only */ (void) inb(HT_SELECT_PORT); (void) inb(HT_SELECT_PORT); (void) inb(HT_SELECT_PORT); /* * Note: input bits are reversed to output bits!! */ t = inb(HT_SELECT_PORT) ^ 0x3f; t &= (~0x21); t |= (current_select & 0x21); outb(t, HT_SELECT_PORT); /* * Set timing for this drive: */ outb (timing, IDE_SELECT_REG); (void) inb (IDE_STATUS_REG); __restore_flags (flags); /* local CPU only */ #ifdef DEBUG printk("ht6560b: %s: select=%#x timing=%#x\n", drive->name, t, timing); #endif } }
asmlinkage void do_IRQ(int irq, struct pt_regs * regs) { struct irqaction *action; int do_random, cpu; cpu = smp_processor_id(); irq_enter(cpu); kstat.irqs[cpu][irq]++; action = irq_action[irq]; if (action) { if (!(action->flags & SA_INTERRUPT)) __sti(); action = irq_action[irq]; do_random = 0; do { do_random |= action->flags; action->handler(irq, action->dev_id, regs); action = action->next; } while (action); if (do_random & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); __cli(); } irq_exit(cpu); if (softirq_pending(cpu)) do_softirq(); /* unmasking and bottom half handling is done magically for us. */ }
static void apic_pm_suspend(void *data) { unsigned int l, h; unsigned long flags; if (apic_pm_state.perfctr_pmdev) pm_send(apic_pm_state.perfctr_pmdev, PM_SUSPEND, data); apic_pm_state.apic_id = apic_read(APIC_ID); apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); apic_pm_state.apic_ldr = apic_read(APIC_LDR); apic_pm_state.apic_dfr = apic_read(APIC_DFR); apic_pm_state.apic_spiv = apic_read(APIC_SPIV); apic_pm_state.apic_lvtt = apic_read(APIC_LVTT); apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC); apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0); apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1); apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); apic_pm_state.apic_tmict = apic_read(APIC_TMICT); apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); __save_flags(flags); __cli(); disable_local_APIC(); rdmsr(MSR_IA32_APICBASE, l, h); l &= ~MSR_IA32_APICBASE_ENABLE; wrmsr(MSR_IA32_APICBASE, l, h); __restore_flags(flags); }
/* * Auto-detect the IDE controller port. */ static int __init findPort (void) { int i; byte t; unsigned long flags; __save_flags(flags); /* local CPU only */ __cli(); /* local CPU only */ for (i = 0; i < ALI_NUM_PORTS; ++i) { basePort = ports[i]; regOff = inb(basePort); for (regOn = 0x30; regOn <= 0x33; ++regOn) { outb_p(regOn, basePort); if (inb(basePort) == regOn) { regPort = basePort + 4; dataPort = basePort + 8; t = inReg(0) & 0xf0; outb_p(regOff, basePort); __restore_flags(flags); /* local CPU only */ if (t != 0x50) return 0; return 1; /* success */ } } outb_p(regOff, basePort); } __restore_flags(flags); /* local CPU only */ return 0; }
static void apic_pm_resume(void *data) { unsigned int l, h; unsigned long flags; __save_flags(flags); __cli(); rdmsr(MSR_IA32_APICBASE, l, h); l &= ~MSR_IA32_APICBASE_BASE; l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; wrmsr(MSR_IA32_APICBASE, l, h); apic_write(APIC_ID, apic_pm_state.apic_id); apic_write(APIC_DFR, apic_pm_state.apic_dfr); apic_write(APIC_LDR, apic_pm_state.apic_ldr); apic_write(APIC_TASKPRI, apic_pm_state.apic_taskpri); apic_write(APIC_SPIV, apic_pm_state.apic_spiv); apic_write(APIC_LVT0, apic_pm_state.apic_lvt0); apic_write(APIC_LVT1, apic_pm_state.apic_lvt1); apic_write(APIC_ESR, 0); apic_read(APIC_ESR); apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr); apic_write(APIC_ESR, 0); apic_read(APIC_ESR); apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc); apic_write(APIC_LVTT, apic_pm_state.apic_lvtt); apic_write(APIC_TDCR, apic_pm_state.apic_tdcr); apic_write(APIC_TMICT, apic_pm_state.apic_tmict); __restore_flags(flags); if (apic_pm_state.perfctr_pmdev) pm_send(apic_pm_state.perfctr_pmdev, PM_RESUME, data); }
void __init init_umc8672 (void) /* called from ide.c */ { unsigned long flags; __save_flags(flags); /* local CPU only */ __cli(); /* local CPU only */ if (check_region(0x108, 2)) { __restore_flags(flags); printk("\numc8672: PORTS 0x108-0x109 ALREADY IN USE\n"); return; } outb_p (0x5A,0x108); /* enable umc */ if (in_umc (0xd5) != 0xa0) { __restore_flags(flags); /* local CPU only */ printk ("umc8672: not found\n"); return; } outb_p (0xa5,0x108); /* disable umc */ umc_set_speeds (current_speeds); __restore_flags(flags); /* local CPU only */ request_region(0x108, 2, "umc8672"); ide_hwifs[0].chipset = ide_umc8672; ide_hwifs[1].chipset = ide_umc8672; ide_hwifs[0].tuneproc = &tune_umc; ide_hwifs[1].tuneproc = &tune_umc; ide_hwifs[0].mate = &ide_hwifs[1]; ide_hwifs[1].mate = &ide_hwifs[0]; ide_hwifs[1].channel = 1; }
static void sandpoint_power_off(void) { __cli(); for (;;) ; /* No way to shut power off with software */ /* NOTREACHED */ }
static inline void send_IPI_mask_bitmask(int mask, int vector) { unsigned long cfg; unsigned long flags; __save_flags(flags); __cli(); /* * Wait for idle. */ apic_wait_icr_idle(); /* * prepare target chip field */ cfg = __prepare_ICR2(mask); apic_write_around(APIC_ICR2, cfg); /* * program the ICR */ cfg = __prepare_ICR(0, vector); /* * Send the IPI. The write to APIC_ICR fires this off. */ apic_write_around(APIC_ICR, cfg); __restore_flags(flags); }
/* * This routine is invoked from ide.c to prepare for access to a given drive. */ static void ht6560b_selectproc (ide_drive_t *drive) { unsigned long flags; static byte current_select = 0; static byte current_timing = 0; byte select, timing; __save_flags (flags); /* local CPU only */ __cli(); /* local CPU only */ select = HT_CONFIG(drive); timing = HT_TIMING(drive); if (select != current_select || timing != current_timing) { current_select = select; current_timing = timing; if (drive->media != ide_disk || !drive->present) select |= HT_PREFETCH_MODE; (void) inb(HT_CONFIG_PORT); (void) inb(HT_CONFIG_PORT); (void) inb(HT_CONFIG_PORT); (void) inb(HT_CONFIG_PORT); outb(select, HT_CONFIG_PORT); /* * Set timing for this drive: */ outb(timing, IDE_SELECT_REG); (void) inb(IDE_STATUS_REG); #ifdef DEBUG printk("ht6560b: %s: select=%#x timing=%#x\n", drive->name, select, timing); #endif } __restore_flags (flags); /* local CPU only */ }
/* * Update the */ int ide_driveid_update (ide_drive_t *drive) { /* * Re-read drive->id for possible DMA mode * change (copied from ide-probe.c) */ struct hd_driveid *id; unsigned long timeout, flags; SELECT_MASK(HWIF(drive), drive, 1); if (IDE_CONTROL_REG) OUT_BYTE(drive->ctl,IDE_CONTROL_REG); ide_delay_50ms(); OUT_BYTE(WIN_IDENTIFY, IDE_COMMAND_REG); timeout = jiffies + WAIT_WORSTCASE; do { if (0 < (signed long)(jiffies - timeout)) { SELECT_MASK(HWIF(drive), drive, 0); return 0; /* drive timed-out */ } ide_delay_50ms(); /* give drive a breather */ } while (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT); ide_delay_50ms(); /* wait for IRQ and DRQ_STAT */ if (!OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) { SELECT_MASK(HWIF(drive), drive, 0); printk("%s: CHECK for good STATUS\n", drive->name); return 0; } __save_flags(flags); /* local CPU only */ __cli(); /* local CPU only; some systems need this */ SELECT_MASK(HWIF(drive), drive, 0); id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC); if (!id) { __restore_flags(flags); /* local CPU only */ return 0; } ide_input_data(drive, id, SECTOR_WORDS); (void) GET_STAT(); /* clear drive IRQ */ ide__sti(); /* local CPU only */ __restore_flags(flags); /* local CPU only */ ide_fix_driveid(id); if (id) { drive->id->dma_ultra = id->dma_ultra; drive->id->dma_mword = id->dma_mword; drive->id->dma_1word = id->dma_1word; /* anything more ? */ kfree(id); } return 1; }
void smp_send_stop(void) { smp_call_function(stop_this_cpu, NULL, 1, 0); smp_num_cpus = 1; __cli(); disable_local_APIC(); __sti(); }
void bcm947xx_machine_halt(void) { printk("System halted\n"); /* Disable interrupts and watchdog and spin forever */ __cli(); sb_watchdog(sbh, 0); while (1); }
void bcm947xx_machine_restart(char *command) { printk("Please stand by while rebooting the system...\n"); /* Set the watchdog timer to reset immediately */ __cli(); sb_watchdog(sbh, 1); while (1); }
static void stop_this_cpu (void * dummy) { /* * Remove this CPU: */ clear_bit(smp_processor_id(), &cpu_online_map); __cli(); disable_local_APIC(); for(;;) __asm__("hlt"); for (;;); }
static void stop_this_cpu (void) { extern void cpu_halt (void); /* * Remove this CPU: */ clear_bit(smp_processor_id(), &cpu_online_map); max_xtp(); __cli(); cpu_halt(); }
void __global_cli(void) { unsigned long flags; __save_flags(flags); if (flags & ST0_IE) { int cpu = smp_processor_id(); __cli(); if (!local_irq_count(cpu)) get_irqlock(cpu); } }
static void sandpoint_restart(char *cmd) { __cli(); /* Set exception prefix high - to the firmware */ _nmask_and_or_msr(0, MSR_IP); /* Reset system via Port 92 */ outb(0x00, 0x92); outb(0x01, 0x92); for (;;) ; /* Spin until reset happens */ }
static struct pci_ops * __devinit pci_check_direct(void) { unsigned int tmp; unsigned long flags; __save_flags(flags); __cli(); /* * Check if configuration type 1 works. */ if (pci_probe & PCI_PROBE_CONF1) { outb (0x01, 0xCFB); tmp = inl (0xCF8); outl (0x80000000, 0xCF8); if (inl (0xCF8) == 0x80000000 && pci_sanity_check(&pci_direct_conf1)) { outl (tmp, 0xCF8); __restore_flags(flags); printk(KERN_INFO "PCI: Using configuration type 1\n"); request_region(0xCF8, 8, "PCI conf1"); #ifdef CONFIG_MULTIQUAD /* Multi-Quad has an extended PCI Conf1 */ if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ) return &pci_direct_mq_conf1; #endif return &pci_direct_conf1; } outl (tmp, 0xCF8); } /* * Check if configuration type 2 works. */ if (pci_probe & PCI_PROBE_CONF2) { outb (0x00, 0xCFB); outb (0x00, 0xCF8); outb (0x00, 0xCFA); if (inb (0xCF8) == 0x00 && inb (0xCFA) == 0x00 && pci_sanity_check(&pci_direct_conf2)) { __restore_flags(flags); printk(KERN_INFO "PCI: Using configuration type 2\n"); request_region(0xCF8, 4, "PCI conf2"); return &pci_direct_conf2; } } __restore_flags(flags); return NULL; }
/* * Initialize controller registers with default values. */ static int __init initRegisters (void) { RegInitializer *p; byte t; unsigned long flags; __save_flags(flags); /* local CPU only */ __cli(); /* local CPU only */ outb_p(regOn, basePort); for (p = initData; p->reg != 0; ++p) outReg(p->data, p->reg); outb_p(0x01, regPort); t = inb(regPort) & 0x01; outb_p(regOff, basePort); __restore_flags(flags); /* local CPU only */ return t; }
/* * do_pdc4030_io() is called from do_rw_disk, having had the block number * already set up. It issues a READ or WRITE command to the Promise * controller, assuming LBA has been used to set up the block number. */ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, struct request *rq) { unsigned long timeout; byte stat; if (rq->cmd == READ) { ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL); OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG); /* The card's behaviour is odd at this point. If the data is available, DRQ will be true, and no interrupt will be generated by the card. If this is the case, we need to simulate an interrupt. Ugh! Otherwise, if an interrupt will occur, bit0 of the SELECT register will be high, so we can just return and be interrupted.*/ timeout = jiffies + HZ/20; /* 50ms wait */ do { stat=GET_STAT(); if(stat & DRQ_STAT) { disable_irq(HWIF(drive)->irq); ide_intr(HWIF(drive)->irq,HWGROUP(drive),NULL); enable_irq(HWIF(drive)->irq); return ide_stopped; } if(IN_BYTE(IDE_SELECT_REG) & 0x01) return ide_started; udelay(1); } while (time_before(jiffies, timeout)); printk("%s: reading: No DRQ and not waiting - Odd!\n", drive->name); return ide_started; } if (rq->cmd == WRITE) { ide_startstop_t startstop; OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG); if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) { printk("%s: no DRQ after issuing PROMISE_WRITE\n", drive->name); return startstop; } if (!drive->unmask) __cli(); /* local CPU only */ HWGROUP(drive)->wrq = *rq; /* scratchpad */ return promise_write(drive); } printk("%s: bad command: %d\n", drive->name, rq->cmd); ide_end_request(0, HWGROUP(drive)); return ide_stopped; }
void fn0C00_0100(byte cl, byte ah, byte ch) { __cli(); do { do { byte al_26 = __inb(0x03DA); ax = DPB(ax, al_26 & 0x08, 0, 8); } while ((al_26 & 0x08) == 0x00); cl = cl + 0x01; word16 bx_34 = 0x018F; uint8 bl_35 = 0x8F; do { do { byte al_47 = __inb(0x03DA); ax = DPB(ax, al_47 & 0x01, 0, 8); } while ((al_47 & 0x01) != 0x00); do { byte al_54 = __inb(0x03DA); ax = DPB(ax_84, al_54 & 0x01, 0, 8); word16 ax_84 = ax; } while ((al_54 & 0x01) == 0x00); __outb(0x03C8, 0x00); __outb(0x03C9, cl); Eq_50 al_65 = bl_35 >>u 0x01; __outb(0x03C9, al_65); ch = ch + al_65; __outb(0x03C9, ch); bx_34 = bx_34 - 0x0001; ax = DPB(ax_84, ch, 0, 8); bl_35 = (byte) bx_34; } while (bx_34 != 0x0000); word16 ax_75 = DPB(ax_84, __inb(0x60), 0, 8); ax = ax_75 - 0x0001; byte al_77 = (byte) (ax_75 - 0x0001); } while (ax_75 != 0x0001); __outb(0x03C8, al_77); __outb(0x03C9, al_77); __outb(0x03C9, al_77); __outb(0x03C9, al_77); return; }
/* * This routine handles various exception codes. It determines the address, * and the problem, and then passes it off to one of the appropriate * routines. */ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long offset) { static spinlock_t terminate_lock = SPIN_LOCK_UNLOCKED; set_eiem(0); __cli(); spin_lock(&terminate_lock); /* unlock the pdc lock if necessary */ pdc_emergency_unlock(); /* restart pdc console if necessary */ if (!console_drivers) pdc_console_restart(); /* Not all switch paths will gutter the processor... */ switch(code){ case 1: transfer_pim_to_trap_frame(regs); break; default: /* Fall through */ break; } show_stack((unsigned long *)regs->gr[30]); printk("\n"); printk(KERN_CRIT "%s: Code=%d regs=%p (Addr=" RFMT ")\n", msg, code, regs, offset); show_regs(regs); spin_unlock(&terminate_lock); /* put soft power button back under hardware control; * if the user had pressed it once at any time, the * system will shut down immediately right here. */ pdc_soft_power_button(0); /* Gutter the processor... */ for(;;) ; }
static inline void send_IPI_mask_sequence(int mask, int vector) { unsigned long cfg, flags; unsigned int query_cpu, query_mask; /* * Hack. The clustered APIC addressing mode doesn't allow us to send * to an arbitrary mask, so I do a unicasts to each CPU instead. This * should be modified to do 1 message per cluster ID - mbligh */ __save_flags(flags); __cli(); for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) { query_mask = 1 << query_cpu; if (query_mask & mask) { /* * Wait for idle. */ apic_wait_icr_idle(); /* * prepare target chip field */ if(clustered_apic_mode == CLUSTERED_APIC_XAPIC) cfg = __prepare_ICR2(cpu_to_physical_apicid(query_cpu)); else cfg = __prepare_ICR2(cpu_to_logical_apicid(query_cpu)); apic_write_around(APIC_ICR2, cfg); /* * program the ICR */ cfg = __prepare_ICR(0, vector); /* * Send the IPI. The write to APIC_ICR fires this off. */ apic_write_around(APIC_ICR, cfg); } } __restore_flags(flags); }
void __init setup_APIC_clocks (void) { printk("Using local APIC timer interrupts.\n"); using_apic_timer = 1; __cli(); calibration_result = calibrate_APIC_clock(); /* * Now set up the timer for real. */ setup_APIC_timer((void *)calibration_result); __sti(); /* and update all other cpus */ smp_call_function(setup_APIC_timer, (void *)calibration_result, 1, 1); }
static struct pci_ops * __devinit pci_check_direct(void) { unsigned int tmp; unsigned long flags; __save_flags(flags); __cli(); /* * Check if configuration type 1 works. */ if (pci_probe & PCI_PROBE_CONF1) { outb (0x01, 0xCFB); tmp = inl (0xCF8); outl (0x80000000, 0xCF8); if (inl (0xCF8) == 0x80000000 && pci_sanity_check(&pci_direct_conf1)) { outl (tmp, 0xCF8); __restore_flags(flags); printk("PCI: Using configuration type 1\n"); request_region(0xCF8, 8, "PCI conf1"); return &pci_direct_conf1; } outl (tmp, 0xCF8); } /* * Check if configuration type 2 works. */ if (pci_probe & PCI_PROBE_CONF2) { outb (0x00, 0xCFB); outb (0x00, 0xCF8); outb (0x00, 0xCFA); if (inb (0xCF8) == 0x00 && inb (0xCFA) == 0x00 && pci_sanity_check(&pci_direct_conf2)) { __restore_flags(flags); printk("PCI: Using configuration type 2\n"); request_region(0xCF8, 4, "PCI conf2"); return &pci_direct_conf2; } } __restore_flags(flags); return NULL; }