[PATCH 2/11] drivers/watchdog: Eliminate a NULL pointer dereference
[safe/jmp/linux-2.6] / drivers / firewire / ohci.c
index 5bbf42e..9f627e7 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/firewire.h>
 #include <linux/firewire-constants.h>
-#include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -35,6 +34,7 @@
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 
@@ -262,13 +262,13 @@ MODULE_PARM_DESC(quirks, "Chip quirks (default = 0"
        ", no 1394a enhancements = "    __stringify(QUIRK_NO_1394A)
        ")");
 
-#ifdef CONFIG_FIREWIRE_OHCI_DEBUG
-
 #define OHCI_PARAM_DEBUG_AT_AR         1
 #define OHCI_PARAM_DEBUG_SELFIDS       2
 #define OHCI_PARAM_DEBUG_IRQS          4
 #define OHCI_PARAM_DEBUG_BUSRESETS     8 /* only effective before chip init */
 
+#ifdef CONFIG_FIREWIRE_OHCI_DEBUG
+
 static int param_debug;
 module_param_named(debug, param_debug, int, 0644);
 MODULE_PARM_DESC(debug, "Verbose logging (default = 0"
@@ -441,9 +441,10 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
 
 #else
 
-#define log_irqs(evt)
-#define log_selfids(node_id, generation, self_id_count, sid)
-#define log_ar_at_event(dir, speed, header, evt)
+#define param_debug 0
+static inline void log_irqs(u32 evt) {}
+static inline void log_selfids(int node_id, int generation, int self_id_count, u32 *s) {}
+static inline void log_ar_at_event(char dir, int speed, u32 *header, int evt) {}
 
 #endif /* CONFIG_FIREWIRE_OHCI_DEBUG */
 
@@ -1205,7 +1206,7 @@ static void handle_local_lock(struct fw_ohci *ohci,
                              struct fw_packet *packet, u32 csr)
 {
        struct fw_packet response;
-       int tcode, length, ext_tcode, sel;
+       int tcode, length, ext_tcode, sel, try;
        __be32 *payload, lock_old;
        u32 lock_arg, lock_data;
 
@@ -1232,21 +1233,26 @@ static void handle_local_lock(struct fw_ohci *ohci,
        reg_write(ohci, OHCI1394_CSRCompareData, lock_arg);
        reg_write(ohci, OHCI1394_CSRControl, sel);
 
-       if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000)
-               lock_old = cpu_to_be32(reg_read(ohci, OHCI1394_CSRData));
-       else
-               fw_notify("swap not done yet\n");
+       for (try = 0; try < 20; try++)
+               if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) {
+                       lock_old = cpu_to_be32(reg_read(ohci,
+                                                       OHCI1394_CSRData));
+                       fw_fill_response(&response, packet->header,
+                                        RCODE_COMPLETE,
+                                        &lock_old, sizeof(lock_old));
+                       goto out;
+               }
+
+       fw_error("swap not done (CSR lock timeout)\n");
+       fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0);
 
-       fw_fill_response(&response, packet->header,
-                        RCODE_COMPLETE, &lock_old, sizeof(lock_old));
  out:
        fw_core_handle_response(&ohci->card, &response);
 }
 
 static void handle_local_request(struct context *ctx, struct fw_packet *packet)
 {
-       u64 offset;
-       u32 csr;
+       u64 offset, csr;
 
        if (ctx == &ctx->ohci->at_request_ctx) {
                packet->ack = ACK_PENDING;
@@ -1393,7 +1399,7 @@ static void bus_reset_tasklet(unsigned long data)
         * was set up before this reset, the old one is now no longer
         * in use and we can free it. Update the config rom pointers
         * to point to the current config rom and clear the
-        * next_config_rom pointer so a new udpate can take place.
+        * next_config_rom pointer so a new update can take place.
         */
 
        if (ohci->next_config_rom != NULL) {
@@ -2401,7 +2407,7 @@ static const struct fw_card_driver ohci_driver = {
 };
 
 #ifdef CONFIG_PPC_PMAC
-static void ohci_pmac_on(struct pci_dev *dev)
+static void pmac_ohci_on(struct pci_dev *dev)
 {
        if (machine_is(powermac)) {
                struct device_node *ofn = pci_device_to_OF_node(dev);
@@ -2413,7 +2419,7 @@ static void ohci_pmac_on(struct pci_dev *dev)
        }
 }
 
-static void ohci_pmac_off(struct pci_dev *dev)
+static void pmac_ohci_off(struct pci_dev *dev)
 {
        if (machine_is(powermac)) {
                struct device_node *ofn = pci_device_to_OF_node(dev);
@@ -2425,8 +2431,8 @@ static void ohci_pmac_off(struct pci_dev *dev)
        }
 }
 #else
-#define ohci_pmac_on(dev)
-#define ohci_pmac_off(dev)
+static inline void pmac_ohci_on(struct pci_dev *dev) {}
+static inline void pmac_ohci_off(struct pci_dev *dev) {}
 #endif /* CONFIG_PPC_PMAC */
 
 static int __devinit pci_probe(struct pci_dev *dev,
@@ -2446,7 +2452,7 @@ static int __devinit pci_probe(struct pci_dev *dev,
 
        fw_card_initialize(&ohci->card, &ohci_driver, &dev->dev);
 
-       ohci_pmac_on(dev);
+       pmac_ohci_on(dev);
 
        err = pci_enable_device(dev);
        if (err) {
@@ -2580,7 +2586,7 @@ static int __devinit pci_probe(struct pci_dev *dev,
        pci_disable_device(dev);
  fail_free:
        kfree(&ohci->card);
-       ohci_pmac_off(dev);
+       pmac_ohci_off(dev);
  fail:
        if (err == -ENOMEM)
                fw_error("Out of memory\n");
@@ -2623,7 +2629,7 @@ static void pci_remove(struct pci_dev *dev)
        pci_release_region(dev, 0);
        pci_disable_device(dev);
        kfree(&ohci->card);
-       ohci_pmac_off(dev);
+       pmac_ohci_off(dev);
 
        fw_notify("Removed fw-ohci device.\n");
 }
@@ -2644,7 +2650,7 @@ static int pci_suspend(struct pci_dev *dev, pm_message_t state)
        err = pci_set_power_state(dev, pci_choose_state(dev, state));
        if (err)
                fw_error("pci_set_power_state failed with %d\n", err);
-       ohci_pmac_off(dev);
+       pmac_ohci_off(dev);
 
        return 0;
 }
@@ -2654,7 +2660,7 @@ static int pci_resume(struct pci_dev *dev)
        struct fw_ohci *ohci = pci_get_drvdata(dev);
        int err;
 
-       ohci_pmac_on(dev);
+       pmac_ohci_on(dev);
        pci_set_power_state(dev, PCI_D0);
        pci_restore_state(dev);
        err = pci_enable_device(dev);