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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1999-2000 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #ifndef _SYS_1394_ADAPTERS_HCI1394_ASYNC_H 28 #define _SYS_1394_ADAPTERS_HCI1394_ASYNC_H 29 30 /* 31 * hci1394_async.h 32 * These routines the 1394 asynchronous dma engines. These include incoming 33 * and outgoing reads, writes, and lock and their associated responses. 34 */ 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 #include <sys/ddi.h> 41 #include <sys/modctl.h> 42 #include <sys/sunddi.h> 43 #include <sys/types.h> 44 45 #include <sys/1394/h1394.h> 46 47 #include <sys/1394/adapters/hci1394_def.h> 48 #include <sys/1394/adapters/hci1394_tlist.h> 49 #include <sys/1394/adapters/hci1394_q.h> 50 51 52 /* 53 * Async descriptor and data buffer sizes. The AR descriptor buffers do not need 54 * to be very big. There will be 1 16 byte IM for every AR data buffer. If we 55 * alloc a 16KByte ARRESP data buffer on X86, we could get 4 4KByte cookies. 56 * This would use up 64 bytes in the descriptor buffer. We will never need more 57 * space than that. A 256 byte descriptor should handle a 64K buffer on x86 58 * if it is broken into 16 cookies. 59 */ 60 #define ASYNC_ATREQ_DESC_SIZE 16384 61 #define ASYNC_ATREQ_DATA_SIZE 16384 62 #define ASYNC_ARRESP_DESC_SIZE 256 63 #define ASYNC_ARRESP_DATA_SIZE 16384 64 #define ASYNC_ARREQ_DESC_SIZE 256 65 #define ASYNC_ARREQ_DATA_SIZE 16384 66 #define ASYNC_ATRESP_DESC_SIZE 16384 67 #define ASYNC_ATRESP_DATA_SIZE 16384 68 69 70 /* handle passed back from init() and used for rest of functions */ 71 typedef struct hci1394_async_s *hci1394_async_handle_t; 72 73 /* 74 * Async Command State. This state is used to catch a race condition between 75 * the ATREQ complete interrupt handler and the ARRESP interrupt handler. The 76 * ATREQ will always complete before the ARRESP arrives, but SW may not see it 77 * that way. See hci1394_async_atreq_process() for more information on this. 78 */ 79 typedef enum { 80 HCI1394_CMD_STATE_IN_PROGRESS, 81 HCI1394_CMD_STATE_PENDING, 82 HCI1394_CMD_STATE_COMPLETED 83 } hci1394_async_cstate_t; 84 85 86 typedef struct hci1394_async_cmd_s { 87 /* Pointer to framework command allocted by services layer */ 88 cmd1394_cmd_t *ac_cmd; 89 90 /* 91 * Pointer to HAL/SL private area in the command. This is private info 92 * shared between the HAL and Services Layer on a per command basis. 93 */ 94 h1394_cmd_priv_t *ac_priv; 95 96 /* 97 * Status on if we allocated a tlabel for an ATREQ. Normally we will 98 * allocate a tlabel with every ATREQ. But, we will not allocate a 99 * tlabel for a PHY packet. When we initialize the command, we will 100 * assume that we are going to allocate a tlabel. The async phy command 101 * will "override" this setting and set ac_tlabel_alloc to b_false. 102 */ 103 boolean_t ac_tlabel_alloc; 104 105 /* handle for tlabel logic */ 106 hci1394_tlabel_info_t ac_tlabel; 107 108 /* 109 * This is used for ARREQs. When we get a block read or write request, 110 * we allocate a mblk to put the data into. After the ATRESP has been 111 * sent out and has completed, hci1394_async_response_complete() is 112 * called to free up the ARREQ resources which were allocated. This 113 * routine will free the mblk if we allocated it in ARREQ. If an ARREQ 114 * block write is received and the target driver wishes to keep the 115 * mblk w/ the data (to pass it up a stream), but releases the command, 116 * it can set the mblk pointer in the command to null. We will check 117 * for mblk being == to NULL even if ac_mblk_alloc is set to true. 118 */ 119 boolean_t ac_mblk_alloc; 120 121 /* 122 * ac_status contains the 1394 RESP for an ARRESP or the ACK for ARREQ. 123 * This status is set in either hci1394_async_arresp_read() or 124 * hci1394_arreq_read() 125 */ 126 int ac_status; 127 128 /* 129 * Destination packet was sent to. This is used to determine if the 130 * packet was broadcast or not in hci1394_async_arreq_read(). 131 */ 132 uint_t ac_dest; 133 134 /* 135 * Async command state. See comments above for more information. Other 136 * than initialization, this field is only accessed in the ISR. State 137 * is only used in ATREQ/ARRESP processing. 138 */ 139 hci1394_async_cstate_t ac_state; 140 141 /* 142 * Pointer back to the Async private state. This allows us to access 143 * the async state structures if all we have is a pointer to the async 144 * command. 145 */ 146 struct hci1394_async_s *ac_async; 147 148 /* 149 * pending list node structure. If a command is pended, this node is 150 * what's passed to the tlist code to add the node to the pending list. 151 * It contains all the pointers the linked list needs so that we do not 152 * need to allocate any space every time we add something to the list. 153 */ 154 hci1394_tlist_node_t ac_plist_node; 155 156 /* 157 * hci1394_q information about this command. This is used for AT 158 * commands. It contains information passed down to the hci1394_q_at*() 159 * routines like qc_timestamp which is used to tell the HW when an 160 * ATRESP has timed out out. The status of the AT command is returned 161 * in qc_status after calling hci1394_q_at_next(). The rest of the 162 * structure members are private members used to track the descriptor 163 * and data buffer usage. 164 */ 165 hci1394_q_cmd_t ac_qcmd; 166 } hci1394_async_cmd_t; 167 168 _NOTE(SCHEME_PROTECTS_DATA("Used only by one thread", hci1394_async_cmd_s \ 169 hci1394_async_cmd_s::ac_qcmd.qc_arg \ 170 hci1394_async_cmd_s::ac_qcmd.qc_generation \ 171 hci1394_async_cmd_s::ac_qcmd.qc_timestamp \ 172 hci1394_async_cmd_s::ac_tlabel_alloc \ 173 hci1394_async_cmd_s::ac_tlabel.tbi_destination \ 174 hci1394_async_cmd_s::ac_tlabel.tbi_tlabel)) 175 176 /* 177 * async private state information. It contains handles for the various modules 178 * that async uses. 179 */ 180 typedef struct hci1394_async_s { 181 hci1394_tlist_handle_t as_pending_list; 182 hci1394_ohci_handle_t as_ohci; 183 hci1394_tlabel_handle_t as_tlabel; 184 hci1394_csr_handle_t as_csr; 185 hci1394_q_handle_t as_atreq_q; 186 hci1394_q_handle_t as_arresp_q; 187 hci1394_q_handle_t as_arreq_q; 188 hci1394_q_handle_t as_atresp_q; 189 hci1394_drvinfo_t *as_drvinfo; 190 191 /* 192 * as_flushing_arreq is used in bus reset processing. It is set by 193 * hci1394_async_arreq_flush() and tells hci1394_async_arreq_process() 194 * not to send the ARREQ up to the Services Layer. It will be set to 195 * FALSE by hci1394_async_arreq_read_phy() when a bus reset token with 196 * the current bus generation is found. as_phy_reset is used to store 197 * the last PHY packet generation seen in the ARREQ Q. The HW puts a 198 * token in the ARREQ Q so that the SW can flush the Q up to and 199 * including the token. 200 */ 201 boolean_t as_flushing_arreq; 202 uint_t as_phy_reset; 203 204 /* 205 * as_atomic_lookup is used to protect the cmd from a race condition 206 * between the ARRESP and the Pending Timeout callback. This is 207 * explained in more detail in hci1394_async_atreq_process(). 208 */ 209 kmutex_t as_atomic_lookup; 210 } hci1394_async_t; 211 212 _NOTE(SCHEME_PROTECTS_DATA("Used only by one thread", \ 213 hci1394_async_s::as_flushing_arreq hci1394_async_s::as_phy_reset)) 214 215 int hci1394_async_init(hci1394_drvinfo_t *drvinfo, 216 hci1394_ohci_handle_t ohci_handle, hci1394_csr_handle_t csr_handle, 217 hci1394_async_handle_t *async_handle); 218 void hci1394_async_fini(hci1394_async_handle_t *async_handle); 219 void hci1394_async_suspend(hci1394_async_handle_t async_handle); 220 int hci1394_async_resume(hci1394_async_handle_t async_handle); 221 uint_t hci1394_async_cmd_overhead(); 222 223 void hci1394_async_flush(hci1394_async_handle_t async_handle); 224 void hci1394_async_atreq_reset(hci1394_async_handle_t async_handle); 225 void hci1394_async_atresp_reset(hci1394_async_handle_t async_handle); 226 void hci1394_async_pending_timeout_update(hci1394_async_handle_t async_handle, 227 hrtime_t timeout); 228 229 int hci1394_async_atreq_process(hci1394_async_handle_t async_handle, 230 boolean_t flush_q, boolean_t *request_available); 231 int hci1394_async_arresp_process(hci1394_async_handle_t async_handle, 232 boolean_t *response_available); 233 int hci1394_async_arreq_process(hci1394_async_handle_t async_handle, 234 boolean_t *request_available); 235 int hci1394_async_atresp_process(hci1394_async_handle_t async_handle, 236 boolean_t flush_q, boolean_t *response_available); 237 238 int hci1394_async_phy(hci1394_async_handle_t async_handle, 239 cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result); 240 int hci1394_async_write(hci1394_async_handle_t async_handle, 241 cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result); 242 int hci1394_async_read(hci1394_async_handle_t async_handle, 243 cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result); 244 int hci1394_async_lock(hci1394_async_handle_t async_handle, 245 cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result); 246 int hci1394_async_write_response(hci1394_async_handle_t async_handle, 247 cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result); 248 int hci1394_async_read_response(hci1394_async_handle_t async_handle, 249 cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result); 250 int hci1394_async_lock_response(hci1394_async_handle_t async_handle, 251 cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result); 252 void hci1394_async_response_complete(hci1394_async_handle_t async_handle, 253 cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv); 254 255 256 #ifdef __cplusplus 257 } 258 #endif 259 260 #endif /* _SYS_1394_ADAPTERS_HCI1394_ASYNC_H */ 261