Add initial missing port work for 2.6.26 to compile
authorLuis R. Rodriguez <lrodriguez@atheros.com>
Mon, 6 Jul 2009 23:30:08 +0000 (16:30 -0700)
committerLuis R. Rodriguez <lrodriguez@atheros.com>
Mon, 6 Jul 2009 23:30:08 +0000 (16:30 -0700)
Almost there...

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
compat/compat-2.6.27.c
compat/compat-2.6.27.h
compat/compat.diff
config.mk
scripts/gen-compat-autoconf.sh

index 077d2cb1ca67dea9212a74c7fe40e63fa75d0e0c..c2716807eb771a884ad9dc0a292482a80fd7ebd0 100644 (file)
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
 
+#include <linux/pci.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+
 /* rfkill notification chain */
 #define RFKILL_STATE_CHANGED            0x0001  /* state of a normal rfkill
                                                        switch has changed */
 
-static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list);
+/*
+ * e5899e1b7d73e67de758a32174a859cc2586c0b9 made pci_pme_capable() external,
+ * it was defined internally, some drivers want access to this information.
+ */
 
 /**
- * register_rfkill_notifier - Add notifier to rfkill notifier chain
- * @nb: pointer to the new entry to add to the chain
- *
- * See blocking_notifier_chain_register() for return value and further
- * observations.
- *
- * Adds a notifier to the rfkill notifier chain.  The chain will be
- * called with a pointer to the relevant rfkill structure as a parameter,
- * refer to include/linux/rfkill.h for the possible events.
- *
- * Notifiers added to this chain are to always return NOTIFY_DONE.  This
- * chain is a blocking notifier chain: notifiers can sleep.
- *
- * Calls to this chain may have been done through a workqueue.  One must
- * assume unordered asynchronous behaviour, there is no way to know if
- * actions related to the event that generated the notification have been
- * carried out already.
+ * pci_pme_capable - check the capability of PCI device to generate PME#
+ * @dev: PCI device to handle.
+ * @state: PCI state from which device will issue PME#.
  */
-int register_rfkill_notifier(struct notifier_block *nb)
+bool pci_pme_capable(struct pci_dev *dev, pci_power_t state)
 {
-       return blocking_notifier_chain_register(&rfkill_notifier_list, nb);
+       if (!dev->pm_cap)
+               return false;
+
+       return !!(dev->pme_support & (1 << state));
 }
-EXPORT_SYMBOL_GPL(register_rfkill_notifier);
 
 /**
- * unregister_rfkill_notifier - remove notifier from rfkill notifier chain
- * @nb: pointer to the entry to remove from the chain
+ *     mmc_align_data_size - pads a transfer size to a more optimal value
+ *     @card: the MMC card associated with the data transfer
+ *     @sz: original transfer size
+ *
+ *     Pads the original data size with a number of extra bytes in
+ *     order to avoid controller bugs and/or performance hits
+ *     (e.g. some controllers revert to PIO for certain sizes).
  *
- * See blocking_notifier_chain_unregister() for return value and further
- * observations.
+ *     Returns the improved size, which might be unmodified.
  *
- * Removes a notifier from the rfkill notifier chain.
+ *     Note that this function is only relevant when issuing a
+ *     single scatter gather entry.
  */
-int unregister_rfkill_notifier(struct notifier_block *nb)
+unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz)
 {
-       return blocking_notifier_chain_unregister(&rfkill_notifier_list, nb);
-}
-EXPORT_SYMBOL_GPL(unregister_rfkill_notifier);
-
-
-static void notify_rfkill_state_change(struct rfkill *rfkill)
-{
-       blocking_notifier_call_chain(&rfkill_notifier_list,
-                       RFKILL_STATE_CHANGED,
-                       rfkill);
+       /*
+       * FIXME: We don't have a system for the controller to tell
+       * the core about its problems yet, so for now we just 32-bit
+       * align the size.
+       */
+       sz = ((sz + 3) / 4) * 4;
+
+       return sz;
 }
