OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [hotplug/] [cpqphp_ctrl.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
        unlock_kernel();
1731
 
1732
        while (1) {
1733
                dbg("!!!!event_thread sleeping\n");
1734
                down_interruptible (&event_semaphore);
1735
                dbg("event_thread woken finished = %d\n", event_finished);
1736
                if (event_finished) break;
1737
                /* Do stuff here */
1738
                if (pushbutton_pending)
1739
                        cpqhp_pushbutton_thread(pushbutton_pending);
1740
                else
1741
                        for (ctrl = cpqhp_ctrl_list; ctrl; ctrl=ctrl->next)
1742
                                interrupt_event_handler(ctrl);
1743
        }
1744
        dbg("event_thread signals exit\n");
1745
        up(&event_exit);
1746
        return 0;
1747
}
1748
 
1749
 
1750
int cpqhp_event_start_thread (void)
1751
{
1752
        int pid;
1753
 
1754
        /* initialize our semaphores */
1755
        init_MUTEX(&delay_sem);
1756
        init_MUTEX_LOCKED(&event_semaphore);
1757
        init_MUTEX_LOCKED(&event_exit);
1758
        event_finished=0;
1759
 
1760
        pid = kernel_thread(event_thread, 0, 0);
1761
        if (pid < 0) {
1762
                err ("Can't start up our event thread\n");
1763
                return -1;
1764
        }
1765
        dbg("Our event thread pid = %d\n", pid);
1766
        return 0;
1767
}
1768
 
1769
 
1770
void cpqhp_event_stop_thread (void)
1771
{
1772
        event_finished = 1;
1773
        dbg("event_thread finish command given\n");
1774
        up(&event_semaphore);
1775
        dbg("wait for event_thread to exit\n");
1776
        down(&event_exit);
1777
}
1778
 
1779
 
1780
static int update_slot_info (struct controller *ctrl, struct slot *slot)
1781
{
1782
        struct hotplug_slot_info *info;
1783
        char buffer[SLOT_NAME_SIZE];
1784
        int result;
1785
 
1786
        info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
1787
        if (!info)
1788
                return -ENOMEM;
1789
 
1790
        make_slot_name (&buffer[0], SLOT_NAME_SIZE, slot);
1791
        info->power_status = get_slot_enabled(ctrl, slot);
1792
        info->attention_status = cpq_get_attention_status(ctrl, slot);
1793
        info->latch_status = cpq_get_latch_status(ctrl, slot);
1794
        info->adapter_status = get_presence_status(ctrl, slot);
1795
        result = pci_hp_change_slot_info(buffer, info);
1796
        kfree (info);
1797
        return result;
1798
}
1799
 
1800
static void interrupt_event_handler(struct controller *ctrl)
1801
{
1802
        int loop = 0;
1803
        int change = 1;
1804
        struct pci_func *func;
1805
        u8 hp_slot;
1806
        struct slot *p_slot;
1807
 
1808
        while (change) {
1809
                change = 0;
1810
 
1811
                for (loop = 0; loop < 10; loop++) {
1812
                        //dbg("loop %d\n", loop);
1813
                        if (ctrl->event_queue[loop].event_type != 0) {
1814
                                hp_slot = ctrl->event_queue[loop].hp_slot;
1815
 
1816
                                func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0);
1817
 
1818
                                p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1819
 
1820
                                dbg("hp_slot %d, func %p, p_slot %p\n",
1821
                                    hp_slot, func, p_slot);
1822
 
1823
                                if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) {
1824
                                        dbg("button pressed\n");
1825
                                } else if (ctrl->event_queue[loop].event_type ==
1826
                                           INT_BUTTON_CANCEL) {
1827
                                        dbg("button cancel\n");
1828
                                        del_timer(&p_slot->task_event);
1829
 
1830
                                        // Wait for exclusive access to hardware
1831
                                        down(&ctrl->crit_sect);
1832
 
1833
                                        if (p_slot->state == BLINKINGOFF_STATE) {
1834
                                                // slot is on
1835
                                                // turn on green LED
1836
                                                dbg("turn on green LED\n");
1837
                                                green_LED_on (ctrl, hp_slot);
1838
                                        } else if (p_slot->state == BLINKINGON_STATE) {
1839
                                                // slot is off
1840
                                                // turn off green LED
1841
                                                dbg("turn off green LED\n");
1842
                                                green_LED_off (ctrl, hp_slot);
1843
                                        }
1844
 
1845
                                        info(msg_button_cancel, p_slot->number);
1846
 
1847
                                        p_slot->state = STATIC_STATE;
1848
 
1849
                                        amber_LED_off (ctrl, hp_slot);
1850
 
1851
                                        set_SOGO(ctrl);
1852
 
1853
                                        // Wait for SOBS to be unset
1854
                                        wait_for_ctrl_irq (ctrl);
1855
 
1856
                                        // Done with exclusive hardware access
1857
                                        up(&ctrl->crit_sect);
1858
                                }
1859
                                // ***********button Released (No action on press...)
1860
                                else if (ctrl->event_queue[loop].event_type == INT_BUTTON_RELEASE) {
1861
                                        dbg("button release\n");
1862
 
1863
                                        if (is_slot_enabled (ctrl, hp_slot)) {
1864
                                                // slot is on
1865
                                                dbg("slot is on\n");
1866
                                                p_slot->state = BLINKINGOFF_STATE;
1867
                                                info(msg_button_off, p_slot->number);
1868
                                        } else {
1869
                                                // slot is off
1870
                                                dbg("slot is off\n");
1871
                                                p_slot->state = BLINKINGON_STATE;
1872
                                                info(msg_button_on, p_slot->number);
1873
                                        }
1874
                                        // Wait for exclusive access to hardware
1875
                                        down(&ctrl->crit_sect);
1876
 
1877
                                        dbg("blink green LED and turn off amber\n");
1878
                                        amber_LED_off (ctrl, hp_slot);
1879
                                        green_LED_blink (ctrl, hp_slot);
1880
 
1881
                                        set_SOGO(ctrl);
1882
 
1883
                                        // Wait for SOBS to be unset
1884
                                        wait_for_ctrl_irq (ctrl);
1885
 
1886
                                        // Done with exclusive hardware access
1887
                                        up(&ctrl->crit_sect);
1888
                                        init_timer(&p_slot->task_event);
1889
                                        p_slot->hp_slot = hp_slot;
1890
                                        p_slot->ctrl = ctrl;
1891
//                                      p_slot->physical_slot = physical_slot;
1892
                                        p_slot->task_event.expires = jiffies + 5 * HZ;   // 5 second delay
1893
                                        p_slot->task_event.function = pushbutton_helper_thread;
1894
                                        p_slot->task_event.data = (u32) p_slot;
1895
 
1896
                                        dbg("add_timer p_slot = %p\n", p_slot);
1897
                                        add_timer(&p_slot->task_event);
1898
                                }
1899
                                // ***********POWER FAULT
1900
                                else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
1901
                                        dbg("power fault\n");
1902
                                } else {
1903
                                        /* refresh notification */
1904
                                        if (p_slot)
1905
                                                update_slot_info(ctrl, p_slot);
1906
                                }
1907
 
1908
                                ctrl->event_queue[loop].event_type = 0;
1909
 
1910
                                change = 1;
1911
                        }
