📄 aztcd.c
字号:
} 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 MODULEstatic 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; return -EIO; } aztAudioStatus = CDROM_AUDIO_PLAY; break; case CDROMPLAYMSF: /* Play starting at the given MSF address. *//* if (aztAudioStatus == CDROM_AUDIO_PLAY) { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1); STEN_LOW; aztAudioStatus = CDROM_AUDIO_NO_STATUS; }*/ 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_bin2bcd(&msf.cdmsf_min1); azt_bin2bcd(&msf.cdmsf_sec1); azt_bin2bcd(&msf.cdmsf_frame1); 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;#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; return -EIO; } aztAudioStatus = CDROM_AUDIO_PLAY; break; case CDROMREADTOCHDR: /* Read the table of contents header */ tocHdr.cdth_trk0 = DiskInfo.first; tocHdr.cdth_trk1 = DiskInfo.last; if (copy_to_user((void *) arg, &tocHdr, sizeof tocHdr)) return -EFAULT; break; case CDROMREADTOCENTRY: /* Read an entry in the table of contents */ if (copy_from_user(&entry, (void *) arg, sizeof entry)) return -EFAULT; if ((!aztTocUpToDate) || aztDiskChanged) aztUpdateToc(); if (entry.cdte_track == CDROM_LEADOUT) tocPtr = &Toc[DiskInfo.last + 1]; else if (entry.cdte_track > DiskInfo.last || entry.cdte_track < DiskInfo.first) { return -EINVAL; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -