linux-old/drivers/hotplug/pciehp_pci.c
<<
>>
Prefs
   1/*
   2 * PCI Express 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 * Copyright (C) 2003-2004 Intel Corporation
   8 *
   9 * All rights reserved.
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License as published by
  13 * the Free Software Foundation; either version 2 of the License, or (at
  14 * your option) any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful, but
  17 * WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  19 * NON INFRINGEMENT.  See the GNU General Public License for more
  20 * details.
  21 *
  22 * You should have received a copy of the GNU General Public License
  23 * along with this program; if not, write to the Free Software
  24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25 *
  26 * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
  27 *
  28 */
  29
  30#include <linux/config.h>
  31#include <linux/module.h>
  32#include <linux/kernel.h>
  33#include <linux/types.h>
  34#include <linux/slab.h>
  35#include <linux/tqueue.h>
  36#include <linux/proc_fs.h>
  37#include <linux/pci.h>
  38#include "pciehp.h"
  39#ifndef CONFIG_IA64
  40#include "../../arch/i386/kernel/pci-i386.h"    /* horrible hack showing how processor dependant we are... */
  41#endif
  42
  43static int is_pci_dev_in_use(struct pci_dev* dev) 
  44{
  45        /* 
  46         * dev->driver will be set if the device is in use by a new-style 
  47         * driver -- otherwise, check the device's regions to see if any
  48         * driver has claimed them
  49         */
  50
  51        int i, inuse=0;
  52
  53        if (dev->driver) return 1; /* Assume driver feels responsible */
  54
  55        for (i = 0; !dev->driver && !inuse && (i < 6); i++) {
  56                if (!pci_resource_start(dev, i))
  57                        continue;
  58
  59                if (pci_resource_flags(dev, i) & IORESOURCE_IO)
  60                        inuse = check_region(pci_resource_start(dev, i),
  61                                             pci_resource_len(dev, i));
  62                else if (pci_resource_flags(dev, i) & IORESOURCE_MEM)
  63                        inuse = check_mem_region(pci_resource_start(dev, i),
  64                                                 pci_resource_len(dev, i));
  65        }
  66
  67        return inuse;
  68
  69}
  70
  71
  72static int pci_hp_remove_device(struct pci_dev *dev)
  73{
  74        if (is_pci_dev_in_use(dev)) {
  75                err("***Cannot safely power down device -- "
  76                       "it appears to be in use***\n");
  77                return -EBUSY;
  78        }
  79        dbg("%s: dev %p\n", __FUNCTION__, dev);
  80        pci_remove_device(dev);
  81        return 0;
  82}
  83
  84
  85static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus) 
  86{
  87        struct pci_bus* bus = wrapped_bus->bus;
  88        struct pci_dev* dev = wrapped_dev->dev;
  89        struct pci_func *temp_func;
  90        int i=0;
  91
  92        /* We need to fix up the hotplug function representation with the linux representation */
  93        do {
  94                temp_func = pciehp_slot_find(dev->bus->number, dev->devfn >> 3, i++);
  95        } while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
  96
  97        if (temp_func) {
  98                temp_func->pci_dev = dev;
  99        } else {
 100                /* We did not even find a hotplug rep of the function, create it
 101                 * This code might be taken out if we can guarantee the creation of functions
 102                 * in parallel (hotplug and Linux at the same time).
 103                 */
 104                dbg("@@@@@@@@@@@ pciehp_slot_create in %s\n", __FUNCTION__);
 105                temp_func = pciehp_slot_create(bus->number);
 106                if (temp_func == NULL)
 107                        return -ENOMEM;
 108                temp_func->pci_dev = dev;
 109        }
 110
 111        /* Create /proc/bus/pci proc entry for this device and bus device is on */
 112        /* Notify the drivers of the change */
 113        if (temp_func->pci_dev) {
 114                dbg("%s: PCI_ID=%04X:%04X\n", __FUNCTION__, temp_func->pci_dev->vendor,
 115                        temp_func->pci_dev->device); 
 116                dbg("%s: PCI BUS %x DEVFN %x\n", __FUNCTION__, 
 117                        temp_func->pci_dev->bus->number, temp_func->pci_dev->devfn); 
 118                dbg("%s: PCI_SLOT_NAME=%s\n", __FUNCTION__, 
 119                        temp_func->pci_dev->slot_name);
 120                pci_enable_device(temp_func->pci_dev);
 121                pci_proc_attach_device(temp_func->pci_dev);
 122                pci_announce_device_to_drivers(temp_func->pci_dev);
 123        }
 124
 125        return 0;
 126}
 127
 128
 129static int unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus) 
 130{
 131        struct pci_dev* dev = wrapped_dev->dev;
 132
 133        struct pci_func *temp_func;
 134        int i=0;
 135
 136        dbg("%s: dev %p dev->bus->number %x bus->number %x\n", __FUNCTION__, wrapped_dev, 
 137                dev->bus->number, wrapped_bus->bus->number);
 138
 139        /* We need to remove the hotplug function representation with the linux representation */
 140        do {
 141                temp_func = pciehp_slot_find(dev->bus->number, dev->devfn >> 3, i++);
 142                if (temp_func) {
 143                        dbg("%s: temp_func->function = %d\n", __FUNCTION__, temp_func->function);
 144                }
 145        } while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
 146
 147        /* Now, remove the Linux Representation */
 148        if (dev) {
 149                if (pci_hp_remove_device(dev) == 0) {
 150                        kfree(dev); /* Now, remove */
 151                } else {
 152                        return -1; /* problems while freeing, abort visitation */
 153                }
 154        }
 155
 156        if (temp_func) {
 157                temp_func->pci_dev = NULL;
 158        } else {
 159                dbg("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
 160        }
 161
 162        return 0;
 163}
 164
 165
 166static int unconfigure_visit_pci_bus_phase2 (struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_dev) 
 167{
 168        struct pci_bus* bus = wrapped_bus->bus;
 169
 170        /* The cleanup code for proc entries regarding buses should be in the kernel...*/
 171        if (bus->procdir)
 172                dbg("detach_pci_bus %s\n", bus->procdir->name);
 173        pci_proc_detach_bus(bus);
 174        /* The cleanup code should live in the kernel... */
 175        bus->self->subordinate = NULL;
 176        /* unlink from parent bus */
 177        list_del(&bus->node);
 178
 179        /* Now, remove */
 180        if (bus)
 181                kfree(bus);
 182
 183        return 0;
 184}
 185
 186
 187static int unconfigure_visit_pci_dev_phase1 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus) 
 188{
 189        struct pci_dev* dev = wrapped_dev->dev;
 190        int rc;
 191
 192        dbg("attempting removal of driver for device (%x, %x, %x)\n", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
 193        /* Now, remove the Linux Driver Representation */
 194        if (dev->driver) {
 195                if (dev->driver->remove) {
 196                        dev->driver->remove(dev);
 197                        dbg("driver was properly removed\n");
 198                }
 199                dev->driver = NULL;
 200        }
 201
 202        rc = is_pci_dev_in_use(dev);
 203        if (rc)
 204                info("%s: device still in use\n", __FUNCTION__);
 205        return rc;
 206}
 207
 208
 209static struct pci_visit configure_functions = {
 210        .visit_pci_dev =        configure_visit_pci_dev,
 211};
 212
 213
 214static struct pci_visit unconfigure_functions_phase1 = {
 215        .post_visit_pci_dev =   unconfigure_visit_pci_dev_phase1
 216};
 217
 218static struct pci_visit unconfigure_functions_phase2 = {
 219        .post_visit_pci_bus =   unconfigure_visit_pci_bus_phase2,               
 220        .post_visit_pci_dev =   unconfigure_visit_pci_dev_phase2
 221};
 222
 223
 224int pciehp_configure_device (struct controller* ctrl, struct pci_func* func)  
 225{
 226        unsigned char bus;
 227        struct pci_dev dev0;
 228        struct pci_bus *child;
 229        struct pci_dev* temp;
 230        int rc = 0;
 231
 232        struct pci_dev_wrapped wrapped_dev;
 233        struct pci_bus_wrapped wrapped_bus;
 234        memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
 235        memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
 236
 237        memset(&dev0, 0, sizeof(struct pci_dev));
 238        
 239        dbg("%s: func->pci_dev %p bus %x dev %x func %x\n", __FUNCTION__,
 240                func->pci_dev, func->bus, func->device, func->function);
 241        if (func->pci_dev == NULL)
 242                func->pci_dev = pci_find_slot(func->bus, (func->device << 3) | (func->function & 0x7));
 243        dbg("%s: func->pci_dev %p bus %x dev %x func %x\n", __FUNCTION__,
 244                func->pci_dev, func->bus, func->device, func->function);
 245        if (func->pci_dev != NULL) {
 246                dbg("%s: pci_dev %p bus %x devfn %x\n", __FUNCTION__,
 247                        func->pci_dev, func->pci_dev->bus->number, func->pci_dev->devfn);
 248        }
 249        /* Still NULL ? Well then scan for it ! */
 250        if (func->pci_dev == NULL) {
 251                dbg("%s: pci_dev still null. do pci_scan_slot\n", __FUNCTION__);
 252                dev0.bus = ctrl->pci_dev->subordinate;
 253                dbg("%s: dev0.bus %p\n", __FUNCTION__, dev0.bus);
 254                dev0.bus->number = func->bus;
 255                dbg("%s: dev0.bus->number %x\n", __FUNCTION__, func->bus);
 256                dev0.devfn = PCI_DEVFN(func->device, func->function);
 257                dev0.sysdata = ctrl->pci_dev->sysdata;
 258
 259                /* This will generate pci_dev structures for all functions, 
 260                 * but we will only call this case when lookup fails
 261                 */
 262                func->pci_dev = pci_scan_slot(&dev0);
 263                dbg("%s: func->pci_dev %p\n", __FUNCTION__, func->pci_dev);
 264                if (func->pci_dev == NULL) {
 265                        dbg("ERROR: pci_dev still null\n");
 266                        return 0;
 267                }
 268        }
 269
 270        if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
 271                pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
 272                child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
 273                dbg("%s: bridge device - func->pci_dev->bus %p func->pci_dev %p bus %x\n", 
 274                        __FUNCTION__, func->pci_dev->bus,func->pci_dev,bus);
 275                pci_do_scan_bus(child);
 276
 277        }
 278
 279        temp = func->pci_dev;
 280
 281        if (temp) {
 282                wrapped_dev.dev = temp;
 283                wrapped_bus.bus = temp->bus;
 284                rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
 285        }
 286        return rc;
 287}
 288
 289
 290int pciehp_unconfigure_device(struct pci_func* func) 
 291{
 292        int rc = 0;
 293        int j;
 294        struct pci_dev_wrapped wrapped_dev;
 295        struct pci_bus_wrapped wrapped_bus;
 296        
 297        memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
 298        memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
 299
 300        dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, func->device, func->function);
 301
 302        for (j=0; j<8 ; j++) {
 303                struct pci_dev* temp = pci_find_slot(func->bus, (func->device << 3) | j);
 304                dbg("%s: temp %p\n", __FUNCTION__, temp);
 305                if (temp) {
 306                        wrapped_dev.dev = temp;
 307                        wrapped_bus.bus = temp->bus;
 308                        rc = pci_visit_dev(&unconfigure_functions_phase1, &wrapped_dev, &wrapped_bus);
 309                        if (rc)
 310                                break;
 311
 312                        rc = pci_visit_dev(&unconfigure_functions_phase2, &wrapped_dev, &wrapped_bus);
 313                        if (rc)
 314                                break;
 315                }
 316        }
 317        return rc;
 318}
 319
 320/*
 321 * pciehp_set_irq
 322 *
 323 * @bus_num: bus number of PCI device
 324 * @dev_num: device number of PCI device
 325 * @slot: pointer to u8 where slot number will be returned
 326 */
 327int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
 328{
 329#if defined(CONFIG_X86) && !defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_64)
 330        int rc;
 331        u16 temp_word;
 332        struct pci_dev fakedev;
 333        struct pci_bus fakebus;
 334
 335        fakedev.devfn = dev_num << 3;
 336        fakedev.bus = &fakebus;
 337        fakebus.number = bus_num;
 338        dbg("%s: dev %d, bus %d, pin %d, num %d\n",
 339            __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
 340        rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
 341        dbg("%s: rc %d\n", __FUNCTION__, rc);
 342        if (!rc)
 343                return !rc;
 344
 345        /* set the Edge Level Control Register (ELCR) */
 346        temp_word = inb(0x4d0);
 347        temp_word |= inb(0x4d1) << 8;
 348
 349        temp_word |= 0x01 << irq_num;
 350
 351        /* This should only be for x86 as it sets the Edge Level Control Register */
 352        outb((u8) (temp_word & 0xFF), 0x4d0);
 353        outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
 354#endif
 355        return 0;
 356}
 357
 358/* More PCI configuration routines; this time centered around hotplug controller */
 359
 360
 361/*
 362 * pciehp_save_config
 363 *
 364 * Reads configuration for all slots in a PCI bus and saves info.
 365 *
 366 * Note:  For non-hot plug busses, the slot # saved is the device #
 367 *
 368 * returns 0 if success
 369 */
 370int pciehp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num) 
 371{
 372        int rc;
 373        u8 class_code;
 374        u8 header_type;
 375        u32 ID;
 376        u8 secondary_bus;
 377        struct pci_func *new_slot;
 378        int sub_bus;
 379        int max_functions;
 380        int function;
 381        u8 DevError;
 382        int device = 0;
 383        int cloop = 0;
 384        int stop_it;
 385        int index;
 386        int is_hot_plug = num_ctlr_slots || first_device_num; 
 387        struct pci_bus lpci_bus, *pci_bus;
 388        int FirstSupported, LastSupported;
 389        
 390        dbg("%s: Enter\n", __FUNCTION__);
 391
 392        memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
 393        pci_bus = &lpci_bus;
 394
 395        dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__, num_ctlr_slots, 
 396                first_device_num);
 397
 398        /*   Decide which slots are supported */
 399        if (is_hot_plug) {
 400                /*********************************
 401                 *  is_hot_plug is the slot mask
 402                 *********************************/
 403                FirstSupported = first_device_num;
 404                LastSupported = FirstSupported + num_ctlr_slots - 1;
 405        } else {
 406                FirstSupported = 0;
 407                LastSupported = 0x1F;
 408        }
 409
 410        dbg("FirstSupported = %d, LastSupported = %d\n", FirstSupported, LastSupported);
 411
 412        /*   Save PCI configuration space for all devices in supported slots */
 413        dbg("%s: pci_bus->number = %x\n", __FUNCTION__, pci_bus->number);
 414        pci_bus->number = busnumber;
 415        dbg("%s: bus = %x, dev = %x\n", __FUNCTION__, busnumber, device);
 416        for (device = FirstSupported; device <= LastSupported; device++) { 
 417                ID = 0xFFFFFFFF;
 418                rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
 419                /* dbg("%s: ID = %x\n", __FUNCTION__, ID);*/
 420
 421                if (ID != 0xFFFFFFFF) {   /*  device in slot */
 422                        dbg("%s: ID = %x\n", __FUNCTION__, ID);
 423                        rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code);
 424                        if (rc)
 425                                return rc;
 426
 427                        rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, 
 428                                &header_type);
 429                        if (rc)
 430                                return rc;
 431
 432                        dbg("class_code = %x, header_type = %x\n", class_code, header_type);
 433
 434                        /* If multi-function device, set max_functions to 8 */
 435                        if (header_type & 0x80)
 436                                max_functions = 8;
 437                        else
 438                                max_functions = 1;
 439
 440                        function = 0;
 441
 442                        do {
 443                                DevError = 0;
 444                                dbg("%s: In do loop\n", __FUNCTION__);
 445
 446                                if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {   /* P-P Bridge */
 447                                        /* Recurse the subordinate bus
 448                                         * get the subordinate bus number
 449                                         */
 450                                        rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, function), 
 451                                                PCI_SECONDARY_BUS, &secondary_bus);
 452                                        if (rc) {
 453                                                return rc;
 454                                        } else {
 455                                                sub_bus = (int) secondary_bus;
 456
 457                                                /* Save secondary bus cfg spc with this recursive call. */
 458                                                rc = pciehp_save_config(ctrl, sub_bus, 0, 0); 
 459                                                if (rc)
 460                                                        return rc;
 461                                        }
 462                                }
 463
 464                                index = 0;
 465                                new_slot = pciehp_slot_find(busnumber, device, index++);
 466
 467                                dbg("%s: new_slot = %p bus %x dev %x fun %x\n",
 468                                __FUNCTION__, new_slot, busnumber, device, index-1);
 469
 470                                while (new_slot && (new_slot->function != (u8) function)) {
 471                                        new_slot = pciehp_slot_find(busnumber, device, index++);
 472                                        dbg("%s: while loop, new_slot = %p bus %x dev %x fun %x\n",
 473                                        __FUNCTION__, new_slot, busnumber, device, index-1);
 474                                }
 475                                if (!new_slot) {
 476                                        /* Setup slot structure. */
 477                                        new_slot = pciehp_slot_create(busnumber);
 478                                        dbg("%s: if, new_slot = %p bus %x dev %x fun %x\n",
 479                                        __FUNCTION__, new_slot, busnumber, device, function);
 480
 481                                        if (new_slot == NULL)
 482                                                return(1);
 483                                }
 484
 485                                new_slot->bus = (u8) busnumber;
 486                                new_slot->device = (u8) device;
 487                                new_slot->function = (u8) function;
 488                                new_slot->is_a_board = 1;
 489                                new_slot->switch_save = 0x10;
 490                                /* In case of unsupported board */
 491                                new_slot->status = DevError;
 492                                new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
 493                                dbg("new_slot->pci_dev = %p\n", new_slot->pci_dev);
 494
 495                                for (cloop = 0; cloop < 0x20; cloop++) {
 496                                        rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot->config_space [cloop]));
 497                                        /* dbg("new_slot->config_space[%x] = %x\n", cloop, new_slot->config_space[cloop]); */
 498                                        if (rc)
 499                                                return rc;
 500                                }
 501
 502                                function++;
 503
 504                                stop_it = 0;
 505
 506                                /*  This loop skips to the next present function
 507                                 *  reading in Class Code and Header type.
 508                                 */
 509
 510                                while ((function < max_functions)&&(!stop_it)) {
 511                                        dbg("%s: In while loop \n", __FUNCTION__);
 512                                        rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID);
 513
 514                                        if (ID == 0xFFFFFFFF) {  /* Nothing there. */
 515                                                function++;
 516                                                dbg("Nothing there\n");
 517                                        } else {  /* Something there */
 518                                                rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code);
 519                                                if (rc)
 520                                                        return rc;
 521
 522                                                rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type);
 523                                                if (rc)
 524                                                        return rc;
 525
 526                                                dbg("class_code = %x, header_type = %x\n", class_code, header_type);
 527                                                stop_it++;
 528                                        }
 529                                }
 530
 531                        } while (function < max_functions);
 532                }               /* End of IF (device in slot?) */
 533                else if (is_hot_plug) {
 534                        /* Setup slot structure with entry for empty slot */
 535                        new_slot = pciehp_slot_create(busnumber);
 536
 537                        if (new_slot == NULL) {
 538                                return(1);
 539                        }
 540                        dbg("new_slot = %p, bus = %x, dev = %x, fun = %x\n", new_slot,
 541                                new_slot->bus, new_slot->device, new_slot->function);
 542
 543                        new_slot->bus = (u8) busnumber;
 544                        new_slot->device = (u8) device;
 545                        new_slot->function = 0;
 546                        new_slot->is_a_board = 0;
 547                        new_slot->presence_save = 0;
 548                        new_slot->switch_save = 0;
 549                }
 550                /* dbg("%s: End of For loop\n", __FUNCTION__); */
 551         }                      /* End of FOR loop */
 552
 553        dbg("%s: Exit\n", __FUNCTION__);
 554        return(0);
 555}
 556
 557
 558/*
 559 * pciehp_save_slot_config
 560 *
 561 * Saves configuration info for all PCI devices in a given slot
 562 * including subordinate busses.
 563 *
 564 * returns 0 if success
 565 */
 566int pciehp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
 567{
 568        int rc;
 569        u8 class_code;
 570        u8 header_type;
 571        u32 ID;
 572        u8 secondary_bus;
 573        int sub_bus;
 574        int max_functions;
 575        int function;
 576        int cloop = 0;
 577        int stop_it;
 578        struct pci_bus lpci_bus, *pci_bus;
 579
 580        memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
 581        pci_bus = &lpci_bus;
 582        pci_bus->number = new_slot->bus;
 583
 584        ID = 0xFFFFFFFF;
 585
 586        pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);
 587
 588        if (ID != 0xFFFFFFFF) {   /*  Device in slot */
 589                pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
 590
 591                pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);
 592
 593                if (header_type & 0x80) /* Multi-function device */
 594                        max_functions = 8;
 595                else 
 596                        max_functions = 1;
 597
 598                function = 0;
 599
 600                do {
 601                        if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {     /* PCI-PCI Bridge */
 602                                /*  Recurse the subordinate bus */
 603                                pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
 604
 605                                sub_bus = (int) secondary_bus;
 606
 607                                /* Save the config headers for the secondary bus. */
 608                                rc = pciehp_save_config(ctrl, sub_bus, 0, 0); 
 609
 610                                if (rc)
 611                                        return(rc);
 612
 613                        }       /* End of IF */
 614
 615                        new_slot->status = 0;
 616
 617                        for (cloop = 0; cloop < 0x20; cloop++) {
 618                                pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot->config_space [cloop]));
 619                        }
 620
 621                        function++;
 622
 623                        stop_it = 0;
 624
 625                        /*  this loop skips to the next present function
 626                         *  reading in the Class Code and the Header type.
 627                         */
 628
 629                        while ((function < max_functions) && (!stop_it)) {
 630                                pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID);
 631
 632                                if (ID == 0xFFFFFFFF) {  /* Nothing there. */
 633                                        function++;
 634                                } else {  /* Something there */
 635                                        pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code);
 636
 637                                        pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type);
 638
 639                                        stop_it++;
 640                                }
 641                        }
 642
 643                } while (function < max_functions);
 644        }                       /* End of IF (device in slot?) */
 645        else {
 646                return(2);
 647        }
 648
 649        return(0);
 650}
 651
 652
 653/*
 654 * pciehp_save_used_resources
 655 *
 656 * Stores used resource information for existing boards.  this is
 657 * for boards that were in the system when this driver was loaded.
 658 * this function is for hot plug ADD
 659 *
 660 * returns 0 if success
 661 * if disable  == 1(DISABLE_CARD),
 662 *  it loops for all functions of the slot and disables them.
 663 * else, it just get resources of the function and return.
 664 */
 665int pciehp_save_used_resources (struct controller *ctrl, struct pci_func *func, int disable)
 666{
 667        u8 cloop;
 668        u8 header_type;
 669        u8 secondary_bus;
 670        u8 temp_byte;
 671        u16 command;
 672        u16 save_command;
 673        u16 w_base, w_length;
 674        u32 temp_register;
 675        u32 save_base;
 676        u32 base, length;
 677        u64 base64 = 0;
 678        int index = 0;
 679        unsigned int devfn;
 680        struct pci_resource *mem_node = NULL;
 681        struct pci_resource *p_mem_node = NULL;
 682        struct pci_resource *t_mem_node;
 683        struct pci_resource *io_node;
 684        struct pci_resource *bus_node;
 685        struct pci_bus lpci_bus, *pci_bus;
 686
 687        memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
 688        pci_bus = &lpci_bus;
 689
 690        if (disable)
 691                func = pciehp_slot_find(func->bus, func->device, index++);
 692
 693        while ((func != NULL) && func->is_a_board) {
 694                pci_bus->number = func->bus;
 695                devfn = PCI_DEVFN(func->device, func->function);
 696
 697                /* Save the command register */
 698                pci_bus_read_config_word (pci_bus, devfn, PCI_COMMAND, &save_command);
 699
 700                if (disable) {
 701                        /* Disable card */
 702                        command = 0x00;
 703                        pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
 704                }
 705
 706                /* Check for Bridge */
 707                pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
 708
 709                if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {     /* PCI-PCI Bridge */
 710                        dbg("Save_used_res of PCI bridge b:d=0x%x:%x, sc=0x%x\n", func->bus, func->device, save_command);
 711                        if (disable) {
 712                                /* Clear Bridge Control Register */
 713                                command = 0x00;
 714                                pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
 715                        }
 716
 717                        pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
 718                        pci_bus_read_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
 719
 720                        bus_node =(struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
 721                        if (!bus_node)
 722                                return -ENOMEM;
 723
 724                        bus_node->base = (ulong)secondary_bus;
 725                        bus_node->length = (ulong)(temp_byte - secondary_bus + 1);
 726
 727                        bus_node->next = func->bus_head;
 728                        func->bus_head = bus_node;
 729
 730                        /* Save IO base and Limit registers */
 731                        pci_bus_read_config_byte (pci_bus, devfn, PCI_IO_BASE, &temp_byte);
 732                        base = temp_byte;
 733                        pci_bus_read_config_byte (pci_bus, devfn, PCI_IO_LIMIT, &temp_byte);
 734                        length = temp_byte;
 735
 736                        if ((base <= length) && (!disable || (save_command & PCI_COMMAND_IO))) {
 737                                io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
 738                                if (!io_node)
 739                                        return -ENOMEM;
 740
 741                                io_node->base = (ulong)(base & PCI_IO_RANGE_MASK) << 8;
 742                                io_node->length = (ulong)(length - base + 0x10) << 8;
 743
 744                                io_node->next = func->io_head;
 745                                func->io_head = io_node;
 746                        }
 747
 748                        /* Save memory base and Limit registers */
 749                        pci_bus_read_config_word (pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
 750                        pci_bus_read_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
 751
 752                        if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
 753                                mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
 754                                if (!mem_node)
 755                                        return -ENOMEM;
 756
 757                                mem_node->base = (ulong)w_base << 16;
 758                                mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
 759
 760                                mem_node->next = func->mem_head;
 761                                func->mem_head = mem_node;
 762                        }
 763                        /* Save prefetchable memory base and Limit registers */
 764                        pci_bus_read_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
 765                        pci_bus_read_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
 766
 767                        if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
 768                                p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
 769                                if (!p_mem_node)
 770                                        return -ENOMEM;
 771
 772                                p_mem_node->base = (ulong)w_base << 16;
 773                                p_mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
 774
 775                                p_mem_node->next = func->p_mem_head;
 776                                func->p_mem_head = p_mem_node;
 777                        }
 778                } else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
 779                        dbg("Save_used_res of PCI adapter b:d=0x%x:%x, sc=0x%x\n", func->bus, func->device, save_command);
 780
 781                        /* Figure out IO and memory base lengths */
 782                        for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
 783                                pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
 784
 785                                temp_register = 0xFFFFFFFF;
 786                                pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
 787                                pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp_register);
 788
 789                                if (!disable) {
 790                                        pci_bus_write_config_dword (pci_bus, devfn, cloop, save_base);
 791                                }
 792
 793                                if (!temp_register)
 794                                        continue;
 795
 796                                base = temp_register;
 797
 798                                if ((base & PCI_BASE_ADDRESS_SPACE_IO) && (!disable || (save_command & PCI_COMMAND_IO))) {
 799                                        /* IO base */
 800                                        /* Set temp_register = amount of IO space requested */
 801                                        base = base & 0xFFFFFFFCL;
 802                                        base = (~base) + 1;
 803
 804                                        io_node = (struct pci_resource *) kmalloc(sizeof (struct pci_resource), GFP_KERNEL);
 805                                        if (!io_node)
 806                                                return -ENOMEM;
 807
 808                                        io_node->base = (ulong)save_base & PCI_BASE_ADDRESS_IO_MASK;
 809                                        io_node->length = (ulong)base;
 810                                        dbg("sur adapter: IO bar=0x%x(length=0x%x)\n", io_node->base, io_node->length);
 811
 812                                        io_node->next = func->io_head;
 813                                        func->io_head = io_node;
 814                                } else {  /* Map Memory */
 815                                        int prefetchable = 1;
 816                                        /* struct pci_resources **res_node; */
 817                                        char *res_type_str = "PMEM";
 818                                        u32 temp_register2;
 819
 820                                        t_mem_node = (struct pci_resource *) kmalloc(sizeof (struct pci_resource), GFP_KERNEL);
 821                                        if (!t_mem_node)
 822                                                return -ENOMEM;
 823
 824                                        if (!(base & PCI_BASE_ADDRESS_MEM_PREFETCH) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
 825                                                prefetchable = 0;
 826                                                mem_node = t_mem_node;
 827                                                res_type_str++;
 828                                        } else
 829                                                p_mem_node = t_mem_node;
 830
 831                                        base = base & 0xFFFFFFF0L;
 832                                        base = (~base) + 1;
 833
 834                                        switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
 835                                        case PCI_BASE_ADDRESS_MEM_TYPE_32:
 836                                                if (prefetchable) {
 837                                                        p_mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
 838                                                        p_mem_node->length = (ulong)base;
 839                                                        dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n", res_type_str, p_mem_node->base, p_mem_node->length);
 840
 841                                                        p_mem_node->next = func->p_mem_head;
 842                                                        func->p_mem_head = p_mem_node;
 843                                                } else {
 844                                                        mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
 845                                                        mem_node->length = (ulong)base;
 846                                                        dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n", res_type_str, mem_node->base, mem_node->length);
 847
 848                                                        mem_node->next = func->mem_head;
 849                                                        func->mem_head = mem_node;
 850                                                }
 851                                                break;
 852                                        case PCI_BASE_ADDRESS_MEM_TYPE_64:
 853                                                pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
 854                                                base64 = temp_register2;
 855                                                base64 = (base64 << 32) | save_base;
 856
 857                                                if (temp_register2) {
 858                                                        dbg("sur adapter: 64 %s high dword of base64(0x%x:%x) masked to 0\n", res_type_str, temp_register2, (u32)base64);
 859                                                        base64 &= 0x00000000FFFFFFFFL;
 860                                                }
 861
 862                                                if (prefetchable) {
 863                                                        p_mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
 864                                                        p_mem_node->length = base;
 865                                                        dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n", res_type_str, p_mem_node->base, p_mem_node->length);
 866
 867                                                        p_mem_node->next = func->p_mem_head;
 868                                                        func->p_mem_head = p_mem_node;
 869                                                } else {
 870                                                        mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
 871                                                        mem_node->length = base;
 872                                                        dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n", res_type_str, mem_node->base, mem_node->length);
 873
 874                                                        mem_node->next = func->mem_head;
 875                                                        func->mem_head = mem_node;
 876                                                }
 877                                                cloop += 4;
 878                                                break;
 879                                        default:
 880                                                dbg("asur: reserved BAR type=0x%x\n", temp_register);
 881                                                break;
 882                                        }
 883                                } 
 884                        }       /* End of base register loop */
 885                } else {        /* Some other unknown header type */
 886                        dbg("Save_used_res of PCI unknown type b:d=0x%x:%x. skip.\n", func->bus, func->device);
 887                }
 888
 889                /* Find the next device in this slot */
 890                if (!disable)
 891                        break;
 892                func = pciehp_slot_find(func->bus, func->device, index++);
 893        }
 894
 895        return(0);
 896}
 897
 898
 899/*
 900 * pciehp_return_board_resources
 901 *
 902 * this routine returns all resources allocated to a board to
 903 * the available pool.
 904 *
 905 * returns 0 if success
 906 */
 907int pciehp_return_board_resources(struct pci_func * func, struct resource_lists * resources)
 908{
 909        int rc = 0;
 910        struct pci_resource *node;
 911        struct pci_resource *t_node;
 912        dbg("%s\n", __FUNCTION__);
 913
 914        if (!func)
 915                return(1);
 916
 917        node = func->io_head;
 918        func->io_head = NULL;
 919        while (node) {
 920                t_node = node->next;
 921                return_resource(&(resources->io_head), node);
 922                node = t_node;
 923        }
 924
 925        node = func->mem_head;
 926        func->mem_head = NULL;
 927        while (node) {
 928                t_node = node->next;
 929                return_resource(&(resources->mem_head), node);
 930                node = t_node;
 931        }
 932
 933        node = func->p_mem_head;
 934        func->p_mem_head = NULL;
 935        while (node) {
 936                t_node = node->next;
 937                return_resource(&(resources->p_mem_head), node);
 938                node = t_node;
 939        }
 940
 941        node = func->bus_head;
 942        func->bus_head = NULL;
 943        while (node) {
 944                t_node = node->next;
 945                return_resource(&(resources->bus_head), node);
 946                node = t_node;
 947        }
 948
 949        rc |= pciehp_resource_sort_and_combine(&(resources->mem_head));
 950        rc |= pciehp_resource_sort_and_combine(&(resources->p_mem_head));
 951        rc |= pciehp_resource_sort_and_combine(&(resources->io_head));
 952        rc |= pciehp_resource_sort_and_combine(&(resources->bus_head));
 953
 954        return(rc);
 955}
 956
 957
 958/*
 959 * pciehp_destroy_resource_list
 960 *
 961 * Puts node back in the resource list pointed to by head
 962 */
 963void pciehp_destroy_resource_list (struct resource_lists * resources)
 964{
 965        struct pci_resource *res, *tres;
 966
 967        res = resources->io_head;
 968        resources->io_head = NULL;
 969
 970        while (res) {
 971                tres = res;
 972                res = res->next;
 973                kfree(tres);
 974        }
 975
 976        res = resources->mem_head;
 977        resources->mem_head = NULL;
 978
 979        while (res) {
 980                tres = res;
 981                res = res->next;
 982                kfree(tres);
 983        }
 984
 985        res = resources->p_mem_head;
 986        resources->p_mem_head = NULL;
 987
 988        while (res) {
 989                tres = res;
 990                res = res->next;
 991                kfree(tres);
 992        }
 993
 994        res = resources->bus_head;
 995        resources->bus_head = NULL;
 996
 997        while (res) {
 998                tres = res;
 999                res = res->next;
1000                kfree(tres);
1001        }
1002}
1003
1004
1005/*
1006 * pciehp_destroy_board_resources
1007 *
1008 * Puts node back in the resource list pointed to by head
1009 */
1010void pciehp_destroy_board_resources (struct pci_func * func)
1011{
1012        struct pci_resource *res, *tres;
1013
1014        res = func->io_head;
1015        func->io_head = NULL;
1016
1017        while (res) {
1018                tres = res;
1019                res = res->next;
1020                kfree(tres);
1021        }
1022
1023        res = func->mem_head;
1024        func->mem_head = NULL;
1025
1026        while (res) {
1027                tres = res;
1028                res = res->next;
1029                kfree(tres);
1030        }
1031
1032        res = func->p_mem_head;
1033        func->p_mem_head = NULL;
1034
1035        while (res) {
1036                tres = res;
1037                res = res->next;
1038                kfree(tres);
1039        }
1040
1041        res = func->bus_head;
1042        func->bus_head = NULL;
1043
1044        while (res) {
1045                tres = res;
1046                res = res->next;
1047                kfree(tres);
1048        }
1049}
1050
1051
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.