1912
                }               // End of FOR loop
1913
        }
1914
 
1915
        return;
1916
}
1917
 
1918
 
1919
/**
1920
 * cpqhp_pushbutton_thread
1921
 *
1922
 * Scheduled procedure to handle blocking stuff for the pushbuttons
1923
 * Handles all pending events and exits.
1924
 *
1925
 */
1926
void cpqhp_pushbutton_thread (unsigned long slot)
1927
{
1928
        u8 hp_slot;
1929
        u8 device;
1930
        struct pci_func *func;
1931
        struct slot *p_slot = (struct slot *) slot;
1932
        struct controller *ctrl = (struct controller *) p_slot->ctrl;
1933
 
1934
        pushbutton_pending = 0;
1935
        hp_slot = p_slot->hp_slot;
1936
 
1937
        device = p_slot->device;
1938
 
1939
        if (is_slot_enabled (ctrl, hp_slot)) {
1940
                p_slot->state = POWEROFF_STATE;
1941
                // power Down board
1942
                func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
1943
                dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl);
1944
                if (!func) {
1945
                        dbg("Error! func NULL in %s\n", __FUNCTION__);
1946
                        return ;
1947
                }
1948
 
1949
                if (func != NULL && ctrl != NULL) {
1950
                        if (cpqhp_process_SS(ctrl, func) != 0) {
1951
                                amber_LED_on (ctrl, hp_slot);
1952
                                green_LED_on (ctrl, hp_slot);
1953
 
1954
                                set_SOGO(ctrl);
1955
 
1956
                                // Wait for SOBS to be unset
1957
                                wait_for_ctrl_irq (ctrl);
1958
                        }
1959
                }
1960
 
1961
                p_slot->state = STATIC_STATE;
1962
        } else {
1963
                p_slot->state = POWERON_STATE;
1964
                // slot is off
1965
 
1966
                func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
1967
                dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl);
1968
                if (!func) {
1969
                        dbg("Error! func NULL in %s\n", __FUNCTION__);
1970
                        return ;
1971
                }
1972
 
1973
                if (func != NULL && ctrl != NULL) {
1974
                        if (cpqhp_process_SI(ctrl, func) != 0) {
1975
                                amber_LED_on (ctrl, hp_slot);
1976
                                green_LED_off (ctrl, hp_slot);
1977
 
1978
                                set_SOGO(ctrl);
1979
 
1980
                                // Wait for SOBS to be unset
1981
                                wait_for_ctrl_irq (ctrl);
1982
                        }
1983
                }
1984
 
1985
                p_slot->state = STATIC_STATE;
1986
        }
1987
 
1988
        return;
1989
}
1990
 
1991
 
1992
int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func)
1993
{
1994
        u8 device, hp_slot;
1995
        u16 temp_word;
1996
        u32 tempdword;
1997
        int rc;
1998
        struct slot* p_slot;
1999
        int physical_slot = 0;
2000
 
2001
        if (!ctrl)
2002
                return(1);
2003
 
2004
        tempdword = 0;
2005
 
2006
        device = func->device;
2007
        hp_slot = device - ctrl->slot_device_offset;
2008
        p_slot = cpqhp_find_slot(ctrl, device);
2009
        if (p_slot) {
2010
                physical_slot = p_slot->number;
2011
        }
2012
 
2013
        // Check to see if the interlock is closed
2014
        tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
2015
 
2016
        if (tempdword & (0x01 << hp_slot)) {
2017
                return(1);
2018
        }
2019
 
2020
        if (func->is_a_board) {
2021
                rc = board_replaced(func, ctrl);
2022
        } else {
2023
                // add board
2024
                slot_remove(func);
2025
 
2026
                func = cpqhp_slot_create(ctrl->bus);
2027
                if (func == NULL) {
2028
                        return(1);
2029
                }
2030
 
2031
                func->bus = ctrl->bus;
2032
                func->device = device;
2033
                func->function = 0;
2034
                func->configured = 0;
2035
                func->is_a_board = 1;
2036
 
2037
                // We have to save the presence info for these slots
2038
                temp_word = ctrl->ctrl_int_comp >> 16;
2039
                func->presence_save = (temp_word >> hp_slot) & 0x01;
2040
                func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02;
2041
 
2042
                if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
2043
                        func->switch_save = 0;
2044
                } else {
2045
                        func->switch_save = 0x10;
2046
                }
2047
 
2048
                rc = board_added(func, ctrl);
2049
                if (rc) {
2050
                        if (is_bridge(func)) {
2051
                                bridge_slot_remove(func);
2052
                        } else
2053
                                slot_remove(func);
2054
 
2055
                        // Setup slot structure with entry for empty slot
2056
                        func = cpqhp_slot_create(ctrl->bus);
2057
 
2058
                        if (func == NULL) {
2059
                                // Out of memory
2060
                                return(1);
2061
                        }
2062
 
2063
                        func->bus = ctrl->bus;
2064
                        func->device = device;
2065
                        func->function = 0;
2066
                        func->configured = 0;
2067
                        func->is_a_board = 0;
2068
 
2069
                        // We have to save the presence info for these slots
2070
                        temp_word = ctrl->ctrl_int_comp >> 16;
2071
                        func->presence_save = (temp_word >> hp_slot) & 0x01;
2072
                        func->presence_save |=
2073
                        (temp_word >> (hp_slot + 7)) & 0x02;
2074
 
2075
                        if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) {
2076
                                func->switch_save = 0;
2077
                        } else {
2078
                                func->switch_save = 0x10;
2079
                        }
2080
                }
