devmap man page on SmartOS

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

DEVMAP(9E)							    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
		  mapping 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:

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

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

	   o	  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  sys‐
       tem  will repeatedly call devmap() until the original mapping length is
       satisfied. 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

				 Jan 15, 1997			    DEVMAP(9E)
[top]

List of man pages available for SmartOS

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