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

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: {
1.1.1.2 ! root       95:     u_char  sr_cmd[12];
1.1       root       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.