1*2d64210cSWojciech Zajac /*
2*2d64210cSWojciech Zajac * URB formatting related implementation
3*2d64210cSWojciech Zajac */
4*2d64210cSWojciech Zajac
5*2d64210cSWojciech Zajac #include <minix/sysutil.h> /* panic */
6*2d64210cSWojciech Zajac #include <minix/usb.h> /* struct usb_ctrlrequest */
7*2d64210cSWojciech Zajac
8*2d64210cSWojciech Zajac #include <string.h> /* memset */
9*2d64210cSWojciech Zajac #include <assert.h>
10*2d64210cSWojciech Zajac
11*2d64210cSWojciech Zajac #include "common.h"
12*2d64210cSWojciech Zajac #include "urb_helper.h"
13*2d64210cSWojciech Zajac
14*2d64210cSWojciech Zajac /*---------------------------*
15*2d64210cSWojciech Zajac * defined functions *
16*2d64210cSWojciech Zajac *---------------------------*/
17*2d64210cSWojciech Zajac /*===========================================================================*
18*2d64210cSWojciech Zajac * init_urb *
19*2d64210cSWojciech Zajac *===========================================================================*/
20*2d64210cSWojciech Zajac void
init_urb(struct ddekit_usb_urb * urb,struct ddekit_usb_dev * dev,urb_ep_config * conf)21*2d64210cSWojciech Zajac init_urb(struct ddekit_usb_urb * urb, struct ddekit_usb_dev * dev,
22*2d64210cSWojciech Zajac urb_ep_config * conf)
23*2d64210cSWojciech Zajac {
24*2d64210cSWojciech Zajac HUB_DEBUG_DUMP;
25*2d64210cSWojciech Zajac
26*2d64210cSWojciech Zajac /* Sanity checks */
27*2d64210cSWojciech Zajac assert(NULL != urb);
28*2d64210cSWojciech Zajac assert(NULL != dev);
29*2d64210cSWojciech Zajac assert((DDEKIT_USB_TRANSFER_BLK == conf->type) ||
30*2d64210cSWojciech Zajac (DDEKIT_USB_TRANSFER_CTL == conf->type) ||
31*2d64210cSWojciech Zajac (DDEKIT_USB_TRANSFER_INT == conf->type) ||
32*2d64210cSWojciech Zajac (DDEKIT_USB_TRANSFER_ISO == conf->type));
33*2d64210cSWojciech Zajac assert((conf->ep_num >= 0) && (conf->ep_num < 16));
34*2d64210cSWojciech Zajac assert((DDEKIT_USB_IN == conf->direction) ||
35*2d64210cSWojciech Zajac (DDEKIT_USB_OUT == conf->direction));
36*2d64210cSWojciech Zajac
37*2d64210cSWojciech Zajac /* Clear block first */
38*2d64210cSWojciech Zajac memset(urb, 0, sizeof(*urb));
39*2d64210cSWojciech Zajac
40*2d64210cSWojciech Zajac /* Set supplied values */
41*2d64210cSWojciech Zajac urb->dev = dev;
42*2d64210cSWojciech Zajac urb->type = conf->type;
43*2d64210cSWojciech Zajac urb->endpoint = conf->ep_num;
44*2d64210cSWojciech Zajac urb->direction = conf->direction;
45*2d64210cSWojciech Zajac urb->interval = conf->interval;
46*2d64210cSWojciech Zajac }
47*2d64210cSWojciech Zajac
48*2d64210cSWojciech Zajac
49*2d64210cSWojciech Zajac /*===========================================================================*
50*2d64210cSWojciech Zajac * attach_urb_data *
51*2d64210cSWojciech Zajac *===========================================================================*/
52*2d64210cSWojciech Zajac void
attach_urb_data(struct ddekit_usb_urb * urb,int buf_type,void * buf,ddekit_uint32_t buf_len)53*2d64210cSWojciech Zajac attach_urb_data(struct ddekit_usb_urb * urb, int buf_type,
54*2d64210cSWojciech Zajac void * buf, ddekit_uint32_t buf_len)
55*2d64210cSWojciech Zajac {
56*2d64210cSWojciech Zajac HUB_DEBUG_DUMP;
57*2d64210cSWojciech Zajac
58*2d64210cSWojciech Zajac assert(NULL != urb);
59*2d64210cSWojciech Zajac assert(NULL != buf);
60*2d64210cSWojciech Zajac
61*2d64210cSWojciech Zajac /* Mutual exclusion */
62*2d64210cSWojciech Zajac if (URB_BUF_TYPE_DATA == buf_type) {
63*2d64210cSWojciech Zajac urb->data = buf;
64*2d64210cSWojciech Zajac urb->size = buf_len;
65*2d64210cSWojciech Zajac } else if ( URB_BUF_TYPE_SETUP == buf_type ) {
66*2d64210cSWojciech Zajac assert(sizeof(struct usb_ctrlrequest) == buf_len);
67*2d64210cSWojciech Zajac urb->setup_packet = buf;
68*2d64210cSWojciech Zajac } else
69*2d64210cSWojciech Zajac panic("Unexpected buffer type!");
70*2d64210cSWojciech Zajac }
71*2d64210cSWojciech Zajac
72*2d64210cSWojciech Zajac
73*2d64210cSWojciech Zajac /*===========================================================================*
74*2d64210cSWojciech Zajac * blocking_urb_submit *
75*2d64210cSWojciech Zajac *===========================================================================*/
76*2d64210cSWojciech Zajac int
blocking_urb_submit(struct ddekit_usb_urb * urb,ddekit_sem_t * sem,int check_len)77*2d64210cSWojciech Zajac blocking_urb_submit(struct ddekit_usb_urb * urb, ddekit_sem_t * sem,
78*2d64210cSWojciech Zajac int check_len)
79*2d64210cSWojciech Zajac {
80*2d64210cSWojciech Zajac HUB_DEBUG_DUMP;
81*2d64210cSWojciech Zajac
82*2d64210cSWojciech Zajac assert(NULL != urb);
83*2d64210cSWojciech Zajac assert(NULL != sem);
84*2d64210cSWojciech Zajac assert((check_len == URB_SUBMIT_CHECK_LEN) ||
85*2d64210cSWojciech Zajac (check_len == URB_SUBMIT_ALLOW_MISMATCH));
86*2d64210cSWojciech Zajac
87*2d64210cSWojciech Zajac /* Submit and block until semaphore gets up */
88*2d64210cSWojciech Zajac if (ddekit_usb_submit_urb(urb)) {
89*2d64210cSWojciech Zajac HUB_MSG("Submitting DDEKit URB failed");
90*2d64210cSWojciech Zajac return EXIT_FAILURE;
91*2d64210cSWojciech Zajac } else {
92*2d64210cSWojciech Zajac /* Submitting succeeded so block and wait for reply */
93*2d64210cSWojciech Zajac ddekit_sem_down(sem);
94*2d64210cSWojciech Zajac
95*2d64210cSWojciech Zajac /* Check for DDEKit status first */
96*2d64210cSWojciech Zajac if (urb->status) {
97*2d64210cSWojciech Zajac HUB_MSG("Invalid DDEKit URB status");
98*2d64210cSWojciech Zajac return EXIT_FAILURE;
99*2d64210cSWojciech Zajac } else {
100*2d64210cSWojciech Zajac if (URB_SUBMIT_CHECK_LEN == check_len) {
101*2d64210cSWojciech Zajac /* Compare lengths */
102*2d64210cSWojciech Zajac if (urb->actual_length != urb->size) {
103*2d64210cSWojciech Zajac HUB_MSG("URB different than expected");
104*2d64210cSWojciech Zajac return EXIT_FAILURE;
105*2d64210cSWojciech Zajac }
106*2d64210cSWojciech Zajac }
107*2d64210cSWojciech Zajac
108*2d64210cSWojciech Zajac return EXIT_SUCCESS;
109*2d64210cSWojciech Zajac }
110*2d64210cSWojciech Zajac }
111*2d64210cSWojciech Zajac }
112