]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 28 Dec 2010 19:23:50 +0000 (11:23 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 28 Dec 2010 19:23:50 +0000 (11:23 -0800)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6:
  PCI hotplug: Fix unexpected driver unregister in pciehp_acpi.c

138 files changed:
Documentation/scsi/scsi_mid_low_api.txt
MAINTAINERS
arch/arm/common/it8152.c
arch/arm/mach-at91/include/mach/at91_mci.h
arch/arm/mach-ixp4xx/common-pci.c
arch/powerpc/platforms/52xx/mpc52xx_gpt.c
arch/sh/boards/mach-se/7206/irq.c
arch/sh/kernel/cpu/sh2a/clock-sh7201.c
arch/sh/kernel/cpu/sh4/clock-sh4-202.c
arch/x86/kernel/setup.c
drivers/acpi/acpica/evgpeinit.c
drivers/acpi/battery.c
drivers/acpi/scan.c
drivers/ata/Kconfig
drivers/ata/Makefile
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-sff.c
drivers/ata/pata_cs5536.c
drivers/bluetooth/hci_ldisc.c
drivers/char/ramoops.c
drivers/gpio/cs5535-gpio.c
drivers/media/IR/keymaps/rc-rc6-mce.c
drivers/media/IR/lirc_dev.c
drivers/media/IR/mceusb.c
drivers/media/IR/nuvoton-cir.c
drivers/media/IR/streamzap.c
drivers/media/video/mx2_camera.c
drivers/media/video/s5p-fimc/fimc-capture.c
drivers/media/video/s5p-fimc/fimc-core.c
drivers/media/video/s5p-fimc/fimc-core.h
drivers/media/video/s5p-fimc/regs-fimc.h
drivers/media/video/sh_mobile_ceu_camera.c
drivers/media/video/soc_camera.c
drivers/mmc/core/core.c
drivers/mmc/host/at91_mci.c
drivers/mmc/host/atmel-mci.c
drivers/net/atl1c/atl1c_main.c
drivers/net/benet/be.h
drivers/net/benet/be_cmds.c
drivers/net/benet/be_main.c
drivers/net/bonding/bond_ipv6.c
drivers/net/bonding/bond_main.c
drivers/net/bonding/bonding.h
drivers/net/epic100.c
drivers/net/hamachi.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/sundance.c
drivers/net/tehuti.c
drivers/net/typhoon.c
drivers/net/usb/asix.c
drivers/net/usb/mcs7830.c
drivers/net/veth.c
drivers/net/wireless/hostap/hostap_main.c
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-eeprom.h
drivers/net/wireless/libertas/cfg.c
drivers/net/wireless/p54/p54usb.c
drivers/net/wireless/rt2x00/rt2800pci.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/yellowfin.c
drivers/of/of_i2c.c
drivers/scsi/bfa/bfa_fcs.c
drivers/scsi/bfa/bfa_fcs_fcpim.c
drivers/scsi/bfa/bfa_fcs_lport.c
drivers/scsi/bfa/bfa_fcs_rport.c
drivers/scsi/bfa/bfa_ioc.c
drivers/scsi/bfa/bfa_svc.c
drivers/scsi/bfa/bfad.c
drivers/scsi/bfa/bfad_drv.h
drivers/scsi/bfa/bfad_im.c
drivers/sh/intc/core.c
drivers/spi/mpc52xx_spi.c
drivers/spi/spi_fsl_espi.c
drivers/video/fbmem.c
drivers/video/imxfb.c
drivers/video/sh_mobile_hdmi.c
drivers/video/sh_mobile_lcdcfb.c
fs/ext4/resize.c
fs/ocfs2/aops.c
fs/ocfs2/aops.h
fs/ocfs2/cluster/masklog.c
fs/ocfs2/cluster/masklog.h
fs/ocfs2/dir.c
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/file.c
fs/ocfs2/ocfs2_fs.h
include/linux/kthread.h
include/linux/netlink.h
include/net/flow.h
include/net/ip6_route.h
include/net/mac80211.h
include/net/pkt_cls.h
include/net/sch_generic.h
include/net/sock.h
kernel/kthread.c
mm/nommu.c
mm/percpu.c
net/bluetooth/rfcomm/core.c
net/bridge/br_multicast.c
net/core/fib_rules.c
net/core/sock.c
net/ipv4/fib_frontend.c
net/ipv4/route.c
net/ipv4/tcp_ipv4.c
net/ipv4/udp.c
net/ipv4/udplite.c
net/ipv6/addrconf.c
net/ipv6/ip6_output.c
net/ipv6/route.c
net/ipv6/udp.c
net/ipv6/udplite.c
net/ipv6/xfrm6_output.c
net/irda/af_irda.c
net/mac80211/ibss.c
net/mac80211/rx.c
net/mac80211/work.c
net/sched/sch_sfq.c
net/sctp/socket.c
security/keys/request_key.c
sound/core/pcm_lib.c
sound/pci/hda/hda_codec.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
tools/perf/builtin-buildid-list.c
tools/perf/builtin-probe.c
tools/perf/util/header.c
tools/perf/util/probe-event.c
tools/perf/util/probe-finder.c
tools/perf/util/string.c
tools/perf/util/symbol.c
tools/perf/util/symbol.h

index 570ef2b3d79b16c2f57c01f88d5de3a1a954f6a4..df322c1034667eebbced0792f2c8a7c733e5cf78 100644 (file)
@@ -1044,9 +1044,9 @@ Details:
 
 
 /**
- *      queuecommand - queue scsi command, invoke 'done' on completion
+ *      queuecommand - queue scsi command, invoke scp->scsi_done on completion
+ *      @shost: pointer to the scsi host object
  *      @scp: pointer to scsi command object
- *      @done: function pointer to be invoked on completion
  *
  *      Returns 0 on success.
  *
@@ -1074,42 +1074,45 @@ Details:
  *
  *      Other types of errors that are detected immediately may be
  *      flagged by setting scp->result to an appropriate value,
- *      invoking the 'done' callback, and then returning 0 from this
- *      function. If the command is not performed immediately (and the
- *      LLD is starting (or will start) the given command) then this
- *      function should place 0 in scp->result and return 0.
+ *      invoking the scp->scsi_done callback, and then returning 0
+ *      from this function. If the command is not performed
+ *      immediately (and the LLD is starting (or will start) the given
+ *      command) then this function should place 0 in scp->result and
+ *      return 0.
  *
  *      Command ownership.  If the driver returns zero, it owns the
- *      command and must take responsibility for ensuring the 'done'
- *      callback is executed.  Note: the driver may call done before
- *      returning zero, but after it has called done, it may not
- *      return any value other than zero.  If the driver makes a
- *      non-zero return, it must not execute the command's done
- *      callback at any time.
- *
- *      Locks: struct Scsi_Host::host_lock held on entry (with "irqsave")
- *             and is expected to be held on return.
+ *      command and must take responsibility for ensuring the
+ *      scp->scsi_done callback is executed.  Note: the driver may
+ *      call scp->scsi_done before returning zero, but after it has
+ *      called scp->scsi_done, it may not return any value other than
+ *      zero.  If the driver makes a non-zero return, it must not
+ *      execute the command's scsi_done callback at any time.
+ *
+ *      Locks: up to and including 2.6.36, struct Scsi_Host::host_lock
+ *             held on entry (with "irqsave") and is expected to be
+ *             held on return. From 2.6.37 onwards, queuecommand is
+ *             called without any locks held.
  *
  *      Calling context: in interrupt (soft irq) or process context
  *
- *      Notes: This function should be relatively fast. Normally it will
- *      not wait for IO to complete. Hence the 'done' callback is invoked 
- *      (often directly from an interrupt service routine) some time after
- *      this function has returned. In some cases (e.g. pseudo adapter 
- *      drivers that manufacture the response to a SCSI INQUIRY)
- *      the 'done' callback may be invoked before this function returns.
- *      If the 'done' callback is not invoked within a certain period
- *      the SCSI mid level will commence error processing.
- *      If a status of CHECK CONDITION is placed in "result" when the
- *      'done' callback is invoked, then the LLD driver should 
- *      perform autosense and fill in the struct scsi_cmnd::sense_buffer
+ *      Notes: This function should be relatively fast. Normally it
+ *      will not wait for IO to complete. Hence the scp->scsi_done
+ *      callback is invoked (often directly from an interrupt service
+ *      routine) some time after this function has returned. In some
+ *      cases (e.g. pseudo adapter drivers that manufacture the
+ *      response to a SCSI INQUIRY) the scp->scsi_done callback may be
+ *      invoked before this function returns.  If the scp->scsi_done
+ *      callback is not invoked within a certain period the SCSI mid
+ *      level will commence error processing.  If a status of CHECK
+ *      CONDITION is placed in "result" when the scp->scsi_done
+ *      callback is invoked, then the LLD driver should perform
+ *      autosense and fill in the struct scsi_cmnd::sense_buffer
  *      array. The scsi_cmnd::sense_buffer array is zeroed prior to
  *      the mid level queuing a command to an LLD.
  *
  *      Defined in: LLD
  **/
-    int queuecommand(struct scsi_cmnd * scp, 
-                     void (*done)(struct scsi_cmnd *))
+    int queuecommand(struct Scsi_Host *shost, struct scsi_cmnd * scp)
 
 
 /**
index 239782e51f776d6aff7e72d9400ed458a8bd2a43..71e40f9118df5d9d1f002a84f48e8600ac533176 100644 (file)
@@ -4590,7 +4590,7 @@ F:        drivers/pcmcia/
 F:     include/pcmcia/
 
 PCNET32 NETWORK DRIVER
-M:     Don Fry <pcnet32@verizon.net>
+M:     Don Fry <pcnet32@frontier.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/pcnet32.c
index 1bec96e851967101df7a796745b84d24bd320ab8..42ff90b46dfb1f1e0e91fdfe370f493e0b81551f 100644 (file)
@@ -352,3 +352,4 @@ struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys)
        return pci_scan_bus(nr, &it8152_ops, sys);
 }
 
+EXPORT_SYMBOL(dma_set_coherent_mask);
index 57f8ee154943d91b50882a7b01ab2d602d5ba631..27ac6f550fe36eb686e8c180a727c8bf29d2c286 100644 (file)
@@ -74,6 +74,8 @@
 #define                        AT91_MCI_TRTYP_BLOCK    (0 << 19)
 #define                        AT91_MCI_TRTYP_MULTIPLE (1 << 19)
 #define                        AT91_MCI_TRTYP_STREAM   (2 << 19)
+#define                        AT91_MCI_TRTYP_SDIO_BYTE        (4 << 19)
+#define                        AT91_MCI_TRTYP_SDIO_BLOCK       (5 << 19)
 
 #define AT91_MCI_BLKR          0x18            /* Block Register */
 #define                AT91_MCI_BLKR_BCNT(n)   ((0xffff & (n)) << 0)   /* Block count */
index 24498a932ba65b8054de5ba8229ef0e0c838dd71..a54b3db8036678c8c385705b7c22b763769bb515 100644 (file)
@@ -513,4 +513,4 @@ int dma_set_coherent_mask(struct device *dev, u64 mask)
 
 EXPORT_SYMBOL(ixp4xx_pci_read);
 EXPORT_SYMBOL(ixp4xx_pci_write);
-
+EXPORT_SYMBOL(dma_set_coherent_mask);
index fea833e18ad58ab92c78da66e35e2f23dcacd8ff..e0d703c7fdf7cc3e7d1491a963db90ad4735b9e4 100644 (file)
@@ -63,6 +63,7 @@
 #include <linux/of_gpio.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/fs.h>
 #include <linux/watchdog.h>
 #include <linux/miscdevice.h>
 #include <linux/uaccess.h>
index d961949600fd462199f3d9706e86371e815e7b1b..9070d7e607047fccec2d51b865dfe89307cd5d41 100644 (file)
@@ -140,7 +140,7 @@ void __init init_se7206_IRQ(void)
        make_se7206_irq(IRQ1_IRQ); /* ATA */
        make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */
 
-       __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR); /* ICR1 */
+       __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR1); /* ICR1 */
 
        /* FPGA System register setup*/
        __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */
index b26264dc2aefef75e0292cb6c9a4862e8b4f9785..c509c40cba4bfefe3917f5eec9b2ddea3c63763d 100644 (file)
@@ -34,7 +34,7 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12};
 
 static void master_clk_init(struct clk *clk)
 {
-       return 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
+       clk->rate = 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
 }
 
 static struct clk_ops sh7201_master_clk_ops = {
index b601fa3978d1995f53ea466e6aed5145e6ef1f75..6282a839e08e7831c40403c8a8c576ab97242df4 100644 (file)
@@ -81,8 +81,7 @@ static void shoc_clk_init(struct clk *clk)
        for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) {
                int divisor = frqcr3_divisors[i];
 
-               if (clk->ops->set_rate(clk, clk->parent->rate /
-                                               divisor, 0) == 0)
+               if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0)
                        break;
        }
 
index 85268f8eadf667c6034c06882ed661cb7d03e4a8..a0f52af256a037eaca0fce91e00caad47018d65d 100644 (file)
@@ -501,7 +501,18 @@ static inline unsigned long long get_total_mem(void)
        return total << PAGE_SHIFT;
 }
 
-#define DEFAULT_BZIMAGE_ADDR_MAX 0x37FFFFFF
+/*
+ * Keep the crash kernel below this limit.  On 32 bits earlier kernels
+ * would limit the kernel to the low 512 MiB due to mapping restrictions.
+ * On 64 bits, kexec-tools currently limits us to 896 MiB; increase this
+ * limit once kexec-tools are fixed.
+ */
+#ifdef CONFIG_X86_32
+# define CRASH_KERNEL_ADDR_MAX (512 << 20)
+#else
+# define CRASH_KERNEL_ADDR_MAX (896 << 20)
+#endif
+
 static void __init reserve_crashkernel(void)
 {
        unsigned long long total_mem;
@@ -520,10 +531,10 @@ static void __init reserve_crashkernel(void)
                const unsigned long long alignment = 16<<20;    /* 16M */
 
                /*
-                *  kexec want bzImage is below DEFAULT_BZIMAGE_ADDR_MAX
+                *  kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
                 */
                crash_base = memblock_find_in_range(alignment,
-                              DEFAULT_BZIMAGE_ADDR_MAX, crash_size, alignment);
+                              CRASH_KERNEL_ADDR_MAX, crash_size, alignment);
 
                if (crash_base == MEMBLOCK_ERROR) {
                        pr_info("crashkernel reservation failed - No suitable area found.\n");
index 2c7def95f721c6d08596c9ce852a3ac4a1c54e38..4c8dea513b66adeea7881d7f541237c812e5bf14 100644 (file)
@@ -408,6 +408,9 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
                return_ACPI_STATUS(AE_OK);
        }
 
+       /* Disable the GPE in case it's been enabled already. */
+       (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
+
        /*
         * Add the GPE information from above to the gpe_event_info block for
         * use during dispatch of this GPE.
index 9fb9d5ac939db1c071c4cdcaa7fba49364236e25..95649d373071ac93d14bbbb478db1ab4a8cdb801 100644 (file)
@@ -130,8 +130,6 @@ struct acpi_battery {
        unsigned long flags;
 };
 
-static int acpi_battery_update(struct acpi_battery *battery);
-
 #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
 
 inline int acpi_battery_present(struct acpi_battery *battery)
@@ -186,9 +184,6 @@ static int acpi_battery_get_property(struct power_supply *psy,
        int ret = 0;
        struct acpi_battery *battery = to_acpi_battery(psy);
 
-       if (acpi_battery_update(battery))
-               return -ENODEV;
-
        if (acpi_battery_present(battery)) {
                /* run battery update only if it is present */
                acpi_battery_get_state(battery);
index 2b6c21d86b9885571b41679586636fff3b6c53bb..29ef505c487b92efe1b12e79c2231aa85c0298ce 100644 (file)
@@ -705,54 +705,85 @@ static int acpi_bus_get_perf_flags(struct acpi_device *device)
 }
 
 static acpi_status
-acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device,
-                                            union acpi_object *package)
+acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
+                                            struct acpi_device_wakeup *wakeup)
 {
-       int i = 0;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+       union acpi_object *package = NULL;
        union acpi_object *element = NULL;
+       acpi_status status;
+       int i = 0;
 
-       if (!device || !package || (package->package.count < 2))
+       if (!wakeup)
                return AE_BAD_PARAMETER;
 
+       /* _PRW */
+       status = acpi_evaluate_object(handle, "_PRW", NULL, &buffer);
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
+               return status;
+       }
+
+       package = (union acpi_object *)buffer.pointer;
+
+       if (!package || (package->package.count < 2)) {
+               status = AE_BAD_DATA;
+               goto out;
+       }
+
        element = &(package->package.elements[0]);
-       if (!element)
-               return AE_BAD_PARAMETER;
+       if (!element) {
+               status = AE_BAD_DATA;
+               goto out;
+       }
        if (element->type == ACPI_TYPE_PACKAGE) {
                if ((element->package.count < 2) ||
                    (element->package.elements[0].type !=
                     ACPI_TYPE_LOCAL_REFERENCE)
-                   || (element->package.elements[1].type != ACPI_TYPE_INTEGER))
-                       return AE_BAD_DATA;
-               device->wakeup.gpe_device =
+                   || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) {
+                       status = AE_BAD_DATA;
+                       goto out;
+               }
+               wakeup->gpe_device =
                    element->package.elements[0].reference.handle;
-               device->wakeup.gpe_number =
+               wakeup->gpe_number =
                    (u32) element->package.elements[1].integer.value;
        } else if (element->type == ACPI_TYPE_INTEGER) {
-               device->wakeup.gpe_number = element->integer.value;
-       } else
-               return AE_BAD_DATA;
+               wakeup->gpe_device = NULL;
+               wakeup->gpe_number = element->integer.value;
+       } else {
+               status = AE_BAD_DATA;
+               goto out;
+       }
 
        element = &(package->package.elements[1]);
        if (element->type != ACPI_TYPE_INTEGER) {
-               return AE_BAD_DATA;
+               status = AE_BAD_DATA;
+               goto out;
        }
-       device->wakeup.sleep_state = element->integer.value;
+       wakeup->sleep_state = element->integer.value;
 
        if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
-               return AE_NO_MEMORY;
+               status = AE_NO_MEMORY;
+               goto out;
        }
-       device->wakeup.resources.count = package->package.count - 2;
-       for (i = 0; i < device->wakeup.resources.count; i++) {
+       wakeup->resources.count = package->package.count - 2;
+       for (i = 0; i < wakeup->resources.count; i++) {
                element = &(package->package.elements[i + 2]);
-               if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
-                       return AE_BAD_DATA;
+               if (element->type != ACPI_TYPE_LOCAL_REFERENCE) {
+                       status = AE_BAD_DATA;
+                       goto out;
+               }
 
-               device->wakeup.resources.handles[i] = element->reference.handle;
+               wakeup->resources.handles[i] = element->reference.handle;
        }
 
-       acpi_gpe_can_wake(device->wakeup.gpe_device, device->wakeup.gpe_number);
+       acpi_gpe_can_wake(wakeup->gpe_device, wakeup->gpe_number);
 
-       return AE_OK;
+ out:
+       kfree(buffer.pointer);
+
+       return status;
 }
 
 static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
@@ -787,26 +818,15 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
 static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
 {
        acpi_status status = 0;
-       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-       union acpi_object *package = NULL;
        int psw_error;
 
-       /* _PRW */
-       status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
-               goto end;
-       }
-
-       package = (union acpi_object *)buffer.pointer;
-       status = acpi_bus_extract_wakeup_device_power_package(device, package);
+       status = acpi_bus_extract_wakeup_device_power_package(device->handle,
+                                                             &device->wakeup);
        if (ACPI_FAILURE(status)) {
                ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package"));
                goto end;
        }
 
-       kfree(buffer.pointer);
-
        device->wakeup.flags.valid = 1;
        device->wakeup.prepare_count = 0;
        acpi_bus_set_run_wake_flags(device);
@@ -1351,6 +1371,7 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
        struct acpi_bus_ops *ops = context;
        int type;
        unsigned long long sta;
+       struct acpi_device_wakeup wakeup;
        struct acpi_device *device;
        acpi_status status;
        int result;
@@ -1360,8 +1381,10 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
                return AE_OK;
 
        if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
-           !(sta & ACPI_STA_DEVICE_FUNCTIONING))
+           !(sta & ACPI_STA_DEVICE_FUNCTIONING)) {
+               acpi_bus_extract_wakeup_device_power_package(handle, &wakeup);
                return AE_CTRL_DEPTH;
+       }
 
        /*
         * We may already have an acpi_device from a previous enumeration.  If
index 11ec911016c6ab3e81cefe7e202c4cc4c95762f0..36e2319264bd33d7918979105a4f641da36d3dcd 100644 (file)
@@ -128,16 +128,6 @@ config PDC_ADMA
 
          If unsure, say N.
 
-config PATA_MPC52xx
-       tristate "Freescale MPC52xx SoC internal IDE"
-       depends on PPC_MPC52xx && PPC_BESTCOMM
-       select PPC_BESTCOMM_ATA
-       help
-         This option enables support for integrated IDE controller
-         of the Freescale MPC52xx SoC.
-
-         If unsure, say N.
-
 config PATA_OCTEON_CF
        tristate "OCTEON Boot Bus Compact Flash support"
        depends on CPU_CAVIUM_OCTEON
@@ -366,7 +356,7 @@ config PATA_CS5535
 
 config PATA_CS5536
        tristate "CS5536 PATA support"
-       depends on PCI && X86 && !X86_64
+       depends on PCI
        help
          This option enables support for the AMD CS5536
          companion chip used with the Geode LX processor family.
@@ -491,6 +481,16 @@ config PATA_MARVELL
 
          If unsure, say N.
 
+config PATA_MPC52xx
+       tristate "Freescale MPC52xx SoC internal IDE"
+       depends on PPC_MPC52xx && PPC_BESTCOMM
+       select PPC_BESTCOMM_ATA
+       help
+         This option enables support for integrated IDE controller
+         of the Freescale MPC52xx SoC.
+
+         If unsure, say N.
+
 config PATA_NETCELL
        tristate "NETCELL Revolution RAID support"
        depends on PCI
index c501af5b12b959209bde413d9b8bbe35f7be5068..2b67c900a459865c694e0cf012ebcacbfd8f76bd 100644 (file)
@@ -11,7 +11,6 @@ obj-$(CONFIG_SATA_DWC)                += sata_dwc_460ex.o
 
 # SFF w/ custom DMA
 obj-$(CONFIG_PDC_ADMA)         += pdc_adma.o
-obj-$(CONFIG_PATA_MPC52xx)     += pata_mpc52xx.o
 obj-$(CONFIG_PATA_OCTEON_CF)   += pata_octeon_cf.o
 obj-$(CONFIG_SATA_QSTOR)       += sata_qstor.o
 obj-$(CONFIG_SATA_SX4)         += sata_sx4.o
@@ -52,6 +51,7 @@ obj-$(CONFIG_PATA_IT821X)     += pata_it821x.o
 obj-$(CONFIG_PATA_JMICRON)     += pata_jmicron.o
 obj-$(CONFIG_PATA_MACIO)       += pata_macio.o
 obj-$(CONFIG_PATA_MARVELL)     += pata_marvell.o
+obj-$(CONFIG_PATA_MPC52xx)     += pata_mpc52xx.o
 obj-$(CONFIG_PATA_NETCELL)     += pata_netcell.o
 obj-$(CONFIG_PATA_NINJA32)     += pata_ninja32.o
 obj-$(CONFIG_PATA_NS87415)     += pata_ns87415.o
index 7f77c67d267ca454f63b5501ab1bb82d5fe9f16d..f23d6d46b95b1bf7f4f19fb657f86cadc0ccd6b7 100644 (file)
@@ -4807,9 +4807,6 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc)
 {
        struct ata_device *dev = qc->dev;
 
-       if (ata_tag_internal(qc->tag))
-               return;
-
        if (ata_is_nodata(qc->tf.protocol))
                return;
 
@@ -4858,14 +4855,23 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
                if (unlikely(qc->err_mask))
                        qc->flags |= ATA_QCFLAG_FAILED;
 
-               if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
-                       /* always fill result TF for failed qc */
+               /*
+                * Finish internal commands without any further processing
+                * and always with the result TF filled.
+                */
+               if (unlikely(ata_tag_internal(qc->tag))) {
                        fill_result_tf(qc);
+                       __ata_qc_complete(qc);
+                       return;
+               }
 
-                       if (!ata_tag_internal(qc->tag))
-                               ata_qc_schedule_eh(qc);
-                       else
-                               __ata_qc_complete(qc);
+               /*
+                * Non-internal qc has failed.  Fill the result TF and
+                * summon EH.
+                */
+               if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
+                       fill_result_tf(qc);
+                       ata_qc_schedule_eh(qc);
                        return;
                }
 
index 5e590504f3aa15c6c3c73450327a0494c264d20f..17a637877d0311abb7c95c7cd6e2359be4a2c70b 100644 (file)
@@ -3275,6 +3275,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
        struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL;
        struct ata_eh_context *ehc = &link->eh_context;
        struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL;
+       enum ata_lpm_policy old_policy = link->lpm_policy;
        unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM;
        unsigned int err_mask;
        int rc;
@@ -3338,6 +3339,14 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
                goto fail;
        }
 
+       /*
+        * Low level driver acked the transition.  Issue DIPM command
+        * with the new policy set.
+        */
+       link->lpm_policy = policy;
+       if (ap && ap->slave_link)
+               ap->slave_link->lpm_policy = policy;
+
        /* host config updated, enable DIPM if transitioning to MIN_POWER */
        ata_for_each_dev(dev, link, ENABLED) {
                if (policy == ATA_LPM_MIN_POWER && ata_id_has_dipm(dev->id)) {
@@ -3353,12 +3362,14 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
                }
        }
 
