root/kernel/blk_drv/scsi/sr_ioctl.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lock_sr_ioctl
  2. unlock_sr_ioctl
  3. sr_ioctl_done
  4. do_ioctl
  5. sr_ioctl

   1 #include <linux/config.h>
   2 #ifdef CONFIG_BLK_DEV_SR
   3 #include <linux/kernel.h>
   4 #include <linux/sched.h>
   5 #include <linux/fs.h>
   6 #include <asm/segment.h>
   7 #include <linux/errno.h>
   8 
   9 #include "../blk.h"
  10 #include "scsi.h"
  11 #include "sr.h"
  12 #include "scsi_ioctl.h"
  13 
  14 #include <linux/cdrom.h>
  15 
  16 #define IOCTL_RETRIES 3
  17 /* The CDROM is fairly slow, so we need a little extra time */
  18 #define IOCTL_TIMEOUT 200
  19 
  20 static u_char   sr_cmd[10];
  21 static u_char   data_buffer[255];
  22 static u_char   sense_buffer[255];
  23 static int      the_result;
  24 
  25 static struct wait_queue *sr_cmd_wait = NULL;   /* For waiting until cmd done*/
  26 static u_char   sr_lock = 0;   /* To make sure that only one person is doing
  27                                   an ioctl at one time */
  28 static int      target;
  29 
  30 extern int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
  31 
  32 static void lock_sr_ioctl( void )
     /* [previous][next][first][last][top][bottom][index][help] */
  33 {
  34   /* We do not use wakeup here because there could conceivably be three
  35      processes trying to get at the drive simultaneously, and we would
  36      be screwed if that happened.
  37      */
  38 
  39         while (sr_lock);
  40         sr_lock = 1;
  41 }
  42 
  43 static void unlock_sr_ioctl( void )
     /* [previous][next][first][last][top][bottom][index][help] */
  44 {
  45         sr_lock = 0;
  46 }
  47 
  48 static void sr_ioctl_done( int host, int result )
     /* [previous][next][first][last][top][bottom][index][help] */
  49 {
  50         the_result = result;
  51         wake_up(&sr_cmd_wait);
  52 }
  53 
  54 /* We do our own retries because we want to know what the specific
  55    error code is.  Normally the UNIT_ATTENTION code will automatically
  56    clear after one error */
  57 
  58 static int do_ioctl( void )
     /* [previous][next][first][last][top][bottom][index][help] */
  59 {
  60         int retries = IOCTL_RETRIES;
  61 retry:     
  62 
  63         the_result = -1;
  64 
  65         scsi_do_cmd(scsi_CDs[target].device->host_no, scsi_CDs[target].device->id,
  66                     (void *) sr_cmd, (void *) data_buffer, 255, sr_ioctl_done, 
  67                     IOCTL_TIMEOUT, (void *) sense_buffer, 0);
  68 
  69         while (the_result < 0) sleep_on(&sr_cmd_wait);
  70 
  71         if(driver_byte(the_result) != 0 && 
  72            (sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
  73           scsi_CDs[target].device->changed = 1;
  74           printk("Disc change detected.\n");
  75         };
  76 
  77         if (the_result && retries)
  78                 {
  79                 retries--;
  80                 goto retry;
  81                 }
  82 
  83 /* Minimal error checking.  Ignore cases we know about, and report the rest. */
  84         if(driver_byte(the_result) != 0)
  85           switch(sense_buffer[2] & 0xf) {
  86           case UNIT_ATTENTION:
  87             scsi_CDs[target].device->changed = 1;
  88             printk("Disc change detected.\n");
  89             break;
  90           case NOT_READY: /* This happens if there is no disc in drive */
  91             printk("CDROM not ready.  Make sure there is a disc in the drive.\n");
  92             break;
  93           case ILLEGAL_REQUEST:
  94             printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n");
  95             break;
  96           default:
  97             printk("SCSI CD error: host %d id %d lun %d return code = %03x\n", 
  98                    scsi_CDs[target].device->host_no, 
  99                    scsi_CDs[target].device->id,
 100                    scsi_CDs[target].device->lun,
 101                    the_result);
 102             printk("\tSense class %x, sense error %x, extended sense %x\n",
 103                    sense_class(sense_buffer[0]), 
 104                    sense_error(sense_buffer[0]),
 105                    sense_buffer[2] & 0xf);
 106             
 107         };
 108         return the_result;
 109 }
 110 
 111 int sr_ioctl(struct inode * inode, struct file * file, unsigned long cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 112 {
 113         int dev = inode->i_rdev;
 114         int result;
 115 
 116         target = MINOR(dev);
 117 
 118         switch (cmd) 
 119                 {
 120                 /* Sun-compatible */
 121                 case CDROMPAUSE:
 122                         lock_sr_ioctl();
 123 
 124                         sr_cmd[0] = SCMD_PAUSE_RESUME;
 125                         sr_cmd[1] = scsi_CDs[target].device->lun << 5;
 126                         sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
 127                         sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
 128                         sr_cmd[8] = 1;
 129                         sr_cmd[9] = 0;
 130 
 131                         result = do_ioctl();
 132 
 133                         unlock_sr_ioctl();
 134                         return result;
 135 
 136                 case CDROMRESUME:
 137                         lock_sr_ioctl();
 138 
 139                         sr_cmd[0] = SCMD_PAUSE_RESUME;
 140                         sr_cmd[1] = scsi_CDs[target].device->lun << 5;
 141                         sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
 142                         sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
 143                         sr_cmd[8] = 0;
 144                         sr_cmd[9] = 0;
 145 
 146                         result = do_ioctl();
 147 
 148                         unlock_sr_ioctl();
 149                         return result;
 150 
 151                 case CDROMPLAYMSF:
 152                         {
 153                         struct cdrom_msf msf;
 154                         lock_sr_ioctl();
 155 
 156                         memcpy_fromfs(&msf, (void *) arg, sizeof(msf));
 157 
 158                         sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
 159                         sr_cmd[1] = scsi_CDs[target].device->lun << 5;
 160                         sr_cmd[2] = 0;
 161                         sr_cmd[3] = msf.cdmsf_min0;
 162                         sr_cmd[4] = msf.cdmsf_sec0;
 163                         sr_cmd[5] = msf.cdmsf_frame0;
 164                         sr_cmd[6] = msf.cdmsf_min1;
 165                         sr_cmd[7] = msf.cdmsf_sec1;
 166                         sr_cmd[8] = msf.cdmsf_frame1;
 167                         sr_cmd[9] = 0;
 168 
 169                         result = do_ioctl();
 170 
 171                         unlock_sr_ioctl();
 172                         return result;
 173                         }
 174 
 175                 case CDROMPLAYTRKIND:
 176                         {
 177                         struct cdrom_ti ti;
 178                         lock_sr_ioctl();
 179 
 180                         memcpy_fromfs(&ti, (void *) arg, sizeof(ti));
 181 
 182                         sr_cmd[0] = SCMD_PLAYAUDIO_TI;
 183                         sr_cmd[1] = scsi_CDs[target].device->lun << 5;
 184                         sr_cmd[2] = 0;
 185                         sr_cmd[3] = 0;
 186                         sr_cmd[4] = ti.cdti_trk0;
 187                         sr_cmd[5] = ti.cdti_ind0;
 188                         sr_cmd[6] = 0;
 189                         sr_cmd[7] = ti.cdti_trk1;
 190                         sr_cmd[8] = ti.cdti_ind1;
 191                         sr_cmd[9] = 0;
 192 
 193                         result = do_ioctl();
 194 
 195                         unlock_sr_ioctl();
 196                         return result;
 197                         }
 198 
 199                 case CDROMREADTOCHDR:
 200                         return -EINVAL;
 201                 case CDROMREADTOCENTRY:
 202                         return -EINVAL;
 203 
 204                 case CDROMSTOP:
 205                         lock_sr_ioctl();
 206 
 207                         sr_cmd[0] = START_STOP;
 208                         sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
 209                         sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
 210                         sr_cmd[4] = 0;
 211 
 212                         result = do_ioctl();
 213 
 214                         unlock_sr_ioctl();
 215                         return result;
 216                         
 217                 case CDROMSTART:
 218                         lock_sr_ioctl();
 219 
 220                         sr_cmd[0] = START_STOP;
 221                         sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
 222                         sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
 223                         sr_cmd[4] = 1;
 224 
 225                         result = do_ioctl();
 226 
 227                         unlock_sr_ioctl();
 228                         return result;
 229 
 230                 case CDROMEJECT:
 231                         lock_sr_ioctl();
 232 
 233                         sr_cmd[0] = START_STOP;
 234                         sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
 235                         sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
 236                         sr_cmd[4] = 0x02;
 237 
 238                         result = do_ioctl();
 239 
 240                         unlock_sr_ioctl();
 241                         return result;
 242 
 243                 case CDROMVOLCTRL:
 244                         return -EINVAL;
 245                 case CDROMSUBCHNL:
 246                         return -EINVAL;
 247                 case CDROMREADMODE2:
 248                         return -EINVAL;
 249                 case CDROMREADMODE1:
 250                         return -EINVAL;
 251 
 252                 RO_IOCTLS(dev,arg);
 253                 default:
 254                         return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
 255                 }
 256 }
 257 
 258 #endif

/* [previous][next][first][last][top][bottom][index][help] */