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

📄 sis_main.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* Sanity check for offsets */	if(var->xoffset < 0) var->xoffset = 0;	if(var->yoffset < 0) var->yoffset = 0;	/* Horiz-panning not supported */	if(var->xres != var->xres_virtual) {	   var->xres_virtual = var->xres;	}		if(ivideo->sisfb_ypan) {	   maxyres = ivideo->heapstart / (var->xres * (var->bits_per_pixel >> 3));	   if(maxyres > 32767) maxyres = 32767;	   if(ivideo->sisfb_max) {	      var->yres_virtual = maxyres;	   } else {	      if(var->yres_virtual > maxyres) {	         var->yres_virtual = maxyres;	      }	   }	   if(var->yres_virtual <= var->yres) {	      var->yres_virtual = var->yres;	   }	} else {	   if(var->yres != var->yres_virtual) {	      var->yres_virtual = var->yres;	   }	   var->xoffset = 0;	   var->yoffset = 0;	}		/* Truncate offsets to maximum if too high */	if(var->xoffset > var->xres_virtual - var->xres) {	   var->xoffset = var->xres_virtual - var->xres - 1;	}	if(var->yoffset > var->yres_virtual - var->yres) {	   var->yoffset = var->yres_virtual - var->yres - 1;	}		/* Set everything else to 0 */	var->red.msb_right = 	var->green.msb_right =	var->blue.msb_right =	var->transp.offset = 	var->transp.length = 	var->transp.msb_right = 0;			return 0;}static intsisfb_pan_display(struct fb_var_screeninfo *var, struct fb_info* info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;	int err;	if(var->xoffset > (var->xres_virtual - var->xres)) {		return -EINVAL;	}	if(var->yoffset > (var->yres_virtual - var->yres)) {		return -EINVAL;	}	if(var->vmode & FB_VMODE_YWRAP) {		if((var->yoffset < 0) ||		   (var->yoffset >= info->var.yres_virtual) ||		   (var->xoffset)) {		    	return -EINVAL;		}	} else {		if(var->xoffset + info->var.xres > info->var.xres_virtual ||		   var->yoffset + info->var.yres > info->var.yres_virtual) {			return -EINVAL;		}	}	if((err = sisfb_pan_var(ivideo, var)) < 0) return err;	info->var.xoffset = var->xoffset;	info->var.yoffset = var->yoffset;	if(var->vmode & FB_VMODE_YWRAP) {		info->var.vmode |= FB_VMODE_YWRAP;	} else {		info->var.vmode &= ~FB_VMODE_YWRAP;	}	return 0;}static intsisfb_blank(int blank, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;		return(sisfb_myblank(ivideo, blank));}#endif/* ----------- FBDev related routines for all series ---------- */static int sisfb_ioctl(struct inode *inode, struct file *file,            unsigned int cmd, unsigned long arg, #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		       	    int con,#endif		       	    struct fb_info *info){	struct sis_video_info 	*ivideo = (struct sis_video_info *)info->par;	struct sis_memreq 	sismemreq;	struct fb_vblank  	sisvbblank;	sisfb_info        	x;	u32			gpu32 = 0;	static int 		count = 0;	switch (cmd) {	   case FBIO_ALLOC:		if(!capable(CAP_SYS_RAWIO)) {			return -EPERM;		}		if(copy_from_user(&sismemreq, (void *)arg, sizeof(sismemreq))) {		   	return -EFAULT;		}        	sis_malloc(&sismemreq);		if(copy_to_user((void *)arg, &sismemreq, sizeof(sismemreq))) {			sis_free((u32)sismemreq.offset);		    	return -EFAULT;		}		break;			   case FBIO_FREE:		if(!capable(CAP_SYS_RAWIO)) {			return -EPERM;		}		if(get_user(gpu32, (u32 *)arg)) {			return -EFAULT;		}		sis_free(gpu32);		break;			   case FBIOGET_VBLANK:		sisvbblank.count = 0;		sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount);		if(copy_to_user((void *)arg, &sisvbblank, sizeof(sisvbblank))) {			return -EFAULT;		}		break;			   case SISFB_GET_INFO_SIZE:	        return put_user(sizeof(sisfb_info), (u32 *)arg);			   case SISFB_GET_INFO_OLD:	        if(++count < 50) {	           printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");		}	   case SISFB_GET_INFO:  /* For communication with X driver */		x.sisfb_id         = SISFB_ID;		x.sisfb_version    = VER_MAJOR;		x.sisfb_revision   = VER_MINOR;		x.sisfb_patchlevel = VER_LEVEL;		x.chip_id = ivideo->chip_id;		x.memory = ivideo->video_size / 1024;		x.heapstart = ivideo->heapstart / 1024;		if(ivideo->modechanged) {		   x.fbvidmode = ivideo->mode_no;		} else {		   x.fbvidmode = ivideo->modeprechange;		}		x.sisfb_caps = ivideo->caps;		x.sisfb_tqlen = 512; /* yet fixed */		x.sisfb_pcibus = ivideo->pcibus;		x.sisfb_pcislot = ivideo->pcislot;		x.sisfb_pcifunc = ivideo->pcifunc;		x.sisfb_lcdpdc = ivideo->detectedpdc;		x.sisfb_lcdpdca = ivideo->detectedpdca;		x.sisfb_lcda = ivideo->detectedlcda;		x.sisfb_vbflags = ivideo->vbflags;		x.sisfb_currentvbflags = ivideo->currentvbflags;		x.sisfb_scalelcd = ivideo->SiS_Pr.UsePanelScaler;		x.sisfb_specialtiming = ivideo->SiS_Pr.SiS_CustomT;		x.sisfb_haveemi = ivideo->SiS_Pr.HaveEMI ? 1 : 0;		x.sisfb_haveemilcd = ivideo->SiS_Pr.HaveEMILCD ? 1 : 0;		x.sisfb_emi30 = ivideo->SiS_Pr.EMI_30;		x.sisfb_emi31 = ivideo->SiS_Pr.EMI_31;		x.sisfb_emi32 = ivideo->SiS_Pr.EMI_32;		x.sisfb_emi33 = ivideo->SiS_Pr.EMI_33;		x.sisfb_tvxpos = (u16)(ivideo->tvxpos + 32);		x.sisfb_tvypos = (u16)(ivideo->tvypos + 32);					if(copy_to_user((void *)arg, &x, sizeof(x))) {			return -EFAULT;		}	        break;			   case SISFB_GET_VBRSTATUS_OLD:	   	if(++count < 50) {	           printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");		}	   case SISFB_GET_VBRSTATUS:	        if(sisfb_CheckVBRetrace(ivideo)) {			return put_user((u32)1, (u32 *) arg);		} else {			return put_user((u32)0, (u32 *) arg);		}			   case SISFB_GET_AUTOMAXIMIZE_OLD:	   	if(++count < 50) {	           printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");		}	   case SISFB_GET_AUTOMAXIMIZE:	        if(ivideo->sisfb_max) return put_user((u32)1, (u32 *)arg);		else 	              return put_user((u32)0, (u32 *)arg);			   case SISFB_SET_AUTOMAXIMIZE_OLD:	   	if(++count < 50) {		   printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");		}	   case SISFB_SET_AUTOMAXIMIZE:		if(copy_from_user(&gpu32, (u32 *)arg, sizeof(gpu32))) {			return -EFAULT;		}		ivideo->sisfb_max = (gpu32) ? 1 : 0;		break;	   case SISFB_SET_TVPOSOFFSET:		if(copy_from_user(&gpu32, (u32 *)arg, sizeof(gpu32))) {			return -EFAULT;		}		sisfb_set_TVxposoffset(ivideo, ((int)(gpu32 >> 16)) - 32);		sisfb_set_TVyposoffset(ivideo, ((int)(gpu32 & 0xffff)) - 32);		break;	   case SISFB_GET_TVPOSOFFSET:	        return put_user((u32)(((ivideo->tvxpos+32)<<16)|((ivideo->tvypos+32)&0xffff)), (u32 *)arg);			   case SISFB_SET_LOCK:		if(copy_from_user(&gpu32, (u32 *)arg, sizeof(gpu32))) {			return -EFAULT;		}		ivideo->sisfblocked = (gpu32) ? 1 : 0;		break;	        	   default:		return -EINVAL;	}	return 0;}static intsisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;		memset(fix, 0, sizeof(struct fb_fix_screeninfo));	strcpy(fix->id, ivideo->myid);	fix->smem_start  = ivideo->video_base;	fix->smem_len    = ivideo->sisfb_mem;	fix->type        = FB_TYPE_PACKED_PIXELS;	fix->type_aux    = 0;	fix->visual      = (ivideo->video_bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;	fix->xpanstep    = 0;	fix->ypanstep 	 = (ivideo->sisfb_ypan) ? 1 : 0;	fix->ywrapstep   = 0;	fix->line_length = ivideo->video_linelength;	fix->mmio_start  = ivideo->mmio_base;	fix->mmio_len    = ivideo->mmio_size;	if(ivideo->sisvga_engine == SIS_300_VGA) {	   fix->accel    = FB_ACCEL_SIS_GLAMOUR;	} else if((ivideo->chip == SIS_330) || (ivideo->chip == SIS_760)) {	   fix->accel    = FB_ACCEL_SIS_XABRE;	} else {	   fix->accel    = FB_ACCEL_SIS_GLAMOUR_2;	}	return 0;}/* ----------------  fb_ops structures ----------------- */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)static struct fb_ops sisfb_ops = {	.owner		= THIS_MODULE,	.fb_get_fix	= sisfb_get_fix,	.fb_get_var	= sisfb_get_var,	.fb_set_var	= sisfb_set_var,	.fb_get_cmap	= sisfb_get_cmap,	.fb_set_cmap	= sisfb_set_cmap,        .fb_pan_display = sisfb_pan_display,	.fb_ioctl	= sisfb_ioctl};#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)static struct fb_ops sisfb_ops = {	.owner          = THIS_MODULE,	.fb_open        = sisfb_open,	.fb_release     = sisfb_release,	.fb_check_var   = sisfb_check_var,	.fb_set_par     = sisfb_set_par,	.fb_setcolreg   = sisfb_setcolreg,        .fb_pan_display = sisfb_pan_display,        .fb_blank       = sisfb_blank,	.fb_fillrect    = fbcon_sis_fillrect,	.fb_copyarea    = fbcon_sis_copyarea,	.fb_imageblit   = cfb_imageblit,	.fb_cursor      = soft_cursor,		.fb_sync        = fbcon_sis_sync,	.fb_ioctl       = sisfb_ioctl};#endif/* ---------------- Chip generation dependent routines ---------------- */static struct pci_dev * sisfb_get_northbridge(int basechipid){	struct pci_dev *pdev = NULL;	int nbridgenum, nbridgeidx, i;	const unsigned short nbridgeids[] = { 		PCI_DEVICE_ID_SI_540,	/* for SiS 540 VGA */		PCI_DEVICE_ID_SI_630,	/* for SiS 630/730 VGA */		PCI_DEVICE_ID_SI_730,		PCI_DEVICE_ID_SI_550,   /* for SiS 550 VGA */		PCI_DEVICE_ID_SI_650,   /* for SiS 650/651/740 VGA */		PCI_DEVICE_ID_SI_651,		PCI_DEVICE_ID_SI_740,		PCI_DEVICE_ID_SI_661,	/* for SiS 661/741/660/760 VGA */		PCI_DEVICE_ID_SI_741,		PCI_DEVICE_ID_SI_660,		PCI_DEVICE_ID_SI_760	};		    	switch(basechipid) {#ifdef CONFIG_FB_SIS_300		case SIS_540:	nbridgeidx = 0; nbridgenum = 1; break;	case SIS_630:	nbridgeidx = 1; nbridgenum = 2; break;#endif			#ifdef CONFIG_FB_SIS_315				case SIS_550:   nbridgeidx = 3; nbridgenum = 1; break;	case SIS_650:	nbridgeidx = 4; nbridgenum = 3; break;	case SIS_660:	nbridgeidx = 7; nbridgenum = 4; break;#endif				default:	return NULL;	}	for(i = 0; i < nbridgenum; i++) {		if((pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridgeids[nbridgeidx+i], NULL))) break;	}	return pdev;}static int __devinit sisfb_get_dram_size(struct sis_video_info *ivideo){	u8 reg;		ivideo->video_size = 0;	switch(ivideo->chip) {#ifdef CONFIG_FB_SIS_300 	case SIS_300:	        inSISIDXREG(SISSR, 0x14, reg);		ivideo->video_size = ((reg & 0x3F) + 1) << 20;		break;	case SIS_540:	case SIS_630:	case SIS_730:	   	if(!ivideo->nbridge) return -1;	   	pci_read_config_byte(ivideo->nbridge, 0x63, &reg);		ivideo->video_size = 1 << (((reg & 0x70) >> 4) + 21);		break;#endif  #ifdef CONFIG_FB_SIS_315	case SIS_315H:	case SIS_315PRO:	case SIS_315:	   	inSISIDXREG(SISSR, 0x14, reg);		ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;		switch((reg >> 2) & 0x03) {		case 0x01:		case 0x03:		   ivideo->video_size <<= 1;		   break;		case 0x02:		   ivideo->video_size += (ivideo->video_size/2);		}	   	break;		case SIS_330:	   	inSISIDXREG(SISSR, 0x14, reg);		ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;		if(reg & 0x0c) ivideo->video_size <<= 1;	   	break;	case SIS_550:	case SIS_650:	case SIS_740:	    	inSISIDXREG(SISSR, 0x14, reg);		ivideo->video_size = (((reg & 0x3f) + 1) << 2) << 20;		break;	case SIS_661:	case SIS_741:	     	inSISIDXREG(SISCR, 0x79, reg);		ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;	   	break;	case SIS_660:	case SIS_760:		inSISIDXREG(SISCR, 0x79, reg);		reg = (reg & 0xf0) >> 4;		if(reg)	ivideo->video_size = (1 << reg) << 20;		inSISIDXREG(SISCR, 0x78, reg);		reg &= 0x30;		if(reg) {		   if(reg == 0x10) ivideo->video_size += (32 << 20);		   else		   ivideo->video_size += (64 << 20);		}	   	break;#endif			default:		return -1;	}	return 0;}/* -------------- video bridge device detection --------------- */static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo){	u8 cr32, temp;#ifdef CONFIG_FB_SIS_300		if(ivideo->sisvga_engine == SIS_300_VGA) {			inSISIDXREG(SISSR, 0x17, temp);	      		if((temp & 0x0F) && (ivideo->chip != SIS_300)) {			/* PAL/NTSC is stored on SR16 on such machines */			if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN))) {		   		inSISIDXREG(SISSR, 0x16, temp);				if(temp & 0x20)					ivideo->vbflags |= TV_PAL;				else					ivideo->vbflags |= TV_NTSC;			}		} 	}#endif		inSISIDXREG(SISCR, 0x32, cr32);	if(cr32 & SIS_CRT1) {		ivideo->sisfb_crt1off = 0;	} else {		ivideo->sisfb_crt1off = (cr32 & 0xDF) ? 1 : 0;	}	ivideo->vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);	if(cr32 & SIS_VB_TV)   ivideo->vbflags |= CRT2_TV;	if(cr32 & SIS_VB_LCD)  ivideo->vbflags |= CRT2_LCD;	if(cr32 & SIS_VB_CRT2) ivideo->vbflags |= CRT2_VGA;		/* Check given parms for hardware compatibility.	 * (Cannot do this in the search_xx routines since we don't 	 * know what hardware we are running on then)	 */ 		if(ivideo->chip != SIS_550) {	   ivideo->sisfb_dstn = ivideo->sisfb_fstn = 0;	}		if(ivideo->sisfb_tvplug != -1) {	   if( (ivideo->sisvga_engine != SIS_315_VGA) || 	       (!(ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV))) ) {	      if(ivideo->sisf

⌨️ 快捷键说明

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