[PATCH] devfs: Remove the devfs_fs_kernel.h file from the tree
[linux-2.6.git] / drivers / cdrom / sbpcd.c
index fc2c433..a75b363 100644 (file)
 #include <linux/kernel.h>
 #include <linux/cdrom.h>
 #include <linux/ioport.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/major.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
@@ -464,8 +463,13 @@ static int sbpcd[] =
 static  __cacheline_aligned DEFINE_SPINLOCK(sbpcd_lock);
 static struct request_queue *sbpcd_queue;
 
-MODULE_PARM(sbpcd, "2i");
-MODULE_PARM(max_drives, "i");
+/* You can only set the first pair, from old MODULE_PARM code.  */
+static int sbpcd_set(const char *val, struct kernel_param *kp)
+{
+       get_options((char *)val, 2, (int *)sbpcd);
+       return 0;
+}
+module_param_call(sbpcd, sbpcd_set, NULL, NULL, 0);
 
 #define NUM_PROBE  (sizeof(sbpcd) / sizeof(int))
 
@@ -553,6 +557,7 @@ static unsigned char msgnum;
 static char msgbuf[80];
 
 static int max_drives = MAX_DRIVES;
+module_param(max_drives, int, 0);
 #ifndef MODULE
 static unsigned char setup_done;
 static const char *str_sb_l = "soundblaster";
@@ -742,13 +747,10 @@ static struct sbpcd_drive *current_drive = D_S;
 unsigned long cli_sti; /* for saving the processor flags */
 #endif
 /*==========================================================================*/
-static struct timer_list delay_timer =
-               TIMER_INITIALIZER(mark_timeout_delay, 0, 0);
-static struct timer_list data_timer =
-               TIMER_INITIALIZER(mark_timeout_data, 0, 0);
+static DEFINE_TIMER(delay_timer, mark_timeout_delay, 0, 0);
+static DEFINE_TIMER(data_timer, mark_timeout_data, 0, 0);
 #if 0
-static struct timer_list audio_timer =
-               TIMER_INITIALIZER(mark_timeout_audio, 0, 0);
+static DEFINE_TIMER(audio_timer, mark_timeout_audio, 0, 0);
 #endif
 /*==========================================================================*/
 /*
@@ -830,8 +832,7 @@ static void mark_timeout_audio(u_long i)
 static void sbp_sleep(u_int time)
 {
        sti();
-       current->state = TASK_INTERRUPTIBLE;
-       schedule_timeout(time);
+       schedule_timeout_interruptible(time);
        sti();
 }
 /*==========================================================================*/
@@ -4164,331 +4165,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)
 {
@@ -4533,7 +4209,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  */
@@ -4547,12 +4223,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);
@@ -4587,7 +4263,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");
@@ -4657,13 +4333,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));
@@ -4673,7 +4349,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();
@@ -4697,7 +4373,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) {
@@ -4718,8 +4394,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!
                */
@@ -4778,7 +4454,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);
@@ -4791,7 +4467,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) )
@@ -4810,11 +4486,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
@@ -4886,19 +4562,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)
@@ -4917,10 +4593,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--)
@@ -4943,7 +4619,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);
@@ -4954,7 +4630,7 @@ static void do_sbpcd_request(request_queue_t * q)
                        goto request_loop;
                }
        }
-       
+
  err_done:
 #if OLD_BUSY
        busy_data=0;
@@ -4979,7 +4655,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;
@@ -4996,7 +4672,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)
@@ -5095,7 +4771,7 @@ static int sbp_data(struct request *req)
        int success;
        int wait;
        int duration;
-       
+
        error_flag=0;
        success=0;
 #if LONG_TIMING
@@ -5108,12 +4784,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;
@@ -5210,9 +4886,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);
@@ -5314,7 +4990,7 @@ static int sbp_data(struct request *req)
                }
                SBPCD_STI;
        }
-       
+
 #if 0
        if (!success)
 #endif
@@ -5373,7 +5049,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)
@@ -5481,10 +5476,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,
 };
 
@@ -5813,8 +5807,6 @@ int __init sbpcd_init(void)
                return -ENOMEM;
        }
 
-       devfs_mk_dir("sbp");
-
        for (j=0;j<NR_SBPCD;j++)
        {
                struct cdrom_device_info * sbpcd_infop;
@@ -5895,7 +5887,7 @@ int __init sbpcd_init(void)
 }
 /*==========================================================================*/
 #ifdef MODULE
-void sbpcd_exit(void)
+static void sbpcd_exit(void)
 {
        int j;
        
@@ -5911,9 +5903,9 @@ void sbpcd_exit(void)
                if (D_S[j].drv_id==-1) continue;
                del_gendisk(D_S[j].disk);
                put_disk(D_S[j].disk);
-               devfs_remove("sbp/c0t%d", j);
                vfree(D_S[j].sbp_buf);
-               if (D_S[j].sbp_audsiz>0) vfree(D_S[j].aud_buf);
+               if (D_S[j].sbp_audsiz>0)
+                       vfree(D_S[j].aud_buf);
                if ((unregister_cdrom(D_S[j].sbpcd_infop) == -EINVAL))
                {
                        msg(DBG_INF, "What's that: can't unregister info %s.\n", major_name);
@@ -5921,7 +5913,6 @@ void sbpcd_exit(void)
                }
                vfree(D_S[j].sbpcd_infop);
        }
-       devfs_remove("sbp");
        msg(DBG_INF, "%s module released.\n", major_name);
 }