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

📄 aztcd.c

📁 cdrom device drive for linux.
💻 C
📖 第 1 页 / 共 5 页
字号:
		    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;
		}
		if (qInfo.pointIndex == 0xA1) {	/*Number of LastTrack */
			DiskInfo.last = qInfo.diskTime.min;
			DiskInfo.last = azt_bcd2bin(DiskInfo.last);
			test = test | 0x02;
		}
		if (qInfo.pointIndex == 0xA2) {	/*DiskLength */
			DiskInfo.diskLength.min = qInfo.diskTime.min;
			DiskInfo.diskLength.sec = qInfo.diskTime.sec;
			DiskInfo.diskLength.frame = qInfo.diskTime.frame;
			test = test | 0x04;
		}
		if ((qInfo.pointIndex == DiskInfo.first) && (test & 0x01)) {	/*StartTime of First Track */
			DiskInfo.firstTrack.min = qInfo.diskTime.min;
			DiskInfo.firstTrack.sec = qInfo.diskTime.sec;
			DiskInfo.firstTrack.frame = qInfo.diskTime.frame;
			test = test | 0x08;
		}
		if (test == 0x0F)
			break;
	}
#ifdef AZT_DEBUG
	printk("aztcd: exiting aztGetDiskInfo  Time:%li\n", jiffies);
	printk
	    ("Disk Info: first %d last %d length %02X:%02X.%02X dez  first %02X:%02X.%02X dez\n",
	     DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min,
	     DiskInfo.diskLength.sec, DiskInfo.diskLength.frame,
	     DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec,
	     DiskInfo.firstTrack.frame);
#endif
	if (test != 0x0F)
		return -1;
	return 0;
}

#if AZT_MULTISESSION
/*
 * Get Multisession Disk Info
 */
static int aztGetMultiDiskInfo(void)
{
	int limit, k = 5;
	unsigned char test;
	struct azt_Toc qInfo;

#ifdef AZT_DEBUG
	printk("aztcd: starting aztGetMultiDiskInfo\n");
#endif

	do {
		azt_Play.start.min = Toc[DiskInfo.last + 1].diskTime.min;
		azt_Play.start.sec = Toc[DiskInfo.last + 1].diskTime.sec;
		azt_Play.start.frame =
		    Toc[DiskInfo.last + 1].diskTime.frame;
		test = 0;

		for (limit = 30; limit > 0; limit--) {	/*Seek for LeadIn of next session */
			if (aztSeek(&azt_Play))
				RETURNM("aztGetMultiDiskInfo 1", -1);
			if (aztGetQChannelInfo(&qInfo) < 0)
				RETURNM("aztGetMultiDiskInfo 2", -1);
			if ((qInfo.track == 0) && (qInfo.pointIndex))
				break;	/*LeadIn found */
			if ((azt_Play.start.sec += 10) > 59) {
				azt_Play.start.sec = 0;
				azt_Play.start.min++;
			}
		}
		if (!limit)
			break;	/*Check, if a leadin track was found, if not we're
				   at the end of the disk */
#ifdef AZT_DEBUG_MULTISESSION
		printk("leadin found track %d  pointIndex %x  limit %d\n",
		       qInfo.track, qInfo.pointIndex, limit);
#endif
		for (limit = 300; limit > 0; limit--) {
			if (++azt_Play.start.frame > 74) {
				azt_Play.start.frame = 0;
				if (azt_Play.start.sec > 59) {
					azt_Play.start.sec = 0;
					azt_Play.start.min++;
				}
			}
			if (aztSeek(&azt_Play))
				RETURNM("aztGetMultiDiskInfo 3", -1);
			if (aztGetQChannelInfo(&qInfo) < 0)
				RETURNM("aztGetMultiDiskInfo 4", -1);
			if (qInfo.pointIndex == 0xA0) {	/*Number of NextTrack */
				DiskInfo.next = qInfo.diskTime.min;
				DiskInfo.next = azt_bcd2bin(DiskInfo.next);
				test = test | 0x01;
			}
			if (qInfo.pointIndex == 0xA1) {	/*Number of LastTrack */
				DiskInfo.last = qInfo.diskTime.min;
				DiskInfo.last = azt_bcd2bin(DiskInfo.last);
				test = test | 0x02;
			}
			if (qInfo.pointIndex == 0xA2) {	/*DiskLength */
				DiskInfo.diskLength.min =
				    qInfo.diskTime.min;
				DiskInfo.diskLength.sec =
				    qInfo.diskTime.sec;
				DiskInfo.diskLength.frame =
				    qInfo.diskTime.frame;
				test = test | 0x04;
			}
			if ((qInfo.pointIndex == DiskInfo.next) && (test & 0x01)) {	/*StartTime of Next Track */
				DiskInfo.nextSession.min =
				    qInfo.diskTime.min;
				DiskInfo.nextSession.sec =
				    qInfo.diskTime.sec;
				DiskInfo.nextSession.frame =
				    qInfo.diskTime.frame;
				test = test | 0x08;
			}
			if (test == 0x0F)
				break;
		}
#ifdef AZT_DEBUG_MULTISESSION
		printk
		    ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez  first %02x:%02x.%02x dez  next %02x:%02x.%02x dez\n",
		     DiskInfo.first, DiskInfo.next, DiskInfo.last,
		     DiskInfo.diskLength.min, DiskInfo.diskLength.sec,
		     DiskInfo.diskLength.frame, DiskInfo.firstTrack.min,
		     DiskInfo.firstTrack.sec, DiskInfo.firstTrack.frame,
		     DiskInfo.nextSession.min, DiskInfo.nextSession.sec,
		     DiskInfo.nextSession.frame);
#endif
		if (test != 0x0F)
			break;
		else
			DiskInfo.multi = 1;	/*found TOC of more than one session */
		aztGetToc(1);
	} while (--k);

