1scsi_init_pkt(9F) Kernel Functions for Drivers scsi_init_pkt(9F)
2
3
4
6 scsi_init_pkt - prepare a complete SCSI packet
7
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
19 Solaris DDI specific (Solaris DDI).
20
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
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
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
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
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
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
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)