Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions libusb/Makefile
Original file line number Diff line number Diff line change
@@ -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)
49 changes: 49 additions & 0 deletions libusb/devinfo.c
Original file line number Diff line number Diff line change
@@ -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 <usbdriver.h>

#include <usbdevinfo.h>

#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;
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
25 changes: 25 additions & 0 deletions libusb/include/usbdevinfo.h
Original file line number Diff line number Diff line change
@@ -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 <usb.h>
#include <usbdriver.h>


int usb_devinfoGet(oid_t oid, usb_devinfo_desc_t *desc);


#endif
43 changes: 37 additions & 6 deletions libusb/usbdriver.h → libusb/include/usbdriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include <sys/msg.h>
#include <posix/idtree.h>

#define USB_DRVNAME_MAX 10
#define USB_STR_MAX 254 /* per USB 2.0 spec */

#define USBDRV_ANY ((unsigned)-1)


Expand Down Expand Up @@ -54,6 +57,7 @@ typedef struct {
typedef struct {
unsigned port;
unsigned nfilters;
char name[USB_DRVNAME_MAX];
} usb_connect_t;


Expand Down Expand Up @@ -117,14 +121,20 @@ typedef struct {
} usb_completion_t;


typedef struct {
oid_t oid;
} usb_devdesc_t;


typedef struct {
enum { usb_msg_connect,
usb_msg_insertion,
usb_msg_deletion,
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;
Expand All @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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);


Expand Down
File renamed without changes.
30 changes: 30 additions & 0 deletions libusb/internal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Phoenix-RTOS
*
* libusb/internal.c
*
* Copyright 2025 Phoenix Systems
* Author: Adam Greloch
*
* %LICENSE%
*/


#include <usbinternal.h>
#include <unistd.h>


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);
}
}
30 changes: 30 additions & 0 deletions libusb/log.h
Original file line number Diff line number Diff line change
@@ -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
Loading
Loading