2081
        }
2082
 
2083
        if (rc) {
2084
                dbg("%s: rc = %d\n", __FUNCTION__, rc);
2085
        }
2086
 
2087
        if (p_slot)
2088
                update_slot_info(ctrl, p_slot);
2089
 
2090
        return rc;
2091
}
2092
 
2093
 
2094
int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
2095
{
2096
        u8 device, class_code, header_type, BCR;
2097
        u8 index = 0;
2098
        u8 replace_flag;
2099
        u32 rc = 0;
2100
        struct slot* p_slot;
2101
        int physical_slot=0;
2102
 
2103
        device = func->device;
2104
        func = cpqhp_slot_find(ctrl->bus, device, index++);
2105
        p_slot = cpqhp_find_slot(ctrl, device);
2106
        if (p_slot) {
2107
                physical_slot = p_slot->number;
2108
        }
2109
 
2110
        // Make sure there are no video controllers here
2111
        while (func && !rc) {
2112
                // Check the Class Code
2113
                rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0B, &class_code);
2114
                if (rc)
2115
                        return rc;
2116
 
2117
                if (class_code == PCI_BASE_CLASS_DISPLAY) {
2118
                        /* Display/Video adapter (not supported) */
2119
                        rc = REMOVE_NOT_SUPPORTED;
2120
                } else {
2121
                        // See if it's a bridge
2122
                        rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type);
2123
                        if (rc)
2124
                                return rc;
2125
 
2126
                        // If it's a bridge, check the VGA Enable bit
2127
                        if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
2128
                                rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_BRIDGE_CONTROL, &BCR);
2129
                                if (rc)
2130
                                        return rc;
2131
 
2132
                                // If the VGA Enable bit is set, remove isn't supported
2133
                                if (BCR & PCI_BRIDGE_CTL_VGA) {
2134
                                        rc = REMOVE_NOT_SUPPORTED;
2135
                                }
2136
                        }
2137
                }
2138
 
2139
                func = cpqhp_slot_find(ctrl->bus, device, index++);
2140
        }
2141
 
2142
        func = cpqhp_slot_find(ctrl->bus, device, 0);
2143
        if ((func != NULL) && !rc) {
2144
                //FIXME: Replace flag should be passed into process_SS
2145
                replace_flag = !(ctrl->add_support);
2146
                rc = remove_board(func, replace_flag, ctrl);
2147
        } else if (!rc) {
2148
                rc = 1;
2149
        }
2150
 
2151
        if (p_slot)
2152
                update_slot_info(ctrl, p_slot);
2153
 
2154
        return(rc);
2155
}
2156
 
2157
 
2158
 
2159
/**
2160
 * hardware_test - runs hardware tests
2161
 *
2162
 * For hot plug ctrl folks to play with.
2163
 * test_num is the number entered in the GUI
2164
 *
2165
 */
2166
int cpqhp_hardware_test(struct controller *ctrl, int test_num)
2167
{
2168
        u32 save_LED;
2169
        u32 work_LED;
2170
        int loop;
2171
        int num_of_slots;
2172
 
2173
        num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f;
2174
 
2175
        switch (test_num) {
2176
                case 1:
2177
                        // Do stuff here!
2178
 
2179
                        // Do that funky LED thing
2180
                        save_LED = readl(ctrl->hpc_reg + LED_CONTROL);  // so we can restore them later
2181
                        work_LED = 0x01010101;
2182
                        writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2183
                        for (loop = 0; loop < num_of_slots; loop++) {
2184
                                set_SOGO(ctrl);
2185
 
2186
                                // Wait for SOGO interrupt
2187
                                wait_for_ctrl_irq (ctrl);
2188
 
2189
                                // Get ready for next iteration
2190
                                work_LED = work_LED << 1;
2191
                                writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2192
                                long_delay((2*HZ)/10);
2193
                        }
2194
                        for (loop = 0; loop < num_of_slots; loop++) {
2195
                                work_LED = work_LED >> 1;
2196
                                writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2197
 
2198
                                set_SOGO(ctrl);
2199
 
2200
                                // Wait for SOGO interrupt
2201
                                wait_for_ctrl_irq (ctrl);
2202
 
2203
                                // Get ready for next iteration
2204
                                long_delay((2*HZ)/10);
2205
                        }
2206
                        for (loop = 0; loop < num_of_slots; loop++) {
2207
                                work_LED = work_LED << 1;
2208
                                writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2209
 
2210
                                set_SOGO(ctrl);
2211
 
2212
                                // Wait for SOGO interrupt
2213
                                wait_for_ctrl_irq (ctrl);
2214
 
2215
                                // Get ready for next iteration
2216
                                long_delay((2*HZ)/10);
2217
                        }
2218
                        for (loop = 0; loop < num_of_slots; loop++) {
2219
                                work_LED = work_LED >> 1;
2220
                                writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2221
 
2222
                                set_SOGO(ctrl);
2223
 
2224
                                // Wait for SOGO interrupt
2225
                                wait_for_ctrl_irq (ctrl);
2226
 
2227
                                // Get ready for next iteration
2228
                                long_delay((2*HZ)/10);
2229
                        }
2230
 
2231
                        work_LED = 0x01010000;
2232
                        writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2233
                        for (loop = 0; loop < num_of_slots; loop++) {
2234
                                set_SOGO(ctrl);
2235
 
2236
                                // Wait for SOGO interrupt
2237
                                wait_for_ctrl_irq (ctrl);
2238
 
2239
                                // Get ready for next iteration
2240
                                work_LED = work_LED << 1;
2241
                                writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2242
                                long_delay((2*HZ)/10);
2243
                        }
2244
                        for (loop = 0; loop < num_of_slots; loop++) {
2245
                                work_LED = work_LED >> 1;
2246
                                writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2247
 
2248
                                set_SOGO(ctrl);
2249
 
2250
                                // Wait for SOGO interrupt
2251
                                wait_for_ctrl_irq (ctrl);
2252
 
2253
                                // Get ready for next iteration
2254
                                long_delay((2*HZ)/10);
2255
                        }
2256
                        work_LED = 0x00000101;
2257
                        writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2258
                        for (loop = 0; loop < num_of_slots; loop++) {
2259
                                work_LED = work_LED << 1;
2260
                                writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2261
 
2262
                                set_SOGO(ctrl);
2263
 
2264
                                // Wait for SOGO interrupt
2265
                                wait_for_ctrl_irq (ctrl);
2266
 
2267
                                // Get ready for next iteration
2268
                                long_delay((2*HZ)/10);
2269
                        }
2270
                        for (loop = 0; loop < num_of_slots; loop++) {
2271
                                work_LED = work_LED >> 1;
2272
                                writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2273
 
2274
                                set_SOGO(ctrl);
2275
 
2276
                                // Wait for SOGO interrupt
2277
                                wait_for_ctrl_irq (ctrl);
2278
 
2279
                                // Get ready for next iteration
2280
                                long_delay((2*HZ)/10);
2281
                        }
2282
 
2283
 
2284
                        work_LED = 0x01010000;
2285
                        writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2286
                        for (loop = 0; loop < num_of_slots; loop++) {
2287
                                set_SOGO(ctrl);
2288
 
2289
                                // Wait for SOGO interrupt
2290
                                wait_for_ctrl_irq (ctrl);
2291
 
2292
                                // Get ready for next iteration
2293
                                long_delay((3*HZ)/10);
2294
                                work_LED = work_LED >> 16;
2295
                                writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2296
 
2297
                                set_SOGO(ctrl);
2298
 
2299
                                // Wait for SOGO interrupt
2300
                                wait_for_ctrl_irq (ctrl);
2301
 
2302
                                // Get ready for next iteration
2303
                                long_delay((3*HZ)/10);
2304
                                work_LED = work_LED << 16;
2305
                                writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2306
                                work_LED = work_LED << 1;
2307
                                writel(work_LED, ctrl->hpc_reg + LED_CONTROL);
2308
                        }
2309
 
2310
                        writel (save_LED, ctrl->hpc_reg + LED_CONTROL); // put it back the way it was
2311
 
2312
                        set_SOGO(ctrl);
2313
 
2314
                        // Wait for SOBS to be unset
2315
                        wait_for_ctrl_irq (ctrl);
2316
                        break;
2317
                case 2:
2318
                        // Do other stuff here!
2319
                        break;
2320
                case 3:
2321
                        // and more...
2322
                        break;
2323
        }
2324
        return 0;
2325
}
2326
 
