[PATCH] kill cdrom ->dev_ioctl method
Christoph Hellwig [Thu, 23 Mar 2006 11:00:15 +0000 (03:00 -0800)]
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>

drivers/cdrom/cdrom.c
drivers/cdrom/cdu31a.c
drivers/cdrom/cm206.c
drivers/cdrom/sbpcd.c
drivers/cdrom/viocd.c
drivers/ide/ide-cd.c
drivers/scsi/sr.c
drivers/scsi/sr.h
drivers/scsi/sr_ioctl.c
include/linux/cdrom.h

index d6653fc..a59876a 100644 (file)
@@ -407,7 +407,6 @@ int register_cdrom(struct cdrom_device_info *cdi)
        ENSURE(get_mcn, CDC_MCN);
        ENSURE(reset, CDC_RESET);
        ENSURE(audio_ioctl, CDC_PLAY_AUDIO);
-       ENSURE(dev_ioctl, CDC_IOCTLS);
        ENSURE(generic_packet, CDC_GENERIC_PACKET);
        cdi->mc_flags = 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);
        }
 
-       /*
-        * Finally, do the device specific ioctls
-        */
-       if (CDROM_CAN(CDC_IOCTLS))
-               return cdi->ops->dev_ioctl(cdi, cmd, arg);
-
        return -ENOSYS;
 }
 
index 378e88d..72ffd64 100644 (file)
@@ -2668,7 +2668,7 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi,
        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)
 {
        void __user *argp = (void __user *)arg;
@@ -2894,11 +2894,10 @@ static struct cdrom_device_ops scd_dops = {
        .get_mcn                = scd_get_mcn,
        .reset                  = scd_reset,
        .audio_ioctl            = scd_audio_ioctl,
-       .dev_ioctl              = scd_dev_ioctl,
        .capability             = CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
                                  CDC_SELECT_SPEED | CDC_MULTI_SESSION |
                                  CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
-                                 CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS,
+                                 CDC_RESET | CDC_DRIVE_STATUS,
        .n_minors               = 1,
 };
 
@@ -2936,6 +2935,9 @@ static int scd_block_ioctl(struct inode *inode, struct file *file,
                case CDROMCLOSETRAY:
                        retval = scd_tray_move(&scd_info, 0);
                        break;
+               case CDROMREADAUDIO:
+                       retval = scd_read_audio(&scd_info, CDROMREADAUDIO, arg);
+                       break;
                default:
                        retval = cdrom_ioctl(file, &scd_info, inode, cmd, arg);
        }
index ce127f7..fad27a8 100644 (file)
@@ -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)
 {
        if (cd != NULL) {
@@ -1321,11 +1295,10 @@ static struct cdrom_device_ops cm206_dops = {
        .get_mcn                = cm206_get_upc,
        .reset                  = cm206_reset,
        .audio_ioctl            = cm206_audio_ioctl,
-       .dev_ioctl              = cm206_ioctl,
        .capability             = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
                                  CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
                                  CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
-                                 CDC_IOCTLS | CDC_DRIVE_STATUS,
+                                 CDC_DRIVE_STATUS,
        .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,
                                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);
 }
 
index 466e9c2..4760f51 100644 (file)
@@ -4160,332 +4160,6 @@ static int sbpcd_get_last_session(struct cdrom_device_info *cdi, struct cdrom_mu
        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,
                       void * arg)
 {
@@ -4530,7 +4204,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
                default:
                        RETURN_UP(-EINVAL);
                }
-               
+
        case CDROMRESUME: /* resume paused audio play */
                msg(DBG_IOC,"ioctl: CDROMRESUME entered.\n");
                /* resume playing audio tracks when a previous PLAY AUDIO call has  */
@@ -4544,12 +4218,12 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
                if (i<0) RETURN_UP(-EIO);
                current_drive->audio_state=audio_playing;
                RETURN_UP(0);
-               
+
        case CDROMPLAYMSF:
                msg(DBG_IOC,"ioctl: CDROMPLAYMSF entered.\n");
 #ifdef SAFE_MIXED
                if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */ 
+#endif /* SAFE_MIXED */
                if (current_drive->audio_state==audio_playing)
                {
                        i=cc_Pause_Resume(1);
@@ -4584,7 +4258,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
                msg(DBG_IOC,"ioctl: CDROMPLAYTRKIND entered.\n");
 #ifdef SAFE_MIXED
                if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */ 
+#endif /* SAFE_MIXED */
                if (current_drive->audio_state==audio_playing)
                {
                        msg(DBG_IOX,"CDROMPLAYTRKIND: already audio_playing.\n");
@@ -4654,13 +4328,13 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
                cc_DriveReset();
 #endif
                RETURN_UP(i);
-               
+
        case CDROMSTART:  /* Spin up the drive */
                msg(DBG_IOC,"ioctl: CDROMSTART entered.\n");
                cc_SpinUp();
                current_drive->audio_state=0;
                RETURN_UP(0);
-               
+
        case CDROMVOLCTRL:   /* Volume control */
                msg(DBG_IOC,"ioctl: CDROMVOLCTRL entered.\n");
                memcpy(&volctrl,(char *) arg,sizeof(volctrl));
@@ -4670,7 +4344,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
                current_drive->vol_ctrl1=volctrl.channel1;
                i=cc_SetVolume();
                RETURN_UP(0);
-               
+
        case CDROMVOLREAD:   /* read Volume settings from drive */
                msg(DBG_IOC,"ioctl: CDROMVOLREAD entered.\n");
                st=cc_GetVolume();
@@ -4694,7 +4368,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
                if (i<0) {
                        j=cc_ReadError(); /* clear out error status from drive */
                        current_drive->audio_state=CDROM_AUDIO_NO_STATUS;
-                       /* get and set the disk state here, 
+                       /* get and set the disk state here,
                        probably not the right place, but who cares!
                        It makes it work properly! --AJK */
                        if (current_drive->CD_changed==0xFF) {
@@ -4715,8 +4389,8 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
                        }
                }
                memcpy(&SC, (void *) arg, sizeof(struct cdrom_subchnl));
-               /* 
-                       This virtual crap is very bogus! 
+               /*
+                       This virtual crap is very bogus!
                        It doesn't detect when the cd is done playing audio!
                        Lets do this right with proper hardware register reading!
                */
@@ -4775,7 +4449,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
                    SC.cdsc_trk,SC.cdsc_ind,
                    SC.cdsc_absaddr,SC.cdsc_reladdr);
                RETURN_UP(0);
-               
+
        default:
                msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
                RETURN_UP(-EINVAL);
@@ -4788,7 +4462,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
 static void sbp_transfer(struct request *req)
 {
        long offs;
-       
+
        while ( (req->nr_sectors > 0) &&
               (req->sector/4 >= current_drive->sbp_first_frame) &&
               (req->sector/4 <= current_drive->sbp_last_frame) )
@@ -4807,11 +4481,11 @@ static void sbp_transfer(struct request *req)
  *
  *  This is a kludge so we don't need to modify end_request.
  *  We put the req we take out after INIT_REQUEST in the requests list,
- *  so that end_request will discard it. 
+ *  so that end_request will discard it.
  *
  *  The bug could be present in other block devices, perhaps we
  *  should modify INIT_REQUEST and end_request instead, and
- *  change every block device.. 
+ *  change every block device..
  *
  *  Could be a race here?? Could e.g. a timer interrupt schedule() us?
  *  If so, we should copy end_request here, and do it right.. (or
@@ -4883,19 +4557,19 @@ static void do_sbpcd_request(request_queue_t * q)
        while (busy_audio) sbp_sleep(HZ); /* wait a bit */
        busy_data=1;
 #endif /* OLD_BUSY */
-       
+
        if (p->audio_state==audio_playing) goto err_done;
        if (p != current_drive)
                switch_drive(p);
 
        block = req->sector; /* always numbered as 512-byte-pieces */
        nsect = req->nr_sectors; /* always counted as 512-byte-pieces */
-       
+
        msg(DBG_BSZ,"read sector %d (%d sectors)\n", block, nsect);
 #if 0
        msg(DBG_MUL,"read LBA %d\n", block/4);
 #endif
-       
+
        sbp_transfer(req);
        /* if we satisfied the request from the buffer, we're done. */
        if (req->nr_sectors == 0)
@@ -4914,10 +4588,10 @@ static void do_sbpcd_request(request_queue_t * q)
        i=prepare(0,0); /* at moment not really a hassle check, but ... */
        if (i!=0)
                msg(DBG_INF,"\"prepare\" tells error %d -- ignored\n", i);
-#endif /* FUTURE */ 
-       
+#endif /* FUTURE */
+
        if (!st_spinning) cc_SpinUp();
-       
+
        for (data_tries=n_retries; data_tries > 0; data_tries--)
        {
                for (status_tries=3; status_tries > 0; status_tries--)
@@ -4940,7 +4614,7 @@ static void do_sbpcd_request(request_queue_t * q)
                {
 #ifdef SAFE_MIXED
                        current_drive->has_data=2; /* is really a data disk */
-#endif /* SAFE_MIXED */ 
+#endif /* SAFE_MIXED */
 #ifdef DEBUG_GTL
                        printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 3, Time:%li\n",
                                xnr, req, req->sector, req->nr_sectors, jiffies);
@@ -4951,7 +4625,7 @@ static void do_sbpcd_request(request_queue_t * q)
                        goto request_loop;
                }
        }
-       
+
  err_done:
 #if OLD_BUSY
        busy_data=0;
@@ -4976,7 +4650,7 @@ static void sbp_read_cmd(struct request *req)
 
        int i;
        int block;
-       
+
        current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1;      /* purge buffer */
        current_drive->sbp_current = 0;
        block=req->sector/4;
@@ -4993,7 +4667,7 @@ static void sbp_read_cmd(struct request *req)
                        current_drive->sbp_read_frames=1;
                }
        }
-       
+
        flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
        clr_cmdbuf();
        if (famV_drive)
@@ -5092,7 +4766,7 @@ static int sbp_data(struct request *req)
        int success;
        int wait;
        int duration;
-       
+
        error_flag=0;
        success=0;
 #if LONG_TIMING
@@ -5105,12 +4779,12 @@ static int sbp_data(struct request *req)
        for (frame=0;frame<current_drive->sbp_read_frames&&!error_flag; frame++)
        {
                SBPCD_CLI;
-               
+
                del_timer(&data_timer);
                data_timer.expires=jiffies+max_latency;
                timed_out_data=0;
                add_timer(&data_timer);
-               while (!timed_out_data) 
+               while (!timed_out_data)
                {
                        if (current_drive->f_multisession) try=maxtim_data*4;
                        else try=maxtim_data;
@@ -5207,9 +4881,9 @@ static int sbp_data(struct request *req)
                         else
                           {
                             sbp_sleep(1);
-                            OUT(CDo_sel_i_d,0); 
+                            OUT(CDo_sel_i_d,0);
                             i=inb(CDi_status);
-                          } 
+                          }
                        if (!(i&s_not_data_ready))
                        {
                                OUT(CDo_sel_i_d,1);
@@ -5311,7 +4985,7 @@ static int sbp_data(struct request *req)
                }
                SBPCD_STI;
        }
-       
+
 #if 0
        if (!success)
 #endif
@@ -5370,7 +5044,326 @@ static int sbpcd_block_ioctl(struct inode *inode, struct file *file,
                                unsigned cmd, unsigned long arg)
 {
        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)
@@ -5478,10 +5471,9 @@ static struct cdrom_device_ops sbpcd_dops = {
        .get_mcn                = sbpcd_get_mcn,
        .reset                  = sbpcd_reset,
        .audio_ioctl            = sbpcd_audio_ioctl,
-       .dev_ioctl              = sbpcd_dev_ioctl,
        .capability             = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
                                CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
-                               CDC_MCN | CDC_PLAY_AUDIO | CDC_IOCTLS,
+                               CDC_MCN | CDC_PLAY_AUDIO,
        .n_minors               = 1,
 };
 
index e276172..c0f817b 100644 (file)
@@ -627,7 +627,7 @@ static struct cdrom_device_ops viocd_dops = {
        .media_changed = viocd_media_changed,
        .lock_door = viocd_lock_door,
        .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)
index 3325660..430d8af 100644 (file)
@@ -2471,52 +2471,6 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi,
 }
 
 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
 int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
                           unsigned int cmd, void *arg)
                           
