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