depends on SSB_POSSIBLE && MAC80211 && HAS_DMA
        select SSB
        select FW_LOADER
-       select SSB_BLOCKIO
        ---help---
          b43 is a driver for the Broadcom 43xx series wireless devices.
 
 
          If unsure, say N.
 
+#Data transfers to the device via PIO. We want it as a fallback even
+# if we can do DMA.
+config B43_PIO
+       bool
+       depends on B43
+       select SSB_BLOCKIO
+       default y
+
 config B43_NPHY
        bool "Pre IEEE 802.11n support (BROKEN)"
        depends on B43 && EXPERIMENTAL && BROKEN
          for production use.
          Only say Y, if you are debugging a problem in the b43 driver sourcecode.
 
+config B43_FORCE_PIO
+       bool "Force usage of PIO instead of DMA"
+       depends on B43 && B43_DEBUG
+       ---help---
+         This will disable DMA and always enable PIO instead.
 
+         Say N!
+         This is only for debugging the PIO engine code. You do
+         _NOT_ want to enable this.
 
        bool radio_hw_enable;   /* saved state of radio hardware enabled state */
        bool qos_enabled;               /* TRUE, if QoS is used. */
        bool hwcrypto_enabled;          /* TRUE, if HW crypto acceleration is enabled. */
+       bool use_pio;                   /* TRUE if next init should use PIO */
 
        /* PHY/Radio device. */
        struct b43_phy phy;
        return dev->__using_pio_transfers;
 }
 
+#ifdef CONFIG_B43_FORCE_PIO
+# define B43_PIO_DEFAULT 1
+#else
+# define B43_PIO_DEFAULT 0
+#endif
+
 /* Message printing */
 void b43info(struct b43_wl *wl, const char *fmt, ...)
     __attribute__ ((format(printf, 2, 3)));
 
 module_param_named(verbose, b43_modparam_verbose, int, 0644);
 MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug");
 
-static int modparam_pio;
-module_param_named(pio, modparam_pio, int, 0444);
-MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode");
+int b43_modparam_pio = B43_PIO_DEFAULT;
+module_param_named(pio, b43_modparam_pio, int, 0644);
+MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
 
 static const struct ssb_device_id b43_ssb_tbl[] = {
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
                               dma_reason[4], dma_reason[5]);
                        b43err(dev->wl, "This device does not support DMA "
                               "on your system. Please use PIO instead.\n");
-                       b43err(dev->wl, "Unload the b43 module and reload "
-                              "with 'pio=1'\n");
+                       /* Fall back to PIO transfers if we get fatal DMA errors! */
+                       dev->use_pio = 1;
+                       b43_controller_restart(dev, "DMA error");
                        return;
                }
                if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) {
 
        if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
            (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) ||
-           modparam_pio) {
+           dev->use_pio) {
                dev->__using_pio_transfers = 1;
                err = b43_pio_init(dev);
        } else {
        if (!wldev)
                goto out;
 
+       wldev->use_pio = b43_modparam_pio;
        wldev->dev = dev;
        wldev->wl = wl;
        b43_set_status(wldev, B43_STAT_UNINIT);