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

📄 aztcd.c

📁 powerpc内核 mpc8241芯片 linux系统下cdrom驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
          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;	}      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  ##########################################################################*/#ifdef AZT_KERNEL_PRIOR_2_1void aztcd_setup(char *str, int *ints)#else__initfunc(void aztcd_setup(char *str, int *ints))#endif{  if (ints[0] > 0)      azt_port = ints[1];   if (ints[0] > 1)      azt_cont = ints[2];}/*  * 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, st;	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		  st = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct cdrom_multisession));		  if (st) return st;		  memcpy_fromfs(&ms, (void*) arg, sizeof(struct cdrom_multisession));		  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;	  	  memcpy_tofs((void*) arg, &ms, sizeof(struct cdrom_multisession));#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,

⌨️ 快捷键说明

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