Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0d99451
usb: move phy to union with pci_dev in hcd_info_t
adamgreloch Nov 6, 2024
e8d3500
usb: fix urbSync transfers
adamgreloch Oct 18, 2024
1992a84
libusb: lookup `devfs` in addition to `/dev` when connecting
adamgreloch Nov 6, 2024
6241f95
drv: fix drvBind to fail if no driver is matched
adamgreloch Jan 3, 2025
0791bfa
drv: wait for any drivers to be added before trying to match iface
adamgreloch Jan 3, 2025
0602c75
usb: add port change detect workaround for L2 TTs
adamgreloch Jan 10, 2025
77aab09
dev: deduce product name from class if string descriptors are unavail…
adamgreloch Jan 3, 2025
76cc2f7
hcd: use uint32_t for base/phybase instead of int
adamgreloch Mar 27, 2025
743b0bc
libusb/driver: add generic insertion/deletion/completion handling
adamgreloch Nov 6, 2024
f16b500
libusb/driver: add usb_driver_t struct and run drivers from it
adamgreloch Nov 7, 2024
2a4fe5c
libusb/driver: generalize pipeOps
adamgreloch Nov 8, 2024
824615b
usb: add ability to run device drivers from usbhost process
adamgreloch Nov 14, 2024
50c9489
usb: add option to restrict to internal drivers only
adamgreloch Dec 2, 2024
7807d8b
usb/hcd: avoid potential race by initializing roothub before hcd init
adamgreloch Dec 17, 2024
61db7c5
libusb: fix insertion result not being passed to msg sender
adamgreloch Apr 23, 2025
5294de4
usb: pass device insertion result from driver to usbhost
adamgreloch Mar 18, 2025
7e41edf
libusb: move external headers to `include` dir
adamgreloch Mar 27, 2025
29f3c91
unify libusb/usb log prints
adamgreloch Apr 10, 2025
7085871
usb/usb: replace USB_INTERNAL_ONLY ifdefs to always create /dev/usb
adamgreloch Apr 25, 2025
90bc653
libusb: fix driver name passing if using procdriver
adamgreloch Mar 28, 2025
beda0f0
usb: preserve utf16 value of string descriptors
adamgreloch Apr 3, 2025
c6eb186
dev: print vid:pid on device insertion
adamgreloch Apr 10, 2025
e858d51
usb/drv: fix drivers not being bound to all possible dev interfaces
adamgreloch Apr 23, 2025
6643ced
usb: add device info retrieval API based on driver's device file oid
adamgreloch Apr 17, 2025
91853a6
usb/drv: reset msg before each msgSend
adamgreloch Apr 25, 2025
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
6 changes: 3 additions & 3 deletions libusb/Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +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
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;
}
216 changes: 54 additions & 162 deletions libusb/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,121 +3,70 @@
*
* libusb/driver.c
*
* Copyright 2021 Phoenix Systems
* Author: Maciej Purski
* Copyright 2021, 2024 Phoenix Systems
* Author: Maciej Purski, Adam Greloch
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#include <errno.h>
#include <usbdriver.h>
#include <sys/msg.h>
#include <sys/threads.h>
#include <sys/list.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#include <usbdriver.h>


static struct {
unsigned port;
usb_driver_t *registeredDrivers;
} usbdrv_common;


int usb_connect(const usb_device_id_t *filters, int nfilters, unsigned drvport)
void usb_driverRegister(usb_driver_t *driver)
{
msg_t msg = { 0 };
usb_msg_t *umsg = (usb_msg_t *)&msg.i.raw;
oid_t oid;

while (lookup("/dev/usb", NULL, &oid) < 0)
usleep(1000000);

msg.type = mtDevCtl;
msg.i.size = sizeof(*filters) * nfilters;
msg.i.data = (void *)filters;

umsg->type = usb_msg_connect;
umsg->connect.port = drvport;
umsg->connect.nfilters = nfilters;

if (msgSend(oid.port, &msg) < 0)
return -1;

usbdrv_common.port = oid.port;

return oid.port;
LIST_ADD(&usbdrv_common.registeredDrivers, driver);
}


int usb_eventsWait(int port, msg_t *msg)
usb_driver_t *usb_registeredDriverPop(void)
{
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;
usb_driver_t *drv = usbdrv_common.registeredDrivers;
if (drv != NULL) {
LIST_REMOVE(&usbdrv_common.registeredDrivers, drv);
}
return drv;
}


