1mmap(9E)                      Driver Entry Points                     mmap(9E)
2
3
4

NAME

6       mmap - check virtual mapping for memory mapped device
7

SYNOPSIS

9       #include <sys/types.h>
10       #include <sys/cred.h>
11       #include <sys/mman.h>
12       #include <sys/ddi.h>
13
14
15
16       int prefixmmap(dev_t dev, off_t off, int prot);
17
18

INTERFACE LEVEL

20       This interface is obsolete. devmap(9E) should be used instead.
21

PARAMETERS

23       dev      Device whose memory is to be mapped.
24
25
26       off      Offset within device memory at which mapping begins.
27
28
29       prot     A bit field that specifies the protections this page of memory
30                will receive. Possible settings are:
31
32                PROT_READ      Read access will be granted.
33
34
35                PROT_WRITE     Write access will be granted.
36
37
38                PROT_EXEC      Execute access will be granted.
39
40
41                PROT_USER      User-level access will be granted.
42
43
44                PROT_ALL       All access will be granted.
45
46
47

DESCRIPTION

49       Future releases of Solaris will provide this function  for  binary  and
50       source   compatibility.   However,  for  increased  functionality,  use
51       devmap(9E) instead. See devmap(9E) for details.
52
53
54       The mmap() entry point is a required entry point for character  drivers
55       supporting  memory-mapped  devices.  A  memory mapped device has memory
56       that can be mapped into a process's address space. The  mmap(2)  system
57       call, when applied to a character special file, allows this device mem‐
58       ory to be mapped into user space for direct access by the user applica‐
59       tion.
60
61
62       The mmap() entry point is called as a result of an mmap(2) system call,
63       and also as a result of a page fault. mmap() is called to translate the
64       offset  off  in  device memory to the corresponding physical page frame
65       number.
66
67
68       The mmap() entry point checks if the offset off is within the range  of
69       pages  exported by the device. For example, a device that has 512 bytes
70       of memory that can be mapped into user space should not support offsets
71       greater than 512. If the offset does not exist, then -1 is returned. If
72       the  offset  does  exist,  mmap()  returns  the   value   returned   by
73       hat_getkpfnum(9F) for the physical page in device memory containing the
74       offset off.
75
76
77       hat_getkpfnum(9F) accepts a kernel virtual address as  an  argument.  A
78       kernel  virtual  address  can  be obtained by calling ddi_regs_map_set‐
79       up(9F)  in  the  driver's   attach(9E)   routine.   The   corresponding
80       ddi_regs_map_free(9F)  call can be made in the driver's detach(9E) rou‐
81       tine. Refer to the example below mmap Entry Point for more information.
82
83
84       mmap()  should  only  be  supported  for  memory-mapped  devices.   See
85       segmap(9E) for further information on memory-mapped device drivers.
86
87
88       If  a  device  driver  shares data structures with the application, for
89       example through exported kernel memory, and the driver gets  recompiled
90       for a 64-bit kernel but the application remains 32-bit, the binary lay‐
91       out of any data structures will be incompatible if they  contain  longs
92       or pointers. The driver needs to know whether there is a model mismatch
93       between the current thread and the kernel and  take  necessary  action.
94       ddi_mmap_get_model(9F)  can  be  use  to  get the C Language Type Model
95       which the current thread expects. In  combination  with  ddi_model_con‐
96       vert_from(9F)  the  driver  can determine whether there is a data model
97       mismatch between the current thread and the device driver.  The  device
98       driver might have to adjust the shape of data structures before export‐
99       ing them to a user thread which supports a different  data  model.  See
100       ddi_mmap_get_model(9F) for an example.
101

RETURN VALUES

103       If  the  protection  and  offset  are  valid for the device, the driver
104       should return the value returned by hat_getkpfnum(9F), for the page  at
105       offset off in the device's memory. If not, -1 should be returned.
106

EXAMPLES

108       Example 1 mmap() Entry Point
109
110
111       The following is an example of the mmap() entry point. If offset off is
112       valid, hat_getkpfnum(9F) is called to obtain the page frame number cor‐
113       responding  to  this  offset  in  the device's memory. In this example,
114       xsp→regp→csr is a kernel virtual address which maps to  device  memory.
115       ddi_regs_map_setup(9F) can be used to obtain this address. For example,
116       ddi_regs_map_setup(9F) can be called in the  driver's  attach(9E)  rou‐
117       tine.  The  resulting  kernel  virtual address is stored in the xxstate
118       structure, which is accessible from the driver's  mmap()  entry  point.
119       See  ddi_soft_state(9F).  The corresponding  ddi_regs_map_free(9F) call
120       can be made in the driver's  detach(9E) routine.
121
122
123         struct reg {
124                      uint8_t     csr;
125                      uint8_t     data;
126         };
127         struct xxstate {
128                 ...
129                      struct reg  *regp
130                 ...
131         };
132
133         struct xxstate *xsp;
134         ...
135
136         static int
137         xxmmap(dev_t dev, off_t off, int prot)
138         {
139                 int         instance;
140                 struct xxstate *xsp;
141
142                  /* No write access */
143                 if (prot & PROT_WRITE)
144                               return (-1);
145
146                 instance = getminor(dev);
147                 xsp = ddi_get_soft_state(statep, instance);
148                 if (xsp == NULL)
149                               return (-1);
150
151                 /* check for a valid offset */
152                     if ( off is invalid )
153                               return (-1);
154                     return (hat_getkpfnum (xsp->regp->csr + off));
155         }
156
157

ATTRIBUTES

159       See attributes(5) for a description of the following attributes:
160
161
162
163
164       ┌─────────────────────────────┬─────────────────────────────┐
165ATTRIBUTE TYPE         ATTRIBUTE VALUE        
166       ├─────────────────────────────┼─────────────────────────────┤
167       │Stability Level              │Obsolete                     │
168       └─────────────────────────────┴─────────────────────────────┘
169

SEE ALSO

171       mmap(2), attributes(5), attach(9E), detach(9E), devmap(9E), segmap(9E),
172       ddi_btop(9F),      ddi_get_soft_state(9F),      ddi_mmap_get_model(9F),
173       ddi_model_convert_from(9F),  ddi_regs_map_free(9F),   ddi_regs_map_set‐
174       up(9F),     ddi_soft_state(9F),     devmap_setup(9F),     getminor(9F),
175       hat_getkpfnum(9F)
176
177
178       Writing Device Drivers
179

NOTES

181       For some devices, mapping device memory in the driver's attach(9E) rou‐
182       tine  and unmapping device memory in the driver's detach(9E) routine is
183       a sizeable drain on system  resources.  This  is  especially  true  for
184       devices with a large amount of physical address space.
185
186
187       One  alternative  is  to  create  a  mapping for only the first page of
188       device memory in attach(9E). If the device memory is contiguous, a ker‐
189       nel page frame number may be obtained by calling hat_getkpfnum(9F) with
190       the kernel virtual address of the  first  page  of  device  memory  and
191       adding  the  desired  page offset to the result. The page offset may be
192       obtained by converting the byte offset off to pages. See ddi_btop(9F).
193
194
195       Another   alternative   is   to   call    ddi_regs_map_setup(9F)    and
196       ddi_regs_map_free(9F) in mmap(). These function calls would bracket the
197       call to hat_getkpfnum(9F).
198
199
200       However, note that the above alternatives may not work  in  all  cases.
201       The existence of intermediate nexus devices with memory management unit
202       translation resources that are not locked down may cause unexpected and
203       undefined behavior.
204
205
206
207SunOS 5.11                        27 Sep 2002                         mmap(9E)
Impressum