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

1.1       root        1: #include <linux/config.h>
                      2: #ifdef CONFIG_SCSI 
                      3: 
                      4: #include <asm/io.h>
                      5: #include <asm/segment.h>
                      6: #include <asm/system.h>
                      7: 
1.1.1.2 ! root        8: #include <linux/errno.h>
1.1       root        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
1.1.1.2 ! root       19: #define MAX_BUF 8192   
1.1       root       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:  * 
1.1.1.2 ! root       47:  * dev is the SCSI device struct ptr, *(int *) arg is the length of the
        !            48:  * input data, if any, not including the command string & counts, 
        !            49:  * *((int *)arg + 1) is the output buffer size in bytes.
1.1       root       50:  * 
1.1.1.2 ! root       51:  * *(char *) ((int *) arg)[2] the actual command byte.   
1.1       root       52:  * 
1.1.1.2 ! root       53:  * Note that no more than MAX_BUF data bytes will be transfered.  Since
1.1       root       54:  * SCSI block device size is 512 bytes, I figured 1K was good.
1.1.1.2 ! root       55:  * but (WDE) changed it to 8192 to handle large bad track buffers.
1.1       root       56:  * 
1.1.1.2 ! root       57:  * This size *does not* include the initial lengths that were passed.
1.1       root       58:  * 
1.1.1.2 ! root       59:  * The SCSI command is read from the memory location immediately after the
        !            60:  * length words, and the input data is right after the command.  The SCSI
        !            61:  * routines know the command size based on the opcode decode.  
1.1       root       62:  * 
1.1.1.2 ! root       63:  * The output area is then filled in starting from the command byte. 
1.1       root       64:  */
                     65: 
                     66: static int the_result[MAX_SCSI_HOSTS];
                     67: 
                     68: static void scsi_ioctl_done (int host, int result)
                     69: {
                     70:        the_result[host] = result;      
                     71: }      
                     72:        
                     73: static int ioctl_command(Scsi_Device *dev, void *buffer)
                     74: {
                     75:        char buf[MAX_BUF];
                     76:        char cmd[10];
                     77:        char * cmd_in;
                     78:        unsigned char opcode;
                     79:        int inlen, outlen, cmdlen, temp, host;
                     80: 
                     81:        if (!buffer)
                     82:                return -EINVAL;
                     83:        
                     84:        inlen = get_fs_long((int *) buffer);
1.1.1.2 ! root       85:        outlen = get_fs_long( ((int *) buffer) + 1);
1.1       root       86: 
                     87:        cmd_in = (char *) ( ((int *)buffer) + 2);
                     88:        opcode = get_fs_byte(cmd_in); 
                     89: 
1.1.1.2 ! root       90:        memcpy_fromfs ((void *) cmd,  cmd_in,  cmdlen = COMMAND_SIZE (opcode));
        !            91:        memcpy_fromfs ((void *) buf,  (void *) (cmd_in + cmdlen),  inlen);
1.1       root       92:        host = dev->host_no;
                     93: 
                     94: #ifndef DEBUG_NO_CMD
                     95:        do {
                     96:                cli();
                     97:                if (the_result[host]) {
                     98:                        sti();
                     99:                        while(the_result[host])
                    100:                                /* nothing */;
                    101:                } else {
                    102:                        the_result[host]=-1;
                    103:                        sti();
                    104:                        break;
                    105:                }
                    106:        } while (1);
                    107:        
1.1.1.2 ! root      108:        scsi_do_cmd(host,  dev->id,  cmd,  buf,  ((outlen > MAX_BUF) ? 
        !           109:                        MAX_BUF : outlen),  scsi_ioctl_done,  MAX_TIMEOUT, 
        !           110:                        buf,  MAX_RETRIES);
1.1       root      111: 
                    112:        while (the_result[host] == -1)
                    113:                /* nothing */;
                    114:        temp = the_result[host];
1.1.1.2 ! root      115:        the_result[host] = 0;
        !           116:        memcpy_tofs ((void *) cmd_in,  buf,  (outlen > MAX_BUF) ? MAX_BUF  : outlen);
1.1       root      117:        return temp;
                    118: #else
                    119:        {
                    120:        int i;
1.1.1.2 ! root      121:        printk("scsi_ioctl : device %d.  command = ", dev->id);
1.1       root      122:        for (i = 0; i < 10; ++i)
                    123:                printk("%02x ", cmd[i]);
                    124:        printk("\r\nbuffer =");
                    125:        for (i = 0; i < 20; ++i)
                    126:                printk("%02x ", buf[i]);
                    127:        printk("\r\n");
1.1.1.2 ! root      128:        printk("inlen = %d, outlen = %d, cmdlen = %d\n",
        !           129:                inlen, outlen, cmdlen);
        !           130:        printk("buffer = %d, cmd_in = %d\n", buffer, cmd_in);
1.1       root      131:        }
                    132:        return 0;
                    133: #endif
                    134: }
                    135: 
                    136:        
                    137: /*
                    138:        the scsi_ioctl() function differs from most ioctls in that it does
                    139:        not take a major/minor number as the dev filed.  Rather, it takes
1.1.1.2 ! root      140:        a pointer to a scsi_devices[] element, a structure. 
1.1       root      141: */
1.1.1.2 ! root      142: int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
1.1       root      143: {
1.1.1.2 ! root      144:        if ((cmd != 0 && dev->id > NR_SCSI_DEVICES))
1.1       root      145:                return -ENODEV;
1.1.1.2 ! root      146:        if ((cmd == 0 && dev->host_no > MAX_SCSI_HOSTS))
1.1       root      147:                return -ENODEV;
                    148:        
                    149:        switch (cmd) {
                    150:                case SCSI_IOCTL_PROBE_HOST:
1.1.1.2 ! root      151:                        return ioctl_probe(dev->host_no, arg);
1.1       root      152:                case SCSI_IOCTL_SEND_COMMAND:
                    153:                        return ioctl_command((Scsi_Device *) dev, arg);
                    154:                default :                       
                    155:                        return -EINVAL;
                    156:        }
                    157: }
                    158: #endif

unix.superglobalmegacorp.com

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