Merge branch 'master' of git://github.com/libopencm3/libopencm3 into upstream-merge
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user