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

📄 aztcd.c

📁 powerpc内核 mpc8241芯片 linux系统下cdrom驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
			      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 + -