|
|
1.1 root 1: /*
2: * Don't import our own symbols, as this would severely mess up our
3: * symbol tables.
4: */
5: #define _SCSI_SYMS_VER_
6: #define __NO_VERSION__
7: #include <linux/module.h>
8:
9: #include <asm/io.h>
10: #include <asm/segment.h>
11: #include <asm/system.h>
12:
13: #include <linux/errno.h>
14: #include <linux/kernel.h>
15: #include <linux/sched.h>
16: #include <linux/mm.h>
17: #include <linux/string.h>
18:
19: #include <linux/blk.h>
20: #include "scsi.h"
21: #include "hosts.h"
22: #include "scsi_ioctl.h"
23:
24: #define MAX_RETRIES 5
25: #define MAX_TIMEOUT 900
26: #define MAX_BUF 4096
27:
28: #define max(a,b) (((a) > (b)) ? (a) : (b))
29:
30: /*
31: * If we are told to probe a host, we will return 0 if the host is not
32: * present, 1 if the host is present, and will return an identifying
33: * string at *arg, if arg is non null, filling to the length stored at
34: * (int *) arg
35: */
36:
37: static int ioctl_probe(struct Scsi_Host * host, void *buffer)
38: {
39: int temp, result;
40: unsigned int len,slen;
41: const char * string;
42:
43: if ((temp = host->hostt->present) && buffer) {
44: result = verify_area(VERIFY_READ, buffer, sizeof(long));
45: if (result) return result;
46:
47: len = get_user ((unsigned int *) buffer);
48: if(host->hostt->info)
49: string = host->hostt->info(host);
50: else
51: string = host->hostt->name;
52: if(string) {
53: slen = strlen(string);
54: if (len > slen)
55: len = slen + 1;
56: result = verify_area(VERIFY_WRITE, buffer, len);
57: if (result) return result;
58:
59: memcpy_tofs (buffer, string, len);
60: }
61: }
62: return temp;
63: }
64:
65: /*
66: *
67: * The SCSI_IOCTL_SEND_COMMAND ioctl sends a command out to the SCSI host.
68: * The MAX_TIMEOUT and MAX_RETRIES variables are used.
69: *
70: * dev is the SCSI device struct ptr, *(int *) arg is the length of the
71: * input data, if any, not including the command string & counts,
72: * *((int *)arg + 1) is the output buffer size in bytes.
73: *
74: * *(char *) ((int *) arg)[2] the actual command byte.
75: *
76: * Note that no more than MAX_BUF data bytes will be transfered. Since
77: * SCSI block device size is 512 bytes, I figured 1K was good.
78: * but (WDE) changed it to 8192 to handle large bad track buffers.
79: * ERY: I changed this to a dynamic allocation using scsi_malloc - we were
80: * getting a kernel stack overflow which was crashing the system when we
81: * were using 8192 bytes.
82: *
83: * This size *does not* include the initial lengths that were passed.
84: *
85: * The SCSI command is read from the memory location immediately after the
86: * length words, and the input data is right after the command. The SCSI
87: * routines know the command size based on the opcode decode.
88: *
89: * The output area is then filled in starting from the command byte.
90: */
91:
92: static void scsi_ioctl_done (Scsi_Cmnd * SCpnt)
93: {
94: struct request * req;
95:
96: req = &SCpnt->request;
97: req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
98:
99: if (req->sem != NULL) {
100: up(req->sem);
101: }
102: }
103:
104: static int ioctl_internal_command(Scsi_Device *dev, char * cmd)
105: {
106: int result;
107: Scsi_Cmnd * SCpnt;
108:
109: SCpnt = allocate_device(NULL, dev, 1);
110: {
111: struct semaphore sem = MUTEX_LOCKED;
112: SCpnt->request.sem = &sem;
113: scsi_do_cmd(SCpnt, cmd, NULL, 0,
114: scsi_ioctl_done, MAX_TIMEOUT,
115: MAX_RETRIES);
116: down(&sem);
117: }
118:
119: if(driver_byte(SCpnt->result) != 0)
120: switch(SCpnt->sense_buffer[2] & 0xf) {
121: case ILLEGAL_REQUEST:
122: if(cmd[0] == ALLOW_MEDIUM_REMOVAL) dev->lockable = 0;
123: else printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
124: break;
125: case NOT_READY: /* This happens if there is no disc in drive */
126: if(dev->removable){
127: printk(KERN_INFO "Device not ready. Make sure there is a disc in the drive.\n");
128: break;
129: };
130: case UNIT_ATTENTION:
131: if (dev->removable){
132: dev->changed = 1;
133: SCpnt->result = 0; /* This is no longer considered an error */
134: printk(KERN_INFO "Disc change detected.\n");
135: break;
136: };
137: default: /* Fall through for non-removable media */
138: printk("SCSI error: host %d id %d lun %d return code = %x\n",
139: dev->host->host_no,
140: dev->id,
141: dev->lun,
142: SCpnt->result);
143: printk("\tSense class %x, sense error %x, extended sense %x\n",
144: sense_class(SCpnt->sense_buffer[0]),
145: sense_error(SCpnt->sense_buffer[0]),
146: SCpnt->sense_buffer[2] & 0xf);
147:
148: };
149:
150: result = SCpnt->result;
151: SCpnt->request.rq_status = RQ_INACTIVE;
152: wake_up(&SCpnt->device->device_wait);
153: return result;
154: }
155:
156: /*
157: * This interface is depreciated - users should use the scsi generics
158: * interface instead, as this is a more flexible approach to performing
159: * generic SCSI commands on a device.
160: */
161: static int ioctl_command(Scsi_Device *dev, void *buffer)
162: {
163: char * buf;
164: char cmd[12];
165: char * cmd_in;
166: Scsi_Cmnd * SCpnt;
167: unsigned char opcode;
168: int inlen, outlen, cmdlen;
169: int needed, buf_needed;
170: int result;
171:
172: if (!buffer)
173: return -EINVAL;
174:
175:
176: /*
177: * Verify that we can read at least this much.
178: */
179: result = verify_area(VERIFY_READ, buffer, 2*sizeof(long) + 1);
180: if (result) return result;
181:
182: /*
183: * The structure that we are passed should look like:
184: *
185: * struct sdata{
186: * int inlen;
187: * int outlen;
188: * char cmd[]; # However many bytes are used for cmd.
189: * char data[];
190: */
191: inlen = get_user((unsigned int *) buffer);
192: outlen = get_user( ((unsigned int *) buffer) + 1);
193:
194: /*
195: * We do not transfer more than MAX_BUF with this interface.
196: * If the user needs to transfer more data than this, they
197: * should use scsi_generics instead.
198: */
199: if( inlen > MAX_BUF ) inlen = MAX_BUF;
200: if( outlen > MAX_BUF ) outlen = MAX_BUF;
201:
202: cmd_in = (char *) ( ((int *)buffer) + 2);
203: opcode = get_user(cmd_in);
204:
205: needed = buf_needed = (inlen > outlen ? inlen : outlen);
206: if(buf_needed){
207: buf_needed = (buf_needed + 511) & ~511;
208: if (buf_needed > MAX_BUF) buf_needed = MAX_BUF;
209: buf = (char *) scsi_malloc(buf_needed);
210: if (!buf) return -ENOMEM;
211: memset(buf, 0, buf_needed);
212: } else
213: buf = NULL;
214:
215: /*
216: * Obtain the command from the user's address space.
217: */
218: cmdlen = COMMAND_SIZE(opcode);
219:
220: result = verify_area(VERIFY_READ, cmd_in,
221: cmdlen + inlen > MAX_BUF ? MAX_BUF : inlen);
222: if (result) return result;
223:
224: memcpy_fromfs ((void *) cmd, cmd_in, cmdlen);
225:
226: /*
227: * Obtain the data to be sent to the device (if any).
228: */
229: memcpy_fromfs ((void *) buf,
230: (void *) (cmd_in + cmdlen),
231: inlen);
232:
233: /*
234: * Set the lun field to the correct value.
235: */
236: cmd[1] = ( cmd[1] & 0x1f ) | (dev->lun << 5);
237:
238: #ifndef DEBUG_NO_CMD
239:
240: SCpnt = allocate_device(NULL, dev, 1);
241:
242: {
243: struct semaphore sem = MUTEX_LOCKED;
244: SCpnt->request.sem = &sem;
245: scsi_do_cmd(SCpnt, cmd, buf, needed, scsi_ioctl_done, MAX_TIMEOUT,
246: MAX_RETRIES);
247: down(&sem);
248: }
249:
250: /*
251: * If there was an error condition, pass the info back to the user.
252: */
253: if(SCpnt->result) {
254: result = verify_area(VERIFY_WRITE,
255: cmd_in,
256: sizeof(SCpnt->sense_buffer));
257: if (result) return result;
258: memcpy_tofs((void *) cmd_in,
259: SCpnt->sense_buffer,
260: sizeof(SCpnt->sense_buffer));
261: } else {
262: result = verify_area(VERIFY_WRITE, cmd_in, outlen);
263: if (result) return result;
264: memcpy_tofs ((void *) cmd_in, buf, outlen);
265: }
266: result = SCpnt->result;
267:
268: SCpnt->request.rq_status = RQ_INACTIVE;
269:
270: if (buf) scsi_free(buf, buf_needed);
271:
272: if(SCpnt->device->scsi_request_fn)
273: (*SCpnt->device->scsi_request_fn)();
274:
275: wake_up(&SCpnt->device->device_wait);
276: return result;
277: #else
278: {
279: int i;
280: printk("scsi_ioctl : device %d. command = ", dev->id);
281: for (i = 0; i < 12; ++i)
282: printk("%02x ", cmd[i]);
283: printk("\nbuffer =");
284: for (i = 0; i < 20; ++i)
285: printk("%02x ", buf[i]);
286: printk("\n");
287: printk("inlen = %d, outlen = %d, cmdlen = %d\n",
288: inlen, outlen, cmdlen);
289: printk("buffer = %d, cmd_in = %d\n", buffer, cmd_in);
290: }
291: return 0;
292: #endif
293: }
294:
295: /*
296: * the scsi_ioctl() function differs from most ioctls in that it does
297: * not take a major/minor number as the dev filed. Rather, it takes
298: * a pointer to a scsi_devices[] element, a structure.
299: */
300: int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
301: {
302: int result;
303: char scsi_cmd[12];
304:
305: /* No idea how this happens.... */
306: if (!dev) return -ENXIO;
307:
308: switch (cmd) {
309: case SCSI_IOCTL_GET_IDLUN:
310: result = verify_area(VERIFY_WRITE, (void *) arg, 2*sizeof(long));
311: if (result) return result;
312:
313: put_user(dev->id
314: + (dev->lun << 8)
315: + (dev->channel << 16)
316: + ((dev->host->hostt->proc_dir->low_ino & 0xff) << 24),
317: (unsigned long *) arg);
318: put_user( dev->host->unique_id, (unsigned long *) arg+1);
319: return 0;
320: case SCSI_IOCTL_TAGGED_ENABLE:
321: if(!suser()) return -EACCES;
322: if(!dev->tagged_supported) return -EINVAL;
323: dev->tagged_queue = 1;
324: dev->current_tag = 1;
325: break;
326: case SCSI_IOCTL_TAGGED_DISABLE:
327: if(!suser()) return -EACCES;
328: if(!dev->tagged_supported) return -EINVAL;
329: dev->tagged_queue = 0;
330: dev->current_tag = 0;
331: break;
332: case SCSI_IOCTL_PROBE_HOST:
333: return ioctl_probe(dev->host, arg);
334: case SCSI_IOCTL_SEND_COMMAND:
335: if(!suser()) return -EACCES;
336: return ioctl_command((Scsi_Device *) dev, arg);
337: case SCSI_IOCTL_DOORLOCK:
338: if (!dev->removable || !dev->lockable) return 0;
339: scsi_cmd[0] = ALLOW_MEDIUM_REMOVAL;
340: scsi_cmd[1] = dev->lun << 5;
341: scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
342: scsi_cmd[4] = SCSI_REMOVAL_PREVENT;
343: return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd);
344: break;
345: case SCSI_IOCTL_DOORUNLOCK:
346: if (!dev->removable || !dev->lockable) return 0;
347: scsi_cmd[0] = ALLOW_MEDIUM_REMOVAL;
348: scsi_cmd[1] = dev->lun << 5;
349: scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
350: scsi_cmd[4] = SCSI_REMOVAL_ALLOW;
351: return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd);
352: case SCSI_IOCTL_TEST_UNIT_READY:
353: scsi_cmd[0] = TEST_UNIT_READY;
354: scsi_cmd[1] = dev->lun << 5;
355: scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
356: scsi_cmd[4] = 0;
357: return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd);
358: break;
359: default :
360: return -EINVAL;
361: }
362: return -EINVAL;
363: }
364:
365: /*
366: * Just like scsi_ioctl, only callable from kernel space with no
367: * fs segment fiddling.
368: */
369:
370: int kernel_scsi_ioctl (Scsi_Device *dev, int cmd, void *arg) {
371: unsigned long oldfs;
372: int tmp;
373: oldfs = get_fs();
374: set_fs(get_ds());
375: tmp = scsi_ioctl (dev, cmd, arg);
376: set_fs(oldfs);
377: return tmp;
378: }
379:
380: /*
381: * Overrides for Emacs so that we almost follow Linus's tabbing style.
382: * Emacs will notice this stuff at the end of the file and automatically
383: * adjust the settings for this buffer only. This must remain at the end
384: * of the file.
385: * ---------------------------------------------------------------------------
386: * Local variables:
387: * c-indent-level: 4
388: * c-brace-imaginary-offset: 0
389: * c-brace-offset: -4
390: * c-argdecl-indent: 4
391: * c-label-offset: -4
392: * c-continued-statement-offset: 4
393: * c-continued-brace-offset: 0
394: * indent-tabs-mode: nil
395: * tab-width: 8
396: * End:
397: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.