-       link->lpm_policy = policy;
-       if (ap && ap->slave_link)
-               ap->slave_link->lpm_policy = policy;
        return 0;
 
 fail:
+       /* restore the old policy */
+       link->lpm_policy = old_policy;
+       if (ap && ap->slave_link)
+               ap->slave_link->lpm_policy = old_policy;
+
        /* if no device or only one more chance is left, disable LPM */
        if (!dev || ehc->tries[dev->devno] <= 2) {
                ata_link_printk(link, KERN_WARNING,
index d05387d1e14be5aedf2f23dae45e86b7ed989276..484697fef3867dce2c1926f0ad50bb53de3b40e7 100644 (file)
@@ -1532,11 +1532,10 @@ static unsigned int __ata_sff_port_intr(struct ata_port *ap,
                if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
                        return ata_sff_idle_irq(ap);
                break;
-       case HSM_ST:
-       case HSM_ST_LAST:
-               break;
-       default:
+       case HSM_ST_IDLE:
                return ata_sff_idle_irq(ap);
+       default:
+               break;
        }
 
        /* check main status, clearing INTRQ if needed */
index 21ee23f89e88b153ee8e35af5d75c61f83f92496..628c8fae5937183f24b9a607c17f0765609a3a5e 100644 (file)
 #include <linux/delay.h>
 #include <linux/libata.h>
 #include <scsi/scsi_host.h>
+
+#ifdef CONFIG_X86_32
 #include <asm/msr.h>
+static int use_msr;
+module_param_named(msr, use_msr, int, 0644);
+MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)");
+#else
+#undef rdmsr   /* avoid accidental MSR usage on, e.g. x86-64 */
+#undef wrmsr
+#define rdmsr(x, y, z) do { } while (0)
+#define wrmsr(x, y, z) do { } while (0)
+#define use_msr 0
+#endif
 
 #define DRV_NAME       "pata_cs5536"
-#define DRV_VERSION    "0.0.7"
+#define DRV_VERSION    "0.0.8"
 
 enum {
        CFG                     = 0,
@@ -75,8 +87,6 @@ enum {
        IDE_ETC_NODMA           = 0x03,
 };
 
-static int use_msr;
-
 static const u32 msr_reg[4] = {
        MSR_IDE_CFG, MSR_IDE_DTC, MSR_IDE_CAST, MSR_IDE_ETC,
 };
@@ -88,7 +98,7 @@ static const u8 pci_reg[4] = {
 static inline int cs5536_read(struct pci_dev *pdev, int reg, u32 *val)
 {
        if (unlikely(use_msr)) {
-               u32 dummy;
+               u32 dummy __maybe_unused;
 
                rdmsr(msr_reg[reg], *val, dummy);
                return 0;
@@ -294,8 +304,6 @@ MODULE_DESCRIPTION("low-level driver for the CS5536 IDE controller");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, cs5536);
 MODULE_VERSION(DRV_VERSION);
-module_param_named(msr, use_msr, int, 0644);
-MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)");
 
 module_init(cs5536_init);
 module_exit(cs5536_exit);
index 720148294e648473a1a82cc0c68f50ac1fd923c3..3c6cabcb7d84b0428cdeae91b3f9a98f2bc85715 100644 (file)
@@ -311,8 +311,10 @@ static void hci_uart_tty_close(struct tty_struct *tty)
 
                if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
                        hu->proto->close(hu);
-                       hci_unregister_dev(hdev);
-                       hci_free_dev(hdev);
+                       if (hdev) {
+                               hci_unregister_dev(hdev);
+                               hci_free_dev(hdev);
+                       }
                }
        }
 }
index 73dcb0ee41fdaebcbefee2b0ddf705bd5a26b1e9..d3d63be2cd37efc15c5b261ab10492ba8b01caf6 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/ramoops.h>
 
 #define RAMOOPS_KERNMSG_HDR "===="
-#define RAMOOPS_HEADER_SIZE   (5 + sizeof(struct timeval))
 
 #define RECORD_SIZE 4096
 
@@ -65,8 +64,8 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper,
                        struct ramoops_context, dump);
        unsigned long s1_start, s2_start;
        unsigned long l1_cpy, l2_cpy;
-       int res;
-       char *buf;
+       int res, hdr_size;
+       char *buf, *buf_orig;
        struct timeval timestamp;
 
        /* Only dump oopses if dump_oops is set */
@@ -74,6 +73,8 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper,
                return;
 
        buf = (char *)(cxt->virt_addr + (cxt->count * RECORD_SIZE));
+       buf_orig = buf;
+
        memset(buf, '\0', RECORD_SIZE);
        res = sprintf(buf, "%s", RAMOOPS_KERNMSG_HDR);
        buf += res;
@@ -81,8 +82,9 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper,
        res = sprintf(buf, "%lu.%lu\n", (long)timestamp.tv_sec, (long)timestamp.tv_usec);
        buf += res;
 
-       l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE));
-       l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE) - l2_cpy);
+       hdr_size = buf - buf_orig;
+       l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - hdr_size));
+       l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - hdr_size) - l2_cpy);
 
        s2_start = l2 - l2_cpy;
        s1_start = l1 - l1_cpy;
index 599f6c9e0fbf18661d7607407d11b73cd3cda7ff..d3e55a0ae92be02e5f46ea7d6f7f82c87e75c807 100644 (file)
@@ -56,15 +56,26 @@ static struct cs5535_gpio_chip {
  * registers, see include/linux/cs5535.h.
  */
 
-static void errata_outl(u32 val, unsigned long addr)
+static void errata_outl(struct cs5535_gpio_chip *chip, u32 val,
+               unsigned int reg)
 {
+       unsigned long addr = chip->base + 0x80 + reg;
+
        /*
         * According to the CS5536 errata (#36), after suspend
         * a write to the high bank GPIO register will clear all
         * non-selected bits; the recommended workaround is a
         * read-modify-write operation.
+        *
+        * Don't apply this errata to the edge status GPIOs, as writing
+        * to their lower bits will clear them.
         */
-       val |= inl(addr);
+       if (reg != GPIO_POSITIVE_EDGE_STS && reg != GPIO_NEGATIVE_EDGE_STS) {
+               if (val & 0xffff)
+                       val |= (inl(addr) & 0xffff); /* ignore the high bits */
+               else
+                       val |= (inl(addr) ^ (val >> 16));
+       }
        outl(val, addr);
 }
 
@@ -76,7 +87,7 @@ static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
                outl(1 << offset, chip->base + reg);
        else
                /* high bank register */
-               errata_outl(1 << (offset - 16), chip->base + 0x80 + reg);
+               errata_outl(chip, 1 << (offset - 16), reg);
 }
 
 void cs5535_gpio_set(unsigned offset, unsigned int reg)
@@ -98,7 +109,7 @@ static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
                outl(1 << (offset + 16), chip->base + reg);
        else
                /* high bank register */
-               errata_outl(1 << offset, chip->base + 0x80 + reg);
+               errata_outl(chip, 1 << offset, reg);
 }
 
 void cs5535_gpio_clear(unsigned offset, unsigned int reg)
index 1b7adabbcee99d4affc24f48e335f33cb3dd409e..6da955dfef48989a1773792f09bf1715326a86b5 100644 (file)
@@ -26,8 +26,8 @@ static struct ir_scancode rc6_mce[] = {
 
        { 0x800f040a, KEY_DELETE },
        { 0x800f040b, KEY_ENTER },
-       { 0x800f040c, KEY_POWER },
-       { 0x800f040d, KEY_PROG1 },              /* Windows MCE button */
+       { 0x800f040c, KEY_POWER },              /* PC Power */
+       { 0x800f040d, KEY_PROG1 },              /* Windows MCE button */
        { 0x800f040e, KEY_MUTE },
        { 0x800f040f, KEY_INFO },
 
@@ -56,31 +56,32 @@ static struct ir_scancode rc6_mce[] = {
        { 0x800f0422, KEY_OK },
        { 0x800f0423, KEY_EXIT },
        { 0x800f0424, KEY_DVD },
-       { 0x800f0425, KEY_TUNER },              /* LiveTV */
-       { 0x800f0426, KEY_EPG },                /* Guide */
-       { 0x800f0427, KEY_ZOOM },               /* Aspect */
+       { 0x800f0425, KEY_TUNER },              /* LiveTV */
+       { 0x800f0426, KEY_EPG },                /* Guide */
+       { 0x800f0427, KEY_ZOOM },               /* Aspect */
 
        { 0x800f043a, KEY_BRIGHTNESSUP },
 
        { 0x800f0446, KEY_TV },
-       { 0x800f0447, KEY_AUDIO },              /* My Music */
-       { 0x800f0448, KEY_PVR },                /* RecordedTV */
+       { 0x800f0447, KEY_AUDIO },              /* My Music */
+       { 0x800f0448, KEY_PVR },                /* RecordedTV */
        { 0x800f0449, KEY_CAMERA },
        { 0x800f044a, KEY_VIDEO },
        { 0x800f044c, KEY_LANGUAGE },
        { 0x800f044d, KEY_TITLE },
-       { 0x800f044e, KEY_PRINT },      /* Print - HP OEM version of remote */
+       { 0x800f044e, KEY_PRINT },      /* Print - HP OEM version of remote */
 
        { 0x800f0450, KEY_RADIO },
 
-       { 0x800f045a, KEY_SUBTITLE },           /* Caption/Teletext */
+       { 0x800f045a, KEY_SUBTITLE },           /* Caption/Teletext */
        { 0x800f045b, KEY_RED },
        { 0x800f045c, KEY_GREEN },
        { 0x800f045d, KEY_YELLOW },
        { 0x800f045e, KEY_BLUE },
 
+       { 0x800f0465, KEY_POWER2 },     /* TV Power */
        { 0x800f046e, KEY_PLAYPAUSE },
-       { 0x800f046f, KEY_MEDIA },      /* Start media application (NEW) */
+       { 0x800f046f, KEY_MEDIA },      /* Start media application (NEW) */
 
        { 0x800f0480, KEY_BRIGHTNESSDOWN },
        { 0x800f0481, KEY_PLAYPAUSE },
index 8418b14ee4d2244ee3b6528549d0d22f35c85159..756656e17bddb035dbff24529155a86e82d19b3c 100644 (file)
@@ -522,10 +522,8 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait)
 
        dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor);
 
-       if (!ir->attached) {
-               mutex_unlock(&ir->irctl_lock);
+       if (!ir->attached)
                return POLLERR;
-       }
 
        poll_wait(file, &ir->buf->wait_poll, wait);
 
@@ -649,18 +647,18 @@ ssize_t lirc_dev_fop_read(struct file *file,
        if (!buf)
                return -ENOMEM;
 
-       if (mutex_lock_interruptible(&ir->irctl_lock))
-               return -ERESTARTSYS;
+       if (mutex_lock_interruptible(&ir->irctl_lock)) {
+               ret = -ERESTARTSYS;
+               goto out_unlocked;
+       }
        if (!ir->attached) {
-               mutex_unlock(&ir->irctl_lock);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto out_locked;
        }
 
        if (length % ir->chunk_size) {
-               dev_dbg(ir->d.dev, LOGHEAD "read result = -EINVAL\n",
-                       ir->d.name, ir->d.minor);
-               mutex_unlock(&ir->irctl_lock);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_locked;
        }
 
        /*
@@ -711,18 +709,23 @@ ssize_t lirc_dev_fop_read(struct file *file,
                        lirc_buffer_read(ir->buf, buf);
                        ret = copy_to_user((void *)buffer+written, buf,
                                           ir->buf->chunk_size);
-                       written += ir->buf->chunk_size;
+                       if (!ret)
+                               written += ir->buf->chunk_size;
+                       else
+                               ret = -EFAULT;
                }
        }
 
        remove_wait_queue(&ir->buf->wait_poll, &wait);
        set_current_state(TASK_RUNNING);
+
+out_locked:
        mutex_unlock(&ir->irctl_lock);
 
 out_unlocked:
        kfree(buf);
        dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n",
-               ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret);
+               ir->d.name, ir->d.minor, ret ? "<fail>" : "<ok>", ret);
 
        return ret ? ret : written;
 }
index 9dce684fd23113d13a3d445995983089cff56c60..392ca24132dafd5456e905fa61c216d566703976 100644 (file)
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <linux/usb.h>
 #include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/usb/input.h>
 #include <media/ir-core.h>
-#include <media/ir-common.h>
 
 #define DRIVER_VERSION "1.91"
 #define DRIVER_AUTHOR  "Jarod Wilson <jarod@wilsonet.com>"
@@ -49,6 +49,7 @@
 #define USB_BUFLEN             32 /* USB reception buffer length */
 #define USB_CTRL_MSG_SZ                2  /* Size of usb ctrl msg on gen1 hw */
 #define MCE_G1_INIT_MSGS       40 /* Init messages on gen1 hw to throw out */
+#define MS_TO_NS(msec)         ((msec) * 1000)
 
 /* MCE constants */
 #define MCE_CMDBUF_SIZE                384  /* MCE Command buffer length */
@@ -74,6 +75,7 @@
 #define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */
 
 /* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */
+#define MCE_CMD_SIG_END                0x01    /* End of signal */
 #define MCE_CMD_PING           0x03    /* Ping device */
 #define MCE_CMD_UNKNOWN                0x04    /* Unknown */
 #define MCE_CMD_UNKNOWN2       0x05    /* Unknown */
@@ -91,6 +93,7 @@
 #define MCE_CMD_G_TXMASK       0x13    /* Set TX port bitmask */
 #define MCE_CMD_S_RXSENSOR     0x14    /* Set RX sensor (std/learning) */
 #define MCE_CMD_G_RXSENSOR     0x15    /* Get RX sensor (std/learning) */
+#define MCE_RSP_PULSE_COUNT    0x15    /* RX pulse count (only if learning) */
 #define MCE_CMD_TX_PORTS       0x16    /* Get number of TX ports */
 #define MCE_CMD_G_WAKESRC      0x17    /* Get wake source */
 #define MCE_CMD_UNKNOWN7       0x18    /* Unknown */
@@ -146,14 +149,16 @@ enum mceusb_model_type {
        MCE_GEN3,
        MCE_GEN2_TX_INV,
        POLARIS_EVK,
+       CX_HYBRID_TV,
 };
 
 struct mceusb_model {
        u32 mce_gen1:1;
        u32 mce_gen2:1;
        u32 mce_gen3:1;
-       u32 tx_mask_inverted:1;
+       u32 tx_mask_normal:1;
        u32 is_polaris:1;
+       u32 no_tx:1;
 
        const char *rc_map;     /* Allow specify a per-board map */
        const char *name;       /* per-board name */
@@ -162,18 +167,18 @@ struct mceusb_model {
 static const struct mceusb_model mceusb_model[] = {
        [MCE_GEN1] = {
                .mce_gen1 = 1,
-               .tx_mask_inverted = 1,
+               .tx_mask_normal = 1,
        },
        [MCE_GEN2] = {
                .mce_gen2 = 1,
        },
        [MCE_GEN2_TX_INV] = {
                .mce_gen2 = 1,
-               .tx_mask_inverted = 1,
+               .tx_mask_normal = 1,
        },
        [MCE_GEN3] = {
                .mce_gen3 = 1,
-               .tx_mask_inverted = 1,
+               .tx_mask_normal = 1,
        },
        [POLARIS_EVK] = {
                .is_polaris = 1,
@@ -183,7 +188,12 @@ static const struct mceusb_model mceusb_model[] = {
                 * to allow testing it
                 */
                .rc_map = RC_MAP_RC5_HAUPPAUGE_NEW,
-               .name = "cx231xx MCE IR",
+               .name = "Conexant Hybrid TV (cx231xx) MCE IR",
+       },
+       [CX_HYBRID_TV] = {
+               .is_polaris = 1,
+               .no_tx = 1, /* tx isn't wired up at all */
+               .name = "Conexant Hybrid TV (cx231xx) MCE IR",
        },
 };
 
@@ -273,6 +283,8 @@ static struct usb_device_id mceusb_dev_table[] = {
        { USB_DEVICE(VENDOR_FORMOSA, 0xe03c) },
        /* Formosa Industrial Computing */
        { USB_DEVICE(VENDOR_FORMOSA, 0xe03e) },
+       /* Fintek eHome Infrared Transceiver (HP branded) */
+       { USB_DEVICE(VENDOR_FINTEK, 0x5168) },
        /* Fintek eHome Infrared Transceiver */
        { USB_DEVICE(VENDOR_FINTEK, 0x0602) },
        /* Fintek eHome Infrared Transceiver (in the AOpen MP45) */
@@ -292,9 +304,12 @@ static struct usb_device_id mceusb_dev_table[] = {
        { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) },
        /* TiVo PC IR Receiver */
        { USB_DEVICE(VENDOR_TIVO, 0x2000) },
-       /* Conexant SDK */
+       /* Conexant Hybrid TV "Shelby" Polaris SDK */
        { USB_DEVICE(VENDOR_CONEXANT, 0x58a1),
          .driver_info = POLARIS_EVK },
+       /* Conexant Hybrid TV RDU253S Polaris */
+       { USB_DEVICE(VENDOR_CONEXANT, 0x58a5),
+         .driver_info = CX_HYBRID_TV },
        /* Terminating entry */
        { }
 };
@@ -303,7 +318,10 @@ static struct usb_device_id mceusb_dev_table[] = {
 struct mceusb_dev {
        /* ir-core bits */
        struct ir_dev_props *props;
-       struct ir_raw_event rawir;
+
+       /* optional features we can enable */
+       bool carrier_report_enabled;
+       bool learning_enabled;
 
        /* core device bits */
        struct device *dev;
@@ -318,6 +336,8 @@ struct mceusb_dev {
        /* buffers and dma */
        unsigned char *buf_in;
        unsigned int len_in;
+       dma_addr_t dma_in;
+       dma_addr_t dma_out;
 
        enum {
                CMD_HEADER = 0,
@@ -325,15 +345,14 @@ struct mceusb_dev {
                CMD_DATA,
                PARSE_IRDATA,
        } parser_state;
-       u8 cmd, rem;            /* Remaining IR data bytes in packet */
 
-       dma_addr_t dma_in;
-       dma_addr_t dma_out;
+       u8 cmd, rem;            /* Remaining IR data bytes in packet */
 
        struct {
                u32 connected:1;
-               u32 tx_mask_inverted:1;
+               u32 tx_mask_normal:1;
                u32 microsoft_gen1:1;
+               u32 no_tx:1;
        } flags;
 
        /* transmit support */
@@ -408,9 +427,10 @@ static int mceusb_cmdsize(u8 cmd, u8 subcmd)
                case MCE_CMD_UNKNOWN:
                case MCE_CMD_S_CARRIER:
                case MCE_CMD_S_TIMEOUT:
-               case MCE_CMD_G_RXSENSOR:
+               case MCE_RSP_PULSE_COUNT:
                        datasize = 2;
                        break;
+               case MCE_CMD_SIG_END:
                case MCE_CMD_S_TXMASK:
                case MCE_CMD_S_RXSENSOR:
                        datasize = 1;
@@ -433,7 +453,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
                return;
 
        /* skip meaningless 0xb1 0x60 header bytes on orig receiver */
-       if (ir->flags.microsoft_gen1 && !out)
+       if (ir->flags.microsoft_gen1 && !out && !offset)
                skip = 2;
 
        if (len <= skip)
@@ -491,6 +511,9 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
                break;
        case MCE_COMMAND_HEADER:
                switch (subcmd) {
+               case MCE_CMD_SIG_END:
+                       dev_info(dev, "End of signal\n");
+                       break;
                case MCE_CMD_PING:
                        dev_info(dev, "Ping\n");
                        break;
@@ -525,10 +548,11 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
                                 inout, data1 == 0x02 ? "short" : "long");
                        break;
                case MCE_CMD_G_RXSENSOR:
-                       if (len == 2)
+               /* aka MCE_RSP_PULSE_COUNT */
+                       if (out)
                                dev_info(dev, "Get receive sensor\n");
-                       else
-                               dev_info(dev, "Received pulse count is %d\n",
+                       else if (ir->learning_enabled)
+                               dev_info(dev, "RX pulse count: %d\n",
                                         ((data1 << 8) | data2));
                        break;
                case MCE_RSP_CMD_INVALID:
@@ -724,16 +748,16 @@ out:
        return ret ? ret : n;
 }
 
-/* Sets active IR outputs -- mce devices typically (all?) have two */
+/* Sets active IR outputs -- mce devices typically have two */
 static int mceusb_set_tx_mask(void *priv, u32 mask)
 {
        struct mceusb_dev *ir = priv;
 
-       if (ir->flags.tx_mask_inverted)
+       if (ir->flags.tx_mask_normal)
+               ir->tx_mask = mask;
+       else
                ir->tx_mask = (mask != MCE_DEFAULT_TX_MASK ?
                                mask ^ MCE_DEFAULT_TX_MASK : mask) << 1;
-       else
-               ir->tx_mask = mask;
 
        return 0;
 }
@@ -752,7 +776,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
 
                if (carrier == 0) {
                        ir->carrier = carrier;
-                       cmdbuf[2] = 0x01;
+                       cmdbuf[2] = MCE_CMD_SIG_END;
                        cmdbuf[3] = MCE_IRDATA_TRAILER;
                        dev_dbg(ir->dev, "%s: disabling carrier "
                                "modulation\n", __func__);
@@ -782,6 +806,34 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
        return carrier;
 }
 
+/*
+ * We don't do anything but print debug spew for many of the command bits
+ * we receive from the hardware, but some of them are useful information
+ * we want to store so that we can use them.
+ */
+static void mceusb_handle_command(struct mceusb_dev *ir, int index)
+{
+       u8 hi = ir->buf_in[index + 1] & 0xff;
+       u8 lo = ir->buf_in[index + 2] & 0xff;
+
+       switch (ir->buf_in[index]) {
+       /* 2-byte return value commands */
+       case MCE_CMD_S_TIMEOUT:
+               ir->props->timeout = MS_TO_NS((hi << 8 | lo) / 2);
+               break;
+
+       /* 1-byte return value commands */
+       case MCE_CMD_S_TXMASK:
+               ir->tx_mask = hi;
+               break;
+       case MCE_CMD_S_RXSENSOR:
+               ir->learning_enabled = (hi == 0x02);
+               break;
+       default:
+               break;
+       }
+}
+
 static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
 {
        DEFINE_IR_RAW_EVENT(rawir);
@@ -791,39 +843,30 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
        if (ir->flags.microsoft_gen1)
                i = 2;
 
+       /* if there's no data, just return now */
+       if (buf_len <= i)
+               return;
+
        for (; i < buf_len; i++) {
                switch (ir->parser_state) {
                case SUBCMD:
                        ir->rem = mceusb_cmdsize(ir->cmd, ir->buf_in[i]);
                        mceusb_dev_printdata(ir, ir->buf_in, i - 1,
                                             ir->rem + 2, false);
+                       mceusb_handle_command(ir, i);
                        ir->parser_state = CMD_DATA;
                        break;
                case PARSE_IRDATA:
                        ir->rem--;
                        rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
                        rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
-                                        * MCE_TIME_UNIT * 1000;
-
-                       if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) {
-                               if (ir->rawir.pulse == rawir.pulse) {
-                                       ir->rawir.duration += rawir.duration;
-                               } else {
-                                       ir->rawir.duration = rawir.duration;
-                                       ir->rawir.pulse = rawir.pulse;
-                               }
-                               if (ir->rem)
-                                       break;
-                       }
-                       rawir.duration += ir->rawir.duration;
-                       ir->rawir.duration = 0;
-                       ir->rawir.pulse = rawir.pulse;
+                                        * MS_TO_NS(MCE_TIME_UNIT);
 
                        dev_dbg(ir->dev, "Storing %s with duration %d\n",
                                rawir.pulse ? "pulse" : "space",
                                rawir.duration);
 
-                       ir_raw_event_store(ir->idev, &rawir);
+                       ir_raw_event_store_with_filter(ir->idev, &rawir);
                        break;
                case CMD_DATA:
                        ir->rem--;
@@ -839,17 +882,10 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
                                continue;
                        }
                        ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK);
-                       mceusb_dev_printdata(ir, ir->buf_in, i, ir->rem + 1, false);
-                       if (ir->rem) {
+                       mceusb_dev_printdata(ir, ir->buf_in,
+                                            i, ir->rem + 1, false);
+                       if (ir->rem)
                                ir->parser_state = PARSE_IRDATA;
-                               break;
-                       }
-                       /*
-                        * a package with len=0 (e. g. 0x80) means end of
-                        * data. We could use it to do the call to
-                        * ir_raw_event_handle(). For now, we don't need to
-                        * use it.
-                        */
                        break;
                }
 
@@ -984,9 +1020,11 @@ static void mceusb_get_parameters(struct mceusb_dev *ir)
        mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ));
        mce_sync_in(ir, NULL, maxp);
 
-       /* get the transmitter bitmask */
-       mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
-       mce_sync_in(ir, NULL, maxp);
+       if (!ir->flags.no_tx) {
+               /* get the transmitter bitmask */
+               mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
+               mce_sync_in(ir, NULL, maxp);
+       }
 
        /* get receiver timeout value */
        mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT));
@@ -1035,12 +1073,18 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
        props->priv = ir;
        props->driver_type = RC_DRIVER_IR_RAW;
        props->allowed_protos = IR_TYPE_ALL;
-       props->s_tx_mask = mceusb_set_tx_mask;
-       props->s_tx_carrier = mceusb_set_tx_carrier;
-       props->tx_ir = mceusb_tx_ir;
+       props->timeout = MS_TO_NS(1000);
+       if (!ir->flags.no_tx) {
+               props->s_tx_mask = mceusb_set_tx_mask;
+               props->s_tx_carrier = mceusb_set_tx_carrier;
+               props->tx_ir = mceusb_tx_ir;
+       }
 
        ir->props = props;
 
+       usb_to_input_id(ir->usbdev, &idev->id);
+       idev->dev.parent = ir->dev;
+
        if (mceusb_model[ir->model].rc_map)
                rc_map = mceusb_model[ir->model].rc_map;
 
@@ -1074,16 +1118,16 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
        enum mceusb_model_type model = id->driver_info;
        bool is_gen3;
        bool is_microsoft_gen1;
-       bool tx_mask_inverted;
+       bool tx_mask_normal;
        bool is_polaris;
 
-       dev_dbg(&intf->dev, "%s called\n", __func__);
+       dev_dbg(&intf->dev, "%s called\n", __func__);
 
        idesc  = intf->cur_altsetting;
 
        is_gen3 = mceusb_model[model].mce_gen3;
        is_microsoft_gen1 = mceusb_model[model].mce_gen1;
-       tx_mask_inverted = mceusb_model[model].tx_mask_inverted;
+       tx_mask_normal = mceusb_model[model].tx_mask_normal;
        is_polaris = mceusb_model[model].is_polaris;
 
        if (is_polaris) {
@@ -1107,7 +1151,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
                        ep_in = ep;
                        ep_in->bmAttributes = USB_ENDPOINT_XFER_INT;
                        ep_in->bInterval = 1;
-                       dev_dbg(&intf->dev, "acceptable inbound endpoint "
+                       dev_dbg(&intf->dev, "acceptable inbound endpoint "
                                "found\n");
                }
 
@@ -1122,12 +1166,12 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
                        ep_out = ep;
                        ep_out->bmAttributes = USB_ENDPOINT_XFER_INT;
                        ep_out->bInterval = 1;
-                       dev_dbg(&intf->dev, "acceptable outbound endpoint "
+                       dev_dbg(&intf->dev, "acceptable outbound endpoint "
                                "found\n");
                }
        }
        if (ep_in == NULL) {
-               dev_dbg(&intf->dev, "inbound and/or endpoint not found\n");
+               dev_dbg(&intf->dev, "inbound and/or endpoint not found\n");
                return -ENODEV;
        }
 
@@ -1150,11 +1194,10 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
        ir->dev = &intf->dev;
        ir->len_in = maxp;
        ir->flags.microsoft_gen1 = is_microsoft_gen1;
-       ir->flags.tx_mask_inverted = tx_mask_inverted;
+       ir->flags.tx_mask_normal = tx_mask_normal;
+       ir->flags.no_tx = mceusb_model[model].no_tx;
        ir->model = model;
 
-       init_ir_raw_event(&ir->rawir);
-
        /* Saving usb interface data for use by the transmitter routine */
        ir->usb_ep_in = ep_in;
        ir->usb_ep_out = ep_out;
@@ -1191,7 +1234,8 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
 
        mceusb_get_parameters(ir);
 
-       mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK);
+       if (!ir->flags.no_tx)
+               mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK);
 
        usb_set_intfdata(intf, ir);
 
index 301be53aee857298c43855df887a90ece26a2d8c..acc729c79ceca10afb96b08b101095c1a3e1dc03 100644 (file)
@@ -603,6 +603,8 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
        count = nvt->pkts;
        nvt_dbg_verbose("Processing buffer of len %d", count);
 
+       init_ir_raw_event(&rawir);
+
        for (i = 0; i < count; i++) {
                nvt->pkts--;
                sample = nvt->buf[i];
@@ -643,11 +645,15 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
                 * indicates end of IR signal, but new data incoming. In both
                 * cases, it means we're ready to call ir_raw_event_handle
                 */
-               if (sample == BUF_PULSE_BIT || ((sample != BUF_LEN_MASK) &&
-                   (sample & BUF_REPEAT_MASK) == BUF_REPEAT_BYTE))
+               if ((sample == BUF_PULSE_BIT) && nvt->pkts) {
+                       nvt_dbg("Calling ir_raw_event_handle (signal end)\n");
                        ir_raw_event_handle(nvt->rdev);
+               }
        }
 
+       nvt_dbg("Calling ir_raw_event_handle (buffer empty)\n");
+       ir_raw_event_handle(nvt->rdev);
+
        if (nvt->pkts) {
                nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts);
                nvt->pkts = 0;
index 548381c35bfd1573bf5886b648100e0d06a63f11..3a20aef67d08f97f7f0b92b143a85a67bbe24304 100644 (file)
@@ -34,8 +34,9 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <linux/usb.h>
 #include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/usb/input.h>
 #include <media/ir-core.h>
 
 #define DRIVER_VERSION "1.61"
@@ -140,7 +141,9 @@ static struct usb_driver streamzap_driver = {
 
 static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
 {
-       ir_raw_event_store(sz->idev, &rawir);
+       dev_dbg(sz->dev, "Storing %s with duration %u us\n",
+               (rawir.pulse ? "pulse" : "space"), rawir.duration);
+       ir_raw_event_store_with_filter(sz->idev, &rawir);
 }
 
 static void sz_push_full_pulse(struct streamzap_ir *sz,
@@ -167,7 +170,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
                        rawir.duration *= 1000;
                        rawir.duration &= IR_MAX_DURATION;
                }
-               dev_dbg(sz->dev, "ls %u\n", rawir.duration);
                sz_push(sz, rawir);
 
                sz->idle = false;
@@ -180,7 +182,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
        sz->sum += rawir.duration;
        rawir.duration *= 1000;
        rawir.duration &= IR_MAX_DURATION;
-       dev_dbg(sz->dev, "p %u\n", rawir.duration);
        sz_push(sz, rawir);
 }
 
@@ -200,7 +201,6 @@ static void sz_push_full_space(struct streamzap_ir *sz,
        rawir.duration += SZ_RESOLUTION / 2;
        sz->sum += rawir.duration;
        rawir.duration *= 1000;
-       dev_dbg(sz->dev, "s %u\n", rawir.duration);
        sz_push(sz, rawir);
 }
 
@@ -221,8 +221,6 @@ static void streamzap_callback(struct urb *urb)
        struct streamzap_ir *sz;
        unsigned int i;
        int len;
-       static int timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
-                               IR_MAX_DURATION) | 0x03000000);
 
        if (!urb)
                return;