2327
 
2328
/**
2329
 * configure_new_device - Configures the PCI header information of one board.
2330
 *
2331
 * @ctrl: pointer to controller structure
2332
 * @func: pointer to function structure
2333
 * @behind_bridge: 1 if this is a recursive call, 0 if not
2334
 * @resources: pointer to set of resource lists
2335
 *
2336
 * Returns 0 if success
2337
 *
2338
 */
2339
static u32 configure_new_device (struct controller * ctrl, struct pci_func * func,
2340
                                 u8 behind_bridge, struct resource_lists * resources)
2341
{
2342
        u8 temp_byte, function, max_functions, stop_it;
2343
        int rc;
2344
        u32 ID;
2345
        struct pci_func *new_slot;
2346
        int index;
2347
 
2348
        new_slot = func;
2349
 
2350
        dbg("%s\n", __FUNCTION__);
2351
        // Check for Multi-function device
2352
        rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0E, &temp_byte);
2353
        if (rc) {
2354
                dbg("%s: rc = %d\n", __FUNCTION__, rc);
2355
                return rc;
2356
        }
2357
 
2358
        if (temp_byte & 0x80)   // Multi-function device
2359
                max_functions = 8;
2360
        else
2361
                max_functions = 1;
2362
 
2363
        function = 0;
2364
 
2365
        do {
2366
                rc = configure_new_function(ctrl, new_slot, behind_bridge, resources);
2367
 
2368
                if (rc) {
2369
                        dbg("configure_new_function failed %d\n",rc);
2370
                        index = 0;
2371
 
2372
                        while (new_slot) {
2373
                                new_slot = cpqhp_slot_find(new_slot->bus, new_slot->device, index++);
2374
 
2375
                                if (new_slot)
2376
                                        cpqhp_return_board_resources(new_slot, resources);
2377
                        }
2378
 
2379
                        return(rc);
2380
                }
2381
 
2382
                function++;
2383
 
2384
                stop_it = 0;
2385
 
2386
                //  The following loop skips to the next present function
2387
                //  and creates a board structure
2388
 
2389
                while ((function < max_functions) && (!stop_it)) {
2390
                        pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, function, 0x00, &ID);
2391
 
2392
                        if (ID == 0xFFFFFFFF) {   // There's nothing there. 
2393
                                function++;
2394
                        } else {  // There's something there
2395
                                // Setup slot structure.
2396
                                new_slot = cpqhp_slot_create(func->bus);
2397
 
2398
                                if (new_slot == NULL) {
2399
                                        // Out of memory
2400
                                        return(1);
2401
                                }
2402
 
2403
                                new_slot->bus = func->bus;
2404
                                new_slot->device = func->device;
2405
                                new_slot->function = function;
2406
                                new_slot->is_a_board = 1;
2407
                                new_slot->status = 0;
2408
 
2409
                                stop_it++;
2410
                        }
2411
                }
2412
 
2413
        } while (function < max_functions);
2414
        dbg("returning from configure_new_device\n");
2415
 
2416
        return 0;
2417
}
2418
 
2419
 
2420
/*
2421
  Configuration logic that involves the hotplug data structures and
2422
  their bookkeeping
2423
 */
2424
 
2425
 
2426
/**
2427
 * configure_new_function - Configures the PCI header information of one device
2428
 *
2429
 * @ctrl: pointer to controller structure
2430
 * @func: pointer to function structure
2431
 * @behind_bridge: 1 if this is a recursive call, 0 if not
2432
 * @resources: pointer to set of resource lists
2433
 *
2434
 * Calls itself recursively for bridged devices.
2435
 * Returns 0 if success
2436
 *
2437
 */
2438
static int configure_new_function (struct controller * ctrl, struct pci_func * func,
2439
                                   u8 behind_bridge, struct resource_lists * resources)