@@ -2852,12 +2806,11 @@ static struct cdrom_device_ops ide_cdrom_dops = {
        .get_mcn                = ide_cdrom_get_mcn,
        .reset                  = ide_cdrom_reset,
        .audio_ioctl            = ide_cdrom_audio_ioctl,
-       .dev_ioctl              = ide_cdrom_dev_ioctl,
        .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_CD_R |
+                               CDC_DRIVE_STATUS | CDC_CD_R |
                                CDC_CD_RW | CDC_DVD | CDC_DVD_R| CDC_DVD_RAM |
                                CDC_GENERIC_PACKET | CDC_MO_DRIVE | CDC_MRW |
                                CDC_MRW_W | CDC_RAM,
@@ -3367,6 +3320,45 @@ static int idecd_release(struct inode * inode, struct file * file)
        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,
                        unsigned int cmd, unsigned long arg)
 {
@@ -3374,7 +3366,16 @@ static int idecd_ioctl (struct inode *inode, struct file *file,
        struct cdrom_info *info = ide_cd_g(bdev->bd_disk);
        int err;
 
-       err  = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
+       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);
        if (err == -EINVAL)
                err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg);
 
index f9c1192..7c80711 100644 (file)
@@ -71,7 +71,7 @@ MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_CDROM_MAJOR);
 #define SR_CAPABILITIES \
        (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_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_MRW|CDC_MRW_W|CDC_RAM)
 
