Ticket #4463: usb_midi.diff

File usb_midi.diff, 39.1 KB (added by Pete, 14 years ago)

Provides full multiport USB MIDI access for Class Compliant devices

  • src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.h

     
    22 * midi usb driver
    33 * usb_midi.h
    44 *
    5  * Copyright 2006-2009 Haiku Inc.  All rights reserved.
     5 * Copyright 2006-2011 Haiku Inc.  All rights reserved.
    66 * Distributed under the terms of the MIT Licence.
    77 *
    88 * Authors:
     
    2323
    2424#include "ring_buffer.h"
    2525
     26/* Three levels of printout for convenience: */
    2627/* #define DEBUG 1 -- more convenient to define in the code file when needed */
     28#define DEBUG_INFO 1
    2729#define DEBUG_ERR 1
    2830
    29 #if DEBUG
     31/* Normally leave this enabled to leave a record in syslog */
     32#if DEBUG_ERR
     33    #define DPRINTF_ERR(x)  dprintf x
     34#else
     35    #define DPRINTF_ERR(x)
     36#endif
     37
     38/* Use this for initialization etc. messages -- nothing repetitive: */
     39#if DEBUG_INFO
    3040    #define DPRINTF_INFO(x) dprintf x
    3141#else
    3242    #define DPRINTF_INFO(x)
    3343#endif
    34 #if DEBUG_ERR
    35     #define DPRINTF_ERR(x)  dprintf x
     44
     45/* Enable this to record detailed stuff: */
     46#if DEBUG
     47    #define DPRINTF_DEBUG(x)    dprintf x
    3648#else
    37     #define DPRINTF_ERR(x)
     49    #define DPRINTF_DEBUG(x)
    3850#endif
    3951
    40 /* For local finer debugging control: */
    41 #define DPRINTF_INFOX(x)    dprintf x
    42 #define DPRINTF_INFOZ(x)
    4352
    4453/* driver specific definitions */
    4554
     
    4958#define MY_ERR  "\033[31merror:\033[m "
    5059#define MY_WARN "\033[31mwarning:\033[m "
    5160#define assert(x) \
    52     ((x) ? 0 : dprintf(MY_ID "assertion failed at " __FILE__ ", line %d\n", __LINE__))
     61    ((x) ? 0 : dprintf(MY_ID "assertion failed at " \
     62     __FILE__ ", line %d\n", __LINE__))
    5363
    5464#define DEFAULT_CONFIGURATION   0
    5565
     
    5868
    5969typedef struct usbmidi_device_info
    6070{
    61     /* list structure */
     71    /* list structure */ /* should not be needed eventually */
    6272    struct usbmidi_device_info* next;
    6373
    64     /* maintain device */
     74    /* Set of actual ports ("cables" -- one or more) */
     75    struct usbmidi_port_info* ports[16];
     76
     77    /* maintain device  (common for all ports) */
    6578    sem_id sem_lock;
    6679    sem_id sem_send;
    6780    area_id buffer_area;
    6881    usb_midi_event_packet* buffer;  /* input buffer & base of area */
    69     usb_midi_event_packet* out_buffer;  /* above input buff */
     82    usb_midi_event_packet* out_buffer;  /* above input buffer */
     83    size_t buffer_size;     /* for each of in and out buffers */
    7084   
    7185    const usb_device* dev;
    7286    uint16 ifno;
    73     char name[30];
     87    int devnum; /* unique device number */
     88    char name[20];
     89        /* = "/dev/midi/usb/n" --port number will be appended to this */
    7490   
    75     struct ring_buffer* rbuf;
    76 
    7791    bool active;
    78     int open;
    79     struct driver_cookie* open_fd;
    8092
    8193    /* work area for transfer */
    82     int usbd_status, bus_status, cmd_status;
     94    int bus_status;
    8395    int actual_length;
    8496    const usb_endpoint_info* ept_in;
    8597    const usb_endpoint_info* ept_out;
    8698
    87     size_t buffer_size;
    88     bigtime_t timestamp;
    89     uint flags;
     99    bigtime_t timestamp;    /* Is this needed? Currently set but never read */
     100    uint flags;             /* set to 0 but never used */
    90101} usbmidi_device_info;
    91102
    92103
    93 /* usb_midi.c */
     104typedef struct usbmidi_port_info
     105{
     106    /* list structure for manager */
     107    struct usbmidi_port_info* next;
    94108
     109    /* Common device that does the work */
     110    usbmidi_device_info* device;
     111   
     112    /* Port-specific variables */
     113    char name[40];  /* complete pathname of this port */
     114    struct ring_buffer* rbuf;
     115   
     116    int cable;  /* index of this port */
     117    bool has_in, has_out;
     118
     119    int open;
     120    struct driver_cookie* open_fd;
     121
     122} usbmidi_port_info;
     123
     124
     125/*
     126 usb_midi.c
     127*/
     128
    95129extern usb_module_info* usb;
    96130extern const char* usb_midi_base_name;
    97131
     132usbmidi_port_info*
     133create_usbmidi_port(usbmidi_device_info* devinfo,
     134    int cable, bool has_in, bool has_out);
     135
     136void
     137remove_port(usbmidi_port_info* port);
     138
    98139usbmidi_device_info*
    99 create_device(const usb_device* dev, const usb_interface_info* ii, uint16 ifno);
     140create_device(const usb_device* dev, uint16 ifno);
     141    /*  ifno not actually used -- left in for now */
    100142
    101143void
    102144remove_device(usbmidi_device_info* my_dev);
    103145
    104146
    105 /* devlist.c */
     147/*
     148 devlist.c
     149*/
    106150
    107 extern sem_id usbmidi_device_list_lock;
    108 extern bool usbmidi_device_list_changed;
     151extern sem_id usbmidi_port_list_lock;
     152extern bool usbmidi_port_list_changed;
    109153
    110 void add_device_info(usbmidi_device_info* my_dev);
    111 void remove_device_info(usbmidi_device_info* my_dev);
    112 usbmidi_device_info* search_device_info(const char* name);
     154void
     155add_port_info(usbmidi_port_info* port);
    113156
    114 extern char** usbmidi_device_names;
     157void
     158remove_port_info(usbmidi_port_info* port);
    115159
    116 void alloc_device_names(void);
    117 void free_device_names(void);
    118 void rebuild_device_names(void);
     160usbmidi_port_info*
     161search_port_info(const char* name);
     162
     163int
     164find_free_device_number(void);
     165
     166extern char** usbmidi_port_names;
     167
     168void
     169alloc_port_names(void);
     170
     171void
     172free_port_names(void);
     173
     174void
     175rebuild_port_names(void);
  • src/add-ons/kernel/drivers/midi/usb_midi/devlist.c

     
    22 * midi usb driver
    33 * devlist.c
    44 *
    5  * Copyright 2006-2009 Haiku Inc.  All rights reserved.
     5 * Copyright 2006-2011 Haiku Inc.  All rights reserved.
    66 * Distributed under the terms of the MIT Licence.
    77 *
    88 * Authors:
     
    2323#include <string.h>
    2424
    2525
    26 sem_id          usbmidi_device_list_lock = -1;
    27 bool            usbmidi_device_list_changed = true; /* added or removed */
     26sem_id          usbmidi_port_list_lock = -1;
     27bool            usbmidi_port_list_changed = true;   /* added or removed */
    2828
    29 static usbmidi_device_info* usbmidi_device_list = NULL;
    30 static int      usbmidi_device_count = 0;
     29static usbmidi_port_info*   usbmidi_port_list = NULL;
     30static int      usbmidi_port_count = 0;
    3131
    3232
    3333void
    34 add_device_info(usbmidi_device_info* my_dev)
     34add_port_info(usbmidi_port_info* port)
    3535{
    36     assert(my_dev != NULL);
    37     acquire_sem(usbmidi_device_list_lock);
    38     my_dev->next = usbmidi_device_list;
    39     usbmidi_device_list = my_dev;
    40     usbmidi_device_count++;
    41     usbmidi_device_list_changed = true;
    42     release_sem(usbmidi_device_list_lock);
     36    assert(port != NULL);
     37    acquire_sem(usbmidi_port_list_lock);
     38    port->next = usbmidi_port_list;
     39    usbmidi_port_list = port;
     40    usbmidi_port_count++;
     41    usbmidi_port_list_changed = true;
     42    release_sem(usbmidi_port_list_lock);
    4343}
    4444
    4545
    4646void
    47 remove_device_info(usbmidi_device_info* my_dev)
     47remove_port_info(usbmidi_port_info* port)
    4848{
    49     assert(my_dev != NULL);
    50     acquire_sem(usbmidi_device_list_lock);
    51     if (usbmidi_device_list == my_dev) {
    52         usbmidi_device_list = my_dev->next;
    53         --usbmidi_device_count;
    54         usbmidi_device_list_changed = true;     
     49    assert(port != NULL);
     50    acquire_sem(usbmidi_port_list_lock);
     51    if (usbmidi_port_list == port) {
     52        usbmidi_port_list = port->next;
     53        --usbmidi_port_count;
     54        usbmidi_port_list_changed = true;       
    5555    } else {
    56         usbmidi_device_info* d;
    57         for (d = usbmidi_device_list; d != NULL; d = d->next) {
    58             if (d->next == my_dev) {
    59                 d->next = my_dev->next;
    60                 --usbmidi_device_count;
    61                 usbmidi_device_list_changed = true;
     56        usbmidi_port_info* d;
     57        for (d = usbmidi_port_list; d != NULL; d = d->next) {
     58            if (d->next == port) {
     59                d->next = port->next;
     60                --usbmidi_port_count;
     61                usbmidi_port_list_changed = true;
    6262                break;
    6363            }
    6464        }
    6565        assert(d != NULL);
    6666    }
    67     release_sem(usbmidi_device_list_lock);
     67    release_sem(usbmidi_port_list_lock);
    6868}
    6969
    7070
    71 usbmidi_device_info*
    72 search_device_info(const char* name)
     71usbmidi_port_info*
     72search_port_info(const char* name)
    7373{
    74     usbmidi_device_info* my_dev;
     74    usbmidi_port_info* port;
    7575
    76     acquire_sem(usbmidi_device_list_lock);
    77     for (my_dev = usbmidi_device_list; my_dev != NULL; my_dev = my_dev->next) {
    78         if (strcmp(my_dev->name, name) == 0)
     76    acquire_sem(usbmidi_port_list_lock);
     77    for (port = usbmidi_port_list; port != NULL; port = port->next) {
     78        if (strcmp(port->name, name) == 0)
    7979            break;
    8080    }
    81     release_sem(usbmidi_device_list_lock);
    82     return my_dev;
     81    release_sem(usbmidi_port_list_lock);
     82    return port;
    8383}
    8484
     85int
     86find_free_device_number(void)
     87{
     88    usbmidi_port_info* port;
     89    int number = 0;
    8590
     91    acquire_sem(usbmidi_port_list_lock);
     92    do {
     93        for (port = usbmidi_port_list; port != NULL; port = port->next) {
     94            if (port->device->devnum == number) {
     95                number++;
     96                break;  /* try next higher */
     97            }
     98        }
     99    } while (port);
     100    release_sem(usbmidi_port_list_lock);
     101    return number;
     102}
     103
     104
     105
    86106/*
    87107    device names
    88108*/
    89109
    90110/* dynamically generated */
    91 char** usbmidi_device_names = NULL;
     111char** usbmidi_port_names = NULL;
    92112
    93113
    94114void
    95 alloc_device_names(void)
     115alloc_port_names(void)
    96116{
    97     assert(usbmidi_device_names == NULL);
    98     usbmidi_device_names = malloc(sizeof(char*) * (usbmidi_device_count + 1));
     117    assert(usbmidi_port_names == NULL);
     118    usbmidi_port_names = malloc(sizeof(char*) * (usbmidi_port_count + 1));
    99119}
    100120
    101121
    102122void
    103 free_device_names(void)
     123free_port_names(void)
    104124{
    105     if (usbmidi_device_names != NULL) {
     125    if (usbmidi_port_names != NULL) {
    106126        int i;
    107         for (i = 0; usbmidi_device_names[i] != NULL; i++)
    108             free(usbmidi_device_names[i]);
    109         free(usbmidi_device_names);
    110         usbmidi_device_names = NULL;
     127        for (i = 0; usbmidi_port_names[i] != NULL; i++)
     128            free(usbmidi_port_names[i]);
     129        free(usbmidi_port_names);
     130        usbmidi_port_names = NULL;
    111131    }
    112132}
    113133
    114134
    115135void
    116 rebuild_device_names(void)
     136rebuild_port_names(void)
    117137{
    118138    int i;
    119     usbmidi_device_info* my_dev;
     139    usbmidi_port_info* port;
    120140
    121     assert(usbmidi_device_names != NULL);
    122     acquire_sem(usbmidi_device_list_lock);
    123     for (i = 0, my_dev = usbmidi_device_list; my_dev != NULL; my_dev = my_dev->next) {
    124         usbmidi_device_names[i++] = strdup(my_dev->name);
    125         DPRINTF_INFO((MY_ID "publishing %s\n", my_dev->name));
     141    assert(usbmidi_port_names != NULL);
     142    acquire_sem(usbmidi_port_list_lock);
     143    for (i = 0, port = usbmidi_port_list; port != NULL; port = port->next) {
     144        usbmidi_port_names[i++] = strdup(port->name);
     145        DPRINTF_INFO((MY_ID "publishing %s\n", port->name));
    126146    }
    127     usbmidi_device_names[i] = NULL;
    128     release_sem(usbmidi_device_list_lock);
     147    usbmidi_port_names[i] = NULL;
     148    release_sem(usbmidi_port_list_lock);
    129149}
  • src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.c

     
    22 * midi usb driver
    33 * usb_midi.c
    44 *
    5  * Copyright 2006-2009 Haiku Inc.  All rights reserved.
     5 * Copyright 2006-2011 Haiku Inc.  All rights reserved.
    66 * Distributed under the terms of the MIT Licence.
    77 *
    88 * Authors:
     
    1717 */
    1818
    1919
    20 /* #define DEBUG 1 */   /* Define this to enable DPRINTF_INFO statements */
     20/* #define DEBUG 1 */   /* Define this to enable DPRINTF_DEBUG statements */
     21/* (Other categories of printout set in usb_midi.h) */
     22
    2123#include "usb_midi.h"
    2224
    2325#include <stdio.h>
     
    2527#include <string.h>
    2628#include <unistd.h>
    2729
    28 #include "usbdevs.h"
    29 #include "usbdevs_data.h"
    3030
    31 
    32 static int midi_device_number = 0;
    3331const char* midi_base_name = "midi/usb/";
    3432
     33
     34usbmidi_port_info*
     35create_usbmidi_port(usbmidi_device_info* devinfo,
     36    int cable, bool has_in, bool has_out)
     37{
     38    usbmidi_port_info* port = NULL;
     39    assert(usb != NULL && devinfo != NULL);
     40
     41    port = malloc(sizeof(usbmidi_port_info));
     42    if (port == NULL)
     43        return NULL;
     44
     45    sprintf(port->name, "%s-%d", devinfo->name, cable);
     46    port->device = devinfo;
     47    port->cable = cable;
     48    port->next = NULL;
     49    port->open = 0;
     50    port->open_fd = NULL;
     51    port->has_in = has_in;
     52    port->has_out = has_out;
     53    port->rbuf = create_ring_buffer(1024);
     54   
     55    devinfo->ports[cable] = port;
     56   
     57    DPRINTF_INFO((MY_ID "Created port %p cable %d: %s\n",
     58        port, cable, port->name));
     59
     60    return port;
     61}
     62
     63void
     64remove_port(usbmidi_port_info* port)
     65{
     66    assert(port != NULL);
     67    if (port->rbuf != NULL) {
     68        delete_ring_buffer(port->rbuf);
     69        port->rbuf = NULL;
     70    }
     71    DPRINTF_INFO((MY_ID "remove_port %p done\n", port));
     72 
     73    free(port);
     74}
     75
     76
    3577usbmidi_device_info*
    36 create_device(const usb_device* dev, const usb_interface_info* ii, uint16 ifno)
     78create_device(const usb_device* dev, uint16 ifno)
    3779{
    38     usbmidi_device_info* my_dev = NULL;
     80    usbmidi_device_info* midiDevice = NULL;
    3981    int number;
    4082    area_id area;
    4183    sem_id sem;
    4284    char    area_name[32];
    43     const char* base_name;
    4485   
    4586    assert(usb != NULL && dev != NULL);
    4687
    47     number = midi_device_number++;
    48     base_name = midi_base_name;
     88    number = find_free_device_number();
    4989       
    50     my_dev = malloc(sizeof(usbmidi_device_info));
    51     if (my_dev == NULL)
     90    midiDevice = malloc(sizeof(usbmidi_device_info));
     91    if (midiDevice == NULL)
    5292        return NULL;
    5393
    54     my_dev->sem_lock = sem = create_sem(1, DRIVER_NAME "_lock");
     94    midiDevice->sem_lock = sem = create_sem(1, DRIVER_NAME "_lock");
    5595    if (sem < 0) {
    5696        DPRINTF_ERR((MY_ID "create_sem() failed %d\n", (int)sem));
    57         free(my_dev);
     97        free(midiDevice);
    5898        return NULL;
    5999    }
    60100
    61101    sprintf(area_name, DRIVER_NAME "_buffer%d", number);
    62     my_dev->buffer_area = area = create_area(area_name,
    63         (void**)&my_dev->buffer, B_ANY_KERNEL_ADDRESS,
     102    midiDevice->buffer_area = area = create_area(area_name,
     103        (void**)&midiDevice->buffer, B_ANY_KERNEL_ADDRESS,
    64104        B_PAGE_SIZE, B_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA);
    65105    if (area < 0) {
    66106        DPRINTF_ERR((MY_ID "create_area() failed %d\n", (int)area));
    67         delete_sem(my_dev->sem_lock);
    68         free(my_dev);
     107        delete_sem(midiDevice->sem_lock);
     108        free(midiDevice);
    69109        return NULL;
    70110    }
    71111    /* use half of reserved area for each of in and out buffers: */
    72     my_dev->out_buffer = (usb_midi_event_packet*)((uint8*)my_dev->buffer + B_PAGE_SIZE/2);
    73     my_dev->sem_send =  sem = create_sem(1, DRIVER_NAME "_send");
     112    midiDevice->out_buffer
     113        = (usb_midi_event_packet*)((uint8*)midiDevice->buffer + B_PAGE_SIZE/2);
     114    midiDevice->sem_send =  sem = create_sem(1, DRIVER_NAME "_send");
    74115    if (sem < 0) {
    75116        DPRINTF_ERR((MY_ID "create_sem() failed %d\n", (int)sem));
    76         delete_sem(my_dev->sem_lock);
     117        delete_sem(midiDevice->sem_lock);
    77118        delete_area(area);
    78         free(my_dev);
     119        free(midiDevice);
    79120        return NULL;
    80121    }
    81122    {
    82123        int32 bc;
    83124        get_sem_count(sem, &bc);
    84         DPRINTF_INFO((MY_ID "Allocated %ld write buffers\n", bc));
     125        DPRINTF_DEBUG((MY_ID "Allocated %ld write buffers\n", bc));
    85126    }
    86127
    87128
    88     sprintf(my_dev->name, "%s%d", base_name, number);
    89     my_dev->dev = dev;
    90     my_dev->ifno = ifno;
    91     my_dev->open = 0;
    92     my_dev->open_fd = NULL;
    93     my_dev->active = true;
    94     my_dev->flags = 0;
    95     my_dev->rbuf = create_ring_buffer(1024);
    96     my_dev->buffer_size = B_PAGE_SIZE/2;
    97     DPRINTF_INFO((MY_ID "Created device %p\n", my_dev);)
     129    sprintf(midiDevice->name, "%s%d", midi_base_name, number);
     130    midiDevice->dev = dev;
     131    midiDevice->devnum = number;
     132    midiDevice->ifno = ifno;
     133    midiDevice->active = true;
     134    midiDevice->flags = 0;
     135    memset(midiDevice->ports, 0, sizeof(midiDevice->ports));
     136    midiDevice->buffer_size = B_PAGE_SIZE/2;
     137    DPRINTF_INFO((MY_ID "Created device %p\n", midiDevice));
    98138       
    99     return my_dev;
     139    return midiDevice;
    100140}
    101141
    102142
    103143void
    104 remove_device(usbmidi_device_info* my_dev)
     144remove_device(usbmidi_device_info* midiDevice)
    105145{
    106     assert(my_dev != NULL);
    107     if (my_dev->rbuf != NULL) {
    108         delete_ring_buffer(my_dev->rbuf);
    109         my_dev->rbuf = NULL;
    110     }
    111     DPRINTF_INFO((MY_ID "remove_device %p\n", my_dev);)
     146    assert(midiDevice != NULL);
     147    DPRINTF_INFO((MY_ID "remove_device %p\n", midiDevice));
    112148 
    113     delete_area(my_dev->buffer_area);
    114     delete_sem(my_dev->sem_lock);
    115     delete_sem(my_dev->sem_send);
    116     free(my_dev);
     149    delete_area(midiDevice->buffer_area);
     150    delete_sem(midiDevice->sem_lock);
     151    delete_sem(midiDevice->sem_send);
     152    free(midiDevice);
    117153}
    118154
    119155
    120 /* driver cookie (per open -- but only one open allowed!) */
     156/* driver cookie (per open -- but only one open per port allowed!) */
    121157
    122158typedef struct driver_cookie
    123159{
    124     struct driver_cookie    *next;
    125     usbmidi_device_info         *my_dev;
     160    struct driver_cookie*   next;
     161    usbmidi_device_info*    device; /* a bit redundant, but convenient */
     162    usbmidi_port_info*      port;
    126163    sem_id sem_cb;
    127164} driver_cookie;
    128165
     
    156193
    157194
    158195static void
    159 interpret_midi_buffer(usbmidi_device_info* my_dev)
     196interpret_midi_buffer(usbmidi_device_info* midiDevice)
    160197{
    161     usb_midi_event_packet* packet = my_dev->buffer;
    162     size_t bytes_left = my_dev->actual_length;
     198    usb_midi_event_packet* packet = midiDevice->buffer;
     199    size_t bytes_left = midiDevice->actual_length;
    163200    while (bytes_left) {    /* buffer may have several packets */
    164201        int pktlen = CINbytes[packet->cin];
    165         DPRINTF_INFO((MY_ID "received packet %x:%d %x %x %x\n", packet->cin, packet->cn,
     202        usbmidi_port_info* port = midiDevice->ports[packet->cn];
     203            /* port matching 'cable' */
     204        DPRINTF_DEBUG((MY_ID "received packet %x:%d %x %x %x\n",
     205            packet->cin, packet->cn,
    166206            packet->midi[0], packet->midi[1], packet->midi[2]));
    167         ring_buffer_write(my_dev->rbuf, packet->midi, pktlen);
    168         release_sem_etc(my_dev->open_fd->sem_cb, pktlen, B_DO_NOT_RESCHEDULE);
     207        ring_buffer_write(port->rbuf, packet->midi, pktlen);
     208        release_sem_etc(port->open_fd->sem_cb, pktlen, B_DO_NOT_RESCHEDULE);
    169209        packet++;
    170210        bytes_left -= sizeof(usb_midi_event_packet);
    171211    }
     
    181221    void* data, size_t actual_len)
    182222{
    183223    status_t st;
    184     usbmidi_device_info* my_dev = cookie;
     224    usbmidi_device_info* midiDevice = cookie;
    185225
    186226    assert(cookie != NULL);
    187     DPRINTF_INFO((MY_ID "midi_usb_read_callback() -- packet length %ld\n", actual_len));
     227    DPRINTF_DEBUG((MY_ID "midi_usb_read_callback() -- packet length %ld\n",
     228        actual_len));
    188229
    189     acquire_sem(my_dev->sem_lock);
    190     my_dev->actual_length = actual_len;
    191     my_dev->bus_status = status;    /* B_USB_STATUS_* */
     230    acquire_sem(midiDevice->sem_lock);
     231    midiDevice->actual_length = actual_len;
     232    midiDevice->bus_status = status;    /* B_USB_STATUS_* */
    192233    if (status != B_OK) {
    193234        /* request failed */
    194         DPRINTF_INFO((MY_ID "bus status %d\n", (int)status)); /* previously DPRINTF_ERR */
    195         if (status == B_CANCELED || !my_dev->active) {
     235        DPRINTF_DEBUG((MY_ID "bus status %d\n", (int)status));
     236        if (status == B_CANCELED || !midiDevice->active) {
    196237            /* cancelled: device is unplugged */
    197             DPRINTF_INFO((MY_ID "midi_usb_read_callback: cancelled (status=%lx active=%d -- deleting sem_cb\n",
    198                 status, my_dev->active));
    199             delete_sem(my_dev->open_fd->sem_cb);    /* done here to ensure read is freed */
    200             release_sem(my_dev->sem_lock);
     238            usbmidi_port_info** port = midiDevice->ports;
     239            DPRINTF_DEBUG((MY_ID "midi_usb_read_callback: cancelled"
     240                "(status=%lx active=%d -- deleting sem_cbs\n",
     241                status, midiDevice->active));
     242            while (*port) {
     243                delete_sem((*port)->open_fd->sem_cb);
     244                    /* done here to ensure read is freed */
     245                port++;
     246            }
     247            release_sem(midiDevice->sem_lock);
    201248            return;
    202249        }
    203         release_sem(my_dev->sem_lock);
     250        release_sem(midiDevice->sem_lock);
    204251    } else {
    205252        /* got a report */
    206 #if 0
    207         uint32 i;
    208         char linbuf[256];
    209         uint8* buffer = my_dev->buffer;
     253        midiDevice->timestamp = system_time();  /* not used... */
    210254
    211         for (i = 0; i < 4; i++)
    212             sprintf=&linbuf[i*3], "%02X ", buffer[i]);
    213         DPRINTF_INFO((MY_ID "report: %s\n", linbuf));
    214 #endif
    215         my_dev->timestamp = system_time();
    216 
    217         interpret_midi_buffer(my_dev);
    218         release_sem(my_dev->sem_lock);
     255        interpret_midi_buffer(midiDevice);
     256        release_sem(midiDevice->sem_lock);
    219257    }
    220258
    221259    /* issue next request */
    222 
    223     st = usb->queue_bulk(my_dev->ept_in->handle, my_dev->buffer,
    224         my_dev->buffer_size, (usb_callback_func)midi_usb_read_callback, my_dev);
     260    st = usb->queue_bulk(midiDevice->ept_in->handle,
     261            midiDevice->buffer, midiDevice->buffer_size,
     262            (usb_callback_func)midi_usb_read_callback, midiDevice);
    225263    if (st != B_OK) {
    226         /* XXX probably endpoint stall */
     264        /* probably endpoint stall */
    227265        DPRINTF_ERR((MY_ID "queue_bulk() error %d\n", (int)st));
    228266    }
    229267}
     
    233271midi_usb_write_callback(void* cookie, status_t status,
    234272    void* data, size_t actual_len)
    235273{
    236     usbmidi_device_info* my_dev = cookie;
     274    usbmidi_device_info* midiDevice = cookie;
    237275#ifdef DEBUG
    238276    usb_midi_event_packet* pkt = data;
    239277#endif
    240278
    241279    assert(cookie != NULL);
    242     DPRINTF_INFO((MY_ID "midi_usb_write_callback() status %ld length %ld  pkt %p cin %x\n",
     280    DPRINTF_DEBUG((MY_ID "midi_usb_write_callback()"
     281        " status %ld length %ld  pkt %p cin %x\n",
    243282        status, actual_len, pkt, pkt->cin));
    244     release_sem(my_dev->sem_send); /* done with buffer */
     283    release_sem(midiDevice->sem_send); /* done with buffer */
    245284}
    246285
    247286
     
    252291static status_t
    253292usb_midi_added(const usb_device* dev, void** cookie)
    254293{
    255     usbmidi_device_info* my_dev;
     294    usbmidi_device_info* midiDevice;
     295    usbmidi_port_info* port;
    256296    const usb_device_descriptor* dev_desc;
    257297    const usb_configuration_info* conf;
    258298    const usb_interface_info* intf;
     
    260300    uint16 ifno, i;
    261301    int alt;
    262302   
     303    /* This seems overcomplicated, but endpoints can be in either order...
     304    and could possibly have different number of connectors! */
     305    int in_cables = 0, out_cables = 0;
     306    int cable_count[2] = {0, 0};
     307    int iep = 0;
     308   
    263309    assert(dev != NULL && cookie != NULL);
    264310    DPRINTF_INFO((MY_ID "usb_midi_added(%p, %p)\n", dev, cookie));
    265311
     
    267313
    268314    DPRINTF_INFO((MY_ID "vendor ID 0x%04X, product ID 0x%04X\n",
    269315        dev_desc->vendor_id, dev_desc->product_id));
    270 
     316       
    271317    /* check interface class */
    272318
    273     if ((conf = usb->get_nth_configuration(dev, DEFAULT_CONFIGURATION)) == NULL) {
     319    if ((conf = usb->get_nth_configuration(dev, DEFAULT_CONFIGURATION))
     320        == NULL) {
    274321        DPRINTF_ERR((MY_ID "cannot get default configuration\n"));
    275322        return B_ERROR;
    276323    }
     324    DPRINTF_INFO((MY_ID "Interface count = %ld\n", conf->interface_count));
    277325
    278326    for (ifno = 0; ifno < conf->interface_count; ifno++) {
    279         /* This is C; I can use "class" :-> */
    280         int class, subclass, protocol;
     327        int devclass, subclass, protocol;
    281328
    282329        for (alt = 0; alt < conf->interface[ifno].alt_count; alt++) {
    283330            intf = &conf->interface[ifno].alt[alt];
    284             class    = intf->descr->interface_class;
     331            devclass    = intf->descr->interface_class;
    285332            subclass = intf->descr->interface_subclass;
    286333            protocol = intf->descr->interface_protocol;
    287             DPRINTF_INFO((MY_ID "interface %d, alt : %d: class %d, subclass %d, protocol %d\n",
    288                             ifno, alt, class, subclass, protocol));
     334            DPRINTF_INFO((
     335                MY_ID "interface %d, alt : %d: class %d,"
     336                " subclass %d, protocol %d\n",
     337                ifno, alt, devclass, subclass, protocol));
    289338                           
    290             if (class == USB_AUDIO_DEVICE_CLASS
     339            if (devclass == USB_AUDIO_DEVICE_CLASS
    291340                && subclass == USB_AUDIO_INTERFACE_MIDISTREAMING_SUBCLASS)
    292341                goto got_one;
    293342        }       
     
    298347   
    299348got_one:
    300349
    301     for (i=0; i < sizeof(usb_knowndevs)/sizeof(struct usb_knowndev); i++) {
    302         if (usb_knowndevs[i].vendor == dev_desc->vendor_id
    303             && usb_knowndevs[i].product == dev_desc->product_id) {
    304             DPRINTF_INFO((MY_ID "vendor %s, product %s\n",
    305                 usb_knowndevs[i].vendorname, usb_knowndevs[i].productname));
    306         }
    307     }
    308 
    309        
    310     /* configuration */
    311350    if ((st = usb->set_configuration(dev, conf)) != B_OK) {
    312351        DPRINTF_ERR((MY_ID "set_configuration() failed %d\n", (int)st));
    313352        return B_ERROR;
    314353    }
    315354
    316     if ((my_dev = create_device(dev, intf, ifno)) == NULL) {
     355    if ((midiDevice = create_device(dev, ifno)) == NULL) {
    317356        return B_ERROR;
    318357    }
     358
     359    /* get the actual number of  ports in and out */   
     360    for (i = 0; i < intf->generic_count; i++) {
     361        usb_generic_descriptor *generic = &intf->generic[i]->generic;
     362        DPRINTF_DEBUG((MY_ID "descriptor %d: type %x sub %x\n",
     363            i, generic->descriptor_type, generic->data[0]));
     364        if (generic->descriptor_type == USB_DESCRIPTOR_CS_ENDPOINT
     365            && generic->data[0] == USB_MS_GENERAL_DESCRIPTOR) {
     366            /* These *better* be in the same order as the endpoints! */
     367            cable_count[iep] = generic->data[1];
     368            iep = 1;
     369        }
     370    }
     371
     372    DPRINTF_DEBUG((MY_ID "midiDevice = %p endpoint count = %ld\n",
     373        midiDevice, intf->endpoint_count));
     374    midiDevice->ept_in = midiDevice->ept_out = NULL;
    319375   
    320     DPRINTF_INFO((MY_ID "my_dev = %p endpoint count = %ld\n",
    321         my_dev, intf->endpoint_count));
    322     DPRINTF_INFO((MY_ID " input endpoint = %p\n",
    323         &intf->endpoint[0]));
    324     DPRINTF_INFO((MY_ID " output endpoint = %p\n",
    325         &intf->endpoint[1]));
    326     usb->clear_feature(intf->endpoint[0].handle, USB_FEATURE_ENDPOINT_HALT);
    327     /* This may need more thought...  */
    328     my_dev->ept_in = &intf->endpoint[0];        /* bulk IN */
    329     my_dev->ept_out = &intf->endpoint[1];       /* OUT */
     376    for (i=0; i < intf->endpoint_count && i < 2; i++) {
     377        /* we are actually assuming max one IN, one OUT endpoint... */
     378        DPRINTF_INFO((MY_ID "endpoint %d = %p  %s\n",
     379            i, &intf->endpoint[i],
     380            (intf->endpoint[i].descr->endpoint_address & 0x80) != 0
     381             ? "IN" : "OUT"));
     382        if ((intf->endpoint[i].descr->endpoint_address & 0x80) != 0) {
     383            if (midiDevice->ept_in == NULL) {
     384                midiDevice->ept_in = &intf->endpoint[i];
     385                in_cables = cable_count[i];
     386            }
     387        } else if (midiDevice->ept_out == NULL) {
     388            midiDevice->ept_out = &intf->endpoint[i];
     389            out_cables = cable_count[i];
     390        }
     391    }
    330392   
    331     my_dev->timestamp = system_time();
     393    midiDevice->timestamp = system_time();  /* This never seems to be used */
    332394
     395    /* Create the actual device ports */
     396    for (i=0; in_cables || out_cables; i++) {
     397        port = create_usbmidi_port(midiDevice, i,
     398            (bool)in_cables, (bool)out_cables);
     399        midiDevice->ports[i] = port;
     400        if (in_cables) in_cables--;
     401        if (out_cables) out_cables--;
     402        add_port_info(port);
     403    }
     404   
    333405    /* issue bulk transfer */
    334     DPRINTF_INFO((MY_ID "queueing bulk xfer ep 0\n"));
    335     st = usb->queue_bulk(my_dev->ept_in->handle, my_dev->buffer,
    336         my_dev->buffer_size, (usb_callback_func)midi_usb_read_callback, my_dev);
     406    DPRINTF_DEBUG((MY_ID "queueing bulk xfer IN endpoint\n"));
     407    st = usb->queue_bulk(midiDevice->ept_in->handle, midiDevice->buffer,
     408        midiDevice->buffer_size,
     409        (usb_callback_func)midi_usb_read_callback, midiDevice);
    337410    if (st != B_OK) {
    338411        DPRINTF_ERR((MY_ID "queue_bulk() error %d\n", (int)st));
    339412        return B_ERROR;
    340413    }
    341414
    342     /* create a port */
    343     add_device_info(my_dev);
    344415
    345     *cookie = my_dev;
    346     DPRINTF_INFO((MY_ID "usb_midi_added: added %s\n", my_dev->name));
     416    *cookie = midiDevice;
     417    DPRINTF_INFO((MY_ID "usb_midi_added: %s\n", midiDevice->name));
    347418
    348419    return B_OK;
    349420}
     
    352423static status_t
    353424usb_midi_removed(void* cookie)
    354425{
    355     usbmidi_device_info* my_dev = cookie;
     426    usbmidi_device_info* midiDevice = cookie;
     427    int cable;
    356428
    357429    assert(cookie != NULL);
    358430
    359     DPRINTF_INFO((MY_ID "usb_midi_removed(%s)\n", my_dev->name));
    360     acquire_sem(usbmidi_device_list_lock);  /* convenient mutex for safety */
    361     my_dev->active = false;
    362     if (my_dev->open_fd) {
    363         my_dev->open_fd->my_dev = NULL;
    364         delete_sem(my_dev->open_fd->sem_cb);    /* done here to ensure read is freed */
     431    DPRINTF_INFO((MY_ID "usb_midi_removed(%s)\n", midiDevice->name));
     432    midiDevice->active = false;
     433    for (cable=0; cable < 16; cable++) {
     434        usbmidi_port_info* port = midiDevice->ports[cable];
     435        DPRINTF_DEBUG((MY_ID "removing port %d\n", cable));
     436        if (!port) break;
     437        if (port->open_fd) {
     438            remove_port_info(port);
     439            port->open_fd->port = NULL;
     440            port->open_fd->device = NULL;
     441            delete_sem(port->open_fd->sem_cb);
     442                /* done here to ensure read is freed */
     443        }
     444        remove_port(port);
    365445    }
    366     release_sem(usbmidi_device_list_lock);
    367     usb->cancel_queued_transfers(my_dev->ept_in->handle);
    368     usb->cancel_queued_transfers(my_dev->ept_out->handle);
    369     DPRINTF_INFO((MY_ID "usb_midi_removed: removing info & device: %s\n", my_dev->name));
    370     remove_device_info(my_dev);
    371     remove_device(my_dev);
     446    usb->cancel_queued_transfers(midiDevice->ept_in->handle);
     447    usb->cancel_queued_transfers(midiDevice->ept_out->handle);
     448    DPRINTF_DEBUG((MY_ID "usb_midi_removed: doing remove: %s\n",
     449        midiDevice->name));
     450    remove_device(midiDevice);
    372451    return B_OK;
    373452}
    374453
     
    381460#define SUPPORTED_DEVICES   1
    382461usb_support_descriptor my_supported_devices[SUPPORTED_DEVICES] =
    383462{
    384     { USB_AUDIO_DEVICE_CLASS, USB_AUDIO_INTERFACE_MIDISTREAMING_SUBCLASS, 0, 0, 0 },
     463    {
     464        USB_AUDIO_DEVICE_CLASS,
     465        USB_AUDIO_INTERFACE_MIDISTREAMING_SUBCLASS,
     466        0, 0, 0
     467    },
    385468};
    386469
    387470
    388471/*
    389     usb_midi_open - handle open() calls
     472    Device Driver Hook Functions
     473    -- open, read, write, close, and free
    390474 */
    391475
    392476static status_t
     
    394478    driver_cookie** out_cookie)
    395479{
    396480    driver_cookie* cookie;
    397     usbmidi_device_info* my_dev;
     481    usbmidi_port_info* port;
     482    int mode = flags & O_RWMASK;
    398483
    399484    assert(name != NULL);
    400485    assert(out_cookie != NULL);
    401     DPRINTF_INFO((MY_ID "usb_midi_open(%s)\n", name));
     486    DPRINTF_INFO((MY_ID "usb_midi_open(%s) flags=%lx\n", name, flags));
    402487
    403     if ((my_dev = search_device_info(name)) == NULL)
     488    if ((port = search_port_info(name)) == NULL)
    404489        return B_ENTRY_NOT_FOUND;
    405     if (my_dev->open_fd != NULL)
    406         return B_BUSY;  /* there can only be one open channel to the device */
     490
     491    if (!port->has_in && mode != O_RDONLY)
     492        return B_PERMISSION_DENIED;  /* == EACCES */
     493    else if (!port->has_out && mode != O_WRONLY)
     494        return B_PERMISSION_DENIED;
     495       
    407496    if ((cookie = malloc(sizeof(driver_cookie))) == NULL)
    408497        return B_NO_MEMORY;
    409498
     
    414503        return B_ERROR;
    415504    }
    416505
    417     acquire_sem(usbmidi_device_list_lock);  /* use global mutex now */
    418     cookie->my_dev = my_dev;
    419     my_dev->open_fd = cookie;
    420     my_dev->open++;
    421     release_sem(usbmidi_device_list_lock);
     506    cookie->port = port;
     507    cookie->device = port->device;
    422508
     509    acquire_sem(usbmidi_port_list_lock);
     510    if (port->open_fd != NULL) {
     511        /* there can only be one open channel to the device */
     512        delete_sem(cookie->sem_cb);
     513        free(cookie);
     514        release_sem(usbmidi_port_list_lock);
     515        return B_BUSY;
     516    }
     517    port->open_fd = cookie;
     518    port->open++;
     519    release_sem(usbmidi_port_list_lock);
     520
    423521    *out_cookie = cookie;
    424     DPRINTF_INFO((MY_ID "usb_midi_open: device %s open (%d)\n", name, my_dev->open));
     522    DPRINTF_INFO((MY_ID "usb_midi_open: device %s open (%d)\n",
     523        name, port->open));
    425524    return B_OK;
    426525}
    427526
    428527
    429 /*
    430     usb_midi_read - handle read() calls
    431  */
    432 
    433528static status_t
    434529usb_midi_read(driver_cookie* cookie, off_t position,
    435530    void* buf,  size_t* num_bytes)
    436531{
    437532    status_t err = B_ERROR;
    438     usbmidi_device_info* my_dev;
     533    usbmidi_port_info* port;
     534    usbmidi_device_info* midiDevice;
    439535
    440536    assert(cookie != NULL);
    441     my_dev = cookie->my_dev;
     537    port = cookie->port;
     538    midiDevice = cookie->device;
    442539   
    443     if (!my_dev || !my_dev->active)
     540    if (!midiDevice || !midiDevice->active)
    444541        return B_ERROR; /* already unplugged */
    445542       
    446     DPRINTF_INFO((MY_ID "usb_midi_read: (%ld byte buffer at %ld cookie %p)\n",
     543    DPRINTF_DEBUG((MY_ID "usb_midi_read: (%ld byte buffer at %ld cookie %p)\n",
    447544        *num_bytes, (int32)position, cookie));
    448     while (my_dev && my_dev->active) {
    449         DPRINTF_INFOZ((MY_ID "waiting on acquire_sem_etc\n");)
     545    while (midiDevice && midiDevice->active) {
     546        DPRINTF_DEBUG((MY_ID "waiting on acquire_sem_etc\n"));
    450547        err = acquire_sem_etc(cookie->sem_cb, 1,
    451548             B_RELATIVE_TIMEOUT, 1000000);
    452549        if (err == B_TIMED_OUT) {
    453             DPRINTF_INFOZ((MY_ID "acquire_sem_etc timed out\n");)
     550            DPRINTF_DEBUG((MY_ID "acquire_sem_etc timed out\n"));
    454551            continue;   /* see if we're still active */
    455552        }
    456553        if (err != B_OK) {
    457554            *num_bytes = 0;
    458             DPRINTF_INFO((MY_ID "acquire_sem_etc aborted\n");)
     555            DPRINTF_DEBUG((MY_ID "acquire_sem_etc aborted\n"));
    459556            break;
    460557        }
    461         DPRINTF_INFO((MY_ID "reading from ringbuffer\n");)
    462         acquire_sem(my_dev->sem_lock);
    463         ring_buffer_user_read(my_dev->rbuf, buf, 1);
    464         release_sem(my_dev->sem_lock);
     558        DPRINTF_DEBUG((MY_ID "reading from ringbuffer\n"));
     559        acquire_sem(midiDevice->sem_lock);
     560            /* a global semaphore -- OK, I think */
     561        ring_buffer_user_read(port->rbuf, buf, 1);
     562        release_sem(midiDevice->sem_lock);
    465563        *num_bytes = 1;
    466         DPRINTF_INFO((MY_ID "read byte %x -- cookie %p)\n", *(uint8*)buf, cookie));
     564        DPRINTF_DEBUG((MY_ID "read byte %x -- cookie %p)\n",
     565            *(uint8*)buf, cookie));
    467566        return B_OK;
    468567    }
    469     DPRINTF_INFO((MY_ID "usb_midi_read: loop terminated -- Device no longer active\n");)
     568    DPRINTF_INFO((MY_ID "usb_midi_read: loop terminated"
     569        " -- Device no longer active\n"));
    470570    return B_CANCELED;
    471571}
    472572
    473573
    474 /*
    475     usb_midi_write - handle write() calls
    476  */
    477 
    478574const uint8 CINcode[] = {   /* see USB-MIDI Spec */
    479575    0x4,    /* 0x0 - sysex start */
    480576    0,  /* 0x1 -- undefined */
     
    499595usb_midi_write(driver_cookie* cookie, off_t position,
    500596    const void* buf, size_t* num_bytes)
    501597{
    502     usbmidi_device_info* my_dev;
     598    usbmidi_port_info* port;
     599    usbmidi_device_info* midiDevice;
    503600    uint8* midiseq = (uint8*)buf;
    504601    uint8 midicode = midiseq[0];    /* preserved for reference */
    505602    status_t st;
     
    509606         : (midicode >> 4);
    510607
    511608    assert(cookie != NULL);
    512     my_dev = cookie->my_dev;
     609    port = cookie->port;
     610    midiDevice = cookie->device;
    513611
    514     if (!my_dev || !my_dev->active)
     612    if (!midiDevice || !midiDevice->active)
    515613        return B_ERROR;     /* already unplugged */
    516614       
    517     buff_lim = my_dev->buffer_size * 3 / 4; /* max MIDI bytes buffer space */
     615    buff_lim = midiDevice->buffer_size * 3 / 4;
     616        /* max MIDI bytes buffer space */
    518617   
    519     DPRINTF_INFO((MY_ID "MIDI write (%ld bytes at %Ld)\n", *num_bytes, position));
     618    DPRINTF_DEBUG((MY_ID "MIDI write (%ld bytes at %Ld)\n",
     619        *num_bytes, position));
    520620    if (*num_bytes > 3 && midicode != 0xF0) {
    521         DPRINTF_ERR((MY_ID "Non-SysEx packet of %ld bytes -- too big to handle\n",
    522             *num_bytes));
     621        DPRINTF_ERR((MY_ID "Non-SysEx packet of %ld bytes"
     622            " -- too big to handle\n", *num_bytes));
    523623        return B_ERROR;
    524624    }
    525625
    526626    while (bytes_left) {
    527         size_t xfer_bytes = (bytes_left < buff_lim)?  bytes_left : buff_lim;
    528         usb_midi_event_packet* pkt = my_dev->out_buffer;
     627        size_t xfer_bytes = (bytes_left < buff_lim) ?  bytes_left : buff_lim;
     628        usb_midi_event_packet* pkt = midiDevice->out_buffer;
    529629        int packet_count = 0;
    530630
    531         st = acquire_sem_etc(my_dev->sem_send, 1, B_RELATIVE_TIMEOUT, 2000000LL);
     631        st = acquire_sem_etc(midiDevice->sem_send,
     632            1, B_RELATIVE_TIMEOUT, 2000000LL);
    532633        if (st != B_OK)
    533634            return st;
    534635
     
    536637            uint8 pkt_bytes = CINbytes[cin];
    537638            memset(pkt, 0, sizeof(usb_midi_event_packet));
    538639            pkt->cin = cin;
    539             DPRINTF_INFO((MY_ID "using packet data (code %x -- %d bytes) %x %x %x\n", pkt->cin,
    540               CINbytes[pkt->cin], midiseq[0], midiseq[1], midiseq[2]));
     640            pkt->cn = port->cable;
     641            DPRINTF_DEBUG((MY_ID "using packet data (code %x -- %d bytes)"
     642                " %x %x %x\n", pkt->cin, CINbytes[pkt->cin],
     643                midiseq[0], midiseq[1], midiseq[2]));
    541644            memcpy(pkt->midi, midiseq, pkt_bytes);
    542             DPRINTF_INFO((MY_ID "built packet %p %x:%d %x %x %x\n", pkt, pkt->cin, pkt->cn,
     645            DPRINTF_DEBUG((MY_ID "built packet %p %x:%d %x %x %x\n",
     646                pkt, pkt->cin, pkt->cn,
    543647                pkt->midi[0], pkt->midi[1], pkt->midi[2]));
    544648            xfer_bytes -= pkt_bytes;
    545649            bytes_left -= pkt_bytes;
    546650            midiseq += pkt_bytes;
    547651            packet_count++;
    548652            pkt++;
    549             if (midicode == 0xF0 && bytes_left < 4) cin = 4 + bytes_left;   /* see USB-MIDI Spec */
     653            if (midicode == 0xF0 && bytes_left < 4) cin = 4 + bytes_left;
     654                /* see USB-MIDI Spec */
    550655        }
    551         st = usb->queue_bulk(my_dev->ept_out->handle, my_dev->out_buffer,
    552             sizeof(usb_midi_event_packet) * packet_count,
    553             (usb_callback_func)midi_usb_write_callback, my_dev);
     656        st = usb->queue_bulk(midiDevice->ept_out->handle,
     657                midiDevice->out_buffer,
     658                sizeof(usb_midi_event_packet) * packet_count,
     659                (usb_callback_func)midi_usb_write_callback, midiDevice);
    554660        if (st != B_OK) {
    555661            DPRINTF_ERR((MY_ID "midi write queue_bulk() error %d\n", (int)st));
    556662            return B_ERROR;
     
    560666}
    561667
    562668
    563 /*
    564     usb_midi_control - handle ioctl calls
    565  */
    566 
    567669static status_t
    568670usb_midi_control(void*  cookie, uint32 iop,
    569671    void*  data, size_t len)
     
    572674}
    573675
    574676
    575 /*
    576     usb_midi_close - handle close() calls
    577  */
    578 
    579677static status_t
    580678usb_midi_close(driver_cookie* cookie)
    581679{
    582     usbmidi_device_info* my_dev;
     680    usbmidi_port_info* port;
     681    usbmidi_device_info* midiDevice;
    583682
    584683    assert(cookie != NULL);
    585684    delete_sem(cookie->sem_cb);
    586     my_dev = cookie->my_dev;
    587     DPRINTF_INFO((MY_ID "usb_midi_close(%p device=%p)\n", cookie, my_dev));
     685    port = cookie->port;
     686    midiDevice = cookie->device;
     687    DPRINTF_INFO((MY_ID "usb_midi_close(%p device=%p port=%p)\n",
     688        cookie, midiDevice, port));
    588689
    589690
    590     acquire_sem(usbmidi_device_list_lock);
    591     if (my_dev) {
    592         /* detach the cookie from device */
    593         my_dev->open_fd = NULL;
    594         --my_dev->open;
     691    acquire_sem(usbmidi_port_list_lock);
     692    if (port) {
     693        /* detach the cookie from port */
     694        port->open_fd = NULL;
     695        --port->open;
    595696    }
    596     release_sem(usbmidi_device_list_lock);
    597     DPRINTF_INFO((MY_ID "usb_midi_close: complete\n");)
     697    release_sem(usbmidi_port_list_lock);
     698    DPRINTF_DEBUG((MY_ID "usb_midi_close: complete\n"));
    598699
    599700    return B_OK;
    600701}
    601702
    602703
    603 /*
    604     usb_midi_free - called after the last device is closed, and after
    605     all i/o is complete.
    606  */
    607 
    608704static status_t
    609705usb_midi_free(driver_cookie* cookie)
    610706{
    611     usbmidi_device_info* my_dev;
     707    usbmidi_port_info* port;    /* all only for info */
     708    usbmidi_device_info* midiDevice;
    612709
    613710    assert(cookie != NULL);
    614     my_dev = cookie->my_dev;
    615     DPRINTF_INFO((MY_ID "usb_midi_free(%p device=%p)\n", cookie, my_dev));
     711    port = cookie->port;
     712    midiDevice = cookie->device;
     713    DPRINTF_INFO((MY_ID "usb_midi_free(%p device=%p)\n", cookie, midiDevice));
    616714
    617715    free(cookie);
    618716
     
    620718}
    621719
    622720
    623 /*
    624     function pointers for the device hooks entry points
    625  */
    626 
    627721static device_hooks usb_midi_hooks = {
    628722    (device_open_hook)usb_midi_open,
    629723    (device_close_hook)usb_midi_close,
     
    636730
    637731
    638732/*
    639     init_hardware - called once the first time the driver is loaded
     733    Driver Registration
    640734 */
    641 
     735 
    642736_EXPORT status_t
    643737init_hardware(void)
    644738{
    645     DPRINTF_INFO((MY_ID "init_hardware() " __DATE__ " " __TIME__ "\n"));
     739    DPRINTF_DEBUG((MY_ID "init_hardware() version:"
     740        __DATE__ " " __TIME__ "\n"));
    646741    return B_OK;
    647742}
    648743
    649744
    650 /*
    651     init_driver - optional function - called every time the driver
    652     is loaded.
    653  */
    654 
    655745_EXPORT status_t
    656746init_driver(void)
    657747{
    658748
    659     DPRINTF_INFO((MY_ID "init_driver() " __DATE__ " " __TIME__ "\n"));
     749    DPRINTF_INFO((MY_ID "init_driver() version:" __DATE__ " " __TIME__ "\n"));
    660750
    661751    if (get_module(B_USB_MODULE_NAME, (module_info**)&usb) != B_OK)
    662752        return B_ERROR;
    663753
    664     if ((usbmidi_device_list_lock = create_sem(1, "dev_list_lock")) < 0) {
     754    if ((usbmidi_port_list_lock = create_sem(1, "dev_list_lock")) < 0) {
    665755        put_module(B_USB_MODULE_NAME);
    666         return usbmidi_device_list_lock;        /* error code */
     756        return usbmidi_port_list_lock;      /* error code */
    667757    }
    668758
    669759    usb->register_driver(usb_midi_driver_name, my_supported_devices,
     
    675765}
    676766
    677767
    678 /*
    679     uninit_driver - optional function - called every time the driver
    680     is unloaded
    681  */
    682 
    683768_EXPORT void
    684769uninit_driver(void)
    685770{
    686771    DPRINTF_INFO((MY_ID "uninit_driver()\n"));
    687772    usb->uninstall_notify(usb_midi_driver_name);
    688773   
    689     delete_sem(usbmidi_device_list_lock);
     774    delete_sem(usbmidi_port_list_lock);
    690775    put_module(B_USB_MODULE_NAME);
    691     free_device_names();
     776    free_port_names();
    692777    DPRINTF_INFO((MY_ID "uninit complete\n"));
    693778}
    694779
    695780
    696 /*
    697     publish_devices
    698     device names are generated dynamically
    699 */
    700 
    701781_EXPORT const char**
    702782publish_devices(void)
    703783{
    704784    DPRINTF_INFO((MY_ID "publish_devices()\n"));
    705785
    706     if (usbmidi_device_list_changed) {
    707         free_device_names();
    708         alloc_device_names();
    709         if (usbmidi_device_names != NULL)
    710             rebuild_device_names();
    711         usbmidi_device_list_changed = false;
     786    if (usbmidi_port_list_changed) {
     787        free_port_names();
     788        alloc_port_names();
     789        if (usbmidi_port_names != NULL)
     790            rebuild_port_names();
     791        usbmidi_port_list_changed = false;
    712792    }
    713     assert(usbmidi_device_names != NULL);
    714     return (const char**)usbmidi_device_names;
     793    assert(usbmidi_port_names != NULL);
     794    return (const char**)usbmidi_port_names;
    715795}
    716796
    717797
    718 /*
    719     find_device - return ptr to device hooks structure for a
    720     given device name
    721  */
    722 
    723798_EXPORT device_hooks*
    724799find_device(const char* name)
    725800{
    726801    assert(name != NULL);
    727802    DPRINTF_INFO((MY_ID "find_device(%s)\n", name));
    728     if (search_device_info(name) == NULL)
     803    if (search_port_info(name) == NULL)
    729804        return NULL;
    730805    return &usb_midi_hooks;
    731806}
    732