Update of /cvsroot/alsa/alsa-kernel/usb
In directory sc8-pr-cvs1:/tmp/cvs-serv22817/usb

Modified Files:
        usbaudio.c 
Log Message:
- added async_unlink option.
  the default bahevior is not changed yet.
- added some comments.


Index: usbaudio.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/usb/usbaudio.c,v
retrieving revision 1.67
retrieving revision 1.68
diff -u -r1.67 -r1.68
--- usbaudio.c  23 Oct 2003 14:34:53 -0000      1.67
+++ usbaudio.c  13 Nov 2003 11:20:20 -0000      1.68
@@ -23,6 +23,19 @@
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *
+ *  NOTES:
+ *
+ *   - async unlink should be used for avoiding the sleep inside lock.
+ *     however, it causes oops by unknown reason on usb-uhci, and
+ *     disabled as default.  the feature is enabled by async_unlink=1
+ *     option (especially when preempt is used).
+ *   - the linked URBs would be preferred but not used so far because of
+ *     the instability of unlinking.
+ *   - type II is not supported properly.  there is no device which supports
+ *     this type *correctly*.  SB extigy looks as if it supports, but it's
+ *     indeed an AC3 stream packed in SPDIF frames (i.e. no real AC3 stream).
  */
 
 
@@ -56,6 +69,7 @@
 static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Vendor ID for this 
card */
 static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Product ID for 
this card */
 static int nrpacks = 4;                /* max. number of packets per urb */
+static int async_unlink = 0;
 
 MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
@@ -75,21 +89,9 @@
 MODULE_PARM(nrpacks, "i");
 MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
 MODULE_PARM_SYNTAX(nrpacks, SNDRV_ENABLED ",allows:{{2,10}}");
-
-
-/*
- * for using ASYNC unlink mode, define the following.
- * this will make the driver quicker response for request to STOP-trigger,
- * but it may cause oops by some unknown reason (bug of usb driver?),
- * so turning off might be sure.
- */
-/* #define SND_USE_ASYNC_UNLINK */
-
-#ifdef SND_USB_ASYNC_UNLINK
-#define UNLINK_FLAGS   URB_ASYNC_UNLINK
-#else
-#define UNLINK_FLAGS   0
-#endif
+MODULE_PARM(async_unlink, "i");
+MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
+MODULE_PARM_SYNTAX(async_unlink, SNDRV_BOOLEAN_TRUE_DESC);
 
 
 /*
@@ -617,42 +619,51 @@
  * unlink active urbs.
  * return the number of active urbs.
  */
-static int deactivate_urbs(snd_usb_substream_t *subs, int force)
+static int deactivate_urbs(snd_usb_substream_t *subs, int force, int can_sleep)
 {
        unsigned int i;
-       int alive;
+       int alive, async;
 
        subs->running = 0;
 
        if (!force && subs->stream->chip->shutdown) /* to be sure... */
                return 0;
 
-#ifndef SND_USB_ASYNC_UNLINK
-       if (in_interrupt())
+       async = !can_sleep && async_unlink;
+
+       if (! async && in_interrupt())
                return 0;
-#endif
+
        alive = 0;
        for (i = 0; i < subs->nurbs; i++) {
                if (test_bit(i, &subs->active_mask)) {
                        alive++;
-                       if (! test_and_set_bit(i, &subs->unlink_mask))
-                               usb_unlink_urb(subs->dataurb[i].urb);
+                       if (! test_and_set_bit(i, &subs->unlink_mask)) {
+                               struct urb *u = subs->dataurb[i].urb;
+                               if (async)
+                                       u->transfer_flags |= URB_ASYNC_UNLINK;
+                               else
+                                       u->transfer_flags &= ~URB_ASYNC_UNLINK;
+                               usb_unlink_urb(u);
+                       }
                }
        }
        if (subs->syncpipe) {
                for (i = 0; i < SYNC_URBS; i++) {
                        if (test_bit(i+16, &subs->active_mask)) {
                                alive++;
-                               if (! test_and_set_bit(i+16, &subs->unlink_mask))
-                                       usb_unlink_urb(subs->syncurb[i].urb);
+                               if (! test_and_set_bit(i+16, &subs->unlink_mask)) {
+                                       struct urb *u = subs->syncurb[i].urb;
+                                       if (async)
+                                               u->transfer_flags |= URB_ASYNC_UNLINK;
+                                       else
+                                               u->transfer_flags &= ~URB_ASYNC_UNLINK;
+                                       usb_unlink_urb(u);
+                               }
                        }
                }
        }
-#ifdef SND_USB_ASYNC_UNLINK
-       return alive;
-#else
-       return 0;
-#endif
+       return async ? alive : 0;
 }
 
 
@@ -702,7 +713,7 @@
 
  __error:
        // snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
-       deactivate_urbs(subs, 0);
+       deactivate_urbs(subs, 0, 0);
        return -EPIPE;
 }
 
@@ -762,7 +773,7 @@
                err = start_urbs(subs, substream->runtime);
                break;
        case SNDRV_PCM_TRIGGER_STOP:
-               err = deactivate_urbs(subs, 0);
+               err = deactivate_urbs(subs, 0, 0);
                break;
        default:
                err = -EINVAL;
@@ -795,7 +806,8 @@
        int i;
 
        /* stop urbs (to be sure) */
-       if (deactivate_urbs(subs, force) > 0)
+       deactivate_urbs(subs, force, 1);
+       if (async_unlink)
                wait_clear_urbs(subs);
 
        for (i = 0; i < MAX_URBS; i++)
@@ -914,7 +926,7 @@
                }
                u->urb->dev = subs->dev;
                u->urb->pipe = subs->datapipe;
-               u->urb->transfer_flags = URB_ISO_ASAP | UNLINK_FLAGS;
+               u->urb->transfer_flags = URB_ISO_ASAP;
                u->urb->number_of_packets = u->packets;
                u->urb->context = u;
                u->urb->complete = snd_usb_complete_callback(snd_complete_urb);
@@ -936,7 +948,7 @@
                        u->urb->transfer_buffer_length = nrpacks * 3;
                        u->urb->dev = subs->dev;
                        u->urb->pipe = subs->syncpipe;
-                       u->urb->transfer_flags = URB_ISO_ASAP | UNLINK_FLAGS;
+                       u->urb->transfer_flags = URB_ISO_ASAP;
                        u->urb->number_of_packets = u->packets;
                        u->urb->context = u;
                        u->urb->complete = 
snd_usb_complete_callback(snd_complete_sync_urb);



-------------------------------------------------------
This SF.Net email sponsored by: ApacheCon 2003,
16-19 November in Las Vegas. Learn firsthand the latest
developments in Apache, PHP, Perl, XML, Java, MySQL,
WebDAV, and more! http://www.apachecon.com/
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to