Upgrade libddekit and introduce devmand.
Devmand (Device manager daemon) is the daemon that will dynamically manage services based on events received from the system.
This commit is contained in:
parent
6b8821515d
commit
ade7dc8ded
16 changed files with 1219 additions and 61 deletions
|
@ -8,7 +8,7 @@ SUBDIR= add_route arp ash at awk \
|
||||||
cawf cd cdprobe checkhier cpp \
|
cawf cd cdprobe checkhier cpp \
|
||||||
chmod chown ci cksum cleantmp clear cmp co \
|
chmod chown ci cksum cleantmp clear cmp co \
|
||||||
comm compress cp crc cron crontab cut \
|
comm compress cp crc cron crontab cut \
|
||||||
dd decomp16 DESCRIBE dev2name devsize df dhcpd \
|
dd decomp16 DESCRIBE dev2name devmand devsize df dhcpd \
|
||||||
dhrystone diff dirname diskctl dumpcore \
|
dhrystone diff dirname diskctl dumpcore \
|
||||||
eject elvis env expand factor fbdctl \
|
eject elvis env expand factor fbdctl \
|
||||||
find finger fingerd fix fold format fortune fsck.mfs \
|
find finger fingerd fix fold format fortune fsck.mfs \
|
||||||
|
|
15
commands/devmand/Makefile
Normal file
15
commands/devmand/Makefile
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
PROG = devmand
|
||||||
|
|
||||||
|
SRCS = main.c lex.yy.c y.tab.c
|
||||||
|
|
||||||
|
lex.yy.c: usb_scan.l y.tab.h
|
||||||
|
${LEX} usb_scan.l
|
||||||
|
|
||||||
|
y.tab.c y.tab.h: usb.y
|
||||||
|
${YACC} -d usb.y
|
||||||
|
|
||||||
|
CLEANFILES = y.tab.c y.tab.h *.d lex.yy.c lex.yy.o main.o y.tab.o
|
||||||
|
MAN =
|
||||||
|
.include <bsd.prog.mk>
|
||||||
|
|
||||||
|
|
45
commands/devmand/devmand.cfg
Normal file
45
commands/devmand/devmand.cfg
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
usb_driver usb_storage
|
||||||
|
{
|
||||||
|
binary = /usr/sbin/usb_storage;
|
||||||
|
id {
|
||||||
|
bInterfaceClass = 0x08;
|
||||||
|
}
|
||||||
|
devprefix = usbstor;
|
||||||
|
upscript = /etc/devmand/scripts/block;
|
||||||
|
downscript = /etc/devmand/scripts/block;
|
||||||
|
}
|
||||||
|
|
||||||
|
usb_driver usb_keyboard
|
||||||
|
{
|
||||||
|
binary = /usr/sbin/usb_hid;
|
||||||
|
id {
|
||||||
|
bInterfaceClass = 0x3;
|
||||||
|
bInterfaceProtocol = 0x1;
|
||||||
|
}
|
||||||
|
upscript = /etc/devmand/scripts/singlechar;
|
||||||
|
downscript = /etc/devmand/scripts/singlechar;
|
||||||
|
devprefix = usb_keyboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
usb_driver usb_mouse
|
||||||
|
{
|
||||||
|
binary = /usr/sbin/usb_hid;
|
||||||
|
id {
|
||||||
|
bInterfaceClass = 0x3;
|
||||||
|
bInterfaceProtocol = 0x2;
|
||||||
|
}
|
||||||
|
upscript = /etc/devmand/scripts/singlechar;
|
||||||
|
downscript = /etc/devmand/scripts/singlechar;
|
||||||
|
devprefix = usb_mouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
usb_driver usb_hid
|
||||||
|
{
|
||||||
|
binary = /usr/sbin/usb_hid;
|
||||||
|
id {
|
||||||
|
bInterfaceClass = 0x3;
|
||||||
|
}
|
||||||
|
upscript = /etc/devmand/scripts/singlechar;
|
||||||
|
downscript = /etc/devmand/scripts/singlechar;
|
||||||
|
devprefix = usb_keyboard;
|
||||||
|
}
|
847
commands/devmand/main.c
Normal file
847
commands/devmand/main.c
Normal file
|
@ -0,0 +1,847 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include "usb_driver.h"
|
||||||
|
#include "proto.h"
|
||||||
|
|
||||||
|
#define CONTROL_FIFO_PATH "/var/tmp/devmand_control"
|
||||||
|
#define SERVICE_BINARY "/bin/service"
|
||||||
|
|
||||||
|
|
||||||
|
#define DEVMAN_TYPE_NAME "dev_type"
|
||||||
|
#define PATH_LEN 256
|
||||||
|
#define INVAL_MAJOR -1
|
||||||
|
|
||||||
|
static void main_loop();
|
||||||
|
static void handle_event();
|
||||||
|
static void cleanup();
|
||||||
|
static void parse_config();
|
||||||
|
static void display_usage();
|
||||||
|
static enum dev_type determine_type(char *path);
|
||||||
|
static int get_major();
|
||||||
|
static void create_pid_file();
|
||||||
|
static void put_major(int major);
|
||||||
|
static struct devmand_usb_driver* match_usb_driver(struct usb_device_id *id);
|
||||||
|
static struct devmand_driver_instance *find_instance(int dev_id);
|
||||||
|
|
||||||
|
#define dbg(fmt, ... ) \
|
||||||
|
if (args.verbose) \
|
||||||
|
printf("%8s:%4d: %13s()| "fmt"\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__ )
|
||||||
|
|
||||||
|
static LIST_HEAD(usb_driver_head, devmand_usb_driver) drivers =
|
||||||
|
LIST_HEAD_INITIALIZER(drivers);
|
||||||
|
static LIST_HEAD(usb_driver_inst_head, devmand_driver_instance) instances =
|
||||||
|
LIST_HEAD_INITIALIZER(instances);
|
||||||
|
|
||||||
|
|
||||||
|
static int _run = 1;
|
||||||
|
struct global_args {
|
||||||
|
int deamonize;
|
||||||
|
char *path;
|
||||||
|
char *config;
|
||||||
|
int major_offset;
|
||||||
|
int verbose;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum dev_type {
|
||||||
|
DEV_TYPE_USB_DEVICE,
|
||||||
|
DEV_TYPE_USB_INTF,
|
||||||
|
DEV_TYPE_UNKOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
extern FILE *yyin;
|
||||||
|
|
||||||
|
static struct global_args args = {0,NULL,NULL,25, 0};
|
||||||
|
|
||||||
|
static struct option options[] =
|
||||||
|
{
|
||||||
|
{"deamonize", no_argument, NULL, 'd'},
|
||||||
|
{"path", required_argument, NULL, 'p'},
|
||||||
|
{"config", required_argument, NULL, 'c'},
|
||||||
|
{"verbose", required_argument, NULL, 'v'},
|
||||||
|
{0,0,0,0} /* terminating entry */
|
||||||
|
};
|
||||||
|
|
||||||
|
static char major_bitmap[16]; /* can store up to 128 major number states */
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* run_upscript *
|
||||||
|
*===========================================================================*/
|
||||||
|
int run_upscript(struct devmand_driver_instance *inst)
|
||||||
|
{
|
||||||
|
char cmdl[1024];
|
||||||
|
cmdl[0] = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
snprintf(cmdl, 1024, "%s up %s %d %d",
|
||||||
|
inst->drv->upscript, inst->label, inst->major, inst->dev_id);
|
||||||
|
dbg("Running Upscript: \"%s\"", cmdl);
|
||||||
|
ret = system(cmdl);
|
||||||
|
if (ret != 0) {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* run_cleanscript *
|
||||||
|
*===========================================================================*/
|
||||||
|
int run_cleanscript(struct devmand_usb_driver *drv)
|
||||||
|
{
|
||||||
|
char cmdl[1024];
|
||||||
|
cmdl[0] = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
snprintf(cmdl, 1024, "%s clean %s ",
|
||||||
|
drv->upscript, drv->devprefix);
|
||||||
|
dbg("Running Upscript: \"%s\"", cmdl);
|
||||||
|
ret = system(cmdl);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* run_downscript *
|
||||||
|
*===========================================================================*/
|
||||||
|
int run_downscript(struct devmand_driver_instance *inst)
|
||||||
|
{
|
||||||
|
char cmdl[1024];
|
||||||
|
cmdl[0] = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
snprintf(cmdl, 1024, "%s down %s %d",
|
||||||
|
inst->drv->downscript, inst->label, inst->major);
|
||||||
|
|
||||||
|
dbg("Running Upscript: \"%s\"", cmdl);
|
||||||
|
|
||||||
|
ret = system(cmdl);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* stop_driver *
|
||||||
|
*===========================================================================*/
|
||||||
|
int stop_driver(struct devmand_driver_instance *inst)
|
||||||
|
{
|
||||||
|
char cmdl[1024];
|
||||||
|
cmdl[0] = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
snprintf(cmdl, 1024, "%s down %s %d",
|
||||||
|
SERVICE_BINARY, inst->label, inst->dev_id);
|
||||||
|
dbg("executing service: \"%s\"", cmdl);
|
||||||
|
ret = system(cmdl);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
printf("Stopped driver %s with label %s for device %d.\n",
|
||||||
|
inst->drv->binary, inst->label, inst->dev_id);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* start_driver *
|
||||||
|
*===========================================================================*/
|
||||||
|
int start_driver(struct devmand_driver_instance *inst)
|
||||||
|
{
|
||||||
|
char cmdl[1024];
|
||||||
|
cmdl[0] = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* generate label */
|
||||||
|
ret = snprintf(inst->label, 32, "%s%d", inst->drv->devprefix,
|
||||||
|
inst->dev_id);
|
||||||
|
if (ret < 0 || ret > DEVMAND_DRIVER_LABEL_LEN) {
|
||||||
|
dbg("label too long");
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(cmdl, 1024, "%s up %s -major %d -devid %d -label %s",
|
||||||
|
SERVICE_BINARY, inst->drv->binary, inst->major, inst->dev_id,
|
||||||
|
inst->label);
|
||||||
|
dbg("executing service: \"%s\"", cmdl);
|
||||||
|
|
||||||
|
ret = system(cmdl);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Started driver %s with label %s for device %d.\n",
|
||||||
|
inst->drv->binary, inst->label, inst->dev_id);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* find_instance *
|
||||||
|
*===========================================================================*/
|
||||||
|
static struct devmand_driver_instance *
|
||||||
|
find_instance(int dev_id)
|
||||||
|
{
|
||||||
|
struct devmand_driver_instance *inst;
|
||||||
|
|
||||||
|
LIST_FOREACH(inst, &instances, list) {
|
||||||
|
if (inst->dev_id == dev_id) {
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* match_usb_driver *
|
||||||
|
*===========================================================================*/
|
||||||
|
static int
|
||||||
|
match_usb_id(struct devmand_usb_match_id *mid, struct usb_device_id *id)
|
||||||
|
{
|
||||||
|
int res = 1;
|
||||||
|
unsigned long match = mid->match_flags;
|
||||||
|
struct usb_device_id *_id = &mid->match_id;
|
||||||
|
|
||||||
|
if (match & USB_MATCH_ID_VENDOR)
|
||||||
|
if (id->idVendor != _id->idVendor) res = 0;
|
||||||
|
if (match & USB_MATCH_ID_PRODUCT)
|
||||||
|
if (id->idProduct != _id->idProduct) res = 0;
|
||||||
|
if (match & USB_MATCH_BCD_DEVICE)
|
||||||
|
if (id->bcdDevice != _id->bcdDevice) res = 0;
|
||||||
|
if (match & USB_MATCH_DEVICE_PROTOCOL)
|
||||||
|
if (id->bDeviceProtocol != _id->bDeviceProtocol) res = 0;
|
||||||
|
if (match & USB_MATCH_DEVICE_SUBCLASS)
|
||||||
|
if (id->bDeviceSubClass != _id->bDeviceSubClass) res = 0;
|
||||||
|
if (match & USB_MATCH_DEVICE_PROTOCOL)
|
||||||
|
if (id->bDeviceProtocol != _id->bDeviceProtocol) res = 0;
|
||||||
|
if (match & USB_MATCH_INTERFACE_CLASS)
|
||||||
|
if (id->bInterfaceClass != _id->bInterfaceClass) res = 0;
|
||||||
|
if (match & USB_MATCH_INTERFACE_SUBCLASS)
|
||||||
|
if (id->bInterfaceSubClass != _id->bInterfaceSubClass) res = 0;
|
||||||
|
if (match & USB_MATCH_INTERFACE_PROTOCOL)
|
||||||
|
if (id->bInterfaceProtocol != _id->bInterfaceProtocol) res = 0;
|
||||||
|
|
||||||
|
if (match == 0UL) {
|
||||||
|
res = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* match_usb_driver *
|
||||||
|
*===========================================================================*/
|
||||||
|
static struct devmand_usb_driver*
|
||||||
|
match_usb_driver(struct usb_device_id *id)
|
||||||
|
{
|
||||||
|
struct devmand_usb_driver *driver;
|
||||||
|
struct devmand_usb_match_id *mid;
|
||||||
|
|
||||||
|
LIST_FOREACH(driver, &drivers, list) {
|
||||||
|
LIST_FOREACH(mid, &driver->ids, list) {
|
||||||
|
if (match_usb_id(mid, id)) {
|
||||||
|
return driver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* add_usb_match_id *
|
||||||
|
*===========================================================================*/
|
||||||
|
struct devmand_usb_driver * add_usb_driver(char *name)
|
||||||
|
{
|
||||||
|
struct devmand_usb_driver *udrv = (struct devmand_usb_driver*)
|
||||||
|
malloc(sizeof(struct devmand_usb_driver));
|
||||||
|
|
||||||
|
LIST_INSERT_HEAD(&drivers, udrv, list);
|
||||||
|
LIST_INIT(&udrv->ids);
|
||||||
|
|
||||||
|
udrv->name = name;
|
||||||
|
return udrv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* add_usb_match_id *
|
||||||
|
*===========================================================================*/
|
||||||
|
struct devmand_usb_match_id *
|
||||||
|
add_usb_match_id
|
||||||
|
(struct devmand_usb_driver *drv)
|
||||||
|
{
|
||||||
|
struct devmand_usb_match_id *id = (struct devmand_usb_match_id*)
|
||||||
|
malloc(sizeof(struct devmand_usb_match_id));
|
||||||
|
|
||||||
|
memset(id, 0, sizeof(struct devmand_usb_match_id));
|
||||||
|
|
||||||
|
LIST_INSERT_HEAD(&drv->ids, id, list);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* parse_config *
|
||||||
|
*===========================================================================*/
|
||||||
|
static void parse_config()
|
||||||
|
{
|
||||||
|
yyin = fopen(args.config, "r");
|
||||||
|
|
||||||
|
if (yyin < 0) {
|
||||||
|
printf("Can not open config file: %d.\n", errno);
|
||||||
|
}
|
||||||
|
dbg("Parsing configfile... ");
|
||||||
|
yyparse();
|
||||||
|
dbg("Done.");
|
||||||
|
|
||||||
|
fclose(yyin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* cleanup *
|
||||||
|
*===========================================================================*/
|
||||||
|
static void cleanup() {
|
||||||
|
int res;
|
||||||
|
struct devmand_driver_instance *inst;
|
||||||
|
/* destroy fifo */
|
||||||
|
dbg("cleaning up... ");
|
||||||
|
/* quit all running drivers */
|
||||||
|
LIST_FOREACH(inst, &instances, list) {
|
||||||
|
dbg("stopping driver %s", inst->label);
|
||||||
|
run_downscript (inst);
|
||||||
|
stop_driver(inst);
|
||||||
|
}
|
||||||
|
res = remove(CONTROL_FIFO_PATH);
|
||||||
|
if (res != 0) {
|
||||||
|
fprintf(stderr, "WARNING: could not remove control fifo");
|
||||||
|
}
|
||||||
|
unlink("/var/run/devmand.pid");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sig_int(int sig) {
|
||||||
|
dbg("devman: Received SIGINT... cleaning up.");
|
||||||
|
_run = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* create_pid_file *
|
||||||
|
*===========================================================================*/
|
||||||
|
void create_pid_file()
|
||||||
|
{
|
||||||
|
FILE *fd;
|
||||||
|
|
||||||
|
fd = fopen("/var/run/devmand.pid", "r");
|
||||||
|
if(fd) {
|
||||||
|
fprintf(stderr, "devmand: /var/run/devmand.pid exists... "
|
||||||
|
"another devmand running?\n");
|
||||||
|
fclose(fd);
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
fd = fopen("/var/run/devmand.pid","w");
|
||||||
|
fprintf(fd, "%d", getpid());
|
||||||
|
fclose(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* main *
|
||||||
|
*===========================================================================*/
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int opt, optindex, res;
|
||||||
|
struct devmand_usb_driver *driver;
|
||||||
|
|
||||||
|
create_pid_file();
|
||||||
|
|
||||||
|
/* get command line arguments */
|
||||||
|
while ((opt = getopt_long(argc, argv, "vdc:p:h?", options, &optindex))
|
||||||
|
!= -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'd':
|
||||||
|
args.deamonize = 1;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
args.path = optarg;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
args.config = optarg;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
args.verbose = 1;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
case '?':
|
||||||
|
default:
|
||||||
|
display_usage(argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* is path set? */
|
||||||
|
if (args.path == NULL) {
|
||||||
|
args.path = "/sys/";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* is path set? */
|
||||||
|
if (args.config == NULL) {
|
||||||
|
args.config = "/etc/devmand/devmand.cfg";
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg("Options: deamonize: %s, path: %s",
|
||||||
|
args.deamonize?"true":"false", args.path);
|
||||||
|
|
||||||
|
/* create control socket if not exists */
|
||||||
|
res = mkfifo(CONTROL_FIFO_PATH, S_IWRITE);
|
||||||
|
|
||||||
|
if ( !((res == 0) || (res == EEXIST)) ) {
|
||||||
|
fprintf(stderr, "Could not create control FIFO (%d)\n", res);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_config();
|
||||||
|
LIST_FOREACH(driver, &drivers, list) {
|
||||||
|
run_cleanscript(driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal(SIGINT, sig_int);
|
||||||
|
|
||||||
|
main_loop();
|
||||||
|
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* determine_type *
|
||||||
|
*===========================================================================*/
|
||||||
|
static enum dev_type determine_type (char *path)
|
||||||
|
{
|
||||||
|
FILE * fd;
|
||||||
|
char *mypath;
|
||||||
|
char buf[256];
|
||||||
|
int res;
|
||||||
|
|
||||||
|
mypath = (char *) calloc(1, strlen(path)+strlen(DEVMAN_TYPE_NAME)+1);
|
||||||
|
|
||||||
|
if (mypath == NULL) {
|
||||||
|
fprintf(stderr, "ERROR: out of mem\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(mypath, path);
|
||||||
|
strcat(mypath, DEVMAN_TYPE_NAME);
|
||||||
|
|
||||||
|
fd = fopen(mypath, "r");
|
||||||
|
free(mypath);
|
||||||
|
|
||||||
|
if (fd == NULL) {
|
||||||
|
fprintf(stderr, "WARN: could not open %s\n", mypath);
|
||||||
|
return DEV_TYPE_UNKOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = fscanf(fd , "%s\n", buf);
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
|
if (res != 1) {
|
||||||
|
fprintf(stderr, "WARN: could not parse %s\n", mypath);
|
||||||
|
return DEV_TYPE_UNKOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(buf, "USB_DEV") == 0) {
|
||||||
|
return DEV_TYPE_USB_DEVICE;
|
||||||
|
} else if (strcmp(buf, "USB_INTF") == 0) {
|
||||||
|
return DEV_TYPE_USB_INTF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DEV_TYPE_UNKOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* read_hex_uint *
|
||||||
|
*===========================================================================*/
|
||||||
|
static int read_hex_uint(char *base_path, char *name, unsigned int* val )
|
||||||
|
{
|
||||||
|
char my_path[PATH_LEN];
|
||||||
|
FILE *fd;
|
||||||
|
memset(my_path,0,PATH_LEN);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
strcat(my_path, base_path);
|
||||||
|
strcat(my_path, name);
|
||||||
|
|
||||||
|
fd = fopen(my_path, "r");
|
||||||
|
|
||||||
|
if (fd == NULL) {
|
||||||
|
fprintf(stderr, "WARN: could not open %s\n", my_path);
|
||||||
|
return EEXIST;
|
||||||
|
} else if (fscanf(fd, "0x%x\n", val ) != 1) {
|
||||||
|
fprintf(stderr, "WARN: could not parse %s\n", my_path);
|
||||||
|
ret = EINVAL;
|
||||||
|
}
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* get_major *
|
||||||
|
*===========================================================================*/
|
||||||
|
static int get_major() {
|
||||||
|
int i, ret = args.major_offset;
|
||||||
|
|
||||||
|
for (i=0; i < 16; i++) {
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < 8; j++ ) {
|
||||||
|
if ((major_bitmap[i] & (1 << j))) {
|
||||||
|
major_bitmap[i] &= !(1 << j);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return INVAL_MAJOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* put_major *
|
||||||
|
*===========================================================================*/
|
||||||
|
static void put_major(int major) {
|
||||||
|
int i;
|
||||||
|
major -= args.major_offset;
|
||||||
|
assert(major >= 0);
|
||||||
|
|
||||||
|
for (i=0; i < 16; i++) {
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < 8; j++ ) {
|
||||||
|
if (major==0) {
|
||||||
|
assert(!(major_bitmap[i] & (1 <<j)));
|
||||||
|
major_bitmap[i] |= (1 << j);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
major--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* generate_usb_device_id *
|
||||||
|
*===========================================================================*/
|
||||||
|
static struct usb_device_id *
|
||||||
|
generate_usb_device_id(char * path, int is_interface)
|
||||||
|
{
|
||||||
|
struct usb_device_id *ret;
|
||||||
|
int res;
|
||||||
|
unsigned int val;
|
||||||
|
|
||||||
|
ret = (struct usb_device_id *)
|
||||||
|
calloc(1,sizeof (struct usb_device_id));
|
||||||
|
|
||||||
|
if (is_interface) {
|
||||||
|
|
||||||
|
res = read_hex_uint(path, "../idVendor", &val);
|
||||||
|
if (res) goto err;
|
||||||
|
ret->idVendor = val;
|
||||||
|
|
||||||
|
res = read_hex_uint(path, "../idProduct", &val);
|
||||||
|
if (res) goto err;
|
||||||
|
ret->idProduct = val;
|
||||||
|
#if 0
|
||||||
|
res = read_hex_uint(path, "../bcdDevice", &val);
|
||||||
|
if (res) goto err;
|
||||||
|
ret->bcdDevice = val;
|
||||||
|
#endif
|
||||||
|
res = read_hex_uint(path, "../bDeviceClass", &val);
|
||||||
|
if (res) goto err;
|
||||||
|
ret->bDeviceClass = val;
|
||||||
|
|
||||||
|
res = read_hex_uint(path, "../bDeviceSubClass", &val);
|
||||||
|
if (res) goto err;
|
||||||
|
ret->bDeviceSubClass = val;
|
||||||
|
|
||||||
|
res = read_hex_uint(path, "../bDeviceProtocol", &val);
|
||||||
|
if (res) goto err;
|
||||||
|
ret->bDeviceProtocol = val;
|
||||||
|
|
||||||
|
res = read_hex_uint(path, "/bInterfaceClass", &val);
|
||||||
|
if (res) goto err;
|
||||||
|
ret->bInterfaceClass = val;
|
||||||
|
|
||||||
|
res = read_hex_uint(path, "/bInterfaceSubClass", &val);
|
||||||
|
if (res) goto err;
|
||||||
|
ret->bInterfaceSubClass = val;
|
||||||
|
|
||||||
|
res = read_hex_uint(path, "/bInterfaceProtocol", &val);
|
||||||
|
if (res) goto err;
|
||||||
|
ret->bInterfaceProtocol = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
err:
|
||||||
|
free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* usb_intf_add_even *
|
||||||
|
*===========================================================================*/
|
||||||
|
static void usb_intf_add_event(char *path, int dev_id)
|
||||||
|
{
|
||||||
|
struct usb_device_id *id;
|
||||||
|
struct devmand_usb_driver *drv;
|
||||||
|
struct devmand_driver_instance *drv_inst;
|
||||||
|
int major, ret;
|
||||||
|
|
||||||
|
/* generate usb_match_id */
|
||||||
|
id = generate_usb_device_id(path,TRUE);
|
||||||
|
if (id == NULL) {
|
||||||
|
fprintf(stderr, "WARN: could not create usb_device id...\n"
|
||||||
|
" ommiting event\n");
|
||||||
|
free(id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find suitable driver */
|
||||||
|
drv = match_usb_driver(id);
|
||||||
|
free (id);
|
||||||
|
|
||||||
|
if (drv == NULL) {
|
||||||
|
dbg("INFO: could not find a suitable driver for %s", path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create instance */
|
||||||
|
drv_inst = (struct devmand_driver_instance *)
|
||||||
|
calloc(1,sizeof(struct devmand_driver_instance));
|
||||||
|
|
||||||
|
if (drv_inst == NULL) {
|
||||||
|
fprintf(stderr, "ERROR: out of memory");
|
||||||
|
return; /* maybe better quit here. */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* allocate inode number, if device files needed */
|
||||||
|
major = get_major();
|
||||||
|
if (major == INVAL_MAJOR) {
|
||||||
|
fprintf(stderr, "WARN: ran out of major numbers\n"
|
||||||
|
" cannot start driver %s for %s\n",
|
||||||
|
drv->name, path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
drv_inst->major = major;
|
||||||
|
drv_inst->drv = drv;
|
||||||
|
drv_inst->dev_id = dev_id;
|
||||||
|
|
||||||
|
|
||||||
|
/* start driver (invoke service) */
|
||||||
|
start_driver(drv_inst);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* run the up action
|
||||||
|
*
|
||||||
|
* An up action can be any executable. Before running it devmand
|
||||||
|
* will set certain environment variables so the script can configure
|
||||||
|
* the device (or generate device files, etc). See up_action() for that.
|
||||||
|
*/
|
||||||
|
if (drv->upscript) {
|
||||||
|
ret = run_upscript(drv_inst);
|
||||||
|
if (ret) {
|
||||||
|
stop_driver(drv_inst);
|
||||||
|
fprintf(stderr, "devmand: warning, could not run up_action\n");
|
||||||
|
free(drv_inst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LIST_INSERT_HEAD(&instances,drv_inst,list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* usb_intf_remove_event *
|
||||||
|
*===========================================================================*/
|
||||||
|
static void usb_intf_remove_event(char *path, int dev_id)
|
||||||
|
{
|
||||||
|
struct devmand_driver_instance *inst;
|
||||||
|
struct devmand_usb_driver *drv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* find the driver instance */
|
||||||
|
inst = find_instance(dev_id);
|
||||||
|
|
||||||
|
if (inst == NULL) {
|
||||||
|
dbg("No driver running for id: %d", dev_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
drv = inst->drv;
|
||||||
|
|
||||||
|
/* run the down script */
|
||||||
|
if (drv->downscript) {
|
||||||
|
ret = run_downscript(inst);
|
||||||
|
if (ret) {
|
||||||
|
fprintf(stderr, "WARN: error running up_action");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stop the driver */
|
||||||
|
stop_driver(inst);
|
||||||
|
|
||||||
|
/* free major */
|
||||||
|
put_major(inst->major);
|
||||||
|
|
||||||
|
/* free instance */
|
||||||
|
LIST_REMOVE(inst,list);
|
||||||
|
free(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* handle_event *
|
||||||
|
*===========================================================================*/
|
||||||
|
static void handle_event(char *event)
|
||||||
|
{
|
||||||
|
enum dev_type type;
|
||||||
|
char path[PATH_LEN];
|
||||||
|
char tmp_path[PATH_LEN];
|
||||||
|
int dev_id, res;
|
||||||
|
|
||||||
|
path[0]=0;
|
||||||
|
|
||||||
|
if (strncmp("ADD ", event, 4) == 0) {
|
||||||
|
|
||||||
|
/* read data from event */
|
||||||
|
res = sscanf(event, "ADD %s 0x%x", tmp_path, &dev_id);
|
||||||
|
|
||||||
|
if (res != 2) {
|
||||||
|
fprintf(stderr, "WARN: could not parse event: %s", event);
|
||||||
|
fprintf(stderr, "WARN: omitting event: %s", event);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(path, args.path);
|
||||||
|
strcat(path, tmp_path);
|
||||||
|
|
||||||
|
/* what kind of device is added? */
|
||||||
|
type = determine_type(path);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case DEV_TYPE_USB_DEVICE:
|
||||||
|
dbg("USB device added: ommited....");
|
||||||
|
/* ommit usb devices for now */
|
||||||
|
break;
|
||||||
|
case DEV_TYPE_USB_INTF:
|
||||||
|
dbg("USB interface added: (%s, devid: = %d)",path, dev_id);
|
||||||
|
usb_intf_add_event(path, dev_id);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
dbg("default");
|
||||||
|
fprintf(stderr, "WARN: ommiting event\n");
|
||||||
|
}
|
||||||
|
} else if (strncmp("REMOVE ", event, 7) == 0) {
|
||||||
|
|
||||||
|
/* read data from event */
|
||||||
|
res = sscanf(event,"REMOVE %s 0x%x", tmp_path, &dev_id);
|
||||||
|
|
||||||
|
if (res != 2) {
|
||||||
|
fprintf(stderr, "WARN: could not parse event: %s", event);
|
||||||
|
fprintf(stderr, "WARN: omitting event: %s", event);
|
||||||
|
}
|
||||||
|
|
||||||
|
usb_intf_remove_event(path, dev_id);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
strcpy(path, args.path);
|
||||||
|
strcat(path, tmp_path);
|
||||||
|
|
||||||
|
/* what kind of device is added? */
|
||||||
|
type = determine_type(path);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case DEV_TYPE_USB_DEVICE:
|
||||||
|
/* ommit usb devices for now */
|
||||||
|
break;
|
||||||
|
case DEV_TYPE_USB_INTF:
|
||||||
|
usb_intf_remove_event(path, dev_id);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "WARN: ommiting event\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* main_loop *
|
||||||
|
*===========================================================================*/
|
||||||
|
static void main_loop()
|
||||||
|
{
|
||||||
|
char ev_path[128];
|
||||||
|
char buf[256];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
FILE* fd;
|
||||||
|
len = strlen(args.path);
|
||||||
|
|
||||||
|
/* init major numbers */
|
||||||
|
|
||||||
|
memset(&major_bitmap, 0xff, 16);
|
||||||
|
|
||||||
|
if (len > 128 - 7 /*len of "events" */) {
|
||||||
|
fprintf(stderr, "pathname to long\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(ev_path, args.path);
|
||||||
|
strcat(ev_path, "events");
|
||||||
|
|
||||||
|
|
||||||
|
while (_run) {
|
||||||
|
|
||||||
|
char *res;
|
||||||
|
|
||||||
|
fd = fopen(ev_path, "r");
|
||||||
|
if (fd == NULL) {
|
||||||
|
fprintf(stderr, "ERROR: could not open event file...\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = fgets(buf, 256, fd);
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
|
if (res == NULL) {
|
||||||
|
/* TODO: wait for control events */
|
||||||
|
usleep(50000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dbg("handle_event: %s", buf);
|
||||||
|
handle_event(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* display_usage *
|
||||||
|
*===========================================================================*/
|
||||||
|
static void display_usage(const char *name)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [-d|--deamonize] [{-p|--pathname} PATH_TO_SYS}"
|
||||||
|
" [{-c|--config} CONFIG_FILE]\n", name);
|
||||||
|
}
|
||||||
|
|
11
commands/devmand/proto.h
Normal file
11
commands/devmand/proto.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef _DEVMAND_PROTO_H
|
||||||
|
#define _DEVMAND_PROTO_H
|
||||||
|
|
||||||
|
/* main.c */
|
||||||
|
struct devmand_usb_driver * add_usb_driver(char *name);
|
||||||
|
struct devmand_usb_match_id * add_usb_match_id();
|
||||||
|
|
||||||
|
/* y.tab.c */
|
||||||
|
int yyparse();
|
||||||
|
|
||||||
|
#endif
|
134
commands/devmand/usb.y
Normal file
134
commands/devmand/usb.y
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "usb_driver.h"
|
||||||
|
#define YY_NO_INPUT
|
||||||
|
static struct devmand_usb_driver *current_drv;
|
||||||
|
static struct devmand_usb_match_id *current_id;
|
||||||
|
|
||||||
|
int yylex(void);
|
||||||
|
|
||||||
|
void yyerror(char *s)
|
||||||
|
{
|
||||||
|
fprintf(stderr,"parsing error: %s\n",s);
|
||||||
|
}
|
||||||
|
|
||||||
|
int yywrap()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
%union {
|
||||||
|
char *string;
|
||||||
|
}
|
||||||
|
|
||||||
|
%start drivers
|
||||||
|
%token <string> USB_DRIVER DEV_PREFIX BINARY INTERFACE_CLASS INTERFACE_SUB_CLASS EQUALS DEV_TYPE BLOCK_DEV CHAR_DEV UPSCRIPT DOWNSCRIPT
|
||||||
|
SEMICOLON BRACKET_OPEN BRACKET_CLOSE STRING ID INTERFACE_PROTOCOL
|
||||||
|
|
||||||
|
%%
|
||||||
|
drivers :
|
||||||
|
driver
|
||||||
|
{
|
||||||
|
}
|
||||||
|
| drivers driver
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
driver :
|
||||||
|
USB_DRIVER STRING {current_drv = add_usb_driver($2);}
|
||||||
|
BRACKET_OPEN
|
||||||
|
usb_driver_statements BRACKET_CLOSE
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
usb_driver_statements:
|
||||||
|
usb_driver_statement
|
||||||
|
{
|
||||||
|
}
|
||||||
|
| usb_driver_statements usb_driver_statement
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
usb_driver_statement:
|
||||||
|
{current_id = add_usb_match_id(current_drv);}
|
||||||
|
ID BRACKET_OPEN usb_device_id_statements BRACKET_CLOSE
|
||||||
|
{
|
||||||
|
}
|
||||||
|
| BINARY EQUALS STRING SEMICOLON
|
||||||
|
{
|
||||||
|
current_drv->binary = $3;
|
||||||
|
}
|
||||||
|
| DEV_PREFIX EQUALS STRING SEMICOLON
|
||||||
|
{
|
||||||
|
current_drv->devprefix = $3;
|
||||||
|
}
|
||||||
|
| DEV_TYPE EQUALS BLOCK_DEV SEMICOLON
|
||||||
|
{
|
||||||
|
current_drv->dev_type = block_dev;
|
||||||
|
}
|
||||||
|
| DEV_TYPE EQUALS CHAR_DEV SEMICOLON
|
||||||
|
{
|
||||||
|
current_drv->dev_type = char_dev;
|
||||||
|
}
|
||||||
|
| UPSCRIPT EQUALS STRING SEMICOLON
|
||||||
|
{
|
||||||
|
current_drv->upscript = $3;
|
||||||
|
}
|
||||||
|
| DOWNSCRIPT EQUALS STRING SEMICOLON
|
||||||
|
{
|
||||||
|
current_drv->downscript = $3;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
usb_device_id_statements:
|
||||||
|
usb_device_id_statement
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|usb_device_id_statements usb_device_id_statement
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
usb_device_id_statement:
|
||||||
|
INTERFACE_CLASS EQUALS STRING SEMICOLON
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
unsigned int num;
|
||||||
|
current_id->match_flags |= USB_MATCH_INTERFACE_CLASS;
|
||||||
|
res = sscanf($3, "0x%x", &num);
|
||||||
|
if (res != 1) {
|
||||||
|
fprintf(stderr, "ERROR");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
current_id->match_id.bInterfaceClass = num;
|
||||||
|
}
|
||||||
|
| INTERFACE_SUB_CLASS EQUALS STRING SEMICOLON
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
unsigned int num;
|
||||||
|
current_id->match_flags |= USB_MATCH_INTERFACE_SUBCLASS;
|
||||||
|
res = sscanf($3, "0x%x", &num);
|
||||||
|
if (res != 1) {
|
||||||
|
fprintf(stderr, "ERROR");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
current_id->match_id.bInterfaceSubClass = num;
|
||||||
|
|
||||||
|
}
|
||||||
|
| INTERFACE_PROTOCOL EQUALS STRING SEMICOLON
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
unsigned int num;
|
||||||
|
current_id->match_flags |= USB_MATCH_INTERFACE_PROTOCOL;
|
||||||
|
res = sscanf($3, "0x%x", &num);
|
||||||
|
if (res != 1) {
|
||||||
|
fprintf(stderr, "ERROR");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
current_id->match_id.bInterfaceProtocol = num;
|
||||||
|
|
||||||
|
};
|
||||||
|
%%
|
52
commands/devmand/usb_driver.h
Normal file
52
commands/devmand/usb_driver.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#ifndef DEVMAN_USB_DRIVER
|
||||||
|
#define DEVMAN_USB_DRIVER
|
||||||
|
|
||||||
|
#include <minix/usb.h>
|
||||||
|
#include <sys/queue.h>
|
||||||
|
|
||||||
|
#define USB_MATCH_ID_VENDOR (1 << 0)
|
||||||
|
#define USB_MATCH_ID_PRODUCT (1 << 1)
|
||||||
|
#define USB_MATCH_BCD_DEVICE (1 << 2)
|
||||||
|
#define USB_MATCH_DEVICE_CLASS (1 << 3)
|
||||||
|
#define USB_MATCH_DEVICE_SUBCLASS (1 << 4)
|
||||||
|
#define USB_MATCH_DEVICE_PROTOCOL (1 << 5)
|
||||||
|
#define USB_MATCH_INTERFACE_CLASS (1 << 6)
|
||||||
|
#define USB_MATCH_INTERFACE_SUBCLASS (1 << 7)
|
||||||
|
#define USB_MATCH_INTERFACE_PROTOCOL (1 << 8)
|
||||||
|
|
||||||
|
enum devmand_device_type {
|
||||||
|
char_dev,
|
||||||
|
block_dev
|
||||||
|
};
|
||||||
|
|
||||||
|
struct devmand_usb_match_id {
|
||||||
|
unsigned match_flags;
|
||||||
|
struct usb_device_id match_id;
|
||||||
|
LIST_ENTRY(devmand_usb_match_id) list;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEVMAND_DRIVER_LABEL_LEN 32
|
||||||
|
|
||||||
|
struct devmand_driver_instance {
|
||||||
|
int dev_id;
|
||||||
|
int major;
|
||||||
|
char label[DEVMAND_DRIVER_LABEL_LEN];
|
||||||
|
struct devmand_usb_driver *drv;
|
||||||
|
LIST_ENTRY(devmand_driver_instance) list;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct devmand_usb_driver {
|
||||||
|
char *name;
|
||||||
|
char *devprefix;
|
||||||
|
char *binary;
|
||||||
|
char *upscript;
|
||||||
|
char *downscript;
|
||||||
|
enum devmand_device_type dev_type;
|
||||||
|
LIST_HEAD(devid_head, devmand_usb_match_id) ids;
|
||||||
|
LIST_ENTRY(devmand_usb_driver) list;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct devmand_usb_driver * add_usb_driver(char *name);
|
||||||
|
struct devmand_usb_match_id *add_usb_match_id(struct devmand_usb_driver *drv);
|
||||||
|
|
||||||
|
#endif
|
43
commands/devmand/usb_scan.l
Normal file
43
commands/devmand/usb_scan.l
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/* -*- indented-text -*- */
|
||||||
|
%option noinput
|
||||||
|
%option nounput
|
||||||
|
%{
|
||||||
|
#include "y.tab.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define ECHO fwrite(yytext, yyleng, 1, yyout)
|
||||||
|
#else
|
||||||
|
#define ECHO
|
||||||
|
#endif
|
||||||
|
%}
|
||||||
|
BO [{]
|
||||||
|
BC [}]
|
||||||
|
NL [\n]
|
||||||
|
SC [;]
|
||||||
|
CHAR [0-9a-zA-Z_/\-\*\.]
|
||||||
|
EQ [=]
|
||||||
|
SPACE [\032]
|
||||||
|
%%
|
||||||
|
|
||||||
|
usb_driver { ECHO; return USB_DRIVER;}
|
||||||
|
devprefix { ECHO; return DEV_PREFIX;}
|
||||||
|
devtype { ECHO; return DEV_TYPE;}
|
||||||
|
char { ECHO; return BLOCK_DEV;}
|
||||||
|
block { ECHO; return CHAR_DEV;}
|
||||||
|
binary { ECHO; return BINARY;}
|
||||||
|
bInterfaceClass { ECHO; return INTERFACE_CLASS;}
|
||||||
|
bInterfaceSubClass { ECHO; return INTERFACE_SUB_CLASS;}
|
||||||
|
bInterfaceProtocol { ECHO; return INTERFACE_PROTOCOL;}
|
||||||
|
id { ECHO; return ID;}
|
||||||
|
upscript { ECHO; return UPSCRIPT;}
|
||||||
|
downscript { ECHO; return DOWNSCRIPT;}
|
||||||
|
{EQ} { ECHO; return EQUALS;}
|
||||||
|
{SC} { ECHO; return SEMICOLON;}
|
||||||
|
{BO} { ECHO; return BRACKET_OPEN;}
|
||||||
|
{BC} { ECHO; return BRACKET_CLOSE;}
|
||||||
|
{CHAR}+ { ECHO; yylval.string = (char *)strdup(yytext); return STRING;}
|
||||||
|
. ;
|
||||||
|
%%
|
||||||
|
|
|
@ -7,9 +7,10 @@
|
||||||
|
|
||||||
struct ddekit_minix_msg_q;
|
struct ddekit_minix_msg_q;
|
||||||
|
|
||||||
void ddekit_minix_queue_msg(message *m);
|
void ddekit_minix_queue_msg(message *m, int ipc_status);
|
||||||
|
|
||||||
void ddekit_minix_rcv(struct ddekit_minix_msg_q * mq, message *m);
|
void ddekit_minix_rcv
|
||||||
|
(struct ddekit_minix_msg_q * mq, message *m, int *ipc_status);
|
||||||
|
|
||||||
struct ddekit_minix_msg_q *ddekit_minix_create_msg_q(unsigned from,
|
struct ddekit_minix_msg_q *ddekit_minix_create_msg_q(unsigned from,
|
||||||
unsigned to);
|
unsigned to);
|
||||||
|
|
|
@ -32,7 +32,7 @@ int ddekit_release_mem(ddekit_addr_t start, ddekit_addr_t count);
|
||||||
*
|
*
|
||||||
* \return value read from port
|
* \return value read from port
|
||||||
*/
|
*/
|
||||||
unsigned char dde_kit_inb(ddekit_addr_t port);
|
unsigned char ddekit_inb(ddekit_addr_t port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read I/O port (2-byte)
|
* Read I/O port (2-byte)
|
||||||
|
@ -41,7 +41,7 @@ unsigned char dde_kit_inb(ddekit_addr_t port);
|
||||||
*
|
*
|
||||||
* \return value read from port
|
* \return value read from port
|
||||||
*/
|
*/
|
||||||
unsigned short dde_kit_inw(ddekit_addr_t port);
|
unsigned short ddekit_inw(ddekit_addr_t port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read I/O port (4-byte)
|
* Read I/O port (4-byte)
|
||||||
|
@ -50,7 +50,7 @@ unsigned short dde_kit_inw(ddekit_addr_t port);
|
||||||
*
|
*
|
||||||
* \return value read from port
|
* \return value read from port
|
||||||
*/
|
*/
|
||||||
unsigned long dde_kit_inl(ddekit_addr_t port);
|
unsigned long ddekit_inl(ddekit_addr_t port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write I/O port (byte)
|
* Write I/O port (byte)
|
||||||
|
@ -58,7 +58,7 @@ unsigned long dde_kit_inl(ddekit_addr_t port);
|
||||||
* \param port port to write
|
* \param port port to write
|
||||||
* \param val value to write
|
* \param val value to write
|
||||||
*/
|
*/
|
||||||
void dde_kit_outb(ddekit_addr_t port, unsigned char val);
|
void ddekit_outb(ddekit_addr_t port, unsigned char val);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write I/O port (2-byte)
|
* Write I/O port (2-byte)
|
||||||
|
@ -66,7 +66,7 @@ void dde_kit_outb(ddekit_addr_t port, unsigned char val);
|
||||||
* \param port port to write
|
* \param port port to write
|
||||||
* \param val value to write
|
* \param val value to write
|
||||||
*/
|
*/
|
||||||
void dde_kit_outw(ddekit_addr_t port, unsigned short val);
|
void ddekit_outw(ddekit_addr_t port, unsigned short val);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write I/O port (4-byte)
|
* Write I/O port (4-byte)
|
||||||
|
@ -74,7 +74,7 @@ void dde_kit_outw(ddekit_addr_t port, unsigned short val);
|
||||||
* \param port port to write
|
* \param port port to write
|
||||||
* \param val value to write
|
* \param val value to write
|
||||||
*/
|
*/
|
||||||
void dde_kit_outl(ddekit_addr_t port, unsigned long val);
|
void ddekit_outl(ddekit_addr_t port, unsigned long val);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -58,3 +58,8 @@ error "_MINIX_MACHINE has incorrect value (0)"
|
||||||
#define DEFAULT_STACK_LIMIT (64 * 1024 * 1024)
|
#define DEFAULT_STACK_LIMIT (64 * 1024 * 1024)
|
||||||
|
|
||||||
#endif /* _MINIX_SYS_CONFIG_H */
|
#endif /* _MINIX_SYS_CONFIG_H */
|
||||||
|
|
||||||
|
/* Added by release script */
|
||||||
|
#ifndef _VCS_REVISION
|
||||||
|
#define _VCS_REVISION "116fcea"
|
||||||
|
#endif
|
||||||
|
|
|
@ -30,7 +30,7 @@ static void ddekit_dispatcher_thread_init(void);
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
static void dispatcher_thread(void *unused) {
|
static void dispatcher_thread(void *unused) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gets all messages and dispatches them.
|
* Gets all messages and dispatches them.
|
||||||
*
|
*
|
||||||
* NOTE: this thread runs only when no other ddekit is
|
* NOTE: this thread runs only when no other ddekit is
|
||||||
|
@ -40,6 +40,7 @@ static void dispatcher_thread(void *unused) {
|
||||||
message m;
|
message m;
|
||||||
int r;
|
int r;
|
||||||
int i;
|
int i;
|
||||||
|
int ipc_status;
|
||||||
|
|
||||||
_ddekit_thread_set_myprio(0);
|
_ddekit_thread_set_myprio(0);
|
||||||
|
|
||||||
|
@ -47,17 +48,17 @@ static void dispatcher_thread(void *unused) {
|
||||||
|
|
||||||
/* Trigger a timer interrupt at each loop iteration */
|
/* Trigger a timer interrupt at each loop iteration */
|
||||||
_ddekit_timer_update();
|
_ddekit_timer_update();
|
||||||
|
|
||||||
/* Wait for messages */
|
/* Wait for messages */
|
||||||
if ((r = sef_receive(ANY, &m)) != 0) {
|
if ((r = sef_receive_status(ANY, &m, &ipc_status)) != 0) {
|
||||||
ddekit_panic("ddekit", "sef_receive failed", r);
|
ddekit_panic("ddekit", "sef_receive failed", r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_ddekit_timer_interrupt();
|
_ddekit_timer_interrupt();
|
||||||
|
|
||||||
_ddekit_thread_wakeup_sleeping();
|
_ddekit_thread_wakeup_sleeping();
|
||||||
|
|
||||||
if (is_notify(m.m_type)) {
|
if (is_notify(m.m_type)) {
|
||||||
switch (_ENDPOINT_P(m.m_source)) {
|
switch (_ENDPOINT_P(m.m_source)) {
|
||||||
case HARDWARE:
|
case HARDWARE:
|
||||||
|
@ -77,15 +78,15 @@ static void dispatcher_thread(void *unused) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* I don't know how to handle this msg,
|
* I don't know how to handle this msg,
|
||||||
* but maybe we have a msg queue which can
|
* but maybe we have a msg queue which can
|
||||||
* handle this msg.
|
* handle this msg.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ddekit_minix_queue_msg(&m);
|
ddekit_minix_queue_msg(&m, ipc_status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,9 +115,9 @@ void ddekit_init(void)
|
||||||
ddekit_init_irqs();
|
ddekit_init_irqs();
|
||||||
|
|
||||||
ddekit_init_timers();
|
ddekit_init_timers();
|
||||||
|
|
||||||
ddekit_dispatcher_thread_init();
|
ddekit_dispatcher_thread_init();
|
||||||
|
|
||||||
exit_sem = ddekit_sem_init(0);
|
exit_sem = ddekit_sem_init(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#define DDEBUG DDEKIT_DEBUG_INITCALL
|
#define DDEBUG DDEKIT_DEBUG_INITCALL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
static struct __ddekit_initcall_s head = {0,0,0};
|
static struct __ddekit_initcall_s head = {0,0,0};
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ struct ddekit_minix_msg_q {
|
||||||
unsigned from, to;
|
unsigned from, to;
|
||||||
|
|
||||||
message messages[MESSAGE_QUEUE_SIZE];
|
message messages[MESSAGE_QUEUE_SIZE];
|
||||||
|
int ipc_status[MESSAGE_QUEUE_SIZE];
|
||||||
ddekit_sem_t *msg_w_sem, *msg_r_sem;
|
ddekit_sem_t *msg_w_sem, *msg_r_sem;
|
||||||
int msg_r_pos, msg_w_pos;
|
int msg_r_pos, msg_w_pos;
|
||||||
|
|
||||||
|
@ -26,8 +27,8 @@ struct ddekit_minix_msg_q {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ddekit_minix_msg_q * _list = NULL;
|
static struct ddekit_minix_msg_q * _list = NULL;
|
||||||
static void _ddekit_minix_queue_msg(struct ddekit_minix_msg_q *mq,
|
static void _ddekit_minix_queue_msg
|
||||||
message *m);
|
(struct ddekit_minix_msg_q *mq, message *m, int ipc_status);
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* ddekit_minix_create_msg_q *
|
* ddekit_minix_create_msg_q *
|
||||||
|
@ -37,7 +38,7 @@ ddekit_minix_create_msg_q(unsigned from, unsigned to)
|
||||||
{
|
{
|
||||||
struct ddekit_minix_msg_q *mq = (struct ddekit_minix_msg_q *)
|
struct ddekit_minix_msg_q *mq = (struct ddekit_minix_msg_q *)
|
||||||
ddekit_simple_malloc(sizeof(struct ddekit_minix_msg_q));
|
ddekit_simple_malloc(sizeof(struct ddekit_minix_msg_q));
|
||||||
|
|
||||||
mq->from = from;
|
mq->from = from;
|
||||||
mq->to = to;
|
mq->to = to;
|
||||||
mq->msg_w_pos = 0;
|
mq->msg_w_pos = 0;
|
||||||
|
@ -49,10 +50,10 @@ ddekit_minix_create_msg_q(unsigned from, unsigned to)
|
||||||
/* TODO: check for overlapping message ranges */
|
/* TODO: check for overlapping message ranges */
|
||||||
mq->next = _list;
|
mq->next = _list;
|
||||||
_list = mq;
|
_list = mq;
|
||||||
|
|
||||||
DDEBUG_MSG_VERBOSE("created msg_q from %x to %x\n", from , to);
|
DDEBUG_MSG_VERBOSE("created msg_q from %x to %x\n", from , to);
|
||||||
|
|
||||||
return mq;
|
return mq;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
@ -81,8 +82,12 @@ void ddekit_minix_deregister_msg_q(struct ddekit_minix_msg_q *mq)
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* _ddekit_minix_queue_msg *
|
* _ddekit_minix_queue_msg *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void
|
static void
|
||||||
_ddekit_minix_queue_msg(struct ddekit_minix_msg_q *mq, message *m)
|
_ddekit_minix_queue_msg (
|
||||||
|
struct ddekit_minix_msg_q *mq,
|
||||||
|
message *m,
|
||||||
|
int ipc_status
|
||||||
|
)
|
||||||
{
|
{
|
||||||
int full;
|
int full;
|
||||||
full = ddekit_sem_down_try(mq->msg_w_sem);
|
full = ddekit_sem_down_try(mq->msg_w_sem);
|
||||||
|
@ -95,7 +100,7 @@ _ddekit_minix_queue_msg(struct ddekit_minix_msg_q *mq, message *m)
|
||||||
m->m_type = TASK_REPLY;
|
m->m_type = TASK_REPLY;
|
||||||
m->REP_STATUS = EAGAIN;
|
m->REP_STATUS = EAGAIN;
|
||||||
result = asynsend(m->m_source, m);
|
result = asynsend(m->m_source, m);
|
||||||
|
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
ddekit_panic("unable to send reply to %d: %d\n",
|
ddekit_panic("unable to send reply to %d: %d\n",
|
||||||
m->m_source, result);
|
m->m_source, result);
|
||||||
|
@ -104,7 +109,7 @@ _ddekit_minix_queue_msg(struct ddekit_minix_msg_q *mq, message *m)
|
||||||
} else {
|
} else {
|
||||||
/* queue the message */
|
/* queue the message */
|
||||||
memcpy(&mq->messages[mq->msg_w_pos], m, sizeof(message));
|
memcpy(&mq->messages[mq->msg_w_pos], m, sizeof(message));
|
||||||
|
mq->ipc_status[mq->msg_w_pos] = ipc_status;
|
||||||
if (++mq->msg_w_pos == MESSAGE_QUEUE_SIZE) {
|
if (++mq->msg_w_pos == MESSAGE_QUEUE_SIZE) {
|
||||||
mq->msg_w_pos = 0;
|
mq->msg_w_pos = 0;
|
||||||
}
|
}
|
||||||
|
@ -117,10 +122,10 @@ _ddekit_minix_queue_msg(struct ddekit_minix_msg_q *mq, message *m)
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* ddekit_minix_queue_msg *
|
* ddekit_minix_queue_msg *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void ddekit_minix_queue_msg(message *m)
|
void ddekit_minix_queue_msg(message *m, int ipc_status)
|
||||||
{
|
{
|
||||||
struct ddekit_minix_msg_q *it, *mq = NULL;
|
struct ddekit_minix_msg_q *it, *mq = NULL;
|
||||||
|
|
||||||
for (it = _list; it !=NULL ; it = it->next) {
|
for (it = _list; it !=NULL ; it = it->next) {
|
||||||
if (m->m_type >= it->from && m->m_type <= it->to) {
|
if (m->m_type >= it->from && m->m_type <= it->to) {
|
||||||
mq = it;
|
mq = it;
|
||||||
|
@ -131,25 +136,29 @@ void ddekit_minix_queue_msg(message *m)
|
||||||
DDEBUG_MSG_VERBOSE("no q for msgtype %x\n", m->m_type);
|
DDEBUG_MSG_VERBOSE("no q for msgtype %x\n", m->m_type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_ddekit_minix_queue_msg(mq,m);
|
_ddekit_minix_queue_msg(mq, m, ipc_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* ddekit_minix_rcv *
|
* ddekit_minix_rcv *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void ddekit_minix_rcv(struct ddekit_minix_msg_q *mq, message *m)
|
void ddekit_minix_rcv (
|
||||||
|
struct ddekit_minix_msg_q *mq,
|
||||||
|
message *m,
|
||||||
|
int *ipc_status
|
||||||
|
)
|
||||||
{
|
{
|
||||||
DDEBUG_MSG_VERBOSE("waiting for message");
|
DDEBUG_MSG_VERBOSE("waiting for message");
|
||||||
|
|
||||||
ddekit_sem_down(mq->msg_r_sem);
|
ddekit_sem_down(mq->msg_r_sem);
|
||||||
|
|
||||||
memcpy(m, &mq->messages[mq->msg_r_pos], sizeof(message));
|
memcpy(m, &mq->messages[mq->msg_r_pos], sizeof(message));
|
||||||
|
*ipc_status = mq->ipc_status[mq->msg_r_pos];
|
||||||
if (++mq->msg_r_pos == MESSAGE_QUEUE_SIZE) {
|
if (++mq->msg_r_pos == MESSAGE_QUEUE_SIZE) {
|
||||||
mq->msg_r_pos = 0;
|
mq->msg_r_pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DDEBUG_MSG_VERBOSE("unqueing message");
|
DDEBUG_MSG_VERBOSE("unqueing message");
|
||||||
|
|
||||||
ddekit_sem_up(mq->msg_w_sem);
|
ddekit_sem_up(mq->msg_w_sem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,18 +52,17 @@ static void _ddekit_usb_completion(struct usb_urb *mx_urb)
|
||||||
|
|
||||||
if (mx_urb->type == USB_TRANSFER_ISO) {
|
if (mx_urb->type == USB_TRANSFER_ISO) {
|
||||||
d_urb->start_frame = mx_urb->start_frame;
|
d_urb->start_frame = mx_urb->start_frame;
|
||||||
|
|
||||||
memcpy(d_urb->iso_desc, mx_urb->buffer + d_urb->size,
|
memcpy(d_urb->iso_desc, mx_urb->buffer + d_urb->size,
|
||||||
d_urb->number_of_packets * sizeof(struct usb_iso_packet_desc));
|
d_urb->number_of_packets * sizeof(struct usb_iso_packet_desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(d_urb->data, mx_urb->buffer, d_urb->size);
|
memcpy(d_urb->data, mx_urb->buffer, d_urb->size);
|
||||||
|
|
||||||
/* free mx_urb */
|
/* free mx_urb */
|
||||||
ddekit_simple_free(mx_urb);
|
ddekit_simple_free(mx_urb);
|
||||||
|
|
||||||
/* 'give back' URB */
|
/* 'give back' URB */
|
||||||
|
|
||||||
|
|
||||||
d_usb_driver->completion(d_urb->priv);
|
d_usb_driver->completion(d_urb->priv);
|
||||||
}
|
}
|
||||||
|
@ -139,11 +138,9 @@ int ddekit_usb_submit_urb(struct ddekit_usb_urb *d_urb)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
unsigned urb_size = USB_URBSIZE(d_urb->size, d_urb->number_of_packets);
|
unsigned urb_size = USB_URBSIZE(d_urb->size, d_urb->number_of_packets);
|
||||||
|
|
||||||
/* create mx urb out of d_urb */
|
/* create mx urb out of d_urb */
|
||||||
struct usb_urb *mx_urb = (struct usb_urb*)
|
struct usb_urb *mx_urb = (struct usb_urb*)
|
||||||
ddekit_simple_malloc(urb_size);
|
ddekit_simple_malloc(urb_size);
|
||||||
|
|
||||||
mx_urb->urb_size = urb_size;
|
mx_urb->urb_size = urb_size;
|
||||||
|
|
||||||
mx_urb->dev_id = d_urb->dev->id;
|
mx_urb->dev_id = d_urb->dev->id;
|
||||||
|
@ -162,18 +159,15 @@ int ddekit_usb_submit_urb(struct ddekit_usb_urb *d_urb)
|
||||||
if (mx_urb->type == USB_TRANSFER_ISO) {
|
if (mx_urb->type == USB_TRANSFER_ISO) {
|
||||||
mx_urb->number_of_packets = d_urb->number_of_packets;
|
mx_urb->number_of_packets = d_urb->number_of_packets;
|
||||||
mx_urb->start_frame = d_urb->start_frame;
|
mx_urb->start_frame = d_urb->start_frame;
|
||||||
|
|
||||||
memcpy(mx_urb->buffer + d_urb->size, d_urb->iso_desc,
|
memcpy(mx_urb->buffer + d_urb->size, d_urb->iso_desc,
|
||||||
d_urb->number_of_packets * sizeof(struct usb_iso_packet_desc));
|
d_urb->number_of_packets * sizeof(struct usb_iso_packet_desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(mx_urb->buffer, d_urb->data, d_urb->size);
|
memcpy(mx_urb->buffer, d_urb->data, d_urb->size);
|
||||||
|
|
||||||
d_urb->ddekit_priv = mx_urb;
|
d_urb->ddekit_priv = mx_urb;
|
||||||
|
|
||||||
/* submit mx_urb */
|
/* submit mx_urb */
|
||||||
res = usb_send_urb(mx_urb);
|
res = usb_send_urb(mx_urb);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,14 +191,15 @@ static void _ddekit_usb_thread()
|
||||||
struct ddekit_minix_msg_q *mq = ddekit_minix_create_msg_q(USB_BASE,
|
struct ddekit_minix_msg_q *mq = ddekit_minix_create_msg_q(USB_BASE,
|
||||||
USB_BASE + 0x1000);
|
USB_BASE + 0x1000);
|
||||||
message m;
|
message m;
|
||||||
|
int ipc_status;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
ddekit_minix_rcv(mq, &m);
|
ddekit_minix_rcv(mq, &m, &ipc_status);
|
||||||
usb_handle_msg(&mx_usb_driver,&m);
|
usb_handle_msg(&mx_usb_driver, &m);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* ddekit_usb_init *
|
* ddekit_usb_init *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -213,7 +208,6 @@ int ddekit_usb_init
|
||||||
ddekit_usb_malloc_fn *unused,
|
ddekit_usb_malloc_fn *unused,
|
||||||
ddekit_usb_free_fn *_unused)
|
ddekit_usb_free_fn *_unused)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* start usb_thread */
|
/* start usb_thread */
|
||||||
d_usb_driver = drv;
|
d_usb_driver = drv;
|
||||||
usb_init("dde");
|
usb_init("dde");
|
||||||
|
|
|
@ -415,7 +415,7 @@ static void cancle_urb(message *msg)
|
||||||
endpoint_t ep = msg->m_source;
|
endpoint_t ep = msg->m_source;
|
||||||
|
|
||||||
struct minix_usb_driver *drv;
|
struct minix_usb_driver *drv;
|
||||||
|
|
||||||
msg->USB_RESULT = -1;
|
msg->USB_RESULT = -1;
|
||||||
msg->m_type = USB_REPLY;
|
msg->m_type = USB_REPLY;
|
||||||
|
|
||||||
|
@ -425,7 +425,7 @@ static void cancle_urb(message *msg)
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
struct ddekit_usb_urb *d_urb = NULL;
|
struct ddekit_usb_urb *d_urb = NULL;
|
||||||
|
|
||||||
d_urb = find_pending_urb(drv, msg->USB_URB_ID);
|
d_urb = find_pending_urb(drv, msg->USB_URB_ID);
|
||||||
|
|
||||||
if (d_urb != NULL) {
|
if (d_urb != NULL) {
|
||||||
|
@ -436,7 +436,7 @@ static void cancle_urb(message *msg)
|
||||||
msg->USB_RESULT = ENODEV;
|
msg->USB_RESULT = ENODEV;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send(ep, msg);
|
send(ep, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,9 +468,9 @@ static void completion_callback(void *priv)
|
||||||
mx_urb->actual_length = d_urb->actual_length;
|
mx_urb->actual_length = d_urb->actual_length;
|
||||||
mx_urb->error_count = d_urb->error_count;
|
mx_urb->error_count = d_urb->error_count;
|
||||||
mx_urb->transfer_flags = d_urb->transfer_flags;
|
mx_urb->transfer_flags = d_urb->transfer_flags;
|
||||||
|
|
||||||
remove_from_pending_urbs(drv, d_urb);
|
remove_from_pending_urbs(drv, d_urb);
|
||||||
|
|
||||||
/* copy out URB */
|
/* copy out URB */
|
||||||
res = sys_safecopyto(drv->ep, ctx->gid, 0,
|
res = sys_safecopyto(drv->ep, ctx->gid, 0,
|
||||||
(vir_bytes) ((char*)mx_urb) + sizeof(void*),
|
(vir_bytes) ((char*)mx_urb) + sizeof(void*),
|
||||||
|
@ -486,7 +486,7 @@ static void completion_callback(void *priv)
|
||||||
msg.m_type = USB_COMPLETE_URB;
|
msg.m_type = USB_COMPLETE_URB;
|
||||||
msg.USB_URB_ID = ctx->urb_id;
|
msg.USB_URB_ID = ctx->urb_id;
|
||||||
asynsend3(drv->ep, &msg, AMF_NOREPLY);
|
asynsend3(drv->ep, &msg, AMF_NOREPLY);
|
||||||
|
|
||||||
/* free stuff */
|
/* free stuff */
|
||||||
my_free(ctx);
|
my_free(ctx);
|
||||||
my_free(mx_urb);
|
my_free(mx_urb);
|
||||||
|
@ -725,10 +725,10 @@ static void devman_thread(void *unused)
|
||||||
{
|
{
|
||||||
struct ddekit_minix_msg_q *mq = ddekit_minix_create_msg_q(DEVMAN_BASE,
|
struct ddekit_minix_msg_q *mq = ddekit_minix_create_msg_q(DEVMAN_BASE,
|
||||||
DEVMAN_BASE + 0xff);
|
DEVMAN_BASE + 0xff);
|
||||||
|
int ipc_status;
|
||||||
message m;
|
message m;
|
||||||
while (1) {
|
while (1) {
|
||||||
ddekit_minix_rcv(mq, &m);
|
ddekit_minix_rcv(mq, &m, &ipc_status);
|
||||||
devman_handle_msg(&m);
|
devman_handle_msg(&m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -742,6 +742,7 @@ static void _ddekit_usb_thread(void * unused)
|
||||||
USB_BASE + 0xff);
|
USB_BASE + 0xff);
|
||||||
|
|
||||||
message m;
|
message m;
|
||||||
|
int ipc_status;
|
||||||
|
|
||||||
/* create devman thread */
|
/* create devman thread */
|
||||||
ddekit_thread_t * dmth;
|
ddekit_thread_t * dmth;
|
||||||
|
@ -749,7 +750,7 @@ static void _ddekit_usb_thread(void * unused)
|
||||||
dmth = ddekit_thread_create(devman_thread, NULL, "devman_thread");
|
dmth = ddekit_thread_create(devman_thread, NULL, "devman_thread");
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
ddekit_minix_rcv(mq, &m);
|
ddekit_minix_rcv(mq, &m, &ipc_status);
|
||||||
handle_msg(&m);
|
handle_msg(&m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue