Annotation of Gnu-Mach/linux/src/drivers/scsi/sr_ioctl.c, revision 1.1

1.1     ! root        1: #include <linux/kernel.h>
        !             2: #include <linux/sched.h>
        !             3: #include <linux/mm.h>
        !             4: #include <linux/fs.h>
        !             5: #include <asm/segment.h>
        !             6: #include <linux/errno.h>
        !             7: #include <linux/string.h>
        !             8: 
        !             9: #include <linux/blk.h>
        !            10: #include "scsi.h"
        !            11: #include "hosts.h"
        !            12: #include "sr.h"
        !            13: #include <scsi/scsi_ioctl.h>
        !            14: 
        !            15: #include <linux/cdrom.h>
        !            16: 
        !            17: extern void get_sectorsize(int);
        !            18: extern void sr_photocd(struct inode *);
        !            19: 
        !            20: #define IOCTL_RETRIES 3
        !            21: /* The CDROM is fairly slow, so we need a little extra time */
        !            22: /* In fact, it is very slow if it has to spin up first */
        !            23: #define IOCTL_TIMEOUT 3000
        !            24: 
        !            25: static void sr_ioctl_done(Scsi_Cmnd * SCpnt)
        !            26: {
        !            27:     struct request * req;
        !            28:     
        !            29:     req = &SCpnt->request;
        !            30:     req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
        !            31:     
        !            32:     if (req->sem != NULL) {
        !            33:        up(req->sem);
        !            34:     }
        !            35: }
        !            36: 
        !            37: /* We do our own retries because we want to know what the specific
        !            38:    error code is.  Normally the UNIT_ATTENTION code will automatically
        !            39:    clear after one error */
        !            40: 
        !            41: static int do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned buflength)
        !            42: {
        !            43:     Scsi_Cmnd * SCpnt;
        !            44:     int result;
        !            45: 
        !            46:     SCpnt = allocate_device(NULL, scsi_CDs[target].device, 1);
        !            47:     {
        !            48:        struct semaphore sem = MUTEX_LOCKED;
        !            49:        SCpnt->request.sem = &sem;
        !            50:        scsi_do_cmd(SCpnt,
        !            51:                    (void *) sr_cmd, buffer, buflength, sr_ioctl_done, 
        !            52:                    IOCTL_TIMEOUT, IOCTL_RETRIES);
        !            53:        down(&sem);
        !            54:     }
        !            55:     
        !            56:     result = SCpnt->result;
        !            57:     
        !            58:     /* Minimal error checking.  Ignore cases we know about, and report the rest. */
        !            59:     if(driver_byte(result) != 0)
        !            60:        switch(SCpnt->sense_buffer[2] & 0xf) {
        !            61:        case UNIT_ATTENTION:
        !            62:            scsi_CDs[target].device->changed = 1;
        !            63:            printk("Disc change detected.\n");
        !            64:            break;
        !            65:        case NOT_READY: /* This happens if there is no disc in drive */
        !            66:            printk("CDROM not ready.  Make sure there is a disc in the drive.\n");
        !            67:            break;
        !            68:        case ILLEGAL_REQUEST:
        !            69:          /* CDROMCLOSETRAY should not print an error for caddy drives. */
        !            70:            if (!(sr_cmd[0] == START_STOP && sr_cmd[4] == 0x03))
        !            71:              printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n");
        !            72:            break;
        !            73:        default:
        !            74:            printk("SCSI CD error: host %d id %d lun %d return code = %03x\n", 
        !            75:                   scsi_CDs[target].device->host->host_no, 
        !            76:                   scsi_CDs[target].device->id,
        !            77:                   scsi_CDs[target].device->lun,
        !            78:                   result);
        !            79:            printk("\tSense class %x, sense error %x, extended sense %x\n",
        !            80:                   sense_class(SCpnt->sense_buffer[0]), 
        !            81:                   sense_error(SCpnt->sense_buffer[0]),
        !            82:                   SCpnt->sense_buffer[2] & 0xf);
        !            83:            
        !            84:        };
        !            85:     
        !            86:     result = SCpnt->result;
        !            87:     SCpnt->request.rq_status = RQ_INACTIVE; /* Deallocate */
        !            88:     wake_up(&SCpnt->device->device_wait);
        !            89:     /* Wake up a process waiting for device*/
        !            90:     return result;
        !            91: }
        !            92: 
        !            93: int sr_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
        !            94: {
        !            95:     u_char  sr_cmd[10];
        !            96:     
        !            97:     kdev_t dev = inode->i_rdev;
        !            98:     int result, target, err;
        !            99:     
        !           100:     target = MINOR(dev);
        !           101:     
        !           102:     if (target >= sr_template.nr_dev ||
        !           103:        !scsi_CDs[target].device) return -ENXIO;
        !           104:     
        !           105:     switch (cmd) 
        !           106:     {
        !           107:        /* Sun-compatible */
        !           108:     case CDROMPAUSE:
        !           109:        
        !           110:        sr_cmd[0] = SCMD_PAUSE_RESUME;
        !           111:        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        !           112:        sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
        !           113:        sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
        !           114:        sr_cmd[8] = 0;
        !           115:        sr_cmd[9] = 0;
        !           116:        
        !           117:        result = do_ioctl(target, sr_cmd, NULL, 255);
        !           118:        return result;
        !           119:        
        !           120:     case CDROMRESUME:
        !           121:        
        !           122:        sr_cmd[0] = SCMD_PAUSE_RESUME;
        !           123:        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        !           124:        sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
        !           125:        sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
        !           126:        sr_cmd[8] = 1;
        !           127:        sr_cmd[9] = 0;
        !           128:        
        !           129:        result = do_ioctl(target, sr_cmd, NULL, 255);
        !           130:        
        !           131:        return result;
        !           132:        
        !           133:     case CDROMPLAYMSF:
        !           134:     {
        !           135:        struct cdrom_msf msf;
        !           136: 
        !           137:         err = verify_area (VERIFY_READ, (void *) arg, sizeof (msf));
        !           138:         if (err) return err;
        !           139: 
        !           140:        memcpy_fromfs(&msf, (void *) arg, sizeof(msf));
        !           141:        
        !           142:        sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
        !           143:        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        !           144:        sr_cmd[2] = 0;
        !           145:        sr_cmd[3] = msf.cdmsf_min0;
        !           146:        sr_cmd[4] = msf.cdmsf_sec0;
        !           147:        sr_cmd[5] = msf.cdmsf_frame0;
        !           148:        sr_cmd[6] = msf.cdmsf_min1;
        !           149:        sr_cmd[7] = msf.cdmsf_sec1;
        !           150:        sr_cmd[8] = msf.cdmsf_frame1;
        !           151:        sr_cmd[9] = 0;
        !           152:        
        !           153:        result = do_ioctl(target, sr_cmd, NULL, 255);
        !           154:        return result;
        !           155:     }
        !           156: 
        !           157:     case CDROMPLAYBLK:
        !           158:     {
        !           159:        struct cdrom_blk blk;
        !           160: 
        !           161:         err = verify_area (VERIFY_READ, (void *) arg, sizeof (blk));
        !           162:         if (err) return err;
        !           163: 
        !           164:        memcpy_fromfs(&blk, (void *) arg, sizeof(blk));
        !           165:        
        !           166:        sr_cmd[0] = SCMD_PLAYAUDIO10;
        !           167:        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        !           168:        sr_cmd[2] = blk.from >> 24;
        !           169:        sr_cmd[3] = blk.from >> 16;
        !           170:        sr_cmd[4] = blk.from >> 8;
        !           171:        sr_cmd[5] = blk.from;
        !           172:        sr_cmd[6] = 0;
        !           173:        sr_cmd[7] = blk.len >> 8;
        !           174:        sr_cmd[8] = blk.len;
        !           175:        sr_cmd[9] = 0;
        !           176:        
        !           177:        result = do_ioctl(target, sr_cmd, NULL, 255);
        !           178:        return result;
        !           179:     }
        !           180:                
        !           181:     case CDROMPLAYTRKIND:
        !           182:     {
        !           183:        struct cdrom_ti ti;
        !           184: 
        !           185:         err = verify_area (VERIFY_READ, (void *) arg, sizeof (ti));
        !           186:         if (err) return err;
        !           187: 
        !           188:        memcpy_fromfs(&ti, (void *) arg, sizeof(ti));
        !           189:        
        !           190:        sr_cmd[0] = SCMD_PLAYAUDIO_TI;
        !           191:        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        !           192:        sr_cmd[2] = 0;
        !           193:        sr_cmd[3] = 0;
        !           194:        sr_cmd[4] = ti.cdti_trk0;
        !           195:        sr_cmd[5] = ti.cdti_ind0;
        !           196:        sr_cmd[6] = 0;
        !           197:        sr_cmd[7] = ti.cdti_trk1;
        !           198:        sr_cmd[8] = ti.cdti_ind1;
        !           199:        sr_cmd[9] = 0;
        !           200:        
        !           201:        result = do_ioctl(target, sr_cmd, NULL, 255);
        !           202:        
        !           203:        return result;
        !           204:     }
        !           205:        
        !           206:     case CDROMREADTOCHDR:
        !           207:     {
        !           208:        struct cdrom_tochdr tochdr;
        !           209:        char * buffer;
        !           210:        
        !           211:        sr_cmd[0] = SCMD_READ_TOC;
        !           212:        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5);
        !           213:        sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
        !           214:        sr_cmd[6] = 0;
        !           215:        sr_cmd[7] = 0;              /* MSB of length (12) */
        !           216:        sr_cmd[8] = 12;             /* LSB of length */
        !           217:        sr_cmd[9] = 0;
        !           218:        
        !           219:        buffer = (unsigned char *) scsi_malloc(512);
        !           220:        if(!buffer) return -ENOMEM;
        !           221:        
        !           222:        result = do_ioctl(target, sr_cmd, buffer, 12);
        !           223:        
        !           224:        tochdr.cdth_trk0 = buffer[2];
        !           225:        tochdr.cdth_trk1 = buffer[3];
        !           226:        
        !           227:        scsi_free(buffer, 512);
        !           228:        
        !           229:        err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_tochdr));
        !           230:        if (err)
        !           231:            return err;
        !           232:        memcpy_tofs ((void *) arg, &tochdr, sizeof (struct cdrom_tochdr));
        !           233:        
        !           234:        return result;
        !           235:     }
        !           236:        
        !           237:     case CDROMREADTOCENTRY:
        !           238:     {
        !           239:        struct cdrom_tocentry tocentry;
        !           240:        unsigned char * buffer;
        !           241:        
        !           242:         err = verify_area (VERIFY_READ, (void *) arg, sizeof (struct cdrom_tocentry));
        !           243:         if (err) return err;
        !           244: 
        !           245:        memcpy_fromfs (&tocentry, (void *) arg, sizeof (struct cdrom_tocentry));
        !           246:        
        !           247:        sr_cmd[0] = SCMD_READ_TOC;
        !           248:        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) |
        !           249:           (tocentry.cdte_format == CDROM_MSF ? 0x02 : 0);
        !           250:        sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
        !           251:        sr_cmd[6] = tocentry.cdte_track;
        !           252:        sr_cmd[7] = 0;             /* MSB of length (12)  */
        !           253:        sr_cmd[8] = 12;            /* LSB of length */
        !           254:        sr_cmd[9] = 0;
        !           255:        
        !           256:        buffer = (unsigned char *) scsi_malloc(512);
        !           257:        if(!buffer) return -ENOMEM;
        !           258:        
        !           259:        result = do_ioctl (target, sr_cmd, buffer, 12);
        !           260:        
        !           261:         tocentry.cdte_ctrl = buffer[5] & 0xf;  
        !           262:         tocentry.cdte_adr = buffer[5] >> 4;
        !           263:         tocentry.cdte_datamode = (tocentry.cdte_ctrl & 0x04) ? 1 : 0;
        !           264:        if (tocentry.cdte_format == CDROM_MSF) {
        !           265:            tocentry.cdte_addr.msf.minute = buffer[9];
        !           266:            tocentry.cdte_addr.msf.second = buffer[10];
        !           267:            tocentry.cdte_addr.msf.frame = buffer[11];
        !           268:        }
        !           269:        else
        !           270:            tocentry.cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)
        !           271:                                        + buffer[10]) << 8) + buffer[11];
        !           272:        
        !           273:        scsi_free(buffer, 512);
        !           274:        
        !           275:        err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_tocentry));
        !           276:        if (err)
        !           277:            return err;
        !           278:        memcpy_tofs ((void *) arg, &tocentry, sizeof (struct cdrom_tocentry));
        !           279:        
        !           280:        return result;
        !           281:     }
        !           282:        
        !           283:     case CDROMSTOP:
        !           284:        sr_cmd[0] = START_STOP;
        !           285:        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
        !           286:        sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
        !           287:        sr_cmd[4] = 0;
        !           288:        
        !           289:        result = do_ioctl(target, sr_cmd, NULL, 255);
        !           290:        return result;
        !           291:        
        !           292:     case CDROMSTART:
        !           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(target, sr_cmd, NULL, 255);
        !           299:        return result;
        !           300:        
        !           301:     case CDROMCLOSETRAY:
        !           302:        sr_cmd[0] = START_STOP;
        !           303:        sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5);
        !           304:        sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
        !           305:        sr_cmd[4] = 0x03;
        !           306:        
        !           307:         if ((result = do_ioctl(target, sr_cmd, NULL, 255)))
        !           308:           return result;
        !           309: 
        !           310:         /* Gather information about newly inserted disc */
        !           311:         check_disk_change (inode->i_rdev);
        !           312:         sr_ioctl (inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
        !           313:         sr_photocd (inode);
        !           314: 
        !           315:         if (scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)
        !           316:           get_sectorsize (MINOR(inode->i_rdev));
        !           317: 
        !           318:         return 0;
        !           319: 
        !           320:     case CDROMEJECT:
        !           321:         /*
        !           322:          * Allow 0 for access count for auto-eject feature.
        !           323:          */
        !           324:        if (scsi_CDs[target].device -> access_count > 1)
        !           325:            return -EBUSY;
        !           326:        
        !           327:        sr_ioctl (inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
        !           328:        sr_cmd[0] = START_STOP;
        !           329:        sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5) | 1;
        !           330:        sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
        !           331:        sr_cmd[4] = 0x02;
        !           332:        
        !           333:        if (!(result = do_ioctl(target, sr_cmd, NULL, 255)))
        !           334:            scsi_CDs[target].device -> changed = 1;
        !           335:        
        !           336:        return result;
        !           337:        
        !           338:     case CDROMEJECT_SW:
        !           339:         scsi_CDs[target].auto_eject = !!arg;
        !           340:         return 0;
        !           341: 
        !           342:     case CDROMVOLCTRL:
        !           343:     {
        !           344:        char * buffer, * mask;
        !           345:        struct cdrom_volctrl volctrl;
        !           346:        
        !           347:         err = verify_area (VERIFY_READ, (void *) arg, sizeof (struct cdrom_volctrl));
        !           348:         if (err) return err;
        !           349: 
        !           350:        memcpy_fromfs (&volctrl, (void *) arg, sizeof (struct cdrom_volctrl));
        !           351:        
        !           352:        /* First we get the current params so we can just twiddle the volume */
        !           353:        
        !           354:        sr_cmd[0] = MODE_SENSE;
        !           355:        sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5;
        !           356:        sr_cmd[2] = 0xe;    /* Want mode page 0xe, CDROM audio params */
        !           357:        sr_cmd[3] = 0;
        !           358:        sr_cmd[4] = 28;
        !           359:        sr_cmd[5] = 0;
        !           360:        
        !           361:        buffer = (unsigned char *) scsi_malloc(512);
        !           362:        if(!buffer) return -ENOMEM;
        !           363:        
        !           364:        if ((result = do_ioctl (target, sr_cmd, buffer, 28))) {
        !           365:            printk ("Hosed while obtaining audio mode page\n");
        !           366:            scsi_free(buffer, 512);
        !           367:            return result;
        !           368:        }
        !           369:        
        !           370:        sr_cmd[0] = MODE_SENSE;
        !           371:        sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5;
        !           372:        sr_cmd[2] = 0x4e;   /* Want the mask for mode page 0xe */
        !           373:        sr_cmd[3] = 0;
        !           374:        sr_cmd[4] = 28;
        !           375:        sr_cmd[5] = 0;
        !           376:        
        !           377:        mask = (unsigned char *) scsi_malloc(512);
        !           378:        if(!mask) {
        !           379:            scsi_free(buffer, 512);
        !           380:            return -ENOMEM;
        !           381:        };
        !           382: 
        !           383:        if ((result = do_ioctl (target, sr_cmd, mask, 28))) {
        !           384:            printk ("Hosed while obtaining mask for audio mode page\n");
        !           385:            scsi_free(buffer, 512);
        !           386:            scsi_free(mask, 512);
        !           387:            return result;
        !           388:        }
        !           389:        
        !           390:        /* Now mask and substitute our own volume and reuse the rest */
        !           391:        buffer[0] = 0;  /* Clear reserved field */
        !           392:        
        !           393:        buffer[21] = volctrl.channel0 & mask[21];
        !           394:        buffer[23] = volctrl.channel1 & mask[23];
        !           395:        buffer[25] = volctrl.channel2 & mask[25];
        !           396:        buffer[27] = volctrl.channel3 & mask[27];
        !           397:        
        !           398:        sr_cmd[0] = MODE_SELECT;
        !           399:        sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5) | 0x10;    /* Params are SCSI-2 */
        !           400:        sr_cmd[2] = sr_cmd[3] = 0;
        !           401:        sr_cmd[4] = 28;
        !           402:        sr_cmd[5] = 0;
        !           403:        
        !           404:        result = do_ioctl (target, sr_cmd, buffer, 28);
        !           405:        scsi_free(buffer, 512);
        !           406:        scsi_free(mask, 512);
        !           407:        return result;
        !           408:     }
        !           409:        
        !           410:     case CDROMVOLREAD:
        !           411:     {
        !           412:        char * buffer;
        !           413:        struct cdrom_volctrl volctrl;
        !           414:        
        !           415:         err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_volctrl));
        !           416:         if (err) return err;
        !           417:        
        !           418:        /* Get the current params */
        !           419:        
        !           420:        sr_cmd[0] = MODE_SENSE;
        !           421:        sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5;
        !           422:        sr_cmd[2] = 0xe;    /* Want mode page 0xe, CDROM audio params */
        !           423:        sr_cmd[3] = 0;
        !           424:        sr_cmd[4] = 28;
        !           425:        sr_cmd[5] = 0;
        !           426:        
        !           427:        buffer = (unsigned char *) scsi_malloc(512);
        !           428:        if(!buffer) return -ENOMEM;
        !           429:        
        !           430:        if ((result = do_ioctl (target, sr_cmd, buffer, 28))) {
        !           431:            printk ("(CDROMVOLREAD) Hosed while obtaining audio mode page\n");
        !           432:            scsi_free(buffer, 512);
        !           433:            return result;
        !           434:        }
        !           435: 
        !           436:        volctrl.channel0 = buffer[21];
        !           437:        volctrl.channel1 = buffer[23];
        !           438:        volctrl.channel2 = buffer[25];
        !           439:        volctrl.channel3 = buffer[27];
        !           440: 
        !           441:        memcpy_tofs ((void *) arg, &volctrl, sizeof (struct cdrom_volctrl));
        !           442: 
        !           443:        scsi_free(buffer, 512);
        !           444: 
        !           445:        return 0;
        !           446:     }
        !           447:        
        !           448:     case CDROMSUBCHNL:
        !           449:     {
        !           450:        struct cdrom_subchnl subchnl;
        !           451:        char * buffer;
        !           452:        
        !           453:        sr_cmd[0] = SCMD_READ_SUBCHANNEL;
        !           454:        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 0x02;    /* MSF format */
        !           455:        sr_cmd[2] = 0x40;    /* I do want the subchannel info */
        !           456:        sr_cmd[3] = 0x01;    /* Give me current position info */
        !           457:        sr_cmd[4] = sr_cmd[5] = 0;
        !           458:        sr_cmd[6] = 0;
        !           459:        sr_cmd[7] = 0;
        !           460:        sr_cmd[8] = 16;
        !           461:        sr_cmd[9] = 0;
        !           462:        
        !           463:        buffer = (unsigned char*) scsi_malloc(512);
        !           464:        if(!buffer) return -ENOMEM;
        !           465:        
        !           466:        result = do_ioctl(target, sr_cmd, buffer, 16);
        !           467:        
        !           468:        subchnl.cdsc_audiostatus = buffer[1];
        !           469:        subchnl.cdsc_format = CDROM_MSF;
        !           470:        subchnl.cdsc_ctrl = buffer[5] & 0xf;
        !           471:        subchnl.cdsc_trk = buffer[6];
        !           472:        subchnl.cdsc_ind = buffer[7];
        !           473:        
        !           474:        subchnl.cdsc_reladdr.msf.minute = buffer[13];
        !           475:        subchnl.cdsc_reladdr.msf.second = buffer[14];
        !           476:        subchnl.cdsc_reladdr.msf.frame = buffer[15];
        !           477:        subchnl.cdsc_absaddr.msf.minute = buffer[9];
        !           478:        subchnl.cdsc_absaddr.msf.second = buffer[10];
        !           479:        subchnl.cdsc_absaddr.msf.frame = buffer[11];
        !           480:        
        !           481:        scsi_free(buffer, 512);
        !           482:        
        !           483:        err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_subchnl));
        !           484:        if (err)
        !           485:            return err;
        !           486:        memcpy_tofs ((void *) arg, &subchnl, sizeof (struct cdrom_subchnl));
        !           487:        return result;
        !           488:     }
        !           489:        
        !           490:     case CDROM_GET_UPC:
        !           491:     {
        !           492:        struct cdrom_mcn mcn;
        !           493:        char * buffer;
        !           494:        
        !           495:        sr_cmd[0] = SCMD_READ_SUBCHANNEL;
        !           496:        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5);
        !           497:        sr_cmd[2] = 0x40;    /* I do want the subchannel info */
        !           498:        sr_cmd[3] = 0x02;    /* Give me medium catalog number info */
        !           499:        sr_cmd[4] = sr_cmd[5] = 0;
        !           500:        sr_cmd[6] = 0;
        !           501:        sr_cmd[7] = 0;
        !           502:        sr_cmd[8] = 24;
        !           503:        sr_cmd[9] = 0;
        !           504:        
        !           505:        buffer = (unsigned char*) scsi_malloc(512);
        !           506:        if(!buffer) return -ENOMEM;
        !           507:        
        !           508:        result = do_ioctl(target, sr_cmd, buffer, 24);
        !           509:        
        !           510:        memcpy (mcn.medium_catalog_number, buffer + 9, 13);
        !           511:         mcn.medium_catalog_number[13] = 0;
        !           512: 
        !           513:        scsi_free(buffer, 512);
        !           514:        
        !           515:        err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_mcn));
        !           516:        if (err)
        !           517:            return err;
        !           518:        memcpy_tofs ((void *) arg, &mcn, sizeof (struct cdrom_mcn));
        !           519:        return result;
        !           520:     }
        !           521:        
        !           522:     /* these are compatible with the ide-cd driver */
        !           523:     case CDROMREADRAW:
        !           524:     case CDROMREADMODE1:
        !           525:     case CDROMREADMODE2:
        !           526:        return -EINVAL;
        !           527:        
        !           528:        /* block-copy from ../block/sbpcd.c with some adjustments... */
        !           529:     case CDROMMULTISESSION: /* tell start-of-last-session to user */
        !           530:     {
        !           531:        struct cdrom_multisession  ms_info;
        !           532:        long                       lba;
        !           533:        
        !           534:        err = verify_area(VERIFY_READ, (void *) arg,
        !           535:                          sizeof(struct cdrom_multisession));
        !           536:        if (err) return (err);
        !           537:        
        !           538:        memcpy_fromfs(&ms_info, (void *) arg, sizeof(struct cdrom_multisession));
        !           539:        
        !           540:        if (ms_info.addr_format==CDROM_MSF) { /* MSF-bin requested */
        !           541:            lba = scsi_CDs[target].mpcd_sector+CD_BLOCK_OFFSET;
        !           542:            ms_info.addr.msf.minute = lba / (CD_SECS*CD_FRAMES);
        !           543:            lba %= CD_SECS*CD_FRAMES;
        !           544:            ms_info.addr.msf.second = lba / CD_FRAMES;
        !           545:            ms_info.addr.msf.frame  = lba % CD_FRAMES;
        !           546:        } else if (ms_info.addr_format==CDROM_LBA) /* lba requested */
        !           547:            ms_info.addr.lba=scsi_CDs[target].mpcd_sector;
        !           548:        else return (-EINVAL);
        !           549:        
        !           550:        ms_info.xa_flag=scsi_CDs[target].xa_flags & 0x01;
        !           551:        
        !           552:        err=verify_area(VERIFY_WRITE,(void *) arg,
        !           553:                        sizeof(struct cdrom_multisession));
        !           554:        if (err) return (err);
        !           555:        
        !           556:        memcpy_tofs((void *) arg, &ms_info, sizeof(struct cdrom_multisession));
        !           557:        return (0);
        !           558:     }
        !           559:        
        !           560:     case BLKRAGET:
        !           561:        if (!arg)
        !           562:                return -EINVAL;
        !           563:        err = verify_area(VERIFY_WRITE, (int *) arg, sizeof(int));
        !           564:        if (err)
        !           565:                return err;
        !           566:        put_user(read_ahead[MAJOR(inode->i_rdev)], (int *) arg);
        !           567:        return 0;
        !           568: 
        !           569:     case BLKRASET:
        !           570:        if(!suser())
        !           571:                return -EACCES;
        !           572:        if(!(inode->i_rdev))
        !           573:                return -EINVAL;
        !           574:        if(arg > 0xff)
        !           575:                return -EINVAL;
        !           576:        read_ahead[MAJOR(inode->i_rdev)] = arg;
        !           577:        return 0;
        !           578: 
        !           579:     RO_IOCTLS(dev,arg);
        !           580: 
        !           581:     case CDROMRESET:
        !           582:        invalidate_buffers(inode->i_rdev);
        !           583:        return 0;
        !           584: 
        !           585:     default:
        !           586:        return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
        !           587:     }
        !           588: }
        !           589: 
        !           590: /*
        !           591:  * Overrides for Emacs so that we follow Linus's tabbing style.
        !           592:  * Emacs will notice this stuff at the end of the file and automatically
        !           593:  * adjust the settings for this buffer only.  This must remain at the end
        !           594:  * of the file.
        !           595:  * ---------------------------------------------------------------------------
        !           596:  * Local variables:
        !           597:  * c-indent-level: 4
        !           598:  * c-brace-imaginary-offset: 0
        !           599:  * c-brace-offset: -4
        !           600:  * c-argdecl-indent: 4
        !           601:  * c-label-offset: -4
        !           602:  * c-continued-statement-offset: 4
        !           603:  * c-continued-brace-offset: 0
        !           604:  * indent-tabs-mode: nil
        !           605:  * tab-width: 8
        !           606:  * End:
        !           607:  */

unix.superglobalmegacorp.com

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