xref: /minix3/minix/lib/libddekit/src/usb_client.c (revision 2d64210c1dbcd340904718f2d4e9e81adeab3c7d)
1 #include "common.h"
2 #include <ddekit/usb.h>
3 #include <ddekit/memory.h>
4 #include <ddekit/minix/msg_queue.h>
5 #include <minix/usb.h>
6 
7 struct ddekit_usb_dev {
8 	int id;
9 	unsigned int interfaces;
10 	void *data;
11 	struct ddekit_usb_dev *next;
12 	struct ddekit_usb_dev *prev;
13 };
14 
15 struct ddekit_usb_dev dev_list_head = {
16 	.next = &dev_list_head,
17 	.prev = &dev_list_head,
18 };
19 
20 static struct ddekit_usb_driver *d_usb_driver;
21 
22 static void _ddekit_usb_completion(struct usb_urb *mx);
23 static void _ddekit_usb_connect( unsigned int dev_id, unsigned int
24 	interfaces);
25 static void _ddekit_usb_disconnect(unsigned dev_id);
26 
27 struct usb_driver mx_usb_driver = {
28 	.urb_completion = _ddekit_usb_completion,
29 	.connect_device = _ddekit_usb_connect,
30 	.disconnect_device = _ddekit_usb_disconnect
31 };
32 
33 /*****************************************************************************
34  *         _ddekit_usb_completion                                            *
35  ****************************************************************************/
_ddekit_usb_completion(struct usb_urb * mx_urb)36 static void _ddekit_usb_completion(struct usb_urb *mx_urb)
37 {
38 
39 	struct ddekit_usb_urb *d_urb = (struct ddekit_usb_urb *) mx_urb->priv;
40 
41 	/* XXX: copy stuff back into d_urb */
42 
43 	d_urb->status         = mx_urb->status;
44 	d_urb->error_count    = mx_urb->interval;
45 	d_urb->transfer_flags = mx_urb->error_count;
46 	d_urb->actual_length  = mx_urb->actual_length;
47 	d_urb->ddekit_priv    = NULL;
48 
49 	if (mx_urb->type == USB_TRANSFER_CTL) {
50 		memcpy(d_urb->setup_packet, mx_urb->setup_packet, 8);
51 	}
52 
53 	if (mx_urb->type == USB_TRANSFER_ISO) {
54 		d_urb->start_frame = mx_urb->start_frame;
55 
56 		memcpy(d_urb->iso_desc, mx_urb->buffer + d_urb->size,
57 		       d_urb->number_of_packets * sizeof(struct usb_iso_packet_desc));
58 	}
59 
60 	memcpy(d_urb->data, mx_urb->buffer, d_urb->size);
61 
62 	/* free mx_urb */
63 	ddekit_simple_free(mx_urb);
64 
65 	/* 'give back' URB */
66 
67 	d_usb_driver->completion(d_urb->priv);
68 }
69 
70 
71 /*****************************************************************************
72  *         _ddekit_usb_connect                                               *
73  ****************************************************************************/
_ddekit_usb_connect(unsigned int dev_id,unsigned int interfaces)74 static void _ddekit_usb_connect(unsigned int dev_id, unsigned int interfaces)
75 {
76 	struct ddekit_usb_dev *d_dev = (struct ddekit_usb_dev *)
77 		ddekit_simple_malloc(sizeof(struct ddekit_usb_dev));
78 
79 	d_dev->data       = NULL;
80 	d_dev->id         = dev_id;
81 	d_dev->interfaces = interfaces;
82 
83 	/* add to list */
84 
85 	d_dev->next = dev_list_head.next;
86 	d_dev->prev = &dev_list_head;
87 
88 	dev_list_head.next = d_dev;
89 	d_dev->next->prev = d_dev;
90 	d_usb_driver->connect(d_dev, interfaces);
91 }
92 
93 /*****************************************************************************
94  *         _ddekit_usb_disconnect                                            *
95  ****************************************************************************/
_ddekit_usb_disconnect(unsigned dev_id)96 void _ddekit_usb_disconnect(unsigned dev_id)
97 {
98 	/* find dev */
99 	struct ddekit_usb_dev *it;
100 	struct ddekit_usb_dev *d_dev = NULL;
101 
102 
103 	for (it = dev_list_head.next; it != &dev_list_head; it= it->next) {
104 		if (it->id == dev_id) {
105 			d_dev = it;
106 			break;
107 		}
108 	}
109 
110 	if (d_dev == NULL) {
111 		return;
112 	}
113 
114 	d_usb_driver->disconnect(d_dev);
115 }
116 
117 /*****************************************************************************
118  *         ddekit_usb_dev_set_data                                           *
119  ****************************************************************************/
ddekit_usb_dev_set_data(struct ddekit_usb_dev * dev,void * data)120 int ddekit_usb_dev_set_data(struct ddekit_usb_dev *dev, void *data)
121 {
122 	dev->data = data;
123 	return 0;
124 }
125 
126 /*****************************************************************************
127  *         ddekit_usb_dev_get_data                                           *
128  ****************************************************************************/
ddekit_usb_dev_get_data(struct ddekit_usb_dev * dev)129 void *ddekit_usb_dev_get_data(struct ddekit_usb_dev *dev)
130 {
131 	return dev->data;
132 }
133 
134 /*****************************************************************************
135  *         ddekit_usb_submit_urb                                             *
136  ****************************************************************************/
ddekit_usb_submit_urb(struct ddekit_usb_urb * d_urb)137 int ddekit_usb_submit_urb(struct ddekit_usb_urb *d_urb)
138 {
139 	int res;
140 	unsigned urb_size = USB_URBSIZE(d_urb->size, d_urb->number_of_packets);
141 	/* create mx urb out of d_urb */
142 	struct usb_urb *mx_urb = (struct usb_urb*)
143 	    ddekit_simple_malloc(urb_size);
144 	mx_urb->urb_size = urb_size;
145 
146 	mx_urb->dev_id = d_urb->dev->id;
147 	mx_urb->type = d_urb->type;
148 	mx_urb->endpoint = d_urb->endpoint;
149 	mx_urb->direction = d_urb->direction;
150 	mx_urb->interval = d_urb->interval;
151 	mx_urb->transfer_flags = d_urb->transfer_flags;
152 	mx_urb->size = d_urb->size;
153 	mx_urb->priv = d_urb;
154 
155 	if (mx_urb->type == USB_TRANSFER_CTL) {
156 		memcpy(mx_urb->setup_packet, d_urb->setup_packet, 8);
157 	}
158 
159 	if (mx_urb->type == USB_TRANSFER_ISO) {
160 		mx_urb->number_of_packets = d_urb->number_of_packets;
161 		mx_urb->start_frame = d_urb->start_frame;
162 		memcpy(mx_urb->buffer + d_urb->size, d_urb->iso_desc,
163 		    d_urb->number_of_packets * sizeof(struct usb_iso_packet_desc));
164 	}
165 	memcpy(mx_urb->buffer, d_urb->data, d_urb->size);
166 
167 	d_urb->ddekit_priv = mx_urb;
168 
169 	/* submit mx_urb */
170 	res = usb_send_urb(mx_urb);
171 	return res;
172 }
173 
174 /*****************************************************************************
175  *         ddekit_usb_cancle_urb                                             *
176  ****************************************************************************/
ddekit_usb_cancle_urb(struct ddekit_usb_urb * d_urb)177 int ddekit_usb_cancle_urb(struct ddekit_usb_urb *d_urb)
178 {
179 	int res;
180 
181 	/* get the associated mx_urb */
182 	struct usb_urb *mx_urb = (struct usb_urb *) d_urb->ddekit_priv;
183 
184 	res = usb_cancle_urb(mx_urb);
185 
186 	return res;
187 }
188 
189 
190 /*****************************************************************************
191  *         ddekit_usb_info                                                   *
192  *****************************************************************************/
193 long
ddekit_usb_info(struct ddekit_usb_dev * UNUSED (dev),long type,long value)194 ddekit_usb_info(struct ddekit_usb_dev * UNUSED(dev), long type, long value)
195 {
196 	return usb_send_info(type, value);
197 }
198 
199 
_ddekit_usb_thread()200 static void _ddekit_usb_thread()
201 {
202 	struct ddekit_minix_msg_q *mq = ddekit_minix_create_msg_q(USB_BASE,
203 	                                    USB_BASE + 0x1000);
204 	message m;
205 	int ipc_status;
206 
207 	while (1) {
208 		ddekit_minix_rcv(mq, &m, &ipc_status);
209 		usb_handle_msg(&mx_usb_driver, &m);
210 	}
211 
212 }
213 
214 /*****************************************************************************
215  *         ddekit_usb_init                                             *
216  ****************************************************************************/
ddekit_usb_init(struct ddekit_usb_driver * drv,ddekit_usb_malloc_fn * unused,ddekit_usb_free_fn * _unused)217 int ddekit_usb_init
218 (struct ddekit_usb_driver *drv,
219  ddekit_usb_malloc_fn     *unused,
220  ddekit_usb_free_fn       *_unused)
221 {
222 	/* start usb_thread */
223 	d_usb_driver =  drv;
224 	usb_init("dde");
225 	_ddekit_usb_thread();
226 	return 0;
227 }
228 
229