#ifdef AZT_DEBUG
	printk("aztcd: exiting aztGetMultiDiskInfo  Time:%li\n", jiffies);
#endif
	return 0;
}
#endif

/*
 * Read the table of contents (TOC)
 */
static int aztGetToc(int multi)
{
	int i, px;
	int limit;
	struct azt_Toc qInfo;

#ifdef AZT_DEBUG
	printk("aztcd: starting aztGetToc  Time:%li\n", jiffies);
#endif
	if (!multi) {
		for (i = 0; i < MAX_TRACKS; i++)
			Toc[i].pointIndex = 0;
		i = DiskInfo.last + 3;
	} else {
		for (i = DiskInfo.next; i < MAX_TRACKS; i++)
			Toc[i].pointIndex = 0;
		i = DiskInfo.last + 4 - DiskInfo.next;
	}

/*Is there a good reason to stop motor before TOC read?
  if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1);
      STEN_LOW_WAIT;
*/

	if (!multi) {
		azt_mode = 0x05;
		if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
			RETURNM("aztGetToc 2", -1);
		STEN_LOW_WAIT;
	}
	for (limit = 300; limit > 0; limit--) {
		if (multi) {
			if (++azt_Play.start.sec > 59) {
				azt_Play.start.sec = 0;
				azt_Play.start.min++;
			}
			if (aztSeek(&azt_Play))
				RETURNM("aztGetToc 3", -1);
		}
		if (aztGetQChannelInfo(&qInfo) < 0)
			break;

		px = azt_bcd2bin(qInfo.pointIndex);

		if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
			if (Toc[px].pointIndex == 0) {
				Toc[px] = qInfo;
				i--;
			}

		if (i <= 0)
			break;
	}

	Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
	Toc[DiskInfo.last].trackTime = DiskInfo.diskLength;

#ifdef AZT_DEBUG_MULTISESSION
	printk("aztcd: exiting aztGetToc\n");
	for (i = 1; i <= DiskInfo.last + 1; i++)
		printk
		    ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez  %02X:%02X.%02X dez\n",
		     i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
		     Toc[i].trackTime.min, Toc[i].trackTime.sec,
		     Toc[i].trackTime.frame, Toc[i].diskTime.min,
		     Toc[i].diskTime.sec, Toc[i].diskTime.frame);
	for (i = 100; i < 103; i++)
		printk
		    ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez  %02X:%02X.%02X dez\n",
		     i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
		     Toc[i].trackTime.min, Toc[i].trackTime.sec,
		     Toc[i].trackTime.frame, Toc[i].diskTime.min,
		     Toc[i].diskTime.sec, Toc[i].diskTime.frame);
#endif

	return limit > 0 ? 0 : -1;
}


/*##########################################################################
  Kernel Interface Functions
  ##########################################################################
*/

#ifndef MODULE
static int __init aztcd_setup(char *str)
{
	int ints[4];

	(void) get_options(str, ARRAY_SIZE(ints), ints);

	if (ints[0] > 0)
		azt_port = ints[1];
	if (ints[1] > 1)
		azt_cont = ints[2];
	return 1;
}

__setup("aztcd=", aztcd_setup);

#endif				/* !MODULE */

/* 
 * Checking if the media has been changed
*/
static int check_aztcd_media_change(kdev_t full_dev)
{
	if (aztDiskChanged) {	/* disk changed */
		aztDiskChanged = 0;
		return 1;
	} else
		return 0;	/* no change */
}