@@ -246,7 +244,7 @@ static void streamzap_callback(struct urb *urb)
 
        dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
        for (i = 0; i < len; i++) {
-               dev_dbg(sz->dev, "sz idx %d: %x\n",
+               dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n",
                        i, (unsigned char)sz->buf_in[i]);
                switch (sz->decoder_state) {
                case PulseSpace:
@@ -273,7 +271,7 @@ static void streamzap_callback(struct urb *urb)
                                DEFINE_IR_RAW_EVENT(rawir);
 
                                rawir.pulse = false;
-                               rawir.duration = timeout;
+                               rawir.duration = sz->props->timeout;
                                sz->idle = true;
                                if (sz->timeout_enabled)
                                        sz_push(sz, rawir);
@@ -335,6 +333,9 @@ static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
 
        sz->props = props;
 
+       usb_to_input_id(sz->usbdev, &idev->id);
+       idev->dev.parent = sz->dev;
+
        ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
        if (ret < 0) {
                dev_err(dev, "remote input device register failed\n");
@@ -444,6 +445,8 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
        sz->decoder_state = PulseSpace;
        /* FIXME: don't yet have a way to set this */
        sz->timeout_enabled = true;
+       sz->props->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
+                               IR_MAX_DURATION) | 0x03000000);
        #if 0
        /* not yet supported, depends on patches from maxim */
        /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
index 072bd2d1cfad46f4c5a25ea33f789409c2848a5c..13565cba237d13e0a99922067ceb9edb9edd1e83 100644 (file)
@@ -807,8 +807,6 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd,
 
        if (common_flags & SOCAM_PCLK_SAMPLE_RISING)
                csicr1 |= CSICR1_REDGE;
-       if (common_flags & SOCAM_PCLK_SAMPLE_FALLING)
-               csicr1 |= CSICR1_INV_PCLK;
        if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH)
                csicr1 |= CSICR1_SOF_POL;
        if (common_flags & SOCAM_HSYNC_ACTIVE_HIGH)
index 1b93207c89e84efbbf6a4e3e8357a7af7f32f90d..2f500809f53d9b418dd2d3117ce44ef7706d0287 100644 (file)
@@ -522,6 +522,7 @@ static int fimc_cap_streamon(struct file *file, void *priv,
        INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
        fimc->vid_cap.active_buf_cnt = 0;
        fimc->vid_cap.frame_count = 0;
+       fimc->vid_cap.buf_index = fimc_hw_get_frame_index(fimc);
 
        set_bit(ST_CAPT_PEND, &fimc->state);
        ret = videobuf_streamon(&fimc->vid_cap.vbq);
@@ -652,6 +653,50 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv,
        return ret;
 }
 
+static int fimc_cap_cropcap(struct file *file, void *fh,
+                           struct v4l2_cropcap *cr)
+{
+       struct fimc_frame *f;
+       struct fimc_ctx *ctx = fh;
+       struct fimc_dev *fimc = ctx->fimc_dev;
+
+       if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       if (mutex_lock_interruptible(&fimc->lock))
+               return -ERESTARTSYS;
+
+       f = &ctx->s_frame;
+       cr->bounds.left         = 0;
+       cr->bounds.top          = 0;
+       cr->bounds.width        = f->o_width;
+       cr->bounds.height       = f->o_height;
+       cr->defrect             = cr->bounds;
+
+       mutex_unlock(&fimc->lock);
+       return 0;
+}
+
+static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
+{
+       struct fimc_frame *f;
+       struct fimc_ctx *ctx = file->private_data;
+       struct fimc_dev *fimc = ctx->fimc_dev;
+
+
+       if (mutex_lock_interruptible(&fimc->lock))
+               return -ERESTARTSYS;
+
+       f = &ctx->s_frame;
+       cr->c.left      = f->offs_h;
+       cr->c.top       = f->offs_v;
+       cr->c.width     = f->width;
+       cr->c.height    = f->height;
+
+       mutex_unlock(&fimc->lock);
+       return 0;
+}
+
 static int fimc_cap_s_crop(struct file *file, void *fh,
                               struct v4l2_crop *cr)
 {
@@ -716,9 +761,9 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
        .vidioc_g_ctrl                  = fimc_vidioc_g_ctrl,
        .vidioc_s_ctrl                  = fimc_cap_s_ctrl,
 
-       .vidioc_g_crop                  = fimc_vidioc_g_crop,
+       .vidioc_g_crop                  = fimc_cap_g_crop,
        .vidioc_s_crop                  = fimc_cap_s_crop,
-       .vidioc_cropcap                 = fimc_vidioc_cropcap,
+       .vidioc_cropcap                 = fimc_cap_cropcap,
 
        .vidioc_enum_input              = fimc_cap_enum_input,
        .vidioc_s_input                 = fimc_cap_s_input,
@@ -785,7 +830,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
        videobuf_queue_dma_contig_init(&vid_cap->vbq, &fimc_qops,
                vid_cap->v4l2_dev.dev, &fimc->irqlock,
                V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
-               sizeof(struct fimc_vid_buffer), (void *)ctx);
+               sizeof(struct fimc_vid_buffer), (void *)ctx, NULL);
 
        ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
        if (ret) {
index 2e7c547894b687d9fd37288e365ceae704dbcbfc..bb99f2d805d3347975e0ff32603bd2f7b8f44e20 100644 (file)
@@ -50,8 +50,8 @@ static struct fimc_fmt fimc_formats[] = {
                .planes_cnt = 1,
                .flags = FMT_FLAGS_M2M,
        }, {
-               .name = "XRGB-8-8-8-8, 24 bpp",
-               .fourcc = V4L2_PIX_FMT_RGB24,
+               .name = "XRGB-8-8-8-8, 32 bpp",
+               .fourcc = V4L2_PIX_FMT_RGB32,
                .depth = 32,
                .color  = S5P_FIMC_RGB888,
                .buff_cnt = 1,
@@ -983,6 +983,7 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv,
 {
        struct fimc_ctx *ctx = priv;
        struct v4l2_queryctrl *c;
+       int ret = -EINVAL;
 
        c = get_ctrl(qc->id);
        if (c) {
@@ -990,10 +991,14 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv,
                return 0;
        }
 
-       if (ctx->state & FIMC_CTX_CAP)
-               return v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
+       if (ctx->state & FIMC_CTX_CAP) {
+               if (mutex_lock_interruptible(&ctx->fimc_dev->lock))
+                       return -ERESTARTSYS;
+               ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
                                        core, queryctrl, qc);
-       return -EINVAL;
+               mutex_unlock(&ctx->fimc_dev->lock);
+       }
+       return ret;
 }
 
 int fimc_vidioc_g_ctrl(struct file *file, void *priv,
@@ -1115,7 +1120,7 @@ static int fimc_m2m_s_ctrl(struct file *file, void *priv,
        return 0;
 }
 
-int fimc_vidioc_cropcap(struct file *file, void *fh,
+static int fimc_m2m_cropcap(struct file *file, void *fh,
                        struct v4l2_cropcap *cr)
 {
        struct fimc_frame *frame;
@@ -1139,7 +1144,7 @@ int fimc_vidioc_cropcap(struct file *file, void *fh,
        return 0;
 }
 
-int fimc_vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
+static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
 {
        struct fimc_frame *frame;
        struct fimc_ctx *ctx = file->private_data;
@@ -1167,22 +1172,22 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
        struct fimc_frame *f;
        u32 min_size, halign;
 
-       f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
-               &ctx->s_frame : &ctx->d_frame;
-
        if (cr->c.top < 0 || cr->c.left < 0) {
                v4l2_err(&fimc->m2m.v4l2_dev,
                        "doesn't support negative values for top & left\n");
                return -EINVAL;
        }
 
-       f = ctx_get_frame(ctx, cr->type);
-       if (IS_ERR(f))
-               return PTR_ERR(f);
+       if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               f = (ctx->state & FIMC_CTX_CAP) ? &ctx->s_frame : &ctx->d_frame;
+       else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+                ctx->state & FIMC_CTX_M2M)
+               f = &ctx->s_frame;
+       else
+               return -EINVAL;
 
-       min_size = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
-               ? fimc->variant->min_inp_pixsize
-               : fimc->variant->min_out_pixsize;
+       min_size = (f == &ctx->s_frame) ?
+               fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
 
        if (ctx->state & FIMC_CTX_M2M) {
                if (fimc->id == 1 && fimc->variant->pix_hoff)
@@ -1233,6 +1238,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
        f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
                &ctx->s_frame : &ctx->d_frame;
 
+       if (mutex_lock_interruptible(&fimc->lock))
+               return -ERESTARTSYS;
+
        spin_lock_irqsave(&ctx->slock, flags);
        if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) {
                /* Check to see if scaling ratio is within supported range */
@@ -1241,9 +1249,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
                else
                        ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame);
                if (ret) {
-                       spin_unlock_irqrestore(&ctx->slock, flags);
                        v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range");
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto scr_unlock;
                }
        }
        ctx->state |= FIMC_PARAMS;
@@ -1253,7 +1261,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
        f->width  = cr->c.width;
        f->height = cr->c.height;
 
+scr_unlock:
        spin_unlock_irqrestore(&ctx->slock, flags);
+       mutex_unlock(&fimc->lock);
        return 0;
 }
 
@@ -1285,9 +1295,9 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
        .vidioc_g_ctrl                  = fimc_vidioc_g_ctrl,
        .vidioc_s_ctrl                  = fimc_m2m_s_ctrl,
 
-       .vidioc_g_crop                  = fimc_vidioc_g_crop,
+       .vidioc_g_crop                  = fimc_m2m_g_crop,
        .vidioc_s_crop                  = fimc_m2m_s_crop,
-       .vidioc_cropcap                 = fimc_vidioc_cropcap
+       .vidioc_cropcap                 = fimc_m2m_cropcap
 
 };
 
@@ -1396,7 +1406,7 @@ static const struct v4l2_file_operations fimc_m2m_fops = {
        .open           = fimc_m2m_open,
        .release        = fimc_m2m_release,
        .poll           = fimc_m2m_poll,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .mmap           = fimc_m2m_mmap,
 };
 
@@ -1736,6 +1746,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
        .pix_hoff        = 1,
        .has_inp_rot     = 1,
        .has_out_rot     = 1,
+       .has_cistatus2   = 1,
        .min_inp_pixsize = 16,
        .min_out_pixsize = 16,
        .hor_offs_align  = 1,
@@ -1745,6 +1756,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
 
 static struct samsung_fimc_variant fimc2_variant_s5pv310 = {
        .pix_hoff        = 1,
+       .has_cistatus2   = 1,
        .min_inp_pixsize = 16,
        .min_out_pixsize = 16,
        .hor_offs_align  = 1,
index 3e107851656017adfc1a2567956a93e28fd43cd5..4f047d35f8ad9333ce3b4768836685b3d5f2f411 100644 (file)
 
 /*#define DEBUG*/
 
+#include <linux/sched.h>
 #include <linux/types.h>
+#include <linux/videodev2.h>
 #include <media/videobuf-core.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/v4l2-mediabus.h>
 #include <media/s3c_fimc.h>
-#include <linux/videodev2.h>
+
 #include "regs-fimc.h"
 
 #define err(fmt, args...) \
@@ -369,6 +371,7 @@ struct fimc_pix_limit {
  * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes
  * @has_inp_rot: set if has input rotator
  * @has_out_rot: set if has output rotator
+ * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision
  * @pix_limit: pixel size constraints for the scaler
  * @min_inp_pixsize: minimum input pixel size
  * @min_out_pixsize: minimum output pixel size
@@ -379,6 +382,7 @@ struct samsung_fimc_variant {
        unsigned int    pix_hoff:1;
        unsigned int    has_inp_rot:1;
        unsigned int    has_out_rot:1;
+       unsigned int    has_cistatus2:1;
        struct fimc_pix_limit *pix_limit;
        u16             min_inp_pixsize;
        u16             min_out_pixsize;
@@ -554,11 +558,19 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
        return frame;
 }
 
+/* Return an index to the buffer actually being written. */
 static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
 {
-       u32 reg = readl(dev->regs + S5P_CISTATUS);
-       return (reg & S5P_CISTATUS_FRAMECNT_MASK) >>
-               S5P_CISTATUS_FRAMECNT_SHIFT;
+       u32 reg;
+
+       if (dev->variant->has_cistatus2) {
+               reg = readl(dev->regs + S5P_CISTATUS2) & 0x3F;
+               return reg > 0 ? --reg : reg;
+       } else {
+               reg = readl(dev->regs + S5P_CISTATUS);
+               return (reg & S5P_CISTATUS_FRAMECNT_MASK) >>
+                       S5P_CISTATUS_FRAMECNT_SHIFT;
+       }
 }
 
 /* -----------------------------------------------------*/
@@ -594,10 +606,6 @@ int fimc_vidioc_g_fmt(struct file *file, void *priv,
                      struct v4l2_format *f);
 int fimc_vidioc_try_fmt(struct file *file, void *priv,
                        struct v4l2_format *f);
-int fimc_vidioc_g_crop(struct file *file, void *fh,
-                      struct v4l2_crop *cr);
-int fimc_vidioc_cropcap(struct file *file, void *fh,
-                       struct v4l2_cropcap *cr);
 int fimc_vidioc_queryctrl(struct file *file, void *priv,
                          struct v4l2_queryctrl *qc);
 int fimc_vidioc_g_ctrl(struct file *file, void *priv,
index a57daedb5b5cf7099e273afb276759b4228fef42..57e33f84fcfa5fa4a4fd35d7eb9998e75ac1d003 100644 (file)
 #define S5P_CISTATUS_VVALID_A          (1 << 15)
 #define S5P_CISTATUS_VVALID_B          (1 << 14)
 
+/* Indexes to the last and the currently processed buffer. */
+#define S5P_CISTATUS2                  0x68
+
 /* Image capture control */
 #define S5P_CIIMGCPT                   0xc0
 #define S5P_CIIMGCPT_IMGCPTEN          (1 << 31)
index 5c209afb0ac8ddb434d5c6335c2661161e36aa5b..2486520582f2c576639a28bc231ccf847a472e4b 100644 (file)
@@ -1980,7 +1980,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
                 * we complete the completion.
                 */
 
-               if (!csi2->driver || !csi2->driver->owner) {
+               if (!csi2->driver) {
                        complete(&wait.completion);
                        /* Either too late, or probing failed */
                        bus_unregister_notifier(&platform_bus_type, &wait.notifier);
index 335120c2021bc2cdbf5de98b59f58cc001144ad5..052bd6dfa5a787033d445401ddb114bb40796732 100644 (file)
@@ -405,13 +405,13 @@ static int soc_camera_open(struct file *file)
                ret = soc_camera_set_fmt(icd, &f);
                if (ret < 0)
                        goto esfmt;
+
+               ici->ops->init_videobuf(&icd->vb_vidq, icd);
        }
 
        file->private_data = icd;
        dev_dbg(&icd->dev, "camera device open\n");
 
-       ici->ops->init_videobuf(&icd->vb_vidq, icd);
-
        mutex_unlock(&icd->video_lock);
 
        return 0;
index 31ae07a36576678fb27dbd294623f6f8ac21cc9d..57dcf8fa774a7302be1fbb6f0104d6320c6287c8 100644 (file)
@@ -1773,6 +1773,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
 
        case PM_POST_SUSPEND:
        case PM_POST_HIBERNATION:
+       case PM_POST_RESTORE:
 
                spin_lock_irqsave(&host->lock, flags);
                host->rescan_disable = 0;
index 591ab540b407ad9805c3aa384795b2c59a7d8c69..d3e6a962f42343ac4f30fdd7dc7da8f13ff8a95a 100644 (file)
@@ -69,6 +69,7 @@
 #include <linux/highmem.h>
 
 #include <linux/mmc/host.h>
+#include <linux/mmc/sdio.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -493,10 +494,14 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
                else if (data->flags & MMC_DATA_WRITE)
                        cmdr |= AT91_MCI_TRCMD_START;
 
-               if (data->flags & MMC_DATA_STREAM)
-                       cmdr |= AT91_MCI_TRTYP_STREAM;
-               if (data->blocks > 1)
-                       cmdr |= AT91_MCI_TRTYP_MULTIPLE;
+               if (cmd->opcode == SD_IO_RW_EXTENDED) {
+                       cmdr |= AT91_MCI_TRTYP_SDIO_BLOCK;
+               } else {
+                       if (data->flags & MMC_DATA_STREAM)
+                               cmdr |= AT91_MCI_TRTYP_STREAM;
+                       if (data->blocks > 1)
+                               cmdr |= AT91_MCI_TRTYP_MULTIPLE;
+               }
        }
        else {
                block_length = 0;
index 301351a5d83853f877953a1ecd10553ecc8f5c22..ad2a7a032cdf02478a80cd87055abce9648e31ca 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/stat.h>
 
 #include <linux/mmc/host.h>
+#include <linux/mmc/sdio.h>
 
 #include <mach/atmel-mci.h>
 #include <linux/atmel-mci.h>
@@ -532,12 +533,17 @@ static u32 atmci_prepare_command(struct mmc_host *mmc,
        data = cmd->data;
        if (data) {
                cmdr |= MCI_CMDR_START_XFER;
-               if (data->flags & MMC_DATA_STREAM)
-                       cmdr |= MCI_CMDR_STREAM;
-               else if (data->blocks > 1)
-                       cmdr |= MCI_CMDR_MULTI_BLOCK;
-               else
-                       cmdr |= MCI_CMDR_BLOCK;
+
+               if (cmd->opcode == SD_IO_RW_EXTENDED) {
+                       cmdr |= MCI_CMDR_SDIO_BLOCK;
+               } else {
+                       if (data->flags & MMC_DATA_STREAM)
+                               cmdr |= MCI_CMDR_STREAM;
+                       else if (data->blocks > 1)
+                               cmdr |= MCI_CMDR_MULTI_BLOCK;
+                       else
+                               cmdr |= MCI_CMDR_BLOCK;
+               }
 
                if (data->flags & MMC_DATA_READ)
                        cmdr |= MCI_CMDR_TRDIR_READ;
index 09b099bfab2b1b75c5dc7e3f0b323393e0124f8a..bdf11d89a4997887fc1c1145b393ef91ad5785a4 100644 (file)
@@ -702,6 +702,7 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
 
 
        adapter->wol = 0;
+       device_set_wakeup_enable(&pdev->dev, false);
        adapter->link_speed = SPEED_0;
        adapter->link_duplex = FULL_DUPLEX;
        adapter->num_rx_queues = AT_DEF_RECEIVE_QUEUE;
@@ -2444,8 +2445,9 @@ static int atl1c_close(struct net_device *netdev)
        return 0;
 }
 
-static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state)
+static int atl1c_suspend(struct device *dev)
 {
+       struct pci_dev *pdev = to_pci_dev(dev);
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct atl1c_adapter *adapter = netdev_priv(netdev);
        struct atl1c_hw *hw = &adapter->hw;
@@ -2454,7 +2456,6 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state)
        u32 wol_ctrl_data = 0;
        u16 mii_intr_status_data = 0;
        u32 wufc = adapter->wol;
-       int retval = 0;
 
        atl1c_disable_l0s_l1(hw);
        if (netif_running(netdev)) {
@@ -2462,9 +2463,6 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state)
                atl1c_down(adapter);
        }
        netif_device_detach(netdev);
-       retval = pci_save_state(pdev);
-       if (retval)
-               return retval;
 
        if (wufc)
                if (atl1c_phy_power_saving(hw) != 0)
@@ -2525,12 +2523,8 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state)
                AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data);
                AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
 
-               /* pcie patch */
-               device_set_wakeup_enable(&pdev->dev, 1);
-
                AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT |
                        GPHY_CTRL_EXT_RESET);
-               pci_prepare_to_sleep(pdev);
        } else {
                AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_POWER_SAVING);
                master_ctrl_data |= MASTER_CTRL_CLK_SEL_DIS;
