aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/i2o/i2o_config.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/message/i2o/i2o_config.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/message/i2o/i2o_config.c')
-rw-r--r--drivers/message/i2o/i2o_config.c1160
1 files changed, 1160 insertions, 0 deletions
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
new file mode 100644
index 000000000000..5fc5004ea07a
--- /dev/null
+++ b/drivers/message/i2o/i2o_config.c
@@ -0,0 +1,1160 @@
1/*
2 * I2O Configuration Interface Driver
3 *
4 * (C) Copyright 1999-2002 Red Hat
5 *
6 * Written by Alan Cox, Building Number Three Ltd
7 *
8 * Fixes/additions:
9 * Deepak Saxena (04/20/1999):
10 * Added basic ioctl() support
11 * Deepak Saxena (06/07/1999):
12 * Added software download ioctl (still testing)
13 * Auvo Häkkinen (09/10/1999):
14 * Changes to i2o_cfg_reply(), ioctl_parms()
15 * Added ioct_validate()
16 * Taneli Vähäkangas (09/30/1999):
17 * Fixed ioctl_swdl()
18 * Taneli Vähäkangas (10/04/1999):
19 * Changed ioctl_swdl(), implemented ioctl_swul() and ioctl_swdel()
20 * Deepak Saxena (11/18/1999):
21 * Added event managmenet support
22 * Alan Cox <alan@redhat.com>:
23 * 2.4 rewrite ported to 2.5
24 * Markus Lidel <Markus.Lidel@shadowconnect.com>:
25 * Added pass-thru support for Adaptec's raidutils
26 *
27 * This program is free software; you can redistribute it and/or
28 * modify it under the terms of the GNU General Public License
29 * as published by the Free Software Foundation; either version
30 * 2 of the License, or (at your option) any later version.
31 */
32
33#include <linux/module.h>
34#include <linux/kernel.h>
35#include <linux/pci.h>
36#include <linux/i2o.h>
37#include <linux/errno.h>
38#include <linux/init.h>
39#include <linux/slab.h>
40#include <linux/miscdevice.h>
41#include <linux/mm.h>
42#include <linux/spinlock.h>
43#include <linux/smp_lock.h>
44#include <linux/ioctl32.h>
45#include <linux/compat.h>
46#include <linux/syscalls.h>
47
48#include <asm/uaccess.h>
49#include <asm/io.h>
50
51#define OSM_NAME "config-osm"
52#define OSM_VERSION "$Rev$"
53#define OSM_DESCRIPTION "I2O Configuration OSM"
54
55extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int);
56
57static spinlock_t i2o_config_lock;
58
59#define MODINC(x,y) ((x) = ((x) + 1) % (y))
60
61struct sg_simple_element {
62 u32 flag_count;
63 u32 addr_bus;
64};
65
66struct i2o_cfg_info {
67 struct file *fp;
68 struct fasync_struct *fasync;
69 struct i2o_evt_info event_q[I2O_EVT_Q_LEN];
70 u16 q_in; // Queue head index
71 u16 q_out; // Queue tail index
72 u16 q_len; // Queue length
73 u16 q_lost; // Number of lost events
74 ulong q_id; // Event queue ID...used as tx_context
75 struct i2o_cfg_info *next;
76};
77static struct i2o_cfg_info *open_files = NULL;
78static ulong i2o_cfg_info_id = 0;
79
80/*
81 * Each of these describes an i2o message handler. They are
82 * multiplexed by the i2o_core code
83 */
84
85static struct i2o_driver i2o_config_driver = {
86 .name = OSM_NAME
87};
88
89static int i2o_cfg_getiops(unsigned long arg)
90{
91 struct i2o_controller *c;
92 u8 __user *user_iop_table = (void __user *)arg;
93 u8 tmp[MAX_I2O_CONTROLLERS];
94 int ret = 0;
95
96 memset(tmp, 0, MAX_I2O_CONTROLLERS);
97
98 list_for_each_entry(c, &i2o_controllers, list)
99 tmp[c->unit] = 1;
100
101 if (copy_to_user(user_iop_table, tmp, MAX_I2O_CONTROLLERS))
102 ret = -EFAULT;
103
104 return ret;
105};
106
107static int i2o_cfg_gethrt(unsigned long arg)
108{
109 struct i2o_controller *c;
110 struct i2o_cmd_hrtlct __user *cmd = (struct i2o_cmd_hrtlct __user *)arg;
111 struct i2o_cmd_hrtlct kcmd;
112 i2o_hrt *hrt;
113 int len;
114 u32 reslen;
115 int ret = 0;
116
117 if (copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_hrtlct)))
118 return -EFAULT;
119
120 if (get_user(reslen, kcmd.reslen) < 0)
121 return -EFAULT;
122
123 if (kcmd.resbuf == NULL)
124 return -EFAULT;
125
126 c = i2o_find_iop(kcmd.iop);
127 if (!c)
128 return -ENXIO;
129
130 hrt = (i2o_hrt *) c->hrt.virt;
131
132 len = 8 + ((hrt->entry_len * hrt->num_entries) << 2);
133
134 /* We did a get user...so assuming mem is ok...is this bad? */
135 put_user(len, kcmd.reslen);
136 if (len > reslen)
137 ret = -ENOBUFS;
138 if (copy_to_user(kcmd.resbuf, (void *)hrt, len))
139 ret = -EFAULT;
140
141 return ret;
142};
143
144static int i2o_cfg_getlct(unsigned long arg)
145{
146 struct i2o_controller *c;
147 struct i2o_cmd_hrtlct __user *cmd = (struct i2o_cmd_hrtlct __user *)arg;
148 struct i2o_cmd_hrtlct kcmd;
149 i2o_lct *lct;
150 int len;
151 int ret = 0;
152 u32 reslen;
153
154 if (copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_hrtlct)))
155 return -EFAULT;
156
157 if (get_user(reslen, kcmd.reslen) < 0)
158 return -EFAULT;
159
160 if (kcmd.resbuf == NULL)
161 return -EFAULT;
162
163 c = i2o_find_iop(kcmd.iop);
164 if (!c)
165 return -ENXIO;
166
167 lct = (i2o_lct *) c->lct;
168
169 len = (unsigned int)lct->table_size << 2;
170 put_user(len, kcmd.reslen);
171 if (len > reslen)
172 ret = -ENOBUFS;
173 else if (copy_to_user(kcmd.resbuf, lct, len))
174 ret = -EFAULT;
175
176 return ret;
177};
178
179static int i2o_cfg_parms(unsigned long arg, unsigned int type)
180{
181 int ret = 0;
182 struct i2o_controller *c;
183 struct i2o_device *dev;
184 struct i2o_cmd_psetget __user *cmd =
185 (struct i2o_cmd_psetget __user *)arg;
186 struct i2o_cmd_psetget kcmd;
187 u32 reslen;
188 u8 *ops;
189 u8 *res;
190 int len = 0;
191
192 u32 i2o_cmd = (type == I2OPARMGET ?
193 I2O_CMD_UTIL_PARAMS_GET : I2O_CMD_UTIL_PARAMS_SET);
194
195 if (copy_from_user(&kcmd, cmd, sizeof(struct i2o_cmd_psetget)))
196 return -EFAULT;
197
198 if (get_user(reslen, kcmd.reslen))
199 return -EFAULT;
200
201 c = i2o_find_iop(kcmd.iop);
202 if (!c)
203 return -ENXIO;
204
205 dev = i2o_iop_find_device(c, kcmd.tid);
206 if (!dev)
207 return -ENXIO;
208
209 ops = (u8 *) kmalloc(kcmd.oplen, GFP_KERNEL);
210 if (!ops)
211 return -ENOMEM;
212
213 if (copy_from_user(ops, kcmd.opbuf, kcmd.oplen)) {
214 kfree(ops);
215 return -EFAULT;
216 }
217
218 /*
219 * It's possible to have a _very_ large table
220 * and that the user asks for all of it at once...
221 */
222 res = (u8 *) kmalloc(65536, GFP_KERNEL);
223 if (!res) {
224 kfree(ops);
225 return -ENOMEM;
226 }
227
228 len = i2o_parm_issue(dev, i2o_cmd, ops, kcmd.oplen, res, 65536);
229 kfree(ops);
230
231 if (len < 0) {
232 kfree(res);
233 return -EAGAIN;
234 }
235
236 put_user(len, kcmd.reslen);
237 if (len > reslen)
238 ret = -ENOBUFS;
239 else if (copy_to_user(kcmd.resbuf, res, len))
240 ret = -EFAULT;
241
242 kfree(res);
243
244 return ret;
245};
246
247static int i2o_cfg_swdl(unsigned long arg)
248{
249 struct i2o_sw_xfer kxfer;
250 struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg;
251 unsigned char maxfrag = 0, curfrag = 1;
252 struct i2o_dma buffer;
253 struct i2o_message __iomem *msg;
254 u32 m;
255 unsigned int status = 0, swlen = 0, fragsize = 8192;
256 struct i2o_controller *c;
257
258 if (copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
259 return -EFAULT;
260
261 if (get_user(swlen, kxfer.swlen) < 0)
262 return -EFAULT;
263
264 if (get_user(maxfrag, kxfer.maxfrag) < 0)
265 return -EFAULT;
266
267 if (get_user(curfrag, kxfer.curfrag) < 0)
268 return -EFAULT;
269
270 if (curfrag == maxfrag)
271 fragsize = swlen - (maxfrag - 1) * 8192;
272
273 if (!kxfer.buf || !access_ok(VERIFY_READ, kxfer.buf, fragsize))
274 return -EFAULT;
275
276 c = i2o_find_iop(kxfer.iop);
277 if (!c)
278 return -ENXIO;
279
280 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
281 if (m == I2O_QUEUE_EMPTY)
282 return -EBUSY;
283
284 if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) {
285 i2o_msg_nop(c, m);
286 return -ENOMEM;
287 }
288
289 __copy_from_user(buffer.virt, kxfer.buf, fragsize);
290
291 writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]);
292 writel(I2O_CMD_SW_DOWNLOAD << 24 | HOST_TID << 12 | ADAPTER_TID,
293 &msg->u.head[1]);
294 writel(i2o_config_driver.context, &msg->u.head[2]);
295 writel(0, &msg->u.head[3]);
296 writel((((u32) kxfer.flags) << 24) | (((u32) kxfer.sw_type) << 16) |
297 (((u32) maxfrag) << 8) | (((u32) curfrag)), &msg->body[0]);
298 writel(swlen, &msg->body[1]);
299 writel(kxfer.sw_id, &msg->body[2]);
300 writel(0xD0000000 | fragsize, &msg->body[3]);
301 writel(buffer.phys, &msg->body[4]);
302
303 osm_debug("swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
304 status = i2o_msg_post_wait_mem(c, m, 60, &buffer);
305
306 if (status != -ETIMEDOUT)
307 i2o_dma_free(&c->pdev->dev, &buffer);
308
309 if (status != I2O_POST_WAIT_OK) {
310 // it fails if you try and send frags out of order
311 // and for some yet unknown reasons too
312 osm_info("swdl failed, DetailedStatus = %d\n", status);
313 return status;
314 }
315
316 return 0;
317};
318
319static int i2o_cfg_swul(unsigned long arg)
320{
321 struct i2o_sw_xfer kxfer;
322 struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg;
323 unsigned char maxfrag = 0, curfrag = 1;
324 struct i2o_dma buffer;
325 struct i2o_message __iomem *msg;
326 u32 m;
327 unsigned int status = 0, swlen = 0, fragsize = 8192;
328 struct i2o_controller *c;
329 int ret = 0;
330
331 if (copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
332 goto return_fault;
333
334 if (get_user(swlen, kxfer.swlen) < 0)
335 goto return_fault;
336
337 if (get_user(maxfrag, kxfer.maxfrag) < 0)
338 goto return_fault;
339
340 if (get_user(curfrag, kxfer.curfrag) < 0)
341 goto return_fault;
342
343 if (curfrag == maxfrag)
344 fragsize = swlen - (maxfrag - 1) * 8192;
345
346 if (!kxfer.buf)
347 goto return_fault;
348
349 c = i2o_find_iop(kxfer.iop);
350 if (!c)
351 return -ENXIO;
352
353 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
354 if (m == I2O_QUEUE_EMPTY)
355 return -EBUSY;
356
357 if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) {
358 i2o_msg_nop(c, m);
359 return -ENOMEM;
360 }
361
362 writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]);
363 writel(I2O_CMD_SW_UPLOAD << 24 | HOST_TID << 12 | ADAPTER_TID,
364 &msg->u.head[1]);
365 writel(i2o_config_driver.context, &msg->u.head[2]);
366 writel(0, &msg->u.head[3]);
367 writel((u32) kxfer.flags << 24 | (u32) kxfer.
368 sw_type << 16 | (u32) maxfrag << 8 | (u32) curfrag,
369 &msg->body[0]);
370 writel(swlen, &msg->body[1]);
371 writel(kxfer.sw_id, &msg->body[2]);
372 writel(0xD0000000 | fragsize, &msg->body[3]);
373 writel(buffer.phys, &msg->body[4]);
374
375 osm_debug("swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
376 status = i2o_msg_post_wait_mem(c, m, 60, &buffer);
377
378 if (status != I2O_POST_WAIT_OK) {
379 if (status != -ETIMEDOUT)
380 i2o_dma_free(&c->pdev->dev, &buffer);
381
382 osm_info("swul failed, DetailedStatus = %d\n", status);
383 return status;
384 }
385
386 if (copy_to_user(kxfer.buf, buffer.virt, fragsize))
387 ret = -EFAULT;
388
389 i2o_dma_free(&c->pdev->dev, &buffer);
390
391return_ret:
392 return ret;
393return_fault:
394 ret = -EFAULT;
395 goto return_ret;
396};
397
398static int i2o_cfg_swdel(unsigned long arg)
399{
400 struct i2o_controller *c;
401 struct i2o_sw_xfer kxfer;
402 struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg;
403 struct i2o_message __iomem *msg;
404 u32 m;
405 unsigned int swlen;
406 int token;
407
408 if (copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
409 return -EFAULT;
410
411 if (get_user(swlen, kxfer.swlen) < 0)
412 return -EFAULT;
413
414 c = i2o_find_iop(kxfer.iop);
415 if (!c)
416 return -ENXIO;
417
418 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
419 if (m == I2O_QUEUE_EMPTY)
420 return -EBUSY;
421
422 writel(SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
423 writel(I2O_CMD_SW_REMOVE << 24 | HOST_TID << 12 | ADAPTER_TID,
424 &msg->u.head[1]);
425 writel(i2o_config_driver.context, &msg->u.head[2]);
426 writel(0, &msg->u.head[3]);
427 writel((u32) kxfer.flags << 24 | (u32) kxfer.sw_type << 16,
428 &msg->body[0]);
429 writel(swlen, &msg->body[1]);
430 writel(kxfer.sw_id, &msg->body[2]);
431
432 token = i2o_msg_post_wait(c, m, 10);
433
434 if (token != I2O_POST_WAIT_OK) {
435 osm_info("swdel failed, DetailedStatus = %d\n", token);
436 return -ETIMEDOUT;
437 }
438
439 return 0;
440};
441
442static int i2o_cfg_validate(unsigned long arg)
443{
444 int token;
445 int iop = (int)arg;
446 struct i2o_message __iomem *msg;
447 u32 m;
448 struct i2o_controller *c;
449
450 c = i2o_find_iop(iop);
451 if (!c)
452 return -ENXIO;
453
454 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
455 if (m == I2O_QUEUE_EMPTY)
456 return -EBUSY;
457
458 writel(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
459 writel(I2O_CMD_CONFIG_VALIDATE << 24 | HOST_TID << 12 | iop,
460 &msg->u.head[1]);
461 writel(i2o_config_driver.context, &msg->u.head[2]);
462 writel(0, &msg->u.head[3]);
463
464 token = i2o_msg_post_wait(c, m, 10);
465
466 if (token != I2O_POST_WAIT_OK) {
467 osm_info("Can't validate configuration, ErrorStatus = %d\n",
468 token);
469 return -ETIMEDOUT;
470 }
471
472 return 0;
473};
474
475static int i2o_cfg_evt_reg(unsigned long arg, struct file *fp)
476{
477 struct i2o_message __iomem *msg;
478 u32 m;
479 struct i2o_evt_id __user *pdesc = (struct i2o_evt_id __user *)arg;
480 struct i2o_evt_id kdesc;
481 struct i2o_controller *c;
482 struct i2o_device *d;
483
484 if (copy_from_user(&kdesc, pdesc, sizeof(struct i2o_evt_id)))
485 return -EFAULT;
486
487 /* IOP exists? */
488 c = i2o_find_iop(kdesc.iop);
489 if (!c)
490 return -ENXIO;
491
492 /* Device exists? */
493 d = i2o_iop_find_device(c, kdesc.tid);
494 if (!d)
495 return -ENODEV;
496
497 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
498 if (m == I2O_QUEUE_EMPTY)
499 return -EBUSY;
500
501 writel(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
502 writel(I2O_CMD_UTIL_EVT_REGISTER << 24 | HOST_TID << 12 | kdesc.tid,
503 &msg->u.head[1]);
504 writel(i2o_config_driver.context, &msg->u.head[2]);
505 writel(i2o_cntxt_list_add(c, fp->private_data), &msg->u.head[3]);
506 writel(kdesc.evt_mask, &msg->body[0]);
507
508 i2o_msg_post(c, m);
509
510 return 0;
511}
512
513static int i2o_cfg_evt_get(unsigned long arg, struct file *fp)
514{
515 struct i2o_cfg_info *p = NULL;
516 struct i2o_evt_get __user *uget = (struct i2o_evt_get __user *)arg;
517 struct i2o_evt_get kget;
518 unsigned long flags;
519
520 for (p = open_files; p; p = p->next)
521 if (p->q_id == (ulong) fp->private_data)
522 break;
523
524 if (!p->q_len)
525 return -ENOENT;
526
527 memcpy(&kget.info, &p->event_q[p->q_out], sizeof(struct i2o_evt_info));
528 MODINC(p->q_out, I2O_EVT_Q_LEN);
529 spin_lock_irqsave(&i2o_config_lock, flags);
530 p->q_len--;
531 kget.pending = p->q_len;
532 kget.lost = p->q_lost;
533 spin_unlock_irqrestore(&i2o_config_lock, flags);
534
535 if (copy_to_user(uget, &kget, sizeof(struct i2o_evt_get)))
536 return -EFAULT;
537 return 0;
538}
539
540#ifdef CONFIG_COMPAT
541static int i2o_cfg_passthru32(unsigned fd, unsigned cmnd, unsigned long arg,
542 struct file *file)
543{
544 struct i2o_cmd_passthru32 __user *cmd;
545 struct i2o_controller *c;
546 u32 __user *user_msg;
547 u32 *reply = NULL;
548 u32 __user *user_reply = NULL;
549 u32 size = 0;
550 u32 reply_size = 0;
551 u32 rcode = 0;
552 struct i2o_dma sg_list[SG_TABLESIZE];
553 u32 sg_offset = 0;
554 u32 sg_count = 0;
555 u32 i = 0;
556 i2o_status_block *sb;
557 struct i2o_message *msg;
558 u32 m;
559 unsigned int iop;
560
561 cmd = (struct i2o_cmd_passthru32 __user *)arg;
562
563 if (get_user(iop, &cmd->iop) || get_user(i, &cmd->msg))
564 return -EFAULT;
565
566 user_msg = compat_ptr(i);
567
568 c = i2o_find_iop(iop);
569 if (!c) {
570 osm_debug("controller %d not found\n", iop);
571 return -ENXIO;
572 }
573
574 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
575
576 sb = c->status_block.virt;
577
578 if (get_user(size, &user_msg[0])) {
579 osm_warn("unable to get size!\n");
580 return -EFAULT;
581 }
582 size = size >> 16;
583
584 if (size > sb->inbound_frame_size) {
585 osm_warn("size of message > inbound_frame_size");
586 return -EFAULT;
587 }
588
589 user_reply = &user_msg[size];
590
591 size <<= 2; // Convert to bytes
592
593 /* Copy in the user's I2O command */
594 if (copy_from_user(msg, user_msg, size)) {
595 osm_warn("unable to copy user message\n");
596 return -EFAULT;
597 }
598 i2o_dump_message(msg);
599
600 if (get_user(reply_size, &user_reply[0]) < 0)
601 return -EFAULT;
602
603 reply_size >>= 16;
604 reply_size <<= 2;
605
606 reply = kmalloc(reply_size, GFP_KERNEL);
607 if (!reply) {
608 printk(KERN_WARNING "%s: Could not allocate reply buffer\n",
609 c->name);
610 return -ENOMEM;
611 }
612 memset(reply, 0, reply_size);
613
614 sg_offset = (msg->u.head[0] >> 4) & 0x0f;
615
616 writel(i2o_config_driver.context, &msg->u.s.icntxt);
617 writel(i2o_cntxt_list_add(c, reply), &msg->u.s.tcntxt);
618
619 memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE);
620 if (sg_offset) {
621 struct sg_simple_element *sg;
622
623 if (sg_offset * 4 >= size) {
624 rcode = -EFAULT;
625 goto cleanup;
626 }
627 // TODO 64bit fix
628 sg = (struct sg_simple_element *)((&msg->u.head[0]) +
629 sg_offset);
630 sg_count =
631 (size - sg_offset * 4) / sizeof(struct sg_simple_element);
632 if (sg_count > SG_TABLESIZE) {
633 printk(KERN_DEBUG "%s:IOCTL SG List too large (%u)\n",
634 c->name, sg_count);
635 kfree(reply);
636 return -EINVAL;
637 }
638
639 for (i = 0; i < sg_count; i++) {
640 int sg_size;
641 struct i2o_dma *p;
642
643 if (!(sg[i].flag_count & 0x10000000
644 /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT */ )) {
645 printk(KERN_DEBUG
646 "%s:Bad SG element %d - not simple (%x)\n",
647 c->name, i, sg[i].flag_count);
648 rcode = -EINVAL;
649 goto cleanup;
650 }
651 sg_size = sg[i].flag_count & 0xffffff;
652 p = &(sg_list[i]);
653 /* Allocate memory for the transfer */
654 if (i2o_dma_alloc
655 (&c->pdev->dev, p, sg_size,
656 PCI_DMA_BIDIRECTIONAL)) {
657 printk(KERN_DEBUG
658 "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
659 c->name, sg_size, i, sg_count);
660 rcode = -ENOMEM;
661 goto cleanup;
662 }
663 /* Copy in the user's SG buffer if necessary */
664 if (sg[i].
665 flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) {
666 // TODO 64bit fix
667 if (copy_from_user
668 (p->virt, (void __user *)(unsigned long)sg[i].addr_bus,
669 sg_size)) {
670 printk(KERN_DEBUG
671 "%s: Could not copy SG buf %d FROM user\n",
672 c->name, i);
673 rcode = -EFAULT;
674 goto cleanup;
675 }
676 }
677 //TODO 64bit fix
678 sg[i].addr_bus = (u32) p->phys;
679 }
680 }
681
682 rcode = i2o_msg_post_wait(c, m, 60);
683 if (rcode)
684 goto cleanup;
685
686 if (sg_offset) {
687 u32 msg[128];
688 /* Copy back the Scatter Gather buffers back to user space */
689 u32 j;
690 // TODO 64bit fix
691 struct sg_simple_element *sg;
692 int sg_size;
693
694 // re-acquire the original message to handle correctly the sg copy operation
695 memset(&msg, 0, MSG_FRAME_SIZE * 4);
696 // get user msg size in u32s
697 if (get_user(size, &user_msg[0])) {
698 rcode = -EFAULT;
699 goto cleanup;
700 }
701 size = size >> 16;
702 size *= 4;
703 /* Copy in the user's I2O command */
704 if (copy_from_user(msg, user_msg, size)) {
705 rcode = -EFAULT;
706 goto cleanup;
707 }
708 sg_count =
709 (size - sg_offset * 4) / sizeof(struct sg_simple_element);
710
711 // TODO 64bit fix
712 sg = (struct sg_simple_element *)(msg + sg_offset);
713 for (j = 0; j < sg_count; j++) {
714 /* Copy out the SG list to user's buffer if necessary */
715 if (!
716 (sg[j].
717 flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR */ )) {
718 sg_size = sg[j].flag_count & 0xffffff;
719 // TODO 64bit fix
720 if (copy_to_user
721 ((void __user *)(u64) sg[j].addr_bus,
722 sg_list[j].virt, sg_size)) {
723 printk(KERN_WARNING
724 "%s: Could not copy %p TO user %x\n",
725 c->name, sg_list[j].virt,
726 sg[j].addr_bus);
727 rcode = -EFAULT;
728 goto cleanup;
729 }
730 }
731 }
732 }
733
734 /* Copy back the reply to user space */
735 if (reply_size) {
736 // we wrote our own values for context - now restore the user supplied ones
737 if (copy_from_user(reply + 2, user_msg + 2, sizeof(u32) * 2)) {
738 printk(KERN_WARNING
739 "%s: Could not copy message context FROM user\n",
740 c->name);
741 rcode = -EFAULT;
742 }
743 if (copy_to_user(user_reply, reply, reply_size)) {
744 printk(KERN_WARNING
745 "%s: Could not copy reply TO user\n", c->name);
746 rcode = -EFAULT;
747 }
748 }
749
750 cleanup:
751 kfree(reply);
752 return rcode;
753}
754
755#else
756
757static int i2o_cfg_passthru(unsigned long arg)
758{
759 struct i2o_cmd_passthru __user *cmd =
760 (struct i2o_cmd_passthru __user *)arg;
761 struct i2o_controller *c;
762 u32 __user *user_msg;
763 u32 *reply = NULL;
764 u32 __user *user_reply = NULL;
765 u32 size = 0;
766 u32 reply_size = 0;
767 u32 rcode = 0;
768 void *sg_list[SG_TABLESIZE];
769 u32 sg_offset = 0;
770 u32 sg_count = 0;
771 int sg_index = 0;
772 u32 i = 0;
773 void *p = NULL;
774 i2o_status_block *sb;
775 struct i2o_message __iomem *msg;
776 u32 m;
777 unsigned int iop;
778
779 if (get_user(iop, &cmd->iop) || get_user(user_msg, &cmd->msg))
780 return -EFAULT;
781
782 c = i2o_find_iop(iop);
783 if (!c) {
784 osm_warn("controller %d not found\n", iop);
785 return -ENXIO;
786 }
787
788 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
789
790 sb = c->status_block.virt;
791
792 if (get_user(size, &user_msg[0]))
793 return -EFAULT;
794 size = size >> 16;
795
796 if (size > sb->inbound_frame_size) {
797 osm_warn("size of message > inbound_frame_size");
798 return -EFAULT;
799 }
800
801 user_reply = &user_msg[size];
802
803 size <<= 2; // Convert to bytes
804
805 /* Copy in the user's I2O command */
806 if (copy_from_user(msg, user_msg, size))
807 return -EFAULT;
808
809 if (get_user(reply_size, &user_reply[0]) < 0)
810 return -EFAULT;
811
812 reply_size >>= 16;
813 reply_size <<= 2;
814
815 reply = kmalloc(reply_size, GFP_KERNEL);
816 if (!reply) {
817 printk(KERN_WARNING "%s: Could not allocate reply buffer\n",
818 c->name);
819 return -ENOMEM;
820 }
821 memset(reply, 0, reply_size);
822
823 sg_offset = (msg->u.head[0] >> 4) & 0x0f;
824
825 writel(i2o_config_driver.context, &msg->u.s.icntxt);
826 writel(i2o_cntxt_list_add(c, reply), &msg->u.s.tcntxt);
827
828 memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE);
829 if (sg_offset) {
830 struct sg_simple_element *sg;
831
832 if (sg_offset * 4 >= size) {
833 rcode = -EFAULT;
834 goto cleanup;
835 }
836 // TODO 64bit fix
837 sg = (struct sg_simple_element *)((&msg->u.head[0]) +
838 sg_offset);
839 sg_count =
840 (size - sg_offset * 4) / sizeof(struct sg_simple_element);
841 if (sg_count > SG_TABLESIZE) {
842 printk(KERN_DEBUG "%s:IOCTL SG List too large (%u)\n",
843 c->name, sg_count);
844 kfree(reply);
845 return -EINVAL;
846 }
847
848 for (i = 0; i < sg_count; i++) {
849 int sg_size;
850
851 if (!(sg[i].flag_count & 0x10000000
852 /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT */ )) {
853 printk(KERN_DEBUG
854 "%s:Bad SG element %d - not simple (%x)\n",
855 c->name, i, sg[i].flag_count);
856 rcode = -EINVAL;
857 goto cleanup;
858 }
859 sg_size = sg[i].flag_count & 0xffffff;
860 /* Allocate memory for the transfer */
861 p = kmalloc(sg_size, GFP_KERNEL);
862 if (!p) {
863 printk(KERN_DEBUG
864 "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
865 c->name, sg_size, i, sg_count);
866 rcode = -ENOMEM;
867 goto cleanup;
868 }
869 sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.
870 /* Copy in the user's SG buffer if necessary */
871 if (sg[i].
872 flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) {
873 // TODO 64bit fix
874 if (copy_from_user
875 (p, (void __user *)sg[i].addr_bus,
876 sg_size)) {
877 printk(KERN_DEBUG
878 "%s: Could not copy SG buf %d FROM user\n",
879 c->name, i);
880 rcode = -EFAULT;
881 goto cleanup;
882 }
883 }
884 //TODO 64bit fix
885 sg[i].addr_bus = virt_to_bus(p);
886 }
887 }
888
889 rcode = i2o_msg_post_wait(c, m, 60);
890 if (rcode)
891 goto cleanup;
892
893 if (sg_offset) {
894 u32 msg[128];
895 /* Copy back the Scatter Gather buffers back to user space */
896 u32 j;
897 // TODO 64bit fix
898 struct sg_simple_element *sg;
899 int sg_size;
900
901 // re-acquire the original message to handle correctly the sg copy operation
902 memset(&msg, 0, MSG_FRAME_SIZE * 4);
903 // get user msg size in u32s
904 if (get_user(size, &user_msg[0])) {
905 rcode = -EFAULT;
906 goto cleanup;
907 }
908 size = size >> 16;
909 size *= 4;
910 /* Copy in the user's I2O command */
911 if (copy_from_user(msg, user_msg, size)) {
912 rcode = -EFAULT;
913 goto cleanup;
914 }
915 sg_count =
916 (size - sg_offset * 4) / sizeof(struct sg_simple_element);
917
918 // TODO 64bit fix
919 sg = (struct sg_simple_element *)(msg + sg_offset);
920 for (j = 0; j < sg_count; j++) {
921 /* Copy out the SG list to user's buffer if necessary */
922 if (!
923 (sg[j].
924 flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR */ )) {
925 sg_size = sg[j].flag_count & 0xffffff;
926 // TODO 64bit fix
927 if (copy_to_user
928 ((void __user *)sg[j].addr_bus, sg_list[j],
929 sg_size)) {
930 printk(KERN_WARNING
931 "%s: Could not copy %p TO user %x\n",
932 c->name, sg_list[j],
933 sg[j].addr_bus);
934 rcode = -EFAULT;
935 goto cleanup;
936 }
937 }
938 }
939 }
940
941 /* Copy back the reply to user space */
942 if (reply_size) {
943 // we wrote our own values for context - now restore the user supplied ones
944 if (copy_from_user(reply + 2, user_msg + 2, sizeof(u32) * 2)) {
945 printk(KERN_WARNING
946 "%s: Could not copy message context FROM user\n",
947 c->name);
948 rcode = -EFAULT;
949 }
950 if (copy_to_user(user_reply, reply, reply_size)) {
951 printk(KERN_WARNING
952 "%s: Could not copy reply TO user\n", c->name);
953 rcode = -EFAULT;
954 }
955 }
956
957 cleanup:
958 kfree(reply);
959 return rcode;
960}
961#endif
962
963/*
964 * IOCTL Handler
965 */
966static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd,
967 unsigned long arg)
968{
969 int ret;
970
971 switch (cmd) {
972 case I2OGETIOPS:
973 ret = i2o_cfg_getiops(arg);
974 break;
975
976 case I2OHRTGET:
977 ret = i2o_cfg_gethrt(arg);
978 break;
979
980 case I2OLCTGET:
981 ret = i2o_cfg_getlct(arg);
982 break;
983
984 case I2OPARMSET:
985 ret = i2o_cfg_parms(arg, I2OPARMSET);
986 break;
987
988 case I2OPARMGET:
989 ret = i2o_cfg_parms(arg, I2OPARMGET);
990 break;
991
992 case I2OSWDL:
993 ret = i2o_cfg_swdl(arg);
994 break;
995
996 case I2OSWUL:
997 ret = i2o_cfg_swul(arg);
998 break;
999
1000 case I2OSWDEL:
1001 ret = i2o_cfg_swdel(arg);
1002 break;
1003
1004 case I2OVALIDATE:
1005 ret = i2o_cfg_validate(arg);
1006 break;
1007
1008 case I2OEVTREG:
1009 ret = i2o_cfg_evt_reg(arg, fp);
1010 break;
1011
1012 case I2OEVTGET:
1013 ret = i2o_cfg_evt_get(arg, fp);
1014 break;
1015
1016#ifndef CONFIG_COMPAT
1017 case I2OPASSTHRU:
1018 ret = i2o_cfg_passthru(arg);
1019 break;
1020#endif
1021
1022 default:
1023 osm_debug("unknown ioctl called!\n");
1024 ret = -EINVAL;
1025 }
1026
1027 return ret;
1028}
1029
1030static int cfg_open(struct inode *inode, struct file *file)
1031{
1032 struct i2o_cfg_info *tmp =
1033 (struct i2o_cfg_info *)kmalloc(sizeof(struct i2o_cfg_info),
1034 GFP_KERNEL);
1035 unsigned long flags;
1036
1037 if (!tmp)
1038 return -ENOMEM;
1039
1040 file->private_data = (void *)(i2o_cfg_info_id++);
1041 tmp->fp = file;
1042 tmp->fasync = NULL;
1043 tmp->q_id = (ulong) file->private_data;
1044 tmp->q_len = 0;
1045 tmp->q_in = 0;
1046 tmp->q_out = 0;
1047 tmp->q_lost = 0;
1048 tmp->next = open_files;
1049
1050 spin_lock_irqsave(&i2o_config_lock, flags);
1051 open_files = tmp;
1052 spin_unlock_irqrestore(&i2o_config_lock, flags);
1053
1054 return 0;
1055}
1056
1057static int cfg_fasync(int fd, struct file *fp, int on)
1058{
1059 ulong id = (ulong) fp->private_data;
1060 struct i2o_cfg_info *p;
1061
1062 for (p = open_files; p; p = p->next)
1063 if (p->q_id == id)
1064 break;
1065
1066 if (!p)
1067 return -EBADF;
1068
1069 return fasync_helper(fd, fp, on, &p->fasync);
1070}
1071
1072static int cfg_release(struct inode *inode, struct file *file)
1073{
1074 ulong id = (ulong) file->private_data;
1075 struct i2o_cfg_info *p1, *p2;
1076 unsigned long flags;
1077
1078 lock_kernel();
1079 p1 = p2 = NULL;
1080
1081 spin_lock_irqsave(&i2o_config_lock, flags);
1082 for (p1 = open_files; p1;) {
1083 if (p1->q_id == id) {
1084
1085 if (p1->fasync)
1086 cfg_fasync(-1, file, 0);
1087 if (p2)
1088 p2->next = p1->next;
1089 else
1090 open_files = p1->next;
1091
1092 kfree(p1);
1093 break;
1094 }
1095 p2 = p1;
1096 p1 = p1->next;
1097 }
1098 spin_unlock_irqrestore(&i2o_config_lock, flags);
1099 unlock_kernel();
1100
1101 return 0;
1102}
1103
1104static struct file_operations config_fops = {
1105 .owner = THIS_MODULE,
1106 .llseek = no_llseek,
1107 .ioctl = i2o_cfg_ioctl,
1108 .open = cfg_open,
1109 .release = cfg_release,
1110 .fasync = cfg_fasync,
1111};
1112
1113static struct miscdevice i2o_miscdev = {
1114 I2O_MINOR,
1115 "i2octl",
1116 &config_fops
1117};
1118
1119static int __init i2o_config_init(void)
1120{
1121 printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
1122
1123 spin_lock_init(&i2o_config_lock);
1124
1125 if (misc_register(&i2o_miscdev) < 0) {
1126 osm_err("can't register device.\n");
1127 return -EBUSY;
1128 }
1129 /*
1130 * Install our handler
1131 */
1132 if (i2o_driver_register(&i2o_config_driver)) {
1133 osm_err("handler register failed.\n");
1134 misc_deregister(&i2o_miscdev);
1135 return -EBUSY;
1136 }
1137#ifdef CONFIG_COMPAT
1138 register_ioctl32_conversion(I2OPASSTHRU32, i2o_cfg_passthru32);
1139 register_ioctl32_conversion(I2OGETIOPS, (void *)sys_ioctl);
1140#endif
1141 return 0;
1142}
1143
1144static void i2o_config_exit(void)
1145{
1146#ifdef CONFIG_COMPAT
1147 unregister_ioctl32_conversion(I2OPASSTHRU32);
1148 unregister_ioctl32_conversion(I2OGETIOPS);
1149#endif
1150 misc_deregister(&i2o_miscdev);
1151 i2o_driver_unregister(&i2o_config_driver);
1152}
1153
1154MODULE_AUTHOR("Red Hat Software");
1155MODULE_LICENSE("GPL");
1156MODULE_DESCRIPTION(OSM_DESCRIPTION);
1157MODULE_VERSION(OSM_VERSION);
1158
1159module_init(i2o_config_init);
1160module_exit(i2o_config_exit);