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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [hotplug/] [cpqphp_pci.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/proc_fs.h>
35
#include <linux/pci.h>
36
#include "cpqphp.h"
37
#include "cpqphp_nvram.h"
38
#include "../../arch/i386/kernel/pci-i386.h"    /* horrible hack showing how processor dependant we are... */
39
 
40
 
41
u8 cpqhp_nic_irq;
42
u8 cpqhp_disk_irq;
43
 
44
static u16 unused_IRQ;
45
 
46
 
47
static int is_pci_dev_in_use(struct pci_dev* dev)
48
{
49
        /*
50
         * dev->driver will be set if the device is in use by a new-style
51
         * driver -- otherwise, check the device's regions to see if any
52
         * driver has claimed them
53
         */
54
 
55
        int i, inuse=0;
56
 
57
        if (dev->driver) return 1; //assume driver feels responsible
58
 
59
        for (i = 0; !dev->driver && !inuse && (i < 6); i++) {
60
                if (!pci_resource_start(dev, i))
61
                        continue;
62
 
63
                if (pci_resource_flags(dev, i) & IORESOURCE_IO)
64
                        inuse = check_region(pci_resource_start(dev, i),
65
                                             pci_resource_len(dev, i));
66
                else if (pci_resource_flags(dev, i) & IORESOURCE_MEM)
67
                        inuse = check_mem_region(pci_resource_start(dev, i),
68
                                                 pci_resource_len(dev, i));
69
        }
70
 
71
        return inuse;
72
 
73
}
74
 
75
 
76
static int pci_hp_remove_device(struct pci_dev *dev)
77
{
78
        if (is_pci_dev_in_use(dev)) {
79
                err("***Cannot safely power down device -- "
80
                       "it appears to be in use***\n");
81
                return -EBUSY;
82
        }
83
        pci_remove_device(dev);
84
        return 0;
85
}
86
 
87
 
88
/*
89
 * detect_HRT_floating_pointer
90
 *
91
 * find the Hot Plug Resource Table in the specified region of memory.
92
 *
93
 */
94
static void *detect_HRT_floating_pointer(void *begin, void *end)
95
{
96
        void *fp;
97
        void *endp;
98
        u8 temp1, temp2, temp3, temp4;
99
        int status = 0;
100
 
101
        endp = (end - sizeof(struct hrt) + 1);
102
 
103
        for (fp = begin; fp <= endp; fp += 16) {
104
                temp1 = readb(fp + SIG0);
105
                temp2 = readb(fp + SIG1);
106
                temp3 = readb(fp + SIG2);
107
                temp4 = readb(fp + SIG3);
108
                if (temp1 == '$' &&
109
                    temp2 == 'H' &&
110
                    temp3 == 'R' &&
111
                    temp4 == 'T') {
112
                        status = 1;
113
                        break;
114
                }
115
        }
116
 
117
        if (!status)
118
                fp = NULL;
119
 
120
        dbg("Discovered Hotplug Resource Table at %p\n", fp);
121
        return fp;
122
}
123
 
124
static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
125
{
126
        struct pci_bus* bus = wrapped_bus->bus;
127
        struct pci_dev* dev = wrapped_dev->dev;
128
        struct pci_func *temp_func;
129
        int i=0;
130
 
131
        //We need to fix up the hotplug function representation with the linux representation
132
        do {
133
                temp_func = cpqhp_slot_find(dev->bus->number, dev->devfn >> 3, i++);
134
        } while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
135
 
136
        if (temp_func) {
137
                temp_func->pci_dev = dev;
138
        } else {
139
                //We did not even find a hotplug rep of the function, create it
140
                //This code might be taken out if we can guarantee the creation of functions
141
                //in parallel (hotplug and Linux at the same time).
142
                dbg("@@@@@@@@@@@ cpqhp_slot_create in %s\n", __FUNCTION__);
143
                temp_func = cpqhp_slot_create(bus->number);
144
                if (temp_func == NULL)
145
                        return -ENOMEM;
146
                temp_func->pci_dev = dev;
147
        }
148
 
149
        //Create /proc/bus/pci proc entry for this device and bus device is on
150
        //Notify the drivers of the change
151
        if (temp_func->pci_dev) {
152
                pci_proc_attach_device(temp_func->pci_dev);
153
                pci_announce_device_to_drivers(temp_func->pci_dev);
154
        }
155
 
156
        return 0;
157
}
158
 
159
 
160
static int unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
161
{
162
        struct pci_dev* dev = wrapped_dev->dev;
163
 
164
        struct pci_func *temp_func;
165
        int i=0;
166
 
167
        //We need to remove the hotplug function representation with the linux representation
168
        do {
169
                temp_func = cpqhp_slot_find(dev->bus->number, dev->devfn >> 3, i++);
170
                if (temp_func) {
171
                        dbg("temp_func->function = %d\n", temp_func->function);
172
                }
173
        } while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
174
 
175
        //Now, remove the Linux Representation
176
        if (dev) {
177
                if (pci_hp_remove_device(dev) == 0) {
178
                        kfree(dev); //Now, remove
179
                } else {
180
                        return -1; // problems while freeing, abort visitation
181
                }
182
        }
183
 
184
        if (temp_func) {
185
                temp_func->pci_dev = NULL;
186
        } else {
187
                dbg("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
188
        }
189
 
190
        return 0;
191
}
192
 
193
 
194
static int unconfigure_visit_pci_bus_phase2 (struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_dev)
195
{
196
        struct pci_bus* bus = wrapped_bus->bus;
197
 
198
        //The cleanup code for proc entries regarding buses should be in the kernel...
199
        if (bus->procdir)
200
                dbg("detach_pci_bus %s\n", bus->procdir->name);
201
        pci_proc_detach_bus(bus);
202
        // The cleanup code should live in the kernel...
203
        bus->self->subordinate = NULL;
204
        // unlink from parent bus
205
        list_del(&bus->node);
206
 
207
        // Now, remove
208
        if (bus)
209
                kfree(bus);
210
 
211
        return 0;
212
}
213
 
214
 
215
static int unconfigure_visit_pci_dev_phase1 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
216
{
217
        struct pci_dev* dev = wrapped_dev->dev;
218
 
219
        dbg("attempting removal of driver for device (%x, %x, %x)\n", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
220
        //Now, remove the Linux Driver Representation 
221
        if (dev->driver) {
222
                if (dev->driver->remove) {
223
                        dev->driver->remove(dev);
224
                        dbg("driver was properly removed\n");
225
                }
226
                dev->driver = NULL;
227
        }
228
 
229
        return is_pci_dev_in_use(dev);
230
}
231
 
232
 
233
static struct pci_visit configure_functions = {
234
        visit_pci_dev:          configure_visit_pci_dev,
235
};
236
 
237
 
238
static struct pci_visit unconfigure_functions_phase1 = {
239
        post_visit_pci_dev:     unconfigure_visit_pci_dev_phase1
240
};
241
 
242
static struct pci_visit unconfigure_functions_phase2 = {
243
        post_visit_pci_bus:     unconfigure_visit_pci_bus_phase2,
244
        post_visit_pci_dev:     unconfigure_visit_pci_dev_phase2
245
};
246
 
247
 
248
int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
249
{
250
        unsigned char bus;
251
        struct pci_dev dev0;
252
        struct pci_bus *child;
253
        struct pci_dev* temp;
254
        int rc = 0;
255
 
256
        struct pci_dev_wrapped wrapped_dev;
257
        struct pci_bus_wrapped wrapped_bus;
258
        memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
259
        memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
260
 
261
        memset(&dev0, 0, sizeof(struct pci_dev));
262
 
263
        if (func->pci_dev == NULL)
264
                func->pci_dev = pci_find_slot(func->bus, (func->device << 3) | (func->function & 0x7));
265
 
266
        //Still NULL ? Well then scan for it !
267
        if (func->pci_dev == NULL) {
268
                dbg("INFO: pci_dev still null\n");
269
                dev0.bus = ctrl->pci_dev->bus;
270
                dev0.devfn = (func->device << 3) + (func->function & 0x7);
271
                dev0.sysdata = ctrl->pci_dev->sysdata;
272
 
273
                //this will generate pci_dev structures for all functions, but we will only call this case when lookup fails
274
                func->pci_dev = pci_scan_slot(&dev0);
275
                if (func->pci_dev == NULL) {
276
                        dbg("ERROR: pci_dev still null\n");
277
                        return 0;
278
                }
279
        }
280
 
281
        if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
282
                pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
283
                child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
284
                pci_do_scan_bus(child);
285
 
286
        }
287
 
288
        temp = func->pci_dev;
289
 
290
        if (temp) {
291
                wrapped_dev.dev = temp;
292
                wrapped_bus.bus = temp->bus;
293
                rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
294
        }
295
        return rc;
296
}
297
 
298
 
299
int cpqhp_unconfigure_device(struct pci_func* func)
300
{
301
        int rc = 0;
302
        int j;
303
        struct pci_dev_wrapped wrapped_dev;
304
        struct pci_bus_wrapped wrapped_bus;
305
 
306
        memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
307
        memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
308
 
309
        dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, func->device, func->function);
310
 
311
        for (j=0; j<8 ; j++) {
312
                struct pci_dev* temp = pci_find_slot(func->bus, (func->device << 3) | j);
313
                if (temp) {
314
                        wrapped_dev.dev = temp;
315
                        wrapped_bus.bus = temp->bus;
316
                        rc = pci_visit_dev(&unconfigure_functions_phase1, &wrapped_dev, &wrapped_bus);
317
                        if (rc)
318
                                break;
319
 
320
                        rc = pci_visit_dev(&unconfigure_functions_phase2, &wrapped_dev, &wrapped_bus);
321
                        if (rc)
322
                                break;
323
                }
324
        }
325
        return rc;
326
}
327
 
328
static int PCI_RefinedAccessConfig(struct pci_ops *ops, u8 bus, u8 device, u8 function, u8 offset, u32 *value)
329
{
330
        u32 vendID = 0;
331
 
332
        if (pci_read_config_dword_nodev (ops, bus, device, function, PCI_VENDOR_ID, &vendID) == -1)
333
                return -1;
334
        if (vendID == 0xffffffff)
335
                return -1;
336
        return pci_read_config_dword_nodev (ops, bus, device, function, offset, value);
337
}
338
 
339
 
340
/*
341
 * cpqhp_set_irq
342
 *
343
 * @bus_num: bus number of PCI device
344
 * @dev_num: device number of PCI device
345
 * @slot: pointer to u8 where slot number will be returned
346
 */
347
int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
348
{
349
        int rc;
350
        u16 temp_word;
351
        struct pci_dev fakedev;
352
        struct pci_bus fakebus;
353
 
354
        fakedev.devfn = dev_num << 3;
355
        fakedev.bus = &fakebus;
356
        fakebus.number = bus_num;
357
        dbg("%s: dev %d, bus %d, pin %d, num %d\n",
358
            __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
359
        rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
360
        dbg("%s:rc %d\n", __FUNCTION__, rc);
361
        if (!rc)
362
                return !rc;
363
 
364
        // set the Edge Level Control Register (ELCR)
365
        temp_word = inb(0x4d0);
366
        temp_word |= inb(0x4d1) << 8;
367
 
368
        temp_word |= 0x01 << irq_num;
369
 
370
        // This should only be for x86 as it sets the Edge Level Control Register
371
        outb((u8) (temp_word & 0xFF), 0x4d0);
372
        outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
373
 
374
        return 0;
375
}
376
 
377
 
378
/*
379
 * WTF??? This function isn't in the code, yet a function calls it, but the
380
 * compiler optimizes it away?  strange.  Here as a placeholder to keep the
381
 * compiler happy.
382
 */
383
static int PCI_ScanBusNonBridge (u8 bus, u8 device)
384
{
385
        return 0;
386
}
387
 
388
static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev_num)
389
{
390
        u8 tdevice;
391
        u32 work;
392
        u8 tbus;
393
 
394
        for (tdevice = 0; tdevice < 0x100; tdevice++) {
395
                //Scan for access first
396
                if (PCI_RefinedAccessConfig(ctrl->pci_ops, bus_num, tdevice >> 3, tdevice & 0x7, 0x08, &work) == -1)
397
                        continue;
398
                dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
399
                //Yep we got one. Not a bridge ?
400
                if ((work >> 8) != PCI_TO_PCI_BRIDGE_CLASS) {
401
                        *dev_num = tdevice;
402
                        dbg("found it !\n");
403
                        return 0;
404
                }
405
        }
406
        for (tdevice = 0; tdevice < 0x100; tdevice++) {
407
                //Scan for access first
408
                if (PCI_RefinedAccessConfig(ctrl->pci_ops, bus_num, tdevice >> 3, tdevice & 0x7, 0x08, &work) == -1)
409
                        continue;
410
                dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
411
                //Yep we got one. bridge ?
412
                if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
413
                        pci_read_config_byte_nodev (ctrl->pci_ops, tbus, tdevice, 0, PCI_SECONDARY_BUS, &tbus);
414
                        dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice);
415
                        if (PCI_ScanBusNonBridge(tbus, tdevice) == 0)
416
                                return 0;
417
                }
418
        }
