Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>A device driver is not a "program" that has a <code>main {}</code> with a start point and exit point. It's more like an API or a library or a collection of routines. In this case, it's a set of <em>entry points</em> declared by <code>MODULE_INIT()</code>, <code>MODULE_EXIT()</code>, perhaps <code>EXPORT_SYMBOL()</code> and structures that list entry points for <em>operations</em>.</p> <p>For <em>block devices</em>, the driver is expected to provide the list of operations it can perform by declaring its functions for those operations in (from <code>include/linux/blkdev.h</code>):</p> <pre><code>struct block_device_operations { int (*open) (); int (*release) (); int (*ioctl) (); int (*compat_ioctl) (); int (*direct_access) (); unsigned int (*check_events) (); /* -&gt;media_changed() is DEPRECATED, use -&gt;check_events() instead */ int (*media_changed) (); void (*unlock_native_capacity) (); int (*revalidate_disk) (); int (*getgeo)(); /* this callback is with swap_lock and sometimes page table lock held */ void (*swap_slot_free_notify) (); struct module *owner; }; </code></pre> <p>For <em>char devices</em>, the driver is expected to provide the list of operations it can perform by declaring its functions for those operations in (from <code>include/linux/fs.h</code>):</p> <pre><code>struct file_operations { struct module *owner; loff_t (*llseek) (); ssize_t (*read) (); ssize_t (*write) (); ssize_t (*aio_read) (); ssize_t (*aio_write) (); int (*readdir) (); unsigned int (*poll) (); long (*unlocked_ioctl) (); long (*compat_ioctl) (); int (*mmap) (); int (*open) (); int (*flush) (); int (*release) (); int (*fsync) (); int (*aio_fsync) (); int (*fasync) (); int (*lock) (); ssize_t (*sendpage) (); unsigned long (*get_unmapped_area)(); int (*check_flags)(); int (*flock) (); ssize_t (*splice_write)(); ssize_t (*splice_read)(); int (*setlease)(); long (*fallocate)(); }; </code></pre> <p>For <em>platform devices</em>, the driver is expected to provide the list of operations it can perform by declaring its functions for those operations in (from <code>include/linux/platform_device.h</code>): </p> <pre><code>struct platform_driver { int (*probe)(); int (*remove)(); void (*shutdown)(); int (*suspend)(); int (*resume)(); struct device_driver driver; const struct platform_device_id *id_table; }; </code></pre> <p>The driver, especially char drivers, does not have to support every operation listed. Note that there are macros to facilitate the coding of these structures by naming the structure entries.</p> <blockquote> <p>Does the driver program starts at the MOUDLUE_INIT() macro? </p> </blockquote> <p>The driver's <em>init()</em> routine specified in <code>MODULE_INIT()</code> will be called during boot (when statically linked in) or when the module is dynamically loaded. The driver passes its structure of operations to the device's subsystem when it <em>registers</em> itself during its <em>init()</em>.</p> <p>These device driver entry points, e.g. <em>open()</em> or <em>read()</em>, are typically executed when the user app invokes a C library call (in user space) and after a switch to kernel space. Note that the i2c driver you're looking at is a <a href="http://www.kernel.org/doc/Documentation/driver-model/platform.txt" rel="noreferrer">platform driver</a> for a bus that is used by <em>leaf</em> devices, and its functions exposed by <code>EXPORT_SYMBOL()</code> would be called by other drivers.</p> <p>Only the driver's <em>init()</em> routine specified in <code>MODULE_INIT()</code> is guaranteed to be called. The driver's <em>exit()</em> routine specified in <code>MODULE_EXIT()</code> would only be executed if/when the module is dynamically unloaded. The driver's op routines will be called asynchronously (just like its interrupt service routine) in unknown order. Hopefully user programs will invoke an <em>open()</em> before issuing a <em>read()</em> or an <em>ioctl()</em> operation, and invoke other operations in a sensible fashion. A well-written and robust driver should accommodate any order or sequence of operations, and produce sane results to ensure system integrity. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload