Commit 96021f09 authored by Dan Williams's avatar Dan Williams Committed by John W. Linville
Browse files

libertas: consolidate SDIO firmware wait code



Consolidate a bunch of C&P code that waits for the firmware to be ready.

Signed-off-by: default avatarDan Williams <dcbw@redhat.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent edbe056a
Loading
Loading
Loading
Loading
+35 −63
Original line number Diff line number Diff line
@@ -314,12 +314,28 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
	return ret;
}

static int if_sdio_wait_status(struct if_sdio_card *card, const u8 condition)
{
	u8 status;
	unsigned long timeout;
	int ret = 0;

	timeout = jiffies + HZ;
	while (1) {
		status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
		if (ret || (status & condition))
			break;
		if (time_after(jiffies, timeout))
			return -ETIMEDOUT;
		mdelay(1);
	}
	return ret;
}

static int if_sdio_card_to_host(struct if_sdio_card *card)
{
	int ret;
	u8 status;
	u16 size, type, chunk;
	unsigned long timeout;

	lbs_deb_enter(LBS_DEB_SDIO);

@@ -334,19 +350,9 @@ static int if_sdio_card_to_host(struct if_sdio_card *card)
		goto out;
	}

	timeout = jiffies + HZ;
	while (1) {
		status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
	ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY);
	if (ret)
		goto out;
		if (status & IF_SDIO_IO_RDY)
			break;
		if (time_after(jiffies, timeout)) {
			ret = -ETIMEDOUT;
			goto out;
		}
		mdelay(1);
	}

	/*
	 * The transfer must be in one transaction or the firmware
@@ -413,8 +419,6 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
{
	struct if_sdio_card *card;
	struct if_sdio_packet *packet;
	unsigned long timeout;
	u8 status;
	int ret;
	unsigned long flags;

@@ -434,25 +438,15 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)

		sdio_claim_host(card->func);

		timeout = jiffies + HZ;
		while (1) {
			status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
			if (ret)
				goto release;
			if (status & IF_SDIO_IO_RDY)
				break;
			if (time_after(jiffies, timeout)) {
				ret = -ETIMEDOUT;
				goto release;
			}
			mdelay(1);
		}

		ret = if_sdio_wait_status(card, IF_SDIO_IO_RDY);
		if (ret == 0) {
			ret = sdio_writesb(card->func, card->ioport,
					   packet->buffer, packet->nb);
		}

		if (ret)
			goto release;
release:
			lbs_pr_err("error %d sending packet to firmware\n", ret);

		sdio_release_host(card->func);

		kfree(packet);
@@ -465,10 +459,11 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
/* Firmware                                                         */
/********************************************************************/

#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY)

static int if_sdio_prog_helper(struct if_sdio_card *card)
{
	int ret;
	u8 status;
	const struct firmware *fw;
	unsigned long timeout;
	u8 *chunk_buffer;
@@ -500,20 +495,9 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
	size = fw->size;

	while (size) {
		timeout = jiffies + HZ;
		while (1) {
			status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
		ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
		if (ret)
			goto release;
			if ((status & IF_SDIO_IO_RDY) &&
					(status & IF_SDIO_DL_RDY))
				break;
			if (time_after(jiffies, timeout)) {
				ret = -ETIMEDOUT;
				goto release;
			}
			mdelay(1);
		}

		chunk_size = min(size, (size_t)60);

@@ -583,7 +567,6 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
static int if_sdio_prog_real(struct if_sdio_card *card)
{
	int ret;
	u8 status;
	const struct firmware *fw;
	unsigned long timeout;
	u8 *chunk_buffer;
@@ -615,20 +598,9 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
	size = fw->size;

	while (size) {
		timeout = jiffies + HZ;
		while (1) {
			status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
		ret = if_sdio_wait_status(card, FW_DL_READY_STATUS);
		if (ret)
			goto release;
			if ((status & IF_SDIO_IO_RDY) &&
					(status & IF_SDIO_DL_RDY))
				break;
			if (time_after(jiffies, timeout)) {
				ret = -ETIMEDOUT;
				goto release;
			}
			mdelay(1);
		}

		req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret);
		if (ret)