2440
{
2441
        int cloop;
2442
        u8 IRQ;
2443
        u8 temp_byte;
2444
        u8 device;
2445
        u8 class_code;
2446
        u16 command;
2447
        u16 temp_word;
2448
        u32 temp_dword;
2449
        u32 rc;
2450
        u32 temp_register;
2451
        u32 base;
2452
        u32 ID;
2453
        struct pci_resource *mem_node;
2454
        struct pci_resource *p_mem_node;
2455
        struct pci_resource *io_node;
2456
        struct pci_resource *bus_node;
2457
        struct pci_resource *hold_mem_node;
2458
        struct pci_resource *hold_p_mem_node;
2459
        struct pci_resource *hold_IO_node;
2460
        struct pci_resource *hold_bus_node;
2461
        struct irq_mapping irqs;
2462
        struct pci_func *new_slot;
2463
        struct resource_lists temp_resources;
2464
 
2465
        // Check for Bridge
2466
        rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &temp_byte);
2467
        if (rc)
2468
                return rc;
2469
 
2470
        if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
2471
                // set Primary bus
2472
                dbg("set Primary bus = %d\n", func->bus);
2473
                rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PRIMARY_BUS, func->bus);
2474
                if (rc)
2475
                        return rc;
2476
 
2477
                // find range of busses to use
2478
                dbg("find ranges of buses to use\n");
2479
                bus_node = get_max_resource(&resources->bus_head, 1);
2480
 
2481
                // If we don't have any busses to allocate, we can't continue
2482
                if (!bus_node)
2483
                        return -ENOMEM;
2484
 
2485
                // set Secondary bus
2486
                temp_byte = bus_node->base;
2487
                dbg("set Secondary bus = %d\n", bus_node->base);
2488
                rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SECONDARY_BUS, temp_byte);
2489
                if (rc)
2490
                        return rc;
2491
 
2492
                // set subordinate bus
2493
                temp_byte = bus_node->base + bus_node->length - 1;
2494
                dbg("set subordinate bus = %d\n", bus_node->base + bus_node->length - 1);
2495
                rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBORDINATE_BUS, temp_byte);
2496
                if (rc)
2497
                        return rc;
2498
 
2499
                // set subordinate Latency Timer and base Latency Timer
2500
                temp_byte = 0x40;
2501
                rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SEC_LATENCY_TIMER, temp_byte);
2502
                if (rc)
2503
                        return rc;
2504
                rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_LATENCY_TIMER, temp_byte);
2505
                if (rc)
2506
                        return rc;
2507
 
2508
                // set Cache Line size
2509
                temp_byte = 0x08;
2510
                rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_CACHE_LINE_SIZE, temp_byte);
2511
                if (rc)
2512
                        return rc;
2513
 
2514
                // Setup the IO, memory, and prefetchable windows
2515
 
2516
                io_node = get_max_resource(&(resources->io_head), 0x1000);
2517
                mem_node = get_max_resource(&(resources->mem_head), 0x100000);
2518
                p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000);
2519
                dbg("Setup the IO, memory, and prefetchable windows\n");
2520
                dbg("io_node\n");
2521
                dbg("(base, len, next) (%x, %x, %p)\n", io_node->base, io_node->length, io_node->next);
2522
                dbg("mem_node\n");
2523
                dbg("(base, len, next) (%x, %x, %p)\n", mem_node->base, mem_node->length, mem_node->next);
2524
                dbg("p_mem_node\n");
2525
                dbg("(base, len, next) (%x, %x, %p)\n", p_mem_node->base, p_mem_node->length, p_mem_node->next);
2526
 
2527
                // set up the IRQ info
2528
                if (!resources->irqs) {
2529
                        irqs.barber_pole = 0;
2530
                        irqs.interrupt[0] = 0;
2531
                        irqs.interrupt[1] = 0;
2532
                        irqs.interrupt[2] = 0;
2533
                        irqs.interrupt[3] = 0;
2534
                        irqs.valid_INT = 0;
2535
                } else {
2536
                        irqs.barber_pole = resources->irqs->barber_pole;
2537
                        irqs.interrupt[0] = resources->irqs->interrupt[0];
2538
                        irqs.interrupt[1] = resources->irqs->interrupt[1];
2539
                        irqs.interrupt[2] = resources->irqs->interrupt[2];
2540
                        irqs.interrupt[3] = resources->irqs->interrupt[3];
2541
                        irqs.valid_INT = resources->irqs->valid_INT;
2542
                }
2543
 
2544
                // set up resource lists that are now aligned on top and bottom
2545
                // for anything behind the bridge.
2546
                temp_resources.bus_head = bus_node;
2547
                temp_resources.io_head = io_node;
2548
                temp_resources.mem_head = mem_node;
2549
                temp_resources.p_mem_head = p_mem_node;
2550
                temp_resources.irqs = &irqs;
2551
 
2552
                // Make copies of the nodes we are going to pass down so that
2553
                // if there is a problem,we can just use these to free resources
2554
                hold_bus_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2555
                hold_IO_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2556
                hold_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2557
                hold_p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2558
 
2559
                if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
2560
                        if (hold_bus_node)
2561
                                kfree(hold_bus_node);
2562
                        if (hold_IO_node)
2563
                                kfree(hold_IO_node);
2564
                        if (hold_mem_node)
2565
                                kfree(hold_mem_node);
2566
                        if (hold_p_mem_node)
2567
                                kfree(hold_p_mem_node);
2568
 
2569
                        return(1);
2570
                }
2571
 
2572
                memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
2573
 
2574
                bus_node->base += 1;
2575
                bus_node->length -= 1;
2576
                bus_node->next = NULL;
2577
 
2578
                // If we have IO resources copy them and fill in the bridge's
2579
                // IO range registers
2580
                if (io_node) {
2581
                        memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
2582
                        io_node->next = NULL;
2583
 
2584
                        // set IO base and Limit registers
2585
                        temp_byte = io_node->base >> 8;
2586
                        rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_BASE, temp_byte);
2587
 
2588
                        temp_byte = (io_node->base + io_node->length - 1) >> 8;
2589
                        rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, temp_byte);
2590
                } else {
2591
                        kfree(hold_IO_node);
2592
                        hold_IO_node = NULL;
2593
                }
2594
 
2595
                // If we have memory resources copy them and fill in the bridge's
2596
                // memory range registers.  Otherwise, fill in the range
2597
                // registers with values that disable them.
