The routine scsi_init_pkt(9F) allocates space for a SCSI CDB, allocates DMA resources if necessary, and sets the pkt_flags field, as shown in this example:
pkt = scsi_init_pkt(&sdp->sd_address, NULL, bp, CDB_GROUP0, 1, 0, 0, SLEEP_FUNC, NULL);
This example creates a new packet along with allocating DMA resources as specified in the passed buf(9S) structure pointer. A SCSI CDB is allocated for a Group 0 (6-byte) command. The pkt_flags field is set to zero, but no space is allocated for the pkt_private field. This call to scsi_init_pkt(9F), because of the SLEEP_FUNC parameter, waits indefinitely for resources if no resources are currently available.
The next step is to initialize the SCSI CDB, using the scsi_setup_cdb(9F) function:
if (scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp, SCMD_READ, bp->b_blkno, bp->b_bcount >> DEV_BSHIFT, 0) == 0) goto failed;
This example builds a Group 0 command descriptor block. The example fills in the pkt_cdbp field as follows:
The command itself is in byte 0. The command is set from the parameter SCMD_READ.
The address field is in bits 0-4 of byte 1 and bytes 2 and 3. The address is set from bp->b_blkno.
The count field is in byte 4. The count is set from the last parameter. In this case, count is set to bp->b_bcount >> DEV_BSHIFT, where DEV_BSHIFT is the byte count of the transfer converted to the number of blocks.
scsi_setup_cdb(9F) does not support setting a target device's logical unit number (LUN) in bits 5-7 of byte 1 of the SCSI command block. This requirement is defined by SCSI-1. For SCSI-1 devices that require the LUN bits set in the command block, use makecom_g0(9F) or some equivalent rather than scsi_setup_cdb(9F).
After initializing the SCSI CDB, initialize three other fields in the packet and store as a pointer to the packet in the state structure.
pkt->pkt_private = (opaque_t)bp; pkt->pkt_comp = xxcallback; pkt->pkt_time = 30; xsp->pkt = pkt;
The buf(9S) pointer is saved in the pkt_private field for later use in the completion routine.