419
 
420
        return -1;
421
}
422
 
423
 
424
static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge)
425
{
426
        struct irq_routing_table *PCIIRQRoutingInfoLength;
427
        long len;
428
        long loop;
429
        u32 work;
430
 
431
        u8 tbus, tdevice, tslot;
432
 
433
        PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table();
434
 
435
        len = (PCIIRQRoutingInfoLength->size -
436
               sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
437
        // Make sure I got at least one entry
438
        if (len == 0) {
439
                if (PCIIRQRoutingInfoLength != NULL)
440
                        kfree(PCIIRQRoutingInfoLength );
441
                return -1;
442
        }
443
 
444
        for (loop = 0; loop < len; ++loop) {
445
                tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
446
                tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn;
447
                tslot = PCIIRQRoutingInfoLength->slots[loop].slot;
448
 
449
                if (tslot == slot) {
450
                        *bus_num = tbus;
451
                        *dev_num = tdevice;
452
                        pci_read_config_dword_nodev (ctrl->pci_ops, *bus_num, *dev_num >> 3, *dev_num & 0x7, PCI_VENDOR_ID, &work);
453
                        if (!nobridge || (work == 0xffffffff)) {
454
                                if (PCIIRQRoutingInfoLength != NULL)
455
                                        kfree(PCIIRQRoutingInfoLength );
456
                                return 0;
457
                        }
458
 
459
                        dbg("bus_num %d dev_num %d func_num %d\n", *bus_num, *dev_num >> 3, *dev_num & 0x7);
460
                        pci_read_config_dword_nodev (ctrl->pci_ops, *bus_num, *dev_num >> 3, *dev_num & 0x7, PCI_CLASS_REVISION, &work);
461
                        dbg("work >> 8 (%x) = BRIDGE (%x)\n", work >> 8, PCI_TO_PCI_BRIDGE_CLASS);
462
 
463
                        if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
464
                                pci_read_config_byte_nodev (ctrl->pci_ops, *bus_num, *dev_num >> 3, *dev_num & 0x7, PCI_SECONDARY_BUS, &tbus);
465
                                dbg("Scan bus for Non Bridge: bus %d\n", tbus);
466
                                if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
467
                                        *bus_num = tbus;
468
                                        if (PCIIRQRoutingInfoLength != NULL)
469
                                                kfree(PCIIRQRoutingInfoLength );
470
                                        return 0;
471
                                }
472
                        } else {
473
                                if (PCIIRQRoutingInfoLength != NULL)
474
                                        kfree(PCIIRQRoutingInfoLength );
475
                                return 0;
476
                        }
477
 
478
                }
479
        }
