[dev][usb] reformat usb device stack to spaces
This commit is contained in:
416
dev/usb/usb.c
416
dev/usb/usb.c
@@ -42,291 +42,291 @@ static bool usb_active = false;
|
||||
|
||||
static void append_desc_data(usb_descriptor *desc, const void *dat, size_t len)
|
||||
{
|
||||
uint8_t *ptr = malloc(desc->len + len);
|
||||
uint8_t *ptr = malloc(desc->len + len);
|
||||
|
||||
memcpy(ptr, desc->desc, desc->len);
|
||||
memcpy(ptr + desc->len, dat, len);
|
||||
memcpy(ptr, desc->desc, desc->len);
|
||||
memcpy(ptr + desc->len, dat, len);
|
||||
|
||||
/* free the old buffer if it wasn't marked static */
|
||||
if ((desc->flags & USB_DESC_FLAG_STATIC) == 0)
|
||||
free(desc->desc);
|
||||
desc->flags &= ~USB_DESC_FLAG_STATIC;
|
||||
/* free the old buffer if it wasn't marked static */
|
||||
if ((desc->flags & USB_DESC_FLAG_STATIC) == 0)
|
||||
free(desc->desc);
|
||||
desc->flags &= ~USB_DESC_FLAG_STATIC;
|
||||
|
||||
desc->desc = ptr;
|
||||
desc->len += len;
|
||||
desc->desc = ptr;
|
||||
desc->len += len;
|
||||
}
|
||||
|
||||
/* returns the interface number assigned */
|
||||
static int usb_append_interface(usb_descriptor *desc, const uint8_t *int_descr, size_t len)
|
||||
{
|
||||
uint8_t *ptr = malloc(len);
|
||||
int interface_num;
|
||||
uint8_t *ptr = malloc(len);
|
||||
int interface_num;
|
||||
|
||||
// create a temporary copy of the interface
|
||||
memcpy(ptr, int_descr, len);
|
||||
// create a temporary copy of the interface
|
||||
memcpy(ptr, int_descr, len);
|
||||
|
||||
// find the last interface used
|
||||
interface_num = ((uint8_t *)desc->desc)[4]; // current interface
|
||||
// find the last interface used
|
||||
interface_num = ((uint8_t *)desc->desc)[4]; // current interface
|
||||
|
||||
// patch our interface descriptor with the new id
|
||||
ptr[2] = interface_num;
|
||||
// patch our interface descriptor with the new id
|
||||
ptr[2] = interface_num;
|
||||
|
||||
// append it to our config desriptor
|
||||
append_desc_data(desc, ptr, len);
|
||||
free(ptr);
|
||||
// append it to our config desriptor
|
||||
append_desc_data(desc, ptr, len);
|
||||
free(ptr);
|
||||
|
||||
// patch the total length of the config descriptor and set the number of interfaces
|
||||
((uint16_t *)desc->desc)[1] += len;
|
||||
interface_num++;
|
||||
((uint8_t *)desc->desc)[4] = interface_num;
|
||||
// patch the total length of the config descriptor and set the number of interfaces
|
||||
((uint16_t *)desc->desc)[1] += len;
|
||||
interface_num++;
|
||||
((uint8_t *)desc->desc)[4] = interface_num;
|
||||
|
||||
return interface_num - 1;
|
||||
return interface_num - 1;
|
||||
}
|
||||
|
||||
int usb_append_interface_highspeed(const uint8_t *int_descr, size_t len)
|
||||
{
|
||||
return usb_append_interface(&config->highspeed.config, int_descr, len);
|
||||
return usb_append_interface(&config->highspeed.config, int_descr, len);
|
||||
}
|
||||
|
||||
int usb_append_interface_lowspeed(const uint8_t *int_descr, size_t len)
|
||||
{
|
||||
return usb_append_interface(&config->lowspeed.config, int_descr, len);
|
||||
return usb_append_interface(&config->lowspeed.config, int_descr, len);
|
||||
}
|
||||
|
||||
void usb_set_string_descriptor(usb_descriptor *desc, const char *string)
|
||||
{
|
||||
int len = strlen(string);
|
||||
ushort *data;
|
||||
int datalen = len * 2 + 2;
|
||||
int len = strlen(string);
|
||||
ushort *data;
|
||||
int datalen = len * 2 + 2;
|
||||
|
||||
data = malloc(datalen);
|
||||
data = malloc(datalen);
|
||||
|
||||
/* write length field */
|
||||
data[0] = 0x0300 + datalen;
|
||||
/* write length field */
|
||||
data[0] = 0x0300 + datalen;
|
||||
|
||||
/* copy the string into the uint16_t based usb string */
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
data[i + 1] = string[i];
|
||||
}
|
||||
/* copy the string into the uint16_t based usb string */
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
data[i + 1] = string[i];
|
||||
}
|
||||
|
||||
desc->desc = (void *)data;
|
||||
desc->len = datalen;
|
||||
desc->desc = (void *)data;
|
||||
desc->len = datalen;
|
||||
}
|
||||
|
||||
static void set_usb_id(uint16_t vendor, uint16_t product)
|
||||
{
|
||||
// patch the current configuration to with the vendor/product id
|
||||
((uint16_t *)config->lowspeed.device.desc)[4] = vendor;
|
||||
((uint16_t *)config->lowspeed.device.desc)[5] = product;
|
||||
// patch the current configuration to with the vendor/product id
|
||||
((uint16_t *)config->lowspeed.device.desc)[4] = vendor;
|
||||
((uint16_t *)config->lowspeed.device.desc)[5] = product;
|
||||
|
||||
((uint16_t *)config->highspeed.device.desc)[4] = vendor;
|
||||
((uint16_t *)config->highspeed.device.desc)[5] = product;
|
||||
((uint16_t *)config->highspeed.device.desc)[4] = vendor;
|
||||
((uint16_t *)config->highspeed.device.desc)[5] = product;
|
||||
}
|
||||
|
||||
status_t usb_add_string(const char *string, uint8_t id)
|
||||
{
|
||||
uint i;
|
||||
size_t len = strlen(string);
|
||||
uint16_t *strbuf = malloc(len * 2 + 2);
|
||||
uint i;
|
||||
size_t len = strlen(string);
|
||||
uint16_t *strbuf = malloc(len * 2 + 2);
|
||||
|
||||
/* build the usb string descriptor */
|
||||
strbuf[0] = 0x300 | (len * 2 + 2);
|
||||
for (i = 0; i < len; i++) {
|
||||
strbuf[i + 1] = (uint16_t)string[i];
|
||||
}
|
||||
/* build the usb string descriptor */
|
||||
strbuf[0] = 0x300 | (len * 2 + 2);
|
||||
for (i = 0; i < len; i++) {
|
||||
strbuf[i + 1] = (uint16_t)string[i];
|
||||
}
|
||||
|
||||
/* find a slot to put it */
|
||||
for (i = 0; i < MAX_STRINGS; i++) {
|
||||
if (strings[i].id == 0) {
|
||||
strings[i].string.desc = strbuf;
|
||||
strings[i].string.len = len * 2 + 2;
|
||||
strings[i].id = id;
|
||||
return NO_ERROR;
|
||||
}
|
||||
}
|
||||
/* find a slot to put it */
|
||||
for (i = 0; i < MAX_STRINGS; i++) {
|
||||
if (strings[i].id == 0) {
|
||||
strings[i].string.desc = strbuf;
|
||||
strings[i].string.len = len * 2 + 2;
|
||||
strings[i].id = id;
|
||||
return NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_NO_MEMORY;
|
||||
return ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
static void usb_set_active_config(uint8_t config)
|
||||
{
|
||||
if (config != active_config) {
|
||||
active_config = config;
|
||||
if (active_config != 0)
|
||||
printf("usb online\n");
|
||||
else
|
||||
printf("usb offline\n");
|
||||
}
|
||||
if (config != active_config) {
|
||||
active_config = config;
|
||||
if (active_config != 0)
|
||||
printf("usb online\n");
|
||||
else
|
||||
printf("usb offline\n");
|
||||
}
|
||||
}
|
||||
|
||||
status_t usb_callback(usbc_callback_op_t op, const union usb_callback_args *args)
|
||||
{
|
||||
LTRACEF("op %d, args %p\n", op, args);
|
||||
LTRACEF("op %d, args %p\n", op, args);
|
||||
|
||||
/* start looking for specific things to handle */
|
||||
if (op == USB_CB_SETUP_MSG) {
|
||||
const struct usb_setup *setup = args->setup;
|
||||
DEBUG_ASSERT(setup);
|
||||
LTRACEF("SETUP: req_type=%#x req=%#x value=%#x index=%#x len=%#x\n",
|
||||
setup->request_type, setup->request, setup->value, setup->index, setup->length);
|
||||
/* start looking for specific things to handle */
|
||||
if (op == USB_CB_SETUP_MSG) {
|
||||
const struct usb_setup *setup = args->setup;
|
||||
DEBUG_ASSERT(setup);
|
||||
LTRACEF("SETUP: req_type=%#x req=%#x value=%#x index=%#x len=%#x\n",
|
||||
setup->request_type, setup->request, setup->value, setup->index, setup->length);
|
||||
|
||||
if ((setup->request_type & TYPE_MASK) == TYPE_STANDARD) {
|
||||
switch (setup->request) {
|
||||
case SET_ADDRESS:
|
||||
LTRACEF("SET_ADDRESS 0x%x\n", setup->value);
|
||||
usbc_ep0_ack();
|
||||
usbc_set_address(setup->value);
|
||||
break;
|
||||
case SET_FEATURE:
|
||||
case CLEAR_FEATURE:
|
||||
// OTAY
|
||||
LTRACEF("SET/CLEAR_FEATURE, feature 0x%x\n", setup->value);
|
||||
usbc_ep0_ack();
|
||||
break;
|
||||
case SET_DESCRIPTOR:
|
||||
LTRACEF("SET_DESCRIPTOR\n");
|
||||
usbc_ep0_stall();
|
||||
break;
|
||||
case GET_DESCRIPTOR: {
|
||||
/* Get the right descriptors based on current speed */
|
||||
const struct usb_descriptor_speed *speed;
|
||||
if (usbc_is_highspeed()) {
|
||||
speed = &config->highspeed;
|
||||
} else {
|
||||
speed = &config->lowspeed;
|
||||
}
|
||||
if ((setup->request_type & TYPE_MASK) == TYPE_STANDARD) {
|
||||
switch (setup->request) {
|
||||
case SET_ADDRESS:
|
||||
LTRACEF("SET_ADDRESS 0x%x\n", setup->value);
|
||||
usbc_ep0_ack();
|
||||
usbc_set_address(setup->value);
|
||||
break;
|
||||
case SET_FEATURE:
|
||||
case CLEAR_FEATURE:
|
||||
// OTAY
|
||||
LTRACEF("SET/CLEAR_FEATURE, feature 0x%x\n", setup->value);
|
||||
usbc_ep0_ack();
|
||||
break;
|
||||
case SET_DESCRIPTOR:
|
||||
LTRACEF("SET_DESCRIPTOR\n");
|
||||
usbc_ep0_stall();
|
||||
break;
|
||||
case GET_DESCRIPTOR: {
|
||||
/* Get the right descriptors based on current speed */
|
||||
const struct usb_descriptor_speed *speed;
|
||||
if (usbc_is_highspeed()) {
|
||||
speed = &config->highspeed;
|
||||
} else {
|
||||
speed = &config->lowspeed;
|
||||
}
|
||||
|
||||
if ((setup->request_type & RECIP_MASK) == RECIP_DEVICE) {
|
||||
switch (setup->value) {
|
||||
case 0x100: /* device */
|
||||
LTRACEF("got GET_DESCRIPTOR, device descriptor\n");
|
||||
usbc_ep0_send(speed->device.desc, speed->device.len,
|
||||
setup->length);
|
||||
break;
|
||||
case 0x200: /* CONFIGURATION */
|
||||
LTRACEF("got GET_DESCRIPTOR, config descriptor\n");
|
||||
usbc_ep0_send(speed->config.desc, speed->config.len,
|
||||
setup->length);
|
||||
break;
|
||||
case 0x300: /* Language ID */
|
||||
LTRACEF("got GET_DESCRIPTOR, language id\n");
|
||||
usbc_ep0_send(config->langid.desc,
|
||||
config->langid.len, setup->length);
|
||||
break;
|
||||
case (0x301)...(0x3ff): {
|
||||
/* string descriptor, search our list for a match */
|
||||
uint i;
|
||||
bool found = false;
|
||||
uint8_t id = setup->value & 0xff;
|
||||
for (i = 0; i < MAX_STRINGS; i++) {
|
||||
if (strings[i].id == id) {
|
||||
usbc_ep0_send(strings[i].string.desc,
|
||||
strings[i].string.len,
|
||||
setup->length);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
/* couldn't find one, stall */
|
||||
usbc_ep0_stall();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x600: /* DEVICE QUALIFIER */
|
||||
LTRACEF("got GET_DESCRIPTOR, device qualifier\n");
|
||||
usbc_ep0_send(speed->device_qual.desc,
|
||||
speed->device_qual.len, setup->length);
|
||||
break;
|
||||
case 0xa00:
|
||||
/* we aint got one of these */
|
||||
LTRACEF("got GET_DESCRIPTOR, debug descriptor\n");
|
||||
usbc_ep0_stall();
|
||||
break;
|
||||
default:
|
||||
LTRACEF("unhandled descriptor %#x\n", setup->value);
|
||||
// stall
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// interface/endpoint descriptors? let someone else handle it
|
||||
// STALL
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ((setup->request_type & RECIP_MASK) == RECIP_DEVICE) {
|
||||
switch (setup->value) {
|
||||
case 0x100: /* device */
|
||||
LTRACEF("got GET_DESCRIPTOR, device descriptor\n");
|
||||
usbc_ep0_send(speed->device.desc, speed->device.len,
|
||||
setup->length);
|
||||
break;
|
||||
case 0x200: /* CONFIGURATION */
|
||||
LTRACEF("got GET_DESCRIPTOR, config descriptor\n");
|
||||
usbc_ep0_send(speed->config.desc, speed->config.len,
|
||||
setup->length);
|
||||
break;
|
||||
case 0x300: /* Language ID */
|
||||
LTRACEF("got GET_DESCRIPTOR, language id\n");
|
||||
usbc_ep0_send(config->langid.desc,
|
||||
config->langid.len, setup->length);
|
||||
break;
|
||||
case (0x301)...(0x3ff): {
|
||||
/* string descriptor, search our list for a match */
|
||||
uint i;
|
||||
bool found = false;
|
||||
uint8_t id = setup->value & 0xff;
|
||||
for (i = 0; i < MAX_STRINGS; i++) {
|
||||
if (strings[i].id == id) {
|
||||
usbc_ep0_send(strings[i].string.desc,
|
||||
strings[i].string.len,
|
||||
setup->length);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
/* couldn't find one, stall */
|
||||
usbc_ep0_stall();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x600: /* DEVICE QUALIFIER */
|
||||
LTRACEF("got GET_DESCRIPTOR, device qualifier\n");
|
||||
usbc_ep0_send(speed->device_qual.desc,
|
||||
speed->device_qual.len, setup->length);
|
||||
break;
|
||||
case 0xa00:
|
||||
/* we aint got one of these */
|
||||
LTRACEF("got GET_DESCRIPTOR, debug descriptor\n");
|
||||
usbc_ep0_stall();
|
||||
break;
|
||||
default:
|
||||
LTRACEF("unhandled descriptor %#x\n", setup->value);
|
||||
// stall
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// interface/endpoint descriptors? let someone else handle it
|
||||
// STALL
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SET_CONFIGURATION:
|
||||
LTRACEF("SET_CONFIGURATION %d\n", setup->value);
|
||||
usbc_ep0_ack();
|
||||
usb_set_active_config(setup->value);
|
||||
break;
|
||||
case SET_CONFIGURATION:
|
||||
LTRACEF("SET_CONFIGURATION %d\n", setup->value);
|
||||
usbc_ep0_ack();
|
||||
usb_set_active_config(setup->value);
|
||||
break;
|
||||
|
||||
case GET_CONFIGURATION:
|
||||
LTRACEF("GET_CONFIGURATION\n");
|
||||
usbc_ep0_send(&active_config, 1, setup->length);
|
||||
break;
|
||||
case GET_CONFIGURATION:
|
||||
LTRACEF("GET_CONFIGURATION\n");
|
||||
usbc_ep0_send(&active_config, 1, setup->length);
|
||||
break;
|
||||
|
||||
case SET_INTERFACE:
|
||||
LTRACEF("SET_INTERFACE %d\n", setup->value);
|
||||
usbc_ep0_ack();
|
||||
break;
|
||||
case SET_INTERFACE:
|
||||
LTRACEF("SET_INTERFACE %d\n", setup->value);
|
||||
usbc_ep0_ack();
|
||||
break;
|
||||
|
||||
case GET_INTERFACE: {
|
||||
static uint8_t i = 1;
|
||||
LTRACEF("GET_INTERFACE\n");
|
||||
usbc_ep0_send(&i, 1, setup->length);
|
||||
break;
|
||||
}
|
||||
case GET_INTERFACE: {
|
||||
static uint8_t i = 1;
|
||||
LTRACEF("GET_INTERFACE\n");
|
||||
usbc_ep0_send(&i, 1, setup->length);
|
||||
break;
|
||||
}
|
||||
|
||||
case GET_STATUS: {
|
||||
static uint16_t i = 1; // self powered
|
||||
LTRACEF("GET_STATUS\n");
|
||||
usbc_ep0_send(&i, 2, setup->length);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LTRACEF("unhandled standard request 0x%x\n", setup->request);
|
||||
}
|
||||
} else {
|
||||
LTRACEF("unhandled nonstandard request 0x%x\n", setup->request);
|
||||
}
|
||||
}
|
||||
case GET_STATUS: {
|
||||
static uint16_t i = 1; // self powered
|
||||
LTRACEF("GET_STATUS\n");
|
||||
usbc_ep0_send(&i, 2, setup->length);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LTRACEF("unhandled standard request 0x%x\n", setup->request);
|
||||
}
|
||||
} else {
|
||||
LTRACEF("unhandled nonstandard request 0x%x\n", setup->request);
|
||||
}
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t usb_setup(usb_config *_config)
|
||||
{
|
||||
ASSERT(_config);
|
||||
ASSERT(_config);
|
||||
|
||||
config = _config;
|
||||
config = _config;
|
||||
|
||||
ASSERT(usb_active == false);
|
||||
ASSERT(usb_active == false);
|
||||
|
||||
return NO_ERROR;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t usb_start(void)
|
||||
{
|
||||
ASSERT(config);
|
||||
ASSERT(usb_active == false);
|
||||
ASSERT(config);
|
||||
ASSERT(usb_active == false);
|
||||
|
||||
// go online
|
||||
usbc_set_active(true);
|
||||
usb_active = true;
|
||||
// go online
|
||||
usbc_set_active(true);
|
||||
usb_active = true;
|
||||
|
||||
return NO_ERROR;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t usb_stop(void)
|
||||
{
|
||||
ASSERT(usb_active == true);
|
||||
ASSERT(usb_active == true);
|
||||
|
||||
usb_active = false;
|
||||
usbc_set_active(false);
|
||||
usb_active = false;
|
||||
usbc_set_active(false);
|
||||
|
||||
return NO_ERROR;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
static void usb_init(uint level)
|
||||
@@ -334,5 +334,3 @@ static void usb_init(uint level)
|
||||
}
|
||||
|
||||
LK_INIT_HOOK(usb, usb_init, LK_INIT_LEVEL_THREADING);
|
||||
|
||||
// vim: set ts=4 sw=4 noexpandtab:
|
||||
|
||||
Reference in New Issue
Block a user