UBUNTU: SAUCE: fireware: add NO_MSI quirks for o2micro controller
[linux-flexiantxendom0-natty.git] / drivers / firewire / ohci.c
index 3ae84e2..1818a13 100644 (file)
@@ -156,7 +156,6 @@ struct context {
        descriptor_callback_t callback;
 
        struct tasklet_struct tasklet;
-       bool active;
 };
 
 #define IT_HEADER_SY(v)          ((v) <<  0)
@@ -300,6 +299,8 @@ static const struct {
 
        {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID,
                QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
+       {PCI_VENDOR_ID_O2, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_NO_MSI},
 };
 
 /* This overrides anything that was found in ohci_quirks[]. */
@@ -962,7 +963,7 @@ static int ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci,
        for (i = 0; i < AR_WRAPAROUND_PAGES; i++)
                pages[AR_BUFFERS + i] = ctx->pages[i];
        ctx->buffer = vm_map_ram(pages, AR_BUFFERS + AR_WRAPAROUND_PAGES,
-                                -1, PAGE_KERNEL_RO);
+                                -1, PAGE_KERNEL);
        if (!ctx->buffer)
                goto out_of_memory;
 
@@ -1169,7 +1170,6 @@ static struct descriptor *context_get_descriptors(struct context *ctx,
 static void context_run(struct context *ctx, u32 extra)
 {
        struct fw_ohci *ohci = ctx->ohci;
-       ctx->active = true;
 
        reg_write(ohci, COMMAND_PTR(ctx->regs),
                  le32_to_cpu(ctx->last->branch_address));
@@ -1202,7 +1202,6 @@ static void context_stop(struct context *ctx)
        u32 reg;
        int i;
 
-       ctx->active = false;
        reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN);
        ctx->running = false;
        flush_writes(ctx->ohci);
@@ -2166,7 +2165,6 @@ static int ohci_set_config_rom(struct fw_card *card,
 {
        struct fw_ohci *ohci;
        unsigned long flags;
-       int ret = -EBUSY;
        __be32 *next_config_rom;
        dma_addr_t uninitialized_var(next_config_rom_bus);
 
@@ -2207,22 +2205,37 @@ static int ohci_set_config_rom(struct fw_card *card,
 
        spin_lock_irqsave(&ohci->lock, flags);
 
+       /*
+        * If there is not an already pending config_rom update,
+        * push our new allocation into the ohci->next_config_rom
+        * and then mark the local variable as null so that we
+        * won't deallocate the new buffer.
+        *
+        * OTOH, if there is a pending config_rom update, just
+        * use that buffer with the new config_rom data, and
+        * let this routine free the unused DMA allocation.
+        */
+
        if (ohci->next_config_rom == NULL) {
                ohci->next_config_rom = next_config_rom;
                ohci->next_config_rom_bus = next_config_rom_bus;
+               next_config_rom = NULL;
+       }
 
-               copy_config_rom(ohci->next_config_rom, config_rom, length);
+       copy_config_rom(ohci->next_config_rom, config_rom, length);
 
-               ohci->next_header = config_rom[0];
-               ohci->next_config_rom[0] = 0;
+       ohci->next_header = config_rom[0];
+       ohci->next_config_rom[0] = 0;
 
-               reg_write(ohci, OHCI1394_ConfigROMmap,
-                         ohci->next_config_rom_bus);
-               ret = 0;
-       }
+       reg_write(ohci, OHCI1394_ConfigROMmap, ohci->next_config_rom_bus);
 
        spin_unlock_irqrestore(&ohci->lock, flags);
 
+       /* If we didn't use the DMA allocation, delete it. */
+       if (next_config_rom != NULL)
+               dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
+                                 next_config_rom, next_config_rom_bus);
+
        /*
         * Now initiate a bus reset to have the changes take
         * effect. We clean up the old config rom memory and DMA
@@ -2230,13 +2243,10 @@ static int ohci_set_config_rom(struct fw_card *card,
         * controller could need to access it before the bus reset
         * takes effect.
         */
-       if (ret == 0)
-               fw_schedule_bus_reset(&ohci->card, true, true);
-       else
-               dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
-                                 next_config_rom, next_config_rom_bus);
 
-       return ret;
+       fw_schedule_bus_reset(&ohci->card, true, true);
+
+       return 0;
 }
 
 static void ohci_send_request(struct fw_card *card, struct fw_packet *packet)
@@ -2797,13 +2807,13 @@ static void ohci_resume_iso_dma(struct fw_ohci *ohci)
 
        for (i = 0 ; i < ohci->n_ir ; i++) {
                ctx = &ohci->ir_context_list[i];
-               if (ctx->context.active)
+               if (ctx->context.running)
                        ohci_start_iso(&ctx->base, 0, ctx->sync, ctx->tags);
        }
 
        for (i = 0 ; i < ohci->n_it ; i++) {
                ctx = &ohci->it_context_list[i];
-               if (ctx->context.active)
+               if (ctx->context.running)
                        ohci_start_iso(&ctx->base, 0, ctx->sync, ctx->tags);
        }
 }
@@ -3363,11 +3373,11 @@ static int pci_resume(struct pci_dev *dev)
        }
 
        err = ohci_enable(&ohci->card, NULL, 0);
-
        if (err)
                return err;
 
        ohci_resume_iso_dma(ohci);
+
        return 0;
 }
 #endif