Writing Device Drivers


The scsi_init_pkt(9F) routine allocates and zeros a scsi_pkt(9S) structure; it also sets pointers to pkt_private, *pkt_scbp, and *pkt_cdbp. Additionally, it provides a callback mechanism to handle the case where resources are not available. This structure contains the following fields:

	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)

ap is a pointer to a scsi_address structure. This is the sd_address field of the device's scsi_device(9S) structure.

pktp is a pointer to the scsi_pkt(9S) structure to be initialized. If this is set to NULL, a new packet is allocated.

bp is a pointer to a buf(9S) structure. If this is non-NULL and contains a valid byte count, DMA resources are allocated.

cmdlen is the length of the SCSI command descriptor block in bytes.

statuslen is the required length of the SCSI status completion block in bytes.

privatelen is the number of bytes to allocate for the pkt_private field. To store a pointer, specify the size of the pointer here (such as sizeof(struct xxstate *) when storing a pointer to the state structure).

flags is a set of flags. Possible bits include:

callback specifies the action to take if resources are not available. If set to NULL_FUNC, scsi_init_pkt(9F) returns immediately (returning NULL). If set to SLEEP_FUNC, it 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 is the parameter to pass to the callback function.

The scsi_init_pkt(9F) routine synchronizes the data prior to transport. If the driver needs to access the data after transport, the scsi_sync_pkt(9F) routine can be used to synchronize any cached data.

The scsi_destroy_pkt(9F) routine synchronizes any remaining cached data associated with the packet, if necessary, and then frees the packet and associated command, status, and target driver-private data areas. This routine should be called in the command completion routine.

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, there is no need to call scsi_sync_pkt(9F) after the transport.