2598
                if (mem_node) {
2599
                        memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource));
2600
                        mem_node->next = NULL;
2601
 
2602
                        // set Mem base and Limit registers
2603
                        temp_word = mem_node->base >> 16;
2604
                        rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, temp_word);
2605
 
2606
                        temp_word = (mem_node->base + mem_node->length - 1) >> 16;
2607
                        rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word);
2608
                } else {
2609
                        temp_word = 0xFFFF;
2610
                        rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, temp_word);
2611
 
2612
                        temp_word = 0x0000;
2613
                        rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word);
2614
 
2615
                        kfree(hold_mem_node);
2616
                        hold_mem_node = NULL;
2617
                }
2618
 
2619
                // If we have prefetchable memory resources copy them and 
2620
                // fill in the bridge's memory range registers.  Otherwise,
2621
                // fill in the range registers with values that disable them.
2622
                if (p_mem_node) {
2623
                        memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));
2624
                        p_mem_node->next = NULL;
2625
 
2626
                        // set Pre Mem base and Limit registers
2627
                        temp_word = p_mem_node->base >> 16;
2628
                        rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, temp_word);
2629
 
2630
                        temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
2631
                        rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word);
2632
                } else {
2633
                        temp_word = 0xFFFF;
2634
                        rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, temp_word);
2635
 
2636
                        temp_word = 0x0000;
2637
                        rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word);
2638
 
2639
                        kfree(hold_p_mem_node);
2640
                        hold_p_mem_node = NULL;
2641
                }
2642
 
2643
                // Adjust this to compensate for extra adjustment in first loop
2644
                irqs.barber_pole--;
2645
 
2646
                rc = 0;
2647
 
2648
                // Here we actually find the devices and configure them
2649
                for (device = 0; (device <= 0x1F) && !rc; device++) {
2650
                        irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
2651
 
2652
                        ID = 0xFFFFFFFF;
2653
                        pci_read_config_dword_nodev (ctrl->pci_ops, hold_bus_node->base, device, 0, 0x00, &ID);
2654
 
2655
                        if (ID != 0xFFFFFFFF) {   //  device Present
2656
                                // Setup slot structure.
2657
                                new_slot = cpqhp_slot_create(hold_bus_node->base);
2658
 
2659
                                if (new_slot == NULL) {
2660
                                        // Out of memory
2661
                                        rc = -ENOMEM;
2662
                                        continue;
2663
                                }
2664
 
2665
                                new_slot->bus = hold_bus_node->base;
2666
                                new_slot->device = device;
2667
                                new_slot->function = 0;
2668
                                new_slot->is_a_board = 1;
2669
                                new_slot->status = 0;
2670
 
2671
                                rc = configure_new_device(ctrl, new_slot, 1, &temp_resources);
2672
                                dbg("configure_new_device rc=0x%x\n",rc);
2673
                        }       // End of IF (device in slot?)
2674
                }               // End of FOR loop
2675
 
2676
                if (rc) {
2677
                        cpqhp_destroy_resource_list(&temp_resources);
2678
 
2679
                        return_resource(&(resources->bus_head), hold_bus_node);
2680
                        return_resource(&(resources->io_head), hold_IO_node);
2681
                        return_resource(&(resources->mem_head), hold_mem_node);
2682
                        return_resource(&(resources->p_mem_head), hold_p_mem_node);
2683
                        return(rc);
2684
                }
2685
                // save the interrupt routing information
2686
                if (resources->irqs) {
2687
                        resources->irqs->interrupt[0] = irqs.interrupt[0];
2688
                        resources->irqs->interrupt[1] = irqs.interrupt[1];
2689
                        resources->irqs->interrupt[2] = irqs.interrupt[2];
2690
                        resources->irqs->interrupt[3] = irqs.interrupt[3];
2691
                        resources->irqs->valid_INT = irqs.valid_INT;
2692
                } else if (!behind_bridge) {
2693
                        // We need to hook up the interrupts here
2694
                        for (cloop = 0; cloop < 4; cloop++) {
2695
                                if (irqs.valid_INT & (0x01 << cloop)) {
2696
                                        rc = cpqhp_set_irq(func->bus, func->device,
2697
                                                           0x0A + cloop, irqs.interrupt[cloop]);
2698
                                        if (rc) {
2699
                                                cpqhp_destroy_resource_list (&temp_resources);
2700
 
2701
                                                return_resource(&(resources-> bus_head), hold_bus_node);
2702
                                                return_resource(&(resources-> io_head), hold_IO_node);
2703
                                                return_resource(&(resources-> mem_head), hold_mem_node);
2704
                                                return_resource(&(resources-> p_mem_head), hold_p_mem_node);
2705
                                                return rc;
2706
                                        }
2707
                                }
2708
                        }       // end of for loop
2709
                }
2710
                // Return unused bus resources
2711
                // First use the temporary node to store information for the board
2712
                if (hold_bus_node && bus_node && temp_resources.bus_head) {
2713
                        hold_bus_node->length = bus_node->base - hold_bus_node->base;
2714
 
2715
                        hold_bus_node->next = func->bus_head;
2716
                        func->bus_head = hold_bus_node;
2717
 
2718
                        temp_byte = temp_resources.bus_head->base - 1;
2719
 
2720
                        // set subordinate bus
2721
                        rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBORDINATE_BUS, temp_byte);
2722
 
2723
                        if (temp_resources.bus_head->length == 0) {
2724
                                kfree(temp_resources.bus_head);
2725
                                temp_resources.bus_head = NULL;
2726
                        } else {
2727
                                return_resource(&(resources->bus_head), temp_resources.bus_head);
2728
                        }
2729
                }
2730
 
2731
                // If we have IO space available and there is some left,
2732
                // return the unused portion
2733
                if (hold_IO_node && temp_resources.io_head) {
2734
                        io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
2735
                                                               &hold_IO_node, 0x1000);
2736
 
2737
                        // Check if we were able to split something off
2738
                        if (io_node) {
2739
                                hold_IO_node->base = io_node->base + io_node->length;
2740
 
2741
                                temp_byte = (hold_IO_node->base) >> 8;
2742
                                rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_BASE, temp_byte);
2743
 
2744
                                return_resource(&(resources->io_head), io_node);
2745
                        }
2746
 
2747
                        io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
2748
 