+EXPORT_SYMBOL(mmc_align_data_size);
 
 /**
- * rfkill_force_state - Force the internal rfkill radio state
- * @rfkill: pointer to the rfkill class to modify.
- * @state: the current radio state the class should be forced to.
+ *     sdio_align_size - pads a transfer size to a more optimal value
+ *     @func: SDIO function
+ *     @sz: original transfer size
+ *
+ *     Pads the original data size with a number of extra bytes in
+ *     order to avoid controller bugs and/or performance hits
+ *     (e.g. some controllers revert to PIO for certain sizes).
  *
- * This function updates the internal state of the radio cached
- * by the rfkill class.  It should be used when the driver gets
- * a notification by the firmware/hardware of the current *real*
- * state of the radio rfkill switch.
+ *     If possible, it will also adjust the size so that it can be
+ *     handled in just a single request.
  *
- * It may not be called from an atomic context.
+ *     Returns the improved size, which might be unmodified.
  */
-int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
+unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
 {
-       enum rfkill_state oldstate;
-
-       if (state != RFKILL_STATE_SOFT_BLOCKED &&
-           state != RFKILL_STATE_UNBLOCKED &&
-           state != RFKILL_STATE_HARD_BLOCKED)
-               return -EINVAL;
-
-       mutex_lock(&rfkill->mutex);
-
-       oldstate = rfkill->state;
-       rfkill->state = state;
-
-       if (state != oldstate)
-               notify_rfkill_state_change(rfkill);
-
-       mutex_unlock(&rfkill->mutex);
-
-       return 0;
+       unsigned int orig_sz;
+       unsigned int blk_sz, byte_sz;
+       unsigned chunk_sz;
+
+       orig_sz = sz;
+
+       /*
+        * Do a first check with the controller, in case it
+        * wants to increase the size up to a point where it
+        * might need more than one block.
+        */
+       sz = mmc_align_data_size(func->card, sz);
+
+       /*
+        * If we can still do this with just a byte transfer, then
+        * we're done.
+        */
+       if (sz <= sdio_max_byte_size(func))
+               return sz;
+
+       if (func->card->cccr.multi_block) {
+               /*
+                * Check if the transfer is already block aligned
+                */
+               if ((sz % func->cur_blksize) == 0)
+                       return sz;
+
+               /*
+                * Realign it so that it can be done with one request,
+                * and recheck if the controller still likes it.
+                */
+               blk_sz = ((sz + func->cur_blksize - 1) /
+                       func->cur_blksize) * func->cur_blksize;
+               blk_sz = mmc_align_data_size(func->card, blk_sz);
+
+               /*
+                * This value is only good if it is still just
+                * one request.
+                */
+               if ((blk_sz % func->cur_blksize) == 0)
+                       return blk_sz;
+
+               /*
+                * We failed to do one request, but at least try to
+                * pad the remainder properly.
+                */
+               byte_sz = mmc_align_data_size(func->card,
+                               sz % func->cur_blksize);
+               if (byte_sz <= sdio_max_byte_size(func)) {
+                       blk_sz = sz / func->cur_blksize;
+                       return blk_sz * func->cur_blksize + byte_sz;
+               }
+       } else {
+               /*
+                * We need multiple requests, so first check that the
+                * controller can handle the chunk size;
+                */
+               chunk_sz = mmc_align_data_size(func->card,
+                               sdio_max_byte_size(func));
+               if (chunk_sz == sdio_max_byte_size(func)) {
+                       /*
+                        * Fix up the size of the remainder (if any)
+                        */
+                       byte_sz = orig_sz % chunk_sz;
+                       if (byte_sz) {
+                               byte_sz = mmc_align_data_size(func->card,
+                                               byte_sz);
+                       }
+
+                       return (orig_sz / chunk_sz) * chunk_sz + byte_sz;
+               }
+       }
+
+       /*
+        * The controller is simply incapable of transferring the size
+        * we want in decent manner, so just return the original size.
+        */
+       return orig_sz;
 }
-EXPORT_SYMBOL(rfkill_force_state);
+EXPORT_SYMBOL_GPL(sdio_align_size);
+
 
 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) */
 
index e0f1e83fd4f9c3116ef94cdca9a3409a423f02c9..c60ee44ccf52a02c4ba479cc0e4674dd18f53cd1 100644 (file)
@@ -9,6 +9,41 @@
 
 #include <linux/list.h>
 #include <linux/rfkill.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+
