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

📄 aztcd.c

📁 还有没有人研究过cdrom 的驱动源码啊
💻 C
📖 第 1 页 / 共 5 页
字号:
}static void aztStatTimer(void){	if (!(inb(STATUS_PORT) & AFL_STATUS)) {		wake_up(&azt_waitq);		return;	}	AztTimeout--;	if (AztTimeout <= 0) {		wake_up(&azt_waitq);		printk("aztcd: Error aztStatTimer: Timeout\n");		return;	}	SET_TIMER(aztStatTimer, HZ / 100);}/*##########################################################################  CDROM Drive Command Functions  ##########################################################################*//*  * Send a single command, return -1 on error, else 0*/static int aztSendCmd(int cmd){	unsigned char data;	int retry;#ifdef AZT_DEBUG	printk("aztcd: Executing command %x\n", cmd);#endif	if ((azt_port == 0x1f0) || (azt_port == 0x170))		SWITCH_IDE_SLAVE;	/*switch IDE interface to slave configuration */	aztCmd = cmd;	outb(POLLED, MODE_PORT);	do {		if (inb(STATUS_PORT) & AFL_STATUS)			break;		inb(DATA_PORT);	/* if status left from last command, read and */	} while (1);		/* discard it */	do {		if (inb(STATUS_PORT) & AFL_DATA)			break;		inb(DATA_PORT);	/* if data left from last command, read and */	} while (1);		/* discard it */	for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {		outb((unsigned char) cmd, CMD_PORT);		STEN_LOW;		data = inb(DATA_PORT);		if (data == AFL_OP_OK) {			return 0;		}		/*OP_OK? */		if (data == AFL_OP_ERR) {			STEN_LOW;			data = inb(DATA_PORT);			printk			    ("### Error 1 aztcd: aztSendCmd %x  Error Code %x\n",			     cmd, data);		}	}	if (retry >= AZT_RETRY_ATTEMPTS) {		printk("### Error 2 aztcd: aztSendCmd %x \n", cmd);		azt_error = 0xA5;	}	RETURNM("aztSendCmd", -1);}/* * Send a play or read command to the drive, return -1 on error, else 0*/static int sendAztCmd(int cmd, struct azt_Play_msf *params){	unsigned char data;	int retry;#ifdef AZT_DEBUG	printk("aztcd: play start=%02x:%02x:%02x  end=%02x:%02x:%02x\n",	       params->start.min, params->start.sec, params->start.frame,	       params->end.min, params->end.sec, params->end.frame);#endif	for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {		aztSendCmd(cmd);		outb(params->start.min, CMD_PORT);		outb(params->start.sec, CMD_PORT);		outb(params->start.frame, CMD_PORT);		outb(params->end.min, CMD_PORT);		outb(params->end.sec, CMD_PORT);		outb(params->end.frame, CMD_PORT);		STEN_LOW;		data = inb(DATA_PORT);		if (data == AFL_PA_OK) {			return 0;		}		/*PA_OK ? */		if (data == AFL_PA_ERR) {			STEN_LOW;			data = inb(DATA_PORT);			printk			    ("### Error 1 aztcd: sendAztCmd %x  Error Code %x\n",			     cmd, data);		}	}	if (retry >= AZT_RETRY_ATTEMPTS) {		printk("### Error 2 aztcd: sendAztCmd %x\n ", cmd);		azt_error = 0xA5;	}	RETURNM("sendAztCmd", -1);}/* * Send a seek command to the drive, return -1 on error, else 0*/static int aztSeek(struct azt_Play_msf *params){	unsigned char data;	int retry;#ifdef AZT_DEBUG	printk("aztcd: aztSeek %02x:%02x:%02x\n",	       params->start.min, params->start.sec, params->start.frame);#endif	for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {		aztSendCmd(ACMD_SEEK);		outb(params->start.min, CMD_PORT);		outb(params->start.sec, CMD_PORT);		outb(params->start.frame, CMD_PORT);		STEN_LOW;		data = inb(DATA_PORT);		if (data == AFL_PA_OK) {			return 0;		}		/*PA_OK ? */		if (data == AFL_PA_ERR) {			STEN_LOW;			data = inb(DATA_PORT);			printk("### Error 1 aztcd: aztSeek\n");		}	}	if (retry >= AZT_RETRY_ATTEMPTS) {		printk("### Error 2 aztcd: aztSeek\n ");		azt_error = 0xA5;	}	RETURNM("aztSeek", -1);}/* Send a Set Disk Type command   does not seem to work with Aztech drives, behavior is completely indepen-   dent on which mode is set ???*/static int aztSetDiskType(int type){	unsigned char data;	int retry;#ifdef AZT_DEBUG	printk("aztcd: set disk type command: type= %i\n", type);#endif	for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {		aztSendCmd(ACMD_SET_DISK_TYPE);		outb(type, CMD_PORT);		STEN_LOW;		data = inb(DATA_PORT);		if (data == AFL_PA_OK) {	/*PA_OK ? */			azt_read_mode = type;			return 0;		}		if (data == AFL_PA_ERR) {			STEN_LOW;			data = inb(DATA_PORT);			printk			    ("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",			     type, data);		}	}	if (retry >= AZT_RETRY_ATTEMPTS) {		printk("### Error 2 aztcd: aztSetDiskType %x\n ", type);		azt_error = 0xA5;	}	RETURNM("aztSetDiskType", -1);}/* used in azt_poll to poll the status, expects another program to issue a  * ACMD_GET_STATUS directly before  */static int aztStatus(void){	int st;/*	int i;	i = inb(STATUS_PORT) & AFL_STATUS;    is STEN=0?    ???	if (!i)*/ STEN_LOW;	if (aztTimeOutCount < AZT_TIMEOUT) {		st = inb(DATA_PORT) & 0xFF;		return st;	} else		RETURNM("aztStatus", -1);}/* * Get the drive status */static int getAztStatus(void){	int st;	if (aztSendCmd(ACMD_GET_STATUS))		RETURNM("getAztStatus 1", -1);	STEN_LOW;	st = inb(DATA_PORT) & 0xFF;#ifdef AZT_DEBUG	printk("aztcd: Status = %x\n", st);#endif	if ((st == 0xFF) || (st & AST_CMD_CHECK)) {		printk		    ("aztcd: AST_CMD_CHECK error or no status available\n");		return -1;	}	if (((st & AST_MODE_BITS) != AST_BUSY)	    && (aztAudioStatus == CDROM_AUDIO_PLAY))		/* XXX might be an error? look at q-channel? */		aztAudioStatus = CDROM_AUDIO_COMPLETED;	if ((st & AST_DSK_CHG) || (st & AST_NOT_READY)) {		aztDiskChanged = 1;		aztTocUpToDate = 0;		aztAudioStatus = CDROM_AUDIO_NO_STATUS;	}	return st;}/* * Send a 'Play' command and get the status.  Use only from the top half. */static int aztPlay(struct azt_Play_msf *arg){	if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0)		RETURNM("aztPlay", -1);	return 0;}/* * Subroutines to automatically close the door (tray) and  * lock it closed when the cd is mounted.  Leave the tray * locking as an option */static void aztCloseDoor(void){	aztSendCmd(ACMD_CLOSE);	STEN_LOW;	return;}static void aztLockDoor(void){#if AZT_ALLOW_TRAY_LOCK	aztSendCmd(ACMD_LOCK);	STEN_LOW;#endif	return;}static void aztUnlockDoor(void){#if AZT_ALLOW_TRAY_LOCK	aztSendCmd(ACMD_UNLOCK);	STEN_LOW;#endif	return;}/* * Read a value from the drive.  Should return quickly, so a busy wait * is used to avoid excessive rescheduling. The read command itself must * be issued with aztSendCmd() directly before */static int aztGetValue(unsigned char *result){	int s;	STEN_LOW;	if (aztTimeOutCount >= AZT_TIMEOUT) {		printk("aztcd: aztGetValue timeout\n");		return -1;	}	s = inb(DATA_PORT) & 0xFF;	*result = (unsigned char) s;	return 0;}/* * Read the current Q-channel info.  Also used for reading the * table of contents. */int aztGetQChannelInfo(struct azt_Toc *qp){	unsigned char notUsed;	int st;#ifdef AZT_DEBUG	printk("aztcd: starting aztGetQChannelInfo  Time:%li\n", jiffies);#endif	if ((st = getAztStatus()) == -1)		RETURNM("aztGetQChannelInfo 1", -1);	if (aztSendCmd(ACMD_GET_Q_CHANNEL))		RETURNM("aztGetQChannelInfo 2", -1);	/*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here */	if (aztGetValue(&notUsed))		RETURNM("aztGetQChannelInfo 3", -1);	/*??? Nullbyte einlesen */	if ((st & AST_MODE_BITS) == AST_INITIAL) {		qp->ctrl_addr = 0;	/* when audio stop ACMD_GET_Q_CHANNEL returns */		qp->track = 0;	/* only one byte with Aztech drives */		qp->pointIndex = 0;		qp->trackTime.min = 0;		qp->trackTime.sec = 0;		qp->trackTime.frame = 0;		qp->diskTime.min = 0;		qp->diskTime.sec = 0;		qp->diskTime.frame = 0;		return 0;	} else {		if (aztGetValue(&qp->ctrl_addr) < 0)			RETURNM("aztGetQChannelInfo 4", -1);		if (aztGetValue(&qp->track) < 0)			RETURNM("aztGetQChannelInfo 4", -1);		if (aztGetValue(&qp->pointIndex) < 0)			RETURNM("aztGetQChannelInfo 4", -1);		if (aztGetValue(&qp->trackTime.min) < 0)			RETURNM("aztGetQChannelInfo 4", -1);		if (aztGetValue(&qp->trackTime.sec) < 0)			RETURNM("aztGetQChannelInfo 4", -1);		if (aztGetValue(&qp->trackTime.frame) < 0)			RETURNM("aztGetQChannelInfo 4", -1);		if (aztGetValue(&notUsed) < 0)			RETURNM("aztGetQChannelInfo 4", -1);		if (aztGetValue(&qp->diskTime.min) < 0)			RETURNM("aztGetQChannelInfo 4", -1);		if (aztGetValue(&qp->diskTime.sec) < 0)			RETURNM("aztGetQChannelInfo 4", -1);		if (aztGetValue(&qp->diskTime.frame) < 0)			RETURNM("aztGetQChannelInfo 4", -1);	}#ifdef AZT_DEBUG	printk("aztcd: exiting aztGetQChannelInfo  Time:%li\n", jiffies);#endif	return 0;}/* * Read the table of contents (TOC) and TOC header if necessary */static int aztUpdateToc(){	int st;#ifdef AZT_DEBUG	printk("aztcd: starting aztUpdateToc  Time:%li\n", jiffies);#endif	if (aztTocUpToDate)		return 0;	if (aztGetDiskInfo() < 0)		return -EIO;	if (aztGetToc(0) < 0)		return -EIO;	/*audio disk detection	   with my Aztech drive there is no audio status bit, so I use the copy	   protection bit of the first track. If this track is copy protected 	   (copy bit = 0), I assume, it's an audio  disk. Strange, but works ??? */	if (!(Toc[DiskInfo.first].ctrl_addr & 0x40))		DiskInfo.audio = 1;	else		DiskInfo.audio = 0;	/* XA detection */	if (!DiskInfo.audio) {		azt_Play.start.min = 0;	/*XA detection only seems to work */		azt_Play.start.sec = 2;	/*when we play a track */		azt_Play.start.frame = 0;		azt_Play.end.min = 0;		azt_Play.end.sec = 0;		azt_Play.end.frame = 1;		if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))			return -1;		DTEN_LOW;		for (st = 0; st < CD_FRAMESIZE; st++)			inb(DATA_PORT);	}	DiskInfo.xa = getAztStatus() & AST_MODE;	if (DiskInfo.xa) {		printk		    ("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n");	}	/*multisession detection	   support for multisession CDs is done automatically with Aztech drives,	   we don't have to take care about TOC redirection; if we want the isofs	   to take care about redirection, we have to set AZT_MULTISESSION to 1 */	DiskInfo.multi = 0;#if AZT_MULTISESSION	if (DiskInfo.xa) {		aztGetMultiDiskInfo();	/*here Disk.Info.multi is set */	}#endif	if (DiskInfo.multi) {		DiskInfo.lastSession.min = Toc[DiskInfo.next].diskTime.min;		DiskInfo.lastSession.sec = Toc[DiskInfo.next].diskTime.sec;		DiskInfo.lastSession.frame =		    Toc[DiskInfo.next].diskTime.frame;		printk("aztcd: Multisession support experimental\n");	} else {		DiskInfo.lastSession.min =		    Toc[DiskInfo.first].diskTime.min;		DiskInfo.lastSession.sec =		    Toc[DiskInfo.first].diskTime.sec;		DiskInfo.lastSession.frame =		    Toc[DiskInfo.first].diskTime.frame;	}	aztTocUpToDate = 1;#ifdef AZT_DEBUG	printk("aztcd: exiting aztUpdateToc  Time:%li\n", jiffies);#endif	return 0;}/* Read the table of contents header, i.e. no. of tracks and start of first  * track */static int aztGetDiskInfo(){	int limit;	unsigned char test;	struct azt_Toc qInfo;#ifdef AZT_DEBUG	printk("aztcd: starting aztGetDiskInfo  Time:%li\n", jiffies);#endif	if (aztSendCmd(ACMD_SEEK_TO_LEADIN))		RETURNM("aztGetDiskInfo 1", -1);	STEN_LOW_WAIT;	test = 0;	for (limit = 300; limit > 0; limit--) {		if (aztGetQChannelInfo(&qInfo) < 0)			RETURNM("aztGetDiskInfo 2", -1);		if (qInfo.pointIndex == 0xA0) {	/*Number of FirstTrack */			DiskInfo.first = qInfo.diskTime.min;			DiskInfo.first = azt_bcd2bin(DiskInfo.first);			test = test | 0x01;

⌨️ 快捷键说明

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