mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	[PATCH] kill cdrom ->dev_ioctl method
Since early 2.4.x all cdrom drivers implement the block_device methods themselves, so they can handle additional ioctls directly instead of going through the cdrom layer. Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Jens Axboe <axboe@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
		
							parent
							
								
									d2c5d4fc07
								
							
						
					
					
						commit
						6a2900b676
					
				
					 10 changed files with 999 additions and 1031 deletions
				
			
		| 
						 | 
					@ -407,7 +407,6 @@ int register_cdrom(struct cdrom_device_info *cdi)
 | 
				
			||||||
	ENSURE(get_mcn, CDC_MCN);
 | 
						ENSURE(get_mcn, CDC_MCN);
 | 
				
			||||||
	ENSURE(reset, CDC_RESET);
 | 
						ENSURE(reset, CDC_RESET);
 | 
				
			||||||
	ENSURE(audio_ioctl, CDC_PLAY_AUDIO);
 | 
						ENSURE(audio_ioctl, CDC_PLAY_AUDIO);
 | 
				
			||||||
	ENSURE(dev_ioctl, CDC_IOCTLS);
 | 
					 | 
				
			||||||
	ENSURE(generic_packet, CDC_GENERIC_PACKET);
 | 
						ENSURE(generic_packet, CDC_GENERIC_PACKET);
 | 
				
			||||||
	cdi->mc_flags = 0;
 | 
						cdi->mc_flags = 0;
 | 
				
			||||||
	cdo->n_minors = 0;
 | 
						cdo->n_minors = 0;
 | 
				
			||||||
