root/kernel/blk_drv/scsi/sr_ioctl.c

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

DEFINITIONS

This source file includes following definitions.
  1. sr_ioctl_done
  2. do_ioctl
  3. sr_ioctl

   1 #include <linux/kernel.h>
   2 #include <linux/sched.h>
   3 #include <linux/fs.h>
   4 #include <asm/segment.h>
   5 #include <linux/errno.h>
   6 
   7 #include "../blk.h"
   8 #include "scsi.h"
   9 #include "sr.h"
  10 #include "scsi_ioctl.h"
  11 
  12 #include <linux/cdrom.h>
  13 
  14 #define IOCTL_RETRIES 3
  15 /* The CDROM is fairly slow, so we need a little extra time */
  16 #define IOCTL_TIMEOUT 200
  17 
  18 extern int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
  19 
  20 static void sr_ioctl_done(Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
  21 {
  22   struct request * req;
  23   struct task_struct * p;
  24   
  25   req = &SCpnt->request;
  26   req->dev = 0xfffe; /* Busy, but indicate request done */
  27   
  28   if ((p = req->waiting) != NULL) {
  29     req->waiting = NULL;
  30     p->state = TASK_RUNNING;
  31     if (p->counter > current->counter)
  32       need_resched = 1;
  33   }
  34 }
  35 
  36 /* We do our own retries because we want to know what the specific
  37    error code is.  Normally the UNIT_ATTENTION code will automatically
  38    clear after one error */
  39 
  40 static int do_ioctl(int target, unsigned char * sr_cmd)
     /* [previous][next][first][last][top][bottom][index][help] */
  41 {
  42         Scsi_Cmnd * SCpnt;
  43         int result;
  44 
  45         SCpnt = allocate_device(NULL, scsi_CDs[target].device->index, 1);
  46         scsi_do_cmd(SCpnt,
  47                     (void *) sr_cmd, NULL, 255, sr_ioctl_done, 
  48                     IOCTL_TIMEOUT, IOCTL_RETRIES);
  49 
  50 
  51         if (SCpnt->request.dev != 0xfffe){
  52           SCpnt->request.waiting = current;
  53           current->state = TASK_UNINTERRUPTIBLE;
  54           while (SCpnt->request.dev != 0xfffe) schedule();
  55         };
  56 
  57         result = SCpnt->result;
  58 
  59 /* Minimal error checking.  Ignore cases we know about, and report the rest. */
  60         if(driver_byte(result) != 0)
  61           switch(SCpnt->sense_buffer[2] & 0xf) {
  62           case UNIT_ATTENTION:
  63             scsi_CDs[target].device->changed = 1;
  64             printk("Disc change detected.\n");
  65             break;
  66           case NOT_READY: /* This happens if there is no disc in drive */
  67             printk("CDROM not ready.  Make sure there is a disc in the drive.\n");
  68             break;
  69           case ILLEGAL_REQUEST:
  70             printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n");
  71             break;
  72           default:
  73             printk("SCSI CD error: host %d id %d lun %d return code = %03x\n", 
  74                    scsi_CDs[target].device->host_no, 
  75                    scsi_CDs[target].device->id,
  76                    scsi_CDs[target].device->lun,
  77                    result);
  78             printk("\tSense class %x, sense error %x, extended sense %x\n",
  79                    sense_class(SCpnt->sense_buffer[0]), 
  80                    sense_error(SCpnt->sense_buffer[0]),
  81                    SCpnt->sense_buffer[2] & 0xf);
  82             
  83         };
  84 
  85         result = SCpnt->result;
  86         SCpnt->request.dev = -1; /* Deallocate */
  87         wake_up(&scsi_devices[SCpnt->index].device_wait);
  88         /* Wake up a process waiting for device*/
  89         return result;
  90 }
  91 
  92 int sr_ioctl(struct inode * inode, struct file * file, unsigned long cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94         u_char  sr_cmd[10];
  95 
  96         int dev = inode->i_rdev;
  97         int result, target;
  98 
  99         target = MINOR(dev);
 100         if (target >= NR_SR) return -ENODEV;
 101 
 102         switch (cmd) 
 103                 {
 104                 /* Sun-compatible */
 105                 case CDROMPAUSE:
 106 
 107                         sr_cmd[0] = SCMD_PAUSE_RESUME;
 108                         sr_cmd[1] = scsi_CDs[target].device->lun << 5;
 109                         sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
 110                         sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
 111                         sr_cmd[8] = 1;
 112                         sr_cmd[9] = 0;
 113 
 114                         result = do_ioctl(target, sr_cmd);
 115                         return result;
 116 
 117                 case CDROMRESUME:
 118 
 119                         sr_cmd[0] = SCMD_PAUSE_RESUME;
 120                         sr_cmd[1] = scsi_CDs[target].device->lun << 5;
 121                         sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
 122                         sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
 123                         sr_cmd[8] = 0;
 124                         sr_cmd[9] = 0;
 125 
 126                         result = do_ioctl(target, sr_cmd);
 127 
 128                         return result;
 129 
 130                 case CDROMPLAYMSF:
 131                         {
 132                         struct cdrom_msf msf;
 133                         memcpy_fromfs(&msf, (void *) arg, sizeof(msf));
 134 
 135                         sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
 136                         sr_cmd[1] = scsi_CDs[target].device->lun << 5;
 137                         sr_cmd[2] = 0;
 138                         sr_cmd[3] = msf.cdmsf_min0;
 139                         sr_cmd[4] = msf.cdmsf_sec0;
 140                         sr_cmd[5] = msf.cdmsf_frame0;
 141                         sr_cmd[6] = msf.cdmsf_min1;
 142                         sr_cmd[7] = msf.cdmsf_sec1;
 143                         sr_cmd[8] = msf.cdmsf_frame1;
 144                         sr_cmd[9] = 0;
 145 
 146                         result = do_ioctl(target, sr_cmd);
 147                         return result;
 148                         }
 149 
 150                 case CDROMPLAYTRKIND:
 151                         {
 152                         struct cdrom_ti ti;
 153                         memcpy_fromfs(&ti, (void *) arg, sizeof(ti));
 154 
 155                         sr_cmd[0] = SCMD_PLAYAUDIO_TI;
 156                         sr_cmd[1] = scsi_CDs[target].device->lun << 5;
 157                         sr_cmd[2] = 0;
 158                         sr_cmd[3] = 0;
 159                         sr_cmd[4] = ti.cdti_trk0;
 160                         sr_cmd[5] = ti.cdti_ind0;
 161                         sr_cmd[6] = 0;
 162                         sr_cmd[7] = ti.cdti_trk1;
 163                         sr_cmd[8] = ti.cdti_ind1;
 164                         sr_cmd[9] = 0;
 165 
 166                         result = do_ioctl(target, sr_cmd);
 167 
 168                         return result;
 169                         }
 170 
 171                 case CDROMREADTOCHDR:
 172                         return -EINVAL;
 173                 case CDROMREADTOCENTRY:
 174                         return -EINVAL;
 175 
 176                 case CDROMSTOP:
 177                         sr_cmd[0] = START_STOP;
 178                         sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
 179                         sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
 180                         sr_cmd[4] = 0;
 181 
 182                         result = do_ioctl(target, sr_cmd);
 183                         return result;
 184                         
 185                 case CDROMSTART:
 186                         sr_cmd[0] = START_STOP;
 187                         sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
 188                         sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
 189                         sr_cmd[4] = 1;
 190 
 191                         result = do_ioctl(target, sr_cmd);
 192                         return result;
 193 
 194                 case CDROMEJECT:
 195                         sr_cmd[0] = START_STOP;
 196                         sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
 197                         sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
 198                         sr_cmd[4] = 0x02;
 199 
 200                         result = do_ioctl(target, sr_cmd);
 201                         return result;
 202 
 203                 case CDROMVOLCTRL:
 204                         return -EINVAL;
 205                 case CDROMSUBCHNL:
 206                         return -EINVAL;
 207                 case CDROMREADMODE2:
 208                         return -EINVAL;
 209                 case CDROMREADMODE1:
 210                         return -EINVAL;
 211 
 212                 RO_IOCTLS(dev,arg);
 213                 default:
 214                         return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
 215                 }
 216 }

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