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

📄 video.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	else {		entry->proc_fops = &acpi_video_device_EDID_fops;		entry->data = acpi_driver_data(device);		entry->owner = THIS_MODULE;	}	return 0;}static int acpi_video_device_remove_fs(struct acpi_device *device){	struct acpi_video_device *vid_dev;	vid_dev = acpi_driver_data(device);	if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)		return -ENODEV;	if (acpi_device_dir(device)) {		remove_proc_entry("info", acpi_device_dir(device));		remove_proc_entry("state", acpi_device_dir(device));		remove_proc_entry("brightness", acpi_device_dir(device));		remove_proc_entry("EDID", acpi_device_dir(device));		remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);		acpi_device_dir(device) = NULL;	}	return 0;}/* video bus */static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset){	struct acpi_video_bus *video = seq->private;	if (!video)		goto end;	seq_printf(seq, "Switching heads:              %s\n",		   video->flags.multihead ? "yes" : "no");	seq_printf(seq, "Video ROM:                    %s\n",		   video->flags.rom ? "yes" : "no");	seq_printf(seq, "Device to be POSTed on boot:  %s\n",		   video->flags.post ? "yes" : "no");      end:	return 0;}static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file){	return single_open(file, acpi_video_bus_info_seq_show,			   PDE(inode)->data);}static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset){	struct acpi_video_bus *video = seq->private;	if (!video)		goto end;	printk(KERN_INFO PREFIX "Please implement %s\n", __FUNCTION__);	seq_printf(seq, "<TODO>\n");      end:	return 0;}static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file){	return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data);}static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset){	struct acpi_video_bus *video = seq->private;	unsigned long options;	int status;	if (!video)		goto end;	status = acpi_video_bus_POST_options(video, &options);	if (ACPI_SUCCESS(status)) {		if (!(options & 1)) {			printk(KERN_WARNING PREFIX			       "The motherboard VGA device is not listed as a possible POST device.\n");			printk(KERN_WARNING PREFIX			       "This indicates a BIOS bug. Please contact the manufacturer.\n");		}		printk("%lx\n", options);		seq_printf(seq, "can POST: <integrated video>");		if (options & 2)			seq_printf(seq, " <PCI video>");		if (options & 4)			seq_printf(seq, " <AGP video>");		seq_putc(seq, '\n');	} else		seq_printf(seq, "<not supported>\n");      end:	return 0;}static intacpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file){	return single_open(file, acpi_video_bus_POST_info_seq_show,			   PDE(inode)->data);}static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset){	struct acpi_video_bus *video = seq->private;	int status;	unsigned long id;	if (!video)		goto end;	status = acpi_video_bus_get_POST(video, &id);	if (!ACPI_SUCCESS(status)) {		seq_printf(seq, "<not supported>\n");		goto end;	}	seq_printf(seq, "device POSTed is <%s>\n", device_decode[id & 3]);      end:	return 0;}static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset){	struct acpi_video_bus *video = seq->private;	seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting);	return 0;}static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file){	return single_open(file, acpi_video_bus_POST_seq_show,			   PDE(inode)->data);}static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file){	return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data);}static ssize_tacpi_video_bus_write_POST(struct file *file,			  const char __user * buffer,			  size_t count, loff_t * data){	int status;	struct seq_file *m = file->private_data;	struct acpi_video_bus *video = m->private;	char str[12] = { 0 };	unsigned long opt, options;	if (!video || count + 1 > sizeof str)		return -EINVAL;	status = acpi_video_bus_POST_options(video, &options);	if (!ACPI_SUCCESS(status))		return -EINVAL;	if (copy_from_user(str, buffer, count))		return -EFAULT;	str[count] = 0;	opt = strtoul(str, NULL, 0);	if (opt > 3)		return -EFAULT;	/* just in case an OEM 'forgot' the motherboard... */	options |= 1;	if (options & (1ul << opt)) {		status = acpi_video_bus_set_POST(video, opt);		if (!ACPI_SUCCESS(status))			return -EFAULT;	}	return count;}static ssize_tacpi_video_bus_write_DOS(struct file *file,			 const char __user * buffer,			 size_t count, loff_t * data){	int status;	struct seq_file *m = file->private_data;	struct acpi_video_bus *video = m->private;	char str[12] = { 0 };	unsigned long opt;	if (!video || count + 1 > sizeof str)		return -EINVAL;	if (copy_from_user(str, buffer, count))		return -EFAULT;	str[count] = 0;	opt = strtoul(str, NULL, 0);	if (opt > 7)		return -EFAULT;	status = acpi_video_bus_DOS(video, opt & 0x3, (opt & 0x4) >> 2);	if (!ACPI_SUCCESS(status))		return -EFAULT;	return count;}static int acpi_video_bus_add_fs(struct acpi_device *device){	struct proc_dir_entry *entry = NULL;	struct acpi_video_bus *video;	video = acpi_driver_data(device);	if (!acpi_device_dir(device)) {		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),						     acpi_video_dir);		if (!acpi_device_dir(device))			return -ENODEV;		video->dir = acpi_device_dir(device);		acpi_device_dir(device)->owner = THIS_MODULE;	}	/* 'info' [R] */	entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device));	if (!entry)		return -ENODEV;	else {		entry->proc_fops = &acpi_video_bus_info_fops;		entry->data = acpi_driver_data(device);		entry->owner = THIS_MODULE;	}	/* 'ROM' [R] */	entry = create_proc_entry("ROM", S_IRUGO, acpi_device_dir(device));	if (!entry)		return -ENODEV;	else {		entry->proc_fops = &acpi_video_bus_ROM_fops;		entry->data = acpi_driver_data(device);		entry->owner = THIS_MODULE;	}	/* 'POST_info' [R] */	entry =	    create_proc_entry("POST_info", S_IRUGO, acpi_device_dir(device));	if (!entry)		return -ENODEV;	else {		entry->proc_fops = &acpi_video_bus_POST_info_fops;		entry->data = acpi_driver_data(device);		entry->owner = THIS_MODULE;	}	/* 'POST' [R/W] */	entry =	    create_proc_entry("POST", S_IFREG | S_IRUGO | S_IRUSR,			      acpi_device_dir(device));	if (!entry)		return -ENODEV;	else {		acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;		entry->proc_fops = &acpi_video_bus_POST_fops;		entry->data = acpi_driver_data(device);		entry->owner = THIS_MODULE;	}	/* 'DOS' [R/W] */	entry =	    create_proc_entry("DOS", S_IFREG | S_IRUGO | S_IRUSR,			      acpi_device_dir(device));	if (!entry)		return -ENODEV;	else {		acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;		entry->proc_fops = &acpi_video_bus_DOS_fops;		entry->data = acpi_driver_data(device);		entry->owner = THIS_MODULE;	}	return 0;}static int acpi_video_bus_remove_fs(struct acpi_device *device){	struct acpi_video_bus *video;	video = acpi_driver_data(device);	if (acpi_device_dir(device)) {		remove_proc_entry("info", acpi_device_dir(device));		remove_proc_entry("ROM", acpi_device_dir(device));		remove_proc_entry("POST_info", acpi_device_dir(device));		remove_proc_entry("POST", acpi_device_dir(device));		remove_proc_entry("DOS", acpi_device_dir(device));		remove_proc_entry(acpi_device_bid(device), acpi_video_dir);		acpi_device_dir(device) = NULL;	}	return 0;}/* --------------------------------------------------------------------------                                 Driver Interface   -------------------------------------------------------------------------- *//* device interface */static struct acpi_video_device_attrib*acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id){	int count;	for(count = 0; count < video->attached_count; count++)		if((video->attached_array[count].value.int_val & 0xffff) == device_id)			return &(video->attached_array[count].value.attrib);	return NULL;}static intacpi_video_bus_get_one_device(struct acpi_device *device,			      struct acpi_video_bus *video){	unsigned long device_id;	int status;	struct acpi_video_device *data;	struct acpi_video_device_attrib* attribute;	if (!device || !video)		return -EINVAL;	status =	    acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);	if (ACPI_SUCCESS(status)) {		data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);		if (!data)			return -ENOMEM;		strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);		strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);		acpi_driver_data(device) = data;		data->device_id = device_id;		data->video = video;		data->dev = device;		attribute = acpi_video_get_device_attr(video, device_id);		if((attribute != NULL) && attribute->device_id_scheme) {			switch (attribute->display_type) {			case ACPI_VIDEO_DISPLAY_CRT:				data->flags.crt = 1;				break;			case ACPI_VIDEO_DISPLAY_TV:				data->flags.tvout = 1;				break;			case ACPI_VIDEO_DISPLAY_DVI:				data->flags.dvi = 1;				break;			case ACPI_VIDEO_DISPLAY_LCD:				data->flags.lcd = 1;				break;			default:				data->flags.unknown = 1;				break;			}			if(attribute->bios_can_detect)				data->flags.bios = 1;		} else			data->flags.unknown = 1;		acpi_video_device_bind(video, data);		acpi_video_device_find_cap(data);		status = acpi_install_notify_handler(device->handle,						     ACPI_DEVICE_NOTIFY,						     acpi_video_device_notify,						     data);		if (ACPI_FAILURE(status)) {			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,					  "Error installing notify handler\n"));			if(data->brightness)				kfree(data->brightness->levels);			kfree(data->brightness);			kfree(data);			return -ENODEV;		}		mutex_lock(&video->device_list_lock);		list_add_tail(&data->entry, &video->video_device_list);		mutex_unlock(&video->device_list_lock);		acpi_video_device_add_fs(device);		return 0;	}	return -ENOENT;}/* *  Arg: *  	video	: video bus device  * *  Return: *  	none *   *  Enumerate the video device list of the video bus,  *  bind the ids with the corresponding video devices *  under the video bus. */static void acpi_video_device_rebind(struct acpi_video_bus *video){	struct acpi_video_device *dev;	mutex_lock(&video->device_list_lock);	list_for_each_entry(dev, &video->video_device_list, entry)		acpi_video_device_bind(video, dev);	mutex_unlock(&video->device_list_lock);}/* *  Arg: *  	video	: video bus device  *  	device	: video output device under the video  *  		bus * *  Return: *  	none *   *  Bind the ids with the corresponding video devices *  under the video bus. */static voidacpi_video_device_bind(struct acpi_video_bus *video,		       struct acpi_video_device *device){	int i;#define IDS_VAL(i) video->attached_array[i].value.int_val#define IDS_BIND(i) video->attached_array[i].bind_info	for (i = 0; IDS_VAL(i) != ACPI_VIDEO_HEAD_INVALID &&	     i < video->attached_count; i++) {		if (device->device_id == (IDS_VAL(i) & 0xffff)) {			IDS_BIND(i) = device;			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i));		}	}#undef IDS_VAL#undef IDS_BIND}/* *  Arg: *  	video	: video bus device  * *  Return: *  	< 0	: error *   *  Call _DOD to enumerate all devices attached to display adapter * */static int acpi_video_device_enumerate(struct acpi_video_bus *video){	int status;	int count;	int i;	struct acpi_video_enumerated_device *active_device_list;	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };	union acpi_object *dod = NULL;	union acpi_object *obj;	status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer);	if (!ACPI_SUCCESS(status)) {		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD"));		return status;	}	dod = buffer.pointer;	if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {		ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data"));		status = -EFAULT;		goto out;	}	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n",			  dod->package.count));

⌨️ 快捷键说明

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