more changes on original files
[linux-2.4.git] / drivers / hotplug / cpqphp_ctrl.c
1 /*
2  * Compaq Hot Plug Controller Driver
3  *
4  * Copyright (C) 1995,2001 Compaq Computer Corporation
5  * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6  * Copyright (C) 2001 IBM Corp.
7  *
8  * All rights reserved.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or (at
13  * your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18  * NON INFRINGEMENT.  See the GNU General Public License for more
19  * details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  * Send feedback to <greg@kroah.com>
26  *
27  */
28
29 #include <linux/config.h>
30 #include <linux/module.h>
31 #include <linux/kernel.h>
32 #include <linux/types.h>
33 #include <linux/slab.h>
34 #include <linux/interrupt.h>
35 #include <linux/delay.h>
36 #include <linux/wait.h>
37 #include <linux/smp_lock.h>
38 #include <linux/pci.h>
39 #include "cpqphp.h"
40
41 static u32 configure_new_device(struct controller* ctrl, struct pci_func *func,u8 behind_bridge, struct resource_lists *resources);
42 static int configure_new_function(struct controller* ctrl, struct pci_func *func,u8 behind_bridge, struct resource_lists *resources);
43 static void interrupt_event_handler(struct controller *ctrl);
44
45 static struct semaphore event_semaphore;        /* mutex for process loop (up if something to process) */
46 static struct semaphore event_exit;             /* guard ensure thread has exited before calling it quits */
47 static int event_finished;
48 static unsigned long pushbutton_pending;        /* = 0 */
49
50 /* things needed for the long_delay function */
51 static struct semaphore         delay_sem;
52 static wait_queue_head_t        delay_wait;
53
54 /* delay is in jiffies to wait for */
55 static void long_delay (int delay)
56 {
57         DECLARE_WAITQUEUE(wait, current);
58         
59         /* only allow 1 customer into the delay queue at once
60          * yes this makes some people wait even longer, but who really cares?
61          * this is for _huge_ delays to make the hardware happy as the 
62          * signals bounce around
63          */
64         down (&delay_sem);
65
66         init_waitqueue_head (&delay_wait);
67
68         add_wait_queue(&delay_wait, &wait);
69         set_current_state(TASK_INTERRUPTIBLE);
70         schedule_timeout(delay);
71         remove_wait_queue(&delay_wait, &wait);
72         set_current_state(TASK_RUNNING);
73         
74         up (&delay_sem);
75 }
76
77
78 //FIXME: The following line needs to be somewhere else...
79 #define WRONG_BUS_FREQUENCY 0x07
80 static u8 handle_switch_change(u8 change, struct controller * ctrl)
81 {
82         int hp_slot;
83         u8 rc = 0;
84         u16 temp_word;
85         struct pci_func *func;
86         struct event_info *taskInfo;
87
88         if (!change)
89                 return 0;
90
91         // Switch Change
92         dbg("cpqsbd:  Switch interrupt received.\n");
93
94         for (hp_slot = 0; hp_slot < 6; hp_slot++) {
95                 if (change & (0x1L << hp_slot)) {
96                         //*********************************
97                         // this one changed.
98                         //*********************************
99                         func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
100
101                         //this is the structure that tells the worker thread
102                         //what to do
103                         taskInfo = &(ctrl->event_queue[ctrl->next_event]);
104                         ctrl->next_event = (ctrl->next_event + 1) % 10;
105                         taskInfo->hp_slot = hp_slot;
106
107                         rc++;
108
109                         temp_word = ctrl->ctrl_int_comp >> 16;
110                         func->presence_save = (temp_word >> hp_slot) & 0x01;
111                         func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
112
113                         if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
114                                 //*********************************
115                                 // Switch opened
116                                 //*********************************
117
118                                 func->switch_save = 0;
119
120                                 taskInfo->event_type = INT_SWITCH_OPEN;
121                         } else {
122                                 //*********************************
123                                 // Switch closed
124                                 //*********************************
125
126                                 func->switch_save = 0x10;
127
128                                 taskInfo->event_type = INT_SWITCH_CLOSE;
129                         }
130                 }
131         }
132
133         return rc;
134 }
135
136
137 /*
138  * cpqhp_find_slot
139  */
140 struct slot *cpqhp_find_slot (struct controller * ctrl, u8 device)
141 {
142         struct slot *slot;
143
144         if (!ctrl)
145                 return NULL;
146
147         slot = ctrl->slot;
148
149         while (slot && (slot->device != device)) {
150                 slot = slot->next;
151         }
152
153         return slot;
154 }
155
156
157 static u8 handle_presence_change(u16 change, struct controller * ctrl)
158 {
159         int hp_slot;
160         u8 rc = 0;
161         u8 temp_byte;
162         u16 temp_word;
163         struct pci_func *func;
164         struct event_info *taskInfo;
165         struct slot *p_slot;
166
167         if (!change)
168                 return 0;
169
170         //*********************************
171         // Presence Change
172         //*********************************
173         dbg("cpqsbd:  Presence/Notify input change.\n");
174         dbg("         Changed bits are 0x%4.4x\n", change );
175
176         for (hp_slot = 0; hp_slot < 6; hp_slot++) {
177                 if (change & (0x0101 << hp_slot)) {
178                         //*********************************
179                         // this one changed.
180                         //*********************************
181                         func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
182
183                         taskInfo = &(ctrl->event_queue[ctrl->next_event]);
184                         ctrl->next_event = (ctrl->next_event + 1) % 10;
185                         taskInfo->hp_slot = hp_slot;
186
187                         rc++;
188
189                         p_slot = cpqhp_find_slot(ctrl, hp_slot + (readb(ctrl->hpc_reg + SLOT_MASK) >> 4));
190
191                         // If the switch closed, must be a button
192                         // If not in button mode, nevermind
193                         if (func->switch_save && (ctrl->push_button == 1)) {
194                                 temp_word = ctrl->ctrl_int_comp >> 16;
195                                 temp_byte = (temp_word >> hp_slot) & 0x01;
196                                 temp_byte |= (temp_word >> (hp_slot + 7)) & 0x02;
197
198                                 if (temp_byte != func->presence_save) {
199                                         //*********************************
200                                         // button Pressed (doesn't do anything)
201                                         //*********************************
202                                         dbg("hp_slot %d button pressed\n", hp_slot);
203                                         taskInfo->event_type = INT_BUTTON_PRESS;
204                                 } else {
205                                         //*********************************
206                                         // button Released - TAKE ACTION!!!!
207                                         //*********************************
208                                         dbg("hp_slot %d button released\n", hp_slot);
209                                         taskInfo->event_type = INT_BUTTON_RELEASE;
210
211                                         // Cancel if we are still blinking
212                                         if ((p_slot->state == BLINKINGON_STATE)
213                                             || (p_slot->state == BLINKINGOFF_STATE)) {
214                                                 taskInfo->event_type = INT_BUTTON_CANCEL;
215                                                 dbg("hp_slot %d button cancel\n", hp_slot);
216                                         } else if ((p_slot->state == POWERON_STATE)
217                                                    || (p_slot->state == POWEROFF_STATE)) {
218                                                 //info(msg_button_ignore, p_slot->number);
219                                                 taskInfo->event_type = INT_BUTTON_IGNORE;
220                                                 dbg("hp_slot %d button ignore\n", hp_slot);
221                                         }
222                                 }
223                         } else {
224                                 // Switch is open, assume a presence change
225                                 // Save the presence state
226                                 temp_word = ctrl->ctrl_int_comp >> 16;
227                                 func->presence_save = (temp_word >> hp_slot) & 0x01;
228                                 func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
229
230                                 if ((!(ctrl->ctrl_int_comp & (0x010000 << hp_slot))) ||
231                                     (!(ctrl->ctrl_int_comp & (0x01000000 << hp_slot)))) {
232                                         //*********************************
233                                         // Present
234                                         //*********************************
235                                         taskInfo->event_type = INT_PRESENCE_ON;
236                                 } else {
237                                         //*********************************
238                                         // Not Present
239                                         //*********************************
240                                         taskInfo->event_type = INT_PRESENCE_OFF;
241                                 }
242                         }
243                 }
244         }
245
246         return rc;
247 }
248
249
250 static u8 handle_power_fault(u8 change, struct controller * ctrl)
251 {
252         int hp_slot;
253         u8 rc = 0;
254         struct pci_func *func;
255         struct event_info *taskInfo;
256
257         if (!change)
258                 return 0;
259
260         //*********************************
261         // power fault
262         //*********************************
263
264         info("power fault interrupt\n");
265
266         for (hp_slot = 0; hp_slot < 6; hp_slot++) {
267                 if (change & (0x01 << hp_slot)) {
268                         //*********************************
269                         // this one changed.
270                         //*********************************
271                         func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
272
273                         taskInfo = &(ctrl->event_queue[ctrl->next_event]);
274                         ctrl->next_event = (ctrl->next_event + 1) % 10;
275                         taskInfo->hp_slot = hp_slot;
276
277                         rc++;
278
279                         if (ctrl->ctrl_int_comp & (0x00000100 << hp_slot)) {
280                                 //*********************************
281                                 // power fault Cleared
282                                 //*********************************
283                                 func->status = 0x00;
284
285                                 taskInfo->event_type = INT_POWER_FAULT_CLEAR;
286                         } else {
287                                 //*********************************
288                                 // power fault
289                                 //*********************************
290                                 taskInfo->event_type = INT_POWER_FAULT;
291
292                                 if (ctrl->rev < 4) {
293                                         amber_LED_on (ctrl, hp_slot);
294                                         green_LED_off (ctrl, hp_slot);
295                                         set_SOGO (ctrl);
296
297                                         // this is a fatal condition, we want to crash the
298                                         // machine to protect from data corruption
299                                         // simulated_NMI shouldn't ever return
300                                         //FIXME
301                                         //simulated_NMI(hp_slot, ctrl);
302
303                                         //The following code causes a software crash just in
304                                         //case simulated_NMI did return
305                                         //FIXME
306                                         //panic(msg_power_fault);
307                                 } else {
308                                         // set power fault status for this board
309                                         func->status = 0xFF;
310                                         info("power fault bit %x set\n", hp_slot);
311                                 }
312                         }
313                 }
314         }
315
316         return rc;
317 }
318
319
320 /*
321  * sort_by_size
322  *
323  * Sorts nodes on the list by their length.
324  * Smallest first.
325  *
326  */
327 static int sort_by_size(struct pci_resource **head)
328 {
329         struct pci_resource *current_res;
330         struct pci_resource *next_res;
331         int out_of_order = 1;
332
333         if (!(*head))
334                 return(1);
335
336         if (!((*head)->next))
337                 return(0);
338
339         while (out_of_order) {
340                 out_of_order = 0;
341
342                 // Special case for swapping list head
343                 if (((*head)->next) &&
344                     ((*head)->length > (*head)->next->length)) {
345                         out_of_order++;
346                         current_res = *head;
347                         *head = (*head)->next;
348                         current_res->next = (*head)->next;
349                         (*head)->next = current_res;
350                 }
351
352                 current_res = *head;
353
354                 while (current_res->next && current_res->next->next) {
355                         if (current_res->next->length > current_res->next->next->length) {
356                                 out_of_order++;
357                                 next_res = current_res->next;
358                                 current_res->next = current_res->next->next;
359                                 current_res = current_res->next;
360                                 next_res->next = current_res->next;
361                                 current_res->next = next_res;
362                         } else
363                                 current_res = current_res->next;
364                 }
365         }  // End of out_of_order loop
366
367         return(0);
368 }
369
370
371 /*
372  * sort_by_max_size
373  *
374  * Sorts nodes on the list by their length.
375  * Largest first.
376  *
377  */
378 static int sort_by_max_size(struct pci_resource **head)
379 {
380         struct pci_resource *current_res;
381         struct pci_resource *next_res;
382         int out_of_order = 1;
383
384         if (!(*head))
385                 return(1);
386
387         if (!((*head)->next))
388                 return(0);
389
390         while (out_of_order) {
391                 out_of_order = 0;
392
393                 // Special case for swapping list head
394                 if (((*head)->next) &&
395                     ((*head)->length < (*head)->next->length)) {
396                         out_of_order++;
397                         current_res = *head;
398                         *head = (*head)->next;
399                         current_res->next = (*head)->next;
400                         (*head)->next = current_res;
401                 }
402
403                 current_res = *head;
404
405                 while (current_res->next && current_res->next->next) {
406                         if (current_res->next->length < current_res->next->next->length) {
407                                 out_of_order++;
408                                 next_res = current_res->next;
409                                 current_res->next = current_res->next->next;
410                                 current_res = current_res->next;
411                                 next_res->next = current_res->next;
412                                 current_res->next = next_res;
413                         } else
414                                 current_res = current_res->next;
415                 }
416         }  // End of out_of_order loop
417
418         return(0);
419 }
420
421
422 /*
423  * do_pre_bridge_resource_split
424  *
425  *      Returns zero or one node of resources that aren't in use
426  *
427  */
428 static struct pci_resource *do_pre_bridge_resource_split (struct pci_resource **head, struct pci_resource **orig_head, u32 alignment)
429 {
430         struct pci_resource *prevnode = NULL;
431         struct pci_resource *node;
432         struct pci_resource *split_node;
433         u32 rc;
434         u32 temp_dword;
435         dbg("do_pre_bridge_resource_split\n");
436
437         if (!(*head) || !(*orig_head))
438                 return(NULL);
439
440         rc = cpqhp_resource_sort_and_combine(head);
441
442         if (rc)
443                 return(NULL);
444
445         if ((*head)->base != (*orig_head)->base)
446                 return(NULL);
447
448         if ((*head)->length == (*orig_head)->length)
449                 return(NULL);
450
451
452         // If we got here, there the bridge requires some of the resource, but
453         // we may be able to split some off of the front
454
455         node = *head;
456
457         if (node->length & (alignment -1)) {
458                 // this one isn't an aligned length, so we'll make a new entry
459                 // and split it up.
460                 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
461
462                 if (!split_node)
463                         return(NULL);
464
465                 temp_dword = (node->length | (alignment-1)) + 1 - alignment;
466
467                 split_node->base = node->base;
468                 split_node->length = temp_dword;
469
470                 node->length -= temp_dword;
471                 node->base += split_node->length;
472
473                 // Put it in the list
474                 *head = split_node;
475                 split_node->next = node;
476         }
477
478         if (node->length < alignment) {
479                 return(NULL);
480         }
481
482         // Now unlink it
483         if (*head == node) {
484                 *head = node->next;
485                 node->next = NULL;
486         } else {
487                 prevnode = *head;
488                 while (prevnode->next != node)
489                         prevnode = prevnode->next;
490
491                 prevnode->next = node->next;
492                 node->next = NULL;
493         }
494
495         return(node);
496 }
497
498
499 /*
500  * do_bridge_resource_split
501  *
502  *      Returns zero or one node of resources that aren't in use
503  *
504  */
505 static struct pci_resource *do_bridge_resource_split (struct pci_resource **head, u32 alignment)
506 {
507         struct pci_resource *prevnode = NULL;
508         struct pci_resource *node;
509         u32 rc;
510         u32 temp_dword;
511
512         if (!(*head))
513                 return(NULL);
514
515         rc = cpqhp_resource_sort_and_combine(head);
516
517         if (rc)
518                 return(NULL);
519
520         node = *head;
521
522         while (node->next) {
523                 prevnode = node;
524                 node = node->next;
525                 kfree(prevnode);
526         }
527
528         if (node->length < alignment) {
529                 kfree(node);
530                 return(NULL);
531         }
532
533         if (node->base & (alignment - 1)) {
534                 // Short circuit if adjusted size is too small
535                 temp_dword = (node->base | (alignment-1)) + 1;
536                 if ((node->length - (temp_dword - node->base)) < alignment) {
537                         kfree(node);
538                         return(NULL);
539                 }
540
541                 node->length -= (temp_dword - node->base);
542                 node->base = temp_dword;
543         }
544
545         if (node->length & (alignment - 1)) {
546                 // There's stuff in use after this node
547                 kfree(node);
548                 return(NULL);
549         }
550
551         return(node);
552 }
553
554
555 /*
556  * get_io_resource
557  *
558  * this function sorts the resource list by size and then
559  * returns the first node of "size" length that is not in the
560  * ISA aliasing window.  If it finds a node larger than "size"
561  * it will split it up.
562  *
563  * size must be a power of two.
564  */
565 static struct pci_resource *get_io_resource (struct pci_resource **head, u32 size)
566 {
567         struct pci_resource *prevnode;
568         struct pci_resource *node;
569         struct pci_resource *split_node;
570         u32 temp_dword;
571
572         if (!(*head))
573                 return(NULL);
574
575         if ( cpqhp_resource_sort_and_combine(head) )
576                 return(NULL);
577
578         if ( sort_by_size(head) )
579                 return(NULL);
580
581         for (node = *head; node; node = node->next) {
582                 if (node->length < size)
583                         continue;
584
585                 if (node->base & (size - 1)) {
586                         // this one isn't base aligned properly
587                         // so we'll make a new entry and split it up
588                         temp_dword = (node->base | (size-1)) + 1;
589
590                         // Short circuit if adjusted size is too small
591                         if ((node->length - (temp_dword - node->base)) < size)
592                                 continue;
593
594                         split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
595
596                         if (!split_node)
597                                 return(NULL);
598
599                         split_node->base = node->base;
600                         split_node->length = temp_dword - node->base;
601                         node->base = temp_dword;
602                         node->length -= split_node->length;
603
604                         // Put it in the list
605                         split_node->next = node->next;
606                         node->next = split_node;
607                 } // End of non-aligned base
608
609                 // Don't need to check if too small since we already did
610                 if (node->length > size) {
611                         // this one is longer than we need
612                         // so we'll make a new entry and split it up
613                         split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
614
615                         if (!split_node)
616                                 return(NULL);
617
618                         split_node->base = node->base + size;
619                         split_node->length = node->length - size;
620                         node->length = size;
621
622                         // Put it in the list
623                         split_node->next = node->next;
624                         node->next = split_node;
625                 }  // End of too big on top end
626
627                 // For IO make sure it's not in the ISA aliasing space
628                 if (node->base & 0x300L)
629                         continue;
630
631                 // If we got here, then it is the right size
632                 // Now take it out of the list
633                 if (*head == node) {
634                         *head = node->next;
635                 } else {
636                         prevnode = *head;
637                         while (prevnode->next != node)
638                                 prevnode = prevnode->next;
639
640                         prevnode->next = node->next;
641                 }
642                 node->next = NULL;
643                 // Stop looping
644                 break;
645         }
646
647         return(node);
648 }
649
650
651 /*
652  * get_max_resource
653  *
654  * Gets the largest node that is at least "size" big from the
655  * list pointed to by head.  It aligns the node on top and bottom
656  * to "size" alignment before returning it.
657  */
658 static struct pci_resource *get_max_resource (struct pci_resource **head, u32 size)
659 {
660         struct pci_resource *max;
661         struct pci_resource *temp;
662         struct pci_resource *split_node;
663         u32 temp_dword;
664
665         if (!(*head))
666                 return(NULL);
667
668         if (cpqhp_resource_sort_and_combine(head))
669                 return(NULL);
670
671         if (sort_by_max_size(head))
672                 return(NULL);
673
674         for (max = *head;max; max = max->next) {
675
676                 // If not big enough we could probably just bail, 
677                 // instead we'll continue to the next.
678                 if (max->length < size)
679                         continue;
680
681                 if (max->base & (size - 1)) {
682                         // this one isn't base aligned properly
683                         // so we'll make a new entry and split it up
684                         temp_dword = (max->base | (size-1)) + 1;
685
686                         // Short circuit if adjusted size is too small
687                         if ((max->length - (temp_dword - max->base)) < size)
688                                 continue;
689
690                         split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
691
692                         if (!split_node)
693                                 return(NULL);
694
695                         split_node->base = max->base;
696                         split_node->length = temp_dword - max->base;
697                         max->base = temp_dword;
698                         max->length -= split_node->length;
699
700                         // Put it next in the list
701                         split_node->next = max->next;
702                         max->next = split_node;
703                 }
704
705                 if ((max->base + max->length) & (size - 1)) {
706                         // this one isn't end aligned properly at the top
707                         // so we'll make a new entry and split it up
708                         split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
709
710                         if (!split_node)
711                                 return(NULL);
712                         temp_dword = ((max->base + max->length) & ~(size - 1));
713                         split_node->base = temp_dword;
714                         split_node->length = max->length + max->base
715                                              - split_node->base;
716                         max->length -= split_node->length;
717
718                         // Put it in the list
719                         split_node->next = max->next;
720                         max->next = split_node;
721                 }
722
723                 // Make sure it didn't shrink too much when we aligned it
724                 if (max->length < size)
725                         continue;
726
727                 // Now take it out of the list
728                 temp = (struct pci_resource*) *head;
729                 if (temp == max) {
730                         *head = max->next;
731                 } else {
732                         while (temp && temp->next != max) {
733                                 temp = temp->next;
734                         }
735
736                         temp->next = max->next;
737                 }
738
739                 max->next = NULL;
740                 return(max);
741         }
742
743         // If we get here, we couldn't find one
744         return(NULL);
745 }
746
747
748 /*
749  * get_resource
750  *
751  * this function sorts the resource list by size and then
752  * returns the first node of "size" length.  If it finds a node
753  * larger than "size" it will split it up.
754  *
755  * size must be a power of two.
756  */
757 static struct pci_resource *get_resource (struct pci_resource **head, u32 size)
758 {
759         struct pci_resource *prevnode;
760         struct pci_resource *node;
761         struct pci_resource *split_node;
762         u32 temp_dword;
763
764         if (!(*head))
765                 return(NULL);
766
767         if ( cpqhp_resource_sort_and_combine(head) )
768                 return(NULL);
769
770         if ( sort_by_size(head) )
771                 return(NULL);
772
773         for (node = *head; node; node = node->next) {
774                 dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
775                     __FUNCTION__, size, node, node->base, node->length);
776                 if (node->length < size)
777                         continue;
778
779                 if (node->base & (size - 1)) {
780                         dbg("%s: not aligned\n", __FUNCTION__);
781                         // this one isn't base aligned properly
782                         // so we'll make a new entry and split it up
783                         temp_dword = (node->base | (size-1)) + 1;
784
785                         // Short circuit if adjusted size is too small
786                         if ((node->length - (temp_dword - node->base)) < size)
787                                 continue;
788
789                         split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
790
791                         if (!split_node)
792                                 return(NULL);
793
794                         split_node->base = node->base;
795                         split_node->length = temp_dword - node->base;
796                         node->base = temp_dword;
797                         node->length -= split_node->length;
798
799                         // Put it in the list
800                         split_node->next = node->next;
801                         node->next = split_node;
802                 } // End of non-aligned base
803
804                 // Don't need to check if too small since we already did
805                 if (node->length > size) {
806                         dbg("%s: too big\n", __FUNCTION__);
807                         // this one is longer than we need
808                         // so we'll make a new entry and split it up
809                         split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
810
811                         if (!split_node)
812                                 return(NULL);
813
814                         split_node->base = node->base + size;
815                         split_node->length = node->length - size;
816                         node->length = size;
817
818                         // Put it in the list
819                         split_node->next = node->next;
820                         node->next = split_node;
821                 }  // End of too big on top end
822
823                 dbg("%s: got one!!!\n", __FUNCTION__);
824                 // If we got here, then it is the right size
825                 // Now take it out of the list
826                 if (*head == node) {
827                         *head = node->next;
828                 } else {
829                         prevnode = *head;
830                         while (prevnode->next != node)
831                                 prevnode = prevnode->next;
832
833                         prevnode->next = node->next;
834                 }
835                 node->next = NULL;
836                 // Stop looping
837                 break;
838         }
839         return(node);
840 }
841
842
843 /*
844  * cpqhp_resource_sort_and_combine
845  *
846  * Sorts all of the nodes in the list in ascending order by
847  * their base addresses.  Also does garbage collection by
848  * combining adjacent nodes.
849  *
850  * returns 0 if success
851  */
852 int cpqhp_resource_sort_and_combine(struct pci_resource **head)
853 {
854         struct pci_resource *node1;
855         struct pci_resource *node2;
856         int out_of_order = 1;
857
858         dbg("%s: head = %p, *head = %p\n",__FUNCTION__, head, *head);
859
860         if (!(*head))
861                 return(1);
862
863         dbg("*head->next = %p\n",(*head)->next);
864
865         if (!(*head)->next)
866                 return(0);      /* only one item on the list, already sorted! */
867
868         dbg("*head->base = 0x%x\n",(*head)->base);
869         dbg("*head->next->base = 0x%x\n",(*head)->next->base);
870         while (out_of_order) {
871                 out_of_order = 0;
872
873                 // Special case for swapping list head
874                 if (((*head)->next) &&
875                     ((*head)->base > (*head)->next->base)) {
876                         node1 = *head;
877                         (*head) = (*head)->next;
878                         node1->next = (*head)->next;
879                         (*head)->next = node1;
880                         out_of_order++;
881                 }
882
883                 node1 = (*head);
884
885                 while (node1->next && node1->next->next) {
886                         if (node1->next->base > node1->next->next->base) {
887                                 out_of_order++;
888                                 node2 = node1->next;
889                                 node1->next = node1->next->next;
890                                 node1 = node1->next;
891                                 node2->next = node1->next;
892                                 node1->next = node2;
893                         } else
894                                 node1 = node1->next;
895                 }
896         }  // End of out_of_order loop
897
898         node1 = *head;
899
900         while (node1 && node1->next) {
901                 if ((node1->base + node1->length) == node1->next->base) {
902                         // Combine
903                         dbg("8..\n");
904                         node1->length += node1->next->length;
905                         node2 = node1->next;
906                         node1->next = node1->next->next;
907                         kfree(node2);
908                 } else
909                         node1 = node1->next;
910         }
911
912         return(0);
913 }
914
915
916 void cpqhp_ctrl_intr(int IRQ, struct controller * ctrl, struct pt_regs *regs)
917 {
918         u8 schedule_flag = 0;
919         u8 reset;
920         u16 misc;
921         u32 Diff;
922         u32 temp_dword;
923
924         
925         misc = readw(ctrl->hpc_reg + MISC);
926         //*********************************
927         // Check to see if it was our interrupt
928         //*********************************
929         if (!(misc & 0x000C)) {
930                 return;
931         }
932
933         if (misc & 0x0004) {
934                 //*********************************
935                 // Serial Output interrupt Pending
936                 //*********************************
937
938                 // Clear the interrupt
939                 misc |= 0x0004;
940                 writew(misc, ctrl->hpc_reg + MISC);
941
942                 // Read to clear posted writes
943                 misc = readw(ctrl->hpc_reg + MISC);
944
945                 dbg ("%s - waking up\n", __FUNCTION__);
946                 wake_up_interruptible(&ctrl->queue);
947         }
948
949         if (misc & 0x0008) {
950                 // General-interrupt-input interrupt Pending
951                 Diff = readl(ctrl->hpc_reg + INT_INPUT_CLEAR) ^ ctrl->ctrl_int_comp;
952
953                 ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
954
955                 // Clear the interrupt
956                 writel(Diff, ctrl->hpc_reg + INT_INPUT_CLEAR);
957
958                 // Read it back to clear any posted writes
959                 temp_dword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
960
961                 if (!Diff) {
962                         // Clear all interrupts
963                         writel(0xFFFFFFFF, ctrl->hpc_reg + INT_INPUT_CLEAR);
964                 }
965
966                 schedule_flag += handle_switch_change((u8)(Diff & 0xFFL), ctrl);
967                 schedule_flag += handle_presence_change((u16)((Diff & 0xFFFF0000L) >> 16), ctrl);
968                 schedule_flag += handle_power_fault((u8)((Diff & 0xFF00L) >> 8), ctrl);
969         }
970         
971         reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
972         if (reset & 0x40) {
973                 /* Bus Reset has completed */
974                 reset &= 0xCF;
975                 writeb(reset, ctrl->hpc_reg + RESET_FREQ_MODE);
976                 reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
977                 wake_up_interruptible(&ctrl->queue);
978         }
979
980         if (schedule_flag) {
981                 up(&event_semaphore);
982                 dbg("Signal event_semaphore\n");
983                 mark_bh(IMMEDIATE_BH);
984         }
985
986 }
987
988
989 /**
990  * cpqhp_slot_create - Creates a node and adds it to the proper bus.
991  * @busnumber - bus where new node is to be located
992  *
993  * Returns pointer to the new node or NULL if unsuccessful
994  */
995 struct pci_func *cpqhp_slot_create(u8 busnumber)
996 {
997         struct pci_func *new_slot;
998         struct pci_func *next;
999
1000         new_slot = (struct pci_func *) kmalloc(sizeof(struct pci_func), GFP_KERNEL);
1001
1002         if (new_slot == NULL) {
1003                 // I'm not dead yet!
1004                 // You will be.
1005                 return(new_slot);
1006         }
1007
1008         memset(new_slot, 0, sizeof(struct pci_func));
1009
1010         new_slot->next = NULL;
1011         new_slot->configured = 1;
1012
1013         if (cpqhp_slot_list[busnumber] == NULL) {
1014                 cpqhp_slot_list[busnumber] = new_slot;
1015         } else {
1016                 next = cpqhp_slot_list[busnumber];
1017                 while (next->next != NULL)
1018                         next = next->next;
1019                 next->next = new_slot;
1020         }
1021         return(new_slot);
1022 }
1023
1024
1025 /*
1026  * slot_remove - Removes a node from the linked list of slots.
1027  * @old_slot: slot to remove
1028  *
1029  * Returns 0 if successful, !0 otherwise.
1030  */
1031 static int slot_remove(struct pci_func * old_slot)
1032 {
1033         struct pci_func *next;
1034
1035         if (old_slot == NULL)
1036                 return(1);
1037
1038         next = cpqhp_slot_list[old_slot->bus];
1039
1040         if (next == NULL) {
1041                 return(1);
1042         }
1043
1044         if (next == old_slot) {
1045                 cpqhp_slot_list[old_slot->bus] = old_slot->next;
1046                 cpqhp_destroy_board_resources(old_slot);
1047                 kfree(old_slot);
1048                 return(0);
1049         }
1050
1051         while ((next->next != old_slot) && (next->next != NULL)) {
1052                 next = next->next;
1053         }
1054
1055         if (next->next == old_slot) {
1056                 next->next = old_slot->next;
1057                 cpqhp_destroy_board_resources(old_slot);
1058                 kfree(old_slot);
1059                 return(0);
1060         } else
1061                 return(2);
1062 }
1063
1064
1065 /**
1066  * bridge_slot_remove - Removes a node from the linked list of slots.
1067  * @bridge: bridge to remove
1068  *
1069  * Returns 0 if successful, !0 otherwise.
1070  */
1071 static int bridge_slot_remove(struct pci_func *bridge)
1072 {
1073         u8 subordinateBus, secondaryBus;
1074         u8 tempBus;
1075         struct pci_func *next;
1076
1077         if (bridge == NULL)
1078                 return(1);
1079
1080         secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
1081         subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
1082
1083         for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
1084                 next = cpqhp_slot_list[tempBus];
1085
1086                 while (!slot_remove(next)) {
1087                         next = cpqhp_slot_list[tempBus];
1088                 }
1089         }
1090
1091         next = cpqhp_slot_list[bridge->bus];
1092
1093         if (next == NULL) {
1094                 return(1);
1095         }
1096
1097         if (next == bridge) {
1098                 cpqhp_slot_list[bridge->bus] = bridge->next;
1099                 kfree(bridge);
1100                 return(0);
1101         }
1102
1103         while ((next->next != bridge) && (next->next != NULL)) {
1104                 next = next->next;
1105         }
1106
1107         if (next->next == bridge) {
1108                 next->next = bridge->next;
1109                 kfree(bridge);
1110                 return(0);
1111         } else
1112                 return(2);
1113 }
1114
1115
1116 /**
1117  * cpqhp_slot_find - Looks for a node by bus, and device, multiple functions accessed
1118  * @bus: bus to find
1119  * @device: device to find
1120  * @index: is 0 for first function found, 1 for the second...
1121  *
1122  * Returns pointer to the node if successful, %NULL otherwise.
1123  */
1124 struct pci_func *cpqhp_slot_find(u8 bus, u8 device, u8 index)
1125 {
1126         int found = -1;
1127         struct pci_func *func;
1128
1129         func = cpqhp_slot_list[bus];
1130
1131         if ((func == NULL) || ((func->device == device) && (index == 0)))
1132                 return(func);
1133
1134         if (func->device == device)
1135                 found++;
1136
1137         while (func->next != NULL) {
1138                 func = func->next;
1139
1140                 if (func->device == device)
1141                         found++;
1142
1143                 if (found == index)
1144                         return(func);
1145         }
1146
1147         return(NULL);
1148 }
1149
1150
1151 // DJZ: I don't think is_bridge will work as is.
1152 //FIXME
1153 static int is_bridge(struct pci_func * func)
1154 {
1155         // Check the header type
1156         if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
1157                 return 1;
1158         else
1159                 return 0;
1160 }
1161
1162
1163 /* the following routines constitute the bulk of the 
1164    hotplug controller logic
1165  */
1166
1167
1168 /**
1169  * board_replaced - Called after a board has been replaced in the system.
1170  *
1171  * This is only used if we don't have resources for hot add
1172  * Turns power on for the board
1173  * Checks to see if board is the same
1174  * If board is same, reconfigures it
1175  * If board isn't same, turns it back off.
1176  *
1177  */
1178 static u32 board_replaced(struct pci_func * func, struct controller * ctrl)
1179 {
1180         u8 hp_slot;
1181         u8 temp_byte;
1182         u8 adapter_speed;
1183         u32 index;
1184         u32 rc = 0;
1185         u32 src = 8;
1186
1187         hp_slot = func->device - ctrl->slot_device_offset;
1188
1189         if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)) {
1190                 //*********************************
1191                 // The switch is open.
1192                 //*********************************
1193                 rc = INTERLOCK_OPEN;
1194         } else if (is_slot_enabled (ctrl, hp_slot)) {
1195                 //*********************************
1196                 // The board is already on
1197                 //*********************************
1198                 rc = CARD_FUNCTIONING;
1199         } else {
1200                 // Wait for exclusive access to hardware
1201                 down(&ctrl->crit_sect);
1202
1203                 // turn on board without attaching to the bus
1204                 enable_slot_power (ctrl, hp_slot);
1205
1206                 set_SOGO(ctrl);
1207
1208                 // Wait for SOBS to be unset
1209                 wait_for_ctrl_irq (ctrl);
1210
1211                 // Change bits in slot power register to force another shift out
1212                 // NOTE: this is to work around the timer bug
1213                 temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
1214                 writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
1215                 writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
1216
1217                 set_SOGO(ctrl);
1218
1219                 // Wait for SOBS to be unset
1220                 wait_for_ctrl_irq (ctrl);
1221                 
1222                 // 66MHz and/or PCI-X support check
1223                 adapter_speed = get_adapter_speed(ctrl, hp_slot);
1224                 if (ctrl->speed != adapter_speed)
1225                         if (set_controller_speed(ctrl, adapter_speed, hp_slot))
1226                                 rc = WRONG_BUS_FREQUENCY;
1227
1228                 // turn off board without attaching to the bus
1229                 disable_slot_power (ctrl, hp_slot);
1230
1231                 set_SOGO(ctrl);
1232
1233                 // Wait for SOBS to be unset
1234                 wait_for_ctrl_irq (ctrl);
1235
1236                 // Done with exclusive hardware access
1237                 up(&ctrl->crit_sect);
1238
1239                 if (rc)
1240                         return(rc);
1241
1242                 // Wait for exclusive access to hardware
1243                 down(&ctrl->crit_sect);
1244
1245                 slot_enable (ctrl, hp_slot);
1246                 green_LED_blink (ctrl, hp_slot);
1247
1248                 amber_LED_off (ctrl, hp_slot);
1249
1250                 set_SOGO(ctrl);
1251
1252                 // Wait for SOBS to be unset
1253                 wait_for_ctrl_irq (ctrl);
1254
1255                 // Done with exclusive hardware access
1256                 up(&ctrl->crit_sect);
1257
1258                 // Wait for ~1 second because of hot plug spec
1259                 long_delay(1*HZ);
1260
1261                 // Check for a power fault
1262                 if (func->status == 0xFF) {
1263                         // power fault occurred, but it was benign
1264                         rc = POWER_FAILURE;
1265                         func->status = 0;
1266                 } else
1267                         rc = cpqhp_valid_replace(ctrl, func);
1268
1269                 if (!rc) {
1270                         // It must be the same board
1271
1272                         rc = cpqhp_configure_board(ctrl, func);
1273
1274                         if (rc || src) {
1275                                 // If configuration fails, turn it off
1276                                 // Get slot won't work for devices behind bridges, but
1277                                 // in this case it will always be called for the "base"
1278                                 // bus/dev/func of an adapter.
1279
1280                                 // Wait for exclusive access to hardware
1281                                 down(&ctrl->crit_sect);
1282
1283                                 amber_LED_on (ctrl, hp_slot);
1284                                 green_LED_off (ctrl, hp_slot);
1285                                 slot_disable (ctrl, hp_slot);
1286
1287                                 set_SOGO(ctrl);
1288
1289                                 // Wait for SOBS to be unset
1290                                 wait_for_ctrl_irq (ctrl);
1291
1292                                 // Done with exclusive hardware access
1293                                 up(&ctrl->crit_sect);
1294
1295                                 if (rc)
1296                                         return(rc);
1297                                 else
1298                                         return(1);
1299                         }
1300
1301                         func->status = 0;
1302                         func->switch_save = 0x10;
1303
1304                         index = 1;
1305                         while (((func = cpqhp_slot_find(func->bus, func->device, index)) != NULL) && !rc) {
1306                                 rc |= cpqhp_configure_board(ctrl, func);
1307                                 index++;
1308                         }
1309
1310                         if (rc) {
1311                                 // If configuration fails, turn it off
1312                                 // Get slot won't work for devices behind bridges, but
1313                                 // in this case it will always be called for the "base"
1314                                 // bus/dev/func of an adapter.
1315
1316                                 // Wait for exclusive access to hardware
1317                                 down(&ctrl->crit_sect);
1318
1319                                 amber_LED_on (ctrl, hp_slot);
1320                                 green_LED_off (ctrl, hp_slot);
1321                                 slot_disable (ctrl, hp_slot);
1322
1323                                 set_SOGO(ctrl);
1324
1325                                 // Wait for SOBS to be unset
1326                                 wait_for_ctrl_irq (ctrl);
1327
1328                                 // Done with exclusive hardware access
1329                                 up(&ctrl->crit_sect);
1330
1331                                 return(rc);
1332                         }
1333                         // Done configuring so turn LED on full time
1334
1335                         // Wait for exclusive access to hardware
1336                         down(&ctrl->crit_sect);
1337
1338                         green_LED_on (ctrl, hp_slot);
1339
1340                         set_SOGO(ctrl);
1341
1342                         // Wait for SOBS to be unset
1343                         wait_for_ctrl_irq (ctrl);
1344
1345                         // Done with exclusive hardware access
1346                         up(&ctrl->crit_sect);
1347                         rc = 0;
1348                 } else {
1349                         // Something is wrong
1350
1351                         // Get slot won't work for devices behind bridges, but
1352                         // in this case it will always be called for the "base"
1353                         // bus/dev/func of an adapter.
1354
1355                         // Wait for exclusive access to hardware
1356                         down(&ctrl->crit_sect);
1357
1358                         amber_LED_on (ctrl, hp_slot);
1359                         green_LED_off (ctrl, hp_slot);
1360                         slot_disable (ctrl, hp_slot);
1361
1362                         set_SOGO(ctrl);
1363
1364                         // Wait for SOBS to be unset
1365                         wait_for_ctrl_irq (ctrl);
1366
1367                         // Done with exclusive hardware access
1368                         up(&ctrl->crit_sect);
1369                 }
1370
1371         }
1372         return(rc);
1373
1374 }
1375
1376
1377 /**
1378  * board_added - Called after a board has been added to the system.
1379  *
1380  * Turns power on for the board
1381  * Configures board
1382  *
1383  */
1384 static u32 board_added(struct pci_func * func, struct controller * ctrl)
1385 {
1386         u8 hp_slot;
1387         u8 temp_byte;
1388         u8 adapter_speed;
1389         int index;
1390         u32 temp_register = 0xFFFFFFFF;
1391         u32 rc = 0;
1392         struct pci_func *new_slot = NULL;
1393         struct slot *p_slot;
1394         struct resource_lists res_lists;
1395
1396         hp_slot = func->device - ctrl->slot_device_offset;
1397         dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n",
1398             __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
1399         
1400         // Wait for exclusive access to hardware
1401         down(&ctrl->crit_sect);
1402
1403         // turn on board without attaching to the bus
1404         enable_slot_power (ctrl, hp_slot);
1405
1406         set_SOGO(ctrl);
1407
1408         // Wait for SOBS to be unset
1409         wait_for_ctrl_irq (ctrl);
1410
1411         // Change bits in slot power register to force another shift out
1412         // NOTE: this is to work around the timer bug
1413         temp_byte = readb(ctrl->hpc_reg + SLOT_POWER);
1414         writeb(0x00, ctrl->hpc_reg + SLOT_POWER);
1415         writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER);
1416
1417         set_SOGO(ctrl);
1418
1419         // Wait for SOBS to be unset
1420         wait_for_ctrl_irq (ctrl);
1421         
1422         // 66MHz and/or PCI-X support check
1423         adapter_speed = get_adapter_speed(ctrl, hp_slot);
1424         if (ctrl->speed != adapter_speed)
1425                 if (set_controller_speed(ctrl, adapter_speed, hp_slot))
1426                         rc = WRONG_BUS_FREQUENCY;
1427         
1428         // turn off board without attaching to the bus
1429         disable_slot_power (ctrl, hp_slot);
1430
1431         set_SOGO(ctrl);
1432
1433         // Wait for SOBS to be unset
1434         wait_for_ctrl_irq (ctrl);
1435
1436         // Done with exclusive hardware access
1437         up(&ctrl->crit_sect);
1438
1439         if (rc)
1440                 return(rc);
1441         
1442         p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1443
1444         // turn on board and blink green LED
1445
1446         // Wait for exclusive access to hardware
1447         dbg("%s: before down\n", __FUNCTION__);
1448         down(&ctrl->crit_sect);
1449         dbg("%s: after down\n", __FUNCTION__);
1450
1451         dbg("%s: before slot_enable\n", __FUNCTION__);
1452         slot_enable (ctrl, hp_slot);
1453
1454         dbg("%s: before green_LED_blink\n", __FUNCTION__);
1455         green_LED_blink (ctrl, hp_slot);
1456
1457         dbg("%s: before amber_LED_blink\n", __FUNCTION__);
1458         amber_LED_off (ctrl, hp_slot);
1459
1460         dbg("%s: before set_SOGO\n", __FUNCTION__);
1461         set_SOGO(ctrl);
1462
1463         // Wait for SOBS to be unset
1464         dbg("%s: before wait_for_ctrl_irq\n", __FUNCTION__);
1465         wait_for_ctrl_irq (ctrl);
1466         dbg("%s: after wait_for_ctrl_irq\n", __FUNCTION__);
1467
1468         // Done with exclusive hardware access
1469         dbg("%s: before up\n", __FUNCTION__);
1470         up(&ctrl->crit_sect);
1471         dbg("%s: after up\n", __FUNCTION__);
1472
1473         // Wait for ~1 second because of hot plug spec
1474         dbg("%s: before long_delay\n", __FUNCTION__);
1475         long_delay(1*HZ);
1476         dbg("%s: after long_delay\n", __FUNCTION__);
1477
1478         dbg("%s: func status = %x\n", __FUNCTION__, func->status);
1479         // Check for a power fault
1480         if (func->status == 0xFF) {
1481                 // power fault occurred, but it was benign
1482                 temp_register = 0xFFFFFFFF;
1483                 dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
1484                 rc = POWER_FAILURE;
1485                 func->status = 0;
1486         } else {
1487                 // Get vendor/device ID u32
1488                 rc = pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_VENDOR_ID, &temp_register);
1489                 dbg("%s: pci_read_config_dword returns %d\n", __FUNCTION__, rc);
1490                 dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
1491
1492                 if (rc != 0) {
1493                         // Something's wrong here
1494                         temp_register = 0xFFFFFFFF;
1495                         dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
1496                 }
1497                 // Preset return code.  It will be changed later if things go okay.
1498                 rc = NO_ADAPTER_PRESENT;
1499         }
1500
1501         // All F's is an empty slot or an invalid board
1502         if (temp_register != 0xFFFFFFFF) {        // Check for a board in the slot
1503                 res_lists.io_head = ctrl->io_head;
1504                 res_lists.mem_head = ctrl->mem_head;
1505                 res_lists.p_mem_head = ctrl->p_mem_head;
1506                 res_lists.bus_head = ctrl->bus_head;
1507                 res_lists.irqs = NULL;
1508
1509                 rc = configure_new_device(ctrl, func, 0, &res_lists);
1510
1511                 dbg("%s: back from configure_new_device\n", __FUNCTION__);
1512                 ctrl->io_head = res_lists.io_head;
1513                 ctrl->mem_head = res_lists.mem_head;
1514                 ctrl->p_mem_head = res_lists.p_mem_head;
1515                 ctrl->bus_head = res_lists.bus_head;
1516
1517                 cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
1518                 cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
1519                 cpqhp_resource_sort_and_combine(&(ctrl->io_head));
1520                 cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
1521
1522                 if (rc) {
1523                         // Wait for exclusive access to hardware
1524                         down(&ctrl->crit_sect);
1525
1526                         amber_LED_on (ctrl, hp_slot);
1527                         green_LED_off (ctrl, hp_slot);
1528                         slot_disable (ctrl, hp_slot);
1529
1530                         set_SOGO(ctrl);
1531
1532                         // Wait for SOBS to be unset
1533                         wait_for_ctrl_irq (ctrl);
1534
1535                         // Done with exclusive hardware access
1536                         up(&ctrl->crit_sect);
1537                         return(rc);
1538                 } else {
1539                         cpqhp_save_slot_config(ctrl, func);
1540                 }
1541
1542
1543                 func->status = 0;
1544                 func->switch_save = 0x10;
1545                 func->is_a_board = 0x01;
1546
1547                 //next, we will instantiate the linux pci_dev structures (with appropriate driver notification, if already present)
1548                 dbg("%s: configure linux pci_dev structure\n", __FUNCTION__);
1549                 index = 0;
1550                 do {
1551                         new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++);
1552                         if (new_slot && !new_slot->pci_dev) {
1553                                 cpqhp_configure_device(ctrl, new_slot);
1554                         }
1555                 } while (new_slot);
1556
1557                 // Wait for exclusive access to hardware
1558                 down(&ctrl->crit_sect);
1559
1560                 green_LED_on (ctrl, hp_slot);
1561
1562                 set_SOGO(ctrl);
1563
1564                 // Wait for SOBS to be unset
1565                 wait_for_ctrl_irq (ctrl);
1566
1567                 // Done with exclusive hardware access
1568                 up(&ctrl->crit_sect);
1569         } else {
1570                 // Wait for exclusive access to hardware
1571                 down(&ctrl->crit_sect);
1572
1573                 amber_LED_on (ctrl, hp_slot);
1574                 green_LED_off (ctrl, hp_slot);
1575                 slot_disable (ctrl, hp_slot);
1576
1577                 set_SOGO(ctrl);
1578
1579                 // Wait for SOBS to be unset
1580                 wait_for_ctrl_irq (ctrl);
1581
1582                 // Done with exclusive hardware access
1583                 up(&ctrl->crit_sect);
1584
1585                 return(rc);
1586         }
1587         return 0;
1588 }
1589
1590
1591 /**
1592  * remove_board - Turns off slot and LED's
1593  *
1594  */
1595 static u32 remove_board(struct pci_func * func, u32 replace_flag, struct controller * ctrl)
1596 {
1597         int index;
1598         u8 skip = 0;
1599         u8 device;
1600         u8 hp_slot;
1601         u8 temp_byte;
1602         u32 rc;
1603         struct resource_lists res_lists;
1604         struct pci_func *temp_func;
1605
1606         if (func == NULL)
1607                 return(1);
1608
1609         if (cpqhp_unconfigure_device(func))
1610                 return(1);
1611
1612         device = func->device;
1613
1614         hp_slot = func->device - ctrl->slot_device_offset;
1615         dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
1616
1617         // When we get here, it is safe to change base Address Registers.
1618         // We will attempt to save the base Address Register Lengths
1619         if (replace_flag || !ctrl->add_support)
1620                 rc = cpqhp_save_base_addr_length(ctrl, func);
1621         else if (!func->bus_head && !func->mem_head &&
1622                  !func->p_mem_head && !func->io_head) {
1623                 // Here we check to see if we've saved any of the board's
1624                 // resources already.  If so, we'll skip the attempt to
1625                 // determine what's being used.
1626                 index = 0;
1627                 temp_func = cpqhp_slot_find(func->bus, func->device, index++);
1628                 while (temp_func) {
1629                         if (temp_func->bus_head || temp_func->mem_head
1630                             || temp_func->p_mem_head || temp_func->io_head) {
1631                                 skip = 1;
1632                                 break;
1633                         }
1634                         temp_func = cpqhp_slot_find(temp_func->bus, temp_func->device, index++);
1635                 }
1636
1637                 if (!skip)
1638                         rc = cpqhp_save_used_resources(ctrl, func);
1639         }
1640         // Change status to shutdown
1641         if (func->is_a_board)
1642                 func->status = 0x01;
1643         func->configured = 0;
1644
1645         // Wait for exclusive access to hardware
1646         down(&ctrl->crit_sect);
1647
1648         green_LED_off (ctrl, hp_slot);
1649         slot_disable (ctrl, hp_slot);
1650
1651         set_SOGO(ctrl);
1652
1653         // turn off SERR for slot
1654         temp_byte = readb(ctrl->hpc_reg + SLOT_SERR);
1655         temp_byte &= ~(0x01 << hp_slot);
1656         writeb(temp_byte, ctrl->hpc_reg + SLOT_SERR);
1657
1658         // Wait for SOBS to be unset
1659         wait_for_ctrl_irq (ctrl);
1660
1661         // Done with exclusive hardware access
1662         up(&ctrl->crit_sect);
1663
1664         if (!replace_flag && ctrl->add_support) {
1665                 while (func) {
1666                         res_lists.io_head = ctrl->io_head;
1667                         res_lists.mem_head = ctrl->mem_head;
1668                         res_lists.p_mem_head = ctrl->p_mem_head;
1669                         res_lists.bus_head = ctrl->bus_head;
1670
1671                         cpqhp_return_board_resources(func, &res_lists);
1672
1673                         ctrl->io_head = res_lists.io_head;
1674                         ctrl->mem_head = res_lists.mem_head;
1675                         ctrl->p_mem_head = res_lists.p_mem_head;
1676                         ctrl->bus_head = res_lists.bus_head;
1677
1678                         cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
1679                         cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
1680                         cpqhp_resource_sort_and_combine(&(ctrl->io_head));
1681                         cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
1682
1683                         if (is_bridge(func)) {
1684                                 bridge_slot_remove(func);
1685                         } else
1686                                 slot_remove(func);
1687
1688                         func = cpqhp_slot_find(ctrl->bus, device, 0);
1689                 }
1690
1691                 // Setup slot structure with entry for empty slot
1692                 func = cpqhp_slot_create(ctrl->bus);
1693
1694                 if (func == NULL) {
1695                         // Out of memory
1696                         return(1);
1697                 }
1698
1699                 func->bus = ctrl->bus;
1700                 func->device = device;
1701                 func->function = 0;
1702                 func->configured = 0;
1703                 func->switch_save = 0x10;
1704                 func->is_a_board = 0;
1705                 func->p_task_event = NULL;
1706         }
1707
1708         return 0;
1709 }
1710
1711
1712 static void pushbutton_helper_thread (unsigned long data)
1713 {
1714         pushbutton_pending = data;
1715         up(&event_semaphore);
1716 }
1717
1718
1719 // this is the main worker thread
1720 static int event_thread(void* data)
1721 {
1722         struct controller *ctrl;
1723         lock_kernel();
1724         daemonize();
1725         reparent_to_init();
1726         
1727         //  New name
1728         strcpy(current->comm, "phpd_event");
1729
1730         /* avoid getting signals */
1731         spin_lock_irq(&current->sigmask_lock);
1732         flush_signals(current);
1733         sigfillset(&current->blocked);
1734         recalc_sigpending(current);
1735         spin_unlock_irq(&current->sigmask_lock);
1736
1737         unlock_kernel();
1738
1739         while (1) {
1740                 dbg("!!!!event_thread sleeping\n");
1741                 down_interruptible (&event_semaphore);
1742                 dbg("event_thread woken finished = %d\n", event_finished);
1743                 if (event_finished) break;
1744                 /* Do stuff here */
1745                 if (pushbutton_pending)
1746                         cpqhp_pushbutton_thread(pushbutton_pending);
1747                 else
1748                         for (ctrl = cpqhp_ctrl_list; ctrl; ctrl=ctrl->next)
1749                                 interrupt_event_handler(ctrl);
1750         }
1751         dbg("event_thread signals exit\n");
1752         up(&event_exit);
1753         return 0;
1754 }
1755
1756
1757 int cpqhp_event_start_thread (void)
1758 {
1759         int pid;
1760
1761         /* initialize our semaphores */
1762         init_MUTEX(&delay_sem);
1763         init_MUTEX_LOCKED(&event_semaphore);
1764         init_MUTEX_LOCKED(&event_exit);
1765         event_finished=0;
1766
1767         pid = kernel_thread(event_thread, 0, 0);
1768         if (pid < 0) {
1769                 err ("Can't start up our event thread\n");
1770                 return -1;
1771         }
1772         dbg("Our event thread pid = %d\n", pid);
1773         return 0;
1774 }
1775
1776
1777 void cpqhp_event_stop_thread (void)
1778 {
1779         event_finished = 1;
1780         dbg("event_thread finish command given\n");
1781         up(&event_semaphore);
1782         dbg("wait for event_thread to exit\n");
1783         down(&event_exit);
1784 }
1785
1786
1787 static int update_slot_info (struct controller *ctrl, struct slot *slot)
1788 {
1789         struct hotplug_slot_info *info;
1790         char buffer[SLOT_NAME_SIZE];
1791         int result;
1792
1793         info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
1794         if (!info)
1795                 return -ENOMEM;
1796
1797         make_slot_name (&buffer[0], SLOT_NAME_SIZE, slot);
1798         info->power_status = get_slot_enabled(ctrl, slot);
1799         info->attention_status = cpq_get_attention_status(ctrl, slot);
1800         info->latch_status = cpq_get_latch_status(ctrl, slot);
1801         info->adapter_status = get_presence_status(ctrl, slot);
1802         result = pci_hp_change_slot_info(buffer, info);
1803         kfree (info);
1804         return result;
1805 }
1806
1807 static void interrupt_event_handler(struct controller *ctrl)
1808 {
1809         int loop = 0;
1810         int change = 1;
1811         struct pci_func *func;
1812         u8 hp_slot;
1813         struct slot *p_slot;
1814
1815         while (change) {
1816                 change = 0;
1817
1818                 for (loop = 0; loop < 10; loop++) {
1819                         //dbg("loop %d\n", loop);
1820                         if (ctrl->event_queue[loop].event_type != 0) {
1821                                 hp_slot = ctrl->event_queue[loop].hp_slot;
1822
1823                                 func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
1824
1825                                 p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1826
1827                                 dbg("hp_slot %d, func %p, p_slot %p\n",
1828                                     hp_slot, func, p_slot);
1829
1830                                 if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {
1831                                         dbg("button pressed\n");
1832                                 } else if (ctrl->event_queue[loop].event_type == 
1833                                            INT_BUTTON_CANCEL) {
1834                                         dbg("button cancel\n");
1835                                         del_timer(&p_slot->task_event);
1836
1837                                         // Wait for exclusive access to hardware
1838                                         down(&ctrl->crit_sect);
1839
1840                                         if (p_slot->state == BLINKINGOFF_STATE) {
1841                                                 // slot is on
1842                                                 // turn on green LED
1843                                                 dbg("turn on green LED\n");
1844                                                 green_LED_on (ctrl, hp_slot);
1845                                         } else if (p_slot->state == BLINKINGON_STATE) {
1846                                                 // slot is off
1847                                                 // turn off green LED
1848                                                 dbg("turn off green LED\n");
1849                                                 green_LED_off (ctrl, hp_slot);
1850                                         }
1851
1852                                         info(msg_button_cancel, p_slot->number);
1853
1854                                         p_slot->state = STATIC_STATE;
1855
1856                                         amber_LED_off (ctrl, hp_slot);
1857
1858                                         set_SOGO(ctrl);
1859
1860                                         // Wait for SOBS to be unset
1861                                         wait_for_ctrl_irq (ctrl);
1862
1863                                         // Done with exclusive hardware access
1864                                         up(&ctrl->crit_sect);
1865                                 }
1866                                 // ***********button Released (No action on press...)
1867                                 else if (ctrl->event_queue[loop].event_type == INT_BUTTON_RELEASE) {
1868                                         dbg("button release\n");
1869
1870                                         if (is_slot_enabled (ctrl, hp_slot)) {
1871                                                 // slot is on
1872                                                 dbg("slot is on\n");
1873                                                 p_slot->state = BLINKINGOFF_STATE;
1874                                                 info(msg_button_off, p_slot->number);
1875                                         } else {
1876                                                 // slot is off
1877                                                 dbg("slot is off\n");
1878                                                 p_slot->state = BLINKINGON_STATE;
1879                                                 info(msg_button_on, p_slot->number);
1880                                         }
1881                                         // Wait for exclusive access to hardware
1882                                         down(&ctrl->crit_sect);
1883
1884                                         dbg("blink green LED and turn off amber\n");
1885                                         amber_LED_off (ctrl, hp_slot);
1886                                         green_LED_blink (ctrl, hp_slot);
1887
1888                                         set_SOGO(ctrl);
1889
1890                                         // Wait for SOBS to be unset
1891                                         wait_for_ctrl_irq (ctrl);
1892
1893                                         // Done with exclusive hardware access
1894                                         up(&ctrl->crit_sect);
1895                                         init_timer(&p_slot->task_event);
1896                                         p_slot->hp_slot = hp_slot;
1897                                         p_slot->ctrl = ctrl;
1898 //                                      p_slot->physical_slot = physical_slot;
1899                                         p_slot->task_event.expires = jiffies + 5 * HZ;   // 5 second delay
1900                                         p_slot->task_event.function = pushbutton_helper_thread;
1901                                         p_slot->task_event.data = (u32) p_slot;
1902
1903                                         dbg("add_timer p_slot = %p\n", p_slot);
1904                                         add_timer(&p_slot->task_event);
1905                                 }
1906                                 // ***********POWER FAULT
1907                                 else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
1908                                         dbg("power fault\n");
1909                                 } else {
1910                                         /* refresh notification */
1911                                         if (p_slot)
1912                                                 update_slot_info(ctrl, p_slot);
1913                                 }
1914
1915                                 ctrl->event_queue[loop].event_type = 0;
1916
1917                                 change = 1;
1918                         }
1919                 }               // End of FOR loop
1920         }
1921
1922         return;
1923 }
1924
1925
1926 /**
1927  * cpqhp_pushbutton_thread
1928  *
1929  * Scheduled procedure to handle blocking stuff for the pushbuttons
1930  * Handles all pending events and exits.
1931  *
1932  */
1933 void cpqhp_pushbutton_thread (unsigned long slot)
1934 {
1935         u8 hp_slot;
1936         u8 device;
1937         struct pci_func *func;
1938         struct slot *p_slot = (struct slot *) slot;
1939         struct controller *ctrl = (struct controller *) p_slot->ctrl;
1940
1941         pushbutton_pending = 0;
1942         hp_slot = p_slot->hp_slot;
1943
1944         device = p_slot->device;
1945
1946         if (is_slot_enabled (ctrl, hp_slot)) {
1947                 p_slot->state = POWEROFF_STATE;
1948                 // power Down board
1949                 func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
1950                 dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl);
1951                 if (!func) {
1952                         dbg("Error! func NULL in %s\n", __FUNCTION__);
1953                         return ;
1954                 }
1955
1956                 if (func != NULL && ctrl != NULL) {
1957                         if (cpqhp_process_SS(ctrl, func) != 0) {
1958                                 amber_LED_on (ctrl, hp_slot);
1959                                 green_LED_on (ctrl, hp_slot);
1960                                 
1961                                 set_SOGO(ctrl);
1962
1963                                 // Wait for SOBS to be unset
1964                                 wait_for_ctrl_irq (ctrl);
1965                         }
1966                 }
1967
1968                 p_slot->state = STATIC_STATE;
1969         } else {
1970                 p_slot->state = POWERON_STATE;
1971                 // slot is off
1972
1973                 func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
1974                 dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl);
1975                 if (!func) {
1976                         dbg("Error! func NULL in %s\n", __FUNCTION__);
1977                         return ;
1978                 }
1979
1980                 if (func != NULL && ctrl != NULL) {
1981                         if (cpqhp_process_SI(ctrl, func) != 0) {
1982                                 amber_LED_on (ctrl, hp_slot);
1983                                 green_LED_off (ctrl, hp_slot);
1984                                 
1985                                 set_SOGO(ctrl);
1986
1987                                 // Wait for SOBS to be unset
1988                                 wait_for_ctrl_irq (ctrl);
1989                         }
1990                 }
1991
1992                 p_slot->state = STATIC_STATE;
1993         }
1994
1995         return;
1996 }
1997
1998
1999 int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func)
2000 {
2001         u8 device, hp_slot;
2002         u16 temp_word;
2003         u32 tempdword;
2004         int rc;
2005         struct slot* p_slot;
2006         int physical_slot = 0;
2007
2008         if (!ctrl)
2009                 return(1);
2010
2011         tempdword = 0;
2012
2013         device = func->device;
2014         hp_slot = device - ctrl->slot_device_offset;
2015         p_slot = cpqhp_find_slot(ctrl, device);
2016         if (p_slot) {
2017                 physical_slot = p_slot->number;
2018         }
2019
2020         // Check to see if the interlock is closed
2021         tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
2022
2023         if (tempdword & (0x01 << hp_slot)) {
2024                 return(1);
2025         }
2026
2027         if (func->is_a_board) {
2028                 rc = board_replaced(func, ctrl);
2029         } else {
2030                 // add board
2031                 slot_remove(func);
2032
2033                 func = cpqhp_slot_create(ctrl->bus);
2034                 if (func == NULL) {
2035                         return(1);
2036                 }
2037
2038                 func->bus = ctrl->bus;
2039                 func->device = device;
2040                 func->function = 0;
2041                 func->configured = 0;
2042                 func->is_a_board = 1;
2043
2044                 // We have to save the presence info for these slots
2045                 temp_word = ctrl->ctrl_int_comp >> 16;
2046                 func->presence_save = (temp_word >> hp_slot) & 0x01;
2047                 func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
2048
2049                 if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
2050                         func->switch_save = 0;
2051                 } else {
2052                         func->switch_save = 0x10;
2053                 }
2054
2055                 rc = board_added(func, ctrl);
2056                 if (rc) {
2057                         if (is_bridge(func)) {
2058                                 bridge_slot_remove(func);
2059                         } else
2060                                 slot_remove(func);
2061
2062                         // Setup slot structure with entry for empty slot
2063                         func = cpqhp_slot_create(ctrl->bus);
2064
2065                         if (func == NULL) {
2066                                 // Out of memory
2067                                 return(1);
2068                         }
2069
2070                         func->bus = ctrl->bus;
2071                         func->device = device;
2072                         func->function = 0;
2073                         func->configured = 0;
2074                         func->is_a_board = 0;
2075
2076                         // We have to save the presence info for these slots
2077                         temp_word = ctrl->ctrl_int_comp >> 16;
2078                         func->presence_save = (temp_word >> hp_slot) & 0x01;
2079                         func->presence_save |=
2080                         (temp_word >> (hp_slot + 7)) & 0x02;
2081
2082                         if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
2083                                 func->switch_save = 0;
2084                         } else {
2085                                 func->switch_save = 0x10;
2086                         }
2087                 }
2088         }
2089
2090         if (rc) {
2091                 dbg("%s: rc = %d\n", __FUNCTION__, rc);
2092         }
2093
2094         if (p_slot)
2095                 update_slot_info(ctrl, p_slot);
2096
2097         return rc;
2098 }
2099
2100
2101 int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
2102 {
2103         u8 device, class_code, header_type, BCR;
2104         u8 index = 0;
2105         u8 replace_flag;
2106         u32 rc = 0;
2107         struct slot* p_slot;
2108         int physical_slot=0;
2109
2110         device = func->device; 
2111         func = cpqhp_slot_find(ctrl->bus, device, index++);
2112         p_slot = cpqhp_find_slot(ctrl, device);
2113         if (p_slot) {
2114                 physical_slot = p_slot->number;
2115         }
2116
2117         // Make sure there are no video controllers here
2118         while (func && !rc) {
2119                 // Check the Class Code
2120                 rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0B, &class_code);
2121                 if (rc)
2122                         return rc;
2123
2124                 if (class_code == PCI_BASE_CLASS_DISPLAY) {
2125                         /* Display/Video adapter (not supported) */
2126                         rc = REMOVE_NOT_SUPPORTED;
2127                 } else {
2128                         // See if it's a bridge
2129                         rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type);
2130                         if (rc)
2131                                 return rc;
2132
2133                         // If it's a bridge, check the VGA Enable bit
2134                         if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
2135                                 rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_BRIDGE_CONTROL, &BCR);
2136                                 if (rc)
2137                                         return rc;
2138
2139                                 // If the VGA Enable bit is set, remove isn't supported
2140                                 if (BCR & PCI_BRIDGE_CTL_VGA) {
2141                                         rc = REMOVE_NOT_SUPPORTED;
2142                                 }
2143                         }
2144                 }
2145
2146                 func = cpqhp_slot_find(ctrl->bus, device, index++);
2147         }
2148
2149         func = cpqhp_slot_find(ctrl->bus, device, 0);
2150         if ((func != NULL) && !rc) {
2151                 //FIXME: Replace flag should be passed into process_SS
2152                 replace_flag = !(ctrl->add_support);
2153                 rc = remove_board(func, replace_flag, ctrl);
2154         } else if (!rc) {
2155                 rc = 1;
2156         }
2157
2158         if (p_slot)
2159                 update_slot_info(ctrl, p_slot);
2160
2161         return(rc);
2162 }
2163
2164
2165
2166 /**
2167  * hardware_test - runs hardware tests
2168  *
2169  * For hot plug ctrl folks to play with.
2170  * test_num is the number entered in the GUI
2171  *
2172  */
2173 int cpqhp_hardware_test(struct controller *ctrl, int test_num)
2174 {
2175         u32 save_LED;
2176         u32 work_LED;
2177         int loop;
2178         int num_of_slots;
2179
2180         num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f;
2181
2182         switch (test_num) {
2183                 case 1:
2184                         // Do stuff here!
2185
2186                         // Do that funky LED thing
2187                         save_LED = readl(ctrl->hpc_reg + LED_CONTROL);  // so we can restore them later
2188                         work_LED = 0x01010101;
2189                         writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2190                         for (loop = 0; loop < num_of_slots; loop++) {
2191                                 set_SOGO(ctrl);
2192
2193                                 // Wait for SOGO interrupt
2194                                 wait_for_ctrl_irq (ctrl);
2195
2196                                 // Get ready for next iteration
2197                                 work_LED = work_LED << 1;
2198                                 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2199                                 long_delay((2*HZ)/10);
2200                         }
2201                         for (loop = 0; loop < num_of_slots; loop++) {
2202                                 work_LED = work_LED >> 1;
2203                                 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2204                                 
2205                                 set_SOGO(ctrl);
2206
2207                                 // Wait for SOGO interrupt
2208                                 wait_for_ctrl_irq (ctrl);
2209
2210                                 // Get ready for next iteration
2211                                 long_delay((2*HZ)/10);
2212                         }
2213                         for (loop = 0; loop < num_of_slots; loop++) {
2214                                 work_LED = work_LED << 1;
2215                                 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2216                                 
2217                                 set_SOGO(ctrl);
2218
2219                                 // Wait for SOGO interrupt
2220                                 wait_for_ctrl_irq (ctrl);
2221
2222                                 // Get ready for next iteration
2223                                 long_delay((2*HZ)/10);
2224                         }
2225                         for (loop = 0; loop < num_of_slots; loop++) {
2226                                 work_LED = work_LED >> 1;
2227                                 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2228                                 
2229                                 set_SOGO(ctrl);
2230
2231                                 // Wait for SOGO interrupt
2232                                 wait_for_ctrl_irq (ctrl);
2233
2234                                 // Get ready for next iteration
2235                                 long_delay((2*HZ)/10);
2236                         }
2237
2238                         work_LED = 0x01010000;
2239                         writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2240                         for (loop = 0; loop < num_of_slots; loop++) {
2241                                 set_SOGO(ctrl);
2242
2243                                 // Wait for SOGO interrupt
2244                                 wait_for_ctrl_irq (ctrl);
2245
2246                                 // Get ready for next iteration
2247                                 work_LED = work_LED << 1;
2248                                 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2249                                 long_delay((2*HZ)/10);
2250                         }
2251                         for (loop = 0; loop < num_of_slots; loop++) {
2252                                 work_LED = work_LED >> 1;
2253                                 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2254                                 
2255                                 set_SOGO(ctrl);
2256
2257                                 // Wait for SOGO interrupt
2258                                 wait_for_ctrl_irq (ctrl);
2259
2260                                 // Get ready for next iteration
2261                                 long_delay((2*HZ)/10);
2262                         }
2263                         work_LED = 0x00000101;
2264                         writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2265                         for (loop = 0; loop < num_of_slots; loop++) {
2266                                 work_LED = work_LED << 1;
2267                                 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2268                                 
2269                                 set_SOGO(ctrl);
2270
2271                                 // Wait for SOGO interrupt
2272                                 wait_for_ctrl_irq (ctrl);
2273
2274                                 // Get ready for next iteration
2275                                 long_delay((2*HZ)/10);
2276                         }
2277                         for (loop = 0; loop < num_of_slots; loop++) {
2278                                 work_LED = work_LED >> 1;
2279                                 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2280                                 
2281                                 set_SOGO(ctrl);
2282
2283                                 // Wait for SOGO interrupt
2284                                 wait_for_ctrl_irq (ctrl);
2285
2286                                 // Get ready for next iteration
2287                                 long_delay((2*HZ)/10);
2288                         }
2289
2290
2291                         work_LED = 0x01010000;
2292                         writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2293                         for (loop = 0; loop < num_of_slots; loop++) {
2294                                 set_SOGO(ctrl);
2295
2296                                 // Wait for SOGO interrupt
2297                                 wait_for_ctrl_irq (ctrl);
2298
2299                                 // Get ready for next iteration
2300                                 long_delay((3*HZ)/10);
2301                                 work_LED = work_LED >> 16;
2302                                 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2303                                 
2304                                 set_SOGO(ctrl);
2305
2306                                 // Wait for SOGO interrupt
2307                                 wait_for_ctrl_irq (ctrl);
2308
2309                                 // Get ready for next iteration
2310                                 long_delay((3*HZ)/10);
2311                                 work_LED = work_LED << 16;
2312                                 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2313                                 work_LED = work_LED << 1;
2314                                 writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2315                         }
2316
2317                         writel (save_LED, ctrl->hpc_reg + LED_CONTROL); // put it back the way it was
2318
2319                         set_SOGO(ctrl);
2320
2321                         // Wait for SOBS to be unset
2322                         wait_for_ctrl_irq (ctrl);
2323                         break;
2324                 case 2:
2325                         // Do other stuff here!
2326                         break;
2327                 case 3:
2328                         // and more...
2329                         break;
2330         }
2331         return 0;
2332 }
2333
2334
2335 /**
2336  * configure_new_device - Configures the PCI header information of one board.
2337  *
2338  * @ctrl: pointer to controller structure
2339  * @func: pointer to function structure
2340  * @behind_bridge: 1 if this is a recursive call, 0 if not
2341  * @resources: pointer to set of resource lists
2342  *
2343  * Returns 0 if success
2344  *
2345  */
2346 static u32 configure_new_device (struct controller * ctrl, struct pci_func * func,
2347                                  u8 behind_bridge, struct resource_lists * resources)
2348 {
2349         u8 temp_byte, function, max_functions, stop_it;
2350         int rc;
2351         u32 ID;
2352         struct pci_func *new_slot;
2353         int index;
2354
2355         new_slot = func;
2356
2357         dbg("%s\n", __FUNCTION__);
2358         // Check for Multi-function device
2359         rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0E, &temp_byte);
2360         if (rc) {
2361                 dbg("%s: rc = %d\n", __FUNCTION__, rc);
2362                 return rc;
2363         }
2364
2365         if (temp_byte & 0x80)   // Multi-function device
2366                 max_functions = 8;
2367         else
2368                 max_functions = 1;
2369
2370         function = 0;
2371
2372         do {
2373                 rc = configure_new_function(ctrl, new_slot, behind_bridge, resources);
2374
2375                 if (rc) {
2376                         dbg("configure_new_function failed %d\n",rc);
2377                         index = 0;
2378
2379                         while (new_slot) {
2380                                 new_slot = cpqhp_slot_find(new_slot->bus, new_slot->device, index++);
2381
2382                                 if (new_slot)
2383                                         cpqhp_return_board_resources(new_slot, resources);
2384                         }
2385
2386                         return(rc);
2387                 }
2388
2389                 function++;
2390
2391                 stop_it = 0;
2392
2393                 //  The following loop skips to the next present function
2394                 //  and creates a board structure
2395
2396                 while ((function < max_functions) && (!stop_it)) {
2397                         pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, function, 0x00, &ID);
2398
2399                         if (ID == 0xFFFFFFFF) {   // There's nothing there. 
2400                                 function++;
2401                         } else {  // There's something there
2402                                 // Setup slot structure.
2403                                 new_slot = cpqhp_slot_create(func->bus);
2404
2405                                 if (new_slot == NULL) {
2406                                         // Out of memory
2407                                         return(1);
2408                                 }
2409
2410                                 new_slot->bus = func->bus;
2411                                 new_slot->device = func->device;
2412                                 new_slot->function = function;
2413                                 new_slot->is_a_board = 1;
2414                                 new_slot->status = 0;
2415
2416                                 stop_it++;
2417                         }
2418                 }
2419
2420         } while (function < max_functions);
2421         dbg("returning from configure_new_device\n");
2422
2423         return 0;
2424 }
2425
2426
2427 /*
2428   Configuration logic that involves the hotplug data structures and 
2429   their bookkeeping
2430  */
2431
2432
2433 /**
2434  * configure_new_function - Configures the PCI header information of one device
2435  *
2436  * @ctrl: pointer to controller structure
2437  * @func: pointer to function structure
2438  * @behind_bridge: 1 if this is a recursive call, 0 if not
2439  * @resources: pointer to set of resource lists
2440  *
2441  * Calls itself recursively for bridged devices.
2442  * Returns 0 if success
2443  *
2444  */
2445 static int configure_new_function (struct controller * ctrl, struct pci_func * func,
2446                                    u8 behind_bridge, struct resource_lists * resources)
2447 {
2448         int cloop;
2449         u8 IRQ;
2450         u8 temp_byte;
2451         u8 device;
2452         u8 class_code;
2453         u16 command;
2454         u16 temp_word;
2455         u32 temp_dword;
2456         u32 rc;
2457         u32 temp_register;
2458         u32 base;
2459         u32 ID;
2460         struct pci_resource *mem_node;
2461         struct pci_resource *p_mem_node;
2462         struct pci_resource *io_node;
2463         struct pci_resource *bus_node;
2464         struct pci_resource *hold_mem_node;
2465         struct pci_resource *hold_p_mem_node;
2466         struct pci_resource *hold_IO_node;
2467         struct pci_resource *hold_bus_node;
2468         struct irq_mapping irqs;
2469         struct pci_func *new_slot;
2470         struct resource_lists temp_resources;
2471
2472         // Check for Bridge
2473         rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &temp_byte);
2474         if (rc)
2475                 return rc;
2476
2477         if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
2478                 // set Primary bus
2479                 dbg("set Primary bus = %d\n", func->bus);
2480                 rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PRIMARY_BUS, func->bus);
2481                 if (rc)
2482                         return rc;
2483
2484                 // find range of busses to use
2485                 dbg("find ranges of buses to use\n");
2486                 bus_node = get_max_resource(&resources->bus_head, 1);
2487
2488                 // If we don't have any busses to allocate, we can't continue
2489                 if (!bus_node)
2490                         return -ENOMEM;
2491
2492                 // set Secondary bus
2493                 temp_byte = bus_node->base;
2494                 dbg("set Secondary bus = %d\n", bus_node->base);
2495                 rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SECONDARY_BUS, temp_byte);
2496                 if (rc)
2497                         return rc;
2498
2499                 // set subordinate bus
2500                 temp_byte = bus_node->base + bus_node->length - 1;
2501                 dbg("set subordinate bus = %d\n", bus_node->base + bus_node->length - 1);
2502                 rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBORDINATE_BUS, temp_byte);
2503                 if (rc)
2504                         return rc;
2505
2506                 // set subordinate Latency Timer and base Latency Timer
2507                 temp_byte = 0x40;
2508                 rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SEC_LATENCY_TIMER, temp_byte);
2509                 if (rc)
2510                         return rc;
2511                 rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_LATENCY_TIMER, temp_byte);
2512                 if (rc)
2513                         return rc;
2514
2515                 // set Cache Line size
2516                 temp_byte = 0x08;
2517                 rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_CACHE_LINE_SIZE, temp_byte);
2518                 if (rc)
2519                         return rc;
2520
2521                 // Setup the IO, memory, and prefetchable windows
2522
2523                 io_node = get_max_resource(&(resources->io_head), 0x1000);
2524                 mem_node = get_max_resource(&(resources->mem_head), 0x100000);
2525                 p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000);
2526                 dbg("Setup the IO, memory, and prefetchable windows\n");
2527                 dbg("io_node\n");
2528                 dbg("(base, len, next) (%x, %x, %p)\n", io_node->base, io_node->length, io_node->next);
2529                 dbg("mem_node\n");
2530                 dbg("(base, len, next) (%x, %x, %p)\n", mem_node->base, mem_node->length, mem_node->next);
2531                 dbg("p_mem_node\n");
2532                 dbg("(base, len, next) (%x, %x, %p)\n", p_mem_node->base, p_mem_node->length, p_mem_node->next);
2533
2534                 // set up the IRQ info
2535                 if (!resources->irqs) {
2536                         irqs.barber_pole = 0;
2537                         irqs.interrupt[0] = 0;
2538                         irqs.interrupt[1] = 0;
2539                         irqs.interrupt[2] = 0;
2540                         irqs.interrupt[3] = 0;
2541                         irqs.valid_INT = 0;
2542                 } else {
2543                         irqs.barber_pole = resources->irqs->barber_pole;
2544                         irqs.interrupt[0] = resources->irqs->interrupt[0];
2545                         irqs.interrupt[1] = resources->irqs->interrupt[1];
2546                         irqs.interrupt[2] = resources->irqs->interrupt[2];
2547                         irqs.interrupt[3] = resources->irqs->interrupt[3];
2548                         irqs.valid_INT = resources->irqs->valid_INT;
2549                 }
2550
2551                 // set up resource lists that are now aligned on top and bottom
2552                 // for anything behind the bridge.
2553                 temp_resources.bus_head = bus_node;
2554                 temp_resources.io_head = io_node;
2555                 temp_resources.mem_head = mem_node;
2556                 temp_resources.p_mem_head = p_mem_node;
2557                 temp_resources.irqs = &irqs;
2558
2559                 // Make copies of the nodes we are going to pass down so that
2560                 // if there is a problem,we can just use these to free resources
2561                 hold_bus_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2562                 hold_IO_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2563                 hold_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2564                 hold_p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2565
2566                 if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
2567                         if (hold_bus_node)
2568                                 kfree(hold_bus_node);
2569                         if (hold_IO_node)
2570                                 kfree(hold_IO_node);
2571                         if (hold_mem_node)
2572                                 kfree(hold_mem_node);
2573                         if (hold_p_mem_node)
2574                                 kfree(hold_p_mem_node);
2575
2576                         return(1);
2577                 }
2578
2579                 memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
2580
2581                 bus_node->base += 1;
2582                 bus_node->length -= 1;
2583                 bus_node->next = NULL;
2584
2585                 // If we have IO resources copy them and fill in the bridge's
2586                 // IO range registers
2587                 if (io_node) {
2588                         memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
2589                         io_node->next = NULL;
2590
2591                         // set IO base and Limit registers
2592                         temp_byte = io_node->base >> 8;
2593                         rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_BASE, temp_byte);
2594
2595                         temp_byte = (io_node->base + io_node->length - 1) >> 8;
2596                         rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, temp_byte);
2597                 } else {
2598                         kfree(hold_IO_node);
2599                         hold_IO_node = NULL;
2600                 }
2601
2602                 // If we have memory resources copy them and fill in the bridge's
2603                 // memory range registers.  Otherwise, fill in the range
2604                 // registers with values that disable them.
2605                 if (mem_node) {
2606                         memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource));
2607                         mem_node->next = NULL;
2608
2609                         // set Mem base and Limit registers
2610                         temp_word = mem_node->base >> 16;
2611                         rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, temp_word);
2612
2613                         temp_word = (mem_node->base + mem_node->length - 1) >> 16;
2614                         rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word);
2615                 } else {
2616                         temp_word = 0xFFFF;
2617                         rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, temp_word);
2618
2619                         temp_word = 0x0000;
2620                         rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word);
2621
2622                         kfree(hold_mem_node);
2623                         hold_mem_node = NULL;
2624                 }
2625
2626                 // If we have prefetchable memory resources copy them and 
2627                 // fill in the bridge's memory range registers.  Otherwise,
2628                 // fill in the range registers with values that disable them.
2629                 if (p_mem_node) {
2630                         memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));
2631                         p_mem_node->next = NULL;
2632
2633                         // set Pre Mem base and Limit registers
2634                         temp_word = p_mem_node->base >> 16;
2635                         rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, temp_word);
2636
2637                         temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
2638                         rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word);
2639                 } else {
2640                         temp_word = 0xFFFF;
2641                         rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, temp_word);
2642
2643                         temp_word = 0x0000;
2644                         rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word);
2645
2646                         kfree(hold_p_mem_node);
2647                         hold_p_mem_node = NULL;
2648                 }
2649
2650                 // Adjust this to compensate for extra adjustment in first loop
2651                 irqs.barber_pole--;
2652
2653                 rc = 0;
2654
2655                 // Here we actually find the devices and configure them
2656                 for (device = 0; (device <= 0x1F) && !rc; device++) {
2657                         irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
2658
2659                         ID = 0xFFFFFFFF;
2660                         pci_read_config_dword_nodev (ctrl->pci_ops, hold_bus_node->base, device, 0, 0x00, &ID);
2661
2662                         if (ID != 0xFFFFFFFF) {   //  device Present
2663                                 // Setup slot structure.
2664                                 new_slot = cpqhp_slot_create(hold_bus_node->base);
2665
2666                                 if (new_slot == NULL) {
2667                                         // Out of memory
2668                                         rc = -ENOMEM;
2669                                         continue;
2670                                 }
2671
2672                                 new_slot->bus = hold_bus_node->base;
2673                                 new_slot->device = device;
2674                                 new_slot->function = 0;
2675                                 new_slot->is_a_board = 1;
2676                                 new_slot->status = 0;
2677
2678                                 rc = configure_new_device(ctrl, new_slot, 1, &temp_resources);
2679                                 dbg("configure_new_device rc=0x%x\n",rc);
2680                         }       // End of IF (device in slot?)
2681                 }               // End of FOR loop
2682
2683                 if (rc) {
2684                         cpqhp_destroy_resource_list(&temp_resources);
2685
2686                         return_resource(&(resources->bus_head), hold_bus_node);
2687                         return_resource(&(resources->io_head), hold_IO_node);
2688                         return_resource(&(resources->mem_head), hold_mem_node);
2689                         return_resource(&(resources->p_mem_head), hold_p_mem_node);
2690                         return(rc);
2691                 }
2692                 // save the interrupt routing information
2693                 if (resources->irqs) {
2694                         resources->irqs->interrupt[0] = irqs.interrupt[0];
2695                         resources->irqs->interrupt[1] = irqs.interrupt[1];
2696                         resources->irqs->interrupt[2] = irqs.interrupt[2];
2697                         resources->irqs->interrupt[3] = irqs.interrupt[3];
2698                         resources->irqs->valid_INT = irqs.valid_INT;
2699                 } else if (!behind_bridge) {
2700                         // We need to hook up the interrupts here
2701                         for (cloop = 0; cloop < 4; cloop++) {
2702                                 if (irqs.valid_INT & (0x01 << cloop)) {
2703                                         rc = cpqhp_set_irq(func->bus, func->device,
2704                                                            0x0A + cloop, irqs.interrupt[cloop]);
2705                                         if (rc) {
2706                                                 cpqhp_destroy_resource_list (&temp_resources);
2707
2708                                                 return_resource(&(resources-> bus_head), hold_bus_node);
2709                                                 return_resource(&(resources-> io_head), hold_IO_node);
2710                                                 return_resource(&(resources-> mem_head), hold_mem_node);
2711                                                 return_resource(&(resources-> p_mem_head), hold_p_mem_node);
2712                                                 return rc;
2713                                         }
2714                                 }
2715                         }       // end of for loop
2716                 }
2717                 // Return unused bus resources
2718                 // First use the temporary node to store information for the board
2719                 if (hold_bus_node && bus_node && temp_resources.bus_head) {
2720                         hold_bus_node->length = bus_node->base - hold_bus_node->base;
2721
2722                         hold_bus_node->next = func->bus_head;
2723                         func->bus_head = hold_bus_node;
2724
2725                         temp_byte = temp_resources.bus_head->base - 1;
2726
2727                         // set subordinate bus
2728                         rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBORDINATE_BUS, temp_byte);
2729
2730                         if (temp_resources.bus_head->length == 0) {
2731                                 kfree(temp_resources.bus_head);
2732                                 temp_resources.bus_head = NULL;
2733                         } else {
2734                                 return_resource(&(resources->bus_head), temp_resources.bus_head);
2735                         }
2736                 }
2737
2738                 // If we have IO space available and there is some left,
2739                 // return the unused portion
2740                 if (hold_IO_node && temp_resources.io_head) {
2741                         io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
2742                                                                &hold_IO_node, 0x1000);
2743
2744                         // Check if we were able to split something off
2745                         if (io_node) {
2746                                 hold_IO_node->base = io_node->base + io_node->length;
2747
2748                                 temp_byte = (hold_IO_node->base) >> 8;
2749                                 rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_BASE, temp_byte);
2750
2751                                 return_resource(&(resources->io_head), io_node);
2752                         }
2753
2754                         io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
2755
2756                         // Check if we were able to split something off
2757                         if (io_node) {
2758                                 // First use the temporary node to store information for the board
2759                                 hold_IO_node->length = io_node->base - hold_IO_node->base;
2760
2761                                 // If we used any, add it to the board's list
2762                                 if (hold_IO_node->length) {
2763                                         hold_IO_node->next = func->io_head;
2764                                         func->io_head = hold_IO_node;
2765
2766                                         temp_byte = (io_node->base - 1) >> 8;
2767                                         rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, temp_byte);
2768
2769                                         return_resource(&(resources->io_head), io_node);
2770                                 } else {
2771                                         // it doesn't need any IO
2772                                         temp_word = 0x0000;
2773                                         pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, temp_word);
2774
2775                                         return_resource(&(resources->io_head), io_node);
2776                                         kfree(hold_IO_node);
2777                                 }
2778                         } else {
2779                                 // it used most of the range
2780                                 hold_IO_node->next = func->io_head;
2781                                 func->io_head = hold_IO_node;
2782                         }
2783                 } else if (hold_IO_node) {
2784                         // it used the whole range
2785                         hold_IO_node->next = func->io_head;
2786                         func->io_head = hold_IO_node;
2787                 }
2788                 // If we have memory space available and there is some left,
2789                 // return the unused portion
2790                 if (hold_mem_node && temp_resources.mem_head) {
2791                         mem_node = do_pre_bridge_resource_split(&(temp_resources.  mem_head),
2792                                                                 &hold_mem_node, 0x100000);
2793
2794                         // Check if we were able to split something off
2795                         if (mem_node) {
2796                                 hold_mem_node->base = mem_node->base + mem_node->length;
2797
2798                                 temp_word = (hold_mem_node->base) >> 16;
2799                                 rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, temp_word);
2800
2801                                 return_resource(&(resources->mem_head), mem_node);
2802                         }
2803
2804                         mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000);
2805
2806                         // Check if we were able to split something off
2807                         if (mem_node) {
2808                                 // First use the temporary node to store information for the board
2809                                 hold_mem_node->length = mem_node->base - hold_mem_node->base;
2810
2811                                 if (hold_mem_node->length) {
2812                                         hold_mem_node->next = func->mem_head;
2813                                         func->mem_head = hold_mem_node;
2814
2815                                         // configure end address
2816                                         temp_word = (mem_node->base - 1) >> 16;
2817                                         rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word);
2818
2819                                         // Return unused resources to the pool
2820                                         return_resource(&(resources->mem_head), mem_node);
2821                                 } else {
2822                                         // it doesn't need any Mem
2823                                         temp_word = 0x0000;
2824                                         rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word);
2825
2826                                         return_resource(&(resources->mem_head), mem_node);
2827                                         kfree(hold_mem_node);
2828                                 }
2829                         } else {
2830                                 // it used most of the range
2831                                 hold_mem_node->next = func->mem_head;
2832                                 func->mem_head = hold_mem_node;
2833                         }
2834                 } else if (hold_mem_node) {
2835                         // it used the whole range
2836                         hold_mem_node->next = func->mem_head;
2837                         func->mem_head = hold_mem_node;
2838                 }
2839                 // If we have prefetchable memory space available and there is some 
2840                 // left at the end, return the unused portion
2841                 if (hold_p_mem_node && temp_resources.p_mem_head) {
2842                         p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
2843                                                                   &hold_p_mem_node, 0x100000);
2844
2845                         // Check if we were able to split something off
2846                         if (p_mem_node) {
2847                                 hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
2848
2849                                 temp_word = (hold_p_mem_node->base) >> 16;
2850                                 rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, temp_word);
2851
2852                                 return_resource(&(resources->p_mem_head), p_mem_node);
2853                         }
2854
2855                         p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000);
2856
2857                         // Check if we were able to split something off
2858                         if (p_mem_node) {
2859                                 // First use the temporary node to store information for the board
2860                                 hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
2861
2862                                 // If we used any, add it to the board's list
2863                                 if (hold_p_mem_node->length) {
2864                                         hold_p_mem_node->next = func->p_mem_head;
2865                                         func->p_mem_head = hold_p_mem_node;
2866
2867                                         temp_word = (p_mem_node->base - 1) >> 16;
2868                                         rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word);
2869
2870                                         return_resource(&(resources->p_mem_head), p_mem_node);
2871                                 } else {
2872                                         // it doesn't need any PMem
2873                                         temp_word = 0x0000;
2874                                         rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word);
2875
2876                                         return_resource(&(resources->p_mem_head), p_mem_node);
2877                                         kfree(hold_p_mem_node);
2878                                 }
2879                         } else {
2880                                 // it used the most of the range
2881                                 hold_p_mem_node->next = func->p_mem_head;
2882                                 func->p_mem_head = hold_p_mem_node;
2883                         }
2884                 } else if (hold_p_mem_node) {
2885                         // it used the whole range
2886                         hold_p_mem_node->next = func->p_mem_head;
2887                         func->p_mem_head = hold_p_mem_node;
2888                 }
2889                 // We should be configuring an IRQ and the bridge's base address
2890                 // registers if it needs them.  Although we have never seen such
2891                 // a device
2892
2893                 // enable card
2894                 command = 0x0157;       // = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |  PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR
2895                 rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_COMMAND, command);
2896
2897                 // set Bridge Control Register
2898                 command = 0x07;         // = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA
2899                 rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_BRIDGE_CONTROL, command);
2900         } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
2901                 // Standard device
2902                 rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0B, &class_code);
2903
2904                 if (class_code == PCI_BASE_CLASS_DISPLAY) {
2905                         // Display (video) adapter (not supported)
2906                         return(DEVICE_TYPE_NOT_SUPPORTED);
2907                 }
2908                 // Figure out IO and memory needs
2909                 for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
2910                         temp_register = 0xFFFFFFFF;
2911
2912                         dbg("CND: bus=%d, device=%d, func=%d, offset=%d\n", func->bus, func->device, func->function, cloop);
2913                         rc = pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register);
2914
2915                         rc = pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &temp_register);
2916                         dbg("CND: base = 0x%x\n", temp_register);
2917
2918                         if (temp_register) {      // If this register is implemented
2919                                 if ((temp_register & 0x03L) == 0x01) {
2920                                         // Map IO
2921
2922                                         // set base = amount of IO space
2923                                         base = temp_register & 0xFFFFFFFC;
2924                                         base = ~base + 1;
2925
2926                                         dbg("CND:      length = 0x%x\n", base);
2927                                         io_node = get_io_resource(&(resources->io_head), base);
2928                                         dbg("Got io_node start = %8.8x, length = %8.8x next (%p)\n",
2929                                             io_node->base, io_node->length, io_node->next);
2930                                         dbg("func (%p) io_head (%p)\n", func, func->io_head);
2931
2932                                         // allocate the resource to the board
2933                                         if (io_node) {
2934                                                 base = io_node->base;
2935
2936                                                 io_node->next = func->io_head;
2937                                                 func->io_head = io_node;
2938                                         } else
2939                                                 return -ENOMEM;
2940                                 } else if ((temp_register & 0x0BL) == 0x08) {
2941                                         // Map prefetchable memory
2942                                         base = temp_register & 0xFFFFFFF0;
2943                                         base = ~base + 1;
2944
2945                                         dbg("CND:      length = 0x%x\n", base);
2946                                         p_mem_node = get_resource(&(resources->p_mem_head), base);
2947
2948                                         // allocate the resource to the board
2949                                         if (p_mem_node) {
2950                                                 base = p_mem_node->base;
2951
2952                                                 p_mem_node->next = func->p_mem_head;
2953                                                 func->p_mem_head = p_mem_node;
2954                                         } else
2955                                                 return -ENOMEM;
2956                                 } else if ((temp_register & 0x0BL) == 0x00) {
2957                                         // Map memory
2958                                         base = temp_register & 0xFFFFFFF0;
2959                                         base = ~base + 1;
2960
2961                                         dbg("CND:      length = 0x%x\n", base);
2962                                         mem_node = get_resource(&(resources->mem_head), base);
2963
2964                                         // allocate the resource to the board
2965                                         if (mem_node) {
2966                                                 base = mem_node->base;
2967
2968                                                 mem_node->next = func->mem_head;
2969                                                 func->mem_head = mem_node;
2970                                         } else
2971                                                 return -ENOMEM;
2972                                 } else if ((temp_register & 0x0BL) == 0x04) {
2973                                         // Map memory
2974                                         base = temp_register & 0xFFFFFFF0;
2975                                         base = ~base + 1;
2976
2977                                         dbg("CND:      length = 0x%x\n", base);
2978                                         mem_node = get_resource(&(resources->mem_head), base);
2979
2980                                         // allocate the resource to the board
2981                                         if (mem_node) {
2982                                                 base = mem_node->base;
2983
2984                                                 mem_node->next = func->mem_head;
2985                                                 func->mem_head = mem_node;
2986                                         } else
2987                                                 return -ENOMEM;
2988                                 } else if ((temp_register & 0x0BL) == 0x06) {
2989                                         // Those bits are reserved, we can't handle this
2990                                         return(1);
2991                                 } else {
2992                                         // Requesting space below 1M
2993                                         return(NOT_ENOUGH_RESOURCES);
2994                                 }
2995
2996                                 rc = pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, base);
2997
2998                                 // Check for 64-bit base
2999                                 if ((temp_register & 0x07L) == 0x04) {
3000                                         cloop += 4;
3001
3002                                         // Upper 32 bits of address always zero on today's systems
3003                                         // FIXME this is probably not true on Alpha and ia64???
3004                                         base = 0;
3005                                         rc = pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, base);
3006                                 }
3007                         }
3008                 }               // End of base register loop
3009
3010                 // Figure out which interrupt pin this function uses
3011                 rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_INTERRUPT_PIN, &temp_byte);
3012
3013                 // If this function needs an interrupt and we are behind a bridge
3014                 // and the pin is tied to something that's alread mapped,
3015                 // set this one the same
3016                 if (temp_byte && resources->irqs && 
3017                     (resources->irqs->valid_INT & 
3018                      (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
3019                         // We have to share with something already set up
3020                         IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03];
3021                 } else {
3022                         // Program IRQ based on card type
3023                         rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0B, &class_code);
3024
3025                         if (class_code == PCI_BASE_CLASS_STORAGE) {
3026                                 IRQ = cpqhp_disk_irq;
3027                         } else {
3028                                 IRQ = cpqhp_nic_irq;
3029                         }
3030                 }
3031
3032                 // IRQ Line
3033                 rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_INTERRUPT_LINE, IRQ);
3034
3035                 if (!behind_bridge) {
3036                         rc = cpqhp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ);
3037                         if (rc)
3038                                 return(1);
3039                 } else {
3040                         //TBD - this code may also belong in the other clause of this If statement
3041                         resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03] = IRQ;
3042                         resources->irqs->valid_INT |= 0x01 << (temp_byte + resources->irqs->barber_pole - 1) & 0x03;
3043                 }
3044
3045                 // Latency Timer
3046                 temp_byte = 0x40;
3047                 rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_LATENCY_TIMER, temp_byte);
3048
3049                 // Cache Line size
3050                 temp_byte = 0x08;
3051                 rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_CACHE_LINE_SIZE, temp_byte);
3052
3053                 // disable ROM base Address
3054                 temp_dword = 0x00L;
3055                 rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_ROM_ADDRESS, temp_dword);
3056
3057                 // enable card
3058                 temp_word = 0x0157;     // = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |  PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR
3059                 rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_COMMAND, temp_word);
3060         }                       // End of Not-A-Bridge else
3061         else {
3062                 // It's some strange type of PCI adapter (Cardbus?)
3063                 return(DEVICE_TYPE_NOT_SUPPORTED);
3064         }
3065
3066         func->configured = 1;
3067
3068         return 0;
3069 }
3070