This source file includes following definitions.
- ioctl_probe
- scsi_ioctl_done
- ioctl_command
- scsi_ioctl
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
8 #include <linux/errno.h>
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 8192
20
21 #define max(a,b) (((a) > (b)) ? (a) : (b))
22
23
24
25
26
27
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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);
85 outlen = get_fs_long( ((int *) buffer) + 1);
86
87 cmd_in = (char *) ( ((int *)buffer) + 2);
88 opcode = get_fs_byte(cmd_in);
89
90 memcpy_fromfs ((void *) cmd, cmd_in, cmdlen = COMMAND_SIZE (opcode));
91 memcpy_fromfs ((void *) buf, (void *) (cmd_in + cmdlen), inlen);
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 ;
101 } else {
102 the_result[host]=-1;
103 sti();
104 break;
105 }
106 } while (1);
107
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);
111
112 while (the_result[host] == -1)
113 ;
114 temp = the_result[host];
115 the_result[host] = 0;
116 memcpy_tofs ((void *) cmd_in, buf, (outlen > MAX_BUF) ? MAX_BUF : outlen);
117 return temp;
118 #else
119 {
120 int i;
121 printk("scsi_ioctl : device %d. command = ", dev->id);
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");
128 printk("inlen = %d, outlen = %d, cmdlen = %d\n",
129 inlen, outlen, cmdlen);
130 printk("buffer = %d, cmd_in = %d\n", buffer, cmd_in);
131 }
132 return 0;
133 #endif
134 }
135
136
137
138
139
140
141
142 int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
143 {
144 if ((cmd != 0 && dev->id > NR_SCSI_DEVICES))
145 return -ENODEV;
146 if ((cmd == 0 && dev->host_no > MAX_SCSI_HOSTS))
147 return -ENODEV;
148
149 switch (cmd) {
150 case SCSI_IOCTL_PROBE_HOST:
151 return ioctl_probe(dev->host_no, arg);
152 case SCSI_IOCTL_SEND_COMMAND:
153 return ioctl_command((Scsi_Device *) dev, arg);
154 default :
155 return -EINVAL;
156 }
157 }
158 #endif