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

📄 aztcd.c

📁 powerpc内核 mpc8241芯片 linux系统下cdrom驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
  ##########################################################################*//* Macros for the drive hardware interface handshake, these macros use   busy waiting *//* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/# define OP_OK op_ok()void op_ok(void){ aztTimeOutCount=0;   do { aztIndatum=inb(DATA_PORT);       aztTimeOutCount++;       if (aztTimeOutCount>=AZT_TIMEOUT)	{ printk("aztcd: Error Wait OP_OK\n");	  break;	}     } while (aztIndatum!=AFL_OP_OK);}/* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/# define PA_OK pa_ok()void pa_ok(void){ aztTimeOutCount=0;   do { aztIndatum=inb(DATA_PORT);       aztTimeOutCount++;       if (aztTimeOutCount>=AZT_TIMEOUT)	{ printk("aztcd: Error Wait PA_OK\n");	  break;	}     } while (aztIndatum!=AFL_PA_OK);}     /* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/# define STEN_LOW  sten_low()void sten_low(void){ aztTimeOutCount=0;   do { aztIndatum=inb(STATUS_PORT);       aztTimeOutCount++;       if (aztTimeOutCount>=AZT_TIMEOUT)	{ if (azt_init_end) printk("aztcd: Error Wait STEN_LOW commands:%x\n",aztCmd);	  break;	}     } while (aztIndatum&AFL_STATUS);}/* Wait for DTEN=Low = handshake signal 'Data available'*/# define DTEN_LOW dten_low()void dten_low(void){ aztTimeOutCount=0;   do { aztIndatum=inb(STATUS_PORT);       aztTimeOutCount++;       if (aztTimeOutCount>=AZT_TIMEOUT)	{ printk("aztcd: Error Wait DTEN_OK\n");	  break;	}     } while (aztIndatum&AFL_DATA);}/*  * Macro for timer wait on STEN=Low, should only be used for 'slow' commands; * may cause kernel panic when used in the wrong place*/#define STEN_LOW_WAIT   statusAzt()void statusAzt(void){ AztTimeout = AZT_STATUS_DELAY;  SET_TIMER(aztStatTimer, HZ/100);   sleep_on(&azt_waitq);  if (AztTimeout <= 0) printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",aztCmd);  return;}static void aztStatTimer(void){ if (!(inb(STATUS_PORT) & AFL_STATUS))     { wake_up(&azt_waitq);       return;     }  AztTimeout--;  if (AztTimeout <= 0)     { wake_up(&azt_waitq);       printk("aztcd: Error aztStatTimer: Timeout\n");       return;     }  SET_TIMER(aztStatTimer, HZ/100);}/*##########################################################################  CDROM Drive Command Functions  ##########################################################################*//*  * Send a single command, return -1 on error, else 0*/static int aztSendCmd(int cmd){  unsigned char data;   int retry;#ifdef AZT_DEBUG   printk("aztcd: Executing command %x\n",cmd);#endif   if ((azt_port==0x1f0)||(azt_port==0x170))        SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration*/      aztCmd=cmd;   outb(POLLED,MODE_PORT);   do { if (inb(STATUS_PORT)&AFL_STATUS) break;	inb(DATA_PORT);    /* if status left from last command, read and */      } while (1);         /* discard it */   do { if (inb(STATUS_PORT)&AFL_DATA) break;	inb(DATA_PORT);    /* if data left from last command, read and */      } while (1);         /* discard it */   for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)     { outb((unsigned char) cmd,CMD_PORT);       STEN_LOW;       data=inb(DATA_PORT);       if (data==AFL_OP_OK)	 { return 0;}           /*OP_OK?*/       if (data==AFL_OP_ERR)	 { STEN_LOW;	   data=inb(DATA_PORT);	   printk("### Error 1 aztcd: aztSendCmd %x  Error Code %x\n",cmd,data);	 }     }   if (retry>=AZT_RETRY_ATTEMPTS)     { printk("### Error 2 aztcd: aztSendCmd %x \n",cmd);       azt_error=0xA5;     }   RETURNM("aztSendCmd",-1);}/* * Send a play or read command to the drive, return -1 on error, else 0*/static int sendAztCmd(int cmd, struct azt_Play_msf *params){  unsigned char data;   int retry;#ifdef AZT_DEBUG   printk("aztcd: play start=%02x:%02x:%02x  end=%02x:%02x:%02x\n", \	   params->start.min, params->start.sec, params->start.frame, \	   params->end.min,   params->end.sec,   params->end.frame);#endif      for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)     { aztSendCmd(cmd);       outb(params -> start.min,CMD_PORT);       outb(params -> start.sec,CMD_PORT);       outb(params -> start.frame,CMD_PORT);       outb(params -> end.min,CMD_PORT);       outb(params -> end.sec,CMD_PORT);       outb(params -> end.frame,CMD_PORT);       STEN_LOW;       data=inb(DATA_PORT);       if (data==AFL_PA_OK)	 { return 0;}           /*PA_OK ?*/       if (data==AFL_PA_ERR)	 { STEN_LOW;	   data=inb(DATA_PORT);	   printk("### Error 1 aztcd: sendAztCmd %x  Error Code %x\n",cmd,data);	 }     }   if (retry>=AZT_RETRY_ATTEMPTS)     { printk("### Error 2 aztcd: sendAztCmd %x\n ",cmd);       azt_error=0xA5;     }   RETURNM("sendAztCmd",-1);}/* * Send a seek command to the drive, return -1 on error, else 0*/static int aztSeek(struct azt_Play_msf *params){  unsigned char data;   int retry;#ifdef AZT_DEBUG   printk("aztcd: aztSeek %02x:%02x:%02x\n", \	   params->start.min, params->start.sec, params->start.frame);#endif      for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)     { aztSendCmd(ACMD_SEEK);       outb(params -> start.min,CMD_PORT);       outb(params -> start.sec,CMD_PORT);       outb(params -> start.frame,CMD_PORT);       STEN_LOW;       data=inb(DATA_PORT);       if (data==AFL_PA_OK)	 { return 0;}           /*PA_OK ?*/       if (data==AFL_PA_ERR)	 { STEN_LOW;	   data=inb(DATA_PORT);	   printk("### Error 1 aztcd: aztSeek\n");	 }     }   if (retry>=AZT_RETRY_ATTEMPTS)     { printk("### Error 2 aztcd: aztSeek\n ");       azt_error=0xA5;     }   RETURNM("aztSeek",-1);}/* Send a Set Disk Type command   does not seem to work with Aztech drives, behavior is completely indepen-   dent on which mode is set ???*/static int aztSetDiskType(int type){  unsigned char data;   int retry;#ifdef AZT_DEBUG   printk("aztcd: set disk type command: type= %i\n",type);#endif   for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)     { aztSendCmd(ACMD_SET_DISK_TYPE);       outb(type,CMD_PORT);       STEN_LOW;       data=inb(DATA_PORT);       if (data==AFL_PA_OK)     /*PA_OK ?*/	 { azt_read_mode=type;	   return 0;            	 }         if (data==AFL_PA_ERR)	 { STEN_LOW;	   data=inb(DATA_PORT);	   printk("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",type,data);	 }     }   if (retry>=AZT_RETRY_ATTEMPTS)     { printk("### Error 2 aztcd: aztSetDiskType %x\n ",type);       azt_error=0xA5;     }   RETURNM("aztSetDiskType",-1);}/* used in azt_poll to poll the status, expects another program to issue a  * ACMD_GET_STATUS directly before  */static int aztStatus(void)  {       int st;/*	int i;	i = inb(STATUS_PORT) & AFL_STATUS;    is STEN=0?    ???	if (!i)*/      STEN_LOW;        if (aztTimeOutCount<AZT_TIMEOUT)		{   	st = inb(DATA_PORT) & 0xFF;		return st;	}	else		RETURNM("aztStatus",-1);}/* * Get the drive status */static int getAztStatus(void){       int st;	if (aztSendCmd(ACMD_GET_STATUS)) RETURNM("getAztStatus 1",-1);	STEN_LOW;	st = inb(DATA_PORT) & 0xFF;#ifdef AZT_DEBUG	printk("aztcd: Status = %x\n",st);#endif	if ((st == 0xFF)||(st&AST_CMD_CHECK))	 { printk("aztcd: AST_CMD_CHECK error or no status available\n");	   return -1;	 }	if (((st&AST_MODE_BITS)!=AST_BUSY) && (aztAudioStatus == CDROM_AUDIO_PLAY))	   /* XXX might be an error? look at q-channel? */	   aztAudioStatus = CDROM_AUDIO_COMPLETED;	if ((st & AST_DSK_CHG)||(st & AST_NOT_READY))	 { aztDiskChanged = 1;	   aztTocUpToDate = 0;	   aztAudioStatus = CDROM_AUDIO_NO_STATUS;	 }	return st;}/* * Send a 'Play' command and get the status.  Use only from the top half. */static int aztPlay(struct azt_Play_msf *arg){       if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0) RETURNM("aztPlay",-1);	return 0;}/* * Subroutines to automatically close the door (tray) and  * lock it closed when the cd is mounted.  Leave the tray * locking as an option */static void aztCloseDoor(void){  aztSendCmd(ACMD_CLOSE);  STEN_LOW;  return;}static void aztLockDoor(void){#if AZT_ALLOW_TRAY_LOCK  aztSendCmd(ACMD_LOCK);  STEN_LOW;#endif  return;}static void aztUnlockDoor(void){#if AZT_ALLOW_TRAY_LOCK  aztSendCmd(ACMD_UNLOCK);  STEN_LOW;#endif  return;}/* * Read a value from the drive.  Should return quickly, so a busy wait * is used to avoid excessive rescheduling. The read command itself must * be issued with aztSendCmd() directly before */static int aztGetValue(unsigned char *result){       int s;	STEN_LOW;	if (aztTimeOutCount>=AZT_TIMEOUT)	{       printk("aztcd: aztGetValue timeout\n");		return -1;	}	s = inb(DATA_PORT) & 0xFF;	*result = (unsigned char) s;	return 0;}/* * Read the current Q-channel info.  Also used for reading the * table of contents. */int aztGetQChannelInfo(struct azt_Toc *qp){       unsigned char notUsed;	int st;#ifdef AZT_DEBUG	printk("aztcd: starting aztGetQChannelInfo  Time:%li\n",jiffies);#endif	if ((st=getAztStatus())==-1)        RETURNM("aztGetQChannelInfo 1",-1);	if (aztSendCmd(ACMD_GET_Q_CHANNEL)) RETURNM("aztGetQChannelInfo 2",-1);	/*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here*/	if (aztGetValue(&notUsed)) RETURNM("aztGetQChannelInfo 3",-1); /*??? Nullbyte einlesen*/	if ((st&AST_MODE_BITS)==AST_INITIAL)	 { qp->ctrl_addr=0;      /* when audio stop ACMD_GET_Q_CHANNEL returns */	   qp->track=0;          /* only one byte with Aztech drives */	   qp->pointIndex=0;	   qp->trackTime.min=0;	   qp->trackTime.sec=0;	   qp->trackTime.frame=0;	   qp->diskTime.min=0;	   qp->diskTime.sec=0;	   qp->diskTime.frame=0;	   return 0;  	 }	else	 { if (aztGetValue(&qp -> ctrl_addr) < 0)       RETURNM("aztGetQChannelInfo 4",-1);	   if (aztGetValue(&qp -> track) < 0)           RETURNM("aztGetQChannelInfo 4",-1);	   if (aztGetValue(&qp -> pointIndex) < 0)      RETURNM("aztGetQChannelInfo 4",-1);	   if (aztGetValue(&qp -> trackTime.min) < 0)   RETURNM("aztGetQChannelInfo 4",-1);	   if (aztGetValue(&qp -> trackTime.sec) < 0)   RETURNM("aztGetQChannelInfo 4",-1);	   if (aztGetValue(&qp -> trackTime.frame) < 0) RETURNM("aztGetQChannelInfo 4",-1);	   if (aztGetValue(&notUsed) < 0)               RETURNM("aztGetQChannelInfo 4",-1);	   if (aztGetValue(&qp -> diskTime.min) < 0)    RETURNM("aztGetQChannelInfo 4",-1);	   if (aztGetValue(&qp -> diskTime.sec) < 0)    RETURNM("aztGetQChannelInfo 4",-1);	   if (aztGetValue(&qp -> diskTime.frame) < 0)  RETURNM("aztGetQChannelInfo 4",-1);	 }#ifdef AZT_DEBUG	printk("aztcd: exiting aztGetQChannelInfo  Time:%li\n",jiffies);#endif	return 0;}/* * Read the table of contents (TOC) and TOC header if necessary */static int aztUpdateToc(){       int st;#ifdef AZT_DEBUG	printk("aztcd: starting aztUpdateToc  Time:%li\n",jiffies);#endif  	if (aztTocUpToDate)		return 0;	if (aztGetDiskInfo() < 0)		return -EIO;	if (aztGetToc(0) < 0)		return -EIO;        /*audio disk detection

⌨️ 快捷键说明

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