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

📄 aztcd.c

📁 还有没有人研究过cdrom 的驱动源码啊
💻 C
📖 第 1 页 / 共 5 页
字号:
			tocPtr = &Toc[entry.cdte_track];		entry.cdte_adr = tocPtr->ctrl_addr;		entry.cdte_ctrl = tocPtr->ctrl_addr >> 4;		if (entry.cdte_format == CDROM_LBA)			entry.cdte_addr.lba =			    azt_msf2hsg(&tocPtr->diskTime);		else if (entry.cdte_format == CDROM_MSF) {			entry.cdte_addr.msf.minute =			    azt_bcd2bin(tocPtr->diskTime.min);			entry.cdte_addr.msf.second =			    azt_bcd2bin(tocPtr->diskTime.sec);			entry.cdte_addr.msf.frame =			    azt_bcd2bin(tocPtr->diskTime.frame);		} else {			return -EINVAL;		}		if (copy_to_user((void *) arg, &entry, sizeof entry))			return -EFAULT;		break;	case CDROMSUBCHNL:	/* Get subchannel info */		if (copy_from_user		    (&subchnl, (void *) arg, sizeof(struct cdrom_subchnl)))			return -EFAULT;		if (aztGetQChannelInfo(&qInfo) < 0) {#ifdef AZT_DEBUG			printk			    ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",			     cmd);#endif			return -EIO;		}		subchnl.cdsc_audiostatus = aztAudioStatus;		subchnl.cdsc_adr = qInfo.ctrl_addr;		subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;		subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);		subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);		if (subchnl.cdsc_format == CDROM_LBA) {			subchnl.cdsc_absaddr.lba =			    azt_msf2hsg(&qInfo.diskTime);			subchnl.cdsc_reladdr.lba =			    azt_msf2hsg(&qInfo.trackTime);		} else {	/*default */			subchnl.cdsc_format = CDROM_MSF;			subchnl.cdsc_absaddr.msf.minute =			    azt_bcd2bin(qInfo.diskTime.min);			subchnl.cdsc_absaddr.msf.second =			    azt_bcd2bin(qInfo.diskTime.sec);			subchnl.cdsc_absaddr.msf.frame =			    azt_bcd2bin(qInfo.diskTime.frame);			subchnl.cdsc_reladdr.msf.minute =			    azt_bcd2bin(qInfo.trackTime.min);			subchnl.cdsc_reladdr.msf.second =			    azt_bcd2bin(qInfo.trackTime.sec);			subchnl.cdsc_reladdr.msf.frame =			    azt_bcd2bin(qInfo.trackTime.frame);		}		if (copy_to_user		    ((void *) arg, &subchnl, sizeof(struct cdrom_subchnl)))			return -EFAULT;		break;	case CDROMVOLCTRL:	/* Volume control 				   * With my Aztech CD268-01A volume control does not work, I can only				   turn the channels on (any value !=0) or off (value==0). Maybe it				   works better with your drive */		if (copy_from_user		    (&volctrl, (char *) arg, sizeof(volctrl)))			return -EFAULT;		azt_Play.start.min = 0x21;		azt_Play.start.sec = 0x84;		azt_Play.start.frame = volctrl.channel0;		azt_Play.end.min = volctrl.channel1;		azt_Play.end.sec = volctrl.channel2;		azt_Play.end.frame = volctrl.channel3;		sendAztCmd(ACMD_SET_VOLUME, &azt_Play);		STEN_LOW_WAIT;		break;	case CDROMEJECT:		aztUnlockDoor();	/* Assume user knows what they're doing */		/* all drives can at least stop! */		if (aztAudioStatus == CDROM_AUDIO_PLAY) {			if (aztSendCmd(ACMD_STOP))				RETURNM("azt_ioctl 10", -1);			STEN_LOW_WAIT;		}		if (aztSendCmd(ACMD_EJECT))			RETURNM("azt_ioctl 11", -1);		STEN_LOW_WAIT;		aztAudioStatus = CDROM_AUDIO_NO_STATUS;		break;	case CDROMEJECT_SW:		azt_auto_eject = (char) arg;		break;	case CDROMRESET:		outb(ACMD_SOFT_RESET, CMD_PORT);	/*send reset */		STEN_LOW;		if (inb(DATA_PORT) != AFL_OP_OK) {	/*OP_OK? */			printk			    ("aztcd: AZTECH CD-ROM drive does not respond\n");		}		break;/*Take care, the following code is not compatible with other CD-ROM drivers,  use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,  if you do not want to use it!*/#if AZT_PRIVATE_IOCTLS	case CDROMREADCOOKED:	/*read data in mode 1 (2048 Bytes) */	case CDROMREADRAW:	/*read data in mode 2 (2336 Bytes) */		{			if (copy_from_user(&msf, (void *) arg, sizeof msf))				return -EFAULT;			/* convert to bcd */			azt_bin2bcd(&msf.cdmsf_min0);			azt_bin2bcd(&msf.cdmsf_sec0);			azt_bin2bcd(&msf.cdmsf_frame0);			msf.cdmsf_min1 = 0;			msf.cdmsf_sec1 = 0;			msf.cdmsf_frame1 = 1;	/*read only one frame */			azt_Play.start.min = msf.cdmsf_min0;			azt_Play.start.sec = msf.cdmsf_sec0;			azt_Play.start.frame = msf.cdmsf_frame0;			azt_Play.end.min = msf.cdmsf_min1;			azt_Play.end.sec = msf.cdmsf_sec1;			azt_Play.end.frame = msf.cdmsf_frame1;			if (cmd == CDROMREADRAW) {				if (DiskInfo.xa) {					return -1;	/*XA Disks can't be read raw */				} else {					if (sendAztCmd					    (ACMD_PLAY_READ_RAW,					     &azt_Play))						return -1;					DTEN_LOW;					insb(DATA_PORT, buf,					     CD_FRAMESIZE_RAW);					if (copy_to_user					    ((void *) arg, &buf,					     CD_FRAMESIZE_RAW))						return -EFAULT;				}			} else				/*CDROMREADCOOKED*/ {				if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))					return -1;				DTEN_LOW;				insb(DATA_PORT, buf, CD_FRAMESIZE);				if (copy_to_user				    ((void *) arg, &buf, CD_FRAMESIZE))					return -EFAULT;				}		}		break;	case CDROMSEEK:	/*seek msf address */		if (copy_from_user(&msf, (void *) arg, sizeof msf))			return -EFAULT;		/* convert to bcd */		azt_bin2bcd(&msf.cdmsf_min0);		azt_bin2bcd(&msf.cdmsf_sec0);		azt_bin2bcd(&msf.cdmsf_frame0);		azt_Play.start.min = msf.cdmsf_min0;		azt_Play.start.sec = msf.cdmsf_sec0;		azt_Play.start.frame = msf.cdmsf_frame0;		if (aztSeek(&azt_Play))			return -1;		break;#endif				/*end of incompatible code */	case CDROMREADMODE1:	/*set read data in mode 1 */		return aztSetDiskType(AZT_MODE_1);	case CDROMREADMODE2:	/*set read data in mode 2 */		return aztSetDiskType(AZT_MODE_2);	default:		return -EINVAL;	}#ifdef AZT_DEBUG	printk("aztcd: exiting aztcd_ioctl Command:%x  Time:%li\n", cmd,	       jiffies);#endif	return 0;}/* * Take care of the different block sizes between cdrom and Linux. * When Linux gets variable block sizes this will probably go away. */static void azt_transfer(void){#ifdef AZT_TEST	printk("aztcd: executing azt_transfer Time:%li\n", jiffies);#endif	if (CURRENT_VALID) {		while (CURRENT->nr_sectors) {			int bn = CURRENT->sector / 4;			int i;			for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn;			     ++i);			if (i < AZT_BUF_SIZ) {				int offs =				    (i * 4 + (CURRENT->sector & 3)) * 512;				int nr_sectors = 4 - (CURRENT->sector & 3);				if (azt_buf_out != i) {					azt_buf_out = i;					if (azt_buf_bn[i] != bn) {						azt_buf_out = -1;						continue;					}				}				if (nr_sectors > CURRENT->nr_sectors)					nr_sectors = CURRENT->nr_sectors;				memcpy(CURRENT->buffer, azt_buf + offs,				       nr_sectors * 512);				CURRENT->nr_sectors -= nr_sectors;				CURRENT->sector += nr_sectors;				CURRENT->buffer += nr_sectors * 512;			} else {				azt_buf_out = -1;				break;			}		}	}}static void do_aztcd_request(request_queue_t * q){#ifdef AZT_TEST	printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector,	       CURRENT->nr_sectors, jiffies);#endif	if (DiskInfo.audio) {		printk("aztcd: Error, tried to mount an Audio CD\n");		end_request(0);		return;	}	azt_transfer_is_active = 1;	while (CURRENT_VALID) {		if (CURRENT->bh) {			if (!buffer_locked(CURRENT->bh))				panic(DEVICE_NAME ": block not locked");		}		azt_transfer();		if (CURRENT->nr_sectors == 0) {			end_request(1);		} else {			azt_buf_out = -1;	/* Want to read a block not in buffer */			if (azt_state == AZT_S_IDLE) {				if ((!aztTocUpToDate) || aztDiskChanged) {					if (aztUpdateToc() < 0) {						while (CURRENT_VALID)							end_request(0);						break;					}				}				azt_state = AZT_S_START;				AztTries = 5;				SET_TIMER(azt_poll, HZ / 100);			}			break;		}	}	azt_transfer_is_active = 0;#ifdef AZT_TEST2	printk	    ("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n",	     azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);	printk(" do_aztcd_request ends  Time:%li\n", jiffies);#endif}static void azt_invalidate_buffers(void){	int i;#ifdef AZT_DEBUG	printk("aztcd: executing azt_invalidate_buffers\n");#endif	for (i = 0; i < AZT_BUF_SIZ; ++i)		azt_buf_bn[i] = -1;	azt_buf_out = -1;}/* * Open the device special file.  Check that a disk is in. */int aztcd_open(struct inode *ip, struct file *fp){	int st;#ifdef AZT_DEBUG	printk("aztcd: starting aztcd_open\n");#endif	if (aztPresent == 0)		return -ENXIO;	/* no hardware */	if (!azt_open_count && azt_state == AZT_S_IDLE) {		azt_invalidate_buffers();		st = getAztStatus();	/* check drive status */		if (st == -1)			goto err_out;	/* drive doesn't respond */		if (st & AST_DOOR_OPEN) {	/* close door, then get the status again. */			printk("aztcd: Door Open?\n");			aztCloseDoor();			st = getAztStatus();		}		if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) {	/*no disk in drive or changed */			printk			    ("aztcd: Disk Changed or No Disk in Drive?\n");			aztTocUpToDate = 0;		}		if (aztUpdateToc())			goto err_out;	}	++azt_open_count;	aztLockDoor();#ifdef AZT_DEBUG	printk("aztcd: exiting aztcd_open\n");#endif	return 0;      err_out:	return -EIO;}/* * On close, we flush all azt blocks from the buffer cache. */static int aztcd_release(struct inode *inode, struct file *file){#ifdef AZT_DEBUG	printk("aztcd: executing aztcd_release\n");	printk("inode: %p, inode->i_rdev: %x    file: %p\n", inode,	       inode->i_rdev, file);#endif	if (!--azt_open_count) {		azt_invalidate_buffers();		aztUnlockDoor();		if (azt_auto_eject)			aztSendCmd(ACMD_EJECT);		CLEAR_TIMER;	}	return 0;}/* * Test for presence of drive and initialize it.  Called at boot time. */int __init aztcd_init(void){	long int count, max_count;	unsigned char result[50];	int st;	int i = 0;	if (azt_port == 0) {		printk("aztcd: no Aztech CD-ROM Initialization");		return -EIO;	}	printk	    ("aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM CD-ROM Driver\n");	printk("aztcd: (C) 1994-98 W.Zimmermann\n");	if (azt_port == -1) {		printk		    ("aztcd: KernelVersion=%s DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",		     UTS_RELEASE, AZT_VERSION);	} else		printk		    ("aztcd: DriverVersion=%s BaseAddress=0x%x  For IDE/ATAPI-drives use ide-cd.c\n",		     AZT_VERSION, azt_port);	printk	    ("aztcd: If you have problems, read /usr/src/linux/Documentation/cdrom/aztcd\n");#ifdef AZT_SW32			/*CDROM connected to Soundwave32 card */	if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {		printk		    ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",		     AZT_SW32_BASE_ADDR, AZT_SW32_INIT,		     AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);		return -EIO;	} else {		printk(KERN_INFO		       "aztcd: Soundwave32 card detected at %x  Version %x\n",		       AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));		outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);		for (count = 0; count < 10000; count++);	/*delay a bit */	}#endif	/* check for presence of drive */	if (azt_port == -1) {	/* autoprobing */		for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {			azt_port = azt_port_auto[i];			printk("aztcd: Autoprobing BaseAddress=0x%x \n",			       azt_port);			st = check_region(azt_port, 4);	/*proprietary interfaces need 4 bytes */			if (st)				continue;			outb(POLLED, MODE_PORT);			inb(CMD_PORT);			inb(CMD_PORT);			outb(ACMD_GET_VERSION, CMD_PORT);	/*Try to get version info */			aztTimeOutCount = 0;			do {				aztIndatum = inb(STATUS_PORT);				aztTimeOutCount++;				if (aztTimeOutCount >= AZT_FAST_TIMEOUT)					break;			} while (aztIndatum & AFL_STATUS);			if (inb(DATA_PORT) == AFL_OP_OK)				break;		}		if ((azt_port_auto[i] == 0) || (i == 16)) {			printk("aztcd: no AZTECH CD-ROM drive found\n");			return -EIO;		}	} else {		/* no autoprobing */		if ((azt_port == 0x1f0) || (azt_port == 0x170))			st = check_region(azt_port, 8);	/*IDE-interfaces need 8 bytes */		else			st = check_region(azt_port, 4);	/*proprietary interfaces need 4 bytes */		if (st) {			printk			    ("aztcd: conflict, I/O port (%X) already used\n",			     azt_port);			return -EIO;		}		if ((azt_port == 0x1f0) || (azt_port == 0x170))			SWITCH_IDE_SLAVE;	/*switch IDE interface to slave configuration */		outb(POLLED, MODE_PORT);		inb(CMD_PORT);		inb(CMD_PORT);		outb(ACMD_GET_VERSION, CMD_PORT);	/*Try to get version info */		aztTimeOutCount = 0;		do {			aztIndatum = inb(STATUS_PORT);			aztTimeOutCount++;			if (aztTimeOutCount >= AZT_FAST_TIMEOUT)				break;		} while (aztIndatum & AFL_STATUS);		if (inb(DATA_PORT) != AFL_OP_OK) {	/*OP_OK? If not, reset and try again */

⌨️ 快捷键说明

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