~~~~~~~~~~
struct bus_type {
- char * name;
- rwlock_t lock;
- atomic_t refcount;
+ char * name;
- struct list_head node;
- struct list_head devices;
- struct list_head drivers;
+ struct subsystem subsys;
+ struct kset drivers;
+ struct kset devices;
- struct driver_dir_entry dir;
- struct driver_dir_entry device_dir;
- struct driver_dir_entry driver_dir;
+ struct bus_attribute * bus_attrs;
+ struct device_attribute * dev_attrs;
+ struct driver_attribute * drv_attrs;
- int (*match) (struct device * dev, struct device_driver * drv);
- struct device (*add) (struct device * parent, char * bus_id);
+ int (*match)(struct device * dev, struct device_driver * drv);
+ int (*hotplug) (struct device *dev, char **envp,
+ int num_envp, char *buffer, int buffer_size);
+ int (*suspend)(struct device * dev, u32 state);
+ int (*resume)(struct device * dev);
};
int bus_register(struct bus_type * bus);
When a bus driver is initialized, it calls bus_register. This
initializes the rest of the fields in the bus object and inserts it
into a global list of bus types. Once the bus object is registered,
-the fields in it (e.g. the rwlock_t) are usable by the bus driver.
+the fields in it are usable by the bus driver.
Callbacks
iterated over, and the match callback is called for each device that
does not have a driver associated with it.
-add(): Adding a child device
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The add callback is available to notify the bus about a child device
-at a particular location.
-
-The parent parameter is the parent device of the child to be added. If
-parent == NULL, the bus should add the device as a child of a default
-parent device or as a child of the root. This policy decision is up to
-the bus driver.
-
-The format of the bus_id field should be consistent with the format of
-the bus_id field of the rest of the devices on the bus. This requires
-the caller to know the format.
-
-On return, the bus driver should return a pointer to the device that
-was created. If the device was not created, the bus driver should
-return an appropriate error code. Refer to include/linux/err.h for
-helper functions to encode errors. Some sample code:
-
-struct device * pci_bus_add(struct device * parent, char * bus_id)
-{
- ...
- /* the device already exists */
- return ERR_PTR(-EEXIST);
- ...
-}
-
-The caller can check the return value using IS_ERR():
-
- struct device * newdev = pci_bus_type.add(parent,bus_id);
- if (IS_ERR(newdev)) {
- ...
- }
Device and Driver Lists
The LDM core provides helper functions for iterating over each list.
-int bus_for_each_dev(struct bus_type * bus, void * data,
- int (*callback)(struct device * dev, void * data));
-int bus_for_each_drv(struct bus_type * bus, void * data,
- int (*callback)(struct device_driver * drv, void * data));
+int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data,
+ int (*fn)(struct device *, void *));
+
+int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
+ void * data, int (*fn)(struct device_driver *, void *));
These helpers iterate over the respective list, and call the callback
for each device or driver in the list. All list accesses are
Exporting Attributes
~~~~~~~~~~~~~~~~~~~~
struct bus_attribute {
- struct attribute attr;
- ssize_t (*show)(struct bus_type *, char * buf, size_t count, loff_t off);
- ssize_t (*store)(struct bus_type *, const char * buf, size_t count, loff_t off);
+ struct attribute attr;
+ ssize_t (*show)(struct bus_type *, char * buf);
+ ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
};
Bus drivers can export attributes using the BUS_ATTR macro that works