Solaris device driver tutorial

  • Upload
    pericoi

  • View
    240

  • Download
    0

Embed Size (px)

Citation preview

  • 7/28/2019 Solaris device driver tutorial

    1/124

    Device Driver Tutorial

    Sun Microsystems, Inc.4150 Network CircleSanta Clara, CA 95054U.S.A.

    PartNo: 817578915April 2008

  • 7/28/2019 Solaris device driver tutorial

    2/124

    Copyright2008 SunMicrosystems, Inc. 4150 Network Circle, Santa Clara,CA 95054 U.S.A. Allrightsreserved.

    SunMicrosystems, Inc. hasintellectual property rightsrelatingto technology embodied in theproduct that is describedin this document.In particular, andwithoutlimitation, these intellectualpropertyrights mayinclude oneor more U.S. patents or pending patentapplications in theU.S. andin other countries.

    U.S. Government Rights Commercial sotware. Government users are subject to the Sun Microsystems, Inc. standard license agreement and applicableprovisionso theFARand itssupplements.

    This distribution may include materials developed by thirdparties.Partso theproduct maybe derived rom Berkeley BSDsystems, licensed rom theUniversity o Caliornia. UNIXis a registered trademarkin theU.S. andothercountries, exclusivelylicensed through X/OpenCompany, Ltd.

    Sun, SunMicrosystems, theSun logo, theSolaris logo, theJavaCofeeCup logo, docs.sun.com,Java,and Solaris aretrademarks or registered trademarks o SunMicrosystems, Inc. in theU.S. andothercountries. AllSPARC trademarks areused under licenseand aretrademarks or registered trademarks o SPARCInternational, Inc. in theU.S. andothercountries. Products bearing SPARCtrademarks arebasedupon an architecturedeveloped by SunMicrosystems, Inc.

    The OPENLOOKandSunTM GraphicalUser Interacewas developedby SunMicrosystems, Inc. orits users andlicensees. Sunacknowledges thepioneering efortso Xerox in researching anddeveloping theconcept o visualor graphicaluser interaces orthe computer industry.Sun holds a non-exclusive licenseromXeroxtotheXeroxGraphical UserInterace,whichlicense also coversSun'slicenseeswho implementOPEN LOOK GUIs andotherwise complywith Sun's written licenseagreements.

    Products covered by andinormationcontained in this publication arecontrolled by U.S. ExportControl laws andmay be subjectto theexport or importlaws inother countries. Nuclear,missile,chemicalor biological weapons or nuclear maritime enduses or endusers,whether director indirect,are strictly prohibited. Exportor reexport to countriessubject to U.S. embargo or to entities identiedon U.S. exportexclusion lists,including, butnot limited to,the deniedpersons andspeciallydesignated nationals lists is strictly prohibited.

    DOCUMENTATION IS PROVIDED AS IS AND ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONSAND WARRANTIES, INCLUDINGANYIMPLIED WARRANTYOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPTTOTHEEXTENTTHAT SUCH DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.

    Copyright2008 SunMicrosystems, Inc. 4150 Network Circle, Santa Clara,CA 95054 U.S.A. Tous droitsrservs.

    SunMicrosystems, Inc. dtient lesdroits de propritintellectuellerelatis la technologie incorpore dans le produit quiest dcritdans ce document.En particulier,

    et ce sans limitation, cesdroits de propritintellectuellepeuvent inclure un ou plusieursbrevets amricains ou desapplications de breveten attente auxEtats-Uniset dans d'autres pays.

    Cette distribution peut comprendredes composants dveloppspar des tierces personnes.

    Certainescomposants de ce produit peuvent tre drives du logiciel Berkeley BSD, licencispar l'Universitde Caliornie. UNIXest unemarque dpose auxEtats-Uniset dans d'autres pays; elle estlicencie exclusivementpar X/OpenCompany,Ltd.

    Sun, SunMicrosystems, le logo Sun, le logo Solaris, le logo Java Cofee Cup, docs.sun.com,Java et Solaris sont desmarques de abrique ou desmarques dposes deSunMicrosystems, Inc. auxEtats-Unis et dans d'autres pays. Toutesles marques SPARCsont utilisessous licence et sont desmarques de abrique ou desmarquesdposes de SPARC International, Inc. auxEtats-Uniset dans d'autres pays. Lesproduitsportant lesmarques SPARC sont bass surune architecturedveloppe parSun Microsystems, Inc.

    L'interace d'utilisation graphiqueOPEN LOOK et Suna tdveloppe parSun Microsystems, Inc. pour ses utilisateurset licencis. Sunreconnat leseforts de

    pionniersde Xerox pour la rechercheet le dveloppement du concept desinteraces d'utilisation visuelle ou graphiquepour l'industrie de l'inormatique.Sun dtientunelicence nonexclusive de Xerox surl'interaced'utilisation graphiqueXerox, cette licence couvrant galementles licencisde Sunqui mettent en place l'interaced'utilisation graphiqueOPEN LOOK et qui, en outre,se conorment auxlicencescrites de Sun.

    Lesproduitsqui ont l'objet de cette publication et lesinormations qu'il contient sontrgispar la legislation amricaine en matire de contrle desexportations etpeuvent tre soumisau droit d'autres pays dans le domaine desexportations et importations. Lesutilisations nales, ou utilisateursnaux, pour desarmesnuclaires,des missiles, des armeschimiques ou biologiquesou pour le nuclaire maritime, directementou indirectement, sont strictementinterdites. Les exportations ourexportations vers despays sous embargo desEtats-Unis,ou vers desentits gurantsur leslistes d'exclusion d'exportation amricaines, y compris, mais de manirenonexclusive, la liste de personnesqui ontobjet d'un ordre de ne pasparticiper,d'uneaondirecte ou indirecte, auxexportations desproduitsou desservicesquisont rgispar la legislationamricaine en matire de contrle des exportations et la listede ressortissants spciquement designs, sont rigoureusement interdites.

    LA DOCUMENTATION EST FOURNIE "EN L'ETAT" ET TOUTES AUTRES CONDITIONS, DECLARATIONS ET GARANTIES EXPRESSES OU TACITESSONT FORMELLEMENTEXCLUES, DANS LA MESUREAUTORISEE PAR LA LOI APPLICABLE, Y COMPRISNOTAMMENTTOUTE GARANTIEIMPLICITE RELATIVE A LA QUALITE MARCHANDE, A L'APTITUDE A UNE UTILISATION PARTICULIERE OU A L'ABSENCE DE CONTREFACON.

    080401@19860

  • 7/28/2019 Solaris device driver tutorial

    3/124

    Contents

    Preace ...................................................................................................................................................11

    1 Introduction to Device Drivers ..........................................................................................................15

    Solaris Operating System Denition ................................................................................................. 15

    Kernel Overview ...................................................................................................................... ............ 15

    Diferences Between Kernel Modules and User Programs ..................................................... 15

    User and Kernel Address Spaces on x86 and SPARC Machines ............................................. 18

    Device Drivers .............................................................................................................................. 19

    Driver Directory Organization ................................................................................................... 21

    Devices as Files ....................................................................................................................... .............. 22

    Devices Directories ...................................................................................................................... 23

    Device Tree ................................................................................................................................... 23

    Character and Block Devices ...................................................................................................... 24

    Device Names ............................................................................................................................... 24

    Device Numbers ........................................................................................................................... 25

    Development Environment and Tools ............................................................................................. 26

    Writing a Driver ........................................................................................................................... 27

    Building a Driver .......................................................................................................................... 28

    Installing a Driver ........................................................................................................................ 31

    Adding, Updating, and Removing a Driver .............................................................................. 32Loading and Unloading a Driver ............................................................................................... 33

    Testing a Driver ............................................................................................................................ 33

    2 Template Driver Example ...................................................................................................................35

    Overview o the Template Driver Example ...................................................................................... 35

    Writing the Template Driver ............................................................................................................. 36Writing the Loadable Module Conguration Entry Points .................................................... 37

    3

  • 7/28/2019 Solaris device driver tutorial

    4/124

    Writing the Autoconguration Entry Points ............................................................................ 41

    Writing the User Context Entry Points ..................................................................................... 48

    Writing the Driver Data Structures ........................................................................................... 52Writing the Device Conguration File ............................................................................................. 58

    Building and Installing the Template Driver ................................................................................... 58

    Testing the Template Driver .............................................................................................................. 59

    Adding the Template Driver ....................................................................................................... 59

    Reading and Writing the Device ................................................................................................ 60

    Removing the Template Driver .................................................................................................. 61

    Complete Template Driver Source .................................................................................................... 62

    3 Reading and Writing Datain Kernel Memory ................................................................................. 67

    Displaying Data Stored in Kernel Memory ...................................................................................... 67

    Writing Quote O The Day Version 1 ....................................................................................... 67

    Building, Installing, and Using Quote O The Day Version 1 ................................................ 69Displaying Data on Demand .............................................................................................................. 70

    Writing Quote O The Day Version 2 ....................................................................................... 70

    Building, Installing, and Using Quote O The Day Version 2 ................................................ 80

    Modiying Data Stored in Kernel Memory ....................................................................................... 82

    Writing Quote O The Day Version 3 ....................................................................................... 82

    Building and Installing Quote O The Day Version 3 ........................................................... 103

    Using Quote O The Day Version 3 ......................................................................................... 104

    4 Tips orDeveloping Device Drivers ................................................................................................111

    Device Driver Coding Tips ............................................................................................................... 112

    Device Driver Testing Tips ............................................................................................................... 115

    Device Driver Debugging and Tuning Tips ................................................................................... 117

    Index ................................................................................................................................................... 119

    Contents

    Device Driver Tutorial April 20084

  • 7/28/2019 Solaris device driver tutorial

    5/124

    Figures

    FIGURE 11 Typical Device Driver Entry Points .........................................................................19

    FIGURE 12 Entry Points or Diferent Types o Drivers ........................................................... 20

    FIGURE 13 Typical Device Driver Interactions ......................................................................... 21

    FIGURE 21 Entry Points or the dummy Example ........................................................................ 36

    5

  • 7/28/2019 Solaris device driver tutorial

    6/124

    6

  • 7/28/2019 Solaris device driver tutorial

    7/124

    Tables

    TABLE 21 Get Driver Inormation Entry Point Arguments ................................................... 46

    7

  • 7/28/2019 Solaris device driver tutorial

    8/124

    8

  • 7/28/2019 Solaris device driver tutorial

    9/124

    Examples

    EXAMPLE 31 Quote O The Day Version 1 Source File ................................................................ 68

    EXAMPLE 32 Quote O The Day Version 1 Conguration File ...................................................69

    EXAMPLE 33 Quote O The Day Version 2 Source File ................................................................ 74

    EXAMPLE 34 Quote O The Day Version 2 Conguration File ...................................................80

    EXAMPLE 35 Quote O The Day Version 3 Source File ................................................................ 91

    EXAMPLE 36 Quote O The Day Version 3 Header File .............................................................102

    EXAMPLE 37 Quote O The Day Version 3 Conguration File .................................................103

    EXAMPLE 38 Quote O The Day I/O Control Command Source File ......................................106

    9

  • 7/28/2019 Solaris device driver tutorial

    10/124

    10

  • 7/28/2019 Solaris device driver tutorial

    11/124

    Preace

    This Device Driver Tutorialis a hands-on guide that shows you how to develop a simple device

    driver or the SolarisTM

    Operating System (Solaris OS). Device Driver Tutorialalso explains howdevice drivers work in the Solaris OS. This book is a companion to Writing Device Drivers.Writing Device Drivers is a thorough reerence document that discusses many types o devicesand drivers. Device Driver Tutorialexamines complete drivers but does not provide acomprehensive treatment o all driver types. Device Driver Tutorialoten points to WritingDevice Drivers and other books or urther inormation.

    Note This Solaris release supports systems that use the SPARC and x86 amilies o processorarchitectures: UltraSPARC, SPARC64, AMD64, Pentium, and Xeon EM64T. The supportedsystems appear in the Solaris OS Hardware Compatibility Lists athttp://www.sun.com/bigadmin/hcl/ . This document cites any implementation diferencesbetween the platorm types.

    Who Should Use This BookYou should read this tutorial i you need to develop, install, and congure device drivers or theSolaris OS. You also should read this book i you need to maintain existing drivers or add newunctionality to existing Solaris OS drivers. Inormation about the kernel provided in this bookalso will help you troubleshoot any problems you might encounter installing or conguringSolaris systems.

    User BackgroundTo write device drivers or the Solaris OS, you should have the ollowing background:

    Be a condent C programmer Have experience with data structures, especially with linked lists Understand bit operations Understand indirect unction calls Understand caching Understand multithreading (see theMultithreaded Programming Guide)

    11

    http://www.sun.com/bigadmin/hcl/http://www.sun.com/bigadmin/hcl/
  • 7/28/2019 Solaris device driver tutorial

    12/124

    Be amiliar with a UNIX shell Understand the basics o UNIX system and I/O architecture

    The most important inormation you need to have to write a device driver are thecharacteristics o the device. Get a detailed specication or the device you want to drive.

    Experience with Solaris OS compilers, debuggers, and other tools will be very helpul to you.You also need to understand where the le system ts with the kernel and the application layer.These topics are discussed in this tutorial.

    How This Book Is OrganizedThis book is organized into the ollowing chapters:

    Chapter 1, Introduction to Device Drivers, provides an overview o the Solaris OperatingSystem and kernel. This chapter also discusses the driver development environment and tools.

    Chapter 2, Template Driver Example, shows a simple template driver. This chapter shows indetail the steps to develop, build, install, load, and test this simple driver.

    Chapter 3, Reading and Writing Data in Kernel Memory, describes how to develop a driverthat reads data rom and writes data to kernel memory.

    Chapter 4, Tips or Developing Device Drivers, discusses some common errors in driverdevelopment and how to avoid them or handle them. This chapter also introduces driveranalysis and debugging tools.

    Related BooksFor detailed reerence inormation about the device driver interaces, see the section 9 manpages. Section 9E, Intro(9E), describes DDI/DKI (Device Driver Interace, Driver-KernelInterace) driver entry points. Section 9F, Intro(9F), describes DDI/DKI kernel unctions.Sections 9P and 9S, Intro(9S), describe DDI/DKI properties and data structures.

    For inormation on other driver-related tools and issues, see these books rom SunMicrosystems:

    Writing Device Drivers. Sun Microsystems, Inc., 2007.

    Multithreaded Programming Guide. Sun Microsystems, Inc., 2005.

    STREAMS Programming Guide. Sun Microsystems, Inc., 2005.

    Solaris 64-bit Developers Guide. Sun Microsystems, Inc., 2005.

    Sun Studio 12: C Users Guide. Sun Microsystems, Inc., 2007.

    ClickSun Studio 12 Collection at the top let o this page to see Sun Studio books about dbx,dmake, Perormance Analyzer, and other sotware development topics.

    Preace

    Device Driver Tutorial April 200812

  • 7/28/2019 Solaris device driver tutorial

    13/124

    Solaris Modular Debugger Guide. Sun Microsystems, Inc., 2007.

    Solaris Dynamic Tracing Guide. Sun Microsystems, Inc., 2007.

    DTrace User Guide. Sun Microsystems, Inc., 2006. System Administration Guide: Devices and File Systems. Sun Microsystems, Inc., 2007.

    Application Packaging Developers Guide. Sun Microsystems, Inc., 2005.

    Documentation, Support, andTraining

    The Sun web site provides inormation about the ollowing additional resources:

    Documentation (http://www.sun.com/documentation/) Support (http://www.sun.com/support/) Training (http://www.sun.com/training/)

    Typographic ConventionsThe ollowing table describes the typographic conventions that are used in this book.

    TABLE P1 TypographicConventions

    Typeface Meaning Example

    AaBbCc123 The names o commands, les, anddirectories,and onscreen computer output Edit your.login le.

    Use ls -a to list all les.

    machine_name% you have mail.

    AaBbCc123 What youtype, contrasted with onscreen

    computer outputmachine_name% su

    Password:

    aabbcc123 Placeholder: replace with a real nameor value The command to remove a le is rm

    flename.

    AaBbCc123 Book titles, new terms, and terms to be

    emphasized

    ReadChapter 6 in the User's Guide.

    A cache is a copy that is stored

    locally.

    Do notsave thele.

    Note: Some emphasized itemsappear bold online.

    Preace

    13

    http://www.sun.com/documentation/http://www.sun.com/documentation/http://www.sun.com/documentation/http://www.sun.com/support/http://www.sun.com/support/http://www.sun.com/support/http://www.sun.com/training/http://www.sun.com/training/http://www.sun.com/training/http://www.sun.com/training/http://www.sun.com/support/http://www.sun.com/documentation/
  • 7/28/2019 Solaris device driver tutorial

    14/124

    Shell Prompts in Command ExamplesThe ollowing table shows the deault UNIX system prompt and superuser prompt or the Cshell, Bourne shell, and Korn shell.

    TABLE P2 Shell Prompts

    Shell Prompt

    C shell machine_name%

    C shell or superuser machine_name#

    Bourne shell andKorn shell $

    Bourne shell andKorn shell or superuser #

    Preace

    Device Driver Tutorial April 200814

  • 7/28/2019 Solaris device driver tutorial

    15/124

    Introduction to Device Drivers

    This chapter gives an overview o the Solaris Operating System and kernel. This chapter alsogives an overview o the driver development environment and the development tools availableto you.

    Solaris Operating System DefnitionThe Solaris Operating System (Solaris OS) is implemented as an executable le that runs at boottime. The Solaris OS is reerred to as the kernel. The kernel contains all o the routines that arenecessary or the system to run. Because the kernel is essential or the running o the machine,the kernel runs in a special, protected mode that is called kernel mode. In contrast, user-levelapplications operate in a restricted mode called user mode that has no access to kernelinstructions or to the kernel address space. Device drivers run in kernel mode and are prevented

    rom directly accessing processes in user mode.

    Kernel OverviewThe kernel manages the system resources, including le systems, processes, and physicaldevices. The kernel provides applications with system services such as I/O management, virtualmemory, and scheduling. The kernel coordinates interactions o all user processes and system

    resources. The kernel assigns priorities, services resource requests, and services hardwareinterrupts and exceptions. The kernel schedules and switches threads, pages memory, andswaps processes.

    Dierences Between Kernel Modules and UserPrograms

    This section discusses several important diferences between kernel modules and userprograms.

    1C H A P T E R 1

    15

  • 7/28/2019 Solaris device driver tutorial

    16/124

    Execution Dierences Between Kernel Modules and User Programs

    The ollowing characteristics o kernel modules highlight important diferences between the

    execution o kernel modules and the execution o user programs: Kernel modules have separate address space.A module runs in kernel space. An

    application runs in user space. System sotware is protected rom user programs. Kernel

    space and user space have their own memory address spaces. See User and Kernel Address

    Spaces on x86 and SPARC Machines on page 18 or important inormation about address

    spaces.

    Kernelmodules havehigher execution privilege.Code that runs in kernel space has

    greater privilege than code that runs in user space. Driver modules potentially have a muchgreater impact on the system than user programs. Test and debug your driver modules

    careully and thoroughly to avoid adverse impact on the system. See Device Driver Testing

    Tips on page 115.

    Kernelmodules donotexecute sequentially.A user program typically executes

    sequentially and perorms a single task rom beginning to end. A kernel module does not

    execute sequentially. A kernel module registers itsel in order to serve uture requests.

    Kernel modules canbe interrupted.More than one process can request your driver at thesame time. An interrupt handler can request your driver at the same time that your driver is

    serving a system call. In a symmetric multiprocessor (SMP) system, your driver could be

    executing concurrently on more than one CPU.

    Kernel modulesmust bepreemptable. You cannot assume that your driver code is sae just

    because your driver code does not block. Design your driver assuming your driver might be

    preempted.

    Kernel modules cansharedata.Diferent threads o an application program usually do notshare data. By contrast, the data structures and routines that constitute a driver are shared

    by all threads that use the driver. Your driver must be able to handle contention issues that

    result rom multiple requests. Design your driver data structures careully to keep multiple

    threads o execution separate. Driver code must access shared data without corrupting the

    data. See Chapter 3, Multithreading, in Writing Device Drivers andMultithreaded

    Programming Guide.

    Kernel Overview

    Device Driver Tutorial April 200816

  • 7/28/2019 Solaris device driver tutorial

    17/124

    Structural Dierences Between Kernel Modules and User Programs

    The ollowing characteristics o kernel modules highlight important diferences between the

    structure o kernel modules and the structure o user programs: Kernelmodules donot defne amainprogram.Kernel modules, including device drivers,

    have no main() routine. Instead, a kernel module is a collection o subroutines and data. A

    device driver is a kernel module that orms a sotware interace to an input/output (I/O)

    device. The subroutines in a device driver provide entry points to the device. The kernel uses

    a device number attribute to locate the open() routine and other routines o the correct

    device driver. See Device Drivers on page 19 or more inormation on entry points. See

    Device Numbers on page 25 or a description o device numbers. Kernelmodules are linkedonly to thekernel. Kernel modules do not link in the same

    libraries that user programs link in. The only unctions a kernel module can call are

    unctions that are exported by the kernel. I your driver reerences symbols that are not

    dened in the kernel, your driver will compile but will ail to load. Solaris OS driver modules

    should use prescribed DDI/DKI (Device Driver Interace, Driver-Kernel Interace)

    interaces. When you use these standard interaces you can upgrade to a new Solaris release

    or migrate to a new platorm without recompiling your driver. For more inormation on the

    DDI, seeDDI/DKI Interaces in Writing Device Drivers. Kernel modules can depend on

    other kernel modules by using the -N option during link editing. See the ld(1) man page or

    more inormation.

    Kernelmodules usedierentheaderfles.Kernel modules require a diferent set o header

    les than user programs require. The required header les are listed in the man page or

    each unction. See man pages section 9: DDI and DKI Kernel Functions or DDI/DKI

    unctions, man pages section 9: DDI and DKI Driver Entry Points or entry points, and man

    pages section 9: DDI and DKI Properties and Data Structures or structures. Kernel modulescan include header les that are shared by user programs i the user and kernel interaces

    within such shared header les are dened conditionally using the _KERNEL macro.

    Kernelmodules shouldavoidglobalvariables. Avoiding global variables in kernel

    modules is even more important than avoiding global variables in user programs. As much

    as possible, declare symbols as static. When you must use global symbols, give them a

    prex that is unique within the kernel. Using this prex or private symbols within the

    module also is a good practice. Kernelmodules canbe customized orhardware.Kernel modules can dedicate process

    registers to specic roles. Kernel code can be optimized or a specic processor.

    Kernelmodules canbedynamically loaded. The collection o subroutines and data that

    constitute a device driver can be compiled into a single loadable module o object code. This

    loadable module can then be statically or dynamically linked into the kernel and unlinked

    rom the kernel. You can add unctionality to the kernel while the system is up and running.

    You can test new versions o your driver without rebooting your system.

    Kernel Overview

    Chapter 1 Introduction to Device Drivers 17

  • 7/28/2019 Solaris device driver tutorial

    18/124

    Data Transer Dierences Between Kernel Modules and User Programs

    Data transer between a device and the system typically is slower than data transer within the

    CPU. Thereore, a driver typically suspends execution o the calling thread until the datatranser is complete. While the thread that called the driver is suspended, the CPU is ree toexecute other threads. When the data transer is complete, the device sends an interrupt. Thedriver handles the interrupt that the driver receives rom the device. The driver then tells theCPU to resume execution o the calling thread. See Chapter 8, Interrupt Handlers, in WritingDevice Drivers.

    Drivers must work with user process (virtual) addresses, system (kernel) addresses, and I/O busaddresses. Drivers sometimes copy data rom one address space to another address space andsometimes just manipulate address-mapping tables. See Bus Architectures in Writing DeviceDrivers.

    User and Kernel Address Spaces on x86 and SPARCMachines

    On SPARC machines, the system panics when a kernel module attempts to directly access useraddress space. You must make sure your driver does not attempt to directly access user addressspace on a SPARC machine.

    On x86 machines, the system does not enter an error state when a kernel module attempts todirectly access user address space. You still should make sure your driver does not attempt todirectly access user address space on an x86 machine. Drivers should be written to be asportable as possible. Any driver that directly accesses user address space is a poorly written

    driver.

    Caution A driver that works on an x86 machine might not work on a SPARC machine becausethe driver might access an invalid address.

    Do not access user data directly. A driver that directly accesses user address space is using poor

    programming practice. Such a driver is not portable and is not supportable. Use theddi_copyin(9F) and ddi_copyout(9F) routines to transer data to and rom user address space.These two routines are the only supported interaces or accessing user memory. ModiyingData Stored in Kernel Memory on page 82 shows an example driver that uses ddi_copyin(9F)and ddi_copyout(9F).

    The mmap(2) system call maps pages o memory between a process's address space and a le orshared memory object. In response to an mmap(2) system call, the system calls the devmap(9E)entry point to map device memory into user space. This inormation is then available or directaccess by user applications.

    Kernel Overview

    Device Driver Tutorial April 200818

  • 7/28/2019 Solaris device driver tutorial

    19/124

    Device Drivers

    A device driver is a loadable kernel module that manages data transers between a device and

    the OS. Loadable modules are loaded at boot time or by request and are unloaded by request. Adevice driver is a collection o C routines and data structures that can be accessed by other

    kernel modules. These routines must use standard interaces called entry points. Through the

    use o entry points, the calling modules are shielded rom the internal details o the driver. See

    Device Driver Entry Points in Writing Device Drivers or more inormation on entry points.

    A device driver declares its general entry points in its dev_ops(9S) structure. A driver declares

    entry points or routines that are related to character or block data in its cb_ops(9S) structure.

    Some entry points and structures that are common to most drivers are shown in the ollowing

    diagram.

    The Solaris OS provides many driver entry points. Diferent types o devices require diferent

    entry points in the driver. The ollowing diagram shows some o the available entry points,

    grouped by driver type. No single device driver would use all the entry points shown in the

    diagram.

    cb_ops Structure

    xxopen(9E)xxclose(9E)...

    xxprop_op(9E)For property information

    dev_ops Structure

    xxattach(9E)xxdetach(9E)xxgetinfo(9E)xxprobe(9E)...xx_init(9E)xx_fini(9E)xx_info(9E)...xxks_snapshot(9E)xxks_update(9E)...xxpower(9E)

    ...xxdump(9E)

    For autoconfiguration

    For kernel statistics

    For operating onloadable modules

    For power management

    For dumping memory duringsystem failure

    FIGURE 11 Typical DeviceDriver Entry Points

    Kernel Overview

    Chapter 1 Introduction to Device Drivers 19

  • 7/28/2019 Solaris device driver tutorial

    20/124

    In the Solaris OS, drivers can manage physical devices, such as disk drives, or sotware (pseudo)

    devices, such as bus nexus devices or ramdisk devices. In the case o hardware devices, the

    device driver communicates with the hardware controller that manages the device. The device

    driver shields the user application layer rom the details o a specic device so that application

    level or system calls can be generic or device independent.

    Drivers are accessed in the ollowing situations:

    System initialization. The kernel calls device drivers during system initialization to

    determine which devices are available and to initialize those devices.

    Systemcalls romuser processes.The kernel calls a device driver to perorm I/O operations

    on the device such as open(2), read(2), and ioctl(2).

    User-level requests.The kernel calls device drivers to service requests rom commands such

    as prtconf(1M).

    Generic LAN DeviceDriver Entry Points

    ...gldm_(9E)gldm_get_stats(9E)gldm_intr(9E)

    gldm_ioctl(9E)gldm_reset(9E)gldm_send(9E)gldm_set_mac_addr(9E)gldm_set_multicast(9E)gldm_set_promiscuous(9E)gldm_start(9E)gldm_stop(9E)...

    SCSI HBA DeviceDriver Entry Points

    ...tran_abort(9E)tran_bus_reset(9E)tran_destroy_pkt(9E)tran_dma_free(9E)tran_getcap(9E)tran_init_pkt(9E)tran_quiesce(9E)tran_reset(9E)

    tran_reset_notify(9E)tran_setcap(9E)tran_start(9E)tran_sync_pkt(9E)tran_tgt_free(9E)tran_tgt_init(9E)tran_tgt_probe(9E)tran_unquiesce(9E)...

    Block DriverEntry Points

    ...aread(9E)awrite(9E)print(9E)strategy(9E)...

    Memory Mapped DeviceDriver Entry Points

    ...devmap9E)devmap_access(9E)devmap_contextmgt(9E)devmap_dup(9E)devmap_map(9E)devmap_unmap(9E)...

    Character Device

    Driver Entry Points

    ...chpoll9E)ioctl(9E)read(9E)write(9E)segmap(9E)...

    STREAMS DeviceDriver Entry Points

    ...put9E)srv(9E)...

    PC Card DeviceDriver Entry Points

    ...csx_event_handler(9E)...

    FIGURE 12 Entry Points or Diferent Types o Drivers

    Kernel Overview

    Device Driver Tutorial April 200820

    K l O i

  • 7/28/2019 Solaris device driver tutorial

    21/124

    Device interrupts.The kernel calls a device driver to handle interrupts generated by adevice.

    Busreset. The kernel calls a device driver to re-initialize the driver, the device, or both whenthe bus is reset. The bus is the path rom the CPU to the device.

    The ollowing diagram illustrates how a device driver interacts with the rest o the system.

    Driver Directory Organization

    Device drivers and other kernel modules are organized into the ollowing directories in theSolaris OS. See the kernel(1M) and system(4) man pages or more inormation about kernelorganization and how to add directories to your kernel module search path.

    /kernel These modules are common across most platorms.Modules that are required or booting or or systeminitialization belong in this directory.

    /platform/uname -i/kernel These modules are specic to the platorm identied by thecommand uname -i.

    /platform/uname -m/kernel These modules are specic to the platorm identied by thecommand uname -m. These modules are specic to ahardware class but more generic than modules in the uname-i kernel directory.

    boot Bus driver

    HW controller

    Device driver

    Userapplication

    Systemcommand

    init() bus reset

    Device

    interrupt

    interrupt

    Kernel level

    User level

    read(2) prtconf(1M)

    FIGURE 13 Typical DeviceDriver Interactions

    Kernel Overview

    Chapter 1 Introduction to Device Drivers 21

    Devices as Files

  • 7/28/2019 Solaris device driver tutorial

    22/124

    /usr/kernel These are user modules. Modules that are not essential tobooting belong in this directory. This tutorial instructs youto put all your drivers in the /usr/kernel directory.

    One benet o organizing drivers into diferent directories is that you can selectively loaddiferent groups o drivers on startup when you boot interactively at the boot prompt as shownin the ollowing example. See the boot(1M) man page or more inormation.

    Type b [file-name] [boot-flags] to boot with options

    or i to enter boot interpreter

    or to boot with defaults

    >

    Select (b)oot or (i)nterpreter: b -a

    bootpath: /pci@0,0/pci8086,2545@3/pci8086,

    Enter default directory for modules [/platform/i86pc/kernel /kernel

    /usr/kernel]: /platform/i86pc/kernel /kernel

    In this example, the /usr/kernel location is omitted rom the list o directories to search or

    modules to load. You might want to do this i you have a driver in /usr/kernel that causes thekernel to panic during startup or on attach. Instead o omitting all /usr/kernel modules, abetter method or testing drivers is to put them in their own directory. Use the moddir kernelvariable to add this test directory to your kernel modules search path. The moddir kernelvariable is described in kernel(1M) and system(4). Another method or working with driversthat might have startup problems is described in Device Driver Testing Tips on page 115.

    Devices as FilesIn UNIX, almost everything can be treated as a le. UNIX user applications access devices as ithe devices were les. Files that represent devices are called special fles or device nodes. Devicespecial les are divided into two classes: block devices and characterdevices. See Character andBlock Devices on page 24 or more inormation.

    Every I/O service request initially reers to a named le. Most I/O operations that read or write

    data perorm equally well on ordinary or special les. For example, the same read(2) system callreads bytes rom a le created with a text editor and reads bytes rom a terminal device.

    Control signals also are handled as les. Use the ioctl(9E) unction to manipulate controlsignals.

    Devices as Files

    Device Driver Tutorial April 200822

    Devices as Files

  • 7/28/2019 Solaris device driver tutorial

    23/124

    Devices Directories

    The Solaris OS includes both /dev and /devices directories or device drivers. Almost all the

    drivers in the /dev directory are links to the /devices directory. The /dev directory is UNIXstandard. The /devices directory is specic to the Solaris OS.

    By convention, le names in the /dev directory are more readable. For example, the /devdirectory might contain les with names such as kdb and mouse that are links to les such as/devices/pseudo/conskbd@0:kbd and /devices/pseudo/consms@0:mouse .Theprtconf(1M) command shows device names that are very similar to the le names in the/devices directory. In the ollowing example, only selected output o the command is shown.

    % prtconf -P

    conskbd, instance #0

    consms, instance #0

    Entries in the /dev directory that are not links to the /devices directory are device nodes orspecial les created bymknod(1M) or mknod(2). These are zero-length les that just have a majornumber and minor number attached to them. Linking to the physical name o the device in the/devices directory is preerred to using mknod(1M).

    Prior to the Solaris 10 OS, /devices was an on-disk lesystem composed o subdirectories andles. Beginning with the Solaris 10 OS, /devices is a virtual lesystem that creates thesesubdirectories and special les on demand.

    For more inormation about the devices le system, see the devfs(7FS) man page.

    DeviceTreeThe device les in the /devices directory are also called the device tree.

    The device tree shows relationships among devices. In the device tree, a directory represents anexus device. A nexus is a device that can be a parent o other devices. In the ollowing example,pci@1f,0 is a nexus device. Only selected output rom the command is shown.

    # ls -l /devicesdrwxr-xr-x 4 root sys 512 date time pci@1f,0/crw------- 1 root sys 111,255 date time pci@1f,0:devctl

    You can use prtconf(1M) or prtpicl(1M) to see a graphic representation o the device tree.See Overview o the Device Tree in Writing Device Drivers or more inormation about thedevice tree.

    Devices as Files

    Chapter 1 Introduction to Device Drivers 23

    Devices as Files

  • 7/28/2019 Solaris device driver tutorial

    24/124

    Character and Block Devices

    A le in the device tree that is not a directory represents either a characterdevice or a block

    device.

    A block device can contain addressable, reusable data. An example o a block device is a lesystem. Any device can be a character device. Most block devices also have character interaces.Disks have both block and character interaces. In your /devices/pseudo directory, you mightnd devices such as the ollowing:

    brw-r----- 1 root sys 85, 0 Nov 3 09:43 md@0:0,0,blk

    crw-r----- 1 root sys 85, 0 Nov 3 09:43 md@0:0,0,rawbrw-r----- 1 root sys 85, 1 Nov 3 09:43 md@0:0,1,blk

    crw-r----- 1 root sys 85, 1 Nov 3 09:43 md@0:0,1,raw

    brw-r----- 1 root sys 85, 2 Nov 3 09:43 md@0:0,2,blk

    crw-r----- 1 root sys 85, 2 Nov 3 09:43 md@0:0,2,raw

    Block devices have a b as the rst character o their le mode. Character devices have a c as therst character o their le mode. In this example, the block devices have blk in their names andthe character devices have raw in their names.

    The md(7D) device is a metadevice that provides disk services. The block devices access the diskusing the system's normal bufering mechanism. The character devices provide or directtransmission between the disk and the user's read or write bufer.

    Device Names

    This section shows a complex device name and explains the meaning o each part o the name in/dev and also in /devices. The ollowing example is the name o a disk slice:

    /dev/dsk/c0t0d0s7 -> ../../devices/pci@1c,600000/scsi@2/sd@0,0:h

    First, examine the name o the le in the /dev directory. These names are managed by thedevfsadmd(1M) daemon.

    c0 Controller 0

    t0 Target 0. On SCSI controllers, this value is the disk number.

    d0 SCSI LUN. This value indicates a virtual partitioning o a target or single physical device.

    s7 Slice 7 on the target 0 disk.

    For the same device, compare the name o the le in the /devices directory. These names showthe physical structure and real device names. Note that some o the components o the device

    name in the /devices directory are subdirectories.

    Device Driver Tutorial April 200824

    Devices as Files

  • 7/28/2019 Solaris device driver tutorial

    25/124

    pci@1c,600000 PCI bus at address 1c,600000. These addresses are meaningul only to theparent device.

    scsi@2 SCSI controller at address 2 on the PCI bus at address 1c,600000. Thisname corresponds to the c0 in /dev/dsk/c0t0d0s7.

    sd@0,0 SCSI disk at address 0,0 on the SCSI controller at address 2. This namerepresents target 0, LUN 0 and corresponds to the t0d0 in/dev/dsk/c0t0d0s7.The sd name and driver can also apply to IDECD-ROM devices.

    sd@0,0:h Minor node h on the SCSI disk at address 0,0. This name corresponds to

    thes7

    in/dev/dsk/c0t0d0s7

    .

    Device Numbers

    A device numberidenties a particular device and minor node in the device tree. The dev_tparameter that is required in many DDI/DKI routines is this device number.

    Each device has a major number and a minor number. A device number is a major,minorpair.A long le listing shows the device number in the column where le sizes are usually listed. Inthe ollowing example, the device number is 86,255. The device major number is 86, and thedevice minor number is 255.

    % ls -l /devices/pci@0,0:devctl

    crw------- 1 root sys 86,255 date time /devices/pci@0,0:devctl

    In the Solaris OS, the major number is chosen or you when you install the driver so that it will

    not conict with any other major number. The kernel uses the major number to associate theI/O request with the correct driver code. The kernel uses this association to decide which driverto execute when the user reads or writes the device le. All devices and their major numbers arelisted in the le /etc/name_to_major.

    % grep 86 /etc/name_to_major

    pci 86

    The minor number is assigned in the driver. The minor number must map each driver to aspecic device instance. Minor numbers usually reer to sub-devices. For example, a disk drivermight communicate with a hardware controller device that has several disk drives attached.Minor nodes do not necessarily have a physical representation.

    The ollowing example shows instances 0, 1, and 2 o the md device. The numbers 0, 1, and 2 arethe minor numbers.

    Chapter 1 Introduction to Device Drivers 25

    DevelopmentEnvironment and Tools

  • 7/28/2019 Solaris device driver tutorial

    26/124

    brw-r----- 1 root sys 85, 0 Nov 3 09:43 md@0:0,0,blk

    crw-r----- 1 root sys 85, 0 Nov 3 09:43 md@0:0,0,raw

    brw-r----- 1 root sys 85, 1 Nov 3 09:43 md@0:0,1,blk

    crw-r----- 1 root sys 85, 1 Nov 3 09:43 md@0:0,1,rawbrw-r----- 1 root sys 85, 2 Nov 3 09:43 md@0:0,2,blk

    crw-r----- 1 root sys 85, 2 Nov 3 09:43 md@0:0,2,raw

    In the name sd@0,0:h,, h represents a minor node. When the driver receives a request orminor node h, the driver actually receives a corresponding minor number. The driver or the sdnode interprets that minor number to be a particular section o disk, such as slice 7 mounted on/export.

    Chapter 2, Template Driver Example, shows how to use the ddi_get_instance(9F) routine inyour driver to get an instance number or the device you are driving.

    Development Environment and ToolsThis section summarizes the driver development process and provides some pointers toresources. For more inormation on the development process, see Driver DevelopmentSummary in Writing Device Drivers.

    Sun ofers training courses in Solaris OS internals, crash dump analysis, writing device drivers,DTrace, Sun Studio, and other topics useul to Solaris developers. Seehttp://www.sun.com/training/ or more inormation.

    The general steps in writing a device driver are as ollows:

    1. Write a.c

    source le using the interaces and structures dened in man page sections9E

    ,9F

    ,and 9S. Most o the include les you need are in /usr/include/sys. The unction andstructure man pages show which include les you need.

    2. Write a .conf hardware conguration le to dene property values or your driver.

    3. Compile and link your driver. Always use the -D_KERNEL option when you compile a driveror the Solaris OS. The deault compile result is 32-bit. To get a 64-bit result on a 64-bitplatorm, speciy the appropriate 64-bit option as described in Building a Driver onpage 28.

    4. Copy your driver binary le and your driver conguration le to the appropriate[platorm]/kernel directories. See Driver Directory Organization on page 21 ordescriptions o driver directories.

    5. Use the add_drv(1M) command to load your driver. When your driver is loaded, you cansee your driver in /dev and /devices. You can also see an entry or your driver in the/etc/name_to_major le.

    Device Driver Tutorial April 200826

    DevelopmentEnvironmentand Tools

    http://www.sun.com/training/http://www.sun.com/training/
  • 7/28/2019 Solaris device driver tutorial

    27/124

    Writing a Driver

    A driver consists o a C source le and a hardware conguration le.

    Writing a Driver Module

    The C code or a driver is a collection o data and unctions that dene a kernel module. Asnoted in Structural Diferences Between Kernel Modules and User Programs on page 17, adriver has no main() routine. Many o the subroutines o a driver are special unctions calledentry points. See Device Drivers on page 19 or inormation about entry points.

    The unction man pages provide both the unction declaration that you need in your driver andthe list o header les you need to include. Make sure you consult the correct man page. Forexample, the ollowing command displays the ioctl(2) man page. The ioctl(2) system callcannot be used in a device driver.

    % man ioctl

    Use one o the ollowing commands to display the ioctl(9E) man page. The ioctl(9E)subroutine is a device driver entry point.

    % man ioctl.9e

    % man -s 9e ioctl

    By convention, the names o unctions and data that are unique to this driver begin with acommon prex. The prex is the name o this driver or an abbreviation o the name o thisdriver. Use the same prex or all names that are specic to this driver. This practice makesdebugging much easier. Instead o seeing an error related to an ambiguous attach() unction,

    you see an error message about mydriver_attach() or newdriver_attach().

    A 64-bit system can run both 32-bit user programs and 64-bit user programs. A 64-bit systemruns 32-bit programs by converting all data needed between the two data models. A 64-bitkernel supports both 64-bit and 32-bit user data. Whenever a 64-bit driver copies data betweenkernel space and user space, the driver must use the ddi_model_convert_from(9F) unction todetermine whether the data must be converted between 32-bit and 64-bit models. For anexample, see Reporting and Setting Device Size and Re-initializing the Device on page 90.

    The Sun Studio IDE includes the ollowing three source editors: GVIM, XEmacs, and thebuilt-in Source Editor provided by NetBeans. The IDE provides online help or these tools. Youcan also run GVIM and XEmacs rom the command line. See vim(1) and xemacs(1).

    Chapter 1 Introduction to Device Drivers 27

    DevelopmentEnvironment and Tools

  • 7/28/2019 Solaris device driver tutorial

    28/124

    For more inormation, see the ollowing resources:

    For more inormation about writing device drivers, see Device Driver Coding Tips onpage 112 and Writing Device Drivers.

    For simple example source les, see Chapter 2, Template Driver Example, and Chapter 3,Reading and Writing Data in Kernel Memory.

    For production driver sources, go to http://www.opensolaris.org/ and click SourceBrowser.

    For more driver source and documentation, go to the driver development OpenSolariscommunity at http://www.opensolaris.org/os/community/device_drivers/ .

    For advice and examples on a wide variety o driver topics, see the Driver Development FAQ(Frequently Asked Questions).

    For more help, search the Driver Development Solaris orum athttp://forum.java.sun.com/forum.jspa?forumID=866 or the Kernel orum athttp://forum.java.sun.com/forum.jspa?forumID=865 . See all the Solaris orums athttp://forum.java.sun.com/index.jspa?tab=solaris .

    Writing a Confguration FileA driver that is not sel-identiying must have a conguration le named node_name.conf,where node_name is the prex or the device. A sel-identiying driver is a driver that can obtainall the property inormation it needs rom the DDI property interaces such asddi_prop_get_int(9F) and ddi_prop_lookup(9F). The minimum inormation that aconguration le must contain is the name o the device node and the name or type o thedevice's parent.

    For more inormation about device driver conguration les, see the driver.conf(4) manpage. For an example conguration le, see Writing the Device Conguration File onpage 58.

    Building a Driver

    This section tells you how to compile and link a driver or diferent architectures.

    Make sure you have installed the Solaris OS at the Developer level or above. Follow theinstructions in Chapter 2, Installing With the Solaris Installation Program (Tasks), inSolaris 10 Installation Guide: Basic Installations. Select Custom Install, and select the Developercluster or above.

    In your path environment variable, include /opt/SUNWspro/bin ollowed by/usr/ccs/bin.

    Device Driver Tutorial April 200828

    DevelopmentEnvironmentand Tools

    http://www.opensolaris.org/http://www.opensolaris.org/os/community/device_drivers/http://developers.sun.com/solaris/developer/support/driver/faqs.htmlhttp://forum.java.sun.com/forum.jspa?forumID=866http://forum.java.sun.com/forum.jspa?forumID=865http://forum.java.sun.com/index.jspa?tab=solarishttp://forum.java.sun.com/index.jspa?tab=solarishttp://forum.java.sun.com/forum.jspa?forumID=865http://forum.java.sun.com/forum.jspa?forumID=866http://developers.sun.com/solaris/developer/support/driver/faqs.htmlhttp://www.opensolaris.org/os/community/device_drivers/http://www.opensolaris.org/
  • 7/28/2019 Solaris device driver tutorial

    29/124

    A 64-bit kernel cannot use a 32-bit driver. A 64-bit kernel can use only 64-bit drivers. All partso any particular program must use the same data model. A device driver is not a completeprogram. The kernel is a complete program. A driver is a part o the kernel program. I you

    want your device to work with the Solaris OS in 32-bit mode and with the Solaris OS in 64-bitmode, then you must provide both a 32-bit driver and a 64-bit driver.

    By deault, compilation on the Solaris OS yields a 32-bit result on every architecture. To obtaina 64-bit result, use the compilation options specied in this section or 64-bit architectures.

    Use the prtconf(1M) command with the -x option to determine whether the rmware on thissystem is 64-bit ready.

    Compiling with Sun Studio

    Use the -D_KERNEL option to indicate that this code denes a kernel module.

    I you are compiling or a 64-bit SPARC architecture using Sun Studio 9, Sun Studio 10, orSun Studio 11, use the -xarch=v9 option:

    % cc -D_KERNEL -xarch=v9 -c mydriver.c

    % /usr/ccs/bin/ld -r -o mydriver mydriver.o

    I you are compiling or a 64-bit SPARC architecture using Sun Studio 12, use the -m64option:

    % cc -D_KERNEL -m64 -c mydriver.c

    % /usr/ccs/bin/ld -r -o mydriver mydriver.o

    I you are compiling or a 64-bit x86 architecture using Sun Studio 10 or Sun Studio 11, use

    both the -xarch=amd64 option and the -xmodel=kernel option:

    % cc -D_KERNEL -xarch=amd64 -xmodel=kernel -c mydriver.c

    % /usr/ccs/bin/ld -r -o mydriver mydriver.o

    I you are compiling or a 64-bit x86 architecture using Sun Studio 12, use the -m64 option,the -xarch=sse2a option, and the -xmodel=kernel option:

    % cc -D_KERNEL -m64 -xarch=sse2a -xmodel=kernel -c mydriver.c

    % /usr/ccs/bin/ld -r -o mydriver mydriver.o

    I you are compiling or a 32-bit architecture, use the ollowing build commands:

    % cc -D_KERNEL -c mydriver.c

    % /usr/ccs/bin/ld -r -o mydriver mydriver.o

    Chapter 1 Introduction to Device Drivers 29

    DevelopmentEnvironment and Tools

  • 7/28/2019 Solaris device driver tutorial

    30/124

    Note Sun Studio 9 does not support 64-bit x86 architectures. Use Sun Studio 10, Sun Studio 11,or Sun Studio 12 to compile and debug drivers or 64-bit x86 architectures.

    For more inormation on compile and link options, see the Sun Studio Man Pages and the SunStudio 12: C Users Guide. See the Sun Studio Inormation Center in the Sun Studio 12Collection or Sun Studio books about dbx, dmake, Perormance Analyzer, and other sotwaredevelopment topics. To read technical articles about Sun Studio, see Sun Studio TechnicalArticles. To download Sun Studio, go to http://developers.sun.com/sunstudio/ .

    Compiling with the GNU C CompilerTo get the GNU C compiler, you must install the Solaris OS at the Developer level or above.Follow the instructions in Chapter 2, Installing With the Solaris Installation Program (Tasks),in Solaris 10 Installation Guide: Basic Installations. Select Custom Install, and select theDeveloper cluster or above. The GNU C compiler is installed in /usr/sfw.

    Use the -D_KERNEL option to indicate that this code denes a kernel module. These examplesshow options that are required or correct unctionality o the result.

    I you are compiling or a 64-bit SPARC architecture, use the ollowing build commands:

    % gcc -D_KERNEL -m64 -mcpu=v9 -mcmodel=medlow -fno-pic -mno-fpu

    -ffreestanding -nodefaultlibs -c mydriver.c

    % /usr/ccs/bin/ld -r -o mydriver mydriver.o

    You might also want to use the -mtune=ultrasparc option and the -O2 option.

    I you are compiling or a 64-bit x86 architecture, use the ollowing build commands:

    % gcc -D_KERNEL -m64 -mcmodel=kernel -mno-red-zone -ffreestanding

    -nodefaultlibs -c mydriver.c

    % /usr/ccs/bin/ld -r -o mydriver mydriver.o

    You might also want to use the -mtune=opteron option and the -O2 option.

    I you are compiling or a 32-bit architecture, use the ollowing build commands:

    % gcc -D_KERNEL -ffreestanding -nodefaultlibs -c mydriver.c

    % /usr/ccs/bin/ld -r -o mydriver mydriver.o

    For more inormation on these and other options, see the gcc(1) man page. See also the GCCweb site at http://gcc.gnu.org/. More inormation about using the gcc compiler with theSolaris OS is on the OpenSolaris web site athttp://opensolaris.org/os/community/tools/gcc/ .

    Device Driver Tutorial April 200830

    DevelopmentEnvironmentand Tools

    http://docs.sun.com/app/docs/coll/771.8http://docs.sun.com/app/docs/coll/771.8http://docs.sun.com/app/docs/coll/1787.1http://docs.sun.com/app/docs/coll/1787.1http://docs.sun.com/app/docs/coll/1787.1http://developers.sun.com/sunstudio/http://gcc.gnu.org/http://gcc.gnu.org/http://opensolaris.org/os/community/tools/gcc/http://opensolaris.org/os/community/tools/gcc/http://gcc.gnu.org/http://developers.sun.com/sunstudio/http://docs.sun.com/app/docs/coll/1787.1http://docs.sun.com/app/docs/coll/1787.1http://docs.sun.com/app/docs/coll/771.8http://docs.sun.com/app/docs/coll/771.8
  • 7/28/2019 Solaris device driver tutorial

    31/124

    Installing a Driver

    Ater you write and build your driver, you must install the driver binary. To install a driver,

    copy the driver binary and the conguration le to the appropriate /kernel/drv directory.

    Make sure you are user root when you install a driver.

    Copy the conguration le to the kernel driver area o the system.

    # cp mydriver.conf /usr/kernel/drv

    Install drivers in the /tmp directory until you are nished modiying and testing the _info(),

    _init(),and attach() routines. See Device Driver Testing Tips on page 115 or moreinormation.

    Copy the driver binary to the /tmp directory.

    # cp mydriver /tmp

    Link to the driver rom the kernel driver directory.

    On a 64-bit SPARC architecture, link to the sparcv9 directory:

    # ln -s /tmp/mydriver /usr/kernel/drv/sparcv9/mydriver

    On a 64-bit x86 architecture, link to the amd64 directory:

    # ln -s /tmp/mydriver /usr/kernel/drv/amd64/mydriver

    On a 32-bit architecture, create the link as ollows:

    # ln -s /tmp/mydriver /usr/kernel/drv/mydriver

    When the driver is well tested, copy the driver directly to the appropriate kernel driver area othe system.

    On a 64-bit SPARC architecture, copy the driver to the sparcv9 directory:

    # cp mydriver /usr/kernel/drv/sparcv9/mydriver

    On a 64-bit x86 architecture, copy the driver to the amd64 directory:

    # cp mydriver /usr/kernel/drv/amd64/mydriver

    On a 32-bit architecture, copy the driver to the kernel driver area o the system:

    # cp mydriver /usr/kernel/drv/mydriver

    Chapter 1 Introduction to Device Drivers 31

    DevelopmentEnvironment and Tools

  • 7/28/2019 Solaris device driver tutorial

    32/124

    Adding, Updating, and Removing a Driver

    Use the add_drv(1M) command to make the installed driver usable. Be sure you are user root

    when you use the add_drv(1M) command.

    # add_drv mydriver

    The ollowing events take place when you add a driver:

    The _info(9E), _init(9E), and attach(9E) entry points are called in that order. The driver is added to the /devices directory. The driver is the most recent module listed bymodinfo(1M). The driver is the most recent module listed in the le /etc/name_to_major.

    The le /etc/driver_aliases might be updated. The /etc/driver_aliases le shows whichdevices are bound to which drivers. I a driver is not listed in the /etc/driver_aliases le,then the Solaris OS does not load that driver or attach to that driver. Each line o the/etc/driver_aliases le shows a driver name ollowed by a device name. You can search thisle to determine which driver is managing your device.

    Note Do not editthe /etc/driver_aliases le manually. Use the add_drv(1M) command toestablish a device binding. Use the update_drv(1M) command to change a device binding.

    The example drivers shown in this book manage pseudo devices. I your driver manages realhardware, then you need to use the -c and -i options on the add_drv(1M) command or the -ioption on the update_drv(1M) command. To speciy a device class or device ID, you might ndthe ollowing sites useul. This inormation also is useul to search the /etc/driver_aliasesle to nd out whether a device already is supported.

    List o devices currently supported by the Solaris OS:http://www.sun.com/bigadmin/hcl/devicelist/

    Searchable PCI vendor and device lists: http://www.pcidatabase.com/

    Repository o vendor IDs, device IDs, subsystems, and device classes used in PCI devices:http://pciids.sourceforge.net/

    Use the update_drv(1M) command to notiy the system about attribute changes to an installeddevice driver. By deault, the update_drv(1M) command reloads the hardware congurationle or the specied driver. Use the prtconf(1M) command to review the current congurationinormation or a device and driver. For example, the -D option shows which driver manages aparticular device. The -P option shows inormation about pseudo devices.

    Device Driver Tutorial April 200832

    http://www.sun.com/bigadmin/hcl/devicelist/http://www.pcidatabase.com/http://pciids.sourceforge.net/http://pciids.sourceforge.net/http://www.pcidatabase.com/http://www.sun.com/bigadmin/hcl/devicelist/
  • 7/28/2019 Solaris device driver tutorial

    33/124

  • 7/28/2019 Solaris device driver tutorial

    34/124

    34

  • 7/28/2019 Solaris device driver tutorial

    35/124

    Template Driver Example

    This chapter shows you how to develop a very simple, working driver. This chapter explainshow to write the driver and conguration le, compile the driver, load the driver, and test thedriver.

    The driver that is shown in this chapter is a pseudo device driver that merely writes a message to

    a system log every time an entry point is entered. This driver demonstrates the minimumunctionality that any character driver must implement. You can use this driver as a templateor building a complex driver.

    This chapter discusses the ollowing driver development steps:

    Overview o the Template Driver Example on page 35 Writing the Template Driver on page 36 Writing the Device Conguration File on page 58 Building and Installing the Template Driver on page 58 Testing the Template Driver on page 59 Complete Template Driver Source on page 62

    Overview o the Template Driver Example

    This example guides you through the ollowing steps:

    1. Create a directory where you can develop your driver and open a new text le nameddummy.c.

    2. Write the entry points or loadable module conguration: _init(9E), _info(9E), and_fini(9E).

    3. Write the entry points or autoconguration: attach(9E), detach(9E), getinfo(9E), andprop_op(9E).

    4. Write the entry points or user context: open(9E), close(9E), read(9E), and write(9E).

    2C H A P T E R 2

    35

    Writing theTemplateDriver

  • 7/28/2019 Solaris device driver tutorial

    36/124

    5. Dene the data structures: the character and block operations structure cb_ops(9S), the

    device operations structure dev_ops(9S), and the module linkage structures modldrv(9S)

    and modlinkage(9S).

    6. Create the driver conguration le dummy.conf.

    7. Build and install the driver.

    8. Test the driver by loading the driver, reading rom and writing to the device node, and

    unloading the driver.

    The entry points that are to be created in this example are shown in the ollowing diagram.

    Writing the Template DriverThis section describes the entry points and data structures that are included in this driver and

    shows you how to dene them. All o these data structures and almost all o these entry points

    are required or any character device driver.

    This section describes the ollowing entry points and data structures:

    Loadable module conguration entry points Autoconguration entry points User context entry points Character and block operations structure Device operations structure Module linkage structures

    First, create a directory where you can develop your driver. This driver is named dummy because

    this driver does not do any real work. Next, open a new text le named dummy.c.

    dummy_dev_ops Structure

    dummy_getinfodummy_attachdummy_detach

    dummy_cb_ops Structure

    dummy_opendummy_closedummy_readdummy_writedummy_prop_op

    FIGURE 21 Entry Points orthe dummy Example

    Device Driver Tutorial April 200836

    Writing theTemplateDriver

  • 7/28/2019 Solaris device driver tutorial

    37/124

    Writing the Loadable Module Confguration EntryPoints

    Every kernel module o any type must dene at least the ollowing three loadable moduleconguration entry points:

    The _init(9E) routine initializes a loadable module. The _init(9E) routine must at leastcall the mod_install(9F) unction and return the success or ailure value that is returned bymod_install(9F).

    The _info(9E) routine returns inormation about a loadable module. The _info(9E)routine must at least call the mod_info(9F) unction and return the value that is returned bymod_info(9F).

    The _fini(9E) routine prepares a loadable module or unloading. The _fini(9E) routinemust at least call the mod_remove(9F) unction and return the success or ailure value that isreturned bymod_remove(9F). When mod_remove(9F) is successul, the _fini(9E) routinemust undo everything that the _init(9E) routine did.

    The mod_install(9F), mod_info(9F), and mod_remove(9F) unctions are used in exactly the

    same way in every driver, regardless o the unctionality o the driver. You do not need toinvestigate what the values o the arguments o these unctions should be. You can copy theseunction calls rom this example and paste them into every driver you write.

    In this section, the ollowing code is added to the dummy.c source le:

    /* Loadable module configuration entry points */

    int

    _init(void)

    {

    cmn_err(CE_NOTE, "Inside _init");

    return(mod_install(&ml));

    }

    int

    _info(struct modinfo *modinfop)

    {

    cmn_err(CE_NOTE, "Inside _info");return(mod_info(&ml, modinfop));

    }

    int

    _fini(void)

    {

    cmn_err(CE_NOTE, "Inside _fini");

    return(mod_remove(&ml));

    }

    Chapter 2 Template Driver Example 37

    Writing theTemplateDriver

  • 7/28/2019 Solaris device driver tutorial

    38/124

    Declaring the Loadable Module Confguration Entry Points

    The _init(9E), _info(9E), and _fini(9E) routine names are not unique to any particularkernel module. You customize the behavior o these routines when you dene them in your

    module, but the names o these routines are not unique. These three routines are declared in themodctl.h header le. You need to include the modctl.h header le in your dummy.c le. Do notdeclare these three routines in dummy.c.

    Defning the Module Initialization Entry PointThe _init(9E) routine returns type int and takes no arguments. The _init(9E) routine mustcall the mod_install(9F) unction and return the success or ailure value that is returned by

    mod_install(9F).The mod_install(9F) unction takes an argument that is a modlinkage(9S) structure. SeeDening the Module Linkage Structures on page 56 or inormation about themodlinkage(9S) structure.

    This driver is supposed to write a message each time an entry point is entered. Use thecmn_err(9F) unction to write a message to a system log. The cmn_err(9F) unction usually isused to report an error condition. The cmn_err(9F) unction also is useul or debugging in the

    same way that you might use print statements in a user program. Be sure to remove cmn_err()calls that are used or development or debugging beore you compile your production versiondriver. You might want to use cmn_err() calls in a production driver to write error messagesthat would be useul to a system administrator.

    The cmn_err(9F) unction requires you to include the cmn_err.h header le, the ddi.h headerle, and the sunddi.h header le. The cmn_err(9F) unction takes two arguments. The rstargument is a constant that indicates the severity o the error message. The message written bythis driver is not an error message but is simply a test message. Use CE_NOTE or the value o thisseverity constant. The second argument the cmn_err(9F) unction takes is a string message.

    The ollowing code is the _init(9E) routine that you should enter into your dummy.c le. Theml structure is the modlinkage(9S) structure that is discussed in Dening the Module LinkageStructures on page 56.

    int

    _init(void)

    {cmn_err(CE_NOTE, "Inside _init");

    return(mod_install(&ml));

    }

    Defning the Module Inormation Entry Point

    The _info(9E) routine returns type int and takes an argument that is a pointer to an opaquemodinfo structure. The _info(9E) routine must return the value that is returned by the

    mod_info(9F) unction.

    Device Driver Tutorial April 200838

    Th d i f (9F) i k Th d i f (9F)i

    Writing theTemplateDriver

  • 7/28/2019 Solaris device driver tutorial

    39/124

    The mod_info(9F) unction takes two arguments. The rst argument to mod_info(9F)isa

    modlinkage(9S) structure. See Dening the Module Linkage Structures on page 56 or

    inormation about the modlinkage(9S) structure. The second argument to mod_info(9F) is the

    same modinfo structure pointer that is the argument to the _info(9E) routine. Themod_info(9F) unction returns the module inormation or returns zero i an error occurs.

    Use the cmn_err(9F) unction to write a message to the system log in the same way that you

    used the cmn_err(9F) unction in your _init(9E) entry point.

    The ollowing code is the _info(9E) routine that you should enter into your dummy.c le. The

    ml structure is discussed in Dening the Module Linkage Structures on page 56. The

    modinfop argument is a pointer to an opaque structure that the system uses to pass moduleinormation.

    int

    _info(struct modinfo *modinfop)

    {

    cmn_err(CE_NOTE, "Inside _info");

    return(mod_info(&ml, modinfop));

    }

    Defning the Module Unload Entry Point

    The _fini(9E) routine returns type int and takes no arguments. The _fini(9E) routine must

    call the mod_remove(9F) unction and return the success or ailure value that is returned by

    mod_remove(9F).

    When mod_remove(9F) is successul, the _fini(9E) routine must undo everything that the_init(9E) routine did. The _fini(9E) routine must call mod_remove(9F) because the _init(9E)

    routine called mod_install(9F). The _fini(9E) routine must deallocate anything that was

    allocated, close anything that was opened, and destroy anything that was created in the

    _init(9E) routine.

    The _fini(9E) routine can be called at any time when a module is loaded. In normal operation,

    the _fini(9E) routine oten ails. This behavior is normal because the kernel allows the module

    to determine whether the module can be unloaded. Imod_remove(9F) is successul, the module

    determines that devices were detached, and the module can be unloaded. Imod_remove(9F)

    ails, the module determines that devices were not detached, and the module cannot be

    unloaded.

    Chapter 2 Template Driver Example 39

    The ollo ing actions take place hen mod remo e(9F) is called

    Writing theTemplateDriver

  • 7/28/2019 Solaris device driver tutorial

    40/124

    The ollowing actions take place when mod_remove(9F) is called:

    The kernel checks whether this driver is busy. This driver is busy i one o the ollowingconditions is true:

    A device node that is managed by this driver is open.

    Another module that depends on this driver is open. A module depends on this driver ithe module was linked using the -N option with this driver named as the argument tothat -N option. See the ld(1) man page or more inormation.

    I the driver is busy, then mod_remove(9F) ails and _fini(9E) ails.

    I the driver is not busy, then the kernel calls the detach(9E) entry point o the driver.

    Idetach(9E) ails, then mod_remove(9F) ails and _fini(9E) ails. Idetach(9E) succeeds, then mod_remove(9F) succeeds, and _fini(9E) continues its

    cleanup work.

    The mod_remove(9F) unction takes an argument that is a modlinkage(9S) structure. SeeDening the Module Linkage Structures on page 56 or inormation about themodlinkage(9S) structure.

    Use the cmn_err(9F) unction to write a message to the system log in the same way that youused the cmn_err(9F) unction in your _init(9E) entry point.

    The ollowing code is the _fini(9E) routine that you should enter into your dummy.c le. Theml structure is discussed in Dening the Module Linkage Structures on page 56.

    int

    _fini(void)

    {

    cmn_err(CE_NOTE, "Inside _fini");

    return(mod_remove(&ml));

    }

    Including Loadable Module Confguration Header Files

    The _init(9E), _info(9E), _fini(9E), and mod_install(9F) unctions require you to include

    themodctl.h

    header le. Thecmn_err

    (9F) unction requires you to include thecmn_err.h

    header le, the ddi.h header le, and the sunddi.h header le.

    The ollowing header les are required by the three loadable module conguration routines thatyou have written in this section. Include this code near the top o your dummy.c le.

    #include /* used by _init, _info, _fini */

    #include /* used by all entry points for this driver */

    #include /* used by all entry points for this driver */

    #include /* used by all entry points for this driver */

    Device Driver Tutorial April 200840

    Writing the Autoconfguration Entry Points

    Writing theTemplateDriver

  • 7/28/2019 Solaris device driver tutorial

    41/124

    Writing the Autoconfguration Entry Points

    Every character driver must dene at least the ollowing autoconguration entry points. The

    kernel calls these routines when the device driver is loaded. The attach(9E) routine must call ddi_create_minor_node(9F). The

    ddi_create_minor_node(9F) unction provides the inormation the system needs to createthe device les.

    The detach(9E) routine must call ddi_remove_minor_node(9F) to deallocate everythingthat was allocated byddi_create_minor_node(9F). The detach(9E) routine must undoeverything that the attach(9E) routine did.

    The getinfo(9E) routine returns requested device driver inormation through one o itsarguments.

    The prop_op(9E) routine returns requested device driver property inormation through apointer. You can call the ddi_prop_op(9F) unction instead o writing your ownprop_op(9E) entry point. Use the prop_op(9E) entry point to customize the behavior o theddi_prop_op(9F) unction.

    In this section, the ollowing code is added:

    /* Device autoconfiguration entry points */

    static int

    dummy_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)

    {

    cmn_err(CE_NOTE, "Inside dummy_attach");

    switch(cmd) {

    case DDI_ATTACH:

    dummy_dip = dip;

    if (ddi_create_minor_node(dip, "0", S_IFCHR,

    ddi_get_instance(dip), DDI_PSEUDO,0)

    != DDI_SUCCESS) {

    cmn_err(CE_NOTE,

    "%s%d: attach: could not add character node.",

    "dummy", 0);

    return(DDI_FAILURE);

    } else

    return DDI_SUCCESS;default:

    return DDI_FAILURE;

    }

    }

    static int

    dummy_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)

    {

    cmn_err(CE_NOTE, "Inside dummy_detach");

    Chapter 2 Template Driver Example 41

    switch(cmd) {

    Writing theTemplateDriver

  • 7/28/2019 Solaris device driver tutorial

    42/124

    switch(cmd) {

    case DDI_DETACH:

    dummy_dip = 0;

    ddi_remove_minor_node(dip, NULL);

    return DDI_SUCCESS;

    default:

    return DDI_FAILURE;

    }

    }

    static int

    dummy_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,

    void **resultp)

    {

    cmn_err(CE_NOTE, "Inside dummy_getinfo");

    switch(cmd) {

    case DDI_INFO_DEVT2DEVINFO:

    *resultp = dummy_dip;

    return DDI_SUCCESS;

    case DDI_INFO_DEVT2INSTANCE:

    *resultp = 0;

    return DDI_SUCCESS;default:

    return DDI_FAILURE;

    }

    }

    static int

    dummy_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,

    int flags, char *name, caddr_t valuep, int *lengthp)

    {

    cmn_err(CE_NOTE, "Inside dummy_prop_op");

    return(ddi_prop_op(dev,dip,prop_op,flags,name,valuep,lengthp));

    }

    Declaring the Autoconfguration Entry Points

    The attach(9E), detach(9E), getinfo(9E), and prop_op(9E) entry point routines need to be

    uniquely named or this driver. Choose a prex to use with each entry point routine.

    Note By convention, the prex used or unction and data names that are unique to this driveris either the name o this driver or an abbreviation o the name o this driver. Use the sameprex throughout the driver. This practice makes debugging much easier.

    In the example shown in this chapter, dummy_ is used or the prex to each unction and data

    name that is unique to this example.

    Device Driver Tutorial April 200842

    The ollowing declarations are the autoconguration entry point declarations you should have

    Writing theTemplateDriver

  • 7/28/2019 Solaris device driver tutorial

    43/124

    g g y p yin your dummy.c le. Note that each o these unctions is declared static.

    static int dummy_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);

    static int dummy_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);

    static int dummy_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,

    void **resultp);

    static int dummy_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,

    int flags, char *name, caddr_t valuep, int *lengthp);

    Defning the Device Attach Entry Point

    The attach(9E) routine returns type int.The attach(9E) routine must return eitherDDI_SUCCESS or DDI_FAILURE. These two constants are dened in sunddi.h.Allotheautoconguration entry point routines except or prop_op(9E) return either DDI_SUCCESS orDDI_FAILURE.

    The attach(9E) routine takes two arguments. The rst argument is a pointer to the dev_infostructure or this driver. All o the autoconguration entry point routines take a dev_infoargument. The second argument is a constant that species the attach type. The value that ispassed through this second argument is either DDI_ATTACH or DDI_RESUME. Everyattach(9E)routine must dene behavior or at least DDI_ATTACH.

    The DDI_ATTACH code must initialize a device instance. In a realistic driver, you dene andmanage multiple instances o the driver by using a state structure and the ddi_soft_state(9F)unctions. Each instance o the driver has its own copy o the state structure that holds dataspecic to that instance. One o the pieces o data that is specic to each instance is the deviceinstance pointer. Each instance o the device driver is represented by a separate device le in/devices. Each device instance le is pointed to by a separate device instance pointer. See

    Managing Device State on page 71 or inormation about state structures andddi_soft_state(9F) unctions. See Devices as Files on page 22 or inormation about deviceles and instances.

    This dummy driver allows only one instance. Because this driver allows only one instance, thisdriver does not use a state structure. This driver still must declare a device instance pointer andinitialize the pointer value in the attach(9E) routine. Enter the ollowing code near thebeginning odummy.c to declare a device instance pointer or this driver:

    dev_info_t *dummy_dip; /* keep track of one instance */

    The ollowing code is the dummy_attach() routine that you should enter into your dummy.c le.You can copy the name portion o this unction denition directly rom the declaration youentered in Declaring the Autoconguration Entry Points on page 42.

    static int

    dummy_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)

    {

    Chapter 2 Template Driver Example 43

    cmn_err(CE_NOTE, "Inside dummy_attach");

    Writing theTemplateDriver

  • 7/28/2019 Solaris device driver tutorial

    44/124

    switch(cmd) {

    case DDI_ATTACH:

    dummy_dip = dip;

    if (ddi_create_minor_node(dip, "0", S_IFCHR,ddi_get_instance(dip), DDI_PSEUDO,0)

    != DDI_SUCCESS) {

    cmn_err(CE_NOTE,

    "%s%d: attach: could not add character node.","dummy", 0);

    return(DDI_FAILURE);

    } else

    return DDI_SUCCESS;

    default:

    return DDI_FAILURE;

    }

    }

    First, use cmn_err(9F) to write a message to the system log, as you did in your _init(9E) entrypoint. Then provide DDI_ATTACH behavior. Within the DDI_ATTACH code, rst assign the deviceinstance pointer rom the dummy_attach() argument to the dummy_dipvariable that you

    declared above. You need to save this pointer value in the global variable so that you can use thispointer to get inormation about this instance rom dummy_getinfo() and detach this instancein dummy_detach(). In this dummy_attach() routine, the device instance pointer is used by theddi_get_instance(9F) unction to return the instance number. The device instance pointerand the instance number both are used byddi_create_minor_node(9F) to create a new devicenode.

    A realistic driver probably would use the ddi_soft_state(9F) unctions to create and manage adevice node. This dummy driver uses the ddi_create_minor_node(9F) unction to create adevice node. The ddi_create_minor_node(9F) unction takes six arguments. The rstargument to the ddi_create_minor_node(9F) unction is the device instance pointer thatpoints to the dev_info structure o this device. The second argument is the name o this minornode. The third argument is S_IFCHR i this device is a character minor device or is S_IFBLK ithis device is a block minor device. This dummy driver is a character driver.

    The ourth argument to the ddi_create_minor_node(9F) unction is the minor number o thisminor device. This number is also called the instance number. The ddi_get_instance(9F)

    unction returns this instance number. The th argument to the ddi_create_minor_node(9F)unction is the node type. The ddi_create_minor_node(9F) man page lists the possible nodetypes. The DDI_PSEUDO node type is or pseudo devices. The sixth argument to theddi_create_minor_node(9F) unction species whether this is a clone device. This is not aclone device, so set this argument value to 0.

    I the ddi_create_minor_node(9F) call is not successul, write a message to the system log andreturn DDI_FAILURE.Ithe ddi_create_minor_node(9F) call is successul, return DDI_SUCCESS.

    I this dummy_attach() routine receives anycmd other than DDI_ATTACH, return DDI_FAILURE.

    Device Driver Tutorial April 200844

    Defning the Device Detach Entry Point

    Writing theTemplateDriver

  • 7/28/2019 Solaris device driver tutorial

    45/124

    g y

    The detach(9E) routine takes two arguments. The rst argument is a pointer to the dev_infostructure or this driver. The second argument is a constant that species the detach type. The

    value that is passed through this second argument is either DDI_DETACH or DDI_SUSPEND. Everydetach(9E) routine must dene behavior or at least DDI_DETACH.

    The DDI_DETACH code must undo everything that the DDI_ATTACH code did. In the DDI_ATTACHcode in your attach(9E) routine, you saved the address o a newdev_info structure and youcalled the ddi_create_minor_node(9F) unction to create a new node. In the DDI_DETACH codein this detach(9E) routine, you need to reset the variable that pointed to the dev_info structureor this node. You also need to call the ddi_remove_minor_node(9F) unction to remove this

    node. The detach(9E) routine must deallocate anything that was allocated, close anything thatwas opened, and destroy anything that was created in the attach(9E) routine.

    The ollowing code is the dummy_detach() routine that you should enter into your dummy.c le.You can copy the name portion o this unction denition directly rom the declaration youentered in Declaring the Autoconguration Entry Points on page 42.

    static int

    dummy_detach(dev_info_t *dip, ddi_detach_cmd_t cmd){

    cmn_err(CE_NOTE, "Inside dummy_detach");

    switch(cmd) {

    case DDI_DETACH:

    dummy_dip = 0;

    ddi_remove_minor_node(dip, NULL);

    return DDI_SUCCESS;

    default:

    return DDI_FAILURE;

    }

    }

    First, use cmn_err(9F) to write a message to the system log, as you did in your _init(9E) entrypoint. Then provide DDI_DETACH behavior. Within the DDI_DETACH code, rst reset thedummy_dipvariable that you set in dummy_attach() above. You cannot reset this deviceinstance pointer unless you remove all instances o the device. This dummy driver supports only

    one instance.

    Next, call the ddi_remove_minor_node(9F) unction to remove this device node. Theddi_remove_minor_node(9F) unction takes two arguments. The rst argument is the deviceinstance pointer that points to the dev_info structure o this device. The second argument isthe name o the minor node you want to remove. I the value o the minor node argument isNULL, then ddi_remove_minor_node(9F) removes all instances o this device. Because theDDI_DETACH code o this driver always removes all instances, this dummy driver supports only

    one instance.

    Chapter 2 Template Driver Example 45

    I the value o the cmd argument to this dummy_detach() routine is DDI_DETACH, remove alli hi d i d I hi i i

    Writing theTemplateDriver

  • 7/28/2019 Solaris device driver tutorial

    46/124

    instances o this device and return DDI_SUCCESS. I this dummy_detach() routine receives anycmd other than DDI_DETACH, return DDI_FAILURE.

    Defning the Get Driver Inormation Entry Point

    The getinfo(9E) routine takes a pointer to a device number and returns a pointer to a deviceinormation structure or returns a device instance number. The return value o the getinfo(9E)routine is DDI_SUCCESS or DDI_FAILURE. The pointer or instance