2749
                        // Check if we were able to split something off
2750
                        if (io_node) {
2751
                                // First use the temporary node to store information for the board
2752
                                hold_IO_node->length = io_node->base - hold_IO_node->base;
2753
 
2754
                                // If we used any, add it to the board's list
2755
                                if (hold_IO_node->length) {
2756
                                        hold_IO_node->next = func->io_head;
2757
                                        func->io_head = hold_IO_node;
2758
 
2759
                                        temp_byte = (io_node->base - 1) >> 8;
2760
                                        rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, temp_byte);
2761
 
2762
                                        return_resource(&(resources->io_head), io_node);
2763
                                } else {
2764
                                        // it doesn't need any IO
2765
                                        temp_word = 0x0000;
2766
                                        pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, temp_word);
2767
 
2768
                                        return_resource(&(resources->io_head), io_node);
2769
                                        kfree(hold_IO_node);
2770
                                }
2771
                        } else {
2772
                                // it used most of the range
2773
                                hold_IO_node->next = func->io_head;
2774
                                func->io_head = hold_IO_node;
2775
                        }
2776
                } else if (hold_IO_node) {
2777
                        // it used the whole range
2778
                        hold_IO_node->next = func->io_head;
2779
                        func->io_head = hold_IO_node;
2780
                }
2781
                // If we have memory space available and there is some left,
2782
                // return the unused portion
2783
                if (hold_mem_node && temp_resources.mem_head) {
2784
                        mem_node = do_pre_bridge_resource_split(&(temp_resources.  mem_head),
2785
                                                                &hold_mem_node, 0x100000);
2786
 
2787
                        // Check if we were able to split something off
2788
                        if (mem_node) {
2789
                                hold_mem_node->base = mem_node->base + mem_node->length;
2790
 
2791
                                temp_word = (hold_mem_node->base) >> 16;
2792
                                rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, temp_word);
2793
 
2794
                                return_resource(&(resources->mem_head), mem_node);
2795
                        }
2796
 
2797
                        mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000);
2798
 
2799
                        // Check if we were able to split something off
2800
                        if (mem_node) {
2801
                                // First use the temporary node to store information for the board
2802
                                hold_mem_node->length = mem_node->base - hold_mem_node->base;
2803
 
2804
                                if (hold_mem_node->length) {
2805
                                        hold_mem_node->next = func->mem_head;
2806
                                        func->mem_head = hold_mem_node;
2807
 
2808
                                        // configure end address
2809
                                        temp_word = (mem_node->base - 1) >> 16;
2810
                                        rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word);
2811
 
2812
                                        // Return unused resources to the pool
2813
                                        return_resource(&(resources->mem_head), mem_node);
2814
                                } else {
2815
                                        // it doesn't need any Mem
2816
                                        temp_word = 0x0000;
2817
                                        rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word);
2818
 
2819
                                        return_resource(&(resources->mem_head), mem_node);
2820
                                        kfree(hold_mem_node);
2821
                                }
2822
                        } else {
2823
                                // it used most of the range
2824
                                hold_mem_node->next = func->mem_head;
2825
                                func->mem_head = hold_mem_node;
2826
                        }
2827
                } else if (hold_mem_node) {
2828
                        // it used the whole range
2829
                        hold_mem_node->next = func->mem_head;
2830
                        func->mem_head = hold_mem_node;
2831
                }
2832
                // If we have prefetchable memory space available and there is some 
2833
                // left at the end, return the unused portion
2834
                if (hold_p_mem_node && temp_resources.p_mem_head) {
2835
                        p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
2836
                                                                  &hold_p_mem_node, 0x100000);
2837
 
2838
                        // Check if we were able to split something off
2839
                        if (p_mem_node) {
2840
                                hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
2841
 
2842
                                temp_word = (hold_p_mem_node->base) >> 16;
2843
                                rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, temp_word);
2844
 
2845
                                return_resource(&(resources->p_mem_head), p_mem_node);
2846
                        }
2847
 
2848
                        p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000);
2849
 
2850
                        // Check if we were able to split something off
2851
                        if (p_mem_node) {
2852
                                // First use the temporary node to store information for the board
2853
                                hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
2854
 
2855
                                // If we used any, add it to the board's list
2856
                                if (hold_p_mem_node->length) {
2857
                                        hold_p_mem_node->next = func->p_mem_head;
2858
                                        func->p_mem_head = hold_p_mem_node;
2859
 
2860
                                        temp_word = (p_mem_node->base - 1) >> 16;
2861
                                        rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word);
2862
 
2863
                                        return_resource(&(resources->p_mem_head), p_mem_node);
2864
                                } else {
2865
                                        // it doesn't need any PMem
2866
                                        temp_word = 0x0000;
2867
                                        rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word);
2868
 
2869
                                        return_resource(&(resources->p_mem_head), p_mem_node);
2870
                                        kfree(hold_p_mem_node);
2871
                                }
2872
                        } else {
2873
                                // it used the most of the range
2874
                                hold_p_mem_node->next = func->p_mem_head;
2875
                                func->p_mem_head = hold_p_mem_node;
2876
                        }
2877
                } else if (hold_p_mem_node) {
2878
                        // it used the whole range
2879
                        hold_p_mem_node->next = func->p_mem_head;
2880
                        func->p_mem_head = hold_p_mem_node;
2881
                }
2882
                // We should be configuring an IRQ and the bridge's base address
2883
                // registers if it needs them.  Although we have never seen such
2884
                // a device
2885
 
2886
                // enable card
2887
                command = 0x0157;       // = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |  PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR
2888
                rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_COMMAND, command);
2889
 
2890
                // set Bridge Control Register
2891
                command = 0x07;         // = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA
2892
                rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_BRIDGE_CONTROL, command);
2893
        } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
2894
                // Standard device
2895
                rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0B, &class_code);
2896
 
2897
                if (class_code == PCI_BASE_CLASS_DISPLAY) {
2898
                        // Display (video) adapter (not supported)
2899
                        return(DEVICE_TYPE_NOT_SUPPORTED);
2900
                }
2901
                // Figure out IO and memory needs
2902
                for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
2903
                        temp_register = 0xFFFFFFFF;
2904
 
2905
                        dbg("CND: bus=%d, device=%d, func=%d, offset=%d\n", func->bus, func->device, func->function, cloop);
2906
                        rc = pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register);