@@ -2540,25 +2534,17 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state)
                AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
                AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
                hw->phy_configured = false; /* re-init PHY when resume */
-               pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
        }
 
-       pci_disable_device(pdev);
-       pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
        return 0;
 }
 
-static int atl1c_resume(struct pci_dev *pdev)
+static int atl1c_resume(struct device *dev)
 {
+       struct pci_dev *pdev = to_pci_dev(dev);
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct atl1c_adapter *adapter = netdev_priv(netdev);
 
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-       pci_enable_wake(pdev, PCI_D3hot, 0);
-       pci_enable_wake(pdev, PCI_D3cold, 0);
-
        AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
        atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE |
                        ATL1C_PCIE_PHY_RESET);
@@ -2582,7 +2568,12 @@ static int atl1c_resume(struct pci_dev *pdev)
 
 static void atl1c_shutdown(struct pci_dev *pdev)
 {
-       atl1c_suspend(pdev, PMSG_SUSPEND);
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+       atl1c_suspend(&pdev->dev);
+       pci_wake_from_d3(pdev, adapter->wol);
+       pci_set_power_state(pdev, PCI_D3hot);
 }
 
 static const struct net_device_ops atl1c_netdev_ops = {
@@ -2886,16 +2877,16 @@ static struct pci_error_handlers atl1c_err_handler = {
        .resume = atl1c_io_resume,
 };
 
+static SIMPLE_DEV_PM_OPS(atl1c_pm_ops, atl1c_suspend, atl1c_resume);
+
 static struct pci_driver atl1c_driver = {
        .name     = atl1c_driver_name,
        .id_table = atl1c_pci_tbl,
        .probe    = atl1c_probe,
        .remove   = __devexit_p(atl1c_remove),
-       /* Power Managment Hooks */
-       .suspend  = atl1c_suspend,
-       .resume   = atl1c_resume,
        .shutdown = atl1c_shutdown,
-       .err_handler = &atl1c_err_handler
+       .err_handler = &atl1c_err_handler,
+       .driver.pm = &atl1c_pm_ops,
 };
 
 /*
index 4594a28b1f665ef7923aa462739b96e39182ac5e..d64313b7090e2217038130bb314cedde2bb7c152 100644 (file)
@@ -234,7 +234,7 @@ struct be_adapter {
        u8 __iomem *db;         /* Door Bell */
        u8 __iomem *pcicfg;     /* PCI config space */
 
-       spinlock_t mbox_lock;   /* For serializing mbox cmds to BE card */
+       struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
        struct be_dma_mem mbox_mem;
        /* Mbox mem is adjusted to align to 16 bytes. The allocated addr
         * is stored for freeing purpose */
index e4465d222a7d019654c27c5f4d3db89067f89cf8..1c8c79c9d214e45feb59dbf20b439be1d369702a 100644 (file)
@@ -462,7 +462,8 @@ int be_cmd_fw_init(struct be_adapter *adapter)
        u8 *wrb;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = (u8 *)wrb_from_mbox(adapter);
        *wrb++ = 0xFF;
@@ -476,7 +477,7 @@ int be_cmd_fw_init(struct be_adapter *adapter)
 
        status = be_mbox_notify_wait(adapter);
 
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
        return status;
 }
 
@@ -491,7 +492,8 @@ int be_cmd_fw_clean(struct be_adapter *adapter)
        if (adapter->eeh_err)
                return -EIO;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = (u8 *)wrb_from_mbox(adapter);
        *wrb++ = 0xFF;
@@ -505,7 +507,7 @@ int be_cmd_fw_clean(struct be_adapter *adapter)
 
        status = be_mbox_notify_wait(adapter);
 
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
        return status;
 }
 int be_cmd_eq_create(struct be_adapter *adapter,
@@ -516,7 +518,8 @@ int be_cmd_eq_create(struct be_adapter *adapter,
        struct be_dma_mem *q_mem = &eq->dma_mem;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = wrb_from_mbox(adapter);
        req = embedded_payload(wrb);
@@ -546,7 +549,7 @@ int be_cmd_eq_create(struct be_adapter *adapter,
                eq->created = true;
        }
 
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
        return status;
 }
 
@@ -558,7 +561,8 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
        struct be_cmd_req_mac_query *req;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = wrb_from_mbox(adapter);
        req = embedded_payload(wrb);
@@ -583,7 +587,7 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
                memcpy(mac_addr, resp->mac.addr, ETH_ALEN);
        }
 
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
        return status;
 }
 
@@ -667,7 +671,8 @@ int be_cmd_cq_create(struct be_adapter *adapter,
        void *ctxt;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = wrb_from_mbox(adapter);
        req = embedded_payload(wrb);
@@ -701,7 +706,7 @@ int be_cmd_cq_create(struct be_adapter *adapter,
                cq->created = true;
        }
 
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
 
        return status;
 }
@@ -724,7 +729,8 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
        void *ctxt;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = wrb_from_mbox(adapter);
        req = embedded_payload(wrb);
@@ -754,7 +760,7 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
                mccq->id = le16_to_cpu(resp->id);
                mccq->created = true;
        }
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
 
        return status;
 }
@@ -769,7 +775,8 @@ int be_cmd_txq_create(struct be_adapter *adapter,
        void *ctxt;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = wrb_from_mbox(adapter);
        req = embedded_payload(wrb);
@@ -801,7 +808,7 @@ int be_cmd_txq_create(struct be_adapter *adapter,
                txq->created = true;
        }
 
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
 
        return status;
 }
@@ -816,7 +823,8 @@ int be_cmd_rxq_create(struct be_adapter *adapter,
        struct be_dma_mem *q_mem = &rxq->dma_mem;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = wrb_from_mbox(adapter);
        req = embedded_payload(wrb);
@@ -843,7 +851,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter,
                *rss_id = resp->rss_id;
        }
 
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
 
        return status;
 }
@@ -862,7 +870,8 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
        if (adapter->eeh_err)
                return -EIO;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = wrb_from_mbox(adapter);
        req = embedded_payload(wrb);
@@ -899,7 +908,7 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
 
        status = be_mbox_notify_wait(adapter);
 
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
 
        return status;
 }
@@ -915,7 +924,8 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
        struct be_cmd_req_if_create *req;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = wrb_from_mbox(adapter);
        req = embedded_payload(wrb);
@@ -941,7 +951,7 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags,
                        *pmac_id = le32_to_cpu(resp->pmac_id);
        }
 
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
        return status;
 }
 
@@ -955,7 +965,8 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id)
        if (adapter->eeh_err)
                return -EIO;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = wrb_from_mbox(adapter);
        req = embedded_payload(wrb);
@@ -970,7 +981,7 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id)
 
        status = be_mbox_notify_wait(adapter);
 
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
 
        return status;
 }
@@ -1060,7 +1071,8 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver)
        struct be_cmd_req_get_fw_version *req;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = wrb_from_mbox(adapter);
        req = embedded_payload(wrb);
@@ -1077,7 +1089,7 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver)
                strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN);
        }
 
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
        return status;
 }
 
@@ -1322,7 +1334,8 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
        struct be_cmd_req_query_fw_cfg *req;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = wrb_from_mbox(adapter);
        req = embedded_payload(wrb);
@@ -1341,7 +1354,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
                *caps = le32_to_cpu(resp->function_caps);
        }
 
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
        return status;
 }
 
@@ -1352,7 +1365,8 @@ int be_cmd_reset_function(struct be_adapter *adapter)
        struct be_cmd_req_hdr *req;
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = wrb_from_mbox(adapter);
        req = embedded_payload(wrb);
@@ -1365,7 +1379,7 @@ int be_cmd_reset_function(struct be_adapter *adapter)
 
        status = be_mbox_notify_wait(adapter);
 
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
        return status;
 }
 
@@ -1376,7 +1390,8 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size)
        u32 myhash[10];
        int status;
 
-       spin_lock(&adapter->mbox_lock);
+       if (mutex_lock_interruptible(&adapter->mbox_lock))
+               return -1;
 
        wrb = wrb_from_mbox(adapter);
        req = embedded_payload(wrb);
@@ -1396,7 +1411,7 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size)
 
        status = be_mbox_notify_wait(adapter);
 
-       spin_unlock(&adapter->mbox_lock);
+       mutex_unlock(&adapter->mbox_lock);
        return status;
 }
 
index 93354eee2cfd1e679929054c9cc28fe7b35dea51..fd251b59b7f96b4d58ca0f7b22e91e22485d7005 100644 (file)
@@ -2677,7 +2677,7 @@ static int be_ctrl_init(struct be_adapter *adapter)
        }
        memset(mc_cmd_mem->va, 0, mc_cmd_mem->size);
 
-       spin_lock_init(&adapter->mbox_lock);
+       mutex_init(&adapter->mbox_lock);
        spin_lock_init(&adapter->mcc_lock);
        spin_lock_init(&adapter->mcc_cq_lock);
 
index 121b073a6c3fae1985c164071f0a8f285dba0c14..84fbd4ebd778d472a9cf115cfc4faaf72e92939e 100644 (file)
@@ -88,7 +88,12 @@ static void bond_na_send(struct net_device *slave_dev,
        }
 
        if (vlan_id) {
-               skb = vlan_put_tag(skb, vlan_id);
+               /* The Ethernet header is not present yet, so it is
+                * too early to insert a VLAN tag.  Force use of an
+                * out-of-line tag here and let dev_hard_start_xmit()
+                * insert it if the slave hardware can't.
+                */
+               skb = __vlan_hwaccel_put_tag(skb, vlan_id);
                if (!skb) {
                        pr_err("failed to insert VLAN tag\n");
                        return;
index d0ea760ce419f0ae8040bf880cd80013c651a93a..3b16c34ed86e93ddfacd0338ef42f687ab70fce7 100644 (file)
@@ -418,36 +418,11 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr)
  * @bond: bond device that got this skb for tx.
  * @skb: hw accel VLAN tagged skb to transmit
  * @slave_dev: slave that is supposed to xmit this skbuff
- *
- * When the bond gets an skb to transmit that is
- * already hardware accelerated VLAN tagged, and it
- * needs to relay this skb to a slave that is not
- * hw accel capable, the skb needs to be "unaccelerated",
- * i.e. strip the hwaccel tag and re-insert it as part
- * of the payload.
  */
 int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
                        struct net_device *slave_dev)
 {
-       unsigned short uninitialized_var(vlan_id);
-
-       /* Test vlan_list not vlgrp to catch and handle 802.1p tags */
-       if (!list_empty(&bond->vlan_list) &&
-           !(slave_dev->features & NETIF_F_HW_VLAN_TX) &&
-           vlan_get_tag(skb, &vlan_id) == 0) {
-               skb->dev = slave_dev;
-               skb = vlan_put_tag(skb, vlan_id);
-               if (!skb) {
-                       /* vlan_put_tag() frees the skb in case of error,
-                        * so return success here so the calling functions
-                        * won't attempt to free is again.
-                        */
-                       return 0;
-               }
-       } else {
-               skb->dev = slave_dev;
-       }
-
+       skb->dev = slave_dev;
        skb->priority = 1;
 #ifdef CONFIG_NET_POLL_CONTROLLER
        if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) {
@@ -1203,11 +1178,13 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
                                bond_do_fail_over_mac(bond, new_active,
                                                      old_active);
 
-                       bond->send_grat_arp = bond->params.num_grat_arp;
-                       bond_send_gratuitous_arp(bond);
+                       if (netif_running(bond->dev)) {
+                               bond->send_grat_arp = bond->params.num_grat_arp;
+                               bond_send_gratuitous_arp(bond);
 
-                       bond->send_unsol_na = bond->params.num_unsol_na;
-                       bond_send_unsolicited_na(bond);
+                               bond->send_unsol_na = bond->params.num_unsol_na;
+                               bond_send_unsolicited_na(bond);
+                       }
 
                        write_unlock_bh(&bond->curr_slave_lock);
                        read_unlock(&bond->lock);
@@ -1221,8 +1198,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
 
        /* resend IGMP joins since active slave has changed or
         * all were sent on curr_active_slave */
-       if ((USES_PRIMARY(bond->params.mode) && new_active) ||
-           bond->params.mode == BOND_MODE_ROUNDROBIN) {
+       if (((USES_PRIMARY(bond->params.mode) && new_active) ||
+            bond->params.mode == BOND_MODE_ROUNDROBIN) &&
+           netif_running(bond->dev)) {
                bond->igmp_retrans = bond->params.resend_igmp;
                queue_delayed_work(bond->wq, &bond->mcast_work, 0);
        }
index c2f081352a037894d6e8238ccb70c39e796c4a69..4feeb2d650a4f478bc6ab4f3c70db3f3563c622d 100644 (file)
@@ -269,11 +269,11 @@ static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct n
 
        bond_for_each_slave(bond, slave, i) {
                if (slave->dev == slave_dev) {
-                       break;
+                       return slave;
                }
        }
 
-       return slave;
+       return 0;
 }
 
 static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
index aa56963ad55820e2a763d64c102a36ae1b35dabf..c353bf3113cc335088e4322703a91cd5add4d60d 100644 (file)
@@ -935,7 +935,7 @@ static void epic_init_ring(struct net_device *dev)
 
        /* Fill in the Rx buffers.  Handle allocation failure gracefully. */
        for (i = 0; i < RX_RING_SIZE; i++) {
-               struct sk_buff *skb = dev_alloc_skb(ep->rx_buf_sz);
+               struct sk_buff *skb = dev_alloc_skb(ep->rx_buf_sz + 2);
                ep->rx_skbuff[i] = skb;
                if (skb == NULL)
                        break;
@@ -1233,7 +1233,7 @@ static int epic_rx(struct net_device *dev, int budget)
                entry = ep->dirty_rx % RX_RING_SIZE;
                if (ep->rx_skbuff[entry] == NULL) {
                        struct sk_buff *skb;
-                       skb = ep->rx_skbuff[entry] = dev_alloc_skb(ep->rx_buf_sz);
+                       skb = ep->rx_skbuff[entry] = dev_alloc_skb(ep->rx_buf_sz + 2);
                        if (skb == NULL)
                                break;
                        skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
index 9a6485892b3d48dfbcf783a27b670be83704e803..80d25ed533447735d55804e152bb8d581fc911ef 100644 (file)
@@ -1202,7 +1202,7 @@ static void hamachi_init_ring(struct net_device *dev)
        }
        /* Fill in the Rx buffers.  Handle allocation failure gracefully. */
        for (i = 0; i < RX_RING_SIZE; i++) {
-               struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz);
+               struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz + 2);
                hmp->rx_skbuff[i] = skb;
                if (skb == NULL)
                        break;
@@ -1669,7 +1669,7 @@ static int hamachi_rx(struct net_device *dev)
                entry = hmp->dirty_rx % RX_RING_SIZE;
                desc = &(hmp->rx_ring[entry]);
                if (hmp->rx_skbuff[entry] == NULL) {
-                       struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz);
+                       struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz + 2);
 
                        hmp->rx_skbuff[entry] = skb;
                        if (skb == NULL)
index 8a4d19e5de064bd3fbbb11a2d2e916a28cf593b0..f1047dd8a526715857929e8ca86a47d846e5a15e 100644 (file)
@@ -690,6 +690,7 @@ static void block_output(struct net_device *dev, int count,
 static struct pcmcia_device_id axnet_ids[] = {
        PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x016c, 0x0081),
        PCMCIA_DEVICE_MANF_CARD(0x018a, 0x0301),
+       PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328),
        PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0301),
        PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0303),
        PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309),
index d05c44692f08306f4dc04dbbb30098c46fd8e362..2c158910f7ea8f1784f629df23bfee2a21cc41c9 100644 (file)
@@ -1493,7 +1493,6 @@ static struct pcmcia_device_id pcnet_ids[] = {
        PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530),
        PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab),
        PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110),
-       PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328),
        PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041),
        PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452),
        PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300),
index 3ed2a67bd6d36c5da4608570bc8d494faa614f59..b409d7ec4ac15ff5e5eb82c2aff17111d48954a3 100644 (file)
@@ -1016,7 +1016,7 @@ static void init_ring(struct net_device *dev)
 
        /* Fill in the Rx buffers.  Handle allocation failure gracefully. */
        for (i = 0; i < RX_RING_SIZE; i++) {
-               struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz);
+               struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + 2);
                np->rx_skbuff[i] = skb;
                if (skb == NULL)
                        break;
@@ -1407,7 +1407,7 @@ static void refill_rx (struct net_device *dev)
                struct sk_buff *skb;
                entry = np->dirty_rx % RX_RING_SIZE;
                if (np->rx_skbuff[entry] == NULL) {
-                       skb = dev_alloc_skb(np->rx_buf_sz);
+                       skb = dev_alloc_skb(np->rx_buf_sz + 2);
                        np->rx_skbuff[entry] = skb;
                        if (skb == NULL)
                                break;          /* Better luck next round. */
index 8b3dc1eb401541e8e1c3de31ce5308d84f477845..296000bf5a25d9186826da3c3c2f401802409e07 100644 (file)
@@ -324,7 +324,7 @@ static int bdx_fw_load(struct bdx_priv *priv)
        ENTER;
        master = READ_REG(priv, regINIT_SEMAPHORE);
        if (!READ_REG(priv, regINIT_STATUS) && master) {
-               rc = request_firmware(&fw, "tehuti/firmware.bin", &priv->pdev->dev);
+               rc = request_firmware(&fw, "tehuti/bdx.bin", &priv->pdev->dev);
                if (rc)
                        goto out;
                bdx_tx_push_desc_safe(priv, (char *)fw->data, fw->size);
@@ -2510,4 +2510,4 @@ module_exit(bdx_module_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(BDX_DRV_DESC);
-MODULE_FIRMWARE("tehuti/firmware.bin");
+MODULE_FIRMWARE("tehuti/bdx.bin");
index 5b83c3f35f47c3421a518aaa04fb39224dac2ed3..a3c46f6a15e7c5b02a91542406208928cdb23a6d 100644 (file)
@@ -1004,7 +1004,6 @@ typhoon_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
        }
 
        strcpy(info->driver, KBUILD_MODNAME);
-       strcpy(info->version, UTS_RELEASE);
        strcpy(info->bus_info, pci_name(pci_dev));
 }
 
index aea4645be7f68956472e6f6fbefeadb2e049f060..6140b56cce53d2205638803ce13702bcbfeb8910 100644 (file)
@@ -1507,6 +1507,10 @@ static const struct usb_device_id        products [] = {
        // ASIX AX88178 10/100/1000
        USB_DEVICE (0x0b95, 0x1780),
        .driver_info = (unsigned long) &ax88178_info,
+}, {
+       // Logitec LAN-GTJ/U2A
+       USB_DEVICE (0x0789, 0x0160),
+       .driver_info = (unsigned long) &ax88178_info,
 }, {
        // Linksys USB200M Rev 2
        USB_DEVICE (0x13b1, 0x0018),
index a6281e3987b5c47d6a061e1bb45538000bd6745e..2b791392e788ef893657d04056df673fc3ded672 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * MOSCHIP MCS7830 based USB 2.0 Ethernet Devices
+ * MOSCHIP MCS7830 based (7730/7830/7832) USB 2.0 Ethernet Devices
  *
  * based on usbnet.c, asix.c and the vendor provided mcs7830 driver
  *
@@ -11,6 +11,9 @@
  *
  * Definitions gathered from MOSCHIP, Data Sheet_7830DA.pdf (thanks!).
  *
+ * 2010-12-19: add 7832 USB PID ("functionality same as MCS7830"),
+ *             per active notification by manufacturer
+ *
  * TODO:
  * - support HIF_REG_CONFIG_SLEEPMODE/HIF_REG_CONFIG_TXENABLE (via autopm?)
  * - implement ethtool_ops get_pauseparam/set_pauseparam
@@ -60,6 +63,7 @@
 #define MCS7830_MAX_MCAST      64
 
 #define MCS7830_VENDOR_ID      0x9710
+#define MCS7832_PRODUCT_ID     0x7832
 #define MCS7830_PRODUCT_ID     0x7830
 #define MCS7730_PRODUCT_ID     0x7730
 
@@ -351,7 +355,7 @@ static int mcs7830_set_autoneg(struct usbnet *dev, int ptrUserPhyMode)
        if (!ret)
                ret = mcs7830_write_phy(dev, MII_BMCR,
                                BMCR_ANENABLE | BMCR_ANRESTART  );
-       return ret < 0 ? : 0;
+       return ret;
 }
 
 
@@ -626,7 +630,7 @@ static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 }
 
 static const struct driver_info moschip_info = {
-       .description    = "MOSCHIP 7830/7730 usb-NET adapter",
+       .description    = "MOSCHIP 7830/7832/7730 usb-NET adapter",
        .bind           = mcs7830_bind,
        .rx_fixup       = mcs7830_rx_fixup,
        .flags          = FLAG_ETHER,
@@ -644,6 +648,10 @@ static const struct driver_info sitecom_info = {
 };
 
 static const struct usb_device_id products[] = {
+       {
+               USB_DEVICE(MCS7830_VENDOR_ID, MCS7832_PRODUCT_ID),
+               .driver_info = (unsigned long) &moschip_info,
+       },
        {
                USB_DEVICE(MCS7830_VENDOR_ID, MCS7830_PRODUCT_ID),
                .driver_info = (unsigned long) &moschip_info,
index 0bbc0c3231358de20f395d9fd34b05279e0e13fd..cc83fa71c3ffb970b5107aa812e1e1956c9c7c82 100644 (file)
@@ -166,7 +166,9 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
        if (!(rcv->flags & IFF_UP))
                goto tx_drop;
 
-       if (dev->features & NETIF_F_NO_CSUM)
+       /* don't change ip_summed == CHECKSUM_PARTIAL, as that
+          will cause bad checksum on forwarded packets */
+       if (skb->ip_summed == CHECKSUM_NONE)
                skb->ip_summed = rcv_priv->ip_summed;
 
        length = skb->len + ETH_HLEN;
index 25a2722c8a986ce35a8a37a9076814095cc70ee3..1d9aed6457234fe0cc18c34fe198dc6ca4e4d62b 100644 (file)
@@ -891,7 +891,6 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local,
 
        SET_ETHTOOL_OPS(dev, &prism2_ethtool_ops);
 
-       netif_stop_queue(dev);
 }
 
 static int hostap_enable_hostapd(local_info_t *local, int rtnl_locked)
index db540910b1104d42b5d20d15e542c3fc5da7649c..0e027f787fbce6452b0c78fefc24dbd30cb75100 100644 (file)
@@ -315,6 +315,7 @@ struct iwl_cfg iwl100_bgn_cfg = {
        .mod_params = &iwlagn_mod_params,
        .base_params = &iwl1000_base_params,
        .ht_params = &iwl1000_ht_params,
+       .use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl100_bg_cfg = {
@@ -330,6 +331,7 @@ struct iwl_cfg iwl100_bg_cfg = {
        .ops = &iwl1000_ops,
        .mod_params = &iwlagn_mod_params,
        .base_params = &iwl1000_base_params,
+       .use_new_eeprom_reading = true,
 };
 
 MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
index 11e6532fc573d1ed93d5ec4aaf886342d0fe8073..0ceeaac85eda1ab8a8dd8a046044b47dc5e5df63 100644 (file)
@@ -561,6 +561,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
        .ht_params = &iwl6000_ht_params,
        .need_dc_calib = true,
        .need_temp_offset_calib = true,
+       .use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2a_2abg_cfg = {
@@ -578,6 +579,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = {
        .base_params = &iwl6000_base_params,
        .need_dc_calib = true,
        .need_temp_offset_calib = true,
+       .use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2a_2bg_cfg = {
@@ -595,6 +597,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = {
        .base_params = &iwl6000_base_params,
        .need_dc_calib = true,
        .need_temp_offset_calib = true,
+       .use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2b_2agn_cfg = {
@@ -616,6 +619,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
        .need_temp_offset_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+       .use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2b_2abg_cfg = {
@@ -636,6 +640,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
        .need_temp_offset_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+       .use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2b_2bgn_cfg = {
@@ -657,6 +662,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
        .need_temp_offset_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+       .use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2b_2bg_cfg = {
@@ -677,6 +683,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
        .need_temp_offset_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+       .use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2b_bgn_cfg = {
@@ -698,6 +705,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
        .need_temp_offset_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+       .use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6000g2b_bg_cfg = {
@@ -718,6 +726,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
        .need_temp_offset_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+       .use_new_eeprom_reading = true,
 };
 
 /*
@@ -804,6 +813,7 @@ struct iwl_cfg iwl6050g2_bgn_cfg = {
        .base_params = &iwl6050_base_params,
        .ht_params = &iwl6000_ht_params,
        .need_dc_calib = true,
+       .use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl6050_2abg_cfg = {
@@ -857,6 +867,7 @@ struct iwl_cfg iwl130_bgn_cfg = {
        .need_dc_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+       .use_new_eeprom_reading = true,
 };
 
 struct iwl_cfg iwl130_bg_cfg = {
@@ -876,6 +887,7 @@ struct iwl_cfg iwl130_bg_cfg = {
        .need_dc_calib = true,
        /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
        .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
+       .use_new_eeprom_reading = true,
 };
 
 MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
index a650baba0809d1bf1d56d86f687f7dc07cf53d1b..9eeeda18748de6fb12a09cc5f5b74c90553a4bf4 100644 (file)
@@ -392,7 +392,7 @@ static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
 /**
  * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
  */
-void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
+static void iwlcore_eeprom_enhanced_txpower_old(struct iwl_priv *priv)
 {
        int eeprom_section_count = 0;
        int section, element;
@@ -419,7 +419,8 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
                 * always check for valid entry before process
                 * the information
                 */
-               if (!enhanced_txpower->common || enhanced_txpower->reserved)
+               if (!(enhanced_txpower->flags || enhanced_txpower->channel) ||
+                   enhanced_txpower->delta_20_in_40)
                        continue;
 
                for (element = 0; element < eeprom_section_count; element++) {
@@ -452,3 +453,86 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
                }
        }
 }
+
+static void
+iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv,
+                                   struct iwl_eeprom_enhanced_txpwr *txp,
+                                   s8 max_txpower_avg)
+{
+       int ch_idx;
+       bool is_ht40 = txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ;
+       enum ieee80211_band band;
+
+       band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ?
+               IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ;
+
+       for (ch_idx = 0; ch_idx < priv->channel_count; ch_idx++) {
+               struct iwl_channel_info *ch_info = &priv->channel_info[ch_idx];
+
+               /* update matching channel or from common data only */
+               if (txp->channel != 0 && ch_info->channel != txp->channel)
+                       continue;
+
+               /* update matching band only */
+               if (band != ch_info->band)
+                       continue;
+
+               if (ch_info->max_power_avg < max_txpower_avg && !is_ht40) {
+                       ch_info->max_power_avg = max_txpower_avg;
+                       ch_info->curr_txpow = max_txpower_avg;
+                       ch_info->scan_power = max_txpower_avg;
+               }
+
+               if (is_ht40 && ch_info->ht40_max_power_avg < max_txpower_avg)
+                       ch_info->ht40_max_power_avg = max_txpower_avg;
+       }
+}
+
+#define EEPROM_TXP_OFFS        (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT)
+#define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr)
+#define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE)
+
+static void iwlcore_eeprom_enhanced_txpower_new(struct iwl_priv *priv)
+{
+       struct iwl_eeprom_enhanced_txpwr *txp_array, *txp;
+       int idx, entries;
+       __le16 *txp_len;
+       s8 max_txp_avg, max_txp_avg_halfdbm;
+
+       BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8);
+
+       /* the length is in 16-bit words, but we want entries */
+       txp_len = (__le16 *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS);
+       entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN;
+
+       txp_array = (void *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_OFFS);
+       for (idx = 0; idx < entries; idx++) {
+               txp = &txp_array[idx];
+
+               /* skip invalid entries */
+               if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID))
+                       continue;
+
+               max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx,
+                                                     &max_txp_avg_halfdbm);
+
+               /*
+                * Update the user limit values values to the highest
+                * power supported by any channel
+                */
+               if (max_txp_avg > priv->tx_power_user_lmt)
+                       priv->tx_power_user_lmt = max_txp_avg;
+               if (max_txp_avg_halfdbm > priv->tx_power_lmt_in_half_dbm)
+                       priv->tx_power_lmt_in_half_dbm = max_txp_avg_halfdbm;
+
+               iwlcore_eeprom_enh_txp_read_element(priv, txp, max_txp_avg);
+       }
+}
+
+void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
+{
+       if (priv->cfg->use_new_eeprom_reading)
+               iwlcore_eeprom_enhanced_txpower_new(priv);
+       else
+               iwlcore_eeprom_enhanced_txpower_old(priv);
+}
index b555edd533547e3bf98eed8e948a276ef141aace..554afb7d9670dff564873b9509cd59c3058a346e 100644 (file)
@@ -569,6 +569,12 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
        case INDIRECT_REGULATORY:
                offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY);
                break;
+       case INDIRECT_TXP_LIMIT:
+               offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT);
+               break;
+       case INDIRECT_TXP_LIMIT_SIZE:
+               offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE);
+               break;
        case INDIRECT_CALIBRATION:
                offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION);
                break;
index 64527def059f7de76ac0e4bdcadd0147576805c1..954ecc2c34c41f239dc1d24932d67be68aa741fa 100644 (file)
@@ -390,6 +390,7 @@ struct iwl_cfg {
        const bool need_temp_offset_calib; /* if used set to true */
        u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
        u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
+       const bool use_new_eeprom_reading; /* temporary, remove later */
 };
 
 /***************************
index d9b590625ae4eb16ba996d0bbd8d794acc30dae9..e3a279d2d0b6307fcf5d38948454cb7ba8da29c7 100644 (file)
@@ -120,6 +120,17 @@ struct iwl_eeprom_channel {
        s8 max_power_avg;       /* max power (dBm) on this chnl, limit 31 */
 } __packed;
 
+enum iwl_eeprom_enhanced_txpwr_flags {
+       IWL_EEPROM_ENH_TXP_FL_VALID             = BIT(0),
+       IWL_EEPROM_ENH_TXP_FL_BAND_52G          = BIT(1),
+       IWL_EEPROM_ENH_TXP_FL_OFDM              = BIT(2),
+       IWL_EEPROM_ENH_TXP_FL_40MHZ             = BIT(3),
+       IWL_EEPROM_ENH_TXP_FL_HT_AP             = BIT(4),
+       IWL_EEPROM_ENH_TXP_FL_RES1              = BIT(5),
+       IWL_EEPROM_ENH_TXP_FL_RES2              = BIT(6),
+       IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE       = BIT(7),
+};
+
 /**
  * iwl_eeprom_enhanced_txpwr structure
  *    This structure presents the enhanced regulatory tx power limit layout
@@ -127,21 +138,23 @@ struct iwl_eeprom_channel {
  *    Enhanced regulatory tx power portion of eeprom image can be broken down
  *    into individual structures; each one is 8 bytes in size and contain the
  *    following information
- * @common: (desc + channel) not used by driver, should _NOT_ be "zero"
+ * @flags: entry flags
+ * @channel: channel number
  * @chain_a_max_pwr: chain a max power in 1/2 dBm
  * @chain_b_max_pwr: chain b max power in 1/2 dBm
  * @chain_c_max_pwr: chain c max power in 1/2 dBm
- * @reserved: not used, should be "zero"
+ * @delta_20_in_40: 20-in-40 deltas (hi/lo)
  * @mimo2_max_pwr: mimo2 max power in 1/2 dBm
  * @mimo3_max_pwr: mimo3 max power in 1/2 dBm
  *
  */
 struct iwl_eeprom_enhanced_txpwr {
-       __le16 common;
+       u8 flags;
+       u8 channel;
        s8 chain_a_max;
        s8 chain_b_max;
        s8 chain_c_max;
-       s8 reserved;
+       u8 delta_20_in_40;
        s8 mimo2_max;
        s8 mimo3_max;
 } __packed;
@@ -186,6 +199,8 @@ struct iwl_eeprom_enhanced_txpwr {
 #define EEPROM_LINK_CALIBRATION      (2*0x67)
 #define EEPROM_LINK_PROCESS_ADJST    (2*0x68)
 #define EEPROM_LINK_OTHERS           (2*0x69)
+#define EEPROM_LINK_TXP_LIMIT        (2*0x6a)
+#define EEPROM_LINK_TXP_LIMIT_SIZE   (2*0x6b)
 
 /* agn regulatory - indirect access */
 #define EEPROM_REG_BAND_1_CHANNELS       ((0x08)\
@@ -389,6 +404,8 @@ struct iwl_eeprom_calib_info {
 #define INDIRECT_CALIBRATION        0x00040000
 #define INDIRECT_PROCESS_ADJST      0x00050000
 #define INDIRECT_OTHERS             0x00060000
+#define INDIRECT_TXP_LIMIT          0x00070000
+#define INDIRECT_TXP_LIMIT_SIZE     0x00080000
 #define INDIRECT_ADDRESS            0x00100000
 
 /* General */
index 373930afc26b50f2d7cddeb9027b07f8e5ad7775..113f4f204657ec911b6fe01c112f83f57d0d7fa8 100644 (file)
@@ -619,7 +619,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
                                     print_ssid(ssid_buf, ssid, ssid_len),
                                     LBS_SCAN_RSSI_TO_MBM(rssi)/100);
 
-                       if (channel ||
+                       if (channel &&
                            !(channel->flags & IEEE80211_CHAN_DISABLED))
                                cfg80211_inform_bss(wiphy, channel,
                                        bssid, le64_to_cpu(*(__le64 *)tsfdesc),
index d5bc21e5a02c7520d6599ad5822eafe85b267823..2325e56a9b0bd8cc35c7ee958be19ed5ff2adf2f 100644 (file)
@@ -43,6 +43,7 @@ MODULE_FIRMWARE("isl3887usb");
 
 static struct usb_device_id p54u_table[] __devinitdata = {
        /* Version 1 devices (pci chip + net2280) */
+       {USB_DEVICE(0x0411, 0x0050)},   /* Buffalo WLI2-USB2-G54 */
        {USB_DEVICE(0x045e, 0x00c2)},   /* Microsoft MN-710 */
        {USB_DEVICE(0x0506, 0x0a11)},   /* 3COM 3CRWE254G72 */
        {USB_DEVICE(0x06b9, 0x0120)},   /* Thomson SpeedTouch 120g */
@@ -56,9 +57,13 @@ static struct usb_device_id p54u_table[] __devinitdata = {
        {USB_DEVICE(0x0846, 0x4220)},   /* Netgear WG111 */
        {USB_DEVICE(0x09aa, 0x1000)},   /* Spinnaker Proto board */
        {USB_DEVICE(0x0cde, 0x0006)},   /* Medion 40900, Roper Europe */
+       {USB_DEVICE(0x0db0, 0x6826)},   /* MSI UB54G (MS-6826) */
        {USB_DEVICE(0x107b, 0x55f2)},   /* Gateway WGU-210 (Gemtek) */
        {USB_DEVICE(0x124a, 0x4023)},   /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
+       {USB_DEVICE(0x1435, 0x0210)},   /* Inventel UR054G */
+       {USB_DEVICE(0x15a9, 0x0002)},   /* Gemtek WUBI-100GW 802.11g */
        {USB_DEVICE(0x1630, 0x0005)},   /* 2Wire 802.11g USB (v1) / Z-Com */
+       {USB_DEVICE(0x182d, 0x096b)},   /* Sitecom WL-107 */
        {USB_DEVICE(0x1915, 0x2234)},   /* Linksys WUSB54G OEM */
        {USB_DEVICE(0x1915, 0x2235)},   /* Linksys WUSB54G Portable OEM */
        {USB_DEVICE(0x2001, 0x3701)},   /* DLink DWL-G120 Spinnaker */
@@ -94,6 +99,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
        {USB_DEVICE(0x1435, 0x0427)},   /* Inventel UR054G */
        {USB_DEVICE(0x1668, 0x1050)},   /* Actiontec 802UIG-1 */
        {USB_DEVICE(0x2001, 0x3704)},   /* DLink DWL-G122 rev A2 */
+       {USB_DEVICE(0x2001, 0x3705)},   /* D-Link DWL-G120 rev C1 */
        {USB_DEVICE(0x413c, 0x5513)},   /* Dell WLA3310 USB Wireless Adapter */
        {USB_DEVICE(0x413c, 0x8102)},   /* Spinnaker DUT */
        {USB_DEVICE(0x413c, 0x8104)},   /* Cohiba Proto board */
index b267395359863ca10a55fe8a39f186e5bf08deb9..09a67905c230e5f9a9029ba2c786a707d73b5108 100644 (file)
@@ -912,6 +912,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
        __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
        __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
        __set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags);
+       __set_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags);
        if (!modparam_nohwcrypt)
                __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
        __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
index 94fe589acfaabff06eac097fe7e3ae3e2f7ea310..ab43e7ca2a231000ba0d40489860f950883be16d 100644 (file)
@@ -664,6 +664,7 @@ enum rt2x00_flags {
        DRIVER_REQUIRE_COPY_IV,
        DRIVER_REQUIRE_L2PAD,
        DRIVER_REQUIRE_TXSTATUS_FIFO,
+       DRIVER_REQUIRE_TASKLET_CONTEXT,
 
        /*
         * Driver features
index 5ba79b935f09f5bed56f999653338501584cf141..d019830ca8407c2aa10ed0ae95abe8679c654e55 100644 (file)
@@ -390,9 +390,12 @@ void rt2x00lib_txdone(struct queue_entry *entry,
         * through a mac80211 library call (RTS/CTS) then we should not
         * send the status report back.
         */
-       if (!(skbdesc_flags & SKBDESC_NOT_MAC80211))
-               ieee80211_tx_status(rt2x00dev->hw, entry->skb);
-       else
+       if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) {
+               if (test_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags))
+                       ieee80211_tx_status(rt2x00dev->hw, entry->skb);
+               else
+                       ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb);
+       } else
                dev_kfree_skb_any(entry->skb);
 
        /*
index cd1b3dcd61db67671e28df47cae7a19293fa881f..ec47e22fa186ce89ed7c2758998e6ff008d140aa 100644 (file)
@@ -744,7 +744,7 @@ static int yellowfin_init_ring(struct net_device *dev)
        }
 
        for (i = 0; i < RX_RING_SIZE; i++) {
-               struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz);
+               struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz + 2);
                yp->rx_skbuff[i] = skb;
                if (skb == NULL)
                        break;
@@ -1157,7 +1157,7 @@ static int yellowfin_rx(struct net_device *dev)
        for (; yp->cur_rx - yp->dirty_rx > 0; yp->dirty_rx++) {
                entry = yp->dirty_rx % RX_RING_SIZE;
                if (yp->rx_skbuff[entry] == NULL) {
-                       struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz);
+                       struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz + 2);
                        if (skb == NULL)
                                break;                          /* Better luck next round. */
                        yp->rx_skbuff[entry] = skb;
index c85d3c7421fc94796c6814d0c453b33f831a9279..f37fbeb66a4400c2c7fa28bc45cd8be5af7c7c47 100644 (file)
@@ -61,7 +61,7 @@ void of_i2c_register_devices(struct i2c_adapter *adap)
                info.of_node = of_node_get(node);
                info.archdata = &dev_ad;
 
-               request_module("%s", info.type);
+               request_module("%s%s", I2C_MODULE_PREFIX, info.type);
 
                result = i2c_new_device(adap, &info);
                if (result == NULL) {
index c94502dfac664f55fd42080695989d9e1cb1697b..045d7e87b6323e36213d57ee6615c6362f53bab7 100644 (file)
@@ -677,7 +677,7 @@ bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
        bfa_trc(fabric->fcs, event);
        wwn2str(pwwn_ptr, fabric->bport.port_cfg.pwwn);
 
-       BFA_LOG(KERN_INFO, bfad, log_level,
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "Port is isolated due to VF_ID mismatch. "
                "PWWN: %s Port VF_ID: %04x switch port VF_ID: %04x.",
                pwwn_ptr, fabric->fcs->port_vfid,
@@ -1411,7 +1411,7 @@ bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
                wwn2str(pwwn_ptr, bfa_fcs_lport_get_pwwn(&fabric->bport));
                wwn2str(fwwn_ptr,
                        bfa_fcs_lport_get_fabric_name(&fabric->bport));
-               BFA_LOG(KERN_WARNING, bfad, log_level,
+               BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
                        "Base port WWN = %s Fabric WWN = %s\n",
                        pwwn_ptr, fwwn_ptr);
        }
index 9662bcdeb41d64c50ab7530fd34ab17d543fc44c..413b58eef93a08088cc7957d63fc9c815d58027c 100644 (file)
@@ -261,7 +261,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
                bfa_fcb_itnim_online(itnim->itnim_drv);
                wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port));
                wwn2str(rpwwn_buf, itnim->rport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "Target (WWN = %s) is online for initiator (WWN = %s)\n",
                rpwwn_buf, lpwwn_buf);
                break;
@@ -301,11 +301,11 @@ bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
                wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port));
                wwn2str(rpwwn_buf, itnim->rport->pwwn);
                if (bfa_fcs_lport_is_online(itnim->rport->port) == BFA_TRUE)
-                       BFA_LOG(KERN_ERR, bfad, log_level,
+                       BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                        "Target (WWN = %s) connectivity lost for "
                        "initiator (WWN = %s)\n", rpwwn_buf, lpwwn_buf);
                else
-                       BFA_LOG(KERN_INFO, bfad, log_level,
+                       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Target (WWN = %s) offlined by initiator (WWN = %s)\n",
                        rpwwn_buf, lpwwn_buf);
                break;
index 377cbfff6f2ec88a467b6e8014d27c91d3b4a0c3..8d651309302b1f745ef842869ce782d8c9f490b6 100644 (file)
@@ -491,7 +491,7 @@ bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port)
        __port_action[port->fabric->fab_type].online(port);
 
        wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
-       BFA_LOG(KERN_INFO, bfad, log_level,
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "Logical port online: WWN = %s Role = %s\n",
                lpwwn_buf, "Initiator");
 
@@ -512,11 +512,11 @@ bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port)
 
        wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
        if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE)
-               BFA_LOG(KERN_ERR, bfad, log_level,
+               BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                "Logical port lost fabric connectivity: WWN = %s Role = %s\n",
                lpwwn_buf, "Initiator");
        else
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "Logical port taken offline: WWN = %s Role = %s\n",
                lpwwn_buf, "Initiator");
 
@@ -573,7 +573,7 @@ bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port)
        char    lpwwn_buf[BFA_STRING_32];
 
        wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
-       BFA_LOG(KERN_INFO, bfad, log_level,
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "Logical port deleted: WWN = %s Role = %s\n",
                lpwwn_buf, "Initiator");
 
@@ -878,7 +878,7 @@ bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport,
                                        vport ? vport->vport_drv : NULL);
 
        wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport));
-       BFA_LOG(KERN_INFO, bfad, log_level,
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "New logical port created: WWN = %s Role = %s\n",
                lpwwn_buf, "Initiator");
 
index 47f35c0ef29a0c69f5d6842a6db0d173a0195e84..cf4a6e73e60d7dfa5bcaf9b7d94ea986d7389a57 100644 (file)
@@ -2056,7 +2056,7 @@ bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
        wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
        wwn2str(rpwwn_buf, rport->pwwn);
        if (!BFA_FCS_PID_IS_WKA(rport->pid))
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "Remote port (WWN = %s) online for logical port (WWN = %s)\n",
                rpwwn_buf, lpwwn_buf);
 }
@@ -2075,12 +2075,12 @@ bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport)
        wwn2str(rpwwn_buf, rport->pwwn);
        if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
                if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE)
-                       BFA_LOG(KERN_ERR, bfad, log_level,
+                       BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                                "Remote port (WWN = %s) connectivity lost for "
                                "logical port (WWN = %s)\n",
                                rpwwn_buf, lpwwn_buf);
                else
-                       BFA_LOG(KERN_INFO, bfad, log_level,
+                       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                                "Remote port (WWN = %s) offlined by "
                                "logical port (WWN = %s)\n",
                                rpwwn_buf, lpwwn_buf);
index 54475b53a5ab1494490f2561fdc0c9d7884c0a55..9f4aa391ea9deca5508a0ae90060572ec8a53889 100644 (file)
@@ -402,7 +402,7 @@ bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
 
        ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
        bfa_ioc_hb_monitor(ioc);
-       BFA_LOG(KERN_INFO, bfad, log_level, "IOC enabled\n");
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n");
 }
 
 static void
@@ -444,7 +444,7 @@ bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc)
 {
        struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
        bfa_iocpf_disable(ioc);
-       BFA_LOG(KERN_INFO, bfad, log_level, "IOC disabled\n");
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC disabled\n");
 }
 
 /*
@@ -565,7 +565,7 @@ bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc)
                notify->cbfn(notify->cbarg);
        }
 
-       BFA_LOG(KERN_CRIT, bfad, log_level,
+       BFA_LOG(KERN_CRIT, bfad, bfa_log_level,
                "Heart Beat of IOC has failed\n");
 }
 
@@ -1812,7 +1812,7 @@ bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc)
         * Provide enable completion callback.
         */
        ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
-       BFA_LOG(KERN_WARNING, bfad, log_level,
+       BFA_LOG(KERN_WARNING, bfad, bfa_log_level,
                "Running firmware version is incompatible "
                "with the driver version\n");
 }
