1scsi_init_pkt(9F)        Kernel Functions for Drivers        scsi_init_pkt(9F)
2
3
4

NAME

6       scsi_init_pkt - prepare a complete SCSI packet
7

SYNOPSIS

9       #include <sys/scsi/scsi.h>
10
11
12
13       struct scsi_pkt *scsi_init_pkt(struct scsi_address *ap,
14            struct scsi_pkt *pktp, struct buf *bp, int cmdlen, int statuslen,
15            int privatelen, int flags, int (*callback)(caddr_t), caddr_t arg);
16
17

INTERFACE LEVEL

19       Solaris DDI specific (Solaris DDI).
20

PARAMETERS

22       ap
23
24           Pointer to a scsi_address(9S) structure.
25
26
27       pktp
28
29           A pointer to a scsi_pkt(9S) structure.
30
31
32       bp
33
34           Pointer to a buf(9S) structure.
35
36
37       cmdlen
38
39           The  required length for the SCSI command descriptor block (CDB) in
40           bytes.
41
42
43       statuslen
44
45           The required length for the SCSI status completion block  (SCB)  in
46           bytes. Valid values are:
47
48           0
49
50               No status back.
51
52
53           1
54
55               Return SCSI status byte.
56
57
58           sizeof(scsi_arq_status)
59
60               Return  status information in a scsi_arq_status structure. This
61               will include up to 20 bytes of  sense  data.  Please  refer  to
62               scsi_arq_status(9S) for more information.
63
64               For extra sense packets (PKT_XARQ flag asserted), set statuslen
65               to be a greater number like, (N +  sizeof(struct  scsi_arq_sta‐
66               tus))  where  N is the number of extra bytes beyond the default
67               20. For example, N=1 requests 21 bytes of sense, N=235 asks for
68               255 bytes.
69
70
71
72       privatelen
73
74           The required length for the pkt_private area.
75
76
77       flags
78
79           Flags modifier.
80
81
82       callback
83
84           A pointer to a callback function, NULL_FUNC, or SLEEP_FUNC.
85
86
87       arg
88
89           The callback function argument.
90
91

DESCRIPTION

93       Target  drivers  use  scsi_init_pkt() to request the transport layer to
94       allocate and initialize a packet for  a  SCSI  command  which  possibly
95       includes  a data transfer. If pktp is NULL, a new scsi_pkt(9S) is allo‐
96       cated using the HBA driver's packet allocator. The bp is a pointer to a
97       buf(9S)  structure.  If bp is non-NULL and contains a valid byte count,
98       the buf(9S) structure is also set up for DMA  transfer  using  the  HBA
99       driver DMA resources allocator. When bp is allocated by scsi_alloc_con‐
100       sistent_buf(9F), the PKT_CONSISTENT bit must be set in the flags  argu‐
101       ment  to  ensure proper operation. If privatelen is non-zero then addi‐
102       tional space is allocated for the pkt_private area of the scsi_pkt(9S).
103       On  return  pkt_private  points  to  this  additional  space. Otherwise
104       pkt_private is a pointer that is typically used to store the bp  during
105       execution of the command. In this case pkt_private is NULL on return.
106
107
108       The flags argument is a set of bit flags. Possible bits include:
109
110       PKT_CONSISTENT
111
112           This   must   be   set  if  the  DMA  buffer  was  allocated  using
113           scsi_alloc_consistent_buf(9F). In this case, the  HBA  driver  will
114           guarantee  that  the  data transfer is properly synchronized before
115           performing the target driver's command completion callback.
116
117
118       PKT_DMA_PARTIAL
119
120           This may be set if the driver can accept a partial DMA mapping.  If
121           set,   scsi_init_pkt()   will   allocate  DMA  resources  with  the
122           DDI_DMA_PARTIAL  bit  set  in  the   dmar_flag   element   of   the
123           ddi_dma_req(9S)  structure. The pkt_resid field of the scsi_pkt(9S)
124           structure may be returned with a non-zero  value,  which  indicates
125           the  number  of bytes for which scsi_init_pkt() was unable to allo‐
126           cate  DMA  resources.  In  this  case,   a   subsequent   call   to
127           scsi_init_pkt()  may be made for the same pktp and bp to adjust the
128           DMA resources to the next portion of the  transfer.  This  sequence
129           should  be  repeated  until  the pkt_resid field is returned with a
130           zero value, which indicates that with transport of this final  por‐
131           tion the entire original request will have been satisfied.
132
133
134       PKT_XARQ
135
136           Setting  this  flag  requests that the HBA return  extra sense data
137           for this scsi_pkt(9S). The default  auto  request  sense  mechanism
138           returns  up  to   20 bytes. More than 20 bytes of sense data can be
139           requested by setting this flag and setting the statuslen correctly.
140           Set the statuslen to be the sizeof(struct scsi_arq_status) plus the
141           number of sense bytes needed beyond 20. For example, set  statuslen
142           to be (sizeof(struct scsi_arq_status) + 5) for 25 bytes of sense.
143
144
145
146       When  calling  scsi_init_pkt() to move already-allocated DMA resources,
147       the cmdlen, statuslen, and privatelen fields are ignored.
148
149
150       The last argument arg is supplied to the callback function when  it  is
151       invoked.
152
153
154       callback indicates what the allocator routines should do when resources
155       are not available:
156
157       NULL_FUNC       Do not wait for resources. Return a NULL pointer.
158
159
160       SLEEP_FUNC      Wait indefinitely for resources.
161
162
163       Other Values    callback points to a  function  which  is  called  when
164                       resources  may  have  become  available.  callback must
165                       return either 0 (indicating that it attempted to  allo‐
166                       cate  resources  but  again  failed to do so), in which
167                       case it is put back on a list to be called again later,
168                       or  1 indicating either success in allocating resources
169                       or indicating that it no longer cares for a retry.
170
171
172
173       When allocating DMA resources,  scsi_init_pkt()  returns  the  scsi_pkt
174       field  pkt_resid  as  the number of residual bytes for which the system
175       was unable to allocate DMA resources.  A pkt_resid of 0 means that  all
176       necessary DMA resources were allocated.
177

