Applied patch by Pete Goodeve, which adds multi-ports support to usb_midi driver.
Fixed some coding style and a few sanity checks where it make sense. This driver code is not in a good shape and needs a wide cleanup. unfortunatly, I still don't have any device to test with, so I can't do that anytime soon. Intead of letting his patch collecting dust since 3 months (my bad), I think it's better the multi-port support gets at least more exposure than just Pete's hardware. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41874 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5d6dcc0685
commit
1291377a6e
@ -2,7 +2,7 @@
|
||||
* midi usb driver
|
||||
* devlist.c
|
||||
*
|
||||
* Copyright 2006-2009 Haiku Inc. All rights reserved.
|
||||
* Copyright 2006-2011 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT Licence.
|
||||
*
|
||||
* Authors:
|
||||
@ -23,107 +23,127 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
sem_id usbmidi_device_list_lock = -1;
|
||||
bool usbmidi_device_list_changed = true; /* added or removed */
|
||||
sem_id usbmidi_port_list_lock = -1;
|
||||
bool usbmidi_port_list_changed = true; /* added or removed */
|
||||
|
||||
static usbmidi_device_info* usbmidi_device_list = NULL;
|
||||
static int usbmidi_device_count = 0;
|
||||
static usbmidi_port_info* usbmidi_port_list = NULL;
|
||||
static int usbmidi_port_count = 0;
|
||||
|
||||
|
||||
void
|
||||
add_device_info(usbmidi_device_info* my_dev)
|
||||
add_port_info(usbmidi_port_info* port)
|
||||
{
|
||||
assert(my_dev != NULL);
|
||||
acquire_sem(usbmidi_device_list_lock);
|
||||
my_dev->next = usbmidi_device_list;
|
||||
usbmidi_device_list = my_dev;
|
||||
usbmidi_device_count++;
|
||||
usbmidi_device_list_changed = true;
|
||||
release_sem(usbmidi_device_list_lock);
|
||||
assert(port != NULL);
|
||||
acquire_sem(usbmidi_port_list_lock);
|
||||
port->next = usbmidi_port_list;
|
||||
usbmidi_port_list = port;
|
||||
usbmidi_port_count++;
|
||||
usbmidi_port_list_changed = true;
|
||||
release_sem(usbmidi_port_list_lock);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
remove_device_info(usbmidi_device_info* my_dev)
|
||||
remove_port_info(usbmidi_port_info* port)
|
||||
{
|
||||
assert(my_dev != NULL);
|
||||
acquire_sem(usbmidi_device_list_lock);
|
||||
if (usbmidi_device_list == my_dev) {
|
||||
usbmidi_device_list = my_dev->next;
|
||||
--usbmidi_device_count;
|
||||
usbmidi_device_list_changed = true;
|
||||
assert(port != NULL);
|
||||
acquire_sem(usbmidi_port_list_lock);
|
||||
if (usbmidi_port_list == port) {
|
||||
usbmidi_port_list = port->next;
|
||||
--usbmidi_port_count;
|
||||
usbmidi_port_list_changed = true;
|
||||
} else {
|
||||
usbmidi_device_info* d;
|
||||
for (d = usbmidi_device_list; d != NULL; d = d->next) {
|
||||
if (d->next == my_dev) {
|
||||
d->next = my_dev->next;
|
||||
--usbmidi_device_count;
|
||||
usbmidi_device_list_changed = true;
|
||||
usbmidi_port_info* d;
|
||||
for (d = usbmidi_port_list; d != NULL; d = d->next) {
|
||||
if (d->next == port) {
|
||||
d->next = port->next;
|
||||
--usbmidi_port_count;
|
||||
usbmidi_port_list_changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(d != NULL);
|
||||
}
|
||||
release_sem(usbmidi_device_list_lock);
|
||||
release_sem(usbmidi_port_list_lock);
|
||||
}
|
||||
|
||||
|
||||
usbmidi_device_info*
|
||||
search_device_info(const char* name)
|
||||
usbmidi_port_info*
|
||||
search_port_info(const char* name)
|
||||
{
|
||||
usbmidi_device_info* my_dev;
|
||||
usbmidi_port_info* port;
|
||||
|
||||
acquire_sem(usbmidi_device_list_lock);
|
||||
for (my_dev = usbmidi_device_list; my_dev != NULL; my_dev = my_dev->next) {
|
||||
if (strcmp(my_dev->name, name) == 0)
|
||||
acquire_sem(usbmidi_port_list_lock);
|
||||
for (port = usbmidi_port_list; port != NULL; port = port->next) {
|
||||
if (strcmp(port->name, name) == 0)
|
||||
break;
|
||||
}
|
||||
release_sem(usbmidi_device_list_lock);
|
||||
return my_dev;
|
||||
release_sem(usbmidi_port_list_lock);
|
||||
return port;
|
||||
}
|
||||
|
||||
int
|
||||
find_free_device_number(void)
|
||||
{
|
||||
usbmidi_port_info* port;
|
||||
int number = 0;
|
||||
|
||||
acquire_sem(usbmidi_port_list_lock);
|
||||
do {
|
||||
for (port = usbmidi_port_list; port != NULL; port = port->next) {
|
||||
if (port->device->devnum == number) {
|
||||
number++;
|
||||
break; /* try next higher */
|
||||
}
|
||||
}
|
||||
} while (port);
|
||||
release_sem(usbmidi_port_list_lock);
|
||||
return number;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
device names
|
||||
*/
|
||||
|
||||
/* dynamically generated */
|
||||
char** usbmidi_device_names = NULL;
|
||||
char** usbmidi_port_names = NULL;
|
||||
|
||||
|
||||
void
|
||||
alloc_device_names(void)
|
||||
alloc_port_names(void)
|
||||
{
|
||||
assert(usbmidi_device_names == NULL);
|
||||
usbmidi_device_names = malloc(sizeof(char*) * (usbmidi_device_count + 1));
|
||||
assert(usbmidi_port_names == NULL);
|
||||
usbmidi_port_names = malloc(sizeof(char*) * (usbmidi_port_count + 1));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
free_device_names(void)
|
||||
free_port_names(void)
|
||||
{
|
||||
if (usbmidi_device_names != NULL) {
|
||||
if (usbmidi_port_names != NULL) {
|
||||
int i;
|
||||
for (i = 0; usbmidi_device_names[i] != NULL; i++)
|
||||
free(usbmidi_device_names[i]);
|
||||
free(usbmidi_device_names);
|
||||
usbmidi_device_names = NULL;
|
||||
for (i = 0; usbmidi_port_names[i] != NULL; i++)
|
||||
free(usbmidi_port_names[i]);
|
||||
free(usbmidi_port_names);
|
||||
usbmidi_port_names = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rebuild_device_names(void)
|
||||
rebuild_port_names(void)
|
||||
{
|
||||
int i;
|
||||
usbmidi_device_info* my_dev;
|
||||
usbmidi_port_info* port;
|
||||
|
||||
assert(usbmidi_device_names != NULL);
|
||||
acquire_sem(usbmidi_device_list_lock);
|
||||
for (i = 0, my_dev = usbmidi_device_list; my_dev != NULL; my_dev = my_dev->next) {
|
||||
usbmidi_device_names[i++] = strdup(my_dev->name);
|
||||
DPRINTF_INFO((MY_ID "publishing %s\n", my_dev->name));
|
||||
assert(usbmidi_port_names != NULL);
|
||||
acquire_sem(usbmidi_port_list_lock);
|
||||
for (i = 0, port = usbmidi_port_list; port != NULL; port = port->next) {
|
||||
usbmidi_port_names[i++] = strdup(port->name);
|
||||
DPRINTF_INFO((MY_ID "publishing %s\n", port->name));
|
||||
}
|
||||
usbmidi_device_names[i] = NULL;
|
||||
release_sem(usbmidi_device_list_lock);
|
||||
usbmidi_port_names[i] = NULL;
|
||||
release_sem(usbmidi_port_list_lock);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
* midi usb driver
|
||||
* usb_midi.h
|
||||
*
|
||||
* Copyright 2006-2009 Haiku Inc. All rights reserved.
|
||||
* Copyright 2006-2011 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT Licence.
|
||||
*
|
||||
* Authors:
|
||||
@ -23,23 +23,32 @@
|
||||
|
||||
#include "ring_buffer.h"
|
||||
|
||||
/* Three levels of printout for convenience: */
|
||||
/* #define DEBUG 1 -- more convenient to define in the code file when needed */
|
||||
#define DEBUG_INFO 1
|
||||
#define DEBUG_ERR 1
|
||||
|
||||
#if DEBUG
|
||||
#define DPRINTF_INFO(x) dprintf x
|
||||
#else
|
||||
#define DPRINTF_INFO(x)
|
||||
#endif
|
||||
/* Normally leave this enabled to leave a record in syslog */
|
||||
#if DEBUG_ERR
|
||||
#define DPRINTF_ERR(x) dprintf x
|
||||
#else
|
||||
#define DPRINTF_ERR(x)
|
||||
#endif
|
||||
|
||||
/* For local finer debugging control: */
|
||||
#define DPRINTF_INFOX(x) dprintf x
|
||||
#define DPRINTF_INFOZ(x)
|
||||
/* Use this for initialization etc. messages -- nothing repetitive: */
|
||||
#if DEBUG_INFO
|
||||
#define DPRINTF_INFO(x) dprintf x
|
||||
#else
|
||||
#define DPRINTF_INFO(x)
|
||||
#endif
|
||||
|
||||
/* Enable this to record detailed stuff: */
|
||||
#if DEBUG
|
||||
#define DPRINTF_DEBUG(x) dprintf x
|
||||
#else
|
||||
#define DPRINTF_DEBUG(x)
|
||||
#endif
|
||||
|
||||
|
||||
/* driver specific definitions */
|
||||
|
||||
@ -49,7 +58,8 @@
|
||||
#define MY_ERR "\033[31merror:\033[m "
|
||||
#define MY_WARN "\033[31mwarning:\033[m "
|
||||
#define assert(x) \
|
||||
((x) ? 0 : dprintf(MY_ID "assertion failed at " __FILE__ ", line %d\n", __LINE__))
|
||||
((x) ? 0 : dprintf(MY_ID "assertion failed at " \
|
||||
__FILE__ ", line %d\n", __LINE__))
|
||||
|
||||
#define DEFAULT_CONFIGURATION 0
|
||||
|
||||
@ -58,61 +68,91 @@ struct driver_cookie;
|
||||
|
||||
typedef struct usbmidi_device_info
|
||||
{
|
||||
/* list structure */
|
||||
/* list structure */ /* should not be needed eventually */
|
||||
struct usbmidi_device_info* next;
|
||||
|
||||
/* maintain device */
|
||||
/* Set of actual ports ("cables" -- one or more) */
|
||||
struct usbmidi_port_info* ports[16];
|
||||
|
||||
/* maintain device (common for all ports) */
|
||||
sem_id sem_lock;
|
||||
sem_id sem_send;
|
||||
area_id buffer_area;
|
||||
usb_midi_event_packet* buffer; /* input buffer & base of area */
|
||||
usb_midi_event_packet* out_buffer; /* above input buff */
|
||||
|
||||
usb_midi_event_packet* out_buffer; /* above input buffer */
|
||||
size_t buffer_size; /* for each of in and out buffers */
|
||||
|
||||
const usb_device* dev;
|
||||
uint16 ifno;
|
||||
char name[30];
|
||||
|
||||
struct ring_buffer* rbuf;
|
||||
int devnum; /* unique device number */
|
||||
char name[20];
|
||||
/* = "/dev/midi/usb/n" --port number will be appended to this */
|
||||
|
||||
bool active;
|
||||
int open;
|
||||
struct driver_cookie* open_fd;
|
||||
|
||||
/* work area for transfer */
|
||||
int usbd_status, bus_status, cmd_status;
|
||||
int bus_status;
|
||||
int actual_length;
|
||||
const usb_endpoint_info* ept_in;
|
||||
const usb_endpoint_info* ept_out;
|
||||
|
||||
size_t buffer_size;
|
||||
bigtime_t timestamp;
|
||||
uint flags;
|
||||
bigtime_t timestamp; /* Is this needed? Currently set but never read */
|
||||
uint flags; /* set to 0 but never used */
|
||||
} usbmidi_device_info;
|
||||
|
||||
|
||||
/* usb_midi.c */
|
||||
typedef struct usbmidi_port_info
|
||||
{
|
||||
/* list structure for manager */
|
||||
struct usbmidi_port_info* next;
|
||||
|
||||
/* Common device that does the work */
|
||||
usbmidi_device_info* device;
|
||||
|
||||
/* Port-specific variables */
|
||||
char name[40]; /* complete pathname of this port */
|
||||
struct ring_buffer* rbuf;
|
||||
|
||||
int cable; /* index of this port */
|
||||
bool has_in, has_out;
|
||||
|
||||
int open;
|
||||
struct driver_cookie* open_fd;
|
||||
|
||||
} usbmidi_port_info;
|
||||
|
||||
|
||||
/*
|
||||
usb_midi.c
|
||||
*/
|
||||
|
||||
extern usb_module_info* usb;
|
||||
extern const char* usb_midi_base_name;
|
||||
|
||||
usbmidi_device_info*
|
||||
create_device(const usb_device* dev, const usb_interface_info* ii, uint16 ifno);
|
||||
extern usbmidi_port_info* create_usbmidi_port(usbmidi_device_info* devinfo,
|
||||
int cable, bool has_in, bool has_out);
|
||||
extern void remove_port(usbmidi_port_info* port);
|
||||
|
||||
void
|
||||
remove_device(usbmidi_device_info* my_dev);
|
||||
extern usbmidi_device_info* create_device(const usb_device* dev, uint16 ifno);
|
||||
extern void remove_device(usbmidi_device_info* my_dev);
|
||||
|
||||
|
||||
/* devlist.c */
|
||||
/*
|
||||
devlist.c
|
||||
*/
|
||||
|
||||
extern sem_id usbmidi_device_list_lock;
|
||||
extern bool usbmidi_device_list_changed;
|
||||
extern sem_id usbmidi_port_list_lock;
|
||||
extern bool usbmidi_port_list_changed;
|
||||
|
||||
void add_device_info(usbmidi_device_info* my_dev);
|
||||
void remove_device_info(usbmidi_device_info* my_dev);
|
||||
usbmidi_device_info* search_device_info(const char* name);
|
||||
extern void add_port_info(usbmidi_port_info* port);
|
||||
extern void remove_port_info(usbmidi_port_info* port);
|
||||
|
||||
extern char** usbmidi_device_names;
|
||||
extern usbmidi_port_info* search_port_info(const char* name);
|
||||
|
||||
void alloc_device_names(void);
|
||||
void free_device_names(void);
|
||||
void rebuild_device_names(void);
|
||||
extern int find_free_device_number(void);
|
||||
|
||||
extern char** usbmidi_port_names;
|
||||
|
||||
extern void alloc_port_names(void);
|
||||
extern void free_port_names(void);
|
||||
extern void rebuild_port_names(void);
|
||||
|
Loading…
Reference in New Issue
Block a user