480
        if (PCIIRQRoutingInfoLength != NULL)
481
                kfree(PCIIRQRoutingInfoLength );
482
        return -1;
483
}
484
 
485
 
486
int cpqhp_get_bus_dev (struct controller *ctrl, u8 * bus_num, u8 * dev_num, u8 slot)
487
{
488
        return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0);     //plain (bridges allowed)
489
}
490
 
491
 
492
/* More PCI configuration routines; this time centered around hotplug controller */
493
 
494
 
495
/*
496
 * cpqhp_save_config
497
 *
498
 * Reads configuration for all slots in a PCI bus and saves info.
499
 *
500
 * Note:  For non-hot plug busses, the slot # saved is the device #
501
 *
502
 * returns 0 if success
503
 */
504
int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
505
{
506
        long rc;
507
        u8 class_code;
508
        u8 header_type;
509
        u32 ID;
510
        u8 secondary_bus;
511
        struct pci_func *new_slot;
512
        int sub_bus;
513
        int FirstSupported;
514
        int LastSupported;
515
        int max_functions;
516
        int function;
517
        u8 DevError;
518
        int device = 0;
519
        int cloop = 0;
520
        int stop_it;
521
        int index;
522
 
523
        //              Decide which slots are supported
524
 
525
        if (is_hot_plug) {
526
                //*********************************
527
                // is_hot_plug is the slot mask
528
                //*********************************
529
                FirstSupported = is_hot_plug >> 4;
530
                LastSupported = FirstSupported + (is_hot_plug & 0x0F) - 1;
531
        } else {
532
                FirstSupported = 0;
533
                LastSupported = 0x1F;
534
        }
535
 
536
        //     Save PCI configuration space for all devices in supported slots
537
 
538
        for (device = FirstSupported; device <= LastSupported; device++) {
539
                ID = 0xFFFFFFFF;
540
                rc = pci_read_config_dword_nodev (ctrl->pci_ops, busnumber, device, 0, PCI_VENDOR_ID, &ID);
541
 
542
                if (ID != 0xFFFFFFFF) {   //  device in slot
543
                        rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, 0, 0x0B, &class_code);
544
                        if (rc)
545
                                return rc;
546
 
547
                        rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, 0, PCI_HEADER_TYPE, &header_type);
548
                        if (rc)
549
                                return rc;
550
 
551
                        // If multi-function device, set max_functions to 8
552
                        if (header_type & 0x80)
553
                                max_functions = 8;
554
                        else
555
                                max_functions = 1;
556
 
557
                        function = 0;
558
 
559
                        do {
560
                                DevError = 0;
561
 
562
                                if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {   // P-P Bridge
563
                                        //  Recurse the subordinate bus
564
                                        //  get the subordinate bus number
565
                                        rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, function, PCI_SECONDARY_BUS, &secondary_bus);
566
                                        if (rc) {
567
                                                return rc;
568
                                        } else {
569
                                                sub_bus = (int) secondary_bus;
570
 
571
                                                // Save secondary bus cfg spc
572
                                                // with this recursive call.
573
                                                rc = cpqhp_save_config(ctrl, sub_bus, 0);
574
 
575
                                                if (rc)
576
                                                        return rc;
577
                                        }
578
                                }
579
 
580
                                index = 0;
581
                                new_slot = cpqhp_slot_find(busnumber, device, index++);
582
                                while (new_slot &&
583
                                       (new_slot->function != (u8) function))
584
                                        new_slot = cpqhp_slot_find(busnumber, device, index++);
585
 
586
                                if (!new_slot) {
587
                                        // Setup slot structure.
588
                                        new_slot = cpqhp_slot_create(busnumber);
589
 
590
                                        if (new_slot == NULL)
591
                                                return(1);
592
                                }
593
 
594
                                new_slot->bus = (u8) busnumber;
595
                                new_slot->device = (u8) device;
596
                                new_slot->function = (u8) function;
597
                                new_slot->is_a_board = 1;
598
                                new_slot->switch_save = 0x10;
599
                                // In case of unsupported board
600
                                new_slot->status = DevError;
601
                                new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
602
 
603
                                for (cloop = 0; cloop < 0x20; cloop++) {
604
                                        rc = pci_read_config_dword_nodev (ctrl->pci_ops, busnumber, device, function, cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
605
                                        if (rc)
606
                                                return rc;
607
                                }
608
 
609
                                function++;
610
 
611
                                stop_it = 0;
612
 
613
                                //  this loop skips to the next present function
614
                                //  reading in Class Code and Header type.
615
 
616
                                while ((function < max_functions)&&(!stop_it)) {
617
                                        rc = pci_read_config_dword_nodev (ctrl->pci_ops, busnumber, device, function, PCI_VENDOR_ID, &ID);
618
                                        if (ID == 0xFFFFFFFF) {  // nothing there.
619
                                                function++;
620
                                        } else {  // Something there
621
                                                rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, function, 0x0B, &class_code);
622
                                                if (rc)
623
                                                        return rc;
624
 
625
                                                rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, function, PCI_HEADER_TYPE, &header_type);
626
                                                if (rc)
627
                                                        return rc;
628
 
629
                                                stop_it++;
630
                                        }
631
                                }
632
 
633
                        } while (function < max_functions);
634
                }               // End of IF (device in slot?)
635
                else if (is_hot_plug) {
636
                        // Setup slot structure with entry for empty slot
637
                        new_slot = cpqhp_slot_create(busnumber);
638
 
639
                        if (new_slot == NULL) {
640
                                return(1);
641
                        }
642
 
643
                        new_slot->bus = (u8) busnumber;
644
                        new_slot->device = (u8) device;
645
                        new_slot->function = 0;
646
                        new_slot->is_a_board = 0;
647
                        new_slot->presence_save = 0;
648
                        new_slot->switch_save = 0;
649
                }
650
        }                       // End of FOR loop
651
 
652
        return(0);
653
}
654
 
655
 
656
/*
657
 * cpqhp_save_slot_config
658
 *
659
 * Saves configuration info for all PCI devices in a given slot
660
 * including subordinate busses.
661
 *
662
 * returns 0 if success
663
 */