| 
						 | 
					@ -2776,12 +2775,6 @@ int cdrom_ioctl(struct file * file, struct cdrom_device_info *cdi,
 | 
				
			||||||
		return cdrom_ioctl_audioctl(cdi, cmd);
 | 
							return cdrom_ioctl_audioctl(cdi, cmd);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Finally, do the device specific ioctls
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (CDROM_CAN(CDC_IOCTLS))
 | 
					 | 
				
			||||||
		return cdi->ops->dev_ioctl(cdi, cmd, arg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return -ENOSYS;
 | 
						return -ENOSYS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2668,7 +2668,7 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi,
 | 
				
			||||||
	return retval;
 | 
						return retval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int scd_dev_ioctl(struct cdrom_device_info *cdi,
 | 
					static int scd_read_audio(struct cdrom_device_info *cdi,
 | 
				
			||||||
			 unsigned int cmd, unsigned long arg)
 | 
								 unsigned int cmd, unsigned long arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	void __user *argp = (void __user *)arg;
 | 
						void __user *argp = (void __user *)arg;
 | 
				
			||||||
| 
						 | 
					@ -2894,11 +2894,10 @@ static struct cdrom_device_ops scd_dops = {
 | 
				
			||||||
	.get_mcn		= scd_get_mcn,
 | 
						.get_mcn		= scd_get_mcn,
 | 
				
			||||||
	.reset			= scd_reset,
 | 
						.reset			= scd_reset,
 | 
				
			||||||
	.audio_ioctl		= scd_audio_ioctl,
 | 
						.audio_ioctl		= scd_audio_ioctl,
 | 
				
			||||||
	.dev_ioctl		= scd_dev_ioctl,
 | 
					 | 
				
			||||||
	.capability		= CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
 | 
						.capability		= CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
 | 
				
			||||||
				  CDC_SELECT_SPEED | CDC_MULTI_SESSION |
 | 
									  CDC_SELECT_SPEED | CDC_MULTI_SESSION |
 | 
				
			||||||
				  CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
 | 
									  CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
 | 
				
			||||||
				  CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS,
 | 
									  CDC_RESET | CDC_DRIVE_STATUS,
 | 
				
			||||||
	.n_minors		= 1,
 | 
						.n_minors		= 1,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2936,6 +2935,9 @@ static int scd_block_ioctl(struct inode *inode, struct file *file,
 | 
				
			||||||
		case CDROMCLOSETRAY:
 | 
							case CDROMCLOSETRAY:
 | 
				
			||||||
			retval = scd_tray_move(&scd_info, 0);
 | 
								retval = scd_tray_move(&scd_info, 0);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case CDROMREADAUDIO:
 | 
				
			||||||
 | 
								retval = scd_read_audio(&scd_info, CDROMREADAUDIO, arg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			retval = cdrom_ioctl(file, &scd_info, inode, cmd, arg);
 | 
								retval = cdrom_ioctl(file, &scd_info, inode, cmd, arg);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1157,32 +1157,6 @@ static int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Ioctl. These ioctls are specific to the cm206 driver. I have made
 | 
					 | 
				
			||||||
   some driver statistics accessible through ioctl calls.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
 | 
					 | 
				
			||||||
		       unsigned long arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	switch (cmd) {
 | 
					 | 
				
			||||||
#ifdef STATISTICS
 | 
					 | 
				
			||||||
	case CM206CTL_GET_STAT:
 | 
					 | 
				
			||||||
		if (arg >= NR_STATS)
 | 
					 | 
				
			||||||
			return -EINVAL;
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			return cd->stats[arg];
 | 
					 | 
				
			||||||
	case CM206CTL_GET_LAST_STAT:
 | 
					 | 
				
			||||||
		if (arg >= NR_STATS)
 | 
					 | 
				
			||||||
			return -EINVAL;
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			return cd->last_stat[arg];
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		debug(("Unknown ioctl call 0x%x\n", cmd));
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
 | 
					static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (cd != NULL) {
 | 
						if (cd != NULL) {
 | 
				
			||||||
| 
						 | 
					@ -1321,11 +1295,10 @@ static struct cdrom_device_ops cm206_dops = {
 | 
				
			||||||
	.get_mcn		= cm206_get_upc,
 | 
						.get_mcn		= cm206_get_upc,
 | 
				
			||||||
	.reset			= cm206_reset,
 | 
						.reset			= cm206_reset,
 | 
				
			||||||
	.audio_ioctl		= cm206_audio_ioctl,
 | 
						.audio_ioctl		= cm206_audio_ioctl,
 | 
				
			||||||
	.dev_ioctl		= cm206_ioctl,
 | 
					 | 
				
			||||||
	.capability		= CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
 | 
						.capability		= CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
 | 
				
			||||||
				  CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
 | 
									  CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
 | 
				
			||||||
				  CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
 | 
									  CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
 | 
				
			||||||
				  CDC_IOCTLS | CDC_DRIVE_STATUS,
 | 
									  CDC_DRIVE_STATUS,
 | 
				
			||||||
	.n_minors		= 1,
 | 
						.n_minors		= 1,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1350,6 +1323,21 @@ static int cm206_block_release(struct inode *inode, struct file *file)
 | 
				
			||||||
static int cm206_block_ioctl(struct inode *inode, struct file *file,
 | 
					static int cm206_block_ioctl(struct inode *inode, struct file *file,
 | 
				
			||||||
				unsigned cmd, unsigned long arg)
 | 
									unsigned cmd, unsigned long arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						switch (cmd) {
 | 
				
			||||||
 | 
					#ifdef STATISTICS
 | 
				
			||||||
 | 
						case CM206CTL_GET_STAT:
 | 
				
			||||||
 | 
							if (arg >= NR_STATS)
 | 
				
			||||||
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
							return cd->stats[arg];
 | 
				
			||||||
 | 
						case CM206CTL_GET_LAST_STAT:
 | 
				
			||||||
 | 
							if (arg >= NR_STATS)
 | 
				
			||||||
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
							return cd->last_stat[arg];
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return cdrom_ioctl(file, &cm206_info, inode, cmd, arg);
 | 
						return cdrom_ioctl(file, &cm206_info, inode, cmd, arg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4160,332 +4160,6 @@ static int sbpcd_get_last_session(struct cdrom_device_info *cdi, struct cdrom_mu
 | 
				
			||||||
	return  0;
 | 
						return  0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*==========================================================================*/
 | 
					 | 
				
			||||||
/*==========================================================================*/
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * ioctl support
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
 | 
					 | 
				
			||||||
		      u_long arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct sbpcd_drive *p = cdi->handle;
 | 
					 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08lX)\n", cdi->name, cmd, arg);
 | 
					 | 
				
			||||||
	if (p->drv_id==-1) {
 | 
					 | 
				
			||||||
		msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);
 | 
					 | 
				
			||||||
		return (-ENXIO);             /* no such drive */
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	down(&ioctl_read_sem);
 | 
					 | 
				
			||||||
	if (p != current_drive)
 | 
					 | 
				
			||||||
		switch_drive(p);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);
 | 
					 | 
				
			||||||
	switch (cmd) 		/* Sun-compatible */
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	case DDIOCSDBG:		/* DDI Debug */
 | 
					 | 
				
			||||||
		if (!capable(CAP_SYS_ADMIN)) RETURN_UP(-EPERM);
 | 
					 | 
				
			||||||
		i=sbpcd_dbg_ioctl(arg,1);
 | 
					 | 
				
			||||||
		RETURN_UP(i);
 | 
					 | 
				
			||||||
	case CDROMRESET:      /* hard reset the drive */
 | 
					 | 
				
			||||||
		msg(DBG_IOC,"ioctl: CDROMRESET entered.\n");
 | 
					 | 
				
			||||||
		i=DriveReset();
 | 
					 | 
				
			||||||
		current_drive->audio_state=0;
 | 
					 | 
				
			||||||
		RETURN_UP(i);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
	case CDROMREADMODE1:
 | 
					 | 
				
			||||||
		msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n");
 | 
					 | 
				
			||||||
#ifdef SAFE_MIXED
 | 
					 | 
				
			||||||
		if (current_drive->has_data>1) RETURN_UP(-EBUSY);
 | 
					 | 
				
			||||||
#endif /* SAFE_MIXED */
 | 
					 | 
				
			||||||
		cc_ModeSelect(CD_FRAMESIZE);
 | 
					 | 
				
			||||||
		cc_ModeSense();
 | 
					 | 
				
			||||||
		current_drive->mode=READ_M1;
 | 
					 | 
				
			||||||
		RETURN_UP(0);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
	case CDROMREADMODE2: /* not usable at the moment */
 | 
					 | 
				
			||||||
		msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n");
 | 
					 | 
				
			||||||
#ifdef SAFE_MIXED
 | 
					 | 
				
			||||||
		if (current_drive->has_data>1) RETURN_UP(-EBUSY);
 | 
					 | 
				
			||||||
#endif /* SAFE_MIXED */
 | 
					 | 
				
			||||||
		cc_ModeSelect(CD_FRAMESIZE_RAW1);
 | 
					 | 
				
			||||||
		cc_ModeSense();
 | 
					 | 
				
			||||||
		current_drive->mode=READ_M2;
 | 
					 | 
				
			||||||
		RETURN_UP(0);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
	case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */
 | 
					 | 
				
			||||||
		msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n");
 | 
					 | 
				
			||||||
		if (current_drive->sbp_audsiz>0)
 | 
					 | 
				
			||||||
			vfree(current_drive->aud_buf);
 | 
					 | 
				
			||||||
		current_drive->aud_buf=NULL;
 | 
					 | 
				
			||||||
		current_drive->sbp_audsiz=arg;
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		if (current_drive->sbp_audsiz>16)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			current_drive->sbp_audsiz = 0;
 | 
					 | 
				
			||||||
			RETURN_UP(current_drive->sbp_audsiz);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
		if (current_drive->sbp_audsiz>0)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			current_drive->aud_buf=(u_char *) vmalloc(current_drive->sbp_audsiz*CD_FRAMESIZE_RAW);
 | 
					 | 
				
			||||||
			if (current_drive->aud_buf==NULL)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				msg(DBG_INF,"audio buffer (%d frames) not available.\n",current_drive->sbp_audsiz);
 | 
					 | 
				
			||||||
				current_drive->sbp_audsiz=0;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else msg(DBG_INF,"audio buffer size: %d frames.\n",current_drive->sbp_audsiz);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		RETURN_UP(current_drive->sbp_audsiz);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case CDROMREADAUDIO:
 | 
					 | 
				
			||||||
	{ /* start of CDROMREADAUDIO */
 | 
					 | 
				
			||||||
		int i=0, j=0, frame, block=0;
 | 
					 | 
				
			||||||
		u_int try=0;
 | 
					 | 
				
			||||||
		u_long timeout;
 | 
					 | 
				
			||||||
		u_char *p;
 | 
					 | 
				
			||||||
		u_int data_tries = 0;
 | 
					 | 
				
			||||||
		u_int data_waits = 0;
 | 
					 | 
				
			||||||
		u_int data_retrying = 0;
 | 
					 | 
				
			||||||
		int status_tries;
 | 
					 | 
				
			||||||
		int error_flag;
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n");
 | 
					 | 
				
			||||||
		if (fam0_drive) RETURN_UP(-EINVAL);
 | 
					 | 
				
			||||||
		if (famL_drive) RETURN_UP(-EINVAL);
 | 
					 | 
				
			||||||
		if (famV_drive) RETURN_UP(-EINVAL);
 | 
					 | 
				
			||||||
		if (famT_drive) RETURN_UP(-EINVAL);
 | 
					 | 
				
			||||||
#ifdef SAFE_MIXED
 | 
					 | 
				
			||||||
		if (current_drive->has_data>1) RETURN_UP(-EBUSY);
 | 
					 | 
				
			||||||
#endif /* SAFE_MIXED */ 
 | 
					 | 
				
			||||||
		if (current_drive->aud_buf==NULL) RETURN_UP(-EINVAL);
 | 
					 | 
				
			||||||
		if (copy_from_user(&read_audio, (void __user *)arg,
 | 
					 | 
				
			||||||
				   sizeof(struct cdrom_read_audio)))
 | 
					 | 
				
			||||||
			RETURN_UP(-EFAULT);
 | 
					 | 
				
			||||||
		if (read_audio.nframes < 0 || read_audio.nframes>current_drive->sbp_audsiz) RETURN_UP(-EINVAL);
 | 
					 | 
				
			||||||
		if (!access_ok(VERIFY_WRITE, read_audio.buf,
 | 
					 | 
				
			||||||
			      read_audio.nframes*CD_FRAMESIZE_RAW))
 | 
					 | 
				
			||||||
                	RETURN_UP(-EFAULT);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */
 | 
					 | 
				
			||||||
			block=msf2lba(&read_audio.addr.msf.minute);
 | 
					 | 
				
			||||||
		else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */
 | 
					 | 
				
			||||||
			block=read_audio.addr.lba;
 | 
					 | 
				
			||||||
		else RETURN_UP(-EINVAL);
 | 
					 | 
				
			||||||
#if 000
 | 
					 | 
				
			||||||
		i=cc_SetSpeed(speed_150,0,0);
 | 
					 | 
				
			||||||
		if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
		msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n",
 | 
					 | 
				
			||||||
		    block, blk2msf(block));
 | 
					 | 
				
			||||||
		msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n");
 | 
					 | 
				
			||||||
#if OLD_BUSY
 | 
					 | 
				
			||||||
		while (busy_data) sbp_sleep(HZ/10); /* wait a bit */
 | 
					 | 
				
			||||||
		busy_audio=1;
 | 
					 | 
				
			||||||
#endif /* OLD_BUSY */ 
 | 
					 | 
				
			||||||
		error_flag=0;
 | 
					 | 
				
			||||||
		for (data_tries=5; data_tries>0; data_tries--)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			msg(DBG_AUD,"data_tries=%d ...\n", data_tries);
 | 
					 | 
				
			||||||
			current_drive->mode=READ_AU;
 | 
					 | 
				
			||||||
			cc_ModeSelect(CD_FRAMESIZE_RAW);
 | 
					 | 
				
			||||||
			cc_ModeSense();
 | 
					 | 
				
			||||||
			for (status_tries=3; status_tries > 0; status_tries--)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				flags_cmd_out |= f_respo3;
 | 
					 | 
				
			||||||
				cc_ReadStatus();
 | 
					 | 
				
			||||||
				if (sbp_status() != 0) break;
 | 
					 | 
				
			||||||
				if (st_check) cc_ReadError();
 | 
					 | 
				
			||||||
				sbp_sleep(1);    /* wait a bit, try again */
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (status_tries == 0)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries in line %d.\n", __LINE__);
 | 
					 | 
				
			||||||
				continue;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			msg(DBG_AUD,"read_audio: sbp_status: ok.\n");
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
			flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
 | 
					 | 
				
			||||||
			if (fam0L_drive)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
 | 
					 | 
				
			||||||
				cmd_type=READ_M2;
 | 
					 | 
				
			||||||
				drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
 | 
					 | 
				
			||||||
				drvcmd[1]=(block>>16)&0x000000ff;
 | 
					 | 
				
			||||||
				drvcmd[2]=(block>>8)&0x000000ff;
 | 
					 | 
				
			||||||
				drvcmd[3]=block&0x000000ff;
 | 
					 | 
				
			||||||
				drvcmd[4]=0;
 | 
					 | 
				
			||||||
				drvcmd[5]=read_audio.nframes; /* # of frames */
 | 
					 | 
				
			||||||
				drvcmd[6]=0;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else if (fam1_drive)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				drvcmd[0]=CMD1_READ; /* "read frames", new drives */
 | 
					 | 
				
			||||||
				lba2msf(block,&drvcmd[1]); /* msf-bin format required */
 | 
					 | 
				
			||||||
				drvcmd[4]=0;
 | 
					 | 
				
			||||||
				drvcmd[5]=0;
 | 
					 | 
				
			||||||
				drvcmd[6]=read_audio.nframes; /* # of frames */
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else if (fam2_drive)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				drvcmd[0]=CMD2_READ_XA2;
 | 
					 | 
				
			||||||
				lba2msf(block,&drvcmd[1]); /* msf-bin format required */
 | 
					 | 
				
			||||||
				drvcmd[4]=0;
 | 
					 | 
				
			||||||
				drvcmd[5]=read_audio.nframes; /* # of frames */
 | 
					 | 
				
			||||||
				drvcmd[6]=0x11; /* raw mode */
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else if (famT_drive) /* CD-55A: not tested yet */
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			msg(DBG_AUD,"read_audio: before giving \"read\" command.\n");
 | 
					 | 
				
			||||||
			flags_cmd_out=f_putcmd;
 | 
					 | 
				
			||||||
			response_count=0;
 | 
					 | 
				
			||||||
			i=cmd_out();
 | 
					 | 
				
			||||||
			if (i<0) msg(DBG_INF,"error giving READ AUDIO command: %0d\n", i);
 | 
					 | 
				
			||||||
			sbp_sleep(0);
 | 
					 | 
				
			||||||
			msg(DBG_AUD,"read_audio: after giving \"read\" command.\n");
 | 
					 | 
				
			||||||
			for (frame=1;frame<2 && !error_flag; frame++)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				try=maxtim_data;
 | 
					 | 
				
			||||||
				for (timeout=jiffies+9*HZ; ; )
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					for ( ; try!=0;try--)
 | 
					 | 
				
			||||||
					{
 | 
					 | 
				
			||||||
						j=inb(CDi_status);
 | 
					 | 
				
			||||||
						if (!(j&s_not_data_ready)) break;
 | 
					 | 
				
			||||||
						if (!(j&s_not_result_ready)) break;
 | 
					 | 
				
			||||||
						if (fam0L_drive) if (j&s_attention) break;
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					if (try != 0 || time_after_eq(jiffies, timeout)) break;
 | 
					 | 
				
			||||||
					if (data_retrying == 0) data_waits++;
 | 
					 | 
				
			||||||
					data_retrying = 1;
 | 
					 | 
				
			||||||
					sbp_sleep(1);
 | 
					 | 
				
			||||||
					try = 1;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if (try==0)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					msg(DBG_INF,"read_audio: sbp_data: CDi_status timeout.\n");
 | 
					 | 
				
			||||||
					error_flag++;
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				msg(DBG_AUD,"read_audio: sbp_data: CDi_status ok.\n");
 | 
					 | 
				
			||||||
				if (j&s_not_data_ready)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					msg(DBG_INF, "read_audio: sbp_data: DATA_READY timeout.\n");
 | 
					 | 
				
			||||||
					error_flag++;
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				msg(DBG_AUD,"read_audio: before reading data.\n");
 | 
					 | 
				
			||||||
				error_flag=0;
 | 
					 | 
				
			||||||
				p = current_drive->aud_buf;
 | 
					 | 
				
			||||||
				if (sbpro_type==1) OUT(CDo_sel_i_d,1);
 | 
					 | 
				
			||||||
				if (do_16bit)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					u_short *p2 = (u_short *) p;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					for (; (u_char *) p2 < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
 | 
					 | 
				
			||||||
				  	{
 | 
					 | 
				
			||||||
						if ((inb_p(CDi_status)&s_not_data_ready)) continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						/* get one sample */
 | 
					 | 
				
			||||||
						*p2++ = inw_p(CDi_data);
 | 
					 | 
				
			||||||
						*p2++ = inw_p(CDi_data);
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					for (; p < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
 | 
					 | 
				
			||||||
				  	{
 | 
					 | 
				
			||||||
						if ((inb_p(CDi_status)&s_not_data_ready)) continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						/* get one sample */
 | 
					 | 
				
			||||||
						*p++ = inb_p(CDi_data);
 | 
					 | 
				
			||||||
						*p++ = inb_p(CDi_data);
 | 
					 | 
				
			||||||
						*p++ = inb_p(CDi_data);
 | 
					 | 
				
			||||||
						*p++ = inb_p(CDi_data);
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if (sbpro_type==1) OUT(CDo_sel_i_d,0);
 | 
					 | 
				
			||||||
				data_retrying = 0;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			msg(DBG_AUD,"read_audio: after reading data.\n");
 | 
					 | 
				
			||||||
			if (error_flag)    /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				msg(DBG_AUD,"read_audio: read aborted by drive\n");
 | 
					 | 
				
			||||||
#if 0000
 | 
					 | 
				
			||||||
				i=cc_DriveReset();                /* ugly fix to prevent a hang */
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
				i=cc_ReadError();
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
				continue;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (fam0L_drive)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				i=maxtim_data;
 | 
					 | 
				
			||||||
				for (timeout=jiffies+9*HZ; time_before(jiffies, timeout); timeout--)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					for ( ;i!=0;i--)
 | 
					 | 
				
			||||||
					{
 | 
					 | 
				
			||||||
						j=inb(CDi_status);
 | 
					 | 
				
			||||||
						if (!(j&s_not_data_ready)) break;
 | 
					 | 
				
			||||||
						if (!(j&s_not_result_ready)) break;
 | 
					 | 
				
			||||||
						if (j&s_attention) break;
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					if (i != 0 || time_after_eq(jiffies, timeout)) break;
 | 
					 | 
				
			||||||
					sbp_sleep(0);
 | 
					 | 
				
			||||||
					i = 1;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if (i==0) msg(DBG_AUD,"read_audio: STATUS TIMEOUT AFTER READ");
 | 
					 | 
				
			||||||
				if (!(j&s_attention))
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					msg(DBG_AUD,"read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n");
 | 
					 | 
				
			||||||
					i=cc_DriveReset();  /* ugly fix to prevent a hang */
 | 
					 | 
				
			||||||
					continue;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			do
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				if (fam0L_drive) cc_ReadStatus();
 | 
					 | 
				
			||||||
				i=ResponseStatus();  /* builds status_bits, returns orig. status (old) or faked p_success (new) */
 | 
					 | 
				
			||||||
				if (i<0) { msg(DBG_AUD,
 | 
					 | 
				
			||||||
					       "read_audio: cc_ReadStatus error after read: %02X\n",
 | 
					 | 
				
			||||||
					       current_drive->status_bits);
 | 
					 | 
				
			||||||
					   continue; /* FIXME */
 | 
					 | 
				
			||||||
				   }
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			while ((fam0L_drive)&&(!st_check)&&(!(i&p_success)));
 | 
					 | 
				
			||||||
			if (st_check)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				i=cc_ReadError();
 | 
					 | 
				
			||||||
				msg(DBG_AUD,"read_audio: cc_ReadError was necessary after read: %02X\n",i);
 | 
					 | 
				
			||||||
				continue;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (copy_to_user(read_audio.buf,
 | 
					 | 
				
			||||||
					 current_drive->aud_buf,
 | 
					 | 
				
			||||||
					 read_audio.nframes * CD_FRAMESIZE_RAW))
 | 
					 | 
				
			||||||
				RETURN_UP(-EFAULT);
 | 
					 | 
				
			||||||
			msg(DBG_AUD,"read_audio: copy_to_user done.\n");
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		cc_ModeSelect(CD_FRAMESIZE);
 | 
					 | 
				
			||||||
		cc_ModeSense();
 | 
					 | 
				
			||||||
		current_drive->mode=READ_M1;
 | 
					 | 
				
			||||||
#if OLD_BUSY
 | 
					 | 
				
			||||||
		busy_audio=0;
 | 
					 | 
				
			||||||
#endif /* OLD_BUSY */ 
 | 
					 | 
				
			||||||
		if (data_tries == 0)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__);
 | 
					 | 
				
			||||||
			RETURN_UP(-EIO);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		msg(DBG_AUD,"read_audio: successful return.\n");
 | 
					 | 
				
			||||||
		RETURN_UP(0);
 | 
					 | 
				
			||||||
	} /* end of CDROMREADAUDIO */
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
 | 
					 | 
				
			||||||
		RETURN_UP(-EINVAL);
 | 
					 | 
				
			||||||
	} /* end switch(cmd) */
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
 | 
					static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
 | 
				
			||||||
		       void * arg)
 | 
							       void * arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -5370,7 +5044,326 @@ static int sbpcd_block_ioctl(struct inode *inode, struct file *file,
 | 
				
			||||||
				unsigned cmd, unsigned long arg)
 | 
									unsigned cmd, unsigned long arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
 | 
						struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
 | 
				
			||||||
	return cdrom_ioctl(file, p->sbpcd_infop, inode, cmd, arg);
 | 
						struct cdrom_device_info *cdi = p->sbpcd_infop;
 | 
				
			||||||
 | 
						int ret, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = cdrom_ioctl(file, p->sbpcd_infop, inode, cmd, arg);
 | 
				
			||||||
 | 
						if (ret != -ENOSYS)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08lX)\n", cdi->name, cmd, arg);
 | 
				
			||||||
 | 
						if (p->drv_id==-1) {
 | 
				
			||||||
 | 
							msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);
 | 
				
			||||||
 | 
							return (-ENXIO);             /* no such drive */
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						down(&ioctl_read_sem);
 | 
				
			||||||
 | 
						if (p != current_drive)
 | 
				
			||||||
 | 
							switch_drive(p);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);
 | 
				
			||||||
 | 
						switch (cmd) 		/* Sun-compatible */
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						case DDIOCSDBG:		/* DDI Debug */
 | 
				
			||||||
 | 
							if (!capable(CAP_SYS_ADMIN)) RETURN_UP(-EPERM);
 | 
				
			||||||
 | 
							i=sbpcd_dbg_ioctl(arg,1);
 | 
				
			||||||
 | 
							RETURN_UP(i);
 | 
				
			||||||
 | 
						case CDROMRESET:      /* hard reset the drive */
 | 
				
			||||||
 | 
							msg(DBG_IOC,"ioctl: CDROMRESET entered.\n");
 | 
				
			||||||
 | 
							i=DriveReset();
 | 
				
			||||||
 | 
							current_drive->audio_state=0;
 | 
				
			||||||
 | 
							RETURN_UP(i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case CDROMREADMODE1:
 | 
				
			||||||
 | 
							msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n");
 | 
				
			||||||
 | 
					#ifdef SAFE_MIXED
 | 
				
			||||||
 | 
							if (current_drive->has_data>1) RETURN_UP(-EBUSY);
 | 
				
			||||||
 | 
					#endif /* SAFE_MIXED */
 | 
				
			||||||
 | 
							cc_ModeSelect(CD_FRAMESIZE);
 | 
				
			||||||
 | 
							cc_ModeSense();
 | 
				
			||||||
 | 
							current_drive->mode=READ_M1;
 | 
				
			||||||
 | 
							RETURN_UP(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case CDROMREADMODE2: /* not usable at the moment */
 | 
				
			||||||
 | 
							msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n");
 | 
				
			||||||
 | 
					#ifdef SAFE_MIXED
 | 
				
			||||||
 | 
							if (current_drive->has_data>1) RETURN_UP(-EBUSY);
 | 
				
			||||||
 | 
					#endif /* SAFE_MIXED */
 | 
				
			||||||
 | 
							cc_ModeSelect(CD_FRAMESIZE_RAW1);
 | 
				
			||||||
 | 
							cc_ModeSense();
 | 
				
			||||||
 | 
							current_drive->mode=READ_M2;
 | 
				
			||||||
 | 
							RETURN_UP(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */
 | 
				
			||||||
 | 
							msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n");
 | 
				
			||||||
 | 
							if (current_drive->sbp_audsiz>0)
 | 
				
			||||||
 | 
								vfree(current_drive->aud_buf);
 | 
				
			||||||
 | 
							current_drive->aud_buf=NULL;
 | 
				
			||||||
 | 
							current_drive->sbp_audsiz=arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (current_drive->sbp_audsiz>16)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								current_drive->sbp_audsiz = 0;
 | 
				
			||||||
 | 
								RETURN_UP(current_drive->sbp_audsiz);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
							if (current_drive->sbp_audsiz>0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								current_drive->aud_buf=(u_char *) vmalloc(current_drive->sbp_audsiz*CD_FRAMESIZE_RAW);
 | 
				
			||||||
 | 
								if (current_drive->aud_buf==NULL)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									msg(DBG_INF,"audio buffer (%d frames) not available.\n",current_drive->sbp_audsiz);
 | 
				
			||||||
 | 
									current_drive->sbp_audsiz=0;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else msg(DBG_INF,"audio buffer size: %d frames.\n",current_drive->sbp_audsiz);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							RETURN_UP(current_drive->sbp_audsiz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case CDROMREADAUDIO:
 | 
				
			||||||
 | 
						{ /* start of CDROMREADAUDIO */
 | 
				
			||||||
 | 
							int i=0, j=0, frame, block=0;
 | 
				
			||||||
 | 
							u_int try=0;
 | 
				
			||||||
 | 
							u_long timeout;
 | 
				
			||||||
 | 
							u_char *p;
 | 
				
			||||||
 | 
							u_int data_tries = 0;
 | 
				
			||||||
 | 
							u_int data_waits = 0;
 | 
				
			||||||
 | 
							u_int data_retrying = 0;
 | 
				
			||||||
 | 
							int status_tries;
 | 
				
			||||||
 | 
							int error_flag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n");
 | 
				
			||||||
 | 
							if (fam0_drive) RETURN_UP(-EINVAL);
 | 
				
			||||||
 | 
							if (famL_drive) RETURN_UP(-EINVAL);
 | 
				
			||||||
 | 
							if (famV_drive) RETURN_UP(-EINVAL);
 | 
				
			||||||
 | 
							if (famT_drive) RETURN_UP(-EINVAL);
 | 
				
			||||||
 | 
					#ifdef SAFE_MIXED
 | 
				
			||||||
 | 
							if (current_drive->has_data>1) RETURN_UP(-EBUSY);
 | 
				
			||||||
 | 
					#endif /* SAFE_MIXED */
 | 
				
			||||||
 | 
							if (current_drive->aud_buf==NULL) RETURN_UP(-EINVAL);
 | 
				
			||||||
 | 
							if (copy_from_user(&read_audio, (void __user *)arg,
 | 
				
			||||||
 | 
									   sizeof(struct cdrom_read_audio)))
 | 
				
			||||||
 | 
								RETURN_UP(-EFAULT);
 | 
				
			||||||
 | 
							if (read_audio.nframes < 0 || read_audio.nframes>current_drive->sbp_audsiz) RETURN_UP(-EINVAL);
 | 
				
			||||||
 | 
							if (!access_ok(VERIFY_WRITE, read_audio.buf,
 | 
				
			||||||
 | 
								      read_audio.nframes*CD_FRAMESIZE_RAW))
 | 
				
			||||||
 | 
					                	RETURN_UP(-EFAULT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */
 | 
				
			||||||
 | 
								block=msf2lba(&read_audio.addr.msf.minute);
 | 
				
			||||||
 | 
							else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */
 | 
				
			||||||
 | 
								block=read_audio.addr.lba;
 | 
				
			||||||
 | 
							else RETURN_UP(-EINVAL);
 | 
				
			||||||
 | 
					#if 000
 | 
				
			||||||
 | 
							i=cc_SetSpeed(speed_150,0,0);
 | 
				
			||||||
 | 
							if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n",
 | 
				
			||||||
 | 
							    block, blk2msf(block));
 | 
				
			||||||
 | 
							msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n");
 | 
				
			||||||
 | 
					#if OLD_BUSY
 | 
				
			||||||
 | 
							while (busy_data) sbp_sleep(HZ/10); /* wait a bit */
 | 
				
			||||||
 | 
							busy_audio=1;
 | 
				
			||||||
 | 
					#endif /* OLD_BUSY */
 | 
				
			||||||
 | 
							error_flag=0;
 | 
				
			||||||
 | 
							for (data_tries=5; data_tries>0; data_tries--)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								msg(DBG_AUD,"data_tries=%d ...\n", data_tries);
 | 
				
			||||||
 | 
								current_drive->mode=READ_AU;
 | 
				
			||||||
 | 
								cc_ModeSelect(CD_FRAMESIZE_RAW);
 | 
				
			||||||
 | 
								cc_ModeSense();
 | 
				
			||||||
 | 
								for (status_tries=3; status_tries > 0; status_tries--)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									flags_cmd_out |= f_respo3;
 | 
				
			||||||
 | 
									cc_ReadStatus();
 | 
				
			||||||
 | 
									if (sbp_status() != 0) break;
 | 
				
			||||||
 | 
									if (st_check) cc_ReadError();
 | 
				
			||||||
 | 
									sbp_sleep(1);    /* wait a bit, try again */
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (status_tries == 0)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries in line %d.\n", __LINE__);
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								msg(DBG_AUD,"read_audio: sbp_status: ok.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
 | 
				
			||||||
 | 
								if (fam0L_drive)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
 | 
				
			||||||
 | 
									cmd_type=READ_M2;
 | 
				
			||||||
 | 
									drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
 | 
				
			||||||
 | 
									drvcmd[1]=(block>>16)&0x000000ff;
 | 
				
			||||||
 | 
									drvcmd[2]=(block>>8)&0x000000ff;
 | 
				
			||||||
 | 
									drvcmd[3]=block&0x000000ff;
 | 
				
			||||||
 | 
									drvcmd[4]=0;
 | 
				
			||||||
 | 
									drvcmd[5]=read_audio.nframes; /* # of frames */
 | 
				
			||||||
 | 
									drvcmd[6]=0;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if (fam1_drive)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									drvcmd[0]=CMD1_READ; /* "read frames", new drives */
 | 
				
			||||||
 | 
									lba2msf(block,&drvcmd[1]); /* msf-bin format required */
 | 
				
			||||||
 | 
									drvcmd[4]=0;
 | 
				
			||||||
 | 
									drvcmd[5]=0;
 | 
				
			||||||
 | 
									drvcmd[6]=read_audio.nframes; /* # of frames */
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if (fam2_drive)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									drvcmd[0]=CMD2_READ_XA2;
 | 
				
			||||||
 | 
									lba2msf(block,&drvcmd[1]); /* msf-bin format required */
 | 
				
			||||||
 | 
									drvcmd[4]=0;
 | 
				
			||||||
 | 
									drvcmd[5]=read_audio.nframes; /* # of frames */
 | 
				
			||||||
 | 
									drvcmd[6]=0x11; /* raw mode */
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if (famT_drive) /* CD-55A: not tested yet */
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								msg(DBG_AUD,"read_audio: before giving \"read\" command.\n");
 | 
				
			||||||
 | 
								flags_cmd_out=f_putcmd;
 | 
				
			||||||
 | 
								response_count=0;
 | 
				
			||||||
 | 
								i=cmd_out();
 | 
				
			||||||
 | 
								if (i<0) msg(DBG_INF,"error giving READ AUDIO command: %0d\n", i);
 | 
				
			||||||
 | 
								sbp_sleep(0);
 | 
				
			||||||
 | 
								msg(DBG_AUD,"read_audio: after giving \"read\" command.\n");
 | 
				
			||||||
 | 
								for (frame=1;frame<2 && !error_flag; frame++)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									try=maxtim_data;
 | 
				
			||||||
 | 
									for (timeout=jiffies+9*HZ; ; )
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										for ( ; try!=0;try--)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											j=inb(CDi_status);
 | 
				
			||||||
 | 
											if (!(j&s_not_data_ready)) break;
 | 
				
			||||||
 | 
											if (!(j&s_not_result_ready)) break;
 | 
				
			||||||
 | 
											if (fam0L_drive) if (j&s_attention) break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (try != 0 || time_after_eq(jiffies, timeout)) break;
 | 
				
			||||||
 | 
										if (data_retrying == 0) data_waits++;
 | 
				
			||||||
 | 
										data_retrying = 1;
 | 
				
			||||||
 | 
										sbp_sleep(1);
 | 
				
			||||||
 | 
										try = 1;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if (try==0)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										msg(DBG_INF,"read_audio: sbp_data: CDi_status timeout.\n");
 | 
				
			||||||
 | 
										error_flag++;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									msg(DBG_AUD,"read_audio: sbp_data: CDi_status ok.\n");
 | 
				
			||||||
 | 
									if (j&s_not_data_ready)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										msg(DBG_INF, "read_audio: sbp_data: DATA_READY timeout.\n");
 | 
				
			||||||
 | 
										error_flag++;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									msg(DBG_AUD,"read_audio: before reading data.\n");
 | 
				
			||||||
 | 
									error_flag=0;
 | 
				
			||||||
 | 
									p = current_drive->aud_buf;
 | 
				
			||||||
 | 
									if (sbpro_type==1) OUT(CDo_sel_i_d,1);
 | 
				
			||||||
 | 
									if (do_16bit)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										u_short *p2 = (u_short *) p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										for (; (u_char *) p2 < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
 | 
				
			||||||
 | 
									  	{
 | 
				
			||||||
 | 
											if ((inb_p(CDi_status)&s_not_data_ready)) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											/* get one sample */
 | 
				
			||||||
 | 
											*p2++ = inw_p(CDi_data);
 | 
				
			||||||
 | 
											*p2++ = inw_p(CDi_data);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										for (; p < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
 | 
				
			||||||
 | 
									  	{
 | 
				
			||||||
 | 
											if ((inb_p(CDi_status)&s_not_data_ready)) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											/* get one sample */
 | 
				
			||||||
 | 
											*p++ = inb_p(CDi_data);
 | 
				
			||||||
 | 
											*p++ = inb_p(CDi_data);
 | 
				
			||||||
 | 
											*p++ = inb_p(CDi_data);
 | 
				
			||||||
 | 
											*p++ = inb_p(CDi_data);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if (sbpro_type==1) OUT(CDo_sel_i_d,0);
 | 
				
			||||||
 | 
									data_retrying = 0;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								msg(DBG_AUD,"read_audio: after reading data.\n");
 | 
				
			||||||
 | 
								if (error_flag)    /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									msg(DBG_AUD,"read_audio: read aborted by drive\n");
 | 
				
			||||||
 | 
					#if 0000
 | 
				
			||||||
 | 
									i=cc_DriveReset();                /* ugly fix to prevent a hang */
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
									i=cc_ReadError();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (fam0L_drive)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									i=maxtim_data;
 | 
				
			||||||
 | 
									for (timeout=jiffies+9*HZ; time_before(jiffies, timeout); timeout--)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										for ( ;i!=0;i--)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											j=inb(CDi_status);
 | 
				
			||||||
 | 
											if (!(j&s_not_data_ready)) break;
 | 
				
			||||||
 | 
											if (!(j&s_not_result_ready)) break;
 | 
				
			||||||
 | 
											if (j&s_attention) break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (i != 0 || time_after_eq(jiffies, timeout)) break;
 | 
				
			||||||
 | 
										sbp_sleep(0);
 | 
				
			||||||
 | 
										i = 1;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if (i==0) msg(DBG_AUD,"read_audio: STATUS TIMEOUT AFTER READ");
 | 
				
			||||||
 | 
									if (!(j&s_attention))
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										msg(DBG_AUD,"read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n");
 | 
				
			||||||
 | 
										i=cc_DriveReset();  /* ugly fix to prevent a hang */
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								do
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (fam0L_drive) cc_ReadStatus();
 | 
				
			||||||
 | 
									i=ResponseStatus();  /* builds status_bits, returns orig. status (old) or faked p_success (new) */
 | 
				
			||||||
 | 
									if (i<0) { msg(DBG_AUD,
 | 
				
			||||||
 | 
										       "read_audio: cc_ReadStatus error after read: %02X\n",
 | 
				
			||||||
 | 
										       current_drive->status_bits);
 | 
				
			||||||
 | 
										   continue; /* FIXME */
 | 
				
			||||||
 | 
									   }
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								while ((fam0L_drive)&&(!st_check)&&(!(i&p_success)));
 | 
				
			||||||
 | 
								if (st_check)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									i=cc_ReadError();
 | 
				
			||||||
 | 
									msg(DBG_AUD,"read_audio: cc_ReadError was necessary after read: %02X\n",i);
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (copy_to_user(read_audio.buf,
 | 
				
			||||||
 | 
										 current_drive->aud_buf,
 | 
				
			||||||
 | 
										 read_audio.nframes * CD_FRAMESIZE_RAW))
 | 
				
			||||||
 | 
									RETURN_UP(-EFAULT);
 | 
				
			||||||
 | 
								msg(DBG_AUD,"read_audio: copy_to_user done.\n");
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							cc_ModeSelect(CD_FRAMESIZE);
 | 
				
			||||||
 | 
							cc_ModeSense();
 | 
				
			||||||
 | 
							current_drive->mode=READ_M1;
 | 
				
			||||||
 | 
					#if OLD_BUSY
 | 
				
			||||||
 | 
							busy_audio=0;
 | 
				
			||||||
 | 
					#endif /* OLD_BUSY */
 | 
				
			||||||
 | 
							if (data_tries == 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__);
 | 
				
			||||||
 | 
								RETURN_UP(-EIO);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							msg(DBG_AUD,"read_audio: successful return.\n");
 | 
				
			||||||
 | 
							RETURN_UP(0);
 | 
				
			||||||
 | 
						} /* end of CDROMREADAUDIO */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
 | 
				
			||||||
 | 
							RETURN_UP(-EINVAL);
 | 
				
			||||||
 | 
						} /* end switch(cmd) */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int sbpcd_block_media_changed(struct gendisk *disk)
 | 
					static int sbpcd_block_media_changed(struct gendisk *disk)
 | 
				
			||||||
| 
						 | 
					@ -5478,10 +5471,9 @@ static struct cdrom_device_ops sbpcd_dops = {
 | 
				
			||||||
	.get_mcn		= sbpcd_get_mcn,
 | 
						.get_mcn		= sbpcd_get_mcn,
 | 
				
			||||||
	.reset			= sbpcd_reset,
 | 
						.reset			= sbpcd_reset,
 | 
				
			||||||
	.audio_ioctl		= sbpcd_audio_ioctl,
 | 
						.audio_ioctl		= sbpcd_audio_ioctl,
 | 
				
			||||||
	.dev_ioctl		= sbpcd_dev_ioctl,
 | 
					 | 
				
			||||||
	.capability		= CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
 | 
						.capability		= CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
 | 
				
			||||||
				CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
 | 
									CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
 | 
				
			||||||
				CDC_MCN | CDC_PLAY_AUDIO | CDC_IOCTLS,
 | 
									CDC_MCN | CDC_PLAY_AUDIO,
 | 
				
			||||||
	.n_minors		= 1,
 | 
						.n_minors		= 1,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -627,7 +627,7 @@ static struct cdrom_device_ops viocd_dops = {
 | 
				
			||||||
	.media_changed = viocd_media_changed,
 | 
						.media_changed = viocd_media_changed,
 | 
				
			||||||
	.lock_door = viocd_lock_door,
 | 
						.lock_door = viocd_lock_door,
 | 
				
			||||||
	.generic_packet = viocd_packet,
 | 
						.generic_packet = viocd_packet,
 | 
				
			||||||
	.capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_RAM
 | 
						.capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_RAM
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init find_capability(const char *type)
 | 
					static int __init find_capability(const char *type)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2470,52 +2470,6 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi,
 | 
				
			||||||
	return cgc->stat;
 | 
						return cgc->stat;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static
 | 
					 | 
				
			||||||
int ide_cdrom_dev_ioctl (struct cdrom_device_info *cdi,
 | 
					 | 
				
			||||||
			 unsigned int cmd, unsigned long arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct packet_command cgc;
 | 
					 | 
				
			||||||
	char buffer[16];
 | 
					 | 
				
			||||||
	int stat;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* These will be moved into the Uniform layer shortly... */
 | 
					 | 
				
			||||||
	switch (cmd) {
 | 
					 | 
				
			||||||
 	case CDROMSETSPINDOWN: {
 | 
					 | 
				
			||||||
 		char spindown;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 		if (copy_from_user(&spindown, (void __user *) arg, sizeof(char)))
 | 
					 | 
				
			||||||
			return -EFAULT;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
                if ((stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0)))
 | 
					 | 
				
			||||||
			return stat;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 		buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 		return cdrom_mode_select(cdi, &cgc);
 | 
					 | 
				
			||||||
 	} 
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 	case CDROMGETSPINDOWN: {
 | 
					 | 
				
			||||||
 		char spindown;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
                if ((stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0)))
 | 
					 | 
				
			||||||
			return stat;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 		spindown = buffer[11] & 0x0f;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
		if (copy_to_user((void __user *) arg, &spindown, sizeof (char)))
 | 
					 | 
				
			||||||
			return -EFAULT;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 		return 0;
 | 
					 | 
				
			||||||
 	}
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static
 | 
					static
 | 
				
			||||||
int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
 | 
					int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
 | 
				
			||||||
			   unsigned int cmd, void *arg)
 | 
								   unsigned int cmd, void *arg)
 | 
				
			||||||
| 
						 | 
					@ -2852,12 +2806,11 @@ static struct cdrom_device_ops ide_cdrom_dops = {
 | 
				
			||||||
	.get_mcn		= ide_cdrom_get_mcn,
 | 
						.get_mcn		= ide_cdrom_get_mcn,
 | 
				
			||||||
	.reset			= ide_cdrom_reset,
 | 
						.reset			= ide_cdrom_reset,
 | 
				
			||||||
	.audio_ioctl		= ide_cdrom_audio_ioctl,
 | 
						.audio_ioctl		= ide_cdrom_audio_ioctl,
 | 
				
			||||||
	.dev_ioctl		= ide_cdrom_dev_ioctl,
 | 
					 | 
				
			||||||
	.capability		= CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
 | 
						.capability		= CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
 | 
				
			||||||
				CDC_SELECT_SPEED | CDC_SELECT_DISC |
 | 
									CDC_SELECT_SPEED | CDC_SELECT_DISC |
 | 
				
			||||||
				CDC_MULTI_SESSION | CDC_MCN |
 | 
									CDC_MULTI_SESSION | CDC_MCN |
 | 
				
			||||||
				CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET |
 | 
									CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET |
 | 
				
			||||||
				CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_CD_R |
 | 
									CDC_DRIVE_STATUS | CDC_CD_R |
 | 
				
			||||||
				CDC_CD_RW | CDC_DVD | CDC_DVD_R| CDC_DVD_RAM |
 | 
									CDC_CD_RW | CDC_DVD | CDC_DVD_R| CDC_DVD_RAM |
 | 
				
			||||||
				CDC_GENERIC_PACKET | CDC_MO_DRIVE | CDC_MRW |
 | 
									CDC_GENERIC_PACKET | CDC_MO_DRIVE | CDC_MRW |
 | 
				
			||||||
				CDC_MRW_W | CDC_RAM,
 | 
									CDC_MRW_W | CDC_RAM,
 | 
				
			||||||
| 
						 | 
					@ -3367,6 +3320,45 @@ static int idecd_release(struct inode * inode, struct file * file)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int idecd_set_spindown(struct cdrom_device_info *cdi, unsigned long arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct packet_command cgc;
 | 
				
			||||||
 | 
						char buffer[16];
 | 
				
			||||||
 | 
						int stat;
 | 
				
			||||||
 | 
						char spindown;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (copy_from_user(&spindown, (void __user *)arg, sizeof(char)))
 | 
				
			||||||
 | 
							return -EFAULT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
 | 
				
			||||||
 | 
						if (stat)
 | 
				
			||||||
 | 
							return stat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
 | 
				
			||||||
 | 
						return cdrom_mode_select(cdi, &cgc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct packet_command cgc;
 | 
				
			||||||
 | 
						char buffer[16];
 | 
				
			||||||
 | 
						int stat;
 | 
				
			||||||
 | 
					 	char spindown;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
 | 
				
			||||||
 | 
						if (stat)
 | 
				
			||||||
 | 
							return stat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spindown = buffer[11] & 0x0f;
 | 
				
			||||||
 | 
						if (copy_to_user((void __user *)arg, &spindown, sizeof (char)))
 | 
				
			||||||
 | 
							return -EFAULT;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int idecd_ioctl (struct inode *inode, struct file *file,
 | 
					static int idecd_ioctl (struct inode *inode, struct file *file,
 | 
				
			||||||
			unsigned int cmd, unsigned long arg)
 | 
								unsigned int cmd, unsigned long arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -3374,6 +3366,15 @@ static int idecd_ioctl (struct inode *inode, struct file *file,
 | 
				
			||||||
	struct cdrom_info *info = ide_cd_g(bdev->bd_disk);
 | 
						struct cdrom_info *info = ide_cd_g(bdev->bd_disk);
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (cmd) {
 | 
				
			||||||
 | 
					 	case CDROMSETSPINDOWN:
 | 
				
			||||||
 | 
							return idecd_set_spindown(&info->devinfo, arg);
 | 
				
			||||||
 | 
					 	case CDROMGETSPINDOWN:
 | 
				
			||||||
 | 
							return idecd_get_spindown(&info->devinfo, arg);
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
 | 
						err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
 | 
				
			||||||
	if (err == -EINVAL)
 | 
						if (err == -EINVAL)
 | 
				
			||||||
		err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg);
 | 
							err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -71,7 +71,7 @@ MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_CDROM_MAJOR);
 | 
				
			||||||
#define SR_CAPABILITIES \
 | 
					#define SR_CAPABILITIES \
 | 
				
			||||||
	(CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \
 | 
						(CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \
 | 
				
			||||||
	 CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \
 | 
						 CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \
 | 
				
			||||||
	 CDC_PLAY_AUDIO|CDC_RESET|CDC_IOCTLS|CDC_DRIVE_STATUS| \
 | 
						 CDC_PLAY_AUDIO|CDC_RESET|CDC_DRIVE_STATUS| \
 | 
				
			||||||
	 CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET| \
 | 
						 CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET| \
 | 
				
			||||||
	 CDC_MRW|CDC_MRW_W|CDC_RAM)
 | 
						 CDC_MRW|CDC_MRW_W|CDC_RAM)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,7 +118,6 @@ static struct cdrom_device_ops sr_dops = {
 | 
				
			||||||
	.get_mcn		= sr_get_mcn,
 | 
						.get_mcn		= sr_get_mcn,
 | 
				
			||||||
	.reset			= sr_reset,
 | 
						.reset			= sr_reset,
 | 
				
			||||||
	.audio_ioctl		= sr_audio_ioctl,
 | 
						.audio_ioctl		= sr_audio_ioctl,
 | 
				
			||||||
	.dev_ioctl		= sr_dev_ioctl,
 | 
					 | 
				
			||||||
	.capability		= SR_CAPABILITIES,
 | 
						.capability		= SR_CAPABILITIES,
 | 
				
			||||||
	.generic_packet		= sr_packet,
 | 
						.generic_packet		= sr_packet,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -456,6 +455,8 @@ static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
 | 
						struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
 | 
				
			||||||
	struct scsi_device *sdev = cd->device;
 | 
						struct scsi_device *sdev = cd->device;
 | 
				
			||||||
 | 
						void __user *argp = (void __user *)arg;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Send SCSI addressing ioctls directly to mid level, send other
 | 
						 * Send SCSI addressing ioctls directly to mid level, send other
 | 
				
			||||||
| 
						 | 
					@ -464,9 +465,23 @@ static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd,
 | 
				
			||||||
	switch (cmd) {
 | 
						switch (cmd) {
 | 
				
			||||||
	case SCSI_IOCTL_GET_IDLUN:
 | 
						case SCSI_IOCTL_GET_IDLUN:
 | 
				
			||||||
	case SCSI_IOCTL_GET_BUS_NUMBER:
 | 
						case SCSI_IOCTL_GET_BUS_NUMBER:
 | 
				
			||||||
                        return scsi_ioctl(sdev, cmd, (void __user *)arg);
 | 
							return scsi_ioctl(sdev, cmd, argp);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return cdrom_ioctl(file, &cd->cdi, inode, cmd, arg);
 | 
					
 | 
				
			||||||
 | 
						ret = cdrom_ioctl(file, &cd->cdi, inode, cmd, arg);
 | 
				
			||||||
 | 
						if (ret != ENOSYS)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * ENODEV means that we didn't recognise the ioctl, or that we
 | 
				
			||||||
 | 
						 * cannot execute it in the current device state.  In either
 | 
				
			||||||
 | 
						 * case fall through to scsi_ioctl, which will return ENDOEV again
 | 
				
			||||||
 | 
						 * if it doesn't recognise the ioctl
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						ret = scsi_nonblockable_ioctl(sdev, cmd, argp, NULL);
 | 
				
			||||||
 | 
						if (ret != -ENODEV)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						return scsi_ioctl(sdev, cmd, argp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int sr_block_media_changed(struct gendisk *disk)
 | 
					static int sr_block_media_changed(struct gendisk *disk)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,7 +55,6 @@ int sr_get_mcn(struct cdrom_device_info *, struct cdrom_mcn *);
 | 
				
			||||||
int sr_reset(struct cdrom_device_info *);
 | 
					int sr_reset(struct cdrom_device_info *);
 | 
				
			||||||
int sr_select_speed(struct cdrom_device_info *cdi, int speed);
 | 
					int sr_select_speed(struct cdrom_device_info *cdi, int speed);
 | 
				
			||||||
int sr_audio_ioctl(struct cdrom_device_info *, unsigned int, void *);
 | 
					int sr_audio_ioctl(struct cdrom_device_info *, unsigned int, void *);
 | 
				
			||||||
int sr_dev_ioctl(struct cdrom_device_info *, unsigned int, unsigned long);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int sr_is_xa(Scsi_CD *);
 | 
					int sr_is_xa(Scsi_CD *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -562,22 +562,3 @@ int sr_is_xa(Scsi_CD *cd)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	return is_xa;
 | 
						return is_xa;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
int sr_dev_ioctl(struct cdrom_device_info *cdi,
 | 
					 | 
				
			||||||
		 unsigned int cmd, unsigned long arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	Scsi_CD *cd = cdi->handle;
 | 
					 | 
				
			||||||
	int ret;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ret = scsi_nonblockable_ioctl(cd->device, cmd,
 | 
					 | 
				
			||||||
				      (void __user *)arg, NULL);
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * ENODEV means that we didn't recognise the ioctl, or that we
 | 
					 | 
				
			||||||
	 * cannot execute it in the current device state.  In either
 | 
					 | 
				
			||||||
	 * case fall through to scsi_ioctl, which will return ENDOEV again
 | 
					 | 
				
			||||||
	 * if it doesn't recognise the ioctl
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (ret != -ENODEV)
 | 
					 | 
				
			||||||
		return ret;
 | 
					 | 
				
			||||||
	return scsi_ioctl(cd->device, cmd, (void __user *)arg);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -378,7 +378,6 @@ struct cdrom_generic_command
 | 
				
			||||||
#define CDC_MEDIA_CHANGED 	0x80    /* media changed */
 | 
					#define CDC_MEDIA_CHANGED 	0x80    /* media changed */
 | 
				
			||||||
#define CDC_PLAY_AUDIO		0x100   /* audio functions */
 | 
					#define CDC_PLAY_AUDIO		0x100   /* audio functions */
 | 
				
			||||||
#define CDC_RESET               0x200   /* hard reset device */
 | 
					#define CDC_RESET               0x200   /* hard reset device */
 | 
				
			||||||
#define CDC_IOCTLS              0x400   /* driver has non-standard ioctls */
 | 
					 | 
				
			||||||
#define CDC_DRIVE_STATUS        0x800   /* driver implements drive status */
 | 
					#define CDC_DRIVE_STATUS        0x800   /* driver implements drive status */
 | 
				
			||||||
#define CDC_GENERIC_PACKET	0x1000	/* driver implements generic packets */
 | 
					#define CDC_GENERIC_PACKET	0x1000	/* driver implements generic packets */
 | 
				
			||||||
#define CDC_CD_R		0x2000	/* drive is a CD-R */
 | 
					#define CDC_CD_R		0x2000	/* drive is a CD-R */
 | 
				
			||||||
| 
						 | 
					@ -974,9 +973,7 @@ struct cdrom_device_ops {
 | 
				
			||||||
	int (*reset) (struct cdrom_device_info *);
 | 
						int (*reset) (struct cdrom_device_info *);
 | 
				
			||||||
	/* play stuff */
 | 
						/* play stuff */
 | 
				
			||||||
	int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *);
 | 
						int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *);
 | 
				
			||||||
	/* dev-specific */
 | 
					
 | 
				
			||||||
 	int (*dev_ioctl) (struct cdrom_device_info *,
 | 
					 | 
				
			||||||
			  unsigned int, unsigned long);
 | 
					 | 
				
			||||||
/* driver specifications */
 | 
					/* driver specifications */
 | 
				
			||||||
	const int capability;   /* capability flags */
 | 
						const int capability;   /* capability flags */
 | 
				
			||||||
	int n_minors;           /* number of active minor devices */
 | 
						int n_minors;           /* number of active minor devices */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue