scsi_init_pkt(9F)




NAME

     scsi_init_pkt - prepare a complete SCSI packet


SYNOPSIS

     #include <sys/scsi/scsi.h>

     struct  scsi_pkt  *scsi_init_pkt(struct  scsi_address   *ap,
     struct  scsi_pkt *pktp, struct buf *bp, int cmdlen, int sta-
     tuslen, int privatelen, int flags, int (*callback)(caddr_t),
     caddr_t arg);


INTERFACE LEVEL

     Solaris DDI specific (Solaris DDI).


PARAMETERS

      ap   Pointer to a scsi_address(9S) structure.

     pktp  A pointer to a scsi_pkt(9S) structure.

     bp    Pointer to a buf(9S) structure.

     cmdlen
           The required length for the  SCSI  command  descriptor
           block (CDB) in bytes.

     statuslen
           The required length for  the  SCSI  status  completion
           block (SCB) in bytes. Valid values are:

           0     No status back.

           1     Return SCSI status byte.

           sizeof(scsi_arq_status)
                 Return status information in  a  scsi_arq_status
                 structure.   This will include up to 20 bytes of
                 sense data. Please refer to  scsi_arq_status(9S)
                 for more information.

           EXTCMDS_STATUS_SIZE
                 Same as preceding.

     privatelen
           The required length for the pkt_private area.

     flags Flags modifier.

     callback
           A  pointer  to  a  callback  function,  NULL_FUNC,  or
           SLEEP_FUNC.

     arg   The callback function argument.


DESCRIPTION

     Target drivers use scsi_init_pkt() to request the  transport
     layer to allocate and initialize a packet for a SCSI command
     which possibly includes a data transfer. If pktp is NULL,  a
     new  scsi_pkt(9S) is allocated using the HBA driver's packet
     allocator. The bp is a pointer to a buf(9S) structure. If bp
     is  non-NULL  and  contains  a valid byte count, the buf(9S)
     structure is also set up for  DMA  transfer  using  the  HBA
     driver  DMA  resources  allocator.  When  bp is allocated by
     scsi_alloc_consistent_buf(9F), the PKT_CONSISTENT  bit  must
     be  set in the flags argument to ensure proper operation. If
     privatelen is non-zero then additional  space  is  allocated
     for  the  pkt_private  area  of the scsi_pkt(9S).  On return
     pkt_private points  to  this  additional  space.   Otherwise
     pkt_private is a pointer that is typically used to store the
     bp  during  execution  of  the  command.    In   this   case
     pkt_private is NULL on return.

     The flags argument is a set  of  bit  flags.  Possible  bits
     include:

          PKT_CONSISTENT
                This must be set if the DMA buffer was  allocated
                using   scsi_alloc_consistent_buf(9F).   In  this
                case, the HBA driver will guarantee that the data
                transfer is properly synchronized before perform-
                ing the target driver's command completion  call-
                back.

          PKT_DMA_PARTIAL
                This may be set if the driver can accept  a  par-
                tial  DMA  mapping.  If set, scsi_init_pkt() will
                allocate DMA resources with  the  DDI_DMA_PARTIAL
                bit   set   in   the  dmar_flag  element  of  the
                ddi_dma_req(9S) structure.  The  pkt_resid  field
                of  the  scsi_pkt(9S)  structure  may be returned
                with a non-zero value, which indicates the number
                of  bytes for which scsi_init_pkt() was unable to
                allocate DMA resources. In this  case,  a  subse-
                quent call to scsi_init_pkt() may be made for the
                same pktp and bp to adjust the DMA  resources  to
                the  next  portion of the transfer. This sequence
                should be repeated until the pkt_resid  field  is
                returned  with a zero value, which indicates that
                with transport of this final portion  the  entire
                original request will have been satisfied.

     When calling scsi_init_pkt() to move  already-allocated  DMA
     resources,  the cmdlen, statuslen, and privatelen fields are
     ignored.

     The last argument arg is supplied to the  callback  function
     when it is invoked.

     callback indicates what the  allocator  routines  should  do
     when resources are not available:

          NULL_FUNC
                Do not wait for resources. Return a NULL pointer.

          SLEEP_FUNC
                Wait indefinitely for resources.

          Other Values
                callback points to a  function  which  is  called
                when  resources  may have become available. call-
                back must return either  0  (indicating  that  it
                attempted  to allocate resources but again failed
                to do so), in which case it is put back on a list
                to  be called again later, or 1 indicating either
                success in  allocating  resources  or  indicating
                that it no longer cares for a retry.

     When allocating DMA resources, scsi_init_pkt()  returns  the
     scsi_pkt field pkt_resid as the number of residual bytes for
     which the system was unable to allocate  DMA  resources.   A
     pkt_resid  of  0 means that all necessary DMA resources were
     allocated.


