arm: tegra: dc: corrct order to enable/disable dc irq
[linux-2.6.git] / drivers / firewire / core-iso.c
index 0c8e662..57c3973 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/firewire-constants.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
 
@@ -184,6 +185,12 @@ int fw_iso_context_queue(struct fw_iso_context *ctx,
 }
 EXPORT_SYMBOL(fw_iso_context_queue);
 
+void fw_iso_context_queue_flush(struct fw_iso_context *ctx)
+{
+       ctx->card->driver->flush_queue_iso(ctx);
+}
+EXPORT_SYMBOL(fw_iso_context_queue_flush);
+
 int fw_iso_context_stop(struct fw_iso_context *ctx)
 {
        return ctx->card->driver->stop_iso(ctx);
@@ -195,9 +202,10 @@ EXPORT_SYMBOL(fw_iso_context_stop);
  */
 
 static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
-                           int bandwidth, bool allocate, __be32 data[2])
+                           int bandwidth, bool allocate)
 {
        int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0;
+       __be32 data[2];
 
        /*
         * On a 1394a IRM with low contention, try < 1 is enough.
@@ -207,7 +215,7 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
        for (try = 0; try < 5; try++) {
                new = allocate ? old - bandwidth : old + bandwidth;
                if (new < 0 || new > BANDWIDTH_AVAILABLE_INITIAL)
-                       break;
+                       return -EBUSY;
 
                data[0] = cpu_to_be32(old);
                data[1] = cpu_to_be32(new);
@@ -232,52 +240,59 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
 }
 
 static int manage_channel(struct fw_card *card, int irm_id, int generation,
-               u32 channels_mask, u64 offset, bool allocate, __be32 data[2])
+               u32 channels_mask, u64 offset, bool allocate)
 {
-       __be32 c, all, old;
-       int i, retry = 5;
+       __be32 bit, all, old;
+       __be32 data[2];
+       int channel, ret = -EIO, retry = 5;
 
        old = all = allocate ? cpu_to_be32(~0) : 0;
 
-       for (i = 0; i < 32; i++) {
-               if (!(channels_mask & 1 << i))
+       for (channel = 0; channel < 32; channel++) {
+               if (!(channels_mask & 1 << channel))
                        continue;
 
-               c = cpu_to_be32(1 << (31 - i));
-               if ((old & c) != (all & c))
+               ret = -EBUSY;
+
+               bit = cpu_to_be32(1 << (31 - channel));
+               if ((old & bit) != (all & bit))
                        continue;
 
                data[0] = old;
-               data[1] = old ^ c;
+               data[1] = old ^ bit;
                switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
                                           irm_id, generation, SCODE_100,
                                           offset, data, 8)) {
                case RCODE_GENERATION:
                        /* A generation change frees all channels. */
-                       return allocate ? -EAGAIN : i;
+                       return allocate ? -EAGAIN : channel;
 
                case RCODE_COMPLETE:
                        if (data[0] == old)
-                               return i;
+                               return channel;
 
                        old = data[0];
 
                        /* Is the IRM 1394a-2000 compliant? */
-                       if ((data[0] & c) == (data[1] & c))
+                       if ((data[0] & bit) == (data[1] & bit))
                                continue;
 
                        /* 1394-1995 IRM, fall through to retry. */
                default:
-                       if (retry--)
-                               i--;
+                       if (retry) {
+                               retry--;
+                               channel--;
+                       } else {
+                               ret = -EIO;
+                       }
                }
        }
 
-       return -EIO;
+       return ret;
 }
 
 static void deallocate_channel(struct fw_card *card, int irm_id,
-                              int generation, int channel, __be32 buffer[2])
+                              int generation, int channel)
 {
        u32 mask;
        u64 offset;
@@ -286,7 +301,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id,
        offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI :
                                CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO;
 
-       manage_channel(card, irm_id, generation, mask, offset, false, buffer);
+       manage_channel(card, irm_id, generation, mask, offset, false);
 }
 
 /**
@@ -315,7 +330,7 @@ static void deallocate_channel(struct fw_card *card, int irm_id,
  */
 void fw_iso_resource_manage(struct fw_card *card, int generation,
                            u64 channels_mask, int *channel, int *bandwidth,
-                           bool allocate, __be32 buffer[2])
+                           bool allocate)
 {
        u32 channels_hi = channels_mask;        /* channels 31...0 */
        u32 channels_lo = channels_mask >> 32;  /* channels 63...32 */
@@ -328,11 +343,11 @@ void fw_iso_resource_manage(struct fw_card *card, int generation,
        if (channels_hi)
                c = manage_channel(card, irm_id, generation, channels_hi,
                                CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI,
-                               allocate, buffer);
+                               allocate);
        if (channels_lo && c < 0) {
                c = manage_channel(card, irm_id, generation, channels_lo,
                                CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO,
-                               allocate, buffer);
+                               allocate);
                if (c >= 0)
                        c += 32;
        }
@@ -344,14 +359,14 @@ void fw_iso_resource_manage(struct fw_card *card, int generation,
        if (*bandwidth == 0)
                return;
 
-       ret = manage_bandwidth(card, irm_id, generation, *bandwidth,
-                              allocate, buffer);
+       ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate);
        if (ret < 0)
                *bandwidth = 0;
 
        if (allocate && ret < 0) {
                if (c >= 0)
-                       deallocate_channel(card, irm_id, generation, c, buffer);
+                       deallocate_channel(card, irm_id, generation, c);
                *channel = ret;
        }
 }
+EXPORT_SYMBOL(fw_iso_resource_manage);