/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
* See LICENSE.qla2xxx for copyright and licensing details.
*/
#include "qla_def.h"
#include "qla_tmpl.h"
#define ISPREG(vha) (&(vha)->hw->iobase->isp24)
#define IOBAR(reg) offsetof(typeof(*(reg)), iobase_addr)
#define IOBASE(vha) IOBAR(ISPREG(vha))
#define INVALID_ENTRY ((struct qla27xx_fwdt_entry *)0xffffffffffffffffUL)
/* hardware_lock assumed held. */
static void
qla27xx_write_remote_reg(struct scsi_qla_host *vha,
u32 addr, u32 data)
{
struct device_reg_24xx __iomem *reg = &vha->hw->iobase->isp24;
ql_dbg(ql_dbg_misc, vha, 0xd300,
"%s: addr/data = %xh/%xh\n", __func__, addr, data);
wrt_reg_dword(®->iobase_addr, 0x40);
wrt_reg_dword(®->iobase_c4, data);
wrt_reg_dword(®->iobase_window, addr);
}
void
qla27xx_reset_mpi(scsi_qla_host_t *vha)
{
ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd301,
"Entered %s.\n", __func__);
qla27xx_write_remote_reg(vha, 0x104050, 0x40004);
qla27xx_write_remote_reg(vha, 0x10405c, 0x4);
vha->hw->stat.num_mpi_reset++;
}
static inline void
qla27xx_insert16(uint16_t value, void *buf, ulong *len)
{
if (buf) {
buf += *len;
*(__le16 *)buf = cpu_to_le16(value);
}
*len += sizeof(value);
}
static inline void
qla27xx_insert32(uint32_t value, void *buf, ulong *len)
{
if (buf) {
buf += *len;
*(__le32 *)buf = cpu_to_le32(value);
}
*len += sizeof(value);
}
static inline void
qla27xx_insertbuf(void *mem, ulong size, void *buf, ulong *len)
{
if (buf && mem && size) {
buf += *len;
memcpy(buf, mem, size);
}
*len += size;
}
static inline void
qla27xx_read8(void __iomem *window, void *buf, ulong *len)
{
uint8_t value = ~0;
if (buf) {
value = rd_reg_byte(window);
}
qla27xx_insert32(value, buf, len);
}
static inline void
qla27xx_read16(void __iomem *window, void *buf, ulong *len)
{
uint16_t value = ~0;
if (buf) {
value = rd_reg_word(window);
}
qla27xx_insert32(value, buf, len);
}
static inline void
qla27xx_read32(void __iomem *window, void *buf, ulong *len)
{
uint32_t value = ~0;
if (buf) {
value = rd_reg_dword(window);
}
qla27xx_insert32(value, buf, len);
}
static inline void (*qla27xx_read_vector(uint width))(void __iomem*, void *, ulong *)
{
return
(width == 1) ? qla27xx_read8 :
(width == 2) ? qla27xx_read16 :
qla27xx_read32;
}
static inline void
qla27xx_read_reg