+#include <asm-generic/bug.h>
+
+bool pci_pme_capable(struct pci_dev *dev, pci_power_t state);
+
+/*
+ * The net_device has a spin_lock on newer kernels, on older kernels we're out of luck
+ */
+#define netif_addr_lock_bh
+#define netif_addr_unlock_bh
+
+/*
+ * To port this properly we'd have to port warn_slowpath_null(),
+ * which I'm lazy to do so just do a regular print for now. If you
+ * want to port this read kernel/panic.c
+ */
+#define __WARN_printf(arg...)   do { printk(arg); __WARN(); } while (0)
+
+/* This is ported directly as-is on newer kernels */
+#ifndef WARN
+#define WARN(condition, format...) ({                                  \
+       int __ret_warn_on = !!(condition);                              \
+       if (unlikely(__ret_warn_on))                                    \
+               __WARN_printf(format);                                  \
+       unlikely(__ret_warn_on);                                        \
+})
+#endif
+
+/* On 2.6.27 a second argument was added, on older kernels we ignore it */
+#define dma_mapping_error(pdev, dma_addr) dma_mapping_error(dma_addr)
+#define pci_dma_mapping_error(pdev, dma_addr) dma_mapping_error(pdev, dma_addr)
 
 /* This is from include/linux/rfkill.h */
 #define RFKILL_STATE_SOFT_BLOCKED      RFKILL_STATE_OFF
@@ -106,6 +141,9 @@ static inline void list_splice_tail_init(struct list_head *list,
        }
 }
 
+extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int);
+extern unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz);
+
 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) */
 
 #endif /* LINUX_26_27_COMPAT_H */
index 9e7eb897c2cbd40a6a47761d4c44d1e53d1425dd..d33d8452c513f21c8a963d9d6d0704b4bf84cb1a 100644 (file)
        net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
        net->ethtool_ops = &usbnet_ethtool_ops;
  
---- a/net/wireless/Makefile    2009-07-06 10:20:59.511191302 -0700
-+++ b/net/wireless/Makefile    2009-07-06 10:28:11.310193540 -0700
-@@ -1,11 +1,17 @@
+--- a/net/wireless/Makefile    2009-07-06 15:04:31.423241610 -0700
++++ b/net/wireless/Makefile    2009-07-06 14:58:11.298205326 -0700
+@@ -1,4 +1,3 @@
 -obj-$(CONFIG_WIRELESS_EXT) += wext.o
  obj-$(CONFIG_CFG80211) += cfg80211.o
  obj-$(CONFIG_LIB80211) += lib80211.o
  obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o
- obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
+@@ -6,6 +5,14 @@
  obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
  
  cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o ibss.o
 +
 +# Compat-wireless kernel compatibility code
++cfg80211-y += compat-2.6.27.o
 +cfg80211-y += compat-2.6.28.o
 +cfg80211-y += compat-2.6.29.o
 +cfg80211-y += compat-2.6.30.o
  obj-$(CONFIG_LIBERTAS)                += libertas/
  
  obj-$(CONFIG_LIBERTAS_THINFIRM)       += libertas_tf/
