This source file includes following definitions.
- usbf_errstr
- usbf_realloc
- usbf_probe_and_attach
- usbf_remove_device
- usbf_new_device
- usbf_devinfo_setup
- usbf_devinfo_alloc
- usbf_devinfo_free
- usbf_add_string
- usbf_string_descriptor
- usbf_get_string
- usbf_add_config
- usbf_add_config_desc
- usbf_add_interface
- usbf_add_endpoint
- usbf_end_config
- usbf_device_descriptor
- usbf_config_descriptor
- usbf_interface_number
- usbf_endpoint_address
- usbf_endpoint_attributes
- usbf_open_pipe
- usbf_open_pipe_ival
- usbf_setup_pipe
- usbf_abort_pipe
- usbf_close_pipe
- usbf_stall_pipe
- usbf_iface_endpoint
- usbf_config_endpoint
- usbf_set_endpoint_halt
- usbf_clear_endpoint_halt
- usbf_set_endpoint_feature
- usbf_clear_endpoint_feature
- usbf_alloc_xfer
- usbf_free_xfer
- usbf_allocmem
- usbf_freemem
- usbf_alloc_buffer
- usbf_free_buffer
- usbf_dump_buffer
- usbf_setup_xfer
- usbf_setup_default_xfer
- usbf_get_xfer_status
- usbf_transfer
- usbf_insert_transfer
- usbf_start_next
- usbf_transfer_complete
- usbf_softintr_establish
- usbf_schedsoftintr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <sys/param.h>
24 #include <sys/malloc.h>
25 #include <sys/systm.h>
26 #include <sys/timeout.h>
27
28 #include <machine/bus.h>
29
30 #include <dev/usb/usb.h>
31 #include <dev/usb/usbdi.h>
32 #include <dev/usb/usbdivar.h>
33 #include <dev/usb/usb_mem.h>
34 #include <dev/usb/usbf.h>
35 #include <dev/usb/usbfvar.h>
36
37 #ifndef USBF_DEBUG
38 #define DPRINTF(l, x) do {} while (0)
39 #else
40 extern int usbfdebug;
41 #define DPRINTF(l, x) if ((l) <= usbfdebug) printf x; else {}
42 #endif
43
44 void *usbf_realloc(void **, size_t *, size_t);
45 size_t usbf_get_string(usbf_device_handle, u_int8_t, char *, size_t);
46 usbf_status usbf_open_pipe_ival(usbf_interface_handle, u_int8_t,
47 usbf_pipe_handle *, int);
48 usbf_status usbf_setup_pipe(usbf_device_handle, usbf_interface_handle,
49 struct usbf_endpoint *, int,
50 usbf_pipe_handle *);
51 void usbf_start_next(usbf_pipe_handle);
52 void usbf_set_endpoint_halt(usbf_endpoint_handle);
53 void usbf_clear_endpoint_halt(usbf_endpoint_handle);
54
55 static const char * const usbf_error_strs[] = USBF_ERROR_STRS;
56
57 const char *
58 usbf_errstr(usbf_status err)
59 {
60 static char buffer[5];
61
62 if (err < USBF_ERROR_MAX)
63 return usbf_error_strs[err];
64
65 snprintf(buffer, sizeof buffer, "%d", err);
66 return buffer;
67 }
68
69 void *
70 usbf_realloc(void **pp, size_t *sizep, size_t newsize)
71 {
72 void *p;
73 size_t oldsize;
74
75 if (newsize == 0) {
76 if (*sizep > 0)
77 free(*pp, M_USB);
78 *pp = NULL;
79 *sizep = 0;
80 return NULL;
81 }
82
83 p = malloc(newsize, M_USB, M_NOWAIT);
84 if (p == NULL)
85 return NULL;
86
87 oldsize = MIN(*sizep, newsize);
88 if (oldsize > 0)
89 bcopy(*pp, p, oldsize);
90 *pp = p;
91 *sizep = newsize;
92 return p;
93 }
94
95
96
97
98 static usbf_status
99 usbf_probe_and_attach(struct device *parent, usbf_device_handle dev, int port)
100 {
101 struct usbf_attach_arg uaa;
102 struct device *dv;
103
104 KASSERT(dev->function == NULL);
105
106 bzero(&uaa, sizeof uaa);
107 uaa.device = dev;
108
109
110
111
112
113
114
115 dv = config_found_sm(parent, &uaa, NULL, NULL);
116 if (dv != NULL) {
117 dev->function = (struct usbf_function *)dv;
118 return USBF_NORMAL_COMPLETION;
119 }
120
121
122
123
124
125
126 return USBF_NORMAL_COMPLETION;
127 }
128
129 static void
130 usbf_remove_device(usbf_device_handle dev, struct usbf_port *up)
131 {
132 KASSERT(dev != NULL && dev == up->device);
133
134 if (dev->function != NULL)
135 config_detach((struct device *)dev->function, DETACH_FORCE);
136 if (dev->default_pipe != NULL)
137 usbf_close_pipe(dev->default_pipe);
138 up->device = NULL;
139 free(dev, M_USB);
140 }
141
142 usbf_status
143 usbf_new_device(struct device *parent, usbf_bus_handle bus, int depth,
144 int speed, int port, struct usbf_port *up)
145 {
146 struct usbf_device *dev;
147 usb_device_descriptor_t *ud;
148 usbf_status err;
149
150 #ifdef DIAGNOSTIC
151 KASSERT(up->device == NULL);
152 #endif
153
154 dev = malloc(sizeof(*dev), M_USB, M_NOWAIT);
155 if (dev == NULL)
156 return USBF_NOMEM;
157
158 bzero(dev, sizeof *dev);
159 dev->bus = bus;
160 dev->string_id = USBF_STRING_ID_MIN;
161 SIMPLEQ_INIT(&dev->configs);
162
163
164 USETW(dev->status.wStatus, UDS_SELF_POWERED);
165
166
167
168
169
170 ud = &dev->ddesc;
171 ud->bLength = USB_DEVICE_DESCRIPTOR_SIZE;
172 ud->bDescriptorType = UDESC_DEVICE;
173 ud->bMaxPacketSize = bus->ep0_maxp;
174 if (bus->usbrev >= USBREV_2_0)
175 USETW(ud->bcdUSB, UD_USB_2_0);
176 else
177 USETW(ud->bcdUSB, 0x0101);
178
179
180 dev->def_ep.edesc = &dev->def_ep_desc;
181 dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
182 dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT;
183 dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
184 dev->def_ep_desc.bmAttributes = UE_CONTROL;
185 USETW(dev->def_ep_desc.wMaxPacketSize, ud->bMaxPacketSize);
186 dev->def_ep_desc.bInterval = 0;
187
188
189 err = usbf_setup_pipe(dev, NULL, &dev->def_ep, 0,
190 &dev->default_pipe);
191 if (err) {
192 free(dev, M_USB);
193 return err;
194 }
195
196
197 dev->default_xfer = usbf_alloc_xfer(dev);
198 dev->data_xfer = usbf_alloc_xfer(dev);
199 if (dev->default_xfer == NULL || dev->data_xfer == NULL) {
200 if (dev->default_xfer != NULL)
201 usbf_free_xfer(dev->default_xfer);
202 usbf_close_pipe(dev->default_pipe);
203 free(dev, M_USB);
204 return USBF_NOMEM;
205 }
206
207
208 usbf_setup_default_xfer(dev->default_xfer, dev->default_pipe,
209 NULL, &dev->def_req, 0, 0, usbf_do_request);
210 err = usbf_transfer(dev->default_xfer);
211 if (err && err != USBF_IN_PROGRESS) {
212 usbf_free_xfer(dev->default_xfer);
213 usbf_free_xfer(dev->data_xfer);
214 usbf_close_pipe(dev->default_pipe);
215 free(dev, M_USB);
216 return err;
217 }
218
219
220 bzero(up, sizeof *up);
221 up->portno = port;
222 up->device = dev;
223
224
225 err = usbf_probe_and_attach(parent, dev, port);
226 if (err)
227 usbf_remove_device(dev, up);
228 return err;
229 }
230
231
232
233
234
235 void
236 usbf_devinfo_setup(usbf_device_handle dev, u_int8_t devclass,
237 u_int8_t subclass, u_int8_t proto, u_int16_t vendor, u_int16_t product,
238 u_int16_t device, const char *manf, const char *prod, const char *ser)
239 {
240 usb_device_descriptor_t *dd;
241
242 dd = usbf_device_descriptor(dev);
243 dd->bDeviceClass = devclass;
244 dd->bDeviceSubClass = subclass;
245 dd->bDeviceProtocol = proto;
246 if (vendor != 0)
247 USETW(dd->idVendor, vendor);
248 if (product != 0)
249 USETW(dd->idProduct, product);
250 if (device != 0)
251 USETW(dd->bcdDevice, device);
252 if (manf != NULL)
253 dd->iManufacturer = usbf_add_string(dev, manf);
254 if (prod != NULL)
255 dd->iProduct = usbf_add_string(dev, prod);
256 if (ser != NULL)
257 dd->iSerialNumber = usbf_add_string(dev, ser);
258 }
259
260 char *
261 usbf_devinfo_alloc(usbf_device_handle dev)
262 {
263 char manf[40];
264 char prod[40];
265 usb_device_descriptor_t *dd;
266 size_t len;
267 char *devinfo;
268
269 dd = usbf_device_descriptor(dev);
270 usbf_get_string(dev, dd->iManufacturer, manf, sizeof manf);
271 usbf_get_string(dev, dd->iProduct, prod, sizeof prod);
272
273 len = strlen(manf) + strlen(prod) + 32;
274 devinfo = malloc(len, M_USB, M_NOWAIT);
275 if (devinfo == NULL)
276 return NULL;
277
278 snprintf(devinfo, len, "%s %s, rev %d.%02d/%d.%02d", manf, prod,
279 (UGETW(dd->bcdUSB)>>8) & 0xff, UGETW(dd->bcdUSB) & 0xff,
280 (UGETW(dd->bcdDevice)>>8) & 0xff, UGETW(dd->bcdDevice) & 0xff);
281 return devinfo;
282 }
283
284 void
285 usbf_devinfo_free(char *devinfo)
286 {
287 if (devinfo != NULL)
288 free(devinfo, M_USB);
289 }
290
291
292
293
294
295
296
297
298 u_int8_t
299 usbf_add_string(usbf_device_handle dev, const char *string)
300 {
301 usb_string_descriptor_t *sd;
302 size_t oldsize;
303 size_t newsize;
304 size_t len, i;
305 u_int8_t id;
306
307 if (string == NULL || *string == '\0' ||
308 dev->string_id == USBF_STRING_ID_MAX)
309 return USBF_EMPTY_STRING_ID;
310
311 if ((len = strlen(string)) >= USB_MAX_STRING_LEN)
312 len = USB_MAX_STRING_LEN - 1;
313
314 oldsize = dev->sdesc_size;
315 newsize = oldsize + 2 + 2 * len;
316
317 sd = usbf_realloc((void **)&dev->sdesc, &dev->sdesc_size,
318 newsize);
319 if (sd == NULL)
320 return USBF_EMPTY_STRING_ID;
321
322 sd = (usb_string_descriptor_t *)((char *)sd + oldsize);
323 sd->bLength = newsize - oldsize;
324 sd->bDescriptorType = UDESC_STRING;
325 for (i = 0; string[i] != '\0' && i < len; i++)
326 USETW(sd->bString[i], string[i]);
327
328 id = dev->string_id++;
329 return id;
330 }
331
332 usb_string_descriptor_t *
333 usbf_string_descriptor(usbf_device_handle dev, u_int8_t id)
334 {
335 static usb_string_descriptor_t sd0;
336 static usb_string_descriptor_t sd1;
337 usb_string_descriptor_t *sd;
338
339
340 switch (id) {
341 case USB_LANGUAGE_TABLE:
342 sd0.bLength = 4;
343 sd0.bDescriptorType = UDESC_STRING;
344 USETW(sd0.bString[0], 0x0409 );
345 return &sd0;
346
347 case USBF_EMPTY_STRING_ID:
348 sd1.bLength = 2;
349 sd1.bDescriptorType = UDESC_STRING;
350 return &sd0;
351 }
352
353
354 if (id > dev->string_id)
355 return NULL;
356
357
358 id -= USBF_STRING_ID_MIN;
359 sd = dev->sdesc;
360 while (id-- > 0)
361 sd = (usb_string_descriptor_t *)((char *)sd + sd->bLength);
362 return sd;
363 }
364
365 size_t
366 usbf_get_string(usbf_device_handle dev, u_int8_t id, char *s, size_t size)
367 {
368 usb_string_descriptor_t *sd = NULL;
369 size_t i, len;
370
371 if (id != USB_LANGUAGE_TABLE)
372 sd = usbf_string_descriptor(dev, id);
373
374 if (sd == NULL) {
375 if (size > 0)
376 *s = '\0';
377 return 0;
378 }
379
380 len = (sd->bLength - 2) / 2;
381 if (size < 1)
382 return len;
383
384 for (i = 0; i < (size - 1) && i < len; i++)
385 s[i] = UGETW(sd->bString[i]) & 0xff;
386 s[i] = '\0';
387 return len;
388 }
389
390
391
392
393
394 usbf_status
395 usbf_add_config(usbf_device_handle dev, usbf_config_handle *ucp)
396 {
397 struct usbf_config *uc;
398 usb_config_descriptor_t *cd;
399
400 uc = malloc(sizeof *uc, M_USB, M_NOWAIT);
401 if (uc == NULL)
402 return USBF_NOMEM;
403
404 cd = malloc(sizeof *cd, M_USB, M_NOWAIT);
405 if (cd == NULL) {
406 free(uc, M_USB);
407 return USBF_NOMEM;
408 }
409
410 bzero(uc, sizeof *uc);
411 uc->uc_device = dev;
412 uc->uc_cdesc = cd;
413 uc->uc_cdesc_size = sizeof *cd;
414 SIMPLEQ_INIT(&uc->iface_head);
415
416 bzero(cd, sizeof *cd);
417 cd->bLength = USB_CONFIG_DESCRIPTOR_SIZE;
418 cd->bDescriptorType = UDESC_CONFIG;
419 USETW(cd->wTotalLength, USB_CONFIG_DESCRIPTOR_SIZE);
420 cd->bConfigurationValue = USB_UNCONFIG_NO + 1 +
421 dev->ddesc.bNumConfigurations;
422 cd->iConfiguration = 0;
423 cd->bmAttributes = UC_BUS_POWERED | UC_SELF_POWERED;
424 #if 0
425 cd->bMaxPower = 100 / UC_POWER_FACTOR;
426 #else
427 cd->bMaxPower = 0;
428 #endif
429
430 SIMPLEQ_INSERT_TAIL(&dev->configs, uc, next);
431 dev->ddesc.bNumConfigurations++;
432
433 if (ucp != NULL)
434 *ucp = uc;
435 return USBF_NORMAL_COMPLETION;
436 }
437
438
439
440
441
442 usbf_status
443 usbf_add_config_desc(usbf_config_handle uc, usb_descriptor_t *d,
444 usb_descriptor_t **dp)
445 {
446 usb_config_descriptor_t *cd;
447 size_t oldsize;
448 size_t newsize;
449
450 oldsize = uc->uc_cdesc_size;
451 newsize = oldsize + d->bLength;
452 if (d->bLength < sizeof(usb_descriptor_t) || newsize > 65535)
453 return USBF_INVAL;
454
455 cd = usbf_realloc((void **)&uc->uc_cdesc, &uc->uc_cdesc_size,
456 newsize);
457 if (cd == NULL)
458 return USBF_NOMEM;
459
460 bcopy(d, (char *)cd + oldsize, d->bLength);
461 USETW(cd->wTotalLength, newsize);
462 if (dp != NULL)
463 *dp = (usb_descriptor_t *)((char *)cd + oldsize);
464 return USBF_NORMAL_COMPLETION;
465 }
466
467 usbf_status
468 usbf_add_interface(usbf_config_handle uc, u_int8_t bInterfaceClass,
469 u_int8_t bInterfaceSubClass, u_int8_t bInterfaceProtocol,
470 const char *string, usbf_interface_handle *uip)
471 {
472 struct usbf_interface *ui;
473 usb_interface_descriptor_t *id;
474
475 if (uc->uc_closed)
476 return USBF_INVAL;
477
478 ui = malloc(sizeof *ui, M_USB, M_NOWAIT);
479 if (ui == NULL)
480 return USBF_NOMEM;
481
482 id = malloc(sizeof *id, M_USB, M_NOWAIT);
483 if (id == NULL) {
484 free(ui, M_USB);
485 return USBF_NOMEM;
486 }
487
488 bzero(ui, sizeof *ui);
489 ui->config = uc;
490 ui->idesc = id;
491 LIST_INIT(&ui->pipes);
492 SIMPLEQ_INIT(&ui->endpoint_head);
493
494 bzero(id, sizeof *id);
495 id->bLength = USB_INTERFACE_DESCRIPTOR_SIZE;
496 id->bDescriptorType = UDESC_INTERFACE;
497 id->bInterfaceNumber = uc->uc_cdesc->bNumInterface;
498 id->bInterfaceClass = bInterfaceClass;
499 id->bInterfaceSubClass = bInterfaceSubClass;
500 id->bInterfaceProtocol = bInterfaceProtocol;
501 id->iInterface = 0;
502
503 SIMPLEQ_INSERT_TAIL(&uc->iface_head, ui, next);
504 uc->uc_cdesc->bNumInterface++;
505
506 *uip = ui;
507 return USBF_NORMAL_COMPLETION;
508 }
509
510 usbf_status
511 usbf_add_endpoint(usbf_interface_handle ui, u_int8_t bEndpointAddress,
512 u_int8_t bmAttributes, u_int16_t wMaxPacketSize, u_int8_t bInterval,
513 usbf_endpoint_handle *uep)
514 {
515 struct usbf_endpoint *ue;
516 usb_endpoint_descriptor_t *ed;
517
518 if (ui->config->uc_closed)
519 return USBF_INVAL;
520
521 ue = malloc(sizeof *ue, M_USB, M_NOWAIT);
522 if (ue == NULL)
523 return USBF_NOMEM;
524
525 ed = malloc(sizeof *ed, M_USB, M_NOWAIT);
526 if (ed == NULL) {
527 free(ue, M_USB);
528 return USBF_NOMEM;
529 }
530
531 bzero(ue, sizeof *ue);
532 ue->iface = ui;
533 ue->edesc = ed;
534
535 bzero(ed, sizeof *ed);
536 ed->bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
537 ed->bDescriptorType = UDESC_ENDPOINT;
538 ed->bEndpointAddress = bEndpointAddress;
539 ed->bmAttributes = bmAttributes;
540 USETW(ed->wMaxPacketSize, wMaxPacketSize);
541 ed->bInterval = bInterval;
542
543 SIMPLEQ_INSERT_TAIL(&ui->endpoint_head, ue, next);
544 ui->idesc->bNumEndpoints++;
545
546 *uep = ue;
547 return USBF_NORMAL_COMPLETION;
548 }
549
550
551
552
553
554 usbf_status
555 usbf_end_config(usbf_config_handle uc)
556 {
557 struct usbf_interface *ui;
558 struct usbf_endpoint *ue;
559 usb_descriptor_t *d;
560 usbf_status err = USBF_NORMAL_COMPLETION;
561
562 if (uc->uc_closed)
563 return USBF_INVAL;
564
565 SIMPLEQ_FOREACH(ui, &uc->iface_head, next) {
566 err = usbf_add_config_desc(uc,
567 (usb_descriptor_t *)ui->idesc, &d);
568 if (err)
569 break;
570
571 free(ui->idesc, M_USB);
572 ui->idesc = (usb_interface_descriptor_t *)d;
573
574 SIMPLEQ_FOREACH(ue, &ui->endpoint_head, next) {
575 err = usbf_add_config_desc(uc,
576 (usb_descriptor_t *)ue->edesc, &d);
577 if (err)
578 break;
579
580 free(ue->edesc, M_USB);
581 ue->edesc = (usb_endpoint_descriptor_t *)d;
582 }
583 }
584
585 uc->uc_closed = 1;
586 return err;
587 }
588
589 usb_device_descriptor_t *
590 usbf_device_descriptor(usbf_device_handle dev)
591 {
592 return &dev->ddesc;
593 }
594
595 usb_config_descriptor_t *
596 usbf_config_descriptor(usbf_device_handle dev, u_int8_t index)
597 {
598 struct usbf_config *uc;
599
600 SIMPLEQ_FOREACH(uc, &dev->configs, next) {
601 if (index-- == 0)
602 return uc->uc_cdesc;
603 }
604 return NULL;
605 }
606
607 int
608 usbf_interface_number(usbf_interface_handle iface)
609 {
610 return iface->idesc->bInterfaceNumber;
611 }
612
613 u_int8_t
614 usbf_endpoint_address(usbf_endpoint_handle endpoint)
615 {
616 return endpoint->edesc->bEndpointAddress;
617 }
618
619 u_int8_t
620 usbf_endpoint_attributes(usbf_endpoint_handle endpoint)
621 {
622 return endpoint->edesc->bmAttributes;
623 }
624
625 usbf_status
626 usbf_open_pipe(usbf_interface_handle iface, u_int8_t address,
627 usbf_pipe_handle *pipe)
628 {
629 return usbf_open_pipe_ival(iface, address, pipe, 0);
630 }
631
632 usbf_status
633 usbf_open_pipe_ival(usbf_interface_handle iface, u_int8_t address,
634 usbf_pipe_handle *pipe, int ival)
635 {
636 struct usbf_endpoint *ep;
637 usbf_pipe_handle p;
638 usbf_status err;
639
640 ep = usbf_iface_endpoint(iface, address);
641 if (ep == NULL)
642 return USBF_BAD_ADDRESS;
643
644 err = usbf_setup_pipe(iface->config->uc_device, iface, ep,
645 ival, &p);
646 if (err)
647 return err;
648 LIST_INSERT_HEAD(&iface->pipes, p, next);
649 *pipe = p;
650 return USBF_NORMAL_COMPLETION;
651 }
652
653 usbf_status
654 usbf_setup_pipe(usbf_device_handle dev, usbf_interface_handle iface,
655 struct usbf_endpoint *ep, int ival, usbf_pipe_handle *pipe)
656 {
657 struct usbf_pipe *p;
658 usbf_status err;
659
660 p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT);
661 if (p == NULL)
662 return USBF_NOMEM;
663
664 p->device = dev;
665 p->iface = iface;
666 p->endpoint = ep;
667 ep->refcnt++;
668 p->running = 0;
669 p->refcnt = 1;
670 p->repeat = 0;
671 p->interval = ival;
672 p->methods = NULL;
673 SIMPLEQ_INIT(&p->queue);
674 err = dev->bus->methods->open_pipe(p);
675 if (err) {
676 free(p, M_USB);
677 return err;
678 }
679 *pipe = p;
680 return USBF_NORMAL_COMPLETION;
681 }
682
683
684 void
685 usbf_abort_pipe(usbf_pipe_handle pipe)
686 {
687 usbf_xfer_handle xfer;
688 int s;
689
690 s = splusb();
691 pipe->repeat = 0;
692 pipe->aborting = 1;
693
694 while ((xfer = SIMPLEQ_FIRST(&pipe->queue)) != NULL) {
695 DPRINTF(0,("usbf_abort_pipe: pipe=%p, xfer=%p\n", pipe,
696 xfer));
697
698 pipe->methods->abort(xfer);
699 }
700
701 pipe->aborting = 0;
702 splx(s);
703 }
704
705
706 void
707 usbf_close_pipe(usbf_pipe_handle pipe)
708 {
709 usbf_abort_pipe(pipe);
710 pipe->methods->close(pipe);
711 pipe->endpoint->refcnt--;
712 free(pipe, M_USB);
713 }
714
715 void
716 usbf_stall_pipe(usbf_pipe_handle pipe)
717 {
718 DPRINTF(0,("usbf_stall_pipe not implemented\n"));
719 }
720
721 usbf_endpoint_handle
722 usbf_iface_endpoint(usbf_interface_handle iface, u_int8_t address)
723 {
724 usbf_endpoint_handle ep;
725
726 SIMPLEQ_FOREACH(ep, &iface->endpoint_head, next) {
727 if (ep->edesc->bEndpointAddress == address)
728 return ep;
729 }
730 return NULL;
731 }
732
733 usbf_endpoint_handle
734 usbf_config_endpoint(usbf_config_handle cfg, u_int8_t address)
735 {
736 usbf_interface_handle iface;
737 usbf_endpoint_handle ep;
738
739 SIMPLEQ_FOREACH(iface, &cfg->iface_head, next) {
740 SIMPLEQ_FOREACH(ep, &iface->endpoint_head, next) {
741 if (ep->edesc->bEndpointAddress == address)
742 return ep;
743 }
744 }
745 return NULL;
746 }
747
748 void
749 usbf_set_endpoint_halt(usbf_endpoint_handle endpoint)
750 {
751 }
752
753 void
754 usbf_clear_endpoint_halt(usbf_endpoint_handle endpoint)
755 {
756 }
757
758 usbf_status
759 usbf_set_endpoint_feature(usbf_config_handle cfg, u_int8_t address,
760 u_int16_t value)
761 {
762 usbf_endpoint_handle ep;
763
764 DPRINTF(0,("usbf_set_endpoint_feature: cfg=%p address=%#x"
765 " value=%#x\n", cfg, address, value));
766
767 ep = usbf_config_endpoint(cfg, address);
768 if (ep == NULL)
769 return USBF_BAD_ADDRESS;
770
771 switch (value) {
772 case UF_ENDPOINT_HALT:
773 usbf_set_endpoint_halt(ep);
774 return USBF_NORMAL_COMPLETION;
775 default:
776
777 return USBF_STALLED;
778 }
779 }
780
781 usbf_status
782 usbf_clear_endpoint_feature(usbf_config_handle cfg, u_int8_t address,
783 u_int16_t value)
784 {
785 usbf_endpoint_handle ep;
786
787 DPRINTF(0,("usbf_clear_endpoint_feature: cfg=%p address=%#x"
788 " value=%#x\n", cfg, address, value));
789
790 ep = usbf_config_endpoint(cfg, address);
791 if (ep == NULL)
792 return USBF_BAD_ADDRESS;
793
794 switch (value) {
795 case UF_ENDPOINT_HALT:
796 usbf_clear_endpoint_halt(ep);
797 return USBF_NORMAL_COMPLETION;
798 default:
799
800 return USBF_STALLED;
801 }
802 }
803
804 usbf_xfer_handle
805 usbf_alloc_xfer(usbf_device_handle dev)
806 {
807 struct usbf_xfer *xfer;
808
809
810 xfer = dev->bus->methods->allocx(dev->bus);
811 if (xfer == NULL)
812 return NULL;
813 xfer->device = dev;
814 timeout_set(&xfer->timeout_handle, NULL, NULL);
815 DPRINTF(1,("usbf_alloc_xfer() = %p\n", xfer));
816 return xfer;
817 }
818
819 void
820 usbf_free_xfer(usbf_xfer_handle xfer)
821 {
822 DPRINTF(1,("usbf_free_xfer: %p\n", xfer));
823 if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
824 usbf_free_buffer(xfer);
825 xfer->device->bus->methods->freex(xfer->device->bus, xfer);
826 }
827
828 usbf_status
829 usbf_allocmem(usbf_bus_handle bus, size_t size, size_t align, usb_dma_t *p)
830 {
831 struct usbd_bus dbus;
832 usbd_status err;
833
834
835 dbus.dmatag = bus->dmatag;
836 err = usb_allocmem(&dbus, size, align, p);
837 return err ? USBF_NOMEM : USBF_NORMAL_COMPLETION;
838 }
839
840 void
841 usbf_freemem(usbf_bus_handle bus, usb_dma_t *p)
842 {
843 usb_freemem((usbd_bus_handle)NULL, p);
844 }
845
846 void *
847 usbf_alloc_buffer(usbf_xfer_handle xfer, u_int32_t size)
848 {
849 struct usbf_bus *bus = xfer->device->bus;
850 usbf_status err;
851
852 #ifdef DIAGNOSTIC
853 if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
854 printf("xfer %p already has a buffer\n", xfer);
855 #endif
856
857 err = bus->methods->allocm(bus, &xfer->dmabuf, size);
858 if (err)
859 return NULL;
860
861 xfer->rqflags |= URQ_DEV_DMABUF;
862 return KERNADDR(&xfer->dmabuf, 0);
863 }
864
865 void
866 usbf_free_buffer(usbf_xfer_handle xfer)
867 {
868 #ifdef DIAGNOSTIC
869 if (!(xfer->rqflags & URQ_DEV_DMABUF)) {
870 printf("usbf_free_buffer: no buffer\n");
871 return;
872 }
873 #endif
874 xfer->rqflags &= ~URQ_DEV_DMABUF;
875 xfer->device->bus->methods->freem(xfer->device->bus, &xfer->dmabuf);
876 }
877
878 #ifdef USBF_DEBUG
879
880
881
882
883 static void
884 usbf_dump_buffer(usbf_xfer_handle xfer)
885 {
886 struct device *dev = (struct device *)xfer->pipe->device->bus->usbfctl;
887 usbf_endpoint_handle ep = xfer->pipe->endpoint;
888 int index = usbf_endpoint_index(ep);
889 int dir = usbf_endpoint_dir(ep);
890 u_char *p = xfer->buffer;
891 u_int i;
892
893 printf("%s: ep%d-%s, length=%u, %s", dev->dv_xname, index,
894 (xfer->rqflags & URQ_REQUEST) ? "setup" :
895 (index == 0 ? "in" : (dir == UE_DIR_IN ? "in" : "out")),
896 xfer->length, usbf_errstr(xfer->status));
897
898 for (i = 0; i < xfer->length; i++) {
899 if ((i % 16) == 0)
900 printf("\n%4x:", i);
901 else if ((i % 8) == 0)
902 printf(" ");
903 printf(" %02x", p[i]);
904 }
905 printf("\n");
906 }
907 #endif
908
909 void
910 usbf_setup_xfer(usbf_xfer_handle xfer, usbf_pipe_handle pipe,
911 usbf_private_handle priv, void *buffer, u_int32_t length,
912 u_int16_t flags, u_int32_t timeout, usbf_callback callback)
913 {
914 xfer->pipe = pipe;
915 xfer->priv = priv;
916 xfer->buffer = buffer;
917 xfer->length = length;
918 xfer->actlen = 0;
919 xfer->flags = flags;
920 xfer->timeout = timeout;
921 xfer->status = USBF_NOT_STARTED;
922 xfer->callback = callback;
923 xfer->rqflags &= ~URQ_REQUEST;
924 }
925
926 void
927 usbf_setup_default_xfer(usbf_xfer_handle xfer, usbf_pipe_handle pipe,
928 usbf_private_handle priv, usb_device_request_t *req, u_int16_t flags,
929 u_int32_t timeout, usbf_callback callback)
930 {
931 xfer->pipe = pipe;
932 xfer->priv = priv;
933 xfer->buffer = req;
934 xfer->length = sizeof *req;
935 xfer->actlen = 0;
936 xfer->flags = flags;
937 xfer->timeout = timeout;
938 xfer->status = USBF_NOT_STARTED;
939 xfer->callback = callback;
940 xfer->rqflags |= URQ_REQUEST;
941 }
942
943 void
944 usbf_get_xfer_status(usbf_xfer_handle xfer, usbf_private_handle *priv,
945 void **buffer, u_int32_t *actlen, usbf_status *status)
946 {
947 if (priv != NULL)
948 *priv = xfer->priv;
949 if (buffer != NULL)
950 *buffer = xfer->buffer;
951 if (actlen != NULL)
952 *actlen = xfer->actlen;
953 if (status != NULL)
954 *status = xfer->status;
955 }
956
957 usbf_status
958 usbf_transfer(usbf_xfer_handle xfer)
959 {
960 usbf_pipe_handle pipe = xfer->pipe;
961 usbf_status err;
962
963 err = pipe->methods->transfer(xfer);
964 if (err != USBF_IN_PROGRESS && err) {
965 if (xfer->rqflags & URQ_AUTO_DMABUF) {
966 usbf_free_buffer(xfer);
967 xfer->rqflags &= ~URQ_AUTO_DMABUF;
968 }
969 }
970 return err;
971 }
972
973 usbf_status
974 usbf_insert_transfer(usbf_xfer_handle xfer)
975 {
976 usbf_pipe_handle pipe = xfer->pipe;
977 usbf_status err;
978 int s;
979
980 DPRINTF(1,("usbf_insert_transfer: xfer=%p pipe=%p running=%d\n",
981 xfer, pipe, pipe->running));
982
983 s = splusb();
984 SIMPLEQ_INSERT_TAIL(&pipe->queue, xfer, next);
985 if (pipe->running)
986 err = USBF_IN_PROGRESS;
987 else {
988 pipe->running = 1;
989 err = USBF_NORMAL_COMPLETION;
990 }
991 splx(s);
992 return err;
993 }
994
995 void
996 usbf_start_next(usbf_pipe_handle pipe)
997 {
998 usbf_xfer_handle xfer;
999 usbf_status err;
1000
1001 SPLUSBCHECK;
1002
1003
1004 xfer = SIMPLEQ_FIRST(&pipe->queue);
1005 if (xfer == NULL)
1006 pipe->running = 0;
1007 else {
1008 err = pipe->methods->start(xfer);
1009 if (err != USBF_IN_PROGRESS) {
1010 printf("usbf_start_next: %s\n", usbf_errstr(err));
1011 pipe->running = 0;
1012
1013 }
1014 }
1015 }
1016
1017
1018 void
1019 usbf_transfer_complete(usbf_xfer_handle xfer)
1020 {
1021 usbf_pipe_handle pipe = xfer->pipe;
1022 int repeat = pipe->repeat;
1023
1024 SPLUSBCHECK;
1025 DPRINTF(1,("usbf_transfer_complete: xfer=%p pipe=%p running=%d\n",
1026 xfer, pipe, pipe->running));
1027 #ifdef USBF_DEBUG
1028 if (usbfdebug > 0)
1029 usbf_dump_buffer(xfer);
1030 #endif
1031
1032 if (!repeat) {
1033
1034 KASSERT(SIMPLEQ_FIRST(&pipe->queue) == xfer);
1035 SIMPLEQ_REMOVE_HEAD(&pipe->queue, next);
1036 }
1037
1038 if (xfer->status == USBF_NORMAL_COMPLETION &&
1039 xfer->actlen < xfer->length &&
1040 !(xfer->flags & USBD_SHORT_XFER_OK)) {
1041 DPRINTF(0,("usbf_transfer_complete: short xfer=%p %u<%u\n",
1042 xfer, xfer->actlen, xfer->length));
1043 xfer->status = USBF_SHORT_XFER;
1044 }
1045
1046 if (xfer->callback != NULL)
1047 xfer->callback(xfer, xfer->priv, xfer->status);
1048
1049 pipe->methods->done(xfer);
1050
1051
1052
1053 if (!repeat) {
1054 if (xfer->status != USBF_NORMAL_COMPLETION &&
1055 pipe->iface != NULL)
1056 pipe->running = 0;
1057 else
1058 usbf_start_next(pipe);
1059 }
1060 }
1061
1062
1063
1064
1065
1066 usbf_status
1067 usbf_softintr_establish(struct usbf_bus *bus)
1068 {
1069 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
1070 KASSERT(bus->soft == NULL);
1071
1072 bus->soft = softintr_establish(IPL_SOFTNET,
1073 bus->methods->soft_intr, bus);
1074 if (bus->soft == NULL)
1075 return USBF_INVAL;
1076 #endif
1077 return USBF_NORMAL_COMPLETION;
1078 }
1079
1080 void
1081 usbf_schedsoftintr(struct usbf_bus *bus)
1082 {
1083 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
1084 softintr_schedule(bus->soft);
1085 #else
1086 bus->methods->soft_intr(bus);
1087 #endif
1088 }