@@ -118,7 +118,6 @@ static struct cdrom_device_ops sr_dops = {
        .get_mcn                = sr_get_mcn,
        .reset                  = sr_reset,
        .audio_ioctl            = sr_audio_ioctl,
-       .dev_ioctl              = sr_dev_ioctl,
        .capability             = SR_CAPABILITIES,
        .generic_packet         = sr_packet,
 };
@@ -456,17 +455,33 @@ 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_device *sdev = cd->device;
+       void __user *argp = (void __user *)arg;
+       int ret;
 
-        /*
-         * Send SCSI addressing ioctls directly to mid level, send other
-         * ioctls to cdrom/block level.
-         */
-        switch (cmd) {
-                case SCSI_IOCTL_GET_IDLUN:
-                case SCSI_IOCTL_GET_BUS_NUMBER:
-                        return scsi_ioctl(sdev, cmd, (void __user *)arg);
+       /*
+        * Send SCSI addressing ioctls directly to mid level, send other
+        * ioctls to cdrom/block level.
+        */
+       switch (cmd) {
+       case SCSI_IOCTL_GET_IDLUN:
+       case SCSI_IOCTL_GET_BUS_NUMBER:
+               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)
index d2bcd99..d65de96 100644 (file)
@@ -55,7 +55,6 @@ int sr_get_mcn(struct cdrom_device_info *, struct cdrom_mcn *);
 int sr_reset(struct cdrom_device_info *);
 int sr_select_speed(struct cdrom_device_info *cdi, int speed);
 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 *);
 
index b65462f..d1268cb 100644 (file)
@@ -562,22 +562,3 @@ int sr_is_xa(Scsi_CD *cd)
 #endif
        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);
-}
index b68fdf1..3c9b0bc 100644 (file)
@@ -378,7 +378,6 @@ struct cdrom_generic_command
 #define CDC_MEDIA_CHANGED      0x80    /* media changed */
 #define CDC_PLAY_AUDIO         0x100   /* audio functions */
 #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_GENERIC_PACKET     0x1000  /* driver implements generic packets */
 #define CDC_CD_R               0x2000  /* drive is a CD-R */
@@ -974,9 +973,7 @@ struct cdrom_device_ops {
        int (*reset) (struct cdrom_device_info *);
        /* play stuff */
        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 */
        const int capability;   /* capability flags */
        int n_minors;           /* number of active minor devices */