/*
 * Kernel IO-controls
*/
static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
		       unsigned long arg)
{
	int i;
	struct azt_Toc qInfo;
	struct cdrom_ti ti;
	struct cdrom_tochdr tocHdr;
	struct cdrom_msf msf;
	struct cdrom_tocentry entry;
	struct azt_Toc *tocPtr;
	struct cdrom_subchnl subchnl;
	struct cdrom_volctrl volctrl;

#ifdef AZT_DEBUG
	printk("aztcd: starting aztcd_ioctl - Command:%x   Time: %li\n",
	       cmd, jiffies);
	printk("aztcd Status %x\n", getAztStatus());
#endif
	if (!ip)
		RETURNM("aztcd_ioctl 1", -EINVAL);
	if (getAztStatus() < 0)
		RETURNM("aztcd_ioctl 2", -EIO);
	if ((!aztTocUpToDate) || (aztDiskChanged)) {
		if ((i = aztUpdateToc()) < 0)
			RETURNM("aztcd_ioctl 3", i);	/* error reading TOC */
	}

	switch (cmd) {
	case CDROMSTART:	/* Spin up the drive. Don't know, what to do,
				   at least close the tray */
#if AZT_PRIVATE_IOCTLS
		if (aztSendCmd(ACMD_CLOSE))
			RETURNM("aztcd_ioctl 4", -1);
		STEN_LOW_WAIT;
#endif
		break;
	case CDROMSTOP:	/* Spin down the drive */
		if (aztSendCmd(ACMD_STOP))
			RETURNM("aztcd_ioctl 5", -1);
		STEN_LOW_WAIT;
		/* should we do anything if it fails? */
		aztAudioStatus = CDROM_AUDIO_NO_STATUS;
		break;
	case CDROMPAUSE:	/* Pause the drive */
		if (aztAudioStatus != CDROM_AUDIO_PLAY)
			return -EINVAL;

		if (aztGetQChannelInfo(&qInfo) < 0) {	/* didn't get q channel info */
			aztAudioStatus = CDROM_AUDIO_NO_STATUS;
			RETURNM("aztcd_ioctl 7", 0);
		}
		azt_Play.start = qInfo.diskTime;	/* remember restart point */

		if (aztSendCmd(ACMD_PAUSE))
			RETURNM("aztcd_ioctl 8", -1);
		STEN_LOW_WAIT;
		aztAudioStatus = CDROM_AUDIO_PAUSED;
		break;
	case CDROMRESUME:	/* Play it again, Sam */
		if (aztAudioStatus != CDROM_AUDIO_PAUSED)
			return -EINVAL;
		/* restart the drive at the saved position. */
		i = aztPlay(&azt_Play);
		if (i < 0) {
			aztAudioStatus = CDROM_AUDIO_ERROR;
			return -EIO;
		}
		aztAudioStatus = CDROM_AUDIO_PLAY;
		break;
	case CDROMMULTISESSION:	/*multisession support -- experimental */
		{
			struct cdrom_multisession ms;
#ifdef AZT_DEBUG
			printk("aztcd ioctl MULTISESSION\n");
#endif
			if (copy_from_user
			    (&ms, (void *) arg,
			     sizeof(struct cdrom_multisession)))
				return -EFAULT;
			if (ms.addr_format == CDROM_MSF) {
				ms.addr.msf.minute =
				    azt_bcd2bin(DiskInfo.lastSession.min);
				ms.addr.msf.second =
				    azt_bcd2bin(DiskInfo.lastSession.sec);
				ms.addr.msf.frame =
				    azt_bcd2bin(DiskInfo.lastSession.
						frame);
			} else if (ms.addr_format == CDROM_LBA)
				ms.addr.lba =
				    azt_msf2hsg(&DiskInfo.lastSession);
			else
				return -EINVAL;
			ms.xa_flag = DiskInfo.xa;
			if (copy_to_user
			    ((void *) arg, &ms,
			     sizeof(struct cdrom_multisession)))
				return -EFAULT;
#ifdef AZT_DEBUG
			if (ms.addr_format == CDROM_MSF)
				printk
				    ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
				     ms.xa_flag, ms.addr.msf.minute,
				     ms.addr.msf.second, ms.addr.msf.frame,
				     DiskInfo.lastSession.min,
				     DiskInfo.lastSession.sec,
				     DiskInfo.lastSession.frame);
			else
				printk
				    ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
				     ms.xa_flag, ms.addr.lba,
				     DiskInfo.lastSession.min,
				     DiskInfo.lastSession.sec,
				     DiskInfo.lastSession.frame);
#endif
			return 0;
		}
	case CDROMPLAYTRKIND:	/* Play a track.  This currently ignores index. */
		if (copy_from_user(&ti, (void *) arg, sizeof ti))
			return -EFAULT;
		if (ti.cdti_trk0 < DiskInfo.first
		    || ti.cdti_trk0 > DiskInfo.last
		    || ti.cdti_trk1 < ti.cdti_trk0) {
			return -EINVAL;
		}
		if (ti.cdti_trk1 > DiskInfo.last)
			ti.cdti_trk1 = DiskInfo.last;
		azt_Play.start = Toc[ti.cdti_trk0].diskTime;
		azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
#ifdef AZT_DEBUG
		printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
		       azt_Play.start.min, azt_Play.start.sec,
		       azt_Play.start.frame, azt_Play.end.min,
		       azt_Play.end.sec, azt_Play.end.frame);
#endif
		i = aztPlay(&azt_Play);
		if (i < 0) {
			aztAudioStatus = CDROM_AUDIO_ERROR;

⌨️ 快捷键说明

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