/* * Check if this is a dual port controller. */ static int detect_auxiliary_port(void) { int loops = 10; int retval = 0; /* Put the value 0x5A in the output buffer using the "Write * Auxiliary Device Output Buffer" command (0xD3). Poll the * Status Register for a while to see if the value really * turns up in the Data Register. If the KBD_STAT_MOUSE_OBF * bit is also set to 1 in the Status Register, we assume this * controller has an Auxiliary Port (a.k.a. Mouse Port). */ kb_wait(); kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF); kb_wait(); kbd_write_output(0x5a); /* 0x5a is a random dummy value. */ do { unsigned char status = kbd_read_status(); if (status & KBD_STAT_OBF) { kbd_read_input(); if (status & KBD_STAT_MOUSE_OBF) { printk( "Detected PS/2 Mouse Port.\n"); retval = 1; } break; } mdelay(1); } while (--loops); return retval; }
/* * Send a byte to the mouse. */ static void aux_write_dev(int val) { kb_wait(); kbd_write_command(KBD_CCMD_WRITE_MOUSE); kb_wait(); kbd_write_output(val); }
static void kbd_write_cmd(int cmd) { kb_wait(); kbd_write_command(KBD_CCMD_WRITE_MODE); kb_wait(); kbd_write_output(cmd); }
int pckbd_pm_resume(struct pm_dev *dev, pm_request_t rqst, void *data) { #if defined CONFIG_PSMOUSE unsigned long flags; if (rqst == PM_RESUME) { if (queue) { /* Aux port detected */ if (aux_count == 0) { /* Mouse not in use */ spin_lock_irqsave(&kbd_controller_lock, flags); /* * Dell Lat. C600 A06 enables mouse after resume. * When user touches the pad, it posts IRQ 12 * (which we do not process), thus holding keyboard. */ kbd_write_command(KBD_CCMD_MOUSE_DISABLE); /* kbd_write_cmd(AUX_INTS_OFF); */ /* Config & lock */ kb_wait(); kbd_write_command(KBD_CCMD_WRITE_MODE); kb_wait(); kbd_write_output(AUX_INTS_OFF); spin_unlock_irqrestore(&kbd_controller_lock, flags); } } } #endif return 0; }
void jazz_machine_restart(char *command) { while(1) { kb_wait(); jazz_write_command(0xd1); kb_wait(); jazz_write_output(0x00); } }
static void kbd_write_cmd(int cmd) { unsigned long flags; kb_wait(); kbd_write_command(KBD_CCMD_WRITE_MODE); kb_wait(); kbd_write_output(cmd); }
PRIVATE void set_leds() { u8 leds = (caps_lock << 2) | (num_lock << 1) | (scroll_lock); kb_wait(); out_byte(KB_DATA, LED_CODE); kb_ack(); kb_wait(); out_byte(KB_DATA, leds); kb_ack(); }
/* * Send a byte to the mouse & handle returned ack */ static void __aux_write_ack(int val) { kb_wait(); kbd_write_command(KBD_CCMD_WRITE_MOUSE); kb_wait(); kbd_write_output(val); /* we expect an ACK in response. */ mouse_reply_expected++; kb_wait(); }
static void kbd_write_cmd(int cmd) { unsigned long flags; spin_lock_irqsave(&kbd_controller_lock, flags); kb_wait(); kbd_write_command(KBD_CCMD_WRITE_MODE); kb_wait(); kbd_write_output(cmd); spin_unlock_irqrestore(&kbd_controller_lock, flags); }
/* * Send a byte to the mouse. */ static void aux_write_dev(int val) { unsigned long flags; spin_lock_irqsave(&kbd_controller_lock, flags); kb_wait(); kbd_write_command(KBD_CCMD_WRITE_MOUSE); kb_wait(); kbd_write_output(val); spin_unlock_irqrestore(&kbd_controller_lock, flags); }
static void set_leds(unsigned char TYPE) { /* bits 3-7: Must be zero. bit 2: Capslock LED (1 = on, 0 = off). bit 1: Numlock LED (1 = on, 0 = off). bit 0: Scroll lock LED (1 = on, 0 = off). */ static unsigned char leds=0;/*All leds turned off*/ kb_wait(); outportb(0x60,0xED); kb_wait(); outportb(0x60, leds | TYPE & 0x07 ); }
void KeyboardManager::serviceIRQ(void) { send_cmd(0xAD); // disable the keyboard kb_wait(); uint8 scancode = inportb(0x60); if (extended_scancode == 0xE0) { if (scancode == 0x2A || scancode == 0x36 || scancode >= E0_BASE) { extended_scancode = 0; send_cmd(0xAE); // enable the keyboard return; } scancode = E0_KEYS[scancode]; } else if (extended_scancode == 0xE1 && scancode == 0x1D) { extended_scancode = 0x100; send_cmd(0xAE); // enable the keyboard return; } else if (extended_scancode == 0x100 && scancode == 0x45) scancode = E1_PAUSE; extended_scancode = 0; if (scancode == 0xFF || scancode == 0xFA || scancode == 0xFE || scancode == 0x00) // non parsable codes, ACK and keyb. buffer errors { debug(A_KB_MANAGER, "Non-parsable scancode %X \n", scancode); send_cmd(0xAE); // enable the keyboard return; } if (scancode == 0xE0 || scancode == 0xE1) { extended_scancode = scancode; send_cmd(0xAE); // enable the keyboard return; } modifyKeyboardStatus(scancode); setLEDs(); // setting the leds if ((scancode & 0200)) // if a key was released just ignore it { send_cmd(0xAE); // enable the keyboard return; } if (main_console) { keyboard_buffer_.put(scancode); // put it inside the buffer main_console->addJob(); } send_cmd(0xAE); // enable the keyboard }
void hard_reset( void ) { int i, j; // sti(); /* Write 0x1234 to absolute memory location 0x472. The BIOS reads this on booting to tell it to "Bypass memory test (also warm boot)". This seems like a fairly standard thing that gets set by REBOOT.COM programs. */ unprotect_dos_mem(); *( ( uint16 * )0x472 ) = 0x1234; for ( ;; ) { for ( i = 0; i < 100; ++i ) { kb_wait(); for ( j = 0; j < 100000; ++j ) /*** EMPTY ***/ ; outb( 0xfe, 0x64 ); /* pulse reset low */ // udelay(100); } // __asm__ __volatile__("\tlidt %0": "=m" (no_idt)); } }
static int send_data(unsigned char data) { int retries = 3; unsigned long flags; do { unsigned long timeout = 1000; spin_lock_irqsave(&pcikbd_lock, flags); kb_wait(); acknowledge = 0; resend = 0; reply_expected = 1; pcikbd_outb(data, pcikbd_iobase + KBD_DATA_REG); spin_unlock_irqrestore(&pcikbd_lock, flags); do { if (acknowledge) return 1; if (resend) break; mdelay(1); } while (--timeout); if (timeout == 0) break; } while (retries-- > 0); return 0; }
static void kbd_write_output_w(int data) { unsigned long flags; spin_lock_irqsave(&kbd_controller_lock, flags); kb_wait(); KBDDATA = data & 0xff; spin_unlock_irqrestore(&kbd_controller_lock, flags); }
static void kbd_write_command_w(int data) { unsigned long flags; spin_lock_irqsave(&kbd_controller_lock, flags); kb_wait(); kbd_write_command(data); spin_unlock_irqrestore(&kbd_controller_lock, flags); }
/* * Check if this is a dual port controller. */ static int __init detect_auxiliary_port(void) { unsigned long flags; int loops = 10; int retval = 0; /* Check if the BIOS detected a device on the auxiliary port. */ if (aux_device_present == 0xaa) return 1; spin_lock_irqsave(&kbd_controller_lock, flags); /* Put the value 0x5A in the output buffer using the "Write * Auxiliary Device Output Buffer" command (0xD3). Poll the * Status Register for a while to see if the value really * turns up in the Data Register. If the KBD_STAT_MOUSE_OBF * bit is also set to 1 in the Status Register, we assume this * controller has an Auxiliary Port (a.k.a. Mouse Port). */ kb_wait(); kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF); kb_wait(); kbd_write_output(0x5a); /* 0x5a is a random dummy value. */ do { unsigned char status = kbd_read_status(); if (status & KBD_STAT_OBF) { (void) kbd_read_input(); if (status & KBD_STAT_MOUSE_OBF) { printk(KERN_INFO "Detected PS/2 Mouse Port.\n"); retval = 1; } break; } mdelay(1); } while (--loops); spin_unlock_irqrestore(&kbd_controller_lock, flags); return retval; }
/* * BIOSKeyboardHit - test for keyboard hit */ bool BIOSKeyboardHit( void ) { int type, attr; unsigned char row, col; _uigetcursor( &row, &col, &type, &attr ); _uisetcursor( row, col, C_NORMAL, attr ); _ui_refresh( 0 ); return( ( kb_wait( 0, 0 ) != 0 ) ); } /* BIOSKeyboardHit */
static int kbd_write_output_w_and_wait(int data) { unsigned long flags; int input; spin_lock_irqsave(&kbd_controller_lock, flags); kb_wait(); kbd_write_output(data); input = kbd_wait_for_input(); spin_unlock_irqrestore(&kbd_controller_lock, flags); return input; }
/* XXX This ends up at the ARC firmware prompt ... */ void sni_machine_restart(char *command) { int i, j; /* This does a normal via the keyboard controller like a PC. We can do that easier ... */ local_irq_disable(); for (;;) { for (i=0; i<100; i++) { kb_wait(); for(j = 0; j < 100000 ; j++) /* nothing */; outb_p(0xfe,0x64); /* pulse reset low */ } } }
/* * This routine reboots the machine by asking the keyboard * controller to pulse the reset-line low. We try that for a while, * and if it doesn't work, we do some other stupid things. */ void hard_reset_now(void) { int i, j; extern unsigned long pg0[1024]; sti(); /* rebooting needs to touch the page at absolute addr 0 */ pg0[0] = 7; *((unsigned short *)0x472) = 0x1234; for (;;) { for (i=0; i<100; i++) { kb_wait(); for(j = 0; j < 100000 ; j++) /* nothing */; outb(0xfe,0x64); /* pulse reset low */ } __asm__("\tlidt _no_idt"); } }
void machine_restart(char * __unused) { int i; printk("machine restart\n"); #ifdef CONFIG_SMP smp_halt(); #endif if (!reboot_force) { local_irq_disable(); #ifndef CONFIG_SMP disable_local_APIC(); #endif disable_IO_APIC(); local_irq_enable(); } /* Tell the BIOS if we want cold or warm reboot */ *((unsigned short *)__va(0x472)) = reboot_mode; for (;;) { /* Could also try the reset bit in the Hammer NB */ switch (reboot_type) { case BOOT_KBD: for (i=0; i<100; i++) { kb_wait(); udelay(50); outb(0xfe,0x64); /* pulse reset low */ udelay(50); } case BOOT_TRIPLE: __asm__ __volatile__("lidt (%0)": :"r" (&no_idt)); __asm__ __volatile__("int3"); reboot_type = BOOT_KBD; break; } } }
static EVENT doget( bool update ) /*******************************/ { register EVENT ev; static short ReturnIdle = 1; for( ;; ) { ev = forcedevent(); if( ev > EV_NO_EVENT ) break; ev = _uievent(); if( ev > EV_NO_EVENT ) break; if( ReturnIdle ) { --ReturnIdle; return( EV_IDLE ); } else { if( update ) uirefresh(); if( UIData->busy_wait ) { return( EV_SINK ); } } kb_wait( 60, 0 ); } ReturnIdle = 1; if( ev==EV_REDRAW_SCREEN ){ extern bool UserForcedTermRefresh; SAREA screen={ 0, 0, 0, 0 }; screen.height= UIData->height; screen.width= UIData->width; uidirty( screen ); UserForcedTermRefresh= TRUE; physupdate( &screen ); } return( ev ); }
/* * send_data sends a character to the keyboard and waits * for a acknowledge, possibly retrying if asked to. Returns * the success status. */ static int send_data(unsigned char data) { int retries = 3; int i; do { kb_wait(); acknowledge = 0; resend = 0; outb_p(data, 0x60); for(i=0; i<0x20000; i++) { inb_p(0x64); /* just as a delay */ if (acknowledge) return 1; if (resend) break; } if (!resend) return 0; } while (retries-- > 0); return 0; }
static void kbd_write_command_w(int data) { if(kb_wait()) PRINTF("timeout in kbd_write_command_w\n"); kbd_write_command(data); }
static inline void send_cmd(unsigned char c) { kb_wait(); outb(c,0x64); }
static void keyboard_interrupt(int int_pt_regs) { unsigned char scancode; static unsigned int prev_scancode = 0; /* remember E0, E1 */ char up_flag; /* 0 or 0200 */ char raw_mode; pt_regs = (struct pt_regs *) int_pt_regs; send_cmd(0xAD); /* disable keyboard */ kb_wait(); if ((inb_p(0x64) & kbd_read_mask) != 0x01) goto end_kbd_intr; scancode = inb(0x60); mark_bh(KEYBOARD_BH); if (scancode == 0xfa) { acknowledge = 1; goto end_kbd_intr; } else if (scancode == 0xfe) { resend = 1; goto end_kbd_intr; } else if (scancode == 0) { #ifdef KBD_REPORT_ERR printk("keyboard buffer overflow\n"); #endif goto end_kbd_intr; } else if (scancode == 0xff) { #ifdef KBD_REPORT_ERR printk("keyboard error\n"); #endif prev_scancode = 0; goto end_kbd_intr; } tty = ttytab[fg_console]; kbd = kbd_table + fg_console; if ((raw_mode = vc_kbd_mode(kbd,VC_RAW))) { put_queue(scancode); /* we do not return yet, because we want to maintain the key_down array, so that we have the correct values when finishing RAW mode or when changing VT's */ } if (scancode == 0xe0 || scancode == 0xe1) { prev_scancode = scancode; goto end_kbd_intr; } /* * Convert scancode to keysym, using prev_scancode. */ up_flag = (scancode & 0200); scancode &= 0x7f; if (prev_scancode) { /* * usually it will be 0xe0, but a Pause key generates * e1 1d 45 e1 9d c5 when pressed, and nothing when released */ if (prev_scancode != 0xe0) { if (prev_scancode == 0xe1 && scancode == 0x1d) { prev_scancode = 0x100; goto end_kbd_intr; } else if (prev_scancode == 0x100 && scancode == 0x45) { scancode = E1_PAUSE; prev_scancode = 0; } else { printk("keyboard: unknown e1 escape sequence\n"); prev_scancode = 0; goto end_kbd_intr; } } else { prev_scancode = 0; /* * The keyboard maintains its own internal caps lock and * num lock statuses. In caps lock mode E0 AA precedes make * code and E0 2A follows break code. In num lock mode, * E0 2A precedes make code and E0 AA follows break code. * We do our own book-keeping, so we will just ignore these. */ /* * For my keyboard there is no caps lock mode, but there are * both Shift-L and Shift-R modes. The former mode generates * E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs. * So, we should also ignore the latter. - [email protected] */ if (scancode == 0x2a || scancode == 0x36) goto end_kbd_intr; if (e0_keys[scancode]) scancode = e0_keys[scancode]; else if (!raw_mode) { #ifdef KBD_REPORT_UNKN printk("keyboard: unknown scancode e0 %02x\n", scancode); #endif goto end_kbd_intr; } } } else if (scancode >= E0_BASE && !raw_mode) { #ifdef KBD_REPORT_UNKN printk("keyboard: scancode (%02x) not in range 00 - %2x\n", scancode, E0_BASE - 1); #endif goto end_kbd_intr; } /* * At this point the variable `scancode' contains the keysym. * We keep track of the up/down status of the key, and * return the keysym if in MEDIUMRAW mode. * (Note: earlier kernels had a bug and did not pass the up/down * bit to applications.) */ if (up_flag) { clear_bit(scancode, key_down); rep = 0; } else rep = set_bit(scancode, key_down); if (raw_mode) goto end_kbd_intr; if (vc_kbd_mode(kbd, VC_MEDIUMRAW)) { put_queue(scancode + up_flag); goto end_kbd_intr; } /* * Small change in philosophy: earlier we defined repetition by * rep = scancode == prev_keysym; * prev_keysym = scancode; * but now by the fact that the depressed key was down already. * Does this ever make a difference? */ /* * Repeat a key only if the input buffers are empty or the * characters get echoed locally. This makes key repeat usable * with slow applications and under heavy loads. */ if (!rep || (vc_kbd_mode(kbd,VC_REPEAT) && tty && (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) { u_short key_code; u_char type; /* the XOR below used to be an OR */ int shift_final = shift_state ^ kbd->lockstate; key_code = key_map[shift_final][scancode]; type = KTYP(key_code); if (type == KT_LETTER) { type = KT_LATIN; if (vc_kbd_led(kbd,VC_CAPSLOCK)) key_code = key_map[shift_final ^ (1<<KG_SHIFT)][scancode]; } (*key_handler[type])(key_code & 0xff, up_flag); } end_kbd_intr: send_cmd(0xAE); /* enable keyboard */ }
/* * Windows compatible x86 hardware expects the following on reboot: * * 1) If the FADT has the ACPI reboot register flag set, try it * 2) If still alive, write to the keyboard controller * 3) If still alive, write to the ACPI reboot register again * 4) If still alive, write to the keyboard controller again * * If the machine is still alive at this stage, it gives up. We default to * following the same pattern, except that if we're still alive after (4) we'll * try to force a triple fault and then cycle between hitting the keyboard * controller and doing that */ static void native_machine_emergency_restart(void) { int i; int attempt = 0; int orig_reboot_type = reboot_type; if (reboot_emergency) emergency_vmx_disable_all(); tboot_shutdown(TB_SHUTDOWN_REBOOT); /* Tell the BIOS if we want cold or warm reboot */ *((unsigned short *)__va(0x472)) = reboot_mode; for (;;) { /* Could also try the reset bit in the Hammer NB */ switch (reboot_type) { case BOOT_KBD: mach_reboot_fixups(); /* For board specific fixups */ for (i = 0; i < 10; i++) { kb_wait(); udelay(50); outb(0xfe, 0x64); /* Pulse reset low */ udelay(50); } if (attempt == 0 && orig_reboot_type == BOOT_ACPI) { attempt = 1; reboot_type = BOOT_ACPI; } else { reboot_type = BOOT_TRIPLE; } break; case BOOT_TRIPLE: load_idt(&no_idt); __asm__ __volatile__("int3"); reboot_type = BOOT_KBD; break; case BOOT_BIOS: machine_real_restart(MRR_BIOS); reboot_type = BOOT_KBD; break; case BOOT_ACPI: acpi_reboot(); reboot_type = BOOT_KBD; break; case BOOT_EFI: if (efi_enabled(EFI_RUNTIME_SERVICES)) efi.reset_system(reboot_mode ? EFI_RESET_WARM : EFI_RESET_COLD, EFI_SUCCESS, 0, NULL); reboot_type = BOOT_KBD; break; case BOOT_CF9: port_cf9_safe = true; /* Fall through */ case BOOT_CF9_COND: if (port_cf9_safe) { u8 cf9 = inb(0xcf9) & ~6; outb(cf9|2, 0xcf9); /* Request hard reset */ udelay(50); outb(cf9|6, 0xcf9); /* Actually do the reset */ udelay(50); } reboot_type = BOOT_KBD; break; } } }
static void kbd_write_output_w(int data) { if(kb_wait()) PRINTF("timeout in kbd_write_output_w\n"); kbd_write_output(data); }
static void kbd_write_command_w(int data) { kb_wait(); kbd_write_command(data); }