devmap man page on SunOS

Man page or keyword search:  
man Server   20652 pages
apropos Keyword Search (all sections)
Output format
SunOS logo
[printable version]

devmap(9E)		      Driver Entry Points		    devmap(9E)

NAME
       devmap  -  validate  and	 translate  virtual  mapping for memory mapped
       device

SYNOPSIS
       #include <sys/ddi.h>
       #include <sys/sunddi.h>

       int prefixdevmap(dev_t dev, devmap_cookie_t dhp, offset_t  off,	size_t
       len, size_t *maplen, uint_t model);

INTERFACE LEVEL
       Solaris DDI specific (Solaris DDI).

PARAMETERS
       dev	Device whose memory is to be mapped.

       dhp	An  opaque mapping handle that the system uses to describe the
		mapping.

       off	User offset within the logical device memory at which the map‐
		ping begins.

       len	Length (in bytes) of the mapping to be mapped.

       maplen	Pointer	 to  length  (in bytes) of mapping that has been vali‐
		dated. maplen is less than or equal to	len.

       model	The data model type of the current thread.

DESCRIPTION
       devmap() is a required entry point  for	character  drivers  supporting
       memory-mapped devices if the drivers use the devmap framework to set up
       the mapping. A memory mapped device has memory  that can be mapped into
       a  process's  address space. The mmap(2) system call, when applied to a
       character special file, allows this device memory  to  be  mapped  into
       user space for direct access by the user applications.

       As  a  result  of  a mmap(2) system call, the system calls the devmap()
       entry point during the mapping  setup  when  D_DEVMAP  is  set  in  the
       cb_flag	field  of  the	cb_ops(9S) structure, and any of the following
       conditions apply:

	 ·  ddi_devmap_segmap(9F) is used as the segmap(9E) entry point.

	 ·  segmap(9E) entry point is set to NULL.

	 ·  mmap(9E) entry point is set to NULL.

       Otherwise EINVAL will be returned to mmap(2).

       Device drivers should use devmap() to validate the user mappings to the
       device,	to  translate  the  logical offset,  off, to the corresponding
       physical offset within the device address space, and to pass  the  map‐
       ping information to the system for setting up the mapping.

       dhp  is a device mapping handle that the system uses to describe a map‐
       ping to a memory that is either contiguous in physical address space or
       in kernel virtual address space. The system may create multiple mapping
       handles in one mmap(2) system call (for example, if  the	 mapping  con‐
       tains multiple physically discontiguous memory regions).

       model  returns  the  C  Language	 Type  Model  which the current thread
       expects.	 It is set to DDI_MODEL_ILP32 if the  current  thread  expects
       32-bit  (  ILP32)  semantics,  or  DDI_MODEL_LP64 if the current thread
       expects 64-bit ( LP64) semantics. model is  used	 in  combination  with
       ddi_model_convert_from(9F)  to  determine whether there is a data model
       mismatch between the current thread and the device driver.  The	device
       driver might have to adjust the shape of data structures before export‐
       ing them to a user thread which supports a different data model.

       devmap() should return EINVAL if the logical offset, off, is out of the
       range  of  memory  exported  by	the device to user space. If off + len
       exceeds the range of the contiguous memory, devmap() should return  the
       length from  off to the end of the contiguous memory region. The system
       will repeatedly call devmap() until the original mapping length is sat‐
       isfied.	The  driver sets *maplen to the validated length which must be
       either less than or equal to len.

       The devmap() entry point must initialize the mapping parameters	before
       passing	them  to the system through either devmap_devmem_setup(9F) (if
       the memory being mapped is device memory) or devmap_umem_setup(9F)  (if
       the  memory  being  mapped  is kernel memory). The devmap() entry point
       initializes the mapping parameters  by  mapping	the  control  callback
       structure  (see devmap_callback_ctl(9S)), the device access attributes,
       mapping length,	maximum	 protection  possible  for  the	 mapping,  and
       optional	   mapping    flags.	 See	devmap_devmem_setup(9F)	   and
       devmap_umem_setup(9F) for further information on initializing the  map‐
       ping parameters.

       The system will copy the driver's devmap_callback_ctl(9S) data into its
       private memory so the drivers do not need to keep  the  data  structure
       after	the    return	 from	 either	  devmap_devmem_setup(9F)   or
       devmap_umem_setup(9F).

       For device mappings, the system establishes the mapping to the physical
       address	that corresponds to off by passing the register number and the
       offset within the register address space to  devmap_devmem_setup(9F).

       For kernel memory mapping, the system selects a	user  virtual  address
       that  is	 aligned with the kernel address being mapped for cache coher‐
       ence.

