diff options
author | Markus Lidel <Markus.Lidel@shadowconnect.com> | 2006-01-06 03:19:29 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 11:33:53 -0500 |
commit | a1a5ea70a6e9db6332b27fe2d96666e17aa1436b (patch) | |
tree | 7edfe920aa40af94464ab05539d449dbe5689254 /drivers/message/i2o/i2o_config.c | |
parent | 347a8dc3b815f0c0fa62a1df075184ffe4cbdcf1 (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/i2o_config.c')
-rw-r--r-- | drivers/message/i2o/i2o_config.c | 169 |
1 files changed, 83 insertions, 86 deletions
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index 3c3a7abebb1b..4fe73d628c5b 100644 --- a/drivers/message/i2o/i2o_config.c +++ b/drivers/message/i2o/i2o_config.c | |||
@@ -230,8 +230,7 @@ static int i2o_cfg_swdl(unsigned long arg) | |||
230 | struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; | 230 | struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; |
231 | unsigned char maxfrag = 0, curfrag = 1; | 231 | unsigned char maxfrag = 0, curfrag = 1; |
232 | struct i2o_dma buffer; | 232 | struct i2o_dma buffer; |
233 | struct i2o_message __iomem *msg; | 233 | struct i2o_message *msg; |
234 | u32 m; | ||
235 | unsigned int status = 0, swlen = 0, fragsize = 8192; | 234 | unsigned int status = 0, swlen = 0, fragsize = 8192; |
236 | struct i2o_controller *c; | 235 | struct i2o_controller *c; |
237 | 236 | ||
@@ -257,31 +256,34 @@ static int i2o_cfg_swdl(unsigned long arg) | |||
257 | if (!c) | 256 | if (!c) |
258 | return -ENXIO; | 257 | return -ENXIO; |
259 | 258 | ||
260 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 259 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
261 | if (m == I2O_QUEUE_EMPTY) | 260 | if (IS_ERR(msg)) |
262 | return -EBUSY; | 261 | return PTR_ERR(msg); |
263 | 262 | ||
264 | if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) { | 263 | if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) { |
265 | i2o_msg_nop(c, m); | 264 | i2o_msg_nop(c, msg); |
266 | return -ENOMEM; | 265 | return -ENOMEM; |
267 | } | 266 | } |
268 | 267 | ||
269 | __copy_from_user(buffer.virt, kxfer.buf, fragsize); | 268 | __copy_from_user(buffer.virt, kxfer.buf, fragsize); |
270 | 269 | ||
271 | writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]); | 270 | msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_7); |
272 | writel(I2O_CMD_SW_DOWNLOAD << 24 | HOST_TID << 12 | ADAPTER_TID, | 271 | msg->u.head[1] = |
273 | &msg->u.head[1]); | 272 | cpu_to_le32(I2O_CMD_SW_DOWNLOAD << 24 | HOST_TID << 12 | |
274 | writel(i2o_config_driver.context, &msg->u.head[2]); | 273 | ADAPTER_TID); |
275 | writel(0, &msg->u.head[3]); | 274 | msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); |
276 | writel((((u32) kxfer.flags) << 24) | (((u32) kxfer.sw_type) << 16) | | 275 | msg->u.head[3] = cpu_to_le32(0); |
277 | (((u32) maxfrag) << 8) | (((u32) curfrag)), &msg->body[0]); | 276 | msg->body[0] = |
278 | writel(swlen, &msg->body[1]); | 277 | cpu_to_le32((((u32) kxfer.flags) << 24) | (((u32) kxfer. |
279 | writel(kxfer.sw_id, &msg->body[2]); | 278 | sw_type) << 16) | |
280 | writel(0xD0000000 | fragsize, &msg->body[3]); | 279 | (((u32) maxfrag) << 8) | (((u32) curfrag))); |
281 | writel(buffer.phys, &msg->body[4]); | 280 | msg->body[1] = cpu_to_le32(swlen); |
281 | msg->body[2] = cpu_to_le32(kxfer.sw_id); | ||
282 | msg->body[3] = cpu_to_le32(0xD0000000 | fragsize); | ||
283 | msg->body[4] = cpu_to_le32(buffer.phys); | ||
282 | 284 | ||
283 | osm_debug("swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize); | 285 | osm_debug("swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize); |
284 | status = i2o_msg_post_wait_mem(c, m, 60, &buffer); | 286 | status = i2o_msg_post_wait_mem(c, msg, 60, &buffer); |
285 | 287 | ||
286 | if (status != -ETIMEDOUT) | 288 | if (status != -ETIMEDOUT) |
287 | i2o_dma_free(&c->pdev->dev, &buffer); | 289 | i2o_dma_free(&c->pdev->dev, &buffer); |
@@ -302,8 +304,7 @@ static int i2o_cfg_swul(unsigned long arg) | |||
302 | struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; | 304 | struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; |
303 | unsigned char maxfrag = 0, curfrag = 1; | 305 | unsigned char maxfrag = 0, curfrag = 1; |
304 | struct i2o_dma buffer; | 306 | struct i2o_dma buffer; |
305 | struct i2o_message __iomem *msg; | 307 | struct i2o_message *msg; |
306 | u32 m; | ||
307 | unsigned int status = 0, swlen = 0, fragsize = 8192; | 308 | unsigned int status = 0, swlen = 0, fragsize = 8192; |
308 | struct i2o_controller *c; | 309 | struct i2o_controller *c; |
309 | int ret = 0; | 310 | int ret = 0; |
@@ -330,30 +331,30 @@ static int i2o_cfg_swul(unsigned long arg) | |||
330 | if (!c) | 331 | if (!c) |
331 | return -ENXIO; | 332 | return -ENXIO; |
332 | 333 | ||
333 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 334 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
334 | if (m == I2O_QUEUE_EMPTY) | 335 | if (IS_ERR(msg)) |
335 | return -EBUSY; | 336 | return PTR_ERR(msg); |
336 | 337 | ||
337 | if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) { | 338 | if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) { |
338 | i2o_msg_nop(c, m); | 339 | i2o_msg_nop(c, msg); |
339 | return -ENOMEM; | 340 | return -ENOMEM; |
340 | } | 341 | } |
341 | 342 | ||
342 | writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]); | 343 | msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_7); |
343 | writel(I2O_CMD_SW_UPLOAD << 24 | HOST_TID << 12 | ADAPTER_TID, | 344 | msg->u.head[1] = |
344 | &msg->u.head[1]); | 345 | cpu_to_le32(I2O_CMD_SW_UPLOAD << 24 | HOST_TID << 12 | ADAPTER_TID); |
345 | writel(i2o_config_driver.context, &msg->u.head[2]); | 346 | msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); |
346 | writel(0, &msg->u.head[3]); | 347 | msg->u.head[3] = cpu_to_le32(0); |
347 | writel((u32) kxfer.flags << 24 | (u32) kxfer. | 348 | msg->body[0] = |
348 | sw_type << 16 | (u32) maxfrag << 8 | (u32) curfrag, | 349 | cpu_to_le32((u32) kxfer.flags << 24 | (u32) kxfer. |
349 | &msg->body[0]); | 350 | sw_type << 16 | (u32) maxfrag << 8 | (u32) curfrag); |
350 | writel(swlen, &msg->body[1]); | 351 | msg->body[1] = cpu_to_le32(swlen); |
351 | writel(kxfer.sw_id, &msg->body[2]); | 352 | msg->body[2] = cpu_to_le32(kxfer.sw_id); |
352 | writel(0xD0000000 | fragsize, &msg->body[3]); | 353 | msg->body[3] = cpu_to_le32(0xD0000000 | fragsize); |
353 | writel(buffer.phys, &msg->body[4]); | 354 | msg->body[4] = cpu_to_le32(buffer.phys); |
354 | 355 | ||
355 | osm_debug("swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize); | 356 | osm_debug("swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize); |
356 | status = i2o_msg_post_wait_mem(c, m, 60, &buffer); | 357 | status = i2o_msg_post_wait_mem(c, msg, 60, &buffer); |
357 | 358 | ||
358 | if (status != I2O_POST_WAIT_OK) { | 359 | if (status != I2O_POST_WAIT_OK) { |
359 | if (status != -ETIMEDOUT) | 360 | if (status != -ETIMEDOUT) |
@@ -380,8 +381,7 @@ static int i2o_cfg_swdel(unsigned long arg) | |||
380 | struct i2o_controller *c; | 381 | struct i2o_controller *c; |
381 | struct i2o_sw_xfer kxfer; | 382 | struct i2o_sw_xfer kxfer; |
382 | struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; | 383 | struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg; |
383 | struct i2o_message __iomem *msg; | 384 | struct i2o_message *msg; |
384 | u32 m; | ||
385 | unsigned int swlen; | 385 | unsigned int swlen; |
386 | int token; | 386 | int token; |
387 | 387 | ||
@@ -395,21 +395,21 @@ static int i2o_cfg_swdel(unsigned long arg) | |||
395 | if (!c) | 395 | if (!c) |
396 | return -ENXIO; | 396 | return -ENXIO; |
397 | 397 | ||
398 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 398 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
399 | if (m == I2O_QUEUE_EMPTY) | 399 | if (IS_ERR(msg)) |
400 | return -EBUSY; | 400 | return PTR_ERR(msg); |
401 | 401 | ||
402 | writel(SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); | 402 | msg->u.head[0] = cpu_to_le32(SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0); |
403 | writel(I2O_CMD_SW_REMOVE << 24 | HOST_TID << 12 | ADAPTER_TID, | 403 | msg->u.head[1] = |
404 | &msg->u.head[1]); | 404 | cpu_to_le32(I2O_CMD_SW_REMOVE << 24 | HOST_TID << 12 | ADAPTER_TID); |
405 | writel(i2o_config_driver.context, &msg->u.head[2]); | 405 | msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); |
406 | writel(0, &msg->u.head[3]); | 406 | msg->u.head[3] = cpu_to_le32(0); |
407 | writel((u32) kxfer.flags << 24 | (u32) kxfer.sw_type << 16, | 407 | msg->body[0] = |
408 | &msg->body[0]); | 408 | cpu_to_le32((u32) kxfer.flags << 24 | (u32) kxfer.sw_type << 16); |
409 | writel(swlen, &msg->body[1]); | 409 | msg->body[1] = cpu_to_le32(swlen); |
410 | writel(kxfer.sw_id, &msg->body[2]); | 410 | msg->body[2] = cpu_to_le32(kxfer.sw_id); |
411 | 411 | ||
412 | token = i2o_msg_post_wait(c, m, 10); | 412 | token = i2o_msg_post_wait(c, msg, 10); |
413 | 413 | ||
414 | if (token != I2O_POST_WAIT_OK) { | 414 | if (token != I2O_POST_WAIT_OK) { |
415 | osm_info("swdel failed, DetailedStatus = %d\n", token); | 415 | osm_info("swdel failed, DetailedStatus = %d\n", token); |
@@ -423,25 +423,24 @@ static int i2o_cfg_validate(unsigned long arg) | |||
423 | { | 423 | { |
424 | int token; | 424 | int token; |
425 | int iop = (int)arg; | 425 | int iop = (int)arg; |
426 | struct i2o_message __iomem *msg; | 426 | struct i2o_message *msg; |
427 | u32 m; | ||
428 | struct i2o_controller *c; | 427 | struct i2o_controller *c; |
429 | 428 | ||
430 | c = i2o_find_iop(iop); | 429 | c = i2o_find_iop(iop); |
431 | if (!c) | 430 | if (!c) |
432 | return -ENXIO; | 431 | return -ENXIO; |
433 | 432 | ||
434 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 433 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
435 | if (m == I2O_QUEUE_EMPTY) | 434 | if (IS_ERR(msg)) |
436 | return -EBUSY; | 435 | return PTR_ERR(msg); |
437 | 436 | ||
438 | writel(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); | 437 | msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0); |
439 | writel(I2O_CMD_CONFIG_VALIDATE << 24 | HOST_TID << 12 | iop, | 438 | msg->u.head[1] = |
440 | &msg->u.head[1]); | 439 | cpu_to_le32(I2O_CMD_CONFIG_VALIDATE << 24 | HOST_TID << 12 | iop); |
441 | writel(i2o_config_driver.context, &msg->u.head[2]); | 440 | msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); |
442 | writel(0, &msg->u.head[3]); | 441 | msg->u.head[3] = cpu_to_le32(0); |
443 | 442 | ||
444 | token = i2o_msg_post_wait(c, m, 10); | 443 | token = i2o_msg_post_wait(c, msg, 10); |
445 | 444 | ||
446 | if (token != I2O_POST_WAIT_OK) { | 445 | if (token != I2O_POST_WAIT_OK) { |
447 | osm_info("Can't validate configuration, ErrorStatus = %d\n", | 446 | osm_info("Can't validate configuration, ErrorStatus = %d\n", |
@@ -454,8 +453,7 @@ static int i2o_cfg_validate(unsigned long arg) | |||
454 | 453 | ||
455 | static int i2o_cfg_evt_reg(unsigned long arg, struct file *fp) | 454 | static int i2o_cfg_evt_reg(unsigned long arg, struct file *fp) |
456 | { | 455 | { |
457 | struct i2o_message __iomem *msg; | 456 | struct i2o_message *msg; |
458 | u32 m; | ||
459 | struct i2o_evt_id __user *pdesc = (struct i2o_evt_id __user *)arg; | 457 | struct i2o_evt_id __user *pdesc = (struct i2o_evt_id __user *)arg; |
460 | struct i2o_evt_id kdesc; | 458 | struct i2o_evt_id kdesc; |
461 | struct i2o_controller *c; | 459 | struct i2o_controller *c; |
@@ -474,18 +472,19 @@ static int i2o_cfg_evt_reg(unsigned long arg, struct file *fp) | |||
474 | if (!d) | 472 | if (!d) |
475 | return -ENODEV; | 473 | return -ENODEV; |
476 | 474 | ||
477 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 475 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
478 | if (m == I2O_QUEUE_EMPTY) | 476 | if (IS_ERR(msg)) |
479 | return -EBUSY; | 477 | return PTR_ERR(msg); |
480 | 478 | ||
481 | writel(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); | 479 | msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0); |
482 | writel(I2O_CMD_UTIL_EVT_REGISTER << 24 | HOST_TID << 12 | kdesc.tid, | 480 | msg->u.head[1] = |
483 | &msg->u.head[1]); | 481 | cpu_to_le32(I2O_CMD_UTIL_EVT_REGISTER << 24 | HOST_TID << 12 | |
484 | writel(i2o_config_driver.context, &msg->u.head[2]); | 482 | kdesc.tid); |
485 | writel(i2o_cntxt_list_add(c, fp->private_data), &msg->u.head[3]); | 483 | msg->u.head[2] = cpu_to_le32(i2o_config_driver.context); |
486 | writel(kdesc.evt_mask, &msg->body[0]); | 484 | msg->u.head[3] = cpu_to_le32(i2o_cntxt_list_add(c, fp->private_data)); |
485 | msg->body[0] = cpu_to_le32(kdesc.evt_mask); | ||
487 | 486 | ||
488 | i2o_msg_post(c, m); | 487 | i2o_msg_post(c, msg); |
489 | 488 | ||
490 | return 0; | 489 | return 0; |
491 | } | 490 | } |
@@ -537,7 +536,6 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, | |||
537 | u32 sg_index = 0; | 536 | u32 sg_index = 0; |
538 | i2o_status_block *sb; | 537 | i2o_status_block *sb; |
539 | struct i2o_message *msg; | 538 | struct i2o_message *msg; |
540 | u32 m; | ||
541 | unsigned int iop; | 539 | unsigned int iop; |
542 | 540 | ||
543 | cmd = (struct i2o_cmd_passthru32 __user *)arg; | 541 | cmd = (struct i2o_cmd_passthru32 __user *)arg; |
@@ -553,7 +551,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, | |||
553 | return -ENXIO; | 551 | return -ENXIO; |
554 | } | 552 | } |
555 | 553 | ||
556 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 554 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
557 | 555 | ||
558 | sb = c->status_block.virt; | 556 | sb = c->status_block.virt; |
559 | 557 | ||
@@ -595,8 +593,8 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, | |||
595 | 593 | ||
596 | sg_offset = (msg->u.head[0] >> 4) & 0x0f; | 594 | sg_offset = (msg->u.head[0] >> 4) & 0x0f; |
597 | 595 | ||
598 | writel(i2o_config_driver.context, &msg->u.s.icntxt); | 596 | msg->u.s.icntxt = cpu_to_le32(i2o_config_driver.context); |
599 | writel(i2o_cntxt_list_add(c, reply), &msg->u.s.tcntxt); | 597 | msg->u.s.tcntxt = cpu_to_le32(i2o_cntxt_list_add(c, reply)); |
600 | 598 | ||
601 | memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE); | 599 | memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE); |
602 | if (sg_offset) { | 600 | if (sg_offset) { |
@@ -662,7 +660,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, | |||
662 | } | 660 | } |
663 | } | 661 | } |
664 | 662 | ||
665 | rcode = i2o_msg_post_wait(c, m, 60); | 663 | rcode = i2o_msg_post_wait(c, msg, 60); |
666 | if (rcode) | 664 | if (rcode) |
667 | goto sg_list_cleanup; | 665 | goto sg_list_cleanup; |
668 | 666 | ||
@@ -780,8 +778,7 @@ static int i2o_cfg_passthru(unsigned long arg) | |||
780 | u32 i = 0; | 778 | u32 i = 0; |
781 | void *p = NULL; | 779 | void *p = NULL; |
782 | i2o_status_block *sb; | 780 | i2o_status_block *sb; |
783 | struct i2o_message __iomem *msg; | 781 | struct i2o_message *msg; |
784 | u32 m; | ||
785 | unsigned int iop; | 782 | unsigned int iop; |
786 | 783 | ||
787 | if (get_user(iop, &cmd->iop) || get_user(user_msg, &cmd->msg)) | 784 | if (get_user(iop, &cmd->iop) || get_user(user_msg, &cmd->msg)) |
@@ -793,7 +790,7 @@ static int i2o_cfg_passthru(unsigned long arg) | |||
793 | return -ENXIO; | 790 | return -ENXIO; |
794 | } | 791 | } |
795 | 792 | ||
796 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 793 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
797 | 794 | ||
798 | sb = c->status_block.virt; | 795 | sb = c->status_block.virt; |
799 | 796 | ||
@@ -830,8 +827,8 @@ static int i2o_cfg_passthru(unsigned long arg) | |||
830 | 827 | ||
831 | sg_offset = (msg->u.head[0] >> 4) & 0x0f; | 828 | sg_offset = (msg->u.head[0] >> 4) & 0x0f; |
832 | 829 | ||
833 | writel(i2o_config_driver.context, &msg->u.s.icntxt); | 830 | msg->u.s.icntxt = cpu_to_le32(i2o_config_driver.context); |
834 | writel(i2o_cntxt_list_add(c, reply), &msg->u.s.tcntxt); | 831 | msg->u.s.tcntxt = cpu_to_le32(i2o_cntxt_list_add(c, reply)); |
835 | 832 | ||
836 | memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE); | 833 | memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE); |
837 | if (sg_offset) { | 834 | if (sg_offset) { |
@@ -894,7 +891,7 @@ static int i2o_cfg_passthru(unsigned long arg) | |||
894 | } | 891 | } |
895 | } | 892 | } |
896 | 893 | ||
897 | rcode = i2o_msg_post_wait(c, m, 60); | 894 | rcode = i2o_msg_post_wait(c, msg, 60); |
898 | if (rcode) | 895 | if (rcode) |
899 | goto sg_list_cleanup; | 896 | goto sg_list_cleanup; |
900 | 897 | ||