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