index c768143f4805a7cb5f0094682a39c30b73ea433d..37e16ac8f249a33a4045506df74c360d3c5eb698 100644 (file)
@@ -2138,7 +2138,7 @@ bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
                bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                                BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
                wwn2str(pwwn_buf, fcport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port disabled: WWN = %s\n", pwwn_buf);
                break;
 
@@ -2198,7 +2198,7 @@ bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
                bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                                BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
                wwn2str(pwwn_buf, fcport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port disabled: WWN = %s\n", pwwn_buf);
                break;
 
@@ -2251,7 +2251,7 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
 
                bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE);
                wwn2str(pwwn_buf, fcport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port online: WWN = %s\n", pwwn_buf);
                break;
 
@@ -2277,7 +2277,7 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
                bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                                BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
                wwn2str(pwwn_buf, fcport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port disabled: WWN = %s\n", pwwn_buf);
                break;
 
@@ -2322,9 +2322,9 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
                bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                                BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
                wwn2str(pwwn_buf, fcport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port offline: WWN = %s\n", pwwn_buf);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port disabled: WWN = %s\n", pwwn_buf);
                break;
 
@@ -2336,10 +2336,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
                                BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
                wwn2str(pwwn_buf, fcport->pwwn);
                if (BFA_PORT_IS_DISABLED(fcport->bfa))
-                       BFA_LOG(KERN_INFO, bfad, log_level,
+                       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                                "Base port offline: WWN = %s\n", pwwn_buf);
                else
-                       BFA_LOG(KERN_ERR, bfad, log_level,
+                       BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                                "Base port (WWN = %s) "
                                "lost fabric connectivity\n", pwwn_buf);
                break;
@@ -2349,10 +2349,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
                bfa_fcport_reset_linkinfo(fcport);
                wwn2str(pwwn_buf, fcport->pwwn);
                if (BFA_PORT_IS_DISABLED(fcport->bfa))
-                       BFA_LOG(KERN_INFO, bfad, log_level,
+                       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                                "Base port offline: WWN = %s\n", pwwn_buf);
                else
-                       BFA_LOG(KERN_ERR, bfad, log_level,
+                       BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                                "Base port (WWN = %s) "
                                "lost fabric connectivity\n", pwwn_buf);
                break;
@@ -2363,10 +2363,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
                bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE);
                wwn2str(pwwn_buf, fcport->pwwn);
                if (BFA_PORT_IS_DISABLED(fcport->bfa))
-                       BFA_LOG(KERN_INFO, bfad, log_level,
+                       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                                "Base port offline: WWN = %s\n", pwwn_buf);
                else
-                       BFA_LOG(KERN_ERR, bfad, log_level,
+                       BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                                "Base port (WWN = %s) "
                                "lost fabric connectivity\n", pwwn_buf);
                break;
@@ -2497,7 +2497,7 @@ bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
                bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                                BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
                wwn2str(pwwn_buf, fcport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port enabled: WWN = %s\n", pwwn_buf);
                break;
 
@@ -2551,7 +2551,7 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
                bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
                                BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
                wwn2str(pwwn_buf, fcport->pwwn);
-               BFA_LOG(KERN_INFO, bfad, log_level,
+               BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                        "Base port enabled: WWN = %s\n", pwwn_buf);
                break;
 
index 1f938974b84876978600b40d97c265ddd7c2c7c0..6797720213b233bf444937445be983630e60d50d 100644 (file)
@@ -50,7 +50,7 @@ int           reqq_size, rspq_size, num_sgpgs;
 int            rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT;
 int            bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
 int            bfa_io_max_sge = BFAD_IO_MAX_SGE;
-int            log_level = 3; /* WARNING log level */
+int            bfa_log_level = 3; /* WARNING log level */
 int            ioc_auto_recover = BFA_TRUE;
 int            bfa_linkup_delay = -1;
 int            fdmi_enable = BFA_TRUE;
@@ -108,8 +108,8 @@ module_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(bfa_lun_queue_depth, "Lun queue depth, default=32, Range[>0]");
 module_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(bfa_io_max_sge, "Max io scatter/gather elements, default=255");
-module_param(log_level, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(log_level, "Driver log level, default=3, "
+module_param(bfa_log_level, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(bfa_log_level, "Driver log level, default=3, "
                                "Range[Critical:1|Error:2|Warning:3|Info:4]");
 module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(ioc_auto_recover, "IOC auto recovery, default=1, "
@@ -1112,7 +1112,7 @@ bfad_start_ops(struct bfad_s *bfad) {
        } else
                bfad_os_rport_online_wait(bfad);
 
-       BFA_LOG(KERN_INFO, bfad, log_level, "bfa device claimed\n");
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level, "bfa device claimed\n");
 
        return BFA_STATUS_OK;
 }
index 97f9b6c0937e75cf3a16762092ac46ac6f6cb890..d5ce2349ac59fa5c13c6d3b89d3ec2927561b84c 100644 (file)
@@ -337,7 +337,7 @@ extern int  num_sgpgs;
 extern int      rport_del_timeout;
 extern int      bfa_lun_queue_depth;
 extern int      bfa_io_max_sge;
-extern int      log_level;
+extern int      bfa_log_level;
 extern int      ioc_auto_recover;
 extern int      bfa_linkup_delay;
 extern int      msix_disable_cb;
index 8ca967dee66d4eac1b551c82ff5416454e0ffcb6..fbad5e9b240218bb349ac4c5217e328e785106c3 100644 (file)
@@ -225,7 +225,8 @@ bfad_im_abort_handler(struct scsi_cmnd *cmnd)
        }
 
        bfa_trc(bfad, hal_io->iotag);
-       BFA_LOG(KERN_INFO, bfad, log_level, "scsi%d: abort cmnd %p iotag %x\n",
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
+               "scsi%d: abort cmnd %p iotag %x\n",
                im_port->shost->host_no, cmnd, hal_io->iotag);
        (void) bfa_ioim_abort(hal_io);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -241,7 +242,7 @@ bfad_im_abort_handler(struct scsi_cmnd *cmnd)
 
        cmnd->scsi_done(cmnd);
        bfa_trc(bfad, hal_io->iotag);
-       BFA_LOG(KERN_INFO, bfad, log_level,
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "scsi%d: complete abort 0x%p iotag 0x%x\n",
                im_port->shost->host_no, cmnd, hal_io->iotag);
        return SUCCESS;
@@ -260,7 +261,7 @@ bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd,
 
        tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd);
        if (!tskim) {
-               BFA_LOG(KERN_ERR, bfad, log_level,
+               BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                        "target reset, fail to allocate tskim\n");
                rc = BFA_STATUS_FAILED;
                goto out;
@@ -311,7 +312,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
 
        tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd);
        if (!tskim) {
-               BFA_LOG(KERN_ERR, bfad, log_level,
+               BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                                "LUN reset, fail to allocate tskim");
                spin_unlock_irqrestore(&bfad->bfad_lock, flags);
                rc = FAILED;
@@ -336,7 +337,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
 
        task_status = cmnd->SCp.Status >> 1;
        if (task_status != BFI_TSKIM_STS_OK) {
-               BFA_LOG(KERN_ERR, bfad, log_level,
+               BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                        "LUN reset failure, status: %d\n", task_status);
                rc = FAILED;
        }
@@ -380,7 +381,7 @@ bfad_im_reset_bus_handler(struct scsi_cmnd *cmnd)
 
                        task_status = cmnd->SCp.Status >> 1;
                        if (task_status != BFI_TSKIM_STS_OK) {
-                               BFA_LOG(KERN_ERR, bfad, log_level,
+                               BFA_LOG(KERN_ERR, bfad, bfa_log_level,
                                        "target reset failure,"
                                        " status: %d\n", task_status);
                                err_cnt++;
@@ -460,7 +461,7 @@ bfa_fcb_itnim_free(struct bfad_s *bfad, struct bfad_itnim_s *itnim_drv)
        fcid = bfa_fcs_itnim_get_fcid(&itnim_drv->fcs_itnim);
        wwn2str(wwpn_str, wwpn);
        fcid2str(fcid_str, fcid);
-       BFA_LOG(KERN_INFO, bfad, log_level,
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                "ITNIM FREE scsi%d: FCID: %s WWPN: %s\n",
                port->im_port->shost->host_no,
                fcid_str, wwpn_str);
@@ -589,7 +590,7 @@ void
 bfad_im_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
 {
        bfa_trc(bfad, bfad->inst_no);
-       BFA_LOG(KERN_INFO, bfad, log_level, "Free scsi%d\n",
+       BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Free scsi%d\n",
                        im_port->shost->host_no);
 
        fc_remove_host(im_port->shost);
@@ -1048,7 +1049,7 @@ bfad_im_itnim_work_handler(struct work_struct *work)
                        fcid2str(fcid_str, fcid);
                        list_add_tail(&itnim->list_entry,
                                &im_port->itnim_mapped_list);
-                       BFA_LOG(KERN_INFO, bfad, log_level,
+                       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                                "ITNIM ONLINE Target: %d:0:%d "
                                "FCID: %s WWPN: %s\n",
                                im_port->shost->host_no,
@@ -1081,7 +1082,7 @@ bfad_im_itnim_work_handler(struct work_struct *work)
                        wwn2str(wwpn_str, wwpn);
                        fcid2str(fcid_str, fcid);
                        list_del(&itnim->list_entry);
-                       BFA_LOG(KERN_INFO, bfad, log_level,
+                       BFA_LOG(KERN_INFO, bfad, bfa_log_level,
                                "ITNIM OFFLINE Target: %d:0:%d "
                                "FCID: %s WWPN: %s\n",
                                im_port->shost->host_no,
index e5e9e6735f7d62e3d585505de7be4fe379fbbd40..9739431092d126aefdef78ec03888c66b40b256d 100644 (file)
@@ -198,6 +198,7 @@ int __init register_intc_controller(struct intc_desc *desc)
        list_add_tail(&d->list, &intc_list);
 
        raw_spin_lock_init(&d->lock);
+       INIT_RADIX_TREE(&d->tree, GFP_ATOMIC);
 
        d->index = nr_intc_controllers;
 
index ec9f0b1bf86494da73bd8d14cc69fe5927db8065..84439f655601f71577483acd423aed7622fae807 100644 (file)
@@ -563,7 +563,7 @@ static struct of_platform_driver mpc52xx_spi_of_driver = {
                .of_match_table = mpc52xx_spi_match,
        },
        .probe = mpc52xx_spi_probe,
-       .remove = __exit_p(mpc52xx_spi_remove),
+       .remove = __devexit_p(mpc52xx_spi_remove),
 };
 
 static int __init mpc52xx_spi_init(void)
index e3b4f645196603e517e22ef782205a02fb224b22..a99e2333b949efdbc10e391253ae952137238b7d 100644 (file)
@@ -258,18 +258,18 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
        return mpc8xxx_spi->count;
 }
 
-static void fsl_espi_addr2cmd(unsigned int addr, u8 *cmd)
+static inline void fsl_espi_addr2cmd(unsigned int addr, u8 *cmd)
 {
-       if (cmd[1] && cmd[2] && cmd[3]) {
+       if (cmd) {
                cmd[1] = (u8)(addr >> 16);
                cmd[2] = (u8)(addr >> 8);
                cmd[3] = (u8)(addr >> 0);
        }
 }
 
-static unsigned int fsl_espi_cmd2addr(u8 *cmd)
+static inline unsigned int fsl_espi_cmd2addr(u8 *cmd)
 {
-       if (cmd[1] && cmd[2] && cmd[3])
+       if (cmd)
                return cmd[1] << 16 | cmd[2] << 8 | cmd[3] << 0;
 
        return 0;
@@ -395,9 +395,11 @@ static void fsl_espi_rw_trans(struct spi_message *m,
                        }
                }
 
-               addr = fsl_espi_cmd2addr(local_buf);
-               addr += pos;
-               fsl_espi_addr2cmd(addr, local_buf);
+               if (pos > 0) {
+                       addr = fsl_espi_cmd2addr(local_buf);
+                       addr += pos;
+                       fsl_espi_addr2cmd(addr, local_buf);
+               }
 
                espi_trans->n_tx = n_tx;
                espi_trans->n_rx = trans_len;
@@ -507,16 +509,29 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
 
        /* We need handle RX first */
        if (events & SPIE_NE) {
-               u32 rx_data;
+               u32 rx_data, tmp;
+               u8 rx_data_8;
 
                /* Spin until RX is done */
                while (SPIE_RXCNT(events) < min(4, mspi->len)) {
                        cpu_relax();
                        events = mpc8xxx_spi_read_reg(&reg_base->event);
                }
-               mspi->len -= 4;
 
-               rx_data = mpc8xxx_spi_read_reg(&reg_base->receive);
+               if (mspi->len >= 4) {
+                       rx_data = mpc8xxx_spi_read_reg(&reg_base->receive);
+               } else {
+                       tmp = mspi->len;
+                       rx_data = 0;
+                       while (tmp--) {
+                               rx_data_8 = in_8((u8 *)&reg_base->receive);
+                               rx_data |= (rx_data_8 << (tmp * 8));
+                       }
+
+                       rx_data <<= (4 - mspi->len) * 8;
+               }
+
+               mspi->len -= 4;
 
                if (mspi->rx)
                        mspi->get_rx(rx_data, mspi);
index 0e6aa3d96a4246f7c05b0274a2295a3275d6d2ac..4ac1201ad6c2fb3229a60e1377f29b4eef78a2eb 100644 (file)
@@ -1458,7 +1458,7 @@ static bool apertures_overlap(struct aperture *gen, struct aperture *hw)
        if (gen->base == hw->base)
                return true;
        /* is the generic aperture base inside the hw base->hw base+size */
-       if (gen->base > hw->base && gen->base <= hw->base + hw->size)
+       if (gen->base > hw->base && gen->base < hw->base + hw->size)
                return true;
        return false;
 }
index 5c363d026f64c2856b44e748ecb149d9242be6b6..1ab2c25886757616c4faa324620ed7536fac9350 100644 (file)
 #define LCDC_SIZE      0x04
 #define SIZE_XMAX(x)   ((((x) >> 4) & 0x3f) << 20)
 
-#ifdef CONFIG_ARCH_MX1
-#define SIZE_YMAX(y)   ((y) & 0x1ff)
-#else
-#define SIZE_YMAX(y)   ((y) & 0x3ff)
-#endif
+#define YMAX_MASK       (cpu_is_mx1() ? 0x1ff : 0x3ff)
+#define SIZE_YMAX(y)   ((y) & YMAX_MASK)
 
 #define LCDC_VPW       0x08
 #define VPW_VPW(x)     ((x) & 0x3ff)
@@ -623,7 +620,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
        if (var->right_margin > 255)
                printk(KERN_ERR "%s: invalid right_margin %d\n",
                        info->fix.id, var->right_margin);
-       if (var->yres < 1 || var->yres > 511)
+       if (var->yres < 1 || var->yres > YMAX_MASK)
                printk(KERN_ERR "%s: invalid yres %d\n",
                        info->fix.id, var->yres);
        if (var->vsync_len > 100)
index d7df10315d8d6f51aba676328985a52128e81876..fcda0e97011384bd7ee55eaeeed5377f328cf016 100644 (file)
@@ -787,6 +787,9 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi)
                found_rate_error = rate_error;
        }
 
+       hdmi->var.width = hdmi->monspec.max_x * 10;
+       hdmi->var.height = hdmi->monspec.max_y * 10;
+
        /*
         * TODO 1: if no ->info is present, postpone running the config until
         * after ->info first gets registered.
@@ -960,8 +963,12 @@ static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)
        dev_dbg(info->dev, "Old %ux%u, new %ux%u\n",
                mode1.xres, mode1.yres, mode2.xres, mode2.yres);
 
-       if (fb_mode_is_equal(&mode1, &mode2))
+       if (fb_mode_is_equal(&mode1, &mode2)) {
+               /* It can be a different monitor with an equal video-mode */
+               old_var->width = new_var->width;
+               old_var->height = new_var->height;
                return false;
+       }
 
        dev_dbg(info->dev, "Switching %u -> %u lines\n",
                mode1.yres, mode2.yres);
@@ -1057,8 +1064,11 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
                         * on, if we run a resume here, the logo disappears
                         */
                        if (lock_fb_info(hdmi->info)) {
-                               sh_hdmi_display_on(hdmi, hdmi->info);
-                               unlock_fb_info(hdmi->info);
+                               struct fb_info *info = hdmi->info;
+                               info->var.width = hdmi->var.width;
+                               info->var.height = hdmi->var.height;
+                               sh_hdmi_display_on(hdmi, info);
+                               unlock_fb_info(info);
                        }
                } else {
                        /* New monitor or have to wake up */
index b02d97a879d67256992a3941536fcd7e88626f63..c05326b61235e724e18ea288d88aa66138751899 100644 (file)
@@ -54,8 +54,8 @@ static int lcdc_shared_regs[] = {
 };
 #define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs)
 
-#define DEFAULT_XRES 1280
-#define DEFAULT_YRES 1024
+#define MAX_XRES 1920
+#define MAX_YRES 1080
 
 static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
        [LDDCKPAT1R] = 0x400,
@@ -914,22 +914,12 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in
 {
        struct sh_mobile_lcdc_chan *ch = info->par;
 
-       if (var->xres < 160 || var->xres > 1920 ||
-           var->yres < 120 || var->yres > 1080 ||
-           var->left_margin < 32 || var->left_margin > 320 ||
-           var->right_margin < 12 || var->right_margin > 240 ||
-           var->upper_margin < 12 || var->upper_margin > 120 ||
-           var->lower_margin < 1 || var->lower_margin > 64 ||
-           var->hsync_len < 32 || var->hsync_len > 240 ||
-           var->vsync_len < 2 || var->vsync_len > 64 ||
-           var->pixclock < 6000 || var->pixclock > 40000 ||
+       if (var->xres > MAX_XRES || var->yres > MAX_YRES ||
            var->xres * var->yres * (ch->cfg.bpp / 8) * 2 > info->fix.smem_len) {
-               dev_warn(info->dev, "Invalid info: %u %u %u %u %u %u %u %u %u!\n",
-                        var->xres, var->yres,
-                        var->left_margin, var->right_margin,
-                        var->upper_margin, var->lower_margin,
-                        var->hsync_len, var->vsync_len,
-                        var->pixclock);
+               dev_warn(info->dev, "Invalid info: %u-%u-%u-%u x %u-%u-%u-%u @ %ukHz!\n",
+                        var->left_margin, var->xres, var->right_margin, var->hsync_len,
+                        var->upper_margin, var->yres, var->lower_margin, var->vsync_len,
+                        PICOS2KHZ(var->pixclock));
                return -EINVAL;
        }
        return 0;
@@ -1226,7 +1216,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
                }
 
                if (!mode)
-                       max_size = DEFAULT_XRES * DEFAULT_YRES;
+                       max_size = MAX_XRES * MAX_YRES;
                else if (max_cfg)
                        dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n",
                                max_cfg->xres, max_cfg->yres);
@@ -1238,12 +1228,14 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
                        mode = &default_720p;
                        num_cfg = 1;
                } else {
-                       num_cfg = ch->cfg.num_cfg;
+                       num_cfg = cfg->num_cfg;
                }
 
                fb_videomode_to_modelist(mode, num_cfg, &info->modelist);
 
                fb_videomode_to_var(var, mode);
+               var->width = cfg->lcd_size_cfg.width;
+               var->height = cfg->lcd_size_cfg.height;
                /* Default Y virtual resolution is 2x panel size */
                var->yres_virtual = var->yres * 2;
                var->activate = FB_ACTIVATE_NOW;
index dc963929de652cb997550e38338855823832e53c..981c8477adab6dcde6708d2b8bfde8bf83c8d53b 100644 (file)
@@ -232,6 +232,8 @@ static int setup_new_group_blocks(struct super_block *sb,
                               GFP_NOFS);
        if (err)
                goto exit_bh;
+       for (i = 0, bit = gdblocks + 1; i < reserved_gdb; i++, bit++)
+               ext4_set_bit(bit, bh->b_data);
 
        ext4_debug("mark block bitmap %#04llx (+%llu)\n", input->block_bitmap,
                   input->block_bitmap - start);
@@ -247,6 +249,9 @@ static int setup_new_group_blocks(struct super_block *sb,
        err = sb_issue_zeroout(sb, block, sbi->s_itb_per_group, GFP_NOFS);
        if (err)
                goto exit_bh;
+       for (i = 0, bit = input->inode_table - start;
+            i < sbi->s_itb_per_group; i++, bit++)
+               ext4_set_bit(bit, bh->b_data);
 
        if ((err = extend_or_restart_transaction(handle, 2, bh)))
                goto exit_bh;
index f1e962cb3b73084699a182933b7760926c36880e..0d7c5540ad669a55d4def39f21bbe7b42bfb83cc 100644 (file)
@@ -573,11 +573,14 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
        /* this io's submitter should not have unlocked this before we could */
        BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));
 
+       if (ocfs2_iocb_is_sem_locked(iocb)) {
+               up_read(&inode->i_alloc_sem);
+               ocfs2_iocb_clear_sem_locked(iocb);
+       }
+
        ocfs2_iocb_clear_rw_locked(iocb);
 
        level = ocfs2_iocb_rw_locked_level(iocb);
-       if (!level)
-               up_read(&inode->i_alloc_sem);
        ocfs2_rw_unlock(inode, level);
 
        if (is_async)
index 76bfdfda691a03b1790ac9670a8bb79d042e7584..eceb456037c11c7a2e68cc2d510908ef781cfdbf 100644 (file)
@@ -68,8 +68,27 @@ static inline void ocfs2_iocb_set_rw_locked(struct kiocb *iocb, int level)
        else
                clear_bit(1, (unsigned long *)&iocb->private);
 }
+
+/*
+ * Using a named enum representing lock types in terms of #N bit stored in
+ * iocb->private, which is going to be used for communication bewteen
+ * ocfs2_dio_end_io() and ocfs2_file_aio_write/read().
+ */
+enum ocfs2_iocb_lock_bits {
+       OCFS2_IOCB_RW_LOCK = 0,
+       OCFS2_IOCB_RW_LOCK_LEVEL,
+       OCFS2_IOCB_SEM,
+       OCFS2_IOCB_NUM_LOCKS
+};
+
 #define ocfs2_iocb_clear_rw_locked(iocb) \
-       clear_bit(0, (unsigned long *)&iocb->private)
+       clear_bit(OCFS2_IOCB_RW_LOCK, (unsigned long *)&iocb->private)
 #define ocfs2_iocb_rw_locked_level(iocb) \
-       test_bit(1, (unsigned long *)&iocb->private)
+       test_bit(OCFS2_IOCB_RW_LOCK_LEVEL, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_set_sem_locked(iocb) \
+       set_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_clear_sem_locked(iocb) \
+       clear_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_is_sem_locked(iocb) \
+       test_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
 #endif /* OCFS2_FILE_H */
index c7fba396392d8c0a866c5194204eb1abb49d827d..6c61771469af24ef9e2610e93e65092768b59691 100644 (file)
@@ -113,10 +113,11 @@ static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = {
        define_mask(QUOTA),
        define_mask(REFCOUNT),
        define_mask(BASTS),
+       define_mask(RESERVATIONS),
+       define_mask(CLUSTER),
        define_mask(ERROR),
        define_mask(NOTICE),
        define_mask(KTHREAD),
-       define_mask(RESERVATIONS),
 };
 
 static struct attribute *mlog_attr_ptrs[MLOG_MAX_BITS] = {NULL, };
index ea2ed9f56c94ad0654a5f79259e50a1f046bed97..34d6544357d9718699af25e25aecc48a1f26c9c0 100644 (file)
@@ -81,7 +81,7 @@
 #include <linux/sched.h>
 
 /* bits that are frequently given and infrequently matched in the low word */
-/* NOTE: If you add a flag, you need to also update mlog.c! */
+/* NOTE: If you add a flag, you need to also update masklog.c! */
 #define ML_ENTRY       0x0000000000000001ULL /* func call entry */
 #define ML_EXIT                0x0000000000000002ULL /* func call exit */
 #define ML_TCP         0x0000000000000004ULL /* net cluster/tcp.c */
 #define ML_XATTR       0x0000000020000000ULL /* ocfs2 extended attributes */
 #define ML_QUOTA       0x0000000040000000ULL /* ocfs2 quota operations */
 #define ML_REFCOUNT    0x0000000080000000ULL /* refcount tree operations */
-#define ML_BASTS       0x0000001000000000ULL /* dlmglue asts and basts */
+#define ML_BASTS       0x0000000100000000ULL /* dlmglue asts and basts */
+#define ML_RESERVATIONS        0x0000000200000000ULL /* ocfs2 alloc reservations */
+#define ML_CLUSTER     0x0000000400000000ULL /* cluster stack */
+
 /* bits that are infrequently given and frequently matched in the high word */
-#define ML_ERROR       0x0000000100000000ULL /* sent to KERN_ERR */
-#define ML_NOTICE      0x0000000200000000ULL /* setn to KERN_NOTICE */
-#define ML_KTHREAD     0x0000000400000000ULL /* kernel thread activity */
-#define ML_RESERVATIONS        0x0000000800000000ULL /* ocfs2 alloc reservations */
-#define ML_CLUSTER     0x0000001000000000ULL /* cluster stack */
+#define ML_ERROR       0x1000000000000000ULL /* sent to KERN_ERR */
+#define ML_NOTICE      0x2000000000000000ULL /* setn to KERN_NOTICE */
+#define ML_KTHREAD     0x4000000000000000ULL /* kernel thread activity */
 
 #define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE)
 #define MLOG_INITIAL_NOT_MASK (ML_ENTRY|ML_EXIT)
index c49f6de0e7abb6e096ddc56e795957e0194bb8dd..d417b3f9b0c730e5cbb8d475358e6d8891fdc05c 100644 (file)
@@ -2461,8 +2461,10 @@ static int ocfs2_dx_dir_attach_index(struct ocfs2_super *osb,
 
        di->i_dx_root = cpu_to_le64(dr_blkno);
 
+       spin_lock(&OCFS2_I(dir)->ip_lock);
        OCFS2_I(dir)->ip_dyn_features |= OCFS2_INDEXED_DIR_FL;
        di->i_dyn_features = cpu_to_le16(OCFS2_I(dir)->ip_dyn_features);
+       spin_unlock(&OCFS2_I(dir)->ip_lock);
 
        ocfs2_journal_dirty(handle, di_bh);
 
@@ -4466,8 +4468,10 @@ static int ocfs2_dx_dir_remove_index(struct inode *dir,
                goto out_commit;
        }
 
+       spin_lock(&OCFS2_I(dir)->ip_lock);
        OCFS2_I(dir)->ip_dyn_features &= ~OCFS2_INDEXED_DIR_FL;
        di->i_dyn_features = cpu_to_le16(OCFS2_I(dir)->ip_dyn_features);
+       spin_unlock(&OCFS2_I(dir)->ip_lock);
        di->i_dx_root = cpu_to_le64(0ULL);
 
        ocfs2_journal_dirty(handle, di_bh);
index f564b0e5f80d8c89e08eeba4a5e133b24cb67373..59f0f6bdfc62110141ca7ad413dc51abadd4b3c8 100644 (file)
@@ -2346,7 +2346,8 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data)
  */
 static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm,
                                      struct dlm_lock_resource *res,
-                                     int *numlocks)
+                                     int *numlocks,
+                                     int *hasrefs)
 {
        int ret;
        int i;
@@ -2356,6 +2357,9 @@ static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm,
 
        assert_spin_locked(&res->spinlock);
 
+       *numlocks = 0;
+       *hasrefs = 0;
+
        ret = -EINVAL;
        if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN) {
                mlog(0, "cannot migrate lockres with unknown owner!\n");
@@ -2386,7 +2390,13 @@ static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm,
        }
 
        *numlocks = count;
-       mlog(0, "migrateable lockres having %d locks\n", *numlocks);
+
+       count = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
+       if (count < O2NM_MAX_NODES)
+               *hasrefs = 1;
+
+       mlog(0, "%s: res %.*s, Migrateable, locks %d, refs %d\n", dlm->name,
+            res->lockname.len, res->lockname.name, *numlocks, *hasrefs);
 
 leave:
        return ret;
@@ -2408,7 +2418,7 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
        const char *name;
        unsigned int namelen;
        int mle_added = 0;
-       int numlocks;
+       int numlocks, hasrefs;
        int wake = 0;
 
        if (!dlm_grab(dlm))
@@ -2417,13 +2427,13 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
        name = res->lockname.name;
        namelen = res->lockname.len;
 
-       mlog(0, "migrating %.*s to %u\n", namelen, name, target);
+       mlog(0, "%s: Migrating %.*s to %u\n", dlm->name, namelen, name, target);
 
        /*
         * ensure this lockres is a proper candidate for migration
         */
        spin_lock(&res->spinlock);
-       ret = dlm_is_lockres_migrateable(dlm, res, &numlocks);
+       ret = dlm_is_lockres_migrateable(dlm, res, &numlocks, &hasrefs);
        if (ret < 0) {
                spin_unlock(&res->spinlock);
                goto leave;
@@ -2431,10 +2441,8 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
        spin_unlock(&res->spinlock);
 
        /* no work to do */
-       if (numlocks == 0) {
-               mlog(0, "no locks were found on this lockres! done!\n");
+       if (numlocks == 0 && !hasrefs)
                goto leave;
-       }
 
        /*
         * preallocate up front
@@ -2459,14 +2467,14 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
         * find a node to migrate the lockres to
         */
 
-       mlog(0, "picking a migration node\n");
        spin_lock(&dlm->spinlock);
        /* pick a new node */
        if (!test_bit(target, dlm->domain_map) ||
            target >= O2NM_MAX_NODES) {
                target = dlm_pick_migration_target(dlm, res);
        }
-       mlog(0, "node %u chosen for migration\n", target);
+       mlog(0, "%s: res %.*s, Node %u chosen for migration\n", dlm->name,
+            namelen, name, target);
 
        if (target >= O2NM_MAX_NODES ||
            !test_bit(target, dlm->domain_map)) {
@@ -2667,7 +2675,7 @@ int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
 {
        int ret;
        int lock_dropped = 0;
-       int numlocks;
+       int numlocks, hasrefs;
 
        spin_lock(&res->spinlock);
        if (res->owner != dlm->node_num) {
@@ -2681,8 +2689,8 @@ int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
        }
 
        /* No need to migrate a lockres having no locks */
-       ret = dlm_is_lockres_migrateable(dlm, res, &numlocks);
-       if (ret >= 0 && numlocks == 0) {
+       ret = dlm_is_lockres_migrateable(dlm, res, &numlocks, &hasrefs);
+       if (ret >= 0 && numlocks == 0 && !hasrefs) {
                spin_unlock(&res->spinlock);
                goto leave;
        }
@@ -2915,6 +2923,12 @@ static u8 dlm_pick_migration_target(struct dlm_ctxt *dlm,
                }
                queue++;
        }
+
+       nodenum = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
+       if (nodenum < O2NM_MAX_NODES) {
+               spin_unlock(&res->spinlock);
+               return nodenum;
+       }
        spin_unlock(&res->spinlock);
        mlog(0, "have not found a suitable target yet! checking domain map\n");
 
index 77b4c04a2809831e7209d1be3f8e860a0ba7edc8..f6cba566429d314fe82f9f433889d1e22111462a 100644 (file)
@@ -2241,11 +2241,15 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
 
        mutex_lock(&inode->i_mutex);
 
+       ocfs2_iocb_clear_sem_locked(iocb);
+
 relock:
        /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */
        if (direct_io) {
                down_read(&inode->i_alloc_sem);
                have_alloc_sem = 1;
+               /* communicate with ocfs2_dio_end_io */
+               ocfs2_iocb_set_sem_locked(iocb);
        }
 
        /*
@@ -2382,8 +2386,10 @@ out:
                ocfs2_rw_unlock(inode, rw_level);
 
 out_sems:
-       if (have_alloc_sem)
+       if (have_alloc_sem) {
                up_read(&inode->i_alloc_sem);
+               ocfs2_iocb_clear_sem_locked(iocb);
+       }
 
        mutex_unlock(&inode->i_mutex);
 
@@ -2527,6 +2533,8 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
                goto bail;
        }
 
+       ocfs2_iocb_clear_sem_locked(iocb);
+
        /*
         * buffered reads protect themselves in ->readpage().  O_DIRECT reads
         * need locks to protect pending reads from racing with truncate.
@@ -2534,6 +2542,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
        if (filp->f_flags & O_DIRECT) {
                down_read(&inode->i_alloc_sem);
                have_alloc_sem = 1;
+               ocfs2_iocb_set_sem_locked(iocb);
 
                ret = ocfs2_rw_lock(inode, 0);
                if (ret < 0) {
@@ -2575,8 +2584,10 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
        }
 
 bail:
-       if (have_alloc_sem)
+       if (have_alloc_sem) {
                up_read(&inode->i_alloc_sem);
+               ocfs2_iocb_clear_sem_locked(iocb);
+       }
        if (rw_level != -1)
                ocfs2_rw_unlock(inode, rw_level);
        mlog_exit(ret);
index c2e4f8222e2f0ac707de217555bee7edd51f76d6..bf2e7764920e92e3d621a94caac7124b3fa15914 100644 (file)
@@ -350,7 +350,7 @@ enum {
 #define OCFS2_LAST_LOCAL_SYSTEM_INODE LOCAL_GROUP_QUOTA_SYSTEM_INODE
        NUM_SYSTEM_INODES
 };
-#define NUM_GLOBAL_SYSTEM_INODES OCFS2_LAST_GLOBAL_SYSTEM_INODE
+#define NUM_GLOBAL_SYSTEM_INODES OCFS2_FIRST_LOCAL_SYSTEM_INODE
 #define NUM_LOCAL_SYSTEM_INODES        \
                (NUM_SYSTEM_INODES - OCFS2_FIRST_LOCAL_SYSTEM_INODE)
 
index 685ea65eb803fddf1c47ee3e420fe3056278685b..ce0775aa64c376b8980a6af70ef59f14d19f1ba0 100644 (file)
@@ -81,16 +81,41 @@ struct kthread_work {
 #define DEFINE_KTHREAD_WORK(work, fn)                                  \
        struct kthread_work work = KTHREAD_WORK_INIT(work, fn)
 
-static inline void init_kthread_worker(struct kthread_worker *worker)
-{
-       *worker = (struct kthread_worker)KTHREAD_WORKER_INIT(*worker);
-}
-
-static inline void init_kthread_work(struct kthread_work *work,
-                                    kthread_work_func_t fn)
-{
-       *work = (struct kthread_work)KTHREAD_WORK_INIT(*work, fn);
-}
+/*
+ * kthread_worker.lock and kthread_work.done need their own lockdep class
+ * keys if they are defined on stack with lockdep enabled.  Use the
+ * following macros when defining them on stack.
+ */
+#ifdef CONFIG_LOCKDEP
+# define KTHREAD_WORKER_INIT_ONSTACK(worker)                           \
+       ({ init_kthread_worker(&worker); worker; })
+# define DEFINE_KTHREAD_WORKER_ONSTACK(worker)                         \
+       struct kthread_worker worker = KTHREAD_WORKER_INIT_ONSTACK(worker)
+# define KTHREAD_WORK_INIT_ONSTACK(work, fn)                           \
+       ({ init_kthread_work((&work), fn); work; })
+# define DEFINE_KTHREAD_WORK_ONSTACK(work, fn)                         \
+       struct kthread_work work = KTHREAD_WORK_INIT_ONSTACK(work, fn)
+#else
+# define DEFINE_KTHREAD_WORKER_ONSTACK(worker) DEFINE_KTHREAD_WORKER(worker)
+# define DEFINE_KTHREAD_WORK_ONSTACK(work, fn) DEFINE_KTHREAD_WORK(work, fn)
+#endif
+
+extern void __init_kthread_worker(struct kthread_worker *worker,
+                       const char *name, struct lock_class_key *key);
+
+#define init_kthread_worker(worker)                                    \
+       do {                                                            \
+               static struct lock_class_key __key;                     \
+               __init_kthread_worker((worker), "("#worker")->lock", &__key); \
+       } while (0)
+
+#define init_kthread_work(work, fn)                                    \
+       do {                                                            \
+               memset((work), 0, sizeof(struct kthread_work));         \
+               INIT_LIST_HEAD(&(work)->node);                          \
+               (work)->func = (fn);                                    \
+               init_waitqueue_head(&(work)->done);                     \
+       } while (0)
 
 int kthread_worker_fn(void *worker_ptr);
 
index 123566912d7312f276bf975cd1a48c97b2ffa830..e2b9e63afa68b53f45fdc60c1a3f76cf0f338705 100644 (file)
@@ -70,7 +70,7 @@ struct nlmsghdr {
    Check               NLM_F_EXCL
  */
 
-#define NLMSG_ALIGNTO  4
+#define NLMSG_ALIGNTO  4U
 #define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
 #define NLMSG_HDRLEN    ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
 #define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN))
index 0ac3fb5e0973460f3046cdf1f00a0e1114a13dff..bb08692a20b08841ead94acce78c9ead82293d94 100644 (file)
@@ -49,7 +49,6 @@ struct flowi {
        __u8    proto;
        __u8    flags;
 #define FLOWI_FLAG_ANYSRC 0x01
-#define FLOWI_FLAG_MATCH_ANY_IIF 0x02
        union {
                struct {
                        __be16  sport;
index 278312c95f9600bd863fa0dc76c52a7c048a9d19..2ab926860cd855b6ec7861a998d19612624980e6 100644 (file)
@@ -164,5 +164,15 @@ static inline int ipv6_unicast_destination(struct sk_buff *skb)
        return rt->rt6i_flags & RTF_LOCAL;
 }
 
+int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
+
+static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
+{
+       struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
+
+       return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ?
+              skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
+}
+
 #endif
 #endif
index 9fdf982d1286a95c02a73bae4131746f05de9343..365359b24177a1a52310679293c43dba7b97533f 100644 (file)
@@ -2024,8 +2024,8 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw,
  *
  * This function may not be called in IRQ context. Calls to this function
  * for a single hardware must be synchronized against each other. Calls
- * to this function and ieee80211_tx_status_irqsafe() may not be mixed
- * for a single hardware.
+ * to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe()
+ * may not be mixed for a single hardware.
  *
  * @hw: the hardware the frame was transmitted by
  * @skb: the frame that was transmitted, owned by mac80211 after this call
@@ -2033,14 +2033,34 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw,
 void ieee80211_tx_status(struct ieee80211_hw *hw,
                         struct sk_buff *skb);
 
+/**
+ * ieee80211_tx_status_ni - transmit status callback (in process context)
+ *
+ * Like ieee80211_tx_status() but can be called in process context.
+ *
+ * Calls to this function, ieee80211_tx_status() and
+ * ieee80211_tx_status_irqsafe() may not be mixed
+ * for a single hardware.
+ *
+ * @hw: the hardware the frame was transmitted by
+ * @skb: the frame that was transmitted, owned by mac80211 after this call
+ */
+static inline void ieee80211_tx_status_ni(struct ieee80211_hw *hw,
+                                         struct sk_buff *skb)
+{
+       local_bh_disable();
+       ieee80211_tx_status(hw, skb);
+       local_bh_enable();
+}
+
 /**
  * ieee80211_tx_status_irqsafe - IRQ-safe transmit status callback
  *
  * Like ieee80211_tx_status() but can be called in IRQ context
  * (internally defers to a tasklet.)
  *
- * Calls to this function and ieee80211_tx_status() may not be mixed for a
- * single hardware.
+ * Calls to this function, ieee80211_tx_status() and
+ * ieee80211_tx_status_ni() may not be mixed for a single hardware.
  *
  * @hw: the hardware the frame was transmitted by
  * @skb: the frame that was transmitted, owned by mac80211 after this call
index dd3031aed9d52e7c3bf5d2c6ad464dbdc23477c0..9fcc680ab6b9d1f4de4d15583275efe7acf66975 100644 (file)
@@ -323,7 +323,9 @@ static inline unsigned char * tcf_get_base_ptr(struct sk_buff *skb, int layer)
 static inline int tcf_valid_offset(const struct sk_buff *skb,
                                   const unsigned char *ptr, const int len)
 {
-       return unlikely((ptr + len) < skb_tail_pointer(skb) && ptr > skb->head);
+       return likely((ptr + len) <= skb_tail_pointer(skb) &&
+                     ptr >= skb->head &&
+                     (ptr <= (ptr + len)));
 }
 
 #ifdef CONFIG_NET_CLS_IND
index ea1f8a83160df419e986d51ad864a14a215cbea3..79f34e2b752f61479a4b8aae9bc29551cff3b7d0 100644 (file)
@@ -610,11 +610,7 @@ static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask,
 {
        struct sk_buff *n;
 
-       if ((action == TC_ACT_STOLEN || action == TC_ACT_QUEUED) &&
-           !skb_shared(skb))
-               n = skb_get(skb);
-       else
-               n = skb_clone(skb, gfp_mask);
+       n = skb_clone(skb, gfp_mask);
 
        if (n) {
                n->tc_verd = SET_TC_VERD(n->tc_verd, 0);
index 659d968d95c54afe6df51c3289a0d2d6fb5b34ed..7d3f7ce239b5b831c66b20b7df61e593384604b2 100644 (file)
@@ -754,6 +754,7 @@ struct proto {
        void                    (*unhash)(struct sock *sk);
        void                    (*rehash)(struct sock *sk);
        int                     (*get_port)(struct sock *sk, unsigned short snum);
+       void                    (*clear_sk)(struct sock *sk, int size);
 
        /* Keeping track of sockets in use */
 #ifdef CONFIG_PROC_FS
@@ -852,6 +853,8 @@ static inline void __sk_prot_rehash(struct sock *sk)
        sk->sk_prot->hash(sk);
 }
 
+void sk_prot_clear_portaddr_nulls(struct sock *sk, int size);
+
 /* About 10 seconds */
 #define SOCK_DESTROY_TIME (10*HZ)
 
index 2dc3786349d1723394c25e512b9b570bcf5a4f7e..ca61bbdd44b2e11acad4d866ab31224a5a5cab16 100644 (file)
@@ -265,6 +265,17 @@ int kthreadd(void *unused)
        return 0;
 }
 
+void __init_kthread_worker(struct kthread_worker *worker,
+                               const char *name,
+                               struct lock_class_key *key)
+{
+       spin_lock_init(&worker->lock);
+       lockdep_set_class_and_name(&worker->lock, key, name);
+       INIT_LIST_HEAD(&worker->work_list);
+       worker->task = NULL;
+}
+EXPORT_SYMBOL_GPL(__init_kthread_worker);
+
 /**
  * kthread_worker_fn - kthread function to process kthread_worker
  * @worker_ptr: pointer to initialized kthread_worker
index 27a9ac58851678d30c7c477d00a857cf2f63bc35..ef4045d010d5f37631c3ad2f9de0e824e1de65a7 100644 (file)
@@ -10,7 +10,7 @@
  *  Copyright (c) 2000-2003 David McCullough <davidm@snapgear.com>
  *  Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org>
  *  Copyright (c) 2002      Greg Ungerer <gerg@snapgear.com>
- *  Copyright (c) 2007-2009 Paul Mundt <lethal@linux-sh.org>
+ *  Copyright (c) 2007-2010 Paul Mundt <lethal@linux-sh.org>
  */
 
 #include <linux/module.h>
@@ -328,6 +328,7 @@ void *vmalloc_node(unsigned long size, int node)
 {
        return vmalloc(size);
 }
+EXPORT_SYMBOL(vmalloc_node);
 
 /**
  * vzalloc_node - allocate memory on a specific node with zero fill
@@ -440,6 +441,31 @@ void  __attribute__((weak)) vmalloc_sync_all(void)
 {
 }
 
+/**
+ *     alloc_vm_area - allocate a range of kernel address space
+ *     @size:          size of the area
+ *
+ *     Returns:        NULL on failure, vm_struct on success
+ *
+ *     This function reserves a range of kernel address space, and
+ *     allocates pagetables to map that range.  No actual mappings
+ *     are created.  If the kernel address space is not shared
+ *     between processes, it syncs the pagetable across all
+ *     processes.
+ */
+struct vm_struct *alloc_vm_area(size_t size)
+{
+       BUG();
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(alloc_vm_area);
+
+void free_vm_area(struct vm_struct *area)
+{
+       BUG();
+}
+EXPORT_SYMBOL_GPL(free_vm_area);
+
 int vm_insert_page(struct vm_area_struct *vma, unsigned long addr,
                   struct page *page)
 {
index efe816856a9d777b284f8bf25cc7548154f374d6..02ba91230b99269f45beea6387c165e042800347 100644 (file)
@@ -1268,7 +1268,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
 
        /* we're done parsing the input, undefine BUG macro and dump config */
 #undef PCPU_SETUP_BUG_ON
-       pcpu_dump_alloc_info(KERN_INFO, ai);
+       pcpu_dump_alloc_info(KERN_DEBUG, ai);
 
        pcpu_nr_groups = ai->nr_groups;
        pcpu_group_offsets = group_offsets;
index fa642aa652bdba0d4b0b3f47c77dc9e55571c19f..432a9a633e8d8da4ddcabdb1a9a3cef1a55a3253 100644 (file)
@@ -311,6 +311,7 @@ static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d)
        d->state      = BT_OPEN;
        d->flags      = 0;
        d->mscex      = 0;
+       d->sec_level  = BT_SECURITY_LOW;
        d->mtu        = RFCOMM_DEFAULT_MTU;
        d->v24_sig    = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
 
index eb5b256ffc8801ff7e187c64ee3dde5da268f570..f19e347f56f6f41543b33f174af38c997739294e 100644 (file)
@@ -437,7 +437,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br,
        ip6h = ipv6_hdr(skb);
 
        *(__force __be32 *)ip6h = htonl(0x60000000);
-       ip6h->payload_len = 8 + sizeof(*mldq);
+       ip6h->payload_len = htons(8 + sizeof(*mldq));
        ip6h->nexthdr = IPPROTO_HOPOPTS;
        ip6h->hop_limit = 1;
        ipv6_addr_set(&ip6h->saddr, 0, 0, 0, 0);
index 82a4369ae15091520d99effdcbb36dec7b3bab42..a20e5d3bbfa017db76959cfd448962c134d5d309 100644 (file)
@@ -181,8 +181,7 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
 {
        int ret = 0;
 
-       if (rule->iifindex && (rule->iifindex != fl->iif) &&
-           !(fl->flags & FLOWI_FLAG_MATCH_ANY_IIF))
+       if (rule->iifindex && (rule->iifindex != fl->iif))
                goto out;
 
        if (rule->oifindex && (rule->oifindex != fl->oif))
index fb6080111461546953b34979db77f5e2d516e060..e5af8d5d5b505d79e3102a0aa879ba3d3e17f82b 100644 (file)
@@ -1009,6 +1009,36 @@ static void sock_copy(struct sock *nsk, const struct sock *osk)
 #endif
 }
 
+/*
+ * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes
+ * un-modified. Special care is taken when initializing object to zero.
+ */
+static inline void sk_prot_clear_nulls(struct sock *sk, int size)
+{
+       if (offsetof(struct sock, sk_node.next) != 0)
+               memset(sk, 0, offsetof(struct sock, sk_node.next));
+       memset(&sk->sk_node.pprev, 0,
+              size - offsetof(struct sock, sk_node.pprev));
+}
+
+void sk_prot_clear_portaddr_nulls(struct sock *sk, int size)
+{
+       unsigned long nulls1, nulls2;
+
+       nulls1 = offsetof(struct sock, __sk_common.skc_node.next);
+       nulls2 = offsetof(struct sock, __sk_common.skc_portaddr_node.next);
+       if (nulls1 > nulls2)
+               swap(nulls1, nulls2);
+
+       if (nulls1 != 0)
+               memset((char *)sk, 0, nulls1);
+       memset((char *)sk + nulls1 + sizeof(void *), 0,
+              nulls2 - nulls1 - sizeof(void *));
+       memset((char *)sk + nulls2 + sizeof(void *), 0,
+              size - nulls2 - sizeof(void *));
+}
+EXPORT_SYMBOL(sk_prot_clear_portaddr_nulls);
+
 static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority,
                int family)
 {
@@ -1021,19 +1051,12 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority,
                if (!sk)
                        return sk;
                if (priority & __GFP_ZERO) {
-                       /*
-                        * caches using SLAB_DESTROY_BY_RCU should let
-                        * sk_node.next un-modified. Special care is taken
-                        * when initializing object to zero.
-                        */
-                       if (offsetof(struct sock, sk_node.next) != 0)
-                               memset(sk, 0, offsetof(struct sock, sk_node.next));
-                       memset(&sk->sk_node.pprev, 0,
-                              prot->obj_size - offsetof(struct sock,
-                                                        sk_node.pprev));
+                       if (prot->clear_sk)
+                               prot->clear_sk(sk, prot->obj_size);
+                       else
+                               sk_prot_clear_nulls(sk, prot->obj_size);
                }
-       }
-       else
+       } else
                sk = kmalloc(prot->obj_size, priority);
 
        if (sk != NULL) {
index eb6f69a8f27aff4db2de494389dd7d9584b93ece..c19c1f739fbadc48d39a87c25c550f49de100db4 100644 (file)
@@ -163,13 +163,19 @@ struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref)
                                .daddr = addr
                        }
                },
-               .flags = FLOWI_FLAG_MATCH_ANY_IIF
        };
        struct fib_result res = { 0 };
        struct net_device *dev = NULL;
+       struct fib_table *local_table;
+
+#ifdef CONFIG_IP_MULTIPLE_TABLES
+       res.r = NULL;
+#endif
 
        rcu_read_lock();
-       if (fib_lookup(net, &fl, &res)) {
+       local_table = fib_get_table(net, RT_TABLE_LOCAL);
+       if (!local_table ||
+           fib_table_lookup(local_table, &fl, &res, FIB_LOOKUP_NOREF)) {
                rcu_read_unlock();
                return NULL;
        }
index 987bf9adb31833c19a0db04ce76060306d8e6994..df948b0f1ac97c0e1d436690c6bb49f4c9fd056d 100644 (file)
@@ -2585,9 +2585,10 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
                        goto out;
 
                /* RACE: Check return value of inet_select_addr instead. */
-               if (rcu_dereference(dev_out->ip_ptr) == NULL)
-                       goto out;       /* Wrong error code */
-
+               if (!(dev_out->flags & IFF_UP) || !__in_dev_get_rcu(dev_out)) {
+                       err = -ENETUNREACH;
+                       goto out;
+               }
                if (ipv4_is_local_multicast(oldflp->fl4_dst) ||
                    ipv4_is_lbcast(oldflp->fl4_dst)) {
                        if (!fl.fl4_src)
index e13da6de1fc79e26dc6d03b671e1becf9e6c8754..d978bb2f748b34d99efb0162e4e083a460275630 100644 (file)
@@ -2030,7 +2030,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
 get_req:
                        req = icsk->icsk_accept_queue.listen_opt->syn_table[st->sbucket];
                }
-               sk        = sk_next(st->syn_wait_sk);
+               sk        = sk_nulls_next(st->syn_wait_sk);
                st->state = TCP_SEQ_STATE_LISTENING;
                read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
        } else {
@@ -2039,7 +2039,7 @@ get_req:
                if (reqsk_queue_len(&icsk->icsk_accept_queue))
                        goto start_req;
                read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock);
-               sk = sk_next(sk);
+               sk = sk_nulls_next(sk);
        }
 get_sk:
        sk_nulls_for_each_from(sk, node) {
index 5e0a3a582a59a05466468b244371dc5675bedc67..2d3ded4d078684298f9116f5c225f92b8908120e 100644 (file)
@@ -1899,6 +1899,7 @@ struct proto udp_prot = {
        .compat_setsockopt = compat_udp_setsockopt,
        .compat_getsockopt = compat_udp_getsockopt,
 #endif
+       .clear_sk          = sk_prot_clear_portaddr_nulls,
 };
 EXPORT_SYMBOL(udp_prot);
 
index ab76aa928fa98d6f1b8a8f6371d2b898ebdccb24..aee9963f7f5a497efc06429d3ab730e9f3efc999 100644 (file)
@@ -57,6 +57,7 @@ struct proto  udplite_prot = {
        .compat_setsockopt = compat_udp_setsockopt,
        .compat_getsockopt = compat_udp_getsockopt,
 #endif
+       .clear_sk          = sk_prot_clear_portaddr_nulls,
 };
 EXPORT_SYMBOL(udplite_prot);
 
index 93b7a933a7758254ed70ed849d333ad4d19114a7..848b355910424e75d42df6b9218eae3824ee213c 100644 (file)
@@ -2669,7 +2669,9 @@ static int addrconf_ifdown(struct net_device *dev, int how)
 
        ASSERT_RTNL();
 
-       rt6_ifdown(net, dev);
+       /* Flush routes if device is being removed or it is not loopback */
+       if (how || !(dev->flags & IFF_LOOPBACK))
+               rt6_ifdown(net, dev);
        neigh_ifdown(&nd_tbl, dev);
 
        idev = __in6_dev_get(dev);
index 99157b4cd56e2fa619939a17aa5b716680fc8799..94b5bf132b2e33a467f662b8c0e402a459f00a3d 100644 (file)
@@ -56,7 +56,7 @@
 #include <net/checksum.h>
 #include <linux/mroute6.h>
 
-static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
+int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
 
 int __ip6_local_out(struct sk_buff *skb)
 {
@@ -145,14 +145,6 @@ static int ip6_finish_output2(struct sk_buff *skb)
        return -EINVAL;
 }
 
-static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
-{
-       struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
-
-       return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ?
-              skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
-}
-
 static int ip6_finish_output(struct sk_buff *skb)
 {
        if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
@@ -601,7 +593,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
        return offset;
 }
 
-static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
+int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 {
        struct sk_buff *frag;
        struct rt6_info *rt = (struct rt6_info*)skb_dst(skb);
index 96455ffb76fb8b92aa90c3a711aa6635d45b91fa..7659d6f16e6bae4b7e8a1701161181f627c0e41f 100644 (file)
@@ -1565,11 +1565,16 @@ static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr,
 {
        struct rt6_info *rt, *nrt;
        int allfrag = 0;
-
+again:
        rt = rt6_lookup(net, daddr, saddr, ifindex, 0);
        if (rt == NULL)
                return;
 
+       if (rt6_check_expired(rt)) {
+               ip6_del_rt(rt);
+               goto again;
+       }
+
        if (pmtu >= dst_mtu(&rt->dst))
                goto out;
 
index 91def93bec85060e7571218c20439cabd4ec824f..cd6cb7c3e5636e5911a36b5e1b4ebb4cb96b4be4 100644 (file)
@@ -1477,6 +1477,7 @@ struct proto udpv6_prot = {
        .compat_setsockopt = compat_udpv6_setsockopt,
        .compat_getsockopt = compat_udpv6_getsockopt,
 #endif
+       .clear_sk          = sk_prot_clear_portaddr_nulls,
 };
 
 static struct inet_protosw udpv6_protosw = {
index 5f48fadc27f7a62aa13632fc31bea73e1d1e6aec..986c4de5292eedf715b25b8bae98ee640917d97e 100644 (file)
@@ -55,6 +55,7 @@ struct proto udplitev6_prot = {
        .compat_setsockopt = compat_udpv6_setsockopt,
        .compat_getsockopt = compat_udpv6_getsockopt,
 #endif
+       .clear_sk          = sk_prot_clear_portaddr_nulls,
 };
 
 static struct inet_protosw udplite6_protosw = {
index 6434bd5ce0885ad20408a2f79eb198b8f30c269a..8e688b3de9abc62ec03c7dd90b33c951791c5587 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/netfilter_ipv6.h>
 #include <net/dst.h>
 #include <net/ipv6.h>
+#include <net/ip6_route.h>
 #include <net/xfrm.h>
 
 int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
@@ -88,8 +89,21 @@ static int xfrm6_output_finish(struct sk_buff *skb)
        return xfrm_output(skb);
 }
 
+static int __xfrm6_output(struct sk_buff *skb)
+{
+       struct dst_entry *dst = skb_dst(skb);
+       struct xfrm_state *x = dst->xfrm;
+
+       if ((x && x->props.mode == XFRM_MODE_TUNNEL) &&
+           ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
+               dst_allfrag(skb_dst(skb)))) {
+                       return ip6_fragment(skb, xfrm6_output_finish);
+       }
+       return xfrm6_output_finish(skb);
+}
+
 int xfrm6_output(struct sk_buff *skb)
 {
        return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL,
-                      skb_dst(skb)->dev, xfrm6_output_finish);
+                      skb_dst(skb)->dev, __xfrm6_output);
 }
index a6de3059746ddd3f3039d564f20acf394225e3ad..c9890e25cd4c9681b14f838976a97ed4db560ac7 100644 (file)
@@ -2280,6 +2280,16 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
 
        switch (optname) {
        case IRLMP_ENUMDEVICES:
+
+               /* Offset to first device entry */
+               offset = sizeof(struct irda_device_list) -
+                       sizeof(struct irda_device_info);
+
+               if (len < offset) {
+                       err = -EINVAL;
+                       goto out;
+               }
+
                /* Ask lmp for the current discovery log */
                discoveries = irlmp_get_discoveries(&list.len, self->mask.word,
                                                    self->nslots);
@@ -2290,15 +2300,9 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
                }
 
                /* Write total list length back to client */
-               if (copy_to_user(optval, &list,
-                                sizeof(struct irda_device_list) -
-                                sizeof(struct irda_device_info)))
+               if (copy_to_user(optval, &list, offset))
                        err = -EFAULT;
 
-               /* Offset to first device entry */
-               offset = sizeof(struct irda_device_list) -
-                       sizeof(struct irda_device_info);
-
                /* Copy the list itself - watch for overflow */
                if (list.len > 2048) {
                        err = -EINVAL;
index 239c4836a946601f27c69f965ae1a0935e71b434..077a93dd1671a841b9db85fe4cf6981aa90c1edf 100644 (file)
@@ -780,6 +780,9 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
 
        mutex_lock(&sdata->u.ibss.mtx);
 
+       if (!sdata->u.ibss.ssid_len)
+               goto mgmt_out; /* not ready to merge yet */
+
        switch (fc & IEEE80211_FCTL_STYPE) {
        case IEEE80211_STYPE_PROBE_REQ:
                ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len);
@@ -797,6 +800,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
                break;
        }
 
+ mgmt_out:
        mutex_unlock(&sdata->u.ibss.mtx);
 }
 
index 54fb4a0e76f03d835c6038cffeabf18874cb2d59..b01e467b76c69f15aa8de00434deca874b89ae48 100644 (file)
@@ -1788,9 +1788,11 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
 
                        fwd_skb = skb_copy(skb, GFP_ATOMIC);
 
-                       if (!fwd_skb && net_ratelimit())
+                       if (!fwd_skb && net_ratelimit()) {
                                printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
                                                   sdata->name);
+                               goto out;
+                       }
 
                        fwd_hdr =  (struct ieee80211_hdr *) fwd_skb->data;
                        memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN);
