mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-09 03:28:04 +07: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
@ -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 New Issue
Block a user