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

📄 gscd.c

📁 还有没有人研究过cdrom 的驱动源码啊
💻 C
📖 第 1 页 / 共 2 页
字号:
			disk_state = ST_x08 | ST_x04 | ST_INVALID;			return;		}		/* ...and waiting */		for (i = 1, dummy = 1; i < 0xFFFF; i++) {			dummy *= i;		}	}	/* LOC_172 */	/* check the unit */	/* and wake it up */	if (cmd_unit_alive() != 0x08) {		/* LOC_174 */		/* game over for this unit */		disk_state = ST_x08 | ST_x04 | ST_INVALID;		return;	}	/* LOC_176 */#ifdef GSCD_DEBUG	printk("LOC_176 ");#endif	if (drv_mode == 0x09) {		/* magic... */		printk("GSCD: magic ...\n");		outb(result, GSCDPORT(2));	}	/* write the command to the drive */	cmd_write_cmd(cmd);	/* LOC_178 */	for (;;) {		result = wait_drv_ready();		if (result != drv_mode) {			/* LOC_179 */			if (result == 0x04) {	/* Mode 4 */				/* LOC_205 */#ifdef GSCD_DEBUG				printk("LOC_205 ");#endif				disk_state = inb(GSCDPORT(2));				do {					result = wait_drv_ready();				} while (result != drv_mode);				return;			} else {				if (result == 0x06) {	/* Mode 6 */					/* LOC_181 */#ifdef GSCD_DEBUG					printk("LOC_181 ");#endif					if (cmd_type == TYPE_DATA) {						/* read data */						/* LOC_184 */						if (drv_mode == 9) {							/* read the data to the buffer (word) */							/* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */							cmd_read_w							    (respo_buf,							     respo_count,							     CD_FRAMESIZE /							     2);							return;						} else {							/* read the data to the buffer (byte) */							/* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW)    */							cmd_read_b							    (respo_buf,							     respo_count,							     CD_FRAMESIZE);							return;						}					} else {						/* read the info to the buffer */						cmd_info_in(respo_buf,							    respo_count);						return;					}					return;				}			}		} else {			disk_state = ST_x08 | ST_x04 | ST_INVALID;			return;		}	}			/* for (;;) */#ifdef GSCD_DEBUG	printk("\n");#endif}static void cmd_write_cmd(char *pstr){	int i, j;	/* LOC_177 */#ifdef GSCD_DEBUG	printk("LOC_177 ");#endif	/* calculate the number of parameter */	j = *pstr & 0x0F;	/* shift it out */	for (i = 0; i < j; i++) {		outb(*pstr, GSCDPORT(2));		pstr++;	}}static int cmd_unit_alive(void){	int result;	unsigned long max_test_loops;	/* LOC_172 */#ifdef GSCD_DEBUG	printk("LOC_172 ");#endif	outb(curr_drv_state, GSCDPORT(0));	max_test_loops = 0xFFFF;	do {		result = wait_drv_ready();		max_test_loops--;	} while ((result != 0x08) && (max_test_loops > 0));	return result;}static void cmd_info_in(char *pb, int count){	int result;	char read;	/* read info */	/* LOC_182 */#ifdef GSCD_DEBUG	printk("LOC_182 ");#endif	do {		read = inb(GSCDPORT(2));		if (count > 0) {			*pb = read;			pb++;			count--;		}		/* LOC_183 */		do {			result = wait_drv_ready();		} while (result == 0x0E);	} while (result == 6);	cmd_end();	return;}static void cmd_read_b(char *pb, int count, int size){	int result;	int i;	/* LOC_188 */	/* LOC_189 */#ifdef GSCD_DEBUG	printk("LOC_189 ");#endif	do {		do {			result = wait_drv_ready();		} while (result != 6 || result == 0x0E);		if (result != 6) {			cmd_end();			return;		}#ifdef GSCD_DEBUG		printk("LOC_191 ");#endif		for (i = 0; i < size; i++) {			*pb = inb(GSCDPORT(2));			pb++;		}		count--;	} while (count > 0);	cmd_end();	return;}static void cmd_end(void){	int result;	/* LOC_204 */#ifdef GSCD_DEBUG	printk("LOC_204 ");#endif	do {		result = wait_drv_ready();		if (result == drv_mode) {			return;		}	} while (result != 4);	/* LOC_205 */#ifdef GSCD_DEBUG	printk("LOC_205 ");#endif	disk_state = inb(GSCDPORT(2));	do {		result = wait_drv_ready();	} while (result != drv_mode);	return;}static void cmd_read_w(char *pb, int count, int size){	int result;	int i;#ifdef GSCD_DEBUG	printk("LOC_185 ");#endif	do {		/* LOC_185 */		do {			result = wait_drv_ready();		} while (result != 6 || result == 0x0E);		if (result != 6) {			cmd_end();			return;		}		for (i = 0; i < size; i++) {			/* na, hier muss ich noch mal drueber nachdenken */			*pb = inw(GSCDPORT(2));			pb++;		}		count--;	} while (count > 0);	cmd_end();	return;}int __init find_drives(void){	int *pdrv;	int drvnum;	int subdrv;	int i;	speed = 0;	pdrv = (int *) &drv_states;	curr_drv_state = 0xFE;	subdrv = 0;	drvnum = 0;	for (i = 0; i < 8; i++) {		subdrv++;		cmd_status();		disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;		if (disk_state != (ST_x08 | ST_x04 | ST_INVALID)) {			/* LOC_240 */			*pdrv = curr_drv_state;			init_cd_drive(drvnum);			pdrv++;			drvnum++;		} else {			if (subdrv < 2) {				continue;			} else {				subdrv = 0;			}		}/*       curr_drv_state<<1;         <-- das geht irgendwie nicht *//* muss heissen:    curr_drv_state <<= 1; (ist ja Wert-Zuweisung) */		curr_drv_state *= 2;		curr_drv_state |= 1;#ifdef GSCD_DEBUG		printk("DriveState: %d\n", curr_drv_state);#endif	}	ndrives = drvnum;	return drvnum;}void __init init_cd_drive(int num){	char resp[50];	int i;	printk("GSCD: init unit %d\n", num);	cc_Ident((char *) &resp);	printk("GSCD: identification: ");	for (i = 0; i < 0x1E; i++) {		printk("%c", resp[i]);	}	printk("\n");	cc_SetSpeed();}#ifdef FUTURE_WORK/* return_done */static void update_state(void){	unsigned int AX;	if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0) {		if (disk_state == (ST_x08 | ST_x04 | ST_INVALID)) {			AX = ST_INVALID;		}		if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01))		    == 0) {			invalidate();			f_drv_ok = 0;		}		AX |= 0x8000;	}	if (disk_state & ST_PLAYING) {		AX |= 0x200;	}	AX |= 0x100;	/* pkt_esbx = AX; */	disk_state = 0;}#endif/* Init for the Module-Version */int init_gscd(void){	long err;	/* call the GoldStar-init */	err = my_gscd_init();	if (err < 0) {		return err;	} else {		printk(KERN_INFO "Happy GoldStar !\n");		return 0;	}}void __exit exit_gscd(void){	CLEAR_TIMER;	devfs_unregister(devfs_find_handle			 (NULL, "gscd", 0, 0, DEVFS_SPECIAL_BLK, 0));	if ((devfs_unregister_blkdev(MAJOR_NR, "gscd") == -EINVAL)) {		printk("What's that: can't unregister GoldStar-module\n");		return;	}	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));	release_region(gscd_port, 4);	printk(KERN_INFO "GoldStar-module released.\n");}#ifdef MODULEmodule_init(init_gscd);#endifmodule_exit(exit_gscd);/* Test for presence of drive and initialize it.  Called only at boot time. */int __init gscd_init(void){	return my_gscd_init();}/* This is the common initialisation for the GoldStar drive. *//* It is called at boot time AND for module init.           */int __init my_gscd_init(void){	int i;	int result;	printk(KERN_INFO "GSCD: version %s\n", GSCD_VERSION);	printk(KERN_INFO	       "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n",	       gscd_port);	if (check_region(gscd_port, 4)) {		printk		    ("GSCD: Init failed, I/O port (%X) already in use.\n",		     gscd_port);		return -EIO;	}	/* check for card */	result = wait_drv_ready();	if (result == 0x09) {		printk("GSCD: DMA kann ich noch nicht!\n");		return -EIO;	}	if (result == 0x0b) {		drv_mode = result;		i = find_drives();		if (i == 0) {			printk			    ("GSCD: GoldStar CD-ROM Drive is not found.\n");			return -EIO;		}	}	if ((result != 0x0b) && (result != 0x09)) {		printk		    ("GSCD: GoldStar Interface Adapter does not exist or H/W error\n");		return -EIO;	}	/* reset all drives */	i = 0;	while (drv_states[i] != 0) {		curr_drv_state = drv_states[i];		printk(KERN_INFO "GSCD: Reset unit %d ... ", i);		cc_Reset();		printk("done\n");		i++;	}	if (devfs_register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0) {		printk		    ("GSCD: Unable to get major %d for GoldStar CD-ROM\n",		     MAJOR_NR);		return -EIO;	}	devfs_register(NULL, "gscd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,		       S_IFBLK | S_IRUGO | S_IWUGO, &gscd_fops, NULL);	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);	blksize_size[MAJOR_NR] = gscd_blocksizes;	read_ahead[MAJOR_NR] = 4;	disk_state = 0;	gscdPresent = 1;	request_region(gscd_port, 4, "gscd");	register_disk(NULL, MKDEV(MAJOR_NR, 0), 1, &gscd_fops, 0);	printk(KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n");	return 0;}static void gscd_hsg2msf(long hsg, struct msf *msf){	hsg += CD_MSF_OFFSET;	msf->min = hsg / (CD_FRAMES * CD_SECS);	hsg %= CD_FRAMES * CD_SECS;	msf->sec = hsg / CD_FRAMES;	msf->frame = hsg % CD_FRAMES;	gscd_bin2bcd(&msf->min);	/* convert to BCD */	gscd_bin2bcd(&msf->sec);	gscd_bin2bcd(&msf->frame);}static void gscd_bin2bcd(unsigned char *p){	int u, t;	u = *p % 10;	t = *p / 10;	*p = u | (t << 4);}#ifdef FUTURE_WORKstatic long gscd_msf2hsg(struct msf *mp){	return gscd_bcd2bin(mp->frame)	    + gscd_bcd2bin(mp->sec) * CD_FRAMES	    + gscd_bcd2bin(mp->min) * CD_FRAMES * CD_SECS - CD_MSF_OFFSET;}static int gscd_bcd2bin(unsigned char bcd){	return (bcd >> 4) * 10 + (bcd & 0xF);}#endifMODULE_AUTHOR("Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>");MODULE_LICENSE("GPL");EXPORT_NO_SYMBOLS;

⌨️ 快捷键说明

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