aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/i2o/device.c
diff options
context:
space:
mode:
authorMarkus Lidel <Markus.Lidel@shadowconnect.com>2006-01-06 03:19:29 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:33:53 -0500
commita1a5ea70a6e9db6332b27fe2d96666e17aa1436b (patch)
tree7edfe920aa40af94464ab05539d449dbe5689254 /drivers/message/i2o/device.c
parent347a8dc3b815f0c0fa62a1df075184ffe4cbdcf1 (diff)
[PATCH] I2O: changed I2O API to create I2O messages in kernel memory
Changed the I2O API to create I2O messages first in kernel memory and then transfer it at once over the PCI bus instead of sending each quad-word over the PCI bus. Signed-off-by: Markus Lidel <Markus.Lidel@shadowconnect.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/message/i2o/device.c')
-rw-r--r--drivers/message/i2o/device.c51
1 files changed, 26 insertions, 25 deletions
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
index 8eb50cdb8ae1..002ae0ed8966 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/message/i2o/device.c
@@ -35,18 +35,18 @@
35static inline int i2o_device_issue_claim(struct i2o_device *dev, u32 cmd, 35static inline int i2o_device_issue_claim(struct i2o_device *dev, u32 cmd,
36 u32 type) 36 u32 type)
37{ 37{
38 struct i2o_message __iomem *msg; 38 struct i2o_message *msg;
39 u32 m;
40 39
41 m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET); 40 msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
42 if (m == I2O_QUEUE_EMPTY) 41 if (IS_ERR(msg))
43 return -ETIMEDOUT; 42 return PTR_ERR(msg);
44 43
45 writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); 44 msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
46 writel(cmd << 24 | HOST_TID << 12 | dev->lct_data.tid, &msg->u.head[1]); 45 msg->u.head[1] =
47 writel(type, &msg->body[0]); 46 cpu_to_le32(cmd << 24 | HOST_TID << 12 | dev->lct_data.tid);
47 msg->body[0] = cpu_to_le32(type);
48 48
49 return i2o_msg_post_wait(dev->iop, m, 60); 49 return i2o_msg_post_wait(dev->iop, msg, 60);
50} 50}
51 51
52/** 52/**
@@ -419,10 +419,9 @@ int i2o_device_parse_lct(struct i2o_controller *c)
419 * ResultCount, ErrorInfoSize, BlockStatus and BlockSize. 419 * ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
420 */ 420 */
421int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist, 421int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
422 int oplen, void *reslist, int reslen) 422 int oplen, void *reslist, int reslen)
423{ 423{
424 struct i2o_message __iomem *msg; 424 struct i2o_message *msg;
425 u32 m;
426 u32 *res32 = (u32 *) reslist; 425 u32 *res32 = (u32 *) reslist;
427 u32 *restmp = (u32 *) reslist; 426 u32 *restmp = (u32 *) reslist;
428 int len = 0; 427 int len = 0;
@@ -437,26 +436,28 @@ int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
437 if (i2o_dma_alloc(dev, &res, reslen, GFP_KERNEL)) 436 if (i2o_dma_alloc(dev, &res, reslen, GFP_KERNEL))
438 return -ENOMEM; 437 return -ENOMEM;
439 438
440 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); 439 msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
441 if (m == I2O_QUEUE_EMPTY) { 440 if (IS_ERR(msg)) {
442 i2o_dma_free(dev, &res); 441 i2o_dma_free(dev, &res);
443 return -ETIMEDOUT; 442 return PTR_ERR(msg);
444 } 443 }
445 444
446 i = 0; 445 i = 0;
447 writel(cmd << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid, 446 msg->u.head[1] =
448 &msg->u.head[1]); 447 cpu_to_le32(cmd << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid);
449 writel(0, &msg->body[i++]); 448 msg->body[i++] = cpu_to_le32(0x00000000);
450 writel(0x4C000000 | oplen, &msg->body[i++]); /* OperationList */ 449 msg->body[i++] = cpu_to_le32(0x4C000000 | oplen); /* OperationList */
451 memcpy_toio(&msg->body[i], oplist, oplen); 450 memcpy(&msg->body[i], oplist, oplen);
451
452 i += (oplen / 4 + (oplen % 4 ? 1 : 0)); 452 i += (oplen / 4 + (oplen % 4 ? 1 : 0));
453 writel(0xD0000000 | res.len, &msg->body[i++]); /* ResultList */ 453 msg->body[i++] = cpu_to_le32(0xD0000000 | res.len); /* ResultList */
454 writel(res.phys, &msg->body[i++]); 454 msg->body[i++] = cpu_to_le32(res.phys);
455 455
456 writel(I2O_MESSAGE_SIZE(i + sizeof(struct i2o_message) / 4) | 456 msg->u.head[0] =
457 SGL_OFFSET_5, &msg->u.head[0]); 457 cpu_to_le32(I2O_MESSAGE_SIZE(i + sizeof(struct i2o_message) / 4) |
458 SGL_OFFSET_5);
458 459
459 rc = i2o_msg_post_wait_mem(c, m, 10, &res); 460 rc = i2o_msg_post_wait_mem(c, msg, 10, &res);
460 461
461 /* This only looks like a memory leak - don't "fix" it. */ 462 /* This only looks like a memory leak - don't "fix" it. */
462 if (rc == -ETIMEDOUT) 463 if (rc == -ETIMEDOUT)