Annotation of Gnu-Mach/linux/src/drivers/scsi/scsi_ioctl.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Don't import our own symbols, as this would severely mess up our
                      3:  * symbol tables.
                      4:  */
                      5: #define _SCSI_SYMS_VER_
                      6: #define __NO_VERSION__
                      7: #include <linux/module.h>
                      8: 
                      9: #include <asm/io.h>
                     10: #include <asm/segment.h>
                     11: #include <asm/system.h>
                     12: #include <asm/page.h>
                     13: 
                     14: #include <linux/errno.h>
                     15: #include <linux/kernel.h>
                     16: #include <linux/sched.h>
                     17: #include <linux/mm.h>
                     18: #include <linux/string.h>
                     19: 
                     20: #include <linux/blk.h>
                     21: #include "scsi.h"
                     22: #include "hosts.h"
                     23: #include <scsi/scsi_ioctl.h>
                     24: 
                     25: #define NORMAL_RETRIES 5   
                     26: #define NORMAL_TIMEOUT (10 * HZ)
                     27: #define FORMAT_UNIT_TIMEOUT (2 * 60 * 60 * HZ)
                     28: #define START_STOP_TIMEOUT (60 * HZ)
                     29: #define MOVE_MEDIUM_TIMEOUT (5 * 60 * HZ)
                     30: #define READ_ELEMENT_STATUS_TIMEOUT (5 * 60 * HZ)
                     31: 
                     32: #define MAX_BUF PAGE_SIZE
                     33: 
                     34: #define max(a,b) (((a) > (b)) ? (a) : (b))
                     35: 
                     36: /*
                     37:  * If we are told to probe a host, we will return 0 if  the host is not
                     38:  * present, 1 if the host is present, and will return an identifying
                     39:  * string at *arg, if arg is non null, filling to the length stored at
                     40:  * (int *) arg
                     41:  */
                     42: 
                     43: static int ioctl_probe(struct Scsi_Host * host, void *buffer)
                     44: {
                     45:     int temp, result;
                     46:     unsigned int len,slen;
                     47:     const char * string;
                     48:     
                     49:     if ((temp = host->hostt->present) && buffer) {
                     50:         result = verify_area(VERIFY_READ, buffer, sizeof(long));
                     51:         if (result) return result;
                     52: 
                     53:        len = get_user ((unsigned int *) buffer);
                     54:        if(host->hostt->info)
                     55:            string = host->hostt->info(host);
                     56:        else 
                     57:            string = host->hostt->name;
                     58:        if(string) {
                     59:            slen = strlen(string);
                     60:            if (len > slen)
                     61:                len = slen + 1;
                     62:             result = verify_area(VERIFY_WRITE, buffer, len);
                     63:             if (result) return result;
                     64: 
                     65:            memcpy_tofs (buffer, string, len);
                     66:        }
                     67:     }
                     68:     return temp;
                     69: }
                     70: 
                     71: /*
                     72:  * 
                     73:  * The SCSI_IOCTL_SEND_COMMAND ioctl sends a command out to the SCSI host.
                     74:  * The NORMAL_TIMEOUT and NORMAL_RETRIES  variables are used.  
                     75:  * 
                     76:  * dev is the SCSI device struct ptr, *(int *) arg is the length of the
                     77:  * input data, if any, not including the command string & counts, 
                     78:  * *((int *)arg + 1) is the output buffer size in bytes.
                     79:  * 
                     80:  * *(char *) ((int *) arg)[2] the actual command byte.   
                     81:  * 
                     82:  * Note that if more than MAX_BUF bytes are requested to be transfered,
                     83:  * the ioctl will fail with error EINVAL.  MAX_BUF can be increased in
                     84:  * the future by increasing the size that scsi_malloc will accept.
                     85:  * 
                     86:  * This size *does not* include the initial lengths that were passed.
                     87:  * 
                     88:  * The SCSI command is read from the memory location immediately after the
                     89:  * length words, and the input data is right after the command.  The SCSI
                     90:  * routines know the command size based on the opcode decode.  
                     91:  * 
                     92:  * The output area is then filled in starting from the command byte. 
                     93:  */
                     94: 
                     95: static void scsi_ioctl_done (Scsi_Cmnd * SCpnt)
                     96: {
                     97:     struct request * req;
                     98:     
                     99:     req = &SCpnt->request;
                    100:     req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
                    101:     
                    102:     if (req->sem != NULL) {
                    103:        up(req->sem);
                    104:     }
                    105: }   
                    106: 
                    107: static int ioctl_internal_command(Scsi_Device *dev, char * cmd,
                    108:                                  int timeout, int retries)
                    109: {
                    110:     int result;
                    111:     Scsi_Cmnd * SCpnt;
                    112:     
                    113:     SCpnt = allocate_device(NULL, dev, 1);
                    114:     {
                    115:        struct semaphore sem = MUTEX_LOCKED;
                    116:        SCpnt->request.sem = &sem;
                    117:        scsi_do_cmd(SCpnt,  cmd, NULL,  0, scsi_ioctl_done,  timeout, retries);
                    118:        down(&sem);
                    119:     }
                    120:     
                    121:     if(driver_byte(SCpnt->result) != 0)
                    122:        switch(SCpnt->sense_buffer[2] & 0xf) {
                    123:        case ILLEGAL_REQUEST:
                    124:            if(cmd[0] == ALLOW_MEDIUM_REMOVAL) dev->lockable = 0;
                    125:            else printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
                    126:            break;
                    127:        case NOT_READY: /* This happens if there is no disc in drive */
                    128:            if(dev->removable){
                    129:                printk(KERN_INFO "Device not ready.  Make sure there is a disc in the drive.\n");
                    130:                break;
                    131:            };
                    132:        case UNIT_ATTENTION:
                    133:            if (dev->removable){
                    134:                dev->changed = 1;
                    135:                SCpnt->result = 0; /* This is no longer considered an error */
                    136:                printk(KERN_INFO "Disc change detected.\n");
                    137:                break;
                    138:            };
                    139:        default: /* Fall through for non-removable media */
                    140:            printk("SCSI error: host %d id %d lun %d return code = %x\n",
                    141:                   dev->host->host_no,
                    142:                   dev->id,
                    143:                   dev->lun,
                    144:                   SCpnt->result);
                    145:            printk("\tSense class %x, sense error %x, extended sense %x\n",
                    146:                   sense_class(SCpnt->sense_buffer[0]),
                    147:                   sense_error(SCpnt->sense_buffer[0]),
                    148:                   SCpnt->sense_buffer[2] & 0xf);
                    149:            
                    150:        };
                    151:     
                    152:     result = SCpnt->result;
                    153:     SCpnt->request.rq_status = RQ_INACTIVE;
                    154: 
                    155:     if (!SCpnt->device->was_reset && SCpnt->device->scsi_request_fn)
                    156:        (*SCpnt->device->scsi_request_fn)();
                    157: 
                    158:     wake_up(&SCpnt->device->device_wait);
                    159:     return result;
                    160: }
                    161: 
                    162: /*
                    163:  * This interface is depreciated - users should use the scsi generics
                    164:  * interface instead, as this is a more flexible approach to performing
                    165:  * generic SCSI commands on a device.
                    166:  */
                    167: int scsi_ioctl_send_command(Scsi_Device *dev, void *buffer)
                    168: {
                    169:     char * buf;
                    170:     unsigned char cmd[12]; 
                    171:     char * cmd_in;
                    172:     Scsi_Cmnd * SCpnt;
                    173:     unsigned char opcode;
                    174:     int inlen, outlen, cmdlen;
                    175:     int needed, buf_needed;
                    176:     int timeout, retries, result;
                    177:     
                    178:     if (!buffer)
                    179:        return -EINVAL;
                    180:     
                    181: 
                    182:     /*
                    183:      * Verify that we can read at least this much.
                    184:      */
                    185:     result = verify_area(VERIFY_READ, buffer, 2*sizeof(long) + 1);
                    186:     if (result) return result;
                    187: 
                    188:     /*
                    189:      * The structure that we are passed should look like:
                    190:      *
                    191:      * struct sdata {
                    192:      * unsigned int inlen;
                    193:      * unsigned int outlen;
                    194:      * unsigned char  cmd[];  # However many bytes are used for cmd.
                    195:      * unsigned char  data[];
                    196:      * };
                    197:      */
                    198:     inlen = get_user((unsigned int *) buffer);
                    199:     outlen = get_user( ((unsigned int *) buffer) + 1);
                    200:     
                    201:     /*
                    202:      * We do not transfer more than MAX_BUF with this interface.
                    203:      * If the user needs to transfer more data than this, they
                    204:      * should use scsi_generics instead.
                    205:      */
                    206:     if( inlen > MAX_BUF )  return -EINVAL;
                    207:     if( outlen > MAX_BUF )  return -EINVAL;
                    208: 
                    209:     cmd_in = (char *) ( ((int *)buffer) + 2);
                    210:     opcode = get_user(cmd_in); 
                    211:     
                    212:     needed = buf_needed = (inlen > outlen ? inlen : outlen);
                    213:     if(buf_needed){
                    214:        buf_needed = (buf_needed + 511) & ~511;
                    215:        if (buf_needed > MAX_BUF) buf_needed = MAX_BUF;
                    216:        buf = (char *) scsi_malloc(buf_needed);
                    217:        if (!buf) return -ENOMEM;
                    218:        memset(buf, 0, buf_needed);
                    219:     } else
                    220:        buf = NULL;
                    221:     
                    222:     /*
                    223:      * Obtain the command from the user's address space.
                    224:      */
                    225:     cmdlen = COMMAND_SIZE(opcode);
                    226: 
                    227:     result = verify_area(VERIFY_READ, cmd_in, 
                    228:                          cmdlen + inlen > MAX_BUF ? MAX_BUF : inlen);
                    229:     if (result) return result;
                    230: 
                    231:     memcpy_fromfs ((void *) cmd,  cmd_in,  cmdlen);
                    232:     
                    233:     /*
                    234:      * Obtain the data to be sent to the device (if any).
                    235:      */
                    236:     memcpy_fromfs ((void *) buf,  
                    237:                    (void *) (cmd_in + cmdlen), 
                    238:                    inlen);
                    239:     
                    240:     /*
                    241:      * Set the lun field to the correct value.
                    242:      */
                    243:     cmd[1] = ( cmd[1] & 0x1f ) | (dev->lun << 5);
                    244:     
                    245:     switch (opcode)
                    246:       {
                    247:       case FORMAT_UNIT:
                    248:        timeout = FORMAT_UNIT_TIMEOUT;
                    249:        retries = 1;
                    250:        break;
                    251:       case START_STOP:
                    252:        timeout = START_STOP_TIMEOUT;
                    253:        retries = NORMAL_RETRIES;
                    254:        break;
                    255:       case MOVE_MEDIUM:
                    256:        timeout = MOVE_MEDIUM_TIMEOUT;
                    257:        retries = NORMAL_RETRIES;
                    258:        break;
                    259:       case READ_ELEMENT_STATUS:
                    260:        timeout = READ_ELEMENT_STATUS_TIMEOUT;
                    261:        retries = NORMAL_RETRIES;
                    262:        break;
                    263:       default:
                    264:        timeout = NORMAL_TIMEOUT;
                    265:        retries = NORMAL_RETRIES;
                    266:        break;
                    267:       }
                    268: 
                    269: #ifndef DEBUG_NO_CMD
                    270:     
                    271:     SCpnt = allocate_device(NULL, dev, 1);
                    272: 
                    273:     {
                    274:        struct semaphore sem = MUTEX_LOCKED;
                    275:        SCpnt->request.sem = &sem;
                    276:        scsi_do_cmd(SCpnt,  cmd,  buf, needed,  scsi_ioctl_done,
                    277:                    timeout, retries);
                    278:        down(&sem);
                    279:     }
                    280:     
                    281:     /* 
                    282:      * If there was an error condition, pass the info back to the user. 
                    283:      */
                    284:     if(SCpnt->result) {
                    285:         result = verify_area(VERIFY_WRITE, 
                    286:                              cmd_in, 
                    287:                              sizeof(SCpnt->sense_buffer));
                    288:         if (result) return result;
                    289:         memcpy_tofs((void *) cmd_in,  
                    290:                     SCpnt->sense_buffer, 
                    291:                     sizeof(SCpnt->sense_buffer));
                    292:     } else {
                    293:         result = verify_area(VERIFY_WRITE, cmd_in, outlen);
                    294:         if (result) return result;
                    295:         memcpy_tofs ((void *) cmd_in,  buf,  outlen);
                    296:     }
                    297:     result = SCpnt->result;
                    298: 
                    299:     SCpnt->request.rq_status = RQ_INACTIVE;
                    300: 
                    301:     if (buf) scsi_free(buf, buf_needed);
                    302:     
                    303:     if(SCpnt->device->scsi_request_fn)
                    304:        (*SCpnt->device->scsi_request_fn)();
                    305:     
                    306:     wake_up(&SCpnt->device->device_wait);
                    307:     return result;
                    308: #else
                    309:     {
                    310:        int i;
                    311:        printk("scsi_ioctl : device %d.  command = ", dev->id);
                    312:        for (i = 0; i < 12; ++i)
                    313:            printk("%02x ", cmd[i]);
                    314:        printk("\nbuffer =");
                    315:        for (i = 0; i < 20; ++i)
                    316:            printk("%02x ", buf[i]);
                    317:        printk("\n");
                    318:        printk("inlen = %d, outlen = %d, cmdlen = %d\n",
                    319:               inlen, outlen, cmdlen);
                    320:        printk("buffer = %d, cmd_in = %d\n", buffer, cmd_in);
                    321:     }
                    322:     return 0;
                    323: #endif
                    324: }
                    325: 
                    326: /*
                    327:  * the scsi_ioctl() function differs from most ioctls in that it does
                    328:  * not take a major/minor number as the dev field.  Rather, it takes
                    329:  * a pointer to a scsi_devices[] element, a structure. 
                    330:  */
                    331: int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
                    332: {
                    333:     int result;
                    334:     char scsi_cmd[12];
                    335:     
                    336:     /* No idea how this happens.... */
                    337:     if (!dev) return -ENXIO;
                    338:     
                    339:     switch (cmd) {
                    340:     case SCSI_IOCTL_GET_IDLUN:
                    341:         result = verify_area(VERIFY_WRITE, (void *) arg, 2*sizeof(long));
                    342:         if (result) return result;
                    343: 
                    344:        put_user(dev->id 
                    345:                  + (dev->lun << 8) 
                    346:                  + (dev->channel << 16)
                    347:                  + ((dev->host->hostt->proc_dir->low_ino & 0xff) << 24),
                    348:                    (unsigned long *) arg);
                    349:         put_user( dev->host->unique_id, (unsigned long *) arg+1);
                    350:        return 0;
                    351:     case SCSI_IOCTL_GET_BUS_NUMBER:
                    352:         result = verify_area(VERIFY_WRITE, (void *) arg, sizeof(int));
                    353:         if (result) return result;
                    354:         put_user( dev->host->host_no, (int *) arg);
                    355:         return 0;
                    356:     case SCSI_IOCTL_TAGGED_ENABLE:
                    357:        if(!suser())  return -EACCES;
                    358:        if(!dev->tagged_supported) return -EINVAL;
                    359:        dev->tagged_queue = 1;
                    360:        dev->current_tag = 1;
                    361:        return 0;
                    362:     case SCSI_IOCTL_TAGGED_DISABLE:
                    363:        if(!suser())  return -EACCES;
                    364:        if(!dev->tagged_supported) return -EINVAL;
                    365:        dev->tagged_queue = 0;
                    366:        dev->current_tag = 0;
                    367:        return 0;
                    368:     case SCSI_IOCTL_PROBE_HOST:
                    369:        return ioctl_probe(dev->host, arg);
                    370:     case SCSI_IOCTL_SEND_COMMAND:
                    371:        if(!suser() || securelevel > 0)  return -EACCES;
                    372:        return scsi_ioctl_send_command((Scsi_Device *) dev, arg);
                    373:     case SCSI_IOCTL_DOORLOCK:
                    374:        if (!dev->removable || !dev->lockable) return 0;
                    375:        scsi_cmd[0] = ALLOW_MEDIUM_REMOVAL;
                    376:        scsi_cmd[1] = dev->lun << 5;
                    377:        scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
                    378:        scsi_cmd[4] = SCSI_REMOVAL_PREVENT;
                    379:        return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
                    380:                                      NORMAL_TIMEOUT, NORMAL_RETRIES);
                    381:        break;
                    382:     case SCSI_IOCTL_DOORUNLOCK:
                    383:        if (!dev->removable || !dev->lockable) return 0;
                    384:        scsi_cmd[0] = ALLOW_MEDIUM_REMOVAL;
                    385:        scsi_cmd[1] = dev->lun << 5;
                    386:        scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
                    387:        scsi_cmd[4] = SCSI_REMOVAL_ALLOW;
                    388:        return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
                    389:                                      NORMAL_TIMEOUT, NORMAL_RETRIES);
                    390:     case SCSI_IOCTL_TEST_UNIT_READY:
                    391:        scsi_cmd[0] = TEST_UNIT_READY;
                    392:        scsi_cmd[1] = dev->lun << 5;
                    393:        scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
                    394:        scsi_cmd[4] = 0;
                    395:        return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
                    396:                                      NORMAL_TIMEOUT, NORMAL_RETRIES);
                    397:        break;
                    398:     case SCSI_IOCTL_START_UNIT:
                    399:        scsi_cmd[0] = START_STOP;
                    400:        scsi_cmd[1] = dev->lun << 5;
                    401:        scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
                    402:        scsi_cmd[4] = 1;
                    403:        return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
                    404:                                      START_STOP_TIMEOUT, NORMAL_RETRIES);
                    405:        break;
                    406:     case SCSI_IOCTL_STOP_UNIT:
                    407:        scsi_cmd[0] = START_STOP;
                    408:        scsi_cmd[1] = dev->lun << 5;
                    409:        scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
                    410:        scsi_cmd[4] = 0;
                    411:        return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
                    412:                                      START_STOP_TIMEOUT, NORMAL_RETRIES);
                    413:        break;
                    414:     default :           
                    415:        return -EINVAL;
                    416:     }
                    417:     return -EINVAL;
                    418: }
                    419: 
                    420: /*
                    421:  * Just like scsi_ioctl, only callable from kernel space with no 
                    422:  * fs segment fiddling.
                    423:  */
                    424: 
                    425: int kernel_scsi_ioctl (Scsi_Device *dev, int cmd, void *arg) {
                    426:     unsigned long oldfs;
                    427:     int tmp;
                    428:     oldfs = get_fs();
                    429:     set_fs(get_ds());
                    430:     tmp = scsi_ioctl (dev, cmd, arg);
                    431:     set_fs(oldfs);
                    432:     return tmp;
                    433: }
                    434: 
                    435: /*
                    436:  * Overrides for Emacs so that we almost follow Linus's tabbing style.
                    437:  * Emacs will notice this stuff at the end of the file and automatically
                    438:  * adjust the settings for this buffer only.  This must remain at the end
                    439:  * of the file.
                    440:  * ---------------------------------------------------------------------------
                    441:  * Local variables:
                    442:  * c-indent-level: 4
                    443:  * c-brace-imaginary-offset: 0
                    444:  * c-brace-offset: -4
                    445:  * c-argdecl-indent: 4
                    446:  * c-label-offset: -4
                    447:  * c-continued-statement-offset: 4
                    448:  * c-continued-brace-offset: 0
                    449:  * indent-tabs-mode: nil
                    450:  * tab-width: 8
                    451:  * End:
                    452:  */

unix.superglobalmegacorp.com

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