xref: /illumos-gate/usr/src/man/man9e/Intro.9e (revision 3448eae2e9d99e7fadeb43056eb8e788c7ea93be)
1.\"
2.\" This file and its contents are supplied under the terms of the
3.\" Common Development and Distribution License ("CDDL"), version 1.0.
4.\" You may only use this file in accordance with the terms of version
5.\" 1.0 of the CDDL.
6.\"
7.\" A full copy of the text of the CDDL should have accompanied this
8.\" source.  A copy of the CDDL is also available via the Internet at
9.\" http://www.illumos.org/license/CDDL.
10.\"
11.\"
12.\" Copyright 2024 Oxide Computer Company
13.\"
14.Dd April 28, 2024
15.Dt INTRO 9E
16.Os
17.Sh NAME
18.Nm Intro
19.Nd introduction to device driver entry points
20.Sh DESCRIPTION
21Section 9E of the manual describes the entry points and building blocks that are
22used to build and implement all kinds of device drivers and kernel modules.
23Often times, modules and device drivers are talked about interchangeably.
24The operating system is built around the idea of loadable kernel modules.
25Device drivers are the primary type that we think about; however, there are
26loadable kernel modules for file systems, STREAMS devices, and even system
27calls!
28.Pp
29The vast majority of this section focuses on documenting device
30.Pq and STREAMS
31drivers.
32Device driver are further broken down into different categories depending on
33what they are targeting.
34For example, there are dedicated frameworks for SCSI/SAS HBA drivers, networking
35drivers, USB drivers, and then general character and block device drivers.
36While most of the time we think about device drivers as corresponding to a piece
37of physical hardware, there are also pseudo-device drivers which are device
38drivers that provide functionality, but aren't backed by any hardware.
39For example,
40.Xr dtrace 4D
41and
42.Xr lofi 4D
43are both pseudo-device drivers.
44.Pp
45To help understand the relationship between these different types of things,
46consider the following image:
47.Bd -literal
48  +--------------------+
49  |                    |
50  |  Loadable Modules  |
51  |                    |
52  +--------------------+
53    |                          +--------------+      +------------+
54    |                          |              |      |            |
55    +------------------------->| Cryptography | ...  | Scheduling |  ...
56    |                          |              |      |            |
57    |                          +--------------+      +------------+
58    |   +----------------+     +--------------+     +--------------+
59    |   |                |     |              |     |              |
60    +-->| Device Drivers | ... | File Systems | ... | System Calls | ...
61        |                |     |              |     |              |
62        +----------------+     +--------------+     +--------------+
63                v
64    +-----------+
65    |
66    |   +------------+  +---------+     +-----------+     +-----------+
67    +-->| Networking |->| igb(4D) | ... | mlxcx(4D) | ... | cxgbe(4D) | ...
68    |   +------------+  +---------+     +-----------+     +-----------+
69    |
70    |   +-------+       +----------+     +-------------+     +----------+
71    +-->|  HBA  |------>| smrt(4D) | ... | mpt_sas(4D) | ... | ahci(4D) | ...
72    |   +-------+       +----------+     +-------------+     +----------+
73    |
74    |   +-------+       +--------------+     +----------+     +---------+
75    +-->|  USB  |------>| scsa2usb(4D) | ... | ccid(4D) | ... | hid(4D) | ...
76    |   +-------+       +--------------+     +----------+     +---------+
77    |
78    |   +---------+     +------------+     +-------------+
79    +-->| Sensors |---->| smntemp(4) | ... | pchtemp(4D) | ...
80    |   +---------+     +------------+     +-------------+
81    |
82    +-------+-------------+-----------+----------+
83            |             v           V          |
84            v       +-----------+  +-----+       v
85        +-------+   | Character |  | USB |   +-------+
86        | Audio |   | and Block |  | HCD |   | Nexus |  ...
87        +-------+   |  Devices  |  +-----+   +-------+
88                    +-----------+
89.Ed
90.Pp
91The above diagram attempts to explain some of the relationships that were
92mentioned above at a high level.
93All device drivers are loadable modules that leverage the
94.Xr modldrv 9S
95structure and implement similar
96.Xr _init 9E
97and
98.Xr _fini 9E
99entry points.
100.Pp
101Some hardware implements more than one type of thing.
102The most common example here would be a NIC that implements a temperature sensor
103or a current sensor.
104Many devices also implement and leverage the kernel statistics framework called
105.Dq kstats .
106A device driver is not strictly limited to only a single class of thing.
107For example, many USB client devices are networking device drivers.
108In the subsequent sections we'll go into the functions and structures that are
109related to creating the different device drivers and their associated
110functions.
111.Ss Kernel Initialization
112To begin with, all loadable modules in the system are required to implement
113three entry points.
114If these entry points are not present, then the module cannot be installed in
115the system.
116These entry points are
117.Xr _init 9E ,
118.Xr _fini 9E ,
119and
120.Xr _info 9E .
121.Pp
122The
123.Xr _init 9E
124entry point will be the first thing called in the module and this is where
125any global initialization should be taken care of.
126Once all global state has been successfully created, the driver should call
127.Xr mod_install 9F
128to actually register with the system.
129Conversely,
130.Xr _fini 9E
131is used to tear down the module.
132The driver uses
133.Xr mod_remove 9F
134to first remove the driver from the system and then it can tear down any global
135state that was added there.
136.Pp
137While we mention global state here, this isn't widely used in most device
138drivers.
139A device driver can have multiple instances instantiated, one for each instance
140of a hardware device that is found and most state is tied to those instances.
141We'll discuss that more in the next section.
142.Pp
143The
144.Xr info 9E
145entry point these days just calls
146.Xr mod_info 9F
147directly and can return it.
148.Pp
149All of these entry points directly or indirectly require a
150.Vt "struct modlinkage" .
151This structure is used by all types of loadable kernel modules and is filled in
152with information that varies based on the type of module one is creating.
153Here, everything that we're creating is going to use a
154.Vt "struct modldrv" ,
155which describes a loadable driver.
156Every device driver will declare a static global variable for these and fill
157them out.
158They are documented in
159.Xr modlinkage 9S
160and
161.Xr modldrv 9S
162respectively.
163.Pp
164The following is an example of these structures borrowed from
165.Xr igc 4D :
166.Bd -literal
167static struct modldrv igc_modldrv = {
168        .drv_modops = &mod_driverops,
169        .drv_linkinfo = "Intel I226/226 Ethernet Controller",
170        .drv_dev_ops = &igc_dev_ops
171};
172
173static struct modlinkage igc_modlinkage = {
174        .ml_rev = MODREV_1,
175        .ml_linkage = { &igc_modldrv, NULL }
176};
177.Ed
178.Pp
179From this there are a few important things to take away.
180A single kernel module may implement more than one type of linkage, though this
181is the exception and not the norm.
182The second part to call out here is that while the
183.Fa drv_modops
184will be the same for all drivers that use the
185.Vt "struct modldrv" ,
186the
187.Fa drv_linkinfo
188and
189.Fa drv_dev_ops
190will be unique to each driver.
191The next section discusses the
192.Vt "struct dev_ops" .
193.Ss The Devices Tree and Instances
194Device drivers have a unique challenge that makes them different from other
195kinds of loadable modules: there may be very well more than a single instance of
196the hardware that they support.
197Consider a few examples: a user can plug in two distinct USB mass storage
198devices or keyboards.
199A system may have more than one NIC present or the hardware may expose multiple
200physical ports as distinct devices.
201Many systems have more than one disk device.
202Conversely, if a given piece of hardware isn't present then there's no reason
203for the driver for it to be loaded.
204There is nothing that the Intel 1 GbE Ethernet NIC driver,
205.Xr igb 4D ,
206can do if there are no supported devices plugged in.
207.Pp
208Devices are organized into a tree that is full of parent and child
209relationships.
210This tree is what you see when you run
211.Xr prtconf 8 .
212As an example, a USB device is plugged into a port on a hub, which may be
213plugged into another hub, and then is eventually plugged into a PCI device that
214is the USB host controller, which itself may be under a PCI-PCI bridge, and this
215chain continues all the way up to the root of the tree, which we call
216.Dq rootnex .
217Device drivers that can enumerate children and provide operations for them are
218called
219.Dq nexus
220drivers.
221.Pp
222The system automatically fills out the device tree through a combination of
223built-in mechanisms and through operations on other nexus drivers.
224When a new hardware unit is discovered, a
225.Vt dev_info_t
226structure, the device information, is created for it and it is linked into the
227tree.
228Generally, the system can then use automatic information embedded in the device
229to determine what driver is responsible for the piece of hardware through the
230use of the
231.Dq compatible
232property which the systems and nexus drivers set up on their children.
233For example, PCI and PCIe drivers automatically set up the compatible property
234based on information discovered in PCI configuration space like the device's
235vendor, device ID, and class IDs.
236The same is true of USB.
237.Pp
238When a device driver is packaged, it contains metadata that indicates which
239devices it supports.
240For example, the aforementioned igb driver will have a rule that it matches
241.Dq pciex8086,10a7 .
242When the kernel discovers a device with this alias present, it will know that it
243should assign it to the igb driver and then it will assign the
244.Vt dev_info_t
245structure a new instance number.
246.Pp
247To emphasize here, each time the device is discovered in the tree, it will have
248an independent instance number and an independent
249.Vt dev_info_t
250that accompanies it.
251Each instance has an independent life time too.
252The most obvious way to think about this is with something that can be
253physically removed while the system is on, like a USB device.
254Just because you pull one USB keyboard doesn't mean it impacts the other one
255there.
256They are inherently different devices
257.Po
258albeit if they were plugged into the same HUB and the HUB was removed, then they
259both would be removed; however, each would be acted on independently
260.Pc .
261.Pp
262Here is a slimmed down example from a system's
263.Xr prtconf 8
264output:
265.Bd -literal
266Oxide,Gimlet (driver name: rootnex)
267    scsi_vhci, instance #0 (driver name: scsi_vhci)
268    pci, instance #0 (driver name: npe)
269        pci1022,1480, instance #13 (driver name: amdzen_stub)
270        pci1022,164f
271        pci1022,1482
272        pci1de,fff9, instance #0 (driver name: pcieb)
273            pci1344,3100, instance #4 (driver name: nvme)
274                blkdev, instance #10 (driver name: blkdev)
275        pci1022,1482
276        pci1022,1482
277        pci1de,fff9, instance #1 (driver name: pcieb)
278            pci1b96,0, instance #7 (driver name: nvme)
279                blkdev, instance #0 (driver name: blkdev)
280        pci1de,fff9, instance #2 (driver name: pcieb)
281            pci1b96,0, instance #8 (driver name: nvme)
282                blkdev, instance #4 (driver name: blkdev)
283        pci1de,fff9, instance #3 (driver name: pcieb)
284            pci1b96,0, instance #10 (driver name: nvme)
285                blkdev, instance #1 (driver name: blkdev)
286.Ed
287.Pp
288From this we can see that there are multiple instances of the NVMe
289.Pq nvme ,
290PCIe bridge
291.Pq pcieb ,
292and
293generic block device
294.Pq blkdev
295driver present.
296Each of these has their own
297.Vt dev_info_t
298and has their various entry points called in parallel.
299With that, let's dig into the specifics of what the
300.Vt "struct dev_ops"
301actually is and the different operations to be aware.
302.Ss struct dev_ops
303The device operations structure,
304.Vt "struct dev_ops" ,
305controls all of the basic entry points that a loadable device contains.
306This is something that every driver has to implement, no matter the type.
307The most important things that will be present are the
308.Fa devo_attach
309and
310.Fa devo_detach
311members which are used to create and destroy instances of the driver and then a
312pointer to any subsequent operations that exist, such as the
313.Fa devo_cb_ops ,
314which is used for character and block device drivers and the
315.Fa devo_bus_ops ,
316which is used for nexus drivers.
317.Pp
318Attach and detach are the most important entry points in this structure.
319This could be practically thought of as the
320.Dq main
321function entry point for a device driver.
322This is where any initialization of the instance will occur.
323This would include many traditional things like setting up access to registers,
324allocating and assigning interrupts, and interfacing with the various other
325device driver frameworks such as
326.Xr mac 9E .
327.Pp
328The actions taken here are generally device-specific, while certain classes of
329devices
330.Pq e.g. PCI, USB, etc.
331will have overlapping concerns.
332In addition, this is where the driver will take care of creating anything like a
333minor node which will be used to access it by userland software if it's a
334character or block device driver.
335.Pp
336There is generally a per-instance data structure that a driver creates.
337It may do this by calling
338.Xr kmem_zalloc 9F
339and assigning the structure with the
340.Xr ddi_set_driver_private 9F
341entry point or it may use the DDI's soft state management functions rooted in
342.Xr ddi_soft_state_init 9F .
343A driver should try to tie as much state to the instance as possible, where
344possible.
345There should not be anything like a fixed size global array of possible
346instances.
347Someone usually finds a way to attach many more instances of some type of
348hardware than you might expect!
349.Pp
350The
351.Xr attach 9E
352and
353.Xr detach 9E
354entry points both have a unique command argument that is used to describe a
355specific action that is going on.
356This action may be a normal attach or it could be related to putting the system
357into the ACPI S3 sleep or similar state with the suspend and resume commands.
358.Pp
359The following table are the common functions that most drivers end up having to
360think a little bit about:
361.Vt "struct dev_ops" :
362.Bl -column -offset -indent "mac_capab_transceiver" "mac_capab_transceiver"
363.It Xr attach 9E Ta Xr detach 9E
364.It Xr getinfo 9E Ta Xr quiesce 9E
365.El
366.Pp
367Briefly, the
368.Xr getinfo 9E
369entry point is used to map between instances of a device driver and the minor
370nodes it creates.
371Drivers that participate in a framework like the SCSI HBA, Networking, or
372related don't usually end up implementing this.
373However, drivers that manually create minor nodes generally do.
374The
375.Xr quiesce 9E
376entry point is used as part of the fast reboot operation.
377It is basically intended to stop and/or reset the hardware and discard any
378ongoing I/O.
379For pseudo-device drivers or drivers which do not perform I/O, they can use the
380symbol
381.Ql ddi_quiesce_not_needed
382in lieu of a standard implementation.
383.Pp
384In addition, the following additional entry points exist, but are less commonly
385required either because the system generally takes care of it, such as
386.Xr probe 9E .
387.Bl -column -offset -indent "mac_capab_transceiver" "mac_capab_transceiver"
388.It Xr identify 9E Ta Xr power 9E
389.It Xr probe 9E Ta
390.El
391.Pp
392For more information on the structure, see also
393.Xr dev_ops 9S .
394The following are a few examples of the
395.Vt "struct dev_ops"
396structure from a few drivers.
397We recommend using the C99 style for all new instances.
398.Bd -literal
399static struct dev_ops ksensor_dev_ops = {
400        .devo_rev = DEVO_REV,
401        .devo_refcnt = 0,
402        .devo_getinfo = ksensor_getinfo,
403        .devo_identify = nulldev,
404        .devo_probe = nulldev,
405        .devo_attach = ksensor_attach,
406        .devo_detach = ksensor_detach,
407        .devo_reset = nodev,
408        .devo_power = ddi_power,
409        .devo_quiesce = ddi_quiesce_not_needed,
410        .devo_cb_ops = &ksensor_cb_ops
411};
412
413static struct dev_ops igc_dev_ops = {
414        .devo_rev = DEVO_REV,
415        .devo_refcnt = 0,
416        .devo_getinfo = NULL,
417        .devo_identify = nulldev,
418        .devo_probe = nulldev,
419        .devo_attach = igc_attach,
420        .devo_detach = igc_detach,
421        .devo_reset = nodev,
422        .devo_quiesce = ddi_quiesce_not_supported,
423        .devo_cb_ops = &igc_cb_ops
424};
425
426static struct dev_ops pchtemp_dev_ops = {
427        .devo_rev = DEVO_REV,
428        .devo_refcnt = 0,
429        .devo_getinfo = nodev,
430        .devo_identify = nulldev,
431        .devo_probe = nulldev,
432        .devo_attach = pchtemp_attach,
433        .devo_detach = pchtemp_detach,
434        .devo_reset = nodev,
435        .devo_quiesce = ddi_quiesce_not_needed
436};
437.Ed
438.Ss Character and Block Operations
439In the history of UNIX, the most common device drivers that were created were
440for block and character devices.
441The interfaces in block and character devices are usually in service of common
442I/O patterns that the system exposes.
443For example, when you call
444.Xr open 2 ,
445.Xr ioctl 2 ,
446or
447.Xr read 2
448on a device, it goes through the device's corresponding entry point here.
449Both block and character devices operate on the shared
450.Vt "struct cb_ops"
451structure, with different members being expected for both of them.
452While they both require that someone implement the
453.Fa cb_open
454and
455.Fa cb_close
456members, block devices perform I/O through the
457.Xr strategy 9E
458entry point and support the
459.Xr dump 9E
460entry point for kernel crash dumps, while character devices implement the more
461historically familiar
462.Xr read 9E ,
463.Xr write 9E,
464and the
465.Xr devmap 9E
466entry point for supporting memory-mapping.
467.Pp
468While the device operations structures worked with the
469.Vt dev_info_t
470structure and there was one per-instance, character and block operations work
471with minor nodes: named entities that exist in the file system.
472UNIX has long had the idea of a major and minor number that is encoded in the
473.Vt dev_t
474which is embedded in the file system, which is what you see in the
475.Fa st_rdev
476member of stat structure when you call
477.Xr stat 2 .
478The major number is assigned to the driver
479.Em as a whole ,
480not an instance.
481The minor number space is shared between all instances of a driver.
482Minor node numbers are assigned by the driver when it calls
483.Xr ddi_create_minor_node 9F
484to create a minor node and when one of its character or block entry points are
485called, it will get this minor number back and it must translate it to the
486corresponding instance on its own.
487.Pp
488A special property of the
489.Xr open 9E
490entry point is that it can change the minor number a client gets during its call
491to open which it will use for all subsequent calls.
492This is called a
493.Dq cloning
494open.
495Whether this is used or not depends on the type of driver that you are creating.
496For example, many pseudo-device drivers like DTrace will use this so each client
497has its own state.
498Similarly, devices that have certain internal locking and transaction schemes
499will give each caller a unique minor.
500The
501.Xr ccid 4D
502and
503.Xr nvme 4D
504driver are examples of this.
505However, many drivers will have just a single minor node per instance and just
506say that the minor node's number is the instance number, making it very simple
507to figure out the mapping.
508When it's not so simple, often an AVL tree or some other structure is used to
509help map this together.
510.Pp
511The following entry points are generally used for character devices:
512.Bl -tag -width Ds
513.It Xr ioctl 9E
514The I/O control or ioctl entry point is used extensively throughout the system
515to perform different kinds of operations.
516These operations are often driver specific, though there are also some which are
517also common operations that are used across multiple devices like the disk
518operations described in
519.Xr dkio 4I
520or the ioctls that are used under the hood by
521.Xr cfgadm 8
522and friends.
523.Pp
524Whether a driver supports ioctls or not depends on it.
525If it does, it is up to the driver to always perform any requisite privilege and
526permission checking as well as take care in copying in and out any kind of
527memory from the user process through calls like
528.Xr ddi_copyin 9F
529and
530.Xr ddi_copyout 9F .
531.Pp
532The ioctl interface gives the driver writer great flexibility to create equally
533useful or hard to consume interfaces.
534When crafting a new committed interface over an ioctl, take care to ensure there
535is an ability to version the structure or use something that has more
536flexibility like a
537.Vt nvlist_t .
538See the
539.Sq Copying Data to and from Userland
540section of
541.Xr Intro 9F
542for more information.
543.It Xr read 9E , Xr write 9E , Xr aread 9E , and Xr awrite 9E
544These are the classic I/O routines of the system.
545A driver's read and write routines operate on a
546.Xr uio 9S
547structure which describes the I/O that is occurring, the offset into the
548device that the I/O should occur at, and has various flags that
549describe properties of the I/O request, such as whether or not it is a
550non-blocking request.
551.Pp
552The majority of device drivers that implement these entry points are using them
553to create some kind of file-like abstraction for a device.
554For example, the
555.Xr ccid 4D
556driver uses these interfaces for submitting commands and reading responses back
557from an underlying device.
558.Pp
559For most use cases
560.Xr read 9E
561and
562.Xr write 9E
563are sufficient; however, the
564.Xr aread 9E
565and
566.Xr awrite 9E
567are versions that tie into the kernel's asynchronous I/O engine.
568.It Xr chpoll 9E
569This entry point allows a device to be polled by user code for an event of
570interest and connects through the kernel to different polling mechanisms such as
571.Xr poll 2 ,
572.Xr port_get 3C ,
573and many others.
574Currently this interface only allows a driver to define the classic poll style
575events such as
576.Dv POLLIN ,
577.Dv POLLOUT, and
578.Dv POLLHUP .
579The exact semantics of these are up to the driver; however, it is expected that
580the read and write oriented semantics of the various events will be honored by
581the device driver.
582.It Xr devmap 9E and Xr segmap 9E
583These are entry points that are used to set up memory mappings for a device and
584replace the older
585.Xr mmap 9E
586entry point.
587When a function calls
588.Xr mmap 2
589on a device, it'll reach these, starting with the
590.Xr devmap 9E
591entry point.
592The driver is responsible for confirming that the mappings request and its
593semantics are sensible, after which it will set up memory for consumption.
594The
595.Xr devmap 9E
596manual page has more details on the specifics here and the related entry points
597that can be implemented as part of the
598.Xr devmap_callback_ctl 9S
599structures such as
600.Xr devmap_access 9E .
601The segment mapping is an optional part that provides some additional controls
602for a driver such as assigning certain mapping attributes or wanting to maintain
603separate contexts for different mappings.
604See
605.Xr segmap 9E
606for more information.
607It is common for drivers to just provide a
608.Xr devmap 9E
609entry point.
610.It Xr prop_op 9E
611This entry point is used for drive's to manage and deal with property creation.
612While this is its own entry point, most callers can just specify
613.Xr ddi_prop_op 9F
614for this and don't need any special handling.
615.El
616.Pp
617The following entry points are used uniquely used for block devices:
618.Bl -tag -width Ds
619.It Xr strategy 9E
620A driver's strategy entry point is used to actually perform I/O as described by
621the
622.Xr buf 9S
623structure.
624It is responsible for allocating all resources and then initiating the actual
625request.
626The actual request will finish potentially asynchronously through calls to
627.Xr biodone 9F
628or
629.Xr bioerror 9F .
630HBA or blkdev-based drivers do not usually end up implementing this interface.
631.It Xr dump 9E
632A driver's dump implementation is used when the operating system has had a fatal
633error and is trying to persist a crash dump to disk.
634This is a delicate operation as the system has already failed, which means many
635normal operations like interrupt handlers, timeouts, and blocking will no longer
636work.
637.El
638.Pp
639In general, the
640.Xr print 9E
641entry point for block devices is vestigial and users should fill in
642.Xr nodev 9F
643there instead.
644.Pp
645The following are some examples of different character device operations
646structures that drivers have employed.
647Note that using C99 structure definitions is preferred:
648.Bd -literal
649static struct cb_ops ksensor_cb_ops = {
650        .cb_open = ksensor_open,
651        .cb_close = ksensor_close,
652        .cb_strategy = nodev,
653        .cb_print = nodev,
654        .cb_dump = nodev,
655        .cb_read = nodev,
656        .cb_write = nodev,
657        .cb_ioctl = ksensor_ioctl,
658        .cb_devmap = nodev,
659        .cb_mmap = nodev,
660        .cb_segmap = nodev,
661        .cb_chpoll = nochpoll,
662        .cb_prop_op = ddi_prop_op,
663        .cb_flag = D_MP,
664        .cb_rev = CB_REV,
665        .cb_aread = nodev,
666        .cb_awrite = nodev
667};
668
669static struct cb_ops vio9p_cb_ops = {
670        .cb_rev =                       CB_REV,
671        .cb_flag =                      D_NEW | D_MP,
672        .cb_open =                      vio9p_open,
673        .cb_close =                     vio9p_close,
674        .cb_read =                      vio9p_read,
675        .cb_write =                     vio9p_write,
676        .cb_ioctl =                     vio9p_ioctl,
677        .cb_strategy =                  nodev,
678        .cb_print =                     nodev,
679        .cb_dump =                      nodev,
680        .cb_devmap =                    nodev,
681        .cb_mmap =                      nodev,
682        .cb_segmap =                    nodev,
683        .cb_chpoll =                    nochpoll,
684        .cb_prop_op =                   ddi_prop_op,
685        .cb_str =                       NULL,
686        .cb_aread =                     nodev,
687        .cb_awrite =                    nodev,
688};
689
690static struct cb_ops bd_cb_ops = {
691        bd_open,                /* open */
692        bd_close,               /* close */
693        bd_strategy,            /* strategy */
694        nodev,                  /* print */
695        bd_dump,                /* dump */
696        bd_read,                /* read */
697        bd_write,               /* write */
698        bd_ioctl,               /* ioctl */
699        nodev,                  /* devmap */
700        nodev,                  /* mmap */
701        nodev,                  /* segmap */
702        nochpoll,               /* poll */
703        bd_prop_op,             /* cb_prop_op */
704        0,                      /* streamtab  */
705        D_64BIT | D_MP,         /* Driver compatibility flag */
706        CB_REV,                 /* cb_rev */
707        bd_aread,               /* async read */
708        bd_awrite               /* async write */
709};
710.Ed
711.Ss Networking Drivers
712Networking device drivers come in many forms and flavors.
713They may interface to the host via PCIe, USB, be a pseudo-device, or use
714something entirely different like SPI
715.Pq Serial Peripheral Interface .
716The system provides a dedicated networking interface driver framework that is
717documented in
718.Xr mac 9E  .
719This framework is sometimes also referred to as GLDv3
720.Pq Generic LAN Device version 3 .
721.Pp
722All networking drivers will still implement a basic
723.Vt "struct dev_ops"
724and a minimal
725.Vt "struct cb_ops" .
726The
727.Xr mac 9E
728framework takes care of implementing all of the standard character device entry
729points at the end of the day and instead provides a number of different
730networking-specific entry points that take care of things like getting and
731setting properties, installing and removing MAC addresses and filters, and
732actually transmitting and providing callbacks for receiving packets.
733.Pp
734Each instance of a device driver will generally have a separate registration
735with
736.Xr mac 9E .
737In other words, there is usually a one to one relationship between a driver
738having its
739.Xr attach 9E
740entry point called and it registering with the
741.Xr mac 9E
742framework.
743.Ss STREAMS Modules
744STREAMS modules are a historical way to provide certain services in the kernel.
745For networking device drivers, instead see the prior section and
746.Xr mac 9E .
747Conceptually STREAMS break things into queues, with one side being designed for
748a module to read data and another side for it write or produce data.
749These modules are arranged in a stack, with additional modules being pushed on
750for additional processing.
751For example, the TTY subsystem has a serial console as a base STREAMS module,
752but it then pushes on additional modules like the pseudo-terminal emulation
753.Po
754.Xr ptem 4M
755.Pc ,
756the standard line discipline
757.Po
758.Xr ldterm 4M
759.Pc ,
760etc.
761.Pp
762STREAMS drivers don't use the normal character device entry points
763.Pq though sometimes they do define them
764or even the
765.Vt "struct modldrv" .
766Instead they use the
767.Vt "struct modlstrmod"
768which is discussed in
769.Xr modlstrmod 9S ,
770which in turn requires one to fill out the
771.Xr fmodsw 9S ,
772.Xr streamtab 9S ,
773and
774.Xr qinit 9S
775structures.
776The latter of these has two of the more common entry points:
777.Bl -column -offset -indent "mac_capab_transceiver" "mac_capab_transceiver"
778.It Xr put 9E Ta Xr srv 9E
779.El
780.Pp
781These entry points are used when different kinds of messages are received by the
782device driver on a queue.
783In addition, those entry points define an alternative set of entry points for
784.Xr open 9E
785and
786.Xr close 9E
787as STREAMS modules open and close routines all operate in the context of a given
788.Vt queue_t .
789There are other differences here.
790An ioctl is not a dedicated entry point, but rather a specific message type
791.Po
792.Dv M_IOCTL
793.Pc
794that is
795received in a driver's
796.Xr put 9E
797routine.
798.Pp
799Finally, it's worth noting the
800.Xr mt-streams 9F
801manual page which discusses several concurrency related considerations for
802STREAMS related drivers.
803.Ss HBA Drivers
804Host bus adapters are used to interface with the various SCSI and SAS
805controllers.
806Like with networking, the kernel provides a framework under the name of SCSA.
807HBA drivers still often implement character device entry points; however, they
808generally end up calling into shared framework entry points for
809.Xr open 9E ,
810.Xr ioctl 9E ,
811and
812.Xr close 9E .
813For several of the concepts related with the 3rd version for the framework, see
814.Xr iport 9 .
815.Pp
816The following entry points are associated with HBA drivers:
817.Bl -column -offset -indent "mac_capab_transceiver" "mac_capab_transceiver"
818.It Xr tran_abort 9E Ta Xr tran_bus_reset 9E
819.It Xr tran_dmafree 9E Ta Xr tran_getcap 9E
820.It Xr tran_init_pkt 9E Ta Xr tran_quiesce 9E
821.It Xr tran_reset 9E Ta Xr tran_reset_notify 9E
822.It Xr tran_setup_pkt 9E Ta Xr tran_start 9E
823.It Xr tran_sync_pkt 9E Ta Xr tran_tgt_free 9E
824.It Xr tran_tgt_init 9E Ta Xr tran_tgt_probe 9E
825.El
826.Pp
827In addition to these, when using SCSAv3 with iports, drivers will call
828.Xr scsi_hba_iport_register 9F
829to create various iports.
830This has the unique effect of causing the driver's top-level
831.Xr attach 9E
832entry point to be called again, but referring to the iport instead of the main
833hardware instance.
834.Ss USB Drivers
835The kernel provides a framework for USB client devices to access various USB
836services such as getting access to device and configuration descriptors, issuing
837control, bulk, interrupt, and isochronous requests, and being notified when they
838are removed from the system.
839Generally a USB device driver leverages a framework of some kind, like
840.Xr mac 9E
841in addition to the USB pieces.
842As such, there are no entry points specific to USB device drivers; however,
843there are plenty of provided functions.
844.Pp
845To get started with a USB device driver, one will generally perform some of the
846following steps:
847.Bl -enum
848.It
849Register with the USB framework by calling
850.Xr usb_client_attach 9F .
851.It
852Ask the kernel to fetch all of the device and class descriptors that are
853appropriate with the
854.Xr usb_get_dev_data 9F
855function.
856.It
857Parse the relevant descriptors to figure out which endpoints to attach.
858.It
859Open up pipes to the specific USB endpoints by using
860.Xr usb_lookup_ep_data 9F ,
861.Xr usb_ep_xdescr_fill 9F ,
862and
863.Xr usb_pipe_xopen 9F .
864.It
865Proceed with the rest of device initialization and service.
866.El
867.Ss Virtio Drivers
868The kernel provides an uncommitted interface for Virtio device drivers, which is
869discussed in some detail in
870.Pa uts/common/io/virtio/virtio.h .
871A client device driver will register with the framework through and then use
872that to begin feature and interrupt negotiation.
873As part of that, they are given the ability to set up virtqueues which can be
874used for communicating to and from the hypervisor.
875.Ss Kernel Statistics
876Drivers have the ability to export kstats
877.Pq kernel statistics
878that will appear in the
879.Xr kstat 8
880command.
881Any kind of module in the system can create and register a kstat, it is not
882strictly tied to anything like a
883.Vt dev_info_t .
884kstats have different types that they come in.
885The most common kstat type is the
886.Dv KSTAT_TYPE_NAMED
887which allows for multiple, typed name-value pairs to be part of the stat.
888This is what the kernel uses under the hood for many things such as the various
889.Xr mac 9E
890statistics that are managed on behalf of drivers.
891.Pp
892To create a kstat, a driver utilizes the
893.Xr kstat_create 9F
894function, after which it has a chance to set up the kstat and make choices about
895which entry points that it will implement.
896A kstat will not be made visible until the caller calls
897.Xr kstat_install 9F
898on it.
899The two entry points that a driver may implement are:
900.Bl -column -offset -indent "mac_capab_transceiver" "mac_capab_transceiver"
901.It Xr ks_snapshot 9E Ta Xr ks_update 9E
902.El
903.Pp
904First, let's discuss the
905.Xr ks_update 9E
906entry point.
907A kstat may be updated in one of two ways: either by having its
908.Xr ks_update 9E
909function called or by having the system update information as it goes in the
910kstat's data.
911One would use the former when it involves doing something like going out to
912hardware and reading registers, where as the latter approach might be used when
913operations can be tracked as part of a normal flow, such as the number of errors
914or particular requests a driver has encountered.
915The
916.Xr ks_snapshot 9E
917entry point is not as commonly used by comparison and allows a caller to
918interpose on the data marshalling process for copying out to userland.
919.Ss Upgradable Firmware Modules
920The UFM
921.Pq Upgradable Firmware Module
922system in the kernel allows a device driver to provide information about the
923firmware modules that are present on a device and is generally used as
924supplementary information about a device.
925The UFM framework allows a driver to declare a given number of modules that
926exist on a given
927.Vt dev_info_t .
928Each module has some number of slots with different versions.
929This information is automatically exported into various consumers such as
930.Xr fwflash 8 ,
931the Fault Management Architecture,
932and the
933.Xr ufm 4D
934driver's specific ioctls.
935.Pp
936A driver fills in the operations vector discussed in
937.Xr ddi_ufm 9E
938and registers it with the kernel by calling
939.Xr ddi_ufm_init 9F .
940These interfaces have entry points include:
941.Bl -column -offset -indent "ddi_ufm_op_fill_image(9E)" "ddi_ufp_op_fill_image(9E)"
942.It Xr ddi_ufm_op_getcaps 9E Ta Xr ddi_ufm_op_nimages 9E
943.It Xr ddi_ufm_op_fill_image 9E Ta Xr ddi_ufm_op_fill_slot 9E
944.It Xr ddi_ufm_op_readimg 9E Ta
945.El
946.Pp
947The
948.Xr ddi_ufm_op_getcaps 9E
949entry point describes the capabilities of the device and what other entry points
950the kernel and callers can expect to exist.
951The
952.Xr ddi_ufm_op_nimages 9E
953entry point tells the system how many images there are and if it is not
954implemented, then the system assumes there is a single slot.
955The
956.Xr ddi_ufm_op_fill_image 9E
957and
958.Xr ddi_ufm_op_fill_slot 9E
959entry points are used to fill in information about slots and images
960respectively, while the
961.Xr ddi_ufm_op_readimg 9E
962entry point is used to read an image from the device for the operating system.
963That entry point is often supported when dealing with EEPROMs as many devices do
964not have a way of retrieving the actual current firmware.
965.Ss USB Host Interface Drivers
966Opposite of USB device drivers are the device drivers that make the USB
967abstractions work: USB host interface controllers.
968The kernel provides a private framework for these, which is discussed in
969.Xr usba_hcdi 9E .
970A HCDI driver is a character device driver and ends up also instantiating a root
971hub as part of its operation and forwards many of its open, close, and ioctl
972routines to the corresponding usba hubdi functions.
973.Pp
974To get started with the framework, a driver will need to call
975.Xr usba_hcdi_register 9F
976with a filled out
977.Xr usba_hcdi_register_args_t 9S
978structure.
979That registration structure includes the operation vector of callbacks that the
980driver fills in, which involve opening and closing pipes
981.Po
982.Xr usba_hcdi_pipe_open 9E
983.Pc ,
984issuing the various ctrl, interrupt, bulk, and isochronous transfers
985.Po
986.Xr usba_hcdi_pipe_bulk_xfer 9E ,
987etc.
988.Pc ,
989and more.
990.Sh DTRACE PROBES
991By default, the DTrace
992.Xr fbt 4D ,
993function boundary tracing,
994provider will create DTrace probes based on the entry and return points
995of most functions in a module
996.Pq the primary exception being for some hand-written assembler .
997While this is very powerful, there are often times that driver writers
998want to define their own semantic probes.
999The
1000.Xr sdt 4D ,
1001statically defined tracing, provider can be used for this.
1002.Pp
1003To define an SDT probe, a driver should include
1004.In sys/sdt.h ,
1005which defines several macros for probes based on the number of arguments
1006that are present.
1007Each probe takes a name, which is constrained by the rules of a C
1008identifier.
1009If two underscore characters are present in a row
1010.Pq Sq _
1011they will be transformed into a hyphen
1012.Pq Sq - .
1013That is a probe declared with a name of
1014.Sq hello__world
1015will be named
1016.Sq hello-world
1017and accessible as the DTrace probe
1018.Ql sdt:::hello-world .
1019.Pp
1020Each probe can present a varying number of arguments in DTrace, ranging
1021from 0-8.
1022For each DTrace probe argument, one passes both the type of the argument
1023and the actual value.
1024The following example from the
1025.Xr igc 4D
1026driver shows a DTrace probe that provides four arguments and would be
1027accessible using the probe
1028.Ql sdt:::igc-context-desc :
1029.Bd -literal -offset indent
1030DTRACE_PROBE4(igc__context__desc, igc_t *, igc, igc_tx_ring_t *,
1031    ring, igc_tx_state_t *, tx, struct igc_adv_tx_context_desc *,
1032    ctx);
1033.Ed
1034.Pp
1035In the above example,
1036.Fa igc ,
1037.Fa ring ,
1038.Fa tx ,
1039and
1040.Fa ctx
1041are local variables and function parameters.
1042.Pp
1043By default SDT probes are considered
1044.Sy Volatile ,
1045in other words they can change at any time and disappear.
1046This is used to encourage widespread use of SDT probes for what may be
1047useful for a particular problem or issue that is being investigated.
1048SDT probes that are stabilized are transformed into their own first
1049class provider.
1050.Sh SEE ALSO
1051.Xr Intro 9 ,
1052.Xr Intro 9F ,
1053.Xr Intro 9S
1054