Annotation of linux/kernel/blk_drv/scsi/sr.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *      sr.c by David Giller
                      3:  *
                      4:  *      adapted from:
                      5:  *     sd.c Copyright (C) 1992 Drew Eckhardt 
                      6:  *     Linux scsi disk driver by
                      7:  *             Drew Eckhardt 
                      8:  *
                      9:  *     <[email protected]>
                     10:  */
                     11: 
                     12: #include <linux/config.h>
                     13: 
                     14: #ifdef CONFIG_BLK_DEV_SR
                     15: 
                     16: #include <linux/fs.h>
                     17: #include <linux/kernel.h>
                     18: #include <linux/sched.h>
                     19: #include <linux/string.h>
                     20: 
                     21: #include "scsi.h"
                     22: #include "sr.h"
                     23: 
                     24: #define MAJOR_NR 11
                     25: 
                     26: #include "../blk.h"
                     27: 
                     28: #define MAX_RETRIES 0
                     29: #define SR_TIMEOUT 200
                     30: 
                     31: int NR_SR=0;
                     32: Scsi_CD scsi_CDs[MAX_SR];
                     33: static int sr_sizes[MAX_SR << 4];
                     34: static unsigned long int this_count;
                     35: 
                     36: struct block_buffer
                     37:        {
                     38:        unsigned        block;
                     39:        unsigned        start;
                     40:        unsigned        use:1;
                     41:        unsigned char   buffer[2048];
                     42:        };
                     43: 
                     44: static struct block_buffer bb[MAX_SR];
                     45: 
                     46: static int sr_result;
                     47: 
                     48: static int sr_open(struct inode *, struct file *);
                     49: 
                     50: extern int sr_ioctl(struct inode *, struct file *, unsigned int, unsigned int);
                     51: 
                     52: static void sr_release(struct inode * inode, struct file * file)
                     53: {
                     54:        sync_dev(inode->i_rdev);
                     55: }
                     56: 
                     57: static struct file_operations sr_fops = 
                     58: {
                     59:        NULL,                   /* lseek - default */
                     60:        block_read,             /* read - general block-dev read */
                     61:        block_write,            /* write - general block-dev write */
                     62:        NULL,                   /* readdir - bad */
                     63:        NULL,                   /* select */
                     64:        sr_ioctl,               /* ioctl */
                     65:        sr_open,                /* no special open code */
                     66:        sr_release              /* release */
                     67: };
                     68: 
                     69: /*
                     70:  * The sense_buffer is where we put data for all mode sense commands performed.
                     71:  */
                     72: 
                     73: static unsigned char sense_buffer[255];
                     74: 
                     75: /*
                     76:  * rw_intr is the interrupt routine for the device driver.  It will be notified on the 
                     77:  * end of a SCSI read / write, and will take on of several actions based on success or failure.
                     78:  */
                     79: 
                     80: static void rw_intr (int host, int result)
                     81: {
                     82:        if (SR_HOST != host)            
                     83:                {
                     84:                panic ("sr.o : rw_intr() recieving interrupt for different host.");
                     85:                }
                     86: 
                     87:        if (!result)
                     88:                { /* No error */
                     89:                if (bb[DEVICE_NR(CURRENT->dev)].use)
                     90:                        {
                     91:                        memcpy((char *)CURRENT->buffer, 
                     92:                               bb[DEVICE_NR(CURRENT->dev)].buffer + 
                     93:                               (bb[DEVICE_NR(CURRENT->dev)].start << 9), 
                     94:                               this_count << 9);
                     95:                        }
                     96: 
                     97:                CURRENT->nr_sectors -= this_count;
                     98: 
                     99: #ifdef DEBUG
                    100:                printk("(%x %x %x) ",CURRENT->bh, CURRENT->nr_sectors, 
                    101:                       this_count);
                    102: #endif
                    103:                if (CURRENT->nr_sectors)
                    104:                        {        
                    105:                        CURRENT->sector += this_count;
                    106:                        CURRENT->errors = 0;
                    107:                        if (!CURRENT->bh)
                    108:                          {
                    109:                            (char *) CURRENT->buffer += this_count << 9;
                    110:                          } else {
                    111:                            end_request(1);
                    112:                            do_sr_request();
                    113:                          }
                    114:                        }
                    115:                else 
                    116:                        {
                    117:                        end_request(1);  /* All done */
                    118:                        do_sr_request();
                    119:                        } 
                    120:                }
                    121: 
                    122:        /* We only come through here if we have an error of some kind */
                    123: 
                    124:        if (driver_byte(result) != 0) {
                    125:                bb[DEVICE_NR(CURRENT->dev)].block = -1;
                    126:                
                    127:                if ((sense_buffer[0] & 0x7f) == 0x70) {
                    128:                        if ((sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
                    129:                                /* detected disc change.  set a bit and quietly refuse  */
                    130:                                /* further access.                                      */
                    131:                    
                    132:                                scsi_CDs[DEVICE_NR(CURRENT->dev)].changed = 1;
                    133:                                end_request(0);
                    134:                                return;
                    135:                        }
                    136:                }
                    137:            
                    138:                if (sense_buffer[2] == ILLEGAL_REQUEST) {
                    139:                        printk("CD-ROM error: Drive reports ILLEGAL REQUEST.\n");
                    140:                        if (scsi_CDs[DEVICE_NR(CURRENT->dev)].ten) {
                    141:                                scsi_CDs[DEVICE_NR(CURRENT->dev)].ten = 0;
                    142:                                do_sr_request();
                    143:                                result = 0;
                    144:                                return;
                    145:                        } else {
                    146:                                end_request(0);
                    147:                                do_sr_request(); /* Do next request */
                    148:                                return;
                    149:                        }
                    150: 
                    151:                }
                    152: 
                    153:                if (sense_buffer[2] == NOT_READY) {
                    154:                        printk("CDROM not ready.  Make sure you have a disc in the drive.\n");
                    155:                        end_request(0);
                    156:                        do_sr_request(); /* Do next request */
                    157:                        return;
                    158:                };
                    159:              }
                    160:        
                    161:        /* We only get this far if we have an error we have not recognized */
                    162:        if(result) {
                    163:          printk("SCSI CD error : host %d id %d lun %d return code = %03x\n", 
                    164:                 scsi_CDs[DEVICE_NR(CURRENT->dev)].device->host_no, 
                    165:                 scsi_CDs[DEVICE_NR(CURRENT->dev)].device->id,
                    166:                 scsi_CDs[DEVICE_NR(CURRENT->dev)].device->lun,
                    167:                 result);
                    168:            
                    169:        if (status_byte(result) == CHECK_CONDITION)
                    170:            printk("\tSense class %x, sense error %x, extended sense %x\n",
                    171:                 sense_class(sense_buffer[0]), 
                    172:                 sense_error(sense_buffer[0]),
                    173:                 sense_buffer[2] & 0xf);
                    174:        
                    175:        end_request(0);
                    176:        do_sr_request();
                    177:        }
                    178: }
                    179: 
                    180: static int sr_open(struct inode * inode, struct file * filp)
                    181: {
                    182:        if (filp->f_mode)
                    183:                check_disk_change(inode->i_rdev);
                    184:        return 0;
                    185: }
                    186: 
                    187: /*
                    188:  * do_sr_request() is the request handler function for the sr driver.  Its function in life 
                    189:  * is to take block device requests, and translate them to SCSI commands.
                    190:  */
                    191:        
                    192: void do_sr_request (void)
                    193: {
                    194:        unsigned int dev, block, realcount;
                    195:        unsigned char cmd[10], *buffer, tries;
                    196: 
                    197:        tries = 2;
                    198: 
                    199:       repeat:
                    200:        INIT_REQUEST;
                    201:        dev =  MINOR(CURRENT->dev);
                    202:        block = CURRENT->sector;        
                    203: 
                    204:        bb[dev].start = block % 4;
                    205:        block = block / 4;
                    206: 
                    207:        if (dev >= NR_SR)
                    208:                {
                    209:                /* printk("CD-ROM request error: invalid device.\n");                   */
                    210:                end_request(0);
                    211:                tries = 2;
                    212:                goto repeat;
                    213:                }
                    214: 
                    215:        if (!scsi_CDs[dev].use)
                    216:                {
                    217:                /* printk("CD-ROM request error: device marked not in use.\n");         */
                    218:                end_request(0);
                    219:                tries = 2;
                    220:                goto repeat;
                    221:                }
                    222: 
                    223:        if (scsi_CDs[dev].changed)
                    224:                {
                    225: /* 
                    226:  * quietly refuse to do anything to a changed disc until the changed bit has been reset
                    227:  */
                    228:                /* printk("CD-ROM has been changed.  Prohibiting further I/O.\n");      */
                    229:                end_request(0);
                    230:                tries = 2;
                    231:                goto repeat;
                    232:                }
                    233:        
                    234:        if (!CURRENT->bh)       
                    235:                this_count = CURRENT->nr_sectors;
                    236:        else
                    237:                this_count = (CURRENT->bh->b_size / 512);
                    238: 
                    239:        if (bb[dev].start)
                    240:                {                                 
                    241:                bb[dev].use = 1;
                    242: 
                    243:                this_count = ((this_count > 4 - bb[dev].start) ? 
                    244:                              (4 - bb[dev].start) : (this_count));
                    245: 
                    246:                if (bb[dev].block == block)
                    247:                        {
                    248:                          rw_intr(SR_HOST, 0);
                    249:                          return;
                    250:                        }
                    251: 
                    252:                buffer = bb[dev].buffer;
                    253:                bb[dev].block = block;
                    254:                } 
                    255:        else if (this_count < 4)
                    256:                {
                    257:                bb[dev].use = 1;
                    258: 
                    259:                if (bb[dev].block == block)
                    260:                        {
                    261:                          rw_intr(SR_HOST, 0);
                    262:                          return;
                    263:                        }
                    264: 
                    265:                buffer = bb[dev].buffer;
                    266:                bb[dev].block = block;
                    267:                }
                    268:        else
                    269:                {
                    270:                this_count -= this_count % 4;
                    271:                buffer = CURRENT->buffer;
                    272:                bb[dev].use = 0;
                    273:                }
                    274: 
                    275:        realcount = (this_count + 3) / 4;
                    276: 
                    277:        switch (CURRENT->cmd)
                    278:                {
                    279:                case WRITE:             
                    280:                        end_request(0);
                    281:                        goto repeat;
                    282:                        break;
                    283:                case READ : 
                    284:                        cmd[0] = READ_6;
                    285:                        break;
                    286:                default : 
                    287:                        printk ("Unknown sr command %d\r\n", CURRENT->cmd);
                    288:                        panic("");
                    289:                }
                    290:        
                    291:        cmd[1] = (SR_LUN << 5) & 0xe0;
                    292: 
                    293:        if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten) 
                    294:                {
                    295:                if (realcount > 0xffff)
                    296:                        {
                    297:                        realcount = 0xffff;
                    298:                        this_count = realcount * 4;
                    299:                        }
                    300: 
                    301:                cmd[0] += READ_10 - READ_6 ;
                    302:                cmd[2] = (unsigned char) (block >> 24) & 0xff;
                    303:                cmd[3] = (unsigned char) (block >> 16) & 0xff;
                    304:                cmd[4] = (unsigned char) (block >> 8) & 0xff;
                    305:                cmd[5] = (unsigned char) block & 0xff;
                    306:                cmd[6] = cmd[9] = 0;
                    307:                cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
                    308:                cmd[8] = (unsigned char) realcount & 0xff;
                    309:                }
                    310:        else
                    311:                {
                    312:                if (realcount > 0xff)
                    313:                        {
                    314:                        realcount = 0xff;
                    315:                        this_count = realcount * 4;
                    316:                        }
                    317:        
                    318:                cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
                    319:                cmd[2] = (unsigned char) ((block >> 8) & 0xff);
                    320:                cmd[3] = (unsigned char) block & 0xff;
                    321:                cmd[4] = (unsigned char) realcount;
                    322:                cmd[5] = 0;
                    323:                }   
                    324: 
                    325:        scsi_do_cmd (SR_HOST, SR_ID, (void *) cmd, buffer, realcount << 11, 
                    326:                     rw_intr, SR_TIMEOUT, sense_buffer, MAX_RETRIES);
                    327: }
                    328: 
                    329: void sr_init(void)
                    330: {
                    331:        int i;
                    332: 
                    333:        for (i = 0; i < NR_SR; ++i)
                    334:                {
                    335:                scsi_CDs[i].capacity = 0x1fffff;
                    336:                scsi_CDs[i].sector_size = 2048;
                    337:                scsi_CDs[i].use = 1;
                    338:                scsi_CDs[i].ten = 1;
                    339:                scsi_CDs[i].remap = 1;
                    340:                scsi_CDs[i].changed = 0;
                    341:                sr_sizes[i] = scsi_CDs[i].capacity;
                    342: 
                    343:                bb[i].block = -1;
                    344:                }
                    345: 
                    346:        blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
                    347:        blk_size[MAJOR_NR] = sr_sizes;  
                    348:        blkdev_fops[MAJOR_NR] = &sr_fops; 
                    349: }      
                    350: #endif
                    351: 
                    352: 
                    353: 
                    354: 
                    355: 

unix.superglobalmegacorp.com

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