664
int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
665
{
666
        long rc;
667
        u8 class_code;
668
        u8 header_type;
669
        u32 ID;
670
        u8 secondary_bus;
671
        int sub_bus;
672
        int max_functions;
673
        int function;
674
        int cloop = 0;
675
        int stop_it;
676
 
677
        ID = 0xFFFFFFFF;
678
 
679
        pci_read_config_dword_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, 0, PCI_VENDOR_ID, &ID);
680
 
681
        if (ID != 0xFFFFFFFF) {   //  device in slot
682
                pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, 0, 0x0B, &class_code);
683
 
684
                pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, 0, PCI_HEADER_TYPE, &header_type);
685
 
686
                if (header_type & 0x80) // Multi-function device
687
                        max_functions = 8;
688
                else
689
                        max_functions = 1;
690
 
691
                function = 0;
692
 
693
                do {
694
                        if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {     // PCI-PCI Bridge
695
                                //  Recurse the subordinate bus
696
                                pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, PCI_SECONDARY_BUS, &secondary_bus);
697
 
698
                                sub_bus = (int) secondary_bus;
699
 
700
                                // Save the config headers for the secondary bus.
701
                                rc = cpqhp_save_config(ctrl, sub_bus, 0);
702
 
703
                                if (rc)
704
                                        return(rc);
705
 
706
                        }       // End of IF
707
 
708
                        new_slot->status = 0;
709
 
710
                        for (cloop = 0; cloop < 0x20; cloop++) {
711
                                pci_read_config_dword_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
712
                        }
713
 
714
                        function++;
715
 
716
                        stop_it = 0;
717
 
718
                        //  this loop skips to the next present function
719
                        //  reading in the Class Code and the Header type.
720
 
721
                        while ((function < max_functions) && (!stop_it)) {
722
                                pci_read_config_dword_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, PCI_VENDOR_ID, &ID);
723
 
724
                                if (ID == 0xFFFFFFFF) {  // nothing there.
725
                                        function++;
726
                                } else {  // Something there
727
                                        pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, 0x0B, &class_code);
728
 
729
                                        pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, PCI_HEADER_TYPE, &header_type);
730
 
731
                                        stop_it++;
732
                                }
733
                        }
734
 
735
                } while (function < max_functions);
736
        }                       // End of IF (device in slot?)
737
        else {
738
                return(2);
739
        }
740
 
741
        return(0);
742
}
743
 
744
 
745
/*
746
 * cpqhp_save_base_addr_length
747
 *
748
 * Saves the length of all base address registers for the
749
 * specified slot.  this is for hot plug REPLACE
750
 *
751
 * returns 0 if success
752
 */
753
int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
754
{
755
        u8 cloop;
756
        u8 header_type;
757
        u8 secondary_bus;
758
        u8 type;
759
        int sub_bus;
760
        u32 temp_register;
761
        u32 base;
762
        u32 rc;
763
        struct pci_func *next;
764
        int index = 0;
765
 
766
        func = cpqhp_slot_find(func->bus, func->device, index++);
767
 
768
        while (func != NULL) {
769
 
770
                // Check for Bridge
771
                pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type);
772
 
773
                if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
774
                        // PCI-PCI Bridge
775
                        pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SECONDARY_BUS, &secondary_bus);
776
 
777
                        sub_bus = (int) secondary_bus;
778
 
779
                        next = cpqhp_slot_list[sub_bus];
780
 
781
                        while (next != NULL) {
782
                                rc = cpqhp_save_base_addr_length(ctrl, next);
783
 
784
                                if (rc)
785
                                        return(rc);
786
 
787
                                next = next->next;
788
                        }
789
 
790
                        //FIXME: this loop is duplicated in the non-bridge case.  The two could be rolled together
791
                        // Figure out IO and memory base lengths
792
                        for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
793
                                temp_register = 0xFFFFFFFF;
794
                                pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register);
795
                                pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
796
 
797
                                if (base) {  // If this register is implemented
798
                                        if (base & 0x01L) {
799
                                                // IO base
800
                                                // set base = amount of IO space requested
801
                                                base = base & 0xFFFFFFFE;
802
                                                base = (~base) + 1;
803
 
804
                                                type = 1;
805
                                        } else {
806
                                                // memory base
807
                                                base = base & 0xFFFFFFF0;
808
                                                base = (~base) + 1;
809
 
810
                                                type = 0;
811
                                        }
812
                                } else {
813
                                        base = 0x0L;
814
                                        type = 0;
815
                                }
816
 
817
                                // Save information in slot structure
818
                                func->base_length[(cloop - 0x10) >> 2] =
819
                                base;
820
                                func->base_type[(cloop - 0x10) >> 2] = type;
821
 
822
                        }       // End of base register loop
823
 
824
 
825
                } else if ((header_type & 0x7F) == 0x00) {        // PCI-PCI Bridge
826
                        // Figure out IO and memory base lengths
827
                        for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
828
                                temp_register = 0xFFFFFFFF;
829
                                pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register);
830
                                pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
831
 
832
                                if (base) {  // If this register is implemented
833
                                        if (base & 0x01L) {
834
                                                // IO base
835
                                                // base = amount of IO space requested
836
                                                base = base & 0xFFFFFFFE;
837
                                                base = (~base) + 1;
838
 
839
                                                type = 1;
840
                                        } else {
841
                                                // memory base
842
                                                // base = amount of memory space requested
843
                                                base = base & 0xFFFFFFF0;
844
                                                base = (~base) + 1;
845
 
846
                                                type = 0;
847
                                        }
848
                                } else {
849
                                        base = 0x0L;
850
                                        type = 0;
851
                                }
852
 
853
                                // Save information in slot structure
854
                                func->base_length[(cloop - 0x10) >> 2] = base;
855
                                func->base_type[(cloop - 0x10) >> 2] = type;
856
 
857
                        }       // End of base register loop
858
 
859
                } else {          // Some other unknown header type
860
                }
861
 
862
                // find the next device in this slot
863
                func = cpqhp_slot_find(func->bus, func->device, index++);
864
        }
865
 
866
        return(0);
867
}
868
 
869
 
870
/*
871
 * cpqhp_save_used_resources
872
 *
873
 * Stores used resource information for existing boards.  this is
874
 * for boards that were in the system when this driver was loaded.
875
 * this function is for hot plug ADD
876
 *
877
 * returns 0 if success
878
 */
879
int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
880
{
881
        u8 cloop;
882
        u8 header_type;
883
        u8 secondary_bus;
884
        u8 temp_byte;
885
        u8 b_base;
886
        u8 b_length;
887
        u16 command;
888
        u16 save_command;
889
        u16 w_base;
890
        u16 w_length;
891
        u32 temp_register;
892
        u32 save_base;
893
        u32 base;
894
        int index = 0;
895
        struct pci_resource *mem_node;
896
        struct pci_resource *p_mem_node;
897
        struct pci_resource *io_node;
898
        struct pci_resource *bus_node;
899
 
900
        func = cpqhp_slot_find(func->bus, func->device, index++);
901
 
902
        while ((func != NULL) && func->is_a_board) {
903
                // Save the command register
904
                pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_COMMAND, &save_command);
905
 
906
                // disable card
907
                command = 0x00;
908
                pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_COMMAND, command);