RETURN VALUES

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

CONTEXT

185       If callback is SLEEP_FUNC, then this routine can be  called  only  from
186       user-level  code.  Otherwise, it can be called from user, interrupt, or
187       kernel context. The callback function may not block  or  call  routines
188       that block.
189

EXAMPLES

191       Example 1 Allocating a Packet Without DMA Resources Attached
192
193
194       To allocate a packet without DMA resources attached, use:
195
196
197         pkt = scsi_init_pkt(&devp->sd_address, NULL, NULL, CDB_GROUP1,
198                 1, sizeof (struct my_pkt_private *), 0,
199                 sd_runout, sd_unit);
200
201
202       Example 2 Allocating a Packet With DMA Resources Attached
203
204
205       To allocate a packet with DMA resources attached use:
206
207
208         pkt = scsi_init_pkt(&devp->sd_address, NULL, bp, CDB_GROUP1,
209                 sizeof(struct scsi_arq_status), 0, 0, NULL_FUNC, NULL);
210
211
212       Example 3 Attaching DMA Resources to a Preallocated Packet
213
214
215       To attach DMA resources to a preallocated packet, use:
216
217
218         pkt = scsi_init_pkt(&devp->sd_address, old_pkt, bp, 0,
219                 0, 0, 0, sd_runout, (caddr_t) sd_unit);
220
221
222       Example 4 Allocating a Packet with Consistent DMA Resources Attached
223
224
225       Since  the  packet is already allocated, the cmdlen, statuslen and pri‐
226       vatelen are 0. To allocate  a  packet  with  consistent  DMA  resources
227       attached, use:
228
229
230         bp = scsi_alloc_consistent_buf(&devp->sd_address, NULL,
231                     SENSE_LENGTH, B_READ, SLEEP_FUNC, NULL);
232              pkt = scsi_init_pkt(&devp->sd_address, NULL, bp, CDB_GROUP0,
233                 sizeof(struct scsi_arq_status), sizeof (struct my_pkt_private *),
234                 PKT_CONSISTENT, SLEEP_FUNC, NULL);
235
236
237       Example 5 Allocating a Packet with Partial DMA Resources Attached
238
239
240       To allocate a packet with partial DMA resources attached, use:
241
242
243         my_pkt = scsi_init_pkt(&devp->sd_address, NULL, bp, CDB_GROUP0,
244                   1, sizeof (struct buf *), PKT_DMA_PARTIAL,
245                   SLEEP_FUNC, NULL);
246
247

SEE ALSO

249       scsi_alloc_consistent_buf(9F),  scsi_destroy_pkt(9F),  scsi_dmaget(9F),
250       scsi_pktalloc(9F),    buf(9S),    ddi_dma_req(9S),    scsi_address(9S),
251       scsi_pkt(9S)
252
253
254       Writing Device Drivers
255

NOTES

257       If  a  DMA allocation request fails with DDI_DMA_NOMAPPING, the B_ERROR
258       flag will be set in bp, and the b_error field will be set to EFAULT.
259
260
261       If a DMA allocation request fails with DDI_DMA_TOOBIG, the B_ERROR flag
262       will be set in bp, and the b_error field will be set to EINVAL.
263
264
265
266SunOS 5.11                        16 Jan 2006                scsi_init_pkt(9F)
Impressum