#include <sys/scsi/scsi.h>
struct scsi_pkt *scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pktp, struct buf *bp, int cmdlen, int statuslen, int privatelen, int flags, int (*callback )(caddr_t), caddr_t arg);
The flags argument is a set of bit flags. Possible bits include:
When calling scsi_init_pkt() to move already-allocated DMA resources, the cmdlen, statuslen and privatelen fields are ignored.
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:
- NULL_FUNC
- Do not wait for resources. Return a NULL pointer.
- SLEEP_FUNC
- Wait indefinitely for resources.
- Other Values
- callback points to a function which is called when resources may have become available. callback must return either 0 (indicating 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 indicating that it no longer cares for a retry.
When allocating DMA resources, scsi_init_pkt() returns the scsi_pkt field pkt_resid as the number of residual bytes for which the system was unable to allocate DMA resources. A pkt_resid of 0 means that all necessary DMA resources were allocated.
scsi_init_pkt() returns NULL if the packet or dma resources could not be allocated. Otherwise, it returns a pointer to an initialized scsi_pkt(9S) . If pktp was not NULL the return value will be pktp on successful initialization of the packet.
If callback is SLEEP_FUNC, then this routine may only be called from user-level code. Otherwise, it may be called from either user or interrupt level. The callback function may not block or call routines that block.
pkt = scsi_init_pkt(&devp->sd_address, NULL, NULL, CDB_GROUP1, STATUS_LEN, sizeof (struct my_pkt_private *), 0, sd_runout, sd_unit);
To allocate a packet with DMA resources attached use:
pkt = scsi_init_pkt(&devp->sd_address, NULL, bp, CDB_GROUP1, STATUS_LEN, 0, 0, NULL_FUNC, NULL);
To attach DMA resources to a preallocated packet, use:
pkt = scsi_init_pkt(&devp->sd_address, old_pkt, bp, 0, 0, 0, 0, sd_runout, (caddr_t) sd_unit);
Since the packet is already allocated the cmdlen, statuslen and privatelen are 0.
To allocate a packet with consistent DMA resources attached, use:
bp = scsi_alloc_consistent_buf(&devp->sd_address, NULL, SENSE_LENGTH, B_READ, SLEEP_FUNC, NULL); pkt = scsi_init_pkt(&devp->sd_address, NULL, bp, CDB_GROUP0, STATUS_LEN, sizeof (struct my_pkt_private *), PKT_CONSISTENT, SLEEP_FUNC, NULL);
To allocate a packet with partial DMA resources attached, use:
my_pkt = scsi_init_pkt(&devp->sd_address, NULL, bp, CDB_GROUP0, STATUS_LEN, sizeof (struct buf *), PKT_DMA_PARTIAL, SLEEP_FUNC, NULL);
If a DMA allocation request fails with DDI_DMA_NOMAPPING , the B_ERROR flag will be set in bp, and the b_error field will be set to EFAULT .
If a DMA allocation request fails with DDI_DMA_TOOBIG , the B_ERROR flag will be set in bp, and the b_error field will be set to EINVAL .