Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db9683fb authored by Stefano Brivio's avatar Stefano Brivio Committed by David S. Miller
Browse files

b43legacy: rewrite and fix rfkill initialization



The rfkill subsystem doesn't like code like that
rfkill_allocate();
rfkill_register();
rfkill_unregister();
rfkill_register(); /* <- This will crash */

This sequence happens with
modprobe b43
ifconfig wlanX up
ifconfig wlanX down
ifconfig wlanX up

Fix this by always re-allocating the rfkill stuff before register.

The patch to b43 by Michael Buesch <mb@bu3sch.de> has been ported to
b43legacy.

Signed-off-by: default avatarStefano Brivio <stefano.brivio@polimi.it>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 33a3dc93
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -3384,7 +3384,6 @@ static int b43legacy_setup_modes(struct b43legacy_wldev *dev,

static void b43legacy_wireless_core_detach(struct b43legacy_wldev *dev)
{
	b43legacy_rfkill_free(dev);
	/* We release firmware that late to not be required to re-request
	 * is all the time when we reinit the core. */
	b43legacy_release_firmware(dev);
@@ -3466,7 +3465,6 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev)
	if (!wl->current_dev)
		wl->current_dev = dev;
	INIT_WORK(&dev->restart_work, b43legacy_chip_reset);
	b43legacy_rfkill_alloc(dev);

	b43legacy_radio_turn_off(dev, 1);
	b43legacy_switch_analog(dev, 0);
+10 −6
Original line number Diff line number Diff line
@@ -48,18 +48,21 @@ static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev)
	struct b43legacy_wldev *dev = poll_dev->private;
	struct b43legacy_wl *wl = dev->wl;
	bool enabled;
	bool report_change = 0;

	mutex_lock(&wl->mutex);
	B43legacy_WARN_ON(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED);
	enabled = b43legacy_is_hw_radio_enabled(dev);
	if (unlikely(enabled != dev->radio_hw_enable)) {
		dev->radio_hw_enable = enabled;
		report_change = 1;
		b43legacyinfo(wl, "Radio hardware status changed to %s\n",
			enabled ? "ENABLED" : "DISABLED");
	}
	mutex_unlock(&wl->mutex);

	if (unlikely(report_change))
		input_report_key(poll_dev->input, KEY_WLAN, enabled);
	} else
		mutex_unlock(&wl->mutex);
}

/* Called when the RFKILL toggled in software.
@@ -70,10 +73,11 @@ static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state)
	struct b43legacy_wl *wl = dev->wl;
	int err = 0;

	mutex_lock(&wl->mutex);
	if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)
		goto out_unlock;
	if (!wl->rfkill.registered)
		return 0;

	mutex_lock(&wl->mutex);
	B43legacy_WARN_ON(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED);
	switch (state) {
	case RFKILL_STATE_ON:
		if (!dev->radio_hw_enable) {
+4 −4
Original line number Diff line number Diff line
@@ -16,14 +16,14 @@ struct b43legacy_rfkill {
	struct rfkill *rfkill;
	/* The poll device for the RFKILL input button */
	struct input_polled_dev *poll_dev;
	/* Did initialization succeed? Used for freeing. */
	bool registered;
	/* The unique name of this rfkill switch */
	char name[32];
	char name[sizeof("b43legacy-phy4294967295")];
};

/* All the init functions return void, because we are not interested
/* The init function returns void, because we are not interested
 * in failing the b43 init process when rfkill init failed. */
void b43legacy_rfkill_alloc(struct b43legacy_wldev *dev);
void b43legacy_rfkill_free(struct b43legacy_wldev *dev);
void b43legacy_rfkill_init(struct b43legacy_wldev *dev);
void b43legacy_rfkill_exit(struct b43legacy_wldev *dev);