Ticket #4463: usb_midi.diff
File usb_midi.diff, 39.1 KB (added by , 14 years ago) |
---|
-
src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.h
2 2 * midi usb driver 3 3 * usb_midi.h 4 4 * 5 * Copyright 2006-20 09Haiku Inc. All rights reserved.5 * Copyright 2006-2011 Haiku Inc. All rights reserved. 6 6 * Distributed under the terms of the MIT Licence. 7 7 * 8 8 * Authors: … … 23 23 24 24 #include "ring_buffer.h" 25 25 26 /* Three levels of printout for convenience: */ 26 27 /* #define DEBUG 1 -- more convenient to define in the code file when needed */ 28 #define DEBUG_INFO 1 27 29 #define DEBUG_ERR 1 28 30 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 30 40 #define DPRINTF_INFO(x) dprintf x 31 41 #else 32 42 #define DPRINTF_INFO(x) 33 43 #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 36 48 #else 37 #define DPRINTF_ ERR(x)49 #define DPRINTF_DEBUG(x) 38 50 #endif 39 51 40 /* For local finer debugging control: */41 #define DPRINTF_INFOX(x) dprintf x42 #define DPRINTF_INFOZ(x)43 52 44 53 /* driver specific definitions */ 45 54 … … 49 58 #define MY_ERR "\033[31merror:\033[m " 50 59 #define MY_WARN "\033[31mwarning:\033[m " 51 60 #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__)) 53 63 54 64 #define DEFAULT_CONFIGURATION 0 55 65 … … 58 68 59 69 typedef struct usbmidi_device_info 60 70 { 61 /* list structure */ 71 /* list structure */ /* should not be needed eventually */ 62 72 struct usbmidi_device_info* next; 63 73 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) */ 65 78 sem_id sem_lock; 66 79 sem_id sem_send; 67 80 area_id buffer_area; 68 81 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 */ 70 84 71 85 const usb_device* dev; 72 86 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 */ 74 90 75 struct ring_buffer* rbuf;76 77 91 bool active; 78 int open;79 struct driver_cookie* open_fd;80 92 81 93 /* work area for transfer */ 82 int usbd_status, bus_status, cmd_status;94 int bus_status; 83 95 int actual_length; 84 96 const usb_endpoint_info* ept_in; 85 97 const usb_endpoint_info* ept_out; 86 98 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 */ 90 101 } usbmidi_device_info; 91 102 92 103 93 /* usb_midi.c */ 104 typedef struct usbmidi_port_info 105 { 106 /* list structure for manager */ 107 struct usbmidi_port_info* next; 94 108 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 95 129 extern usb_module_info* usb; 96 130 extern const char* usb_midi_base_name; 97 131 132 usbmidi_port_info* 133 create_usbmidi_port(usbmidi_device_info* devinfo, 134 int cable, bool has_in, bool has_out); 135 136 void 137 remove_port(usbmidi_port_info* port); 138 98 139 usbmidi_device_info* 99 create_device(const usb_device* dev, const usb_interface_info* ii, uint16 ifno); 140 create_device(const usb_device* dev, uint16 ifno); 141 /* ifno not actually used -- left in for now */ 100 142 101 143 void 102 144 remove_device(usbmidi_device_info* my_dev); 103 145 104 146 105 /* devlist.c */ 147 /* 148 devlist.c 149 */ 106 150 107 extern sem_id usbmidi_ device_list_lock;108 extern bool usbmidi_ device_list_changed;151 extern sem_id usbmidi_port_list_lock; 152 extern bool usbmidi_port_list_changed; 109 153 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); 154 void 155 add_port_info(usbmidi_port_info* port); 113 156 114 extern char** usbmidi_device_names; 157 void 158 remove_port_info(usbmidi_port_info* port); 115 159 116 void alloc_device_names(void); 117 void free_device_names(void); 118 void rebuild_device_names(void); 160 usbmidi_port_info* 161 search_port_info(const char* name); 162 163 int 164 find_free_device_number(void); 165 166 extern char** usbmidi_port_names; 167 168 void 169 alloc_port_names(void); 170 171 void 172 free_port_names(void); 173 174 void 175 rebuild_port_names(void); -
src/add-ons/kernel/drivers/midi/usb_midi/devlist.c
2 2 * midi usb driver 3 3 * devlist.c 4 4 * 5 * Copyright 2006-20 09Haiku Inc. All rights reserved.5 * Copyright 2006-2011 Haiku Inc. All rights reserved. 6 6 * Distributed under the terms of the MIT Licence. 7 7 * 8 8 * Authors: … … 23 23 #include <string.h> 24 24 25 25 26 sem_id usbmidi_ device_list_lock = -1;27 bool usbmidi_ device_list_changed = true; /* added or removed */26 sem_id usbmidi_port_list_lock = -1; 27 bool usbmidi_port_list_changed = true; /* added or removed */ 28 28 29 static usbmidi_ device_info* usbmidi_device_list = NULL;30 static int usbmidi_ device_count = 0;29 static usbmidi_port_info* usbmidi_port_list = NULL; 30 static int usbmidi_port_count = 0; 31 31 32 32 33 33 void 34 add_ device_info(usbmidi_device_info* my_dev)34 add_port_info(usbmidi_port_info* port) 35 35 { 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); 43 43 } 44 44 45 45 46 46 void 47 remove_ device_info(usbmidi_device_info* my_dev)47 remove_port_info(usbmidi_port_info* port) 48 48 { 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; 55 55 } 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; 62 62 break; 63 63 } 64 64 } 65 65 assert(d != NULL); 66 66 } 67 release_sem(usbmidi_ device_list_lock);67 release_sem(usbmidi_port_list_lock); 68 68 } 69 69 70 70 71 usbmidi_ device_info*72 search_ device_info(const char* name)71 usbmidi_port_info* 72 search_port_info(const char* name) 73 73 { 74 usbmidi_ device_info* my_dev;74 usbmidi_port_info* port; 75 75 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) 79 79 break; 80 80 } 81 release_sem(usbmidi_ device_list_lock);82 return my_dev;81 release_sem(usbmidi_port_list_lock); 82 return port; 83 83 } 84 84 85 int 86 find_free_device_number(void) 87 { 88 usbmidi_port_info* port; 89 int number = 0; 85 90 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 86 106 /* 87 107 device names 88 108 */ 89 109 90 110 /* dynamically generated */ 91 char** usbmidi_ device_names = NULL;111 char** usbmidi_port_names = NULL; 92 112 93 113 94 114 void 95 alloc_ device_names(void)115 alloc_port_names(void) 96 116 { 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)); 99 119 } 100 120 101 121 102 122 void 103 free_ device_names(void)123 free_port_names(void) 104 124 { 105 if (usbmidi_ device_names != NULL) {125 if (usbmidi_port_names != NULL) { 106 126 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; 111 131 } 112 132 } 113 133 114 134 115 135 void 116 rebuild_ device_names(void)136 rebuild_port_names(void) 117 137 { 118 138 int i; 119 usbmidi_ device_info* my_dev;139 usbmidi_port_info* port; 120 140 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)); 126 146 } 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); 129 149 } -
src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.c
2 2 * midi usb driver 3 3 * usb_midi.c 4 4 * 5 * Copyright 2006-20 09Haiku Inc. All rights reserved.5 * Copyright 2006-2011 Haiku Inc. All rights reserved. 6 6 * Distributed under the terms of the MIT Licence. 7 7 * 8 8 * Authors: … … 17 17 */ 18 18 19 19 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 21 23 #include "usb_midi.h" 22 24 23 25 #include <stdio.h> … … 25 27 #include <string.h> 26 28 #include <unistd.h> 27 29 28 #include "usbdevs.h"29 #include "usbdevs_data.h"30 30 31 32 static int midi_device_number = 0;33 31 const char* midi_base_name = "midi/usb/"; 34 32 33 34 usbmidi_port_info* 35 create_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 63 void 64 remove_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 35 77 usbmidi_device_info* 36 create_device(const usb_device* dev, const usb_interface_info* ii,uint16 ifno)78 create_device(const usb_device* dev, uint16 ifno) 37 79 { 38 usbmidi_device_info* m y_dev= NULL;80 usbmidi_device_info* midiDevice = NULL; 39 81 int number; 40 82 area_id area; 41 83 sem_id sem; 42 84 char area_name[32]; 43 const char* base_name;44 85 45 86 assert(usb != NULL && dev != NULL); 46 87 47 number = midi_device_number++; 48 base_name = midi_base_name; 88 number = find_free_device_number(); 49 89 50 m y_dev= malloc(sizeof(usbmidi_device_info));51 if (m y_dev== NULL)90 midiDevice = malloc(sizeof(usbmidi_device_info)); 91 if (midiDevice == NULL) 52 92 return NULL; 53 93 54 m y_dev->sem_lock = sem = create_sem(1, DRIVER_NAME "_lock");94 midiDevice->sem_lock = sem = create_sem(1, DRIVER_NAME "_lock"); 55 95 if (sem < 0) { 56 96 DPRINTF_ERR((MY_ID "create_sem() failed %d\n", (int)sem)); 57 free(m y_dev);97 free(midiDevice); 58 98 return NULL; 59 99 } 60 100 61 101 sprintf(area_name, DRIVER_NAME "_buffer%d", number); 62 m y_dev->buffer_area = area = create_area(area_name,63 (void**)&m y_dev->buffer, B_ANY_KERNEL_ADDRESS,102 midiDevice->buffer_area = area = create_area(area_name, 103 (void**)&midiDevice->buffer, B_ANY_KERNEL_ADDRESS, 64 104 B_PAGE_SIZE, B_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA); 65 105 if (area < 0) { 66 106 DPRINTF_ERR((MY_ID "create_area() failed %d\n", (int)area)); 67 delete_sem(m y_dev->sem_lock);68 free(m y_dev);107 delete_sem(midiDevice->sem_lock); 108 free(midiDevice); 69 109 return NULL; 70 110 } 71 111 /* 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"); 74 115 if (sem < 0) { 75 116 DPRINTF_ERR((MY_ID "create_sem() failed %d\n", (int)sem)); 76 delete_sem(m y_dev->sem_lock);117 delete_sem(midiDevice->sem_lock); 77 118 delete_area(area); 78 free(m y_dev);119 free(midiDevice); 79 120 return NULL; 80 121 } 81 122 { 82 123 int32 bc; 83 124 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)); 85 126 } 86 127 87 128 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)); 98 138 99 return m y_dev;139 return midiDevice; 100 140 } 101 141 102 142 103 143 void 104 remove_device(usbmidi_device_info* m y_dev)144 remove_device(usbmidi_device_info* midiDevice) 105 145 { 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)); 112 148 113 delete_area(m y_dev->buffer_area);114 delete_sem(m y_dev->sem_lock);115 delete_sem(m y_dev->sem_send);116 free(m y_dev);149 delete_area(midiDevice->buffer_area); 150 delete_sem(midiDevice->sem_lock); 151 delete_sem(midiDevice->sem_send); 152 free(midiDevice); 117 153 } 118 154 119 155 120 /* driver cookie (per open -- but only one open allowed!) */156 /* driver cookie (per open -- but only one open per port allowed!) */ 121 157 122 158 typedef struct driver_cookie 123 159 { 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; 126 163 sem_id sem_cb; 127 164 } driver_cookie; 128 165 … … 156 193 157 194 158 195 static void 159 interpret_midi_buffer(usbmidi_device_info* m y_dev)196 interpret_midi_buffer(usbmidi_device_info* midiDevice) 160 197 { 161 usb_midi_event_packet* packet = m y_dev->buffer;162 size_t bytes_left = m y_dev->actual_length;198 usb_midi_event_packet* packet = midiDevice->buffer; 199 size_t bytes_left = midiDevice->actual_length; 163 200 while (bytes_left) { /* buffer may have several packets */ 164 201 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, 166 206 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); 169 209 packet++; 170 210 bytes_left -= sizeof(usb_midi_event_packet); 171 211 } … … 181 221 void* data, size_t actual_len) 182 222 { 183 223 status_t st; 184 usbmidi_device_info* m y_dev= cookie;224 usbmidi_device_info* midiDevice = cookie; 185 225 186 226 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)); 188 229 189 acquire_sem(m y_dev->sem_lock);190 m y_dev->actual_length = actual_len;191 m y_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_* */ 192 233 if (status != B_OK) { 193 234 /* request failed */ 194 DPRINTF_ INFO((MY_ID "bus status %d\n", (int)status)); /* previously DPRINTF_ERR */195 if (status == B_CANCELED || !m y_dev->active) {235 DPRINTF_DEBUG((MY_ID "bus status %d\n", (int)status)); 236 if (status == B_CANCELED || !midiDevice->active) { 196 237 /* 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); 201 248 return; 202 249 } 203 release_sem(m y_dev->sem_lock);250 release_sem(midiDevice->sem_lock); 204 251 } else { 205 252 /* 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... */ 210 254 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); 219 257 } 220 258 221 259 /* 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); 225 263 if (st != B_OK) { 226 /* XXXprobably endpoint stall */264 /* probably endpoint stall */ 227 265 DPRINTF_ERR((MY_ID "queue_bulk() error %d\n", (int)st)); 228 266 } 229 267 } … … 233 271 midi_usb_write_callback(void* cookie, status_t status, 234 272 void* data, size_t actual_len) 235 273 { 236 usbmidi_device_info* m y_dev= cookie;274 usbmidi_device_info* midiDevice = cookie; 237 275 #ifdef DEBUG 238 276 usb_midi_event_packet* pkt = data; 239 277 #endif 240 278 241 279 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", 243 282 status, actual_len, pkt, pkt->cin)); 244 release_sem(m y_dev->sem_send); /* done with buffer */283 release_sem(midiDevice->sem_send); /* done with buffer */ 245 284 } 246 285 247 286 … … 252 291 static status_t 253 292 usb_midi_added(const usb_device* dev, void** cookie) 254 293 { 255 usbmidi_device_info* my_dev; 294 usbmidi_device_info* midiDevice; 295 usbmidi_port_info* port; 256 296 const usb_device_descriptor* dev_desc; 257 297 const usb_configuration_info* conf; 258 298 const usb_interface_info* intf; … … 260 300 uint16 ifno, i; 261 301 int alt; 262 302 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 263 309 assert(dev != NULL && cookie != NULL); 264 310 DPRINTF_INFO((MY_ID "usb_midi_added(%p, %p)\n", dev, cookie)); 265 311 … … 267 313 268 314 DPRINTF_INFO((MY_ID "vendor ID 0x%04X, product ID 0x%04X\n", 269 315 dev_desc->vendor_id, dev_desc->product_id)); 270 316 271 317 /* check interface class */ 272 318 273 if ((conf = usb->get_nth_configuration(dev, DEFAULT_CONFIGURATION)) == NULL) { 319 if ((conf = usb->get_nth_configuration(dev, DEFAULT_CONFIGURATION)) 320 == NULL) { 274 321 DPRINTF_ERR((MY_ID "cannot get default configuration\n")); 275 322 return B_ERROR; 276 323 } 324 DPRINTF_INFO((MY_ID "Interface count = %ld\n", conf->interface_count)); 277 325 278 326 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; 281 328 282 329 for (alt = 0; alt < conf->interface[ifno].alt_count; alt++) { 283 330 intf = &conf->interface[ifno].alt[alt]; 284 class = intf->descr->interface_class;331 devclass = intf->descr->interface_class; 285 332 subclass = intf->descr->interface_subclass; 286 333 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)); 289 338 290 if ( class == USB_AUDIO_DEVICE_CLASS339 if (devclass == USB_AUDIO_DEVICE_CLASS 291 340 && subclass == USB_AUDIO_INTERFACE_MIDISTREAMING_SUBCLASS) 292 341 goto got_one; 293 342 } … … 298 347 299 348 got_one: 300 349 301 for (i=0; i < sizeof(usb_knowndevs)/sizeof(struct usb_knowndev); i++) {302 if (usb_knowndevs[i].vendor == dev_desc->vendor_id303 && 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 */311 350 if ((st = usb->set_configuration(dev, conf)) != B_OK) { 312 351 DPRINTF_ERR((MY_ID "set_configuration() failed %d\n", (int)st)); 313 352 return B_ERROR; 314 353 } 315 354 316 if ((m y_dev = create_device(dev, intf, ifno)) == NULL) {355 if ((midiDevice = create_device(dev, ifno)) == NULL) { 317 356 return B_ERROR; 318 357 } 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; 319 375 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 } 330 392 331 m y_dev->timestamp = system_time();393 midiDevice->timestamp = system_time(); /* This never seems to be used */ 332 394 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 333 405 /* 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); 337 410 if (st != B_OK) { 338 411 DPRINTF_ERR((MY_ID "queue_bulk() error %d\n", (int)st)); 339 412 return B_ERROR; 340 413 } 341 414 342 /* create a port */343 add_device_info(my_dev);344 415 345 *cookie = m y_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)); 347 418 348 419 return B_OK; 349 420 } … … 352 423 static status_t 353 424 usb_midi_removed(void* cookie) 354 425 { 355 usbmidi_device_info* my_dev = cookie; 426 usbmidi_device_info* midiDevice = cookie; 427 int cable; 356 428 357 429 assert(cookie != NULL); 358 430 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); 365 445 } 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); 372 451 return B_OK; 373 452 } 374 453 … … 381 460 #define SUPPORTED_DEVICES 1 382 461 usb_support_descriptor my_supported_devices[SUPPORTED_DEVICES] = 383 462 { 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 }, 385 468 }; 386 469 387 470 388 471 /* 389 usb_midi_open - handle open() calls 472 Device Driver Hook Functions 473 -- open, read, write, close, and free 390 474 */ 391 475 392 476 static status_t … … 394 478 driver_cookie** out_cookie) 395 479 { 396 480 driver_cookie* cookie; 397 usbmidi_device_info* my_dev; 481 usbmidi_port_info* port; 482 int mode = flags & O_RWMASK; 398 483 399 484 assert(name != NULL); 400 485 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)); 402 487 403 if (( my_dev = search_device_info(name)) == NULL)488 if ((port = search_port_info(name)) == NULL) 404 489 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 407 496 if ((cookie = malloc(sizeof(driver_cookie))) == NULL) 408 497 return B_NO_MEMORY; 409 498 … … 414 503 return B_ERROR; 415 504 } 416 505 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; 422 508 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 423 521 *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)); 425 524 return B_OK; 426 525 } 427 526 428 527 429 /*430 usb_midi_read - handle read() calls431 */432 433 528 static status_t 434 529 usb_midi_read(driver_cookie* cookie, off_t position, 435 530 void* buf, size_t* num_bytes) 436 531 { 437 532 status_t err = B_ERROR; 438 usbmidi_device_info* my_dev; 533 usbmidi_port_info* port; 534 usbmidi_device_info* midiDevice; 439 535 440 536 assert(cookie != NULL); 441 my_dev = cookie->my_dev; 537 port = cookie->port; 538 midiDevice = cookie->device; 442 539 443 if (!m y_dev || !my_dev->active)540 if (!midiDevice || !midiDevice->active) 444 541 return B_ERROR; /* already unplugged */ 445 542 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", 447 544 *num_bytes, (int32)position, cookie)); 448 while (m y_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")); 450 547 err = acquire_sem_etc(cookie->sem_cb, 1, 451 548 B_RELATIVE_TIMEOUT, 1000000); 452 549 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")); 454 551 continue; /* see if we're still active */ 455 552 } 456 553 if (err != B_OK) { 457 554 *num_bytes = 0; 458 DPRINTF_ INFO((MY_ID "acquire_sem_etc aborted\n");)555 DPRINTF_DEBUG((MY_ID "acquire_sem_etc aborted\n")); 459 556 break; 460 557 } 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); 465 563 *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)); 467 566 return B_OK; 468 567 } 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")); 470 570 return B_CANCELED; 471 571 } 472 572 473 573 474 /*475 usb_midi_write - handle write() calls476 */477 478 574 const uint8 CINcode[] = { /* see USB-MIDI Spec */ 479 575 0x4, /* 0x0 - sysex start */ 480 576 0, /* 0x1 -- undefined */ … … 499 595 usb_midi_write(driver_cookie* cookie, off_t position, 500 596 const void* buf, size_t* num_bytes) 501 597 { 502 usbmidi_device_info* my_dev; 598 usbmidi_port_info* port; 599 usbmidi_device_info* midiDevice; 503 600 uint8* midiseq = (uint8*)buf; 504 601 uint8 midicode = midiseq[0]; /* preserved for reference */ 505 602 status_t st; … … 509 606 : (midicode >> 4); 510 607 511 608 assert(cookie != NULL); 512 my_dev = cookie->my_dev; 609 port = cookie->port; 610 midiDevice = cookie->device; 513 611 514 if (!m y_dev || !my_dev->active)612 if (!midiDevice || !midiDevice->active) 515 613 return B_ERROR; /* already unplugged */ 516 614 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 */ 518 617 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)); 520 620 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)); 523 623 return B_ERROR; 524 624 } 525 625 526 626 while (bytes_left) { 527 size_t xfer_bytes = (bytes_left < buff_lim) ? bytes_left : buff_lim;528 usb_midi_event_packet* pkt = m y_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; 529 629 int packet_count = 0; 530 630 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); 532 633 if (st != B_OK) 533 634 return st; 534 635 … … 536 637 uint8 pkt_bytes = CINbytes[cin]; 537 638 memset(pkt, 0, sizeof(usb_midi_event_packet)); 538 639 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])); 541 644 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, 543 647 pkt->midi[0], pkt->midi[1], pkt->midi[2])); 544 648 xfer_bytes -= pkt_bytes; 545 649 bytes_left -= pkt_bytes; 546 650 midiseq += pkt_bytes; 547 651 packet_count++; 548 652 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 */ 550 655 } 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); 554 660 if (st != B_OK) { 555 661 DPRINTF_ERR((MY_ID "midi write queue_bulk() error %d\n", (int)st)); 556 662 return B_ERROR; … … 560 666 } 561 667 562 668 563 /*564 usb_midi_control - handle ioctl calls565 */566 567 669 static status_t 568 670 usb_midi_control(void* cookie, uint32 iop, 569 671 void* data, size_t len) … … 572 674 } 573 675 574 676 575 /*576 usb_midi_close - handle close() calls577 */578 579 677 static status_t 580 678 usb_midi_close(driver_cookie* cookie) 581 679 { 582 usbmidi_device_info* my_dev; 680 usbmidi_port_info* port; 681 usbmidi_device_info* midiDevice; 583 682 584 683 assert(cookie != NULL); 585 684 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)); 588 689 589 690 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; 595 696 } 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")); 598 699 599 700 return B_OK; 600 701 } 601 702 602 703 603 /*604 usb_midi_free - called after the last device is closed, and after605 all i/o is complete.606 */607 608 704 static status_t 609 705 usb_midi_free(driver_cookie* cookie) 610 706 { 611 usbmidi_device_info* my_dev; 707 usbmidi_port_info* port; /* all only for info */ 708 usbmidi_device_info* midiDevice; 612 709 613 710 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)); 616 714 617 715 free(cookie); 618 716 … … 620 718 } 621 719 622 720 623 /*624 function pointers for the device hooks entry points625 */626 627 721 static device_hooks usb_midi_hooks = { 628 722 (device_open_hook)usb_midi_open, 629 723 (device_close_hook)usb_midi_close, … … 636 730 637 731 638 732 /* 639 init_hardware - called once the first time the driver is loaded733 Driver Registration 640 734 */ 641 735 642 736 _EXPORT status_t 643 737 init_hardware(void) 644 738 { 645 DPRINTF_INFO((MY_ID "init_hardware() " __DATE__ " " __TIME__ "\n")); 739 DPRINTF_DEBUG((MY_ID "init_hardware() version:" 740 __DATE__ " " __TIME__ "\n")); 646 741 return B_OK; 647 742 } 648 743 649 744 650 /*651 init_driver - optional function - called every time the driver652 is loaded.653 */654 655 745 _EXPORT status_t 656 746 init_driver(void) 657 747 { 658 748 659 DPRINTF_INFO((MY_ID "init_driver() " __DATE__ " " __TIME__ "\n"));749 DPRINTF_INFO((MY_ID "init_driver() version:" __DATE__ " " __TIME__ "\n")); 660 750 661 751 if (get_module(B_USB_MODULE_NAME, (module_info**)&usb) != B_OK) 662 752 return B_ERROR; 663 753 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) { 665 755 put_module(B_USB_MODULE_NAME); 666 return usbmidi_ device_list_lock; /* error code */756 return usbmidi_port_list_lock; /* error code */ 667 757 } 668 758 669 759 usb->register_driver(usb_midi_driver_name, my_supported_devices, … … 675 765 } 676 766 677 767 678 /*679 uninit_driver - optional function - called every time the driver680 is unloaded681 */682 683 768 _EXPORT void 684 769 uninit_driver(void) 685 770 { 686 771 DPRINTF_INFO((MY_ID "uninit_driver()\n")); 687 772 usb->uninstall_notify(usb_midi_driver_name); 688 773 689 delete_sem(usbmidi_ device_list_lock);774 delete_sem(usbmidi_port_list_lock); 690 775 put_module(B_USB_MODULE_NAME); 691 free_ device_names();776 free_port_names(); 692 777 DPRINTF_INFO((MY_ID "uninit complete\n")); 693 778 } 694 779 695 780 696 /*697 publish_devices698 device names are generated dynamically699 */700 701 781 _EXPORT const char** 702 782 publish_devices(void) 703 783 { 704 784 DPRINTF_INFO((MY_ID "publish_devices()\n")); 705 785 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; 712 792 } 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; 715 795 } 716 796 717 797 718 /*719 find_device - return ptr to device hooks structure for a720 given device name721 */722 723 798 _EXPORT device_hooks* 724 799 find_device(const char* name) 725 800 { 726 801 assert(name != NULL); 727 802 DPRINTF_INFO((MY_ID "find_device(%s)\n", name)); 728 if (search_ device_info(name) == NULL)803 if (search_port_info(name) == NULL) 729 804 return NULL; 730 805 return &usb_midi_hooks; 731 806 } 732