909
 
910
                // Check for Bridge
911
                pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type);
912
 
913
                if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {     // PCI-PCI Bridge
914
                        // Clear Bridge Control Register
915
                        command = 0x00;
916
                        pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_BRIDGE_CONTROL, command);
917
 
918
                        pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SECONDARY_BUS, &secondary_bus);
919
 
920
                        pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBORDINATE_BUS, &temp_byte);
921
 
922
                        bus_node =(struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
923
                        if (!bus_node)
924
                                return -ENOMEM;
925
 
926
                        bus_node->base = secondary_bus;
927
                        bus_node->length = temp_byte - secondary_bus + 1;
928
 
929
                        bus_node->next = func->bus_head;
930
                        func->bus_head = bus_node;
931
 
932
                        // Save IO base and Limit registers
933
                        pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_BASE, &b_base);
934
 
935
                        pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, &b_length);
936
 
937
                        if ((b_base <= b_length) && (save_command & 0x01)) {
938
                                io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
939
                                if (!io_node)
940
                                        return -ENOMEM;
941
 
942
                                io_node->base = (b_base & 0xF0) << 8;
943
                                io_node->length = (b_length - b_base + 0x10) << 8;
944
 
945
                                io_node->next = func->io_head;
946
                                func->io_head = io_node;
947
                        }
948
                        // Save memory base and Limit registers
949
                        pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, &w_base);
950
 
951
                        pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, &w_length);
952
 
953
                        if ((w_base <= w_length) && (save_command & 0x02)) {
954
                                mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
955
                                if (!mem_node)
956
                                        return -ENOMEM;
957
 
958
                                mem_node->base = w_base << 16;
959
                                mem_node->length = (w_length - w_base + 0x10) << 16;
960
 
961
                                mem_node->next = func->mem_head;
962
                                func->mem_head = mem_node;
963
                        }
964
                        // Save prefetchable memory base and Limit registers
965
                        pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, &w_base);
966
 
967
                        pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, &w_length);
968
 
969
                        if ((w_base <= w_length) && (save_command & 0x02)) {
970
                                p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
971
                                if (!p_mem_node)
972
                                        return -ENOMEM;
973
 
974
                                p_mem_node->base = w_base << 16;
975
                                p_mem_node->length = (w_length - w_base + 0x10) << 16;
976
 
977
                                p_mem_node->next = func->p_mem_head;
978
                                func->p_mem_head = p_mem_node;
979
                        }
980
                        // Figure out IO and memory base lengths
981
                        for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
982
                                pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &save_base);
983
 
984
                                temp_register = 0xFFFFFFFF;
985
                                pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register);
986
 
987
                                pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
988
 
989
                                temp_register = base;
990
 
991
                                if (base) {  // If this register is implemented
992
                                        if (((base & 0x03L) == 0x01)
993
                                            && (save_command & 0x01)) {
994
                                                // IO base
995
                                                // set temp_register = amount of IO space requested
996
                                                temp_register = base & 0xFFFFFFFE;
997
                                                temp_register = (~temp_register) + 1;
998
 
999
                                                io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
1000
                                                if (!io_node)
1001
                                                        return -ENOMEM;
1002
 
1003
                                                io_node->base =
1004
                                                save_base & (~0x03L);
1005
                                                io_node->length = temp_register;
1006
 
1007
                                                io_node->next = func->io_head;
1008
                                                func->io_head = io_node;
1009
                                        } else
1010
                                                if (((base & 0x0BL) == 0x08)
1011
                                                    && (save_command & 0x02)) {
1012
                                                // prefetchable memory base
1013
                                                temp_register = base & 0xFFFFFFF0;
1014
                                                temp_register = (~temp_register) + 1;
1015
 
1016
                                                p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
1017
                                                if (!p_mem_node)
1018
                                                        return -ENOMEM;
1019
 
1020
                                                p_mem_node->base = save_base & (~0x0FL);
1021
                                                p_mem_node->length = temp_register;
1022
 
1023
                                                p_mem_node->next = func->p_mem_head;
1024
                                                func->p_mem_head = p_mem_node;
1025
                                        } else
1026
                                                if (((base & 0x0BL) == 0x00)
1027
                                                    && (save_command & 0x02)) {
1028
                                                // prefetchable memory base
1029
                                                temp_register = base & 0xFFFFFFF0;
1030
                                                temp_register = (~temp_register) + 1;
1031
 
1032
                                                mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
1033
                                                if (!mem_node)
1034
                                                        return -ENOMEM;
1035
 
1036
                                                mem_node->base = save_base & (~0x0FL);
1037
                                                mem_node->length = temp_register;
1038
 
1039
                                                mem_node->next = func->mem_head;
1040
                                                func->mem_head = mem_node;
1041
                                        } else
1042
                                                return(1);
1043
                                }
1044
                        }       // End of base register loop
1045
                } else if ((header_type & 0x7F) == 0x00) {        // Standard header
1046
                        // Figure out IO and memory base lengths
1047
                        for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
1048
                                pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &save_base);
1049
 
1050
                                temp_register = 0xFFFFFFFF;
1051
                                pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register);
1052
 
1053
                                pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
1054
 
1055
                                temp_register = base;
1056
 
1057
                                if (base) {       // If this register is implemented
1058
                                        if (((base & 0x03L) == 0x01)
1059
                                            && (save_command & 0x01)) {
1060
                                                // IO base
1061
                                                // set temp_register = amount of IO space requested
1062
                                                temp_register = base & 0xFFFFFFFE;
1063
                                                temp_register = (~temp_register) + 1;
1064
 
1065
                                                io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
1066
                                                if (!io_node)
1067
                                                        return -ENOMEM;
1068
 
1069
                                                io_node->base = save_base & (~0x01L);
1070
                                                io_node->length = temp_register;
1071
 
1072
                                                io_node->next = func->io_head;
1073
                                                func->io_head = io_node;
1074
                                        } else
1075
                                                if (((base & 0x0BL) == 0x08)
1076
                                                    && (save_command & 0x02)) {
1077
                                                // prefetchable memory base
1078
                                                temp_register = base & 0xFFFFFFF0;
1079
                                                temp_register = (~temp_register) + 1;
1080
 
1081
                                                p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
1082
                                                if (!p_mem_node)
1083
                                                        return -ENOMEM;
1084
 
1085
                                                p_mem_node->base = save_base & (~0x0FL);
1086
                                                p_mem_node->length = temp_register;
1087
 
1088
                                                p_mem_node->next = func->p_mem_head;
1089
                                                func->p_mem_head = p_mem_node;
1090
                                        } else
1091
                                                if (((base & 0x0BL) == 0x00)
1092
                                                    && (save_command & 0x02)) {
1093
                                                // prefetchable memory base
1094
                                                temp_register = base & 0xFFFFFFF0;
1095
                                                temp_register = (~temp_register) + 1;
1096
 
1097
                                                mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
1098
                                                if (!mem_node)
1099
                                                        return -ENOMEM;
1100
 
1101
                                                mem_node->base = save_base & (~0x0FL);
1102
                                                mem_node->length = temp_register;
1103
 
1104
                                                mem_node->next = func->mem_head;
1105
                                                func->mem_head = mem_node;
1106
                                        } else
1107
                                                return(1);
1108
                                }