RETURN VALUES
       0	       Successful completion.

       Non-zero	       An error occurred.

EXAMPLES
       Example 1: Implementing the devmap() Entry Point

       The following is an example of  the  implementation  for	 the  devmap()
       entry	point.	  For	 mapping   device   memory,   devmap()	 calls
       devmap_devmem_setup(9F) with the register number, rnumber, and the off‐
       set  within  the	 register, roff. For mapping kernel memory, the driver
       must first allocate the kernel memory  using  ddi_umem_alloc(9F).   For
       example,	 ddi_umem_alloc(9F)  can  be called in the attach(9E) routine.
       The resulting kernel memory cookie is stored in the driver  soft	 state
       structure,  which  is  accessible  from	the  devmap() entry point. See
       ddi_soft_state(9F).  devmap()   passes	the   cookie   obtained	  from
       ddi_umem_alloc(9F) and the offset within the allocated kernel memory to
       devmap_umem_setup(9F). The corresponding ddi_umem_free(9F) can be  made
       in the detach(9E) routine to free up the kernel memory.

       ...
       #define MAPPING_SIZE 0x2000	  /* size of the mapping */
       #define MAPPING_START 0x70000000	  /* logical offset at beginning
					     of the mapping */
       static
       struct devmap_callback_ctl xxmap_ops = {
	       DEVMAP_OPS_REV,		      /* devmap_ops version number */
	       xxmap_map,		      /* devmap_ops map routine */
	       xxmap_access,		      /* devmap_ops access routine */
	       xxmap_dup,		      /* devmap_ops dup routine */
	       xxmap_unmap,		      /* devmap_ops unmap routine  */
       };

       static int
       xxdevmap(dev_t dev, devmap_cookie_t dhp, offset_t off, size_t len,
	  size_t *maplen, uint_t model)
       {
	  int	 instance;
	  struct xxstate *xsp;
	  struct ddi_device_acc_attr *endian_attr;
	  struct devmap_callback_ctl *callbackops = NULL;
	  ddi_umem_cookie_t cookie;
	  dev_info_t *dip;
	  offset_t   roff;
	  offset_t   koff;
	  uint_t rnumber;
	  uint_t maxprot;
	  uint_t flags = 0;
	  size_t length;
	  int	 err;

	  /* get device soft state */
	  instance = getminor(dev);
	  xsp = ddi_get_soft_state(statep, instance);
	  if (xsp == NULL)
	     return (-1);

	  dip = xsp->dip;
	  /* check for a valid offset */
	  if ( off is invalid )
	     return (-1);
	  /* check if len is within the range of contiguous memory */
	  if ( (off + len) is contiguous.)
	      length = len;
	  else
	      length = MAPPING_START + MAPPING_SIZE - off;

	  /* device access attributes */
	  endian_attr = xsp->endian_attr;

	  if (	off is referring to a device memory.  ) {
					/* assign register related parameters */
	     rnumber = XXX;		/* index to register set at off */
	     roff = XXX;		/* offset of rnumber at local bus */
	     callbackops = &xxmap_ops;	/* do all callbacks for this mapping */
	     maxprot = PROT_ALL;	/* allowing all access */
	     if ((err = devmap_devmem_setup(dhp, dip, callbackops, rnumber, roff,
		      length, maxprot, flags, endian_attr)) < 0)

		 return (err);

	  } else if ( off is referring to a kernel memory.) {
	     cookie = xsp->cookie;	/* cookie is obtained from
					   ddi_umem_alloc(9F) */
	     koff = XXX;		/* offset within the kernel memory. */
	     callbackops = NULL;	/* don't do callback for this mapping */
	     maxprot = PROT_ALL;	/* allowing all access */
	     if ((err = devmap_umem_setup(dhp, dip, callbackops, cookie, koff,
		      length, maxprot, flags, endian_attr)) < 0)
		return (err);
	 }

		*maplen = length;
	   return (0);
       }

SEE ALSO
       mmap(2),	     attach(9E),     detach(9E),     mmap(9E),	   segmap(9E),
       ddi_devmap_segmap(9F), ddi_model_convert_from(9F),  ddi_soft_state(9F),
       ddi_umem_alloc(9F),     ddi_umem_free(9F),     devmap_devmem_setup(9F),
       devmap_setup(9F),   devmap_umem_setup(9F),   cb_ops(9S),	  devmap_call‐
       back_ctl(9S)

       Writing Device Drivers

SunOS 5.10			  15 Jan 1997			    devmap(9E)
[top]

List of man pages available for SunOS

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net