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

📄 sisusb.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		ret |= SETIREG(SISSR, 0x29, mclktable[(ramtype * 4) + 1]);		ret |= SETIREG(SISSR, 0x2a, mclktable[(ramtype * 4) + 2]);		ret |= SETIREG(SISSR, 0x2e, eclktable[ramtype * 4]);		ret |= SETIREG(SISSR, 0x2f, eclktable[(ramtype * 4) + 1]);		ret |= SETIREG(SISSR, 0x30, eclktable[(ramtype * 4) + 2]);		ret |= SETIREG(SISSR, 0x07, 0x18);		ret |= SETIREG(SISSR, 0x11, 0x0f);		if (ret) continue;		for (i = 0x15, j = 0; i <= 0x1b; i++, j++) {			ret |= SETIREG(SISSR, i, ramtypetable1[(j*4) + ramtype]);		}		for (i = 0x40, j = 0; i <= 0x44; i++, j++) {			ret |= SETIREG(SISCR, i, ramtypetable2[(j*4) + ramtype]);		}		ret |= SETIREG(SISCR, 0x49, 0xaa);		ret |= SETIREG(SISSR, 0x1f, 0x00);		ret |= SETIREG(SISSR, 0x20, 0xa0);		ret |= SETIREG(SISSR, 0x23, 0xf6);		ret |= SETIREG(SISSR, 0x24, 0x0d);		ret |= SETIREG(SISSR, 0x25, 0x33);		ret |= SETIREG(SISSR, 0x11, 0x0f);		ret |= SETIREGOR(SISPART1, 0x2f, 0x01);		ret |= SETIREGAND(SISCAP, 0x3f, 0xef);		if (ret) continue;		ret |= SETIREG(SISPART1, 0x00, 0x00);		ret |= GETIREG(SISSR, 0x13, &tmp8);		tmp8 >>= 4;		ret |= SETIREG(SISPART1, 0x02, 0x00);		ret |= SETIREG(SISPART1, 0x2e, 0x08);		ret |= sisusb_read_pci_config(sisusb, 0x50, &tmp32);		tmp32 &= 0x00f00000;		tmp8 = (tmp32 == 0x100000) ? 0x33 : 0x03;		ret |= SETIREG(SISSR, 0x25, tmp8);		tmp8 = (tmp32 == 0x100000) ? 0xaa : 0x88;		ret |= SETIREG(SISCR, 0x49, tmp8);		ret |= SETIREG(SISSR, 0x27, 0x1f);		ret |= SETIREG(SISSR, 0x31, 0x00);		ret |= SETIREG(SISSR, 0x32, 0x11);		ret |= SETIREG(SISSR, 0x33, 0x00);		if (ret) continue;		ret |= SETIREG(SISCR, 0x83, 0x00);		ret |= sisusb_set_default_mode(sisusb, 0);		ret |= SETIREGAND(SISSR, 0x21, 0xdf);		ret |= SETIREGOR(SISSR, 0x01, 0x20);		ret |= SETIREGOR(SISSR, 0x16, 0x0f);		ret |= sisusb_triggersr16(sisusb, ramtype);		/* Disable refresh */		ret |= SETIREGAND(SISSR, 0x17, 0xf8);		ret |= SETIREGOR(SISSR, 0x19, 0x03);		ret |= sisusb_getbuswidth(sisusb, &bw, &chab);		ret |= sisusb_verify_mclk(sisusb);		if (ramtype <= 1) {			ret |= sisusb_get_sdram_size(sisusb, &iret, bw, chab);			if (iret) {				printk(KERN_ERR "sisusbvga[%d]: RAM size "					"detection failed, "					"assuming 8MB video RAM\n",					sisusb->minor);				ret |= SETIREG(SISSR,0x14,0x31);				/* TODO */			}		} else {			printk(KERN_ERR "sisusbvga[%d]: DDR RAM device found, "					"assuming 8MB video RAM\n",					sisusb->minor);			ret |= SETIREG(SISSR,0x14,0x31);			/* *** TODO *** */		}		/* Enable refresh */		ret |= SETIREG(SISSR, 0x16, ramtypetable1[4 + ramtype]);		ret |= SETIREG(SISSR, 0x17, ramtypetable1[8 + ramtype]);		ret |= SETIREG(SISSR, 0x19, ramtypetable1[16 + ramtype]);		ret |= SETIREGOR(SISSR, 0x21, 0x20);		ret |= SETIREG(SISSR, 0x22, 0xfb);		ret |= SETIREG(SISSR, 0x21, 0xa5);		if (ret == 0)			break;	}	return ret;}#undef SETREG#undef GETREG#undef SETIREG#undef GETIREG#undef SETIREGOR#undef SETIREGAND#undef SETIREGANDOR#undef READL#undef WRITELstatic voidsisusb_get_ramconfig(struct sisusb_usb_data *sisusb){	u8 tmp8, tmp82, ramtype;	int bw = 0;	char *ramtypetext1 = NULL;	const char *ramtypetext2[] = {	"SDR SDRAM", "SDR SGRAM",					"DDR SDRAM", "DDR SGRAM" };	static const int busSDR[4]  = {64, 64, 128, 128};	static const int busDDR[4]  = {32, 32,  64,  64};	static const int busDDRA[4] = {64+32, 64+32 , (64+32)*2, (64+32)*2};	sisusb_getidxreg(sisusb, SISSR, 0x14, &tmp8);	sisusb_getidxreg(sisusb, SISSR, 0x15, &tmp82);	sisusb_getidxreg(sisusb, SISSR, 0x3a, &ramtype);	sisusb->vramsize = (1 << ((tmp8 & 0xf0) >> 4)) * 1024 * 1024;	ramtype &= 0x03;	switch ((tmp8 >> 2) & 0x03) {	case 0: ramtypetext1 = "1 ch/1 r";		if (tmp82 & 0x10) {			bw = 32;		} else {			bw = busSDR[(tmp8 & 0x03)];		}		break;	case 1: ramtypetext1 = "1 ch/2 r";		sisusb->vramsize <<= 1;		bw = busSDR[(tmp8 & 0x03)];		break;	case 2: ramtypetext1 = "asymmeric";		sisusb->vramsize += sisusb->vramsize/2;		bw = busDDRA[(tmp8 & 0x03)];		break;	case 3: ramtypetext1 = "2 channel";		sisusb->vramsize <<= 1;		bw = busDDR[(tmp8 & 0x03)];		break;	}	printk(KERN_INFO "sisusbvga[%d]: %dMB %s %s, bus width %d\n",			sisusb->minor, (sisusb->vramsize >> 20), ramtypetext1,			ramtypetext2[ramtype], bw);}static intsisusb_do_init_gfxdevice(struct sisusb_usb_data *sisusb){	struct sisusb_packet packet;	int ret;	u32 tmp32;	/* Do some magic */	packet.header  = 0x001f;	packet.address = 0x00000324;	packet.data    = 0x00000004;	ret = sisusb_send_bridge_packet(sisusb, 10, &packet, 0);	packet.header  = 0x001f;	packet.address = 0x00000364;	packet.data    = 0x00000004;	ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);	packet.header  = 0x001f;	packet.address = 0x00000384;	packet.data    = 0x00000004;	ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);	packet.header  = 0x001f;	packet.address = 0x00000100;	packet.data    = 0x00000700;	ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);	packet.header  = 0x000f;	packet.address = 0x00000004;	ret |= sisusb_send_bridge_packet(sisusb, 6, &packet, 0);	packet.data |= 0x17;	ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);	/* Init BAR 0 (VRAM) */	ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32);	ret |= sisusb_write_pci_config(sisusb, 0x10, 0xfffffff0);	ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32);	tmp32 &= 0x0f;	tmp32 |= SISUSB_PCI_MEMBASE;	ret |= sisusb_write_pci_config(sisusb, 0x10, tmp32);	/* Init BAR 1 (MMIO) */	ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32);	ret |= sisusb_write_pci_config(sisusb, 0x14, 0xfffffff0);	ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32);	tmp32 &= 0x0f;	tmp32 |= SISUSB_PCI_MMIOBASE;	ret |= sisusb_write_pci_config(sisusb, 0x14, tmp32);	/* Init BAR 2 (i/o ports) */	ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32);	ret |= sisusb_write_pci_config(sisusb, 0x18, 0xfffffff0);	ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32);	tmp32 &= 0x0f;	tmp32 |= SISUSB_PCI_IOPORTBASE;	ret |= sisusb_write_pci_config(sisusb, 0x18, tmp32);	/* Enable memory and i/o access */	ret |= sisusb_read_pci_config(sisusb, 0x04, &tmp32);	tmp32 |= 0x3;	ret |= sisusb_write_pci_config(sisusb, 0x04, tmp32);	if (ret == 0) {		/* Some further magic */		packet.header  = 0x001f;		packet.address = 0x00000050;		packet.data    = 0x000000ff;		ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);	}	return ret;}/* Initialize the graphics device (return 0 on success) * This initializes the net2280 as well as the PCI registers * of the graphics board. */static intsisusb_init_gfxdevice(struct sisusb_usb_data *sisusb, int initscreen){	int ret = 0, test = 0;	u32 tmp32;	if (sisusb->devinit == 1) {		/* Read PCI BARs and see if they have been set up */		ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32);		if (ret) return ret;		if ((tmp32 & 0xfffffff0) == SISUSB_PCI_MEMBASE) test++;		ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32);		if (ret) return ret;		if ((tmp32 & 0xfffffff0) == SISUSB_PCI_MMIOBASE) test++;		ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32);		if (ret) return ret;		if ((tmp32 & 0xfffffff0) == SISUSB_PCI_IOPORTBASE) test++;	}	/* No? So reset the device */	if ((sisusb->devinit == 0) || (test != 3)) {		ret |= sisusb_do_init_gfxdevice(sisusb);		if (ret == 0)			sisusb->devinit = 1;	}	if (sisusb->devinit) {		/* Initialize the graphics core */		if (sisusb_init_gfxcore(sisusb) == 0) {			sisusb->gfxinit = 1;			sisusb_get_ramconfig(sisusb);			ret |= sisusb_set_default_mode(sisusb, 1);			ret |= sisusb_setup_screen(sisusb, 1, initscreen);		}	}	return ret;}#ifdef INCL_SISUSB_CON/* Set up default text mode:   - Set text mode (0x03)   - Upload default font   - Upload user font (if available)*/intsisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init){	int ret = 0, slot = sisusb->font_slot, i;	const struct font_desc *myfont;	u8 *tempbuf;	u16 *tempbufb;	size_t written;	static const char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer.";	static const char bootlogo[] = "(o_ //\\ V_/_";	/* sisusb->lock is down */	if (!sisusb->SiS_Pr)		return 1;	sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30;	sisusb->SiS_Pr->sisusb = (void *)sisusb;	/* Set mode 0x03 */	SiSUSBSetMode(sisusb->SiS_Pr, 0x03);	if (!(myfont = find_font("VGA8x16")))		return 1;	if (!(tempbuf = vmalloc(8192)))		return 1;	for (i = 0; i < 256; i++)		memcpy(tempbuf + (i * 32), myfont->data + (i * 16), 16);	/* Upload default font */	ret = sisusbcon_do_font_op(sisusb, 1, 0, tempbuf, 8192, 0, 1, NULL, 16, 0);	vfree(tempbuf);	/* Upload user font (and reset current slot) */	if (sisusb->font_backup) {		ret |= sisusbcon_do_font_op(sisusb, 1, 2, sisusb->font_backup,				8192, sisusb->font_backup_512, 1, NULL,				sisusb->font_backup_height, 0);		if (slot != 2)			sisusbcon_do_font_op(sisusb, 1, 0, NULL, 0, 0, 1,					NULL, 16, 0);	}	if (init && !sisusb->scrbuf) {		if ((tempbuf = vmalloc(8192))) {			i = 4096;			tempbufb = (u16 *)tempbuf;			while (i--)				*(tempbufb++) = 0x0720;			i = 0;			tempbufb = (u16 *)tempbuf;			while (bootlogo[i]) {				*(tempbufb++) = 0x0700 | bootlogo[i++];				if (!(i % 4))					tempbufb += 76;			}			i = 0;			tempbufb = (u16 *)tempbuf + 6;			while (bootstring[i])				*(tempbufb++) = 0x0700 | bootstring[i++];			ret |= sisusb_copy_memory(sisusb, tempbuf,				sisusb->vrambase, 8192, &written);			vfree(tempbuf);		}	} else if (sisusb->scrbuf) {		ret |= sisusb_copy_memory(sisusb, (char *)sisusb->scrbuf,				sisusb->vrambase, sisusb->scrbuf_size, &written);	}	if (sisusb->sisusb_cursor_size_from >= 0 &&	    sisusb->sisusb_cursor_size_to >= 0) {		sisusb_setidxreg(sisusb, SISCR, 0x0a,				sisusb->sisusb_cursor_size_from);		sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0xe0,				sisusb->sisusb_cursor_size_to);	} else {		sisusb_setidxreg(sisusb, SISCR, 0x0a, 0x2d);		sisusb_setidxreg(sisusb, SISCR, 0x0b, 0x0e);		sisusb->sisusb_cursor_size_to = -1;	}	slot = sisusb->sisusb_cursor_loc;	if(slot < 0) slot = 0;	sisusb->sisusb_cursor_loc = -1;	sisusb->bad_cursor_pos = 1;	sisusb_set_cursor(sisusb, slot);	sisusb_setidxreg(sisusb, SISCR, 0x0c, (sisusb->cur_start_addr >> 8));	sisusb_setidxreg(sisusb, SISCR, 0x0d, (sisusb->cur_start_addr & 0xff));	sisusb->textmodedestroyed = 0;	/* sisusb->lock is down */	return ret;}#endif/* fops */static intsisusb_open(struct inode *inode, struct file *file){	struct sisusb_usb_data *sisusb;	struct usb_interface *interface;	int subminor = iminor(inode);	down(&disconnect_sem);	if (!(interface = usb_find_interface(&sisusb_driver, subminor))) {		printk(KERN_ERR "sisusb[%d]: Failed to find interface\n",				subminor);		up(&disconnect_sem);		return -ENODEV;	}	if (!(sisusb = usb_get_intfdata(interface))) {		up(&disconnect_sem);		return -ENODEV;	}	down(&sisusb->lock);	if (!sisusb->present || !sisusb->ready) {		up(&sisusb->lock);		up(&disconnect_sem);		return -ENODEV;	}	if (sisusb->isopen) {		up(&sisusb->lock);		up(&disconnect_sem);		return -EBUSY;	}	if (!sisusb->devinit) {		if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH) {			if (sisusb_init_gfxdevice(sisusb, 0)) {				up(&sisusb->lock);				up(&disconnect_sem);				printk(KERN_ERR					"sisusbvga[%d]: Failed to initialize "					"device\n",					sisusb->minor);				return -EIO;			}		} else {			up(&sisusb->lock);			up(&disconnect_sem);			printk(KERN_ERR				"sisusbvga[%d]: Device not attached to "				"USB 2.0 hub\n",				sisusb->minor);			return -EIO;		}	}	/* Increment usage count for our sisusb */	kref_get(&sisusb->kref);	sisusb->isopen = 1;	file->private_data = sisusb;	up(&sisusb->lock);	up(&disconnect_sem);	return 0;}voidsisusb_delete(struct kref *kref){	struct sisusb_usb_data *sisusb = to_sisusb_dev(kref);	if (!sisusb)		return;	if (sisusb->sisusb_dev)		usb_put_dev(sisusb->sisusb_dev);	sisusb->sisusb_dev = NULL;	sisusb_free_buffers(sisusb);	sisusb_free_urbs(sisusb);#ifdef INCL_SISUSB_CON	kfree(sisusb->SiS_Pr);#endif	kfree(sisusb);}static intsisusb_release(struct inode *inode, struct file *file){	struct sisusb_usb_data *sisusb;	int myminor;	down(&disconnect_sem);	if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) {		up(&disconnect_sem);		return -ENODEV;	}	down(&sisusb->lock);	if (sisusb->present) {		/* Wait for all URBs to finish if device still present */		if (!sisusb_wait_all_out_complete(sisusb))			sisusb_kill_all_busy(sisusb);	}	myminor = sisusb->minor;	sisusb->isopen = 0;	file->private_data = NULL;	up(&sisusb->lock);	/* decrement the usage count on our device */	kref_put(&sisusb->kref, sisus

⌨️ 快捷键说明

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