cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

porting.rst (13463B)


      1=======================================
      2Porting Drivers to the New Driver Model
      3=======================================
      4
      5Patrick Mochel
      6
      77 January 2003
      8
      9
     10Overview
     11
     12Please refer to `Documentation/driver-api/driver-model/*.rst` for definitions of
     13various driver types and concepts.
     14
     15Most of the work of porting devices drivers to the new model happens
     16at the bus driver layer. This was intentional, to minimize the
     17negative effect on kernel drivers, and to allow a gradual transition
     18of bus drivers.
     19
     20In a nutshell, the driver model consists of a set of objects that can
     21be embedded in larger, bus-specific objects. Fields in these generic
     22objects can replace fields in the bus-specific objects.
     23
     24The generic objects must be registered with the driver model core. By
     25doing so, they will exported via the sysfs filesystem. sysfs can be
     26mounted by doing::
     27
     28	# mount -t sysfs sysfs /sys
     29
     30
     31
     32The Process
     33
     34Step 0: Read include/linux/device.h for object and function definitions.
     35
     36Step 1: Registering the bus driver.
     37
     38
     39- Define a struct bus_type for the bus driver::
     40
     41    struct bus_type pci_bus_type = {
     42          .name           = "pci",
     43    };
     44
     45
     46- Register the bus type.
     47
     48  This should be done in the initialization function for the bus type,
     49  which is usually the module_init(), or equivalent, function::
     50
     51    static int __init pci_driver_init(void)
     52    {
     53            return bus_register(&pci_bus_type);
     54    }
     55
     56    subsys_initcall(pci_driver_init);
     57
     58
     59  The bus type may be unregistered (if the bus driver may be compiled
     60  as a module) by doing::
     61
     62     bus_unregister(&pci_bus_type);
     63
     64
     65- Export the bus type for others to use.
     66
     67  Other code may wish to reference the bus type, so declare it in a
     68  shared header file and export the symbol.
     69
     70From include/linux/pci.h::
     71
     72  extern struct bus_type pci_bus_type;
     73
     74
     75From file the above code appears in::
     76
     77  EXPORT_SYMBOL(pci_bus_type);
     78
     79
     80
     81- This will cause the bus to show up in /sys/bus/pci/ with two
     82  subdirectories: 'devices' and 'drivers'::
     83
     84    # tree -d /sys/bus/pci/
     85    /sys/bus/pci/
     86    |-- devices
     87    `-- drivers
     88
     89
     90
     91Step 2: Registering Devices.
     92
     93struct device represents a single device. It mainly contains metadata
     94describing the relationship the device has to other entities.
     95
     96
     97- Embed a struct device in the bus-specific device type::
     98
     99
    100    struct pci_dev {
    101           ...
    102           struct  device  dev;            /* Generic device interface */
    103           ...
    104    };
    105
    106  It is recommended that the generic device not be the first item in
    107  the struct to discourage programmers from doing mindless casts
    108  between the object types. Instead macros, or inline functions,
    109  should be created to convert from the generic object type::
    110
    111
    112    #define to_pci_dev(n) container_of(n, struct pci_dev, dev)
    113
    114    or
    115
    116    static inline struct pci_dev * to_pci_dev(struct kobject * kobj)
    117    {
    118	return container_of(n, struct pci_dev, dev);
    119    }
    120
    121  This allows the compiler to verify type-safety of the operations
    122  that are performed (which is Good).
    123
    124
    125- Initialize the device on registration.
    126
    127  When devices are discovered or registered with the bus type, the
    128  bus driver should initialize the generic device. The most important
    129  things to initialize are the bus_id, parent, and bus fields.
    130
    131  The bus_id is an ASCII string that contains the device's address on
    132  the bus. The format of this string is bus-specific. This is
    133  necessary for representing devices in sysfs.
    134
    135  parent is the physical parent of the device. It is important that
    136  the bus driver sets this field correctly.
    137
    138  The driver model maintains an ordered list of devices that it uses
    139  for power management. This list must be in order to guarantee that
    140  devices are shutdown before their physical parents, and vice versa.
    141  The order of this list is determined by the parent of registered
    142  devices.
    143
    144  Also, the location of the device's sysfs directory depends on a
    145  device's parent. sysfs exports a directory structure that mirrors
    146  the device hierarchy. Accurately setting the parent guarantees that
    147  sysfs will accurately represent the hierarchy.
    148
    149  The device's bus field is a pointer to the bus type the device
    150  belongs to. This should be set to the bus_type that was declared
    151  and initialized before.
    152
    153  Optionally, the bus driver may set the device's name and release
    154  fields.
    155
    156  The name field is an ASCII string describing the device, like
    157
    158     "ATI Technologies Inc Radeon QD"
    159
    160  The release field is a callback that the driver model core calls
    161  when the device has been removed, and all references to it have
    162  been released. More on this in a moment.
    163
    164
    165- Register the device.
    166
    167  Once the generic device has been initialized, it can be registered
    168  with the driver model core by doing::
    169
    170       device_register(&dev->dev);
    171
    172  It can later be unregistered by doing::
    173
    174       device_unregister(&dev->dev);
    175
    176  This should happen on buses that support hotpluggable devices.
    177  If a bus driver unregisters a device, it should not immediately free
    178  it. It should instead wait for the driver model core to call the
    179  device's release method, then free the bus-specific object.
    180  (There may be other code that is currently referencing the device
    181  structure, and it would be rude to free the device while that is
    182  happening).
    183
    184
    185  When the device is registered, a directory in sysfs is created.
    186  The PCI tree in sysfs looks like::
    187
    188    /sys/devices/pci0/
    189    |-- 00:00.0
    190    |-- 00:01.0
    191    |   `-- 01:00.0
    192    |-- 00:02.0
    193    |   `-- 02:1f.0
    194    |       `-- 03:00.0
    195    |-- 00:1e.0
    196    |   `-- 04:04.0
    197    |-- 00:1f.0
    198    |-- 00:1f.1
    199    |   |-- ide0
    200    |   |   |-- 0.0
    201    |   |   `-- 0.1
    202    |   `-- ide1
    203    |       `-- 1.0
    204    |-- 00:1f.2
    205    |-- 00:1f.3
    206    `-- 00:1f.5
    207
    208  Also, symlinks are created in the bus's 'devices' directory
    209  that point to the device's directory in the physical hierarchy::
    210
    211    /sys/bus/pci/devices/
    212    |-- 00:00.0 -> ../../../devices/pci0/00:00.0
    213    |-- 00:01.0 -> ../../../devices/pci0/00:01.0
    214    |-- 00:02.0 -> ../../../devices/pci0/00:02.0
    215    |-- 00:1e.0 -> ../../../devices/pci0/00:1e.0
    216    |-- 00:1f.0 -> ../../../devices/pci0/00:1f.0
    217    |-- 00:1f.1 -> ../../../devices/pci0/00:1f.1
    218    |-- 00:1f.2 -> ../../../devices/pci0/00:1f.2
    219    |-- 00:1f.3 -> ../../../devices/pci0/00:1f.3
    220    |-- 00:1f.5 -> ../../../devices/pci0/00:1f.5
    221    |-- 01:00.0 -> ../../../devices/pci0/00:01.0/01:00.0
    222    |-- 02:1f.0 -> ../../../devices/pci0/00:02.0/02:1f.0
    223    |-- 03:00.0 -> ../../../devices/pci0/00:02.0/02:1f.0/03:00.0
    224    `-- 04:04.0 -> ../../../devices/pci0/00:1e.0/04:04.0
    225
    226
    227
    228Step 3: Registering Drivers.
    229
    230struct device_driver is a simple driver structure that contains a set
    231of operations that the driver model core may call.
    232
    233
    234- Embed a struct device_driver in the bus-specific driver.
    235
    236  Just like with devices, do something like::
    237
    238    struct pci_driver {
    239           ...
    240           struct device_driver    driver;
    241    };
    242
    243
    244- Initialize the generic driver structure.
    245
    246  When the driver registers with the bus (e.g. doing pci_register_driver()),
    247  initialize the necessary fields of the driver: the name and bus
    248  fields.
    249
    250
    251- Register the driver.
    252
    253  After the generic driver has been initialized, call::
    254
    255	driver_register(&drv->driver);
    256
    257  to register the driver with the core.
    258
    259  When the driver is unregistered from the bus, unregister it from the
    260  core by doing::
    261
    262        driver_unregister(&drv->driver);
    263
    264  Note that this will block until all references to the driver have
    265  gone away. Normally, there will not be any.
    266
    267
    268- Sysfs representation.
    269
    270  Drivers are exported via sysfs in their bus's 'driver's directory.
    271  For example::
    272
    273    /sys/bus/pci/drivers/
    274    |-- 3c59x
    275    |-- Ensoniq AudioPCI
    276    |-- agpgart-amdk7
    277    |-- e100
    278    `-- serial
    279
    280
    281Step 4: Define Generic Methods for Drivers.
    282
    283struct device_driver defines a set of operations that the driver model
    284core calls. Most of these operations are probably similar to
    285operations the bus already defines for drivers, but taking different
    286parameters.
    287
    288It would be difficult and tedious to force every driver on a bus to
    289simultaneously convert their drivers to generic format. Instead, the
    290bus driver should define single instances of the generic methods that
    291forward call to the bus-specific drivers. For instance::
    292
    293
    294  static int pci_device_remove(struct device * dev)
    295  {
    296          struct pci_dev * pci_dev = to_pci_dev(dev);
    297          struct pci_driver * drv = pci_dev->driver;
    298
    299          if (drv) {
    300                  if (drv->remove)
    301                          drv->remove(pci_dev);
    302                  pci_dev->driver = NULL;
    303          }
    304          return 0;
    305  }
    306
    307
    308The generic driver should be initialized with these methods before it
    309is registered::
    310
    311        /* initialize common driver fields */
    312        drv->driver.name = drv->name;
    313        drv->driver.bus = &pci_bus_type;
    314        drv->driver.probe = pci_device_probe;
    315        drv->driver.resume = pci_device_resume;
    316        drv->driver.suspend = pci_device_suspend;
    317        drv->driver.remove = pci_device_remove;
    318
    319        /* register with core */
    320        driver_register(&drv->driver);
    321
    322
    323Ideally, the bus should only initialize the fields if they are not
    324already set. This allows the drivers to implement their own generic
    325methods.
    326
    327
    328Step 5: Support generic driver binding.
    329
    330The model assumes that a device or driver can be dynamically
    331registered with the bus at any time. When registration happens,
    332devices must be bound to a driver, or drivers must be bound to all
    333devices that it supports.
    334
    335A driver typically contains a list of device IDs that it supports. The
    336bus driver compares these IDs to the IDs of devices registered with it.
    337The format of the device IDs, and the semantics for comparing them are
    338bus-specific, so the generic model does attempt to generalize them.
    339
    340Instead, a bus may supply a method in struct bus_type that does the
    341comparison::
    342
    343  int (*match)(struct device * dev, struct device_driver * drv);
    344
    345match should return positive value if the driver supports the device,
    346and zero otherwise. It may also return error code (for example
    347-EPROBE_DEFER) if determining that given driver supports the device is
    348not possible.
    349
    350When a device is registered, the bus's list of drivers is iterated
    351over. bus->match() is called for each one until a match is found.
    352
    353When a driver is registered, the bus's list of devices is iterated
    354over. bus->match() is called for each device that is not already
    355claimed by a driver.
    356
    357When a device is successfully bound to a driver, device->driver is
    358set, the device is added to a per-driver list of devices, and a
    359symlink is created in the driver's sysfs directory that points to the
    360device's physical directory::
    361
    362  /sys/bus/pci/drivers/
    363  |-- 3c59x
    364  |   `-- 00:0b.0 -> ../../../../devices/pci0/00:0b.0
    365  |-- Ensoniq AudioPCI
    366  |-- agpgart-amdk7
    367  |   `-- 00:00.0 -> ../../../../devices/pci0/00:00.0
    368  |-- e100
    369  |   `-- 00:0c.0 -> ../../../../devices/pci0/00:0c.0
    370  `-- serial
    371
    372
    373This driver binding should replace the existing driver binding
    374mechanism the bus currently uses.
    375
    376
    377Step 6: Supply a hotplug callback.
    378
    379Whenever a device is registered with the driver model core, the
    380userspace program /sbin/hotplug is called to notify userspace.
    381Users can define actions to perform when a device is inserted or
    382removed.
    383
    384The driver model core passes several arguments to userspace via
    385environment variables, including
    386
    387- ACTION: set to 'add' or 'remove'
    388- DEVPATH: set to the device's physical path in sysfs.
    389
    390A bus driver may also supply additional parameters for userspace to
    391consume. To do this, a bus must implement the 'hotplug' method in
    392struct bus_type::
    393
    394     int (*hotplug) (struct device *dev, char **envp,
    395                     int num_envp, char *buffer, int buffer_size);
    396
    397This is called immediately before /sbin/hotplug is executed.
    398
    399
    400Step 7: Cleaning up the bus driver.
    401
    402The generic bus, device, and driver structures provide several fields
    403that can replace those defined privately to the bus driver.
    404
    405- Device list.
    406
    407struct bus_type contains a list of all devices registered with the bus
    408type. This includes all devices on all instances of that bus type.
    409An internal list that the bus uses may be removed, in favor of using
    410this one.
    411
    412The core provides an iterator to access these devices::
    413
    414  int bus_for_each_dev(struct bus_type * bus, struct device * start,
    415                       void * data, int (*fn)(struct device *, void *));
    416
    417
    418- Driver list.
    419
    420struct bus_type also contains a list of all drivers registered with
    421it. An internal list of drivers that the bus driver maintains may
    422be removed in favor of using the generic one.
    423
    424The drivers may be iterated over, like devices::
    425
    426  int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
    427                       void * data, int (*fn)(struct device_driver *, void *));
    428
    429
    430Please see drivers/base/bus.c for more information.
    431
    432
    433- rwsem
    434
    435struct bus_type contains an rwsem that protects all core accesses to
    436the device and driver lists. This can be used by the bus driver
    437internally, and should be used when accessing the device or driver
    438lists the bus maintains.
    439
    440
    441- Device and driver fields.
    442
    443Some of the fields in struct device and struct device_driver duplicate
    444fields in the bus-specific representations of these objects. Feel free
    445to remove the bus-specific ones and favor the generic ones. Note
    446though, that this will likely mean fixing up all the drivers that
    447reference the bus-specific fields (though those should all be 1-line
    448changes).