/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Callback id
*/
extern ddi_dma_attr_t scsi_alloc_attr;
struct buf *
{
int kmflag;
"scsi_alloc_consistent_buf_start");
if (!in_bp) {
goto no_resource;
}
} else {
/* we are establishing a new buffer memory association */
}
/* limit bits that can be set by bflags argument */
if (datalen) {
/*
* use i_ddi_mem_alloc() for now until we have an interface to
* allocate memory for DMA which doesn't require a DMA handle.
*/
if (callback == SLEEP_FUNC) {
} else {
if (!in_bp)
goto no_resource;
}
}
}
"scsi_alloc_consistent_buf_end");
return (bp);
}
"scsi_alloc_consistent_buf_end (return1)");
return (NULL);
}
void
{
"scsi_free_consistent_buf_start");
if (!bp)
return;
if (scsi_callback_id != 0) {
}
"scsi_free_consistent_buf_end");
}
void
{
(struct scsi_pkt_cache_wrapper *)pktp;
"unbind handle failed");
}
pktp->pkt_numcookies = 0;
pktw->pcw_totalwin = 0;
}
struct buf *
{
}
int
int dma_flags,
int (*callback)(),
{
int status;
/*
* First time, need to establish the handle.
*/
&pktp->pkt_numcookies);
switch (status) {
case DDI_DMA_MAPPED:
break;
case DDI_DMA_PARTIAL_MAP:
/* enable first call to ddi_dma_getwin */
return (0);
}
break;
case DDI_DMA_NORESOURCES:
return (0);
case DDI_DMA_TOOBIG:
return (0);
case DDI_DMA_NOMAPPING:
case DDI_DMA_INUSE:
default:
return (0);
}
/* initialize the loop controls for scsi_dmaget_attr() */
pktw->pcw_curwin = 0;
pktw->pcw_total_xfer = 0;
return (1);
}
#if defined(_DMA_USES_PHYSADDR)
int
{
int status;
int num_segs = 0;
if (pktw->pcw_curwin != 0) {
/*
* start the next window, and get its first cookie
*/
&pktp->pkt_numcookies);
if (status != DDI_SUCCESS)
return (0);
}
/*
*/
pktp->pkt_dma_len = 0;
for (;;) {
/* take care of the loop-bookkeeping */
num_segs++;
/*
* if this was the last cookie in the current window
* set the loop controls start the next window and
* exit so the HBA can do this partial transfer
*/
pktw->pcw_curwin++;
break;
}
cp++;
}
return (1);
}
#endif
struct scsi_pkt *
{
int kf;
if (callback == SLEEP_FUNC)
else
kf = KM_NOSLEEP;
/*
* By using kmem_cache_alloc(), the layout of the
* scsi_pkt, scsi_pkt_cache_wrapper, hba private data,
* cdb, tgt driver private data, and status block is
* as below.
*
* This is a piece of contiguous memory starting from
* the first structure field scsi_pkt in the struct
* scsi_pkt_cache_wrapper, followed by the hba private
* data, pkt_cdbp, the tgt driver private data and
* pkt_scbp.
*
* |----------------------------|--------------------->
* | struct scsi_pkt | struct
* | ...... |scsi_pkt_cache_wrapper
* | pcw_flags |
* |----------------------------|<---------------------
* | hba private data |tranp->tran_hba_len
* |----------------------------|
* | pkt_cdbp |DEFAULT_CDBLEN
* |----------------------------|
* | tgt private data |DEFAULT_PRIVLEN
* |----------------------------|
* | pkt_scbp |DEFAULT_SCBLEN
* |----------------------------|
*
* If the actual data length of the cdb, or the tgt
* driver private data, or the status block is bigger
* than the default data length, kmem_alloc() will be
* called to get extra space.
*/
kf);
goto fail1;
/*
* target drivers should initialize pkt_comp and
* pkt_time, but sometimes they don't so initialize
* them here to be safe.
*/
in_pktp->pkt_statistics = 0;
in_pktp->pkt_reason = 0;
in_pktp->pkt_dma_offset = 0;
in_pktp->pkt_dma_len = 0;
in_pktp->pkt_dma_flags = 0;
in_pktp->pkt_path_instance = 0;
pktw->pcw_curwin = 0;
pktw->pcw_totalwin = 0;
pktw->pcw_total_xfer = 0;
(cmdlen > DEFAULT_CDBLEN)) {
goto fail2;
}
if (pplen > DEFAULT_PRIVLEN) {
goto fail3;
}
(statuslen > DEFAULT_SCBLEN)) {
goto fail4;
}
goto fail5;
}
if (cmdlen)
if (pplen)
if (statuslen)
} else
int dma_flags = 0;
/*
* we need to transfer data, so we alloc dma resources
* for this packet
*/
/*CONSTCOND*/
/*CONSTCOND*/
#if defined(_DMA_USES_PHYSADDR)
/*
* with an IOMMU we map everything, so we don't
* need to bother with this
*/
pktw->pcw_granular) {
return (NULL);
}
pktw->pcw_granular =
}
#endif
if (in_pktp->pkt_numcookies == 0) {
/*
* set dma flags; the "read" case must be first
* since B_WRITE isn't always be set for writes.
*/
} else {
}
if (flags & PKT_CONSISTENT)
if (flags & PKT_DMA_PARTIAL)
#if defined(__sparc)
/*
* workaround for byte hole issue on psycho and
* schizo pre 2.1
*/
}
#endif
return (NULL);
} else {
}
}
#if defined(_DMA_USES_PHYSADDR)
if (!scsi_dmaget_attr(pktw)) {
goto fail5;
}
#else
#endif
0);
} else {
/* !bp or no b_bcount */
}
return (in_pktp);
sizeof (struct scsi_pkt_cache_wrapper));
in_pktp->pkt_scblen = 0;
}
in_pktp->pkt_tgtlen = 0;
}
sizeof (struct scsi_pkt_cache_wrapper));
in_pktp->pkt_cdblen = 0;
}
}
return (NULL);
}
void
{
/*
* if we allocated memory for anything that wouldn't fit, free
* the memory and restore the pointers
*/
DEFAULT_PRIVLEN + sizeof (struct scsi_pkt_cache_wrapper));
pktp->pkt_scblen = 0;
}
pktp->pkt_tgtlen = 0;
}
sizeof (struct scsi_pkt_cache_wrapper));
pktp->pkt_cdblen = 0;
}
if (scsi_callback_id != 0) {
}
}
struct scsi_pkt *
{
"scsi_init_pkt_start: addr %p in_pktp %p cmdlen %d statuslen %d pplen %d",
if (flags & PKT_CONSISTENT_OLD) {
flags &= ~PKT_CONSISTENT_OLD;
flags |= PKT_CONSISTENT;
}
#endif
}
}
"scsi_init_pkt_end: pktp %p", pktp);
return (pktp);
}
void
{
"scsi_destroy_pkt_start: pkt %p", pkt);
if (scsi_callback_id != 0) {
}
"scsi_destroy_pkt_end");
}
/*
* Generic Resource Allocation Routines
*/
struct scsi_pkt *
{
}
}
return (pkt);
}
struct scsi_pkt *
int (*callback)())
{
}
}
return (pkt);
}
struct scsi_pkt *
{
}
}
return (new_pkt);
}
/*
* Generic Resource Deallocation Routines
*/
void
{
if (scsi_callback_id != 0) {
}
}
/*ARGSUSED*/
void
{
if (scsi_callback_id != 0) {
}
}
void
{
}
/*ARGSUSED*/
void
{
if (pkt->pkt_handle &&
}
}
void
{
if (scsi_callback_id != 0) {
}
}