+--- a/drivers/net/wireless/p54/p54usb.c        2009-07-06 16:05:47.263198670 -0700
++++ b/drivers/net/wireless/p54/p54usb.c        2009-07-06 16:06:32.298597357 -0700
+@@ -1049,7 +1049,9 @@
+       .resume = p54u_resume,
+       .reset_resume = p54u_resume,
+ #endif /* CONFIG_PM */
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
+       .soft_unbind = 1,
++#endif
+ };
+ static int __init p54u_init(void)
+--- a/drivers/net/wireless/zd1211rw/zd_chip.h  2009-07-06 16:09:14.934197004 -0700
++++ b/drivers/net/wireless/zd1211rw/zd_chip.h  2009-07-06 16:10:01.570226234 -0700
+@@ -897,9 +897,9 @@
+ int zd_chip_unlock_phy_regs(struct zd_chip *chip);
+ enum led_status {
+-      LED_OFF = 0,
+-      LED_SCANNING = 1,
+-      LED_ASSOCIATED = 2,
++      ZD_LED_OFF = 0,
++      ZD_LED_SCANNING = 1,
++      ZD_LED_ASSOCIATED = 2,
+ };
+ int zd_chip_control_leds(struct zd_chip *chip, enum led_status status);
+--- a/drivers/net/wireless/zd1211rw/zd_chip.c  2009-07-06 16:09:24.986198445 -0700
++++ b/drivers/net/wireless/zd1211rw/zd_chip.c  2009-07-06 16:10:19.898624742 -0700
+@@ -1278,11 +1278,11 @@
+       other_led = chip->link_led == LED1 ? LED2 : LED1;
+       switch (status) {
+-      case LED_OFF:
++      case ZD_LED_OFF:
+               ioreqs[0].value = FW_LINK_OFF;
+               ioreqs[1].value = v[1] & ~(LED1|LED2);
+               break;
+-      case LED_SCANNING:
++      case ZD_LED_SCANNING:
+               ioreqs[0].value = FW_LINK_OFF;
+               ioreqs[1].value = v[1] & ~other_led;
+               if (get_seconds() % 3 == 0) {
+@@ -1291,7 +1291,7 @@
+                       ioreqs[1].value |= chip->link_led;
+               }
+               break;
+-      case LED_ASSOCIATED:
++      case ZD_LED_ASSOCIATED:
+               ioreqs[0].value = FW_LINK_TX;
+               ioreqs[1].value = v[1] & ~other_led;
+               ioreqs[1].value |= chip->link_led;
+--- a/drivers/net/wireless/zd1211rw/zd_mac.c   2009-07-06 16:09:30.382198435 -0700
++++ b/drivers/net/wireless/zd1211rw/zd_mac.c   2009-07-06 16:11:36.778629948 -0700
+@@ -1013,7 +1013,7 @@
+       spin_unlock_irq(&mac->lock);
+       r = zd_chip_control_leds(chip,
+-                               is_associated ? LED_ASSOCIATED : LED_SCANNING);
++                               is_associated ? ZD_LED_ASSOCIATED : ZD_LED_SCANNING);
+       if (r)
+               dev_dbg_f(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r);
+@@ -1038,5 +1038,5 @@
+       dev_dbg_f(zd_mac_dev(mac), "\n");
+       cancel_rearming_delayed_workqueue(zd_workqueue,
+               &mac->housekeeping.link_led_work);
+-      zd_chip_control_leds(&mac->chip, LED_OFF);
++      zd_chip_control_leds(&mac->chip, ZD_LED_OFF);
+ }
index 809e275d0b74fbae9b445d4433e8fa13f582f95f..d27d0ed71dd5cd0515e000ebda48dbd8b4bda0b0 100644 (file)
--- a/config.mk
+++ b/config.mk
@@ -25,8 +25,8 @@ endif
 ifeq ($(shell test -e $(KLIB_BUILD)/Makefile && echo yes),yes)
 KERNEL_SUBLEVEL = $(shell $(MAKE) -C $(KLIB_BUILD) kernelversion | sed -n 's/^2\.6\.\([0-9]\+\).*/\1/p')
 
-ifeq ($(shell test $(KERNEL_SUBLEVEL) -lt 27 && echo yes),yes)
-$(error "ERROR: You should use compat-wireless-2.6-old for older kernels, this one is for kenrels >= 2.6.27")
+ifeq ($(shell test $(KERNEL_SUBLEVEL) -lt 26 && echo yes),yes)
+$(error "ERROR: You should use compat-wireless-2.6-old for older kernels, this one is for kernels >= 2.6.26")
 endif
 
 ifeq ($(CONFIG_CFG80211),y)
index 194064946c890cea8f6fb552715a8cb03cd0d6c6..a39056f927054edfdd68c02a18fb2a6a0f2a38a7 100755 (executable)
@@ -11,7 +11,7 @@
 
 # This indicates which is the oldest kernel we support
 # Update this if you are adding support for older kernels.
-OLDEST_KERNEL_SUPPORTED="2.6.27"
+OLDEST_KERNEL_SUPPORTED="2.6.26"
 COMPAT_RELEASE="compat-release"
 KERNEL_RELEASE="git-describe"
 MULT_DEP_FILE=".compat_pivot_dep"