RETURN VALUES

     scsi_init_pkt() returns NULL if the packet or DMA  resources
     could  not be allocated.  Otherwise, it returns a pointer to
     an initialized scsi_pkt(9S). If pktp was not NULL the return
     value  will  be  pktp  on  successful  initialization of the
     packet.


CONTEXT

     If callback is SLEEP_FUNC, then this  routine  may  only  be
     called  from  user-level  code.  Otherwise, it may be called
     from either user or interrupt level. The  callback  function
     may not block or call routines that block.


EXAMPLES

     Example  1:  Allocating  a  Packet  Without  DMA   Resources
     Attached

     To allocate a packet without DMA resources attached, use:

     pkt = scsi_init_pkt(&devp->sd_address, NULL, NULL, CDB_GROUP1,
             1, sizeof (struct my_pkt_private *), 0,
             sd_runout, sd_unit);

     Example 2: Allocating a Packet With DMA Resources Attached

     To allocate a packet with DMA resources attached use:

     pkt = scsi_init_pkt(&devp->sd_address, NULL, bp, CDB_GROUP1,
             sizeof(struct scsi_arq_status), 0, 0, NULL_FUNC, NULL);

     Example 3: Attaching DMA Resources to a Preallocated Packet

     To attach DMA resources to a preallocated packet, use:

     pkt = scsi_init_pkt(&devp->sd_address, old_pkt, bp, 0,
             0, 0, 0, sd_runout, (caddr_t) sd_unit);

     Example 4: Allocating a Packet with Consistent DMA Resources
     Attached

     Since the packet is already allocated, the cmdlen, statuslen
     and  privatelen  are 0. To allocate a packet with consistent
     DMA resources attached, use:

     bp = scsi_alloc_consistent_buf(&devp->sd_address, NULL,
                 SENSE_LENGTH, B_READ, SLEEP_FUNC, NULL);
          pkt = scsi_init_pkt(&devp->sd_address, NULL, bp, CDB_GROUP0,
             sizeof(struct scsi_arq_status), sizeof (struct my_pkt_private *),
             PKT_CONSISTENT, SLEEP_FUNC, NULL);

     Example 5: Allocating a Packet with  Partial  DMA  Resources
     Attached

     To allocate a packet with partial  DMA  resources  attached,
     use:

     my_pkt = scsi_init_pkt(&devp->sd_address, NULL, bp, CDB_GROUP0,
               1, sizeof (struct buf *), PKT_DMA_PARTIAL,
               SLEEP_FUNC, NULL);


SEE ALSO

     scsi_alloc_consistent_buf(9F),         scsi_destroy_pkt(9F),
     scsi_dmaget(9F),         scsi_pktalloc(9F),         buf(9S),
     ddi_dma_req(9S), scsi_address(9S), scsi_pkt(9S)

     Writing Device Drivers


NOTES

     If a DMA allocation request  fails  with  DDI_DMA_NOMAPPING,
     the  B_ERROR  flag  will be set in bp, and the b_error field
     will be set to EFAULT.

     If a DMA allocation request fails with  DDI_DMA_TOOBIG,  the
     B_ERROR  flag  will be set in bp, and the b_error field will
     be set to EINVAL.


Man(1) output converted with man2html