cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ql4_nx.c (117235B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * QLogic iSCSI HBA Driver
      4 * Copyright (c)  2003-2013 QLogic Corporation
      5 */
      6#include <linux/delay.h>
      7#include <linux/io.h>
      8#include <linux/pci.h>
      9#include <linux/ratelimit.h>
     10#include "ql4_def.h"
     11#include "ql4_glbl.h"
     12#include "ql4_inline.h"
     13
     14#include <linux/io-64-nonatomic-lo-hi.h>
     15
     16#define TIMEOUT_100_MS	100
     17#define MASK(n)		DMA_BIT_MASK(n)
     18#define MN_WIN(addr)	(((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
     19#define OCM_WIN(addr)	(((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
     20#define MS_WIN(addr)	(addr & 0x0ffc0000)
     21#define QLA82XX_PCI_MN_2M	(0)
     22#define QLA82XX_PCI_MS_2M	(0x80000)
     23#define QLA82XX_PCI_OCM0_2M	(0xc0000)
     24#define VALID_OCM_ADDR(addr)	(((addr) & 0x3f800) != 0x3f800)
     25#define GET_MEM_OFFS_2M(addr)	(addr & MASK(18))
     26
     27/* CRB window related */
     28#define CRB_BLK(off)	((off >> 20) & 0x3f)
     29#define CRB_SUBBLK(off)	((off >> 16) & 0xf)
     30#define CRB_WINDOW_2M	(0x130060)
     31#define CRB_HI(off)	((qla4_82xx_crb_hub_agt[CRB_BLK(off)] << 20) | \
     32			((off) & 0xf0000))
     33#define QLA82XX_PCI_CAMQM_2M_END	(0x04800800UL)
     34#define QLA82XX_PCI_CAMQM_2M_BASE	(0x000ff800UL)
     35#define CRB_INDIRECT_2M			(0x1e0000UL)
     36
     37static inline void __iomem *
     38qla4_8xxx_pci_base_offsetfset(struct scsi_qla_host *ha, unsigned long off)
     39{
     40	if ((off < ha->first_page_group_end) &&
     41	    (off >= ha->first_page_group_start))
     42		return (void __iomem *)(ha->nx_pcibase + off);
     43
     44	return NULL;
     45}
     46
     47static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8,
     48				0x410000AC, 0x410000B8, 0x410000BC };
     49#define MAX_CRB_XFORM 60
     50static unsigned long crb_addr_xform[MAX_CRB_XFORM];
     51static int qla4_8xxx_crb_table_initialized;
     52
     53#define qla4_8xxx_crb_addr_transform(name) \
     54	(crb_addr_xform[QLA82XX_HW_PX_MAP_CRB_##name] = \
     55	 QLA82XX_HW_CRB_HUB_AGT_ADR_##name << 20)
     56static void
     57qla4_82xx_crb_addr_transform_setup(void)
     58{
     59	qla4_8xxx_crb_addr_transform(XDMA);
     60	qla4_8xxx_crb_addr_transform(TIMR);
     61	qla4_8xxx_crb_addr_transform(SRE);
     62	qla4_8xxx_crb_addr_transform(SQN3);
     63	qla4_8xxx_crb_addr_transform(SQN2);
     64	qla4_8xxx_crb_addr_transform(SQN1);
     65	qla4_8xxx_crb_addr_transform(SQN0);
     66	qla4_8xxx_crb_addr_transform(SQS3);
     67	qla4_8xxx_crb_addr_transform(SQS2);
     68	qla4_8xxx_crb_addr_transform(SQS1);
     69	qla4_8xxx_crb_addr_transform(SQS0);
     70	qla4_8xxx_crb_addr_transform(RPMX7);
     71	qla4_8xxx_crb_addr_transform(RPMX6);
     72	qla4_8xxx_crb_addr_transform(RPMX5);
     73	qla4_8xxx_crb_addr_transform(RPMX4);
     74	qla4_8xxx_crb_addr_transform(RPMX3);
     75	qla4_8xxx_crb_addr_transform(RPMX2);
     76	qla4_8xxx_crb_addr_transform(RPMX1);
     77	qla4_8xxx_crb_addr_transform(RPMX0);
     78	qla4_8xxx_crb_addr_transform(ROMUSB);
     79	qla4_8xxx_crb_addr_transform(SN);
     80	qla4_8xxx_crb_addr_transform(QMN);
     81	qla4_8xxx_crb_addr_transform(QMS);
     82	qla4_8xxx_crb_addr_transform(PGNI);
     83	qla4_8xxx_crb_addr_transform(PGND);
     84	qla4_8xxx_crb_addr_transform(PGN3);
     85	qla4_8xxx_crb_addr_transform(PGN2);
     86	qla4_8xxx_crb_addr_transform(PGN1);
     87	qla4_8xxx_crb_addr_transform(PGN0);
     88	qla4_8xxx_crb_addr_transform(PGSI);
     89	qla4_8xxx_crb_addr_transform(PGSD);
     90	qla4_8xxx_crb_addr_transform(PGS3);
     91	qla4_8xxx_crb_addr_transform(PGS2);
     92	qla4_8xxx_crb_addr_transform(PGS1);
     93	qla4_8xxx_crb_addr_transform(PGS0);
     94	qla4_8xxx_crb_addr_transform(PS);
     95	qla4_8xxx_crb_addr_transform(PH);
     96	qla4_8xxx_crb_addr_transform(NIU);
     97	qla4_8xxx_crb_addr_transform(I2Q);
     98	qla4_8xxx_crb_addr_transform(EG);
     99	qla4_8xxx_crb_addr_transform(MN);
    100	qla4_8xxx_crb_addr_transform(MS);
    101	qla4_8xxx_crb_addr_transform(CAS2);
    102	qla4_8xxx_crb_addr_transform(CAS1);
    103	qla4_8xxx_crb_addr_transform(CAS0);
    104	qla4_8xxx_crb_addr_transform(CAM);
    105	qla4_8xxx_crb_addr_transform(C2C1);
    106	qla4_8xxx_crb_addr_transform(C2C0);
    107	qla4_8xxx_crb_addr_transform(SMB);
    108	qla4_8xxx_crb_addr_transform(OCM0);
    109	qla4_8xxx_crb_addr_transform(I2C0);
    110
    111	qla4_8xxx_crb_table_initialized = 1;
    112}
    113
    114static struct crb_128M_2M_block_map crb_128M_2M_map[64] = {
    115	{{{0, 0,         0,         0} } },		/* 0: PCI */
    116	{{{1, 0x0100000, 0x0102000, 0x120000},	/* 1: PCIE */
    117		{1, 0x0110000, 0x0120000, 0x130000},
    118		{1, 0x0120000, 0x0122000, 0x124000},
    119		{1, 0x0130000, 0x0132000, 0x126000},
    120		{1, 0x0140000, 0x0142000, 0x128000},
    121		{1, 0x0150000, 0x0152000, 0x12a000},
    122		{1, 0x0160000, 0x0170000, 0x110000},
    123		{1, 0x0170000, 0x0172000, 0x12e000},
    124		{0, 0x0000000, 0x0000000, 0x000000},
    125		{0, 0x0000000, 0x0000000, 0x000000},
    126		{0, 0x0000000, 0x0000000, 0x000000},
    127		{0, 0x0000000, 0x0000000, 0x000000},
    128		{0, 0x0000000, 0x0000000, 0x000000},
    129		{0, 0x0000000, 0x0000000, 0x000000},
    130		{1, 0x01e0000, 0x01e0800, 0x122000},
    131		{0, 0x0000000, 0x0000000, 0x000000} } },
    132	{{{1, 0x0200000, 0x0210000, 0x180000} } },/* 2: MN */
    133	{{{0, 0,         0,         0} } },	    /* 3: */
    134	{{{1, 0x0400000, 0x0401000, 0x169000} } },/* 4: P2NR1 */
    135	{{{1, 0x0500000, 0x0510000, 0x140000} } },/* 5: SRE   */
    136	{{{1, 0x0600000, 0x0610000, 0x1c0000} } },/* 6: NIU   */
    137	{{{1, 0x0700000, 0x0704000, 0x1b8000} } },/* 7: QM    */
    138	{{{1, 0x0800000, 0x0802000, 0x170000},  /* 8: SQM0  */
    139		{0, 0x0000000, 0x0000000, 0x000000},
    140		{0, 0x0000000, 0x0000000, 0x000000},
    141		{0, 0x0000000, 0x0000000, 0x000000},
    142		{0, 0x0000000, 0x0000000, 0x000000},
    143		{0, 0x0000000, 0x0000000, 0x000000},
    144		{0, 0x0000000, 0x0000000, 0x000000},
    145		{0, 0x0000000, 0x0000000, 0x000000},
    146		{0, 0x0000000, 0x0000000, 0x000000},
    147		{0, 0x0000000, 0x0000000, 0x000000},
    148		{0, 0x0000000, 0x0000000, 0x000000},
    149		{0, 0x0000000, 0x0000000, 0x000000},
    150		{0, 0x0000000, 0x0000000, 0x000000},
    151		{0, 0x0000000, 0x0000000, 0x000000},
    152		{0, 0x0000000, 0x0000000, 0x000000},
    153		{1, 0x08f0000, 0x08f2000, 0x172000} } },
    154	{{{1, 0x0900000, 0x0902000, 0x174000},	/* 9: SQM1*/
    155		{0, 0x0000000, 0x0000000, 0x000000},
    156		{0, 0x0000000, 0x0000000, 0x000000},
    157		{0, 0x0000000, 0x0000000, 0x000000},
    158		{0, 0x0000000, 0x0000000, 0x000000},
    159		{0, 0x0000000, 0x0000000, 0x000000},
    160		{0, 0x0000000, 0x0000000, 0x000000},
    161		{0, 0x0000000, 0x0000000, 0x000000},
    162		{0, 0x0000000, 0x0000000, 0x000000},
    163		{0, 0x0000000, 0x0000000, 0x000000},
    164		{0, 0x0000000, 0x0000000, 0x000000},
    165		{0, 0x0000000, 0x0000000, 0x000000},
    166		{0, 0x0000000, 0x0000000, 0x000000},
    167		{0, 0x0000000, 0x0000000, 0x000000},
    168		{0, 0x0000000, 0x0000000, 0x000000},
    169		{1, 0x09f0000, 0x09f2000, 0x176000} } },
    170	{{{0, 0x0a00000, 0x0a02000, 0x178000},	/* 10: SQM2*/
    171		{0, 0x0000000, 0x0000000, 0x000000},
    172		{0, 0x0000000, 0x0000000, 0x000000},
    173		{0, 0x0000000, 0x0000000, 0x000000},
    174		{0, 0x0000000, 0x0000000, 0x000000},
    175		{0, 0x0000000, 0x0000000, 0x000000},
    176		{0, 0x0000000, 0x0000000, 0x000000},
    177		{0, 0x0000000, 0x0000000, 0x000000},
    178		{0, 0x0000000, 0x0000000, 0x000000},
    179		{0, 0x0000000, 0x0000000, 0x000000},
    180		{0, 0x0000000, 0x0000000, 0x000000},
    181		{0, 0x0000000, 0x0000000, 0x000000},
    182		{0, 0x0000000, 0x0000000, 0x000000},
    183		{0, 0x0000000, 0x0000000, 0x000000},
    184		{0, 0x0000000, 0x0000000, 0x000000},
    185		{1, 0x0af0000, 0x0af2000, 0x17a000} } },
    186	{{{0, 0x0b00000, 0x0b02000, 0x17c000},	/* 11: SQM3*/
    187		{0, 0x0000000, 0x0000000, 0x000000},
    188		{0, 0x0000000, 0x0000000, 0x000000},
    189		{0, 0x0000000, 0x0000000, 0x000000},
    190		{0, 0x0000000, 0x0000000, 0x000000},
    191		{0, 0x0000000, 0x0000000, 0x000000},
    192		{0, 0x0000000, 0x0000000, 0x000000},
    193		{0, 0x0000000, 0x0000000, 0x000000},
    194		{0, 0x0000000, 0x0000000, 0x000000},
    195		{0, 0x0000000, 0x0000000, 0x000000},
    196		{0, 0x0000000, 0x0000000, 0x000000},
    197		{0, 0x0000000, 0x0000000, 0x000000},
    198		{0, 0x0000000, 0x0000000, 0x000000},
    199		{0, 0x0000000, 0x0000000, 0x000000},
    200		{0, 0x0000000, 0x0000000, 0x000000},
    201		{1, 0x0bf0000, 0x0bf2000, 0x17e000} } },
    202	{{{1, 0x0c00000, 0x0c04000, 0x1d4000} } },/* 12: I2Q */
    203	{{{1, 0x0d00000, 0x0d04000, 0x1a4000} } },/* 13: TMR */
    204	{{{1, 0x0e00000, 0x0e04000, 0x1a0000} } },/* 14: ROMUSB */
    205	{{{1, 0x0f00000, 0x0f01000, 0x164000} } },/* 15: PEG4 */
    206	{{{0, 0x1000000, 0x1004000, 0x1a8000} } },/* 16: XDMA */
    207	{{{1, 0x1100000, 0x1101000, 0x160000} } },/* 17: PEG0 */
    208	{{{1, 0x1200000, 0x1201000, 0x161000} } },/* 18: PEG1 */
    209	{{{1, 0x1300000, 0x1301000, 0x162000} } },/* 19: PEG2 */
    210	{{{1, 0x1400000, 0x1401000, 0x163000} } },/* 20: PEG3 */
    211	{{{1, 0x1500000, 0x1501000, 0x165000} } },/* 21: P2ND */
    212	{{{1, 0x1600000, 0x1601000, 0x166000} } },/* 22: P2NI */
    213	{{{0, 0,         0,         0} } },	/* 23: */
    214	{{{0, 0,         0,         0} } },	/* 24: */
    215	{{{0, 0,         0,         0} } },	/* 25: */
    216	{{{0, 0,         0,         0} } },	/* 26: */
    217	{{{0, 0,         0,         0} } },	/* 27: */
    218	{{{0, 0,         0,         0} } },	/* 28: */
    219	{{{1, 0x1d00000, 0x1d10000, 0x190000} } },/* 29: MS */
    220	{{{1, 0x1e00000, 0x1e01000, 0x16a000} } },/* 30: P2NR2 */
    221	{{{1, 0x1f00000, 0x1f10000, 0x150000} } },/* 31: EPG */
    222	{{{0} } },				/* 32: PCI */
    223	{{{1, 0x2100000, 0x2102000, 0x120000},	/* 33: PCIE */
    224		{1, 0x2110000, 0x2120000, 0x130000},
    225		{1, 0x2120000, 0x2122000, 0x124000},
    226		{1, 0x2130000, 0x2132000, 0x126000},
    227		{1, 0x2140000, 0x2142000, 0x128000},
    228		{1, 0x2150000, 0x2152000, 0x12a000},
    229		{1, 0x2160000, 0x2170000, 0x110000},
    230		{1, 0x2170000, 0x2172000, 0x12e000},
    231		{0, 0x0000000, 0x0000000, 0x000000},
    232		{0, 0x0000000, 0x0000000, 0x000000},
    233		{0, 0x0000000, 0x0000000, 0x000000},
    234		{0, 0x0000000, 0x0000000, 0x000000},
    235		{0, 0x0000000, 0x0000000, 0x000000},
    236		{0, 0x0000000, 0x0000000, 0x000000},
    237		{0, 0x0000000, 0x0000000, 0x000000},
    238		{0, 0x0000000, 0x0000000, 0x000000} } },
    239	{{{1, 0x2200000, 0x2204000, 0x1b0000} } },/* 34: CAM */
    240	{{{0} } },				/* 35: */
    241	{{{0} } },				/* 36: */
    242	{{{0} } },				/* 37: */
    243	{{{0} } },				/* 38: */
    244	{{{0} } },				/* 39: */
    245	{{{1, 0x2800000, 0x2804000, 0x1a4000} } },/* 40: TMR */
    246	{{{1, 0x2900000, 0x2901000, 0x16b000} } },/* 41: P2NR3 */
    247	{{{1, 0x2a00000, 0x2a00400, 0x1ac400} } },/* 42: RPMX1 */
    248	{{{1, 0x2b00000, 0x2b00400, 0x1ac800} } },/* 43: RPMX2 */
    249	{{{1, 0x2c00000, 0x2c00400, 0x1acc00} } },/* 44: RPMX3 */
    250	{{{1, 0x2d00000, 0x2d00400, 0x1ad000} } },/* 45: RPMX4 */
    251	{{{1, 0x2e00000, 0x2e00400, 0x1ad400} } },/* 46: RPMX5 */
    252	{{{1, 0x2f00000, 0x2f00400, 0x1ad800} } },/* 47: RPMX6 */
    253	{{{1, 0x3000000, 0x3000400, 0x1adc00} } },/* 48: RPMX7 */
    254	{{{0, 0x3100000, 0x3104000, 0x1a8000} } },/* 49: XDMA */
    255	{{{1, 0x3200000, 0x3204000, 0x1d4000} } },/* 50: I2Q */
    256	{{{1, 0x3300000, 0x3304000, 0x1a0000} } },/* 51: ROMUSB */
    257	{{{0} } },				/* 52: */
    258	{{{1, 0x3500000, 0x3500400, 0x1ac000} } },/* 53: RPMX0 */
    259	{{{1, 0x3600000, 0x3600400, 0x1ae000} } },/* 54: RPMX8 */
    260	{{{1, 0x3700000, 0x3700400, 0x1ae400} } },/* 55: RPMX9 */
    261	{{{1, 0x3800000, 0x3804000, 0x1d0000} } },/* 56: OCM0 */
    262	{{{1, 0x3900000, 0x3904000, 0x1b4000} } },/* 57: CRYPTO */
    263	{{{1, 0x3a00000, 0x3a04000, 0x1d8000} } },/* 58: SMB */
    264	{{{0} } },				/* 59: I2C0 */
    265	{{{0} } },				/* 60: I2C1 */
    266	{{{1, 0x3d00000, 0x3d04000, 0x1dc000} } },/* 61: LPC */
    267	{{{1, 0x3e00000, 0x3e01000, 0x167000} } },/* 62: P2NC */
    268	{{{1, 0x3f00000, 0x3f01000, 0x168000} } }	/* 63: P2NR0 */
    269};
    270
    271/*
    272 * top 12 bits of crb internal address (hub, agent)
    273 */
    274static unsigned qla4_82xx_crb_hub_agt[64] = {
    275	0,
    276	QLA82XX_HW_CRB_HUB_AGT_ADR_PS,
    277	QLA82XX_HW_CRB_HUB_AGT_ADR_MN,
    278	QLA82XX_HW_CRB_HUB_AGT_ADR_MS,
    279	0,
    280	QLA82XX_HW_CRB_HUB_AGT_ADR_SRE,
    281	QLA82XX_HW_CRB_HUB_AGT_ADR_NIU,
    282	QLA82XX_HW_CRB_HUB_AGT_ADR_QMN,
    283	QLA82XX_HW_CRB_HUB_AGT_ADR_SQN0,
    284	QLA82XX_HW_CRB_HUB_AGT_ADR_SQN1,
    285	QLA82XX_HW_CRB_HUB_AGT_ADR_SQN2,
    286	QLA82XX_HW_CRB_HUB_AGT_ADR_SQN3,
    287	QLA82XX_HW_CRB_HUB_AGT_ADR_I2Q,
    288	QLA82XX_HW_CRB_HUB_AGT_ADR_TIMR,
    289	QLA82XX_HW_CRB_HUB_AGT_ADR_ROMUSB,
    290	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN4,
    291	QLA82XX_HW_CRB_HUB_AGT_ADR_XDMA,
    292	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN0,
    293	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN1,
    294	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN2,
    295	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN3,
    296	QLA82XX_HW_CRB_HUB_AGT_ADR_PGND,
    297	QLA82XX_HW_CRB_HUB_AGT_ADR_PGNI,
    298	QLA82XX_HW_CRB_HUB_AGT_ADR_PGS0,
    299	QLA82XX_HW_CRB_HUB_AGT_ADR_PGS1,
    300	QLA82XX_HW_CRB_HUB_AGT_ADR_PGS2,
    301	QLA82XX_HW_CRB_HUB_AGT_ADR_PGS3,
    302	0,
    303	QLA82XX_HW_CRB_HUB_AGT_ADR_PGSI,
    304	QLA82XX_HW_CRB_HUB_AGT_ADR_SN,
    305	0,
    306	QLA82XX_HW_CRB_HUB_AGT_ADR_EG,
    307	0,
    308	QLA82XX_HW_CRB_HUB_AGT_ADR_PS,
    309	QLA82XX_HW_CRB_HUB_AGT_ADR_CAM,
    310	0,
    311	0,
    312	0,
    313	0,
    314	0,
    315	QLA82XX_HW_CRB_HUB_AGT_ADR_TIMR,
    316	0,
    317	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX1,
    318	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX2,
    319	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX3,
    320	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX4,
    321	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX5,
    322	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX6,
    323	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX7,
    324	QLA82XX_HW_CRB_HUB_AGT_ADR_XDMA,
    325	QLA82XX_HW_CRB_HUB_AGT_ADR_I2Q,
    326	QLA82XX_HW_CRB_HUB_AGT_ADR_ROMUSB,
    327	0,
    328	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX0,
    329	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX8,
    330	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX9,
    331	QLA82XX_HW_CRB_HUB_AGT_ADR_OCM0,
    332	0,
    333	QLA82XX_HW_CRB_HUB_AGT_ADR_SMB,
    334	QLA82XX_HW_CRB_HUB_AGT_ADR_I2C0,
    335	QLA82XX_HW_CRB_HUB_AGT_ADR_I2C1,
    336	0,
    337	QLA82XX_HW_CRB_HUB_AGT_ADR_PGNC,
    338	0,
    339};
    340
    341/* Device states */
    342static char *qdev_state[] = {
    343	"Unknown",
    344	"Cold",
    345	"Initializing",
    346	"Ready",
    347	"Need Reset",
    348	"Need Quiescent",
    349	"Failed",
    350	"Quiescent",
    351};
    352
    353/*
    354 * In: 'off' is offset from CRB space in 128M pci map
    355 * Out: 'off' is 2M pci map addr
    356 * side effect: lock crb window
    357 */
    358static void
    359qla4_82xx_pci_set_crbwindow_2M(struct scsi_qla_host *ha, ulong *off)
    360{
    361	u32 win_read;
    362
    363	ha->crb_win = CRB_HI(*off);
    364	writel(ha->crb_win,
    365		(void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
    366
    367	/* Read back value to make sure write has gone through before trying
    368	* to use it. */
    369	win_read = readl((void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
    370	if (win_read != ha->crb_win) {
    371		DEBUG2(ql4_printk(KERN_INFO, ha,
    372		    "%s: Written crbwin (0x%x) != Read crbwin (0x%x),"
    373		    " off=0x%lx\n", __func__, ha->crb_win, win_read, *off));
    374	}
    375	*off = (*off & MASK(16)) + CRB_INDIRECT_2M + ha->nx_pcibase;
    376}
    377
    378#define CRB_WIN_LOCK_TIMEOUT 100000000
    379
    380/*
    381 * Context: atomic
    382 */
    383static int qla4_82xx_crb_win_lock(struct scsi_qla_host *ha)
    384{
    385	int done = 0, timeout = 0;
    386
    387	while (!done) {
    388		/* acquire semaphore3 from PCI HW block */
    389		done = qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_LOCK));
    390		if (done == 1)
    391			break;
    392		if (timeout >= CRB_WIN_LOCK_TIMEOUT)
    393			return -1;
    394
    395		timeout++;
    396		udelay(10);
    397	}
    398	qla4_82xx_wr_32(ha, QLA82XX_CRB_WIN_LOCK_ID, ha->func_num);
    399	return 0;
    400}
    401
    402void qla4_82xx_crb_win_unlock(struct scsi_qla_host *ha)
    403{
    404	qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_UNLOCK));
    405}
    406
    407void
    408qla4_82xx_wr_32(struct scsi_qla_host *ha, ulong off, u32 data)
    409{
    410	unsigned long flags = 0;
    411	int rv;
    412
    413	rv = qla4_82xx_pci_get_crb_addr_2M(ha, &off);
    414
    415	BUG_ON(rv == -1);
    416
    417	if (rv == 1) {
    418		write_lock_irqsave(&ha->hw_lock, flags);
    419		qla4_82xx_crb_win_lock(ha);
    420		qla4_82xx_pci_set_crbwindow_2M(ha, &off);
    421	}
    422
    423	writel(data, (void __iomem *)off);
    424
    425	if (rv == 1) {
    426		qla4_82xx_crb_win_unlock(ha);
    427		write_unlock_irqrestore(&ha->hw_lock, flags);
    428	}
    429}
    430
    431uint32_t qla4_82xx_rd_32(struct scsi_qla_host *ha, ulong off)
    432{
    433	unsigned long flags = 0;
    434	int rv;
    435	u32 data;
    436
    437	rv = qla4_82xx_pci_get_crb_addr_2M(ha, &off);
    438
    439	BUG_ON(rv == -1);
    440
    441	if (rv == 1) {
    442		write_lock_irqsave(&ha->hw_lock, flags);
    443		qla4_82xx_crb_win_lock(ha);
    444		qla4_82xx_pci_set_crbwindow_2M(ha, &off);
    445	}
    446	data = readl((void __iomem *)off);
    447
    448	if (rv == 1) {
    449		qla4_82xx_crb_win_unlock(ha);
    450		write_unlock_irqrestore(&ha->hw_lock, flags);
    451	}
    452	return data;
    453}
    454
    455/* Minidump related functions */
    456int qla4_82xx_md_rd_32(struct scsi_qla_host *ha, uint32_t off, uint32_t *data)
    457{
    458	uint32_t win_read, off_value;
    459	int rval = QLA_SUCCESS;
    460
    461	off_value  = off & 0xFFFF0000;
    462	writel(off_value, (void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
    463
    464	/*
    465	 * Read back value to make sure write has gone through before trying
    466	 * to use it.
    467	 */
    468	win_read = readl((void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
    469	if (win_read != off_value) {
    470		DEBUG2(ql4_printk(KERN_INFO, ha,
    471				  "%s: Written (0x%x) != Read (0x%x), off=0x%x\n",
    472				  __func__, off_value, win_read, off));
    473		rval = QLA_ERROR;
    474	} else {
    475		off_value  = off & 0x0000FFFF;
    476		*data = readl((void __iomem *)(off_value + CRB_INDIRECT_2M +
    477					       ha->nx_pcibase));
    478	}
    479	return rval;
    480}
    481
    482int qla4_82xx_md_wr_32(struct scsi_qla_host *ha, uint32_t off, uint32_t data)
    483{
    484	uint32_t win_read, off_value;
    485	int rval = QLA_SUCCESS;
    486
    487	off_value  = off & 0xFFFF0000;
    488	writel(off_value, (void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
    489
    490	/* Read back value to make sure write has gone through before trying
    491	 * to use it.
    492	 */
    493	win_read = readl((void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
    494	if (win_read != off_value) {
    495		DEBUG2(ql4_printk(KERN_INFO, ha,
    496				  "%s: Written (0x%x) != Read (0x%x), off=0x%x\n",
    497				  __func__, off_value, win_read, off));
    498		rval = QLA_ERROR;
    499	} else {
    500		off_value  = off & 0x0000FFFF;
    501		writel(data, (void __iomem *)(off_value + CRB_INDIRECT_2M +
    502					      ha->nx_pcibase));
    503	}
    504	return rval;
    505}
    506
    507#define IDC_LOCK_TIMEOUT 100000000
    508
    509/**
    510 * qla4_82xx_idc_lock - hw_lock
    511 * @ha: pointer to adapter structure
    512 *
    513 * General purpose lock used to synchronize access to
    514 * CRB_DEV_STATE, CRB_DEV_REF_COUNT, etc.
    515 *
    516 * Context: task, can sleep
    517 **/
    518int qla4_82xx_idc_lock(struct scsi_qla_host *ha)
    519{
    520	int done = 0, timeout = 0;
    521
    522	might_sleep();
    523
    524	while (!done) {
    525		/* acquire semaphore5 from PCI HW block */
    526		done = qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_LOCK));
    527		if (done == 1)
    528			break;
    529		if (timeout >= IDC_LOCK_TIMEOUT)
    530			return -1;
    531
    532		timeout++;
    533		msleep(100);
    534	}
    535	return 0;
    536}
    537
    538void qla4_82xx_idc_unlock(struct scsi_qla_host *ha)
    539{
    540	qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_UNLOCK));
    541}
    542
    543int
    544qla4_82xx_pci_get_crb_addr_2M(struct scsi_qla_host *ha, ulong *off)
    545{
    546	struct crb_128M_2M_sub_block_map *m;
    547
    548	if (*off >= QLA82XX_CRB_MAX)
    549		return -1;
    550
    551	if (*off >= QLA82XX_PCI_CAMQM && (*off < QLA82XX_PCI_CAMQM_2M_END)) {
    552		*off = (*off - QLA82XX_PCI_CAMQM) +
    553		    QLA82XX_PCI_CAMQM_2M_BASE + ha->nx_pcibase;
    554		return 0;
    555	}
    556
    557	if (*off < QLA82XX_PCI_CRBSPACE)
    558		return -1;
    559
    560	*off -= QLA82XX_PCI_CRBSPACE;
    561	/*
    562	 * Try direct map
    563	 */
    564
    565	m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
    566
    567	if (m->valid && (m->start_128M <= *off) && (m->end_128M > *off)) {
    568		*off = *off + m->start_2M - m->start_128M + ha->nx_pcibase;
    569		return 0;
    570	}
    571
    572	/*
    573	 * Not in direct map, use crb window
    574	 */
    575	return 1;
    576}
    577
    578/*
    579* check memory access boundary.
    580* used by test agent. support ddr access only for now
    581*/
    582static unsigned long
    583qla4_82xx_pci_mem_bound_check(struct scsi_qla_host *ha,
    584		unsigned long long addr, int size)
    585{
    586	if (!QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_DDR_NET,
    587	    QLA8XXX_ADDR_DDR_NET_MAX) ||
    588	    !QLA8XXX_ADDR_IN_RANGE(addr + size - 1,
    589	    QLA8XXX_ADDR_DDR_NET, QLA8XXX_ADDR_DDR_NET_MAX) ||
    590	    ((size != 1) && (size != 2) && (size != 4) && (size != 8))) {
    591		return 0;
    592	}
    593	return 1;
    594}
    595
    596static int qla4_82xx_pci_set_window_warning_count;
    597
    598static unsigned long
    599qla4_82xx_pci_set_window(struct scsi_qla_host *ha, unsigned long long addr)
    600{
    601	int window;
    602	u32 win_read;
    603
    604	if (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_DDR_NET,
    605	    QLA8XXX_ADDR_DDR_NET_MAX)) {
    606		/* DDR network side */
    607		window = MN_WIN(addr);
    608		ha->ddr_mn_window = window;
    609		qla4_82xx_wr_32(ha, ha->mn_win_crb |
    610		    QLA82XX_PCI_CRBSPACE, window);
    611		win_read = qla4_82xx_rd_32(ha, ha->mn_win_crb |
    612		    QLA82XX_PCI_CRBSPACE);
    613		if ((win_read << 17) != window) {
    614			ql4_printk(KERN_WARNING, ha,
    615			"%s: Written MNwin (0x%x) != Read MNwin (0x%x)\n",
    616			__func__, window, win_read);
    617		}
    618		addr = GET_MEM_OFFS_2M(addr) + QLA82XX_PCI_DDR_NET;
    619	} else if (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_OCM0,
    620				QLA8XXX_ADDR_OCM0_MAX)) {
    621		unsigned int temp1;
    622		/* if bits 19:18&17:11 are on */
    623		if ((addr & 0x00ff800) == 0xff800) {
    624			printk("%s: QM access not handled.\n", __func__);
    625			addr = -1UL;
    626		}
    627
    628		window = OCM_WIN(addr);
    629		ha->ddr_mn_window = window;
    630		qla4_82xx_wr_32(ha, ha->mn_win_crb |
    631		    QLA82XX_PCI_CRBSPACE, window);
    632		win_read = qla4_82xx_rd_32(ha, ha->mn_win_crb |
    633		    QLA82XX_PCI_CRBSPACE);
    634		temp1 = ((window & 0x1FF) << 7) |
    635		    ((window & 0x0FFFE0000) >> 17);
    636		if (win_read != temp1) {
    637			printk("%s: Written OCMwin (0x%x) != Read"
    638			    " OCMwin (0x%x)\n", __func__, temp1, win_read);
    639		}
    640		addr = GET_MEM_OFFS_2M(addr) + QLA82XX_PCI_OCM0_2M;
    641
    642	} else if (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_QDR_NET,
    643				QLA82XX_P3_ADDR_QDR_NET_MAX)) {
    644		/* QDR network side */
    645		window = MS_WIN(addr);
    646		ha->qdr_sn_window = window;
    647		qla4_82xx_wr_32(ha, ha->ms_win_crb |
    648		    QLA82XX_PCI_CRBSPACE, window);
    649		win_read = qla4_82xx_rd_32(ha,
    650		     ha->ms_win_crb | QLA82XX_PCI_CRBSPACE);
    651		if (win_read != window) {
    652			printk("%s: Written MSwin (0x%x) != Read "
    653			    "MSwin (0x%x)\n", __func__, window, win_read);
    654		}
    655		addr = GET_MEM_OFFS_2M(addr) + QLA82XX_PCI_QDR_NET;
    656
    657	} else {
    658		/*
    659		 * peg gdb frequently accesses memory that doesn't exist,
    660		 * this limits the chit chat so debugging isn't slowed down.
    661		 */
    662		if ((qla4_82xx_pci_set_window_warning_count++ < 8) ||
    663		    (qla4_82xx_pci_set_window_warning_count%64 == 0)) {
    664			printk("%s: Warning:%s Unknown address range!\n",
    665			    __func__, DRIVER_NAME);
    666		}
    667		addr = -1UL;
    668	}
    669	return addr;
    670}
    671
    672/* check if address is in the same windows as the previous access */
    673static int qla4_82xx_pci_is_same_window(struct scsi_qla_host *ha,
    674		unsigned long long addr)
    675{
    676	int window;
    677	unsigned long long qdr_max;
    678
    679	qdr_max = QLA82XX_P3_ADDR_QDR_NET_MAX;
    680
    681	if (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_DDR_NET,
    682	    QLA8XXX_ADDR_DDR_NET_MAX)) {
    683		/* DDR network side */
    684		BUG();	/* MN access can not come here */
    685	} else if (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_OCM0,
    686	     QLA8XXX_ADDR_OCM0_MAX)) {
    687		return 1;
    688	} else if (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_OCM1,
    689	     QLA8XXX_ADDR_OCM1_MAX)) {
    690		return 1;
    691	} else if (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_QDR_NET,
    692	    qdr_max)) {
    693		/* QDR network side */
    694		window = ((addr - QLA8XXX_ADDR_QDR_NET) >> 22) & 0x3f;
    695		if (ha->qdr_sn_window == window)
    696			return 1;
    697	}
    698
    699	return 0;
    700}
    701
    702static int qla4_82xx_pci_mem_read_direct(struct scsi_qla_host *ha,
    703		u64 off, void *data, int size)
    704{
    705	unsigned long flags;
    706	void __iomem *addr;
    707	int ret = 0;
    708	u64 start;
    709	void __iomem *mem_ptr = NULL;
    710	unsigned long mem_base;
    711	unsigned long mem_page;
    712
    713	write_lock_irqsave(&ha->hw_lock, flags);
    714
    715	/*
    716	 * If attempting to access unknown address or straddle hw windows,
    717	 * do not access.
    718	 */
    719	start = qla4_82xx_pci_set_window(ha, off);
    720	if ((start == -1UL) ||
    721	    (qla4_82xx_pci_is_same_window(ha, off + size - 1) == 0)) {
    722		write_unlock_irqrestore(&ha->hw_lock, flags);
    723		printk(KERN_ERR"%s out of bound pci memory access. "
    724				"offset is 0x%llx\n", DRIVER_NAME, off);
    725		return -1;
    726	}
    727
    728	addr = qla4_8xxx_pci_base_offsetfset(ha, start);
    729	if (!addr) {
    730		write_unlock_irqrestore(&ha->hw_lock, flags);
    731		mem_base = pci_resource_start(ha->pdev, 0);
    732		mem_page = start & PAGE_MASK;
    733		/* Map two pages whenever user tries to access addresses in two
    734		   consecutive pages.
    735		 */
    736		if (mem_page != ((start + size - 1) & PAGE_MASK))
    737			mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
    738		else
    739			mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
    740
    741		if (mem_ptr == NULL) {
    742			*(u8 *)data = 0;
    743			return -1;
    744		}
    745		addr = mem_ptr;
    746		addr += start & (PAGE_SIZE - 1);
    747		write_lock_irqsave(&ha->hw_lock, flags);
    748	}
    749
    750	switch (size) {
    751	case 1:
    752		*(u8  *)data = readb(addr);
    753		break;
    754	case 2:
    755		*(u16 *)data = readw(addr);
    756		break;
    757	case 4:
    758		*(u32 *)data = readl(addr);
    759		break;
    760	case 8:
    761		*(u64 *)data = readq(addr);
    762		break;
    763	default:
    764		ret = -1;
    765		break;
    766	}
    767	write_unlock_irqrestore(&ha->hw_lock, flags);
    768
    769	if (mem_ptr)
    770		iounmap(mem_ptr);
    771	return ret;
    772}
    773
    774static int
    775qla4_82xx_pci_mem_write_direct(struct scsi_qla_host *ha, u64 off,
    776		void *data, int size)
    777{
    778	unsigned long flags;
    779	void __iomem *addr;
    780	int ret = 0;
    781	u64 start;
    782	void __iomem *mem_ptr = NULL;
    783	unsigned long mem_base;
    784	unsigned long mem_page;
    785
    786	write_lock_irqsave(&ha->hw_lock, flags);
    787
    788	/*
    789	 * If attempting to access unknown address or straddle hw windows,
    790	 * do not access.
    791	 */
    792	start = qla4_82xx_pci_set_window(ha, off);
    793	if ((start == -1UL) ||
    794	    (qla4_82xx_pci_is_same_window(ha, off + size - 1) == 0)) {
    795		write_unlock_irqrestore(&ha->hw_lock, flags);
    796		printk(KERN_ERR"%s out of bound pci memory access. "
    797				"offset is 0x%llx\n", DRIVER_NAME, off);
    798		return -1;
    799	}
    800
    801	addr = qla4_8xxx_pci_base_offsetfset(ha, start);
    802	if (!addr) {
    803		write_unlock_irqrestore(&ha->hw_lock, flags);
    804		mem_base = pci_resource_start(ha->pdev, 0);
    805		mem_page = start & PAGE_MASK;
    806		/* Map two pages whenever user tries to access addresses in two
    807		   consecutive pages.
    808		 */
    809		if (mem_page != ((start + size - 1) & PAGE_MASK))
    810			mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE*2);
    811		else
    812			mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
    813		if (mem_ptr == NULL)
    814			return -1;
    815
    816		addr = mem_ptr;
    817		addr += start & (PAGE_SIZE - 1);
    818		write_lock_irqsave(&ha->hw_lock, flags);
    819	}
    820
    821	switch (size) {
    822	case 1:
    823		writeb(*(u8 *)data, addr);
    824		break;
    825	case 2:
    826		writew(*(u16 *)data, addr);
    827		break;
    828	case 4:
    829		writel(*(u32 *)data, addr);
    830		break;
    831	case 8:
    832		writeq(*(u64 *)data, addr);
    833		break;
    834	default:
    835		ret = -1;
    836		break;
    837	}
    838	write_unlock_irqrestore(&ha->hw_lock, flags);
    839	if (mem_ptr)
    840		iounmap(mem_ptr);
    841	return ret;
    842}
    843
    844#define MTU_FUDGE_FACTOR 100
    845
    846static unsigned long
    847qla4_82xx_decode_crb_addr(unsigned long addr)
    848{
    849	int i;
    850	unsigned long base_addr, offset, pci_base;
    851
    852	if (!qla4_8xxx_crb_table_initialized)
    853		qla4_82xx_crb_addr_transform_setup();
    854
    855	pci_base = ADDR_ERROR;
    856	base_addr = addr & 0xfff00000;
    857	offset = addr & 0x000fffff;
    858
    859	for (i = 0; i < MAX_CRB_XFORM; i++) {
    860		if (crb_addr_xform[i] == base_addr) {
    861			pci_base = i << 20;
    862			break;
    863		}
    864	}
    865	if (pci_base == ADDR_ERROR)
    866		return pci_base;
    867	else
    868		return pci_base + offset;
    869}
    870
    871static long rom_max_timeout = 100;
    872static long qla4_82xx_rom_lock_timeout = 100;
    873
    874/*
    875 * Context: task, can_sleep
    876 */
    877static int
    878qla4_82xx_rom_lock(struct scsi_qla_host *ha)
    879{
    880	int done = 0, timeout = 0;
    881
    882	might_sleep();
    883
    884	while (!done) {
    885		/* acquire semaphore2 from PCI HW block */
    886		done = qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_LOCK));
    887		if (done == 1)
    888			break;
    889		if (timeout >= qla4_82xx_rom_lock_timeout)
    890			return -1;
    891
    892		timeout++;
    893		msleep(20);
    894	}
    895	qla4_82xx_wr_32(ha, QLA82XX_ROM_LOCK_ID, ROM_LOCK_DRIVER);
    896	return 0;
    897}
    898
    899static void
    900qla4_82xx_rom_unlock(struct scsi_qla_host *ha)
    901{
    902	qla4_82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
    903}
    904
    905static int
    906qla4_82xx_wait_rom_done(struct scsi_qla_host *ha)
    907{
    908	long timeout = 0;
    909	long done = 0 ;
    910
    911	while (done == 0) {
    912		done = qla4_82xx_rd_32(ha, QLA82XX_ROMUSB_GLB_STATUS);
    913		done &= 2;
    914		timeout++;
    915		if (timeout >= rom_max_timeout) {
    916			printk("%s: Timeout reached  waiting for rom done",
    917					DRIVER_NAME);
    918			return -1;
    919		}
    920	}
    921	return 0;
    922}
    923
    924static int
    925qla4_82xx_do_rom_fast_read(struct scsi_qla_host *ha, int addr, int *valp)
    926{
    927	qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ADDRESS, addr);
    928	qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
    929	qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 3);
    930	qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, 0xb);
    931	if (qla4_82xx_wait_rom_done(ha)) {
    932		printk("%s: Error waiting for rom done\n", DRIVER_NAME);
    933		return -1;
    934	}
    935	/* reset abyte_cnt and dummy_byte_cnt */
    936	qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
    937	udelay(10);
    938	qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 0);
    939
    940	*valp = qla4_82xx_rd_32(ha, QLA82XX_ROMUSB_ROM_RDATA);
    941	return 0;
    942}
    943
    944static int
    945qla4_82xx_rom_fast_read(struct scsi_qla_host *ha, int addr, int *valp)
    946{
    947	int ret, loops = 0;
    948
    949	while ((qla4_82xx_rom_lock(ha) != 0) && (loops < 50000)) {
    950		udelay(100);
    951		loops++;
    952	}
    953	if (loops >= 50000) {
    954		ql4_printk(KERN_WARNING, ha, "%s: qla4_82xx_rom_lock failed\n",
    955			   DRIVER_NAME);
    956		return -1;
    957	}
    958	ret = qla4_82xx_do_rom_fast_read(ha, addr, valp);
    959	qla4_82xx_rom_unlock(ha);
    960	return ret;
    961}
    962
    963/*
    964 * This routine does CRB initialize sequence
    965 * to put the ISP into operational state
    966 */
    967static int
    968qla4_82xx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
    969{
    970	int addr, val;
    971	int i ;
    972	struct crb_addr_pair *buf;
    973	unsigned long off;
    974	unsigned offset, n;
    975
    976	struct crb_addr_pair {
    977		long addr;
    978		long data;
    979	};
    980
    981	/* Halt all the indiviual PEGs and other blocks of the ISP */
    982	qla4_82xx_rom_lock(ha);
    983
    984	/* disable all I2Q */
    985	qla4_82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x10, 0x0);
    986	qla4_82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x14, 0x0);
    987	qla4_82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x18, 0x0);
    988	qla4_82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x1c, 0x0);
    989	qla4_82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x20, 0x0);
    990	qla4_82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x24, 0x0);
    991
    992	/* disable all niu interrupts */
    993	qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x40, 0xff);
    994	/* disable xge rx/tx */
    995	qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x70000, 0x00);
    996	/* disable xg1 rx/tx */
    997	qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x80000, 0x00);
    998	/* disable sideband mac */
    999	qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x90000, 0x00);
   1000	/* disable ap0 mac */
   1001	qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0xa0000, 0x00);
   1002	/* disable ap1 mac */
   1003	qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0xb0000, 0x00);
   1004
   1005	/* halt sre */
   1006	val = qla4_82xx_rd_32(ha, QLA82XX_CRB_SRE + 0x1000);
   1007	qla4_82xx_wr_32(ha, QLA82XX_CRB_SRE + 0x1000, val & (~(0x1)));
   1008
   1009	/* halt epg */
   1010	qla4_82xx_wr_32(ha, QLA82XX_CRB_EPG + 0x1300, 0x1);
   1011
   1012	/* halt timers */
   1013	qla4_82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x0, 0x0);
   1014	qla4_82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x8, 0x0);
   1015	qla4_82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x10, 0x0);
   1016	qla4_82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x18, 0x0);
   1017	qla4_82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x100, 0x0);
   1018	qla4_82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x200, 0x0);
   1019
   1020	/* halt pegs */
   1021	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x3c, 1);
   1022	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_1 + 0x3c, 1);
   1023	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_2 + 0x3c, 1);
   1024	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_3 + 0x3c, 1);
   1025	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c, 1);
   1026	msleep(5);
   1027
   1028	/* big hammer */
   1029	if (test_bit(DPC_RESET_HA, &ha->dpc_flags))
   1030		/* don't reset CAM block on reset */
   1031		qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff);
   1032	else
   1033		qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xffffffff);
   1034
   1035	qla4_82xx_rom_unlock(ha);
   1036
   1037	/* Read the signature value from the flash.
   1038	 * Offset 0: Contain signature (0xcafecafe)
   1039	 * Offset 4: Offset and number of addr/value pairs
   1040	 * that present in CRB initialize sequence
   1041	 */
   1042	if (qla4_82xx_rom_fast_read(ha, 0, &n) != 0 || n != 0xcafecafeUL ||
   1043	    qla4_82xx_rom_fast_read(ha, 4, &n) != 0) {
   1044		ql4_printk(KERN_WARNING, ha,
   1045			"[ERROR] Reading crb_init area: n: %08x\n", n);
   1046		return -1;
   1047	}
   1048
   1049	/* Offset in flash = lower 16 bits
   1050	 * Number of enteries = upper 16 bits
   1051	 */
   1052	offset = n & 0xffffU;
   1053	n = (n >> 16) & 0xffffU;
   1054
   1055	/* number of addr/value pair should not exceed 1024 enteries */
   1056	if (n  >= 1024) {
   1057		ql4_printk(KERN_WARNING, ha,
   1058		    "%s: %s:n=0x%x [ERROR] Card flash not initialized.\n",
   1059		    DRIVER_NAME, __func__, n);
   1060		return -1;
   1061	}
   1062
   1063	ql4_printk(KERN_INFO, ha,
   1064		"%s: %d CRB init values found in ROM.\n", DRIVER_NAME, n);
   1065
   1066	buf = kmalloc_array(n, sizeof(struct crb_addr_pair), GFP_KERNEL);
   1067	if (buf == NULL) {
   1068		ql4_printk(KERN_WARNING, ha,
   1069		    "%s: [ERROR] Unable to malloc memory.\n", DRIVER_NAME);
   1070		return -1;
   1071	}
   1072
   1073	for (i = 0; i < n; i++) {
   1074		if (qla4_82xx_rom_fast_read(ha, 8*i + 4*offset, &val) != 0 ||
   1075		    qla4_82xx_rom_fast_read(ha, 8*i + 4*offset + 4, &addr) !=
   1076		    0) {
   1077			kfree(buf);
   1078			return -1;
   1079		}
   1080
   1081		buf[i].addr = addr;
   1082		buf[i].data = val;
   1083	}
   1084
   1085	for (i = 0; i < n; i++) {
   1086		/* Translate internal CRB initialization
   1087		 * address to PCI bus address
   1088		 */
   1089		off = qla4_82xx_decode_crb_addr((unsigned long)buf[i].addr) +
   1090		    QLA82XX_PCI_CRBSPACE;
   1091		/* Not all CRB  addr/value pair to be written,
   1092		 * some of them are skipped
   1093		 */
   1094
   1095		/* skip if LS bit is set*/
   1096		if (off & 0x1) {
   1097			DEBUG2(ql4_printk(KERN_WARNING, ha,
   1098			    "Skip CRB init replay for offset = 0x%lx\n", off));
   1099			continue;
   1100		}
   1101
   1102		/* skipping cold reboot MAGIC */
   1103		if (off == QLA82XX_CAM_RAM(0x1fc))
   1104			continue;
   1105
   1106		/* do not reset PCI */
   1107		if (off == (ROMUSB_GLB + 0xbc))
   1108			continue;
   1109
   1110		/* skip core clock, so that firmware can increase the clock */
   1111		if (off == (ROMUSB_GLB + 0xc8))
   1112			continue;
   1113
   1114		/* skip the function enable register */
   1115		if (off == QLA82XX_PCIE_REG(PCIE_SETUP_FUNCTION))
   1116			continue;
   1117
   1118		if (off == QLA82XX_PCIE_REG(PCIE_SETUP_FUNCTION2))
   1119			continue;
   1120
   1121		if ((off & 0x0ff00000) == QLA82XX_CRB_SMB)
   1122			continue;
   1123
   1124		if ((off & 0x0ff00000) == QLA82XX_CRB_DDR_NET)
   1125			continue;
   1126
   1127		if (off == ADDR_ERROR) {
   1128			ql4_printk(KERN_WARNING, ha,
   1129			    "%s: [ERROR] Unknown addr: 0x%08lx\n",
   1130			    DRIVER_NAME, buf[i].addr);
   1131			continue;
   1132		}
   1133
   1134		qla4_82xx_wr_32(ha, off, buf[i].data);
   1135
   1136		/* ISP requires much bigger delay to settle down,
   1137		 * else crb_window returns 0xffffffff
   1138		 */
   1139		if (off == QLA82XX_ROMUSB_GLB_SW_RESET)
   1140			msleep(1000);
   1141
   1142		/* ISP requires millisec delay between
   1143		 * successive CRB register updation
   1144		 */
   1145		msleep(1);
   1146	}
   1147
   1148	kfree(buf);
   1149
   1150	/* Resetting the data and instruction cache */
   1151	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_D+0xec, 0x1e);
   1152	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_D+0x4c, 8);
   1153	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_I+0x4c, 8);
   1154
   1155	/* Clear all protocol processing engines */
   1156	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0+0x8, 0);
   1157	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0+0xc, 0);
   1158	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_1+0x8, 0);
   1159	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_1+0xc, 0);
   1160	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_2+0x8, 0);
   1161	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_2+0xc, 0);
   1162	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_3+0x8, 0);
   1163	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_3+0xc, 0);
   1164
   1165	return 0;
   1166}
   1167
   1168/**
   1169 * qla4_8xxx_ms_mem_write_128b - Writes data to MS/off-chip memory
   1170 * @ha: Pointer to adapter structure
   1171 * @addr: Flash address to write to
   1172 * @data: Data to be written
   1173 * @count: word_count to be written
   1174 *
   1175 * Return: On success return QLA_SUCCESS
   1176 *         On error return QLA_ERROR
   1177 **/
   1178int qla4_8xxx_ms_mem_write_128b(struct scsi_qla_host *ha, uint64_t addr,
   1179				uint32_t *data, uint32_t count)
   1180{
   1181	int i, j;
   1182	uint32_t agt_ctrl;
   1183	unsigned long flags;
   1184	int ret_val = QLA_SUCCESS;
   1185
   1186	/* Only 128-bit aligned access */
   1187	if (addr & 0xF) {
   1188		ret_val = QLA_ERROR;
   1189		goto exit_ms_mem_write;
   1190	}
   1191
   1192	write_lock_irqsave(&ha->hw_lock, flags);
   1193
   1194	/* Write address */
   1195	ret_val = ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_HI, 0);
   1196	if (ret_val == QLA_ERROR) {
   1197		ql4_printk(KERN_ERR, ha, "%s: write to AGT_ADDR_HI failed\n",
   1198			   __func__);
   1199		goto exit_ms_mem_write_unlock;
   1200	}
   1201
   1202	for (i = 0; i < count; i++, addr += 16) {
   1203		if (!((QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_QDR_NET,
   1204					     QLA8XXX_ADDR_QDR_NET_MAX)) ||
   1205		      (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_DDR_NET,
   1206					     QLA8XXX_ADDR_DDR_NET_MAX)))) {
   1207			ret_val = QLA_ERROR;
   1208			goto exit_ms_mem_write_unlock;
   1209		}
   1210
   1211		ret_val = ha->isp_ops->wr_reg_indirect(ha,
   1212						       MD_MIU_TEST_AGT_ADDR_LO,
   1213						       addr);
   1214		/* Write data */
   1215		ret_val |= ha->isp_ops->wr_reg_indirect(ha,
   1216						MD_MIU_TEST_AGT_WRDATA_LO,
   1217						*data++);
   1218		ret_val |= ha->isp_ops->wr_reg_indirect(ha,
   1219						MD_MIU_TEST_AGT_WRDATA_HI,
   1220						*data++);
   1221		ret_val |= ha->isp_ops->wr_reg_indirect(ha,
   1222						MD_MIU_TEST_AGT_WRDATA_ULO,
   1223						*data++);
   1224		ret_val |= ha->isp_ops->wr_reg_indirect(ha,
   1225						MD_MIU_TEST_AGT_WRDATA_UHI,
   1226						*data++);
   1227		if (ret_val == QLA_ERROR) {
   1228			ql4_printk(KERN_ERR, ha, "%s: write to AGT_WRDATA failed\n",
   1229				   __func__);
   1230			goto exit_ms_mem_write_unlock;
   1231		}
   1232
   1233		/* Check write status */
   1234		ret_val = ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL,
   1235						       MIU_TA_CTL_WRITE_ENABLE);
   1236		ret_val |= ha->isp_ops->wr_reg_indirect(ha,
   1237							MD_MIU_TEST_AGT_CTRL,
   1238							MIU_TA_CTL_WRITE_START);
   1239		if (ret_val == QLA_ERROR) {
   1240			ql4_printk(KERN_ERR, ha, "%s: write to AGT_CTRL failed\n",
   1241				   __func__);
   1242			goto exit_ms_mem_write_unlock;
   1243		}
   1244
   1245		for (j = 0; j < MAX_CTL_CHECK; j++) {
   1246			ret_val = ha->isp_ops->rd_reg_indirect(ha,
   1247							MD_MIU_TEST_AGT_CTRL,
   1248							&agt_ctrl);
   1249			if (ret_val == QLA_ERROR) {
   1250				ql4_printk(KERN_ERR, ha, "%s: failed to read MD_MIU_TEST_AGT_CTRL\n",
   1251					   __func__);
   1252				goto exit_ms_mem_write_unlock;
   1253			}
   1254			if ((agt_ctrl & MIU_TA_CTL_BUSY) == 0)
   1255				break;
   1256		}
   1257
   1258		/* Status check failed */
   1259		if (j >= MAX_CTL_CHECK) {
   1260			printk_ratelimited(KERN_ERR "%s: MS memory write failed!\n",
   1261					   __func__);
   1262			ret_val = QLA_ERROR;
   1263			goto exit_ms_mem_write_unlock;
   1264		}
   1265	}
   1266
   1267exit_ms_mem_write_unlock:
   1268	write_unlock_irqrestore(&ha->hw_lock, flags);
   1269
   1270exit_ms_mem_write:
   1271	return ret_val;
   1272}
   1273
   1274static int
   1275qla4_82xx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start)
   1276{
   1277	int  i, rval = 0;
   1278	long size = 0;
   1279	long flashaddr, memaddr;
   1280	u64 data;
   1281	u32 high, low;
   1282
   1283	flashaddr = memaddr = ha->hw.flt_region_bootload;
   1284	size = (image_start - flashaddr) / 8;
   1285
   1286	DEBUG2(printk("scsi%ld: %s: bootldr=0x%lx, fw_image=0x%x\n",
   1287	    ha->host_no, __func__, flashaddr, image_start));
   1288
   1289	for (i = 0; i < size; i++) {
   1290		if ((qla4_82xx_rom_fast_read(ha, flashaddr, (int *)&low)) ||
   1291		    (qla4_82xx_rom_fast_read(ha, flashaddr + 4,
   1292		    (int *)&high))) {
   1293			rval = -1;
   1294			goto exit_load_from_flash;
   1295		}
   1296		data = ((u64)high << 32) | low ;
   1297		rval = qla4_82xx_pci_mem_write_2M(ha, memaddr, &data, 8);
   1298		if (rval)
   1299			goto exit_load_from_flash;
   1300
   1301		flashaddr += 8;
   1302		memaddr   += 8;
   1303
   1304		if (i % 0x1000 == 0)
   1305			msleep(1);
   1306
   1307	}
   1308
   1309	udelay(100);
   1310
   1311	read_lock(&ha->hw_lock);
   1312	qla4_82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x18, 0x1020);
   1313	qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0x80001e);
   1314	read_unlock(&ha->hw_lock);
   1315
   1316exit_load_from_flash:
   1317	return rval;
   1318}
   1319
   1320static int qla4_82xx_load_fw(struct scsi_qla_host *ha, uint32_t image_start)
   1321{
   1322	u32 rst;
   1323
   1324	qla4_82xx_wr_32(ha, CRB_CMDPEG_STATE, 0);
   1325	if (qla4_82xx_pinit_from_rom(ha, 0) != QLA_SUCCESS) {
   1326		printk(KERN_WARNING "%s: Error during CRB Initialization\n",
   1327		    __func__);
   1328		return QLA_ERROR;
   1329	}
   1330
   1331	udelay(500);
   1332
   1333	/* at this point, QM is in reset. This could be a problem if there are
   1334	 * incoming d* transition queue messages. QM/PCIE could wedge.
   1335	 * To get around this, QM is brought out of reset.
   1336	 */
   1337
   1338	rst = qla4_82xx_rd_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET);
   1339	/* unreset qm */
   1340	rst &= ~(1 << 28);
   1341	qla4_82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, rst);
   1342
   1343	if (qla4_82xx_load_from_flash(ha, image_start)) {
   1344		printk("%s: Error trying to load fw from flash!\n", __func__);
   1345		return QLA_ERROR;
   1346	}
   1347
   1348	return QLA_SUCCESS;
   1349}
   1350
   1351int
   1352qla4_82xx_pci_mem_read_2M(struct scsi_qla_host *ha,
   1353		u64 off, void *data, int size)
   1354{
   1355	int i, j = 0, k, start, end, loop, sz[2], off0[2];
   1356	int shift_amount;
   1357	uint32_t temp;
   1358	uint64_t off8, val, mem_crb, word[2] = {0, 0};
   1359
   1360	/*
   1361	 * If not MN, go check for MS or invalid.
   1362	 */
   1363
   1364	if (off >= QLA8XXX_ADDR_QDR_NET && off <= QLA82XX_P3_ADDR_QDR_NET_MAX)
   1365		mem_crb = QLA82XX_CRB_QDR_NET;
   1366	else {
   1367		mem_crb = QLA82XX_CRB_DDR_NET;
   1368		if (qla4_82xx_pci_mem_bound_check(ha, off, size) == 0)
   1369			return qla4_82xx_pci_mem_read_direct(ha,
   1370					off, data, size);
   1371	}
   1372
   1373
   1374	off8 = off & 0xfffffff0;
   1375	off0[0] = off & 0xf;
   1376	sz[0] = (size < (16 - off0[0])) ? size : (16 - off0[0]);
   1377	shift_amount = 4;
   1378
   1379	loop = ((off0[0] + size - 1) >> shift_amount) + 1;
   1380	off0[1] = 0;
   1381	sz[1] = size - sz[0];
   1382
   1383	for (i = 0; i < loop; i++) {
   1384		temp = off8 + (i << shift_amount);
   1385		qla4_82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
   1386		temp = 0;
   1387		qla4_82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
   1388		temp = MIU_TA_CTL_ENABLE;
   1389		qla4_82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
   1390		temp = MIU_TA_CTL_START_ENABLE;
   1391		qla4_82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
   1392
   1393		for (j = 0; j < MAX_CTL_CHECK; j++) {
   1394			temp = qla4_82xx_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL);
   1395			if ((temp & MIU_TA_CTL_BUSY) == 0)
   1396				break;
   1397		}
   1398
   1399		if (j >= MAX_CTL_CHECK) {
   1400			printk_ratelimited(KERN_ERR
   1401					   "%s: failed to read through agent\n",
   1402					   __func__);
   1403			break;
   1404		}
   1405
   1406		start = off0[i] >> 2;
   1407		end   = (off0[i] + sz[i] - 1) >> 2;
   1408		for (k = start; k <= end; k++) {
   1409			temp = qla4_82xx_rd_32(ha,
   1410				mem_crb + MIU_TEST_AGT_RDDATA(k));
   1411			word[i] |= ((uint64_t)temp << (32 * (k & 1)));
   1412		}
   1413	}
   1414
   1415	if (j >= MAX_CTL_CHECK)
   1416		return -1;
   1417
   1418	if ((off0[0] & 7) == 0) {
   1419		val = word[0];
   1420	} else {
   1421		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
   1422		((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
   1423	}
   1424
   1425	switch (size) {
   1426	case 1:
   1427		*(uint8_t  *)data = val;
   1428		break;
   1429	case 2:
   1430		*(uint16_t *)data = val;
   1431		break;
   1432	case 4:
   1433		*(uint32_t *)data = val;
   1434		break;
   1435	case 8:
   1436		*(uint64_t *)data = val;
   1437		break;
   1438	}
   1439	return 0;
   1440}
   1441
   1442int
   1443qla4_82xx_pci_mem_write_2M(struct scsi_qla_host *ha,
   1444		u64 off, void *data, int size)
   1445{
   1446	int i, j, ret = 0, loop, sz[2], off0;
   1447	int scale, shift_amount, startword;
   1448	uint32_t temp;
   1449	uint64_t off8, mem_crb, tmpw, word[2] = {0, 0};
   1450
   1451	/*
   1452	 * If not MN, go check for MS or invalid.
   1453	 */
   1454	if (off >= QLA8XXX_ADDR_QDR_NET && off <= QLA82XX_P3_ADDR_QDR_NET_MAX)
   1455		mem_crb = QLA82XX_CRB_QDR_NET;
   1456	else {
   1457		mem_crb = QLA82XX_CRB_DDR_NET;
   1458		if (qla4_82xx_pci_mem_bound_check(ha, off, size) == 0)
   1459			return qla4_82xx_pci_mem_write_direct(ha,
   1460					off, data, size);
   1461	}
   1462
   1463	off0 = off & 0x7;
   1464	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
   1465	sz[1] = size - sz[0];
   1466
   1467	off8 = off & 0xfffffff0;
   1468	loop = (((off & 0xf) + size - 1) >> 4) + 1;
   1469	shift_amount = 4;
   1470	scale = 2;
   1471	startword = (off & 0xf)/8;
   1472
   1473	for (i = 0; i < loop; i++) {
   1474		if (qla4_82xx_pci_mem_read_2M(ha, off8 +
   1475		    (i << shift_amount), &word[i * scale], 8))
   1476			return -1;
   1477	}
   1478
   1479	switch (size) {
   1480	case 1:
   1481		tmpw = *((uint8_t *)data);
   1482		break;
   1483	case 2:
   1484		tmpw = *((uint16_t *)data);
   1485		break;
   1486	case 4:
   1487		tmpw = *((uint32_t *)data);
   1488		break;
   1489	case 8:
   1490	default:
   1491		tmpw = *((uint64_t *)data);
   1492		break;
   1493	}
   1494
   1495	if (sz[0] == 8)
   1496		word[startword] = tmpw;
   1497	else {
   1498		word[startword] &=
   1499		    ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
   1500		word[startword] |= tmpw << (off0 * 8);
   1501	}
   1502
   1503	if (sz[1] != 0) {
   1504		word[startword+1] &= ~(~0ULL << (sz[1] * 8));
   1505		word[startword+1] |= tmpw >> (sz[0] * 8);
   1506	}
   1507
   1508	for (i = 0; i < loop; i++) {
   1509		temp = off8 + (i << shift_amount);
   1510		qla4_82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
   1511		temp = 0;
   1512		qla4_82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);
   1513		temp = word[i * scale] & 0xffffffff;
   1514		qla4_82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);
   1515		temp = (word[i * scale] >> 32) & 0xffffffff;
   1516		qla4_82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);
   1517		temp = word[i*scale + 1] & 0xffffffff;
   1518		qla4_82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_UPPER_LO,
   1519		    temp);
   1520		temp = (word[i*scale + 1] >> 32) & 0xffffffff;
   1521		qla4_82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_UPPER_HI,
   1522		    temp);
   1523
   1524		temp = MIU_TA_CTL_WRITE_ENABLE;
   1525		qla4_82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_CTRL, temp);
   1526		temp = MIU_TA_CTL_WRITE_START;
   1527		qla4_82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_CTRL, temp);
   1528
   1529		for (j = 0; j < MAX_CTL_CHECK; j++) {
   1530			temp = qla4_82xx_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL);
   1531			if ((temp & MIU_TA_CTL_BUSY) == 0)
   1532				break;
   1533		}
   1534
   1535		if (j >= MAX_CTL_CHECK) {
   1536			if (printk_ratelimit())
   1537				ql4_printk(KERN_ERR, ha,
   1538					   "%s: failed to read through agent\n",
   1539					   __func__);
   1540			ret = -1;
   1541			break;
   1542		}
   1543	}
   1544
   1545	return ret;
   1546}
   1547
   1548static int qla4_82xx_cmdpeg_ready(struct scsi_qla_host *ha, int pegtune_val)
   1549{
   1550	u32 val = 0;
   1551	int retries = 60;
   1552
   1553	if (!pegtune_val) {
   1554		do {
   1555			val = qla4_82xx_rd_32(ha, CRB_CMDPEG_STATE);
   1556			if ((val == PHAN_INITIALIZE_COMPLETE) ||
   1557			    (val == PHAN_INITIALIZE_ACK))
   1558				return 0;
   1559			set_current_state(TASK_UNINTERRUPTIBLE);
   1560			schedule_timeout(500);
   1561
   1562		} while (--retries);
   1563
   1564		if (!retries) {
   1565			pegtune_val = qla4_82xx_rd_32(ha,
   1566				QLA82XX_ROMUSB_GLB_PEGTUNE_DONE);
   1567			printk(KERN_WARNING "%s: init failed, "
   1568				"pegtune_val = %x\n", __func__, pegtune_val);
   1569			return -1;
   1570		}
   1571	}
   1572	return 0;
   1573}
   1574
   1575static int qla4_82xx_rcvpeg_ready(struct scsi_qla_host *ha)
   1576{
   1577	uint32_t state = 0;
   1578	int loops = 0;
   1579
   1580	/* Window 1 call */
   1581	read_lock(&ha->hw_lock);
   1582	state = qla4_82xx_rd_32(ha, CRB_RCVPEG_STATE);
   1583	read_unlock(&ha->hw_lock);
   1584
   1585	while ((state != PHAN_PEG_RCV_INITIALIZED) && (loops < 30000)) {
   1586		udelay(100);
   1587		/* Window 1 call */
   1588		read_lock(&ha->hw_lock);
   1589		state = qla4_82xx_rd_32(ha, CRB_RCVPEG_STATE);
   1590		read_unlock(&ha->hw_lock);
   1591
   1592		loops++;
   1593	}
   1594
   1595	if (loops >= 30000) {
   1596		DEBUG2(ql4_printk(KERN_INFO, ha,
   1597		    "Receive Peg initialization not complete: 0x%x.\n", state));
   1598		return QLA_ERROR;
   1599	}
   1600
   1601	return QLA_SUCCESS;
   1602}
   1603
   1604void
   1605qla4_8xxx_set_drv_active(struct scsi_qla_host *ha)
   1606{
   1607	uint32_t drv_active;
   1608
   1609	drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
   1610
   1611	/*
   1612	 * For ISP8324 and ISP8042, drv_active register has 1 bit per function,
   1613	 * shift 1 by func_num to set a bit for the function.
   1614	 * For ISP8022, drv_active has 4 bits per function
   1615	 */
   1616	if (is_qla8032(ha) || is_qla8042(ha))
   1617		drv_active |= (1 << ha->func_num);
   1618	else
   1619		drv_active |= (1 << (ha->func_num * 4));
   1620
   1621	ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n",
   1622		   __func__, ha->host_no, drv_active);
   1623	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE, drv_active);
   1624}
   1625
   1626void
   1627qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha)
   1628{
   1629	uint32_t drv_active;
   1630
   1631	drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
   1632
   1633	/*
   1634	 * For ISP8324 and ISP8042, drv_active register has 1 bit per function,
   1635	 * shift 1 by func_num to set a bit for the function.
   1636	 * For ISP8022, drv_active has 4 bits per function
   1637	 */
   1638	if (is_qla8032(ha) || is_qla8042(ha))
   1639		drv_active &= ~(1 << (ha->func_num));
   1640	else
   1641		drv_active &= ~(1 << (ha->func_num * 4));
   1642
   1643	ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n",
   1644		   __func__, ha->host_no, drv_active);
   1645	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE, drv_active);
   1646}
   1647
   1648inline int qla4_8xxx_need_reset(struct scsi_qla_host *ha)
   1649{
   1650	uint32_t drv_state, drv_active;
   1651	int rval;
   1652
   1653	drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
   1654	drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
   1655
   1656	/*
   1657	 * For ISP8324 and ISP8042, drv_active register has 1 bit per function,
   1658	 * shift 1 by func_num to set a bit for the function.
   1659	 * For ISP8022, drv_active has 4 bits per function
   1660	 */
   1661	if (is_qla8032(ha) || is_qla8042(ha))
   1662		rval = drv_state & (1 << ha->func_num);
   1663	else
   1664		rval = drv_state & (1 << (ha->func_num * 4));
   1665
   1666	if ((test_bit(AF_EEH_BUSY, &ha->flags)) && drv_active)
   1667		rval = 1;
   1668
   1669	return rval;
   1670}
   1671
   1672void qla4_8xxx_set_rst_ready(struct scsi_qla_host *ha)
   1673{
   1674	uint32_t drv_state;
   1675
   1676	drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
   1677
   1678	/*
   1679	 * For ISP8324 and ISP8042, drv_active register has 1 bit per function,
   1680	 * shift 1 by func_num to set a bit for the function.
   1681	 * For ISP8022, drv_active has 4 bits per function
   1682	 */
   1683	if (is_qla8032(ha) || is_qla8042(ha))
   1684		drv_state |= (1 << ha->func_num);
   1685	else
   1686		drv_state |= (1 << (ha->func_num * 4));
   1687
   1688	ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n",
   1689		   __func__, ha->host_no, drv_state);
   1690	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, drv_state);
   1691}
   1692
   1693void qla4_8xxx_clear_rst_ready(struct scsi_qla_host *ha)
   1694{
   1695	uint32_t drv_state;
   1696
   1697	drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
   1698
   1699	/*
   1700	 * For ISP8324 and ISP8042, drv_active register has 1 bit per function,
   1701	 * shift 1 by func_num to set a bit for the function.
   1702	 * For ISP8022, drv_active has 4 bits per function
   1703	 */
   1704	if (is_qla8032(ha) || is_qla8042(ha))
   1705		drv_state &= ~(1 << ha->func_num);
   1706	else
   1707		drv_state &= ~(1 << (ha->func_num * 4));
   1708
   1709	ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n",
   1710		   __func__, ha->host_no, drv_state);
   1711	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, drv_state);
   1712}
   1713
   1714static inline void
   1715qla4_8xxx_set_qsnt_ready(struct scsi_qla_host *ha)
   1716{
   1717	uint32_t qsnt_state;
   1718
   1719	qsnt_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
   1720
   1721	/*
   1722	 * For ISP8324 and ISP8042, drv_active register has 1 bit per function,
   1723	 * shift 1 by func_num to set a bit for the function.
   1724	 * For ISP8022, drv_active has 4 bits per function.
   1725	 */
   1726	if (is_qla8032(ha) || is_qla8042(ha))
   1727		qsnt_state |= (1 << ha->func_num);
   1728	else
   1729		qsnt_state |= (2 << (ha->func_num * 4));
   1730
   1731	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, qsnt_state);
   1732}
   1733
   1734
   1735static int
   1736qla4_82xx_start_firmware(struct scsi_qla_host *ha, uint32_t image_start)
   1737{
   1738	uint16_t lnk;
   1739
   1740	/* scrub dma mask expansion register */
   1741	qla4_82xx_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
   1742
   1743	/* Overwrite stale initialization register values */
   1744	qla4_82xx_wr_32(ha, CRB_CMDPEG_STATE, 0);
   1745	qla4_82xx_wr_32(ha, CRB_RCVPEG_STATE, 0);
   1746	qla4_82xx_wr_32(ha, QLA82XX_PEG_HALT_STATUS1, 0);
   1747	qla4_82xx_wr_32(ha, QLA82XX_PEG_HALT_STATUS2, 0);
   1748
   1749	if (qla4_82xx_load_fw(ha, image_start) != QLA_SUCCESS) {
   1750		printk("%s: Error trying to start fw!\n", __func__);
   1751		return QLA_ERROR;
   1752	}
   1753
   1754	/* Handshake with the card before we register the devices. */
   1755	if (qla4_82xx_cmdpeg_ready(ha, 0) != QLA_SUCCESS) {
   1756		printk("%s: Error during card handshake!\n", __func__);
   1757		return QLA_ERROR;
   1758	}
   1759
   1760	/* Negotiated Link width */
   1761	pcie_capability_read_word(ha->pdev, PCI_EXP_LNKSTA, &lnk);
   1762	ha->link_width = (lnk >> 4) & 0x3f;
   1763
   1764	/* Synchronize with Receive peg */
   1765	return qla4_82xx_rcvpeg_ready(ha);
   1766}
   1767
   1768int qla4_82xx_try_start_fw(struct scsi_qla_host *ha)
   1769{
   1770	int rval;
   1771
   1772	/*
   1773	 * FW Load priority:
   1774	 * 1) Operational firmware residing in flash.
   1775	 * 2) Fail
   1776	 */
   1777
   1778	ql4_printk(KERN_INFO, ha,
   1779	    "FW: Retrieving flash offsets from FLT/FDT ...\n");
   1780	rval = qla4_8xxx_get_flash_info(ha);
   1781	if (rval != QLA_SUCCESS)
   1782		return rval;
   1783
   1784	ql4_printk(KERN_INFO, ha,
   1785	    "FW: Attempting to load firmware from flash...\n");
   1786	rval = qla4_82xx_start_firmware(ha, ha->hw.flt_region_fw);
   1787
   1788	if (rval != QLA_SUCCESS) {
   1789		ql4_printk(KERN_ERR, ha, "FW: Load firmware from flash"
   1790		    " FAILED...\n");
   1791		return rval;
   1792	}
   1793
   1794	return rval;
   1795}
   1796
   1797void qla4_82xx_rom_lock_recovery(struct scsi_qla_host *ha)
   1798{
   1799	if (qla4_82xx_rom_lock(ha)) {
   1800		/* Someone else is holding the lock. */
   1801		dev_info(&ha->pdev->dev, "Resetting rom_lock\n");
   1802	}
   1803
   1804	/*
   1805	 * Either we got the lock, or someone
   1806	 * else died while holding it.
   1807	 * In either case, unlock.
   1808	 */
   1809	qla4_82xx_rom_unlock(ha);
   1810}
   1811
   1812static uint32_t ql4_84xx_poll_wait_for_ready(struct scsi_qla_host *ha,
   1813					     uint32_t addr1, uint32_t mask)
   1814{
   1815	unsigned long timeout;
   1816	uint32_t rval = QLA_SUCCESS;
   1817	uint32_t temp;
   1818
   1819	timeout = jiffies + msecs_to_jiffies(TIMEOUT_100_MS);
   1820	do {
   1821		ha->isp_ops->rd_reg_indirect(ha, addr1, &temp);
   1822		if ((temp & mask) != 0)
   1823			break;
   1824
   1825		if (time_after_eq(jiffies, timeout)) {
   1826			ql4_printk(KERN_INFO, ha, "Error in processing rdmdio entry\n");
   1827			return QLA_ERROR;
   1828		}
   1829	} while (1);
   1830
   1831	return rval;
   1832}
   1833
   1834static uint32_t ql4_84xx_ipmdio_rd_reg(struct scsi_qla_host *ha, uint32_t addr1,
   1835				uint32_t addr3, uint32_t mask, uint32_t addr,
   1836				uint32_t *data_ptr)
   1837{
   1838	int rval = QLA_SUCCESS;
   1839	uint32_t temp;
   1840	uint32_t data;
   1841
   1842	rval = ql4_84xx_poll_wait_for_ready(ha, addr1, mask);
   1843	if (rval)
   1844		goto exit_ipmdio_rd_reg;
   1845
   1846	temp = (0x40000000 | addr);
   1847	ha->isp_ops->wr_reg_indirect(ha, addr1, temp);
   1848
   1849	rval = ql4_84xx_poll_wait_for_ready(ha, addr1, mask);
   1850	if (rval)
   1851		goto exit_ipmdio_rd_reg;
   1852
   1853	ha->isp_ops->rd_reg_indirect(ha, addr3, &data);
   1854	*data_ptr = data;
   1855
   1856exit_ipmdio_rd_reg:
   1857	return rval;
   1858}
   1859
   1860
   1861static uint32_t ql4_84xx_poll_wait_ipmdio_bus_idle(struct scsi_qla_host *ha,
   1862						    uint32_t addr1,
   1863						    uint32_t addr2,
   1864						    uint32_t addr3,
   1865						    uint32_t mask)
   1866{
   1867	unsigned long timeout;
   1868	uint32_t temp;
   1869	uint32_t rval = QLA_SUCCESS;
   1870
   1871	timeout = jiffies + msecs_to_jiffies(TIMEOUT_100_MS);
   1872	do {
   1873		ql4_84xx_ipmdio_rd_reg(ha, addr1, addr3, mask, addr2, &temp);
   1874		if ((temp & 0x1) != 1)
   1875			break;
   1876		if (time_after_eq(jiffies, timeout)) {
   1877			ql4_printk(KERN_INFO, ha, "Error in processing mdiobus idle\n");
   1878			return QLA_ERROR;
   1879		}
   1880	} while (1);
   1881
   1882	return rval;
   1883}
   1884
   1885static int ql4_84xx_ipmdio_wr_reg(struct scsi_qla_host *ha,
   1886				  uint32_t addr1, uint32_t addr3,
   1887				  uint32_t mask, uint32_t addr,
   1888				  uint32_t value)
   1889{
   1890	int rval = QLA_SUCCESS;
   1891
   1892	rval = ql4_84xx_poll_wait_for_ready(ha, addr1, mask);
   1893	if (rval)
   1894		goto exit_ipmdio_wr_reg;
   1895
   1896	ha->isp_ops->wr_reg_indirect(ha, addr3, value);
   1897	ha->isp_ops->wr_reg_indirect(ha, addr1, addr);
   1898
   1899	rval = ql4_84xx_poll_wait_for_ready(ha, addr1, mask);
   1900	if (rval)
   1901		goto exit_ipmdio_wr_reg;
   1902
   1903exit_ipmdio_wr_reg:
   1904	return rval;
   1905}
   1906
   1907static void qla4_8xxx_minidump_process_rdcrb(struct scsi_qla_host *ha,
   1908				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   1909				uint32_t **d_ptr)
   1910{
   1911	uint32_t r_addr, r_stride, loop_cnt, i, r_value;
   1912	struct qla8xxx_minidump_entry_crb *crb_hdr;
   1913	uint32_t *data_ptr = *d_ptr;
   1914
   1915	DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
   1916	crb_hdr = (struct qla8xxx_minidump_entry_crb *)entry_hdr;
   1917	r_addr = crb_hdr->addr;
   1918	r_stride = crb_hdr->crb_strd.addr_stride;
   1919	loop_cnt = crb_hdr->op_count;
   1920
   1921	for (i = 0; i < loop_cnt; i++) {
   1922		ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
   1923		*data_ptr++ = cpu_to_le32(r_addr);
   1924		*data_ptr++ = cpu_to_le32(r_value);
   1925		r_addr += r_stride;
   1926	}
   1927	*d_ptr = data_ptr;
   1928}
   1929
   1930static int qla4_83xx_check_dma_engine_state(struct scsi_qla_host *ha)
   1931{
   1932	int rval = QLA_SUCCESS;
   1933	uint32_t dma_eng_num = 0, cmd_sts_and_cntrl = 0;
   1934	uint64_t dma_base_addr = 0;
   1935	struct qla4_8xxx_minidump_template_hdr *tmplt_hdr = NULL;
   1936
   1937	tmplt_hdr = (struct qla4_8xxx_minidump_template_hdr *)
   1938							ha->fw_dump_tmplt_hdr;
   1939	dma_eng_num =
   1940		tmplt_hdr->saved_state_array[QLA83XX_PEX_DMA_ENGINE_INDEX];
   1941	dma_base_addr = QLA83XX_PEX_DMA_BASE_ADDRESS +
   1942				(dma_eng_num * QLA83XX_PEX_DMA_NUM_OFFSET);
   1943
   1944	/* Read the pex-dma's command-status-and-control register. */
   1945	rval = ha->isp_ops->rd_reg_indirect(ha,
   1946			(dma_base_addr + QLA83XX_PEX_DMA_CMD_STS_AND_CNTRL),
   1947			&cmd_sts_and_cntrl);
   1948
   1949	if (rval)
   1950		return QLA_ERROR;
   1951
   1952	/* Check if requested pex-dma engine is available. */
   1953	if (cmd_sts_and_cntrl & BIT_31)
   1954		return QLA_SUCCESS;
   1955	else
   1956		return QLA_ERROR;
   1957}
   1958
   1959static int qla4_83xx_start_pex_dma(struct scsi_qla_host *ha,
   1960			   struct qla4_83xx_minidump_entry_rdmem_pex_dma *m_hdr)
   1961{
   1962	int rval = QLA_SUCCESS, wait = 0;
   1963	uint32_t dma_eng_num = 0, cmd_sts_and_cntrl = 0;
   1964	uint64_t dma_base_addr = 0;
   1965	struct qla4_8xxx_minidump_template_hdr *tmplt_hdr = NULL;
   1966
   1967	tmplt_hdr = (struct qla4_8xxx_minidump_template_hdr *)
   1968							ha->fw_dump_tmplt_hdr;
   1969	dma_eng_num =
   1970		tmplt_hdr->saved_state_array[QLA83XX_PEX_DMA_ENGINE_INDEX];
   1971	dma_base_addr = QLA83XX_PEX_DMA_BASE_ADDRESS +
   1972				(dma_eng_num * QLA83XX_PEX_DMA_NUM_OFFSET);
   1973
   1974	rval = ha->isp_ops->wr_reg_indirect(ha,
   1975				dma_base_addr + QLA83XX_PEX_DMA_CMD_ADDR_LOW,
   1976				m_hdr->desc_card_addr);
   1977	if (rval)
   1978		goto error_exit;
   1979
   1980	rval = ha->isp_ops->wr_reg_indirect(ha,
   1981			      dma_base_addr + QLA83XX_PEX_DMA_CMD_ADDR_HIGH, 0);
   1982	if (rval)
   1983		goto error_exit;
   1984
   1985	rval = ha->isp_ops->wr_reg_indirect(ha,
   1986			      dma_base_addr + QLA83XX_PEX_DMA_CMD_STS_AND_CNTRL,
   1987			      m_hdr->start_dma_cmd);
   1988	if (rval)
   1989		goto error_exit;
   1990
   1991	/* Wait for dma operation to complete. */
   1992	for (wait = 0; wait < QLA83XX_PEX_DMA_MAX_WAIT; wait++) {
   1993		rval = ha->isp_ops->rd_reg_indirect(ha,
   1994			    (dma_base_addr + QLA83XX_PEX_DMA_CMD_STS_AND_CNTRL),
   1995			    &cmd_sts_and_cntrl);
   1996		if (rval)
   1997			goto error_exit;
   1998
   1999		if ((cmd_sts_and_cntrl & BIT_1) == 0)
   2000			break;
   2001		else
   2002			udelay(10);
   2003	}
   2004
   2005	/* Wait a max of 100 ms, otherwise fallback to rdmem entry read */
   2006	if (wait >= QLA83XX_PEX_DMA_MAX_WAIT) {
   2007		rval = QLA_ERROR;
   2008		goto error_exit;
   2009	}
   2010
   2011error_exit:
   2012	return rval;
   2013}
   2014
   2015static int qla4_8xxx_minidump_pex_dma_read(struct scsi_qla_host *ha,
   2016				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2017				uint32_t **d_ptr)
   2018{
   2019	int rval = QLA_SUCCESS;
   2020	struct qla4_83xx_minidump_entry_rdmem_pex_dma *m_hdr = NULL;
   2021	uint32_t size, read_size;
   2022	uint8_t *data_ptr = (uint8_t *)*d_ptr;
   2023	void *rdmem_buffer = NULL;
   2024	dma_addr_t rdmem_dma;
   2025	struct qla4_83xx_pex_dma_descriptor dma_desc;
   2026
   2027	DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
   2028
   2029	rval = qla4_83xx_check_dma_engine_state(ha);
   2030	if (rval != QLA_SUCCESS) {
   2031		DEBUG2(ql4_printk(KERN_INFO, ha,
   2032				  "%s: DMA engine not available. Fallback to rdmem-read.\n",
   2033				  __func__));
   2034		return QLA_ERROR;
   2035	}
   2036
   2037	m_hdr = (struct qla4_83xx_minidump_entry_rdmem_pex_dma *)entry_hdr;
   2038	rdmem_buffer = dma_alloc_coherent(&ha->pdev->dev,
   2039					  QLA83XX_PEX_DMA_READ_SIZE,
   2040					  &rdmem_dma, GFP_KERNEL);
   2041	if (!rdmem_buffer) {
   2042		DEBUG2(ql4_printk(KERN_INFO, ha,
   2043				  "%s: Unable to allocate rdmem dma buffer\n",
   2044				  __func__));
   2045		return QLA_ERROR;
   2046	}
   2047
   2048	/* Prepare pex-dma descriptor to be written to MS memory. */
   2049	/* dma-desc-cmd layout:
   2050	 *              0-3: dma-desc-cmd 0-3
   2051	 *              4-7: pcid function number
   2052	 *              8-15: dma-desc-cmd 8-15
   2053	 */
   2054	dma_desc.cmd.dma_desc_cmd = (m_hdr->dma_desc_cmd & 0xff0f);
   2055	dma_desc.cmd.dma_desc_cmd |= ((PCI_FUNC(ha->pdev->devfn) & 0xf) << 0x4);
   2056	dma_desc.dma_bus_addr = rdmem_dma;
   2057
   2058	size = 0;
   2059	read_size = 0;
   2060	/*
   2061	 * Perform rdmem operation using pex-dma.
   2062	 * Prepare dma in chunks of QLA83XX_PEX_DMA_READ_SIZE.
   2063	 */
   2064	while (read_size < m_hdr->read_data_size) {
   2065		if (m_hdr->read_data_size - read_size >=
   2066		    QLA83XX_PEX_DMA_READ_SIZE)
   2067			size = QLA83XX_PEX_DMA_READ_SIZE;
   2068		else {
   2069			size = (m_hdr->read_data_size - read_size);
   2070
   2071			if (rdmem_buffer)
   2072				dma_free_coherent(&ha->pdev->dev,
   2073						  QLA83XX_PEX_DMA_READ_SIZE,
   2074						  rdmem_buffer, rdmem_dma);
   2075
   2076			rdmem_buffer = dma_alloc_coherent(&ha->pdev->dev, size,
   2077							  &rdmem_dma,
   2078							  GFP_KERNEL);
   2079			if (!rdmem_buffer) {
   2080				DEBUG2(ql4_printk(KERN_INFO, ha,
   2081						  "%s: Unable to allocate rdmem dma buffer\n",
   2082						  __func__));
   2083				return QLA_ERROR;
   2084			}
   2085			dma_desc.dma_bus_addr = rdmem_dma;
   2086		}
   2087
   2088		dma_desc.src_addr = m_hdr->read_addr + read_size;
   2089		dma_desc.cmd.read_data_size = size;
   2090
   2091		/* Prepare: Write pex-dma descriptor to MS memory. */
   2092		rval = qla4_8xxx_ms_mem_write_128b(ha,
   2093			      (uint64_t)m_hdr->desc_card_addr,
   2094			      (uint32_t *)&dma_desc,
   2095			      (sizeof(struct qla4_83xx_pex_dma_descriptor)/16));
   2096		if (rval != QLA_SUCCESS) {
   2097			ql4_printk(KERN_INFO, ha,
   2098				   "%s: Error writing rdmem-dma-init to MS !!!\n",
   2099				   __func__);
   2100			goto error_exit;
   2101		}
   2102
   2103		DEBUG2(ql4_printk(KERN_INFO, ha,
   2104				  "%s: Dma-desc: Instruct for rdmem dma (size 0x%x).\n",
   2105				  __func__, size));
   2106		/* Execute: Start pex-dma operation. */
   2107		rval = qla4_83xx_start_pex_dma(ha, m_hdr);
   2108		if (rval != QLA_SUCCESS) {
   2109			DEBUG2(ql4_printk(KERN_INFO, ha,
   2110					  "scsi(%ld): start-pex-dma failed rval=0x%x\n",
   2111					  ha->host_no, rval));
   2112			goto error_exit;
   2113		}
   2114
   2115		memcpy(data_ptr, rdmem_buffer, size);
   2116		data_ptr += size;
   2117		read_size += size;
   2118	}
   2119
   2120	DEBUG2(ql4_printk(KERN_INFO, ha, "Leaving fn: %s\n", __func__));
   2121
   2122	*d_ptr = (uint32_t *)data_ptr;
   2123
   2124error_exit:
   2125	if (rdmem_buffer)
   2126		dma_free_coherent(&ha->pdev->dev, size, rdmem_buffer,
   2127				  rdmem_dma);
   2128
   2129	return rval;
   2130}
   2131
   2132static int qla4_8xxx_minidump_process_l2tag(struct scsi_qla_host *ha,
   2133				 struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2134				 uint32_t **d_ptr)
   2135{
   2136	uint32_t addr, r_addr, c_addr, t_r_addr;
   2137	uint32_t i, k, loop_count, t_value, r_cnt, r_value;
   2138	unsigned long p_wait, w_time, p_mask;
   2139	uint32_t c_value_w, c_value_r;
   2140	struct qla8xxx_minidump_entry_cache *cache_hdr;
   2141	int rval = QLA_ERROR;
   2142	uint32_t *data_ptr = *d_ptr;
   2143
   2144	DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
   2145	cache_hdr = (struct qla8xxx_minidump_entry_cache *)entry_hdr;
   2146
   2147	loop_count = cache_hdr->op_count;
   2148	r_addr = cache_hdr->read_addr;
   2149	c_addr = cache_hdr->control_addr;
   2150	c_value_w = cache_hdr->cache_ctrl.write_value;
   2151
   2152	t_r_addr = cache_hdr->tag_reg_addr;
   2153	t_value = cache_hdr->addr_ctrl.init_tag_value;
   2154	r_cnt = cache_hdr->read_ctrl.read_addr_cnt;
   2155	p_wait = cache_hdr->cache_ctrl.poll_wait;
   2156	p_mask = cache_hdr->cache_ctrl.poll_mask;
   2157
   2158	for (i = 0; i < loop_count; i++) {
   2159		ha->isp_ops->wr_reg_indirect(ha, t_r_addr, t_value);
   2160
   2161		if (c_value_w)
   2162			ha->isp_ops->wr_reg_indirect(ha, c_addr, c_value_w);
   2163
   2164		if (p_mask) {
   2165			w_time = jiffies + p_wait;
   2166			do {
   2167				ha->isp_ops->rd_reg_indirect(ha, c_addr,
   2168							     &c_value_r);
   2169				if ((c_value_r & p_mask) == 0) {
   2170					break;
   2171				} else if (time_after_eq(jiffies, w_time)) {
   2172					/* capturing dump failed */
   2173					return rval;
   2174				}
   2175			} while (1);
   2176		}
   2177
   2178		addr = r_addr;
   2179		for (k = 0; k < r_cnt; k++) {
   2180			ha->isp_ops->rd_reg_indirect(ha, addr, &r_value);
   2181			*data_ptr++ = cpu_to_le32(r_value);
   2182			addr += cache_hdr->read_ctrl.read_addr_stride;
   2183		}
   2184
   2185		t_value += cache_hdr->addr_ctrl.tag_value_stride;
   2186	}
   2187	*d_ptr = data_ptr;
   2188	return QLA_SUCCESS;
   2189}
   2190
   2191static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha,
   2192				struct qla8xxx_minidump_entry_hdr *entry_hdr)
   2193{
   2194	struct qla8xxx_minidump_entry_crb *crb_entry;
   2195	uint32_t read_value, opcode, poll_time, addr, index, rval = QLA_SUCCESS;
   2196	uint32_t crb_addr;
   2197	unsigned long wtime;
   2198	struct qla4_8xxx_minidump_template_hdr *tmplt_hdr;
   2199	int i;
   2200
   2201	DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
   2202	tmplt_hdr = (struct qla4_8xxx_minidump_template_hdr *)
   2203						ha->fw_dump_tmplt_hdr;
   2204	crb_entry = (struct qla8xxx_minidump_entry_crb *)entry_hdr;
   2205
   2206	crb_addr = crb_entry->addr;
   2207	for (i = 0; i < crb_entry->op_count; i++) {
   2208		opcode = crb_entry->crb_ctrl.opcode;
   2209		if (opcode & QLA8XXX_DBG_OPCODE_WR) {
   2210			ha->isp_ops->wr_reg_indirect(ha, crb_addr,
   2211						     crb_entry->value_1);
   2212			opcode &= ~QLA8XXX_DBG_OPCODE_WR;
   2213		}
   2214		if (opcode & QLA8XXX_DBG_OPCODE_RW) {
   2215			ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
   2216			ha->isp_ops->wr_reg_indirect(ha, crb_addr, read_value);
   2217			opcode &= ~QLA8XXX_DBG_OPCODE_RW;
   2218		}
   2219		if (opcode & QLA8XXX_DBG_OPCODE_AND) {
   2220			ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
   2221			read_value &= crb_entry->value_2;
   2222			opcode &= ~QLA8XXX_DBG_OPCODE_AND;
   2223			if (opcode & QLA8XXX_DBG_OPCODE_OR) {
   2224				read_value |= crb_entry->value_3;
   2225				opcode &= ~QLA8XXX_DBG_OPCODE_OR;
   2226			}
   2227			ha->isp_ops->wr_reg_indirect(ha, crb_addr, read_value);
   2228		}
   2229		if (opcode & QLA8XXX_DBG_OPCODE_OR) {
   2230			ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
   2231			read_value |= crb_entry->value_3;
   2232			ha->isp_ops->wr_reg_indirect(ha, crb_addr, read_value);
   2233			opcode &= ~QLA8XXX_DBG_OPCODE_OR;
   2234		}
   2235		if (opcode & QLA8XXX_DBG_OPCODE_POLL) {
   2236			poll_time = crb_entry->crb_strd.poll_timeout;
   2237			wtime = jiffies + poll_time;
   2238			ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
   2239
   2240			do {
   2241				if ((read_value & crb_entry->value_2) ==
   2242				    crb_entry->value_1) {
   2243					break;
   2244				} else if (time_after_eq(jiffies, wtime)) {
   2245					/* capturing dump failed */
   2246					rval = QLA_ERROR;
   2247					break;
   2248				} else {
   2249					ha->isp_ops->rd_reg_indirect(ha,
   2250							crb_addr, &read_value);
   2251				}
   2252			} while (1);
   2253			opcode &= ~QLA8XXX_DBG_OPCODE_POLL;
   2254		}
   2255
   2256		if (opcode & QLA8XXX_DBG_OPCODE_RDSTATE) {
   2257			if (crb_entry->crb_strd.state_index_a) {
   2258				index = crb_entry->crb_strd.state_index_a;
   2259				addr = tmplt_hdr->saved_state_array[index];
   2260			} else {
   2261				addr = crb_addr;
   2262			}
   2263
   2264			ha->isp_ops->rd_reg_indirect(ha, addr, &read_value);
   2265			index = crb_entry->crb_ctrl.state_index_v;
   2266			tmplt_hdr->saved_state_array[index] = read_value;
   2267			opcode &= ~QLA8XXX_DBG_OPCODE_RDSTATE;
   2268		}
   2269
   2270		if (opcode & QLA8XXX_DBG_OPCODE_WRSTATE) {
   2271			if (crb_entry->crb_strd.state_index_a) {
   2272				index = crb_entry->crb_strd.state_index_a;
   2273				addr = tmplt_hdr->saved_state_array[index];
   2274			} else {
   2275				addr = crb_addr;
   2276			}
   2277
   2278			if (crb_entry->crb_ctrl.state_index_v) {
   2279				index = crb_entry->crb_ctrl.state_index_v;
   2280				read_value =
   2281					tmplt_hdr->saved_state_array[index];
   2282			} else {
   2283				read_value = crb_entry->value_1;
   2284			}
   2285
   2286			ha->isp_ops->wr_reg_indirect(ha, addr, read_value);
   2287			opcode &= ~QLA8XXX_DBG_OPCODE_WRSTATE;
   2288		}
   2289
   2290		if (opcode & QLA8XXX_DBG_OPCODE_MDSTATE) {
   2291			index = crb_entry->crb_ctrl.state_index_v;
   2292			read_value = tmplt_hdr->saved_state_array[index];
   2293			read_value <<= crb_entry->crb_ctrl.shl;
   2294			read_value >>= crb_entry->crb_ctrl.shr;
   2295			if (crb_entry->value_2)
   2296				read_value &= crb_entry->value_2;
   2297			read_value |= crb_entry->value_3;
   2298			read_value += crb_entry->value_1;
   2299			tmplt_hdr->saved_state_array[index] = read_value;
   2300			opcode &= ~QLA8XXX_DBG_OPCODE_MDSTATE;
   2301		}
   2302		crb_addr += crb_entry->crb_strd.addr_stride;
   2303	}
   2304	DEBUG2(ql4_printk(KERN_INFO, ha, "Leaving fn: %s\n", __func__));
   2305	return rval;
   2306}
   2307
   2308static void qla4_8xxx_minidump_process_rdocm(struct scsi_qla_host *ha,
   2309				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2310				uint32_t **d_ptr)
   2311{
   2312	uint32_t r_addr, r_stride, loop_cnt, i, r_value;
   2313	struct qla8xxx_minidump_entry_rdocm *ocm_hdr;
   2314	uint32_t *data_ptr = *d_ptr;
   2315
   2316	DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
   2317	ocm_hdr = (struct qla8xxx_minidump_entry_rdocm *)entry_hdr;
   2318	r_addr = ocm_hdr->read_addr;
   2319	r_stride = ocm_hdr->read_addr_stride;
   2320	loop_cnt = ocm_hdr->op_count;
   2321
   2322	DEBUG2(ql4_printk(KERN_INFO, ha,
   2323			  "[%s]: r_addr: 0x%x, r_stride: 0x%x, loop_cnt: 0x%x\n",
   2324			  __func__, r_addr, r_stride, loop_cnt));
   2325
   2326	for (i = 0; i < loop_cnt; i++) {
   2327		r_value = readl((void __iomem *)(r_addr + ha->nx_pcibase));
   2328		*data_ptr++ = cpu_to_le32(r_value);
   2329		r_addr += r_stride;
   2330	}
   2331	DEBUG2(ql4_printk(KERN_INFO, ha, "Leaving fn: %s datacount: 0x%lx\n",
   2332		__func__, (long unsigned int) (loop_cnt * sizeof(uint32_t))));
   2333	*d_ptr = data_ptr;
   2334}
   2335
   2336static void qla4_8xxx_minidump_process_rdmux(struct scsi_qla_host *ha,
   2337				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2338				uint32_t **d_ptr)
   2339{
   2340	uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value;
   2341	struct qla8xxx_minidump_entry_mux *mux_hdr;
   2342	uint32_t *data_ptr = *d_ptr;
   2343
   2344	DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
   2345	mux_hdr = (struct qla8xxx_minidump_entry_mux *)entry_hdr;
   2346	r_addr = mux_hdr->read_addr;
   2347	s_addr = mux_hdr->select_addr;
   2348	s_stride = mux_hdr->select_value_stride;
   2349	s_value = mux_hdr->select_value;
   2350	loop_cnt = mux_hdr->op_count;
   2351
   2352	for (i = 0; i < loop_cnt; i++) {
   2353		ha->isp_ops->wr_reg_indirect(ha, s_addr, s_value);
   2354		ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
   2355		*data_ptr++ = cpu_to_le32(s_value);
   2356		*data_ptr++ = cpu_to_le32(r_value);
   2357		s_value += s_stride;
   2358	}
   2359	*d_ptr = data_ptr;
   2360}
   2361
   2362static void qla4_8xxx_minidump_process_l1cache(struct scsi_qla_host *ha,
   2363				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2364				uint32_t **d_ptr)
   2365{
   2366	uint32_t addr, r_addr, c_addr, t_r_addr;
   2367	uint32_t i, k, loop_count, t_value, r_cnt, r_value;
   2368	uint32_t c_value_w;
   2369	struct qla8xxx_minidump_entry_cache *cache_hdr;
   2370	uint32_t *data_ptr = *d_ptr;
   2371
   2372	cache_hdr = (struct qla8xxx_minidump_entry_cache *)entry_hdr;
   2373	loop_count = cache_hdr->op_count;
   2374	r_addr = cache_hdr->read_addr;
   2375	c_addr = cache_hdr->control_addr;
   2376	c_value_w = cache_hdr->cache_ctrl.write_value;
   2377
   2378	t_r_addr = cache_hdr->tag_reg_addr;
   2379	t_value = cache_hdr->addr_ctrl.init_tag_value;
   2380	r_cnt = cache_hdr->read_ctrl.read_addr_cnt;
   2381
   2382	for (i = 0; i < loop_count; i++) {
   2383		ha->isp_ops->wr_reg_indirect(ha, t_r_addr, t_value);
   2384		ha->isp_ops->wr_reg_indirect(ha, c_addr, c_value_w);
   2385		addr = r_addr;
   2386		for (k = 0; k < r_cnt; k++) {
   2387			ha->isp_ops->rd_reg_indirect(ha, addr, &r_value);
   2388			*data_ptr++ = cpu_to_le32(r_value);
   2389			addr += cache_hdr->read_ctrl.read_addr_stride;
   2390		}
   2391		t_value += cache_hdr->addr_ctrl.tag_value_stride;
   2392	}
   2393	*d_ptr = data_ptr;
   2394}
   2395
   2396static void qla4_8xxx_minidump_process_queue(struct scsi_qla_host *ha,
   2397				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2398				uint32_t **d_ptr)
   2399{
   2400	uint32_t s_addr, r_addr;
   2401	uint32_t r_stride, r_value, r_cnt, qid = 0;
   2402	uint32_t i, k, loop_cnt;
   2403	struct qla8xxx_minidump_entry_queue *q_hdr;
   2404	uint32_t *data_ptr = *d_ptr;
   2405
   2406	DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
   2407	q_hdr = (struct qla8xxx_minidump_entry_queue *)entry_hdr;
   2408	s_addr = q_hdr->select_addr;
   2409	r_cnt = q_hdr->rd_strd.read_addr_cnt;
   2410	r_stride = q_hdr->rd_strd.read_addr_stride;
   2411	loop_cnt = q_hdr->op_count;
   2412
   2413	for (i = 0; i < loop_cnt; i++) {
   2414		ha->isp_ops->wr_reg_indirect(ha, s_addr, qid);
   2415		r_addr = q_hdr->read_addr;
   2416		for (k = 0; k < r_cnt; k++) {
   2417			ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
   2418			*data_ptr++ = cpu_to_le32(r_value);
   2419			r_addr += r_stride;
   2420		}
   2421		qid += q_hdr->q_strd.queue_id_stride;
   2422	}
   2423	*d_ptr = data_ptr;
   2424}
   2425
   2426#define MD_DIRECT_ROM_WINDOW		0x42110030
   2427#define MD_DIRECT_ROM_READ_BASE		0x42150000
   2428
   2429static void qla4_82xx_minidump_process_rdrom(struct scsi_qla_host *ha,
   2430				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2431				uint32_t **d_ptr)
   2432{
   2433	uint32_t r_addr, r_value;
   2434	uint32_t i, loop_cnt;
   2435	struct qla8xxx_minidump_entry_rdrom *rom_hdr;
   2436	uint32_t *data_ptr = *d_ptr;
   2437
   2438	DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
   2439	rom_hdr = (struct qla8xxx_minidump_entry_rdrom *)entry_hdr;
   2440	r_addr = rom_hdr->read_addr;
   2441	loop_cnt = rom_hdr->read_data_size/sizeof(uint32_t);
   2442
   2443	DEBUG2(ql4_printk(KERN_INFO, ha,
   2444			  "[%s]: flash_addr: 0x%x, read_data_size: 0x%x\n",
   2445			   __func__, r_addr, loop_cnt));
   2446
   2447	for (i = 0; i < loop_cnt; i++) {
   2448		ha->isp_ops->wr_reg_indirect(ha, MD_DIRECT_ROM_WINDOW,
   2449					     (r_addr & 0xFFFF0000));
   2450		ha->isp_ops->rd_reg_indirect(ha,
   2451				MD_DIRECT_ROM_READ_BASE + (r_addr & 0x0000FFFF),
   2452				&r_value);
   2453		*data_ptr++ = cpu_to_le32(r_value);
   2454		r_addr += sizeof(uint32_t);
   2455	}
   2456	*d_ptr = data_ptr;
   2457}
   2458
   2459#define MD_MIU_TEST_AGT_CTRL		0x41000090
   2460#define MD_MIU_TEST_AGT_ADDR_LO		0x41000094
   2461#define MD_MIU_TEST_AGT_ADDR_HI		0x41000098
   2462
   2463static int __qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha,
   2464				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2465				uint32_t **d_ptr)
   2466{
   2467	uint32_t r_addr, r_value, r_data;
   2468	uint32_t i, j, loop_cnt;
   2469	struct qla8xxx_minidump_entry_rdmem *m_hdr;
   2470	unsigned long flags;
   2471	uint32_t *data_ptr = *d_ptr;
   2472
   2473	DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__));
   2474	m_hdr = (struct qla8xxx_minidump_entry_rdmem *)entry_hdr;
   2475	r_addr = m_hdr->read_addr;
   2476	loop_cnt = m_hdr->read_data_size/16;
   2477
   2478	DEBUG2(ql4_printk(KERN_INFO, ha,
   2479			  "[%s]: Read addr: 0x%x, read_data_size: 0x%x\n",
   2480			  __func__, r_addr, m_hdr->read_data_size));
   2481
   2482	if (r_addr & 0xf) {
   2483		DEBUG2(ql4_printk(KERN_INFO, ha,
   2484				  "[%s]: Read addr 0x%x not 16 bytes aligned\n",
   2485				  __func__, r_addr));
   2486		return QLA_ERROR;
   2487	}
   2488
   2489	if (m_hdr->read_data_size % 16) {
   2490		DEBUG2(ql4_printk(KERN_INFO, ha,
   2491				  "[%s]: Read data[0x%x] not multiple of 16 bytes\n",
   2492				  __func__, m_hdr->read_data_size));
   2493		return QLA_ERROR;
   2494	}
   2495
   2496	DEBUG2(ql4_printk(KERN_INFO, ha,
   2497			  "[%s]: rdmem_addr: 0x%x, read_data_size: 0x%x, loop_cnt: 0x%x\n",
   2498			  __func__, r_addr, m_hdr->read_data_size, loop_cnt));
   2499
   2500	write_lock_irqsave(&ha->hw_lock, flags);
   2501	for (i = 0; i < loop_cnt; i++) {
   2502		ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_LO,
   2503					     r_addr);
   2504		r_value = 0;
   2505		ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_HI,
   2506					     r_value);
   2507		r_value = MIU_TA_CTL_ENABLE;
   2508		ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL, r_value);
   2509		r_value = MIU_TA_CTL_START_ENABLE;
   2510		ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL, r_value);
   2511
   2512		for (j = 0; j < MAX_CTL_CHECK; j++) {
   2513			ha->isp_ops->rd_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL,
   2514						     &r_value);
   2515			if ((r_value & MIU_TA_CTL_BUSY) == 0)
   2516				break;
   2517		}
   2518
   2519		if (j >= MAX_CTL_CHECK) {
   2520			printk_ratelimited(KERN_ERR
   2521					   "%s: failed to read through agent\n",
   2522					    __func__);
   2523			write_unlock_irqrestore(&ha->hw_lock, flags);
   2524			return QLA_SUCCESS;
   2525		}
   2526
   2527		for (j = 0; j < 4; j++) {
   2528			ha->isp_ops->rd_reg_indirect(ha,
   2529						     MD_MIU_TEST_AGT_RDDATA[j],
   2530						     &r_data);
   2531			*data_ptr++ = cpu_to_le32(r_data);
   2532		}
   2533
   2534		r_addr += 16;
   2535	}
   2536	write_unlock_irqrestore(&ha->hw_lock, flags);
   2537
   2538	DEBUG2(ql4_printk(KERN_INFO, ha, "Leaving fn: %s datacount: 0x%x\n",
   2539			  __func__, (loop_cnt * 16)));
   2540
   2541	*d_ptr = data_ptr;
   2542	return QLA_SUCCESS;
   2543}
   2544
   2545static int qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha,
   2546				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2547				uint32_t **d_ptr)
   2548{
   2549	uint32_t *data_ptr = *d_ptr;
   2550	int rval = QLA_SUCCESS;
   2551
   2552	rval = qla4_8xxx_minidump_pex_dma_read(ha, entry_hdr, &data_ptr);
   2553	if (rval != QLA_SUCCESS)
   2554		rval = __qla4_8xxx_minidump_process_rdmem(ha, entry_hdr,
   2555							  &data_ptr);
   2556	*d_ptr = data_ptr;
   2557	return rval;
   2558}
   2559
   2560static void qla4_8xxx_mark_entry_skipped(struct scsi_qla_host *ha,
   2561				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2562				int index)
   2563{
   2564	entry_hdr->d_ctrl.driver_flags |= QLA8XXX_DBG_SKIPPED_FLAG;
   2565	DEBUG2(ql4_printk(KERN_INFO, ha,
   2566			  "scsi(%ld): Skipping entry[%d]: ETYPE[0x%x]-ELEVEL[0x%x]\n",
   2567			  ha->host_no, index, entry_hdr->entry_type,
   2568			  entry_hdr->d_ctrl.entry_capture_mask));
   2569	/* If driver encounters a new entry type that it cannot process,
   2570	 * it should just skip the entry and adjust the total buffer size by
   2571	 * from subtracting the skipped bytes from it
   2572	 */
   2573	ha->fw_dump_skip_size += entry_hdr->entry_capture_size;
   2574}
   2575
   2576/* ISP83xx functions to process new minidump entries... */
   2577static uint32_t qla83xx_minidump_process_pollrd(struct scsi_qla_host *ha,
   2578				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2579				uint32_t **d_ptr)
   2580{
   2581	uint32_t r_addr, s_addr, s_value, r_value, poll_wait, poll_mask;
   2582	uint16_t s_stride, i;
   2583	uint32_t *data_ptr = *d_ptr;
   2584	uint32_t rval = QLA_SUCCESS;
   2585	struct qla83xx_minidump_entry_pollrd *pollrd_hdr;
   2586
   2587	pollrd_hdr = (struct qla83xx_minidump_entry_pollrd *)entry_hdr;
   2588	s_addr = le32_to_cpu(pollrd_hdr->select_addr);
   2589	r_addr = le32_to_cpu(pollrd_hdr->read_addr);
   2590	s_value = le32_to_cpu(pollrd_hdr->select_value);
   2591	s_stride = le32_to_cpu(pollrd_hdr->select_value_stride);
   2592
   2593	poll_wait = le32_to_cpu(pollrd_hdr->poll_wait);
   2594	poll_mask = le32_to_cpu(pollrd_hdr->poll_mask);
   2595
   2596	for (i = 0; i < le32_to_cpu(pollrd_hdr->op_count); i++) {
   2597		ha->isp_ops->wr_reg_indirect(ha, s_addr, s_value);
   2598		poll_wait = le32_to_cpu(pollrd_hdr->poll_wait);
   2599		while (1) {
   2600			ha->isp_ops->rd_reg_indirect(ha, s_addr, &r_value);
   2601
   2602			if ((r_value & poll_mask) != 0) {
   2603				break;
   2604			} else {
   2605				msleep(1);
   2606				if (--poll_wait == 0) {
   2607					ql4_printk(KERN_ERR, ha, "%s: TIMEOUT\n",
   2608						   __func__);
   2609					rval = QLA_ERROR;
   2610					goto exit_process_pollrd;
   2611				}
   2612			}
   2613		}
   2614		ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
   2615		*data_ptr++ = cpu_to_le32(s_value);
   2616		*data_ptr++ = cpu_to_le32(r_value);
   2617		s_value += s_stride;
   2618	}
   2619
   2620	*d_ptr = data_ptr;
   2621
   2622exit_process_pollrd:
   2623	return rval;
   2624}
   2625
   2626static uint32_t qla4_84xx_minidump_process_rddfe(struct scsi_qla_host *ha,
   2627				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2628				uint32_t **d_ptr)
   2629{
   2630	int loop_cnt;
   2631	uint32_t addr1, addr2, value, data, temp, wrval;
   2632	uint8_t stride, stride2;
   2633	uint16_t count;
   2634	uint32_t poll, mask, modify_mask;
   2635	uint32_t wait_count = 0;
   2636	uint32_t *data_ptr = *d_ptr;
   2637	struct qla8044_minidump_entry_rddfe *rddfe;
   2638	uint32_t rval = QLA_SUCCESS;
   2639
   2640	rddfe = (struct qla8044_minidump_entry_rddfe *)entry_hdr;
   2641	addr1 = le32_to_cpu(rddfe->addr_1);
   2642	value = le32_to_cpu(rddfe->value);
   2643	stride = le32_to_cpu(rddfe->stride);
   2644	stride2 = le32_to_cpu(rddfe->stride2);
   2645	count = le32_to_cpu(rddfe->count);
   2646
   2647	poll = le32_to_cpu(rddfe->poll);
   2648	mask = le32_to_cpu(rddfe->mask);
   2649	modify_mask = le32_to_cpu(rddfe->modify_mask);
   2650
   2651	addr2 = addr1 + stride;
   2652
   2653	for (loop_cnt = 0x0; loop_cnt < count; loop_cnt++) {
   2654		ha->isp_ops->wr_reg_indirect(ha, addr1, (0x40000000 | value));
   2655
   2656		wait_count = 0;
   2657		while (wait_count < poll) {
   2658			ha->isp_ops->rd_reg_indirect(ha, addr1, &temp);
   2659			if ((temp & mask) != 0)
   2660				break;
   2661			wait_count++;
   2662		}
   2663
   2664		if (wait_count == poll) {
   2665			ql4_printk(KERN_ERR, ha, "%s: TIMEOUT\n", __func__);
   2666			rval = QLA_ERROR;
   2667			goto exit_process_rddfe;
   2668		} else {
   2669			ha->isp_ops->rd_reg_indirect(ha, addr2, &temp);
   2670			temp = temp & modify_mask;
   2671			temp = (temp | ((loop_cnt << 16) | loop_cnt));
   2672			wrval = ((temp << 16) | temp);
   2673
   2674			ha->isp_ops->wr_reg_indirect(ha, addr2, wrval);
   2675			ha->isp_ops->wr_reg_indirect(ha, addr1, value);
   2676
   2677			wait_count = 0;
   2678			while (wait_count < poll) {
   2679				ha->isp_ops->rd_reg_indirect(ha, addr1, &temp);
   2680				if ((temp & mask) != 0)
   2681					break;
   2682				wait_count++;
   2683			}
   2684			if (wait_count == poll) {
   2685				ql4_printk(KERN_ERR, ha, "%s: TIMEOUT\n",
   2686					   __func__);
   2687				rval = QLA_ERROR;
   2688				goto exit_process_rddfe;
   2689			}
   2690
   2691			ha->isp_ops->wr_reg_indirect(ha, addr1,
   2692						     ((0x40000000 | value) +
   2693						     stride2));
   2694			wait_count = 0;
   2695			while (wait_count < poll) {
   2696				ha->isp_ops->rd_reg_indirect(ha, addr1, &temp);
   2697				if ((temp & mask) != 0)
   2698					break;
   2699				wait_count++;
   2700			}
   2701
   2702			if (wait_count == poll) {
   2703				ql4_printk(KERN_ERR, ha, "%s: TIMEOUT\n",
   2704					   __func__);
   2705				rval = QLA_ERROR;
   2706				goto exit_process_rddfe;
   2707			}
   2708
   2709			ha->isp_ops->rd_reg_indirect(ha, addr2, &data);
   2710
   2711			*data_ptr++ = cpu_to_le32(wrval);
   2712			*data_ptr++ = cpu_to_le32(data);
   2713		}
   2714	}
   2715
   2716	*d_ptr = data_ptr;
   2717exit_process_rddfe:
   2718	return rval;
   2719}
   2720
   2721static uint32_t qla4_84xx_minidump_process_rdmdio(struct scsi_qla_host *ha,
   2722				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2723				uint32_t **d_ptr)
   2724{
   2725	int rval = QLA_SUCCESS;
   2726	uint32_t addr1, addr2, value1, value2, data, selval;
   2727	uint8_t stride1, stride2;
   2728	uint32_t addr3, addr4, addr5, addr6, addr7;
   2729	uint16_t count, loop_cnt;
   2730	uint32_t mask;
   2731	uint32_t *data_ptr = *d_ptr;
   2732	struct qla8044_minidump_entry_rdmdio *rdmdio;
   2733
   2734	rdmdio = (struct qla8044_minidump_entry_rdmdio *)entry_hdr;
   2735	addr1 = le32_to_cpu(rdmdio->addr_1);
   2736	addr2 = le32_to_cpu(rdmdio->addr_2);
   2737	value1 = le32_to_cpu(rdmdio->value_1);
   2738	stride1 = le32_to_cpu(rdmdio->stride_1);
   2739	stride2 = le32_to_cpu(rdmdio->stride_2);
   2740	count = le32_to_cpu(rdmdio->count);
   2741
   2742	mask = le32_to_cpu(rdmdio->mask);
   2743	value2 = le32_to_cpu(rdmdio->value_2);
   2744
   2745	addr3 = addr1 + stride1;
   2746
   2747	for (loop_cnt = 0; loop_cnt < count; loop_cnt++) {
   2748		rval = ql4_84xx_poll_wait_ipmdio_bus_idle(ha, addr1, addr2,
   2749							 addr3, mask);
   2750		if (rval)
   2751			goto exit_process_rdmdio;
   2752
   2753		addr4 = addr2 - stride1;
   2754		rval = ql4_84xx_ipmdio_wr_reg(ha, addr1, addr3, mask, addr4,
   2755					     value2);
   2756		if (rval)
   2757			goto exit_process_rdmdio;
   2758
   2759		addr5 = addr2 - (2 * stride1);
   2760		rval = ql4_84xx_ipmdio_wr_reg(ha, addr1, addr3, mask, addr5,
   2761					     value1);
   2762		if (rval)
   2763			goto exit_process_rdmdio;
   2764
   2765		addr6 = addr2 - (3 * stride1);
   2766		rval = ql4_84xx_ipmdio_wr_reg(ha, addr1, addr3, mask,
   2767					     addr6, 0x2);
   2768		if (rval)
   2769			goto exit_process_rdmdio;
   2770
   2771		rval = ql4_84xx_poll_wait_ipmdio_bus_idle(ha, addr1, addr2,
   2772							 addr3, mask);
   2773		if (rval)
   2774			goto exit_process_rdmdio;
   2775
   2776		addr7 = addr2 - (4 * stride1);
   2777		rval = ql4_84xx_ipmdio_rd_reg(ha, addr1, addr3,
   2778						      mask, addr7, &data);
   2779		if (rval)
   2780			goto exit_process_rdmdio;
   2781
   2782		selval = (value2 << 18) | (value1 << 2) | 2;
   2783
   2784		stride2 = le32_to_cpu(rdmdio->stride_2);
   2785		*data_ptr++ = cpu_to_le32(selval);
   2786		*data_ptr++ = cpu_to_le32(data);
   2787
   2788		value1 = value1 + stride2;
   2789		*d_ptr = data_ptr;
   2790	}
   2791
   2792exit_process_rdmdio:
   2793	return rval;
   2794}
   2795
   2796static uint32_t qla4_84xx_minidump_process_pollwr(struct scsi_qla_host *ha,
   2797				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2798				uint32_t **d_ptr)
   2799{
   2800	uint32_t addr1, addr2, value1, value2, poll, r_value;
   2801	struct qla8044_minidump_entry_pollwr *pollwr_hdr;
   2802	uint32_t wait_count = 0;
   2803	uint32_t rval = QLA_SUCCESS;
   2804
   2805	pollwr_hdr = (struct qla8044_minidump_entry_pollwr *)entry_hdr;
   2806	addr1 = le32_to_cpu(pollwr_hdr->addr_1);
   2807	addr2 = le32_to_cpu(pollwr_hdr->addr_2);
   2808	value1 = le32_to_cpu(pollwr_hdr->value_1);
   2809	value2 = le32_to_cpu(pollwr_hdr->value_2);
   2810
   2811	poll = le32_to_cpu(pollwr_hdr->poll);
   2812
   2813	while (wait_count < poll) {
   2814		ha->isp_ops->rd_reg_indirect(ha, addr1, &r_value);
   2815
   2816		if ((r_value & poll) != 0)
   2817			break;
   2818
   2819		wait_count++;
   2820	}
   2821
   2822	if (wait_count == poll) {
   2823		ql4_printk(KERN_ERR, ha, "%s: TIMEOUT\n", __func__);
   2824		rval = QLA_ERROR;
   2825		goto exit_process_pollwr;
   2826	}
   2827
   2828	ha->isp_ops->wr_reg_indirect(ha, addr2, value2);
   2829	ha->isp_ops->wr_reg_indirect(ha, addr1, value1);
   2830
   2831	wait_count = 0;
   2832	while (wait_count < poll) {
   2833		ha->isp_ops->rd_reg_indirect(ha, addr1, &r_value);
   2834
   2835		if ((r_value & poll) != 0)
   2836			break;
   2837		wait_count++;
   2838	}
   2839
   2840exit_process_pollwr:
   2841	return rval;
   2842}
   2843
   2844static void qla83xx_minidump_process_rdmux2(struct scsi_qla_host *ha,
   2845				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2846				uint32_t **d_ptr)
   2847{
   2848	uint32_t sel_val1, sel_val2, t_sel_val, data, i;
   2849	uint32_t sel_addr1, sel_addr2, sel_val_mask, read_addr;
   2850	struct qla83xx_minidump_entry_rdmux2 *rdmux2_hdr;
   2851	uint32_t *data_ptr = *d_ptr;
   2852
   2853	rdmux2_hdr = (struct qla83xx_minidump_entry_rdmux2 *)entry_hdr;
   2854	sel_val1 = le32_to_cpu(rdmux2_hdr->select_value_1);
   2855	sel_val2 = le32_to_cpu(rdmux2_hdr->select_value_2);
   2856	sel_addr1 = le32_to_cpu(rdmux2_hdr->select_addr_1);
   2857	sel_addr2 = le32_to_cpu(rdmux2_hdr->select_addr_2);
   2858	sel_val_mask = le32_to_cpu(rdmux2_hdr->select_value_mask);
   2859	read_addr = le32_to_cpu(rdmux2_hdr->read_addr);
   2860
   2861	for (i = 0; i < rdmux2_hdr->op_count; i++) {
   2862		ha->isp_ops->wr_reg_indirect(ha, sel_addr1, sel_val1);
   2863		t_sel_val = sel_val1 & sel_val_mask;
   2864		*data_ptr++ = cpu_to_le32(t_sel_val);
   2865
   2866		ha->isp_ops->wr_reg_indirect(ha, sel_addr2, t_sel_val);
   2867		ha->isp_ops->rd_reg_indirect(ha, read_addr, &data);
   2868
   2869		*data_ptr++ = cpu_to_le32(data);
   2870
   2871		ha->isp_ops->wr_reg_indirect(ha, sel_addr1, sel_val2);
   2872		t_sel_val = sel_val2 & sel_val_mask;
   2873		*data_ptr++ = cpu_to_le32(t_sel_val);
   2874
   2875		ha->isp_ops->wr_reg_indirect(ha, sel_addr2, t_sel_val);
   2876		ha->isp_ops->rd_reg_indirect(ha, read_addr, &data);
   2877
   2878		*data_ptr++ = cpu_to_le32(data);
   2879
   2880		sel_val1 += rdmux2_hdr->select_value_stride;
   2881		sel_val2 += rdmux2_hdr->select_value_stride;
   2882	}
   2883
   2884	*d_ptr = data_ptr;
   2885}
   2886
   2887static uint32_t qla83xx_minidump_process_pollrdmwr(struct scsi_qla_host *ha,
   2888				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2889				uint32_t **d_ptr)
   2890{
   2891	uint32_t poll_wait, poll_mask, r_value, data;
   2892	uint32_t addr_1, addr_2, value_1, value_2;
   2893	uint32_t *data_ptr = *d_ptr;
   2894	uint32_t rval = QLA_SUCCESS;
   2895	struct qla83xx_minidump_entry_pollrdmwr *poll_hdr;
   2896
   2897	poll_hdr = (struct qla83xx_minidump_entry_pollrdmwr *)entry_hdr;
   2898	addr_1 = le32_to_cpu(poll_hdr->addr_1);
   2899	addr_2 = le32_to_cpu(poll_hdr->addr_2);
   2900	value_1 = le32_to_cpu(poll_hdr->value_1);
   2901	value_2 = le32_to_cpu(poll_hdr->value_2);
   2902	poll_mask = le32_to_cpu(poll_hdr->poll_mask);
   2903
   2904	ha->isp_ops->wr_reg_indirect(ha, addr_1, value_1);
   2905
   2906	poll_wait = le32_to_cpu(poll_hdr->poll_wait);
   2907	while (1) {
   2908		ha->isp_ops->rd_reg_indirect(ha, addr_1, &r_value);
   2909
   2910		if ((r_value & poll_mask) != 0) {
   2911			break;
   2912		} else {
   2913			msleep(1);
   2914			if (--poll_wait == 0) {
   2915				ql4_printk(KERN_ERR, ha, "%s: TIMEOUT_1\n",
   2916					   __func__);
   2917				rval = QLA_ERROR;
   2918				goto exit_process_pollrdmwr;
   2919			}
   2920		}
   2921	}
   2922
   2923	ha->isp_ops->rd_reg_indirect(ha, addr_2, &data);
   2924	data &= le32_to_cpu(poll_hdr->modify_mask);
   2925	ha->isp_ops->wr_reg_indirect(ha, addr_2, data);
   2926	ha->isp_ops->wr_reg_indirect(ha, addr_1, value_2);
   2927
   2928	poll_wait = le32_to_cpu(poll_hdr->poll_wait);
   2929	while (1) {
   2930		ha->isp_ops->rd_reg_indirect(ha, addr_1, &r_value);
   2931
   2932		if ((r_value & poll_mask) != 0) {
   2933			break;
   2934		} else {
   2935			msleep(1);
   2936			if (--poll_wait == 0) {
   2937				ql4_printk(KERN_ERR, ha, "%s: TIMEOUT_2\n",
   2938					   __func__);
   2939				rval = QLA_ERROR;
   2940				goto exit_process_pollrdmwr;
   2941			}
   2942		}
   2943	}
   2944
   2945	*data_ptr++ = cpu_to_le32(addr_2);
   2946	*data_ptr++ = cpu_to_le32(data);
   2947	*d_ptr = data_ptr;
   2948
   2949exit_process_pollrdmwr:
   2950	return rval;
   2951}
   2952
   2953static uint32_t qla4_83xx_minidump_process_rdrom(struct scsi_qla_host *ha,
   2954				struct qla8xxx_minidump_entry_hdr *entry_hdr,
   2955				uint32_t **d_ptr)
   2956{
   2957	uint32_t fl_addr, u32_count, rval;
   2958	struct qla8xxx_minidump_entry_rdrom *rom_hdr;
   2959	uint32_t *data_ptr = *d_ptr;
   2960
   2961	rom_hdr = (struct qla8xxx_minidump_entry_rdrom *)entry_hdr;
   2962	fl_addr = le32_to_cpu(rom_hdr->read_addr);
   2963	u32_count = le32_to_cpu(rom_hdr->read_data_size)/sizeof(uint32_t);
   2964
   2965	DEBUG2(ql4_printk(KERN_INFO, ha, "[%s]: fl_addr: 0x%x, count: 0x%x\n",
   2966			  __func__, fl_addr, u32_count));
   2967
   2968	rval = qla4_83xx_lockless_flash_read_u32(ha, fl_addr,
   2969						 (u8 *)(data_ptr), u32_count);
   2970
   2971	if (rval == QLA_ERROR) {
   2972		ql4_printk(KERN_ERR, ha, "%s: Flash Read Error,Count=%d\n",
   2973			   __func__, u32_count);
   2974		goto exit_process_rdrom;
   2975	}
   2976
   2977	data_ptr += u32_count;
   2978	*d_ptr = data_ptr;
   2979
   2980exit_process_rdrom:
   2981	return rval;
   2982}
   2983
   2984/**
   2985 * qla4_8xxx_collect_md_data - Retrieve firmware minidump data.
   2986 * @ha: pointer to adapter structure
   2987 **/
   2988static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha)
   2989{
   2990	int num_entry_hdr = 0;
   2991	struct qla8xxx_minidump_entry_hdr *entry_hdr;
   2992	struct qla4_8xxx_minidump_template_hdr *tmplt_hdr;
   2993	uint32_t *data_ptr;
   2994	uint32_t data_collected = 0;
   2995	int i, rval = QLA_ERROR;
   2996	uint64_t now;
   2997	uint32_t timestamp;
   2998
   2999	ha->fw_dump_skip_size = 0;
   3000	if (!ha->fw_dump) {
   3001		ql4_printk(KERN_INFO, ha, "%s(%ld) No buffer to dump\n",
   3002			   __func__, ha->host_no);
   3003		return rval;
   3004	}
   3005
   3006	tmplt_hdr = (struct qla4_8xxx_minidump_template_hdr *)
   3007						ha->fw_dump_tmplt_hdr;
   3008	data_ptr = (uint32_t *)((uint8_t *)ha->fw_dump +
   3009						ha->fw_dump_tmplt_size);
   3010	data_collected += ha->fw_dump_tmplt_size;
   3011
   3012	num_entry_hdr = tmplt_hdr->num_of_entries;
   3013	ql4_printk(KERN_INFO, ha, "[%s]: starting data ptr: %p\n",
   3014		   __func__, data_ptr);
   3015	ql4_printk(KERN_INFO, ha,
   3016		   "[%s]: no of entry headers in Template: 0x%x\n",
   3017		   __func__, num_entry_hdr);
   3018	ql4_printk(KERN_INFO, ha, "[%s]: Capture Mask obtained: 0x%x\n",
   3019		   __func__, ha->fw_dump_capture_mask);
   3020	ql4_printk(KERN_INFO, ha, "[%s]: Total_data_size 0x%x, %d obtained\n",
   3021		   __func__, ha->fw_dump_size, ha->fw_dump_size);
   3022
   3023	/* Update current timestamp before taking dump */
   3024	now = get_jiffies_64();
   3025	timestamp = (u32)(jiffies_to_msecs(now) / 1000);
   3026	tmplt_hdr->driver_timestamp = timestamp;
   3027
   3028	entry_hdr = (struct qla8xxx_minidump_entry_hdr *)
   3029					(((uint8_t *)ha->fw_dump_tmplt_hdr) +
   3030					 tmplt_hdr->first_entry_offset);
   3031
   3032	if (is_qla8032(ha) || is_qla8042(ha))
   3033		tmplt_hdr->saved_state_array[QLA83XX_SS_OCM_WNDREG_INDEX] =
   3034					tmplt_hdr->ocm_window_reg[ha->func_num];
   3035
   3036	/* Walk through the entry headers - validate/perform required action */
   3037	for (i = 0; i < num_entry_hdr; i++) {
   3038		if (data_collected > ha->fw_dump_size) {
   3039			ql4_printk(KERN_INFO, ha,
   3040				   "Data collected: [0x%x], Total Dump size: [0x%x]\n",
   3041				   data_collected, ha->fw_dump_size);
   3042			return rval;
   3043		}
   3044
   3045		if (!(entry_hdr->d_ctrl.entry_capture_mask &
   3046		      ha->fw_dump_capture_mask)) {
   3047			entry_hdr->d_ctrl.driver_flags |=
   3048						QLA8XXX_DBG_SKIPPED_FLAG;
   3049			goto skip_nxt_entry;
   3050		}
   3051
   3052		DEBUG2(ql4_printk(KERN_INFO, ha,
   3053				  "Data collected: [0x%x], Dump size left:[0x%x]\n",
   3054				  data_collected,
   3055				  (ha->fw_dump_size - data_collected)));
   3056
   3057		/* Decode the entry type and take required action to capture
   3058		 * debug data
   3059		 */
   3060		switch (entry_hdr->entry_type) {
   3061		case QLA8XXX_RDEND:
   3062			qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
   3063			break;
   3064		case QLA8XXX_CNTRL:
   3065			rval = qla4_8xxx_minidump_process_control(ha,
   3066								  entry_hdr);
   3067			if (rval != QLA_SUCCESS) {
   3068				qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
   3069				goto md_failed;
   3070			}
   3071			break;
   3072		case QLA8XXX_RDCRB:
   3073			qla4_8xxx_minidump_process_rdcrb(ha, entry_hdr,
   3074							 &data_ptr);
   3075			break;
   3076		case QLA8XXX_RDMEM:
   3077			rval = qla4_8xxx_minidump_process_rdmem(ha, entry_hdr,
   3078								&data_ptr);
   3079			if (rval != QLA_SUCCESS) {
   3080				qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
   3081				goto md_failed;
   3082			}
   3083			break;
   3084		case QLA8XXX_BOARD:
   3085		case QLA8XXX_RDROM:
   3086			if (is_qla8022(ha)) {
   3087				qla4_82xx_minidump_process_rdrom(ha, entry_hdr,
   3088								 &data_ptr);
   3089			} else if (is_qla8032(ha) || is_qla8042(ha)) {
   3090				rval = qla4_83xx_minidump_process_rdrom(ha,
   3091								    entry_hdr,
   3092								    &data_ptr);
   3093				if (rval != QLA_SUCCESS)
   3094					qla4_8xxx_mark_entry_skipped(ha,
   3095								     entry_hdr,
   3096								     i);
   3097			}
   3098			break;
   3099		case QLA8XXX_L2DTG:
   3100		case QLA8XXX_L2ITG:
   3101		case QLA8XXX_L2DAT:
   3102		case QLA8XXX_L2INS:
   3103			rval = qla4_8xxx_minidump_process_l2tag(ha, entry_hdr,
   3104								&data_ptr);
   3105			if (rval != QLA_SUCCESS) {
   3106				qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
   3107				goto md_failed;
   3108			}
   3109			break;
   3110		case QLA8XXX_L1DTG:
   3111		case QLA8XXX_L1ITG:
   3112		case QLA8XXX_L1DAT:
   3113		case QLA8XXX_L1INS:
   3114			qla4_8xxx_minidump_process_l1cache(ha, entry_hdr,
   3115							   &data_ptr);
   3116			break;
   3117		case QLA8XXX_RDOCM:
   3118			qla4_8xxx_minidump_process_rdocm(ha, entry_hdr,
   3119							 &data_ptr);
   3120			break;
   3121		case QLA8XXX_RDMUX:
   3122			qla4_8xxx_minidump_process_rdmux(ha, entry_hdr,
   3123							 &data_ptr);
   3124			break;
   3125		case QLA8XXX_QUEUE:
   3126			qla4_8xxx_minidump_process_queue(ha, entry_hdr,
   3127							 &data_ptr);
   3128			break;
   3129		case QLA83XX_POLLRD:
   3130			if (is_qla8022(ha)) {
   3131				qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
   3132				break;
   3133			}
   3134			rval = qla83xx_minidump_process_pollrd(ha, entry_hdr,
   3135							       &data_ptr);
   3136			if (rval != QLA_SUCCESS)
   3137				qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
   3138			break;
   3139		case QLA83XX_RDMUX2:
   3140			if (is_qla8022(ha)) {
   3141				qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
   3142				break;
   3143			}
   3144			qla83xx_minidump_process_rdmux2(ha, entry_hdr,
   3145							&data_ptr);
   3146			break;
   3147		case QLA83XX_POLLRDMWR:
   3148			if (is_qla8022(ha)) {
   3149				qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
   3150				break;
   3151			}
   3152			rval = qla83xx_minidump_process_pollrdmwr(ha, entry_hdr,
   3153								  &data_ptr);
   3154			if (rval != QLA_SUCCESS)
   3155				qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
   3156			break;
   3157		case QLA8044_RDDFE:
   3158			rval = qla4_84xx_minidump_process_rddfe(ha, entry_hdr,
   3159								&data_ptr);
   3160			if (rval != QLA_SUCCESS)
   3161				qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
   3162			break;
   3163		case QLA8044_RDMDIO:
   3164			rval = qla4_84xx_minidump_process_rdmdio(ha, entry_hdr,
   3165								 &data_ptr);
   3166			if (rval != QLA_SUCCESS)
   3167				qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
   3168			break;
   3169		case QLA8044_POLLWR:
   3170			rval = qla4_84xx_minidump_process_pollwr(ha, entry_hdr,
   3171								 &data_ptr);
   3172			if (rval != QLA_SUCCESS)
   3173				qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
   3174			break;
   3175		case QLA8XXX_RDNOP:
   3176		default:
   3177			qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
   3178			break;
   3179		}
   3180
   3181		data_collected = (uint8_t *)data_ptr - (uint8_t *)ha->fw_dump;
   3182skip_nxt_entry:
   3183		/*  next entry in the template */
   3184		entry_hdr = (struct qla8xxx_minidump_entry_hdr *)
   3185				(((uint8_t *)entry_hdr) +
   3186				 entry_hdr->entry_size);
   3187	}
   3188
   3189	if ((data_collected + ha->fw_dump_skip_size) != ha->fw_dump_size) {
   3190		ql4_printk(KERN_INFO, ha,
   3191			   "Dump data mismatch: Data collected: [0x%x], total_data_size:[0x%x]\n",
   3192			   data_collected, ha->fw_dump_size);
   3193		rval = QLA_ERROR;
   3194		goto md_failed;
   3195	}
   3196
   3197	DEBUG2(ql4_printk(KERN_INFO, ha, "Leaving fn: %s Last entry: 0x%x\n",
   3198			  __func__, i));
   3199md_failed:
   3200	return rval;
   3201}
   3202
   3203/**
   3204 * qla4_8xxx_uevent_emit - Send uevent when the firmware dump is ready.
   3205 * @ha: pointer to adapter structure
   3206 * @code: uevent code to act upon
   3207 **/
   3208static void qla4_8xxx_uevent_emit(struct scsi_qla_host *ha, u32 code)
   3209{
   3210	char event_string[40];
   3211	char *envp[] = { event_string, NULL };
   3212
   3213	switch (code) {
   3214	case QL4_UEVENT_CODE_FW_DUMP:
   3215		snprintf(event_string, sizeof(event_string), "FW_DUMP=%lu",
   3216			 ha->host_no);
   3217		break;
   3218	default:
   3219		/*do nothing*/
   3220		break;
   3221	}
   3222
   3223	kobject_uevent_env(&(&ha->pdev->dev)->kobj, KOBJ_CHANGE, envp);
   3224}
   3225
   3226void qla4_8xxx_get_minidump(struct scsi_qla_host *ha)
   3227{
   3228	if (ql4xenablemd && test_bit(AF_FW_RECOVERY, &ha->flags) &&
   3229	    !test_bit(AF_82XX_FW_DUMPED, &ha->flags)) {
   3230		if (!qla4_8xxx_collect_md_data(ha)) {
   3231			qla4_8xxx_uevent_emit(ha, QL4_UEVENT_CODE_FW_DUMP);
   3232			set_bit(AF_82XX_FW_DUMPED, &ha->flags);
   3233		} else {
   3234			ql4_printk(KERN_INFO, ha, "%s: Unable to collect minidump\n",
   3235				   __func__);
   3236		}
   3237	}
   3238}
   3239
   3240/**
   3241 * qla4_8xxx_device_bootstrap - Initialize device, set DEV_READY, start fw
   3242 * @ha: pointer to adapter structure
   3243 *
   3244 * Note: IDC lock must be held upon entry
   3245 **/
   3246int qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
   3247{
   3248	int rval = QLA_ERROR;
   3249	int i;
   3250	uint32_t old_count, count;
   3251	int need_reset = 0;
   3252
   3253	need_reset = ha->isp_ops->need_reset(ha);
   3254
   3255	if (need_reset) {
   3256		/* We are trying to perform a recovery here. */
   3257		if (test_bit(AF_FW_RECOVERY, &ha->flags))
   3258			ha->isp_ops->rom_lock_recovery(ha);
   3259	} else  {
   3260		old_count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);
   3261		for (i = 0; i < 10; i++) {
   3262			msleep(200);
   3263			count = qla4_8xxx_rd_direct(ha,
   3264						    QLA8XXX_PEG_ALIVE_COUNTER);
   3265			if (count != old_count) {
   3266				rval = QLA_SUCCESS;
   3267				goto dev_ready;
   3268			}
   3269		}
   3270		ha->isp_ops->rom_lock_recovery(ha);
   3271	}
   3272
   3273	/* set to DEV_INITIALIZING */
   3274	ql4_printk(KERN_INFO, ha, "HW State: INITIALIZING\n");
   3275	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
   3276			    QLA8XXX_DEV_INITIALIZING);
   3277
   3278	ha->isp_ops->idc_unlock(ha);
   3279
   3280	if (is_qla8022(ha))
   3281		qla4_8xxx_get_minidump(ha);
   3282
   3283	rval = ha->isp_ops->restart_firmware(ha);
   3284	ha->isp_ops->idc_lock(ha);
   3285
   3286	if (rval != QLA_SUCCESS) {
   3287		ql4_printk(KERN_INFO, ha, "HW State: FAILED\n");
   3288		qla4_8xxx_clear_drv_active(ha);
   3289		qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
   3290				    QLA8XXX_DEV_FAILED);
   3291		return rval;
   3292	}
   3293
   3294dev_ready:
   3295	ql4_printk(KERN_INFO, ha, "HW State: READY\n");
   3296	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, QLA8XXX_DEV_READY);
   3297
   3298	return rval;
   3299}
   3300
   3301/**
   3302 * qla4_82xx_need_reset_handler - Code to start reset sequence
   3303 * @ha: pointer to adapter structure
   3304 *
   3305 * Note: IDC lock must be held upon entry
   3306 **/
   3307static void
   3308qla4_82xx_need_reset_handler(struct scsi_qla_host *ha)
   3309{
   3310	uint32_t dev_state, drv_state, drv_active;
   3311	uint32_t active_mask = 0xFFFFFFFF;
   3312	unsigned long reset_timeout;
   3313
   3314	ql4_printk(KERN_INFO, ha,
   3315		"Performing ISP error recovery\n");
   3316
   3317	if (test_and_clear_bit(AF_ONLINE, &ha->flags)) {
   3318		qla4_82xx_idc_unlock(ha);
   3319		ha->isp_ops->disable_intrs(ha);
   3320		qla4_82xx_idc_lock(ha);
   3321	}
   3322
   3323	if (!test_bit(AF_8XXX_RST_OWNER, &ha->flags)) {
   3324		DEBUG2(ql4_printk(KERN_INFO, ha,
   3325				  "%s(%ld): reset acknowledged\n",
   3326				  __func__, ha->host_no));
   3327		qla4_8xxx_set_rst_ready(ha);
   3328	} else {
   3329		active_mask = (~(1 << (ha->func_num * 4)));
   3330	}
   3331
   3332	/* wait for 10 seconds for reset ack from all functions */
   3333	reset_timeout = jiffies + (ha->nx_reset_timeout * HZ);
   3334
   3335	drv_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
   3336	drv_active = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
   3337
   3338	ql4_printk(KERN_INFO, ha,
   3339		"%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n",
   3340		__func__, ha->host_no, drv_state, drv_active);
   3341
   3342	while (drv_state != (drv_active & active_mask)) {
   3343		if (time_after_eq(jiffies, reset_timeout)) {
   3344			ql4_printk(KERN_INFO, ha,
   3345				   "%s: RESET TIMEOUT! drv_state: 0x%08x, drv_active: 0x%08x\n",
   3346				   DRIVER_NAME, drv_state, drv_active);
   3347			break;
   3348		}
   3349
   3350		/*
   3351		 * When reset_owner times out, check which functions
   3352		 * acked/did not ack
   3353		 */
   3354		if (test_bit(AF_8XXX_RST_OWNER, &ha->flags)) {
   3355			ql4_printk(KERN_INFO, ha,
   3356				   "%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n",
   3357				   __func__, ha->host_no, drv_state,
   3358				   drv_active);
   3359		}
   3360		qla4_82xx_idc_unlock(ha);
   3361		msleep(1000);
   3362		qla4_82xx_idc_lock(ha);
   3363
   3364		drv_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
   3365		drv_active = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
   3366	}
   3367
   3368	/* Clear RESET OWNER as we are not going to use it any further */
   3369	clear_bit(AF_8XXX_RST_OWNER, &ha->flags);
   3370
   3371	dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
   3372	ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n", dev_state,
   3373		   dev_state < MAX_STATES ? qdev_state[dev_state] : "Unknown");
   3374
   3375	/* Force to DEV_COLD unless someone else is starting a reset */
   3376	if (dev_state != QLA8XXX_DEV_INITIALIZING) {
   3377		ql4_printk(KERN_INFO, ha, "HW State: COLD/RE-INIT\n");
   3378		qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_COLD);
   3379		qla4_8xxx_set_rst_ready(ha);
   3380	}
   3381}
   3382
   3383/**
   3384 * qla4_8xxx_need_qsnt_handler - Code to start qsnt
   3385 * @ha: pointer to adapter structure
   3386 **/
   3387void
   3388qla4_8xxx_need_qsnt_handler(struct scsi_qla_host *ha)
   3389{
   3390	ha->isp_ops->idc_lock(ha);
   3391	qla4_8xxx_set_qsnt_ready(ha);
   3392	ha->isp_ops->idc_unlock(ha);
   3393}
   3394
   3395static void qla4_82xx_set_idc_ver(struct scsi_qla_host *ha)
   3396{
   3397	int idc_ver;
   3398	uint32_t drv_active;
   3399
   3400	drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
   3401	if (drv_active == (1 << (ha->func_num * 4))) {
   3402		qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION,
   3403				    QLA82XX_IDC_VERSION);
   3404		ql4_printk(KERN_INFO, ha,
   3405			   "%s: IDC version updated to %d\n", __func__,
   3406			   QLA82XX_IDC_VERSION);
   3407	} else {
   3408		idc_ver = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION);
   3409		if (QLA82XX_IDC_VERSION != idc_ver) {
   3410			ql4_printk(KERN_INFO, ha,
   3411				   "%s: qla4xxx driver IDC version %d is not compatible with IDC version %d of other drivers!\n",
   3412				   __func__, QLA82XX_IDC_VERSION, idc_ver);
   3413		}
   3414	}
   3415}
   3416
   3417static int qla4_83xx_set_idc_ver(struct scsi_qla_host *ha)
   3418{
   3419	int idc_ver;
   3420	uint32_t drv_active;
   3421	int rval = QLA_SUCCESS;
   3422
   3423	drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
   3424	if (drv_active == (1 << ha->func_num)) {
   3425		idc_ver = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION);
   3426		idc_ver &= (~0xFF);
   3427		idc_ver |= QLA83XX_IDC_VER_MAJ_VALUE;
   3428		qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION, idc_ver);
   3429		ql4_printk(KERN_INFO, ha,
   3430			   "%s: IDC version updated to %d\n", __func__,
   3431			   idc_ver);
   3432	} else {
   3433		idc_ver = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION);
   3434		idc_ver &= 0xFF;
   3435		if (QLA83XX_IDC_VER_MAJ_VALUE != idc_ver) {
   3436			ql4_printk(KERN_INFO, ha,
   3437				   "%s: qla4xxx driver IDC version %d is not compatible with IDC version %d of other drivers!\n",
   3438				   __func__, QLA83XX_IDC_VER_MAJ_VALUE,
   3439				   idc_ver);
   3440			rval = QLA_ERROR;
   3441			goto exit_set_idc_ver;
   3442		}
   3443	}
   3444
   3445	/* Update IDC_MINOR_VERSION */
   3446	idc_ver = qla4_83xx_rd_reg(ha, QLA83XX_CRB_IDC_VER_MINOR);
   3447	idc_ver &= ~(0x03 << (ha->func_num * 2));
   3448	idc_ver |= (QLA83XX_IDC_VER_MIN_VALUE << (ha->func_num * 2));
   3449	qla4_83xx_wr_reg(ha, QLA83XX_CRB_IDC_VER_MINOR, idc_ver);
   3450
   3451exit_set_idc_ver:
   3452	return rval;
   3453}
   3454
   3455int qla4_8xxx_update_idc_reg(struct scsi_qla_host *ha)
   3456{
   3457	uint32_t drv_active;
   3458	int rval = QLA_SUCCESS;
   3459
   3460	if (test_bit(AF_INIT_DONE, &ha->flags))
   3461		goto exit_update_idc_reg;
   3462
   3463	ha->isp_ops->idc_lock(ha);
   3464	qla4_8xxx_set_drv_active(ha);
   3465
   3466	/*
   3467	 * If we are the first driver to load and
   3468	 * ql4xdontresethba is not set, clear IDC_CTRL BIT0.
   3469	 */
   3470	if (is_qla8032(ha) || is_qla8042(ha)) {
   3471		drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
   3472		if ((drv_active == (1 << ha->func_num)) && !ql4xdontresethba)
   3473			qla4_83xx_clear_idc_dontreset(ha);
   3474	}
   3475
   3476	if (is_qla8022(ha)) {
   3477		qla4_82xx_set_idc_ver(ha);
   3478	} else if (is_qla8032(ha) || is_qla8042(ha)) {
   3479		rval = qla4_83xx_set_idc_ver(ha);
   3480		if (rval == QLA_ERROR)
   3481			qla4_8xxx_clear_drv_active(ha);
   3482	}
   3483
   3484	ha->isp_ops->idc_unlock(ha);
   3485
   3486exit_update_idc_reg:
   3487	return rval;
   3488}
   3489
   3490/**
   3491 * qla4_8xxx_device_state_handler - Adapter state machine
   3492 * @ha: pointer to host adapter structure.
   3493 *
   3494 * Note: IDC lock must be UNLOCKED upon entry
   3495 **/
   3496int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
   3497{
   3498	uint32_t dev_state;
   3499	int rval = QLA_SUCCESS;
   3500	unsigned long dev_init_timeout;
   3501
   3502	rval = qla4_8xxx_update_idc_reg(ha);
   3503	if (rval == QLA_ERROR)
   3504		goto exit_state_handler;
   3505
   3506	dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
   3507	DEBUG2(ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n",
   3508			  dev_state, dev_state < MAX_STATES ?
   3509			  qdev_state[dev_state] : "Unknown"));
   3510
   3511	/* wait for 30 seconds for device to go ready */
   3512	dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ);
   3513
   3514	ha->isp_ops->idc_lock(ha);
   3515	while (1) {
   3516
   3517		if (time_after_eq(jiffies, dev_init_timeout)) {
   3518			ql4_printk(KERN_WARNING, ha,
   3519				   "%s: Device Init Failed 0x%x = %s\n",
   3520				   DRIVER_NAME,
   3521				   dev_state, dev_state < MAX_STATES ?
   3522				   qdev_state[dev_state] : "Unknown");
   3523			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
   3524					    QLA8XXX_DEV_FAILED);
   3525		}
   3526
   3527		dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
   3528		ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n",
   3529			   dev_state, dev_state < MAX_STATES ?
   3530			   qdev_state[dev_state] : "Unknown");
   3531
   3532		/* NOTE: Make sure idc unlocked upon exit of switch statement */
   3533		switch (dev_state) {
   3534		case QLA8XXX_DEV_READY:
   3535			goto exit;
   3536		case QLA8XXX_DEV_COLD:
   3537			rval = qla4_8xxx_device_bootstrap(ha);
   3538			goto exit;
   3539		case QLA8XXX_DEV_INITIALIZING:
   3540			ha->isp_ops->idc_unlock(ha);
   3541			msleep(1000);
   3542			ha->isp_ops->idc_lock(ha);
   3543			break;
   3544		case QLA8XXX_DEV_NEED_RESET:
   3545			/*
   3546			 * For ISP8324 and ISP8042, if NEED_RESET is set by any
   3547			 * driver, it should be honored, irrespective of
   3548			 * IDC_CTRL DONTRESET_BIT0
   3549			 */
   3550			if (is_qla8032(ha) || is_qla8042(ha)) {
   3551				qla4_83xx_need_reset_handler(ha);
   3552			} else if (is_qla8022(ha)) {
   3553				if (!ql4xdontresethba) {
   3554					qla4_82xx_need_reset_handler(ha);
   3555					/* Update timeout value after need
   3556					 * reset handler */
   3557					dev_init_timeout = jiffies +
   3558						(ha->nx_dev_init_timeout * HZ);
   3559				} else {
   3560					ha->isp_ops->idc_unlock(ha);
   3561					msleep(1000);
   3562					ha->isp_ops->idc_lock(ha);
   3563				}
   3564			}
   3565			break;
   3566		case QLA8XXX_DEV_NEED_QUIESCENT:
   3567			/* idc locked/unlocked in handler */
   3568			qla4_8xxx_need_qsnt_handler(ha);
   3569			break;
   3570		case QLA8XXX_DEV_QUIESCENT:
   3571			ha->isp_ops->idc_unlock(ha);
   3572			msleep(1000);
   3573			ha->isp_ops->idc_lock(ha);
   3574			break;
   3575		case QLA8XXX_DEV_FAILED:
   3576			ha->isp_ops->idc_unlock(ha);
   3577			qla4xxx_dead_adapter_cleanup(ha);
   3578			rval = QLA_ERROR;
   3579			ha->isp_ops->idc_lock(ha);
   3580			goto exit;
   3581		default:
   3582			ha->isp_ops->idc_unlock(ha);
   3583			qla4xxx_dead_adapter_cleanup(ha);
   3584			rval = QLA_ERROR;
   3585			ha->isp_ops->idc_lock(ha);
   3586			goto exit;
   3587		}
   3588	}
   3589exit:
   3590	ha->isp_ops->idc_unlock(ha);
   3591exit_state_handler:
   3592	return rval;
   3593}
   3594
   3595int qla4_8xxx_load_risc(struct scsi_qla_host *ha)
   3596{
   3597	int retval;
   3598
   3599	/* clear the interrupt */
   3600	if (is_qla8032(ha) || is_qla8042(ha)) {
   3601		writel(0, &ha->qla4_83xx_reg->risc_intr);
   3602		readl(&ha->qla4_83xx_reg->risc_intr);
   3603	} else if (is_qla8022(ha)) {
   3604		writel(0, &ha->qla4_82xx_reg->host_int);
   3605		readl(&ha->qla4_82xx_reg->host_int);
   3606	}
   3607
   3608	retval = qla4_8xxx_device_state_handler(ha);
   3609
   3610	/* Initialize request and response queues. */
   3611	if (retval == QLA_SUCCESS)
   3612		qla4xxx_init_rings(ha);
   3613
   3614	if (retval == QLA_SUCCESS && !test_bit(AF_IRQ_ATTACHED, &ha->flags))
   3615		retval = qla4xxx_request_irqs(ha);
   3616
   3617	return retval;
   3618}
   3619
   3620/*****************************************************************************/
   3621/* Flash Manipulation Routines                                               */
   3622/*****************************************************************************/
   3623
   3624#define OPTROM_BURST_SIZE       0x1000
   3625#define OPTROM_BURST_DWORDS     (OPTROM_BURST_SIZE / 4)
   3626
   3627#define FARX_DATA_FLAG	BIT_31
   3628#define FARX_ACCESS_FLASH_CONF	0x7FFD0000
   3629#define FARX_ACCESS_FLASH_DATA	0x7FF00000
   3630
   3631static inline uint32_t
   3632flash_conf_addr(struct ql82xx_hw_data *hw, uint32_t faddr)
   3633{
   3634	return hw->flash_conf_off | faddr;
   3635}
   3636
   3637static uint32_t *
   3638qla4_82xx_read_flash_data(struct scsi_qla_host *ha, uint32_t *dwptr,
   3639    uint32_t faddr, uint32_t length)
   3640{
   3641	uint32_t i;
   3642	uint32_t val;
   3643	int loops = 0;
   3644	while ((qla4_82xx_rom_lock(ha) != 0) && (loops < 50000)) {
   3645		udelay(100);
   3646		cond_resched();
   3647		loops++;
   3648	}
   3649	if (loops >= 50000) {
   3650		ql4_printk(KERN_WARNING, ha, "ROM lock failed\n");
   3651		return dwptr;
   3652	}
   3653
   3654	/* Dword reads to flash. */
   3655	for (i = 0; i < length/4; i++, faddr += 4) {
   3656		if (qla4_82xx_do_rom_fast_read(ha, faddr, &val)) {
   3657			ql4_printk(KERN_WARNING, ha,
   3658			    "Do ROM fast read failed\n");
   3659			goto done_read;
   3660		}
   3661		dwptr[i] = cpu_to_le32(val);
   3662	}
   3663
   3664done_read:
   3665	qla4_82xx_rom_unlock(ha);
   3666	return dwptr;
   3667}
   3668
   3669/*
   3670 * Address and length are byte address
   3671 */
   3672static uint8_t *
   3673qla4_82xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
   3674		uint32_t offset, uint32_t length)
   3675{
   3676	qla4_82xx_read_flash_data(ha, (uint32_t *)buf, offset, length);
   3677	return buf;
   3678}
   3679
   3680static int
   3681qla4_8xxx_find_flt_start(struct scsi_qla_host *ha, uint32_t *start)
   3682{
   3683	const char *loc, *locations[] = { "DEF", "PCI" };
   3684
   3685	/*
   3686	 * FLT-location structure resides after the last PCI region.
   3687	 */
   3688
   3689	/* Begin with sane defaults. */
   3690	loc = locations[0];
   3691	*start = FA_FLASH_LAYOUT_ADDR_82;
   3692
   3693	DEBUG2(ql4_printk(KERN_INFO, ha, "FLTL[%s] = 0x%x.\n", loc, *start));
   3694	return QLA_SUCCESS;
   3695}
   3696
   3697static void
   3698qla4_8xxx_get_flt_info(struct scsi_qla_host *ha, uint32_t flt_addr)
   3699{
   3700	const char *loc, *locations[] = { "DEF", "FLT" };
   3701	uint16_t *wptr;
   3702	uint16_t cnt, chksum;
   3703	uint32_t start, status;
   3704	struct qla_flt_header *flt;
   3705	struct qla_flt_region *region;
   3706	struct ql82xx_hw_data *hw = &ha->hw;
   3707
   3708	hw->flt_region_flt = flt_addr;
   3709	wptr = (uint16_t *)ha->request_ring;
   3710	flt = (struct qla_flt_header *)ha->request_ring;
   3711	region = (struct qla_flt_region *)&flt[1];
   3712
   3713	if (is_qla8022(ha)) {
   3714		qla4_82xx_read_optrom_data(ha, (uint8_t *)ha->request_ring,
   3715					   flt_addr << 2, OPTROM_BURST_SIZE);
   3716	} else if (is_qla8032(ha) || is_qla8042(ha)) {
   3717		status = qla4_83xx_flash_read_u32(ha, flt_addr << 2,
   3718						  (uint8_t *)ha->request_ring,
   3719						  0x400);
   3720		if (status != QLA_SUCCESS)
   3721			goto no_flash_data;
   3722	}
   3723
   3724	if (*wptr == cpu_to_le16(0xffff))
   3725		goto no_flash_data;
   3726	if (flt->version != cpu_to_le16(1)) {
   3727		DEBUG2(ql4_printk(KERN_INFO, ha, "Unsupported FLT detected: "
   3728			"version=0x%x length=0x%x checksum=0x%x.\n",
   3729			le16_to_cpu(flt->version), le16_to_cpu(flt->length),
   3730			le16_to_cpu(flt->checksum)));
   3731		goto no_flash_data;
   3732	}
   3733
   3734	cnt = (sizeof(struct qla_flt_header) + le16_to_cpu(flt->length)) >> 1;
   3735	for (chksum = 0; cnt; cnt--)
   3736		chksum += le16_to_cpu(*wptr++);
   3737	if (chksum) {
   3738		DEBUG2(ql4_printk(KERN_INFO, ha, "Inconsistent FLT detected: "
   3739			"version=0x%x length=0x%x checksum=0x%x.\n",
   3740			le16_to_cpu(flt->version), le16_to_cpu(flt->length),
   3741			chksum));
   3742		goto no_flash_data;
   3743	}
   3744
   3745	loc = locations[1];
   3746	cnt = le16_to_cpu(flt->length) / sizeof(struct qla_flt_region);
   3747	for ( ; cnt; cnt--, region++) {
   3748		/* Store addresses as DWORD offsets. */
   3749		start = le32_to_cpu(region->start) >> 2;
   3750
   3751		DEBUG3(ql4_printk(KERN_DEBUG, ha, "FLT[%02x]: start=0x%x "
   3752		    "end=0x%x size=0x%x.\n", le32_to_cpu(region->code), start,
   3753		    le32_to_cpu(region->end) >> 2, le32_to_cpu(region->size)));
   3754
   3755		switch (le32_to_cpu(region->code) & 0xff) {
   3756		case FLT_REG_FDT:
   3757			hw->flt_region_fdt = start;
   3758			break;
   3759		case FLT_REG_BOOT_CODE_82:
   3760			hw->flt_region_boot = start;
   3761			break;
   3762		case FLT_REG_FW_82:
   3763		case FLT_REG_FW_82_1:
   3764			hw->flt_region_fw = start;
   3765			break;
   3766		case FLT_REG_BOOTLOAD_82:
   3767			hw->flt_region_bootload = start;
   3768			break;
   3769		case FLT_REG_ISCSI_PARAM:
   3770			hw->flt_iscsi_param =  start;
   3771			break;
   3772		case FLT_REG_ISCSI_CHAP:
   3773			hw->flt_region_chap =  start;
   3774			hw->flt_chap_size =  le32_to_cpu(region->size);
   3775			break;
   3776		case FLT_REG_ISCSI_DDB:
   3777			hw->flt_region_ddb =  start;
   3778			hw->flt_ddb_size =  le32_to_cpu(region->size);
   3779			break;
   3780		}
   3781	}
   3782	goto done;
   3783
   3784no_flash_data:
   3785	/* Use hardcoded defaults. */
   3786	loc = locations[0];
   3787
   3788	hw->flt_region_fdt      = FA_FLASH_DESCR_ADDR_82;
   3789	hw->flt_region_boot     = FA_BOOT_CODE_ADDR_82;
   3790	hw->flt_region_bootload = FA_BOOT_LOAD_ADDR_82;
   3791	hw->flt_region_fw       = FA_RISC_CODE_ADDR_82;
   3792	hw->flt_region_chap	= FA_FLASH_ISCSI_CHAP >> 2;
   3793	hw->flt_chap_size	= FA_FLASH_CHAP_SIZE;
   3794	hw->flt_region_ddb	= FA_FLASH_ISCSI_DDB >> 2;
   3795	hw->flt_ddb_size	= FA_FLASH_DDB_SIZE;
   3796
   3797done:
   3798	DEBUG2(ql4_printk(KERN_INFO, ha,
   3799			  "FLT[%s]: flt=0x%x fdt=0x%x boot=0x%x bootload=0x%x fw=0x%x chap=0x%x chap_size=0x%x ddb=0x%x  ddb_size=0x%x\n",
   3800			  loc, hw->flt_region_flt, hw->flt_region_fdt,
   3801			  hw->flt_region_boot, hw->flt_region_bootload,
   3802			  hw->flt_region_fw, hw->flt_region_chap,
   3803			  hw->flt_chap_size, hw->flt_region_ddb,
   3804			  hw->flt_ddb_size));
   3805}
   3806
   3807static void
   3808qla4_82xx_get_fdt_info(struct scsi_qla_host *ha)
   3809{
   3810#define FLASH_BLK_SIZE_4K       0x1000
   3811#define FLASH_BLK_SIZE_32K      0x8000
   3812#define FLASH_BLK_SIZE_64K      0x10000
   3813	const char *loc, *locations[] = { "MID", "FDT" };
   3814	uint16_t cnt, chksum;
   3815	uint16_t *wptr;
   3816	struct qla_fdt_layout *fdt;
   3817	uint16_t mid = 0;
   3818	uint16_t fid = 0;
   3819	struct ql82xx_hw_data *hw = &ha->hw;
   3820
   3821	hw->flash_conf_off = FARX_ACCESS_FLASH_CONF;
   3822	hw->flash_data_off = FARX_ACCESS_FLASH_DATA;
   3823
   3824	wptr = (uint16_t *)ha->request_ring;
   3825	fdt = (struct qla_fdt_layout *)ha->request_ring;
   3826	qla4_82xx_read_optrom_data(ha, (uint8_t *)ha->request_ring,
   3827	    hw->flt_region_fdt << 2, OPTROM_BURST_SIZE);
   3828
   3829	if (*wptr == cpu_to_le16(0xffff))
   3830		goto no_flash_data;
   3831
   3832	if (fdt->sig[0] != 'Q' || fdt->sig[1] != 'L' || fdt->sig[2] != 'I' ||
   3833	    fdt->sig[3] != 'D')
   3834		goto no_flash_data;
   3835
   3836	for (cnt = 0, chksum = 0; cnt < sizeof(struct qla_fdt_layout) >> 1;
   3837	    cnt++)
   3838		chksum += le16_to_cpu(*wptr++);
   3839
   3840	if (chksum) {
   3841		DEBUG2(ql4_printk(KERN_INFO, ha, "Inconsistent FDT detected: "
   3842		    "checksum=0x%x id=%c version=0x%x.\n", chksum, fdt->sig[0],
   3843		    le16_to_cpu(fdt->version)));
   3844		goto no_flash_data;
   3845	}
   3846
   3847	loc = locations[1];
   3848	mid = le16_to_cpu(fdt->man_id);
   3849	fid = le16_to_cpu(fdt->id);
   3850	hw->fdt_wrt_disable = fdt->wrt_disable_bits;
   3851	hw->fdt_erase_cmd = flash_conf_addr(hw, 0x0300 | fdt->erase_cmd);
   3852	hw->fdt_block_size = le32_to_cpu(fdt->block_size);
   3853
   3854	if (fdt->unprotect_sec_cmd) {
   3855		hw->fdt_unprotect_sec_cmd = flash_conf_addr(hw, 0x0300 |
   3856		    fdt->unprotect_sec_cmd);
   3857		hw->fdt_protect_sec_cmd = fdt->protect_sec_cmd ?
   3858		    flash_conf_addr(hw, 0x0300 | fdt->protect_sec_cmd) :
   3859		    flash_conf_addr(hw, 0x0336);
   3860	}
   3861	goto done;
   3862
   3863no_flash_data:
   3864	loc = locations[0];
   3865	hw->fdt_block_size = FLASH_BLK_SIZE_64K;
   3866done:
   3867	DEBUG2(ql4_printk(KERN_INFO, ha, "FDT[%s]: (0x%x/0x%x) erase=0x%x "
   3868		"pro=%x upro=%x wrtd=0x%x blk=0x%x.\n", loc, mid, fid,
   3869		hw->fdt_erase_cmd, hw->fdt_protect_sec_cmd,
   3870		hw->fdt_unprotect_sec_cmd, hw->fdt_wrt_disable,
   3871		hw->fdt_block_size));
   3872}
   3873
   3874static void
   3875qla4_82xx_get_idc_param(struct scsi_qla_host *ha)
   3876{
   3877#define QLA82XX_IDC_PARAM_ADDR      0x003e885c
   3878	uint32_t *wptr;
   3879
   3880	if (!is_qla8022(ha))
   3881		return;
   3882	wptr = (uint32_t *)ha->request_ring;
   3883	qla4_82xx_read_optrom_data(ha, (uint8_t *)ha->request_ring,
   3884			QLA82XX_IDC_PARAM_ADDR , 8);
   3885
   3886	if (*wptr == cpu_to_le32(0xffffffff)) {
   3887		ha->nx_dev_init_timeout = ROM_DEV_INIT_TIMEOUT;
   3888		ha->nx_reset_timeout = ROM_DRV_RESET_ACK_TIMEOUT;
   3889	} else {
   3890		ha->nx_dev_init_timeout = le32_to_cpu(*wptr++);
   3891		ha->nx_reset_timeout = le32_to_cpu(*wptr);
   3892	}
   3893
   3894	DEBUG2(ql4_printk(KERN_DEBUG, ha,
   3895		"ha->nx_dev_init_timeout = %d\n", ha->nx_dev_init_timeout));
   3896	DEBUG2(ql4_printk(KERN_DEBUG, ha,
   3897		"ha->nx_reset_timeout = %d\n", ha->nx_reset_timeout));
   3898	return;
   3899}
   3900
   3901void qla4_82xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
   3902			      int in_count)
   3903{
   3904	int i;
   3905
   3906	/* Load all mailbox registers, except mailbox 0. */
   3907	for (i = 1; i < in_count; i++)
   3908		writel(mbx_cmd[i], &ha->qla4_82xx_reg->mailbox_in[i]);
   3909
   3910	/* Wakeup firmware  */
   3911	writel(mbx_cmd[0], &ha->qla4_82xx_reg->mailbox_in[0]);
   3912	readl(&ha->qla4_82xx_reg->mailbox_in[0]);
   3913	writel(HINT_MBX_INT_PENDING, &ha->qla4_82xx_reg->hint);
   3914	readl(&ha->qla4_82xx_reg->hint);
   3915}
   3916
   3917void qla4_82xx_process_mbox_intr(struct scsi_qla_host *ha, int out_count)
   3918{
   3919	int intr_status;
   3920
   3921	intr_status = readl(&ha->qla4_82xx_reg->host_int);
   3922	if (intr_status & ISRX_82XX_RISC_INT) {
   3923		ha->mbox_status_count = out_count;
   3924		intr_status = readl(&ha->qla4_82xx_reg->host_status);
   3925		ha->isp_ops->interrupt_service_routine(ha, intr_status);
   3926
   3927		if (test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
   3928		    (!ha->pdev->msi_enabled && !ha->pdev->msix_enabled))
   3929			qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg,
   3930					0xfbff);
   3931	}
   3932}
   3933
   3934int
   3935qla4_8xxx_get_flash_info(struct scsi_qla_host *ha)
   3936{
   3937	int ret;
   3938	uint32_t flt_addr;
   3939
   3940	ret = qla4_8xxx_find_flt_start(ha, &flt_addr);
   3941	if (ret != QLA_SUCCESS)
   3942		return ret;
   3943
   3944	qla4_8xxx_get_flt_info(ha, flt_addr);
   3945	if (is_qla8022(ha)) {
   3946		qla4_82xx_get_fdt_info(ha);
   3947		qla4_82xx_get_idc_param(ha);
   3948	} else if (is_qla8032(ha) || is_qla8042(ha)) {
   3949		qla4_83xx_get_idc_param(ha);
   3950	}
   3951
   3952	return QLA_SUCCESS;
   3953}
   3954
   3955/**
   3956 * qla4_8xxx_stop_firmware - stops firmware on specified adapter instance
   3957 * @ha: pointer to host adapter structure.
   3958 *
   3959 * Remarks:
   3960 * For iSCSI, throws away all I/O and AENs into bit bucket, so they will
   3961 * not be available after successful return.  Driver must cleanup potential
   3962 * outstanding I/O's after calling this funcion.
   3963 **/
   3964int
   3965qla4_8xxx_stop_firmware(struct scsi_qla_host *ha)
   3966{
   3967	int status;
   3968	uint32_t mbox_cmd[MBOX_REG_COUNT];
   3969	uint32_t mbox_sts[MBOX_REG_COUNT];
   3970
   3971	memset(&mbox_cmd, 0, sizeof(mbox_cmd));
   3972	memset(&mbox_sts, 0, sizeof(mbox_sts));
   3973
   3974	mbox_cmd[0] = MBOX_CMD_STOP_FW;
   3975	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1,
   3976	    &mbox_cmd[0], &mbox_sts[0]);
   3977
   3978	DEBUG2(printk("scsi%ld: %s: status = %d\n", ha->host_no,
   3979	    __func__, status));
   3980	return status;
   3981}
   3982
   3983/**
   3984 * qla4_82xx_isp_reset - Resets ISP and aborts all outstanding commands.
   3985 * @ha: pointer to host adapter structure.
   3986 **/
   3987int
   3988qla4_82xx_isp_reset(struct scsi_qla_host *ha)
   3989{
   3990	int rval;
   3991	uint32_t dev_state;
   3992
   3993	qla4_82xx_idc_lock(ha);
   3994	dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
   3995
   3996	if (dev_state == QLA8XXX_DEV_READY) {
   3997		ql4_printk(KERN_INFO, ha, "HW State: NEED RESET\n");
   3998		qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
   3999		    QLA8XXX_DEV_NEED_RESET);
   4000		set_bit(AF_8XXX_RST_OWNER, &ha->flags);
   4001	} else
   4002		ql4_printk(KERN_INFO, ha, "HW State: DEVICE INITIALIZING\n");
   4003
   4004	qla4_82xx_idc_unlock(ha);
   4005
   4006	rval = qla4_8xxx_device_state_handler(ha);
   4007
   4008	qla4_82xx_idc_lock(ha);
   4009	qla4_8xxx_clear_rst_ready(ha);
   4010	qla4_82xx_idc_unlock(ha);
   4011
   4012	if (rval == QLA_SUCCESS) {
   4013		ql4_printk(KERN_INFO, ha, "Clearing AF_RECOVERY in qla4_82xx_isp_reset\n");
   4014		clear_bit(AF_FW_RECOVERY, &ha->flags);
   4015	}
   4016
   4017	return rval;
   4018}
   4019
   4020/**
   4021 * qla4_8xxx_get_sys_info - get adapter MAC address(es) and serial number
   4022 * @ha: pointer to host adapter structure.
   4023 *
   4024 **/
   4025int qla4_8xxx_get_sys_info(struct scsi_qla_host *ha)
   4026{
   4027	uint32_t mbox_cmd[MBOX_REG_COUNT];
   4028	uint32_t mbox_sts[MBOX_REG_COUNT];
   4029	struct mbx_sys_info *sys_info;
   4030	dma_addr_t sys_info_dma;
   4031	int status = QLA_ERROR;
   4032
   4033	sys_info = dma_alloc_coherent(&ha->pdev->dev, sizeof(*sys_info),
   4034				      &sys_info_dma, GFP_KERNEL);
   4035	if (sys_info == NULL) {
   4036		DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n",
   4037		    ha->host_no, __func__));
   4038		return status;
   4039	}
   4040
   4041	memset(&mbox_cmd, 0, sizeof(mbox_cmd));
   4042	memset(&mbox_sts, 0, sizeof(mbox_sts));
   4043
   4044	mbox_cmd[0] = MBOX_CMD_GET_SYS_INFO;
   4045	mbox_cmd[1] = LSDW(sys_info_dma);
   4046	mbox_cmd[2] = MSDW(sys_info_dma);
   4047	mbox_cmd[4] = sizeof(*sys_info);
   4048
   4049	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 6, &mbox_cmd[0],
   4050	    &mbox_sts[0]) != QLA_SUCCESS) {
   4051		DEBUG2(printk("scsi%ld: %s: GET_SYS_INFO failed\n",
   4052		    ha->host_no, __func__));
   4053		goto exit_validate_mac82;
   4054	}
   4055
   4056	/* Make sure we receive the minimum required data to cache internally */
   4057	if (((is_qla8032(ha) || is_qla8042(ha)) ? mbox_sts[3] : mbox_sts[4]) <
   4058	    offsetof(struct mbx_sys_info, reserved)) {
   4059		DEBUG2(printk("scsi%ld: %s: GET_SYS_INFO data receive"
   4060		    " error (%x)\n", ha->host_no, __func__, mbox_sts[4]));
   4061		goto exit_validate_mac82;
   4062	}
   4063
   4064	/* Save M.A.C. address & serial_number */
   4065	ha->port_num = sys_info->port_num;
   4066	memcpy(ha->my_mac, &sys_info->mac_addr[0],
   4067	    min(sizeof(ha->my_mac), sizeof(sys_info->mac_addr)));
   4068	memcpy(ha->serial_number, &sys_info->serial_number,
   4069	    min(sizeof(ha->serial_number), sizeof(sys_info->serial_number)));
   4070	memcpy(ha->model_name, &sys_info->board_id_str,
   4071	       min(sizeof(ha->model_name), sizeof(sys_info->board_id_str)));
   4072	ha->phy_port_cnt = sys_info->phys_port_cnt;
   4073	ha->phy_port_num = sys_info->port_num;
   4074	ha->iscsi_pci_func_cnt = sys_info->iscsi_pci_func_cnt;
   4075
   4076	DEBUG2(printk("scsi%ld: %s: mac %pM serial %s\n",
   4077	    ha->host_no, __func__, ha->my_mac, ha->serial_number));
   4078
   4079	status = QLA_SUCCESS;
   4080
   4081exit_validate_mac82:
   4082	dma_free_coherent(&ha->pdev->dev, sizeof(*sys_info), sys_info,
   4083			  sys_info_dma);
   4084	return status;
   4085}
   4086
   4087/* Interrupt handling helpers. */
   4088
   4089int qla4_8xxx_intr_enable(struct scsi_qla_host *ha)
   4090{
   4091	uint32_t mbox_cmd[MBOX_REG_COUNT];
   4092	uint32_t mbox_sts[MBOX_REG_COUNT];
   4093
   4094	DEBUG2(ql4_printk(KERN_INFO, ha, "%s\n", __func__));
   4095
   4096	memset(&mbox_cmd, 0, sizeof(mbox_cmd));
   4097	memset(&mbox_sts, 0, sizeof(mbox_sts));
   4098	mbox_cmd[0] = MBOX_CMD_ENABLE_INTRS;
   4099	mbox_cmd[1] = INTR_ENABLE;
   4100	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],
   4101		&mbox_sts[0]) != QLA_SUCCESS) {
   4102		DEBUG2(ql4_printk(KERN_INFO, ha,
   4103		    "%s: MBOX_CMD_ENABLE_INTRS failed (0x%04x)\n",
   4104		    __func__, mbox_sts[0]));
   4105		return QLA_ERROR;
   4106	}
   4107	return QLA_SUCCESS;
   4108}
   4109
   4110int qla4_8xxx_intr_disable(struct scsi_qla_host *ha)
   4111{
   4112	uint32_t mbox_cmd[MBOX_REG_COUNT];
   4113	uint32_t mbox_sts[MBOX_REG_COUNT];
   4114
   4115	DEBUG2(ql4_printk(KERN_INFO, ha, "%s\n", __func__));
   4116
   4117	memset(&mbox_cmd, 0, sizeof(mbox_cmd));
   4118	memset(&mbox_sts, 0, sizeof(mbox_sts));
   4119	mbox_cmd[0] = MBOX_CMD_ENABLE_INTRS;
   4120	mbox_cmd[1] = INTR_DISABLE;
   4121	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],
   4122	    &mbox_sts[0]) != QLA_SUCCESS) {
   4123		DEBUG2(ql4_printk(KERN_INFO, ha,
   4124			"%s: MBOX_CMD_ENABLE_INTRS failed (0x%04x)\n",
   4125			__func__, mbox_sts[0]));
   4126		return QLA_ERROR;
   4127	}
   4128
   4129	return QLA_SUCCESS;
   4130}
   4131
   4132void
   4133qla4_82xx_enable_intrs(struct scsi_qla_host *ha)
   4134{
   4135	qla4_8xxx_intr_enable(ha);
   4136
   4137	spin_lock_irq(&ha->hardware_lock);
   4138	/* BIT 10 - reset */
   4139	qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
   4140	spin_unlock_irq(&ha->hardware_lock);
   4141	set_bit(AF_INTERRUPTS_ON, &ha->flags);
   4142}
   4143
   4144void
   4145qla4_82xx_disable_intrs(struct scsi_qla_host *ha)
   4146{
   4147	if (test_and_clear_bit(AF_INTERRUPTS_ON, &ha->flags))
   4148		qla4_8xxx_intr_disable(ha);
   4149
   4150	spin_lock_irq(&ha->hardware_lock);
   4151	/* BIT 10 - set */
   4152	qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
   4153	spin_unlock_irq(&ha->hardware_lock);
   4154}
   4155
   4156int
   4157qla4_8xxx_enable_msix(struct scsi_qla_host *ha)
   4158{
   4159	int ret;
   4160
   4161	ret = pci_alloc_irq_vectors(ha->pdev, QLA_MSIX_ENTRIES,
   4162			QLA_MSIX_ENTRIES, PCI_IRQ_MSIX);
   4163	if (ret < 0) {
   4164		ql4_printk(KERN_WARNING, ha,
   4165		    "MSI-X: Failed to enable support -- %d/%d\n",
   4166		    QLA_MSIX_ENTRIES, ret);
   4167		return ret;
   4168	}
   4169
   4170	ret = request_irq(pci_irq_vector(ha->pdev, 0),
   4171			qla4_8xxx_default_intr_handler, 0, "qla4xxx (default)",
   4172			ha);
   4173	if (ret)
   4174		goto out_free_vectors;
   4175
   4176	ret = request_irq(pci_irq_vector(ha->pdev, 1),
   4177			qla4_8xxx_msix_rsp_q, 0, "qla4xxx (rsp_q)", ha);
   4178	if (ret)
   4179		goto out_free_default_irq;
   4180
   4181	return 0;
   4182
   4183out_free_default_irq:
   4184	free_irq(pci_irq_vector(ha->pdev, 0), ha);
   4185out_free_vectors:
   4186	pci_free_irq_vectors(ha->pdev);
   4187	return ret;
   4188}
   4189
   4190int qla4_8xxx_check_init_adapter_retry(struct scsi_qla_host *ha)
   4191{
   4192	int status = QLA_SUCCESS;
   4193
   4194	/* Dont retry adapter initialization if IRQ allocation failed */
   4195	if (!test_bit(AF_IRQ_ATTACHED, &ha->flags)) {
   4196		ql4_printk(KERN_WARNING, ha, "%s: Skipping retry of adapter initialization as IRQs are not attached\n",
   4197			   __func__);
   4198		status = QLA_ERROR;
   4199		goto exit_init_adapter_failure;
   4200	}
   4201
   4202	/* Since interrupts are registered in start_firmware for
   4203	 * 8xxx, release them here if initialize_adapter fails
   4204	 * and retry adapter initialization */
   4205	qla4xxx_free_irqs(ha);
   4206
   4207exit_init_adapter_failure:
   4208	return status;
   4209}