Annotation of linux/kernel/blk_drv/scsi/scsi_ioctl.c, revision 1.1.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.