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