Kernel Functions for Drivers scsiinitpkt(9F)
NAME
scsiinitpkt - prepare a complete SCSI packet
SYNOPSIS
#include
struct scsipkt *scsiinitpkt(struct scsiaddress *ap,
struct scsipkt *pktp, struct buf *bp, int cmdlen, int statuslen,
int privatelen, int flags, int (*callback)(caddrt), caddrt arg);
INTERFACE LEVEL
Solaris DI specific (Solaris DI).
PARAMETERS
ap
Pointer to a scsiaddress(9S) structure.
pktp
A pointer to a scsipkt(9S) structure.
bp
Pointer to a buf(9S) structure.
cmdlen
The required length for the SCSI command descriptor
block (CDB) in bytes.
statuslen
The required length for the SCSI status completion block
(SCB) in bytes. Valid values are:
0
No status back.
1
Return SCSI status byte.
SunOS 5.11 Last change: 16 Jan 2006 1
Kernel Functions for Drivers scsiinitpkt(9F)
sizeof(scsiarqstatus)
Return status information in a scsiarqstatus
structure. This will include up to 20 bytes of sense
data. Please refer to scsiarqstatus(9S) for more
information.
For extra sense packets (PKTXARQ flag asserted),
set statuslen to be a greater number like, (N ]
sizeof(struct scsiarqstatus)) where N is the
number of extra bytes beyond the default 20. For
example, N=1 requests 21 bytes of sense, N=235 asks
for 255 bytes.
privatelen
The required length for the pktprivate area.
flags
Flags modifier.
callback
A pointer to a callback function, NULFUNC, or
SLEPFUNC.
arg
The callback function argument.
DESCRIPTION
Target drivers use scsiinitpkt() to request the transport
layer to allocate and initialize a packet for a SCSI command
which possibly includes a data transfer. If pktp is NUL, a
new scsipkt(9S) is allocated using the HBA driver's packet
allocator. The bp is a pointer to a buf(9S) structure. If bp
is non-NUL and contains a valid byte count, the buf(9S)
structure is also set up for DMA transfer using the HBA
driver DMA resources allocator. When bp is allocated by
scsiallocconsistentbuf(9F), the PKTCONSISTENT bit must
be set in the flags argument to ensure proper operation. If
privatelen is non-zero then additional space is allocated
for the pktprivate area of the scsipkt(9S). On return
pktprivate points to this additional space. Otherwise
pktprivate is a pointer that is typically used to store the
SunOS 5.11 Last change: 16 Jan 2006 2
Kernel Functions for Drivers scsiinitpkt(9F)
bp during execution of the command. In this case pktprivate
is NUL on return.
The flags argument is a set of bit flags. Possible bits
include:
PKTCONSISTENT
This must be set if the DMA buffer was allocated using
scsiallocconsistentbuf(9F). In this case, the HBA
driver will guarantee that the data transfer is properly
synchronized before performing the target driver's com-
mand completion callback.
PKTDMAPARTIAL
This may be set if the driver can accept a partial DMA
mapping. If set, scsiinitpkt() will allocate DMA
resources with the DIDMAPARTIAL bit set in the
dmarflag element of the ddidmareq(9S) structure. The
pktresid field of the scsipkt(9S) structure may be
returned with a non-zero value, which indicates the
number of bytes for which scsiinitpkt() was unable to
allocate DMA resources. In this case, a subsequent call
to scsiinitpkt() may be made for the same pktp and bp
to adjust the DMA resources to the next portion of the
transfer. This sequence should be repeated until the
pktresid field is returned with a zero value, which
indicates that with transport of this final portion the
entire original request will have been satisfied.
PKTXARQ
Setting this flag requests that the HBA return extra
sense data for this scsipkt(9S). The default auto
request sense mechanism returns up to 20 bytes. More
than 20 bytes of sense data can be requested by setting
this flag and setting the statuslen correctly. Set the
statuslen to be the sizeof(struct scsiarqstatus) plus
the number of sense bytes needed beyond 20. For example,
set statuslen to be (sizeof(struct scsiarqstatus) ] 5)
for 25 bytes of sense.
When calling scsiinitpkt() to move already-allocated DMA
resources, the cmdlen, statuslen, and privatelen fields are
ignored.
SunOS 5.11 Last change: 16 Jan 2006 3
Kernel Functions for Drivers scsiinitpkt(9F)
The last argument arg is supplied to the callback function
when it is invoked.
callback indicates what the allocator routines should do
when resources are not available:
NULFUNC Do not wait for resources. Return a NUL
pointer.
SLEPFUNC Wait indefinitely for resources.
Other Values callback points to a function which is
called when resources may have become avail-
able. callback must return either 0 (indi-
cating that it attempted to allocate
resources but again failed to do so), in
which case it is put back on a list to be
called again later, or 1 indicating either
success in allocating resources or indicat-
ing that it no longer cares for a retry.
When allocating DMA resources, scsiinitpkt() returns the
scsipkt field pktresid as the number of residual bytes for
which the system was unable to allocate DMA resources. A
pktresid of 0 means that all necessary DMA resources were
allocated.
RETURN VALUES
The scsiinitpkt() function returns NUL if the packet or
DMA resources could not be allocated. Otherwise, it returns
a pointer to an initialized scsipkt(9S). If pktp was not
NUL the return value will be pktp on successful initializa-
tion of the packet.
CONTEXT
If callback is SLEPFUNC, then this routine can be called
only from user-level code. Otherwise, it can be called from
user, interrupt, or kernel context. The callback function
may not block or call routines that block.
EXAMPLES
Example 1 Allocating a Packet Without DMA Resources Attached
To allocate a packet without DMA resources attached, use:
SunOS 5.11 Last change: 16 Jan 2006 4
Kernel Functions for Drivers scsiinitpkt(9F)
pkt = scsiinitpkt(&devp->sdaddress, NUL, NUL, CDBGROUP1,
1, sizeof (struct mypktprivate *), 0,
sdrunout, sdunit);
Example 2 Allocating a Packet With DMA Resources Attached
To allocate a packet with DMA resources attached use:
pkt = scsiinitpkt(&devp->sdaddress, NUL, bp, CDBGROUP1,
sizeof(struct scsiarqstatus), 0, 0, NULFUNC, NUL);
Example 3 Attaching DMA Resources to a Preallocated Packet
To attach DMA resources to a preallocated packet, use:
pkt = scsiinitpkt(&devp->sdaddress, oldpkt, bp, 0,
0, 0, 0, sdrunout, (caddrt) sdunit);
Example 4 Allocating a Packet with Consistent DMA Resources
Attached
Since the packet is already allocated, the cmdlen, statuslen
and privatelen are 0. To allocate a packet with consistent
DMA resources attached, use:
bp = scsiallocconsistentbuf(&devp->sdaddress, NUL,
SENSELENGTH, BREAD, SLEPFUNC, NUL);
pkt = scsiinitpkt(&devp->sdaddress, NUL, bp, CDBGROUP0,
sizeof(struct scsiarqstatus), sizeof (struct mypktprivate *),
PKTCONSISTENT, SLEPFUNC, NUL);
Example 5 Allocating a Packet with Partial DMA Resources
Attached
To allocate a packet with partial DMA resources attached,
use:
mypkt = scsiinitpkt(&devp->sdaddress, NUL, bp, CDBGROUP0,
1, sizeof (struct buf *), PKTDMAPARTIAL,
SLEPFUNC, NUL);
SunOS 5.11 Last change: 16 Jan 2006 5
Kernel Functions for Drivers scsiinitpkt(9F)
SEE ALSO
scsiallocconsistentbuf(9F), scsidestroypkt(9F),
scsidmaget(9F), scsipktalloc(9F), buf(9S),
ddidmareq(9S), scsiaddress(9S), scsipkt(9S)
Writing Device Drivers
NOTES
If a DMA allocation request fails with DIDMANOMAPING,
the BEROR flag will be set in bp, and the berror field
will be set to EFAULT.
If a DMA allocation request fails with DIDMATOBIG, the
BEROR flag will be set in bp, and the berror field will
be set to EINVAL.
SunOS 5.11 Last change: 16 Jan 2006 6
|