diff -u haiku/src/add-ons/kernel/drivers/midi/usb_midi_ALPHA1/usb_midi.c haiku/src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.c
--- haiku/src/add-ons/kernel/drivers/midi/usb_midi_ALPHA1/usb_midi.c	2009-09-14 19:57:15.000000000 +0000
+++ haiku/src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.c	2009-10-17 19:20:01.000000000 +0000
@@ -3,7 +3,7 @@
  * usb_midi.c
  *
  * Copyright 2006-2009 Haiku Inc.  All rights reserved.
- * Distributed under the terms of the MIT Licence.
+ * Distributed under tthe terms of the MIT Licence.
  *
  * Authors:
  *		Jérôme Duval
@@ -17,10 +17,10 @@
  */
 
 
-/*#define DEBUG 1*/	/* Define this to enable DPRINTF_INFO statements */
+/* #define DEBUG 1 */	/* Define this to enable DPRINTF_INFO statements */
 #include "usb_midi.h"
 
-#include <support/Debug.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -32,7 +32,6 @@
 static int midi_device_number = 0;
 const char* midi_base_name = "midi/usb/";
 
-
 usbmidi_device_info* 
 create_device(const usb_device* dev, const usb_interface_info* ii, uint16 ifno)
 {
@@ -52,17 +51,9 @@
 	if (my_dev == NULL)
 		return NULL;
 
-	my_dev->sem_cb = sem = create_sem(0, DRIVER_NAME "_cb");
-	if (sem < 0) {
-		DPRINTF_ERR((MY_ID "create_sem() failed %d\n", (int)sem));
-		free(my_dev);
-		return NULL;
-	}
-
 	my_dev->sem_lock = sem = create_sem(1, DRIVER_NAME "_lock");
 	if (sem < 0) {
 		DPRINTF_ERR((MY_ID "create_sem() failed %d\n", (int)sem));
-		delete_sem(my_dev->sem_cb);
 		free(my_dev);
 		return NULL;
 	}
@@ -73,7 +64,6 @@
 		B_PAGE_SIZE, B_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA);
 	if (area < 0) {
 		DPRINTF_ERR((MY_ID "create_area() failed %d\n", (int)area));
-		delete_sem(my_dev->sem_cb);
 		delete_sem(my_dev->sem_lock);
 		free(my_dev);
 		return NULL;
@@ -83,7 +73,6 @@
 	my_dev->sem_send =  sem = create_sem(1, DRIVER_NAME "_send");
 	if (sem < 0) {
 		DPRINTF_ERR((MY_ID "create_sem() failed %d\n", (int)sem));
-		delete_sem(my_dev->sem_cb);
 		delete_sem(my_dev->sem_lock);
 		delete_area(area);
 		free(my_dev);
@@ -92,7 +81,7 @@
 	{
 		int32 bc;
 		get_sem_count(sem, &bc);
-		DPRINTF_INFO((MY_ID "Allocated %d write buffers\n", bc));
+		DPRINTF_INFO((MY_ID "Allocated %ld write buffers\n", bc));
 	}
 
 
@@ -100,11 +89,12 @@
 	my_dev->dev = dev;
 	my_dev->ifno = ifno;
 	my_dev->open = 0;
-	my_dev->open_fds = NULL;
+	my_dev->open_fd = NULL;
 	my_dev->active = true;
 	my_dev->flags = 0;
 	my_dev->rbuf = create_ring_buffer(1024);
 	my_dev->buffer_size = B_PAGE_SIZE/2;
+	DPRINTF_INFO((MY_ID "Created device %p\n", my_dev);)
 	  	
 	return my_dev;
 }
@@ -118,21 +108,22 @@
 		delete_ring_buffer(my_dev->rbuf);
 		my_dev->rbuf = NULL;
 	}
+	DPRINTF_INFO((MY_ID "remove_device %p\n", my_dev);)
   
 	delete_area(my_dev->buffer_area);
