diff --git a/libusb/Makefile b/libusb/Makefile index f471aee..89f2430 100644 --- a/libusb/Makefile +++ b/libusb/Makefile @@ -1,13 +1,12 @@ # # Makefile for Phoenix-RTOS libusb # -# Copyright 2021 Phoenix Systems +# Copyright 2025 Phoenix Systems # NAME := libusb LOCAL_PATH := $(call my-dir) -HEADERS := $(wildcard $(LOCAL_PATH)*.h) -LOCAL_SRCS := cdc_client.c hid_client.c driver.c procdriver.c +LOCAL_SRCS := cdc_client.c hid_client.c driver.c procdriver.c internal.c devinfo.c LOCAL_CFLAGS := -I$(LOCAL_PATH) include $(static-lib.mk) diff --git a/libusb/devinfo.c b/libusb/devinfo.c new file mode 100644 index 0000000..87a6031 --- /dev/null +++ b/libusb/devinfo.c @@ -0,0 +1,49 @@ +/* + * Phoenix-RTOS + * + * Libusb driver interface + * + * USB low-level information API for userspace applications + * + * Copyright 2025 Phoenix Systems + * Author: Adam Greloch + * + * %LICENSE% + */ + +#include + +#include + +#include "usbinternal.h" +#include "log.h" + + +int usb_devinfoGet(oid_t oid, usb_devinfo_desc_t *desc) +{ + int err; + oid_t hostOid; + msg_t msg = { 0 }; + usb_msg_t *imsg = (usb_msg_t *)msg.i.raw; + + usb_hostLookup(&hostOid); + + msg.type = mtDevCtl; + imsg->type = usb_msg_devdesc; + imsg->devdesc.oid = oid; + msg.o.data = desc; + msg.o.size = sizeof(usb_devinfo_desc_t); + + err = msgSend(hostOid.port, &msg); + if (err < 0) { + log_error("msgSend failed: %d\n", err); + return err; + } + + if (msg.o.err < 0) { + log_error("msg.o.err=%d\n", msg.o.err); + return msg.o.err; + } + + return 0; +} diff --git a/libusb/cdc.h b/libusb/include/cdc.h similarity index 100% rename from libusb/cdc.h rename to libusb/include/cdc.h diff --git a/libusb/cdc_client.h b/libusb/include/cdc_client.h similarity index 100% rename from libusb/cdc_client.h rename to libusb/include/cdc_client.h diff --git a/libusb/hid.h b/libusb/include/hid.h similarity index 100% rename from libusb/hid.h rename to libusb/include/hid.h diff --git a/libusb/hid_client.h b/libusb/include/hid_client.h similarity index 100% rename from libusb/hid_client.h rename to libusb/include/hid_client.h diff --git a/libusb/usb.h b/libusb/include/usb.h similarity index 100% rename from libusb/usb.h rename to libusb/include/usb.h diff --git a/libusb/usbclient.h b/libusb/include/usbclient.h similarity index 100% rename from libusb/usbclient.h rename to libusb/include/usbclient.h diff --git a/libusb/include/usbdevinfo.h b/libusb/include/usbdevinfo.h new file mode 100644 index 0000000..b99f528 --- /dev/null +++ b/libusb/include/usbdevinfo.h @@ -0,0 +1,25 @@ +/* + * Phoenix-RTOS + * + * Libusb driver interface + * + * USB low-level information API for userspace applications + * + * Copyright 2025 Phoenix Systems + * Author: Adam Greloch + * + * %LICENSE% + */ + + +#ifndef _USB_DEVINFO_H_ +#define _USB_DEVINFO_H_ + +#include +#include + + +int usb_devinfoGet(oid_t oid, usb_devinfo_desc_t *desc); + + +#endif diff --git a/libusb/usbdriver.h b/libusb/include/usbdriver.h similarity index 83% rename from libusb/usbdriver.h rename to libusb/include/usbdriver.h index 91001f7..2165f95 100644 --- a/libusb/usbdriver.h +++ b/libusb/include/usbdriver.h @@ -23,6 +23,9 @@ #include #include +#define USB_DRVNAME_MAX 10 +#define USB_STR_MAX 254 /* per USB 2.0 spec */ + #define USBDRV_ANY ((unsigned)-1) @@ -54,6 +57,7 @@ typedef struct { typedef struct { unsigned port; unsigned nfilters; + char name[USB_DRVNAME_MAX]; } usb_connect_t; @@ -117,6 +121,11 @@ typedef struct { } usb_completion_t; +typedef struct { + oid_t oid; +} usb_devdesc_t; + + typedef struct { enum { usb_msg_connect, usb_msg_insertion, @@ -124,7 +133,8 @@ typedef struct { usb_msg_urb, usb_msg_open, usb_msg_urbcmd, - usb_msg_completion } type; + usb_msg_completion, + usb_msg_devdesc } type; union { usb_connect_t connect; @@ -134,10 +144,21 @@ typedef struct { usb_devinfo_t insertion; usb_deletion_t deletion; usb_completion_t completion; + usb_devdesc_t devdesc; }; } usb_msg_t; +typedef struct { + usb_device_desc_t desc; + + struct { + unsigned int len; + char str[USB_STR_MAX]; + } manufacturer, product, serialNumber; +} __attribute__((packed)) usb_devinfo_desc_t; + + typedef struct { uint16_t vid; uint16_t pid; @@ -146,13 +167,26 @@ typedef struct { } usb_modeswitch_t; +typedef struct { + bool deviceCreated; /* Set to true by the insertion handler if a device file for the inserted device has been created */ + + /* oid and path to the device file */ + oid_t dev; + char devPath[32]; +} usb_event_insertion_t; + + typedef struct usb_driver usb_driver_t; typedef int (*usb_completion_handler_t)(usb_driver_t *drv, usb_completion_t *completion, const char *data, size_t len); -typedef int (*usb_insertion_handler_t)(usb_driver_t *drv, usb_devinfo_t *devinfo); +/* + * Returns 0 if insertion succeeds. Implementations can assume `event` is a valid pointer provided by the caller. + * The event struct is populated only if insertion succeeds (its contents must be valid after the call) + */ +typedef int (*usb_insertion_handler_t)(usb_driver_t *drv, usb_devinfo_t *devinfo, usb_event_insertion_t *event); typedef int (*usb_deletion_handler_t)(usb_driver_t *drv, usb_deletion_t *deletion); @@ -186,7 +220,7 @@ typedef struct { struct usb_driver { usb_driver_t *next, *prev; - char name[10]; + char name[USB_DRVNAME_MAX]; usb_handlers_t handlers; usb_driverOps_t ops; const usb_pipeOps_t *pipeOps; @@ -204,9 +238,6 @@ int usb_modeswitchHandle(usb_driver_t *drv, usb_devinfo_t *dev, const usb_modesw const usb_modeswitch_t *usb_modeswitchFind(uint16_t vid, uint16_t pid, const usb_modeswitch_t *modes, int nmodes); -int usb_eventsWait(int port, msg_t *msg); - - int usb_open(usb_driver_t *drv, usb_devinfo_t *dev, usb_transfer_type_t type, usb_dir_t dir); diff --git a/libusb/usbprocdriver.h b/libusb/include/usbprocdriver.h similarity index 100% rename from libusb/usbprocdriver.h rename to libusb/include/usbprocdriver.h diff --git a/libusb/internal.c b/libusb/internal.c new file mode 100644 index 0000000..c103ac0 --- /dev/null +++ b/libusb/internal.c @@ -0,0 +1,30 @@ +/* + * Phoenix-RTOS + * + * libusb/internal.c + * + * Copyright 2025 Phoenix Systems + * Author: Adam Greloch + * + * %LICENSE% + */ + + +#include +#include + + +void usb_hostLookup(oid_t *oid) +{ + for (;;) { + if (lookup("devfs/usb", NULL, oid) >= 0) { + break; + } + + if (lookup("/dev/usb", NULL, oid) >= 0) { + break; + } + + usleep(1000000); + } +} diff --git a/libusb/log.h b/libusb/log.h new file mode 100644 index 0000000..8ec52ab --- /dev/null +++ b/libusb/log.h @@ -0,0 +1,30 @@ + +/* + * Phoenix-RTOS + * + * Libusb driver interface + * + * libusb/log.h + * + * Copyright 2025 Phoenix Systems + * Author: Adam Greloch + * + * %LICENSE% + */ + + +#ifndef _LIBUSB_LOG_H_ +#define _LIBUSB_LOG_H_ + + +#define LIBUSB_LOG_TAG "libusb" +#define LIBUSB_TRACE 0 + +/* clang-format off */ +#define log_msg(fmt, ...) do { fprintf(stderr, LIBUSB_LOG_TAG ": " fmt, ##__VA_ARGS__); } while (0) +#define log_trace(fmt, ...) do { if (LIBUSB_TRACE != 0) log_msg("%s: " fmt, __func__ __VA_OPT__(, ) ##__VA_ARGS__); } while (0) +#define log_error(fmt, ...) log_msg(fmt, ##__VA_ARGS__) +/* clang-format on */ + + +#endif diff --git a/libusb/procdriver.c b/libusb/procdriver.c index a57e995..8456d3c 100644 --- a/libusb/procdriver.c +++ b/libusb/procdriver.c @@ -19,6 +19,9 @@ #include #include +#include + +#include "log.h" #ifndef USB_N_UMSG_THREADS @@ -30,6 +33,10 @@ #endif +#undef LIBUSB_LOG_TAG +#define LIBUSB_LOG_TAG "libusb(procdriver)" + + static usb_pipeOps_t usbprocdrv_pipeOps; @@ -40,43 +47,30 @@ static struct { } usbprocdrv_common; -static void usb_hostLookup(oid_t *oid) -{ - int ret; - - for (;;) { - ret = lookup("devfs/usb", NULL, oid); - if (ret >= 0) { - break; - } - - ret = lookup("/dev/usb", NULL, oid); - if (ret >= 0) { - break; - } - - usleep(1000000); - } -} - - static void usb_thread(void *arg) { usb_driver_t *drv = (usb_driver_t *)arg; msg_t msg = { 0 }; usb_msg_t *umsg = (usb_msg_t *)&msg.i.raw; + usb_event_insertion_t event; int ret; + msg_rid_t rid; for (;;) { - ret = usb_eventsWait(usbprocdrv_common.drvport, &msg); - if (ret < 0) { - fprintf(stderr, "usbdrv: error when receiving event from host\n"); - continue; - } + do { + ret = msgRecv(usbprocdrv_common.drvport, &msg, &rid); + if (ret < 0 && ret != -EINTR) { + log_error("error when receiving event from host\n"); + continue; + } + } while (ret == -EINTR); switch (umsg->type) { case usb_msg_insertion: - drv->handlers.insertion(drv, &umsg->insertion); + msg.o.err = drv->handlers.insertion(drv, &umsg->insertion, &event); + if (msg.o.err == 0) { + memcpy(msg.o.raw, &event, sizeof(usb_event_insertion_t)); + } break; case usb_msg_deletion: drv->handlers.deletion(drv, &umsg->deletion); @@ -85,17 +79,24 @@ static void usb_thread(void *arg) drv->handlers.completion(drv, &umsg->completion, msg.i.data, msg.i.size); break; default: - fprintf(stderr, "usbdrv: unknown msg type\n"); + log_error("unknown msg type\n"); break; } + + ret = msgRespond(usbprocdrv_common.drvport, &msg, rid); + if (ret < 0) { + log_error("error when replying to host\n"); + } } } -static int usb_connect(const usb_device_id_t *filters, unsigned int nfilters) +static int usb_connect(usb_driver_t *drv) { msg_t msg = { 0 }; usb_msg_t *umsg = (usb_msg_t *)&msg.i.raw; + const usb_device_id_t *filters = drv->filters; + unsigned int nfilters = drv->nfilters; msg.type = mtDevCtl; msg.i.size = sizeof(*filters) * nfilters; @@ -104,6 +105,7 @@ static int usb_connect(const usb_device_id_t *filters, unsigned int nfilters) umsg->type = usb_msg_connect; umsg->connect.port = usbprocdrv_common.drvport; umsg->connect.nfilters = nfilters; + strncpy(umsg->connect.name, drv->name, USB_DRVNAME_MAX); return msgSend(usbprocdrv_common.srvport, &msg) < 0; } @@ -130,7 +132,7 @@ int usb_driverProcRun(usb_driver_t *drv, void *args) return -1; } - ret = usb_connect(drv->filters, drv->nfilters); + ret = usb_connect(drv); if (ret < 0) { return -1; } @@ -138,7 +140,7 @@ int usb_driverProcRun(usb_driver_t *drv, void *args) for (i = 0; i < USB_N_UMSG_THREADS - 1; i++) { ret = beginthread(usb_thread, USB_UMSG_PRIO, usbprocdrv_common.ustack[i], sizeof(usbprocdrv_common.ustack[i]), drv); if (ret < 0) { - fprintf(stderr, "usbdrv: fail to beginthread ret: %d\n", ret); + log_error("fail to beginthread ret: %d\n", ret); return -1; } } @@ -150,24 +152,6 @@ int usb_driverProcRun(usb_driver_t *drv, void *args) } -int usb_eventsWait(int port, msg_t *msg) -{ - msg_rid_t rid; - int err; - - do { - err = msgRecv(port, msg, &rid); - if (err < 0 && err != -EINTR) - return -1; - } while (err == -EINTR); - - if (msgRespond(port, msg, rid) < 0) - return -1; - - return 0; -} - - static int usbprocdrv_open(usb_driver_t *drv, usb_devinfo_t *dev, usb_transfer_type_t type, usb_dir_t dir) { msg_t msg = { 0 }; diff --git a/libusb/usbinternal.h b/libusb/usbinternal.h new file mode 100644 index 0000000..4d45cf6 --- /dev/null +++ b/libusb/usbinternal.h @@ -0,0 +1,24 @@ +/* + * Phoenix-RTOS + * + * Libusb driver interface + * + * Internal header + * + * Copyright 2025 Phoenix Systems + * Author: Adam Greloch + * + * %LICENSE% + */ + +#ifndef _USB_INTERNAL_H_ +#define _USB_INTERNAL_H_ + + +#include + + +void usb_hostLookup(oid_t *oid); + + +#endif diff --git a/usb/dev.c b/usb/dev.c index fc26898..2dc77f5 100644 --- a/usb/dev.c +++ b/usb/dev.c @@ -17,8 +17,11 @@ #include #include #include +#include +#include #include #include +#include #include @@ -27,14 +30,28 @@ #include "drv.h" #include "hcd.h" #include "hub.h" +#include "log.h" #define USBDEV_BUF_SIZE 0x200 + +typedef struct devOid { + struct devOid *prev, *next; + + /* iface-specific dev oid created by the dev's driver */ + oid_t oid; + + usb_dev_t *dev; +} usb_devOid_t; + + struct { handle_t lock; handle_t cond; char *ctrlBuf; char *setupBuf; + + usb_devOid_t *devOids; } usbdev_common; @@ -130,13 +147,14 @@ void usb_devFree(usb_dev_t *dev) { int i; - free(dev->manufacturer); - free(dev->product); - free(dev->serialNumber); + free(dev->manufacturer.str); + free(dev->product.str); + free(dev->serialNumber.str); free(dev->conf); - for (i = 0; i < dev->nifs; i++) - free(dev->ifs[i].str); + for (i = 0; i < dev->nifs; i++) { + free(dev->ifs[i].name.str); + } usb_drvPipeFree(NULL, dev->ctrlPipe); if (dev->statusTransfer != NULL) { @@ -244,7 +262,7 @@ static int usb_getConfiguration(usb_dev_t *dev) uint8_t len = ((struct usb_desc_header *)ptr)->bLength; if ((len < sizeof(struct usb_desc_header)) || (len > size)) { - USB_LOG("usb: Invalid descriptor size: %u\n", len); + log_error("Invalid descriptor size: %u\n", len); break; } @@ -268,7 +286,7 @@ static int usb_getConfiguration(usb_dev_t *dev) } } else { - USB_LOG("usb: Interface descriptor with invalid size\n"); + log_error("Interface descriptor with invalid size\n"); ret = -1; } break; @@ -296,7 +314,7 @@ static int usb_getConfiguration(usb_dev_t *dev) } } else { - USB_LOG("usb: Endpoint descriptor with invalid size\n"); + log_error("Endpoint descriptor with invalid size\n"); ret = -1; } break; @@ -309,7 +327,7 @@ static int usb_getConfiguration(usb_dev_t *dev) dev->desc.bDeviceProtocol = ((usb_interface_association_desc_t *)ptr)->bFunctionProtocol; } else { - USB_LOG("usb: Interface assoctiation descriptor with invalid size\n"); + log_error("Interface assoctiation descriptor with invalid size\n"); ret = -1; } break; @@ -319,7 +337,7 @@ static int usb_getConfiguration(usb_dev_t *dev) break; default: - USB_LOG("usb: Ignoring unkonown descriptor type: 0x%02x\n", ((struct usb_desc_header *)ptr)->bDescriptorType); + log_error("Ignoring unkonown descriptor type: 0x%02x\n", ((struct usb_desc_header *)ptr)->bDescriptorType); break; } @@ -336,7 +354,7 @@ static int usb_getConfiguration(usb_dev_t *dev) } if (ret != 0) { - USB_LOG("usb: Fail to parse interface descriptors\n"); + log_error("Fail to parse interface descriptors\n"); free(dev->ifs); dev->ifs = NULL; dev->nifs = 0; @@ -350,81 +368,143 @@ static int usb_getConfiguration(usb_dev_t *dev) } -static int usb_getStringDesc(usb_dev_t *dev, char **buf, int index) +static int usb_getStringDesc(usb_dev_t *dev, usb_lenStr_t *dest, int index) { usb_string_desc_t desc = { 0 }; - int i; - size_t asciisz; if (usb_getDescriptor(dev, USB_DESC_STRING, index, (char *)&desc, sizeof(desc)) < 0) { - USB_LOG("usb: Fail to get string descriptor\n"); + log_error("Fail to get string descriptor\n"); return -1; } - asciisz = (desc.bLength - 2) / 2; - /* Convert from unicode to ascii */ - if ((*buf = calloc(1, asciisz + 1)) == NULL) + dest->str = malloc(desc.bLength - 2); + if (dest->str == NULL) { return -ENOMEM; + } - for (i = 0; i < asciisz; i++) - (*buf)[i] = desc.wData[i * 2]; + dest->len = desc.bLength - 2; + memcpy(dest->str, desc.wData, dest->len); return 0; } -#define USB_STRING_MAX_LEN 255 +/* assumes dest buffer size >= len / 2 + 1 */ +static unsigned int usb_utf16ToAscii(char *dest, const char *src, unsigned int len) +{ + unsigned int asciilen = len / 2; + int i; + if (len < 2) { + return 0; + } -static void usb_fallbackProductString(usb_dev_t *dev) + for (i = 0; i < asciilen; i++) { + dest[i] = src[i * 2]; + } + + dest[asciilen] = 0; + + return asciilen; +} + + +#define USB_HID_UTF16_STR u"USB HID" +#define USB_HUB_ROOT_USTR u"USB Root Hub" +#define USB_HUB_SINGLE_TT_USTR u"USB Single TT Hub" +#define USB_HUB_OTHER_USTR u"USB Hub" +#define USB_MASS_STORAGE_USTR u"USB Mass Storage" +#define USB_UNKNOWN_DEV_USTR u"Unknown USB Device" + + +static int usb_fallbackProductString(usb_dev_t *dev) { - char product[USB_STRING_MAX_LEN] = { 0 }; + char *product; + unsigned int len; switch (dev->desc.bDeviceClass) { case USB_CLASS_HID: - strcpy(product, "USB HID"); + product = (char *)USB_HID_UTF16_STR; + len = sizeof(USB_HID_UTF16_STR); break; case USB_CLASS_HUB: switch (dev->desc.bDeviceProtocol) { case USB_HUB_PROTO_ROOT: - strcpy(product, "USB Root Hub"); + product = (char *)USB_HUB_ROOT_USTR; + len = sizeof(USB_HUB_ROOT_USTR); break; case USB_HUB_PROTO_SINGLE_TT: - strcpy(product, "USB Single TT Hub"); + product = (char *)USB_HUB_SINGLE_TT_USTR; + len = sizeof(USB_HUB_SINGLE_TT_USTR); break; default: - strcpy(product, "USB Hub"); + product = (char *)USB_HUB_OTHER_USTR; + len = sizeof(USB_HUB_OTHER_USTR); break; } break; case USB_CLASS_MASS_STORAGE: - strcpy(product, "USB Mass Storage"); + product = (char *)USB_MASS_STORAGE_USTR; + len = sizeof(USB_MASS_STORAGE_USTR); break; default: - strcpy(product, "Unknown USB Device"); + product = (char *)USB_UNKNOWN_DEV_USTR; + len = sizeof(USB_UNKNOWN_DEV_USTR); break; } - dev->product = calloc(sizeof(char), strnlen(product, USB_STRING_MAX_LEN) + 1); - strcpy(dev->product, product); + len -= 2; + + dev->product.str = malloc(len); + + if (dev->product.str == NULL) { + return -ENOMEM; + } + + memcpy(dev->product.str, product, len); + dev->product.len = len; + + return 0; } -static void usb_fallbackManufacturerString(usb_dev_t *dev) +#define USB_MANUFACTURER_USTR u"Generic" + + +static int usb_fallbackManufacturerString(usb_dev_t *dev) { - char manufacturer[] = "Generic"; + const char *manufacturer = (char *)USB_MANUFACTURER_USTR; + int len = sizeof(USB_MANUFACTURER_USTR) - 2; + + dev->manufacturer.str = malloc(len); + if (dev->manufacturer.str == NULL) { + return -ENOMEM; + } - dev->manufacturer = calloc(sizeof(char), strnlen(manufacturer, USB_STRING_MAX_LEN) + 1); - strcpy(dev->manufacturer, manufacturer); + memcpy(dev->manufacturer.str, manufacturer, len); + dev->manufacturer.len = len; + + return 0; } -static void usb_fallbackSerialNumberString(usb_dev_t *dev) +#define USB_SERIAL_NUMBER_USTR u"Unknown" + + +static int usb_fallbackSerialNumberString(usb_dev_t *dev) { - char serialNumber[] = "Unknown"; + const char *serialNumber = (char *)USB_SERIAL_NUMBER_USTR; + int len = sizeof(USB_SERIAL_NUMBER_USTR) - 2; - dev->serialNumber = calloc(sizeof(char), strnlen(serialNumber, USB_STRING_MAX_LEN) + 1); - strcpy(dev->serialNumber, serialNumber); + dev->serialNumber.str = malloc(len); + if (dev->serialNumber.str == NULL) { + return -ENOMEM; + } + + memcpy(dev->serialNumber.str, serialNumber, len); + dev->serialNumber.len = len; + + return 0; } @@ -474,7 +554,7 @@ static int usb_getAllStringDescs(usb_dev_t *dev) for (i = 0; i < dev->nifs; i++) { if (dev->ifs[i].desc->iInterface == 0) continue; - if (usb_getStringDesc(dev, &dev->ifs[i].str, dev->ifs[i].desc->iInterface) != 0) + if (usb_getStringDesc(dev, &dev->ifs[i].name, dev->ifs[i].desc->iInterface) != 0) return -ENOMEM; } @@ -484,17 +564,74 @@ static int usb_getAllStringDescs(usb_dev_t *dev) } +#define USB_DEV_SYMLINK_FORMAT "/dev/usb-%04x-%04x-if%02d" + + +static void usb_devSymlinksCreate(usb_dev_t *dev, const char *devPath, int iface) +{ + char linkpath[32] = { 0 }; + int ret; + + sprintf(linkpath, USB_DEV_SYMLINK_FORMAT, dev->desc.idVendor, dev->desc.idProduct, iface); + + unlink(linkpath); + ret = symlink(devPath, linkpath); + + if (ret < 0) { + log_error("%s -> %s symlink error: %d", linkpath, devPath, errno); + } +} + + +static void usb_devSymlinksDestroy(usb_dev_t *dev, int iface) +{ + char linkpath[32] = { 0 }; + + sprintf(linkpath, USB_DEV_SYMLINK_FORMAT, dev->desc.idVendor, dev->desc.idProduct, iface); + unlink(linkpath); +} + + +static void usb_devOnDrvBindCb(usb_dev_t *dev, usb_event_insertion_t *event, int iface) +{ + usb_devOid_t *devOid; + + if (event->deviceCreated) { + devOid = calloc(1, sizeof(usb_devOid_t)); + + if (devOid == NULL) { + log_error("calloc failed"); + return; + } + + log_info("Dev oid bound to device with addr %d: port=%u, id=%u\n", + dev->address, event->dev.port, (uint32_t)event->dev.id); + + devOid->oid = event->dev; + devOid->dev = dev; + + mutexLock(usbdev_common.lock); + LIST_ADD(&usbdev_common.devOids, devOid); + mutexUnlock(usbdev_common.lock); + + usb_devSymlinksCreate(dev, event->devPath, iface); + } +} + + int usb_devEnumerate(usb_dev_t *dev) { + char manufacturerAscii[USB_STR_MAX / 2 + 1]; + char productAscii[USB_STR_MAX / 2 + 1]; int addr; if (usb_genLocationID(dev) < 0) { - USB_LOG("usb: Fail to generate location ID\n"); + log_error("Fail to generate location ID\n"); return -1; } if (usb_getDevDesc(dev) < 0) { - USB_LOG("usb: Fail to get device descriptor\n"); + log_error("Fail to get device descriptor\n"); return -1; } @@ -502,22 +639,22 @@ int usb_devEnumerate(usb_dev_t *dev) dev->ctrlPipe->maxPacketLen = dev->desc.bMaxPacketSize0; if ((addr = hcd_addrAlloc(dev->hcd)) < 0) { - USB_LOG("usb: Fail to add device to hcd\n"); + log_error("Fail to add device to hcd\n"); return -1; } if (usb_setAddress(dev, addr) < 0) { - USB_LOG("usb: Fail to set device address\n"); + log_error("Fail to set device address\n"); return -1; } if (usb_getDevDesc(dev) < 0) { - USB_LOG("usb: Fail to get device descriptor\n"); + log_error("Fail to get device descriptor\n"); return -1; } if (usb_getConfiguration(dev) < 0) { - USB_LOG("usb: Fail to get configuration descriptor\n"); + log_error("Fail to get configuration descriptor\n"); return -1; } @@ -526,34 +663,90 @@ int usb_devEnumerate(usb_dev_t *dev) if (!usb_isRoothub(dev)) usb_devSetChild(dev->hub, dev->port, dev); - USB_LOG("usb: New device addr: %d locationID: %08x %s, %s\n", dev->address, dev->locationID, - dev->manufacturer, dev->product); + usb_utf16ToAscii(manufacturerAscii, dev->manufacturer.str, dev->manufacturer.len); + usb_utf16ToAscii(productAscii, dev->product.str, dev->product.len); + + log_info("New device: %04x:%04x %s, %s (%d, %08x)\n", + dev->desc.idVendor, dev->desc.idProduct, manufacturerAscii, productAscii, + dev->address, dev->locationID); if (dev->desc.bDeviceClass == USB_CLASS_HUB) { if (hub_conf(dev) != 0) return -1; } - else if (usb_drvBind(dev) != 0) { - USB_LOG("usb: Fail to match drivers for device\n"); + else if (usb_drvBind(dev, usb_devOnDrvBindCb) != 0) { + log_msg("Fail to match drivers for device\n"); /* TODO: make device orphaned */ + return -1; } return 0; } +static usb_dev_t *_usb_devOidFind(oid_t oid) +{ + usb_devOid_t *curr = usbdev_common.devOids; + + if (curr != NULL) { + do { + if (curr->oid.port == oid.port && curr->oid.id == oid.id) { + return curr->dev; + } + curr = curr->next; + } while (curr != usbdev_common.devOids); + } + + return NULL; +} + + +static void usb_devFreeOids(usb_dev_t *dev) +{ + usb_devOid_t *next, *curr = usbdev_common.devOids; + + bool end = false; + + mutexLock(usbdev_common.lock); + + if (curr != NULL) { + do { + next = curr->next; + + if (curr == next) { + end = true; + } + + if (curr->dev == dev) { + LIST_REMOVE(&usbdev_common.devOids, curr); + free(curr); + } + + curr = next; + } while (!end && curr != usbdev_common.devOids); + } + + mutexUnlock(usbdev_common.lock); +} + + static void usb_devUnbind(usb_dev_t *dev) { int i; for (i = 0; i < dev->nports; i++) { - if (dev->devs[i] != NULL) + if (dev->devs[i] != NULL) { usb_devUnbind(dev->devs[i]); + } } + usb_devFreeOids(dev); + for (i = 0; i < dev->nifs; i++) { - if (dev->ifs[i].driver) + if (dev->ifs[i].driver != NULL) { + usb_devSymlinksDestroy(dev, i); usb_drvUnbind(dev->ifs[i].driver, dev, i); + } } } @@ -588,10 +781,44 @@ usb_dev_t *usb_devFind(usb_dev_t *hub, int locationID) } +int usb_devFindDescFromOid(oid_t oid, usb_devinfo_desc_t *desc) +{ + usb_dev_t *dev; + + if (desc == NULL) { + return -EINVAL; + } + + mutexLock(usbdev_common.lock); + + dev = _usb_devOidFind(oid); + if (dev == NULL) { + mutexUnlock(usbdev_common.lock); + log_msg("device not found with oid.id=%u oid.port=%u \n", (uint32_t)oid.id, oid.port); + return -EINVAL; + } + + memcpy(&desc->desc, &dev->desc, sizeof(usb_device_desc_t)); + + memcpy(desc->product.str, dev->product.str, dev->product.len); + desc->product.len = dev->product.len; + + memcpy(desc->manufacturer.str, dev->manufacturer.str, dev->manufacturer.len); + desc->manufacturer.len = dev->manufacturer.len; + + memcpy(desc->serialNumber.str, dev->serialNumber.str, dev->serialNumber.len); + desc->serialNumber.len = dev->serialNumber.len; + + mutexUnlock(usbdev_common.lock); + + return 0; +} + + void usb_devDisconnected(usb_dev_t *dev, bool silent) { if (!silent) { - printf("usb: Device disconnected addr %d locationID: %08x\n", dev->address, dev->locationID); + log_info("Device disconnected addr %d locationID: %08x\n", dev->address, dev->locationID); } usb_devSetChild(dev->hub, dev->port, NULL); usb_devUnbind(dev); @@ -614,20 +841,20 @@ int usb_isRoothub(usb_dev_t *dev) int usb_devInit(void) { if (mutexCreate(&usbdev_common.lock) != 0) { - USB_LOG("usbdev: Can't create mutex!\n"); + log_error("Can't create mutex!\n"); return -ENOMEM; } if (condCreate(&usbdev_common.cond) != 0) { resourceDestroy(usbdev_common.lock); - USB_LOG("usbdev: Can't create cond!\n"); + log_error("Can't create cond!\n"); return -ENOMEM; } if ((usbdev_common.setupBuf = usb_alloc(USBDEV_BUF_SIZE)) == NULL) { resourceDestroy(usbdev_common.lock); resourceDestroy(usbdev_common.cond); - USB_LOG("usbdev: Fail to allocate buffer!\n"); + log_error("Fail to allocate buffer!\n"); return -ENOMEM; } diff --git a/usb/dev.h b/usb/dev.h index e533941..5134992 100644 --- a/usb/dev.h +++ b/usb/dev.h @@ -21,27 +21,43 @@ #include "usbhost.h" -enum usb_speed { usb_full_speed = 0, usb_low_speed, usb_high_speed }; +enum usb_speed { usb_full_speed = 0, + usb_low_speed, + usb_high_speed }; + + +typedef struct { + unsigned int len; + char *str; +} usb_lenStr_t; + typedef struct { usb_interface_desc_t *desc; usb_endpoint_desc_t *eps; void *classDesc; - char *str; + usb_lenStr_t name; struct usb_drvpriv *driver; } usb_iface_t; +typedef struct usb_dev_oid { + struct usb_dev_oid *next, *prev; + oid_t oid; +} usb_dev_oids_t; + + typedef struct _usb_dev { struct _usb_dev *next, *prev; enum usb_speed speed; usb_device_desc_t desc; usb_configuration_desc_t *conf; - char *manufacturer; - char *product; - char *serialNumber; + + usb_lenStr_t manufacturer; + usb_lenStr_t product; + usb_lenStr_t serialNumber; uint16_t langId; int address; @@ -89,4 +105,7 @@ int usb_isRoothub(usb_dev_t *dev); void usb_devSignal(void); +int usb_devFindDescFromOid(oid_t oid, usb_devinfo_desc_t *desc); + + #endif /* _USB_DEV_H_ */ diff --git a/usb/drv.c b/usb/drv.c index c76e47f..10a19e1 100644 --- a/usb/drv.c +++ b/usb/drv.c @@ -26,7 +26,10 @@ #include "drv.h" #include "hcd.h" +#include "log.h" +#undef USB_LOG_TAG +#define USB_LOG_TAG "usbdrv" struct { handle_t lock; @@ -107,12 +110,12 @@ static usb_pipe_t *_usb_drvPipeOpen(usb_drvpriv_t *drv, hcd_t *hcd, int location int i; if ((dev = usb_devFind(hcd->roothub, locationID)) == NULL) { - USB_LOG("usb: Fail to find device\n"); + log_error("Fail to find device\n"); return NULL; } if (dev->nifs < ifaceID) { - USB_LOG("usb: Fail to find iface\n"); + log_error("Fail to find iface\n"); return NULL; } @@ -357,20 +360,15 @@ int usb_drvUnbind(usb_drvpriv_t *drv, usb_dev_t *dev, int iface) } -int usb_drvBind(usb_dev_t *dev) +int usb_drvBind(usb_dev_t *dev, usb_drvOnBindCb_t onBindCb) { usb_drvpriv_t *drv; - msg_t msg = { 0 }; + msg_t msg; usb_msg_t *umsg = (usb_msg_t *)msg.i.raw; - int i, err; + int i, err, ndrvs = 0; - msg.type = mtDevCtl; - umsg->type = usb_msg_insertion; - umsg->insertion.bus = dev->hcd->num; - umsg->insertion.dev = dev->address; - umsg->insertion.descriptor = dev->desc; - umsg->insertion.locationID = dev->locationID; + usb_event_insertion_t event = { 0 }; /* FIXME: drvAdd races with drvMatchIface in multi-driver scenario. * Devices may become orphaned forever if they get added by hcd before the driver @@ -378,32 +376,49 @@ int usb_drvBind(usb_dev_t *dev) for (i = 0; i < dev->nifs; i++) { drv = usb_drvMatchIface(dev, &dev->ifs[i]); if (drv != NULL) { + memset(&msg, 0, sizeof(msg)); + msg.type = mtDevCtl; + umsg->type = usb_msg_insertion; + umsg->insertion.bus = dev->hcd->num; + umsg->insertion.dev = dev->address; + umsg->insertion.descriptor = dev->desc; + umsg->insertion.locationID = dev->locationID; + dev->ifs[i].driver = drv; umsg->insertion.interface = i; switch (drv->type) { case usb_drvType_intrn: - err = drv->driver.handlers.insertion(&drv->driver, &umsg->insertion); + err = drv->driver.handlers.insertion(&drv->driver, &umsg->insertion, &event); break; case usb_drvType_extrn: err = msgSend(drv->extrn.port, &msg); if (err == 0) { err = msg.o.err; } + + if (err == 0) { + memcpy(&event, msg.o.raw, sizeof(usb_event_insertion_t)); + } break; default: - USB_LOG("usb: unexpected driver type: %d\n", drv->type); + log_error("unexpected driver type: %d\n", drv->type); + err = -1; break; } if (err == 0) { - return 0; + if (onBindCb != NULL) { + onBindCb(dev, &event, i); + } + ndrvs++; } } + /* TODO: Make a device orphaned */ } - return -1; + return ndrvs == 0 ? -1 : 0; } @@ -587,7 +602,7 @@ static int _usb_handleUrb(msg_t *msg, unsigned int port, unsigned long rid) drv = _usb_drvFind(msg->pid); if (drv == NULL) { - USB_LOG("usb: driver pid %d does not exist!\n", msg->pid); + log_error("driver pid %d does not exist!\n", msg->pid); return -EINVAL; } @@ -602,7 +617,7 @@ static int _usb_handleUrb(msg_t *msg, unsigned int port, unsigned long rid) t->extrn.osize = msg->o.size; } else { - USB_LOG("usb: urb handler/recipient type mismatch\n"); + log_error("urb handler/recipient type mismatch\n"); return -EINVAL; } t->pipeid = urb->pipe; @@ -668,13 +683,13 @@ int usb_drvInit(void) ret = mutexCreate(&usbdrv_common.lock); if (ret != 0) { - USB_LOG("usbdrv: Can't create mutex!\n"); + log_error("Can't create mutex!\n"); return -ENOMEM; } ret = condCreate(&usbdrv_common.drvAddedCond); if (ret != 0) { - USB_LOG("usbdrv: Can't create cond!\n"); + log_error("Can't create cond!\n"); resourceDestroy(usbdrv_common.lock); return -ENOMEM; } @@ -702,7 +717,7 @@ static int usblibdrv_handleUrb(usb_driver_t *drv, usb_urb_t *urb, void *data) t->intrn.drv = drv; } else { - USB_LOG("usb: urb handler/recipient type mismatch\n"); + log_error("urb handler/recipient type mismatch\n"); usb_transferFree(t); return -EINVAL; } @@ -744,14 +759,14 @@ static int usblibdrv_handleUrb(usb_driver_t *drv, usb_urb_t *urb, void *data) static int usblibdrv_urbSubmitSync(usb_driver_t *drv, usb_urb_t *urb, void *data) { - USB_TRACE("") + log_trace(""); return usblibdrv_handleUrb(drv, urb, data); } static int usblibdrv_urbTransferAsync(usb_driver_t *drv, unsigned pipe, unsigned urbid, size_t size, usb_setup_packet_t *setup) { - USB_TRACE("") + log_trace(""); usb_urbcmd_t urbcmd = { 0 }; usb_drvpriv_t *drvpriv = (usb_drvpriv_t *)drv->hostPriv; int ret; @@ -775,14 +790,14 @@ static int usblibdrv_urbTransferAsync(usb_driver_t *drv, unsigned pipe, unsigned static void usblibdrv_urbSyncCompleted(usb_transfer_t *t) { - USB_TRACE("") + log_trace(""); condSignal(*t->intrn.finishedCond); } static void usblibdrv_urbAsyncCompleted(usb_transfer_t *t) { - USB_TRACE("") + log_trace(""); usb_completion_t c = { 0 }; usb_driver_t *drv = t->intrn.drv; void *data = NULL; @@ -806,7 +821,7 @@ static void usblibdrv_urbAsyncCompleted(usb_transfer_t *t) static int usblibdrv_urbAlloc(usb_driver_t *drv, unsigned pipe, void *data, usb_dir_t dir, size_t size, int type) { - USB_TRACE("") + log_trace(""); usb_urb_t urb = { 0 }; urb.pipe = pipe; urb.type = type; @@ -820,7 +835,7 @@ static int usblibdrv_urbAlloc(usb_driver_t *drv, unsigned pipe, void *data, usb_ static int usblibdrv_urbFree(usb_driver_t *drv, unsigned pipe, unsigned urb) { - USB_TRACE("") + log_trace(""); usb_urbcmd_t urbcmd = { 0 }; usb_drvpriv_t *drvpriv = (usb_drvpriv_t *)drv->hostPriv; int ret; @@ -874,6 +889,6 @@ void usb_libDrvDestroy(usb_driver_t *drv) int ret; ret = drv->ops.destroy(drv); if (ret < 0) { - USB_LOG("usb: driver destroy failed: %d\n", ret); + log_error("driver destroy failed: %d\n", ret); } } diff --git a/usb/drv.h b/usb/drv.h index 7e6442b..41afb73 100644 --- a/usb/drv.h +++ b/usb/drv.h @@ -24,6 +24,9 @@ #define PORT_INTERNAL (-1) +typedef void (*usb_drvOnBindCb_t)(usb_dev_t *dev, usb_event_insertion_t *event, int iface); + + typedef struct usb_drvpriv { struct usb_drvpriv *next, *prev; @@ -58,7 +61,7 @@ void usb_libDrvDestroy(usb_driver_t *drv); void usb_drvAdd(usb_drvpriv_t *drv); -int usb_drvBind(usb_dev_t *dev); +int usb_drvBind(usb_dev_t *dev, usb_drvOnBindCb_t onBindCb); int usb_drvUnbind(usb_drvpriv_t *drv, usb_dev_t *dev, int iface); diff --git a/usb/hcd.c b/usb/hcd.c index 9d425c2..a61cf55 100644 --- a/usb/hcd.c +++ b/usb/hcd.c @@ -21,6 +21,12 @@ #include "dev.h" #include "hub.h" #include "hcd.h" +#include "log.h" + + +#undef USB_LOG_TAG +#define USB_LOG_TAG "usb-hcd" + struct hcd_ops_node { struct hcd_ops_node *prev, *next; @@ -171,33 +177,33 @@ hcd_t *hcd_init(void) for (i = 0; i < nhcd; i++) { ops = hcd_lookup(info[i].type); if (ops == NULL) { - USB_LOG("usb-hcd: No ops found for hcd type %s\n", info[i].type); + log_error("No ops found for hcd type %s\n", info[i].type); continue; } hcd = hcd_create(ops, &info[i], num++); if (hcd == NULL) { - USB_LOG("usb-hcd: Not enough memory to allocate hcd type: %s\n", info[i].type); + log_error("Not enough memory to allocate hcd type: %s\n", info[i].type); return res; } ret = hcd_roothubInit(hcd); if (ret != 0) { - USB_LOG("usb-hcd: Fail to initialize roothub: %s\n", info[i].type); + log_error("Fail to initialize roothub: %s\n", info[i].type); hcd_free(hcd); continue; } ret = hcd->ops->init(hcd); if (ret != 0) { - USB_LOG("usb-hcd: Fail to initialize hcd type: %s\n", info[i].type); + log_error("Fail to initialize hcd type: %s\n", info[i].type); hcd_free(hcd); continue; } ret = usb_devEnumerate(hcd->roothub); if (ret != 0) { - USB_LOG("usb-hcd: Fail to enumerate devices: %s\n", info[i].type); + log_error("Fail to enumerate devices: %s\n", info[i].type); hcd_free(hcd); continue; } diff --git a/usb/hub.c b/usb/hub.c index 97f7841..f8a265d 100644 --- a/usb/hub.c +++ b/usb/hub.c @@ -31,6 +31,7 @@ #include "drv.h" #include "hcd.h" #include "dev.h" +#include "log.h" #define HUB_ENUM_RETRIES 3 #define HUB_DEBOUNCE_STABLE 100000 @@ -39,6 +40,10 @@ #define HUB_TT_POLL_DELAY_MS 1000000 +#undef USB_LOG_TAG +#define USB_LOG_TAG "usbhub" + + typedef struct _hub_event { struct _hub_event *next, *prev; usb_dev_t *hub; @@ -143,20 +148,20 @@ static int hub_interruptInit(usb_dev_t *hub) usb_transfer_t *t; if ((t = calloc(1, sizeof(usb_transfer_t))) == NULL) { - USB_LOG("hub: Out of memory!\n"); + log_error("Out of memory!\n"); return -ENOMEM; } if ((t->buffer = usb_alloc(sizeof(uint32_t))) == NULL) { free(t); - USB_LOG("hub: Out of memory!\n"); + log_error("Out of memory!\n"); return -ENOMEM; } if ((hub->irqPipe = usb_pipeOpen(hub, 0, usb_dir_in, usb_transfer_interrupt)) == NULL) { usb_free(t->buffer, sizeof(uint32_t)); free(t); - USB_LOG("hub: Fail to open interrupt pipe!\n"); + log_error("Fail to open interrupt pipe!\n"); return -ENOMEM; } @@ -290,7 +295,7 @@ static void hub_devConnected(usb_dev_t *hub, int port) int retries = HUB_ENUM_RETRIES; if ((dev = usb_devAlloc()) == NULL) { - USB_LOG("hub: Not enough memory to allocate a new device!\n"); + log_error("Not enough memory to allocate a new device!\n"); return; } @@ -300,7 +305,7 @@ static void hub_devConnected(usb_dev_t *hub, int port) do { if ((ret = hub_portReset(hub, port, &status)) < 0) { - USB_LOG("hub: fail to reset port %d\n", port); + log_error("fail to reset port %d\n", port); break; } @@ -462,12 +467,12 @@ int hub_conf(usb_dev_t *hub) int i; if (hub_setConf(hub, 1) < 0) { - USB_LOG("hub: Fail to set configuration!\n"); + log_error("Fail to set configuration!\n"); return -EINVAL; } if (hub_getDesc(hub, buf, sizeof(buf)) < 0) { - USB_LOG("hub: Fail to get descriptor\n"); + log_error("Fail to get descriptor\n"); return -EINVAL; } @@ -475,13 +480,13 @@ int hub_conf(usb_dev_t *hub) desc = (usb_hub_desc_t *)buf; hub->nports = min(USB_HUB_MAX_PORTS, desc->bNbrPorts); if ((hub->devs = calloc(hub->nports, sizeof(usb_dev_t *))) == NULL) { - USB_LOG("hub: Out of memory!\n"); + log_error("Out of memory!\n"); return -ENOMEM; } for (i = 0; i < hub->nports; i++) { if (hub_setPortPower(hub, i + 1) < 0) { - USB_LOG("hub: Fail to set port %d power!\n", i + 1); + log_error("Fail to set port %d power!\n", i + 1); free(hub->devs); return -EINVAL; } diff --git a/usb/log.h b/usb/log.h new file mode 100644 index 0000000..b9946e0 --- /dev/null +++ b/usb/log.h @@ -0,0 +1,28 @@ +/* + * Phoenix-RTOS + * + * usb/log.h + * + * Copyright 2025 Phoenix Systems + * Author: Adam Greloch + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + + +#ifndef _USB_LOG_H_ +#define _USB_LOG_H_ + +#define USB_LOG_TAG "usb" +#define USB_TRACE 0 + +/* clang-format off */ +#define log_info(fmt, ...) do { fprintf(stdout, USB_LOG_TAG ": " fmt, ##__VA_ARGS__); } while (0) +#define log_msg(fmt, ...) do { fprintf(stderr, USB_LOG_TAG ": " fmt, ##__VA_ARGS__); } while (0) +#define log_trace(fmt, ...) do { if (USB_TRACE != 0) log_msg("%s: " fmt, __func__ __VA_OPT__(, ) ##__VA_ARGS__); } while (0) +#define log_error(fmt, ...) log_msg(fmt, ##__VA_ARGS__) +/* clang-format on */ + +#endif diff --git a/usb/usb.c b/usb/usb.c index 9fadf91..5143c48 100644 --- a/usb/usb.c +++ b/usb/usb.c @@ -33,6 +33,7 @@ #include "drv.h" #include "hcd.h" #include "hub.h" +#include "log.h" #define N_STATUSTHRS 1 #define STATUSTHR_PRIO 3 @@ -40,10 +41,8 @@ static struct { -#ifndef USB_INTERNAL_ONLY char ustack[2048] __attribute__((aligned(8))); uint32_t port; -#endif char stack[N_STATUSTHRS - 1][2048] __attribute__((aligned(8))); handle_t transferLock; handle_t finishedCond; @@ -66,7 +65,7 @@ static int usb_internalDriverInit(usb_driver_t *driver) priv = malloc(sizeof(usb_drvpriv_t)); if (priv == NULL) { - USB_LOG("usb: malloc failed!\n"); + log_error("malloc failed!\n"); usb_libDrvDestroy(driver); return -ENOMEM; } @@ -75,7 +74,7 @@ static int usb_internalDriverInit(usb_driver_t *driver) ret = mutexCreate(&priv->intrn.transferLock); if (ret != 0) { - USB_LOG("usb: Can't create mutex!\n"); + log_error("Can't create mutex!\n"); free(priv); usb_libDrvDestroy(driver); return -ENOMEM; @@ -83,7 +82,7 @@ static int usb_internalDriverInit(usb_driver_t *driver) ret = condCreate(&priv->intrn.finishedCond); if (ret != 0) { - USB_LOG("usb: Can't create cond!\n"); + log_error("Can't create cond!\n"); resourceDestroy(priv->intrn.transferLock); free(priv); usb_libDrvDestroy(driver); @@ -117,7 +116,7 @@ int usb_transferSubmit(usb_transfer_t *t, usb_pipe_t *pipe, handle_t *cond) int ret = 0; if (t->recipient == usb_drvType_none) { - USB_LOG("usb: transfer recipient unspecified!\n"); + log_error("transfer recipient unspecified!\n"); return -EINVAL; } @@ -186,13 +185,13 @@ void usb_transferFinished(usb_transfer_t *t, int status) } -#ifndef USB_INTERNAL_ONLY static int usb_devsList(char *buffer, size_t size) { return 0; } +#ifndef USB_INTERNAL_ONLY static int usb_handleConnect(msg_t *msg, usb_connect_t *c) { usb_drvpriv_t *drv; @@ -212,6 +211,7 @@ static int usb_handleConnect(msg_t *msg, usb_connect_t *c) drv->extrn.id = msg->pid; drv->extrn.port = c->port; drv->driver.nfilters = c->nfilters; + memcpy(drv->driver.name, c->name, sizeof(char) * USB_DRVNAME_MAX); memcpy((void *)drv->driver.filters, msg->i.data, msg->i.size); usb_drvAdd(drv); @@ -228,12 +228,12 @@ static int usb_handleOpen(usb_open_t *o, msg_t *msg) hcd_t *hcd; if ((drv = usb_drvFind(msg->pid)) == NULL) { - USB_LOG("usb: Fail to find driver pid: %d\n", msg->pid); + log_error("Fail to find driver pid: %d\n", msg->pid); return -EINVAL; } if ((hcd = hcd_find(usb_common.hcds, o->locationID)) == NULL) { - USB_LOG("usb: Fail to find dev: %d\n", o->dev); + log_error("Fail to find dev: %d\n", o->dev); return -EINVAL; } @@ -285,6 +285,7 @@ static void usb_urbSyncCompleted(usb_transfer_t *t) msgRespond(usb_common.port, &msg, t->extrn.rid); usb_transferFree(t); } +#endif /* USB_INTERNAL_ONLY */ static void usb_msgthr(void *arg) @@ -293,13 +294,15 @@ static void usb_msgthr(void *arg) msg_rid_t rid; msg_t msg; usb_msg_t *umsg; - int resp; + bool respond; int ret; for (;;) { - if (msgRecv(port, &msg, &rid) < 0) + ret = msgRecv(port, &msg, &rid); + if (ret < 0) { continue; - resp = 1; + } + respond = true; switch (msg.type) { case mtRead: msg.o.err = usb_devsList(msg.o.data, msg.o.size); @@ -307,6 +310,7 @@ static void usb_msgthr(void *arg) case mtDevCtl: umsg = (usb_msg_t *)msg.i.raw; switch (umsg->type) { +#ifndef USB_INTERNAL_ONLY case usb_msg_connect: msg.o.err = usb_handleConnect(&msg, &umsg->connect); break; @@ -317,7 +321,7 @@ static void usb_msgthr(void *arg) ret = usb_handleUrb(&msg, port, rid); if (umsg->urb.sync && ret == 0) { /* Block the sender until the transfer finishes */ - resp = 0; + respond = false; } else { msg.o.err = ret; @@ -326,23 +330,29 @@ static void usb_msgthr(void *arg) case usb_msg_urbcmd: msg.o.err = usb_handleUrbcmd(&msg); break; +#endif + case usb_msg_devdesc: + msg.o.err = usb_devFindDescFromOid(umsg->devdesc.oid, msg.o.data); + break; default: msg.o.err = -EINVAL; - USB_LOG("usb: unsupported usb_msg type: %d\n", umsg->type); + log_error("unsupported usb_msg type: %d\n", umsg->type); break; } break; default: msg.o.err = -EINVAL; - USB_LOG("usb: unsupported msg type\n"); + log_error("unsupported msg type\n"); } - if (resp) + if (respond) { msgRespond(port, &msg, rid); + } } } +#ifndef USB_INTERNAL_ONLY static usb_transferOps_t usbprocdrv_transferOps = { .urbSyncCompleted = usb_urbSyncCompleted, .urbAsyncCompleted = usb_urbAsyncCompleted, @@ -380,36 +390,34 @@ static void usb_statusthr(void *arg) int main(int argc, char *argv[]) { -#ifndef USB_INTERNAL_ONLY oid_t oid; -#endif int i; usb_driver_t *drv; if (mutexCreate(&usb_common.transferLock) != 0) { - USB_LOG("usb: Can't create mutex!\n"); + log_error("Can't create mutex!\n"); return 1; } if (condCreate(&usb_common.finishedCond) != 0) { - USB_LOG("usb: Can't create cond!\n"); + log_error("Can't create cond!\n"); return 1; } if (usb_memInit() != 0) { - USB_LOG("usb: Can't initiate memory management!\n"); + log_error("Can't initiate memory management!\n"); return 1; } if (usb_devInit() != 0) { - USB_LOG("usb: Fail to init devices!\n"); + log_error("Fail to init devices!\n"); return 1; } for (;;) { drv = usb_registeredDriverPop(); if (drv != NULL) { - USB_LOG("usb: Initializing driver as host-side: %s\n", drv->name); + log_msg("Initializing driver as host-side: %s\n", drv->name); usb_internalDriverInit(drv); } else { @@ -418,18 +426,17 @@ int main(int argc, char *argv[]) } if (hub_init() != 0) { - USB_LOG("usb: Fail to init hub driver!\n"); + log_error("Fail to init hub driver!\n"); return 1; } if ((usb_common.hcds = hcd_init()) == NULL) { - USB_LOG("usb: Fail to init hcds!\n"); + log_error("Fail to init hcds!\n"); return 1; } -#ifndef USB_INTERNAL_ONLY if (portCreate(&usb_common.port) != 0) { - USB_LOG("usb: Can't create port!\n"); + log_error("Can't create port!\n"); return 1; } @@ -437,19 +444,18 @@ int main(int argc, char *argv[]) oid.id = 0; if (create_dev(&oid, "/dev/usb") != 0) { - USB_LOG("usb: Can't create dev!\n"); + log_error("Can't create dev!\n"); return 1; } if (beginthread(usb_msgthr, MSGTHR_PRIO, &usb_common.ustack, sizeof(usb_common.ustack), (void *)usb_common.port) != 0) { - USB_LOG("usb: Fail to run msgthr!\n"); + log_error("Fail to run msgthr!\n"); return 1; } -#endif for (i = 0; i < N_STATUSTHRS - 1; i++) { if (beginthread(usb_statusthr, STATUSTHR_PRIO, &usb_common.stack[i], sizeof(usb_common.stack[i]), NULL) != 0) { - USB_LOG("usb: Fail to init hub driver!\n"); + log_error("Fail to init hub driver!\n"); return 1; } } @@ -469,7 +475,7 @@ int usblibdrv_open(usb_driver_t *drv, usb_devinfo_t *dev, usb_transfer_type_t ty hcd = hcd_find(usb_common.hcds, dev->locationID); if (hcd == NULL) { - USB_LOG("usb: Failed to find dev: %d\n", dev->locationID); + log_error("Failed to find dev: %d\n", dev->locationID); return -EINVAL; } diff --git a/usb/usbhost.h b/usb/usbhost.h index d0a071e..27f3bfe 100644 --- a/usb/usbhost.h +++ b/usb/usbhost.h @@ -103,14 +103,6 @@ struct usb_transfer_t { }; -#define USB_LOG(fmt, ...) do { printf(fmt, ##__VA_ARGS__); } while (0); - -#define USB_TRACE(fmt, ...) \ - if (0) { \ - printf("usb, %s: " fmt "\n", __func__ __VA_OPT__(, ) __VA_ARGS__); \ - } - - int usb_memInit(void);