The tran_init_pkt(9E) entry point must allocate a scsi_pkt(9S) structure through scsi_hba_pkt_alloc(9F) if pkt is NULL.
scsi_hba_pkt_alloc(9F) allocates space for the following items:
SCSI CDB of length cmdlen
Completion area for SCSI status of length statuslen
Per-packet target driver private data area of length tgtlen
Per-packet HBA driver private data area of length hbalen
The scsi_pkt(9S) structure members, including pkt, must be initialized to zero except for the following members:
pkt_scbp – Status completion
pkt_cdbp – CDB
pkt_ha_private – HBA driver private data
pkt_private – Target driver private data
These members are pointers to memory space where the values of the fields are stored, as shown in the following figure. For more information, refer to scsi_pkt Structure (HBA).
The following example shows allocation and initialization of a scsi_pkt structure.
static struct scsi_pkt * isp_scsi_init_pkt( struct scsi_address *ap, struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags, int (*callback)(), caddr_t arg) { struct isp_cmd *sp; struct isp *isp; struct scsi_pkt *new_pkt; ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC); isp = (struct isp *)ap->a_hba_tran->tran_hba_private; /* * First step of isp_scsi_init_pkt: pkt allocation */ if (pkt == NULL) { pkt = scsi_hba_pkt_alloc(isp->isp_dip, ap, cmdlen, statuslen, tgtlen, sizeof (struct isp_cmd), callback, arg); if (pkt == NULL) { return (NULL); } sp = (struct isp_cmd *)pkt->pkt_ha_private; /* * Initialize the new pkt */ sp->cmd_pkt = pkt; sp->cmd_flags = 0; sp->cmd_scblen = statuslen; sp->cmd_cdblen = cmdlen; sp->cmd_dmahandle = NULL; sp->cmd_ncookies = 0; sp->cmd_cookie = 0; sp->cmd_cookiecnt = 0; sp->cmd_nwin = 0; pkt->pkt_address = *ap; pkt->pkt_comp = (void (*)())NULL; pkt->pkt_flags = 0; pkt->pkt_time = 0; pkt->pkt_resid = 0; pkt->pkt_statistics = 0; pkt->pkt_reason = 0; new_pkt = pkt; } else { sp = (struct isp_cmd *)pkt->pkt_ha_private; new_pkt = NULL; } /* * Second step of isp_scsi_init_pkt: dma allocation/move */ if (bp && bp->b_bcount != 0) { if (sp->cmd_dmahandle == NULL) { if (isp_i_dma_alloc(isp, pkt, bp, flags, callback) == 0) { if (new_pkt) { scsi_hba_pkt_free(ap, new_pkt); } return ((struct scsi_pkt *)NULL); } } else { ASSERT(new_pkt == NULL); if (isp_i_dma_move(isp, pkt, bp) == 0) { return ((struct scsi_pkt *)NULL); } } } return (pkt); }