📄 aztcd.c
字号:
DiskInfo.lastSession.sec, DiskInfo.lastSession.frame);#endif return 0; } case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */ st = verify_area(VERIFY_READ, (void *) arg, sizeof ti); if (st) return st; memcpy_fromfs(&ti, (void *) arg, sizeof ti); 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_DEBUGprintk("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; }*/ st = verify_area(VERIFY_READ, (void *) arg, sizeof msf); if (st) return st; memcpy_fromfs(&msf, (void *) arg, sizeof msf); /* 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_DEBUGprintk("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 */ st = verify_area(VERIFY_WRITE, (void *) arg, sizeof tocHdr); if (st) return st; tocHdr.cdth_trk0 = DiskInfo.first; tocHdr.cdth_trk1 = DiskInfo.last; memcpy_tofs((void *) arg, &tocHdr, sizeof tocHdr); break; case CDROMREADTOCENTRY: /* Read an entry in the table of contents */ st = verify_area(VERIFY_WRITE, (void *) arg, sizeof entry); if (st) return st; memcpy_fromfs(&entry, (void *) arg, sizeof entry); 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 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; } memcpy_tofs((void *) arg, &entry, sizeof entry); break; case CDROMSUBCHNL: /* Get subchannel info */ st = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cdrom_subchnl)); if (st) { #ifdef AZT_DEBUG printk("aztcd: exiting aztcd_ioctl - Error 1 - Command:%x\n",cmd);#endif return st; } memcpy_fromfs(&subchnl, (void *) arg, sizeof (struct cdrom_subchnl)); if (aztGetQChannelInfo(&qInfo) < 0) if (st) { #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); } memcpy_tofs((void *) arg, &subchnl, sizeof (struct cdrom_subchnl)); 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 */ st=verify_area(VERIFY_READ,(void *) arg, sizeof(volctrl)); if (st) return (st); memcpy_fromfs(&volctrl,(char *) arg,sizeof(volctrl)); 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)*/ { st = verify_area(VERIFY_WRITE, (void *) arg, sizeof buf); if (st) return st; memcpy_fromfs(&msf, (void *) arg, sizeof msf); /* 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); memcpy_tofs((void *) arg, &buf, CD_FRAMESIZE_RAW); } } else /*CDROMREADCOOKED*/ { if (sendAztCmd(ACMD_PLAY_READ, &azt_Play)) return -1; DTEN_LOW; insb(DATA_PORT,buf,CD_FRAMESIZE); memcpy_tofs((void *) arg, &buf, CD_FRAMESIZE); } } break; case CDROMSEEK: /*seek msf address*/ st = verify_area(VERIFY_READ, (void *) arg, sizeof msf); if (st) return st; memcpy_fromfs(&msf, (void *) arg, sizeof msf); /* 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(void){#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) return -EIO; /* 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()) return -EIO; } ++azt_open_count; MOD_INC_USE_COUNT; aztLockDoor();#ifdef AZT_DEBUG printk("aztcd: exiting aztcd_open\n");#endif return 0;}/* * On close, we flush all azt blocks from the buffer cache. */#ifdef AZT_KERNEL_PRIOR_2_1static void aztcd_release(struct inode * inode, struct file * file)#elsestatic int aztcd_release(struct inode * inode, struct file * file)#endif{ #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 MOD_DEC_USE_COUNT; if (!--azt_open_count) { azt_invalidate_buffers(); sync_dev(inode->i_rdev); /*??? isn't it a read only dev?*/ invalidate_buffers(inode -> i_rdev); aztUnlockDoor(); if (azt_auto_eject)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -