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

📄 cdrom.c

📁 powerpc内核 mpc8241芯片 linux系统下cdrom驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
		if (!(cdo->capability & ~cdi->mask & CDC_RESET))			return -ENOSYS;		return cdo->reset(cdi);		}	case CDROM_LOCKDOOR: {		cdinfo(CD_DO_IOCTL, "%socking door.\n",arg?"L":"Unl");		if (!(cdo->capability & ~cdi->mask & CDC_LOCK)) {			return -EDRIVE_CANT_DO_THIS;		} else {			keeplocked = arg ? 1 : 0;			return cdo->lock_door(cdi, arg);		}		}	case CDROM_DEBUG: {		if (!capable(CAP_SYS_ADMIN))			return -EACCES;		cdinfo(CD_DO_IOCTL, "%sabling debug.\n",arg?"En":"Dis");		debug = arg ? 1 : 0;		return debug;		}	case CDROM_GET_CAPABILITY: {		cdinfo(CD_DO_IOCTL, "entering CDROM_GET_CAPABILITY\n");		return cdo->capability;		}/* The following function is implemented, although very few audio * discs give Universal Product Code information, which should just be * the Medium Catalog Number on the box.  Note, that the way the code * is written on the CD is /not/ uniform across all discs! */	case CDROM_GET_MCN: {		int ret;		struct cdrom_mcn mcn;		cdinfo(CD_DO_IOCTL, "entering CDROM_GET_MCN\n"); 		if (!(cdo->capability & CDC_MCN))			return -ENOSYS;		if ((ret=cdo->get_mcn(cdi, &mcn)))			return ret;		IOCTL_OUT(arg, struct cdrom_mcn, mcn);		cdinfo(CD_DO_IOCTL, "CDROM_GET_MCN successful\n"); 		return 0;		}	case CDROM_DRIVE_STATUS: {		cdinfo(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUS\n"); 		if (!(cdo->capability & CDC_DRIVE_STATUS))			return -ENOSYS;                if ((arg == CDSL_CURRENT) || (arg == CDSL_NONE)) 			return cdo->drive_status(cdi, arg);                if (((int)arg > cdi->capacity))			return -EINVAL;		return cdo->drive_status(cdi, arg);		}	/* Ok, this is where problems start.  The current interface for the	   CDROM_DISC_STATUS ioctl is flawed.  It makes the false assumption	   that CDs are all CDS_DATA_1 or all CDS_AUDIO, etc.  Unfortunatly,	   while this is often the case, it is also very common for CDs to	   have some tracks with data, and some tracks with audio.  Just 	   because I feel like it, I declare the following to be the best	   way to cope.  If the CD has ANY data tracks on it, it will be	   returned as a data CD.  If it has any XA tracks, I will return	   it as that.  Now I could simplify this interface by combining these 	   returns with the above, but this more clearly demonstrates	   the problem with the current interface.  Too bad this wasn't 	   designed to use bitmasks...         -Erik 	   Well, now we have the option CDS_MIXED: a mixed-type CD. 	   User level programmers might feel the ioctl is not very useful.	   					---david	*/	case CDROM_DISC_STATUS: {		tracktype tracks;		cdinfo(CD_DO_IOCTL, "entering CDROM_DISC_STATUS\n"); 		cdrom_count_tracks(cdi, &tracks);		if (tracks.error) 			return(tracks.error);		/* Policy mode on */		if (tracks.audio > 0) {			if (tracks.data==0 && tracks.cdi==0 && tracks.xa==0) 				return CDS_AUDIO;			else return CDS_MIXED;		}		if (tracks.cdi > 0) return CDS_XA_2_2;		if (tracks.xa > 0) return CDS_XA_2_1;		if (tracks.data > 0) return CDS_DATA_1;		/* Policy mode off */		cdinfo(CD_WARNING,"This disc doesn't have any tracks I recognise!\n");		return CDS_NO_INFO;		}	case CDROM_CHANGER_NSLOTS:		cdinfo(CD_DO_IOCTL, "entering CDROM_CHANGER_NSLOTS\n"); 	return cdi->capacity;/* The following is not implemented, because there are too many * different data types. We could support /1/ raw mode, that is large * enough to hold everything. */#if 0	case CDROMREADMODE1: {		int ret;		struct cdrom_msf msf;		char buf[CD_FRAMESIZE];		cdinfo(CD_DO_IOCTL, "entering CDROMREADMODE1\n"); 		IOCTL_IN(arg, struct cdrom_msf, msf);		if (ret=cdo->read_audio(dev, cmd, &msf, &buf, cdi))			return ret;		IOCTL_OUT(arg, __typeof__(buf), buf);		return 0;		}#endif	} /* switch *//* Now all the audio-ioctls follow, they are all routed through the   same call audio_ioctl(). */#define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret	if (!(cdo->capability & CDC_PLAY_AUDIO))		return -ENOSYS;	else {		switch (cmd) {		case CDROMSUBCHNL: {			int ret;			struct cdrom_subchnl q;			u_char requested, back;			/* comment out the cdinfo calls here because they			   fill up the sys logs when CD players poll the drive*/			/* cdinfo(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/ 			IOCTL_IN(arg, struct cdrom_subchnl, q);			requested = q.cdsc_format;                        if (!((requested == CDROM_MSF) ||                                (requested == CDROM_LBA)))                                        return -EINVAL;			q.cdsc_format = CDROM_MSF;			if ((ret=cdo->audio_ioctl(cdi, cmd, &q)))				return ret;			back = q.cdsc_format; /* local copy */			sanitize_format(&q.cdsc_absaddr, &back, requested);			sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);			IOCTL_OUT(arg, struct cdrom_subchnl, q);			/* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */ 			return 0;			}		case CDROMREADTOCHDR: {			int ret;			struct cdrom_tochdr header;			/* comment out the cdinfo calls here because they			   fill up the sys logs when CD players poll the drive*/			/* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */ 			IOCTL_IN(arg, struct cdrom_tochdr, header);			if ((ret=cdo->audio_ioctl(cdi, cmd, &header)))				return ret;			IOCTL_OUT(arg, struct cdrom_tochdr, header);			/* cdinfo(CD_DO_IOCTL, "CDROMREADTOCHDR successful\n"); */ 			return 0;			}		case CDROMREADTOCENTRY: {			int ret;			struct cdrom_tocentry entry;			u_char requested_format;			/* comment out the cdinfo calls here because they			   fill up the sys logs when CD players poll the drive*/			/* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */ 			IOCTL_IN(arg, struct cdrom_tocentry, entry);			requested_format = entry.cdte_format;			if (!((requested_format == CDROM_MSF) || 				(requested_format == CDROM_LBA)))					return -EINVAL;			/* make interface to low-level uniform */			entry.cdte_format = CDROM_MSF;			if ((ret=cdo->audio_ioctl(cdi, cmd, &entry)))				return ret;			sanitize_format(&entry.cdte_addr,			&entry.cdte_format, requested_format);			IOCTL_OUT(arg, struct cdrom_tocentry, entry);			/* cdinfo(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */ 			return 0;			}		case CDROMPLAYMSF: {			int ret;			struct cdrom_msf msf;			cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSF\n"); 			IOCTL_IN(arg, struct cdrom_msf, msf);			CHECKAUDIO;			return cdo->audio_ioctl(cdi, cmd, &msf);			}		case CDROMPLAYTRKIND: {			int ret;			struct cdrom_ti ti;			cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n"); 			IOCTL_IN(arg, struct cdrom_ti, ti);			CHECKAUDIO;			return cdo->audio_ioctl(cdi, cmd, &ti);			}		case CDROMVOLCTRL: {			struct cdrom_volctrl volume;			cdinfo(CD_DO_IOCTL, "entering CDROMVOLCTRL\n"); 			IOCTL_IN(arg, struct cdrom_volctrl, volume);			return cdo->audio_ioctl(cdi, cmd, &volume);			}		case CDROMVOLREAD: {			int ret;			struct cdrom_volctrl volume;			cdinfo(CD_DO_IOCTL, "entering CDROMVOLREAD\n"); 			if ((ret=cdo->audio_ioctl(cdi, cmd, &volume)))				return ret;			IOCTL_OUT(arg, struct cdrom_volctrl, volume);			return 0;			}		case CDROMSTART:		case CDROMSTOP:		case CDROMPAUSE:		case CDROMRESUME: {			int ret;			cdinfo(CD_DO_IOCTL, "doing audio ioctl (start/stop/pause/resume)\n"); 			CHECKAUDIO;			return cdo->audio_ioctl(cdi, cmd, NULL);			}		} /* switch */	}	/* device specific ioctls? */	if (!(cdo->capability & CDC_IOCTLS))		return -ENOSYS;	else 		return cdo->dev_ioctl(cdi, cmd, arg);}EXPORT_SYMBOL(cdrom_count_tracks);EXPORT_SYMBOL(register_cdrom);EXPORT_SYMBOL(unregister_cdrom);EXPORT_SYMBOL(cdrom_fops);#ifdef CONFIG_SYSCTL#define CDROM_STR_SIZE 1000static char cdrom_drive_info[CDROM_STR_SIZE]="info\n";int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp,                           void *buffer, size_t *lenp){        int pos;	struct cdrom_device_info *cdi;		if (!*lenp || (filp->f_pos && !write)) {		*lenp = 0;		return 0;	}	pos = sprintf(cdrom_drive_info, "CD-ROM information, " VERSION "\n");		pos += sprintf(cdrom_drive_info+pos, "\ndrive name:\t");	for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)	    pos += sprintf(cdrom_drive_info+pos, "\t%s", cdi->name);	pos += sprintf(cdrom_drive_info+pos, "\ndrive speed:\t");	for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)	    pos += sprintf(cdrom_drive_info+pos, "\t%d", cdi->speed);	pos += sprintf(cdrom_drive_info+pos, "\ndrive # of slots:");	for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)	    pos += sprintf(cdrom_drive_info+pos, "\t%d", cdi->capacity);	pos += sprintf(cdrom_drive_info+pos, "\nCan close tray:\t");	for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)	    pos += sprintf(cdrom_drive_info+pos, "\t%d",			   ((cdi->ops->capability & CDC_CLOSE_TRAY)!=0));	pos += sprintf(cdrom_drive_info+pos, "\nCan open tray:\t");	for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)	    pos += sprintf(cdrom_drive_info+pos, "\t%d",			   ((cdi->ops->capability & CDC_OPEN_TRAY)!=0));	pos += sprintf(cdrom_drive_info+pos, "\nCan lock tray:\t");	for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)	    pos += sprintf(cdrom_drive_info+pos, "\t%d",			   ((cdi->ops->capability & CDC_LOCK)!=0));	pos += sprintf(cdrom_drive_info+pos, "\nCan change speed:");	for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)	    pos += sprintf(cdrom_drive_info+pos, "\t%d",			   ((cdi->ops->capability & CDC_SELECT_SPEED)!=0));	pos += sprintf(cdrom_drive_info+pos, "\nCan select disk:");	for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)	    pos += sprintf(cdrom_drive_info+pos, "\t%d",			   ((cdi->ops->capability & CDC_SELECT_DISC)!=0));	pos += sprintf(cdrom_drive_info+pos, "\nCan read multisession:");	for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)	    pos += sprintf(cdrom_drive_info+pos, "\t%d",			   ((cdi->ops->capability & CDC_MULTI_SESSION)!=0));	pos += sprintf(cdrom_drive_info+pos, "\nCan read MCN:\t");	for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)	    pos += sprintf(cdrom_drive_info+pos, "\t%d",			   ((cdi->ops->capability & CDC_MCN)!=0));	pos += sprintf(cdrom_drive_info+pos, "\nReports media changed:");	for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)	    pos += sprintf(cdrom_drive_info+pos, "\t%d",			   ((cdi->ops->capability & CDC_MEDIA_CHANGED)!=0));	pos += sprintf(cdrom_drive_info+pos, "\nCan play audio:\t");	for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)	    pos += sprintf(cdrom_drive_info+pos, "\t%d",			   ((cdi->ops->capability & CDC_PLAY_AUDIO)!=0));        strcpy(cdrom_drive_info+pos,"\n\n");	*lenp=pos+3;        return proc_dostring(ctl, write, filp, buffer, lenp);}/* Place files in /proc/sys/dev/cdrom */ctl_table cdrom_table[] = {	{DEV_CDROM_INFO, "info", &cdrom_drive_info, 		CDROM_STR_SIZE, 0444, NULL, &cdrom_sysctl_info},	{0}	};ctl_table cdrom_cdrom_table[] = {	{DEV_CDROM, "cdrom", NULL, 0, 0555, cdrom_table},	{0}	};/* Make sure that /proc/sys/dev is there */ctl_table cdrom_root_table[] = {	{CTL_DEV, "dev", NULL, 0, 0555, cdrom_cdrom_table},	{0}	};static struct ctl_table_header *cdrom_sysctl_header;/* * This is called as the fill_inode function when an inode * is going into (fill = 1) or out of service (fill = 0). * We use it here to manage the module use counts. * * Note: only the top-level directory needs to do this; if * a lower level is referenced, the parent will be as well. */static void cdrom_procfs_modcount(struct inode *inode, int fill){	if (fill) {		MOD_INC_USE_COUNT;	} else {		MOD_DEC_USE_COUNT;	}}static void cdrom_sysctl_register(void){	static int initialized = 0;	if (initialized == 1)		return;	cdrom_sysctl_header = register_sysctl_table(cdrom_root_table, 1);	cdrom_root_table->child->de->fill_inode = &cdrom_procfs_modcount;	initialized = 1;}#ifdef MODULEstatic void cdrom_sysctl_unregister(void){	unregister_sysctl_table(cdrom_sysctl_header);}#endif /* endif MODULE */#endif /* endif CONFIG_SYSCTL */#ifdef MODULEint init_module(void){#ifdef CONFIG_SYSCTL	cdrom_sysctl_register();#endif /* CONFIG_SYSCTL */ 	return 0;}void cleanup_module(void){	printk(KERN_INFO "Uniform CD-ROM driver unloaded\n");#ifdef CONFIG_SYSCTL	cdrom_sysctl_unregister();#endif /* CONFIG_SYSCTL */ }#endif /* endif MODULE *//* * Local variables: * comment-column: 40 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -m486 -DCPU=486 -DMODULE -DMODVERSIONS -include /usr/src/linux/include/linux/modversions.h  -c -o cdrom.o cdrom.c" * End: */

⌨️ 快捷键说明

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