xref: /minix3/minix/drivers/usb/usb_hub/urb_helper.c (revision 2d64210c1dbcd340904718f2d4e9e81adeab3c7d)
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