📄 aztcd.c
字号:
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 + -