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

1.1     ! root        1: #include <linux/config.h>
        !             2: #ifdef CONFIG_SCSI 
        !             3: 
        !             4: #include <errno.h>
        !             5: #include <asm/io.h>
        !             6: #include <asm/segment.h>
        !             7: #include <asm/system.h>
        !             8: 
        !             9: #include <linux/kernel.h>
        !            10: #include <linux/sched.h>
        !            11: #include <linux/string.h>
        !            12: 
        !            13: #include "scsi.h"
        !            14: #include "hosts.h"
        !            15: #include "scsi_ioctl.h"
        !            16: 
        !            17: #define MAX_RETRIES 5  
        !            18: #define MAX_TIMEOUT 200
        !            19: #define MAX_BUF 1024   
        !            20: 
        !            21: #define max(a,b) (((a) > (b)) ? (a) : (b))
        !            22: 
        !            23: /*
        !            24:  * If we are told to probe a host, we will return 0 if  the host is not
        !            25:  * present, 1 if the host is present, and will return an identifying
        !            26:  * string at *arg, if arg is non null, filling to the length stored at
        !            27:  * (int *) arg
        !            28:  */
        !            29: 
        !            30: static int ioctl_probe(int dev, void *buffer)
        !            31: {
        !            32:        int temp;
        !            33:        int len;
        !            34:        
        !            35:        if ((temp = scsi_hosts[dev].present) && buffer) {
        !            36:                len = get_fs_long ((int *) buffer);
        !            37:                memcpy_tofs (buffer, scsi_hosts[dev].info(), len);
        !            38:        }
        !            39:        return temp;
        !            40: }
        !            41: 
        !            42: /*
        !            43:  * 
        !            44:  * The SCSI_IOCTL_SEND_COMMAND ioctl sends a command out to the SCSI host.
        !            45:  * The MAX_TIMEOUT and MAX_RETRIES  variables are used.  
        !            46:  * 
        !            47:  * dev is the SCSI device number, *(int *) arg the length of the input
        !            48:  * data, *((int *)arg + 1) the output buffer.
        !            49:  * 
        !            50:  * *(char *) ((int *) arg)[1] the actual command.   
        !            51:  * 
        !            52:  * Note that no more than MAX_BUF bytes will be transfered.  Since
        !            53:  * SCSI block device size is 512 bytes, I figured 1K was good.
        !            54:  * 
        !            55:  * This size * does  * include  the initial lengths that were passed.
        !            56:  * 
        !            57:  * The SCSI command is read from  the memory location immediately after the
        !            58:  * length words, and the out data after the command.  The SCSI routines know the
        !            59:  * command size based on the length byte.  
        !            60:  * 
        !            61:  * The area is then filled in from the byte at offset 0. 
        !            62:  */
        !            63: 
        !            64: static int the_result[MAX_SCSI_HOSTS];
        !            65: 
        !            66: static void scsi_ioctl_done (int host, int result)
        !            67: {
        !            68:        the_result[host] = result;      
        !            69: }      
        !            70:        
        !            71: static int ioctl_command(Scsi_Device *dev, void *buffer)
        !            72: {
        !            73:        char buf[MAX_BUF];
        !            74:        char cmd[10];
        !            75:        char * cmd_in;
        !            76:        unsigned char opcode;
        !            77:        int inlen, outlen, cmdlen, temp, host;
        !            78: 
        !            79:        if (!buffer)
        !            80:                return -EINVAL;
        !            81:        
        !            82:        inlen = get_fs_long((int *) buffer);
        !            83:        outlen = get_fs_long(((int *) buffer) + 1);
        !            84: 
        !            85:        cmd_in = (char *) ( ((int *)buffer) + 2);
        !            86:        opcode = get_fs_byte(cmd_in); 
        !            87: 
        !            88:        memcpy_fromfs ((void *) cmd,  cmd_in, cmdlen = COMMAND_SIZE (opcode));
        !            89:        memcpy_fromfs ((void *) buf,  (void *) (cmd_in + cmdlen), inlen);
        !            90:        host = dev->host_no;
        !            91: 
        !            92: #ifndef DEBUG_NO_CMD
        !            93:        do {
        !            94:                cli();
        !            95:                if (the_result[host]) {
        !            96:                        sti();
        !            97:                        while(the_result[host])
        !            98:                                /* nothing */;
        !            99:                } else {
        !           100:                        the_result[host]=-1;
        !           101:                        sti();
        !           102:                        break;
        !           103:                }
        !           104:        } while (1);
        !           105:        
        !           106:        scsi_do_cmd(host,  dev->id, cmd, buf, ((outlen > MAX_BUF) ? 
        !           107:                        MAX_BUF : outlen),  scsi_ioctl_done, MAX_TIMEOUT, 
        !           108:                        buf, MAX_RETRIES);
        !           109: 
        !           110:        while (the_result[host] == -1)
        !           111:                /* nothing */;
        !           112:        temp = the_result[host];
        !           113:        the_result[host]=0;
        !           114:        memcpy_tofs (buffer, buf, (outlen > MAX_BUF) ? MAX_BUF  : outlen);
        !           115:        return temp;
        !           116: #else
        !           117:        {
        !           118:        int i;
        !           119:        printk("scsi_ioctl : device %d.  command = ", dev);
        !           120:        for (i = 0; i < 10; ++i)
        !           121:                printk("%02x ", cmd[i]);
        !           122:        printk("\r\nbuffer =");
        !           123:        for (i = 0; i < 20; ++i)
        !           124:                printk("%02x ", buf[i]);
        !           125:        printk("\r\n");
        !           126:        }
        !           127:        return 0;
        !           128: #endif
        !           129: }
        !           130: 
        !           131:        
        !           132: /*
        !           133:        the scsi_ioctl() function differs from most ioctls in that it does
        !           134:        not take a major/minor number as the dev filed.  Rather, it takes
        !           135:        an index in scsi_devices[] 
        !           136: */
        !           137: int scsi_ioctl (int dev, int cmd, void *arg)
        !           138: {
        !           139:        if ((cmd != 0 && dev > NR_SCSI_DEVICES) || dev < 0)
        !           140:                return -ENODEV;
        !           141:        if ((cmd == 0 && dev > MAX_SCSI_HOSTS))
        !           142:                return -ENODEV;
        !           143:        
        !           144:        switch (cmd) {
        !           145:                case SCSI_IOCTL_PROBE_HOST:
        !           146:                        return ioctl_probe(dev, arg);
        !           147:                case SCSI_IOCTL_SEND_COMMAND:
        !           148:                        return ioctl_command((Scsi_Device *) dev, arg);
        !           149:                default :                       
        !           150:                        return -EINVAL;
        !           151:        }
        !           152: }
        !           153: #endif

unix.superglobalmegacorp.com

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