1*4882a593Smuzhiyun========= 2*4882a593SmuzhiyunBus Types 3*4882a593Smuzhiyun========= 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunDefinition 6*4882a593Smuzhiyun~~~~~~~~~~ 7*4882a593SmuzhiyunSee the kerneldoc for the struct bus_type. 8*4882a593Smuzhiyun 9*4882a593Smuzhiyunint bus_register(struct bus_type * bus); 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun 12*4882a593SmuzhiyunDeclaration 13*4882a593Smuzhiyun~~~~~~~~~~~ 14*4882a593Smuzhiyun 15*4882a593SmuzhiyunEach bus type in the kernel (PCI, USB, etc) should declare one static 16*4882a593Smuzhiyunobject of this type. They must initialize the name field, and may 17*4882a593Smuzhiyunoptionally initialize the match callback:: 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun struct bus_type pci_bus_type = { 20*4882a593Smuzhiyun .name = "pci", 21*4882a593Smuzhiyun .match = pci_bus_match, 22*4882a593Smuzhiyun }; 23*4882a593Smuzhiyun 24*4882a593SmuzhiyunThe structure should be exported to drivers in a header file: 25*4882a593Smuzhiyun 26*4882a593Smuzhiyunextern struct bus_type pci_bus_type; 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun 29*4882a593SmuzhiyunRegistration 30*4882a593Smuzhiyun~~~~~~~~~~~~ 31*4882a593Smuzhiyun 32*4882a593SmuzhiyunWhen a bus driver is initialized, it calls bus_register. This 33*4882a593Smuzhiyuninitializes the rest of the fields in the bus object and inserts it 34*4882a593Smuzhiyuninto a global list of bus types. Once the bus object is registered, 35*4882a593Smuzhiyunthe fields in it are usable by the bus driver. 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun 38*4882a593SmuzhiyunCallbacks 39*4882a593Smuzhiyun~~~~~~~~~ 40*4882a593Smuzhiyun 41*4882a593Smuzhiyunmatch(): Attaching Drivers to Devices 42*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 43*4882a593Smuzhiyun 44*4882a593SmuzhiyunThe format of device ID structures and the semantics for comparing 45*4882a593Smuzhiyunthem are inherently bus-specific. Drivers typically declare an array 46*4882a593Smuzhiyunof device IDs of devices they support that reside in a bus-specific 47*4882a593Smuzhiyundriver structure. 48*4882a593Smuzhiyun 49*4882a593SmuzhiyunThe purpose of the match callback is to give the bus an opportunity to 50*4882a593Smuzhiyundetermine if a particular driver supports a particular device by 51*4882a593Smuzhiyuncomparing the device IDs the driver supports with the device ID of a 52*4882a593Smuzhiyunparticular device, without sacrificing bus-specific functionality or 53*4882a593Smuzhiyuntype-safety. 54*4882a593Smuzhiyun 55*4882a593SmuzhiyunWhen a driver is registered with the bus, the bus's list of devices is 56*4882a593Smuzhiyuniterated over, and the match callback is called for each device that 57*4882a593Smuzhiyundoes not have a driver associated with it. 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun 61*4882a593SmuzhiyunDevice and Driver Lists 62*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~ 63*4882a593Smuzhiyun 64*4882a593SmuzhiyunThe lists of devices and drivers are intended to replace the local 65*4882a593Smuzhiyunlists that many buses keep. They are lists of struct devices and 66*4882a593Smuzhiyunstruct device_drivers, respectively. Bus drivers are free to use the 67*4882a593Smuzhiyunlists as they please, but conversion to the bus-specific type may be 68*4882a593Smuzhiyunnecessary. 69*4882a593Smuzhiyun 70*4882a593SmuzhiyunThe LDM core provides helper functions for iterating over each list:: 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun int bus_for_each_dev(struct bus_type * bus, struct device * start, 73*4882a593Smuzhiyun void * data, 74*4882a593Smuzhiyun int (*fn)(struct device *, void *)); 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, 77*4882a593Smuzhiyun void * data, int (*fn)(struct device_driver *, void *)); 78*4882a593Smuzhiyun 79*4882a593SmuzhiyunThese helpers iterate over the respective list, and call the callback 80*4882a593Smuzhiyunfor each device or driver in the list. All list accesses are 81*4882a593Smuzhiyunsynchronized by taking the bus's lock (read currently). The reference 82*4882a593Smuzhiyuncount on each object in the list is incremented before the callback is 83*4882a593Smuzhiyuncalled; it is decremented after the next object has been obtained. The 84*4882a593Smuzhiyunlock is not held when calling the callback. 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun 87*4882a593Smuzhiyunsysfs 88*4882a593Smuzhiyun~~~~~~~~ 89*4882a593SmuzhiyunThere is a top-level directory named 'bus'. 90*4882a593Smuzhiyun 91*4882a593SmuzhiyunEach bus gets a directory in the bus directory, along with two default 92*4882a593Smuzhiyundirectories:: 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun /sys/bus/pci/ 95*4882a593Smuzhiyun |-- devices 96*4882a593Smuzhiyun `-- drivers 97*4882a593Smuzhiyun 98*4882a593SmuzhiyunDrivers registered with the bus get a directory in the bus's drivers 99*4882a593Smuzhiyundirectory:: 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun /sys/bus/pci/ 102*4882a593Smuzhiyun |-- devices 103*4882a593Smuzhiyun `-- drivers 104*4882a593Smuzhiyun |-- Intel ICH 105*4882a593Smuzhiyun |-- Intel ICH Joystick 106*4882a593Smuzhiyun |-- agpgart 107*4882a593Smuzhiyun `-- e100 108*4882a593Smuzhiyun 109*4882a593SmuzhiyunEach device that is discovered on a bus of that type gets a symlink in 110*4882a593Smuzhiyunthe bus's devices directory to the device's directory in the physical 111*4882a593Smuzhiyunhierarchy:: 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun /sys/bus/pci/ 114*4882a593Smuzhiyun |-- devices 115*4882a593Smuzhiyun | |-- 00:00.0 -> ../../../root/pci0/00:00.0 116*4882a593Smuzhiyun | |-- 00:01.0 -> ../../../root/pci0/00:01.0 117*4882a593Smuzhiyun | `-- 00:02.0 -> ../../../root/pci0/00:02.0 118*4882a593Smuzhiyun `-- drivers 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun 121*4882a593SmuzhiyunExporting Attributes 122*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~ 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun:: 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun struct bus_attribute { 127*4882a593Smuzhiyun struct attribute attr; 128*4882a593Smuzhiyun ssize_t (*show)(struct bus_type *, char * buf); 129*4882a593Smuzhiyun ssize_t (*store)(struct bus_type *, const char * buf, size_t count); 130*4882a593Smuzhiyun }; 131*4882a593Smuzhiyun 132*4882a593SmuzhiyunBus drivers can export attributes using the BUS_ATTR_RW macro that works 133*4882a593Smuzhiyunsimilarly to the DEVICE_ATTR_RW macro for devices. For example, a 134*4882a593Smuzhiyundefinition like this:: 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun static BUS_ATTR_RW(debug); 137*4882a593Smuzhiyun 138*4882a593Smuzhiyunis equivalent to declaring:: 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun static bus_attribute bus_attr_debug; 141*4882a593Smuzhiyun 142*4882a593SmuzhiyunThis can then be used to add and remove the attribute from the bus's 143*4882a593Smuzhiyunsysfs directory using:: 144*4882a593Smuzhiyun 145*4882a593Smuzhiyun int bus_create_file(struct bus_type *, struct bus_attribute *); 146*4882a593Smuzhiyun void bus_remove_file(struct bus_type *, struct bus_attribute *); 147