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_scsi.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_scsi.c')
-rw-r--r-- | drivers/message/i2o/i2o_scsi.c | 50 |
1 files changed, 24 insertions, 26 deletions
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c index 9f1744c3933b..7a784fd60804 100644 --- a/drivers/message/i2o/i2o_scsi.c +++ b/drivers/message/i2o/i2o_scsi.c | |||
@@ -510,8 +510,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
510 | struct i2o_controller *c; | 510 | struct i2o_controller *c; |
511 | struct i2o_device *i2o_dev; | 511 | struct i2o_device *i2o_dev; |
512 | int tid; | 512 | int tid; |
513 | struct i2o_message __iomem *msg; | 513 | struct i2o_message *msg; |
514 | u32 m; | ||
515 | /* | 514 | /* |
516 | * ENABLE_DISCONNECT | 515 | * ENABLE_DISCONNECT |
517 | * SIMPLE_TAG | 516 | * SIMPLE_TAG |
@@ -519,7 +518,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
519 | */ | 518 | */ |
520 | u32 scsi_flags = 0x20a00000; | 519 | u32 scsi_flags = 0x20a00000; |
521 | u32 sgl_offset; | 520 | u32 sgl_offset; |
522 | u32 __iomem *mptr; | 521 | u32 *mptr; |
523 | u32 cmd = I2O_CMD_SCSI_EXEC << 24; | 522 | u32 cmd = I2O_CMD_SCSI_EXEC << 24; |
524 | int rc = 0; | 523 | int rc = 0; |
525 | 524 | ||
@@ -576,8 +575,8 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
576 | * throw it back to the scsi layer | 575 | * throw it back to the scsi layer |
577 | */ | 576 | */ |
578 | 577 | ||
579 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 578 | msg = i2o_msg_get(c); |
580 | if (m == I2O_QUEUE_EMPTY) { | 579 | if (IS_ERR(msg)) { |
581 | rc = SCSI_MLQUEUE_HOST_BUSY; | 580 | rc = SCSI_MLQUEUE_HOST_BUSY; |
582 | goto exit; | 581 | goto exit; |
583 | } | 582 | } |
@@ -617,16 +616,16 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
617 | if (sgl_offset == SGL_OFFSET_10) | 616 | if (sgl_offset == SGL_OFFSET_10) |
618 | sgl_offset = SGL_OFFSET_12; | 617 | sgl_offset = SGL_OFFSET_12; |
619 | cmd = I2O_CMD_PRIVATE << 24; | 618 | cmd = I2O_CMD_PRIVATE << 24; |
620 | writel(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC, mptr++); | 619 | *mptr++ = cpu_to_le32(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC); |
621 | writel(adpt_flags | tid, mptr++); | 620 | *mptr++ = cpu_to_le32(adpt_flags | tid); |
622 | } | 621 | } |
623 | #endif | 622 | #endif |
624 | 623 | ||
625 | writel(cmd | HOST_TID << 12 | tid, &msg->u.head[1]); | 624 | msg->u.head[1] = cpu_to_le32(cmd | HOST_TID << 12 | tid); |
626 | writel(i2o_scsi_driver.context, &msg->u.s.icntxt); | 625 | msg->u.s.icntxt = cpu_to_le32(i2o_scsi_driver.context); |
627 | 626 | ||
628 | /* We want the SCSI control block back */ | 627 | /* We want the SCSI control block back */ |
629 | writel(i2o_cntxt_list_add(c, SCpnt), &msg->u.s.tcntxt); | 628 | msg->u.s.tcntxt = cpu_to_le32(i2o_cntxt_list_add(c, SCpnt)); |
630 | 629 | ||
631 | /* LSI_920_PCI_QUIRK | 630 | /* LSI_920_PCI_QUIRK |
632 | * | 631 | * |
@@ -649,15 +648,15 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
649 | } | 648 | } |
650 | */ | 649 | */ |
651 | 650 | ||
652 | writel(scsi_flags | SCpnt->cmd_len, mptr++); | 651 | *mptr++ = cpu_to_le32(scsi_flags | SCpnt->cmd_len); |
653 | 652 | ||
654 | /* Write SCSI command into the message - always 16 byte block */ | 653 | /* Write SCSI command into the message - always 16 byte block */ |
655 | memcpy_toio(mptr, SCpnt->cmnd, 16); | 654 | memcpy(mptr, SCpnt->cmnd, 16); |
656 | mptr += 4; | 655 | mptr += 4; |
657 | 656 | ||
658 | if (sgl_offset != SGL_OFFSET_0) { | 657 | if (sgl_offset != SGL_OFFSET_0) { |
659 | /* write size of data addressed by SGL */ | 658 | /* write size of data addressed by SGL */ |
660 | writel(SCpnt->request_bufflen, mptr++); | 659 | *mptr++ = cpu_to_le32(SCpnt->request_bufflen); |
661 | 660 | ||
662 | /* Now fill in the SGList and command */ | 661 | /* Now fill in the SGList and command */ |
663 | if (SCpnt->use_sg) { | 662 | if (SCpnt->use_sg) { |
@@ -676,11 +675,11 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
676 | } | 675 | } |
677 | 676 | ||
678 | /* Stick the headers on */ | 677 | /* Stick the headers on */ |
679 | writel(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | sgl_offset, | 678 | msg->u.head[0] = |
680 | &msg->u.head[0]); | 679 | cpu_to_le32(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | sgl_offset); |
681 | 680 | ||
682 | /* Queue the message */ | 681 | /* Queue the message */ |
683 | i2o_msg_post(c, m); | 682 | i2o_msg_post(c, msg); |
684 | 683 | ||
685 | osm_debug("Issued %ld\n", SCpnt->serial_number); | 684 | osm_debug("Issued %ld\n", SCpnt->serial_number); |
686 | 685 | ||
@@ -688,7 +687,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, | |||
688 | 687 | ||
689 | nomem: | 688 | nomem: |
690 | rc = -ENOMEM; | 689 | rc = -ENOMEM; |
691 | i2o_msg_nop(c, m); | 690 | i2o_msg_nop(c, msg); |
692 | 691 | ||
693 | exit: | 692 | exit: |
694 | return rc; | 693 | return rc; |
@@ -709,8 +708,7 @@ static int i2o_scsi_abort(struct scsi_cmnd *SCpnt) | |||
709 | { | 708 | { |
710 | struct i2o_device *i2o_dev; | 709 | struct i2o_device *i2o_dev; |
711 | struct i2o_controller *c; | 710 | struct i2o_controller *c; |
712 | struct i2o_message __iomem *msg; | 711 | struct i2o_message *msg; |
713 | u32 m; | ||
714 | int tid; | 712 | int tid; |
715 | int status = FAILED; | 713 | int status = FAILED; |
716 | 714 | ||
@@ -720,16 +718,16 @@ static int i2o_scsi_abort(struct scsi_cmnd *SCpnt) | |||
720 | c = i2o_dev->iop; | 718 | c = i2o_dev->iop; |
721 | tid = i2o_dev->lct_data.tid; | 719 | tid = i2o_dev->lct_data.tid; |
722 | 720 | ||
723 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | 721 | msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); |
724 | if (m == I2O_QUEUE_EMPTY) | 722 | if (IS_ERR(msg)) |
725 | return SCSI_MLQUEUE_HOST_BUSY; | 723 | return SCSI_MLQUEUE_HOST_BUSY; |
726 | 724 | ||
727 | writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); | 725 | msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0); |
728 | writel(I2O_CMD_SCSI_ABORT << 24 | HOST_TID << 12 | tid, | 726 | msg->u.head[1] = |
729 | &msg->u.head[1]); | 727 | cpu_to_le32(I2O_CMD_SCSI_ABORT << 24 | HOST_TID << 12 | tid); |
730 | writel(i2o_cntxt_list_get_ptr(c, SCpnt), &msg->body[0]); | 728 | msg->body[0] = cpu_to_le32(i2o_cntxt_list_get_ptr(c, SCpnt)); |
731 | 729 | ||
732 | if (i2o_msg_post_wait(c, m, I2O_TIMEOUT_SCSI_SCB_ABORT)) | 730 | if (i2o_msg_post_wait(c, msg, I2O_TIMEOUT_SCSI_SCB_ABORT)) |
733 | status = SUCCESS; | 731 | status = SUCCESS; |
734 | 732 | ||
735 | return status; | 733 | return status; |