aboutsummaryrefslogtreecommitdiff
path: root/lib/usb/usb_standard.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/usb/usb_standard.c')
-rw-r--r--lib/usb/usb_standard.c128
1 files changed, 77 insertions, 51 deletions
diff --git a/lib/usb/usb_standard.c b/lib/usb/usb_standard.c
index 08923d8..e14fee3 100644
--- a/lib/usb/usb_standard.c
+++ b/lib/usb/usb_standard.c
@@ -21,15 +21,18 @@
#include <libopencm3/usb/usbd.h>
#include "usb_private.h"
-void usbd_register_set_config_callback(void (*callback)(u16 wValue))
+void usbd_register_set_config_callback(usbd_device *usbd_dev,
+ void (*callback)(usbd_device *usbd_dev,
+ u16 wValue))
{
- _usbd_device.user_callback_set_config = callback;
+ usbd_dev->user_callback_set_config = callback;
}
-static u16 build_config_descriptor(u8 index, u8 *buf, u16 len)
+static u16 build_config_descriptor(usbd_device *usbd_dev,
+ u8 index, u8 *buf, u16 len)
{
u8 *tmpbuf = buf;
- const struct usb_config_descriptor *cfg = &_usbd_device.config[index];
+ const struct usb_config_descriptor *cfg = &usbd_dev->config[index];
u16 count, total = 0, totallen = 0;
u16 i, j, k;
@@ -43,7 +46,7 @@ static u16 build_config_descriptor(u8 index, u8 *buf, u16 len)
for (i = 0; i < cfg->bNumInterfaces; i++) {
/* Interface Association Descriptor, if any */
if (cfg->interface[i].iface_assoc) {
- const struct usb_iface_assoc_descriptor *assoc =
+ const struct usb_iface_assoc_descriptor *assoc =
cfg->interface[i].iface_assoc;
memcpy(buf, assoc, count = MIN(len, assoc->bLength));
buf += count;
@@ -97,7 +100,8 @@ static int usb_descriptor_index(u16 wValue)
return wValue & 0xFF;
}
-static int usb_standard_get_descriptor(struct usb_setup_data *req,
+static int usb_standard_get_descriptor(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
int i, array_idx, descr_idx;
@@ -107,15 +111,15 @@ static int usb_standard_get_descriptor(struct usb_setup_data *req,
switch (usb_descriptor_type(req->wValue)) {
case USB_DT_DEVICE:
- *buf = (u8 *) _usbd_device.desc;
- *len = MIN(*len, _usbd_device.desc->bLength);
+ *buf = (u8 *) usbd_dev->desc;
+ *len = MIN(*len, usbd_dev->desc->bLength);
return USBD_REQ_HANDLED;
case USB_DT_CONFIGURATION:
- *buf = _usbd_device.ctrl_buf;
- *len = build_config_descriptor(descr_idx, *buf, *len);
+ *buf = usbd_dev->ctrl_buf;
+ *len = build_config_descriptor(usbd_dev, descr_idx, *buf, *len);
return USBD_REQ_HANDLED;
case USB_DT_STRING:
- sd = (struct usb_string_descriptor *)_usbd_device.ctrl_buf;
+ sd = (struct usb_string_descriptor *)usbd_dev->ctrl_buf;
if (descr_idx == 0) {
/* Send sane Language ID descriptor... */
@@ -127,10 +131,10 @@ static int usb_standard_get_descriptor(struct usb_setup_data *req,
} else {
array_idx = descr_idx - 1;
- if (!_usbd_device.strings)
+ if (!usbd_dev->strings)
return USBD_REQ_NOTSUPP; /* Device doesn't support strings. */
/* Check that string index is in range. */
- if (array_idx >= _usbd_device.num_strings)
+ if (array_idx >= usbd_dev->num_strings)
return USBD_REQ_NOTSUPP;
/* Strings with Language ID differnet from
@@ -139,14 +143,14 @@ static int usb_standard_get_descriptor(struct usb_setup_data *req,
return USBD_REQ_NOTSUPP;
/* Ths string is returned as UTF16, hence the multiplication */
- sd->bLength = strlen(_usbd_device.strings[array_idx]) * 2 +
+ sd->bLength = strlen(usbd_dev->strings[array_idx]) * 2 +
sizeof(sd->bLength) + sizeof(sd->bDescriptorType);
*len = MIN(*len, sd->bLength);
for (i = 0; i < (*len / 2) - 1; i++)
sd->wData[i] =
- _usbd_device.strings[array_idx][i];
+ usbd_dev->strings[array_idx][i];
}
sd->bDescriptorType = USB_DT_STRING;
@@ -157,7 +161,8 @@ static int usb_standard_get_descriptor(struct usb_setup_data *req,
return USBD_REQ_NOTSUPP;
}
-static int usb_standard_set_address(struct usb_setup_data *req, u8 **buf,
+static int usb_standard_set_address(usbd_device *usbd_dev,
+ struct usb_setup_data *req, u8 **buf,
u16 *len)
{
(void)req;
@@ -168,19 +173,20 @@ static int usb_standard_set_address(struct usb_setup_data *req, u8 **buf,
if ((req->bmRequestType != 0) || (req->wValue >= 128))
return 0;
- _usbd_device.current_address = req->wValue;
+ usbd_dev->current_address = req->wValue;
/*
* Special workaround for STM32F10[57] that require the address
* to be set here. This is undocumented!
*/
- if (_usbd_device.driver == &stm32f107_usb_driver)
- _usbd_device.driver->set_address(req->wValue);
+ if ( usbd_dev->driver->set_address_before_status)
+ usbd_dev->driver->set_address(usbd_dev, req->wValue);
return 1;
}
-static int usb_standard_set_configuration(struct usb_setup_data *req,
+static int usb_standard_set_configuration(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
int i;
@@ -190,43 +196,46 @@ static int usb_standard_set_configuration(struct usb_setup_data *req,
(void)len;
/* Is this correct, or should we reset alternate settings. */
- if (req->wValue == _usbd_device.current_config)
+ if (req->wValue == usbd_dev->current_config)
return 1;
- _usbd_device.current_config = req->wValue;
+ usbd_dev->current_config = req->wValue;
/* Reset all endpoints. */
- _usbd_hw_endpoints_reset();
+ usbd_dev->driver->ep_reset(usbd_dev);
- if (_usbd_device.user_callback_set_config) {
+ if (usbd_dev->user_callback_set_config) {
/*
* Flush control callbacks. These will be reregistered
* by the user handler.
*/
for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++)
- _usbd_device.user_control_callback[i].cb = NULL;
+ usbd_dev->user_control_callback[i].cb = NULL;
- _usbd_device.user_callback_set_config(req->wValue);
+ usbd_dev->user_callback_set_config(usbd_dev, req->wValue);
}
return 1;
}
-static int usb_standard_get_configuration(struct usb_setup_data *req,
+static int usb_standard_get_configuration(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
(void)req;
if (*len > 1)
*len = 1;
- (*buf)[0] = _usbd_device.current_config;
+ (*buf)[0] = usbd_dev->current_config;
return 1;
}
-static int usb_standard_set_interface(struct usb_setup_data *req,
+static int usb_standard_set_interface(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
+ (void)usbd_dev;
(void)req;
(void)buf;
@@ -238,9 +247,11 @@ static int usb_standard_set_interface(struct usb_setup_data *req,
return 1;
}
-static int usb_standard_get_interface(struct usb_setup_data *req,
+static int usb_standard_get_interface(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
+ (void)usbd_dev;
(void)req;
(void)buf;
@@ -251,9 +262,11 @@ static int usb_standard_get_interface(struct usb_setup_data *req,
return 1;
}
-static int usb_standard_device_get_status(struct usb_setup_data *req,
+static int usb_standard_device_get_status(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
+ (void)usbd_dev;
(void)req;
/* bit 0: self powered */
@@ -266,9 +279,11 @@ static int usb_standard_device_get_status(struct usb_setup_data *req,
return 1;
}
-static int usb_standard_interface_get_status(struct usb_setup_data *req,
+static int usb_standard_interface_get_status(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
+ (void)usbd_dev;
(void)req;
/* not defined */
@@ -280,45 +295,50 @@ static int usb_standard_interface_get_status(struct usb_setup_data *req,
return 1;
}
-static int usb_standard_endpoint_get_status(struct usb_setup_data *req,
+static int usb_standard_endpoint_get_status(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
(void)req;
if (*len > 2)
*len = 2;
- (*buf)[0] = usbd_ep_stall_get(req->wIndex) ? 1 : 0;
+ (*buf)[0] = usbd_ep_stall_get(usbd_dev, req->wIndex) ? 1 : 0;
(*buf)[1] = 0;
return 1;
}
-static int usb_standard_endpoint_stall(struct usb_setup_data *req,
+static int usb_standard_endpoint_stall(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
(void)buf;
(void)len;
- usbd_ep_stall_set(req->wIndex, 1);
+ usbd_ep_stall_set(usbd_dev, req->wIndex, 1);
return 1;
}
-static int usb_standard_endpoint_unstall(struct usb_setup_data *req,
+static int usb_standard_endpoint_unstall(usbd_device *usbd_dev,
+ struct usb_setup_data *req,
u8 **buf, u16 *len)
{
(void)buf;
(void)len;
- usbd_ep_stall_set(req->wIndex, 0);
+ usbd_ep_stall_set(usbd_dev, req->wIndex, 0);
return 1;
}
-int _usbd_standard_request_device(struct usb_setup_data *req, u8 **buf,
+int _usbd_standard_request_device(usbd_device *usbd_dev,
+ struct usb_setup_data *req, u8 **buf,
u16 *len)
{
- int (*command)(struct usb_setup_data *req, u8 **buf, u16 *len) = NULL;
+ int (*command)(usbd_device *usbd_dev, struct usb_setup_data *req, u8
+ **buf, u16 *len) = NULL;
switch (req->bRequest) {
case USB_REQ_CLEAR_FEATURE:
@@ -361,13 +381,15 @@ int _usbd_standard_request_device(struct usb_setup_data *req, u8 **buf,
if (!command)
return 0;
- return command(req, buf, len);
+ return command(usbd_dev, req, buf, len);
}
-int _usbd_standard_request_interface(struct usb_setup_data *req, u8 **buf,
+int _usbd_standard_request_interface(usbd_device *usbd_dev,
+ struct usb_setup_data *req, u8 **buf,
u16 *len)
{
- int (*command)(struct usb_setup_data *req, u8 **buf, u16 *len) = NULL;
+ int (*command)(usbd_device *usbd_dev, struct usb_setup_data *req,
+ u8 **buf, u16 *len) = NULL;
switch (req->bRequest) {
case USB_REQ_CLEAR_FEATURE:
@@ -388,13 +410,15 @@ int _usbd_standard_request_interface(struct usb_setup_data *req, u8 **buf,
if (!command)
return 0;
- return command(req, buf, len);
+ return command(usbd_dev, req, buf, len);
}
-int _usbd_standard_request_endpoint(struct usb_setup_data *req, u8 **buf,
+int _usbd_standard_request_endpoint(usbd_device *usbd_dev,
+ struct usb_setup_data *req, u8 **buf,
u16 *len)
{
- int (*command) (struct usb_setup_data *req, u8 **buf, u16 *len) = NULL;
+ int (*command) (usbd_device *usbd_dev, struct usb_setup_data *req,
+ u8 **buf, u16 *len) = NULL;
switch (req->bRequest) {
case USB_REQ_CLEAR_FEATURE:
@@ -420,10 +444,11 @@ int _usbd_standard_request_endpoint(struct usb_setup_data *req, u8 **buf,
if (!command)
return 0;
- return command(req, buf, len);
+ return command(usbd_dev, req, buf, len);
}
-int _usbd_standard_request(struct usb_setup_data *req, u8 **buf, u16 *len)
+int _usbd_standard_request(usbd_device *usbd_dev,
+ struct usb_setup_data *req, u8 **buf, u16 *len)
{
/* FIXME: Have class/vendor requests as well. */
if ((req->bmRequestType & USB_REQ_TYPE_TYPE) != USB_REQ_TYPE_STANDARD)
@@ -431,11 +456,12 @@ int _usbd_standard_request(struct usb_setup_data *req, u8 **buf, u16 *len)
switch (req->bmRequestType & USB_REQ_TYPE_RECIPIENT) {
case USB_REQ_TYPE_DEVICE:
- return _usbd_standard_request_device(req, buf, len);
+ return _usbd_standard_request_device(usbd_dev, req, buf, len);
case USB_REQ_TYPE_INTERFACE:
- return _usbd_standard_request_interface(req, buf, len);
+ return _usbd_standard_request_interface(usbd_dev, req,
+ buf, len);
case USB_REQ_TYPE_ENDPOINT:
- return _usbd_standard_request_endpoint(req, buf, len);
+ return _usbd_standard_request_endpoint(usbd_dev, req, buf, len);
default:
return 0;
}