int usb_open(usb_devinfo_t *dev, usb_transfer_type_t type, usb_dir_t dir)
int usb_open(usb_driver_t *drv, usb_devinfo_t *dev, usb_transfer_type_t type, usb_dir_t dir)
{
msg_t msg = { 0 };
usb_msg_t *umsg = (usb_msg_t *)msg.i.raw;
int ret;

msg.type = mtDevCtl;
umsg->type = usb_msg_open;

umsg->open.bus = dev->bus;
umsg->open.dev = dev->dev;
umsg->open.iface = dev->interface;
umsg->open.type = type;
umsg->open.dir = dir;
umsg->open.locationID = dev->locationID;

if ((ret = msgSend(usbdrv_common.port, &msg)) != 0)
return ret;

return msg.o.err;
return drv->pipeOps->open(drv, dev, type, dir);
}


static int usb_urbSubmitSync(usb_urb_t *urb, void *data)
int usb_urbAlloc(usb_driver_t *drv, unsigned pipe, void *data, usb_dir_t dir, size_t size, int type)
{
msg_t msg = { 0 };
usb_msg_t *umsg = (usb_msg_t *)msg.i.raw;
int ret;

msg.type = mtDevCtl;
umsg->type = usb_msg_urb;
return drv->pipeOps->urbAlloc(drv, pipe, data, dir, size, type);
}

memcpy(&umsg->urb, urb, sizeof(usb_urb_t));

if (urb->dir == usb_dir_out) {
msg.i.data = data;
msg.i.size = urb->size;
}
else {
msg.o.data = data;
msg.o.size = urb->size;
}
int usb_urbFree(usb_driver_t *drv, unsigned pipe, unsigned urb)
{
return drv->pipeOps->urbFree(drv, pipe, urb);
}

if ((ret = msgSend(usbdrv_common.port, &msg)) != 0)
return ret;

return msg.o.err;
int usb_transferAsync(usb_driver_t *drv, unsigned pipe, unsigned urbid, size_t size, usb_setup_packet_t *setup)
{
return drv->pipeOps->transferAsync(drv, pipe, urbid, size, setup);
}


