xref: /haiku/src/add-ons/kernel/drivers/midi/usb_midi/devlist.cpp (revision 99d027cd0238c1d86da86d7c3f4200509ccc61a6)
1 /*
2  * midi usb driver
3  * devlist.c
4  *
5  * Copyright 2006-2011 Haiku Inc.  All rights reserved.
6  * Distributed under the terms of the MIT Licence.
7  *
8  * Authors:
9  *		Jérôme Duval
10  *		Pete Goodeve, pete.goodeve@computer.org
11  *
12  *		Some portions of this code were originally derived from
13  *		USB Joystick driver for BeOS R5
14  *		Copyright 2000 (C) ITO, Takayuki
15  *		All rights reserved
16  *
17  */
18 
19 
20 #include "usb_midi.h"
21 
22 #include <stdlib.h>
23 #include <string.h>
24 
25 
26 sem_id			usbmidi_port_list_lock = -1;
27 bool			usbmidi_port_list_changed = true;	/* added or removed */
28 
29 static usbmidi_port_info*	usbmidi_port_list = NULL;
30 static int		usbmidi_port_count = 0;
31 
32 
33 void
34 add_port_info(usbmidi_port_info* port)
35 {
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 }
44 
45 
46 void
47 remove_port_info(usbmidi_port_info* port)
48 {
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 	} else {
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 				break;
63 			}
64 		}
65 		assert(d != NULL);
66 	}
67 	release_sem(usbmidi_port_list_lock);
68 }
69 
70 
71 usbmidi_port_info*
72 search_port_info(const char* name)
73 {
74 	usbmidi_port_info* port;
75 
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 			break;
80 	}
81 	release_sem(usbmidi_port_list_lock);
82 	return port;
83 }
84 
85 
86 int
87 find_free_device_number(void)
88 {
89 	usbmidi_port_info* port;
90 	int number = 0;
91 
92 	acquire_sem(usbmidi_port_list_lock);
93 	do {
94 		for (port = usbmidi_port_list; port != NULL; port = port->next) {
95 			if (port->device->devnum == number) {
96 				number++;
97 				break;	/* try next higher */
98 			}
99 		}
100 	} while (port);
101 	release_sem(usbmidi_port_list_lock);
102 	return number;
103 }
104 
105 
106 
107 /*
108 	device names
109 */
110 
111 /* dynamically generated */
112 char** usbmidi_port_names = NULL;
113 
114 
115 void
116 alloc_port_names(void)
117 {
118 	assert(usbmidi_port_names == NULL);
119 	usbmidi_port_names = (char**)malloc(sizeof(char*)
120 		* (usbmidi_port_count + 1));
121 }
122 
123 
124 void
125 free_port_names(void)
126 {
127 	if (usbmidi_port_names != NULL) {
128 		int i;
129 		for (i = 0; usbmidi_port_names[i] != NULL; i++)
130 			free(usbmidi_port_names[i]);
131 		free(usbmidi_port_names);
132 		usbmidi_port_names = NULL;
133 	}
134 }
135 
136 
137 void
138 rebuild_port_names(void)
139 {
140 	int i;
141 	usbmidi_port_info* port;
142 
143 	assert(usbmidi_port_names != NULL);
144 	acquire_sem(usbmidi_port_list_lock);
145 	for (i = 0, port = usbmidi_port_list; port != NULL; port = port->next) {
146 		usbmidi_port_names[i++] = strdup(port->name);
147 		DPRINTF_INFO((MY_ID "publishing %s\n", port->name));
148 	}
149 	usbmidi_port_names[i] = NULL;
150 	release_sem(usbmidi_port_list_lock);
151 }
152 
153