1109
                        }       // End of base register loop
1110
                } else {          // Some other unknown header type
1111
                }
1112
 
1113
                // find the next device in this slot
1114
                func = cpqhp_slot_find(func->bus, func->device, index++);
1115
        }
1116
 
1117
        return(0);
1118
}
1119
 
1120
 
1121
/*
1122
 * cpqhp_configure_board
1123
 *
1124
 * Copies saved configuration information to one slot.
1125
 * this is called recursively for bridge devices.
1126
 * this is for hot plug REPLACE!
1127
 *
1128
 * returns 0 if success
1129
 */
1130
int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)
1131
{
1132
        int cloop;
1133
        u8 header_type;
1134
        u8 secondary_bus;
1135
        int sub_bus;
1136
        struct pci_func *next;
1137
        u32 temp;
1138
        u32 rc;
1139
        int index = 0;
1140
 
1141
        func = cpqhp_slot_find(func->bus, func->device, index++);
1142
 
1143
        while (func != NULL) {
1144
                // Start at the top of config space so that the control
1145
                // registers are programmed last
1146
                for (cloop = 0x3C; cloop > 0; cloop -= 4) {
1147
                        pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, func->config_space[cloop >> 2]);
1148
                }
1149
 
1150
                pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type);
1151
 
1152
                // If this is a bridge device, restore subordinate devices
1153
                if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {     // PCI-PCI Bridge
1154
                        pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SECONDARY_BUS, &secondary_bus);
1155
 
1156
                        sub_bus = (int) secondary_bus;
1157
 
1158
                        next = cpqhp_slot_list[sub_bus];
1159
 
1160
                        while (next != NULL) {
1161
                                rc = cpqhp_configure_board(ctrl, next);
1162
 
1163
                                if (rc)
1164
                                        return rc;
1165
 
1166
                                next = next->next;
1167
                        }
1168
                } else {
1169
 
1170
                        // Check all the base Address Registers to make sure
1171
                        // they are the same.  If not, the board is different.
1172
 
1173
                        for (cloop = 16; cloop < 40; cloop += 4) {
1174
                                pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &temp);
1175
 
1176
                                if (temp != func->config_space[cloop >> 2]) {
1177
                                        dbg("Config space compare failure!!! offset = %x\n", cloop);
1178
                                        dbg("bus = %x, device = %x, function = %x\n", func->bus, func->device, func->function);
1179
                                        dbg("temp = %x, config space = %x\n\n", temp, func->config_space[cloop]);
1180
                                        return 1;
1181
                                }
1182
                        }
1183
                }
1184
 
1185
                func->configured = 1;
1186
 
1187
                func = cpqhp_slot_find(func->bus, func->device, index++);
1188
        }
1189
 
1190
        return 0;
1191
}
1192
 
1193
 
1194
/*
1195
 * cpqhp_valid_replace
1196
 *
1197
 * this function checks to see if a board is the same as the
1198
 * one it is replacing.  this check will detect if the device's
1199
 * vendor or device id's are the same
1200
 *
1201
 * returns 0 if the board is the same nonzero otherwise
1202
 */
1203
int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
1204
{
1205
        u8 cloop;
1206
        u8 header_type;
1207
        u8 secondary_bus;
1208
        u8 type;
1209
        u32 temp_register = 0;
1210
        u32 base;
1211
        u32 rc;
1212
        struct pci_func *next;
1213
        int index = 0;
1214
 
1215
        if (!func->is_a_board)
1216
                return(ADD_NOT_SUPPORTED);
1217
 
1218
        func = cpqhp_slot_find(func->bus, func->device, index++);
1219
 
1220
        while (func != NULL) {
1221
                pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_VENDOR_ID, &temp_register);
1222
 
1223
                // No adapter present
1224
                if (temp_register == 0xFFFFFFFF)
1225
                        return(NO_ADAPTER_PRESENT);
1226
 
1227
                if (temp_register != func->config_space[0])
1228
                        return(ADAPTER_NOT_SAME);
1229
 
1230
                // Check for same revision number and class code
1231
                pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_CLASS_REVISION, &temp_register);
1232
 
1233
                // Adapter not the same
1234
                if (temp_register != func->config_space[0x08 >> 2])
1235
                        return(ADAPTER_NOT_SAME);
1236
 
1237
                // Check for Bridge
1238
                pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type);
1239
 
1240
                if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {     // PCI-PCI Bridge
1241
                        // In order to continue checking, we must program the
1242
                        // bus registers in the bridge to respond to accesses
1243
                        // for it's subordinate bus(es)
1244
 
1245
                        temp_register = func->config_space[0x18 >> 2];
1246
                        pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PRIMARY_BUS, temp_register);
1247
 
1248
                        secondary_bus = (temp_register >> 8) & 0xFF;
1249
 
1250
                        next = cpqhp_slot_list[secondary_bus];
1251
 
1252
                        while (next != NULL) {
1253
                                rc = cpqhp_valid_replace(ctrl, next);
1254
 
1255
                                if (rc)
1256
                                        return(rc);
1257
 
1258
                                next = next->next;
1259
                        }
1260
 
1261
                }
1262
                // Check to see if it is a standard config header
1263
                else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
1264
                        // Check subsystem vendor and ID
1265
                        pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);
1266
 
1267
                        if (temp_register != func->config_space[0x2C >> 2]) {
1268
                                // If it's a SMART-2 and the register isn't filled
1269
                                // in, ignore the difference because
1270
                                // they just have an old rev of the firmware
1271
 
1272
                                if (!((func->config_space[0] == 0xAE100E11)
1273
                                      && (temp_register == 0x00L)))
1274
                                        return(ADAPTER_NOT_SAME);
1275
                        }
1276
                        // Figure out IO and memory base lengths
1277
                        for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
1278
                                temp_register = 0xFFFFFFFF;
1279
                                pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register);
1280
 
1281
                                pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
1282
 
1283
                                if (base) {       // If this register is implemented
1284
                                        if (base & 0x01L) {
1285
                                                // IO base
1286
                                                // set base = amount of IO space requested
1287
                                                base = base & 0xFFFFFFFE;
1288
                                                base = (~base) + 1;
1289
 
1290
                                                type = 1;
1291
                                        } else {
1292
                                                // memory base
1293
                                                base = base & 0xFFFFFFF0;
1294
                                                base = (~base) + 1;
1295
 
1296
                                                type = 0;
1297
                                        }
1298
                                } else {
1299
                                        base = 0x0L;
1300
                                        type = 0;
1301
                                }
1302
 
1303
                                // Check information in slot structure
1304
                                if (func->base_length[(cloop - 0x10) >> 2] != base)
1305
                                        return(ADAPTER_NOT_SAME);
1306
 
1307
                                if (func->base_type[(cloop - 0x10) >> 2] != type)
1308
                                        return(ADAPTER_NOT_SAME);
1309
 
1310
                        }       // End of base register loop
1311
 
1312
                }               // End of (type 0 config space) else
1313
                else {
1314
                        // this is not a type 0 or 1 config space header so
1315
                        // we don't know how to do it
1316
                        return(DEVICE_TYPE_NOT_SUPPORTED);
1317
                }
1318
 
1319
                // Get the next function
1320
                func = cpqhp_slot_find(func->bus, func->device, index++);
1321
        }
1322
 
1323
 
