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