Home | History | Annotate | Download | only in sys
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #ifndef _SYS_DCOPY_DEVICE_H
     28 #define	_SYS_DCOPY_DEVICE_H
     29 
     30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     31 
     32 #ifdef __cplusplus
     33 extern "C" {
     34 #endif
     35 
     36 #include <sys/types.h>
     37 #include <sys/dcopy.h>
     38 
     39 /*
     40  * private command state. Space for this structure should be allocated during
     41  * (*cb_cmd_alloc). The DMA driver must set dp_private in dcopy_cmd_t to point
     42  * to the memory it allocated. Other than pr_device_cmd_private, the DMA driver
     43  * should not touch any of the fields in this structure. pr_device_cmd_private
     44  * is a private pointer for the DMA engine to use.
     45  */
     46 struct dcopy_cmd_priv_s {
     47 	/*
     48 	 * we only init the state used to track a command which blocks when it
     49 	 * actually blocks. pr_block_init tells us when we need to clean it
     50 	 * up during a cmd_free.
     51 	 */
     52 	boolean_t		pr_block_init;
     53 
     54 	/* dcopy_poll blocking state */
     55 	list_node_t		pr_poll_list_node;
     56 	volatile boolean_t	pr_wait;
     57 	kmutex_t		pr_mutex;
     58 	kcondvar_t		pr_cv;
     59 
     60 	/* back pointer to the command */
     61 	dcopy_cmd_t		pr_cmd;
     62 
     63 	/* shortcut to the channel we're on */
     64 	struct dcopy_channel_s	*pr_channel;
     65 
     66 	/* DMA driver private pointer */
     67 	void			*pr_device_cmd_private;
     68 };
     69 
     70 /* cb_version */
     71 #define	DCOPY_DEVICECB_V0	0
     72 
     73 typedef struct dcopy_device_chaninfo_s {
     74 	uint_t	di_chan_num;
     75 } dcopy_device_chaninfo_t;
     76 
     77 typedef struct dcopy_device_cb_s {
     78 	int	cb_version;
     79 	int	cb_res1;
     80 
     81 	/* allocate/free a DMA channel. See dcopy.h for return status  */
     82 	int	(*cb_channel_alloc)(void *device_private,
     83 		    dcopy_handle_t handle, int flags, uint_t size,
     84 		    dcopy_query_channel_t *info, void *channel_private);
     85 	void	(*cb_channel_free)(void *channel_private);
     86 
     87 	/* allocate/free a command. See dcopy.h for return status  */
     88 	int	(*cb_cmd_alloc)(void *channel_private, int flags,
     89 		    dcopy_cmd_t *cmd);
     90 	void	(*cb_cmd_free)(void *channel_private, dcopy_cmd_t *cmd);
     91 
     92 	/*
     93 	 * post a command/poll for command status. See dcopy.h for return
     94 	 * status
     95 	 */
     96 	int	(*cb_cmd_post)(void *channel_private, dcopy_cmd_t cmd);
     97 	int	(*cb_cmd_poll)(void *channel_private, dcopy_cmd_t cmd);
     98 
     99 	/*
    100 	 * if dcopy_device_unregister() returns DCOPY_PENDING, dcopy will
    101 	 * call this routine when all the channels are no longer being
    102 	 * used and have been free'd up. e.g. it's safe for the DMA driver
    103 	 * to detach.
    104 	 *   status = DCOPY_SUCCESS || DCOPY_FAILURE
    105 	 */
    106 	void	(*cb_unregister_complete)(void *device_private, int status);
    107 } dcopy_device_cb_t;
    108 
    109 
    110 typedef struct dcopy_device_info_s {
    111 	dev_info_t		*di_dip;
    112 	dcopy_device_cb_t	*di_cb; /* must be a static array */
    113 	uint_t			di_num_dma;
    114 	uint_t			di_maxxfer;
    115 	uint_t			di_capabilities;
    116 	uint64_t		di_id;
    117 } dcopy_device_info_t;
    118 
    119 typedef struct dcopy_device_s *dcopy_device_handle_t;
    120 
    121 /* dcopy_device_notify() status */
    122 #define	DCOPY_COMPLETION	0
    123 
    124 /*
    125  * dcopy_device_register()
    126  *   register the DMA device with dcopy.
    127  *    return status => DCOPY_FAILURE, DCOPY_SUCCESS
    128  */
    129 int dcopy_device_register(void *device_private, dcopy_device_info_t *info,
    130     dcopy_device_handle_t *handle);
    131 
    132 /*
    133  * dcopy_device_unregister()
    134  *   try to unregister the DMA device with dcopy. If the DMA engines are
    135  *   still being used by upper layer modules, DCOPY_PENDING will be returned.
    136  *    return status => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_PENDING
    137  *      if DCOPY_PENDING, (*cb_unregister_complete)() will be called when
    138  *      completed.
    139  */
    140 int dcopy_device_unregister(dcopy_device_handle_t *handle);
    141 
    142 /*
    143  * dcopy_device_channel_notify()
    144  *   Notify dcopy of an event.
    145  *     dcopy_handle_t handle => what was passed into (*cb_alloc)()
    146  *     status => DCOPY_COMPLETION
    147  */
    148 void dcopy_device_channel_notify(dcopy_handle_t handle, int status);
    149 
    150 #ifdef __cplusplus
    151 }
    152 #endif
    153 
    154 #endif /* _SYS_DCOPY_DEVICE_H */
    155