Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ALSA: seq: Add port direction to snd_seq_port_info

Add a new field "direction" to snd_seq_port_info for allowing a client
to tell the expected direction of the port access. A port might still
allow subscriptions for read/write (e.g. for MIDI-CI) even if the
primary usage of the port is a single direction (either input or
output only). This new "direction" field can help to indicate such
cases.

When the direction is unspecified at creating a port and the port has
either read or write capability, the corresponding direction bits are
set automatically as default.

Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-29-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

+43 -3
+8 -1
include/uapi/sound/asequencer.h
··· 455 455 #define SNDRV_SEQ_PORT_FLG_TIMESTAMP (1<<1) 456 456 #define SNDRV_SEQ_PORT_FLG_TIME_REAL (1<<2) 457 457 458 + /* port direction */ 459 + #define SNDRV_SEQ_PORT_DIR_UNKNOWN 0 460 + #define SNDRV_SEQ_PORT_DIR_INPUT 1 461 + #define SNDRV_SEQ_PORT_DIR_OUTPUT 2 462 + #define SNDRV_SEQ_PORT_DIR_BIDIRECTION 3 463 + 458 464 struct snd_seq_port_info { 459 465 struct snd_seq_addr addr; /* client/port numbers */ 460 466 char name[64]; /* port name */ ··· 477 471 void *kernel; /* reserved for kernel use (must be NULL) */ 478 472 unsigned int flags; /* misc. conditioning */ 479 473 unsigned char time_queue; /* queue # for timestamping */ 480 - char reserved[59]; /* for future use */ 474 + unsigned char direction; /* port usage direction (r/w/bidir) */ 475 + char reserved[58]; /* for future use */ 481 476 }; 482 477 483 478
+14 -2
sound/core/seq/seq_clientmgr.c
··· 2440 2440 2441 2441 #define FLAG_PERM_DUPLEX(perm) ((perm) & SNDRV_SEQ_PORT_CAP_DUPLEX ? 'X' : '-') 2442 2442 2443 + static const char *port_direction_name(unsigned char dir) 2444 + { 2445 + static const char *names[4] = { 2446 + "-", "In", "Out", "In/Out" 2447 + }; 2448 + 2449 + if (dir > SNDRV_SEQ_PORT_DIR_BIDIRECTION) 2450 + return "Invalid"; 2451 + return names[dir]; 2452 + } 2453 + 2443 2454 static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer, 2444 2455 struct snd_seq_client *client) 2445 2456 { ··· 2460 2449 list_for_each_entry(p, &client->ports_list_head, list) { 2461 2450 if (p->capability & SNDRV_SEQ_PORT_CAP_INACTIVE) 2462 2451 continue; 2463 - snd_iprintf(buffer, " Port %3d : \"%s\" (%c%c%c%c)\n", 2452 + snd_iprintf(buffer, " Port %3d : \"%s\" (%c%c%c%c) [%s]\n", 2464 2453 p->addr.port, p->name, 2465 2454 FLAG_PERM_RD(p->capability), 2466 2455 FLAG_PERM_WR(p->capability), 2467 2456 FLAG_PERM_EX(p->capability), 2468 - FLAG_PERM_DUPLEX(p->capability)); 2457 + FLAG_PERM_DUPLEX(p->capability), 2458 + port_direction_name(p->direction)); 2469 2459 snd_seq_info_dump_subscribers(buffer, &p->c_src, 1, " Connecting To: "); 2470 2460 snd_seq_info_dump_subscribers(buffer, &p->c_dest, 0, " Connected From: "); 2471 2461 }
+1
sound/core/seq/seq_dummy.c
··· 127 127 pinfo.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; 128 128 if (duplex) 129 129 pinfo.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; 130 + pinfo.direction = SNDRV_SEQ_PORT_DIR_BIDIRECTION; 130 131 pinfo.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC 131 132 | SNDRV_SEQ_PORT_TYPE_SOFTWARE 132 133 | SNDRV_SEQ_PORT_TYPE_PORT;
+4
sound/core/seq/seq_midi.c
··· 367 367 if ((port->capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) && 368 368 info->flags & SNDRV_RAWMIDI_INFO_DUPLEX) 369 369 port->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; 370 + if (port->capability & SNDRV_SEQ_PORT_CAP_READ) 371 + port->direction |= SNDRV_SEQ_PORT_DIR_INPUT; 372 + if (port->capability & SNDRV_SEQ_PORT_CAP_WRITE) 373 + port->direction |= SNDRV_SEQ_PORT_DIR_OUTPUT; 370 374 port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC 371 375 | SNDRV_SEQ_PORT_TYPE_HARDWARE 372 376 | SNDRV_SEQ_PORT_TYPE_PORT;
+13
sound/core/seq/seq_ports.c
··· 356 356 port->time_real = (info->flags & SNDRV_SEQ_PORT_FLG_TIME_REAL) ? 1 : 0; 357 357 port->time_queue = info->time_queue; 358 358 359 + /* direction */ 360 + port->direction = info->direction; 361 + /* fill default port direction */ 362 + if (!port->direction) { 363 + if (info->capability & SNDRV_SEQ_PORT_CAP_READ) 364 + port->direction |= SNDRV_SEQ_PORT_DIR_INPUT; 365 + if (info->capability & SNDRV_SEQ_PORT_CAP_WRITE) 366 + port->direction |= SNDRV_SEQ_PORT_DIR_OUTPUT; 367 + } 368 + 359 369 return 0; 360 370 } 361 371 ··· 402 392 info->flags |= SNDRV_SEQ_PORT_FLG_TIME_REAL; 403 393 info->time_queue = port->time_queue; 404 394 } 395 + 396 + /* direction */ 397 + info->direction = port->direction; 405 398 406 399 return 0; 407 400 }
+2
sound/core/seq/seq_ports.h
··· 72 72 int midi_voices; 73 73 int synth_voices; 74 74 75 + /* direction */ 76 + unsigned char direction; 75 77 }; 76 78 77 79 struct snd_seq_client;
+1
sound/core/seq/seq_virmidi.c
··· 385 385 pinfo->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE; 386 386 pinfo->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ; 387 387 pinfo->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX; 388 + pinfo->direction = SNDRV_SEQ_PORT_DIR_BIDIRECTION; 388 389 pinfo->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC 389 390 | SNDRV_SEQ_PORT_TYPE_SOFTWARE 390 391 | SNDRV_SEQ_PORT_TYPE_PORT;