-	delete_sem(my_dev->sem_cb);
 	delete_sem(my_dev->sem_lock);
 	delete_sem(my_dev->sem_send);
 	free(my_dev);
 }
 
 
-/* driver cookie (per open) */
+/* driver cookie (per open -- but only one open allowed!) */
 
 typedef struct driver_cookie
 {
 	struct driver_cookie	*next;
 	usbmidi_device_info			*my_dev;
+	sem_id sem_cb;
 } driver_cookie;
 
 	
@@ -174,7 +165,7 @@
 		DPRINTF_INFO((MY_ID "received packet %x:%d %x %x %x\n", packet->cin, packet->cn,
 			packet->midi[0], packet->midi[1], packet->midi[2]));
 		ring_buffer_write(my_dev->rbuf, packet->midi, pktlen);
-		release_sem_etc(my_dev->sem_cb, pktlen, B_DO_NOT_RESCHEDULE);
+		release_sem_etc(my_dev->open_fd->sem_cb, pktlen, B_DO_NOT_RESCHEDULE);
 		packet++;
 		bytes_left -= sizeof(usb_midi_event_packet);
 	}
@@ -193,19 +184,23 @@
 	usbmidi_device_info* my_dev = cookie;
 
 	assert(cookie != NULL);
-	DPRINTF_INFO((MY_ID "midi_usb_read_callback() -- packet length %d\n", actual_len));
+	DPRINTF_INFO((MY_ID "midi_usb_read_callback() -- packet length %ld\n", actual_len));
 
 	acquire_sem(my_dev->sem_lock);
 	my_dev->actual_length = actual_len;
 	my_dev->bus_status = status;	/* B_USB_STATUS_* */
 	if (status != B_OK) {
 		/* request failed */
-		release_sem(my_dev->sem_lock);
-		DPRINTF_ERR((MY_ID "bus status %d\n", (int)status));
-		if (status == B_CANCELED) {
+		DPRINTF_INFO((MY_ID "bus status %d\n", (int)status)); /* previously DPRINTF_ERR */
+		if (status == B_CANCELED || !my_dev->active) {
 			/* cancelled: device is unplugged */
+			DPRINTF_INFO((MY_ID "midi_usb_read_callback: cancelled (status=%lx active=%d -- deleting sem_cb\n",
+				status, my_dev->active));
+			delete_sem(my_dev->open_fd->sem_cb);	/* done here to ensure read is freed */
+			release_sem(my_dev->sem_lock);
 			return;
 		}
+		release_sem(my_dev->sem_lock);
 	} else {
 		/* got a report */
 #if 0
@@ -244,7 +239,7 @@
 #endif
 
 	assert(cookie != NULL);
-	DPRINTF_INFO((MY_ID "midi_usb_write_callback() status %ld length %d  pkt %p cin %x\n",
+	DPRINTF_INFO((MY_ID "midi_usb_write_callback() status %ld length %ld  pkt %p cin %x\n",
 		status, actual_len, pkt, pkt->cin));
 	release_sem(my_dev->sem_send); /* done with buffer */
 }
@@ -266,7 +261,7 @@
 	int alt;
 	
 	assert(dev != NULL && cookie != NULL);
-	DPRINTF_INFO((MY_ID "device_added()\n"));
+	DPRINTF_INFO((MY_ID "usb_midi_added(%p, %p)\n", dev, cookie));
 
 	dev_desc = usb->get_device_descriptor(dev);
 
@@ -348,7 +343,7 @@
 	add_device_info(my_dev);
 
 	*cookie = my_dev;
-	DPRINTF_INFO((MY_ID "added %s\n", my_dev->name));
+	DPRINTF_INFO((MY_ID "usb_midi_added: added %s\n", my_dev->name));
 
 	return B_OK;
 }
@@ -361,16 +356,19 @@
 
 	assert(cookie != NULL);
 
-	DPRINTF_INFO((MY_ID "device_removed(%s)\n", my_dev->name));
+	DPRINTF_INFO((MY_ID "usb_midi_removed(%s)\n", my_dev->name));
+	acquire_sem(usbmidi_device_list_lock);	/* convenient mutex for safety */
+	my_dev->active = false;
+	if (my_dev->open_fd) {
+		my_dev->open_fd->my_dev = NULL;
+		delete_sem(my_dev->open_fd->sem_cb);	/* done here to ensure read is freed */
+	}
+	release_sem(usbmidi_device_list_lock);
 	usb->cancel_queued_transfers(my_dev->ept_in->handle);
 	usb->cancel_queued_transfers(my_dev->ept_out->handle);
+	DPRINTF_INFO((MY_ID "usb_midi_removed: removing info & device: %s\n", my_dev->name));
 	remove_device_info(my_dev);
-	if (my_dev->open == 0) {
-		remove_device(my_dev);
-	} else {
-		DPRINTF_INFO((MY_ID "%s still open\n", my_dev->name));
-		my_dev->active = false;
-	}
+	remove_device(my_dev);
 	return B_OK;
 }
 
@@ -400,22 +398,30 @@
 
 	assert(name != NULL);
 	assert(out_cookie != NULL);
-	DPRINTF_INFO((MY_ID "open(%s)\n", name));
+	DPRINTF_INFO((MY_ID "usb_midi_open(%s)\n", name));
 
 	if ((my_dev = search_device_info(name)) == NULL)
 		return B_ENTRY_NOT_FOUND;
+	if (my_dev->open_fd != NULL)
+		return B_BUSY;	/* there can only be one open channel to the device */
 	if ((cookie = malloc(sizeof(driver_cookie))) == NULL)
 		return B_NO_MEMORY;
 
-	acquire_sem(my_dev->sem_lock);
+	cookie->sem_cb = create_sem(0, DRIVER_NAME "_cb");
+	if (cookie->sem_cb < 0) {
+		DPRINTF_ERR((MY_ID "create_sem() failed %d\n", (int)cookie->sem_cb));
+		free(cookie);
+		return B_ERROR;
+	}
+
+	acquire_sem(usbmidi_device_list_lock);	/* use global mutex now */
 	cookie->my_dev = my_dev;
-	cookie->next = my_dev->open_fds;
-	my_dev->open_fds = cookie;
+	my_dev->open_fd = cookie;
 	my_dev->open++;
-	release_sem(my_dev->sem_lock);
+	release_sem(usbmidi_device_list_lock);
 
 	*out_cookie = cookie;
-	DPRINTF_INFO((MY_ID "device %s open (%d)\n", name, my_dev->open));
+	DPRINTF_INFO((MY_ID "usb_midi_open: device %s open (%d)\n", name, my_dev->open));
 	return B_OK;
 }
 
