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_Q_H 28 #define _SYS_1394_ADAPTERS_HCI1394_Q_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /* 33 * hci1394_q.h 34 * This code decouples some of the OpenHCI async descriptor logic/structures 35 * from the async processing. The goal was to combine as much of the 36 * duplicate code as possible for the different type of async transfers 37 * without going too overboard. 38 * 39 * There are two parts to the Q, the descriptor buffer and the data buffer. 40 * for the most part, data to be transmitted and data which is received go 41 * in the data buffers. The information of where to get the data and put 42 * the data reside in the descriptor buffers. There are exceptions to this. 43 */ 44 45 #ifdef __cplusplus 46 extern "C" { 47 #endif 48 49 #include <sys/ddi.h> 50 #include <sys/modctl.h> 51 #include <sys/sunddi.h> 52 #include <sys/types.h> 53 #include <sys/note.h> 54 55 #include <sys/1394/adapters/hci1394_def.h> 56 #include <sys/1394/adapters/hci1394_tlist.h> 57 #include <sys/1394/adapters/hci1394_buf.h> 58 #include <sys/1394/adapters/hci1394_descriptors.h> 59 60 61 /* 62 * Part of q_info passed in during q_init(). This tells us if this is an async 63 * transmit or async receive Q. This makes a big difference inside of q. For 64 * the transmit Q we will just setup an empty Q ready for TX calls into us. For 65 * receive Q's we have to make sure we get multiple data buffers and then setup 66 * the buffers so they are ready to receive data (by adding in the IM 67 * descriptors). 68 */ 69 typedef enum { 70 HCI1394_ARQ, 71 HCI1394_ATQ 72 } hci1394_q_mode_t; 73 74 /* 75 * Part of q_info passed in during q_init(). These are the callbacks for 76 * starting and waking up the async Q's. When the first descriptor is placed 77 * on the Q, the async DMA engine is started with an address of where to find 78 * the descriptor on the Q. That descriptor will be changed to point to the 79 * next descriptor when the next descriptor is added (i.e. a chained dma). 80 * Whenever an additional descriptor is added, wake is called. 81 */ 82 typedef void (*hci1394_q_start_t)(void *arg, uint32_t io_addr); 83 typedef void (*hci1394_q_wake_t)(void *arg); 84 85 /* 86 * Passed in during q_init(). This contains the size of the descriptor Q, the 87 * size of the data Q, what kind of Q it is (AT or AR), the callbacks for start 88 * and wake, and the argument to pass during start and wake. 89 */ 90 typedef struct hci1394_q_info_s { 91 uint_t qi_desc_size; 92 uint_t qi_data_size; 93 hci1394_q_mode_t qi_mode; 94 hci1394_q_start_t qi_start; 95 hci1394_q_wake_t qi_wake; 96 void *qi_callback_arg; 97 } hci1394_q_info_t; 98 99 /* 100 * Per command tracking information for the AT Q's. This is not used on the AR 101 * side. This structure has two parts to it, the public data and the private 102 * data. The public data is shared between async.c and q.c. The private data 103 * is for internal q.c access only. It is only put in this structure so that 104 * we do not have to dynamically alloc space for each transfer. 105 */ 106 typedef struct hci1394_q_cmd_s { 107 108 /* PUBLIC DATA STRUCTURES */ 109 /* 110 * qc_arg is an input paramter to hci1394_q_at() (along with the data 111 * versions). It is an opaque address pointer which is used by async.c 112 * to determine the commands address after a call to 113 * hci1394_q_at_next(). 114 */ 115 void *qc_arg; 116 117 /* 118 * qc_generation is an input parameter to hci1394_q_at() (along with the 119 * data versions). It is the generation count for which this command is 120 * valid. If qc_generation does not match the current bus generation, 121 * hci1394_q_at*() will return failure. 122 */ 123 uint_t qc_generation; 124 125 /* 126 * qc_timestamp is used when sending an atresp to set the time when the 127 * response is to have timed out. It is also use on at_next to tell 128 * when the AT command completed. 129 */ 130 uint_t qc_timestamp; 131 132 /* 133 * qc_status is an output of hci1394_q_at_next(). It contains the 134 * command status after completion. 135 */ 136 uint32_t qc_status; 137 138 139 /* PRIVATE DATA STRUCTURES */ 140 /* 141 * This is the memory address of where the status of this command 142 * resides. 143 */ 144 uint32_t *qc_status_addr; 145 146 /* 147 * qc_descriptor_end and qc_descriptor_buf are used to track where the 148 * descriptor q pointers should be set to when this command has 149 * completed (i.e. free up the space used by this command) 150 */ 151 caddr_t qc_descriptor_end; 152 uint_t qc_descriptor_buf; 153 154 /* 155 * qc_data_end and qc_data_buf are used to track where the data q 156 * pointers should be set to when this command has completed (i.e. free 157 * up the space used by this command). Not all commands use the data 158 * q so qc_data_used give us state on if this command uses the data q. 159 */ 160 boolean_t qc_data_used; 161 caddr_t qc_data_end; 162 uint_t qc_data_buf; 163 164 /* 165 * This is the node for the queued list. Since AT requests finish in 166 * the order that they were submitted, we queue these up in a linked 167 * list so that it is easy to figure out which command has finished. 168 * Just look at the head of the list. 169 */ 170 hci1394_tlist_node_t qc_node; 171 } hci1394_q_cmd_t; 172 173 _NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \ 174 hci1394_q_cmd_s::qc_status \ 175 hci1394_q_cmd_s::qc_timestamp)) 176 177 typedef struct hci1394_q_bufptr_s { 178 /* 179 * kernel virtual addresses. The q may be broken down into multiple 180 * cookies. The q is contiguous relative to the driver, but segmented 181 * relative to the 1394 HW DMA engines. 182 * 183 * qp_top is the top the q. qp_bottom is the bottom of the q. These 184 * never change after initial setup. qp_bottom is inclusive (i.e. for a 185 * q size of 16 bytes where top was = to 0, qp_bottom would be = to 15). 186 * 187 * qp_current and qp_free are pointers within top and bottom. qp_current 188 * refers to the next free space to write and free refers to the end of 189 * free space (i.e. used memory within q). qp_free is inclusive (see 190 * qp_bottom). 191 */ 192 caddr_t qp_top; 193 caddr_t qp_bottom; 194 caddr_t qp_current; 195 caddr_t qp_free; 196 197 /* 198 * qp_begin and qp_end are also kernel virtual addresses. They are the 199 * beginning and ending address of the current_buf (cookie) within the 200 * q. qp_offset is (qp_current - qp_begin). This is used to determine 201 * the 32 bit PCI address to put into the OpenHCI descriptor. We know 202 * the base PCI address from the cookie structure, we add offset to that 203 * to determine the correct PCI address. 204 */ 205 caddr_t qp_begin; 206 caddr_t qp_end; 207 uint32_t qp_offset; 208 209 /* 210 * As stated above, the q may be broken into multiple cookies. 211 * qp_current_buf is the cookie qp_current is in and qp_free_buf is the 212 * cookie qp_free is in. NOTE: The cookie's are numbered 0, 1, 2, ..., 213 * (i.e. if we have 4 cookies, qp_current_buf can be 0, 1, 2, or 3) 214 */ 215 uint_t qp_current_buf; 216 uint_t qp_free_buf; 217 218 /* 219 * qp_resv_size is only used for the AT Q's. 220 * How much space has been reserved. This value is set on the call to 221 * hci1394_q_reserve() and decremented each time a data is written. It 222 * is used to check for overrun conditions. This extra check is in there 223 * as an added sanity check due to the complexity of this code. 224 */ 225 uint_t qp_resv_size; 226 } hci1394_q_bufptr_t; 227 228 229 typedef struct hci1394_q_buf_s { 230 /* pointers to track used/free space/cookies in the buffer */ 231 hci1394_q_bufptr_t qb_ptrs; 232 233 /* 234 * a backup of qb_ptrs. If we fail while setting up an AT Q, we need to 235 * cleanup by putting things back the way that they were. 236 */ 237 hci1394_q_bufptr_t qb_backup_ptrs; 238 239 /* copy of all of the cookie's structures for this buffer */ 240 ddi_dma_cookie_t qb_cookie[OHCI_MAX_COOKIE]; 241 242 /* Buffer handle used for calls into hci1394_buf_* routines */ 243 hci1394_buf_handle_t qb_buf_handle; 244 245 /* Buffer info (i.e. cookie count, kaddr, ddi handles, etc.) */ 246 hci1394_buf_info_t qb_buf; 247 } hci1394_q_buf_t; 248 249 _NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \ 250 hci1394_q_buf_s::qb_ptrs.qp_begin \ 251 hci1394_q_buf_s::qb_ptrs.qp_bottom \ 252 hci1394_q_buf_s::qb_ptrs.qp_current \ 253 hci1394_q_buf_s::qb_ptrs.qp_current_buf \ 254 hci1394_q_buf_s::qb_ptrs.qp_end \ 255 hci1394_q_buf_s::qb_ptrs.qp_offset \ 256 hci1394_q_buf_s::qb_ptrs.qp_top)) 257 258 typedef struct hci1394_q_s { 259 /* 260 * q_queued_list is only used in the AT descriptor Qs. AT commands 261 * complete in the order they were issued. We Q these commands up with 262 * each new command being added to the end of the list. When a command 263 * completes, we look at the top of this list to determine which command 264 * completed. 265 */ 266 hci1394_tlist_handle_t q_queued_list; 267 268 /* 269 * pointer to general driver information (dip, instance, etc) and to 270 * handle for access to openHCI routines. 271 */ 272 hci1394_drvinfo_t *q_drvinfo; 273 hci1394_ohci_handle_t q_ohci; 274 275 /* 276 * The OpenHCI DMA engines are basically just chained DMA engines. Each 277 * "link" in the chain is called a descriptor in OpenHCI. When you want 278 * to add a new descriptor, you init the descriptor, setup its "next" 279 * pointer to "NULL", update the previous descriptor to point to the 280 * new descriptor, and tell the HW you added a new descriptor by setting 281 * its wake bit. q_previous is a pointer to the previous descriptor. 282 * When adding a new descriptor, we just de-reference q_previous to 283 * update its "next" pointer. 284 */ 285 hci1394_desc_t *q_previous; 286 287 /* 288 * When updating the "next" pointer in the previous descriptor block 289 * (as described above in q_previous), one of the things you need to 290 * tell the HW is how many 16 byte blocks the next descriptor block 291 * uses. This is what q_block_cnt is used for. This is only used in the 292 * AT descriptor Q's. Since the IM's used in the AR Q's are the only 293 * descriptor types used in AR, the block count is always the same for 294 * an AR descriptor Q. 295 */ 296 uint_t q_block_cnt; 297 298 /* 299 * q_head is only used in the AR descriptor Qs. It contains the location 300 * of the first descriptor on the Q. This is used to look at the 301 * residual count in the AR data Q. The residual count tells us if we 302 * have received any new packets to process. When a descriptor's data 303 * buffer is empty (q_space_left = 0), we move q_head to the next 304 * descriptor in the descriptor buffer. 305 */ 306 caddr_t q_head; 307 308 /* 309 * q_space_left is only used in the AR descriptor Qs. Each AR 310 * descriptor has residual count embedded in the descriptor which says 311 * how much free space is left in the descriptors associated data 312 * buffer. q_space_left is how much SW thinks is left in the data 313 * buffer. When they do not match, we have a new packet(s) in the data 314 * buffer to process. Since the residual count is not updated by the 315 * HW until the entire packet has been written to memory, we don't have 316 * to worry about any partial packet RX problems. 317 */ 318 uint_t q_space_left; 319 320 /* 321 * status of the dma controller. This tells us if we should do a start 322 * or a wake. If the dma engine is not running, we should start it. If 323 * it is running, we should wake it. When the DMA engine is started, it 324 * expects to have a valid descriptor to process. Since we don't have 325 * anything to send in the beginning (AT), we have to wait until the 326 * first AT packet comes down before we can start the DMA engine. 327 */ 328 boolean_t q_dma_running; 329 330 /* The descriptor buffer for this Q */ 331 hci1394_q_buf_t q_desc; 332 333 /* The data buffer for this Q */ 334 hci1394_q_buf_t q_data; 335 336 /* copy of qinfo passed in during hci1394_q_init() */ 337 hci1394_q_info_t q_info; 338 339 kmutex_t q_mutex; 340 } hci1394_q_t; 341 342 _NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \ 343 hci1394_q_s::q_dma_running \ 344 hci1394_q_s::q_head \ 345 hci1394_q_s::q_previous \ 346 hci1394_q_s::q_space_left)) 347 348 /* handle passed back from init() and used for rest of functions */ 349 typedef struct hci1394_q_s *hci1394_q_handle_t; 350 351 352 int hci1394_q_init(hci1394_drvinfo_t *drvinfo, 353 hci1394_ohci_handle_t ohci_handle, hci1394_q_info_t *qinfo, 354 hci1394_q_handle_t *q_handle); 355 void hci1394_q_fini(hci1394_q_handle_t *q_handle); 356 void hci1394_q_resume(hci1394_q_handle_t q_handle); 357 void hci1394_q_stop(hci1394_q_handle_t q_handle); 358 359 int hci1394_q_at(hci1394_q_handle_t q_handle, hci1394_q_cmd_t *cmd, 360 hci1394_basic_pkt_t *hdr, uint_t hdrsize, int *result); 361 int hci1394_q_at_with_data(hci1394_q_handle_t q_handle, hci1394_q_cmd_t *cmd, 362 hci1394_basic_pkt_t *hdr, uint_t hdrsize, uint8_t *data, uint_t datasize, 363 int *result); 364 int hci1394_q_at_with_mblk(hci1394_q_handle_t q_handle, hci1394_q_cmd_t *cmd, 365 hci1394_basic_pkt_t *hdr, uint_t hdrsize, h1394_mblk_t *mblk, int *result); 366 void hci1394_q_at_next(hci1394_q_handle_t q_handle, boolean_t flush_q, 367 hci1394_q_cmd_t **cmd); 368 369 void hci1394_q_ar_next(hci1394_q_handle_t q_handle, uint32_t **q_addr); 370 void hci1394_q_ar_free(hci1394_q_handle_t q_handle, uint_t size); 371 uint32_t hci1394_q_ar_get32(hci1394_q_handle_t q_handle, uint32_t *addr); 372 void hci1394_q_ar_rep_get8(hci1394_q_handle_t q_handle, uint8_t *dest, 373 uint8_t *q_addr, uint_t size); 374 void hci1394_q_ar_copy_to_mblk(hci1394_q_handle_t q_handle, uint8_t *addr, 375 h1394_mblk_t *mblk); 376 377 378 #ifdef __cplusplus 379 } 380 #endif 381 382 #endif /* _SYS_1394_ADAPTERS_HCI1394_Q_H */ 383