Drop main() prototype. Syncs with NetBSD-8
[minix.git] / minix / lib / libdevman / usb.c
blobf64e181829e29561d8b79d99b1dffa2bb0760fa2
1 #include <errno.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <minix/config.h>
6 #include <minix/const.h>
7 #include <minix/devman.h>
8 #include <minix/usb.h>
9 #include <minix/sysutil.h>
11 #include "local.h"
13 #define CHECKOUTOFMEM(ptr) if(ptr == NULL) \
14 panic("Out of memory! (%s, line %d)", \
15 __FILE__, __LINE__)
18 static int (*bind_cb) (struct devman_usb_bind_cb_data *data, endpoint_t ep);
19 static int (*unbind_cb) (struct devman_usb_bind_cb_data *data, endpoint_t ep);
21 /****************************************************************************
22 * devman_usb_add_attr *
23 ***************************************************************************/
24 static void
25 devman_usb_add_attr
26 (struct devman_dev *dev, const char *name, const char *data)
28 struct devman_static_attribute *attr = (struct devman_static_attribute *)
29 malloc(sizeof(struct devman_static_attribute));
31 CHECKOUTOFMEM(attr);
33 attr->name = malloc((strlen(name)+1)*sizeof(char));
34 memcpy(attr->name, name, (strlen(name)+1));
36 attr->data = malloc((strlen(data)+1)*sizeof(char));
37 memcpy(attr->data, data, (strlen(data)+1));
38 TAILQ_INSERT_TAIL(&dev->attrs, attr, list);
41 /****************************************************************************
42 * add_device_attributes *
43 ***************************************************************************/
44 static void
45 add_device_attributes
46 (struct devman_usb_dev *udev)
48 int ret;
49 char data[32];
51 ret = snprintf(data,sizeof(data),"0x%02x",udev->desc->bDeviceClass);
52 if (ret < 0) {
53 panic("add_device_attributes: snprintf failed");
55 devman_usb_add_attr(udev->dev, "bDeviceClass", data);
57 ret = snprintf(data,sizeof(data),"0x%02x",udev->desc->bDeviceSubClass);
58 if (ret < 0) {
59 panic("add_device_attributes: snprintf failed");
61 devman_usb_add_attr(udev->dev, "bDeviceSubClass", data);
63 ret = snprintf(data,sizeof(data),"0x%02x",udev->desc->bDeviceProtocol);
64 if (ret < 0) {
65 panic("add_device_attributes: snprintf failed");
67 devman_usb_add_attr(udev->dev, "bDeviceProtocol", data);
69 ret = snprintf(data,sizeof(data),"0x%04x",UGETW(udev->desc->idVendor));
70 if (ret < 0) {
71 panic("add_device_attributes: snprintf failed");
73 devman_usb_add_attr(udev->dev, "idVendor", data);
75 ret = snprintf(data,sizeof(data),"0x%04x",UGETW(udev->desc->idProduct));
76 if (ret < 0) {
77 panic("add_device_attributes: snprintf failed");
79 devman_usb_add_attr(udev->dev, "idProduct", data);
81 if (udev->product)
82 devman_usb_add_attr(udev->dev, "Product", udev->product);
83 if (udev->manufacturer)
84 devman_usb_add_attr(udev->dev, "Manufacturer", udev->manufacturer);
85 if (udev->serial)
86 devman_usb_add_attr(udev->dev, "SerialNumber", udev->serial);
87 devman_usb_add_attr(udev->dev, "dev_type", "USB_DEV");
90 /****************************************************************************
91 * add_interface_attributes *
92 ***************************************************************************/
93 static void
94 add_interface_attributes
95 (struct devman_usb_interface *intf)
97 int ret;
98 char data[32];
100 ret = snprintf(data,sizeof(data),"0x%02x",intf->desc->bInterfaceNumber);
101 if (ret < 0) {
102 panic("add_device_attributes: snprintf failed");
104 devman_usb_add_attr(intf->dev, "bInterfaceNumber", data);
106 ret = snprintf(data,sizeof(data),"0x%02x",intf->desc->bAlternateSetting);
107 if (ret < 0) {
108 panic("add_device_attributes: snprintf failed");
110 devman_usb_add_attr(intf->dev, "bAlternateSetting", data);
112 ret = snprintf(data,sizeof(data),"0x%02x",intf->desc->bNumEndpoints);
113 if (ret < 0) {
114 panic("add_device_attributes: snprintf failed");
116 devman_usb_add_attr(intf->dev, "bNumEndpoints", data);
118 ret = snprintf(data,sizeof(data),"0x%02x",intf->desc->bInterfaceClass);
119 if (ret < 0) {
120 panic("add_device_attributes: snprintf failed");
122 devman_usb_add_attr(intf->dev, "bInterfaceClass", data);
124 ret = snprintf(data,sizeof(data),"0x%02x",intf->desc->bInterfaceSubClass);
125 if (ret < 0) {
126 panic("add_device_attributes: snprintf failed");
128 devman_usb_add_attr(intf->dev, "bInterfaceSubClass", data);
130 ret = snprintf(data,sizeof(data),"0x%02x",intf->desc->bInterfaceProtocol);
131 if (ret < 0) {
132 panic("add_device_attributes: snprintf failed");
134 devman_usb_add_attr(intf->dev, "bInterfaceProtocol", data);
136 devman_usb_add_attr(intf->dev, "dev_type", "USB_INTF");
140 /****************************************************************************
141 * devman_usb_device_new *
142 ***************************************************************************/
143 struct devman_usb_dev*
144 devman_usb_device_new
145 (int dev_id)
147 struct devman_usb_dev *udev = NULL;
148 struct devman_dev * dev = NULL;
150 udev = (struct devman_usb_dev *) malloc(sizeof(struct devman_usb_dev));
152 CHECKOUTOFMEM(udev);
154 /* allocate device */
155 dev = (struct devman_dev *) malloc(sizeof(struct devman_dev));
157 CHECKOUTOFMEM(dev);
159 udev->dev_id = dev_id;
160 udev->dev = dev;
162 dev->parent_dev_id = 0; /* For now add it directly to the root dev */
164 snprintf(dev->name, DEVMAN_DEV_NAME_LEN, "USB%d", dev_id);
166 TAILQ_INIT(&dev->attrs);
168 return udev;
171 /****************************************************************************
172 * devman_usb_device_delete *
173 ***************************************************************************/
174 void devman_usb_device_delete(struct devman_usb_dev *udev)
176 int i;
177 struct devman_static_attribute *attr,*temp;
180 for (i=0; i < udev->intf_count; i++) {
181 TAILQ_FOREACH_SAFE(attr, &udev->interfaces[i].dev->attrs, list, temp)
183 free(attr->name);
184 free(attr->data);
185 free(attr);
187 free(udev->interfaces[i].dev);
190 TAILQ_FOREACH_SAFE(attr, &udev->dev->attrs, list, temp) {
191 free(attr->name);
192 free(attr->data);
193 free(attr);
196 free(udev->dev);
197 free(udev);
200 static int devman_usb_bind_cb(void *data, endpoint_t ep) {
201 if (bind_cb) {
202 return bind_cb((struct devman_usb_bind_cb_data *) data, ep);
203 } else {
204 return ENODEV;
208 static int devman_usb_unbind_cb(void *data, endpoint_t ep) {
209 if (unbind_cb) {
210 return unbind_cb((struct devman_usb_bind_cb_data *) data, ep);
211 } else {
212 return ENODEV;
216 /****************************************************************************
217 * devman_usb_device_add *
218 ***************************************************************************/
219 int devman_usb_device_add(struct devman_usb_dev *dev)
221 int i,res = 0;
222 add_device_attributes(dev);
224 /* add the USB device */
225 dev->cb_data.dev_id = dev->dev_id;
226 dev->cb_data.interface = -1;
228 dev->dev->bind_cb = devman_usb_bind_cb;
229 dev->dev->unbind_cb = devman_usb_unbind_cb;
230 dev->dev->data = &dev->cb_data;
232 res = devman_add_device(dev->dev);
234 if (res != 0) {
235 panic("devman_usb_device_add(): devman_add_device failed.");
238 /* add the USB interfaces */
239 for (i=0; i < dev->intf_count; i++) {
240 /* prepare */
241 dev->interfaces[i].dev =
242 (struct devman_dev *) malloc(sizeof(struct devman_dev));
243 CHECKOUTOFMEM(dev->interfaces[i].dev);
245 TAILQ_INIT(&dev->interfaces[i].dev->attrs);
246 snprintf(dev->interfaces[i].dev->name, DEVMAN_DEV_NAME_LEN,
247 "intf%d", i);
249 add_interface_attributes(&dev->interfaces[i]);
251 dev->interfaces[i].dev->parent_dev_id = dev->dev->dev_id;
254 dev->interfaces[i].cb_data.dev_id = dev->dev_id;
255 dev->interfaces[i].cb_data.interface =
256 dev->interfaces[i].desc->bInterfaceNumber;
258 dev->interfaces[i].dev->bind_cb = devman_usb_bind_cb;
259 dev->interfaces[i].dev->unbind_cb = devman_usb_unbind_cb;
260 dev->interfaces[i].dev->data = &dev->interfaces[i].cb_data;
262 /* add */
263 res = devman_add_device(dev->interfaces[i].dev);
265 if (res != 0) {
266 panic("devman_usb_device_add(): devman_add_device failed.");
270 return res;
273 /****************************************************************************
274 * devman_usb_device_remove *
275 ***************************************************************************/
276 int devman_usb_device_remove(struct devman_usb_dev *dev)
278 int i, res = 0;
280 for (i=0; i < dev->intf_count; i++) {
282 res = devman_del_device(dev->interfaces[i].dev);
284 if (res != 0) {
285 panic("devman_usb_device_remove(): devman_del_device failed.");
288 res = devman_del_device(dev->dev);
289 return res;
292 /****************************************************************************
293 * devman_usb_init *
294 ***************************************************************************/
295 void devman_usb_init
296 (int (*_bind_cb) (struct devman_usb_bind_cb_data *data, endpoint_t ep),
297 int (*_unbind_cb) (struct devman_usb_bind_cb_data *data, endpoint_t ep))
299 bind_cb = _bind_cb;
300 unbind_cb = _unbind_cb;