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

📄 uvesafb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
static void __devinit uvesafb_init_mtrr(struct fb_info *info){#ifdef CONFIG_MTRR	if (mtrr && !(info->fix.smem_start & (PAGE_SIZE - 1))) {		int temp_size = info->fix.smem_len;		unsigned int type = 0;		switch (mtrr) {		case 1:			type = MTRR_TYPE_UNCACHABLE;			break;		case 2:			type = MTRR_TYPE_WRBACK;			break;		case 3:			type = MTRR_TYPE_WRCOMB;			break;		case 4:			type = MTRR_TYPE_WRTHROUGH;			break;		default:			type = 0;			break;		}		if (type) {			int rc;			/* Find the largest power-of-two */			while (temp_size & (temp_size - 1))				temp_size &= (temp_size - 1);			/* Try and find a power of two to add */			do {				rc = mtrr_add(info->fix.smem_start,					      temp_size, type, 1);				temp_size >>= 1;			} while (temp_size >= PAGE_SIZE && rc == -EINVAL);		}	}#endif /* CONFIG_MTRR */}static ssize_t uvesafb_show_vbe_ver(struct device *dev,		struct device_attribute *attr, char *buf){	struct fb_info *info = platform_get_drvdata(to_platform_device(dev));	struct uvesafb_par *par = info->par;	return snprintf(buf, PAGE_SIZE, "%.4x\n", par->vbe_ib.vbe_version);}static DEVICE_ATTR(vbe_version, S_IRUGO, uvesafb_show_vbe_ver, NULL);static ssize_t uvesafb_show_vbe_modes(struct device *dev,		struct device_attribute *attr, char *buf){	struct fb_info *info = platform_get_drvdata(to_platform_device(dev));	struct uvesafb_par *par = info->par;	int ret = 0, i;	for (i = 0; i < par->vbe_modes_cnt && ret < PAGE_SIZE; i++) {		ret += snprintf(buf + ret, PAGE_SIZE - ret,			"%dx%d-%d, 0x%.4x\n",			par->vbe_modes[i].x_res, par->vbe_modes[i].y_res,			par->vbe_modes[i].depth, par->vbe_modes[i].mode_id);	}	return ret;}static DEVICE_ATTR(vbe_modes, S_IRUGO, uvesafb_show_vbe_modes, NULL);static ssize_t uvesafb_show_vendor(struct device *dev,		struct device_attribute *attr, char *buf){	struct fb_info *info = platform_get_drvdata(to_platform_device(dev));	struct uvesafb_par *par = info->par;	if (par->vbe_ib.oem_vendor_name_ptr)		return snprintf(buf, PAGE_SIZE, "%s\n", (char *)			(&par->vbe_ib) + par->vbe_ib.oem_vendor_name_ptr);	else		return 0;}static DEVICE_ATTR(oem_vendor, S_IRUGO, uvesafb_show_vendor, NULL);static ssize_t uvesafb_show_product_name(struct device *dev,		struct device_attribute *attr, char *buf){	struct fb_info *info = platform_get_drvdata(to_platform_device(dev));	struct uvesafb_par *par = info->par;	if (par->vbe_ib.oem_product_name_ptr)		return snprintf(buf, PAGE_SIZE, "%s\n", (char *)			(&par->vbe_ib) + par->vbe_ib.oem_product_name_ptr);	else		return 0;}static DEVICE_ATTR(oem_product_name, S_IRUGO, uvesafb_show_product_name, NULL);static ssize_t uvesafb_show_product_rev(struct device *dev,		struct device_attribute *attr, char *buf){	struct fb_info *info = platform_get_drvdata(to_platform_device(dev));	struct uvesafb_par *par = info->par;	if (par->vbe_ib.oem_product_rev_ptr)		return snprintf(buf, PAGE_SIZE, "%s\n", (char *)			(&par->vbe_ib) + par->vbe_ib.oem_product_rev_ptr);	else		return 0;}static DEVICE_ATTR(oem_product_rev, S_IRUGO, uvesafb_show_product_rev, NULL);static ssize_t uvesafb_show_oem_string(struct device *dev,		struct device_attribute *attr, char *buf){	struct fb_info *info = platform_get_drvdata(to_platform_device(dev));	struct uvesafb_par *par = info->par;	if (par->vbe_ib.oem_string_ptr)		return snprintf(buf, PAGE_SIZE, "%s\n",			(char *)(&par->vbe_ib) + par->vbe_ib.oem_string_ptr);	else		return 0;}static DEVICE_ATTR(oem_string, S_IRUGO, uvesafb_show_oem_string, NULL);static ssize_t uvesafb_show_nocrtc(struct device *dev,		struct device_attribute *attr, char *buf){	struct fb_info *info = platform_get_drvdata(to_platform_device(dev));	struct uvesafb_par *par = info->par;	return snprintf(buf, PAGE_SIZE, "%d\n", par->nocrtc);}static ssize_t uvesafb_store_nocrtc(struct device *dev,		struct device_attribute *attr, const char *buf, size_t count){	struct fb_info *info = platform_get_drvdata(to_platform_device(dev));	struct uvesafb_par *par = info->par;	if (count > 0) {		if (buf[0] == '0')			par->nocrtc = 0;		else			par->nocrtc = 1;	}	return count;}static DEVICE_ATTR(nocrtc, S_IRUGO | S_IWUSR, uvesafb_show_nocrtc,			uvesafb_store_nocrtc);static struct attribute *uvesafb_dev_attrs[] = {	&dev_attr_vbe_version.attr,	&dev_attr_vbe_modes.attr,	&dev_attr_oem_vendor.attr,	&dev_attr_oem_product_name.attr,	&dev_attr_oem_product_rev.attr,	&dev_attr_oem_string.attr,	&dev_attr_nocrtc.attr,	NULL,};static struct attribute_group uvesafb_dev_attgrp = {	.name = NULL,	.attrs = uvesafb_dev_attrs,};static int __devinit uvesafb_probe(struct platform_device *dev){	struct fb_info *info;	struct vbe_mode_ib *mode = NULL;	struct uvesafb_par *par;	int err = 0, i;	info = framebuffer_alloc(sizeof(*par) +	sizeof(u32) * 256, &dev->dev);	if (!info)		return -ENOMEM;	par = info->par;	err = uvesafb_vbe_init(info);	if (err) {		printk(KERN_ERR "uvesafb: vbe_init() failed with %d\n", err);		goto out;	}	info->fbops = &uvesafb_ops;	i = uvesafb_vbe_init_mode(info);	if (i < 0) {		err = -EINVAL;		goto out;	} else {		mode = &par->vbe_modes[i];	}	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {		err = -ENXIO;		goto out;	}	uvesafb_init_info(info, mode);	if (!request_mem_region(info->fix.smem_start, info->fix.smem_len,				"uvesafb")) {		printk(KERN_ERR "uvesafb: cannot reserve video memory at "				"0x%lx\n", info->fix.smem_start);		err = -EIO;		goto out_mode;	}	info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);	if (!info->screen_base) {		printk(KERN_ERR			"uvesafb: abort, cannot ioremap 0x%x bytes of video "			"memory at 0x%lx\n",			info->fix.smem_len, info->fix.smem_start);		err = -EIO;		goto out_mem;	}	if (!request_region(0x3c0, 32, "uvesafb")) {		printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");		err = -EIO;		goto out_unmap;	}	uvesafb_init_mtrr(info);	platform_set_drvdata(dev, info);	if (register_framebuffer(info) < 0) {		printk(KERN_ERR			"uvesafb: failed to register framebuffer device\n");		err = -EINVAL;		goto out_reg;	}	printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, "			"using %dk, total %dk\n", info->fix.smem_start,			info->screen_base, info->fix.smem_len/1024,			par->vbe_ib.total_memory * 64);	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,			info->fix.id);	err = sysfs_create_group(&dev->dev.kobj, &uvesafb_dev_attgrp);	if (err != 0)		printk(KERN_WARNING "fb%d: failed to register attributes\n",			info->node);	return 0;out_reg:	release_region(0x3c0, 32);out_unmap:	iounmap(info->screen_base);out_mem:	release_mem_region(info->fix.smem_start, info->fix.smem_len);out_mode:	if (!list_empty(&info->modelist))		fb_destroy_modelist(&info->modelist);	fb_destroy_modedb(info->monspecs.modedb);	fb_dealloc_cmap(&info->cmap);out:	if (par->vbe_modes)		kfree(par->vbe_modes);	framebuffer_release(info);	return err;}static int uvesafb_remove(struct platform_device *dev){	struct fb_info *info = platform_get_drvdata(dev);	if (info) {		struct uvesafb_par *par = info->par;		sysfs_remove_group(&dev->dev.kobj, &uvesafb_dev_attgrp);		unregister_framebuffer(info);		release_region(0x3c0, 32);		iounmap(info->screen_base);		release_mem_region(info->fix.smem_start, info->fix.smem_len);		fb_destroy_modedb(info->monspecs.modedb);		fb_dealloc_cmap(&info->cmap);		if (par) {			if (par->vbe_modes)				kfree(par->vbe_modes);			if (par->vbe_state_orig)				kfree(par->vbe_state_orig);			if (par->vbe_state_saved)				kfree(par->vbe_state_saved);		}		framebuffer_release(info);	}	return 0;}static struct platform_driver uvesafb_driver = {	.probe  = uvesafb_probe,	.remove = uvesafb_remove,	.driver = {		.name = "uvesafb",	},};static struct platform_device *uvesafb_device;#ifndef MODULEstatic int __devinit uvesafb_setup(char *options){	char *this_opt;	if (!options || !*options)		return 0;	while ((this_opt = strsep(&options, ",")) != NULL) {		if (!*this_opt) continue;		if (!strcmp(this_opt, "redraw"))			ypan = 0;		else if (!strcmp(this_opt, "ypan"))			ypan = 1;		else if (!strcmp(this_opt, "ywrap"))			ypan = 2;		else if (!strcmp(this_opt, "vgapal"))			pmi_setpal = 0;		else if (!strcmp(this_opt, "pmipal"))			pmi_setpal = 1;		else if (!strncmp(this_opt, "mtrr:", 5))			mtrr = simple_strtoul(this_opt+5, NULL, 0);		else if (!strcmp(this_opt, "nomtrr"))			mtrr = 0;		else if (!strcmp(this_opt, "nocrtc"))			nocrtc = 1;		else if (!strcmp(this_opt, "noedid"))			noedid = 1;		else if (!strcmp(this_opt, "noblank"))			blank = 0;		else if (!strncmp(this_opt, "vtotal:", 7))			vram_total = simple_strtoul(this_opt + 7, NULL, 0);		else if (!strncmp(this_opt, "vremap:", 7))			vram_remap = simple_strtoul(this_opt + 7, NULL, 0);		else if (!strncmp(this_opt, "maxhf:", 6))			maxhf = simple_strtoul(this_opt + 6, NULL, 0);		else if (!strncmp(this_opt, "maxvf:", 6))			maxvf = simple_strtoul(this_opt + 6, NULL, 0);		else if (!strncmp(this_opt, "maxclk:", 7))			maxclk = simple_strtoul(this_opt + 7, NULL, 0);		else if (!strncmp(this_opt, "vbemode:", 8))			vbemode = simple_strtoul(this_opt + 8, NULL, 0);		else if (this_opt[0] >= '0' && this_opt[0] <= '9') {			mode_option = this_opt;		} else {			printk(KERN_WARNING				"uvesafb: unrecognized option %s\n", this_opt);		}	}	return 0;}#endif /* !MODULE */static ssize_t show_v86d(struct device_driver *dev, char *buf){	return snprintf(buf, PAGE_SIZE, "%s\n", v86d_path);}static ssize_t store_v86d(struct device_driver *dev, const char *buf,		size_t count){	strncpy(v86d_path, buf, PATH_MAX);	return count;}static DRIVER_ATTR(v86d, S_IRUGO | S_IWUSR, show_v86d, store_v86d);static int __devinit uvesafb_init(void){	int err;#ifndef MODULE	char *option = NULL;	if (fb_get_options("uvesafb", &option))		return -ENODEV;	uvesafb_setup(option);#endif	err = cn_add_callback(&uvesafb_cn_id, "uvesafb", uvesafb_cn_callback);	if (err)		return err;	err = platform_driver_register(&uvesafb_driver);	if (!err) {		uvesafb_device = platform_device_alloc("uvesafb", 0);		if (uvesafb_device)			err = platform_device_add(uvesafb_device);		else			err = -ENOMEM;		if (err) {			platform_device_put(uvesafb_device);			platform_driver_unregister(&uvesafb_driver);			cn_del_callback(&uvesafb_cn_id);			return err;		}		err = driver_create_file(&uvesafb_driver.driver,				&driver_attr_v86d);		if (err) {			printk(KERN_WARNING "uvesafb: failed to register "					"attributes\n");			err = 0;		}	}	return err;}module_init(uvesafb_init);static void __devexit uvesafb_exit(void){	struct uvesafb_ktask *task;	if (v86d_started) {		task = uvesafb_prep();		if (task) {			task->t.flags = TF_EXIT;			uvesafb_exec(task);			uvesafb_free(task);		}	}	cn_del_callback(&uvesafb_cn_id);	driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d);	platform_device_unregister(uvesafb_device);	platform_driver_unregister(&uvesafb_driver);}module_exit(uvesafb_exit);static int param_get_scroll(char *buffer, struct kernel_param *kp){	return 0;}static int param_set_scroll(const char *val, struct kernel_param *kp){	ypan = 0;	if (!strcmp(val, "redraw"))		ypan = 0;	else if (!strcmp(val, "ypan"))		ypan = 1;	else if (!strcmp(val, "ywrap"))		ypan = 2;	return 0;}#define param_check_scroll(name, p) __param_check(name, p, void)module_param_named(scroll, ypan, scroll, 0);MODULE_PARM_DESC(scroll,	"Scrolling mode, set to 'redraw', 'ypan', or 'ywrap'");module_param_named(vgapal, pmi_setpal, invbool, 0);MODULE_PARM_DESC(vgapal, "Set palette using VGA registers");module_param_named(pmipal, pmi_setpal, bool, 0);MODULE_PARM_DESC(pmipal, "Set palette using PMI calls");module_param(mtrr, uint, 0);MODULE_PARM_DESC(mtrr,	"Memory Type Range Registers setting. Use 0 to disable.");module_param(blank, bool, 0);MODULE_PARM_DESC(blank, "Enable hardware blanking");module_param(nocrtc, bool, 0);MODULE_PARM_DESC(nocrtc, "Ignore CRTC timings when setting modes");module_param(noedid, bool, 0);MODULE_PARM_DESC(noedid,	"Ignore EDID-provided monitor limits when setting modes");module_param(vram_remap, uint, 0);MODULE_PARM_DESC(vram_remap, "Set amount of video memory to be used [MiB]");module_param(vram_total, uint, 0);MODULE_PARM_DESC(vram_total, "Set total amount of video memoery [MiB]");module_param(maxclk, ushort, 0);MODULE_PARM_DESC(maxclk, "Maximum pixelclock [MHz], overrides EDID data");module_param(maxhf, ushort, 0);MODULE_PARM_DESC(maxhf,	"Maximum horizontal frequency [kHz], overrides EDID data");module_param(maxvf, ushort, 0);MODULE_PARM_DESC(maxvf,	"Maximum vertical frequency [Hz], overrides EDID data");module_param(mode_option, charp, 0);MODULE_PARM_DESC(mode_option,	"Specify initial video mode as \"<xres>x<yres>[-<bpp>][@<refresh>]\"");module_param(vbemode, ushort, 0);MODULE_PARM_DESC(vbemode,	"VBE mode number to set, overrides the 'mode' option");module_param_string(v86d, v86d_path, PATH_MAX, 0660);MODULE_PARM_DESC(v86d, "Path to the v86d userspace helper.");MODULE_LICENSE("GPL");MODULE_AUTHOR("Michal Januszewski <spock@gentoo.org>");MODULE_DESCRIPTION("Framebuffer driver for VBE2.0+ compliant graphics boards");

⌨️ 快捷键说明

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