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 /* 23830363f4Staylor * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <sys/scsi/scsi.h> 307c478bd9Sstevel@tonic-gate #include <sys/vtrace.h> 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #define A_TO_TRAN(ap) ((ap)->a_hba_tran) 347c478bd9Sstevel@tonic-gate #define P_TO_TRAN(pkt) ((pkt)->pkt_address.a_hba_tran) 357c478bd9Sstevel@tonic-gate #define P_TO_ADDR(pkt) (&((pkt)->pkt_address)) 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate /* 387c478bd9Sstevel@tonic-gate * Callback id 397c478bd9Sstevel@tonic-gate */ 407c478bd9Sstevel@tonic-gate uintptr_t scsi_callback_id = 0; 417c478bd9Sstevel@tonic-gate 424ab75253Smrj extern ddi_dma_attr_t scsi_alloc_attr; 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate struct buf * 457c478bd9Sstevel@tonic-gate scsi_alloc_consistent_buf(struct scsi_address *ap, 467c478bd9Sstevel@tonic-gate struct buf *in_bp, size_t datalen, uint_t bflags, 477c478bd9Sstevel@tonic-gate int (*callback)(caddr_t), caddr_t callback_arg) 487c478bd9Sstevel@tonic-gate { 497c478bd9Sstevel@tonic-gate dev_info_t *pdip; 507c478bd9Sstevel@tonic-gate struct buf *bp; 517c478bd9Sstevel@tonic-gate int kmflag; 524ab75253Smrj size_t rlen; 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate TRACE_0(TR_FAC_SCSI_RES, TR_SCSI_ALLOC_CONSISTENT_BUF_START, 557c478bd9Sstevel@tonic-gate "scsi_alloc_consistent_buf_start"); 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate if (!in_bp) { 587c478bd9Sstevel@tonic-gate kmflag = (callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP; 597c478bd9Sstevel@tonic-gate if ((bp = getrbuf(kmflag)) == NULL) { 607c478bd9Sstevel@tonic-gate goto no_resource; 617c478bd9Sstevel@tonic-gate } 627c478bd9Sstevel@tonic-gate } else { 637c478bd9Sstevel@tonic-gate bp = in_bp; 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate /* we are establishing a new buffer memory association */ 667c478bd9Sstevel@tonic-gate bp->b_flags &= ~(B_PAGEIO | B_PHYS | B_REMAPPED | B_SHADOW); 677c478bd9Sstevel@tonic-gate bp->b_proc = NULL; 687c478bd9Sstevel@tonic-gate bp->b_pages = NULL; 697c478bd9Sstevel@tonic-gate bp->b_shadow = NULL; 707c478bd9Sstevel@tonic-gate } 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate /* limit bits that can be set by bflags argument */ 737c478bd9Sstevel@tonic-gate ASSERT(!(bflags & ~(B_READ | B_WRITE))); 747c478bd9Sstevel@tonic-gate bflags &= (B_READ | B_WRITE); 757c478bd9Sstevel@tonic-gate bp->b_un.b_addr = 0; 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate if (datalen) { 787c478bd9Sstevel@tonic-gate pdip = (A_TO_TRAN(ap))->tran_hba_dip; 797c478bd9Sstevel@tonic-gate 804ab75253Smrj /* 814ab75253Smrj * use i_ddi_mem_alloc() for now until we have an interface to 824ab75253Smrj * allocate memory for DMA which doesn't require a DMA handle. 834ab75253Smrj * ddi_iopb_alloc() is obsolete and we want more flexibility in 844ab75253Smrj * controlling the DMA address constraints. 854ab75253Smrj */ 864ab75253Smrj while (i_ddi_mem_alloc(pdip, &scsi_alloc_attr, datalen, 874ab75253Smrj ((callback == SLEEP_FUNC) ? 1 : 0), 0, NULL, 884ab75253Smrj &bp->b_un.b_addr, &rlen, NULL) != DDI_SUCCESS) { 897c478bd9Sstevel@tonic-gate if (callback == SLEEP_FUNC) { 907c478bd9Sstevel@tonic-gate delay(drv_usectohz(10000)); 917c478bd9Sstevel@tonic-gate } else { 927c478bd9Sstevel@tonic-gate if (!in_bp) 937c478bd9Sstevel@tonic-gate freerbuf(bp); 947c478bd9Sstevel@tonic-gate goto no_resource; 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate } 977c478bd9Sstevel@tonic-gate bp->b_flags |= bflags; 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate bp->b_bcount = datalen; 1007c478bd9Sstevel@tonic-gate bp->b_resid = 0; 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate TRACE_0(TR_FAC_SCSI_RES, TR_SCSI_ALLOC_CONSISTENT_BUF_END, 1037c478bd9Sstevel@tonic-gate "scsi_alloc_consistent_buf_end"); 1047c478bd9Sstevel@tonic-gate return (bp); 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate no_resource: 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate if (callback != NULL_FUNC && callback != SLEEP_FUNC) { 1097c478bd9Sstevel@tonic-gate ddi_set_callback(callback, callback_arg, 1107c478bd9Sstevel@tonic-gate &scsi_callback_id); 1117c478bd9Sstevel@tonic-gate } 1127c478bd9Sstevel@tonic-gate TRACE_0(TR_FAC_SCSI_RES, 1137c478bd9Sstevel@tonic-gate TR_SCSI_ALLOC_CONSISTENT_BUF_RETURN1_END, 1147c478bd9Sstevel@tonic-gate "scsi_alloc_consistent_buf_end (return1)"); 1157c478bd9Sstevel@tonic-gate return (NULL); 1167c478bd9Sstevel@tonic-gate } 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate void 1197c478bd9Sstevel@tonic-gate scsi_free_consistent_buf(struct buf *bp) 1207c478bd9Sstevel@tonic-gate { 1217c478bd9Sstevel@tonic-gate TRACE_0(TR_FAC_SCSI_RES, TR_SCSI_FREE_CONSISTENT_BUF_START, 1227c478bd9Sstevel@tonic-gate "scsi_free_consistent_buf_start"); 1237c478bd9Sstevel@tonic-gate if (!bp) 1247c478bd9Sstevel@tonic-gate return; 1257c478bd9Sstevel@tonic-gate if (bp->b_un.b_addr) 126*7b93957cSeota i_ddi_mem_free((caddr_t)bp->b_un.b_addr, NULL); 1277c478bd9Sstevel@tonic-gate freerbuf(bp); 1287c478bd9Sstevel@tonic-gate if (scsi_callback_id != 0) { 1297c478bd9Sstevel@tonic-gate ddi_run_callback(&scsi_callback_id); 1307c478bd9Sstevel@tonic-gate } 1317c478bd9Sstevel@tonic-gate TRACE_0(TR_FAC_SCSI_RES, TR_SCSI_FREE_CONSISTENT_BUF_END, 1327c478bd9Sstevel@tonic-gate "scsi_free_consistent_buf_end"); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate 135cab28b2dStaylor void scsi_free_cache_pkt(struct scsi_address *, struct scsi_pkt *); 136cab28b2dStaylor 137cab28b2dStaylor struct scsi_pkt * 138cab28b2dStaylor scsi_init_cache_pkt(struct scsi_address *ap, struct scsi_pkt *in_pktp, 139cab28b2dStaylor struct buf *bp, int cmdlen, int statuslen, int pplen, 140cab28b2dStaylor int flags, int (*callback)(caddr_t), caddr_t callback_arg) 141cab28b2dStaylor { 142cab28b2dStaylor struct scsi_pkt_cache_wrapper *pktw; 143cab28b2dStaylor scsi_hba_tran_t *tranp = ap->a_hba_tran; 144cab28b2dStaylor int (*func)(caddr_t); 145cab28b2dStaylor 146cab28b2dStaylor func = (callback == SLEEP_FUNC) ? SLEEP_FUNC : NULL_FUNC; 147cab28b2dStaylor 148cab28b2dStaylor if (in_pktp == NULL) { 149cab28b2dStaylor int kf; 150cab28b2dStaylor 151cab28b2dStaylor if (callback == SLEEP_FUNC) 152cab28b2dStaylor kf = KM_SLEEP; 153cab28b2dStaylor else 154cab28b2dStaylor kf = KM_NOSLEEP; 155cab28b2dStaylor pktw = kmem_cache_alloc(tranp->tran_pkt_cache_ptr, 156cab28b2dStaylor kf); 157cab28b2dStaylor if (pktw == NULL) 158cab28b2dStaylor goto fail1; 159cab28b2dStaylor 160cab28b2dStaylor pktw->pcw_kmflags = 0; 161cab28b2dStaylor in_pktp = &(pktw->pcw_pkt); 162cab28b2dStaylor /* 163830363f4Staylor * target drivers should initialize pkt_comp and 164830363f4Staylor * pkt_time, but sometimes they don't so initialize 165830363f4Staylor * them here to be safe. 166cab28b2dStaylor */ 167cab28b2dStaylor in_pktp->pkt_address = *ap; 168830363f4Staylor in_pktp->pkt_flags = 0; 169830363f4Staylor in_pktp->pkt_time = 0; 170cab28b2dStaylor in_pktp->pkt_resid = 0; 171cab28b2dStaylor in_pktp->pkt_state = 0; 172cab28b2dStaylor in_pktp->pkt_statistics = 0; 173cab28b2dStaylor in_pktp->pkt_reason = 0; 174cab28b2dStaylor 175cab28b2dStaylor in_pktp->pkt_cdblen = cmdlen; 176cab28b2dStaylor if ((tranp->tran_hba_flags & SCSI_HBA_TRAN_CDB) && 177cab28b2dStaylor (cmdlen > DEFAULT_CDBLEN)) { 178cab28b2dStaylor pktw->pcw_kmflags |= NEED_EXT_CDB; 179830363f4Staylor in_pktp->pkt_cdbp = kmem_alloc(cmdlen, kf); 180cab28b2dStaylor if (in_pktp->pkt_cdbp == NULL) 181cab28b2dStaylor goto fail2; 182cab28b2dStaylor } 183cab28b2dStaylor in_pktp->pkt_tgtlen = pplen; 184cab28b2dStaylor if (pplen > DEFAULT_PRIVLEN) { 185cab28b2dStaylor pktw->pcw_kmflags |= NEED_EXT_TGT; 186830363f4Staylor in_pktp->pkt_private = kmem_alloc(pplen, kf); 187cab28b2dStaylor if (in_pktp->pkt_private == NULL) 188cab28b2dStaylor goto fail3; 189cab28b2dStaylor } 190cab28b2dStaylor in_pktp->pkt_scblen = statuslen; 191cab28b2dStaylor if ((tranp->tran_hba_flags & SCSI_HBA_TRAN_SCB) && 192cab28b2dStaylor (statuslen > DEFAULT_SCBLEN)) { 193cab28b2dStaylor pktw->pcw_kmflags |= NEED_EXT_SCB; 194830363f4Staylor in_pktp->pkt_scbp = kmem_alloc(statuslen, kf); 195cab28b2dStaylor if (in_pktp->pkt_scbp == NULL) 196cab28b2dStaylor goto fail4; 197cab28b2dStaylor } 198cab28b2dStaylor if ((*tranp->tran_setup_pkt) (in_pktp, 199cab28b2dStaylor func, NULL) == -1) { 200cab28b2dStaylor goto fail5; 201cab28b2dStaylor } 202830363f4Staylor if (cmdlen) 203830363f4Staylor bzero((void *)in_pktp->pkt_cdbp, cmdlen); 204830363f4Staylor if (pplen) 205830363f4Staylor bzero((void *)in_pktp->pkt_private, pplen); 206830363f4Staylor if (statuslen) 207830363f4Staylor bzero((void *)in_pktp->pkt_scbp, statuslen); 208cab28b2dStaylor } 209cab28b2dStaylor if (bp && bp->b_bcount) { 210cab28b2dStaylor if ((*tranp->tran_setup_bp) (in_pktp, bp, 211cab28b2dStaylor flags, func, NULL) == -1) { 212cab28b2dStaylor scsi_free_cache_pkt(ap, in_pktp); 213cab28b2dStaylor in_pktp = NULL; 214cab28b2dStaylor } 215cab28b2dStaylor } 216cab28b2dStaylor return (in_pktp); 217cab28b2dStaylor 218cab28b2dStaylor fail5: 219cab28b2dStaylor if (pktw->pcw_kmflags & NEED_EXT_SCB) { 220cab28b2dStaylor kmem_free(in_pktp->pkt_scbp, statuslen); 221cab28b2dStaylor in_pktp->pkt_scbp = (opaque_t)((char *)in_pktp + 222cab28b2dStaylor tranp->tran_hba_len + DEFAULT_PRIVLEN + 223cab28b2dStaylor sizeof (struct scsi_pkt)); 224cab28b2dStaylor if ((A_TO_TRAN(ap))->tran_hba_flags & SCSI_HBA_TRAN_CDB) 225cab28b2dStaylor in_pktp->pkt_scbp = (opaque_t)((in_pktp->pkt_scbp) + 226cab28b2dStaylor DEFAULT_CDBLEN); 227cab28b2dStaylor in_pktp->pkt_scblen = 0; 228cab28b2dStaylor } 229cab28b2dStaylor fail4: 230cab28b2dStaylor if (pktw->pcw_kmflags & NEED_EXT_TGT) { 231cab28b2dStaylor kmem_free(in_pktp->pkt_private, pplen); 232cab28b2dStaylor in_pktp->pkt_tgtlen = 0; 233cab28b2dStaylor in_pktp->pkt_private = NULL; 234cab28b2dStaylor } 235cab28b2dStaylor fail3: 236cab28b2dStaylor if (pktw->pcw_kmflags & NEED_EXT_CDB) { 237cab28b2dStaylor kmem_free(in_pktp->pkt_cdbp, cmdlen); 238cab28b2dStaylor in_pktp->pkt_cdbp = (opaque_t)((char *)in_pktp + 239cab28b2dStaylor tranp->tran_hba_len + 240cab28b2dStaylor sizeof (struct scsi_pkt)); 241cab28b2dStaylor in_pktp->pkt_cdblen = 0; 242cab28b2dStaylor } 243cab28b2dStaylor pktw->pcw_kmflags &= 244cab28b2dStaylor ~(NEED_EXT_CDB|NEED_EXT_TGT|NEED_EXT_SCB); 245cab28b2dStaylor fail2: 246cab28b2dStaylor kmem_cache_free(tranp->tran_pkt_cache_ptr, pktw); 247cab28b2dStaylor fail1: 248cab28b2dStaylor if (callback != NULL_FUNC && callback != SLEEP_FUNC) { 249cab28b2dStaylor ddi_set_callback(callback, callback_arg, 250cab28b2dStaylor &scsi_callback_id); 251cab28b2dStaylor } 252cab28b2dStaylor 253cab28b2dStaylor return (NULL); 254cab28b2dStaylor } 255cab28b2dStaylor 256cab28b2dStaylor void 257cab28b2dStaylor scsi_free_cache_pkt(struct scsi_address *ap, struct scsi_pkt *pktp) 258cab28b2dStaylor { 259cab28b2dStaylor struct scsi_pkt_cache_wrapper *pktw; 260cab28b2dStaylor 261cab28b2dStaylor (*A_TO_TRAN(ap)->tran_teardown_pkt)(pktp); 262cab28b2dStaylor pktw = (struct scsi_pkt_cache_wrapper *)pktp; 263cab28b2dStaylor 264cab28b2dStaylor /* 265cab28b2dStaylor * if we allocated memory for anything that wouldn't fit, free 266cab28b2dStaylor * the memory and restore the pointers 267cab28b2dStaylor */ 268cab28b2dStaylor if (pktw->pcw_kmflags & NEED_EXT_SCB) { 269cab28b2dStaylor kmem_free(pktp->pkt_scbp, pktp->pkt_scblen); 270cab28b2dStaylor pktp->pkt_scbp = (opaque_t)((char *)pktp + 271cab28b2dStaylor (A_TO_TRAN(ap))->tran_hba_len + 272cab28b2dStaylor DEFAULT_PRIVLEN + sizeof (struct scsi_pkt_cache_wrapper)); 273cab28b2dStaylor if ((A_TO_TRAN(ap))->tran_hba_flags & SCSI_HBA_TRAN_CDB) 274cab28b2dStaylor pktp->pkt_scbp = (opaque_t)((pktp->pkt_scbp) + 275cab28b2dStaylor DEFAULT_CDBLEN); 276cab28b2dStaylor pktp->pkt_scblen = 0; 277cab28b2dStaylor } 278cab28b2dStaylor if (pktw->pcw_kmflags & NEED_EXT_TGT) { 279cab28b2dStaylor kmem_free(pktp->pkt_private, pktp->pkt_tgtlen); 280cab28b2dStaylor pktp->pkt_tgtlen = 0; 281cab28b2dStaylor pktp->pkt_private = NULL; 282cab28b2dStaylor } 283cab28b2dStaylor if (pktw->pcw_kmflags & NEED_EXT_CDB) { 284cab28b2dStaylor kmem_free(pktp->pkt_cdbp, pktp->pkt_cdblen); 285cab28b2dStaylor pktp->pkt_cdbp = (opaque_t)((char *)pktp + 286cab28b2dStaylor (A_TO_TRAN(ap))->tran_hba_len + 287cab28b2dStaylor sizeof (struct scsi_pkt_cache_wrapper)); 288cab28b2dStaylor pktp->pkt_cdblen = 0; 289cab28b2dStaylor } 290cab28b2dStaylor pktw->pcw_kmflags &= 291cab28b2dStaylor ~(NEED_EXT_CDB|NEED_EXT_TGT|NEED_EXT_SCB); 292cab28b2dStaylor ASSERT(pktw->pcw_kmflags == 0); 293cab28b2dStaylor kmem_cache_free(A_TO_TRAN(ap)->tran_pkt_cache_ptr, pktw); 294cab28b2dStaylor 295cab28b2dStaylor if (scsi_callback_id != 0) { 296cab28b2dStaylor ddi_run_callback(&scsi_callback_id); 297cab28b2dStaylor } 298cab28b2dStaylor 299cab28b2dStaylor } 300cab28b2dStaylor 3017c478bd9Sstevel@tonic-gate struct scsi_pkt * 3027c478bd9Sstevel@tonic-gate scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *in_pktp, 3037c478bd9Sstevel@tonic-gate struct buf *bp, int cmdlen, int statuslen, int pplen, 3047c478bd9Sstevel@tonic-gate int flags, int (*callback)(caddr_t), caddr_t callback_arg) 3057c478bd9Sstevel@tonic-gate { 3067c478bd9Sstevel@tonic-gate struct scsi_pkt *pktp; 3077c478bd9Sstevel@tonic-gate scsi_hba_tran_t *tranp = ap->a_hba_tran; 3087c478bd9Sstevel@tonic-gate int (*func)(caddr_t); 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate TRACE_5(TR_FAC_SCSI_RES, TR_SCSI_INIT_PKT_START, 3117c478bd9Sstevel@tonic-gate "scsi_init_pkt_start: addr %p in_pktp %p cmdlen %d statuslen %d pplen %d", 3127c478bd9Sstevel@tonic-gate ap, in_pktp, cmdlen, statuslen, pplen); 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate #if defined(__i386) || defined(__amd64) 3157c478bd9Sstevel@tonic-gate if (flags & PKT_CONSISTENT_OLD) { 3167c478bd9Sstevel@tonic-gate flags &= ~PKT_CONSISTENT_OLD; 3177c478bd9Sstevel@tonic-gate flags |= PKT_CONSISTENT; 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate #endif 3207c478bd9Sstevel@tonic-gate 3217c478bd9Sstevel@tonic-gate func = (callback == SLEEP_FUNC) ? SLEEP_FUNC : NULL_FUNC; 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate pktp = (*tranp->tran_init_pkt) (ap, in_pktp, bp, cmdlen, 3247c478bd9Sstevel@tonic-gate statuslen, pplen, flags, func, NULL); 3257c478bd9Sstevel@tonic-gate if (pktp == NULL) { 3267c478bd9Sstevel@tonic-gate if (callback != NULL_FUNC && callback != SLEEP_FUNC) { 3277c478bd9Sstevel@tonic-gate ddi_set_callback(callback, callback_arg, 3287c478bd9Sstevel@tonic-gate &scsi_callback_id); 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate TRACE_1(TR_FAC_SCSI_RES, TR_SCSI_INIT_PKT_END, 3337c478bd9Sstevel@tonic-gate "scsi_init_pkt_end: pktp %p", pktp); 3347c478bd9Sstevel@tonic-gate return (pktp); 3357c478bd9Sstevel@tonic-gate } 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate void 3387c478bd9Sstevel@tonic-gate scsi_destroy_pkt(struct scsi_pkt *pkt) 3397c478bd9Sstevel@tonic-gate { 3407c478bd9Sstevel@tonic-gate struct scsi_address *ap = P_TO_ADDR(pkt); 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate TRACE_1(TR_FAC_SCSI_RES, TR_SCSI_DESTROY_PKT_START, 3437c478bd9Sstevel@tonic-gate "scsi_destroy_pkt_start: pkt %p", pkt); 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate (*A_TO_TRAN(ap)->tran_destroy_pkt)(ap, pkt); 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate if (scsi_callback_id != 0) { 3487c478bd9Sstevel@tonic-gate ddi_run_callback(&scsi_callback_id); 3497c478bd9Sstevel@tonic-gate } 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate TRACE_0(TR_FAC_SCSI_RES, TR_SCSI_DESTROY_PKT_END, 3527c478bd9Sstevel@tonic-gate "scsi_destroy_pkt_end"); 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate /* 3577c478bd9Sstevel@tonic-gate * Generic Resource Allocation Routines 3587c478bd9Sstevel@tonic-gate */ 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate struct scsi_pkt * 3617c478bd9Sstevel@tonic-gate scsi_resalloc(struct scsi_address *ap, int cmdlen, int statuslen, 3627c478bd9Sstevel@tonic-gate opaque_t dmatoken, int (*callback)()) 3637c478bd9Sstevel@tonic-gate { 3647c478bd9Sstevel@tonic-gate register struct scsi_pkt *pkt; 3657c478bd9Sstevel@tonic-gate register scsi_hba_tran_t *tranp = ap->a_hba_tran; 3667c478bd9Sstevel@tonic-gate register int (*func)(caddr_t); 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate func = (callback == SLEEP_FUNC) ? SLEEP_FUNC : NULL_FUNC; 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate pkt = (*tranp->tran_init_pkt) (ap, NULL, (struct buf *)dmatoken, 3717c478bd9Sstevel@tonic-gate cmdlen, statuslen, 0, 0, func, NULL); 3727c478bd9Sstevel@tonic-gate if (pkt == NULL) { 3737c478bd9Sstevel@tonic-gate if (callback != NULL_FUNC && callback != SLEEP_FUNC) { 3747c478bd9Sstevel@tonic-gate ddi_set_callback(callback, NULL, &scsi_callback_id); 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate } 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate return (pkt); 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate struct scsi_pkt * 3827c478bd9Sstevel@tonic-gate scsi_pktalloc(struct scsi_address *ap, int cmdlen, int statuslen, 3837c478bd9Sstevel@tonic-gate int (*callback)()) 3847c478bd9Sstevel@tonic-gate { 3857c478bd9Sstevel@tonic-gate struct scsi_pkt *pkt; 3867c478bd9Sstevel@tonic-gate struct scsi_hba_tran *tran = ap->a_hba_tran; 3877c478bd9Sstevel@tonic-gate register int (*func)(caddr_t); 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate func = (callback == SLEEP_FUNC) ? SLEEP_FUNC : NULL_FUNC; 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate pkt = (*tran->tran_init_pkt) (ap, NULL, NULL, cmdlen, 3927c478bd9Sstevel@tonic-gate statuslen, 0, 0, func, NULL); 3937c478bd9Sstevel@tonic-gate if (pkt == NULL) { 3947c478bd9Sstevel@tonic-gate if (callback != NULL_FUNC && callback != SLEEP_FUNC) { 3957c478bd9Sstevel@tonic-gate ddi_set_callback(callback, NULL, &scsi_callback_id); 3967c478bd9Sstevel@tonic-gate } 3977c478bd9Sstevel@tonic-gate } 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate return (pkt); 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate struct scsi_pkt * 4037c478bd9Sstevel@tonic-gate scsi_dmaget(struct scsi_pkt *pkt, opaque_t dmatoken, int (*callback)()) 4047c478bd9Sstevel@tonic-gate { 4057c478bd9Sstevel@tonic-gate struct scsi_pkt *new_pkt; 4067c478bd9Sstevel@tonic-gate register int (*func)(caddr_t); 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate func = (callback == SLEEP_FUNC) ? SLEEP_FUNC : NULL_FUNC; 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate new_pkt = (*P_TO_TRAN(pkt)->tran_init_pkt) (&pkt->pkt_address, 4117c478bd9Sstevel@tonic-gate pkt, (struct buf *)dmatoken, 4127c478bd9Sstevel@tonic-gate 0, 0, 0, 0, func, NULL); 4137c478bd9Sstevel@tonic-gate ASSERT(new_pkt == pkt || new_pkt == NULL); 4147c478bd9Sstevel@tonic-gate if (new_pkt == NULL) { 4157c478bd9Sstevel@tonic-gate if (callback != NULL_FUNC && callback != SLEEP_FUNC) { 4167c478bd9Sstevel@tonic-gate ddi_set_callback(callback, NULL, &scsi_callback_id); 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate } 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate return (new_pkt); 4217c478bd9Sstevel@tonic-gate } 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate /* 4257c478bd9Sstevel@tonic-gate * Generic Resource Deallocation Routines 4267c478bd9Sstevel@tonic-gate */ 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate void 4297c478bd9Sstevel@tonic-gate scsi_dmafree(struct scsi_pkt *pkt) 4307c478bd9Sstevel@tonic-gate { 4317c478bd9Sstevel@tonic-gate register struct scsi_address *ap = P_TO_ADDR(pkt); 4327c478bd9Sstevel@tonic-gate (*A_TO_TRAN(ap)->tran_dmafree)(ap, pkt); 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate if (scsi_callback_id != 0) { 4357c478bd9Sstevel@tonic-gate ddi_run_callback(&scsi_callback_id); 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate } 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate void 4407c478bd9Sstevel@tonic-gate scsi_sync_pkt(struct scsi_pkt *pkt) 4417c478bd9Sstevel@tonic-gate { 4427c478bd9Sstevel@tonic-gate register struct scsi_address *ap = P_TO_ADDR(pkt); 4437c478bd9Sstevel@tonic-gate (*A_TO_TRAN(ap)->tran_sync_pkt)(ap, pkt); 4447c478bd9Sstevel@tonic-gate } 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate void 4477c478bd9Sstevel@tonic-gate scsi_resfree(struct scsi_pkt *pkt) 4487c478bd9Sstevel@tonic-gate { 4497c478bd9Sstevel@tonic-gate register struct scsi_address *ap = P_TO_ADDR(pkt); 4507c478bd9Sstevel@tonic-gate (*A_TO_TRAN(ap)->tran_destroy_pkt)(ap, pkt); 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate if (scsi_callback_id != 0) { 4537c478bd9Sstevel@tonic-gate ddi_run_callback(&scsi_callback_id); 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate } 456