@@ -433,22 +439,35 @@
 
 	assert(cookie != NULL);
 	my_dev = cookie->my_dev;
-	assert(my_dev != NULL);
 	
-	if (!my_dev->active)
-		return B_ERROR;		/* already unplugged */
+	if (!my_dev || !my_dev->active)
+		return B_ERROR;	/* already unplugged */
 		
-	DPRINTF_INFO((MY_ID "MIDI read (%d byte buffer at %ld cookie %p)\n",
+	DPRINTF_INFO((MY_ID "usb_midi_read: (%ld byte buffer at %ld cookie %p)\n",
 		*num_bytes, (int32)position, cookie));
-	err = acquire_sem_etc(my_dev->sem_cb, 1, B_CAN_INTERRUPT, 0LL);
-	if (err != B_OK)
-		return err;
-	acquire_sem(my_dev->sem_lock);
-	ring_buffer_user_read(my_dev->rbuf, buf, 1);
-	release_sem(my_dev->sem_lock);
-	*num_bytes = 1;
-	DPRINTF_INFO((MY_ID "read byte %x -- cookie %p)\n", *(uint8*)buf, cookie));
-	return err;
+	while (my_dev && my_dev->active) {
+		DPRINTF_INFOZ((MY_ID "waiting on acquire_sem_etc\n");)
+		err = acquire_sem_etc(cookie->sem_cb, 1,
+			 B_RELATIVE_TIMEOUT, 1000000);
+		if (err == B_TIMED_OUT) {
+			DPRINTF_INFOZ((MY_ID "acquire_sem_etc timed out\n");)
+			continue;	/* see if we're still active */
+		}
+		if (err != B_OK) {
+			*num_bytes = 0;
+			DPRINTF_INFO((MY_ID "acquire_sem_etc aborted\n");)
+			break;
+		}
+		DPRINTF_INFO((MY_ID "reading from ringbuffer\n");)
+		acquire_sem(my_dev->sem_lock);
+		ring_buffer_user_read(my_dev->rbuf, buf, 1);
+		release_sem(my_dev->sem_lock);
+		*num_bytes = 1;
+		DPRINTF_INFO((MY_ID "read byte %x -- cookie %p)\n", *(uint8*)buf, cookie));
+		return B_OK;
+	}
+	DPRINTF_INFO((MY_ID "usb_midi_read: loop terminated -- Device no longer active\n");)
+	return B_CANCELED;
 }
 
 
@@ -491,14 +510,13 @@
 
 	assert(cookie != NULL);
 	my_dev = cookie->my_dev;
-	assert(my_dev != NULL);
 
-	if (!my_dev->active)
+	if (!my_dev || !my_dev->active)
 		return B_ERROR;		/* already unplugged */
 		
 	buff_lim = my_dev->buffer_size * 3 / 4;	/* max MIDI bytes buffer space */
 	
-	DPRINTF_INFO((MY_ID "MIDI write (%d bytes at %ld)\n", *num_bytes, position));
+	DPRINTF_INFO((MY_ID "MIDI write (%ld bytes at %Ld)\n", *num_bytes, position));
 	if (*num_bytes > 3 && midicode != 0xF0) {
 		DPRINTF_ERR((MY_ID "Non-SysEx packet of %ld bytes -- too big to handle\n",
 			*num_bytes));
@@ -563,26 +581,20 @@
 {
 	usbmidi_device_info* my_dev;
 
-	assert(cookie != NULL && cookie->my_dev != NULL);
+	assert(cookie != NULL);
+	delete_sem(cookie->sem_cb);
 	my_dev = cookie->my_dev;
-	DPRINTF_INFO((MY_ID "close(%s)\n", my_dev->name));
+	DPRINTF_INFO((MY_ID "usb_midi_close(%p device=%p)\n", cookie, my_dev));
 
-	/* detach the cookie from list */
 
-	acquire_sem(my_dev->sem_lock);
-	if (my_dev->open_fds == cookie)
-		my_dev->open_fds = cookie->next;
-	else {
-		driver_cookie* p;
-		for (p = my_dev->open_fds; p != NULL; p = p->next) {
-			if (p->next == cookie) {
-				p->next = cookie->next;
-				break;
-			}
-		}
+	acquire_sem(usbmidi_device_list_lock);
+	if (my_dev) {
+		/* detach the cookie from device */
+		my_dev->open_fd = NULL;
+		--my_dev->open;
 	}
-	--my_dev->open;
-	release_sem(my_dev->sem_lock);
+	release_sem(usbmidi_device_list_lock);
+	DPRINTF_INFO((MY_ID "usb_midi_close: complete\n");)
 
 	return B_OK;
 }
@@ -598,17 +610,11 @@
 {
 	usbmidi_device_info* my_dev;
 
-	assert(cookie != NULL && cookie->my_dev != NULL);
+	assert(cookie != NULL);
 	my_dev = cookie->my_dev;
-	DPRINTF_INFO((MY_ID "free(%s)\n", my_dev->name));
+	DPRINTF_INFO((MY_ID "usb_midi_free(%p device=%p)\n", cookie, my_dev));
 
 	free(cookie);
-	if (my_dev->open > 0)
-		DPRINTF_INFO((MY_ID "%d opens left\n", my_dev->open));
-	else if (!my_dev->active) {
-		DPRINTF_INFO((MY_ID "removed %s\n", my_dev->name));
-		remove_device(my_dev);
-	}
 
 	return B_OK;
 }
@@ -683,6 +689,7 @@
 	delete_sem(usbmidi_device_list_lock);
 	put_module(B_USB_MODULE_NAME);
 	free_device_names();
+	DPRINTF_INFO((MY_ID "uninit complete\n"));
 }
 
 
diff -u haiku/src/add-ons/kernel/drivers/midi/usb_midi_ALPHA1/usb_midi.h haiku/src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.h
--- haiku/src/add-ons/kernel/drivers/midi/usb_midi_ALPHA1/usb_midi.h	2009-09-14 19:57:15.000000000 +0000
+++ haiku/src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.h	2009-10-17 19:08:19.000000000 +0000
@@ -62,7 +62,6 @@
 	struct usbmidi_device_info* next;
 
 	/* maintain device */
-	sem_id sem_cb;
 	sem_id sem_lock;
 	sem_id sem_send;
 	area_id buffer_area;
@@ -77,7 +76,7 @@
 
 	bool active;
 	int open;
-	struct driver_cookie* open_fds;
+	struct driver_cookie* open_fd;
 
 	/* work area for transfer */
 	int usbd_status, bus_status, cmd_status;
diff -u haiku/src/servers/midi_ALPHA1/DeviceWatcher.cpp haiku/src/servers/midi/DeviceWatcher.cpp
--- haiku/src/servers/midi_ALPHA1/DeviceWatcher.cpp	2009-09-24 17:53:49.000000000 +0000
+++ haiku/src/servers/midi/DeviceWatcher.cpp	2009-10-17 17:47:29.000000000 +0000
@@ -8,7 +8,6 @@
  *		Philippe Houdoin
  */
 
-
 #include "debug.h"
 #include "DeviceWatcher.h"
 #include "PortDrivers.h"
@@ -32,8 +31,9 @@
 using BPrivate::HashMap;
 using BPrivate::HashString;
 
+
+
 const char *kDevicesRoot = "/dev/midi";
-// const char *kDevicesRoot = "/Data/tmp";
 
 
 class DeviceEndpoints {
@@ -132,9 +132,15 @@
 	if (message->FindString("path", &path) != B_OK)
 		return;
 
+	const char* filename;
+	if (message->FindString("name", &filename) != B_OK)
+		return;
+
 	switch (opcode) {
 		case B_ENTRY_CREATED: {
-			_AddDevice(path);
+			BPath bpath(path);
+			TRACE(("got path %s leaf %s name %s\n", path, bpath.Leaf(), filename));
+			if (strcmp(bpath.Leaf(), filename) == 0) _AddDevice(path);
 			break;
 		}
 		case B_ENTRY_REMOVED: {
@@ -152,7 +158,7 @@
 int32 
 DeviceWatcher::_InitialDevicesScanThread(void* data)
 {
-	((DeviceWatcher*)data)->_ScanDevices(kDevicesRoot);
+	((DeviceWatcher*) data)->_ScanDevices(kDevicesRoot);
 	return 0;
 }
 
@@ -183,28 +189,19 @@
 {
 	TRACE(("DeviceWatcher::_AddDevice(\"%s\");\n", path));
 
-	if (fDeviceEndpointsMap.ContainsKey(path)) {
+	if ( fDeviceEndpointsMap.ContainsKey(path) ) {
 		// Already known
+		TRACE(("already known...!\n"));
 		return;
 	}
 		
-	BEntry entry(path);
-	if (entry.IsDirectory())
-		// Invalid path !
-		return;
-		
-	if (entry.IsSymLink()) {
-		BEntry symlink(path, true);
-		if (symlink.IsDirectory()) {
-			// Invalid path!
-			return;
-		}
-	}
-
 	int fd = open(path, O_RDWR | O_EXCL);
 	if (fd < 0)
-		return;	
+		return;
+		
 	
+	TRACE(("Doing _AddDevice(\"%s\"); fd=%d\n", path, fd));
+
 	MidiPortConsumer* consumer = new MidiPortConsumer(fd, path);
 	_SetIcons(consumer);
 	TRACE(("Register %s MidiPortConsumer\n", consumer->Name()));
@@ -215,8 +212,9 @@
 	TRACE(("Register %s MidiPortProducer\n", producer->Name()));
 	producer->Register();
 
-	DeviceEndpoints* deviceEndpoints = new DeviceEndpoints(fd, consumer, producer);
+	DeviceEndpoints * deviceEndpoints = new DeviceEndpoints(fd, consumer, producer);
 	fDeviceEndpointsMap.Put(path, deviceEndpoints);	
+	TRACE(("Done _AddDevice(\"%s\")\n", path));
 }
 
 
@@ -225,19 +223,24 @@
 {
 	TRACE(("DeviceWatcher::_RemoveDevice(\"%s\");\n", path));
 		
-	DeviceEndpoints* deviceEndpoints = fDeviceEndpointsMap.Get(path);
-	if (!deviceEndpoints)
+	DeviceEndpoints * deviceEndpoints = fDeviceEndpointsMap.Get(path);
+	if (!deviceEndpoints) {
+		TRACE(("_RemoveDevice(\"%s\") didn't find endpoint in map!!\n", path));
 		return;
+	}
 		
-	close(deviceEndpoints->fFD);
 
+	TRACE((" _RemoveDevice(\"%s\") unregistering\n", path));
 	deviceEndpoints->fConsumer->Unregister();
 	deviceEndpoints->fProducer->Unregister();
 
+	TRACE((" _RemoveDevice(\"%s\") releasing\n", path));
 	deviceEndpoints->fConsumer->Release();
 	deviceEndpoints->fProducer->Release();
 
+	TRACE((" _RemoveDevice(\"%s\") removing from map\n", path));
 	fDeviceEndpointsMap.Remove(path);
+	TRACE(("Done _RemoveDevice(\"%s\")\n", path));
 }
 
 
diff -u haiku/src/servers/midi_ALPHA1/PortDrivers.cpp haiku/src/servers/midi/PortDrivers.cpp
--- haiku/src/servers/midi_ALPHA1/PortDrivers.cpp	2009-09-24 17:53:49.000000000 +0000
+++ haiku/src/servers/midi/PortDrivers.cpp	2009-10-17 16:00:42.000000000 +0000
@@ -15,6 +15,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include <String.h>
 
@@ -90,7 +91,8 @@
 
 	while (fKeepRunning) {
 		if (read(fFileDescriptor, &next, 1) != 1) {
-			perror("Error reading data from driver");
+			if (errno == B_CANCELED) fKeepRunning = false;
+			else perror("Error reading data from driver");
 			break;
 		}
 
@@ -234,5 +236,5 @@
 	if (haveSysEx)
 		free(sysexBuf);
 
-	return fKeepRunning ? B_ERROR : B_OK;
+	return fKeepRunning ? errno : B_OK;
 }
diff -u haiku/src/servers/midi_ALPHA1/midi_server.rdef haiku/src/servers/midi/midi_server.rdef
--- haiku/src/servers/midi_ALPHA1/midi_server.rdef	2009-07-15 22:56:55.000000000 +0000
+++ haiku/src/servers/midi/midi_server.rdef	2009-10-17 15:02:55.000000000 +0000
@@ -10,7 +10,7 @@
 	variety    = B_APPV_ALPHA,
 	internal   = 0,
 	short_info = "midi_server",
-	long_info  = "midi_server ©2002-2006 Haiku"
+	long_info  = "midi_server ©2002-2009 Haiku"
 };
 
 resource vector_icon array {
