root/sound/firewire/oxfw/oxfw-stream.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_rate
  2. set_stream_format
  3. start_stream
  4. check_connection_used_by_others
  5. init_stream
  6. keep_resources
  7. snd_oxfw_stream_reserve_duplex
  8. snd_oxfw_stream_start_duplex
  9. snd_oxfw_stream_stop_duplex
  10. destroy_stream
  11. snd_oxfw_stream_init_duplex
  12. snd_oxfw_stream_destroy_duplex
  13. snd_oxfw_stream_update_duplex
  14. snd_oxfw_stream_get_current_formation
  15. snd_oxfw_stream_parse_format
  16. assume_stream_formats
  17. fill_stream_formats
  18. snd_oxfw_stream_discover
  19. snd_oxfw_stream_lock_changed
  20. snd_oxfw_stream_lock_try
  21. snd_oxfw_stream_lock_release

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * oxfw_stream.c - a part of driver for OXFW970/971 based devices
   4  *
   5  * Copyright (c) 2014 Takashi Sakamoto
   6  */
   7 
   8 #include "oxfw.h"
   9 #include <linux/delay.h>
  10 
  11 #define AVC_GENERIC_FRAME_MAXIMUM_BYTES 512
  12 #define CALLBACK_TIMEOUT        200
  13 
  14 /*
  15  * According to datasheet of Oxford Semiconductor:
  16  *  OXFW970: 32.0/44.1/48.0/96.0 Khz, 8 audio channels I/O
  17  *  OXFW971: 32.0/44.1/48.0/88.2/96.0/192.0 kHz, 16 audio channels I/O, MIDI I/O
  18  */
  19 static const unsigned int oxfw_rate_table[] = {
  20         [0] = 32000,
  21         [1] = 44100,
  22         [2] = 48000,
  23         [3] = 88200,
  24         [4] = 96000,
  25         [5] = 192000,
  26 };
  27 
  28 /*
  29  * See Table 5.7 – Sampling frequency for Multi-bit Audio
  30  * in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
  31  */
  32 static const unsigned int avc_stream_rate_table[] = {
  33         [0] = 0x02,
  34         [1] = 0x03,
  35         [2] = 0x04,
  36         [3] = 0x0a,
  37         [4] = 0x05,
  38         [5] = 0x07,
  39 };
  40 
  41 static int set_rate(struct snd_oxfw *oxfw, unsigned int rate)
  42 {
  43         int err;
  44 
  45         err = avc_general_set_sig_fmt(oxfw->unit, rate,
  46                                       AVC_GENERAL_PLUG_DIR_IN, 0);
  47         if (err < 0)
  48                 goto end;
  49 
  50         if (oxfw->has_output)
  51                 err = avc_general_set_sig_fmt(oxfw->unit, rate,
  52                                               AVC_GENERAL_PLUG_DIR_OUT, 0);
  53 end:
  54         return err;
  55 }
  56 
  57 static int set_stream_format(struct snd_oxfw *oxfw, struct amdtp_stream *s,
  58                              unsigned int rate, unsigned int pcm_channels)
  59 {
  60         u8 **formats;
  61         struct snd_oxfw_stream_formation formation;
  62         enum avc_general_plug_dir dir;
  63         unsigned int len;
  64         int i, err;
  65 
  66         if (s == &oxfw->tx_stream) {
  67                 formats = oxfw->tx_stream_formats;
  68                 dir = AVC_GENERAL_PLUG_DIR_OUT;
  69         } else {
  70                 formats = oxfw->rx_stream_formats;
  71                 dir = AVC_GENERAL_PLUG_DIR_IN;
  72         }
  73 
  74         /* Seek stream format for requirements. */
  75         for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
  76                 err = snd_oxfw_stream_parse_format(formats[i], &formation);
  77                 if (err < 0)
  78                         return err;
  79 
  80                 if ((formation.rate == rate) && (formation.pcm == pcm_channels))
  81                         break;
  82         }
  83         if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
  84                 return -EINVAL;
  85 
  86         /* If assumed, just change rate. */
  87         if (oxfw->assumed)
  88                 return set_rate(oxfw, rate);
  89 
  90         /* Calculate format length. */
  91         len = 5 + formats[i][4] * 2;
  92 
  93         err = avc_stream_set_format(oxfw->unit, dir, 0, formats[i], len);
  94         if (err < 0)
  95                 return err;
  96 
  97         /* Some requests just after changing format causes freezing. */
  98         msleep(100);
  99 
 100         return 0;
 101 }
 102 
 103 static int start_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
 104 {
 105         struct cmp_connection *conn;
 106         int err;
 107 
 108         if (stream == &oxfw->rx_stream)
 109                 conn = &oxfw->in_conn;
 110         else
 111                 conn = &oxfw->out_conn;
 112 
 113         err = cmp_connection_establish(conn);
 114         if (err < 0)
 115                 return err;
 116 
 117         err = amdtp_domain_add_stream(&oxfw->domain, stream,
 118                                       conn->resources.channel, conn->speed);
 119         if (err < 0) {
 120                 cmp_connection_break(conn);
 121                 return err;
 122         }
 123 
 124         return 0;
 125 }
 126 
 127 static int check_connection_used_by_others(struct snd_oxfw *oxfw,
 128                                            struct amdtp_stream *stream)
 129 {
 130         struct cmp_connection *conn;
 131         bool used;
 132         int err;
 133 
 134         if (stream == &oxfw->tx_stream)
 135                 conn = &oxfw->out_conn;
 136         else
 137                 conn = &oxfw->in_conn;
 138 
 139         err = cmp_connection_check_used(conn, &used);
 140         if ((err >= 0) && used && !amdtp_stream_running(stream)) {
 141                 dev_err(&oxfw->unit->device,
 142                         "Connection established by others: %cPCR[%d]\n",
 143                         (conn->direction == CMP_OUTPUT) ? 'o' : 'i',
 144                         conn->pcr_index);
 145                 err = -EBUSY;
 146         }
 147 
 148         return err;
 149 }
 150 
 151 static int init_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
 152 {
 153         struct cmp_connection *conn;
 154         enum cmp_direction c_dir;
 155         enum amdtp_stream_direction s_dir;
 156         int err;
 157 
 158         if (stream == &oxfw->tx_stream) {
 159                 conn = &oxfw->out_conn;
 160                 c_dir = CMP_OUTPUT;
 161                 s_dir = AMDTP_IN_STREAM;
 162         } else {
 163                 conn = &oxfw->in_conn;
 164                 c_dir = CMP_INPUT;
 165                 s_dir = AMDTP_OUT_STREAM;
 166         }
 167 
 168         err = cmp_connection_init(conn, oxfw->unit, c_dir, 0);
 169         if (err < 0)
 170                 return err;
 171 
 172         err = amdtp_am824_init(stream, oxfw->unit, s_dir, CIP_NONBLOCKING);
 173         if (err < 0) {
 174                 cmp_connection_destroy(conn);
 175                 return err;
 176         }
 177 
 178         /*
 179          * OXFW starts to transmit packets with non-zero dbc.
 180          * OXFW postpone transferring packets till handling any asynchronous
 181          * packets. As a result, next isochronous packet includes more data
 182          * blocks than IEC 61883-6 defines.
 183          */
 184         if (stream == &oxfw->tx_stream) {
 185                 oxfw->tx_stream.flags |= CIP_JUMBO_PAYLOAD;
 186                 if (oxfw->wrong_dbs)
 187                         oxfw->tx_stream.flags |= CIP_WRONG_DBS;
 188         }
 189 
 190         return 0;
 191 }
 192 
 193 static int keep_resources(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
 194 {
 195         enum avc_general_plug_dir dir;
 196         u8 **formats;
 197         struct snd_oxfw_stream_formation formation;
 198         struct cmp_connection *conn;
 199         int i;
 200         int err;
 201 
 202         if (stream == &oxfw->rx_stream) {
 203                 dir = AVC_GENERAL_PLUG_DIR_IN;
 204                 formats = oxfw->rx_stream_formats;
 205                 conn = &oxfw->in_conn;
 206         } else {
 207                 dir = AVC_GENERAL_PLUG_DIR_OUT;
 208                 formats = oxfw->tx_stream_formats;
 209                 conn = &oxfw->out_conn;
 210         }
 211 
 212         err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
 213         if (err < 0)
 214                 return err;
 215 
 216         for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
 217                 struct snd_oxfw_stream_formation fmt;
 218 
 219                 if (formats[i] == NULL)
 220                         break;
 221 
 222                 err = snd_oxfw_stream_parse_format(formats[i], &fmt);
 223                 if (err < 0)
 224                         return err;
 225 
 226                 if (fmt.rate == formation.rate && fmt.pcm == formation.pcm &&
 227                     fmt.midi == formation.midi)
 228                         break;
 229         }
 230         if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
 231                 return -EINVAL;
 232 
 233         // The stream should have one pcm channels at least.
 234         if (formation.pcm == 0)
 235                 return -EINVAL;
 236 
 237         err = amdtp_am824_set_parameters(stream, formation.rate, formation.pcm,
 238                                          formation.midi * 8, false);
 239         if (err < 0)
 240                 return err;
 241 
 242         return cmp_connection_reserve(conn, amdtp_stream_get_max_payload(stream));
 243 }
 244 
 245 int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
 246                                    struct amdtp_stream *stream,
 247                                    unsigned int rate, unsigned int pcm_channels)
 248 {
 249         struct snd_oxfw_stream_formation formation;
 250         enum avc_general_plug_dir dir;
 251         int err;
 252 
 253         // Considering JACK/FFADO streaming:
 254         // TODO: This can be removed hwdep functionality becomes popular.
 255         err = check_connection_used_by_others(oxfw, &oxfw->rx_stream);
 256         if (err < 0)
 257                 return err;
 258         if (oxfw->has_output) {
 259                 err = check_connection_used_by_others(oxfw, &oxfw->tx_stream);
 260                 if (err < 0)
 261                         return err;
 262         }
 263 
 264         if (stream == &oxfw->tx_stream)
 265                 dir = AVC_GENERAL_PLUG_DIR_OUT;
 266         else
 267                 dir = AVC_GENERAL_PLUG_DIR_IN;
 268 
 269         err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
 270         if (err < 0)
 271                 return err;
 272         if (rate == 0) {
 273                 rate = formation.rate;
 274                 pcm_channels = formation.pcm;
 275         }
 276         if (formation.rate != rate || formation.pcm != pcm_channels) {
 277                 amdtp_domain_stop(&oxfw->domain);
 278 
 279                 cmp_connection_break(&oxfw->in_conn);
 280                 cmp_connection_release(&oxfw->in_conn);
 281 
 282                 if (oxfw->has_output) {
 283                         cmp_connection_break(&oxfw->out_conn);
 284                         cmp_connection_release(&oxfw->out_conn);
 285                 }
 286         }
 287 
 288         if (oxfw->substreams_count == 0 ||
 289             formation.rate != rate || formation.pcm != pcm_channels) {
 290                 err = set_stream_format(oxfw, stream, rate, pcm_channels);
 291                 if (err < 0) {
 292                         dev_err(&oxfw->unit->device,
 293                                 "fail to set stream format: %d\n", err);
 294                         return err;
 295                 }
 296 
 297                 err = keep_resources(oxfw, &oxfw->rx_stream);
 298                 if (err < 0)
 299                         return err;
 300 
 301                 if (oxfw->has_output) {
 302                         err = keep_resources(oxfw, &oxfw->tx_stream);
 303                         if (err < 0) {
 304                                 cmp_connection_release(&oxfw->in_conn);
 305                                 return err;
 306                         }
 307                 }
 308         }
 309 
 310         return 0;
 311 }
 312 
 313 int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw)
 314 {
 315         int err;
 316 
 317         if (oxfw->substreams_count == 0)
 318                 return -EIO;
 319 
 320         if (amdtp_streaming_error(&oxfw->rx_stream) ||
 321             amdtp_streaming_error(&oxfw->tx_stream)) {
 322                 amdtp_domain_stop(&oxfw->domain);
 323 
 324                 cmp_connection_break(&oxfw->in_conn);
 325                 if (oxfw->has_output)
 326                         cmp_connection_break(&oxfw->out_conn);
 327         }
 328 
 329         if (!amdtp_stream_running(&oxfw->rx_stream)) {
 330                 err = start_stream(oxfw, &oxfw->rx_stream);
 331                 if (err < 0) {
 332                         dev_err(&oxfw->unit->device,
 333                                 "fail to prepare rx stream: %d\n", err);
 334                         goto error;
 335                 }
 336 
 337                 if (oxfw->has_output &&
 338                     !amdtp_stream_running(&oxfw->tx_stream)) {
 339                         err = start_stream(oxfw, &oxfw->tx_stream);
 340                         if (err < 0) {
 341                                 dev_err(&oxfw->unit->device,
 342                                         "fail to prepare tx stream: %d\n", err);
 343                                 goto error;
 344                         }
 345                 }
 346 
 347                 err = amdtp_domain_start(&oxfw->domain);
 348                 if (err < 0)
 349                         goto error;
 350 
 351                 // Wait first packet.
 352                 if (!amdtp_stream_wait_callback(&oxfw->rx_stream,
 353                                                 CALLBACK_TIMEOUT)) {
 354                         err = -ETIMEDOUT;
 355                         goto error;
 356                 }
 357 
 358                 if (oxfw->has_output) {
 359                         if (!amdtp_stream_wait_callback(&oxfw->tx_stream,
 360                                                         CALLBACK_TIMEOUT)) {
 361                                 err = -ETIMEDOUT;
 362                                 goto error;
 363                         }
 364                 }
 365         }
 366 
 367         return 0;
 368 error:
 369         amdtp_domain_stop(&oxfw->domain);
 370 
 371         cmp_connection_break(&oxfw->in_conn);
 372         if (oxfw->has_output)
 373                 cmp_connection_break(&oxfw->out_conn);
 374 
 375         return err;
 376 }
 377 
 378 void snd_oxfw_stream_stop_duplex(struct snd_oxfw *oxfw)
 379 {
 380         if (oxfw->substreams_count == 0) {
 381                 amdtp_domain_stop(&oxfw->domain);
 382 
 383                 cmp_connection_break(&oxfw->in_conn);
 384                 cmp_connection_release(&oxfw->in_conn);
 385 
 386                 if (oxfw->has_output) {
 387                         cmp_connection_break(&oxfw->out_conn);
 388                         cmp_connection_release(&oxfw->out_conn);
 389                 }
 390         }
 391 }
 392 
 393 static void destroy_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
 394 {
 395         struct cmp_connection *conn;
 396 
 397         if (stream == &oxfw->tx_stream)
 398                 conn = &oxfw->out_conn;
 399         else
 400                 conn = &oxfw->in_conn;
 401 
 402         amdtp_stream_destroy(stream);
 403         cmp_connection_destroy(conn);
 404 }
 405 
 406 int snd_oxfw_stream_init_duplex(struct snd_oxfw *oxfw)
 407 {
 408         int err;
 409 
 410         err = init_stream(oxfw, &oxfw->rx_stream);
 411         if (err < 0)
 412                 return err;
 413 
 414         if (oxfw->has_output) {
 415                 err = init_stream(oxfw, &oxfw->tx_stream);
 416                 if (err < 0) {
 417                         destroy_stream(oxfw, &oxfw->rx_stream);
 418                         return err;
 419                 }
 420         }
 421 
 422         err = amdtp_domain_init(&oxfw->domain);
 423         if (err < 0) {
 424                 destroy_stream(oxfw, &oxfw->rx_stream);
 425                 if (oxfw->has_output)
 426                         destroy_stream(oxfw, &oxfw->tx_stream);
 427         }
 428 
 429         return err;
 430 }
 431 
 432 // This function should be called before starting the stream or after stopping
 433 // the streams.
 434 void snd_oxfw_stream_destroy_duplex(struct snd_oxfw *oxfw)
 435 {
 436         amdtp_domain_destroy(&oxfw->domain);
 437 
 438         destroy_stream(oxfw, &oxfw->rx_stream);
 439 
 440         if (oxfw->has_output)
 441                 destroy_stream(oxfw, &oxfw->tx_stream);
 442 }
 443 
 444 void snd_oxfw_stream_update_duplex(struct snd_oxfw *oxfw)
 445 {
 446         amdtp_domain_stop(&oxfw->domain);
 447 
 448         cmp_connection_break(&oxfw->in_conn);
 449 
 450         amdtp_stream_pcm_abort(&oxfw->rx_stream);
 451 
 452         if (oxfw->has_output) {
 453                 cmp_connection_break(&oxfw->out_conn);
 454 
 455                 amdtp_stream_pcm_abort(&oxfw->tx_stream);
 456         }
 457 }
 458 
 459 int snd_oxfw_stream_get_current_formation(struct snd_oxfw *oxfw,
 460                                 enum avc_general_plug_dir dir,
 461                                 struct snd_oxfw_stream_formation *formation)
 462 {
 463         u8 *format;
 464         unsigned int len;
 465         int err;
 466 
 467         len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
 468         format = kmalloc(len, GFP_KERNEL);
 469         if (format == NULL)
 470                 return -ENOMEM;
 471 
 472         err = avc_stream_get_format_single(oxfw->unit, dir, 0, format, &len);
 473         if (err < 0)
 474                 goto end;
 475         if (len < 3) {
 476                 err = -EIO;
 477                 goto end;
 478         }
 479 
 480         err = snd_oxfw_stream_parse_format(format, formation);
 481 end:
 482         kfree(format);
 483         return err;
 484 }
 485 
 486 /*
 487  * See Table 6.16 - AM824 Stream Format
 488  *     Figure 6.19 - format_information field for AM824 Compound
 489  * in AV/C Stream Format Information Specification 1.1 (Apr 2005, 1394TA)
 490  * Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005
 491  */
 492 int snd_oxfw_stream_parse_format(u8 *format,
 493                                  struct snd_oxfw_stream_formation *formation)
 494 {
 495         unsigned int i, e, channels, type;
 496 
 497         memset(formation, 0, sizeof(struct snd_oxfw_stream_formation));
 498 
 499         /*
 500          * this module can support a hierarchy combination that:
 501          *  Root:       Audio and Music (0x90)
 502          *  Level 1:    AM824 Compound  (0x40)
 503          */
 504         if ((format[0] != 0x90) || (format[1] != 0x40))
 505                 return -ENOSYS;
 506 
 507         /* check the sampling rate */
 508         for (i = 0; i < ARRAY_SIZE(avc_stream_rate_table); i++) {
 509                 if (format[2] == avc_stream_rate_table[i])
 510                         break;
 511         }
 512         if (i == ARRAY_SIZE(avc_stream_rate_table))
 513                 return -ENOSYS;
 514 
 515         formation->rate = oxfw_rate_table[i];
 516 
 517         for (e = 0; e < format[4]; e++) {
 518                 channels = format[5 + e * 2];
 519                 type = format[6 + e * 2];
 520 
 521                 switch (type) {
 522                 /* IEC 60958 Conformant, currently handled as MBLA */
 523                 case 0x00:
 524                 /* Multi Bit Linear Audio (Raw) */
 525                 case 0x06:
 526                         formation->pcm += channels;
 527                         break;
 528                 /* MIDI Conformant */
 529                 case 0x0d:
 530                         formation->midi = channels;
 531                         break;
 532                 /* IEC 61937-3 to 7 */
 533                 case 0x01:
 534                 case 0x02:
 535                 case 0x03:
 536                 case 0x04:
 537                 case 0x05:
 538                 /* Multi Bit Linear Audio */
 539                 case 0x07:      /* DVD-Audio */
 540                 case 0x0c:      /* High Precision */
 541                 /* One Bit Audio */
 542                 case 0x08:      /* (Plain) Raw */
 543                 case 0x09:      /* (Plain) SACD */
 544                 case 0x0a:      /* (Encoded) Raw */
 545                 case 0x0b:      /* (Encoded) SACD */
 546                 /* SMPTE Time-Code conformant */
 547                 case 0x0e:
 548                 /* Sample Count */
 549                 case 0x0f:
 550                 /* Anciliary Data */
 551                 case 0x10:
 552                 /* Synchronization Stream (Stereo Raw audio) */
 553                 case 0x40:
 554                 /* Don't care */
 555                 case 0xff:
 556                 default:
 557                         return -ENOSYS; /* not supported */
 558                 }
 559         }
 560 
 561         if (formation->pcm  > AM824_MAX_CHANNELS_FOR_PCM ||
 562             formation->midi > AM824_MAX_CHANNELS_FOR_MIDI)
 563                 return -ENOSYS;
 564 
 565         return 0;
 566 }
 567 
 568 static int
 569 assume_stream_formats(struct snd_oxfw *oxfw, enum avc_general_plug_dir dir,
 570                       unsigned int pid, u8 *buf, unsigned int *len,
 571                       u8 **formats)
 572 {
 573         struct snd_oxfw_stream_formation formation;
 574         unsigned int i, eid;
 575         int err;
 576 
 577         /* get format at current sampling rate */
 578         err = avc_stream_get_format_single(oxfw->unit, dir, pid, buf, len);
 579         if (err < 0) {
 580                 dev_err(&oxfw->unit->device,
 581                 "fail to get current stream format for isoc %s plug %d:%d\n",
 582                         (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
 583                         pid, err);
 584                 goto end;
 585         }
 586 
 587         /* parse and set stream format */
 588         eid = 0;
 589         err = snd_oxfw_stream_parse_format(buf, &formation);
 590         if (err < 0)
 591                 goto end;
 592 
 593         formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, *len,
 594                                     GFP_KERNEL);
 595         if (!formats[eid]) {
 596                 err = -ENOMEM;
 597                 goto end;
 598         }
 599 
 600         /* apply the format for each available sampling rate */
 601         for (i = 0; i < ARRAY_SIZE(oxfw_rate_table); i++) {
 602                 if (formation.rate == oxfw_rate_table[i])
 603                         continue;
 604 
 605                 err = avc_general_inquiry_sig_fmt(oxfw->unit,
 606                                                   oxfw_rate_table[i],
 607                                                   dir, pid);
 608                 if (err < 0)
 609                         continue;
 610 
 611                 eid++;
 612                 formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, *len,
 613                                             GFP_KERNEL);
 614                 if (formats[eid] == NULL) {
 615                         err = -ENOMEM;
 616                         goto end;
 617                 }
 618                 formats[eid][2] = avc_stream_rate_table[i];
 619         }
 620 
 621         err = 0;
 622         oxfw->assumed = true;
 623 end:
 624         return err;
 625 }
 626 
 627 static int fill_stream_formats(struct snd_oxfw *oxfw,
 628                                enum avc_general_plug_dir dir,
 629                                unsigned short pid)
 630 {
 631         u8 *buf, **formats;
 632         unsigned int len, eid = 0;
 633         struct snd_oxfw_stream_formation dummy;
 634         int err;
 635 
 636         buf = kmalloc(AVC_GENERIC_FRAME_MAXIMUM_BYTES, GFP_KERNEL);
 637         if (buf == NULL)
 638                 return -ENOMEM;
 639 
 640         if (dir == AVC_GENERAL_PLUG_DIR_OUT)
 641                 formats = oxfw->tx_stream_formats;
 642         else
 643                 formats = oxfw->rx_stream_formats;
 644 
 645         /* get first entry */
 646         len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
 647         err = avc_stream_get_format_list(oxfw->unit, dir, 0, buf, &len, 0);
 648         if (err == -ENOSYS) {
 649                 /* LIST subfunction is not implemented */
 650                 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
 651                 err = assume_stream_formats(oxfw, dir, pid, buf, &len,
 652                                             formats);
 653                 goto end;
 654         } else if (err < 0) {
 655                 dev_err(&oxfw->unit->device,
 656                         "fail to get stream format %d for isoc %s plug %d:%d\n",
 657                         eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" : "out",
 658                         pid, err);
 659                 goto end;
 660         }
 661 
 662         /* LIST subfunction is implemented */
 663         while (eid < SND_OXFW_STREAM_FORMAT_ENTRIES) {
 664                 /* The format is too short. */
 665                 if (len < 3) {
 666                         err = -EIO;
 667                         break;
 668                 }
 669 
 670                 /* parse and set stream format */
 671                 err = snd_oxfw_stream_parse_format(buf, &dummy);
 672                 if (err < 0)
 673                         break;
 674 
 675                 formats[eid] = devm_kmemdup(&oxfw->card->card_dev, buf, len,
 676                                             GFP_KERNEL);
 677                 if (!formats[eid]) {
 678                         err = -ENOMEM;
 679                         break;
 680                 }
 681 
 682                 /* get next entry */
 683                 len = AVC_GENERIC_FRAME_MAXIMUM_BYTES;
 684                 err = avc_stream_get_format_list(oxfw->unit, dir, 0,
 685                                                  buf, &len, ++eid);
 686                 /* No entries remained. */
 687                 if (err == -EINVAL) {
 688                         err = 0;
 689                         break;
 690                 } else if (err < 0) {
 691                         dev_err(&oxfw->unit->device,
 692                         "fail to get stream format %d for isoc %s plug %d:%d\n",
 693                                 eid, (dir == AVC_GENERAL_PLUG_DIR_IN) ? "in" :
 694                                                                         "out",
 695                                 pid, err);
 696                         break;
 697                 }
 698         }
 699 end:
 700         kfree(buf);
 701         return err;
 702 }
 703 
 704 int snd_oxfw_stream_discover(struct snd_oxfw *oxfw)
 705 {
 706         u8 plugs[AVC_PLUG_INFO_BUF_BYTES];
 707         struct snd_oxfw_stream_formation formation;
 708         u8 *format;
 709         unsigned int i;
 710         int err;
 711 
 712         /* the number of plugs for isoc in/out, ext in/out  */
 713         err = avc_general_get_plug_info(oxfw->unit, 0x1f, 0x07, 0x00, plugs);
 714         if (err < 0) {
 715                 dev_err(&oxfw->unit->device,
 716                 "fail to get info for isoc/external in/out plugs: %d\n",
 717                         err);
 718                 goto end;
 719         } else if ((plugs[0] == 0) && (plugs[1] == 0)) {
 720                 err = -ENOSYS;
 721                 goto end;
 722         }
 723 
 724         /* use oPCR[0] if exists */
 725         if (plugs[1] > 0) {
 726                 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_OUT, 0);
 727                 if (err < 0)
 728                         goto end;
 729 
 730                 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
 731                         format = oxfw->tx_stream_formats[i];
 732                         if (format == NULL)
 733                                 continue;
 734                         err = snd_oxfw_stream_parse_format(format, &formation);
 735                         if (err < 0)
 736                                 continue;
 737 
 738                         /* Add one MIDI port. */
 739                         if (formation.midi > 0)
 740                                 oxfw->midi_input_ports = 1;
 741                 }
 742 
 743                 oxfw->has_output = true;
 744         }
 745 
 746         /* use iPCR[0] if exists */
 747         if (plugs[0] > 0) {
 748                 err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_IN, 0);
 749                 if (err < 0)
 750                         goto end;
 751 
 752                 for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
 753                         format = oxfw->rx_stream_formats[i];
 754                         if (format == NULL)
 755                                 continue;
 756                         err = snd_oxfw_stream_parse_format(format, &formation);
 757                         if (err < 0)
 758                                 continue;
 759 
 760                         /* Add one MIDI port. */
 761                         if (formation.midi > 0)
 762                                 oxfw->midi_output_ports = 1;
 763                 }
 764         }
 765 end:
 766         return err;
 767 }
 768 
 769 void snd_oxfw_stream_lock_changed(struct snd_oxfw *oxfw)
 770 {
 771         oxfw->dev_lock_changed = true;
 772         wake_up(&oxfw->hwdep_wait);
 773 }
 774 
 775 int snd_oxfw_stream_lock_try(struct snd_oxfw *oxfw)
 776 {
 777         int err;
 778 
 779         spin_lock_irq(&oxfw->lock);
 780 
 781         /* user land lock this */
 782         if (oxfw->dev_lock_count < 0) {
 783                 err = -EBUSY;
 784                 goto end;
 785         }
 786 
 787         /* this is the first time */
 788         if (oxfw->dev_lock_count++ == 0)
 789                 snd_oxfw_stream_lock_changed(oxfw);
 790         err = 0;
 791 end:
 792         spin_unlock_irq(&oxfw->lock);
 793         return err;
 794 }
 795 
 796 void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw)
 797 {
 798         spin_lock_irq(&oxfw->lock);
 799 
 800         if (WARN_ON(oxfw->dev_lock_count <= 0))
 801                 goto end;
 802         if (--oxfw->dev_lock_count == 0)
 803                 snd_oxfw_stream_lock_changed(oxfw);
 804 end:
 805         spin_unlock_irq(&oxfw->lock);
 806 }

/* [<][>][^][v][top][bottom][index][help] */