1324
        return(0);
1325
}
1326
 
1327
 
1328
/*
1329
 * cpqhp_find_available_resources
1330
 *
1331
 * Finds available memory, IO, and IRQ resources for programming
1332
 * devices which may be added to the system
1333
 * this function is for hot plug ADD!
1334
 *
1335
 * returns 0 if success
1336
 */
1337
int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start)
1338
{
1339
        u8 temp;
1340
        u8 populated_slot;
1341
        u8 bridged_slot;
1342
        void *one_slot;
1343
        struct pci_func *func = NULL;
1344
        int i = 10, index;
1345
        u32 temp_dword, rc;
1346
        struct pci_resource *mem_node;
1347
        struct pci_resource *p_mem_node;
1348
        struct pci_resource *io_node;
1349
        struct pci_resource *bus_node;
1350
        void *rom_resource_table;
1351
 
1352
        rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff);
1353
        dbg("rom_resource_table = %p\n", rom_resource_table);
1354
 
1355
        if (rom_resource_table == NULL) {
1356
                return -ENODEV;
1357
        }
1358
        // Sum all resources and setup resource maps
1359
        unused_IRQ = readl(rom_resource_table + UNUSED_IRQ);
1360
        dbg("unused_IRQ = %x\n", unused_IRQ);
1361
 
1362
        temp = 0;
1363
        while (unused_IRQ) {
1364
                if (unused_IRQ & 1) {
1365
                        cpqhp_disk_irq = temp;
1366
                        break;
1367
                }
1368
                unused_IRQ = unused_IRQ >> 1;
1369
                temp++;
1370
        }
1371
 
1372
        dbg("cpqhp_disk_irq= %d\n", cpqhp_disk_irq);
1373
        unused_IRQ = unused_IRQ >> 1;
1374
        temp++;
1375
 
1376
        while (unused_IRQ) {
1377
                if (unused_IRQ & 1) {
1378
                        cpqhp_nic_irq = temp;
1379
                        break;
1380
                }
1381
                unused_IRQ = unused_IRQ >> 1;
1382
                temp++;
1383
        }
1384
 
1385
        dbg("cpqhp_nic_irq= %d\n", cpqhp_nic_irq);
1386
        unused_IRQ = readl(rom_resource_table + PCIIRQ);
1387
 
1388
        temp = 0;
1389
 
1390
        if (!cpqhp_nic_irq) {
1391
                cpqhp_nic_irq = ctrl->interrupt;
1392
        }
1393
 
1394
        if (!cpqhp_disk_irq) {
1395
                cpqhp_disk_irq = ctrl->interrupt;
1396
        }
1397
 
1398
        dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq);
1399
 
1400
        rc = compaq_nvram_load(rom_start, ctrl);
1401
        if (rc)
1402
                return rc;
1403
 
1404
        one_slot = rom_resource_table + sizeof (struct hrt);
1405
 
1406
        i = readb(rom_resource_table + NUMBER_OF_ENTRIES);
1407
        dbg("number_of_entries = %d\n", i);
1408
 
1409
        if (!readb(one_slot + SECONDARY_BUS)) {
1410
                return(1);
1411
        }
1412
 
1413
        dbg("dev|IO base|length|Mem base|length|Pre base|length|PB SB MB\n");
1414
 
1415
        while (i && readb(one_slot + SECONDARY_BUS)) {
1416
                u8 dev_func = readb(one_slot + DEV_FUNC);
1417
                u8 primary_bus = readb(one_slot + PRIMARY_BUS);
1418
                u8 secondary_bus = readb(one_slot + SECONDARY_BUS);
1419
                u8 max_bus = readb(one_slot + MAX_BUS);
1420
                u16 io_base = readw(one_slot + IO_BASE);
1421
                u16 io_length = readw(one_slot + IO_LENGTH);
1422
                u16 mem_base = readw(one_slot + MEM_BASE);
1423
                u16 mem_length = readw(one_slot + MEM_LENGTH);
1424
                u16 pre_mem_base = readw(one_slot + PRE_MEM_BASE);
1425
                u16 pre_mem_length = readw(one_slot + PRE_MEM_LENGTH);
1426
 
1427
                dbg("%2.2x | %4.4x  | %4.4x | %4.4x   | %4.4x | %4.4x   | %4.4x |%2.2x %2.2x %2.2x\n",
1428
                    dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length,
1429
                    primary_bus, secondary_bus, max_bus);
1430
 
1431
                // If this entry isn't for our controller's bus, ignore it
1432
                if (primary_bus != ctrl->bus) {
1433
                        i--;
1434
                        one_slot += sizeof (struct slot_rt);
1435
                        continue;
1436
                }
1437
                // find out if this entry is for an occupied slot
1438
                pci_read_config_dword_nodev (ctrl->pci_ops, primary_bus, dev_func >> 3, dev_func & 0x07, PCI_VENDOR_ID, &temp_dword);
1439
 
1440
                dbg("temp_D_word = %x\n", temp_dword);
1441
 
1442
                if (temp_dword != 0xFFFFFFFF) {
1443
                        index = 0;
1444
                        func = cpqhp_slot_find(primary_bus, dev_func >> 3, 0);
1445
 
1446
                        while (func && (func->function != (dev_func & 0x07))) {
1447
                                dbg("func = %p (bus, dev, fun) = (%d, %d, %d)\n", func, primary_bus, dev_func >> 3, index);
1448
                                func = cpqhp_slot_find(primary_bus, dev_func >> 3, index++);
1449
                        }
1450
 
1451
                        // If we can't find a match, skip this table entry
1452
                        if (!func) {
1453
                                i--;
1454
                                one_slot += sizeof (struct slot_rt);
1455
                                continue;
1456
                        }
1457
                        // this may not work and shouldn't be used
1458
                        if (secondary_bus != primary_bus)
1459
                                bridged_slot = 1;
1460
                        else
1461
                                bridged_slot = 0;
1462
 
1463
                        populated_slot = 1;
1464
                } else {
1465
                        populated_slot = 0;
1466
                        bridged_slot = 0;
1467
                }
1468
 
1469
 
1470
                // If we've got a valid IO base, use it
1471
 
1472
                temp_dword = io_base + io_length;
1473
 
1474
                if ((io_base) && (temp_dword < 0x10000)) {
1475
                        io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
1476
                        if (!io_node)
1477
                                return -ENOMEM;
1478
 
1479
                        io_node->base = io_base;
1480
                        io_node->length = io_length;
1481
 
1482
                        dbg("found io_node(base, length) = %x, %x\n", io_node->base, io_node->length);
1483
                        dbg("populated slot =%d \n", populated_slot);
1484
                        if (!populated_slot) {
1485
                                io_node->next = ctrl->io_head;
1486
                                ctrl->io_head = io_node;
1487
                        } else {
1488
                                io_node->next = func->io_head;
1489
                                func->io_head = io_node;
1490
                        }
1491
                }
1492
 
1493
                // If we've got a valid memory base, use it
1494
                temp_dword = mem_base + mem_length;
1495
                if ((mem_base) && (temp_dword < 0x10000)) {
1496
                        mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
1497
                        if (!mem_node)
1498
                                return -ENOMEM;
1499
 
1500
                        mem_node->base = mem_base << 16;
1501
 
1502
                        mem_node->length = mem_length << 16;
1503
 
1504
                        dbg("found mem_node(base, length) = %x, %x\n", mem_node->base, mem_node->length);
1505
                        dbg("populated slot =%d \n", populated_slot);
1506
                        if (!populated_slot) {
1507
                                mem_node->next = ctrl->mem_head;
1508
                                ctrl->mem_head = mem_node;
1509
                        } else {
1510
                                mem_node->next = func->mem_head;
1511
                                func->mem_head = mem_node;
1512
                        }
1513
                }
1514
 
1515
                // If we've got a valid prefetchable memory base, and
1516
                // the base + length isn't greater than 0xFFFF
1517
                temp_dword = pre_mem_base + pre_mem_length;
1518
                if ((pre_mem_base) && (temp_dword < 0x10000)) {
1519
                        p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
1520
                        if (!p_mem_node)
1521
                                return -ENOMEM;
1522
 
1523
                        p_mem_node->base = pre_mem_base << 16;
1524
 
1525
                        p_mem_node->length = pre_mem_length << 16;
1526
                        dbg("found p_mem_node(base, length) = %x, %x\n", p_mem_node->base, p_mem_node->length);
1527
                        dbg("populated slot =%d \n", populated_slot);
1528
 
1529
                        if (!populated_slot) {
1530
                                p_mem_node->next = ctrl->p_mem_head;
1531
                                ctrl->p_mem_head = p_mem_node;
1532
                        } else {
1533
                                p_mem_node->next = func->p_mem_head;
1534
                                func->p_mem_head = p_mem_node;
1535
                        }
1536
                }
1537
 
1538
                // If we've got a valid bus number, use it
1539
                // The second condition is to ignore bus numbers on
1540
                // populated slots that don't have PCI-PCI bridges
1541
                if (secondary_bus && (secondary_bus != primary_bus)) {
1542
                        bus_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
1543
                        if (!bus_node)
1544
                                return -ENOMEM;
1545
 
1546
                        bus_node->base = secondary_bus;
1547
                        bus_node->length = max_bus - secondary_bus + 1;
1548
                        dbg("found bus_node(base, length) = %x, %x\n", bus_node->base, bus_node->length);
1549
                        dbg("populated slot =%d \n", populated_slot);
1550
                        if (!populated_slot) {
1551
                                bus_node->next = ctrl->bus_head;
1552
                                ctrl->bus_head = bus_node;
1553
                        } else {
1554
                                bus_node->next = func->bus_head;
1555
                                func->bus_head = bus_node;
1556
                        }
1557
                }
1558
 
1559
                i--;
1560
                one_slot += sizeof (struct slot_rt);
1561
        }
