Resource Allocation
To send a SCSI command to the device, the target driver must create
and initialize a scsi_pkt(9S) structure. This structure must then be passed to the
host bus adapter driver.
scsi_init_pkt() Function
The scsi_init_pkt(9F) routine allocates and zeroes a scsi_pkt(9S) structure. scsi_init_pkt() also sets pointers
to pkt_private, *pkt_scbp, and *pkt_cdbp. Additionally, scsi_init_pkt() provides a callback mechanism to
handle the case where resources are not available. This function has the following
syntax:
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)
where:
- ap
Pointer to a scsi_address structure. ap is the sd_address field of the device's scsi_device(9S) structure.
- pktp
Pointer to the scsi_pkt(9S) structure to be initialized. If this pointer is set to NULL, a new packet is allocated.
- bp
Pointer to a buf(9S) structure. If this pointer is not null and has a valid byte count, DMA resources are allocated.
- cmdlen
Length of the SCSI command descriptor block in bytes.
- statuslen
Required length of the SCSI status completion block in bytes.
- privatelen
Number of bytes to allocate for the pkt_private field.
- flags
Set of flags:
PKT_CONSISTENT – This bit must be set if the DMA buffer was allocated using scsi_alloc_consistent_buf(9F). In this case, the host bus adapter driver guarantees that the data transfer is properly synchronized before performing the target driver's command completion callback.
PKT_DMA_PARTIAL – This bit can be set if the driver accepts a partial DMA mapping. If set, scsi_init_pkt(9F) allocates DMA resources with the DDI_DMA_PARTIAL flag set. The pkt_resid field of the scsi_pkt(9S) structure can be returned with a nonzero residual. A nonzero value indicates the number of bytes for which scsi_init_pkt(9F) was unable to allocate DMA resources.
- callback
Specifies the action to take if resources are not available. If set to NULL_FUNC, scsi_init_pkt(9F) returns the value NULL immediately. If set to SLEEP_FUNC, scsi_init_pkt() does not return until resources are available. Any other valid kernel address is interpreted as the address of a function to be called when resources are likely to be available.
- arg
Parameter to pass to the callback function.
The scsi_init_pkt() routine synchronizes the data prior to transport. If the driver needs
to access the data after transport, the driver should call scsi_sync_pkt(9F) to flush
any intermediate caches. The scsi_sync_pkt() routine can be used to synchronize any
cached data.
scsi_sync_pkt() Function
If the target driver needs to resubmit the packet after changing the data,
scsi_sync_pkt(9F) must be called before calling scsi_transport(9F). However, if the target
driver does not need to access the data, scsi_sync_pkt() does not need to
be called after the transport.
scsi_destroy_pkt() Function
The scsi_destroy_pkt(9F) routine synchronizes any remaining cached data that is associated with the
packet, if necessary. The routine then frees the packet and associated command, status,
and target driver-private data areas. This routine should be called in the command
completion routine.
scsi_alloc_consistent_buf() Function
For most I/O requests, the data buffer passed to the driver entry points
is not accessed directly by the driver. The buffer is just passed
on to scsi_init_pkt(9F). If a driver sends SCSI commands that operate on buffers that
the driver itself examines, the buffers should be DMA consistent. The SCSI request
sense command is a good example. The scsi_alloc_consistent_buf(9F) routine allocates a
buf(9S) structure and a data buffer that is suitable for DMA-consistent operations. The
HBA performs any necessary synchronization of the buffer before performing the command completion callback.
Note - scsi_alloc_consistent_buf(9F) uses scarce system resources. Thus, you should use scsi_alloc_consistent_buf() sparingly.
scsi_free_consistent_buf() Function
scsi_free_consistent_buf(9F) releases a buf(9S) structure and the associated data buffer allocated with scsi_alloc_consistent_buf(9F).
See attach() Entry Point (SCSI Target Drivers) and detach() Entry Point (SCSI Target Drivers) for examples.