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