17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 54ab75253Smrj * Common Development and Distribution License (the "License"). 64ab75253Smrj * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 214ab75253Smrj 227c478bd9Sstevel@tonic-gate /* 2332141dfcSNikko He * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <sys/scsi/scsi.h> 287c478bd9Sstevel@tonic-gate #include <sys/vtrace.h> 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #define A_TO_TRAN(ap) ((ap)->a_hba_tran) 327c478bd9Sstevel@tonic-gate #define P_TO_TRAN(pkt) ((pkt)->pkt_address.a_hba_tran) 337c478bd9Sstevel@tonic-gate #define P_TO_ADDR(pkt) (&((pkt)->pkt_address)) 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate /* 367c478bd9Sstevel@tonic-gate * Callback id 377c478bd9Sstevel@tonic-gate */ 387c478bd9Sstevel@tonic-gate uintptr_t scsi_callback_id = 0; 397c478bd9Sstevel@tonic-gate 404ab75253Smrj extern ddi_dma_attr_t scsi_alloc_attr; 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate struct buf * 437c478bd9Sstevel@tonic-gate scsi_alloc_consistent_buf(struct scsi_address *ap, 447c478bd9Sstevel@tonic-gate struct buf *in_bp, size_t datalen, uint_t bflags, 457c478bd9Sstevel@tonic-gate int (*callback)(caddr_t), caddr_t callback_arg) 467c478bd9Sstevel@tonic-gate { 477c478bd9Sstevel@tonic-gate dev_info_t *pdip; 487c478bd9Sstevel@tonic-gate struct buf *bp; 497c478bd9Sstevel@tonic-gate int kmflag; 504ab75253Smrj size_t rlen; 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate TRACE_0(TR_FAC_SCSI_RES, TR_SCSI_ALLOC_CONSISTENT_BUF_START, 53c6c44d06Sjw "scsi_alloc_consistent_buf_start"); 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate if (!in_bp) { 567c478bd9Sstevel@tonic-gate kmflag = (callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP; 577c478bd9Sstevel@tonic-gate if ((bp = getrbuf(kmflag)) == NULL) { 587c478bd9Sstevel@tonic-gate goto no_resource; 597c478bd9Sstevel@tonic-gate } 607c478bd9Sstevel@tonic-gate } else { 617c478bd9Sstevel@tonic-gate bp = in_bp; 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate /* we are establishing a new buffer memory association */ 647c478bd9Sstevel@tonic-gate bp->b_flags &= ~(B_PAGEIO | B_PHYS | B_REMAPPED | B_SHADOW); 657c478bd9Sstevel@tonic-gate bp->b_proc = NULL; 667c478bd9Sstevel@tonic-gate bp->b_pages = NULL; 677c478bd9Sstevel@tonic-gate bp->b_shadow = NULL; 687c478bd9Sstevel@tonic-gate } 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate /* limit bits that can be set by bflags argument */ 717c478bd9Sstevel@tonic-gate ASSERT(!(bflags & ~(B_READ | B_WRITE))); 727c478bd9Sstevel@tonic-gate bflags &= (B_READ | B_WRITE); 737c478bd9Sstevel@tonic-gate bp->b_un.b_addr = 0; 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate if (datalen) { 767c478bd9Sstevel@tonic-gate pdip = (A_TO_TRAN(ap))->tran_hba_dip; 777c478bd9Sstevel@tonic-gate 784ab75253Smrj /* 794ab75253Smrj * use i_ddi_mem_alloc() for now until we have an interface to 804ab75253Smrj * allocate memory for DMA which doesn't require a DMA handle. 814ab75253Smrj * ddi_iopb_alloc() is obsolete and we want more flexibility in 824ab75253Smrj * controlling the DMA address constraints. 834ab75253Smrj */ 844ab75253Smrj while (i_ddi_mem_alloc(pdip, &scsi_alloc_attr, datalen, 854ab75253Smrj ((callback == SLEEP_FUNC) ? 1 : 0), 0, NULL, 864ab75253Smrj &bp->b_un.b_addr, &rlen, NULL) != DDI_SUCCESS) { 877c478bd9Sstevel@tonic-gate if (callback == SLEEP_FUNC) { 887c478bd9Sstevel@tonic-gate delay(drv_usectohz(10000)); 897c478bd9Sstevel@tonic-gate } else { 907c478bd9Sstevel@tonic-gate if (!in_bp) 917c478bd9Sstevel@tonic-gate freerbuf(bp); 927c478bd9Sstevel@tonic-gate goto no_resource; 937c478bd9Sstevel@tonic-gate } 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate bp->b_flags |= bflags; 967c478bd9Sstevel@tonic-gate } 977c478bd9Sstevel@tonic-gate bp->b_bcount = datalen; 987c478bd9Sstevel@tonic-gate bp->b_resid = 0; 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate TRACE_0(TR_FAC_SCSI_RES, TR_SCSI_ALLOC_CONSISTENT_BUF_END, 101c6c44d06Sjw "scsi_alloc_consistent_buf_end"); 1027c478bd9Sstevel@tonic-gate return (bp); 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate no_resource: 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate if (callback != NULL_FUNC && callback != SLEEP_FUNC) { 1077c478bd9Sstevel@tonic-gate ddi_set_callback(callback, callback_arg, 108c6c44d06Sjw &scsi_callback_id); 1097c478bd9Sstevel@tonic-gate } 1107c478bd9Sstevel@tonic-gate TRACE_0(TR_FAC_SCSI_RES, 1117c478bd9Sstevel@tonic-gate TR_SCSI_ALLOC_CONSISTENT_BUF_RETURN1_END, 1127c478bd9Sstevel@tonic-gate "scsi_alloc_consistent_buf_end (return1)"); 1137c478bd9Sstevel@tonic-gate return (NULL); 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate void 1177c478bd9Sstevel@tonic-gate scsi_free_consistent_buf(struct buf *bp) 1187c478bd9Sstevel@tonic-gate { 1197c478bd9Sstevel@tonic-gate TRACE_0(TR_FAC_SCSI_RES, TR_SCSI_FREE_CONSISTENT_BUF_START, 120c6c44d06Sjw "scsi_free_consistent_buf_start"); 1217c478bd9Sstevel@tonic-gate if (!bp) 1227c478bd9Sstevel@tonic-gate return; 1237c478bd9Sstevel@tonic-gate if (bp->b_un.b_addr) 1247b93957cSeota i_ddi_mem_free((caddr_t)bp->b_un.b_addr, NULL); 1257c478bd9Sstevel@tonic-gate freerbuf(bp); 1267c478bd9Sstevel@tonic-gate if (scsi_callback_id != 0) { 1277c478bd9Sstevel@tonic-gate ddi_run_callback(&scsi_callback_id); 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate TRACE_0(TR_FAC_SCSI_RES, TR_SCSI_FREE_CONSISTENT_BUF_END, 130c6c44d06Sjw "scsi_free_consistent_buf_end"); 1317c478bd9Sstevel@tonic-gate } 1327c478bd9Sstevel@tonic-gate 1338faf39b2Staylor void 1348faf39b2Staylor scsi_dmafree_attr(struct scsi_pkt *pktp) 1358faf39b2Staylor { 1368faf39b2Staylor struct scsi_pkt_cache_wrapper *pktw = 137c6c44d06Sjw (struct scsi_pkt_cache_wrapper *)pktp; 1388faf39b2Staylor 1398faf39b2Staylor if (pktw->pcw_flags & PCW_BOUND) { 1408faf39b2Staylor if (ddi_dma_unbind_handle(pktp->pkt_handle) != 1418faf39b2Staylor DDI_SUCCESS) 1428faf39b2Staylor cmn_err(CE_WARN, "scsi_dmafree_attr: " 1438faf39b2Staylor "unbind handle failed"); 1448faf39b2Staylor pktw->pcw_flags &= ~PCW_BOUND; 1458faf39b2Staylor } 1468faf39b2Staylor pktp->pkt_numcookies = 0; 14732141dfcSNikko He pktw->pcw_totalwin = 0; 1488faf39b2Staylor } 1498faf39b2Staylor 1508faf39b2Staylor struct buf * 1518faf39b2Staylor scsi_pkt2bp(struct scsi_pkt *pkt) 1528faf39b2Staylor { 1538faf39b2Staylor return (((struct scsi_pkt_cache_wrapper *)pkt)->pcw_bp); 1548faf39b2Staylor } 1558faf39b2Staylor 1568faf39b2Staylor int 1578faf39b2Staylor scsi_dma_buf_bind_attr(struct scsi_pkt_cache_wrapper *pktw, 1588faf39b2Staylor struct buf *bp, 1598faf39b2Staylor int dma_flags, 1608faf39b2Staylor int (*callback)(), 1618faf39b2Staylor caddr_t arg) 1628faf39b2Staylor { 1638faf39b2Staylor struct scsi_pkt *pktp = &(pktw->pcw_pkt); 1648faf39b2Staylor int status; 1658faf39b2Staylor 1668faf39b2Staylor /* 1678faf39b2Staylor * First time, need to establish the handle. 1688faf39b2Staylor */ 1698faf39b2Staylor 1708faf39b2Staylor ASSERT(pktp->pkt_numcookies == 0); 1718faf39b2Staylor ASSERT(pktw->pcw_totalwin == 0); 1728faf39b2Staylor 1738faf39b2Staylor status = ddi_dma_buf_bind_handle(pktp->pkt_handle, bp, dma_flags, 174c6c44d06Sjw callback, arg, &pktw->pcw_cookie, 175c6c44d06Sjw &pktp->pkt_numcookies); 1768faf39b2Staylor 1778faf39b2Staylor switch (status) { 1788faf39b2Staylor case DDI_DMA_MAPPED: 1798faf39b2Staylor pktw->pcw_totalwin = 1; 1808faf39b2Staylor break; 1818faf39b2Staylor 1828faf39b2Staylor case DDI_DMA_PARTIAL_MAP: 1838faf39b2Staylor /* enable first call to ddi_dma_getwin */ 1848faf39b2Staylor if (ddi_dma_numwin(pktp->pkt_handle, 1858faf39b2Staylor &pktw->pcw_totalwin) != DDI_SUCCESS) { 1868faf39b2Staylor bp->b_error = 0; 1878faf39b2Staylor return (0); 1888faf39b2Staylor } 1898faf39b2Staylor break; 1908faf39b2Staylor 1918faf39b2Staylor case DDI_DMA_NORESOURCES: 1928faf39b2Staylor bp->b_error = 0; 1938faf39b2Staylor return (0); 1948faf39b2Staylor 1958faf39b2Staylor case DDI_DMA_TOOBIG: 1968faf39b2Staylor bioerror(bp, EINVAL); 1978faf39b2Staylor return (0); 1988faf39b2Staylor 1998faf39b2Staylor case DDI_DMA_NOMAPPING: 2008faf39b2Staylor case DDI_DMA_INUSE: 2018faf39b2Staylor default: 2028faf39b2Staylor bioerror(bp, EFAULT); 2038faf39b2Staylor return (0); 2048faf39b2Staylor } 2058faf39b2Staylor 2068faf39b2Staylor /* initialize the loop controls for scsi_dmaget_attr() */ 2078faf39b2Staylor pktw->pcw_curwin = 0; 2088faf39b2Staylor pktw->pcw_total_xfer = 0; 2098faf39b2Staylor pktp->pkt_dma_flags = dma_flags; 2108faf39b2Staylor return (1); 2118faf39b2Staylor } 2128faf39b2Staylor 2138faf39b2Staylor #if defined(_DMA_USES_PHYSADDR) 2148faf39b2Staylor int 2158faf39b2Staylor scsi_dmaget_attr(struct scsi_pkt_cache_wrapper *pktw) 2168faf39b2Staylor { 2178faf39b2Staylor struct scsi_pkt *pktp = &(pktw->pcw_pkt); 2188faf39b2Staylor 2198faf39b2Staylor int status; 2208faf39b2Staylor int num_segs = 0; 2218faf39b2Staylor ddi_dma_impl_t *hp = (ddi_dma_impl_t *)pktp->pkt_handle; 2228faf39b2Staylor ddi_dma_cookie_t *cp; 2238faf39b2Staylor 2248faf39b2Staylor if (pktw->pcw_curwin != 0) { 2258faf39b2Staylor ddi_dma_cookie_t cookie; 2268faf39b2Staylor 2278faf39b2Staylor /* 2288faf39b2Staylor * start the next window, and get its first cookie 2298faf39b2Staylor */ 2308faf39b2Staylor status = ddi_dma_getwin(pktp->pkt_handle, 231c6c44d06Sjw pktw->pcw_curwin, &pktp->pkt_dma_offset, 232c6c44d06Sjw &pktp->pkt_dma_len, &cookie, 233c6c44d06Sjw &pktp->pkt_numcookies); 2348faf39b2Staylor if (status != DDI_SUCCESS) 2358faf39b2Staylor return (0); 2368faf39b2Staylor } 2378faf39b2Staylor 2388faf39b2Staylor /* 2398faf39b2Staylor * start the Scatter/Gather loop 2408faf39b2Staylor */ 2418faf39b2Staylor cp = hp->dmai_cookie - 1; 2428faf39b2Staylor pktp->pkt_dma_len = 0; 2438faf39b2Staylor for (;;) { 2448faf39b2Staylor 2458faf39b2Staylor /* take care of the loop-bookkeeping */ 2468faf39b2Staylor pktp->pkt_dma_len += cp->dmac_size; 2478faf39b2Staylor num_segs++; 2488faf39b2Staylor /* 2498faf39b2Staylor * if this was the last cookie in the current window 2508faf39b2Staylor * set the loop controls start the next window and 2518faf39b2Staylor * exit so the HBA can do this partial transfer 2528faf39b2Staylor */ 2538faf39b2Staylor if (num_segs >= pktp->pkt_numcookies) { 2548faf39b2Staylor pktw->pcw_curwin++; 2558faf39b2Staylor break; 2568faf39b2Staylor } 2578faf39b2Staylor 2588faf39b2Staylor cp++; 2598faf39b2Staylor } 2608faf39b2Staylor pktw->pcw_total_xfer += pktp->pkt_dma_len; 2618faf39b2Staylor pktp->pkt_cookies = hp->dmai_cookie - 1; 2628faf39b2Staylor hp->dmai_cookie = cp; 2638faf39b2Staylor 2648faf39b2Staylor return (1); 2658faf39b2Staylor } 2668faf39b2Staylor #endif 2678faf39b2Staylor 268cab28b2dStaylor void scsi_free_cache_pkt(struct scsi_address *, struct scsi_pkt *); 269cab28b2dStaylor 270cab28b2dStaylor struct scsi_pkt * 271cab28b2dStaylor scsi_init_cache_pkt(struct scsi_address *ap, struct scsi_pkt *in_pktp, 272cab28b2dStaylor struct buf *bp, int cmdlen, int statuslen, int pplen, 273cab28b2dStaylor int flags, int (*callback)(caddr_t), caddr_t callback_arg) 274cab28b2dStaylor { 275cab28b2dStaylor struct scsi_pkt_cache_wrapper *pktw; 276cab28b2dStaylor scsi_hba_tran_t *tranp = ap->a_hba_tran; 277cab28b2dStaylor int (*func)(caddr_t); 278cab28b2dStaylor 279cab28b2dStaylor func = (callback == SLEEP_FUNC) ? SLEEP_FUNC : NULL_FUNC; 280cab28b2dStaylor 281cab28b2dStaylor if (in_pktp == NULL) { 282cab28b2dStaylor int kf; 283cab28b2dStaylor 284cab28b2dStaylor if (callback == SLEEP_FUNC) 285cab28b2dStaylor kf = KM_SLEEP; 286cab28b2dStaylor else 287cab28b2dStaylor kf = KM_NOSLEEP; 288*66027529SNikko He /* 289*66027529SNikko He * By using kmem_cache_alloc(), the layout of the 290*66027529SNikko He * scsi_pkt, scsi_pkt_cache_wrapper, hba private data, 291*66027529SNikko He * cdb, tgt driver private data, and status block is 292*66027529SNikko He * as below. 293*66027529SNikko He * 294*66027529SNikko He * This is a piece of contiguous memory starting from 295*66027529SNikko He * the first structure field scsi_pkt in the struct 296*66027529SNikko He * scsi_pkt_cache_wrapper, followed by the hba private 297*66027529SNikko He * data, pkt_cdbp, the tgt driver private data and 298*66027529SNikko He * pkt_scbp. 299*66027529SNikko He * 300*66027529SNikko He * |----------------------------|---------------------> 301*66027529SNikko He * | struct scsi_pkt | struct 302*66027529SNikko He * | ...... |scsi_pkt_cache_wrapper 303*66027529SNikko He * | pcw_flags | 304*66027529SNikko He * |----------------------------|<--------------------- 305*66027529SNikko He * | hba private data |tranp->tran_hba_len 306*66027529SNikko He * |----------------------------| 307*66027529SNikko He * | pkt_cdbp |DEFAULT_CDBLEN 308*66027529SNikko He * |----------------------------| 309*66027529SNikko He * | tgt private data |DEFAULT_PRIVLEN 310*66027529SNikko He * |----------------------------| 311*66027529SNikko He * | pkt_scbp |DEFAULT_SCBLEN 312*66027529SNikko He * |----------------------------| 313*66027529SNikko He * 314*66027529SNikko He * If the actual data length of the cdb, or the tgt 315*66027529SNikko He * driver private data, or the status block is bigger 316*66027529SNikko He * than the default data length, kmem_alloc() will be 317*66027529SNikko He * called to get extra space. 318*66027529SNikko He */ 319cab28b2dStaylor pktw = kmem_cache_alloc(tranp->tran_pkt_cache_ptr, 320c6c44d06Sjw kf); 321cab28b2dStaylor if (pktw == NULL) 322cab28b2dStaylor goto fail1; 323cab28b2dStaylor 3248faf39b2Staylor pktw->pcw_flags = 0; 325cab28b2dStaylor in_pktp = &(pktw->pcw_pkt); 3268faf39b2Staylor in_pktp->pkt_address = *ap; 327cab28b2dStaylor /* 328830363f4Staylor * target drivers should initialize pkt_comp and 329830363f4Staylor * pkt_time, but sometimes they don't so initialize 330830363f4Staylor * them here to be safe. 331cab28b2dStaylor */ 332cab28b2dStaylor in_pktp->pkt_address = *ap; 333830363f4Staylor in_pktp->pkt_flags = 0; 334830363f4Staylor in_pktp->pkt_time = 0; 335cab28b2dStaylor in_pktp->pkt_resid = 0; 336cab28b2dStaylor in_pktp->pkt_state = 0; 337cab28b2dStaylor in_pktp->pkt_statistics = 0; 338cab28b2dStaylor in_pktp->pkt_reason = 0; 3398faf39b2Staylor in_pktp->pkt_dma_offset = 0; 3408faf39b2Staylor in_pktp->pkt_dma_len = 0; 3418faf39b2Staylor in_pktp->pkt_dma_flags = 0; 342602ca9eaScth in_pktp->pkt_path_instance = 0; 3438faf39b2Staylor ASSERT(in_pktp->pkt_numcookies == 0); 3448faf39b2Staylor pktw->pcw_curwin = 0; 3458faf39b2Staylor pktw->pcw_totalwin = 0; 3468faf39b2Staylor pktw->pcw_total_xfer = 0; 347cab28b2dStaylor 348cab28b2dStaylor in_pktp->pkt_cdblen = cmdlen; 349cab28b2dStaylor if ((tranp->tran_hba_flags & SCSI_HBA_TRAN_CDB) && 350cab28b2dStaylor (cmdlen > DEFAULT_CDBLEN)) { 3518faf39b2Staylor pktw->pcw_flags |= PCW_NEED_EXT_CDB; 352830363f4Staylor in_pktp->pkt_cdbp = kmem_alloc(cmdlen, kf); 353cab28b2dStaylor if (in_pktp->pkt_cdbp == NULL) 354cab28b2dStaylor goto fail2; 355cab28b2dStaylor } 356cab28b2dStaylor in_pktp->pkt_tgtlen = pplen; 357cab28b2dStaylor if (pplen > DEFAULT_PRIVLEN) { 3588faf39b2Staylor pktw->pcw_flags |= PCW_NEED_EXT_TGT; 359830363f4Staylor in_pktp->pkt_private = kmem_alloc(pplen, kf); 360cab28b2dStaylor if (in_pktp->pkt_private == NULL) 361cab28b2dStaylor goto fail3; 362cab28b2dStaylor } 363cab28b2dStaylor in_pktp->pkt_scblen = statuslen; 364cab28b2dStaylor if ((tranp->tran_hba_flags & SCSI_HBA_TRAN_SCB) && 365cab28b2dStaylor (statuslen > DEFAULT_SCBLEN)) { 3668faf39b2Staylor pktw->pcw_flags |= PCW_NEED_EXT_SCB; 367830363f4Staylor in_pktp->pkt_scbp = kmem_alloc(statuslen, kf); 368cab28b2dStaylor if (in_pktp->pkt_scbp == NULL) 369cab28b2dStaylor goto fail4; 370cab28b2dStaylor } 371cab28b2dStaylor if ((*tranp->tran_setup_pkt) (in_pktp, 372c6c44d06Sjw func, NULL) == -1) { 373cab28b2dStaylor goto fail5; 374cab28b2dStaylor } 375830363f4Staylor if (cmdlen) 376830363f4Staylor bzero((void *)in_pktp->pkt_cdbp, cmdlen); 377830363f4Staylor if (pplen) 378830363f4Staylor bzero((void *)in_pktp->pkt_private, pplen); 379830363f4Staylor if (statuslen) 380830363f4Staylor bzero((void *)in_pktp->pkt_scbp, statuslen); 3818faf39b2Staylor } else 3828faf39b2Staylor pktw = (struct scsi_pkt_cache_wrapper *)in_pktp; 3838faf39b2Staylor 384cab28b2dStaylor if (bp && bp->b_bcount) { 3858faf39b2Staylor 3868faf39b2Staylor int dma_flags = 0; 3878faf39b2Staylor 3888faf39b2Staylor /* 3898faf39b2Staylor * we need to transfer data, so we alloc dma resources 3908faf39b2Staylor * for this packet 3918faf39b2Staylor */ 3928faf39b2Staylor /*CONSTCOND*/ 3938faf39b2Staylor ASSERT(SLEEP_FUNC == DDI_DMA_SLEEP); 3948faf39b2Staylor /*CONSTCOND*/ 3958faf39b2Staylor ASSERT(NULL_FUNC == DDI_DMA_DONTWAIT); 3968faf39b2Staylor 3978faf39b2Staylor #if defined(_DMA_USES_PHYSADDR) 3988faf39b2Staylor /* 3998faf39b2Staylor * with an IOMMU we map everything, so we don't 4008faf39b2Staylor * need to bother with this 4018faf39b2Staylor */ 4028faf39b2Staylor if (tranp->tran_dma_attr.dma_attr_granular != 403c6c44d06Sjw pktw->pcw_granular) { 4048faf39b2Staylor 4058faf39b2Staylor ddi_dma_free_handle(&in_pktp->pkt_handle); 4068faf39b2Staylor if (ddi_dma_alloc_handle(tranp->tran_hba_dip, 407c6c44d06Sjw &tranp->tran_dma_attr, 408c6c44d06Sjw func, NULL, 409c6c44d06Sjw &in_pktp->pkt_handle) != DDI_SUCCESS) { 4108faf39b2Staylor 4118faf39b2Staylor in_pktp->pkt_handle = NULL; 4128faf39b2Staylor return (NULL); 4138faf39b2Staylor } 4148faf39b2Staylor pktw->pcw_granular = 415c6c44d06Sjw tranp->tran_dma_attr.dma_attr_granular; 416cab28b2dStaylor } 4178faf39b2Staylor #endif 4188faf39b2Staylor 4198faf39b2Staylor if (in_pktp->pkt_numcookies == 0) { 4208faf39b2Staylor pktw->pcw_bp = bp; 4218faf39b2Staylor /* 4228faf39b2Staylor * set dma flags; the "read" case must be first 4238faf39b2Staylor * since B_WRITE isn't always be set for writes. 4248faf39b2Staylor */ 4258faf39b2Staylor if (bp->b_flags & B_READ) { 4268faf39b2Staylor dma_flags |= DDI_DMA_READ; 4278faf39b2Staylor } else { 4288faf39b2Staylor dma_flags |= DDI_DMA_WRITE; 4298faf39b2Staylor } 4308faf39b2Staylor if (flags & PKT_CONSISTENT) 4318faf39b2Staylor dma_flags |= DDI_DMA_CONSISTENT; 4328faf39b2Staylor if (flags & PKT_DMA_PARTIAL) 4338faf39b2Staylor dma_flags |= DDI_DMA_PARTIAL; 4348faf39b2Staylor 4358faf39b2Staylor #if defined(__sparc) 4368faf39b2Staylor /* 4378faf39b2Staylor * workaround for byte hole issue on psycho and 4388faf39b2Staylor * schizo pre 2.1 4398faf39b2Staylor */ 4408faf39b2Staylor if ((bp->b_flags & B_READ) && ((bp->b_flags & 4418faf39b2Staylor (B_PAGEIO|B_REMAPPED)) != B_PAGEIO) && 4428faf39b2Staylor (((uintptr_t)bp->b_un.b_addr & 0x7) || 4438faf39b2Staylor ((uintptr_t)bp->b_bcount & 0x7))) { 4448faf39b2Staylor dma_flags |= DDI_DMA_CONSISTENT; 4458faf39b2Staylor } 4468faf39b2Staylor #endif 4478faf39b2Staylor if (!scsi_dma_buf_bind_attr(pktw, bp, 4488faf39b2Staylor dma_flags, callback, callback_arg)) { 4498faf39b2Staylor return (NULL); 4508faf39b2Staylor } else { 4518faf39b2Staylor pktw->pcw_flags |= PCW_BOUND; 4528faf39b2Staylor } 4538faf39b2Staylor } 4548faf39b2Staylor 4558faf39b2Staylor #if defined(_DMA_USES_PHYSADDR) 4568faf39b2Staylor if (!scsi_dmaget_attr(pktw)) { 4578faf39b2Staylor scsi_dmafree_attr(in_pktp); 4588faf39b2Staylor goto fail5; 4598faf39b2Staylor } 4608faf39b2Staylor #else 4618faf39b2Staylor in_pktp->pkt_cookies = &pktw->pcw_cookie; 4628faf39b2Staylor in_pktp->pkt_dma_len = pktw->pcw_cookie.dmac_size; 4638faf39b2Staylor pktw->pcw_total_xfer += in_pktp->pkt_dma_len; 4648faf39b2Staylor #endif 4658faf39b2Staylor ASSERT(in_pktp->pkt_numcookies <= 466c6c44d06Sjw tranp->tran_dma_attr.dma_attr_sgllen); 4678faf39b2Staylor ASSERT(pktw->pcw_total_xfer <= bp->b_bcount); 4688faf39b2Staylor in_pktp->pkt_resid = bp->b_bcount - 469c6c44d06Sjw pktw->pcw_total_xfer; 4708faf39b2Staylor 4718faf39b2Staylor ASSERT((in_pktp->pkt_resid % pktw->pcw_granular) == 472c6c44d06Sjw 0); 4738faf39b2Staylor } else { 4748faf39b2Staylor /* !bp or no b_bcount */ 4758faf39b2Staylor in_pktp->pkt_resid = 0; 476cab28b2dStaylor } 477cab28b2dStaylor return (in_pktp); 478cab28b2dStaylor 479cab28b2dStaylor fail5: 4808faf39b2Staylor if (pktw->pcw_flags & PCW_NEED_EXT_SCB) { 481cab28b2dStaylor kmem_free(in_pktp->pkt_scbp, statuslen); 482cab28b2dStaylor in_pktp->pkt_scbp = (opaque_t)((char *)in_pktp + 483cab28b2dStaylor tranp->tran_hba_len + DEFAULT_PRIVLEN + 484*66027529SNikko He sizeof (struct scsi_pkt_cache_wrapper)); 485cab28b2dStaylor if ((A_TO_TRAN(ap))->tran_hba_flags & SCSI_HBA_TRAN_CDB) 486cab28b2dStaylor in_pktp->pkt_scbp = (opaque_t)((in_pktp->pkt_scbp) + 487c6c44d06Sjw DEFAULT_CDBLEN); 488cab28b2dStaylor in_pktp->pkt_scblen = 0; 489cab28b2dStaylor } 490cab28b2dStaylor fail4: 4918faf39b2Staylor if (pktw->pcw_flags & PCW_NEED_EXT_TGT) { 492cab28b2dStaylor kmem_free(in_pktp->pkt_private, pplen); 493cab28b2dStaylor in_pktp->pkt_tgtlen = 0; 494cab28b2dStaylor in_pktp->pkt_private = NULL; 495cab28b2dStaylor } 496cab28b2dStaylor fail3: 4978faf39b2Staylor if (pktw->pcw_flags & PCW_NEED_EXT_CDB) { 498cab28b2dStaylor kmem_free(in_pktp->pkt_cdbp, cmdlen); 499cab28b2dStaylor in_pktp->pkt_cdbp = (opaque_t)((char *)in_pktp + 500cab28b2dStaylor tranp->tran_hba_len + 501*66027529SNikko He sizeof (struct scsi_pkt_cache_wrapper)); 502cab28b2dStaylor in_pktp->pkt_cdblen = 0; 503cab28b2dStaylor } 5048faf39b2Staylor pktw->pcw_flags &= 5058faf39b2Staylor ~(PCW_NEED_EXT_CDB|PCW_NEED_EXT_TGT|PCW_NEED_EXT_SCB); 506cab28b2dStaylor fail2: 507cab28b2dStaylor kmem_cache_free(tranp->tran_pkt_cache_ptr, pktw); 508cab28b2dStaylor fail1: 509cab28b2dStaylor if (callback != NULL_FUNC && callback != SLEEP_FUNC) { 510cab28b2dStaylor ddi_set_callback(callback, callback_arg, 511c6c44d06Sjw &scsi_callback_id); 512cab28b2dStaylor } 513cab28b2dStaylor 514cab28b2dStaylor return (NULL); 515cab28b2dStaylor } 516cab28b2dStaylor 517cab28b2dStaylor void 518cab28b2dStaylor scsi_free_cache_pkt(struct scsi_address *ap, struct scsi_pkt *pktp) 519cab28b2dStaylor { 520cab28b2dStaylor struct scsi_pkt_cache_wrapper *pktw; 521cab28b2dStaylor 522cab28b2dStaylor (*A_TO_TRAN(ap)->tran_teardown_pkt)(pktp); 523cab28b2dStaylor pktw = (struct scsi_pkt_cache_wrapper *)pktp; 5248faf39b2Staylor if (pktw->pcw_flags & PCW_BOUND) 5258faf39b2Staylor scsi_dmafree_attr(pktp); 526cab28b2dStaylor 527cab28b2dStaylor /* 528cab28b2dStaylor * if we allocated memory for anything that wouldn't fit, free 529cab28b2dStaylor * the memory and restore the pointers 530cab28b2dStaylor */ 5318faf39b2Staylor if (pktw->pcw_flags & PCW_NEED_EXT_SCB) { 532cab28b2dStaylor kmem_free(pktp->pkt_scbp, pktp->pkt_scblen); 533cab28b2dStaylor pktp->pkt_scbp = (opaque_t)((char *)pktp + 534cab28b2dStaylor (A_TO_TRAN(ap))->tran_hba_len + 535cab28b2dStaylor DEFAULT_PRIVLEN + sizeof (struct scsi_pkt_cache_wrapper)); 536cab28b2dStaylor if ((A_TO_TRAN(ap))->tran_hba_flags & SCSI_HBA_TRAN_CDB) 537cab28b2dStaylor pktp->pkt_scbp = (opaque_t)((pktp->pkt_scbp) + 538c6c44d06Sjw DEFAULT_CDBLEN); 539cab28b2dStaylor pktp->pkt_scblen = 0; 540cab28b2dStaylor } 5418faf39b2Staylor if (pktw->pcw_flags & PCW_NEED_EXT_TGT) { 542cab28b2dStaylor kmem_free(pktp->pkt_private, pktp->pkt_tgtlen); 543cab28b2dStaylor pktp->pkt_tgtlen = 0; 544cab28b2dStaylor pktp->pkt_private = NULL; 545cab28b2dStaylor } 5468faf39b2Staylor if (pktw->pcw_flags & PCW_NEED_EXT_CDB) { 547cab28b2dStaylor kmem_free(pktp->pkt_cdbp, pktp->pkt_cdblen); 548cab28b2dStaylor pktp->pkt_cdbp = (opaque_t)((char *)pktp + 549cab28b2dStaylor (A_TO_TRAN(ap))->tran_hba_len + 550cab28b2dStaylor sizeof (struct scsi_pkt_cache_wrapper)); 551cab28b2dStaylor pktp->pkt_cdblen = 0; 552cab28b2dStaylor } 5538faf39b2Staylor pktw->pcw_flags &= 5548faf39b2Staylor ~(PCW_NEED_EXT_CDB|PCW_NEED_EXT_TGT|PCW_NEED_EXT_SCB); 555cab28b2dStaylor kmem_cache_free(A_TO_TRAN(ap)->tran_pkt_cache_ptr, pktw); 556cab28b2dStaylor 557cab28b2dStaylor if (scsi_callback_id != 0) { 558cab28b2dStaylor ddi_run_callback(&scsi_callback_id); 559cab28b2dStaylor } 560cab28b2dStaylor 561cab28b2dStaylor } 562cab28b2dStaylor 5638faf39b2Staylor 5647c478bd9Sstevel@tonic-gate struct scsi_pkt * 5657c478bd9Sstevel@tonic-gate scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *in_pktp, 5667c478bd9Sstevel@tonic-gate struct buf *bp, int cmdlen, int statuslen, int pplen, 5677c478bd9Sstevel@tonic-gate int flags, int (*callback)(caddr_t), caddr_t callback_arg) 5687c478bd9Sstevel@tonic-gate { 5697c478bd9Sstevel@tonic-gate struct scsi_pkt *pktp; 5707c478bd9Sstevel@tonic-gate scsi_hba_tran_t *tranp = ap->a_hba_tran; 5717c478bd9Sstevel@tonic-gate int (*func)(caddr_t); 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate TRACE_5(TR_FAC_SCSI_RES, TR_SCSI_INIT_PKT_START, 5747c478bd9Sstevel@tonic-gate "scsi_init_pkt_start: addr %p in_pktp %p cmdlen %d statuslen %d pplen %d", 5757c478bd9Sstevel@tonic-gate ap, in_pktp, cmdlen, statuslen, pplen); 5767c478bd9Sstevel@tonic-gate 5777c478bd9Sstevel@tonic-gate #if defined(__i386) || defined(__amd64) 5787c478bd9Sstevel@tonic-gate if (flags & PKT_CONSISTENT_OLD) { 5797c478bd9Sstevel@tonic-gate flags &= ~PKT_CONSISTENT_OLD; 5807c478bd9Sstevel@tonic-gate flags |= PKT_CONSISTENT; 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate #endif 5837c478bd9Sstevel@tonic-gate 5847c478bd9Sstevel@tonic-gate func = (callback == SLEEP_FUNC) ? SLEEP_FUNC : NULL_FUNC; 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate pktp = (*tranp->tran_init_pkt) (ap, in_pktp, bp, cmdlen, 587c6c44d06Sjw statuslen, pplen, flags, func, NULL); 5887c478bd9Sstevel@tonic-gate if (pktp == NULL) { 5897c478bd9Sstevel@tonic-gate if (callback != NULL_FUNC && callback != SLEEP_FUNC) { 5907c478bd9Sstevel@tonic-gate ddi_set_callback(callback, callback_arg, 591c6c44d06Sjw &scsi_callback_id); 5927c478bd9Sstevel@tonic-gate } 5937c478bd9Sstevel@tonic-gate } 5947c478bd9Sstevel@tonic-gate 5957c478bd9Sstevel@tonic-gate TRACE_1(TR_FAC_SCSI_RES, TR_SCSI_INIT_PKT_END, 596c6c44d06Sjw "scsi_init_pkt_end: pktp %p", pktp); 5977c478bd9Sstevel@tonic-gate return (pktp); 5987c478bd9Sstevel@tonic-gate } 5997c478bd9Sstevel@tonic-gate 6007c478bd9Sstevel@tonic-gate void 6017c478bd9Sstevel@tonic-gate scsi_destroy_pkt(struct scsi_pkt *pkt) 6027c478bd9Sstevel@tonic-gate { 6037c478bd9Sstevel@tonic-gate struct scsi_address *ap = P_TO_ADDR(pkt); 6047c478bd9Sstevel@tonic-gate 6057c478bd9Sstevel@tonic-gate TRACE_1(TR_FAC_SCSI_RES, TR_SCSI_DESTROY_PKT_START, 606c6c44d06Sjw "scsi_destroy_pkt_start: pkt %p", pkt); 6077c478bd9Sstevel@tonic-gate 6087c478bd9Sstevel@tonic-gate (*A_TO_TRAN(ap)->tran_destroy_pkt)(ap, pkt); 6097c478bd9Sstevel@tonic-gate 6107c478bd9Sstevel@tonic-gate if (scsi_callback_id != 0) { 6117c478bd9Sstevel@tonic-gate ddi_run_callback(&scsi_callback_id); 6127c478bd9Sstevel@tonic-gate } 6137c478bd9Sstevel@tonic-gate 6147c478bd9Sstevel@tonic-gate TRACE_0(TR_FAC_SCSI_RES, TR_SCSI_DESTROY_PKT_END, 615c6c44d06Sjw "scsi_destroy_pkt_end"); 6167c478bd9Sstevel@tonic-gate } 6177c478bd9Sstevel@tonic-gate 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate /* 6207c478bd9Sstevel@tonic-gate * Generic Resource Allocation Routines 6217c478bd9Sstevel@tonic-gate */ 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate struct scsi_pkt * 6247c478bd9Sstevel@tonic-gate scsi_resalloc(struct scsi_address *ap, int cmdlen, int statuslen, 6257c478bd9Sstevel@tonic-gate opaque_t dmatoken, int (*callback)()) 6267c478bd9Sstevel@tonic-gate { 6277c478bd9Sstevel@tonic-gate register struct scsi_pkt *pkt; 6287c478bd9Sstevel@tonic-gate register scsi_hba_tran_t *tranp = ap->a_hba_tran; 6297c478bd9Sstevel@tonic-gate register int (*func)(caddr_t); 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate func = (callback == SLEEP_FUNC) ? SLEEP_FUNC : NULL_FUNC; 6327c478bd9Sstevel@tonic-gate 6337c478bd9Sstevel@tonic-gate pkt = (*tranp->tran_init_pkt) (ap, NULL, (struct buf *)dmatoken, 634c6c44d06Sjw cmdlen, statuslen, 0, 0, func, NULL); 6357c478bd9Sstevel@tonic-gate if (pkt == NULL) { 6367c478bd9Sstevel@tonic-gate if (callback != NULL_FUNC && callback != SLEEP_FUNC) { 6377c478bd9Sstevel@tonic-gate ddi_set_callback(callback, NULL, &scsi_callback_id); 6387c478bd9Sstevel@tonic-gate } 6397c478bd9Sstevel@tonic-gate } 6407c478bd9Sstevel@tonic-gate 6417c478bd9Sstevel@tonic-gate return (pkt); 6427c478bd9Sstevel@tonic-gate } 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate struct scsi_pkt * 6457c478bd9Sstevel@tonic-gate scsi_pktalloc(struct scsi_address *ap, int cmdlen, int statuslen, 6467c478bd9Sstevel@tonic-gate int (*callback)()) 6477c478bd9Sstevel@tonic-gate { 6487c478bd9Sstevel@tonic-gate struct scsi_pkt *pkt; 6497c478bd9Sstevel@tonic-gate struct scsi_hba_tran *tran = ap->a_hba_tran; 6507c478bd9Sstevel@tonic-gate register int (*func)(caddr_t); 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate func = (callback == SLEEP_FUNC) ? SLEEP_FUNC : NULL_FUNC; 6537c478bd9Sstevel@tonic-gate 6547c478bd9Sstevel@tonic-gate pkt = (*tran->tran_init_pkt) (ap, NULL, NULL, cmdlen, 655c6c44d06Sjw statuslen, 0, 0, func, NULL); 6567c478bd9Sstevel@tonic-gate if (pkt == NULL) { 6577c478bd9Sstevel@tonic-gate if (callback != NULL_FUNC && callback != SLEEP_FUNC) { 6587c478bd9Sstevel@tonic-gate ddi_set_callback(callback, NULL, &scsi_callback_id); 6597c478bd9Sstevel@tonic-gate } 6607c478bd9Sstevel@tonic-gate } 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate return (pkt); 6637c478bd9Sstevel@tonic-gate } 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate struct scsi_pkt * 6667c478bd9Sstevel@tonic-gate scsi_dmaget(struct scsi_pkt *pkt, opaque_t dmatoken, int (*callback)()) 6677c478bd9Sstevel@tonic-gate { 6687c478bd9Sstevel@tonic-gate struct scsi_pkt *new_pkt; 6697c478bd9Sstevel@tonic-gate register int (*func)(caddr_t); 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate func = (callback == SLEEP_FUNC) ? SLEEP_FUNC : NULL_FUNC; 6727c478bd9Sstevel@tonic-gate 6737c478bd9Sstevel@tonic-gate new_pkt = (*P_TO_TRAN(pkt)->tran_init_pkt) (&pkt->pkt_address, 674c6c44d06Sjw pkt, (struct buf *)dmatoken, 675c6c44d06Sjw 0, 0, 0, 0, func, NULL); 6767c478bd9Sstevel@tonic-gate ASSERT(new_pkt == pkt || new_pkt == NULL); 6777c478bd9Sstevel@tonic-gate if (new_pkt == NULL) { 6787c478bd9Sstevel@tonic-gate if (callback != NULL_FUNC && callback != SLEEP_FUNC) { 6797c478bd9Sstevel@tonic-gate ddi_set_callback(callback, NULL, &scsi_callback_id); 6807c478bd9Sstevel@tonic-gate } 6817c478bd9Sstevel@tonic-gate } 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate return (new_pkt); 6847c478bd9Sstevel@tonic-gate } 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate /* 6887c478bd9Sstevel@tonic-gate * Generic Resource Deallocation Routines 6897c478bd9Sstevel@tonic-gate */ 6907c478bd9Sstevel@tonic-gate 6917c478bd9Sstevel@tonic-gate void 6927c478bd9Sstevel@tonic-gate scsi_dmafree(struct scsi_pkt *pkt) 6937c478bd9Sstevel@tonic-gate { 6947c478bd9Sstevel@tonic-gate register struct scsi_address *ap = P_TO_ADDR(pkt); 6958faf39b2Staylor 6967c478bd9Sstevel@tonic-gate (*A_TO_TRAN(ap)->tran_dmafree)(ap, pkt); 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate if (scsi_callback_id != 0) { 6997c478bd9Sstevel@tonic-gate ddi_run_callback(&scsi_callback_id); 7007c478bd9Sstevel@tonic-gate } 7017c478bd9Sstevel@tonic-gate } 7027c478bd9Sstevel@tonic-gate 7038faf39b2Staylor /*ARGSUSED*/ 7048faf39b2Staylor void 7058faf39b2Staylor scsi_cache_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt) 7068faf39b2Staylor { 707a231f2c8SNikko He ASSERT(pkt->pkt_numcookies == 0 || 708a231f2c8SNikko He ((struct scsi_pkt_cache_wrapper *)pkt)->pcw_flags & PCW_BOUND); 7098faf39b2Staylor ASSERT(pkt->pkt_handle != NULL); 7108faf39b2Staylor scsi_dmafree_attr(pkt); 7118faf39b2Staylor 7128faf39b2Staylor if (scsi_callback_id != 0) { 7138faf39b2Staylor ddi_run_callback(&scsi_callback_id); 7148faf39b2Staylor } 7158faf39b2Staylor } 7168faf39b2Staylor 7177c478bd9Sstevel@tonic-gate void 7187c478bd9Sstevel@tonic-gate scsi_sync_pkt(struct scsi_pkt *pkt) 7197c478bd9Sstevel@tonic-gate { 7207c478bd9Sstevel@tonic-gate register struct scsi_address *ap = P_TO_ADDR(pkt); 721c6c44d06Sjw 722c6c44d06Sjw if (pkt->pkt_state & STATE_XFERRED_DATA) 723c6c44d06Sjw (*A_TO_TRAN(ap)->tran_sync_pkt)(ap, pkt); 7247c478bd9Sstevel@tonic-gate } 7257c478bd9Sstevel@tonic-gate 7268faf39b2Staylor /*ARGSUSED*/ 7278faf39b2Staylor void 7288faf39b2Staylor scsi_sync_cache_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 7298faf39b2Staylor { 730afcdc791Scth if (pkt->pkt_handle && 731afcdc791Scth (pkt->pkt_dma_flags & (DDI_DMA_WRITE | DDI_DMA_READ))) { 7328faf39b2Staylor (void) ddi_dma_sync(pkt->pkt_handle, 733afcdc791Scth pkt->pkt_dma_offset, pkt->pkt_dma_len, 734afcdc791Scth (pkt->pkt_dma_flags & DDI_DMA_WRITE) ? 735afcdc791Scth DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU); 7368faf39b2Staylor } 7378faf39b2Staylor } 7388faf39b2Staylor 7397c478bd9Sstevel@tonic-gate void 7407c478bd9Sstevel@tonic-gate scsi_resfree(struct scsi_pkt *pkt) 7417c478bd9Sstevel@tonic-gate { 7427c478bd9Sstevel@tonic-gate register struct scsi_address *ap = P_TO_ADDR(pkt); 7437c478bd9Sstevel@tonic-gate (*A_TO_TRAN(ap)->tran_destroy_pkt)(ap, pkt); 7447c478bd9Sstevel@tonic-gate 7457c478bd9Sstevel@tonic-gate if (scsi_callback_id != 0) { 7467c478bd9Sstevel@tonic-gate ddi_run_callback(&scsi_callback_id); 7477c478bd9Sstevel@tonic-gate } 7487c478bd9Sstevel@tonic-gate } 749