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 
 101         switch (cmd) 
 102                 {
 103                 /* Sun-compatible */
 104                 case CDROMPAUSE:
 105 
 106                         sr_cmd[0] = SCMD_PAUSE_RESUME;
 107                         sr_cmd[1] = scsi_CDs[target].device->lun << 5;
 108                         sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
 109                         sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
 110                         sr_cmd[8] = 1;
 111                         sr_cmd[9] = 0;
 112 
 113                         result = do_ioctl(target, sr_cmd);
 114                         return result;
 115 
 116                 case CDROMRESUME:
 117 
 118                         sr_cmd[0] = SCMD_PAUSE_RESUME;
 119                         sr_cmd[1] = scsi_CDs[target].device->lun << 5;
 120                         sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
 121                         sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
 122                         sr_cmd[8] = 0;
 123                         sr_cmd[9] = 0;
 124 
 125                         result = do_ioctl(target, sr_cmd);
 126 
 127                         return result;
 128 
 129                 case CDROMPLAYMSF:
 130                         {
 131                         struct cdrom_msf msf;
 132                         memcpy_fromfs(&msf, (void *) arg, sizeof(msf));
 133 
 134                         sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
 135                         sr_cmd[1] = scsi_CDs[target].device->lun << 5;
 136                         sr_cmd[2] = 0;
 137                         sr_cmd[3] = msf.cdmsf_min0;
 138                         sr_cmd[4] = msf.cdmsf_sec0;
 139                         sr_cmd[5] = msf.cdmsf_frame0;
 140                         sr_cmd[6] = msf.cdmsf_min1;
 141                         sr_cmd[7] = msf.cdmsf_sec1;
 142                         sr_cmd[8] = msf.cdmsf_frame1;
 143                         sr_cmd[9] = 0;
 144 
 145                         result = do_ioctl(target, sr_cmd);
 146                         return result;
 147                         }
 148 
 149                 case CDROMPLAYTRKIND:
 150                         {
 151                         struct cdrom_ti ti;
 152                         memcpy_fromfs(&ti, (void *) arg, sizeof(ti));
 153 
 154                         sr_cmd[0] = SCMD_PLAYAUDIO_TI;
 155                         sr_cmd[1] = scsi_CDs[target].device->lun << 5;
 156                         sr_cmd[2] = 0;
 157                         sr_cmd[3] = 0;
 158                         sr_cmd[4] = ti.cdti_trk0;
 159                         sr_cmd[5] = ti.cdti_ind0;
 160                         sr_cmd[6] = 0;
 161                         sr_cmd[7] = ti.cdti_trk1;
 162                         sr_cmd[8] = ti.cdti_ind1;
 163                         sr_cmd[9] = 0;
 164 
 165                         result = do_ioctl(target, sr_cmd);
 166 
 167                         return result;
 168                         }
 169 
 170                 case CDROMREADTOCHDR:
 171                         return -EINVAL;
 172                 case CDROMREADTOCENTRY:
 173                         return -EINVAL;
 174 
 175                 case CDROMSTOP:
 176                         sr_cmd[0] = START_STOP;
 177                         sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
 178                         sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
 179                         sr_cmd[4] = 0;
 180 
 181                         result = do_ioctl(target, sr_cmd);
 182                         return result;
 183                         
 184                 case CDROMSTART:
 185                         sr_cmd[0] = START_STOP;
 186                         sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
 187                         sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
 188                         sr_cmd[4] = 1;
 189 
 190                         result = do_ioctl(target, sr_cmd);
 191                         return result;
 192 
 193                 case CDROMEJECT:
 194                         sr_cmd[0] = START_STOP;
 195                         sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
 196                         sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
 197                         sr_cmd[4] = 0x02;
 198 
 199                         result = do_ioctl(target, sr_cmd);
 200                         return result;
 201 
 202                 case CDROMVOLCTRL:
 203                         return -EINVAL;
 204                 case CDROMSUBCHNL:
 205                         return -EINVAL;
 206                 case CDROMREADMODE2:
 207                         return -EINVAL;
 208                 case CDROMREADMODE1:
 209                         return -EINVAL;
 210 
 211                 RO_IOCTLS(dev,arg);
 212                 default:
 213                         return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
 214                 }
 215 }

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