@@ -1828,6 +1830,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
                }
        }
 
+ out:
        if (is_multicast_ether_addr(hdr->addr1) ||
            sdata->dev->flags & IFF_PROMISC)
                return RX_CONTINUE;
index ae344d1ba0560480665e1b939b15b058f5fddc4c..146097cb43a710d756ab997770faa812293ba85e 100644 (file)
@@ -1051,11 +1051,13 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_work *wk;
+       bool cleanup = false;
 
        mutex_lock(&local->mtx);
        list_for_each_entry(wk, &local->work_list, list) {
                if (wk->sdata != sdata)
                        continue;
+               cleanup = true;
                wk->type = IEEE80211_WORK_ABORT;
                wk->started = true;
                wk->timeout = jiffies;
@@ -1063,7 +1065,8 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
        mutex_unlock(&local->mtx);
 
        /* run cleanups etc. */
-       ieee80211_work_work(&local->work_work);
+       if (cleanup)
+               ieee80211_work_work(&local->work_work);
 
        mutex_lock(&local->mtx);
        list_for_each_entry(wk, &local->work_list, list) {
index 3cf478d012dd4f29b7a67f951c2cfa901b64248f..7150705f1d0b8b7aa12de87067928c25605ffbbb 100644 (file)
@@ -270,7 +270,6 @@ static unsigned int sfq_drop(struct Qdisc *sch)
                /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */
                d = q->next[q->tail];
                q->next[q->tail] = q->next[d];
-               q->allot[q->next[d]] += q->quantum;
                skb = q->qs[d].prev;
                len = qdisc_pkt_len(skb);
                __skb_unlink(skb, &q->qs[d]);
@@ -321,14 +320,13 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        sfq_inc(q, x);
        if (q->qs[x].qlen == 1) {               /* The flow is new */
                if (q->tail == SFQ_DEPTH) {     /* It is the first flow */
-                       q->tail = x;
                        q->next[x] = x;
-                       q->allot[x] = q->quantum;
                } else {
                        q->next[x] = q->next[q->tail];
                        q->next[q->tail] = x;
-                       q->tail = x;
                }
+               q->tail = x;
+               q->allot[x] = q->quantum;
        }
        if (++sch->q.qlen <= q->limit) {
                sch->bstats.bytes += qdisc_pkt_len(skb);
@@ -359,13 +357,13 @@ sfq_dequeue(struct Qdisc *sch)
 {
        struct sfq_sched_data *q = qdisc_priv(sch);
        struct sk_buff *skb;
-       sfq_index a, old_a;
+       sfq_index a, next_a;
 
        /* No active slots */
        if (q->tail == SFQ_DEPTH)
                return NULL;
 
-       a = old_a = q->next[q->tail];
+       a = q->next[q->tail];
 
        /* Grab packet */
        skb = __skb_dequeue(&q->qs[a]);
@@ -376,17 +374,15 @@ sfq_dequeue(struct Qdisc *sch)
        /* Is the slot empty? */
        if (q->qs[a].qlen == 0) {
                q->ht[q->hash[a]] = SFQ_DEPTH;
-               a = q->next[a];
-               if (a == old_a) {
+               next_a = q->next[a];
+               if (a == next_a) {
                        q->tail = SFQ_DEPTH;
                        return skb;
                }
-               q->next[q->tail] = a;
-               q->allot[a] += q->quantum;
+               q->next[q->tail] = next_a;
        } else if ((q->allot[a] -= qdisc_pkt_len(skb)) <= 0) {
-               q->tail = a;
-               a = q->next[a];
                q->allot[a] += q->quantum;
+               q->tail = a;
        }
        return skb;
 }
index 0b9ee34ad35ceb31ff764baf9cec73fba010f55b..fff0926b11112a8dd04d11e1e7f9ba378c40fcc3 100644 (file)
@@ -5053,7 +5053,7 @@ static int sctp_getsockopt_partial_delivery_point(struct sock *sk, int len,
        if (copy_to_user(optval, &val, len))
                return -EFAULT;
 
-       return -ENOTSUPP;
+       return 0;
 }
 
 /*
index 0088dd8bf68a77b29637527733ff0b8985b8ecb7..0ea52d25a6bda8b3568fdb7752539403e93086b6 100644 (file)
@@ -403,7 +403,6 @@ link_check_failed:
        return ret;
 
 link_prealloc_failed:
-       up_write(&dest_keyring->sem);
        mutex_unlock(&user->cons_lock);
        kleave(" = %d [prelink]", ret);
        return ret;
index b75db8e9cc0f36fff03d0ecf1884b23b3bad724b..11446a1506dad244b2d11c447e6dc39e906427f1 100644 (file)
@@ -1070,8 +1070,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
                struct snd_pcm_hw_rule *new;
                unsigned int new_rules = constrs->rules_all + 16;
                new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL);
-               if (!new)
+               if (!new) {
+                       va_end(args);
                        return -ENOMEM;
+               }
                if (constrs->rules) {
                        memcpy(new, constrs->rules,
                               constrs->rules_num * sizeof(*c));
@@ -1087,8 +1089,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
        c->private = private;
        k = 0;
        while (1) {
-               if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps)))
+               if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) {
+                       va_end(args);
                        return -EINVAL;
+               }
                c->deps[k++] = dep;
                if (dep < 0)
                        break;
@@ -1097,7 +1101,7 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
        constrs->rules_num++;
        va_end(args);
        return 0;
-}                                  
+}
 
 EXPORT_SYMBOL(snd_pcm_hw_rule_add);
 
index 644e3f14f8ca5aea7af2e465450caab86d2f90cb..98b6d02a36c9c0600a7b26dffbbf1f4f378fccd8 100644 (file)
@@ -1919,6 +1919,16 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
 }
 EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
 
+static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name)
+{
+       int idx;
+       for (idx = 0; idx < 16; idx++) { /* 16 ctlrs should be large enough */
+               if (!_snd_hda_find_mixer_ctl(codec, name, idx))
+                       return idx;
+       }
+       return -EBUSY;
+}
+
 /**
  * snd_hda_ctl_add - Add a control element and assign to the codec
  * @codec: HD-audio codec
@@ -2654,8 +2664,6 @@ static struct snd_kcontrol_new dig_mixes[] = {
        { } /* end */
 };
 
-#define SPDIF_MAX_IDX  4       /* 4 instances should be enough to probe */
-
 /**
  * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls
  * @codec: the HDA codec
@@ -2673,12 +2681,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
        struct snd_kcontrol_new *dig_mix;
        int idx;
 
-       for (idx = 0; idx < SPDIF_MAX_IDX; idx++) {
-               if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch",
-                                            idx))
-                       break;
-       }
-       if (idx >= SPDIF_MAX_IDX) {
+       idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch");
+       if (idx < 0) {
                printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
                return -EBUSY;
        }
@@ -2829,12 +2833,8 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
        struct snd_kcontrol_new *dig_mix;
        int idx;
 
-       for (idx = 0; idx < SPDIF_MAX_IDX; idx++) {
-               if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch",
-                                            idx))
-                       break;
-       }
-       if (idx >= SPDIF_MAX_IDX) {
+       idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch");
+       if (idx < 0) {
                printk(KERN_ERR "hda_codec: too many IEC958 inputs\n");
                return -EBUSY;
        }
@@ -3808,21 +3808,32 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
 
        for (; knew->name; knew++) {
                struct snd_kcontrol *kctl;
+               int addr = 0, idx = 0;
                if (knew->iface == -1)  /* skip this codec private value */
                        continue;
-               kctl = snd_ctl_new1(knew, codec);
-               if (!kctl)
-                       return -ENOMEM;
-               err = snd_hda_ctl_add(codec, 0, kctl);
-               if (err < 0) {
-                       if (!codec->addr)
-                               return err;
+               for (;;) {
                        kctl = snd_ctl_new1(knew, codec);
                        if (!kctl)
                                return -ENOMEM;
-                       kctl->id.device = codec->addr;
+                       if (addr > 0)
+                               kctl->id.device = addr;
+                       if (idx > 0)
+                               kctl->id.index = idx;
                        err = snd_hda_ctl_add(codec, 0, kctl);
-                       if (err < 0)
+                       if (!err)
+                               break;
+                       /* try first with another device index corresponding to
+                        * the codec addr; if it still fails (or it's the
+                        * primary codec), then try another control index
+                        */
+                       if (!addr && codec->addr)
+                               addr = codec->addr;
+                       else if (!idx && !knew->index) {
+                               idx = find_empty_mixer_ctl_idx(codec,
+                                                              knew->name);
+                               if (idx <= 0)
+                                       return err;
+                       } else
                                return err;
                }
        }
index 427da45d7906560f517e04de74c84ab971c0a50a..552a09e9211ff355c185314339d48b99d5a0cb65 100644 (file)
@@ -14806,8 +14806,9 @@ static int alc269_resume(struct hda_codec *codec)
 
 enum {
        ALC269_FIXUP_SONY_VAIO,
+       ALC275_FIX_SONY_VAIO_GPIO2,
        ALC269_FIXUP_DELL_M101Z,
-       ALC269_FIXUP_LENOVO_EDGE14,
+       ALC269_FIXUP_SKU_IGNORE,
        ALC269_FIXUP_ASUS_G73JW,
 };
 
@@ -14818,6 +14819,14 @@ static const struct alc_fixup alc269_fixups[] = {
                        {}
                }
        },
