Annotation of linux/kernel/blk_drv/scsi/sr_ioctl.c, revision 1.1

1.1     ! root        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: 
        !            13: #include <linux/cdrom.h>
        !            14: 
        !            15: #define IOCTL_RETRIES 3
        !            16: /* The CDROM is fairly slow, so we need a little extra time */
        !            17: #define IOCTL_TIMEOUT 200
        !            18: 
        !            19: static u_char  sr_cmd[10];
        !            20: static u_char  data_buffer[255];
        !            21: static u_char  sense_buffer[255];
        !            22: static int     the_result;
        !            23: 
        !            24: static struct wait_queue *sr_cmd_wait = NULL;   /* For waiting until cmd done*/
        !            25: static u_char  sr_lock = 0;   /* To make sure that only one person is doing
        !            26:                                  an ioctl at one time */
        !            27: static int     target;
        !            28: 
        !            29: extern int scsi_ioctl (int dev, int cmd, void *arg);
        !            30: 
        !            31: static void lock_sr_ioctl( void )
        !            32: {
        !            33:   /* We do not use wakeup here because there could conceivably be three
        !            34:      processes trying to get at the drive simultaneously, and we would
        !            35:      be screwed if that happened.
        !            36:      */
        !            37: 
        !            38:        while (sr_lock);
        !            39:        sr_lock = 1;
        !            40: }
        !            41: 
        !            42: static void unlock_sr_ioctl( void )
        !            43: {
        !            44:        sr_lock = 0;
        !            45: }
        !            46: 
        !            47: static void sr_ioctl_done( int host, int result )
        !            48: {
        !            49:        the_result = result;
        !            50:        wake_up(&sr_cmd_wait);
        !            51: }
        !            52: 
        !            53: /* We do our own retries because we want to know what the specific
        !            54:    error code is.  Normally the UNIT_ATTENTION code will automatically
        !            55:    clear after one error */
        !            56: 
        !            57: static int do_ioctl( void )
        !            58: {
        !            59:        int retries = IOCTL_RETRIES;
        !            60: retry:     
        !            61: 
        !            62:        the_result = -1;
        !            63: 
        !            64:        scsi_do_cmd(scsi_CDs[target].device->host_no, scsi_CDs[target].device->id,
        !            65:                    (void *) sr_cmd, (void *) data_buffer, 255, sr_ioctl_done, 
        !            66:                    IOCTL_TIMEOUT, (void *) sense_buffer, 0);
        !            67: 
        !            68:        while (the_result < 0) sleep_on(&sr_cmd_wait);
        !            69: 
        !            70:        if(driver_byte(the_result) != 0 && 
        !            71:           (sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
        !            72:          scsi_CDs[target].changed = 1;
        !            73:          printk("Disc change detected.\n");
        !            74:        };
        !            75: 
        !            76:        if (the_result && retries)
        !            77:                {
        !            78:                retries--;
        !            79:                goto retry;
        !            80:                }
        !            81: 
        !            82: /* Minimal error checking.  Ignore cases we know about, and report the rest. */
        !            83:        if(driver_byte(the_result) != 0)
        !            84:          switch(sense_buffer[2] & 0xf) {
        !            85:          case UNIT_ATTENTION:
        !            86:            scsi_CDs[target].changed = 1;
        !            87:            printk("Disc change detected.\n");
        !            88:            break;
        !            89:          case NOT_READY: /* This happens if there is no disc in drive */
        !            90:            printk("CDROM not ready.  Make sure there is a disc in the drive.\n");
        !            91:            break;
        !            92:          case ILLEGAL_REQUEST:
        !            93:            printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n");
        !            94:            break;
        !            95:          default:
        !            96:            printk("SCSI CD error: host %d id %d lun %d return code = %03x\n", 
        !            97:                   scsi_CDs[target].device->host_no, 
        !            98:                   scsi_CDs[target].device->id,
        !            99:                   scsi_CDs[target].device->lun,
        !           100:                   the_result);
        !           101:            printk("\tSense class %x, sense error %x, extended sense %x\n",
        !           102:                   sense_class(sense_buffer[0]), 
        !           103:                   sense_error(sense_buffer[0]),
        !           104:                   sense_buffer[2] & 0xf);
        !           105:            
        !           106:        };
        !           107:        return the_result;
        !           108: }
        !           109:        
        !           110: /*
        !           111:  * This function checks to see if the media has been changed in the
        !           112:  * CDROM drive.  It is possible that we have already sensed a change,
        !           113:  * or the drive may have sensed one and not yet reported it.  We must
        !           114:  * be ready for either case. This function always reports the current
        !           115:  * value of the changed bit.  If flag is 0, then the changed bit is reset.
        !           116:  * This function could be done as an ioctl, but we would need to have
        !           117:  * an inode for that to work, and we do not always have one.
        !           118:  */
        !           119: 
        !           120: int check_cdrom_media_change(int full_dev, int flag){
        !           121:        int retval;
        !           122: 
        !           123:        lock_sr_ioctl();
        !           124: 
        !           125:        target =  MINOR(full_dev);
        !           126: 
        !           127:        if (target >= NR_SR) {
        !           128:                printk("CD-ROM request error: invalid device.\n");
        !           129:                unlock_sr_ioctl();
        !           130:                return 0;
        !           131:        };
        !           132: 
        !           133:        sr_cmd[0] = TEST_UNIT_READY;
        !           134:        sr_cmd[1] = (scsi_CDs[target].device->lun << 5) & 0xe0;
        !           135:        sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
        !           136: 
        !           137:        retval = do_ioctl();
        !           138: 
        !           139:        if(retval){ /* Unable to test, unit probably not ready.  This usually
        !           140:                     means there is no disc in the drive.  Mark as changed,
        !           141:                     and we will figure it out later once the drive is
        !           142:                     available again.  */
        !           143: 
        !           144:          scsi_CDs[target].changed = 1;
        !           145:          unlock_sr_ioctl();
        !           146:          return 1; /* This will force a flush, if called from
        !           147:                       check_disk_change */
        !           148:        };
        !           149: 
        !           150:        retval = scsi_CDs[target].changed;
        !           151:        if(!flag) scsi_CDs[target].changed = 0;
        !           152:        unlock_sr_ioctl();
        !           153: 
        !           154:        return retval;
        !           155: }
        !           156: 
        !           157: int sr_ioctl(struct inode * inode, struct file * file, unsigned long cmd, unsigned long arg)
        !           158: {
        !           159:        int dev = inode->i_rdev;
        !           160:        int result;
        !           161: 
        !           162:        target = MINOR(dev);
        !           163: 
        !           164:        switch (cmd) 
        !           165:                {
        !           166:                /* linux-specific */
        !           167:                case CDROMDOORUNLOCK:
        !           168:                        lock_sr_ioctl();
        !           169: 
        !           170:                        sr_cmd[0] = ALLOW_MEDIUM_REMOVAL;
        !           171:                        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        !           172:                        sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
        !           173:                        sr_cmd[4] = SR_REMOVAL_ALLOW;
        !           174: 
        !           175:                        result = do_ioctl();
        !           176: 
        !           177:                        unlock_sr_ioctl();
        !           178:                        return result;
        !           179: 
        !           180:                case CDROMDOORLOCK:
        !           181:                        lock_sr_ioctl();
        !           182: 
        !           183:                        sr_cmd[0] = ALLOW_MEDIUM_REMOVAL;
        !           184:                        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        !           185:                        sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
        !           186:                        sr_cmd[4] = SR_REMOVAL_PREVENT;
        !           187: 
        !           188:                        result = do_ioctl();
        !           189: 
        !           190:                        unlock_sr_ioctl();
        !           191:                        return result;
        !           192: 
        !           193:                /* Sun-compatible */
        !           194:                case CDROMPAUSE:
        !           195:                        lock_sr_ioctl();
        !           196: 
        !           197:                        sr_cmd[0] = SCMD_PAUSE_RESUME;
        !           198:                        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        !           199:                        sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
        !           200:                        sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
        !           201:                        sr_cmd[8] = 1;
        !           202:                        sr_cmd[9] = 0;
        !           203: 
        !           204:                        result = do_ioctl();
        !           205: 
        !           206:                        unlock_sr_ioctl();
        !           207:                        return result;
        !           208: 
        !           209:                case CDROMRESUME:
        !           210:                        lock_sr_ioctl();
        !           211: 
        !           212:                        sr_cmd[0] = SCMD_PAUSE_RESUME;
        !           213:                        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        !           214:                        sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
        !           215:                        sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
        !           216:                        sr_cmd[8] = 0;
        !           217:                        sr_cmd[9] = 0;
        !           218: 
        !           219:                        result = do_ioctl();
        !           220: 
        !           221:                        unlock_sr_ioctl();
        !           222:                        return result;
        !           223: 
        !           224:                case CDROMPLAYMSF:
        !           225:                        {
        !           226:                        struct cdrom_msf msf;
        !           227:                        lock_sr_ioctl();
        !           228: 
        !           229:                        memcpy_fromfs(&msf, (void *) arg, sizeof(msf));
        !           230: 
        !           231:                        sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
        !           232:                        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        !           233:                        sr_cmd[2] = 0;
        !           234:                        sr_cmd[3] = msf.cdmsf_min0;
        !           235:                        sr_cmd[4] = msf.cdmsf_sec0;
        !           236:                        sr_cmd[5] = msf.cdmsf_frame0;
        !           237:                        sr_cmd[6] = msf.cdmsf_min1;
        !           238:                        sr_cmd[7] = msf.cdmsf_sec1;
        !           239:                        sr_cmd[8] = msf.cdmsf_frame1;
        !           240:                        sr_cmd[9] = 0;
        !           241: 
        !           242:                        result = do_ioctl();
        !           243: 
        !           244:                        unlock_sr_ioctl();
        !           245:                        return result;
        !           246:                        }
        !           247: 
        !           248:                case CDROMPLAYTRKIND:
        !           249:                        {
        !           250:                        struct cdrom_ti ti;
        !           251:                        lock_sr_ioctl();
        !           252: 
        !           253:                        memcpy_fromfs(&ti, (void *) arg, sizeof(ti));
        !           254: 
        !           255:                        sr_cmd[0] = SCMD_PLAYAUDIO_TI;
        !           256:                        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        !           257:                        sr_cmd[2] = 0;
        !           258:                        sr_cmd[3] = 0;
        !           259:                        sr_cmd[4] = ti.cdti_trk0;
        !           260:                        sr_cmd[5] = ti.cdti_ind0;
        !           261:                        sr_cmd[6] = 0;
        !           262:                        sr_cmd[7] = ti.cdti_trk1;
        !           263:                        sr_cmd[8] = ti.cdti_ind1;
        !           264:                        sr_cmd[9] = 0;
        !           265: 
        !           266:                        result = do_ioctl();
        !           267: 
        !           268:                        unlock_sr_ioctl();
        !           269:                        return result;
        !           270:                        }
        !           271: 
        !           272:                case CDROMREADTOCHDR:
        !           273:                        return -EINVAL;
        !           274:                case CDROMREADTOCENTRY:
        !           275:                        return -EINVAL;
        !           276: 
        !           277:                case CDROMSTOP:
        !           278:                        lock_sr_ioctl();
        !           279: 
        !           280:                        sr_cmd[0] = START_STOP;
        !           281:                        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
        !           282:                        sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
        !           283:                        sr_cmd[4] = 0;
        !           284: 
        !           285:                        result = do_ioctl();
        !           286: 
        !           287:                        unlock_sr_ioctl();
        !           288:                        return result;
        !           289:                        
        !           290:                case CDROMSTART:
        !           291:                        lock_sr_ioctl();
        !           292: 
        !           293:                        sr_cmd[0] = START_STOP;
        !           294:                        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
        !           295:                        sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
        !           296:                        sr_cmd[4] = 1;
        !           297: 
        !           298:                        result = do_ioctl();
        !           299: 
        !           300:                        unlock_sr_ioctl();
        !           301:                        return result;
        !           302: 
        !           303:                case CDROMEJECT:
        !           304:                        lock_sr_ioctl();
        !           305: 
        !           306:                        sr_cmd[0] = START_STOP;
        !           307:                        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
        !           308:                        sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
        !           309:                        sr_cmd[4] = 0x02;
        !           310: 
        !           311:                        result = do_ioctl();
        !           312: 
        !           313:                        unlock_sr_ioctl();
        !           314:                        return result;
        !           315: 
        !           316:                case CDROMVOLCTRL:
        !           317:                        return -EINVAL;
        !           318:                case CDROMSUBCHNL:
        !           319:                        return -EINVAL;
        !           320:                case CDROMREADMODE2:
        !           321:                        return -EINVAL;
        !           322:                case CDROMREADMODE1:
        !           323:                        return -EINVAL;
        !           324: 
        !           325:                RO_IOCTLS(dev,arg);
        !           326:                default:
        !           327:                        return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
        !           328:                }
        !           329: }
        !           330: 
        !           331: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.