int usb_transferControl(unsigned pipe, usb_setup_packet_t *setup, void *data, size_t size, usb_dir_t dir)
int usb_transferControl(usb_driver_t *drv, unsigned pipe, usb_setup_packet_t *setup, void *data, size_t size, usb_dir_t dir)
{
usb_urb_t urb = {
.pipe = pipe,
Expand All @@ -128,11 +77,11 @@ int usb_transferControl(unsigned pipe, usb_setup_packet_t *setup, void *data, si
.sync = 1
};

return usb_urbSubmitSync(&urb, data);
return drv->pipeOps->submitSync(drv, &urb, data);
}


int usb_transferBulk(unsigned pipe, void *data, size_t size, usb_dir_t dir)
int usb_transferBulk(usb_driver_t *drv, unsigned pipe, void *data, size_t size, usb_dir_t dir)
{
usb_urb_t urb = {
.pipe = pipe,
Expand All @@ -142,11 +91,11 @@ int usb_transferBulk(unsigned pipe, void *data, size_t size, usb_dir_t dir)
.sync = 1
};

return usb_urbSubmitSync(&urb, data);
return drv->pipeOps->submitSync(drv, &urb, data);
}


int usb_setConfiguration(unsigned pipe, int conf)
int usb_setConfiguration(usb_driver_t *drv, unsigned pipe, int conf)
{
usb_setup_packet_t setup = (usb_setup_packet_t) {
.bmRequestType = REQUEST_DIR_HOST2DEV | REQUEST_TYPE_STANDARD | REQUEST_RECIPIENT_DEVICE,
Expand All @@ -156,11 +105,11 @@ int usb_setConfiguration(unsigned pipe, int conf)
.wLength = 0,
};

return usb_transferControl(pipe, &setup, NULL, 0, usb_dir_out);
return usb_transferControl(drv, pipe, &setup, NULL, 0, usb_dir_out);
}


int usb_clearFeatureHalt(unsigned pipe, int ep)
int usb_clearFeatureHalt(usb_driver_t *drv, unsigned pipe, int ep)
{
usb_setup_packet_t setup = (usb_setup_packet_t) {
.bmRequestType = REQUEST_DIR_HOST2DEV | REQUEST_TYPE_STANDARD | REQUEST_RECIPIENT_DEVICE,
Expand All @@ -170,75 +119,7 @@ int usb_clearFeatureHalt(unsigned pipe, int ep)
.wLength = 0,
};

return usb_transferControl(pipe, &setup, NULL, 0, usb_dir_out);
}


int usb_urbAlloc(unsigned pipe, void *data, usb_dir_t dir, size_t size, int type)
{
msg_t msg = { 0 };
usb_msg_t *umsg = (usb_msg_t *)msg.i.raw;
int ret;
usb_urb_t *urb = &umsg->urb;

urb->pipe = pipe;
urb->type = type;
urb->dir = dir;
urb->size = size;
urb->sync = 0;

msg.type = mtDevCtl;
umsg->type = usb_msg_urb;

if ((ret = msgSend(usbdrv_common.port, &msg)) < 0)
return ret;

/* URB id */
return msg.o.err;
}


int usb_transferAsync(unsigned pipe, unsigned urbid, size_t size, usb_setup_packet_t *setup)
{
msg_t msg = { 0 };
usb_msg_t *umsg = (usb_msg_t *)msg.i.raw;
int ret;
usb_urbcmd_t *urbcmd = &umsg->urbcmd;

urbcmd->pipeid = pipe;
urbcmd->size = size;
urbcmd->urbid = urbid;
urbcmd->cmd = urbcmd_submit;

if (setup != NULL) {
memcpy(&urbcmd->setup, setup, sizeof(*setup));
}
msg.type = mtDevCtl;
umsg->type = usb_msg_urbcmd;
if ((ret = msgSend(usbdrv_common.port, &msg)) < 0)
return ret;

return 0;
}


int usb_urbFree(unsigned pipe, unsigned urb)
{
msg_t msg = { 0 };
usb_msg_t *umsg = (usb_msg_t *)msg.i.raw;
int ret;
usb_urbcmd_t *urbcmd = &umsg->urbcmd;

urbcmd->pipeid = pipe;
urbcmd->urbid = urb;
urbcmd->cmd = urbcmd_free;

msg.type = mtDevCtl;
umsg->type = usb_msg_urbcmd;
if ((ret = msgSend(usbdrv_common.port, &msg)) < 0)
return ret;

return 0;
return usb_transferControl(drv, pipe, &setup, NULL, 0, usb_dir_out);
}


Expand Down Expand Up @@ -324,26 +205,37 @@ void usb_dumpStringDesc(FILE *stream, usb_string_desc_t *descr)
}


int usb_modeswitchHandle(usb_devinfo_t *dev, const usb_modeswitch_t *mode)
int usb_modeswitchHandle(usb_driver_t *drv, usb_devinfo_t *dev, const usb_modeswitch_t *mode)
{
char msg[sizeof(mode->msg)];
int pipeCtrl, pipeIn, pipeOut;
int pipeCtrl, pipeIn, pipeOut, ret;

if ((pipeCtrl = usb_open(dev, usb_transfer_control, 0)) < 0)
pipeCtrl = usb_open(drv, dev, usb_transfer_control, 0);
if (pipeCtrl < 0) {
return -EINVAL;
}

if (usb_setConfiguration(pipeCtrl, 1) != 0)
ret = usb_setConfiguration(drv, pipeCtrl, 1);
if (ret != 0) {
return -EINVAL;
}

if ((pipeIn = usb_open(dev, usb_transfer_bulk, usb_dir_in)) < 0)
pipeIn = usb_open(drv, dev, usb_transfer_bulk, usb_dir_in);
if (pipeIn < 0) {
return -EINVAL;
}

if ((pipeOut = usb_open(dev, usb_transfer_bulk, usb_dir_out)) < 0)
pipeOut = usb_open(drv, dev, usb_transfer_bulk, usb_dir_out);
if (pipeOut < 0) {
return -EINVAL;
}

memcpy(msg, mode->msg, sizeof(msg));
if (usb_transferBulk(pipeOut, msg, sizeof(msg), usb_dir_out) < 0)

ret = usb_transferBulk(drv, pipeOut, msg, sizeof(msg), usb_dir_out);
if (ret < 0) {
return -EINVAL;
}

return 0;
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions libusb/usb.h → libusb/include/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#define CLASS_REQ_SET_CONTROL_LINE_STATE 0x22

/* class codes */
#define USB_CLASS_HID 0x3
#define USB_CLASS_MASS_STORAGE 0x8
#define USB_CLASS_HUB 0x9

Expand Down
File renamed without changes.
Loading
Loading