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 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Copyright (c) 2009, Intel Corporation. 29 * All rights reserved. 30 */ 31 32 #include <sys/errno.h> 33 #include <sys/types.h> 34 #include <sys/conf.h> 35 #include <sys/kmem.h> 36 #include <sys/ddi.h> 37 #include <sys/stat.h> 38 #include <sys/sunddi.h> 39 #include <sys/file.h> 40 #include <sys/open.h> 41 #include <sys/modctl.h> 42 #include <sys/ddi_impldefs.h> 43 #include <sys/sysmacros.h> 44 #include <vm/hat.h> 45 #include <vm/as.h> 46 #include <sys/mach_mmu.h> 47 #ifdef __xpv 48 #include <sys/hypervisor.h> 49 #endif 50 51 #include <sys/ioat.h> 52 53 54 extern ddi_device_acc_attr_t ioat_acc_attr; 55 56 /* dma attr for the descriptor rings */ 57 ddi_dma_attr_t ioat_desc_dma_attr = { 58 DMA_ATTR_V0, /* dma_attr_version */ 59 0x0, /* dma_attr_addr_lo */ 60 0xffffffffffffffff, /* dma_attr_addr_hi */ 61 0xffffffff, /* dma_attr_count_max */ 62 0x1000, /* dma_attr_align */ 63 0x1, /* dma_attr_burstsizes */ 64 0x1, /* dma_attr_minxfer */ 65 0xffffffff, /* dma_attr_maxxfer */ 66 0xffffffff, /* dma_attr_seg */ 67 0x1, /* dma_attr_sgllen */ 68 0x1, /* dma_attr_granular */ 69 0x0, /* dma_attr_flags */ 70 }; 71 72 /* dma attr for the completion buffers */ 73 ddi_dma_attr_t ioat_cmpl_dma_attr = { 74 DMA_ATTR_V0, /* dma_attr_version */ 75 0x0, /* dma_attr_addr_lo */ 76 0xffffffffffffffff, /* dma_attr_addr_hi */ 77 0xffffffff, /* dma_attr_count_max */ 78 0x40, /* dma_attr_align */ 79 0x1, /* dma_attr_burstsizes */ 80 0x1, /* dma_attr_minxfer */ 81 0xffffffff, /* dma_attr_maxxfer */ 82 0xffffffff, /* dma_attr_seg */ 83 0x1, /* dma_attr_sgllen */ 84 0x1, /* dma_attr_granular */ 85 0x0, /* dma_attr_flags */ 86 }; 87 88 static int ioat_completion_alloc(ioat_channel_t channel); 89 static void ioat_completion_free(ioat_channel_t channel); 90 static void ioat_channel_start(ioat_channel_t channel); 91 static void ioat_channel_reset(ioat_channel_t channel); 92 93 int ioat_ring_alloc(ioat_channel_t channel, uint_t desc_cnt); 94 void ioat_ring_free(ioat_channel_t channel); 95 void ioat_ring_seed(ioat_channel_t channel, ioat_chan_dma_desc_t *desc); 96 int ioat_ring_reserve(ioat_channel_t channel, ioat_channel_ring_t *ring, 97 dcopy_cmd_t cmd); 98 99 static void ioat_cmd_post_copy(ioat_channel_ring_t *ring, uint64_t src_addr, 100 uint64_t dest_addr, uint32_t size, uint32_t ctrl); 101 static void ioat_cmd_post_dca(ioat_channel_ring_t *ring, uint32_t dca_id); 102 103 104 /* 105 * ioat_channel_init() 106 */ 107 int 108 ioat_channel_init(ioat_state_t *state) 109 { 110 int i; 111 112 /* 113 * initialize each dma channel's state which doesn't change across 114 * channel alloc/free. 115 */ 116 state->is_chansize = sizeof (struct ioat_channel_s) * 117 state->is_num_channels; 118 state->is_channel = kmem_zalloc(state->is_chansize, KM_SLEEP); 119 for (i = 0; i < state->is_num_channels; i++) { 120 state->is_channel[i].ic_state = state; 121 state->is_channel[i].ic_regs = (uint8_t *) 122 ((uintptr_t)state->is_genregs + 123 (uintptr_t)(IOAT_CHANNELREG_OFFSET * (i + 1))); 124 } 125 126 /* initial the allocator (from 0 to state->is_num_channels) */ 127 ioat_rs_init(state, 0, state->is_num_channels, &state->is_channel_rs); 128 129 return (DDI_SUCCESS); 130 } 131 132 133 /* 134 * ioat_channel_fini() 135 */ 136 void 137 ioat_channel_fini(ioat_state_t *state) 138 { 139 ioat_rs_fini(&state->is_channel_rs); 140 kmem_free(state->is_channel, state->is_chansize); 141 } 142 143 144 /* 145 * ioat_channel_alloc() 146 * NOTE: We intentionaly don't handle DCOPY_SLEEP (if no channels are 147 * available) 148 */ 149 /*ARGSUSED*/ 150 int 151 ioat_channel_alloc(void *device_private, dcopy_handle_t handle, int flags, 152 uint_t size, dcopy_query_channel_t *info, void *channel_private) 153 { 154 #define CHANSTRSIZE 20 155 struct ioat_channel_s *channel; 156 char chanstr[CHANSTRSIZE]; 157 ioat_channel_t *chan; 158 ioat_state_t *state; 159 size_t cmd_size; 160 uint_t chan_num; 161 uint32_t estat; 162 int e; 163 164 165 state = (ioat_state_t *)device_private; 166 chan = (ioat_channel_t *)channel_private; 167 168 /* allocate a H/W channel */ 169 e = ioat_rs_alloc(state->is_channel_rs, &chan_num); 170 if (e != DDI_SUCCESS) { 171 return (DCOPY_NORESOURCES); 172 } 173 174 channel = &state->is_channel[chan_num]; 175 channel->ic_inuse = B_TRUE; 176 channel->ic_chan_num = chan_num; 177 channel->ic_ver = state->is_ver; 178 channel->ic_dca_active = B_FALSE; 179 channel->ic_channel_state = IOAT_CHANNEL_OK; 180 channel->ic_dcopy_handle = handle; 181 182 #ifdef DEBUG 183 { 184 /* if we're cbv2, verify that the V2 compatibility bit is set */ 185 uint16_t reg; 186 if (channel->ic_ver == IOAT_CBv2) { 187 reg = ddi_get16(state->is_reg_handle, 188 (uint16_t *)&channel->ic_regs[IOAT_CHAN_COMP]); 189 ASSERT(reg & 0x2); 190 } 191 } 192 #endif 193 194 /* 195 * Configure DMA channel 196 * Channel In Use 197 * Error Interrupt Enable 198 * Any Error Abort Enable 199 * Error Completion Enable 200 */ 201 ddi_put16(state->is_reg_handle, 202 (uint16_t *)&channel->ic_regs[IOAT_CHAN_CTL], 0x011C); 203 204 /* check channel error register, clear any errors */ 205 estat = ddi_get32(state->is_reg_handle, 206 (uint32_t *)&channel->ic_regs[IOAT_CHAN_ERR]); 207 if (estat != 0) { 208 #ifdef DEBUG 209 cmn_err(CE_CONT, "cleared errors (0x%x) before channel (%d) " 210 "enable\n", estat, channel->ic_chan_num); 211 #endif 212 ddi_put32(state->is_reg_handle, 213 (uint32_t *)&channel->ic_regs[IOAT_CHAN_ERR], estat); 214 } 215 216 /* allocate and initialize the descriptor buf */ 217 e = ioat_ring_alloc(channel, size); 218 if (e != DDI_SUCCESS) { 219 goto chinitfail_desc_alloc; 220 } 221 222 /* allocate and initialize the completion space */ 223 e = ioat_completion_alloc(channel); 224 if (e != DDI_SUCCESS) { 225 goto chinitfail_completion_alloc; 226 } 227 228 /* setup kmem_cache for commands */ 229 cmd_size = sizeof (struct dcopy_cmd_s) + 230 sizeof (struct dcopy_cmd_priv_s) + 231 sizeof (struct ioat_cmd_private_s); 232 (void) snprintf(chanstr, CHANSTRSIZE, "ioat%dchan%dcmd", 233 state->is_instance, channel->ic_chan_num); 234 channel->ic_cmd_cache = kmem_cache_create(chanstr, cmd_size, 64, 235 NULL, NULL, NULL, NULL, NULL, 0); 236 if (channel->ic_cmd_cache == NULL) { 237 goto chinitfail_kmem_cache; 238 } 239 240 /* start-up the channel */ 241 ioat_channel_start(channel); 242 243 /* fill in the channel info returned to dcopy */ 244 info->qc_version = DCOPY_QUERY_CHANNEL_V0; 245 info->qc_id = state->is_deviceinfo.di_id; 246 info->qc_capabilities = (uint64_t)state->is_capabilities; 247 info->qc_channel_size = (uint64_t)size; 248 info->qc_chan_num = (uint64_t)channel->ic_chan_num; 249 if (channel->ic_ver == IOAT_CBv1) { 250 info->qc_dca_supported = B_FALSE; 251 } else { 252 if (info->qc_capabilities & IOAT_DMACAP_DCA) { 253 info->qc_dca_supported = B_TRUE; 254 } else { 255 info->qc_dca_supported = B_FALSE; 256 } 257 } 258 259 *chan = channel; 260 261 return (DCOPY_SUCCESS); 262 263 chinitfail_kmem_cache: 264 ioat_completion_free(channel); 265 chinitfail_completion_alloc: 266 ioat_ring_free(channel); 267 chinitfail_desc_alloc: 268 return (DCOPY_FAILURE); 269 } 270 271 272 /* 273 * ioat_channel_suspend() 274 */ 275 /*ARGSUSED*/ 276 void 277 ioat_channel_suspend(ioat_state_t *state) 278 { 279 /* 280 * normally you would disable interrupts and reset the H/W here. But 281 * since the suspend framework doesn't know who is using us, it may 282 * not suspend their I/O before us. Since we won't actively be doing 283 * any DMA or interrupts unless someone asks us to, it's safe to not 284 * do anything here. 285 */ 286 } 287 288 289 /* 290 * ioat_channel_resume() 291 */ 292 int 293 ioat_channel_resume(ioat_state_t *state) 294 { 295 ioat_channel_ring_t *ring; 296 ioat_channel_t channel; 297 uint32_t estat; 298 int i; 299 300 301 for (i = 0; i < state->is_num_channels; i++) { 302 channel = &state->is_channel[i]; 303 ring = channel->ic_ring; 304 305 if (!channel->ic_inuse) { 306 continue; 307 } 308 309 /* 310 * Configure DMA channel 311 * Channel In Use 312 * Error Interrupt Enable 313 * Any Error Abort Enable 314 * Error Completion Enable 315 */ 316 ddi_put16(state->is_reg_handle, 317 (uint16_t *)&channel->ic_regs[IOAT_CHAN_CTL], 0x011C); 318 319 /* check channel error register, clear any errors */ 320 estat = ddi_get32(state->is_reg_handle, 321 (uint32_t *)&channel->ic_regs[IOAT_CHAN_ERR]); 322 if (estat != 0) { 323 #ifdef DEBUG 324 cmn_err(CE_CONT, "cleared errors (0x%x) before channel" 325 " (%d) enable\n", estat, channel->ic_chan_num); 326 #endif 327 ddi_put32(state->is_reg_handle, 328 (uint32_t *)&channel->ic_regs[IOAT_CHAN_ERR], 329 estat); 330 } 331 332 /* Re-initialize the ring */ 333 bzero(ring->cr_desc, channel->ic_desc_alloc_size); 334 /* write the physical address into the chain address register */ 335 if (channel->ic_ver == IOAT_CBv1) { 336 ddi_put32(state->is_reg_handle, 337 (uint32_t *)&channel->ic_regs[IOAT_V1_CHAN_ADDR_LO], 338 (uint32_t)(ring->cr_phys_desc & 0xffffffff)); 339 ddi_put32(state->is_reg_handle, 340 (uint32_t *)&channel->ic_regs[IOAT_V1_CHAN_ADDR_HI], 341 (uint32_t)(ring->cr_phys_desc >> 32)); 342 } else { 343 ASSERT(channel->ic_ver == IOAT_CBv2); 344 ddi_put32(state->is_reg_handle, 345 (uint32_t *)&channel->ic_regs[IOAT_V2_CHAN_ADDR_LO], 346 (uint32_t)(ring->cr_phys_desc & 0xffffffff)); 347 ddi_put32(state->is_reg_handle, 348 (uint32_t *)&channel->ic_regs[IOAT_V2_CHAN_ADDR_HI], 349 (uint32_t)(ring->cr_phys_desc >> 32)); 350 } 351 352 /* re-initialize the completion buffer */ 353 bzero((void *)channel->ic_cmpl, channel->ic_cmpl_alloc_size); 354 /* write the phys addr into the completion address register */ 355 ddi_put32(state->is_reg_handle, 356 (uint32_t *)&channel->ic_regs[IOAT_CHAN_CMPL_LO], 357 (uint32_t)(channel->ic_phys_cmpl & 0xffffffff)); 358 ddi_put32(state->is_reg_handle, 359 (uint32_t *)&channel->ic_regs[IOAT_CHAN_CMPL_HI], 360 (uint32_t)(channel->ic_phys_cmpl >> 32)); 361 362 /* start-up the channel */ 363 ioat_channel_start(channel); 364 365 } 366 367 return (DDI_SUCCESS); 368 } 369 370 /* 371 * quiesce(9E) entry point. 372 * 373 * This function is called when the system is single-threaded at high 374 * PIL with preemption disabled. Therefore, this function must not be 375 * blocked. 376 * 377 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 378 * DDI_FAILURE indicates an error condition and should almost never happen. 379 */ 380 void 381 ioat_channel_quiesce(ioat_state_t *state) 382 { 383 int i; 384 385 /* 386 * Walk through all channels and quiesce 387 */ 388 for (i = 0; i < state->is_num_channels; i++) { 389 390 ioat_channel_t channel = state->is_channel + i; 391 392 if (!channel->ic_inuse) 393 continue; 394 395 /* disable the interrupts */ 396 ddi_put16(state->is_reg_handle, 397 (uint16_t *)&channel->ic_regs[IOAT_CHAN_CTL], 398 0x0); 399 400 ioat_channel_reset(channel); 401 } 402 } 403 404 405 /* 406 * ioat_channel_free() 407 */ 408 void 409 ioat_channel_free(void *channel_private) 410 { 411 struct ioat_channel_s *channel; 412 ioat_channel_t *chan; 413 ioat_state_t *state; 414 uint_t chan_num; 415 416 417 chan = (ioat_channel_t *)channel_private; 418 channel = *chan; 419 420 state = channel->ic_state; 421 chan_num = channel->ic_chan_num; 422 423 /* disable the interrupts */ 424 ddi_put16(state->is_reg_handle, 425 (uint16_t *)&channel->ic_regs[IOAT_CHAN_CTL], 0x0); 426 427 ioat_channel_reset(channel); 428 429 /* cleanup command cache */ 430 kmem_cache_destroy(channel->ic_cmd_cache); 431 432 /* clean-up/free-up the completion space and descriptors */ 433 ioat_completion_free(channel); 434 ioat_ring_free(channel); 435 436 channel->ic_inuse = B_FALSE; 437 438 /* free the H/W DMA engine */ 439 ioat_rs_free(state->is_channel_rs, chan_num); 440 441 *chan = NULL; 442 } 443 444 445 /* 446 * ioat_channel_intr() 447 */ 448 void 449 ioat_channel_intr(ioat_channel_t channel) 450 { 451 ioat_state_t *state; 452 uint16_t chanctrl; 453 uint32_t chanerr; 454 uint32_t status; 455 456 457 state = channel->ic_state; 458 459 if (channel->ic_ver == IOAT_CBv1) { 460 status = ddi_get32(state->is_reg_handle, 461 (uint32_t *)&channel->ic_regs[IOAT_V1_CHAN_STS_LO]); 462 } else { 463 ASSERT(channel->ic_ver == IOAT_CBv2); 464 status = ddi_get32(state->is_reg_handle, 465 (uint32_t *)&channel->ic_regs[IOAT_V2_CHAN_STS_LO]); 466 } 467 468 /* if that status isn't ACTIVE or IDLE, the channel has failed */ 469 if (status & IOAT_CHAN_STS_FAIL_MASK) { 470 chanerr = ddi_get32(state->is_reg_handle, 471 (uint32_t *)&channel->ic_regs[IOAT_CHAN_ERR]); 472 cmn_err(CE_WARN, "channel(%d) fatal failure! " 473 "chanstat_lo=0x%X; chanerr=0x%X\n", 474 channel->ic_chan_num, status, chanerr); 475 channel->ic_channel_state = IOAT_CHANNEL_IN_FAILURE; 476 ioat_channel_reset(channel); 477 478 return; 479 } 480 481 /* 482 * clear interrupt disable bit if set (it's a RW1C). Read it back to 483 * ensure the write completes. 484 */ 485 chanctrl = ddi_get16(state->is_reg_handle, 486 (uint16_t *)&channel->ic_regs[IOAT_CHAN_CTL]); 487 ddi_put16(state->is_reg_handle, 488 (uint16_t *)&channel->ic_regs[IOAT_CHAN_CTL], chanctrl); 489 (void) ddi_get16(state->is_reg_handle, 490 (uint16_t *)&channel->ic_regs[IOAT_CHAN_CTL]); 491 492 /* tell dcopy we have seen a completion on this channel */ 493 dcopy_device_channel_notify(channel->ic_dcopy_handle, DCOPY_COMPLETION); 494 } 495 496 497 /* 498 * ioat_channel_start() 499 */ 500 void 501 ioat_channel_start(ioat_channel_t channel) 502 { 503 ioat_chan_dma_desc_t desc; 504 505 /* set the first descriptor up as a NULL descriptor */ 506 bzero(&desc, sizeof (desc)); 507 desc.dd_size = 0; 508 desc.dd_ctrl = IOAT_DESC_CTRL_OP_DMA | IOAT_DESC_DMACTRL_NULL | 509 IOAT_DESC_CTRL_CMPL; 510 desc.dd_next_desc = 0x0; 511 512 /* setup the very first descriptor */ 513 ioat_ring_seed(channel, &desc); 514 } 515 516 517 /* 518 * ioat_channel_reset() 519 */ 520 void 521 ioat_channel_reset(ioat_channel_t channel) 522 { 523 ioat_state_t *state; 524 525 state = channel->ic_state; 526 527 /* hit the reset bit */ 528 if (channel->ic_ver == IOAT_CBv1) { 529 ddi_put8(state->is_reg_handle, 530 &channel->ic_regs[IOAT_V1_CHAN_CMD], 0x20); 531 } else { 532 ASSERT(channel->ic_ver == IOAT_CBv2); 533 ddi_put8(state->is_reg_handle, 534 &channel->ic_regs[IOAT_V2_CHAN_CMD], 0x20); 535 } 536 } 537 538 539 /* 540 * ioat_completion_alloc() 541 */ 542 int 543 ioat_completion_alloc(ioat_channel_t channel) 544 { 545 ioat_state_t *state; 546 size_t real_length; 547 uint_t cookie_cnt; 548 int e; 549 550 551 state = channel->ic_state; 552 553 /* 554 * allocate memory for the completion status, zero it out, and get 555 * the paddr. We'll allocate a physically contiguous cache line. 556 */ 557 e = ddi_dma_alloc_handle(state->is_dip, &ioat_cmpl_dma_attr, 558 DDI_DMA_SLEEP, NULL, &channel->ic_cmpl_dma_handle); 559 if (e != DDI_SUCCESS) { 560 goto cmplallocfail_alloc_handle; 561 } 562 channel->ic_cmpl_alloc_size = 64; 563 e = ddi_dma_mem_alloc(channel->ic_cmpl_dma_handle, 564 channel->ic_cmpl_alloc_size, &ioat_acc_attr, 565 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 566 (caddr_t *)&channel->ic_cmpl, &real_length, 567 &channel->ic_cmpl_handle); 568 if (e != DDI_SUCCESS) { 569 goto cmplallocfail_mem_alloc; 570 } 571 bzero((void *)channel->ic_cmpl, channel->ic_cmpl_alloc_size); 572 e = ddi_dma_addr_bind_handle(channel->ic_cmpl_dma_handle, NULL, 573 (caddr_t)channel->ic_cmpl, channel->ic_cmpl_alloc_size, 574 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 575 &channel->ic_cmpl_cookie, &cookie_cnt); 576 if (e != DDI_SUCCESS) { 577 goto cmplallocfail_addr_bind; 578 } 579 ASSERT(cookie_cnt == 1); 580 ASSERT(channel->ic_cmpl_cookie.dmac_size == 581 channel->ic_cmpl_alloc_size); 582 channel->ic_phys_cmpl = channel->ic_cmpl_cookie.dmac_laddress; 583 584 /* write the physical address into the completion address register */ 585 ddi_put32(state->is_reg_handle, 586 (uint32_t *)&channel->ic_regs[IOAT_CHAN_CMPL_LO], 587 (uint32_t)(channel->ic_phys_cmpl & 0xffffffff)); 588 ddi_put32(state->is_reg_handle, 589 (uint32_t *)&channel->ic_regs[IOAT_CHAN_CMPL_HI], 590 (uint32_t)(channel->ic_phys_cmpl >> 32)); 591 592 return (DDI_SUCCESS); 593 594 cmplallocfail_addr_bind: 595 ddi_dma_mem_free(&channel->ic_desc_handle); 596 cmplallocfail_mem_alloc: 597 ddi_dma_free_handle(&channel->ic_desc_dma_handle); 598 cmplallocfail_alloc_handle: 599 return (DDI_FAILURE); 600 } 601 602 603 /* 604 * ioat_completion_free() 605 */ 606 void 607 ioat_completion_free(ioat_channel_t channel) 608 { 609 ioat_state_t *state; 610 611 state = channel->ic_state; 612 613 /* reset the completion address register */ 614 ddi_put32(state->is_reg_handle, 615 (uint32_t *)&channel->ic_regs[IOAT_CHAN_CMPL_LO], 0x0); 616 ddi_put32(state->is_reg_handle, 617 (uint32_t *)&channel->ic_regs[IOAT_CHAN_CMPL_HI], 0x0); 618 619 /* unbind, then free up the memory, dma handle */ 620 (void) ddi_dma_unbind_handle(channel->ic_cmpl_dma_handle); 621 ddi_dma_mem_free(&channel->ic_cmpl_handle); 622 ddi_dma_free_handle(&channel->ic_cmpl_dma_handle); 623 } 624 625 /* 626 * ioat_ring_alloc() 627 */ 628 int 629 ioat_ring_alloc(ioat_channel_t channel, uint_t desc_cnt) 630 { 631 ioat_channel_ring_t *ring; 632 ioat_state_t *state; 633 size_t real_length; 634 uint_t cookie_cnt; 635 int e; 636 637 638 state = channel->ic_state; 639 640 ring = kmem_zalloc(sizeof (ioat_channel_ring_t), KM_SLEEP); 641 channel->ic_ring = ring; 642 ring->cr_chan = channel; 643 ring->cr_post_cnt = 0; 644 645 mutex_init(&ring->cr_cmpl_mutex, NULL, MUTEX_DRIVER, 646 channel->ic_state->is_iblock_cookie); 647 mutex_init(&ring->cr_desc_mutex, NULL, MUTEX_DRIVER, 648 channel->ic_state->is_iblock_cookie); 649 650 /* 651 * allocate memory for the ring, zero it out, and get the paddr. 652 * We'll allocate a physically contiguous chunck of memory which 653 * simplifies the completion logic. 654 */ 655 e = ddi_dma_alloc_handle(state->is_dip, &ioat_desc_dma_attr, 656 DDI_DMA_SLEEP, NULL, &channel->ic_desc_dma_handle); 657 if (e != DDI_SUCCESS) { 658 goto ringallocfail_alloc_handle; 659 } 660 /* 661 * allocate one extra descriptor so we can simplify the empty/full 662 * logic. Then round that number up to a whole multiple of 4. 663 */ 664 channel->ic_chan_desc_cnt = ((desc_cnt + 1) + 3) & ~0x3; 665 ring->cr_desc_last = channel->ic_chan_desc_cnt - 1; 666 channel->ic_desc_alloc_size = channel->ic_chan_desc_cnt * 667 sizeof (ioat_chan_desc_t); 668 e = ddi_dma_mem_alloc(channel->ic_desc_dma_handle, 669 channel->ic_desc_alloc_size, &ioat_acc_attr, 670 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 671 (caddr_t *)&ring->cr_desc, &real_length, &channel->ic_desc_handle); 672 if (e != DDI_SUCCESS) { 673 goto ringallocfail_mem_alloc; 674 } 675 bzero(ring->cr_desc, channel->ic_desc_alloc_size); 676 e = ddi_dma_addr_bind_handle(channel->ic_desc_dma_handle, NULL, 677 (caddr_t)ring->cr_desc, channel->ic_desc_alloc_size, 678 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 679 &channel->ic_desc_cookies, &cookie_cnt); 680 if (e != DDI_SUCCESS) { 681 goto ringallocfail_addr_bind; 682 } 683 ASSERT(cookie_cnt == 1); 684 ASSERT(channel->ic_desc_cookies.dmac_size == 685 channel->ic_desc_alloc_size); 686 ring->cr_phys_desc = channel->ic_desc_cookies.dmac_laddress; 687 688 /* write the physical address into the chain address register */ 689 if (channel->ic_ver == IOAT_CBv1) { 690 ddi_put32(state->is_reg_handle, 691 (uint32_t *)&channel->ic_regs[IOAT_V1_CHAN_ADDR_LO], 692 (uint32_t)(ring->cr_phys_desc & 0xffffffff)); 693 ddi_put32(state->is_reg_handle, 694 (uint32_t *)&channel->ic_regs[IOAT_V1_CHAN_ADDR_HI], 695 (uint32_t)(ring->cr_phys_desc >> 32)); 696 } else { 697 ASSERT(channel->ic_ver == IOAT_CBv2); 698 ddi_put32(state->is_reg_handle, 699 (uint32_t *)&channel->ic_regs[IOAT_V2_CHAN_ADDR_LO], 700 (uint32_t)(ring->cr_phys_desc & 0xffffffff)); 701 ddi_put32(state->is_reg_handle, 702 (uint32_t *)&channel->ic_regs[IOAT_V2_CHAN_ADDR_HI], 703 (uint32_t)(ring->cr_phys_desc >> 32)); 704 } 705 706 return (DCOPY_SUCCESS); 707 708 ringallocfail_addr_bind: 709 ddi_dma_mem_free(&channel->ic_desc_handle); 710 ringallocfail_mem_alloc: 711 ddi_dma_free_handle(&channel->ic_desc_dma_handle); 712 ringallocfail_alloc_handle: 713 mutex_destroy(&ring->cr_desc_mutex); 714 mutex_destroy(&ring->cr_cmpl_mutex); 715 kmem_free(channel->ic_ring, sizeof (ioat_channel_ring_t)); 716 717 return (DCOPY_FAILURE); 718 } 719 720 721 /* 722 * ioat_ring_free() 723 */ 724 void 725 ioat_ring_free(ioat_channel_t channel) 726 { 727 ioat_state_t *state; 728 729 730 state = channel->ic_state; 731 732 /* reset the chain address register */ 733 if (channel->ic_ver == IOAT_CBv1) { 734 ddi_put32(state->is_reg_handle, 735 (uint32_t *)&channel->ic_regs[IOAT_V1_CHAN_ADDR_LO], 0x0); 736 ddi_put32(state->is_reg_handle, 737 (uint32_t *)&channel->ic_regs[IOAT_V1_CHAN_ADDR_HI], 0x0); 738 } else { 739 ASSERT(channel->ic_ver == IOAT_CBv2); 740 ddi_put32(state->is_reg_handle, 741 (uint32_t *)&channel->ic_regs[IOAT_V2_CHAN_ADDR_LO], 0x0); 742 ddi_put32(state->is_reg_handle, 743 (uint32_t *)&channel->ic_regs[IOAT_V2_CHAN_ADDR_HI], 0x0); 744 } 745 746 /* unbind, then free up the memory, dma handle */ 747 (void) ddi_dma_unbind_handle(channel->ic_desc_dma_handle); 748 ddi_dma_mem_free(&channel->ic_desc_handle); 749 ddi_dma_free_handle(&channel->ic_desc_dma_handle); 750 751 mutex_destroy(&channel->ic_ring->cr_desc_mutex); 752 mutex_destroy(&channel->ic_ring->cr_cmpl_mutex); 753 kmem_free(channel->ic_ring, sizeof (ioat_channel_ring_t)); 754 755 } 756 757 758 /* 759 * ioat_ring_seed() 760 * write the first descriptor in the ring. 761 */ 762 void 763 ioat_ring_seed(ioat_channel_t channel, ioat_chan_dma_desc_t *in_desc) 764 { 765 ioat_channel_ring_t *ring; 766 ioat_chan_dma_desc_t *desc; 767 ioat_chan_dma_desc_t *prev; 768 ioat_state_t *state; 769 770 771 state = channel->ic_state; 772 ring = channel->ic_ring; 773 774 /* init the completion state */ 775 ring->cr_cmpl_gen = 0x0; 776 ring->cr_cmpl_last = 0x0; 777 778 /* write in the descriptor and init the descriptor state */ 779 ring->cr_post_cnt++; 780 channel->ic_ring->cr_desc[0] = *(ioat_chan_desc_t *)in_desc; 781 ring->cr_desc_gen = 0; 782 ring->cr_desc_prev = 0; 783 ring->cr_desc_next = 1; 784 785 if (channel->ic_ver == IOAT_CBv1) { 786 /* hit the start bit */ 787 ddi_put8(state->is_reg_handle, 788 &channel->ic_regs[IOAT_V1_CHAN_CMD], 0x1); 789 } else { 790 /* 791 * if this is CBv2, link the descriptor to an empty 792 * descriptor 793 */ 794 ASSERT(ring->cr_chan->ic_ver == IOAT_CBv2); 795 desc = (ioat_chan_dma_desc_t *) 796 &ring->cr_desc[ring->cr_desc_next]; 797 prev = (ioat_chan_dma_desc_t *) 798 &ring->cr_desc[ring->cr_desc_prev]; 799 800 desc->dd_ctrl = 0; 801 desc->dd_next_desc = 0x0; 802 803 prev->dd_next_desc = ring->cr_phys_desc + 804 (ring->cr_desc_next << 6); 805 806 ddi_put16(state->is_reg_handle, 807 (uint16_t *)&channel->ic_regs[IOAT_V2_CHAN_CNT], 808 (uint16_t)1); 809 } 810 811 } 812 813 /* 814 * ioat_ring_loop() 815 * Make the ring loop for CB v1 816 * This function assume we are in the ring->cr_desc_mutex mutex context 817 */ 818 int 819 ioat_ring_loop(ioat_channel_ring_t *ring, dcopy_cmd_t cmd) 820 { 821 uint64_t count; 822 ioat_channel_t channel; 823 ioat_chan_dma_desc_t *curr; 824 ioat_cmd_private_t *prevpriv; 825 ioat_cmd_private_t *currpriv; 826 827 currpriv = NULL; 828 channel = ring->cr_chan; 829 ASSERT(channel->ic_ver == IOAT_CBv1); 830 831 /* 832 * For each cmd in the command queue, check whether they are continuous 833 * in descriptor ring. Return error if not continuous. 834 */ 835 for (count = 0, prevpriv = NULL; 836 cmd != NULL && count <= channel->ic_chan_desc_cnt; 837 prevpriv = currpriv) { 838 currpriv = cmd->dp_private->pr_device_cmd_private; 839 if (prevpriv != NULL && 840 currpriv->ip_index + 1 != prevpriv->ip_start && 841 currpriv->ip_index + 1 != prevpriv->ip_start + 842 channel->ic_chan_desc_cnt) { 843 /* Non-continuous, other commands get interleaved */ 844 return (DCOPY_FAILURE); 845 } 846 if (currpriv->ip_index < currpriv->ip_start) { 847 count += channel->ic_chan_desc_cnt 848 + currpriv->ip_index - currpriv->ip_start + 1; 849 } else { 850 count += currpriv->ip_index - currpriv->ip_start + 1; 851 } 852 cmd = currpriv->ip_next; 853 } 854 /* 855 * Check for too many descriptors which would cause wrap around in 856 * descriptor ring. And make sure there is space for cancel operation. 857 */ 858 if (count >= channel->ic_chan_desc_cnt) { 859 return (DCOPY_FAILURE); 860 } 861 862 /* Point next descriptor to header of chain. */ 863 curr = (ioat_chan_dma_desc_t *)&ring->cr_desc[ring->cr_desc_prev]; 864 curr->dd_next_desc = ring->cr_phys_desc + (currpriv->ip_start << 6); 865 866 /* sync the last desc */ 867 (void) ddi_dma_sync(channel->ic_desc_dma_handle, 868 ring->cr_desc_prev << 6, 64, DDI_DMA_SYNC_FORDEV); 869 870 return (DCOPY_SUCCESS); 871 } 872 873 874 /* 875 * ioat_cmd_alloc() 876 */ 877 int 878 ioat_cmd_alloc(void *private, int flags, dcopy_cmd_t *cmd) 879 { 880 ioat_cmd_private_t *priv; 881 ioat_channel_t channel; 882 dcopy_cmd_t oldcmd; 883 int kmflag; 884 885 886 channel = (ioat_channel_t)private; 887 888 if (flags & DCOPY_NOSLEEP) { 889 kmflag = KM_NOSLEEP; 890 } else { 891 kmflag = KM_SLEEP; 892 } 893 894 /* save the command passed incase DCOPY_ALLOC_LINK is set */ 895 oldcmd = *cmd; 896 897 *cmd = kmem_cache_alloc(channel->ic_cmd_cache, kmflag); 898 if (*cmd == NULL) { 899 return (DCOPY_NORESOURCES); 900 } 901 902 /* setup the dcopy and ioat private state pointers */ 903 (*cmd)->dp_version = DCOPY_CMD_V0; 904 (*cmd)->dp_cmd = 0; 905 (*cmd)->dp_private = (struct dcopy_cmd_priv_s *) 906 ((uintptr_t)(*cmd) + sizeof (struct dcopy_cmd_s)); 907 (*cmd)->dp_private->pr_device_cmd_private = 908 (struct ioat_cmd_private_s *)((uintptr_t)(*cmd)->dp_private + 909 sizeof (struct dcopy_cmd_priv_s)); 910 911 /* 912 * if DCOPY_ALLOC_LINK is set, link the old command to the new one 913 * just allocated. 914 */ 915 priv = (*cmd)->dp_private->pr_device_cmd_private; 916 if (flags & DCOPY_ALLOC_LINK) { 917 priv->ip_next = oldcmd; 918 } else { 919 priv->ip_next = NULL; 920 } 921 922 return (DCOPY_SUCCESS); 923 } 924 925 926 /* 927 * ioat_cmd_free() 928 */ 929 void 930 ioat_cmd_free(void *private, dcopy_cmd_t *cmdp) 931 { 932 ioat_cmd_private_t *priv; 933 ioat_channel_t channel; 934 dcopy_cmd_t next; 935 dcopy_cmd_t cmd; 936 937 938 channel = (ioat_channel_t)private; 939 cmd = *(cmdp); 940 941 /* 942 * free all the commands in the chain (see DCOPY_ALLOC_LINK in 943 * ioat_cmd_alloc() for more info). 944 */ 945 while (cmd != NULL) { 946 priv = cmd->dp_private->pr_device_cmd_private; 947 next = priv->ip_next; 948 kmem_cache_free(channel->ic_cmd_cache, cmd); 949 cmd = next; 950 } 951 *cmdp = NULL; 952 } 953 954 955 /* 956 * ioat_cmd_post() 957 */ 958 int 959 ioat_cmd_post(void *private, dcopy_cmd_t cmd) 960 { 961 ioat_channel_ring_t *ring; 962 ioat_cmd_private_t *priv; 963 ioat_channel_t channel; 964 ioat_state_t *state; 965 uint64_t dest_paddr; 966 uint64_t src_paddr; 967 uint64_t dest_addr; 968 uint32_t dest_size; 969 uint64_t src_addr; 970 uint32_t src_size; 971 size_t xfer_size; 972 uint32_t ctrl; 973 size_t size; 974 int e; 975 976 977 channel = (ioat_channel_t)private; 978 priv = cmd->dp_private->pr_device_cmd_private; 979 980 state = channel->ic_state; 981 ring = channel->ic_ring; 982 983 /* 984 * Special support for DCOPY_CMD_LOOP option, only supported on CBv1. 985 * DCOPY_CMD_QUEUE should also be set if DCOPY_CMD_LOOP is set. 986 */ 987 if ((cmd->dp_flags & DCOPY_CMD_LOOP) && 988 (channel->ic_ver != IOAT_CBv1 || 989 (cmd->dp_flags & DCOPY_CMD_QUEUE))) { 990 return (DCOPY_FAILURE); 991 } 992 993 if ((cmd->dp_flags & DCOPY_CMD_NOWAIT) == 0) { 994 mutex_enter(&ring->cr_desc_mutex); 995 996 /* 997 * Try to acquire mutex if NOWAIT flag is set. 998 * Return failure if failed to acquire mutex. 999 */ 1000 } else if (mutex_tryenter(&ring->cr_desc_mutex) == 0) { 1001 return (DCOPY_FAILURE); 1002 } 1003 1004 /* if the channel has had a fatal failure, return failure */ 1005 if (channel->ic_channel_state == IOAT_CHANNEL_IN_FAILURE) { 1006 mutex_exit(&ring->cr_desc_mutex); 1007 return (DCOPY_FAILURE); 1008 } 1009 1010 /* make sure we have space for the descriptors */ 1011 e = ioat_ring_reserve(channel, ring, cmd); 1012 if (e != DCOPY_SUCCESS) { 1013 mutex_exit(&ring->cr_desc_mutex); 1014 return (DCOPY_NORESOURCES); 1015 } 1016 1017 /* if we support DCA, and the DCA flag is set, post a DCA desc */ 1018 if ((channel->ic_ver == IOAT_CBv2) && 1019 (cmd->dp_flags & DCOPY_CMD_DCA)) { 1020 ioat_cmd_post_dca(ring, cmd->dp_dca_id); 1021 } 1022 1023 /* 1024 * the dma copy may have to be broken up into multiple descriptors 1025 * since we can't cross a page boundary. 1026 */ 1027 ASSERT(cmd->dp_version == DCOPY_CMD_V0); 1028 ASSERT(cmd->dp_cmd == DCOPY_CMD_COPY); 1029 src_addr = cmd->dp.copy.cc_source; 1030 dest_addr = cmd->dp.copy.cc_dest; 1031 size = cmd->dp.copy.cc_size; 1032 priv->ip_start = ring->cr_desc_next; 1033 while (size > 0) { 1034 src_paddr = pa_to_ma(src_addr); 1035 dest_paddr = pa_to_ma(dest_addr); 1036 1037 /* adjust for any offset into the page */ 1038 if ((src_addr & PAGEOFFSET) == 0) { 1039 src_size = PAGESIZE; 1040 } else { 1041 src_size = PAGESIZE - (src_addr & PAGEOFFSET); 1042 } 1043 if ((dest_addr & PAGEOFFSET) == 0) { 1044 dest_size = PAGESIZE; 1045 } else { 1046 dest_size = PAGESIZE - (dest_addr & PAGEOFFSET); 1047 } 1048 1049 /* take the smallest of the three */ 1050 xfer_size = MIN(src_size, dest_size); 1051 xfer_size = MIN(xfer_size, size); 1052 1053 /* 1054 * if this is the last descriptor, and we are supposed to 1055 * generate a completion, generate a completion. same logic 1056 * for interrupt. 1057 */ 1058 ctrl = 0; 1059 if (cmd->dp_flags & DCOPY_CMD_NOSRCSNP) { 1060 ctrl |= IOAT_DESC_CTRL_NOSRCSNP; 1061 } 1062 if (cmd->dp_flags & DCOPY_CMD_NODSTSNP) { 1063 ctrl |= IOAT_DESC_CTRL_NODSTSNP; 1064 } 1065 if (xfer_size == size) { 1066 if (!(cmd->dp_flags & DCOPY_CMD_NOSTAT)) { 1067 ctrl |= IOAT_DESC_CTRL_CMPL; 1068 } 1069 if ((cmd->dp_flags & DCOPY_CMD_INTR)) { 1070 ctrl |= IOAT_DESC_CTRL_INTR; 1071 } 1072 } 1073 1074 ioat_cmd_post_copy(ring, src_paddr, dest_paddr, xfer_size, 1075 ctrl); 1076 1077 /* go to the next page */ 1078 src_addr += xfer_size; 1079 dest_addr += xfer_size; 1080 size -= xfer_size; 1081 } 1082 1083 /* save away the state so we can poll on it. */ 1084 priv->ip_generation = ring->cr_desc_gen_prev; 1085 priv->ip_index = ring->cr_desc_prev; 1086 1087 /* if queue not defined, tell the DMA engine about it */ 1088 if (!(cmd->dp_flags & DCOPY_CMD_QUEUE)) { 1089 /* 1090 * Link the ring to a loop (currently only for FIPE). 1091 */ 1092 if (cmd->dp_flags & DCOPY_CMD_LOOP) { 1093 e = ioat_ring_loop(ring, cmd); 1094 if (e != DCOPY_SUCCESS) { 1095 mutex_exit(&ring->cr_desc_mutex); 1096 return (DCOPY_FAILURE); 1097 } 1098 } 1099 1100 if (channel->ic_ver == IOAT_CBv1) { 1101 ddi_put8(state->is_reg_handle, 1102 (uint8_t *)&channel->ic_regs[IOAT_V1_CHAN_CMD], 1103 0x2); 1104 } else { 1105 ASSERT(channel->ic_ver == IOAT_CBv2); 1106 ddi_put16(state->is_reg_handle, 1107 (uint16_t *)&channel->ic_regs[IOAT_V2_CHAN_CNT], 1108 (uint16_t)(ring->cr_post_cnt & 0xFFFF)); 1109 } 1110 } 1111 1112 mutex_exit(&ring->cr_desc_mutex); 1113 1114 return (DCOPY_SUCCESS); 1115 } 1116 1117 1118 /* 1119 * ioat_cmd_post_dca() 1120 */ 1121 static void 1122 ioat_cmd_post_dca(ioat_channel_ring_t *ring, uint32_t dca_id) 1123 { 1124 ioat_chan_dca_desc_t *saved_prev; 1125 ioat_chan_dca_desc_t *desc; 1126 ioat_chan_dca_desc_t *prev; 1127 ioat_channel_t channel; 1128 uint64_t next_desc_phys; 1129 off_t prev_offset; 1130 off_t next_offset; 1131 1132 1133 channel = ring->cr_chan; 1134 desc = (ioat_chan_dca_desc_t *)&ring->cr_desc[ring->cr_desc_next]; 1135 prev = (ioat_chan_dca_desc_t *)&ring->cr_desc[ring->cr_desc_prev]; 1136 1137 /* keep track of the number of descs posted for cbv2 */ 1138 ring->cr_post_cnt++; 1139 1140 /* 1141 * post a context change desriptor. If dca has never been used on 1142 * this channel, or if the id doesn't match the last id used on this 1143 * channel, set CONTEXT_CHANGE bit and dca id, set dca state to active, 1144 * and save away the id we're using. 1145 */ 1146 desc->dd_ctrl = IOAT_DESC_CTRL_OP_CNTX; 1147 desc->dd_next_desc = 0x0; 1148 if (!channel->ic_dca_active || (channel->ic_dca_current != dca_id)) { 1149 channel->ic_dca_active = B_TRUE; 1150 channel->ic_dca_current = dca_id; 1151 desc->dd_ctrl |= IOAT_DESC_CTRL_CNTX_CHNG; 1152 desc->dd_cntx = dca_id; 1153 } 1154 1155 /* 1156 * save next desc and prev offset for when we link the two 1157 * descriptors together. 1158 */ 1159 saved_prev = prev; 1160 prev_offset = ring->cr_desc_prev << 6; 1161 next_offset = ring->cr_desc_next << 6; 1162 next_desc_phys = ring->cr_phys_desc + next_offset; 1163 1164 /* save the current desc_next and desc_last for the completion */ 1165 ring->cr_desc_prev = ring->cr_desc_next; 1166 ring->cr_desc_gen_prev = ring->cr_desc_gen; 1167 1168 /* increment next/gen so it points to the next free desc */ 1169 ring->cr_desc_next++; 1170 if (ring->cr_desc_next > ring->cr_desc_last) { 1171 ring->cr_desc_next = 0; 1172 ring->cr_desc_gen++; 1173 } 1174 1175 /* 1176 * if this is CBv2, link the descriptor to an empty descriptor. Since 1177 * we always leave on desc empty to detect full, this works out. 1178 */ 1179 if (ring->cr_chan->ic_ver == IOAT_CBv2) { 1180 desc = (ioat_chan_dca_desc_t *) 1181 &ring->cr_desc[ring->cr_desc_next]; 1182 prev = (ioat_chan_dca_desc_t *) 1183 &ring->cr_desc[ring->cr_desc_prev]; 1184 desc->dd_ctrl = 0; 1185 desc->dd_next_desc = 0x0; 1186 (void) ddi_dma_sync(channel->ic_desc_dma_handle, 1187 ring->cr_desc_next << 6, 64, DDI_DMA_SYNC_FORDEV); 1188 prev->dd_next_desc = ring->cr_phys_desc + 1189 (ring->cr_desc_next << 6); 1190 } 1191 1192 /* Put the descriptors physical address in the previous descriptor */ 1193 /*LINTED:E_TRUE_LOGICAL_EXPR*/ 1194 ASSERT(sizeof (ioat_chan_dca_desc_t) == 64); 1195 1196 /* sync the current desc */ 1197 (void) ddi_dma_sync(channel->ic_desc_dma_handle, next_offset, 64, 1198 DDI_DMA_SYNC_FORDEV); 1199 1200 /* update the previous desc and sync it too */ 1201 saved_prev->dd_next_desc = next_desc_phys; 1202 (void) ddi_dma_sync(channel->ic_desc_dma_handle, prev_offset, 64, 1203 DDI_DMA_SYNC_FORDEV); 1204 } 1205 1206 1207 /* 1208 * ioat_cmd_post_copy() 1209 * 1210 */ 1211 static void 1212 ioat_cmd_post_copy(ioat_channel_ring_t *ring, uint64_t src_addr, 1213 uint64_t dest_addr, uint32_t size, uint32_t ctrl) 1214 { 1215 ioat_chan_dma_desc_t *saved_prev; 1216 ioat_chan_dma_desc_t *desc; 1217 ioat_chan_dma_desc_t *prev; 1218 ioat_channel_t channel; 1219 uint64_t next_desc_phy; 1220 off_t prev_offset; 1221 off_t next_offset; 1222 1223 1224 channel = ring->cr_chan; 1225 desc = (ioat_chan_dma_desc_t *)&ring->cr_desc[ring->cr_desc_next]; 1226 prev = (ioat_chan_dma_desc_t *)&ring->cr_desc[ring->cr_desc_prev]; 1227 1228 /* keep track of the number of descs posted for cbv2 */ 1229 ring->cr_post_cnt++; 1230 1231 /* write in the DMA desc */ 1232 desc->dd_ctrl = IOAT_DESC_CTRL_OP_DMA | ctrl; 1233 desc->dd_size = size; 1234 desc->dd_src_paddr = src_addr; 1235 desc->dd_dest_paddr = dest_addr; 1236 desc->dd_next_desc = 0x0; 1237 1238 /* 1239 * save next desc and prev offset for when we link the two 1240 * descriptors together. 1241 */ 1242 saved_prev = prev; 1243 prev_offset = ring->cr_desc_prev << 6; 1244 next_offset = ring->cr_desc_next << 6; 1245 next_desc_phy = ring->cr_phys_desc + next_offset; 1246 1247 /* increment next/gen so it points to the next free desc */ 1248 ring->cr_desc_prev = ring->cr_desc_next; 1249 ring->cr_desc_gen_prev = ring->cr_desc_gen; 1250 1251 /* increment next/gen so it points to the next free desc */ 1252 ring->cr_desc_next++; 1253 if (ring->cr_desc_next > ring->cr_desc_last) { 1254 ring->cr_desc_next = 0; 1255 ring->cr_desc_gen++; 1256 } 1257 1258 /* 1259 * if this is CBv2, link the descriptor to an empty descriptor. Since 1260 * we always leave on desc empty to detect full, this works out. 1261 */ 1262 if (ring->cr_chan->ic_ver == IOAT_CBv2) { 1263 desc = (ioat_chan_dma_desc_t *) 1264 &ring->cr_desc[ring->cr_desc_next]; 1265 prev = (ioat_chan_dma_desc_t *) 1266 &ring->cr_desc[ring->cr_desc_prev]; 1267 desc->dd_size = 0; 1268 desc->dd_ctrl = 0; 1269 desc->dd_next_desc = 0x0; 1270 (void) ddi_dma_sync(channel->ic_desc_dma_handle, 1271 ring->cr_desc_next << 6, 64, DDI_DMA_SYNC_FORDEV); 1272 prev->dd_next_desc = ring->cr_phys_desc + 1273 (ring->cr_desc_next << 6); 1274 } 1275 1276 /* Put the descriptors physical address in the previous descriptor */ 1277 /*LINTED:E_TRUE_LOGICAL_EXPR*/ 1278 ASSERT(sizeof (ioat_chan_dma_desc_t) == 64); 1279 1280 /* sync the current desc */ 1281 (void) ddi_dma_sync(channel->ic_desc_dma_handle, next_offset, 64, 1282 DDI_DMA_SYNC_FORDEV); 1283 1284 /* update the previous desc and sync it too */ 1285 saved_prev->dd_next_desc = next_desc_phy; 1286 (void) ddi_dma_sync(channel->ic_desc_dma_handle, prev_offset, 64, 1287 DDI_DMA_SYNC_FORDEV); 1288 } 1289 1290 1291 /* 1292 * ioat_cmd_poll() 1293 */ 1294 int 1295 ioat_cmd_poll(void *private, dcopy_cmd_t cmd) 1296 { 1297 ioat_channel_ring_t *ring; 1298 ioat_cmd_private_t *priv; 1299 ioat_channel_t channel; 1300 uint64_t generation; 1301 uint64_t last_cmpl; 1302 1303 ASSERT(cmd != NULL); 1304 channel = (ioat_channel_t)private; 1305 priv = cmd->dp_private->pr_device_cmd_private; 1306 1307 ring = channel->ic_ring; 1308 ASSERT(ring != NULL); 1309 1310 if ((cmd->dp_flags & DCOPY_CMD_NOWAIT) == 0) { 1311 mutex_enter(&ring->cr_cmpl_mutex); 1312 1313 /* 1314 * Try to acquire mutex if NOWAIT flag is set. 1315 * Return failure if failed to acquire mutex. 1316 */ 1317 } else if (mutex_tryenter(&ring->cr_cmpl_mutex) == 0) { 1318 return (DCOPY_FAILURE); 1319 } 1320 1321 /* if the channel had a fatal failure, fail all polls */ 1322 if ((channel->ic_channel_state == IOAT_CHANNEL_IN_FAILURE) || 1323 IOAT_CMPL_FAILED(channel)) { 1324 mutex_exit(&ring->cr_cmpl_mutex); 1325 return (DCOPY_FAILURE); 1326 } 1327 1328 /* 1329 * if the current completion is the same as the last time we read one, 1330 * post is still pending, nothing further to do. We track completions 1331 * as indexes into the ring since post uses VAs and the H/W returns 1332 * PAs. We grab a snapshot of generation and last_cmpl in the mutex. 1333 */ 1334 (void) ddi_dma_sync(channel->ic_cmpl_dma_handle, 0, 0, 1335 DDI_DMA_SYNC_FORCPU); 1336 last_cmpl = IOAT_CMPL_INDEX(channel); 1337 if (last_cmpl != ring->cr_cmpl_last) { 1338 /* 1339 * if we wrapped the ring, increment the generation. Store 1340 * the last cmpl. This logic assumes a physically contiguous 1341 * ring. 1342 */ 1343 if (last_cmpl < ring->cr_cmpl_last) { 1344 ring->cr_cmpl_gen++; 1345 } 1346 ring->cr_cmpl_last = last_cmpl; 1347 generation = ring->cr_cmpl_gen; 1348 1349 } else { 1350 generation = ring->cr_cmpl_gen; 1351 } 1352 1353 mutex_exit(&ring->cr_cmpl_mutex); 1354 1355 /* 1356 * if cmd isn't passed in, well return. Useful for updating the 1357 * consumer pointer (ring->cr_cmpl_last). 1358 */ 1359 if (cmd->dp_flags & DCOPY_CMD_SYNC) { 1360 return (DCOPY_PENDING); 1361 } 1362 1363 /* 1364 * if the post's generation is old, this post has completed. No reason 1365 * to go check the last completion. if the generation is the same 1366 * and if the post is before or = to the last completion processed, 1367 * the post has completed. 1368 */ 1369 if (priv->ip_generation < generation) { 1370 return (DCOPY_COMPLETED); 1371 } else if ((priv->ip_generation == generation) && 1372 (priv->ip_index <= last_cmpl)) { 1373 return (DCOPY_COMPLETED); 1374 } 1375 1376 return (DCOPY_PENDING); 1377 } 1378 1379 1380 /* 1381 * ioat_ring_reserve() 1382 */ 1383 int 1384 ioat_ring_reserve(ioat_channel_t channel, ioat_channel_ring_t *ring, 1385 dcopy_cmd_t cmd) 1386 { 1387 uint64_t dest_addr; 1388 uint32_t dest_size; 1389 uint64_t src_addr; 1390 uint32_t src_size; 1391 size_t xfer_size; 1392 uint64_t desc; 1393 int num_desc; 1394 size_t size; 1395 int i; 1396 1397 1398 /* 1399 * figure out how many descriptors we need. This can include a dca 1400 * desc and multiple desc for a dma copy. 1401 */ 1402 num_desc = 0; 1403 if ((channel->ic_ver == IOAT_CBv2) && 1404 (cmd->dp_flags & DCOPY_CMD_DCA)) { 1405 num_desc++; 1406 } 1407 src_addr = cmd->dp.copy.cc_source; 1408 dest_addr = cmd->dp.copy.cc_dest; 1409 size = cmd->dp.copy.cc_size; 1410 while (size > 0) { 1411 num_desc++; 1412 1413 /* adjust for any offset into the page */ 1414 if ((src_addr & PAGEOFFSET) == 0) { 1415 src_size = PAGESIZE; 1416 } else { 1417 src_size = PAGESIZE - (src_addr & PAGEOFFSET); 1418 } 1419 if ((dest_addr & PAGEOFFSET) == 0) { 1420 dest_size = PAGESIZE; 1421 } else { 1422 dest_size = PAGESIZE - (dest_addr & PAGEOFFSET); 1423 } 1424 1425 /* take the smallest of the three */ 1426 xfer_size = MIN(src_size, dest_size); 1427 xfer_size = MIN(xfer_size, size); 1428 1429 /* go to the next page */ 1430 src_addr += xfer_size; 1431 dest_addr += xfer_size; 1432 size -= xfer_size; 1433 } 1434 1435 /* Make sure we have space for these descriptors */ 1436 desc = ring->cr_desc_next; 1437 for (i = 0; i < num_desc; i++) { 1438 1439 /* 1440 * if this is the last descriptor in the ring, see if the 1441 * last completed descriptor is #0. 1442 */ 1443 if (desc == ring->cr_desc_last) { 1444 if (ring->cr_cmpl_last == 0) { 1445 /* 1446 * if we think the ring is full, update where 1447 * the H/W really is and check for full again. 1448 */ 1449 cmd->dp_flags |= DCOPY_CMD_SYNC; 1450 (void) ioat_cmd_poll(channel, cmd); 1451 cmd->dp_flags &= ~DCOPY_CMD_SYNC; 1452 if (ring->cr_cmpl_last == 0) { 1453 return (DCOPY_NORESOURCES); 1454 } 1455 } 1456 1457 /* 1458 * go to the next descriptor which is zero in this 1459 * case. 1460 */ 1461 desc = 0; 1462 1463 /* 1464 * if this is not the last descriptor in the ring, see if 1465 * the last completion we saw was the next descriptor. 1466 */ 1467 } else { 1468 if ((desc + 1) == ring->cr_cmpl_last) { 1469 /* 1470 * if we think the ring is full, update where 1471 * the H/W really is and check for full again. 1472 */ 1473 cmd->dp_flags |= DCOPY_CMD_SYNC; 1474 (void) ioat_cmd_poll(channel, cmd); 1475 cmd->dp_flags &= ~DCOPY_CMD_SYNC; 1476 if ((desc + 1) == ring->cr_cmpl_last) { 1477 return (DCOPY_NORESOURCES); 1478 } 1479 } 1480 1481 /* go to the next descriptor */ 1482 desc++; 1483 } 1484 } 1485 1486 return (DCOPY_SUCCESS); 1487 } 1488