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 <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
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 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 ;
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 ;
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
134
135
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