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