From 36148198df04bfd8873b6e6ebe5dad2f4d18f296 Mon Sep 17 00:00:00 2001
From: Pete Goodeve <pete.goodeve@computer.org>
Date: Wed, 1 May 2013 15:11:04 -0700
Subject: [PATCH] usb_midi: fixed handling of multiport devices
---
.../kernel/drivers/midi/usb_midi/usb_midi.cpp | 45 ++++++++++++--------
.../kernel/drivers/midi/usb_midi/usb_midi.h | 7 ++-
2 files changed, 33 insertions(+), 19 deletions(-)
diff --git a/src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.cpp b/src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.cpp
index 40f58eb..7650aee 100644
a
|
b
|
|
2 | 2 | * midi usb driver |
3 | 3 | * usb_midi.c |
4 | 4 | * |
5 | | * Copyright 2006-2011 Haiku Inc. All rights reserved. |
| 5 | * Copyright 2006-2012 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_DEBUG statements */ |
| 20 | /* #define DEBUG 1 */ /* Define this to enable DPRINTF_DEBUG statements */ |
21 | 21 | /* (Other categories of printout set in usb_midi.h) */ |
22 | 22 | |
23 | 23 | #include "usb_midi.h" |
… |
… |
create_device(const usb_device* dev, uint16 ifno)
|
134 | 134 | midiDevice->active = true; |
135 | 135 | midiDevice->flags = 0; |
136 | 136 | memset(midiDevice->ports, 0, sizeof(midiDevice->ports)); |
137 | | midiDevice->buffer_size = B_PAGE_SIZE / 2; |
| 137 | midiDevice->inMaxPkt = midiDevice->outMaxPkt = B_PAGE_SIZE / 2; |
| 138 | /* Initially -- will get reduced */ |
138 | 139 | DPRINTF_INFO((MY_ID "Created device %p\n", midiDevice)); |
139 | 140 | |
140 | 141 | return midiDevice; |
… |
… |
midi_usb_read_callback(void* cookie, status_t status,
|
234 | 235 | usbmidi_device_info* midiDevice = (usbmidi_device_info*)cookie; |
235 | 236 | |
236 | 237 | assert(cookie != NULL); |
237 | | DPRINTF_DEBUG((MY_ID "midi_usb_read_callback() -- packet length %ld\n", |
238 | | actual_len)); |
| 238 | if (actual_len > 0) { |
| 239 | DPRINTF_DEBUG((MY_ID "midi_usb_read_callback() -- packet length %ld\n", |
| 240 | actual_len)); |
| 241 | } |
239 | 242 | |
240 | 243 | acquire_sem(midiDevice->sem_lock); |
241 | 244 | midiDevice->actual_length = actual_len; |
… |
… |
midi_usb_read_callback(void* cookie, status_t status,
|
271 | 274 | |
272 | 275 | /* issue next request */ |
273 | 276 | st = usb->queue_bulk(midiDevice->ept_in->handle, |
274 | | midiDevice->buffer, midiDevice->buffer_size, |
| 277 | midiDevice->buffer, midiDevice->inMaxPkt, |
275 | 278 | (usb_callback_func)midi_usb_read_callback, midiDevice); |
276 | 279 | if (st != B_OK) { |
277 | 280 | /* probably endpoint stall */ |
… |
… |
got_one:
|
383 | 386 | |
384 | 387 | for (uint16 i = 0; i < intf->endpoint_count && i < 2; i++) { |
385 | 388 | /* we are actually assuming max one IN, one OUT endpoint... */ |
386 | | DPRINTF_INFO((MY_ID "endpoint %d = %p %s\n", |
| 389 | DPRINTF_INFO((MY_ID "endpoint %d = %p %s maxPkt=%d\n", |
387 | 390 | i, &intf->endpoint[i], |
388 | 391 | (intf->endpoint[i].descr->endpoint_address & 0x80) != 0 |
389 | | ? "IN" : "OUT")); |
| 392 | ? "IN" : "OUT", intf->endpoint[i].descr->max_packet_size)); |
390 | 393 | if ((intf->endpoint[i].descr->endpoint_address & 0x80) != 0) { |
391 | 394 | if (midiDevice->ept_in == NULL) { |
392 | 395 | midiDevice->ept_in = &intf->endpoint[i]; |
393 | 396 | in_cables = cable_count[i]; |
| 397 | if (intf->endpoint[i].descr->max_packet_size |
| 398 | < midiDevice->inMaxPkt) |
| 399 | midiDevice->inMaxPkt = intf->endpoint[i].descr->max_packet_size; |
| 400 | } |
| 401 | } else { |
| 402 | if (midiDevice->ept_out == NULL) { |
| 403 | midiDevice->ept_out = &intf->endpoint[i]; |
| 404 | out_cables = cable_count[i]; |
| 405 | if (intf->endpoint[i].descr->max_packet_size |
| 406 | < midiDevice->outMaxPkt) |
| 407 | midiDevice->outMaxPkt = intf->endpoint[i].descr->max_packet_size; |
394 | 408 | } |
395 | | } else if (midiDevice->ept_out == NULL) { |
396 | | midiDevice->ept_out = &intf->endpoint[i]; |
397 | | out_cables = cable_count[i]; |
398 | 409 | } |
399 | 410 | } |
400 | 411 | |
… |
… |
got_one:
|
416 | 427 | /* issue bulk transfer */ |
417 | 428 | DPRINTF_DEBUG((MY_ID "queueing bulk xfer IN endpoint\n")); |
418 | 429 | status = usb->queue_bulk(midiDevice->ept_in->handle, midiDevice->buffer, |
419 | | midiDevice->buffer_size, |
| 430 | midiDevice->inMaxPkt, |
420 | 431 | (usb_callback_func)midi_usb_read_callback, midiDevice); |
421 | 432 | if (status != B_OK) { |
422 | 433 | DPRINTF_ERR((MY_ID "queue_bulk() error 0x%lx\n", status)); |
… |
… |
usb_midi_open(const char* name, uint32 flags,
|
498 | 509 | if ((port = search_port_info(name)) == NULL) |
499 | 510 | return B_ENTRY_NOT_FOUND; |
500 | 511 | |
501 | | if (!port->has_in && mode != O_RDONLY) |
| 512 | if (!port->has_in && mode != O_WRONLY) |
502 | 513 | return B_PERMISSION_DENIED; /* == EACCES */ |
503 | | else if (!port->has_out && mode != O_WRONLY) |
| 514 | else if (!port->has_out && mode != O_RDONLY) |
504 | 515 | return B_PERMISSION_DENIED; |
505 | 516 | |
506 | 517 | if ((cookie = (driver_cookie*)malloc(sizeof(driver_cookie))) == NULL) |
… |
… |
usb_midi_read(driver_cookie* cookie, off_t position,
|
550 | 561 | DPRINTF_DEBUG((MY_ID "usb_midi_read: (%ld byte buffer at %lld cookie %p)" |
551 | 562 | "\n", *num_bytes, position, cookie)); |
552 | 563 | while (midiDevice && midiDevice->active) { |
553 | | DPRINTF_DEBUG((MY_ID "waiting on acquire_sem_etc\n")); |
| 564 | ZDPRINTF_DEBUG((MY_ID "waiting on acquire_sem_etc\n")); |
554 | 565 | err = acquire_sem_etc(cookie->sem_cb, 1, |
555 | 566 | B_RELATIVE_TIMEOUT, 1000000); |
556 | 567 | if (err == B_TIMED_OUT) { |
557 | | DPRINTF_DEBUG((MY_ID "acquire_sem_etc timed out\n")); |
| 568 | ZDPRINTF_DEBUG((MY_ID "acquire_sem_etc timed out\n")); |
558 | 569 | continue; /* see if we're still active */ |
559 | 570 | } |
560 | 571 | if (err != B_OK) { |
… |
… |
usb_midi_write(driver_cookie* cookie, off_t position,
|
616 | 627 | if (!midiDevice || !midiDevice->active) |
617 | 628 | return B_ERROR; /* already unplugged */ |
618 | 629 | |
619 | | buff_lim = midiDevice->buffer_size * 3 / 4; |
| 630 | buff_lim = midiDevice->outMaxPkt * 3 / 4; |
620 | 631 | /* max MIDI bytes buffer space */ |
621 | 632 | |
622 | 633 | DPRINTF_DEBUG((MY_ID "MIDI write (%ld bytes at %lld)\n", |
diff --git a/src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.h b/src/add-ons/kernel/drivers/midi/usb_midi/usb_midi.h
index f3e91e3..929eb62 100644
a
|
b
|
|
2 | 2 | * midi usb driver |
3 | 3 | * usb_midi.h |
4 | 4 | * |
5 | | * Copyright 2006-2011 Haiku Inc. All rights reserved. |
| 5 | * Copyright 2006-2012 Haiku Inc. All rights reserved. |
6 | 6 | * Distributed under the terms of the MIT Licence. |
7 | 7 | * |
8 | 8 | * Authors: |
… |
… |
|
51 | 51 | #define DPRINTF_DEBUG(x) |
52 | 52 | #endif |
53 | 53 | |
| 54 | /* a convenient way of suppressing some printouts: */ |
| 55 | #define ZDPRINTF_DEBUG(x) |
| 56 | |
54 | 57 | |
55 | 58 | /* driver specific definitions */ |
56 | 59 | |
… |
… |
typedef struct usbmidi_device_info
|
82 | 85 | area_id buffer_area; |
83 | 86 | usb_midi_event_packet* buffer; /* input buffer & base of area */ |
84 | 87 | usb_midi_event_packet* out_buffer; /* above input buffer */ |
85 | | size_t buffer_size; /* for each of in and out buffers */ |
| 88 | size_t inMaxPkt, outMaxPkt; /* for each of in and out buffers */ |
86 | 89 | |
87 | 90 | const usb_device* dev; |
88 | 91 | uint16 ifno; |