linux/drivers/base/bus.c
<<
>>
Prefs
   1/*
   2 * bus.c - bus driver management
   3 *
   4 * Copyright (c) 2002-3 Patrick Mochel
   5 * Copyright (c) 2002-3 Open Source Development Labs
   6 *
   7 * This file is released under the GPLv2
   8 *
   9 */
  10
  11#include <linux/config.h>
  12#include <linux/device.h>
  13#include <linux/module.h>
  14#include <linux/errno.h>
  15#include <linux/init.h>
  16#include <linux/string.h>
  17#include "base.h"
  18#include "power/power.h"
  19
  20#define to_dev(node) container_of(node, struct device, bus_list)
  21#define to_drv(node) container_of(node, struct device_driver, kobj.entry)
  22
  23#define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
  24#define to_bus(obj) container_of(obj, struct bus_type, subsys.kset.kobj)
  25
  26/*
  27 * sysfs bindings for drivers
  28 */
  29
  30#define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr)
  31#define to_driver(obj) container_of(obj, struct device_driver, kobj)
  32
  33
  34static ssize_t
  35drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
  36{
  37        struct driver_attribute * drv_attr = to_drv_attr(attr);
  38        struct device_driver * drv = to_driver(kobj);
  39        ssize_t ret = 0;
  40
  41        if (drv_attr->show)
  42                ret = drv_attr->show(drv, buf);
  43        return ret;
  44}
  45
  46static ssize_t
  47drv_attr_store(struct kobject * kobj, struct attribute * attr,
  48               const char * buf, size_t count)
  49{
  50        struct driver_attribute * drv_attr = to_drv_attr(attr);
  51        struct device_driver * drv = to_driver(kobj);
  52        ssize_t ret = 0;
  53
  54        if (drv_attr->store)
  55                ret = drv_attr->store(drv, buf, count);
  56        return ret;
  57}
  58
  59static struct sysfs_ops driver_sysfs_ops = {
  60        .show   = drv_attr_show,
  61        .store  = drv_attr_store,
  62};
  63
  64
  65static void driver_release(struct kobject * kobj)
  66{
  67        struct device_driver * drv = to_driver(kobj);
  68        up(&drv->unload_sem);
  69}
  70
  71static struct kobj_type ktype_driver = {
  72        .sysfs_ops      = &driver_sysfs_ops,
  73        .release        = driver_release,
  74};
  75
  76
  77/*
  78 * sysfs bindings for buses
  79 */
  80
  81
  82static ssize_t
  83bus_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
  84{
  85        struct bus_attribute * bus_attr = to_bus_attr(attr);
  86        struct bus_type * bus = to_bus(kobj);
  87        ssize_t ret = 0;
  88
  89        if (bus_attr->show)
  90                ret = bus_attr->show(bus, buf);
  91        return ret;
  92}
  93
  94static ssize_t
  95bus_attr_store(struct kobject * kobj, struct attribute * attr,
  96               const char * buf, size_t count)
  97{
  98        struct bus_attribute * bus_attr = to_bus_attr(attr);
  99        struct bus_type * bus = to_bus(kobj);
 100        ssize_t ret = 0;
 101
 102        if (bus_attr->store)
 103                ret = bus_attr->store(bus, buf, count);
 104        return ret;
 105}
 106
 107static struct sysfs_ops bus_sysfs_ops = {
 108        .show   = bus_attr_show,
 109        .store  = bus_attr_store,
 110};
 111
 112int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
 113{
 114        int error;
 115        if (get_bus(bus)) {
 116                error = sysfs_create_file(&bus->subsys.kset.kobj, &attr->attr);
 117                put_bus(bus);
 118        } else
 119                error = -EINVAL;
 120        return error;
 121}
 122
 123void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
 124{
 125        if (get_bus(bus)) {
 126                sysfs_remove_file(&bus->subsys.kset.kobj, &attr->attr);
 127                put_bus(bus);
 128        }
 129}
 130
 131static struct kobj_type ktype_bus = {
 132        .sysfs_ops      = &bus_sysfs_ops,
 133
 134};
 135
 136decl_subsys(bus, &ktype_bus, NULL);
 137
 138static int __bus_for_each_dev(struct bus_type *bus, struct device *start,
 139                              void *data, int (*fn)(struct device *, void *))
 140{
 141        struct list_head *head;
 142        struct device *dev;
 143        int error = 0;
 144
 145        if (!(bus = get_bus(bus)))
 146                return -EINVAL;
 147
 148        head = &bus->devices.list;
 149        dev = list_prepare_entry(start, head, bus_list);
 150        list_for_each_entry_continue(dev, head, bus_list) {
 151                get_device(dev);
 152                error = fn(dev, data);
 153                put_device(dev);
 154                if (error)
 155                        break;
 156        }
 157        put_bus(bus);
 158        return error;
 159}
 160
 161static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
 162                              void * data, int (*fn)(struct device_driver *, void *))
 163{
 164        struct list_head *head;
 165        struct device_driver *drv;
 166        int error = 0;
 167
 168        if (!(bus = get_bus(bus)))
 169                return -EINVAL;
 170
 171        head = &bus->drivers.list;
 172        drv = list_prepare_entry(start, head, kobj.entry);
 173        list_for_each_entry_continue(drv, head, kobj.entry) {
 174                get_driver(drv);
 175                error = fn(drv, data);
 176                put_driver(drv);
 177                if (error)
 178                        break;
 179        }
 180        put_bus(bus);
 181        return error;
 182}
 183
 184/**
 185 *      bus_for_each_dev - device iterator.
 186 *      @bus:   bus type.
 187 *      @start: device to start iterating from.
 188 *      @data:  data for the callback.
 189 *      @fn:    function to be called for each device.
 190 *
 191 *      Iterate over @bus's list of devices, and call @fn for each,
 192 *      passing it @data. If @start is not NULL, we use that device to
 193 *      begin iterating from.
 194 *
 195 *      We check the return of @fn each time. If it returns anything
 196 *      other than 0, we break out and return that value.
 197 *
 198 *      NOTE: The device that returns a non-zero value is not retained
 199 *      in any way, nor is its refcount incremented. If the caller needs
 200 *      to retain this data, it should do, and increment the reference
 201 *      count in the supplied callback.
 202 */
 203
 204int bus_for_each_dev(struct bus_type * bus, struct device * start,
 205                     void * data, int (*fn)(struct device *, void *))
 206{
 207        int ret;
 208
 209        down_read(&bus->subsys.rwsem);
 210        ret = __bus_for_each_dev(bus, start, data, fn);
 211        up_read(&bus->subsys.rwsem);
 212        return ret;
 213}
 214
 215/**
 216 *      bus_for_each_drv - driver iterator
 217 *      @bus:   bus we're dealing with.
 218 *      @start: driver to start iterating on.
 219 *      @data:  data to pass to the callback.
 220 *      @fn:    function to call for each driver.
 221 *
 222 *      This is nearly identical to the device iterator above.
 223 *      We iterate over each driver that belongs to @bus, and call
 224 *      @fn for each. If @fn returns anything but 0, we break out
 225 *      and return it. If @start is not NULL, we use it as the head
 226 *      of the list.
 227 *
 228 *      NOTE: we don't return the driver that returns a non-zero
 229 *      value, nor do we leave the reference count incremented for that
 230 *      driver. If the caller needs to know that info, it must set it
 231 *      in the callback. It must also be sure to increment the refcount
 232 *      so it doesn't disappear before returning to the caller.
 233 */
 234
 235int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
 236                     void * data, int (*fn)(struct device_driver *, void *))
 237{
 238        int ret;
 239
 240        down_read(&bus->subsys.rwsem);
 241        ret = __bus_for_each_drv(bus, start, data, fn);
 242        up_read(&bus->subsys.rwsem);
 243        return ret;
 244}
 245
 246/**
 247 *      device_bind_driver - bind a driver to one device.
 248 *      @dev:   device.
 249 *
 250 *      Allow manual attachment of a driver to a device.
 251 *      Caller must have already set @dev->driver.
 252 *
 253 *      Note that this does not modify the bus reference count
 254 *      nor take the bus's rwsem. Please verify those are accounted
 255 *      for before calling this. (It is ok to call with no other effort
 256 *      from a driver's probe() method.)
 257 */
 258
 259void device_bind_driver(struct device * dev)
 260{
 261        pr_debug("bound device '%s' to driver '%s'\n",
 262                 dev->bus_id, dev->driver->name);
 263        list_add_tail(&dev->driver_list, &dev->driver->devices);
 264        sysfs_create_link(&dev->driver->kobj, &dev->kobj,
 265                          kobject_name(&dev->kobj));
 266        sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
 267}
 268
 269
 270/**
 271 *      driver_probe_device - attempt to bind device & driver.
 272 *      @drv:   driver.
 273 *      @dev:   device.
 274 *
 275 *      First, we call the bus's match function, if one present, which
 276 *      should compare the device IDs the driver supports with the
 277 *      device IDs of the device. Note we don't do this ourselves
 278 *      because we don't know the format of the ID structures, nor what
 279 *      is to be considered a match and what is not.
 280 *
 281 *      If we find a match, we call @drv->probe(@dev) if it exists, and
 282 *      call device_bind_driver() above.
 283 */
 284int driver_probe_device(struct device_driver * drv, struct device * dev)
 285{
 286        if (drv->bus->match && !drv->bus->match(dev, drv))
 287                return -ENODEV;
 288
 289        dev->driver = drv;
 290        if (drv->probe) {
 291                int error = drv->probe(dev);
 292                if (error) {
 293                        dev->driver = NULL;
 294                        return error;
 295                }
 296        }
 297
 298        device_bind_driver(dev);
 299        return 0;
 300}
 301
 302
 303/**
 304 *      device_attach - try to attach device to a driver.
 305 *      @dev:   device.
 306 *
 307 *      Walk the list of drivers that the bus has and call
 308 *      driver_probe_device() for each pair. If a compatible
 309 *      pair is found, break out and return.
 310 */
 311int device_attach(struct device * dev)
 312{
 313        struct bus_type * bus = dev->bus;
 314        struct list_head * entry;
 315        int error;
 316
 317        if (dev->driver) {
 318                device_bind_driver(dev);
 319                return 1;
 320        }
 321
 322        if (bus->match) {
 323                list_for_each(entry, &bus->drivers.list) {
 324                        struct device_driver * drv = to_drv(entry);
 325                        error = driver_probe_device(drv, dev);
 326                        if (!error)
 327                                /* success, driver matched */
 328                                return 1;
 329                        if (error != -ENODEV && error != -ENXIO)
 330                                /* driver matched but the probe failed */
 331                                printk(KERN_WARNING
 332                                    "%s: probe of %s failed with error %d\n",
 333                                    drv->name, dev->bus_id, error);
 334                }
 335        }
 336
 337        return 0;
 338}
 339
 340
 341/**
 342 *      driver_attach - try to bind driver to devices.
 343 *      @drv:   driver.
 344 *
 345 *      Walk the list of devices that the bus has on it and try to
 346 *      match the driver with each one.  If driver_probe_device()
 347 *      returns 0 and the @dev->driver is set, we've found a
 348 *      compatible pair.
 349 *
 350 *      Note that we ignore the -ENODEV error from driver_probe_device(),
 351 *      since it's perfectly valid for a driver not to bind to any devices.
 352 */
 353void driver_attach(struct device_driver * drv)
 354{
 355        struct bus_type * bus = drv->bus;
 356        struct list_head * entry;
 357        int error;
 358
 359        if (!bus->match)
 360                return;
 361
 362        list_for_each(entry, &bus->devices.list) {
 363                struct device * dev = container_of(entry, struct device, bus_list);
 364                if (!dev->driver) {
 365                        error = driver_probe_device(drv, dev);
 366                        if (error && (error != -ENODEV))
 367                                /* driver matched but the probe failed */
 368                                printk(KERN_WARNING
 369                                    "%s: probe of %s failed with error %d\n",
 370                                    drv->name, dev->bus_id, error);
 371                }
 372        }
 373}
 374
 375
 376/**
 377 *      device_release_driver - manually detach device from driver.
 378 *      @dev:   device.
 379 *
 380 *      Manually detach device from driver.
 381 *      Note that this is called without incrementing the bus
 382 *      reference count nor taking the bus's rwsem. Be sure that
 383 *      those are accounted for before calling this function.
 384 */
 385
 386void device_release_driver(struct device * dev)
 387{
 388        struct device_driver * drv = dev->driver;
 389        if (drv) {
 390                sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
 391                sysfs_remove_link(&dev->kobj, "driver");
 392                list_del_init(&dev->driver_list);
 393                device_detach_shutdown(dev);
 394                if (drv->remove)
 395                        drv->remove(dev);
 396                dev->driver = NULL;
 397        }
 398}
 399
 400
 401/**
 402 *      driver_detach - detach driver from all devices it controls.
 403 *      @drv:   driver.
 404 */
 405
 406static void driver_detach(struct device_driver * drv)
 407{
 408        struct list_head * entry, * next;
 409        list_for_each_safe(entry, next, &drv->devices) {
 410                struct device * dev = container_of(entry, struct device, driver_list);
 411                device_release_driver(dev);
 412        }
 413}
 414
 415static int device_add_attrs(struct bus_type * bus, struct device * dev)
 416{
 417        int error = 0;
 418        int i;
 419
 420        if (bus->dev_attrs) {
 421                for (i = 0; attr_name(bus->dev_attrs[i]); i++) {
 422                        error = device_create_file(dev,&bus->dev_attrs[i]);
 423                        if (error)
 424                                goto Err;
 425                }
 426        }
 427 Done:
 428        return error;
 429 Err:
 430        while (--i >= 0)
 431                device_remove_file(dev,&bus->dev_attrs[i]);
 432        goto Done;
 433}
 434
 435
 436static void device_remove_attrs(struct bus_type * bus, struct device * dev)
 437{
 438        int i;
 439
 440        if (bus->dev_attrs) {
 441                for (i = 0; attr_name(bus->dev_attrs[i]); i++)
 442                        device_remove_file(dev,&bus->dev_attrs[i]);
 443        }
 444}
 445
 446
 447/**
 448 *      bus_add_device - add device to bus
 449 *      @dev:   device being added
 450 *
 451 *      - Add the device to its bus's list of devices.
 452 *      - Try to attach to driver.
 453 *      - Create link to device's physical location.
 454 */
 455int bus_add_device(struct device * dev)
 456{
 457        struct bus_type * bus = get_bus(dev->bus);
 458        int error = 0;
 459
 460        if (bus) {
 461                down_write(&dev->bus->subsys.rwsem);
 462                pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
 463                list_add_tail(&dev->bus_list, &dev->bus->devices.list);
 464                device_attach(dev);
 465                up_write(&dev->bus->subsys.rwsem);
 466                device_add_attrs(bus, dev);
 467                sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
 468        }
 469        return error;
 470}
 471
 472/**
 473 *      bus_remove_device - remove device from bus
 474 *      @dev:   device to be removed
 475 *
 476 *      - Remove symlink from bus's directory.
 477 *      - Delete device from bus's list.
 478 *      - Detach from its driver.
 479 *      - Drop reference taken in bus_add_device().
 480 */
 481void bus_remove_device(struct device * dev)
 482{
 483        if (dev->bus) {
 484                sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
 485                device_remove_attrs(dev->bus, dev);
 486                down_write(&dev->bus->subsys.rwsem);
 487                pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
 488                device_release_driver(dev);
 489                list_del_init(&dev->bus_list);
 490                up_write(&dev->bus->subsys.rwsem);
 491                put_bus(dev->bus);
 492        }
 493}
 494
 495static int driver_add_attrs(struct bus_type * bus, struct device_driver * drv)
 496{
 497        int error = 0;
 498        int i;
 499
 500        if (bus->drv_attrs) {
 501                for (i = 0; attr_name(bus->drv_attrs[i]); i++) {
 502                        error = driver_create_file(drv, &bus->drv_attrs[i]);
 503                        if (error)
 504                                goto Err;
 505                }
 506        }
 507 Done:
 508        return error;
 509 Err:
 510        while (--i >= 0)
 511                driver_remove_file(drv, &bus->drv_attrs[i]);
 512        goto Done;
 513}
 514
 515
 516static void driver_remove_attrs(struct bus_type * bus, struct device_driver * drv)
 517{
 518        int i;
 519
 520        if (bus->drv_attrs) {
 521                for (i = 0; attr_name(bus->drv_attrs[i]); i++)
 522                        driver_remove_file(drv, &bus->drv_attrs[i]);
 523        }
 524}
 525
 526
 527/**
 528 *      bus_add_driver - Add a driver to the bus.
 529 *      @drv:   driver.
 530 *
 531 */
 532int bus_add_driver(struct device_driver * drv)
 533{
 534        struct bus_type * bus = get_bus(drv->bus);
 535        int error = 0;
 536
 537        if (bus) {
 538                pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
 539                error = kobject_set_name(&drv->kobj, "%s", drv->name);
 540                if (error) {
 541                        put_bus(bus);
 542                        return error;
 543                }
 544                drv->kobj.kset = &bus->drivers;
 545                if ((error = kobject_register(&drv->kobj))) {
 546                        put_bus(bus);
 547                        return error;
 548                }
 549
 550                down_write(&bus->subsys.rwsem);
 551                driver_attach(drv);
 552                up_write(&bus->subsys.rwsem);
 553                module_add_driver(drv->owner, drv);
 554
 555                driver_add_attrs(bus, drv);
 556        }
 557        return error;
 558}
 559
 560
 561/**
 562 *      bus_remove_driver - delete driver from bus's knowledge.
 563 *      @drv:   driver.
 564 *
 565 *      Detach the driver from the devices it controls, and remove
 566 *      it from its bus's list of drivers. Finally, we drop the reference
 567 *      to the bus we took in bus_add_driver().
 568 */
 569
 570void bus_remove_driver(struct device_driver * drv)
 571{
 572        if (drv->bus) {
 573                driver_remove_attrs(drv->bus, drv);
 574                down_write(&drv->bus->subsys.rwsem);
 575                pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
 576                driver_detach(drv);
 577                up_write(&drv->bus->subsys.rwsem);
 578                module_remove_driver(drv);
 579                kobject_unregister(&drv->kobj);
 580                put_bus(drv->bus);
 581        }
 582}
 583
 584
 585/* Helper for bus_rescan_devices's iter */
 586static int bus_rescan_devices_helper(struct device *dev, void *data)
 587{
 588        int *count = data;
 589
 590        if (!dev->driver && device_attach(dev))
 591                (*count)++;
 592
 593        return 0;
 594}
 595
 596
 597/**
 598 *      bus_rescan_devices - rescan devices on the bus for possible drivers
 599 *      @bus:   the bus to scan.
 600 *
 601 *      This function will look for devices on the bus with no driver
 602 *      attached and rescan it against existing drivers to see if it
 603 *      matches any. Calls device_attach(). Returns the number of devices
 604 *      that were sucessfully bound to a driver.
 605 */
 606int bus_rescan_devices(struct bus_type * bus)
 607{
 608        int count = 0;
 609
 610        down_write(&bus->subsys.rwsem);
 611        __bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper);
 612        up_write(&bus->subsys.rwsem);
 613
 614        return count;
 615}
 616
 617
 618struct bus_type * get_bus(struct bus_type * bus)
 619{
 620        return bus ? container_of(subsys_get(&bus->subsys), struct bus_type, subsys) : NULL;
 621}
 622
 623void put_bus(struct bus_type * bus)
 624{
 625        subsys_put(&bus->subsys);
 626}
 627
 628
 629/**
 630 *      find_bus - locate bus by name.
 631 *      @name:  name of bus.
 632 *
 633 *      Call kset_find_obj() to iterate over list of buses to
 634 *      find a bus by name. Return bus if found.
 635 *
 636 *      Note that kset_find_obj increments bus' reference count.
 637 */
 638
 639struct bus_type * find_bus(char * name)
 640{
 641        struct kobject * k = kset_find_obj(&bus_subsys.kset, name);
 642        return k ? to_bus(k) : NULL;
 643}
 644
 645
 646/**
 647 *      bus_add_attrs - Add default attributes for this bus.
 648 *      @bus:   Bus that has just been registered.
 649 */
 650
 651static int bus_add_attrs(struct bus_type * bus)
 652{
 653        int error = 0;
 654        int i;
 655
 656        if (bus->bus_attrs) {
 657                for (i = 0; attr_name(bus->bus_attrs[i]); i++) {
 658                        if ((error = bus_create_file(bus,&bus->bus_attrs[i])))
 659                                goto Err;
 660                }
 661        }
 662 Done:
 663        return error;
 664 Err:
 665        while (--i >= 0)
 666                bus_remove_file(bus,&bus->bus_attrs[i]);
 667        goto Done;
 668}
 669
 670static void bus_remove_attrs(struct bus_type * bus)
 671{
 672        int i;
 673
 674        if (bus->bus_attrs) {
 675                for (i = 0; attr_name(bus->bus_attrs[i]); i++)
 676                        bus_remove_file(bus,&bus->bus_attrs[i]);
 677        }
 678}
 679
 680/**
 681 *      bus_register - register a bus with the system.
 682 *      @bus:   bus.
 683 *
 684 *      Once we have that, we registered the bus with the kobject
 685 *      infrastructure, then register the children subsystems it has:
 686 *      the devices and drivers that belong to the bus.
 687 */
 688int bus_register(struct bus_type * bus)
 689{
 690        int retval;
 691
 692        retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name);
 693        if (retval)
 694                goto out;
 695
 696        subsys_set_kset(bus, bus_subsys);
 697        retval = subsystem_register(&bus->subsys);
 698        if (retval)
 699                goto out;
 700
 701        kobject_set_name(&bus->devices.kobj, "devices");
 702        bus->devices.subsys = &bus->subsys;
 703        retval = kset_register(&bus->devices);
 704        if (retval)
 705                goto bus_devices_fail;
 706
 707        kobject_set_name(&bus->drivers.kobj, "drivers");
 708        bus->drivers.subsys = &bus->subsys;
 709        bus->drivers.ktype = &ktype_driver;
 710        retval = kset_register(&bus->drivers);
 711        if (retval)
 712                goto bus_drivers_fail;
 713        bus_add_attrs(bus);
 714
 715        pr_debug("bus type '%s' registered\n", bus->name);
 716        return 0;
 717
 718bus_drivers_fail:
 719        kset_unregister(&bus->devices);
 720bus_devices_fail:
 721        subsystem_unregister(&bus->subsys);
 722out:
 723        return retval;
 724}
 725
 726
 727/**
 728 *      bus_unregister - remove a bus from the system
 729 *      @bus:   bus.
 730 *
 731 *      Unregister the child subsystems and the bus itself.
 732 *      Finally, we call put_bus() to release the refcount
 733 */
 734void bus_unregister(struct bus_type * bus)
 735{
 736        pr_debug("bus %s: unregistering\n", bus->name);
 737        bus_remove_attrs(bus);
 738        kset_unregister(&bus->drivers);
 739        kset_unregister(&bus->devices);
 740        subsystem_unregister(&bus->subsys);
 741}
 742
 743int __init buses_init(void)
 744{
 745        return subsystem_register(&bus_subsys);
 746}
 747
 748
 749EXPORT_SYMBOL_GPL(bus_for_each_dev);
 750EXPORT_SYMBOL_GPL(bus_for_each_drv);
 751
 752EXPORT_SYMBOL_GPL(driver_probe_device);
 753EXPORT_SYMBOL_GPL(device_bind_driver);
 754EXPORT_SYMBOL_GPL(device_release_driver);
 755EXPORT_SYMBOL_GPL(device_attach);
 756EXPORT_SYMBOL_GPL(driver_attach);
 757
 758EXPORT_SYMBOL_GPL(bus_add_device);
 759EXPORT_SYMBOL_GPL(bus_remove_device);
 760EXPORT_SYMBOL_GPL(bus_register);
 761EXPORT_SYMBOL_GPL(bus_unregister);
 762EXPORT_SYMBOL_GPL(bus_rescan_devices);
 763EXPORT_SYMBOL_GPL(get_bus);
 764EXPORT_SYMBOL_GPL(put_bus);
 765EXPORT_SYMBOL_GPL(find_bus);
 766
 767EXPORT_SYMBOL_GPL(bus_create_file);
 768EXPORT_SYMBOL_GPL(bus_remove_file);
 769
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.