⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sm_osl.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * * Module Name: sm_osl.c *   $Revision: 16 $ * *****************************************************************************//* *  Copyright (C) 2000, 2001 Andrew Grover * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/types.h>#include <linux/proc_fs.h>#include <linux/pm.h>#include <asm/uaccess.h>#include <linux/acpi.h>#include <asm/io.h>#include <linux/mc146818rtc.h>#include <linux/delay.h>#include <acpi.h>#include "sm.h"MODULE_AUTHOR("Andrew Grover");MODULE_DESCRIPTION("ACPI Component Architecture (CA) - ACPI System Driver");MODULE_LICENSE("GPL");#define SM_PROC_INFO		"info"#define SM_PROC_DSDT		"dsdt"extern struct proc_dir_entry	*bm_proc_root;struct proc_dir_entry		*sm_proc_root = NULL;static void 			(*sm_pm_power_off)(void) = NULL;static ssize_t sm_osl_read_dsdt(struct file *, char *, size_t, loff_t *);static struct file_operations proc_dsdt_operations = {	read:		sm_osl_read_dsdt,};static acpi_status sm_osl_suspend(u32 state);struct proc_dir_entry *bm_proc_sleep;struct proc_dir_entry *bm_proc_alarm;struct proc_dir_entry *bm_proc_gpe;static intsm_osl_proc_read_sleep (        char                    *page,        char                    **start,        off_t                   off,        int                     count,        int                     *eof,        void                    *context){	SM_CONTEXT    *system = (SM_CONTEXT*) context;	char          *str = page;	int           len;	int           i;	if (!system)               goto end;	if (off != 0)               goto end;	for (i = 0; i <= ACPI_S5; i++) {		if (system->states[i])			str += sprintf(str,"S%d ", i);	}	str += sprintf(str, "\n");end:	len = (str - page);	if (len < (off + count))		*eof = 1;	*start = page + off;	len -= off;	if (len > count)		len = count;	if (len < 0)		len = 0;	return (len);}int sm_osl_proc_write_sleep (struct file *file,			     const char *buffer,			     unsigned long count,			     void *data){	SM_CONTEXT    *system = (SM_CONTEXT*) data;	char          str[10];	char          *strend;	unsigned long value;		if (count > (sizeof(str) - 1))		return -EINVAL;		if (copy_from_user(str,buffer,count))		return -EFAULT;		str[count] = '\0';		value = simple_strtoul(str,&strend,0);	if (str == strend)		return -EINVAL;		if (value == 0 || value >= ACPI_S5)		return -EINVAL;		/*	 * make sure that the sleep state is supported	 */	if (system->states[value] != TRUE)		return -EINVAL;		sm_osl_suspend(value);		return (count);}/**************************************************************************** * * FUNCTION:	sm_osl_proc_read_info * ****************************************************************************/static intsm_osl_proc_read_info (	char			*page,	char			**start,	off_t			off,	int 			count,	int 			*eof,	void			*context){	acpi_status		status = AE_OK;	SM_CONTEXT		*system = NULL;	char			*p = page;	int			len;	acpi_system_info	system_info;	acpi_buffer		buffer;	u32			i = 0;	if (!context) {		goto end;	}	system = (SM_CONTEXT*) context;	/* don't get status more than once for a single proc read */	if (off != 0) {		goto end;	}	/*	 * Get ACPI CA Information.	 */	buffer.length  = sizeof(system_info);	buffer.pointer = &system_info;	status = acpi_get_system_info(&buffer);	if (ACPI_FAILURE(status)) {		p += sprintf(p, "ACPI-CA Version:         unknown\n");	}	else {		p += sprintf(p, "ACPI-CA Version:         %x\n",			system_info.acpi_ca_version);	}	p += sprintf(p, "Sx States Supported:     ");	for (i=0; i<SM_MAX_SYSTEM_STATES; i++) {		if (system->states[i]) {			p += sprintf(p, "S%d ", i);		}	}	p += sprintf(p, "\n");end:	len = (p - page);	if (len <= off+count) *eof = 1;	*start = page + off;	len -= off;	if (len>count) len = count;	if (len<0) len = 0;	return(len);}/**************************************************************************** * * FUNCTION:	sm_osl_read_dsdt * ****************************************************************************/static ssize_tsm_osl_read_dsdt(	struct file		*file,	char			*buf,	size_t			count,	loff_t			*ppos){	acpi_buffer		acpi_buf;	void			*data;	size_t			size = 0;	acpi_buf.length = 0;	acpi_buf.pointer = NULL;	/* determine what buffer size we will need */	if (acpi_get_table(ACPI_TABLE_DSDT, 1, &acpi_buf) != AE_BUFFER_OVERFLOW) {		return 0;	}	acpi_buf.pointer = kmalloc(acpi_buf.length, GFP_KERNEL);	if (!acpi_buf.pointer) {		return -ENOMEM;	}	/* get the table for real */	if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_DSDT, 1, &acpi_buf))) {		kfree(acpi_buf.pointer);		return 0;	}	if (*ppos < acpi_buf.length) {		data = acpi_buf.pointer + file->f_pos;		size = acpi_buf.length - file->f_pos;		if (size > count)			size = count;		if (copy_to_user(buf, data, size)) {			kfree(acpi_buf.pointer);			return -EFAULT;		}	}	kfree(acpi_buf.pointer);	*ppos += size;	return size;}static intsm_osl_proc_read_alarm (	char                    *page,	char                    **start,	off_t                   off,	int                     count,	int                     *eof,	void                    *context){	char *str = page;	int len;	u32 sec,min,hr;	u32 day,mo,yr;	if (off != 0) goto out;	spin_lock(&rtc_lock);	sec = CMOS_READ(RTC_SECONDS_ALARM);	min = CMOS_READ(RTC_MINUTES_ALARM);	hr = CMOS_READ(RTC_HOURS_ALARM);#if 0	/* if I ever get an FACP with proper values, maybe I'll enable this code */	if (acpi_gbl_FADT->day_alrm)		day = CMOS_READ(acpi_gbl_FADT->day_alrm);	else		day =  CMOS_READ(RTC_DAY_OF_MONTH);	if (acpi_gbl_FADT->mon_alrm)		mo = CMOS_READ(acpi_gbl_FADT->mon_alrm);	else		mo = CMOS_READ(RTC_MONTH);;	if (acpi_gbl_FADT->century)		yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + CMOS_READ(RTC_YEAR);	else		yr = CMOS_READ(RTC_YEAR);#else	day = CMOS_READ(RTC_DAY_OF_MONTH);	mo = CMOS_READ(RTC_MONTH);	yr = CMOS_READ(RTC_YEAR);#endif	spin_unlock(&rtc_lock);	BCD_TO_BIN(sec);	BCD_TO_BIN(min);	BCD_TO_BIN(hr);	BCD_TO_BIN(day);	BCD_TO_BIN(mo);	BCD_TO_BIN(yr);	str += sprintf(str,"%4.4u-",yr);	str += (mo > 12) ?		sprintf(str,"**-") :		sprintf(str,"%2.2u-",mo);	str += (day > 31) ?		sprintf(str,"** ") :		sprintf(str,"%2.2u ",day);	str += (hr > 23) ?		sprintf(str,"**:") :		sprintf(str,"%2.2u:",hr);	str += (min > 59) ?		sprintf(str,"**:") :		sprintf(str,"%2.2u:",min);	str += (sec > 59) ?		sprintf(str,"**\n") :		sprintf(str,"%2.2u\n",sec); out:	len = str - page;	if (len < count) *eof = 1;	else if (len > count) len = count;	if (len < 0) len = 0;	*start = page;	return len;}static int get_date_field(char **str, u32 *value){	char *next,*strend;	int error = -EINVAL;	/* try to find delimeter, only to insert null;	 *  the end of string won't have one, but is still valid	 */	next = strpbrk(*str,"- :");	if (next) *next++ = '\0';	*value = simple_strtoul(*str,&strend,10);	/* signal success if we got a good digit */	if (strend != *str) error = 0;	if (next) *str = next;	return error;}int sm_osl_proc_write_alarm (	struct file *file,	const char *buffer,	unsigned long count,	void *data){	char buf[30];	char *str = buf;	u32 sec,min,hr;	u32 day,mo,yr;	int adjust = 0;	unsigned char rtc_control;	int error = -EINVAL;	if (count > sizeof(buf) - 1) return -EINVAL;		if (copy_from_user(str,buffer,count)) return -EFAULT;	str[count] = '\0';	/* check for time adjustment */	if (str[0] == '+') {		str++;		adjust = 1;	}	if ((error = get_date_field(&str,&yr)))  goto out;	if ((error = get_date_field(&str,&mo)))  goto out;	if ((error = get_date_field(&str,&day))) goto out;	if ((error = get_date_field(&str,&hr)))  goto out;	if ((error = get_date_field(&str,&min))) goto out;	if ((error = get_date_field(&str,&sec))) goto out;	if (sec > 59) {		min += 1;		sec -= 60;	}	if (min > 59) {		hr += 1;		min -= 60;	} 	if (hr > 23) {		day += 1;		hr -= 24;	}	if (day > 31) { 		mo += 1;		day -= 31;	}	if (mo > 12) {		yr += 1;		mo -= 12;	}	spin_lock_irq(&rtc_lock);	rtc_control = CMOS_READ(RTC_CONTROL);	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {		BIN_TO_BCD(yr);		BIN_TO_BCD(mo);		BIN_TO_BCD(day);		BIN_TO_BCD(hr);		BIN_TO_BCD(min);		BIN_TO_BCD(sec);	}	if (adjust) {		yr  += CMOS_READ(RTC_YEAR);		mo  += CMOS_READ(RTC_MONTH);		day += CMOS_READ(RTC_DAY_OF_MONTH);		hr  += CMOS_READ(RTC_HOURS);		min += CMOS_READ(RTC_MINUTES);		sec += CMOS_READ(RTC_SECONDS);	}	spin_unlock_irq(&rtc_lock);	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {		BCD_TO_BIN(yr);		BCD_TO_BIN(mo);		BCD_TO_BIN(day);		BCD_TO_BIN(hr);		BCD_TO_BIN(min);		BCD_TO_BIN(sec);	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -