编写设备驱动程序

分配和初始化 scsi_pkt(9S) 结构

如果 pktNULL,则 tran_init_pkt(9E) 入口点必须通过 scsi_hba_pkt_alloc(9F) 分配 scsi_pkt(9S) 结构。

scsi_hba_pkt_alloc(9F) 可为以下各项分配空间:

除以下成员外,必须将 scsi_pkt(9S) 结构成员(包括 pkt)初始化为零:

这些成员是指向存储字段值的内存空间的指针,如下图所示。有关更多信息,请参阅scsi_pkt 结构 (HBA)

图 18–5 scsi_pkt(9S) 结构指针

图中显示了包含指向值而未初始化为零的那些成员的 scsi_pkt 结构。

以下示例说明了 scsi_pkt 结构的分配和初始化。


示例 18–2 SCSI 包结构的 HBA 驱动程序初始化

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);
}