diff options
-rw-r--r-- | arch/x86_64/kernel/pci-calgary.c | 85 | ||||
-rw-r--r-- | include/asm-x86_64/rio.h | 8 |
2 files changed, 52 insertions, 41 deletions
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index afc0a53505f1..8a1e4f35bc3c 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c | |||
@@ -138,7 +138,7 @@ static int calgary_detected __read_mostly = 0; | |||
138 | 138 | ||
139 | static struct rio_table_hdr *rio_table_hdr __initdata; | 139 | static struct rio_table_hdr *rio_table_hdr __initdata; |
140 | static struct scal_detail *scal_devs[MAX_NUMNODES] __initdata; | 140 | static struct scal_detail *scal_devs[MAX_NUMNODES] __initdata; |
141 | static struct rio_detail *rio_devs[MAX_NUMNODES*4] __initdata; | 141 | static struct rio_detail *rio_devs[MAX_NUMNODES * 4] __initdata; |
142 | 142 | ||
143 | struct calgary_bus_info { | 143 | struct calgary_bus_info { |
144 | void *tce_space; | 144 | void *tce_space; |
@@ -855,11 +855,6 @@ static void __init calgary_disable_translation(struct pci_dev *dev) | |||
855 | del_timer_sync(&tbl->watchdog_timer); | 855 | del_timer_sync(&tbl->watchdog_timer); |
856 | } | 856 | } |
857 | 857 | ||
858 | static inline void __iomem * __init locate_register_space(struct pci_dev *dev) | ||
859 | { | ||
860 | return busno_to_bbar(dev->bus->number); | ||
861 | } | ||
862 | |||
863 | static void __init calgary_init_one_nontraslated(struct pci_dev *dev) | 858 | static void __init calgary_init_one_nontraslated(struct pci_dev *dev) |
864 | { | 859 | { |
865 | pci_dev_get(dev); | 860 | pci_dev_get(dev); |
@@ -874,15 +869,10 @@ static int __init calgary_init_one(struct pci_dev *dev) | |||
874 | 869 | ||
875 | BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM); | 870 | BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM); |
876 | 871 | ||
877 | bbar = locate_register_space(dev); | 872 | bbar = busno_to_bbar(dev->bus->number); |
878 | if (!bbar) { | ||
879 | ret = -ENODATA; | ||
880 | goto done; | ||
881 | } | ||
882 | |||
883 | ret = calgary_setup_tar(dev, bbar); | 873 | ret = calgary_setup_tar(dev, bbar); |
884 | if (ret) | 874 | if (ret) |
885 | goto iounmap; | 875 | goto done; |
886 | 876 | ||
887 | pci_dev_get(dev); | 877 | pci_dev_get(dev); |
888 | dev->bus->self = dev; | 878 | dev->bus->self = dev; |
@@ -890,38 +880,39 @@ static int __init calgary_init_one(struct pci_dev *dev) | |||
890 | 880 | ||
891 | return 0; | 881 | return 0; |
892 | 882 | ||
893 | iounmap: | ||
894 | iounmap(bbar); | ||
895 | done: | 883 | done: |
896 | return ret; | 884 | return ret; |
897 | } | 885 | } |
898 | 886 | ||
899 | static int __init calgary_init(void) | 887 | static int __init calgary_locate_bbars(void) |
900 | { | 888 | { |
901 | int ret = -ENODEV; | 889 | int ret; |
902 | struct pci_dev *dev = NULL; | 890 | int rioidx, phb, bus; |
903 | int rio, phb, bus; | ||
904 | void __iomem *bbar; | 891 | void __iomem *bbar; |
905 | void __iomem *target; | 892 | void __iomem *target; |
893 | unsigned long offset; | ||
906 | u8 start_bus, end_bus; | 894 | u8 start_bus, end_bus; |
907 | u32 val; | 895 | u32 val; |
908 | 896 | ||
909 | for (rio = 0; rio < rio_table_hdr->num_rio_dev; rio++) { | 897 | ret = -ENODATA; |
898 | for (rioidx = 0; rioidx < rio_table_hdr->num_rio_dev; rioidx++) { | ||
899 | struct rio_detail *rio = rio_devs[rioidx]; | ||
910 | 900 | ||
911 | if ( (rio_devs[rio]->type != COMPAT_CALGARY) && | 901 | if ((rio->type != COMPAT_CALGARY) && (rio->type != ALT_CALGARY)) |
912 | (rio_devs[rio]->type != ALT_CALGARY) ) | ||
913 | continue; | 902 | continue; |
914 | 903 | ||
915 | /* map entire 1MB of Calgary config space */ | 904 | /* map entire 1MB of Calgary config space */ |
916 | bbar = ioremap_nocache(rio_devs[rio]->BBAR, 1024 * 1024); | 905 | bbar = ioremap_nocache(rio->BBAR, 1024 * 1024); |
906 | if (!bbar) | ||
907 | goto error; | ||
917 | 908 | ||
918 | for (phb = 0; phb < PHBS_PER_CALGARY; phb++) { | 909 | for (phb = 0; phb < PHBS_PER_CALGARY; phb++) { |
910 | offset = phb_debug_offsets[phb] | PHB_DEBUG_STUFF_OFFSET; | ||
911 | target = calgary_reg(bbar, offset); | ||
919 | 912 | ||
920 | target = calgary_reg(bbar, phb_debug_offsets[phb] | | ||
921 | PHB_DEBUG_STUFF_OFFSET); | ||
922 | val = be32_to_cpu(readl(target)); | 913 | val = be32_to_cpu(readl(target)); |
923 | start_bus = (u8)((val & 0x00FF0000) >> 16); | 914 | start_bus = (u8)((val & 0x00FF0000) >> 16); |
924 | end_bus = (u8)((val & 0x0000FF00) >> 8); | 915 | end_bus = (u8)((val & 0x0000FF00) >> 8); |
925 | for (bus = start_bus; bus <= end_bus; bus++) { | 916 | for (bus = start_bus; bus <= end_bus; bus++) { |
926 | bus_info[bus].bbar = bbar; | 917 | bus_info[bus].bbar = bbar; |
927 | bus_info[bus].phbid = phb; | 918 | bus_info[bus].phbid = phb; |
@@ -929,6 +920,25 @@ static int __init calgary_init(void) | |||
929 | } | 920 | } |
930 | } | 921 | } |
931 | 922 | ||
923 | return 0; | ||
924 | |||
925 | error: | ||
926 | /* scan bus_info and iounmap any bbars we previously ioremap'd */ | ||
927 | for (bus = 0; bus < ARRAY_SIZE(bus_info); bus++) | ||
928 | if (bus_info[bus].bbar) | ||
929 | iounmap(bus_info[bus].bbar); | ||
930 | |||
931 | return ret; | ||
932 | } | ||
933 | |||
934 | static int __init calgary_init(void) | ||
935 | { | ||
936 | int ret; | ||
937 | struct pci_dev *dev = NULL; | ||
938 | |||
939 | ret = calgary_locate_bbars(); | ||
940 | if (ret) | ||
941 | return ret; | ||
932 | 942 | ||
933 | do { | 943 | do { |
934 | dev = pci_get_device(PCI_VENDOR_ID_IBM, | 944 | dev = pci_get_device(PCI_VENDOR_ID_IBM, |
@@ -1000,18 +1010,13 @@ static int __init build_detail_arrays(void) | |||
1000 | 1010 | ||
1001 | if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){ | 1011 | if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){ |
1002 | printk(KERN_WARNING | 1012 | printk(KERN_WARNING |
1003 | "Calgary: MAX_NUMNODES too low! Defined as %d, " | 1013 | "Calgary: MAX_NUMNODES too low! Defined as %d, " |
1004 | "but system has %d nodes.\n", | 1014 | "but system has %d nodes.\n", |
1005 | MAX_NUMNODES, rio_table_hdr->num_scal_dev); | 1015 | MAX_NUMNODES, rio_table_hdr->num_scal_dev); |
1006 | return -ENODEV; | 1016 | return -ENODEV; |
1007 | } | 1017 | } |
1008 | 1018 | ||
1009 | switch (rio_table_hdr->version){ | 1019 | switch (rio_table_hdr->version){ |
1010 | default: | ||
1011 | printk(KERN_WARNING | ||
1012 | "Calgary: Invalid Rio Grande Table Version: %d\n", | ||
1013 | rio_table_hdr->version); | ||
1014 | return -ENODEV; | ||
1015 | case 2: | 1020 | case 2: |
1016 | scal_detail_size = 11; | 1021 | scal_detail_size = 11; |
1017 | rio_detail_size = 13; | 1022 | rio_detail_size = 13; |
@@ -1020,6 +1025,11 @@ static int __init build_detail_arrays(void) | |||
1020 | scal_detail_size = 12; | 1025 | scal_detail_size = 12; |
1021 | rio_detail_size = 15; | 1026 | rio_detail_size = 15; |
1022 | break; | 1027 | break; |
1028 | default: | ||
1029 | printk(KERN_WARNING | ||
1030 | "Calgary: Invalid Rio Grande Table Version: %d\n", | ||
1031 | rio_table_hdr->version); | ||
1032 | return -EPROTO; | ||
1023 | } | 1033 | } |
1024 | 1034 | ||
1025 | ptr = ((unsigned long)rio_table_hdr) + 3; | 1035 | ptr = ((unsigned long)rio_table_hdr) + 3; |
@@ -1042,6 +1052,7 @@ void __init detect_calgary(void) | |||
1042 | int calgary_found = 0; | 1052 | int calgary_found = 0; |
1043 | unsigned long ptr; | 1053 | unsigned long ptr; |
1044 | int offset; | 1054 | int offset; |
1055 | int ret; | ||
1045 | 1056 | ||
1046 | /* | 1057 | /* |
1047 | * if the user specified iommu=off or iommu=soft or we found | 1058 | * if the user specified iommu=off or iommu=soft or we found |
@@ -1061,27 +1072,29 @@ void __init detect_calgary(void) | |||
1061 | /* The block id is stored in the 2nd word */ | 1072 | /* The block id is stored in the 2nd word */ |
1062 | if (*((unsigned short *)(ptr + offset + 2)) == 0x4752){ | 1073 | if (*((unsigned short *)(ptr + offset + 2)) == 0x4752){ |
1063 | /* set the pointer past the offset & block id */ | 1074 | /* set the pointer past the offset & block id */ |
1064 | rio_table_hdr = (struct rio_table_hdr *)(ptr+offset+4); | 1075 | rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4); |
1065 | break; | 1076 | break; |
1066 | } | 1077 | } |
1067 | /* The next offset is stored in the 1st word. 0 means no more */ | 1078 | /* The next offset is stored in the 1st word. 0 means no more */ |
1068 | offset = *((unsigned short *)(ptr + offset)); | 1079 | offset = *((unsigned short *)(ptr + offset)); |
1069 | } | 1080 | } |
1070 | if (!rio_table_hdr){ | 1081 | if (!rio_table_hdr) { |
1071 | printk(KERN_ERR "Calgary: Unable to locate " | 1082 | printk(KERN_ERR "Calgary: Unable to locate " |
1072 | "Rio Grande Table in EBDA - bailing!\n"); | 1083 | "Rio Grande Table in EBDA - bailing!\n"); |
1073 | return; | 1084 | return; |
1074 | } | 1085 | } |
1075 | 1086 | ||
1076 | if (build_detail_arrays()) | 1087 | ret = build_detail_arrays(); |
1088 | if (ret) { | ||
1089 | printk(KERN_ERR "Calgary: build_detail_arrays ret %d\n", ret); | ||
1077 | return; | 1090 | return; |
1091 | } | ||
1078 | 1092 | ||
1079 | specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE); | 1093 | specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE); |
1080 | 1094 | ||
1081 | for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) { | 1095 | for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) { |
1082 | int dev; | 1096 | int dev; |
1083 | struct calgary_bus_info *info = &bus_info[bus]; | 1097 | struct calgary_bus_info *info = &bus_info[bus]; |
1084 | info->phbid = -1; | ||
1085 | 1098 | ||
1086 | if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY) | 1099 | if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY) |
1087 | continue; | 1100 | continue; |
diff --git a/include/asm-x86_64/rio.h b/include/asm-x86_64/rio.h index 1f315c39d76e..c7350f6d2015 100644 --- a/include/asm-x86_64/rio.h +++ b/include/asm-x86_64/rio.h | |||
@@ -3,7 +3,6 @@ | |||
3 | * and include/asm-i386/mach-default/bios_ebda.h | 3 | * and include/asm-i386/mach-default/bios_ebda.h |
4 | * | 4 | * |
5 | * Author: Laurent Vivier <Laurent.Vivier@bull.net> | 5 | * Author: Laurent Vivier <Laurent.Vivier@bull.net> |
6 | * | ||
7 | */ | 6 | */ |
8 | 7 | ||
9 | #ifndef __ASM_RIO_H | 8 | #ifndef __ASM_RIO_H |
@@ -19,7 +18,7 @@ struct rio_table_hdr { | |||
19 | 18 | ||
20 | struct scal_detail { | 19 | struct scal_detail { |
21 | u8 node_id; /* Scalability Node ID */ | 20 | u8 node_id; /* Scalability Node ID */ |
22 | u32 CBAR; /* Address of 1MB register space */ | 21 | u32 CBAR; /* Address of 1MB register space */ |
23 | u8 port0node; /* Node ID port connected to: 0xFF=None */ | 22 | u8 port0node; /* Node ID port connected to: 0xFF=None */ |
24 | u8 port0port; /* Port num port connected to: 0,1,2, or */ | 23 | u8 port0port; /* Port num port connected to: 0,1,2, or */ |
25 | /* 0xFF=None */ | 24 | /* 0xFF=None */ |
@@ -34,7 +33,7 @@ struct scal_detail { | |||
34 | 33 | ||
35 | struct rio_detail { | 34 | struct rio_detail { |
36 | u8 node_id; /* RIO Node ID */ | 35 | u8 node_id; /* RIO Node ID */ |
37 | u32 BBAR; /* Address of 1MB register space */ | 36 | u32 BBAR; /* Address of 1MB register space */ |
38 | u8 type; /* Type of device */ | 37 | u8 type; /* Type of device */ |
39 | u8 owner_id; /* Node ID of Hurricane that owns this */ | 38 | u8 owner_id; /* Node ID of Hurricane that owns this */ |
40 | /* node */ | 39 | /* node */ |
@@ -65,10 +64,9 @@ enum { | |||
65 | * there is a real-mode segmented pointer pointing to the | 64 | * there is a real-mode segmented pointer pointing to the |
66 | * 4K EBDA area at 0x40E. | 65 | * 4K EBDA area at 0x40E. |
67 | */ | 66 | */ |
68 | |||
69 | static inline unsigned long get_bios_ebda(void) | 67 | static inline unsigned long get_bios_ebda(void) |
70 | { | 68 | { |
71 | unsigned long address= *(unsigned short *)phys_to_virt(0x40Eul); | 69 | unsigned long address = *(unsigned short *)phys_to_virt(0x40EUL); |
72 | address <<= 4; | 70 | address <<= 4; |
73 | return address; | 71 | return address; |
74 | } | 72 | } |