507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * CDDL HEADER START
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * The contents of this file are subject to the terms of the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Common Development and Distribution License (the "License").
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * You may not use this file except in compliance with the License.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * or http://www.opensolaris.org/os/licensing.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * See the License for the specific language governing permissions
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * and limitations under the License.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * When distributing Covered Code, include this CDDL HEADER in each
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * If applicable, add the following below this CDDL HEADER, with the
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * fields enclosed by brackets "[]" replaced with your own identifying
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * information: Portions Copyright [yyyy] [name of copyright owner]
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * CDDL HEADER END
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Use is subject to license terms.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf#pragma ident "%Z%%M% %I% %E% SMI"
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf#include "ghd.h"
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Local Function Prototypes
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic struct scsi_pkt *ghd_pktalloc(ccc_t *cccp, struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int cmdlen, int statuslen, int tgtlen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int (*callback)(), caddr_t arg, int ccblen);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Round up all allocations so that we can guarantee
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * long-long alignment. This is the same alignment
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * provided by kmem_alloc().
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf#define ROUNDUP(x) (((x) + 0x07) & ~0x07)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Private wrapper for gcmd_t
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * round up the size so the HBA private area is on a 8 byte boundary
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf#define GW_PADDED_LENGTH ROUNDUP(sizeof (gcmd_t))
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlftypedef struct gcmd_padded_wrapper {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf union {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gcmd_t gw_gcmd;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf char gw_pad[GW_PADDED_LENGTH];
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf } gwrap;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf} gwrap_t;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*ARGSUSED*/
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfvoid
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfghd_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pktp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gcmd_t *gcmdp = PKTP2GCMDP(pktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int status;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (gcmdp->cmd_dma_handle) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf status = ddi_dma_sync(gcmdp->cmd_dma_handle, 0, 0,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh (gcmdp->cmd_dma_flags & DDI_DMA_READ) ?
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh DDI_DMA_SYNC_FORCPU : DDI_DMA_SYNC_FORDEV);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (status != DDI_SUCCESS) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf cmn_err(CE_WARN, "ghd_tran_sync_pkt() fail\n");
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstatic struct scsi_pkt *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfghd_pktalloc(ccc_t *cccp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int cmdlen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int statuslen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int tgtlen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int (*callback)(),
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf caddr_t arg,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int ccblen)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gtgt_t *gtgtp = ADDR2GTGTP(ap);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_pkt *pktp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gcmd_t *gcmdp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gwrap_t *gwp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int gwrap_len;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gwrap_len = sizeof (gwrap_t) + ROUNDUP(ccblen);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* allocate everything from kmem pool */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf pktp = scsi_hba_pkt_alloc(cccp->ccc_hba_dip, ap, cmdlen, statuslen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf tgtlen, gwrap_len, callback, arg);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (pktp == NULL) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (NULL);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* get the ptr to the HBA specific buffer */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gwp = (gwrap_t *)(pktp->pkt_ha_private);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* get the ptr to the GHD specific buffer */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gcmdp = &gwp->gwrap.gw_gcmd;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ASSERT((caddr_t)gwp == (caddr_t)gcmdp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * save the ptr to HBA private area and initialize the rest
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * of the gcmd_t members
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf GHD_GCMD_INIT(gcmdp, (void *)(gwp + 1), gtgtp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * save the the scsi_pkt ptr in gcmd_t.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gcmdp->cmd_pktp = pktp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * callback to the HBA driver so it can initalize its
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * buffer and return the ptr to my cmd_t structure which is
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * probably embedded in its buffer.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!(*cccp->ccc_ccballoc)(gtgtp, gcmdp, cmdlen, statuslen, tgtlen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ccblen)) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf scsi_hba_pkt_free(ap, pktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (NULL);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (pktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * packet free
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf/*ARGSUSED*/
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfvoid
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfghd_pktfree(ccc_t *cccp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_pkt *pktp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf GDBG_PKT(("ghd_pktfree: cccp 0x%p ap 0x%p pktp 0x%p\n",
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh (void *)cccp, (void *)ap, (void *)pktp));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* free any extra resources allocated by the HBA */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf (*cccp->ccc_ccbfree)(PKTP2GCMDP(pktp));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* free the scsi_pkt and the GHD and HBA private areas */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf scsi_hba_pkt_free(ap, pktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfstruct scsi_pkt *
507c32411f3f101e90ca2120f042b5ee698ba1d5mlfghd_tran_init_pkt_attr(ccc_t *cccp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_address *ap,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct scsi_pkt *pktp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf struct buf *bp,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int cmdlen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int statuslen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int tgtlen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int flags,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int (*callback)(),
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf caddr_t arg,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int ccblen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ddi_dma_attr_t *sg_attrp)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf{
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gcmd_t *gcmdp;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int new_pkt;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf uint_t xfercount;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Allocate a pkt
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (pktp == NULL) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf pktp = ghd_pktalloc(cccp, ap, cmdlen, statuslen, tgtlen,
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf callback, arg, ccblen);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (pktp == NULL)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (NULL);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf new_pkt = TRUE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf } else {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf new_pkt = FALSE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf gcmdp = PKTP2GCMDP(pktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf GDBG_PKT(("ghd_tran_init_pkt_attr: gcmdp 0x%p dma_handle 0x%p\n",
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh (void *)gcmdp, (void *)gcmdp->cmd_dma_handle));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * free stale DMA window if necessary.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (cmdlen && gcmdp->cmd_dma_handle) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* release the old DMA resources */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ghd_dmafree_attr(gcmdp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /*
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * Set up dma info if there's any data and
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf * if the device supports DMA.
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf GDBG_PKT(("ghd_tran_init_pkt: gcmdp 0x%p bp 0x%p limp 0x%p\n",
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh (void *)gcmdp, (void *)bp, (void *)sg_attrp));
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (bp && bp->b_bcount && sg_attrp) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf int dma_flags;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* check direction for data transfer */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (bp->b_flags & B_READ)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf dma_flags = DDI_DMA_READ;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf else
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf dma_flags = DDI_DMA_WRITE;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* check dma option flags */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (flags & PKT_CONSISTENT)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf dma_flags |= DDI_DMA_CONSISTENT;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (flags & PKT_DMA_PARTIAL)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf dma_flags |= DDI_DMA_PARTIAL;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (gcmdp->cmd_dma_handle == NULL) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!ghd_dma_buf_bind_attr(cccp, gcmdp, bp, dma_flags,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh callback, arg, sg_attrp)) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (new_pkt)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ghd_pktfree(cccp, ap, pktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (NULL);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf /* map the buffer and/or create the scatter/gather list */
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (!ghd_dmaget_attr(cccp, gcmdp,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh bp->b_bcount - gcmdp->cmd_totxfer,
903a11ebdc8df157c4700150f41f1f262f4a8ae8rh sg_attrp->dma_attr_sgllen, &xfercount)) {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf if (new_pkt)
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf ghd_pktfree(cccp, ap, pktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (NULL);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf pktp->pkt_resid = bp->b_bcount - gcmdp->cmd_totxfer;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf } else {
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf pktp->pkt_resid = 0;
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf }
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf return (pktp);
507c32411f3f101e90ca2120f042b5ee698ba1d5mlf}