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 #pragma ident "%Z%%M% %I% %E% SMI" 31*17169044Sbrutus 32*17169044Sbrutus #ifdef __cplusplus 33*17169044Sbrutus extern "C" { 34*17169044Sbrutus #endif 35*17169044Sbrutus 36*17169044Sbrutus #include <sys/types.h> 37*17169044Sbrutus #include <sys/dcopy.h> 38*17169044Sbrutus 39*17169044Sbrutus /* 40*17169044Sbrutus * private command state. Space for this structure should be allocated during 41*17169044Sbrutus * (*cb_cmd_alloc). The DMA driver must set dp_private in dcopy_cmd_t to point 42*17169044Sbrutus * to the memory it allocated. Other than pr_device_cmd_private, the DMA driver 43*17169044Sbrutus * should not touch any of the fields in this structure. pr_device_cmd_private 44*17169044Sbrutus * is a private pointer for the DMA engine to use. 45*17169044Sbrutus */ 46*17169044Sbrutus struct dcopy_cmd_priv_s { 47*17169044Sbrutus /* 48*17169044Sbrutus * we only init the state used to track a command which blocks when it 49*17169044Sbrutus * actually blocks. pr_block_init tells us when we need to clean it 50*17169044Sbrutus * up during a cmd_free. 51*17169044Sbrutus */ 52*17169044Sbrutus boolean_t pr_block_init; 53*17169044Sbrutus 54*17169044Sbrutus /* dcopy_poll blocking state */ 55*17169044Sbrutus list_node_t pr_poll_list_node; 56*17169044Sbrutus volatile boolean_t pr_wait; 57*17169044Sbrutus kmutex_t pr_mutex; 58*17169044Sbrutus kcondvar_t pr_cv; 59*17169044Sbrutus 60*17169044Sbrutus /* back pointer to the command */ 61*17169044Sbrutus dcopy_cmd_t pr_cmd; 62*17169044Sbrutus 63*17169044Sbrutus /* shortcut to the channel we're on */ 64*17169044Sbrutus struct dcopy_channel_s *pr_channel; 65*17169044Sbrutus 66*17169044Sbrutus /* DMA driver private pointer */ 67*17169044Sbrutus void *pr_device_cmd_private; 68*17169044Sbrutus }; 69*17169044Sbrutus 70*17169044Sbrutus /* cb_version */ 71*17169044Sbrutus #define DCOPY_DEVICECB_V0 0 72*17169044Sbrutus 73*17169044Sbrutus typedef struct dcopy_device_chaninfo_s { 74*17169044Sbrutus uint_t di_chan_num; 75*17169044Sbrutus } dcopy_device_chaninfo_t; 76*17169044Sbrutus 77*17169044Sbrutus typedef struct dcopy_device_cb_s { 78*17169044Sbrutus int cb_version; 79*17169044Sbrutus int cb_res1; 80*17169044Sbrutus 81*17169044Sbrutus /* allocate/free a DMA channel. See dcopy.h for return status */ 82*17169044Sbrutus int (*cb_channel_alloc)(void *device_private, 83*17169044Sbrutus dcopy_handle_t handle, int flags, uint_t size, 84*17169044Sbrutus dcopy_query_channel_t *info, void *channel_private); 85*17169044Sbrutus void (*cb_channel_free)(void *channel_private); 86*17169044Sbrutus 87*17169044Sbrutus /* allocate/free a command. See dcopy.h for return status */ 88*17169044Sbrutus int (*cb_cmd_alloc)(void *channel_private, int flags, 89*17169044Sbrutus dcopy_cmd_t *cmd); 90*17169044Sbrutus void (*cb_cmd_free)(void *channel_private, dcopy_cmd_t *cmd); 91*17169044Sbrutus 92*17169044Sbrutus /* 93*17169044Sbrutus * post a command/poll for command status. See dcopy.h for return 94*17169044Sbrutus * status 95*17169044Sbrutus */ 96*17169044Sbrutus int (*cb_cmd_post)(void *channel_private, dcopy_cmd_t cmd); 97*17169044Sbrutus int (*cb_cmd_poll)(void *channel_private, dcopy_cmd_t cmd); 98*17169044Sbrutus 99*17169044Sbrutus /* 100*17169044Sbrutus * if dcopy_device_unregister() returns DCOPY_PENDING, dcopy will 101*17169044Sbrutus * call this routine when all the channels are no longer being 102*17169044Sbrutus * used and have been free'd up. e.g. it's safe for the DMA driver 103*17169044Sbrutus * to detach. 104*17169044Sbrutus * status = DCOPY_SUCCESS || DCOPY_FAILURE 105*17169044Sbrutus */ 106*17169044Sbrutus void (*cb_unregister_complete)(void *device_private, int status); 107*17169044Sbrutus } dcopy_device_cb_t; 108*17169044Sbrutus 109*17169044Sbrutus 110*17169044Sbrutus typedef struct dcopy_device_info_s { 111*17169044Sbrutus dev_info_t *di_dip; 112*17169044Sbrutus dcopy_device_cb_t *di_cb; /* must be a static array */ 113*17169044Sbrutus uint_t di_num_dma; 114*17169044Sbrutus uint_t di_maxxfer; 115*17169044Sbrutus uint_t di_capabilities; 116*17169044Sbrutus uint64_t di_id; 117*17169044Sbrutus } dcopy_device_info_t; 118*17169044Sbrutus 119*17169044Sbrutus typedef struct dcopy_device_s *dcopy_device_handle_t; 120*17169044Sbrutus 121*17169044Sbrutus /* dcopy_device_notify() status */ 122*17169044Sbrutus #define DCOPY_COMPLETION 0 123*17169044Sbrutus 124*17169044Sbrutus /* 125*17169044Sbrutus * dcopy_device_register() 126*17169044Sbrutus * register the DMA device with dcopy. 127*17169044Sbrutus * return status => DCOPY_FAILURE, DCOPY_SUCCESS 128*17169044Sbrutus */ 129*17169044Sbrutus int dcopy_device_register(void *device_private, dcopy_device_info_t *info, 130*17169044Sbrutus dcopy_device_handle_t *handle); 131*17169044Sbrutus 132*17169044Sbrutus /* 133*17169044Sbrutus * dcopy_device_unregister() 134*17169044Sbrutus * try to unregister the DMA device with dcopy. If the DMA engines are 135*17169044Sbrutus * still being used by upper layer modules, DCOPY_PENDING will be returned. 136*17169044Sbrutus * return status => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_PENDING 137*17169044Sbrutus * if DCOPY_PENDING, (*cb_unregister_complete)() will be called when 138*17169044Sbrutus * completed. 139*17169044Sbrutus */ 140*17169044Sbrutus int dcopy_device_unregister(dcopy_device_handle_t *handle); 141*17169044Sbrutus 142*17169044Sbrutus /* 143*17169044Sbrutus * dcopy_device_channel_notify() 144*17169044Sbrutus * Notify dcopy of an event. 145*17169044Sbrutus * dcopy_handle_t handle => what was passed into (*cb_alloc)() 146*17169044Sbrutus * status => DCOPY_COMPLETION 147*17169044Sbrutus */ 148*17169044Sbrutus void dcopy_device_channel_notify(dcopy_handle_t handle, int status); 149*17169044Sbrutus 150*17169044Sbrutus #ifdef __cplusplus 151*17169044Sbrutus } 152*17169044Sbrutus #endif 153*17169044Sbrutus 154*17169044Sbrutus #endif /* _SYS_DCOPY_DEVICE_H */ 155