diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2006-12-29 17:47:04 -0500 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2006-12-30 08:26:59 -0500 |
commit | 97d552e35d9404df3254e1157df3340e4e2eaedc (patch) | |
tree | 028f458771d19c9c64d95a7034f728791ae4b8d8 | |
parent | b2bb550c4a10c44e99fe469cfaee81e2e3109994 (diff) |
ieee1394: sbp2: fix bogus dma mapping
Need to use a PCI device, not a FireWire host device. Problem found by
Andreas Schwab, mistake pointed out by Benjamin Herrenschmidt.
http://ozlabs.org/pipermail/linuxppc-dev/2006-December/029595.html
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Tested-by: Andreas Schwab <schwab@suse.de>
-rw-r--r-- | drivers/ieee1394/sbp2.c | 73 |
1 files changed, 40 insertions, 33 deletions
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index d8042830ffed..2b5d7ab3adf7 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
@@ -490,11 +490,11 @@ static int sbp2util_create_command_orb_pool(struct sbp2_lu *lu) | |||
490 | spin_unlock_irqrestore(&lu->cmd_orb_lock, flags); | 490 | spin_unlock_irqrestore(&lu->cmd_orb_lock, flags); |
491 | return -ENOMEM; | 491 | return -ENOMEM; |
492 | } | 492 | } |
493 | cmd->command_orb_dma = dma_map_single(&hi->host->device, | 493 | cmd->command_orb_dma = dma_map_single(hi->host->device.parent, |
494 | &cmd->command_orb, | 494 | &cmd->command_orb, |
495 | sizeof(struct sbp2_command_orb), | 495 | sizeof(struct sbp2_command_orb), |
496 | DMA_TO_DEVICE); | 496 | DMA_TO_DEVICE); |
497 | cmd->sge_dma = dma_map_single(&hi->host->device, | 497 | cmd->sge_dma = dma_map_single(hi->host->device.parent, |
498 | &cmd->scatter_gather_element, | 498 | &cmd->scatter_gather_element, |
499 | sizeof(cmd->scatter_gather_element), | 499 | sizeof(cmd->scatter_gather_element), |
500 | DMA_BIDIRECTIONAL); | 500 | DMA_BIDIRECTIONAL); |
@@ -516,10 +516,11 @@ static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu) | |||
516 | if (!list_empty(&lu->cmd_orb_completed)) | 516 | if (!list_empty(&lu->cmd_orb_completed)) |
517 | list_for_each_safe(lh, next, &lu->cmd_orb_completed) { | 517 | list_for_each_safe(lh, next, &lu->cmd_orb_completed) { |
518 | cmd = list_entry(lh, struct sbp2_command_info, list); | 518 | cmd = list_entry(lh, struct sbp2_command_info, list); |
519 | dma_unmap_single(&host->device, cmd->command_orb_dma, | 519 | dma_unmap_single(host->device.parent, |
520 | cmd->command_orb_dma, | ||
520 | sizeof(struct sbp2_command_orb), | 521 | sizeof(struct sbp2_command_orb), |
521 | DMA_TO_DEVICE); | 522 | DMA_TO_DEVICE); |
522 | dma_unmap_single(&host->device, cmd->sge_dma, | 523 | dma_unmap_single(host->device.parent, cmd->sge_dma, |
523 | sizeof(cmd->scatter_gather_element), | 524 | sizeof(cmd->scatter_gather_element), |
524 | DMA_BIDIRECTIONAL); | 525 | DMA_BIDIRECTIONAL); |
525 | kfree(cmd); | 526 | kfree(cmd); |
@@ -601,17 +602,17 @@ static void sbp2util_mark_command_completed(struct sbp2_lu *lu, | |||
601 | 602 | ||
602 | if (cmd->cmd_dma) { | 603 | if (cmd->cmd_dma) { |
603 | if (cmd->dma_type == CMD_DMA_SINGLE) | 604 | if (cmd->dma_type == CMD_DMA_SINGLE) |
604 | dma_unmap_single(&host->device, cmd->cmd_dma, | 605 | dma_unmap_single(host->device.parent, cmd->cmd_dma, |
605 | cmd->dma_size, cmd->dma_dir); | 606 | cmd->dma_size, cmd->dma_dir); |
606 | else if (cmd->dma_type == CMD_DMA_PAGE) | 607 | else if (cmd->dma_type == CMD_DMA_PAGE) |
607 | dma_unmap_page(&host->device, cmd->cmd_dma, | 608 | dma_unmap_page(host->device.parent, cmd->cmd_dma, |
608 | cmd->dma_size, cmd->dma_dir); | 609 | cmd->dma_size, cmd->dma_dir); |
609 | /* XXX: Check for CMD_DMA_NONE bug */ | 610 | /* XXX: Check for CMD_DMA_NONE bug */ |
610 | cmd->dma_type = CMD_DMA_NONE; | 611 | cmd->dma_type = CMD_DMA_NONE; |
611 | cmd->cmd_dma = 0; | 612 | cmd->cmd_dma = 0; |
612 | } | 613 | } |
613 | if (cmd->sge_buffer) { | 614 | if (cmd->sge_buffer) { |
614 | dma_unmap_sg(&host->device, cmd->sge_buffer, | 615 | dma_unmap_sg(host->device.parent, cmd->sge_buffer, |
615 | cmd->dma_size, cmd->dma_dir); | 616 | cmd->dma_size, cmd->dma_dir); |
616 | cmd->sge_buffer = NULL; | 617 | cmd->sge_buffer = NULL; |
617 | } | 618 | } |
@@ -836,37 +837,37 @@ static int sbp2_start_device(struct sbp2_lu *lu) | |||
836 | struct sbp2_fwhost_info *hi = lu->hi; | 837 | struct sbp2_fwhost_info *hi = lu->hi; |
837 | int error; | 838 | int error; |
838 | 839 | ||
839 | lu->login_response = dma_alloc_coherent(&hi->host->device, | 840 | lu->login_response = dma_alloc_coherent(hi->host->device.parent, |
840 | sizeof(struct sbp2_login_response), | 841 | sizeof(struct sbp2_login_response), |
841 | &lu->login_response_dma, GFP_KERNEL); | 842 | &lu->login_response_dma, GFP_KERNEL); |
842 | if (!lu->login_response) | 843 | if (!lu->login_response) |
843 | goto alloc_fail; | 844 | goto alloc_fail; |
844 | 845 | ||
845 | lu->query_logins_orb = dma_alloc_coherent(&hi->host->device, | 846 | lu->query_logins_orb = dma_alloc_coherent(hi->host->device.parent, |
846 | sizeof(struct sbp2_query_logins_orb), | 847 | sizeof(struct sbp2_query_logins_orb), |
847 | &lu->query_logins_orb_dma, GFP_KERNEL); | 848 | &lu->query_logins_orb_dma, GFP_KERNEL); |
848 | if (!lu->query_logins_orb) | 849 | if (!lu->query_logins_orb) |
849 | goto alloc_fail; | 850 | goto alloc_fail; |
850 | 851 | ||
851 | lu->query_logins_response = dma_alloc_coherent(&hi->host->device, | 852 | lu->query_logins_response = dma_alloc_coherent(hi->host->device.parent, |
852 | sizeof(struct sbp2_query_logins_response), | 853 | sizeof(struct sbp2_query_logins_response), |
853 | &lu->query_logins_response_dma, GFP_KERNEL); | 854 | &lu->query_logins_response_dma, GFP_KERNEL); |
854 | if (!lu->query_logins_response) | 855 | if (!lu->query_logins_response) |
855 | goto alloc_fail; | 856 | goto alloc_fail; |
856 | 857 | ||
857 | lu->reconnect_orb = dma_alloc_coherent(&hi->host->device, | 858 | lu->reconnect_orb = dma_alloc_coherent(hi->host->device.parent, |
858 | sizeof(struct sbp2_reconnect_orb), | 859 | sizeof(struct sbp2_reconnect_orb), |
859 | &lu->reconnect_orb_dma, GFP_KERNEL); | 860 | &lu->reconnect_orb_dma, GFP_KERNEL); |
860 | if (!lu->reconnect_orb) | 861 | if (!lu->reconnect_orb) |
861 | goto alloc_fail; | 862 | goto alloc_fail; |
862 | 863 | ||
863 | lu->logout_orb = dma_alloc_coherent(&hi->host->device, | 864 | lu->logout_orb = dma_alloc_coherent(hi->host->device.parent, |
864 | sizeof(struct sbp2_logout_orb), | 865 | sizeof(struct sbp2_logout_orb), |
865 | &lu->logout_orb_dma, GFP_KERNEL); | 866 | &lu->logout_orb_dma, GFP_KERNEL); |
866 | if (!lu->logout_orb) | 867 | if (!lu->logout_orb) |
867 | goto alloc_fail; | 868 | goto alloc_fail; |
868 | 869 | ||
869 | lu->login_orb = dma_alloc_coherent(&hi->host->device, | 870 | lu->login_orb = dma_alloc_coherent(hi->host->device.parent, |
870 | sizeof(struct sbp2_login_orb), | 871 | sizeof(struct sbp2_login_orb), |
871 | &lu->login_orb_dma, GFP_KERNEL); | 872 | &lu->login_orb_dma, GFP_KERNEL); |
872 | if (!lu->login_orb) | 873 | if (!lu->login_orb) |
@@ -929,32 +930,32 @@ static void sbp2_remove_device(struct sbp2_lu *lu) | |||
929 | list_del(&lu->lu_list); | 930 | list_del(&lu->lu_list); |
930 | 931 | ||
931 | if (lu->login_response) | 932 | if (lu->login_response) |
932 | dma_free_coherent(&hi->host->device, | 933 | dma_free_coherent(hi->host->device.parent, |
933 | sizeof(struct sbp2_login_response), | 934 | sizeof(struct sbp2_login_response), |
934 | lu->login_response, | 935 | lu->login_response, |
935 | lu->login_response_dma); | 936 | lu->login_response_dma); |
936 | if (lu->login_orb) | 937 | if (lu->login_orb) |
937 | dma_free_coherent(&hi->host->device, | 938 | dma_free_coherent(hi->host->device.parent, |
938 | sizeof(struct sbp2_login_orb), | 939 | sizeof(struct sbp2_login_orb), |
939 | lu->login_orb, | 940 | lu->login_orb, |
940 | lu->login_orb_dma); | 941 | lu->login_orb_dma); |
941 | if (lu->reconnect_orb) | 942 | if (lu->reconnect_orb) |
942 | dma_free_coherent(&hi->host->device, | 943 | dma_free_coherent(hi->host->device.parent, |
943 | sizeof(struct sbp2_reconnect_orb), | 944 | sizeof(struct sbp2_reconnect_orb), |
944 | lu->reconnect_orb, | 945 | lu->reconnect_orb, |
945 | lu->reconnect_orb_dma); | 946 | lu->reconnect_orb_dma); |
946 | if (lu->logout_orb) | 947 | if (lu->logout_orb) |
947 | dma_free_coherent(&hi->host->device, | 948 | dma_free_coherent(hi->host->device.parent, |
948 | sizeof(struct sbp2_logout_orb), | 949 | sizeof(struct sbp2_logout_orb), |
949 | lu->logout_orb, | 950 | lu->logout_orb, |
950 | lu->logout_orb_dma); | 951 | lu->logout_orb_dma); |
951 | if (lu->query_logins_orb) | 952 | if (lu->query_logins_orb) |
952 | dma_free_coherent(&hi->host->device, | 953 | dma_free_coherent(hi->host->device.parent, |
953 | sizeof(struct sbp2_query_logins_orb), | 954 | sizeof(struct sbp2_query_logins_orb), |
954 | lu->query_logins_orb, | 955 | lu->query_logins_orb, |
955 | lu->query_logins_orb_dma); | 956 | lu->query_logins_orb_dma); |
956 | if (lu->query_logins_response) | 957 | if (lu->query_logins_response) |
957 | dma_free_coherent(&hi->host->device, | 958 | dma_free_coherent(hi->host->device.parent, |
958 | sizeof(struct sbp2_query_logins_response), | 959 | sizeof(struct sbp2_query_logins_response), |
959 | lu->query_logins_response, | 960 | lu->query_logins_response, |
960 | lu->query_logins_response_dma); | 961 | lu->query_logins_response_dma); |
@@ -1445,7 +1446,7 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, | |||
1445 | 1446 | ||
1446 | cmd->dma_size = sgpnt[0].length; | 1447 | cmd->dma_size = sgpnt[0].length; |
1447 | cmd->dma_type = CMD_DMA_PAGE; | 1448 | cmd->dma_type = CMD_DMA_PAGE; |
1448 | cmd->cmd_dma = dma_map_page(&hi->host->device, | 1449 | cmd->cmd_dma = dma_map_page(hi->host->device.parent, |
1449 | sgpnt[0].page, sgpnt[0].offset, | 1450 | sgpnt[0].page, sgpnt[0].offset, |
1450 | cmd->dma_size, cmd->dma_dir); | 1451 | cmd->dma_size, cmd->dma_dir); |
1451 | 1452 | ||
@@ -1457,8 +1458,8 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, | |||
1457 | &cmd->scatter_gather_element[0]; | 1458 | &cmd->scatter_gather_element[0]; |
1458 | u32 sg_count, sg_len; | 1459 | u32 sg_count, sg_len; |
1459 | dma_addr_t sg_addr; | 1460 | dma_addr_t sg_addr; |
1460 | int i, count = dma_map_sg(&hi->host->device, sgpnt, scsi_use_sg, | 1461 | int i, count = dma_map_sg(hi->host->device.parent, sgpnt, |
1461 | dma_dir); | 1462 | scsi_use_sg, dma_dir); |
1462 | 1463 | ||
1463 | cmd->dma_size = scsi_use_sg; | 1464 | cmd->dma_size = scsi_use_sg; |
1464 | cmd->sge_buffer = sgpnt; | 1465 | cmd->sge_buffer = sgpnt; |
@@ -1508,7 +1509,8 @@ static void sbp2_prep_command_orb_no_sg(struct sbp2_command_orb *orb, | |||
1508 | cmd->dma_dir = dma_dir; | 1509 | cmd->dma_dir = dma_dir; |
1509 | cmd->dma_size = scsi_request_bufflen; | 1510 | cmd->dma_size = scsi_request_bufflen; |
1510 | cmd->dma_type = CMD_DMA_SINGLE; | 1511 | cmd->dma_type = CMD_DMA_SINGLE; |
1511 | cmd->cmd_dma = dma_map_single(&hi->host->device, scsi_request_buffer, | 1512 | cmd->cmd_dma = dma_map_single(hi->host->device.parent, |
1513 | scsi_request_buffer, | ||
1512 | cmd->dma_size, cmd->dma_dir); | 1514 | cmd->dma_size, cmd->dma_dir); |
1513 | orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id); | 1515 | orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id); |
1514 | orb->misc |= ORB_SET_DIRECTION(orb_direction); | 1516 | orb->misc |= ORB_SET_DIRECTION(orb_direction); |
@@ -1626,10 +1628,11 @@ static void sbp2_link_orb_command(struct sbp2_lu *lu, | |||
1626 | size_t length; | 1628 | size_t length; |
1627 | unsigned long flags; | 1629 | unsigned long flags; |
1628 | 1630 | ||
1629 | dma_sync_single_for_device(&hi->host->device, cmd->command_orb_dma, | 1631 | dma_sync_single_for_device(hi->host->device.parent, |
1632 | cmd->command_orb_dma, | ||
1630 | sizeof(struct sbp2_command_orb), | 1633 | sizeof(struct sbp2_command_orb), |
1631 | DMA_TO_DEVICE); | 1634 | DMA_TO_DEVICE); |
1632 | dma_sync_single_for_device(&hi->host->device, cmd->sge_dma, | 1635 | dma_sync_single_for_device(hi->host->device.parent, cmd->sge_dma, |
1633 | sizeof(cmd->scatter_gather_element), | 1636 | sizeof(cmd->scatter_gather_element), |
1634 | DMA_BIDIRECTIONAL); | 1637 | DMA_BIDIRECTIONAL); |
1635 | 1638 | ||
@@ -1655,14 +1658,15 @@ static void sbp2_link_orb_command(struct sbp2_lu *lu, | |||
1655 | * The target's fetch agent may or may not have read this | 1658 | * The target's fetch agent may or may not have read this |
1656 | * previous ORB yet. | 1659 | * previous ORB yet. |
1657 | */ | 1660 | */ |
1658 | dma_sync_single_for_cpu(&hi->host->device, last_orb_dma, | 1661 | dma_sync_single_for_cpu(hi->host->device.parent, last_orb_dma, |
1659 | sizeof(struct sbp2_command_orb), | 1662 | sizeof(struct sbp2_command_orb), |
1660 | DMA_TO_DEVICE); | 1663 | DMA_TO_DEVICE); |
1661 | last_orb->next_ORB_lo = cpu_to_be32(cmd->command_orb_dma); | 1664 | last_orb->next_ORB_lo = cpu_to_be32(cmd->command_orb_dma); |
1662 | wmb(); | 1665 | wmb(); |
1663 | /* Tells hardware that this pointer is valid */ | 1666 | /* Tells hardware that this pointer is valid */ |
1664 | last_orb->next_ORB_hi = 0; | 1667 | last_orb->next_ORB_hi = 0; |
1665 | dma_sync_single_for_device(&hi->host->device, last_orb_dma, | 1668 | dma_sync_single_for_device(hi->host->device.parent, |
1669 | last_orb_dma, | ||
1666 | sizeof(struct sbp2_command_orb), | 1670 | sizeof(struct sbp2_command_orb), |
1667 | DMA_TO_DEVICE); | 1671 | DMA_TO_DEVICE); |
1668 | addr += SBP2_DOORBELL_OFFSET; | 1672 | addr += SBP2_DOORBELL_OFFSET; |
@@ -1790,10 +1794,11 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, | |||
1790 | else | 1794 | else |
1791 | cmd = sbp2util_find_command_for_orb(lu, sb->ORB_offset_lo); | 1795 | cmd = sbp2util_find_command_for_orb(lu, sb->ORB_offset_lo); |
1792 | if (cmd) { | 1796 | if (cmd) { |
1793 | dma_sync_single_for_cpu(&hi->host->device, cmd->command_orb_dma, | 1797 | dma_sync_single_for_cpu(hi->host->device.parent, |
1798 | cmd->command_orb_dma, | ||
1794 | sizeof(struct sbp2_command_orb), | 1799 | sizeof(struct sbp2_command_orb), |
1795 | DMA_TO_DEVICE); | 1800 | DMA_TO_DEVICE); |
1796 | dma_sync_single_for_cpu(&hi->host->device, cmd->sge_dma, | 1801 | dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma, |
1797 | sizeof(cmd->scatter_gather_element), | 1802 | sizeof(cmd->scatter_gather_element), |
1798 | DMA_BIDIRECTIONAL); | 1803 | DMA_BIDIRECTIONAL); |
1799 | /* Grab SCSI command pointers and check status. */ | 1804 | /* Grab SCSI command pointers and check status. */ |
@@ -1921,10 +1926,11 @@ static void sbp2scsi_complete_all_commands(struct sbp2_lu *lu, u32 status) | |||
1921 | while (!list_empty(&lu->cmd_orb_inuse)) { | 1926 | while (!list_empty(&lu->cmd_orb_inuse)) { |
1922 | lh = lu->cmd_orb_inuse.next; | 1927 | lh = lu->cmd_orb_inuse.next; |
1923 | cmd = list_entry(lh, struct sbp2_command_info, list); | 1928 | cmd = list_entry(lh, struct sbp2_command_info, list); |
1924 | dma_sync_single_for_cpu(&hi->host->device, cmd->command_orb_dma, | 1929 | dma_sync_single_for_cpu(hi->host->device.parent, |
1930 | cmd->command_orb_dma, | ||
1925 | sizeof(struct sbp2_command_orb), | 1931 | sizeof(struct sbp2_command_orb), |
1926 | DMA_TO_DEVICE); | 1932 | DMA_TO_DEVICE); |
1927 | dma_sync_single_for_cpu(&hi->host->device, cmd->sge_dma, | 1933 | dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma, |
1928 | sizeof(cmd->scatter_gather_element), | 1934 | sizeof(cmd->scatter_gather_element), |
1929 | DMA_BIDIRECTIONAL); | 1935 | DMA_BIDIRECTIONAL); |
1930 | sbp2util_mark_command_completed(lu, cmd); | 1936 | sbp2util_mark_command_completed(lu, cmd); |
@@ -2049,11 +2055,12 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt) | |||
2049 | spin_lock_irqsave(&lu->cmd_orb_lock, flags); | 2055 | spin_lock_irqsave(&lu->cmd_orb_lock, flags); |
2050 | cmd = sbp2util_find_command_for_SCpnt(lu, SCpnt); | 2056 | cmd = sbp2util_find_command_for_SCpnt(lu, SCpnt); |
2051 | if (cmd) { | 2057 | if (cmd) { |
2052 | dma_sync_single_for_cpu(&hi->host->device, | 2058 | dma_sync_single_for_cpu(hi->host->device.parent, |
2053 | cmd->command_orb_dma, | 2059 | cmd->command_orb_dma, |
2054 | sizeof(struct sbp2_command_orb), | 2060 | sizeof(struct sbp2_command_orb), |
2055 | DMA_TO_DEVICE); | 2061 | DMA_TO_DEVICE); |
2056 | dma_sync_single_for_cpu(&hi->host->device, cmd->sge_dma, | 2062 | dma_sync_single_for_cpu(hi->host->device.parent, |
2063 | cmd->sge_dma, | ||
2057 | sizeof(cmd->scatter_gather_element), | 2064 | sizeof(cmd->scatter_gather_element), |
2058 | DMA_BIDIRECTIONAL); | 2065 | DMA_BIDIRECTIONAL); |
2059 | sbp2util_mark_command_completed(lu, cmd); | 2066 | sbp2util_mark_command_completed(lu, cmd); |