sys_reboot()&acpi_enter_sleep_state()

asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void * arg)
{
    char buffer[256];
    
    /* We only trust the superuser with rebooting the system. */
    if (!capable(CAP_SYS_BOOT))
      return -EPERM;

    /* For safety, we require "magic" arguments. */
    if (magic1 != LINUX_REBOOT_MAGIC1 ||
        (magic2 != LINUX_REBOOT_MAGIC2 && magic2 != LINUX_REBOOT_MAGIC2A &&
    magic2 != LINUX_REBOOT_MAGIC2B))
      return -EINVAL;

    lock_kernel();
    
    switch (cmd) {
    case LINUX_REBOOT_CMD_RESTART:
      notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
      printk(KERN_EMERG "Restarting system.\n");
      machine_restart(NULL);
      break;
    case LINUX_REBOOT_CMD_CAD_ON:
      C_A_D = 1;
      break;
    case LINUX_REBOOT_CMD_CAD_OFF:
      C_A_D = 0;
      break;
    case LINUX_REBOOT_CMD_HALT:
      notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
      printk(KERN_EMERG "System halted.\n");
      machine_halt();
      do_exit(0);
      break;
    case LINUX_REBOOT_CMD_POWER_OFF:
      notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
      printk(KERN_EMERG "Power down.\n");
      machine_power_off();
      do_exit(0);
      break;
    case LINUX_REBOOT_CMD_RESTART2:
      if (strncpy_from_user(&buffer[0], (char *)arg, sizeof(buffer) - 1) < 0) {
      unlock_kernel();
      return -EFAULT;
      }
      buffer[sizeof(buffer) - 1] = '\0';
      notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);
      printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
      machine_restart(buffer);
      break;
    default:
      unlock_kernel();
      return -EINVAL;
    }
    
    unlock_kernel();
    
    return 0;
}
 
Hwsleep.c
/******************************************************************************
 *
 * FUNCTION:    Acpi_enter_sleep_state
 *
 * PARAMETERS:  Sleep_state         - Which sleep state to enter
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231)
 *
 ******************************************************************************/

ACPI_STATUS
acpi_enter_sleep_state (
	u8                  sleep_state)
{
	ACPI_STATUS         status;
	ACPI_OBJECT_LIST    arg_list;
	ACPI_OBJECT         arg;
	u8                  type_a;
	u8                  type_b;
	u16                 PM1_acontrol;
	u16                 PM1_bcontrol;


	/*
	 * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
	 */

	status = acpi_hw_obtain_sleep_type_register_data (sleep_state, &type_a, &type_b);
	if (!ACPI_SUCCESS (status)) {
		return status;
	}

	/* run the _PTS and _GTS methods */

	MEMSET(&arg_list, 0, sizeof(arg_list));
	arg_list.count = 1;
	arg_list.pointer = &arg;

	MEMSET(&arg, 0, sizeof(arg));
	arg.type = ACPI_TYPE_INTEGER;
	arg.integer.value = sleep_state;

	acpi_evaluate_object(NULL, "\\_PTS", &arg_list, NULL);
	acpi_evaluate_object(NULL, "\\_GTS", &arg_list, NULL);

	/* clear wake status */

	acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, WAK_STS, 1);

	disable();

	PM1_acontrol = (u16) acpi_hw_register_read(ACPI_MTX_LOCK, PM1_CONTROL);

	/* mask off SLP_EN and SLP_TYP fields */
	PM1_acontrol &= 0xC3FF;
	PM1_bcontrol = PM1_acontrol;

	/* mask in SLP_TYP */
	PM1_acontrol |= (type_a << acpi_hw_get_bit_shift (SLP_TYPE_X_MASK));
	PM1_bcontrol |= (type_b << acpi_hw_get_bit_shift (SLP_TYPE_X_MASK));

	/* write #1: fill in SLP_TYPE data */
	acpi_hw_register_write(ACPI_MTX_LOCK, PM1_a_CONTROL, PM1_acontrol);
	acpi_hw_register_write(ACPI_MTX_LOCK, PM1_b_CONTROL, PM1_bcontrol);

	/* mask in SLP_EN */
	PM1_acontrol |= (1 << acpi_hw_get_bit_shift (SLP_EN_MASK));
	PM1_bcontrol |= (1 << acpi_hw_get_bit_shift (SLP_EN_MASK));

	/* write #2: the whole tamale */
	acpi_hw_register_write(ACPI_MTX_LOCK, PM1_a_CONTROL, PM1_acontrol);
	acpi_hw_register_write(ACPI_MTX_LOCK, PM1_b_CONTROL, PM1_bcontrol);

	enable();

	return (AE_OK);
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章