+       [ALC275_FIX_SONY_VAIO_GPIO2] = {
+               .verbs = (const struct hda_verb[]) {
+                       {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
+                       {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
+                       {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
+                       { }
+               }
+       },
        [ALC269_FIXUP_DELL_M101Z] = {
                .verbs = (const struct hda_verb[]) {
                        /* Enables internal speaker */
@@ -14826,7 +14835,7 @@ static const struct alc_fixup alc269_fixups[] = {
                        {}
                }
        },
-       [ALC269_FIXUP_LENOVO_EDGE14] = {
+       [ALC269_FIXUP_SKU_IGNORE] = {
                .sku = ALC_FIXUP_SKU_IGNORE,
        },
        [ALC269_FIXUP_ASUS_G73JW] = {
@@ -14838,9 +14847,13 @@ static const struct alc_fixup alc269_fixups[] = {
 };
 
 static struct snd_pci_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
+       SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
+       SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
        SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
        SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
-       SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_LENOVO_EDGE14),
+       SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
+       SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
        {}
 };
@@ -15091,28 +15104,29 @@ static int patch_alc269(struct hda_codec *codec)
 
        alc_auto_parse_customize_define(codec);
 
-       coef = alc_read_coef_idx(codec, 0);
-       if ((coef & 0x00f0) == 0x0010) {
-               if (codec->bus->pci->subsystem_vendor == 0x1025 &&
-                   spec->cdefine.platform_type == 1) {
-                       alc_codec_rename(codec, "ALC271X");
-                       spec->codec_variant = ALC269_TYPE_ALC271X;
-               } else if ((coef & 0xf000) == 0x1000) {
-                       spec->codec_variant = ALC269_TYPE_ALC270;
-               } else if ((coef & 0xf000) == 0x2000) {
-                       alc_codec_rename(codec, "ALC259");
-                       spec->codec_variant = ALC269_TYPE_ALC259;
-               } else if ((coef & 0xf000) == 0x3000) {
-                       alc_codec_rename(codec, "ALC258");
-                       spec->codec_variant = ALC269_TYPE_ALC258;
-               } else {
-                       alc_codec_rename(codec, "ALC269VB");
-                       spec->codec_variant = ALC269_TYPE_ALC269VB;
-               }
-       } else
-               alc_fix_pll_init(codec, 0x20, 0x04, 15);
-
-       alc269_fill_coef(codec);
+       if (codec->vendor_id == 0x10ec0269) {
+               coef = alc_read_coef_idx(codec, 0);
+               if ((coef & 0x00f0) == 0x0010) {
+                       if (codec->bus->pci->subsystem_vendor == 0x1025 &&
+                           spec->cdefine.platform_type == 1) {
+                               alc_codec_rename(codec, "ALC271X");
+                               spec->codec_variant = ALC269_TYPE_ALC271X;
+                       } else if ((coef & 0xf000) == 0x1000) {
+                               spec->codec_variant = ALC269_TYPE_ALC270;
+                       } else if ((coef & 0xf000) == 0x2000) {
+                               alc_codec_rename(codec, "ALC259");
+                               spec->codec_variant = ALC269_TYPE_ALC259;
+                       } else if ((coef & 0xf000) == 0x3000) {
+                               alc_codec_rename(codec, "ALC258");
+                               spec->codec_variant = ALC269_TYPE_ALC258;
+                       } else {
+                               alc_codec_rename(codec, "ALC269VB");
+                               spec->codec_variant = ALC269_TYPE_ALC269VB;
+                       }
+               } else
+                       alc_fix_pll_init(codec, 0x20, 0x04, 15);
+               alc269_fill_coef(codec);
+       }
 
        board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
                                                  alc269_models,
index efa4225f5fd6c95f9f0218d38002d1ca12d88bd3..f03b2ff90496f86151b01cec6131e9cc94996a42 100644 (file)
@@ -3481,6 +3481,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
 
                label = hda_get_input_pin_label(codec, nid, 1);
                snd_hda_add_imux_item(dimux, label, index, &type_idx);
+               if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
+                       snd_hda_add_imux_item(imux, label, index, &type_idx);
 
                err = create_elem_capture_vol(codec, nid, label, type_idx,
                                              HDA_INPUT);
@@ -3492,9 +3494,6 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
                        if (err < 0)
                                return err;
                }
-
-               if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
-                       snd_hda_add_imux_item(imux, label, index, NULL);
        }
 
        return 0;
index 44a47e13bd673eb362f956b80bd02adbec367d45..c49837de7d3f74eb9254d83e4f6457b11ae38c17 100644 (file)
@@ -36,7 +36,6 @@ static const struct option options[] = {
 
 static int __cmd_buildid_list(void)
 {
-       int err = -1;
        struct perf_session *session;
 
        session = perf_session__new(input_name, O_RDONLY, force, false);
@@ -49,7 +48,7 @@ static int __cmd_buildid_list(void)
        perf_session__fprintf_dsos_buildid(session, stdout, with_hits);
 
        perf_session__delete(session);
-       return err;
+       return 0;
 }
 
 int cmd_buildid_list(int argc, const char **argv, const char *prefix __used)
index 2e000c068cc5a377d87923bb302a383abafd3a33..add163c9f0e7d4db3fe01afe704a72c5a923597b 100644 (file)
@@ -249,6 +249,11 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
             !params.show_lines))
                usage_with_options(probe_usage, options);
 
+       /*
+        * Only consider the user's kernel image path if given.
+        */
+       symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
+
        if (params.list_events) {
                if (params.mod_events) {
                        pr_err("  Error: Don't use --list with --add/--del.\n");
index 64a85bafde63a1c6f05451a32b31eec521c799d9..7cba0551a56550888c98ff1a933fd6bec8ab9ca0 100644 (file)
@@ -265,15 +265,16 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
                          const char *name, bool is_kallsyms)
 {
        const size_t size = PATH_MAX;
-       char *filename = malloc(size),
+       char *realname = realpath(name, NULL),
+            *filename = malloc(size),
             *linkname = malloc(size), *targetname;
        int len, err = -1;
 
-       if (filename == NULL || linkname == NULL)
+       if (realname == NULL || filename == NULL || linkname == NULL)
                goto out_free;
 
        len = snprintf(filename, size, "%s%s%s",
-                      debugdir, is_kallsyms ? "/" : "", name);
+                      debugdir, is_kallsyms ? "/" : "", realname);
        if (mkdir_p(filename, 0755))
                goto out_free;
 
@@ -283,7 +284,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
                if (is_kallsyms) {
                         if (copyfile("/proc/kallsyms", filename))
                                goto out_free;
-               } else if (link(name, filename) && copyfile(name, filename))
+               } else if (link(realname, filename) && copyfile(name, filename))
                        goto out_free;
        }
 
@@ -300,6 +301,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
        if (symlink(targetname, linkname) == 0)
                err = 0;
 out_free:
+       free(realname);
        free(filename);
        free(linkname);
        return err;
index 3b6a5297bf16cd5a318273bc0a9bf198734a0cfe..61191c6cbe7a8d04af83e1af5426029a73bc7b99 100644 (file)
@@ -114,6 +114,8 @@ static struct symbol *__find_kernel_function_by_name(const char *name,
 const char *kernel_get_module_path(const char *module)
 {
        struct dso *dso;
+       struct map *map;
+       const char *vmlinux_name;
 
        if (module) {
                list_for_each_entry(dso, &machine.kernel_dsos, node) {
@@ -123,10 +125,17 @@ const char *kernel_get_module_path(const char *module)
                }
                pr_debug("Failed to find module %s.\n", module);
                return NULL;
+       }
+
+       map = machine.vmlinux_maps[MAP__FUNCTION];
+       dso = map->dso;
+
+       vmlinux_name = symbol_conf.vmlinux_name;
+       if (vmlinux_name) {
+               if (dso__load_vmlinux(dso, map, vmlinux_name, NULL) <= 0)
+                       return NULL;
        } else {
-               dso = machine.vmlinux_maps[MAP__FUNCTION]->dso;
-               if (dso__load_vmlinux_path(dso,
-                        machine.vmlinux_maps[MAP__FUNCTION], NULL) < 0) {
+               if (dso__load_vmlinux_path(dso, map, NULL) <= 0) {
                        pr_debug("Failed to load kernel map.\n");
                        return NULL;
                }
index 3991d73d1cff9164cb23fb4aae3169af97abfe77..ddf4d45563218ad9e2d8971d32f2a8f25097c502 100644 (file)
@@ -117,28 +117,6 @@ static void line_list__free(struct list_head *head)
 }
 
 /* Dwarf FL wrappers */
-
-static int __linux_kernel_find_elf(Dwfl_Module *mod,
-                                  void **userdata,
-                                  const char *module_name,
-                                  Dwarf_Addr base,
-                                  char **file_name, Elf **elfp)
-{
-       int fd;
-       const char *path = kernel_get_module_path(module_name);
-
-       if (path) {
-               fd = open(path, O_RDONLY);
-               if (fd >= 0) {
-                       *file_name = strdup(path);
-                       return fd;
-               }
-       }
-       /* If failed, try to call standard method */
-       return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base,
-                                         file_name, elfp);
-}
-
 static char *debuginfo_path;   /* Currently dummy */
 
 static const Dwfl_Callbacks offline_callbacks = {
@@ -151,14 +129,6 @@ static const Dwfl_Callbacks offline_callbacks = {
        .find_elf = dwfl_build_id_find_elf,
 };
 
-static const Dwfl_Callbacks kernel_callbacks = {
-       .find_debuginfo = dwfl_standard_find_debuginfo,
-       .debuginfo_path = &debuginfo_path,
-
-       .find_elf = __linux_kernel_find_elf,
-       .section_address = dwfl_linux_kernel_module_section_address,
-};
-
 /* Get a Dwarf from offline image */
 static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias)
 {
@@ -185,6 +155,38 @@ error:
        return dbg;
 }
 
+#if _ELFUTILS_PREREQ(0, 148)
+/* This method is buggy if elfutils is older than 0.148 */
+static int __linux_kernel_find_elf(Dwfl_Module *mod,
+                                  void **userdata,
+                                  const char *module_name,
+                                  Dwarf_Addr base,
+                                  char **file_name, Elf **elfp)
+{
+       int fd;
+       const char *path = kernel_get_module_path(module_name);
+
+       pr_debug2("Use file %s for %s\n", path, module_name);
+       if (path) {
+               fd = open(path, O_RDONLY);
+               if (fd >= 0) {
+                       *file_name = strdup(path);
+                       return fd;
+               }
+       }
+       /* If failed, try to call standard method */
+       return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base,
+                                         file_name, elfp);
+}
+
+static const Dwfl_Callbacks kernel_callbacks = {
+       .find_debuginfo = dwfl_standard_find_debuginfo,
+       .debuginfo_path = &debuginfo_path,
+
+       .find_elf = __linux_kernel_find_elf,
+       .section_address = dwfl_linux_kernel_module_section_address,
+};
+
 /* Get a Dwarf from live kernel image */
 static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp,
                                          Dwarf_Addr *bias)
@@ -205,11 +207,34 @@ static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp,
        dbg = dwfl_addrdwarf(*dwflp, addr, bias);
        /* Here, check whether we could get a real dwarf */
        if (!dbg) {
+               pr_debug("Failed to find kernel dwarf at %lx\n",
+                        (unsigned long)addr);
                dwfl_end(*dwflp);
                *dwflp = NULL;
        }
        return dbg;
 }
+#else
+/* With older elfutils, this just support kernel module... */
+static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr __used, Dwfl **dwflp,
+                                         Dwarf_Addr *bias)
+{
+       int fd;
+       const char *path = kernel_get_module_path("kernel");
+
+       if (!path) {
+               pr_err("Failed to find vmlinux path\n");
+               return NULL;
+       }
+
+       pr_debug2("Use file %s for debuginfo\n", path);
+       fd = open(path, O_RDONLY);
+       if (fd < 0)
+               return NULL;
+
+       return dwfl_init_offline_dwarf(fd, dwflp, bias);
+}
+#endif
 
 /* Dwarf wrappers */
 
index 0409fc7c0058809f01da646c4d5ee98c21f69b1d..8fc0bd3a3a4a6bd3f816a6619cc1de0793a98caa 100644 (file)
@@ -259,7 +259,7 @@ static bool __match_glob(const char *str, const char *pat, bool ignore_space)
                if (!*pat)      /* Tail wild card matches all */
                        return true;
                while (*str)
-                       if (strglobmatch(str++, pat))
+                       if (__match_glob(str++, pat, ignore_space))
                                return true;
        }
        return !*str && !*pat;
index d628c8d1cf5ec11111ab3b750da0d14f6d8fff7f..439ab947daf4af9da352caac290d372ce23846ac 100644 (file)
@@ -1780,8 +1780,8 @@ out_failure:
        return -1;
 }
 
-static int dso__load_vmlinux(struct dso *self, struct map *map,
-                            const char *vmlinux, symbol_filter_t filter)
+int dso__load_vmlinux(struct dso *self, struct map *map,
+                     const char *vmlinux, symbol_filter_t filter)
 {
        int err = -1, fd;
 
index 038f2201ee09579ca3f460d9f59576770ea477d2..6c6eafdb932dacefd29c3ea21e5bef90a80cc9a9 100644 (file)
@@ -166,6 +166,8 @@ void dso__sort_by_name(struct dso *self, enum map_type type);
 struct dso *__dsos__findnew(struct list_head *head, const char *name);
 
 int dso__load(struct dso *self, struct map *map, symbol_filter_t filter);
+int dso__load_vmlinux(struct dso *self, struct map *map,
+                     const char *vmlinux, symbol_filter_t filter);
 int dso__load_vmlinux_path(struct dso *self, struct map *map,
                           symbol_filter_t filter);
 int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map,