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