/*
* Copyright (c) 2004-2011 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/module.h>
#include <linux/mmc/card.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/sd.h>
#include "hif.h"
#include "hif-ops.h"
#include "target.h"
#include "debug.h"
#include "cfg80211.h"
struct ath6kl_sdio {
struct sdio_func *func;
spinlock_t lock;
/* free list */
struct list_head bus_req_freeq;
/* available bus requests */
struct bus_request bus_req[BUS_REQUEST_MAX_NUM];
struct ath6kl *ar;
u8 *dma_buffer;
/* protects access to dma_buffer */
struct mutex dma_buffer_mutex;
/* scatter request list head */
struct list_head scat_req;
spinlock_t scat_lock;
bool scatter_enabled;
bool is_disabled;
atomic_t irq_handling;
const struct sdio_device_id *id;
struct work_struct wr_async_work;
struct list_head wr_asyncq;
spinlock_t wr_async_lock;
};
#define CMD53_ARG_READ 0
#define CMD53_ARG_WRITE 1
#define CMD53_ARG_BLOCK_BASIS 1
#define CMD53_ARG_FIXED_ADDRESS 0
#define CMD53_ARG_INCR_ADDRESS 1
static inline struct ath6kl_sdio *ath6kl_sdio_priv(struct ath6kl *ar)
{
return ar->hif_priv;
}
/*
* Macro to check if DMA buffer is WORD-aligned and DMA-able.
* Most host controllers assume the buffer is DMA'able and will
* bug-check otherwise (i.e. buffers on the stack). virt_addr_valid
* check fails on stack memory.
*/
static inline bool buf_needs_bounce(u8 *buf)
{
return ((unsigned long) buf & 0x3) || !virt_addr_valid(buf);
}
static void ath6kl_sdio_set_mbox_info(struct ath6kl *ar