diff options
Diffstat (limited to 'drivers/pci/hotplug/cpqphp_ctrl.c')
-rw-r--r-- | drivers/pci/hotplug/cpqphp_ctrl.c | 371 |
1 files changed, 191 insertions, 180 deletions
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index cc227a8c4b11..2fa47af992a8 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c | |||
@@ -81,14 +81,15 @@ static u8 handle_switch_change(u8 change, struct controller * ctrl) | |||
81 | 81 | ||
82 | for (hp_slot = 0; hp_slot < 6; hp_slot++) { | 82 | for (hp_slot = 0; hp_slot < 6; hp_slot++) { |
83 | if (change & (0x1L << hp_slot)) { | 83 | if (change & (0x1L << hp_slot)) { |
84 | /********************************** | 84 | /* |
85 | * this one changed. | 85 | * this one changed. |
86 | **********************************/ | 86 | */ |
87 | func = cpqhp_slot_find(ctrl->bus, | 87 | func = cpqhp_slot_find(ctrl->bus, |
88 | (hp_slot + ctrl->slot_device_offset), 0); | 88 | (hp_slot + ctrl->slot_device_offset), 0); |
89 | 89 | ||
90 | /* this is the structure that tells the worker thread | 90 | /* this is the structure that tells the worker thread |
91 | *what to do */ | 91 | * what to do |
92 | */ | ||
92 | taskInfo = &(ctrl->event_queue[ctrl->next_event]); | 93 | taskInfo = &(ctrl->event_queue[ctrl->next_event]); |
93 | ctrl->next_event = (ctrl->next_event + 1) % 10; | 94 | ctrl->next_event = (ctrl->next_event + 1) % 10; |
94 | taskInfo->hp_slot = hp_slot; | 95 | taskInfo->hp_slot = hp_slot; |
@@ -100,17 +101,17 @@ static u8 handle_switch_change(u8 change, struct controller * ctrl) | |||
100 | func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02; | 101 | func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02; |
101 | 102 | ||
102 | if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) { | 103 | if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) { |
103 | /********************************** | 104 | /* |
104 | * Switch opened | 105 | * Switch opened |
105 | **********************************/ | 106 | */ |
106 | 107 | ||
107 | func->switch_save = 0; | 108 | func->switch_save = 0; |
108 | 109 | ||
109 | taskInfo->event_type = INT_SWITCH_OPEN; | 110 | taskInfo->event_type = INT_SWITCH_OPEN; |
110 | } else { | 111 | } else { |
111 | /********************************** | 112 | /* |
112 | * Switch closed | 113 | * Switch closed |
113 | **********************************/ | 114 | */ |
114 | 115 | ||
115 | func->switch_save = 0x10; | 116 | func->switch_save = 0x10; |
116 | 117 | ||
@@ -131,9 +132,8 @@ static struct slot *cpqhp_find_slot(struct controller *ctrl, u8 device) | |||
131 | { | 132 | { |
132 | struct slot *slot = ctrl->slot; | 133 | struct slot *slot = ctrl->slot; |
133 | 134 | ||
134 | while (slot && (slot->device != device)) { | 135 | while (slot && (slot->device != device)) |
135 | slot = slot->next; | 136 | slot = slot->next; |
136 | } | ||
137 | 137 | ||
138 | return slot; | 138 | return slot; |
139 | } | 139 | } |
@@ -152,17 +152,17 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl) | |||
152 | if (!change) | 152 | if (!change) |
153 | return 0; | 153 | return 0; |
154 | 154 | ||
155 | /********************************** | 155 | /* |
156 | * Presence Change | 156 | * Presence Change |
157 | **********************************/ | 157 | */ |
158 | dbg("cpqsbd: Presence/Notify input change.\n"); | 158 | dbg("cpqsbd: Presence/Notify input change.\n"); |
159 | dbg(" Changed bits are 0x%4.4x\n", change ); | 159 | dbg(" Changed bits are 0x%4.4x\n", change ); |
160 | 160 | ||
161 | for (hp_slot = 0; hp_slot < 6; hp_slot++) { | 161 | for (hp_slot = 0; hp_slot < 6; hp_slot++) { |
162 | if (change & (0x0101 << hp_slot)) { | 162 | if (change & (0x0101 << hp_slot)) { |
163 | /********************************** | 163 | /* |
164 | * this one changed. | 164 | * this one changed. |
165 | **********************************/ | 165 | */ |
166 | func = cpqhp_slot_find(ctrl->bus, | 166 | func = cpqhp_slot_find(ctrl->bus, |
167 | (hp_slot + ctrl->slot_device_offset), 0); | 167 | (hp_slot + ctrl->slot_device_offset), 0); |
168 | 168 | ||
@@ -177,22 +177,23 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl) | |||
177 | return 0; | 177 | return 0; |
178 | 178 | ||
179 | /* If the switch closed, must be a button | 179 | /* If the switch closed, must be a button |
180 | * If not in button mode, nevermind */ | 180 | * If not in button mode, nevermind |
181 | */ | ||
181 | if (func->switch_save && (ctrl->push_button == 1)) { | 182 | if (func->switch_save && (ctrl->push_button == 1)) { |
182 | temp_word = ctrl->ctrl_int_comp >> 16; | 183 | temp_word = ctrl->ctrl_int_comp >> 16; |
183 | temp_byte = (temp_word >> hp_slot) & 0x01; | 184 | temp_byte = (temp_word >> hp_slot) & 0x01; |
184 | temp_byte |= (temp_word >> (hp_slot + 7)) & 0x02; | 185 | temp_byte |= (temp_word >> (hp_slot + 7)) & 0x02; |
185 | 186 | ||
186 | if (temp_byte != func->presence_save) { | 187 | if (temp_byte != func->presence_save) { |
187 | /************************************** | 188 | /* |
188 | * button Pressed (doesn't do anything) | 189 | * button Pressed (doesn't do anything) |
189 | **************************************/ | 190 | */ |
190 | dbg("hp_slot %d button pressed\n", hp_slot); | 191 | dbg("hp_slot %d button pressed\n", hp_slot); |
191 | taskInfo->event_type = INT_BUTTON_PRESS; | 192 | taskInfo->event_type = INT_BUTTON_PRESS; |
192 | } else { | 193 | } else { |
193 | /********************************** | 194 | /* |
194 | * button Released - TAKE ACTION!!!! | 195 | * button Released - TAKE ACTION!!!! |
195 | **********************************/ | 196 | */ |
196 | dbg("hp_slot %d button released\n", hp_slot); | 197 | dbg("hp_slot %d button released\n", hp_slot); |
197 | taskInfo->event_type = INT_BUTTON_RELEASE; | 198 | taskInfo->event_type = INT_BUTTON_RELEASE; |
198 | 199 | ||
@@ -210,7 +211,8 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl) | |||
210 | } | 211 | } |
211 | } else { | 212 | } else { |
212 | /* Switch is open, assume a presence change | 213 | /* Switch is open, assume a presence change |
213 | * Save the presence state */ | 214 | * Save the presence state |
215 | */ | ||
214 | temp_word = ctrl->ctrl_int_comp >> 16; | 216 | temp_word = ctrl->ctrl_int_comp >> 16; |
215 | func->presence_save = (temp_word >> hp_slot) & 0x01; | 217 | func->presence_save = (temp_word >> hp_slot) & 0x01; |
216 | func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02; | 218 | func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02; |
@@ -241,17 +243,17 @@ static u8 handle_power_fault(u8 change, struct controller * ctrl) | |||
241 | if (!change) | 243 | if (!change) |
242 | return 0; | 244 | return 0; |
243 | 245 | ||
244 | /********************************** | 246 | /* |
245 | * power fault | 247 | * power fault |
246 | **********************************/ | 248 | */ |
247 | 249 | ||
248 | info("power fault interrupt\n"); | 250 | info("power fault interrupt\n"); |
249 | 251 | ||
250 | for (hp_slot = 0; hp_slot < 6; hp_slot++) { | 252 | for (hp_slot = 0; hp_slot < 6; hp_slot++) { |
251 | if (change & (0x01 << hp_slot)) { | 253 | if (change & (0x01 << hp_slot)) { |
252 | /********************************** | 254 | /* |
253 | * this one changed. | 255 | * this one changed. |
254 | **********************************/ | 256 | */ |
255 | func = cpqhp_slot_find(ctrl->bus, | 257 | func = cpqhp_slot_find(ctrl->bus, |
256 | (hp_slot + ctrl->slot_device_offset), 0); | 258 | (hp_slot + ctrl->slot_device_offset), 0); |
257 | 259 | ||
@@ -262,16 +264,16 @@ static u8 handle_power_fault(u8 change, struct controller * ctrl) | |||
262 | rc++; | 264 | rc++; |
263 | 265 | ||
264 | if (ctrl->ctrl_int_comp & (0x00000100 << hp_slot)) { | 266 | if (ctrl->ctrl_int_comp & (0x00000100 << hp_slot)) { |
265 | /********************************** | 267 | /* |
266 | * power fault Cleared | 268 | * power fault Cleared |
267 | **********************************/ | 269 | */ |
268 | func->status = 0x00; | 270 | func->status = 0x00; |
269 | 271 | ||
270 | taskInfo->event_type = INT_POWER_FAULT_CLEAR; | 272 | taskInfo->event_type = INT_POWER_FAULT_CLEAR; |
271 | } else { | 273 | } else { |
272 | /********************************** | 274 | /* |
273 | * power fault | 275 | * power fault |
274 | **********************************/ | 276 | */ |
275 | taskInfo->event_type = INT_POWER_FAULT; | 277 | taskInfo->event_type = INT_POWER_FAULT; |
276 | 278 | ||
277 | if (ctrl->rev < 4) { | 279 | if (ctrl->rev < 4) { |
@@ -432,13 +434,15 @@ static struct pci_resource *do_pre_bridge_resource_split(struct pci_resource **h | |||
432 | 434 | ||
433 | 435 | ||
434 | /* If we got here, there the bridge requires some of the resource, but | 436 | /* If we got here, there the bridge requires some of the resource, but |
435 | * we may be able to split some off of the front */ | 437 | * we may be able to split some off of the front |
438 | */ | ||
436 | 439 | ||
437 | node = *head; | 440 | node = *head; |
438 | 441 | ||
439 | if (node->length & (alignment -1)) { | 442 | if (node->length & (alignment -1)) { |
440 | /* this one isn't an aligned length, so we'll make a new entry | 443 | /* this one isn't an aligned length, so we'll make a new entry |
441 | * and split it up. */ | 444 | * and split it up. |
445 | */ | ||
442 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); | 446 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); |
443 | 447 | ||
444 | if (!split_node) | 448 | if (!split_node) |
@@ -544,10 +548,10 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size | |||
544 | if (!(*head)) | 548 | if (!(*head)) |
545 | return NULL; | 549 | return NULL; |
546 | 550 | ||
547 | if ( cpqhp_resource_sort_and_combine(head) ) | 551 | if (cpqhp_resource_sort_and_combine(head)) |
548 | return NULL; | 552 | return NULL; |
549 | 553 | ||
550 | if ( sort_by_size(head) ) | 554 | if (sort_by_size(head)) |
551 | return NULL; | 555 | return NULL; |
552 | 556 | ||
553 | for (node = *head; node; node = node->next) { | 557 | for (node = *head; node; node = node->next) { |
@@ -556,7 +560,8 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size | |||
556 | 560 | ||
557 | if (node->base & (size - 1)) { | 561 | if (node->base & (size - 1)) { |
558 | /* this one isn't base aligned properly | 562 | /* this one isn't base aligned properly |
559 | * so we'll make a new entry and split it up */ | 563 | * so we'll make a new entry and split it up |
564 | */ | ||
560 | temp_dword = (node->base | (size-1)) + 1; | 565 | temp_dword = (node->base | (size-1)) + 1; |
561 | 566 | ||
562 | /* Short circuit if adjusted size is too small */ | 567 | /* Short circuit if adjusted size is too small */ |
@@ -581,7 +586,8 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size | |||
581 | /* Don't need to check if too small since we already did */ | 586 | /* Don't need to check if too small since we already did */ |
582 | if (node->length > size) { | 587 | if (node->length > size) { |
583 | /* this one is longer than we need | 588 | /* this one is longer than we need |
584 | * so we'll make a new entry and split it up */ | 589 | * so we'll make a new entry and split it up |
590 | */ | ||
585 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); | 591 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); |
586 | 592 | ||
587 | if (!split_node) | 593 | if (!split_node) |
@@ -601,7 +607,8 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size | |||
601 | continue; | 607 | continue; |
602 | 608 | ||
603 | /* If we got here, then it is the right size | 609 | /* If we got here, then it is the right size |
604 | * Now take it out of the list and break */ | 610 | * Now take it out of the list and break |
611 | */ | ||
605 | if (*head == node) { | 612 | if (*head == node) { |
606 | *head = node->next; | 613 | *head = node->next; |
607 | } else { | 614 | } else { |
@@ -642,14 +649,16 @@ static struct pci_resource *get_max_resource(struct pci_resource **head, u32 siz | |||
642 | return NULL; | 649 | return NULL; |
643 | 650 | ||
644 | for (max = *head; max; max = max->next) { | 651 | for (max = *head; max; max = max->next) { |
645 | /* If not big enough we could probably just bail, | 652 | /* If not big enough we could probably just bail, |
646 | * instead we'll continue to the next. */ | 653 | * instead we'll continue to the next. |
654 | */ | ||
647 | if (max->length < size) | 655 | if (max->length < size) |
648 | continue; | 656 | continue; |
649 | 657 | ||
650 | if (max->base & (size - 1)) { | 658 | if (max->base & (size - 1)) { |
651 | /* this one isn't base aligned properly | 659 | /* this one isn't base aligned properly |
652 | * so we'll make a new entry and split it up */ | 660 | * so we'll make a new entry and split it up |
661 | */ | ||
653 | temp_dword = (max->base | (size-1)) + 1; | 662 | temp_dword = (max->base | (size-1)) + 1; |
654 | 663 | ||
655 | /* Short circuit if adjusted size is too small */ | 664 | /* Short circuit if adjusted size is too small */ |
@@ -672,7 +681,8 @@ static struct pci_resource *get_max_resource(struct pci_resource **head, u32 siz | |||
672 | 681 | ||
673 | if ((max->base + max->length) & (size - 1)) { | 682 | if ((max->base + max->length) & (size - 1)) { |
674 | /* this one isn't end aligned properly at the top | 683 | /* this one isn't end aligned properly at the top |
675 | * so we'll make a new entry and split it up */ | 684 | * so we'll make a new entry and split it up |
685 | */ | ||
676 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); | 686 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); |
677 | 687 | ||
678 | if (!split_node) | 688 | if (!split_node) |
@@ -744,7 +754,8 @@ static struct pci_resource *get_resource(struct pci_resource **head, u32 size) | |||
744 | if (node->base & (size - 1)) { | 754 | if (node->base & (size - 1)) { |
745 | dbg("%s: not aligned\n", __func__); | 755 | dbg("%s: not aligned\n", __func__); |
746 | /* this one isn't base aligned properly | 756 | /* this one isn't base aligned properly |
747 | * so we'll make a new entry and split it up */ | 757 | * so we'll make a new entry and split it up |
758 | */ | ||
748 | temp_dword = (node->base | (size-1)) + 1; | 759 | temp_dword = (node->base | (size-1)) + 1; |
749 | 760 | ||
750 | /* Short circuit if adjusted size is too small */ | 761 | /* Short circuit if adjusted size is too small */ |
@@ -769,7 +780,8 @@ static struct pci_resource *get_resource(struct pci_resource **head, u32 size) | |||
769 | if (node->length > size) { | 780 | if (node->length > size) { |
770 | dbg("%s: too big\n", __func__); | 781 | dbg("%s: too big\n", __func__); |
771 | /* this one is longer than we need | 782 | /* this one is longer than we need |
772 | * so we'll make a new entry and split it up */ | 783 | * so we'll make a new entry and split it up |
784 | */ | ||
773 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); | 785 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); |
774 | 786 | ||
775 | if (!split_node) | 787 | if (!split_node) |
@@ -886,19 +898,19 @@ irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data) | |||
886 | u32 Diff; | 898 | u32 Diff; |
887 | u32 temp_dword; | 899 | u32 temp_dword; |
888 | 900 | ||
889 | 901 | ||
890 | misc = readw(ctrl->hpc_reg + MISC); | 902 | misc = readw(ctrl->hpc_reg + MISC); |
891 | /*************************************** | 903 | /* |
892 | * Check to see if it was our interrupt | 904 | * Check to see if it was our interrupt |
893 | ***************************************/ | 905 | */ |
894 | if (!(misc & 0x000C)) { | 906 | if (!(misc & 0x000C)) { |
895 | return IRQ_NONE; | 907 | return IRQ_NONE; |
896 | } | 908 | } |
897 | 909 | ||
898 | if (misc & 0x0004) { | 910 | if (misc & 0x0004) { |
899 | /********************************** | 911 | /* |
900 | * Serial Output interrupt Pending | 912 | * Serial Output interrupt Pending |
901 | **********************************/ | 913 | */ |
902 | 914 | ||
903 | /* Clear the interrupt */ | 915 | /* Clear the interrupt */ |
904 | misc |= 0x0004; | 916 | misc |= 0x0004; |
@@ -961,11 +973,8 @@ struct pci_func *cpqhp_slot_create(u8 busnumber) | |||
961 | struct pci_func *next; | 973 | struct pci_func *next; |
962 | 974 | ||
963 | new_slot = kzalloc(sizeof(*new_slot), GFP_KERNEL); | 975 | new_slot = kzalloc(sizeof(*new_slot), GFP_KERNEL); |
964 | if (new_slot == NULL) { | 976 | if (new_slot == NULL) |
965 | /* I'm not dead yet! | ||
966 | * You will be. */ | ||
967 | return new_slot; | 977 | return new_slot; |
968 | } | ||
969 | 978 | ||
970 | new_slot->next = NULL; | 979 | new_slot->next = NULL; |
971 | new_slot->configured = 1; | 980 | new_slot->configured = 1; |
@@ -996,10 +1005,8 @@ static int slot_remove(struct pci_func * old_slot) | |||
996 | return 1; | 1005 | return 1; |
997 | 1006 | ||
998 | next = cpqhp_slot_list[old_slot->bus]; | 1007 | next = cpqhp_slot_list[old_slot->bus]; |
999 | 1008 | if (next == NULL) | |
1000 | if (next == NULL) { | ||
1001 | return 1; | 1009 | return 1; |
1002 | } | ||
1003 | 1010 | ||
1004 | if (next == old_slot) { | 1011 | if (next == old_slot) { |
1005 | cpqhp_slot_list[old_slot->bus] = old_slot->next; | 1012 | cpqhp_slot_list[old_slot->bus] = old_slot->next; |
@@ -1008,9 +1015,8 @@ static int slot_remove(struct pci_func * old_slot) | |||
1008 | return 0; | 1015 | return 0; |
1009 | } | 1016 | } |
1010 | 1017 | ||
1011 | while ((next->next != old_slot) && (next->next != NULL)) { | 1018 | while ((next->next != old_slot) && (next->next != NULL)) |
1012 | next = next->next; | 1019 | next = next->next; |
1013 | } | ||
1014 | 1020 | ||
1015 | if (next->next == old_slot) { | 1021 | if (next->next == old_slot) { |
1016 | next->next = old_slot->next; | 1022 | next->next = old_slot->next; |
@@ -1040,9 +1046,8 @@ static int bridge_slot_remove(struct pci_func *bridge) | |||
1040 | for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) { | 1046 | for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) { |
1041 | next = cpqhp_slot_list[tempBus]; | 1047 | next = cpqhp_slot_list[tempBus]; |
1042 | 1048 | ||
1043 | while (!slot_remove(next)) { | 1049 | while (!slot_remove(next)) |
1044 | next = cpqhp_slot_list[tempBus]; | 1050 | next = cpqhp_slot_list[tempBus]; |
1045 | } | ||
1046 | } | 1051 | } |
1047 | 1052 | ||
1048 | next = cpqhp_slot_list[bridge->bus]; | 1053 | next = cpqhp_slot_list[bridge->bus]; |
@@ -1130,39 +1135,43 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1130 | u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER); | 1135 | u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER); |
1131 | u16 reg16; | 1136 | u16 reg16; |
1132 | u32 leds = readl(ctrl->hpc_reg + LED_CONTROL); | 1137 | u32 leds = readl(ctrl->hpc_reg + LED_CONTROL); |
1133 | 1138 | ||
1134 | if (ctrl->speed == adapter_speed) | 1139 | if (ctrl->speed == adapter_speed) |
1135 | return 0; | 1140 | return 0; |
1136 | 1141 | ||
1137 | /* We don't allow freq/mode changes if we find another adapter running | 1142 | /* We don't allow freq/mode changes if we find another adapter running |
1138 | * in another slot on this controller */ | 1143 | * in another slot on this controller |
1144 | */ | ||
1139 | for(slot = ctrl->slot; slot; slot = slot->next) { | 1145 | for(slot = ctrl->slot; slot; slot = slot->next) { |
1140 | if (slot->device == (hp_slot + ctrl->slot_device_offset)) | 1146 | if (slot->device == (hp_slot + ctrl->slot_device_offset)) |
1141 | continue; | 1147 | continue; |
1142 | if (!slot->hotplug_slot || !slot->hotplug_slot->info) | 1148 | if (!slot->hotplug_slot || !slot->hotplug_slot->info) |
1143 | continue; | 1149 | continue; |
1144 | if (slot->hotplug_slot->info->adapter_status == 0) | 1150 | if (slot->hotplug_slot->info->adapter_status == 0) |
1145 | continue; | 1151 | continue; |
1146 | /* If another adapter is running on the same segment but at a | 1152 | /* If another adapter is running on the same segment but at a |
1147 | * lower speed/mode, we allow the new adapter to function at | 1153 | * lower speed/mode, we allow the new adapter to function at |
1148 | * this rate if supported */ | 1154 | * this rate if supported |
1149 | if (ctrl->speed < adapter_speed) | 1155 | */ |
1156 | if (ctrl->speed < adapter_speed) | ||
1150 | return 0; | 1157 | return 0; |
1151 | 1158 | ||
1152 | return 1; | 1159 | return 1; |
1153 | } | 1160 | } |
1154 | 1161 | ||
1155 | /* If the controller doesn't support freq/mode changes and the | 1162 | /* If the controller doesn't support freq/mode changes and the |
1156 | * controller is running at a higher mode, we bail */ | 1163 | * controller is running at a higher mode, we bail |
1164 | */ | ||
1157 | if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability)) | 1165 | if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability)) |
1158 | return 1; | 1166 | return 1; |
1159 | 1167 | ||
1160 | /* But we allow the adapter to run at a lower rate if possible */ | 1168 | /* But we allow the adapter to run at a lower rate if possible */ |
1161 | if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability)) | 1169 | if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability)) |
1162 | return 0; | 1170 | return 0; |
1163 | 1171 | ||
1164 | /* We try to set the max speed supported by both the adapter and | 1172 | /* We try to set the max speed supported by both the adapter and |
1165 | * controller */ | 1173 | * controller |
1174 | */ | ||
1166 | if (ctrl->speed_capability < adapter_speed) { | 1175 | if (ctrl->speed_capability < adapter_speed) { |
1167 | if (ctrl->speed == ctrl->speed_capability) | 1176 | if (ctrl->speed == ctrl->speed_capability) |
1168 | return 0; | 1177 | return 0; |
@@ -1171,22 +1180,22 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1171 | 1180 | ||
1172 | writel(0x0L, ctrl->hpc_reg + LED_CONTROL); | 1181 | writel(0x0L, ctrl->hpc_reg + LED_CONTROL); |
1173 | writeb(0x00, ctrl->hpc_reg + SLOT_ENABLE); | 1182 | writeb(0x00, ctrl->hpc_reg + SLOT_ENABLE); |
1174 | 1183 | ||
1175 | set_SOGO(ctrl); | 1184 | set_SOGO(ctrl); |
1176 | wait_for_ctrl_irq(ctrl); | 1185 | wait_for_ctrl_irq(ctrl); |
1177 | 1186 | ||
1178 | if (adapter_speed != PCI_SPEED_133MHz_PCIX) | 1187 | if (adapter_speed != PCI_SPEED_133MHz_PCIX) |
1179 | reg = 0xF5; | 1188 | reg = 0xF5; |
1180 | else | 1189 | else |
1181 | reg = 0xF4; | 1190 | reg = 0xF4; |
1182 | pci_write_config_byte(ctrl->pci_dev, 0x41, reg); | 1191 | pci_write_config_byte(ctrl->pci_dev, 0x41, reg); |
1183 | 1192 | ||
1184 | reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ); | 1193 | reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ); |
1185 | reg16 &= ~0x000F; | 1194 | reg16 &= ~0x000F; |
1186 | switch(adapter_speed) { | 1195 | switch(adapter_speed) { |
1187 | case(PCI_SPEED_133MHz_PCIX): | 1196 | case(PCI_SPEED_133MHz_PCIX): |
1188 | reg = 0x75; | 1197 | reg = 0x75; |
1189 | reg16 |= 0xB; | 1198 | reg16 |= 0xB; |
1190 | break; | 1199 | break; |
1191 | case(PCI_SPEED_100MHz_PCIX): | 1200 | case(PCI_SPEED_100MHz_PCIX): |
1192 | reg = 0x74; | 1201 | reg = 0x74; |
@@ -1203,48 +1212,48 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1203 | default: /* 33MHz PCI 2.2 */ | 1212 | default: /* 33MHz PCI 2.2 */ |
1204 | reg = 0x71; | 1213 | reg = 0x71; |
1205 | break; | 1214 | break; |
1206 | 1215 | ||
1207 | } | 1216 | } |
1208 | reg16 |= 0xB << 12; | 1217 | reg16 |= 0xB << 12; |
1209 | writew(reg16, ctrl->hpc_reg + NEXT_CURR_FREQ); | 1218 | writew(reg16, ctrl->hpc_reg + NEXT_CURR_FREQ); |
1210 | 1219 | ||
1211 | mdelay(5); | 1220 | mdelay(5); |
1212 | 1221 | ||
1213 | /* Reenable interrupts */ | 1222 | /* Reenable interrupts */ |
1214 | writel(0, ctrl->hpc_reg + INT_MASK); | 1223 | writel(0, ctrl->hpc_reg + INT_MASK); |
1215 | 1224 | ||
1216 | pci_write_config_byte(ctrl->pci_dev, 0x41, reg); | 1225 | pci_write_config_byte(ctrl->pci_dev, 0x41, reg); |
1217 | 1226 | ||
1218 | /* Restart state machine */ | 1227 | /* Restart state machine */ |
1219 | reg = ~0xF; | 1228 | reg = ~0xF; |
1220 | pci_read_config_byte(ctrl->pci_dev, 0x43, ®); | 1229 | pci_read_config_byte(ctrl->pci_dev, 0x43, ®); |
1221 | pci_write_config_byte(ctrl->pci_dev, 0x43, reg); | 1230 | pci_write_config_byte(ctrl->pci_dev, 0x43, reg); |
1222 | 1231 | ||
1223 | /* Only if mode change...*/ | 1232 | /* Only if mode change...*/ |
1224 | if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || | 1233 | if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || |
1225 | ((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) | 1234 | ((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) |
1226 | set_SOGO(ctrl); | 1235 | set_SOGO(ctrl); |
1227 | 1236 | ||
1228 | wait_for_ctrl_irq(ctrl); | 1237 | wait_for_ctrl_irq(ctrl); |
1229 | mdelay(1100); | 1238 | mdelay(1100); |
1230 | 1239 | ||
1231 | /* Restore LED/Slot state */ | 1240 | /* Restore LED/Slot state */ |
1232 | writel(leds, ctrl->hpc_reg + LED_CONTROL); | 1241 | writel(leds, ctrl->hpc_reg + LED_CONTROL); |
1233 | writeb(slot_power, ctrl->hpc_reg + SLOT_ENABLE); | 1242 | writeb(slot_power, ctrl->hpc_reg + SLOT_ENABLE); |
1234 | 1243 | ||
1235 | set_SOGO(ctrl); | 1244 | set_SOGO(ctrl); |
1236 | wait_for_ctrl_irq(ctrl); | 1245 | wait_for_ctrl_irq(ctrl); |
1237 | 1246 | ||
1238 | ctrl->speed = adapter_speed; | 1247 | ctrl->speed = adapter_speed; |
1239 | slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | 1248 | slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); |
1240 | 1249 | ||
1241 | info("Successfully changed frequency/mode for adapter in slot %d\n", | 1250 | info("Successfully changed frequency/mode for adapter in slot %d\n", |
1242 | slot->number); | 1251 | slot->number); |
1243 | return 0; | 1252 | return 0; |
1244 | } | 1253 | } |
1245 | 1254 | ||
1246 | /* the following routines constitute the bulk of the | 1255 | /* the following routines constitute the bulk of the |
1247 | hotplug controller logic | 1256 | * hotplug controller logic |
1248 | */ | 1257 | */ |
1249 | 1258 | ||
1250 | 1259 | ||
@@ -1268,17 +1277,17 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) | |||
1268 | 1277 | ||
1269 | hp_slot = func->device - ctrl->slot_device_offset; | 1278 | hp_slot = func->device - ctrl->slot_device_offset; |
1270 | 1279 | ||
1271 | if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)) { | 1280 | /* |
1272 | /********************************** | 1281 | * The switch is open. |
1273 | * The switch is open. | 1282 | */ |
1274 | **********************************/ | 1283 | if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)) |
1275 | rc = INTERLOCK_OPEN; | 1284 | rc = INTERLOCK_OPEN; |
1276 | } else if (is_slot_enabled (ctrl, hp_slot)) { | 1285 | /* |
1277 | /********************************** | 1286 | * The board is already on |
1278 | * The board is already on | 1287 | */ |
1279 | **********************************/ | 1288 | else if (is_slot_enabled (ctrl, hp_slot)) |
1280 | rc = CARD_FUNCTIONING; | 1289 | rc = CARD_FUNCTIONING; |
1281 | } else { | 1290 | else { |
1282 | mutex_lock(&ctrl->crit_sect); | 1291 | mutex_lock(&ctrl->crit_sect); |
1283 | 1292 | ||
1284 | /* turn on board without attaching to the bus */ | 1293 | /* turn on board without attaching to the bus */ |
@@ -1299,7 +1308,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) | |||
1299 | 1308 | ||
1300 | /* Wait for SOBS to be unset */ | 1309 | /* Wait for SOBS to be unset */ |
1301 | wait_for_ctrl_irq (ctrl); | 1310 | wait_for_ctrl_irq (ctrl); |
1302 | 1311 | ||
1303 | adapter_speed = get_adapter_speed(ctrl, hp_slot); | 1312 | adapter_speed = get_adapter_speed(ctrl, hp_slot); |
1304 | if (ctrl->speed != adapter_speed) | 1313 | if (ctrl->speed != adapter_speed) |
1305 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) | 1314 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) |
@@ -1352,7 +1361,8 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) | |||
1352 | * Get slot won't work for devices behind | 1361 | * Get slot won't work for devices behind |
1353 | * bridges, but in this case it will always be | 1362 | * bridges, but in this case it will always be |
1354 | * called for the "base" bus/dev/func of an | 1363 | * called for the "base" bus/dev/func of an |
1355 | * adapter. */ | 1364 | * adapter. |
1365 | */ | ||
1356 | 1366 | ||
1357 | mutex_lock(&ctrl->crit_sect); | 1367 | mutex_lock(&ctrl->crit_sect); |
1358 | 1368 | ||
@@ -1377,7 +1387,8 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) | |||
1377 | 1387 | ||
1378 | * Get slot won't work for devices behind bridges, but | 1388 | * Get slot won't work for devices behind bridges, but |
1379 | * in this case it will always be called for the "base" | 1389 | * in this case it will always be called for the "base" |
1380 | * bus/dev/func of an adapter. */ | 1390 | * bus/dev/func of an adapter. |
1391 | */ | ||
1381 | 1392 | ||
1382 | mutex_lock(&ctrl->crit_sect); | 1393 | mutex_lock(&ctrl->crit_sect); |
1383 | 1394 | ||
@@ -1434,7 +1445,8 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) | |||
1434 | wait_for_ctrl_irq (ctrl); | 1445 | wait_for_ctrl_irq (ctrl); |
1435 | 1446 | ||
1436 | /* Change bits in slot power register to force another shift out | 1447 | /* Change bits in slot power register to force another shift out |
1437 | * NOTE: this is to work around the timer bug */ | 1448 | * NOTE: this is to work around the timer bug |
1449 | */ | ||
1438 | temp_byte = readb(ctrl->hpc_reg + SLOT_POWER); | 1450 | temp_byte = readb(ctrl->hpc_reg + SLOT_POWER); |
1439 | writeb(0x00, ctrl->hpc_reg + SLOT_POWER); | 1451 | writeb(0x00, ctrl->hpc_reg + SLOT_POWER); |
1440 | writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER); | 1452 | writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER); |
@@ -1443,12 +1455,12 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) | |||
1443 | 1455 | ||
1444 | /* Wait for SOBS to be unset */ | 1456 | /* Wait for SOBS to be unset */ |
1445 | wait_for_ctrl_irq (ctrl); | 1457 | wait_for_ctrl_irq (ctrl); |
1446 | 1458 | ||
1447 | adapter_speed = get_adapter_speed(ctrl, hp_slot); | 1459 | adapter_speed = get_adapter_speed(ctrl, hp_slot); |
1448 | if (ctrl->speed != adapter_speed) | 1460 | if (ctrl->speed != adapter_speed) |
1449 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) | 1461 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) |
1450 | rc = WRONG_BUS_FREQUENCY; | 1462 | rc = WRONG_BUS_FREQUENCY; |
1451 | 1463 | ||
1452 | /* turn off board without attaching to the bus */ | 1464 | /* turn off board without attaching to the bus */ |
1453 | disable_slot_power (ctrl, hp_slot); | 1465 | disable_slot_power (ctrl, hp_slot); |
1454 | 1466 | ||
@@ -1461,7 +1473,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) | |||
1461 | 1473 | ||
1462 | if (rc) | 1474 | if (rc) |
1463 | return rc; | 1475 | return rc; |
1464 | 1476 | ||
1465 | p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | 1477 | p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); |
1466 | 1478 | ||
1467 | /* turn on board and blink green LED */ | 1479 | /* turn on board and blink green LED */ |
@@ -1521,7 +1533,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) | |||
1521 | } | 1533 | } |
1522 | 1534 | ||
1523 | /* All F's is an empty slot or an invalid board */ | 1535 | /* All F's is an empty slot or an invalid board */ |
1524 | if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */ | 1536 | if (temp_register != 0xFFFFFFFF) { |
1525 | res_lists.io_head = ctrl->io_head; | 1537 | res_lists.io_head = ctrl->io_head; |
1526 | res_lists.mem_head = ctrl->mem_head; | 1538 | res_lists.mem_head = ctrl->mem_head; |
1527 | res_lists.p_mem_head = ctrl->p_mem_head; | 1539 | res_lists.p_mem_head = ctrl->p_mem_head; |
@@ -1570,9 +1582,8 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) | |||
1570 | index = 0; | 1582 | index = 0; |
1571 | do { | 1583 | do { |
1572 | new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++); | 1584 | new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++); |
1573 | if (new_slot && !new_slot->pci_dev) { | 1585 | if (new_slot && !new_slot->pci_dev) |
1574 | cpqhp_configure_device(ctrl, new_slot); | 1586 | cpqhp_configure_device(ctrl, new_slot); |
1575 | } | ||
1576 | } while (new_slot); | 1587 | } while (new_slot); |
1577 | 1588 | ||
1578 | mutex_lock(&ctrl->crit_sect); | 1589 | mutex_lock(&ctrl->crit_sect); |
@@ -1859,12 +1870,12 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
1859 | info(msg_button_on, p_slot->number); | 1870 | info(msg_button_on, p_slot->number); |
1860 | } | 1871 | } |
1861 | mutex_lock(&ctrl->crit_sect); | 1872 | mutex_lock(&ctrl->crit_sect); |
1862 | 1873 | ||
1863 | dbg("blink green LED and turn off amber\n"); | 1874 | dbg("blink green LED and turn off amber\n"); |
1864 | 1875 | ||
1865 | amber_LED_off (ctrl, hp_slot); | 1876 | amber_LED_off (ctrl, hp_slot); |
1866 | green_LED_blink (ctrl, hp_slot); | 1877 | green_LED_blink (ctrl, hp_slot); |
1867 | 1878 | ||
1868 | set_SOGO(ctrl); | 1879 | set_SOGO(ctrl); |
1869 | 1880 | ||
1870 | /* Wait for SOBS to be unset */ | 1881 | /* Wait for SOBS to be unset */ |
@@ -1958,7 +1969,7 @@ void cpqhp_pushbutton_thread(unsigned long slot) | |||
1958 | if (cpqhp_process_SI(ctrl, func) != 0) { | 1969 | if (cpqhp_process_SI(ctrl, func) != 0) { |
1959 | amber_LED_on(ctrl, hp_slot); | 1970 | amber_LED_on(ctrl, hp_slot); |
1960 | green_LED_off(ctrl, hp_slot); | 1971 | green_LED_off(ctrl, hp_slot); |
1961 | 1972 | ||
1962 | set_SOGO(ctrl); | 1973 | set_SOGO(ctrl); |
1963 | 1974 | ||
1964 | /* Wait for SOBS to be unset */ | 1975 | /* Wait for SOBS to be unset */ |
@@ -2079,7 +2090,7 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func) | |||
2079 | struct pci_bus *pci_bus = ctrl->pci_bus; | 2090 | struct pci_bus *pci_bus = ctrl->pci_bus; |
2080 | int physical_slot=0; | 2091 | int physical_slot=0; |
2081 | 2092 | ||
2082 | device = func->device; | 2093 | device = func->device; |
2083 | func = cpqhp_slot_find(ctrl->bus, device, index++); | 2094 | func = cpqhp_slot_find(ctrl->bus, device, index++); |
2084 | p_slot = cpqhp_find_slot(ctrl, device); | 2095 | p_slot = cpqhp_find_slot(ctrl, device); |
2085 | if (p_slot) { | 2096 | if (p_slot) { |
@@ -2113,9 +2124,8 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func) | |||
2113 | 2124 | ||
2114 | /* If the VGA Enable bit is set, remove isn't | 2125 | /* If the VGA Enable bit is set, remove isn't |
2115 | * supported */ | 2126 | * supported */ |
2116 | if (BCR & PCI_BRIDGE_CTL_VGA) { | 2127 | if (BCR & PCI_BRIDGE_CTL_VGA) |
2117 | rc = REMOVE_NOT_SUPPORTED; | 2128 | rc = REMOVE_NOT_SUPPORTED; |
2118 | } | ||
2119 | } | 2129 | } |
2120 | } | 2130 | } |
2121 | 2131 | ||
@@ -2183,67 +2193,67 @@ int cpqhp_hardware_test(struct controller *ctrl, int test_num) | |||
2183 | num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f; | 2193 | num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f; |
2184 | 2194 | ||
2185 | switch (test_num) { | 2195 | switch (test_num) { |
2186 | case 1: | 2196 | case 1: |
2187 | /* Do stuff here! */ | 2197 | /* Do stuff here! */ |
2188 | 2198 | ||
2189 | /* Do that funky LED thing */ | 2199 | /* Do that funky LED thing */ |
2190 | /* so we can restore them later */ | 2200 | /* so we can restore them later */ |
2191 | save_LED = readl(ctrl->hpc_reg + LED_CONTROL); | 2201 | save_LED = readl(ctrl->hpc_reg + LED_CONTROL); |
2192 | work_LED = 0x01010101; | 2202 | work_LED = 0x01010101; |
2193 | switch_leds(ctrl, num_of_slots, &work_LED, 0); | 2203 | switch_leds(ctrl, num_of_slots, &work_LED, 0); |
2194 | switch_leds(ctrl, num_of_slots, &work_LED, 1); | 2204 | switch_leds(ctrl, num_of_slots, &work_LED, 1); |
2195 | switch_leds(ctrl, num_of_slots, &work_LED, 0); | 2205 | switch_leds(ctrl, num_of_slots, &work_LED, 0); |
2196 | switch_leds(ctrl, num_of_slots, &work_LED, 1); | 2206 | switch_leds(ctrl, num_of_slots, &work_LED, 1); |
2197 | 2207 | ||
2198 | work_LED = 0x01010000; | 2208 | work_LED = 0x01010000; |
2199 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | 2209 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); |
2200 | switch_leds(ctrl, num_of_slots, &work_LED, 0); | 2210 | switch_leds(ctrl, num_of_slots, &work_LED, 0); |
2201 | switch_leds(ctrl, num_of_slots, &work_LED, 1); | 2211 | switch_leds(ctrl, num_of_slots, &work_LED, 1); |
2202 | work_LED = 0x00000101; | 2212 | work_LED = 0x00000101; |
2203 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | 2213 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); |
2204 | switch_leds(ctrl, num_of_slots, &work_LED, 0); | 2214 | switch_leds(ctrl, num_of_slots, &work_LED, 0); |
2205 | switch_leds(ctrl, num_of_slots, &work_LED, 1); | 2215 | switch_leds(ctrl, num_of_slots, &work_LED, 1); |
2216 | |||
2217 | work_LED = 0x01010000; | ||
2218 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | ||
2219 | for (loop = 0; loop < num_of_slots; loop++) { | ||
2220 | set_SOGO(ctrl); | ||
2206 | 2221 | ||
2207 | work_LED = 0x01010000; | 2222 | /* Wait for SOGO interrupt */ |
2208 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | 2223 | wait_for_ctrl_irq (ctrl); |
2209 | for (loop = 0; loop < num_of_slots; loop++) { | ||
2210 | set_SOGO(ctrl); | ||
2211 | 2224 | ||
2212 | /* Wait for SOGO interrupt */ | 2225 | /* Get ready for next iteration */ |
2213 | wait_for_ctrl_irq (ctrl); | 2226 | long_delay((3*HZ)/10); |
2227 | work_LED = work_LED >> 16; | ||
2228 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | ||
2214 | 2229 | ||
2215 | /* Get ready for next iteration */ | 2230 | set_SOGO(ctrl); |
2216 | long_delay((3*HZ)/10); | ||
2217 | work_LED = work_LED >> 16; | ||
2218 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | ||
2219 | |||
2220 | set_SOGO(ctrl); | ||
2221 | 2231 | ||
2222 | /* Wait for SOGO interrupt */ | 2232 | /* Wait for SOGO interrupt */ |
2223 | wait_for_ctrl_irq (ctrl); | 2233 | wait_for_ctrl_irq (ctrl); |
2224 | 2234 | ||
2225 | /* Get ready for next iteration */ | 2235 | /* Get ready for next iteration */ |
2226 | long_delay((3*HZ)/10); | 2236 | long_delay((3*HZ)/10); |
2227 | work_LED = work_LED << 16; | 2237 | work_LED = work_LED << 16; |
2228 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | 2238 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); |
2229 | work_LED = work_LED << 1; | 2239 | work_LED = work_LED << 1; |
2230 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | 2240 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); |
2231 | } | 2241 | } |
2232 | 2242 | ||
2233 | /* put it back the way it was */ | 2243 | /* put it back the way it was */ |
2234 | writel(save_LED, ctrl->hpc_reg + LED_CONTROL); | 2244 | writel(save_LED, ctrl->hpc_reg + LED_CONTROL); |
2235 | 2245 | ||
2236 | set_SOGO(ctrl); | 2246 | set_SOGO(ctrl); |
2237 | 2247 | ||
2238 | /* Wait for SOBS to be unset */ | 2248 | /* Wait for SOBS to be unset */ |
2239 | wait_for_ctrl_irq (ctrl); | 2249 | wait_for_ctrl_irq (ctrl); |
2240 | break; | 2250 | break; |
2241 | case 2: | 2251 | case 2: |
2242 | /* Do other stuff here! */ | 2252 | /* Do other stuff here! */ |
2243 | break; | 2253 | break; |
2244 | case 3: | 2254 | case 3: |
2245 | /* and more... */ | 2255 | /* and more... */ |
2246 | break; | 2256 | break; |
2247 | } | 2257 | } |
2248 | return 0; | 2258 | return 0; |
2249 | } | 2259 | } |
@@ -2312,9 +2322,9 @@ static u32 configure_new_device(struct controller * ctrl, struct pci_func * func | |||
2312 | while ((function < max_functions) && (!stop_it)) { | 2322 | while ((function < max_functions) && (!stop_it)) { |
2313 | pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID); | 2323 | pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID); |
2314 | 2324 | ||
2315 | if (ID == 0xFFFFFFFF) { /* There's nothing there. */ | 2325 | if (ID == 0xFFFFFFFF) { |
2316 | function++; | 2326 | function++; |
2317 | } else { /* There's something there */ | 2327 | } else { |
2318 | /* Setup slot structure. */ | 2328 | /* Setup slot structure. */ |
2319 | new_slot = cpqhp_slot_create(func->bus); | 2329 | new_slot = cpqhp_slot_create(func->bus); |
2320 | 2330 | ||
@@ -2339,8 +2349,8 @@ static u32 configure_new_device(struct controller * ctrl, struct pci_func * func | |||
2339 | 2349 | ||
2340 | 2350 | ||
2341 | /* | 2351 | /* |
2342 | Configuration logic that involves the hotplug data structures and | 2352 | * Configuration logic that involves the hotplug data structures and |
2343 | their bookkeeping | 2353 | * their bookkeeping |
2344 | */ | 2354 | */ |
2345 | 2355 | ||
2346 | 2356 | ||
@@ -2393,7 +2403,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2393 | if (rc) | 2403 | if (rc) |
2394 | return rc; | 2404 | return rc; |
2395 | 2405 | ||
2396 | if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */ | 2406 | if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
2397 | /* set Primary bus */ | 2407 | /* set Primary bus */ |
2398 | dbg("set Primary bus = %d\n", func->bus); | 2408 | dbg("set Primary bus = %d\n", func->bus); |
2399 | rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus); | 2409 | rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus); |
@@ -2484,7 +2494,8 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2484 | temp_resources.irqs = &irqs; | 2494 | temp_resources.irqs = &irqs; |
2485 | 2495 | ||
2486 | /* Make copies of the nodes we are going to pass down so that | 2496 | /* Make copies of the nodes we are going to pass down so that |
2487 | * if there is a problem,we can just use these to free resources */ | 2497 | * if there is a problem,we can just use these to free resources |
2498 | */ | ||
2488 | hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL); | 2499 | hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL); |
2489 | hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL); | 2500 | hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL); |
2490 | hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL); | 2501 | hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL); |
@@ -2556,7 +2567,8 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2556 | temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16; | 2567 | temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16; |
2557 | rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word); | 2568 | rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word); |
2558 | 2569 | ||
2559 | /* Adjust this to compensate for extra adjustment in first loop */ | 2570 | /* Adjust this to compensate for extra adjustment in first loop |
2571 | */ | ||
2560 | irqs.barber_pole--; | 2572 | irqs.barber_pole--; |
2561 | 2573 | ||
2562 | rc = 0; | 2574 | rc = 0; |
@@ -2917,27 +2929,26 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2917 | } /* End of base register loop */ | 2929 | } /* End of base register loop */ |
2918 | if (cpqhp_legacy_mode) { | 2930 | if (cpqhp_legacy_mode) { |
2919 | /* Figure out which interrupt pin this function uses */ | 2931 | /* Figure out which interrupt pin this function uses */ |
2920 | rc = pci_bus_read_config_byte (pci_bus, devfn, | 2932 | rc = pci_bus_read_config_byte (pci_bus, devfn, |
2921 | PCI_INTERRUPT_PIN, &temp_byte); | 2933 | PCI_INTERRUPT_PIN, &temp_byte); |
2922 | 2934 | ||
2923 | /* If this function needs an interrupt and we are behind | 2935 | /* If this function needs an interrupt and we are behind |
2924 | * a bridge and the pin is tied to something that's | 2936 | * a bridge and the pin is tied to something that's |
2925 | * alread mapped, set this one the same */ | 2937 | * alread mapped, set this one the same */ |
2926 | if (temp_byte && resources->irqs && | 2938 | if (temp_byte && resources->irqs && |
2927 | (resources->irqs->valid_INT & | 2939 | (resources->irqs->valid_INT & |
2928 | (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) { | 2940 | (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) { |
2929 | /* We have to share with something already set up */ | 2941 | /* We have to share with something already set up */ |
2930 | IRQ = resources->irqs->interrupt[(temp_byte + | 2942 | IRQ = resources->irqs->interrupt[(temp_byte + |
2931 | resources->irqs->barber_pole - 1) & 0x03]; | 2943 | resources->irqs->barber_pole - 1) & 0x03]; |
2932 | } else { | 2944 | } else { |
2933 | /* Program IRQ based on card type */ | 2945 | /* Program IRQ based on card type */ |
2934 | rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code); | 2946 | rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code); |
2935 | 2947 | ||
2936 | if (class_code == PCI_BASE_CLASS_STORAGE) { | 2948 | if (class_code == PCI_BASE_CLASS_STORAGE) |
2937 | IRQ = cpqhp_disk_irq; | 2949 | IRQ = cpqhp_disk_irq; |
2938 | } else { | 2950 | else |
2939 | IRQ = cpqhp_nic_irq; | 2951 | IRQ = cpqhp_nic_irq; |
2940 | } | ||
2941 | } | 2952 | } |
2942 | 2953 | ||
2943 | /* IRQ Line */ | 2954 | /* IRQ Line */ |