1562
 
1563
        // If all of the following fail, we don't have any resources for
1564
        // hot plug add
1565
        rc = 1;
1566
        rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
1567
        rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
1568
        rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));
1569
        rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));
1570
 
1571
        return(rc);
1572
}
1573
 
1574
 
1575
/*
1576
 * cpqhp_return_board_resources
1577
 *
1578
 * this routine returns all resources allocated to a board to
1579
 * the available pool.
1580
 *
1581
 * returns 0 if success
1582
 */
1583
int cpqhp_return_board_resources(struct pci_func * func, struct resource_lists * resources)
1584
{
1585
        int rc = 0;
1586
        struct pci_resource *node;
1587
        struct pci_resource *t_node;
1588
        dbg("%s\n", __FUNCTION__);
1589
 
1590
        if (!func)
1591
                return(1);
1592
 
1593
        node = func->io_head;
1594
        func->io_head = NULL;
1595
        while (node) {
1596
                t_node = node->next;
1597
                return_resource(&(resources->io_head), node);
1598
                node = t_node;
1599
        }
1600
 
1601
        node = func->mem_head;
1602
        func->mem_head = NULL;
1603
        while (node) {
1604
                t_node = node->next;
1605
                return_resource(&(resources->mem_head), node);
1606
                node = t_node;
1607
        }
1608
 
1609
        node = func->p_mem_head;
1610
        func->p_mem_head = NULL;
1611
        while (node) {
1612
                t_node = node->next;
1613
                return_resource(&(resources->p_mem_head), node);
1614
                node = t_node;
1615
        }
1616
 
1617
        node = func->bus_head;
1618
        func->bus_head = NULL;
1619
        while (node) {
1620
                t_node = node->next;
1621
                return_resource(&(resources->bus_head), node);
1622
                node = t_node;
1623
        }
1624
 
1625
        rc |= cpqhp_resource_sort_and_combine(&(resources->mem_head));
1626
        rc |= cpqhp_resource_sort_and_combine(&(resources->p_mem_head));
1627
        rc |= cpqhp_resource_sort_and_combine(&(resources->io_head));
1628
        rc |= cpqhp_resource_sort_and_combine(&(resources->bus_head));
1629
 
1630
        return(rc);
1631
}
1632
 
1633
 
1634
/*
1635
 * cpqhp_destroy_resource_list
1636
 *
1637
 * Puts node back in the resource list pointed to by head
1638
 */
1639
void cpqhp_destroy_resource_list (struct resource_lists * resources)
1640
{
1641
        struct pci_resource *res, *tres;
1642
 
1643
        res = resources->io_head;
1644
        resources->io_head = NULL;
1645
 
1646
        while (res) {
1647
                tres = res;
1648
                res = res->next;
1649
                kfree(tres);
1650
        }
1651
 
1652
        res = resources->mem_head;
1653
        resources->mem_head = NULL;
1654
 
1655
        while (res) {
1656
                tres = res;
1657
                res = res->next;
1658
                kfree(tres);
1659
        }
1660
 
1661
        res = resources->p_mem_head;
1662
        resources->p_mem_head = NULL;
1663
 
1664
        while (res) {
1665
                tres = res;
1666
                res = res->next;
1667
                kfree(tres);
1668
        }
1669
 
1670
        res = resources->bus_head;
1671
        resources->bus_head = NULL;
1672
 
1673
        while (res) {
1674
                tres = res;
1675
                res = res->next;
1676
                kfree(tres);
1677
        }
1678
}
1679
 
1680
 
1681
/*
1682
 * cpqhp_destroy_board_resources
1683
 *
1684
 * Puts node back in the resource list pointed to by head
1685
 */
1686
void cpqhp_destroy_board_resources (struct pci_func * func)
1687
{
1688
        struct pci_resource *res, *tres;
1689
 
1690
        res = func->io_head;
1691
        func->io_head = NULL;
1692
 
1693
        while (res) {
1694
                tres = res;
1695
                res = res->next;
1696
                kfree(tres);
1697
        }
1698
 
1699
        res = func->mem_head;
1700
        func->mem_head = NULL;
1701
 
1702
        while (res) {
1703
                tres = res;
1704
                res = res->next;
1705
                kfree(tres);
1706
        }
1707
 
1708
        res = func->p_mem_head;
1709
        func->p_mem_head = NULL;
1710
 
1711
        while (res) {
1712
                tres = res;
1713
                res = res->next;
1714
                kfree(tres);
1715
        }
1716
 
1717
        res = func->bus_head;
1718
        func->bus_head = NULL;
1719
 
1720
        while (res) {
1721
                tres = res;
1722
                res = res->next;
1723
                kfree(tres);
1724
        }
1725
}
1726
 

powered by: WebSVN 2.1.0

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