1usb_pipe_ctrl_xfer(9F) Kernel Functions for Drivers usb_pipe_ctrl_xfer(9F)
2
3
4
6 usb_pipe_ctrl_xfer, usb_pipe_ctrl_xfer_wait - USB control pipe transfer
7 functions
8
10 #include <sys/usb/usba.h>
11
12 int usb_pipe_ctrl_xfer(usb_pipe_handle_t pipe_handle,
13 usb_ctrl_req_t *request, usb_flags_t flags);
14
15
16
17 int usb_pipe_ctrl_xfer_wait(usb_pipe_handle_t pipe_handle,
18 usb_ctrl_setup_t *setup, mblk_t **data,
19 usb_cr_t * completion_reason, usb_cb_flags_t *cb_flags,
20 usb_flags_t flags);
21
22
24 Solaris DDI specific (Solaris DDI)
25
27 For usb_pipe_ctrl_xfer():
28
29 pipe_handle Control pipe handle on which request is made.
30
31
32 request Pointer to control transfer request.
33
34
35 flags USB_FLAGS_SLEEP is the only flag recognized. Wait for
36 all pending request callbacks to complete.
37
38
39
40 For usb_pipe_ctrl_xfer_wait():
41
42 pipe_handle Control pipe handle on which request is made.
43
44
45 setup Pointer to setup parameters. (See below.)
46
47
48 data Pointer to mblk containing data bytes to transfer
49 with command. Ignored if NULL.
50
51
52 completion_reason Returns overall completion status. Ignored if
53 NULL. Please see usb_callback_flags(9S) for more
54 information.
55
56
57 callback_flags Returns flags set either during autoclearing or
58 some other callback, which indicate recovery han‐
59 dling done in callback. Ignored if NULL.
60
61
62 flags No flags are recognized. Reserved for future
63 expansion.
64
65
67 The usb_pipe_ctrl_xfer() function requests the USBA framework to per‐
68 form a transfer through a USB control pipe. The request is passed to
69 the host controller driver (HCD), which performs the necessary transac‐
70 tions to complete the request. Requests are synchronous when
71 USB_FLAGS_SLEEP is specified in flags; calls for synchronous requests
72 do not return until their transaction is completed. Asynchronous
73 requests (made without specifying the USB_FLAGS_SLEEP flag) notifies
74 the caller of their completion via a callback function.
75
76
77 The usb_pipe_ctrl_xfer_wait() function is a wrapper around
78 usb_pipe_ctrl_xfer() that performs allocation and deallocation of all
79 required data structures, and a synchronous control-pipe transfer. It
80 takes a usb_ctrl_setup_t containing most usb setup parameters as an
81 argument:
82
83 uchar_t bmRequestType /* characteristics of request. */
84 /* (See USB 2.0 spec, section 9.3). */
85 /* Combine one direction of: */
86 /* USB_DEV_REQ_HOST_TO_DEV */
87 /* USB_DEV_REQ_DEV_TO_HOST */
88 /* with one request type of: */
89 /* USB_DEV_REQ_TYPE_STANDARD */
90 /* USB_DEV_REQ_TYPE_CLASS */
91 /* USB_DEV_REQ_TYPE_VENDOR */
92 /* with one recipient type of: */
93 /* USB_DEV_REQ_RCPT_DEV */
94 /* USB_DEV_REQ_RCPT_IF */
95 /* USB_DEV_REQ_RCPT_EP */
96 /* USB_DEV_REQ_RCPT_OTHER. */
97
98 uchar_t bRequest /* request or command. */
99 /* (See USB 2.0 spec, section */
100 /* 9.3 for standard commands.) */
101
102 uint16_t wValue /* value which varies according to */
103 /* the command (bRequest). */
104
105 uint16_t wIndex /* value which varies according to */
106 /* the command, typically used to */
107 /* pass an index or offset. */
108
109 uint16_t wLength /* number of data bytes to transfer */
110 /* with command, if any. Same as */
111 /* size of mblk "data" below. */
112
113 usb_req_attrs_t attrs; /* required request attributes */
114
115
116
117 Please see usb_request_attributes(9S), or refer to Section 5.5 of the
118 USB 2.0 specification for more information on these parameters. (The
119 USB 2.0 specification is available at www.usb.org.)
120
121
122 Mblks for data are allocated optionally when a request is allocated via
123 usb_alloc_ctrl_req(9F) by passing a positive value for the len argu‐
124 ment. Control requests passing or receiving no supplemental data need
125 not allocate an mblk.
126
128 For usb_pipe_ctrl_xfer():
129
130 USB_SUCCESS Transfer was successful.
131
132
133 USB_INVALID_ARGS Request is NULL.
134
135
136 USB_INVALID_CONTEXT Called from interrupt context with the
137 USB_FLAGS_SLEEP flag set.
138
139
140 USB_INVALID_REQUEST The request has been freed or otherwise inval‐
141 idated.
142
143 A set of conflicting attributes were speci‐
144 fied. See usb_request_attributes(9S).
145
146 The normal and/or exception callback is NULL
147 and USB_FLAGS_SLEEP is not set.
148
149 Data space not provided to a control request
150 while ctrl_wLength is nonzero.
151
152
153 USB_INVALID_PIPE Pipe handle is NULL or invalid.
154
155 Pipe is closing or closed.
156
157
158 USB_NO_RESOURCES Memory, descriptors or other resources
159 unavailable.
160
161
162 USB_HC_HARDWARE_ERROR Host controller is in error state.
163
164
165 USB_FAILURE An asynchronous transfer failed or an internal
166 error occurred.
167
168 The pipe is in an unsuitable state (error,
169 busy, not ready).
170
171
172
173 Additional status information may be available in the ctrl_comple‐
174 tion_reason and ctrl_cb_flags fields of the request. Please see
175 usb_callback_flags(9S) and usb_completion_reason(9S) for more informa‐
176 tion.
177
178
179 For usb_pipe_ctrl_xfer_wait():
180
181 USB_SUCCESS Request was successful.
182
183
184 USB_INVALID_CONTEXT Called from interrupt context.
185
186
187 USB_INVALID_ARGS dip is NULL.
188
189
190
191 Any error code returned by usb_pipe_ctrl_xfer().
192
193
194 Additional status information may be available in the ctrl_comple‐
195 tion_reason and ctrl_cb_flags fields of the request. Please see
196 usb_callback_flags(9S) and usb_completion_reason(9S) for more informa‐
197 tion.
198
200 The usb_pipe_ctrl_xfer() function may be called from kernel or user
201 context without regard to arguments and from the interrupt context only
202 when the USB_FLAGS_SLEEP flag is clear.
203
204
205 The usb_pipe_ctrl_xfer_wait() function may be called from kernel or
206 user context.
207
209 /* Allocate, initialize and issue a synchronous control request. */
210
211 usb_ctrl_req_t ctrl_req;
212 void control_pipe_exception_callback(
213 usb_pipe_handle_t, usb_ctrl_req_t*);
214
215 ctrl_req = usb_alloc_ctrl_req(dip, 0, USB_FLAGS_SLEEP);
216
217 ctrl_req->ctrl_bmRequestType = USB_DEV_REQ_HOST_TO_DEV |
218 USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_RCPT_OTHER;
219
220 ctrl_req->ctrl_bRequest = (uint8_t)USB_PRINTER_SOFT_RESET;
221 ctrl_req->ctrl_exc_cb = control_pipe_exception_callback;
222 ...
223 ...
224 if ((rval = usb_pipe_ctrl_xfer(pipe, ctrl_req, USB_FLAGS_SLEEP))
225 != USB_SUCCESS) {
226 cmn_err (CE_WARN, "%s%d: Error issuing USB cmd.",
227 ddi_driver_name(dip), ddi_get_instance(dip));
228 }
229
230 -------
231
232 /*
233 * Allocate, initialize and issue an asynchronous control request to
234 * read a configuration descriptor.
235 */
236
237 usb_ctrl_req_t *ctrl_req;
238 void control_pipe_normal_callback(
239 usb_pipe_handle_t, usb_ctrl_req_t*);
240 void control_pipe_exception_callback(
241 usb_pipe_handle_t, usb_ctrl_req_t*);
242 struct buf *bp = ...;
243
244 ctrl_req =
245 usb_alloc_ctrl_req(dip, sizeof(usb_cfg_descr_t), USB_FLAGS_SLEEP);
246
247 ctrl_req->ctrl_bmRequestType = USB_DEV_REQ_DEV_TO_HOST |
248 USB_DEV_REQ_TYPE_STANDARD | USB_DEV_REQ_RCPT_DEV;
249
250 ctrl_req->ctrl_wLength = sizeof(usb_cfg_descr_t);
251 ctrl_req->ctrl_wValue = USB_DESCR_TYPE_SETUP_CFG | 0;
252 ctrl_req->ctrl_bRequest = (uint8_t)USB_REQ_GET_DESCR;
253 ctrl_req->ctrl_cb = control_pipe_normal_callback;
254 ctrl_req->ctrl_exc_cb = control_pipe_exception_callback;
255
256 /* Make buf struct available to callback handler. */
257 ctrl_req->ctrl_client_private = (usb_opaque_t)bp;
258 ...
259 ...
260 if ((rval = usb_pipe_ctrl_xfer(pipe, ctrl_req, USB_FLAGS_NOSLEEP))
261 != USB_SUCCESS) {
262 cmn_err (CE_WARN, "%s%d: Error issuing USB cmd.",
263 ddi_driver_name(dip), ddi_get_instance(dip));
264 }
265
266 -------
267
268 /* Call usb_pipe_ctrl_xfer_wait() to get device status. */
269
270 mblk_t *data;
271 usb_cr_t completion_reason;
272 usb_cb_flags_t callback_flags;
273 usb_ctrl_setup_t setup_params = {
274 USB_DEV_REQ_DEV_TO_HOST | /* bmRequestType */
275 USB_DEV_REQ_TYPE_STANDARD | USB_DEV_REQ_RCPT_DEV,
276 USB_REQ_GET_STATUS, /* bRequest */
277 0, /* wValue */
278 0, /* wIndex */
279 USB_GET_STATUS_LEN, /* wLength */
280 0 /* attributes. */
281 };
282
283 if (usb_pipe_ctrl_xfer_wait(
284 pipe,
285 &setup_params,
286 &data,
287 &compleetion_reason,
288 &callback_flags,
289 0) != USB_SUCCESS) {
290 cmn_err (CE_WARN,
291 "%s%d: USB get status command failed: "
292 "reason=%d callback_flags=0x%x",
293 ddi_driver_name(dip), ddi_get_instance(dip),
294 completion_reason, callback_flags);
295 return (EIO);
296 }
297
298 /* Check data length. Should be USB_GET_STATUS_LEN (2 bytes). */
299 length_returned = data->b_wptr - data->b_rptr;
300 if (length_returned != USB_GET_STATUS_LEN) {
301 cmn_err (CE_WARN,
302 "%s%d: USB get status command returned %d bytes of data.",
303 ddi_driver_name(dip), ddi_get_instance(dip), length_returned);
304 return (EIO);
305 }
306
307 /* Retrieve data in endian neutral way. */
308 status = (*(data->b_rptr + 1) << 8) | *(data->b_rptr);
309
310
311
313 See attributes(5) for descriptions of the following attributes:
314
315
316
317
318 ┌─────────────────────────────┬─────────────────────────────┐
319 │ ATTRIBUTE TYPE │ ATTRIBUTE VALUE │
320 ├─────────────────────────────┼─────────────────────────────┤
321 │Architecture │PCI-based systems │
322 ├─────────────────────────────┼─────────────────────────────┤
323 │Interface stability │Committed │
324 ├─────────────────────────────┼─────────────────────────────┤
325 │Availability │SUNWusb │
326 └─────────────────────────────┴─────────────────────────────┘
327
329 attributes(5), usb_alloc_request(9F), usb_get_cfg(9F), usb_get_sta‐
330 tus(9F). usb_pipe_bulk_xfer(9F), usb_pipe_intr_xfer(9F),
331 usb_pipe_isoc_xfer(9F), usb_pipe_open(9F), usb_pipe_reset(9F),
332 usb_pipe_get_state(9F), usb_bulk_request(9S), usb_callback_flags(9S),
333 usb_ctrl_request(9S), usb_completion_reason(9S), usb_intr_request(9S),
334 usb_isoc_request(9S)
335
336
337
338SunOS 5.11 15 Sep 2009 usb_pipe_ctrl_xfer(9F)