2907
 
2908
                        rc = pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &temp_register);
2909
                        dbg("CND: base = 0x%x\n", temp_register);
2910
 
2911
                        if (temp_register) {      // If this register is implemented
2912
                                if ((temp_register & 0x03L) == 0x01) {
2913
                                        // Map IO
2914
 
2915
                                        // set base = amount of IO space
2916
                                        base = temp_register & 0xFFFFFFFC;
2917
                                        base = ~base + 1;
2918
 
2919
                                        dbg("CND:      length = 0x%x\n", base);
2920
                                        io_node = get_io_resource(&(resources->io_head), base);
2921
                                        dbg("Got io_node start = %8.8x, length = %8.8x next (%p)\n",
2922
                                            io_node->base, io_node->length, io_node->next);
2923
                                        dbg("func (%p) io_head (%p)\n", func, func->io_head);
2924
 
2925
                                        // allocate the resource to the board
2926
                                        if (io_node) {
2927
                                                base = io_node->base;
2928
 
2929
                                                io_node->next = func->io_head;
2930
                                                func->io_head = io_node;
2931
                                        } else
2932
                                                return -ENOMEM;
2933
                                } else if ((temp_register & 0x0BL) == 0x08) {
2934
                                        // Map prefetchable memory
2935
                                        base = temp_register & 0xFFFFFFF0;
2936
                                        base = ~base + 1;
2937
 
2938
                                        dbg("CND:      length = 0x%x\n", base);
2939
                                        p_mem_node = get_resource(&(resources->p_mem_head), base);
2940
 
2941
                                        // allocate the resource to the board
2942
                                        if (p_mem_node) {
2943
                                                base = p_mem_node->base;
2944
 
2945
                                                p_mem_node->next = func->p_mem_head;
2946
                                                func->p_mem_head = p_mem_node;
2947
                                        } else
2948
                                                return -ENOMEM;
2949
                                } else if ((temp_register & 0x0BL) == 0x00) {
2950
                                        // Map memory
2951
                                        base = temp_register & 0xFFFFFFF0;
2952
                                        base = ~base + 1;
2953
 
2954
                                        dbg("CND:      length = 0x%x\n", base);
2955
                                        mem_node = get_resource(&(resources->mem_head), base);
2956
 
2957
                                        // allocate the resource to the board
2958
                                        if (mem_node) {
2959
                                                base = mem_node->base;
2960
 
2961
                                                mem_node->next = func->mem_head;
2962
                                                func->mem_head = mem_node;
2963
                                        } else
2964
                                                return -ENOMEM;
2965
                                } else if ((temp_register & 0x0BL) == 0x04) {
2966
                                        // Map memory
2967
                                        base = temp_register & 0xFFFFFFF0;
2968
                                        base = ~base + 1;
2969
 
2970
                                        dbg("CND:      length = 0x%x\n", base);
2971
                                        mem_node = get_resource(&(resources->mem_head), base);
2972
 
2973
                                        // allocate the resource to the board
2974
                                        if (mem_node) {
2975
                                                base = mem_node->base;
2976
 
2977
                                                mem_node->next = func->mem_head;
2978
                                                func->mem_head = mem_node;
2979
                                        } else
2980
                                                return -ENOMEM;
2981
                                } else if ((temp_register & 0x0BL) == 0x06) {
2982
                                        // Those bits are reserved, we can't handle this
2983
                                        return(1);
2984
                                } else {
2985
                                        // Requesting space below 1M
2986
                                        return(NOT_ENOUGH_RESOURCES);
2987
                                }
2988
 
2989
                                rc = pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, base);
2990
 
2991
                                // Check for 64-bit base
2992
                                if ((temp_register & 0x07L) == 0x04) {
2993
                                        cloop += 4;
2994
 
2995
                                        // Upper 32 bits of address always zero on today's systems
2996
                                        // FIXME this is probably not true on Alpha and ia64???
2997
                                        base = 0;
2998
                                        rc = pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, base);
2999
                                }
3000
                        }
3001
                }               // End of base register loop
3002
 
3003
                // Figure out which interrupt pin this function uses
3004
                rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_INTERRUPT_PIN, &temp_byte);
3005
 
3006
                // If this function needs an interrupt and we are behind a bridge
3007
                // and the pin is tied to something that's alread mapped,
3008
                // set this one the same
3009
                if (temp_byte && resources->irqs &&
3010
                    (resources->irqs->valid_INT &
3011
                     (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) {
3012
                        // We have to share with something already set up
3013
                        IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03];
3014
                } else {
3015
                        // Program IRQ based on card type
3016
                        rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0B, &class_code);
3017
 
3018
                        if (class_code == PCI_BASE_CLASS_STORAGE) {
3019
                                IRQ = cpqhp_disk_irq;
3020
                        } else {
3021
                                IRQ = cpqhp_nic_irq;
3022
                        }
3023
                }
3024
 
3025
                // IRQ Line
3026
                rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_INTERRUPT_LINE, IRQ);
3027
 
3028
                if (!behind_bridge) {
3029
                        rc = cpqhp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ);
3030
                        if (rc)
3031
                                return(1);
3032
                } else {
3033
                        //TBD - this code may also belong in the other clause of this If statement
3034
                        resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03] = IRQ;
3035
                        resources->irqs->valid_INT |= 0x01 << (temp_byte + resources->irqs->barber_pole - 1) & 0x03;
3036
                }
3037
 
3038
                // Latency Timer
3039
                temp_byte = 0x40;
3040
                rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_LATENCY_TIMER, temp_byte);
3041
 
3042
                // Cache Line size
3043
                temp_byte = 0x08;
3044
                rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_CACHE_LINE_SIZE, temp_byte);
3045
 
3046
                // disable ROM base Address
3047
                temp_dword = 0x00L;
3048
                rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_ROM_ADDRESS, temp_dword);
3049
 
3050
                // enable card
3051
                temp_word = 0x0157;     // = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |  PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR
3052
                rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_COMMAND, temp_word);
3053
        }                       // End of Not-A-Bridge else
3054
        else {
3055
                // It's some strange type of PCI adapter (Cardbus?)
3056
                return(DEVICE_TYPE_NOT_SUPPORTED);
3057
        }
3058
 
3059
        func->configured = 1;
3060
 
3061
        return 0;
3062
}
3063
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.