[SCSI] qla4xxx: Capture minidump for ISP82XX on firmware failure

Added support to capture dump (Minidump) which allows us to
catpure a snapshot of the firmware/hardware states at the time
of firmware failure

Signed-off-by: Tej Parkash <tej.parkash@qlogic.com>
Signed-off-by: Shyam Sundar <shyam.sundar@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
diff --git a/drivers/scsi/qla4xxx/ql4_nx.h b/drivers/scsi/qla4xxx/ql4_nx.h
index dc7500e..3025847 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.h
+++ b/drivers/scsi/qla4xxx/ql4_nx.h
@@ -792,4 +792,196 @@
 #define MIU_TEST_AGT_WRDATA_UPPER_LO	(0x0b0)
 #define	MIU_TEST_AGT_WRDATA_UPPER_HI	(0x0b4)
 
+/* Minidump related */
+
+/* Entry Type Defines */
+#define QLA82XX_RDNOP	0
+#define QLA82XX_RDCRB	1
+#define QLA82XX_RDMUX	2
+#define QLA82XX_QUEUE	3
+#define QLA82XX_BOARD	4
+#define QLA82XX_RDOCM	6
+#define QLA82XX_PREGS	7
+#define QLA82XX_L1DTG	8
+#define QLA82XX_L1ITG	9
+#define QLA82XX_L1DAT	11
+#define QLA82XX_L1INS	12
+#define QLA82XX_L2DTG	21
+#define QLA82XX_L2ITG	22
+#define QLA82XX_L2DAT	23
+#define QLA82XX_L2INS	24
+#define QLA82XX_RDROM	71
+#define QLA82XX_RDMEM	72
+#define QLA82XX_CNTRL	98
+#define QLA82XX_RDEND	255
+
+/* Opcodes for Control Entries.
+ * These Flags are bit fields.
+ */
+#define QLA82XX_DBG_OPCODE_WR		0x01
+#define QLA82XX_DBG_OPCODE_RW		0x02
+#define QLA82XX_DBG_OPCODE_AND		0x04
+#define QLA82XX_DBG_OPCODE_OR		0x08
+#define QLA82XX_DBG_OPCODE_POLL		0x10
+#define QLA82XX_DBG_OPCODE_RDSTATE	0x20
+#define QLA82XX_DBG_OPCODE_WRSTATE	0x40
+#define QLA82XX_DBG_OPCODE_MDSTATE	0x80
+
+/* Driver Flags */
+#define QLA82XX_DBG_SKIPPED_FLAG	0x80 /* driver skipped this entry  */
+#define QLA82XX_DBG_SIZE_ERR_FLAG	0x40 /* Entry vs Capture size
+					      * mismatch */
+
+/* Driver_code is for driver to write some info about the entry
+ * currently not used.
+ */
+struct qla82xx_minidump_entry_hdr {
+	uint32_t entry_type;
+	uint32_t entry_size;
+	uint32_t entry_capture_size;
+	struct {
+		uint8_t entry_capture_mask;
+		uint8_t entry_code;
+		uint8_t driver_code;
+		uint8_t driver_flags;
+	} d_ctrl;
+};
+
+/*  Read CRB entry header */
+struct qla82xx_minidump_entry_crb {
+	struct qla82xx_minidump_entry_hdr h;
+	uint32_t addr;
+	struct {
+		uint8_t addr_stride;
+		uint8_t state_index_a;
+		uint16_t poll_timeout;
+	} crb_strd;
+	uint32_t data_size;
+	uint32_t op_count;
+
+	struct {
+		uint8_t opcode;
+		uint8_t state_index_v;
+		uint8_t shl;
+		uint8_t shr;
+	} crb_ctrl;
+
+	uint32_t value_1;
+	uint32_t value_2;
+	uint32_t value_3;
+};
+
+struct qla82xx_minidump_entry_cache {
+	struct qla82xx_minidump_entry_hdr h;
+	uint32_t tag_reg_addr;
+	struct {
+		uint16_t tag_value_stride;
+		uint16_t init_tag_value;
+	} addr_ctrl;
+	uint32_t data_size;
+	uint32_t op_count;
+	uint32_t control_addr;
+	struct {
+		uint16_t write_value;
+		uint8_t poll_mask;
+		uint8_t poll_wait;
+	} cache_ctrl;
+	uint32_t read_addr;
+	struct {
+		uint8_t read_addr_stride;
+		uint8_t read_addr_cnt;
+		uint16_t rsvd_1;
+	} read_ctrl;
+};
+
+/* Read OCM */
+struct qla82xx_minidump_entry_rdocm {
+	struct qla82xx_minidump_entry_hdr h;
+	uint32_t rsvd_0;
+	uint32_t rsvd_1;
+	uint32_t data_size;
+	uint32_t op_count;
+	uint32_t rsvd_2;
+	uint32_t rsvd_3;
+	uint32_t read_addr;
+	uint32_t read_addr_stride;
+};
+
+/* Read Memory */
+struct qla82xx_minidump_entry_rdmem {
+	struct qla82xx_minidump_entry_hdr h;
+	uint32_t rsvd[6];
+	uint32_t read_addr;
+	uint32_t read_data_size;
+};
+
+/* Read ROM */
+struct qla82xx_minidump_entry_rdrom {
+	struct qla82xx_minidump_entry_hdr h;
+	uint32_t rsvd[6];
+	uint32_t read_addr;
+	uint32_t read_data_size;
+};
+
+/* Mux entry */
+struct qla82xx_minidump_entry_mux {
+	struct qla82xx_minidump_entry_hdr h;
+	uint32_t select_addr;
+	uint32_t rsvd_0;
+	uint32_t data_size;
+	uint32_t op_count;
+	uint32_t select_value;
+	uint32_t select_value_stride;
+	uint32_t read_addr;
+	uint32_t rsvd_1;
+};
+
+/* Queue entry */
+struct qla82xx_minidump_entry_queue {
+	struct qla82xx_minidump_entry_hdr h;
+	uint32_t select_addr;
+	struct {
+		uint16_t queue_id_stride;
+		uint16_t rsvd_0;
+	} q_strd;
+	uint32_t data_size;
+	uint32_t op_count;
+	uint32_t rsvd_1;
+	uint32_t rsvd_2;
+	uint32_t read_addr;
+	struct {
+		uint8_t read_addr_stride;
+		uint8_t read_addr_cnt;
+		uint16_t rsvd_3;
+	} rd_strd;
+};
+
+#define QLA82XX_MINIDUMP_OCM0_SIZE		(256 * 1024)
+#define QLA82XX_MINIDUMP_L1C_SIZE		(256 * 1024)
+#define QLA82XX_MINIDUMP_L2C_SIZE		1572864
+#define QLA82XX_MINIDUMP_COMMON_STR_SIZE	0
+#define QLA82XX_MINIDUMP_FCOE_STR_SIZE		0
+#define QLA82XX_MINIDUMP_MEM_SIZE		0
+#define QLA82XX_MAX_ENTRY_HDR			4
+
+struct qla82xx_minidump {
+	uint32_t md_ocm0_data[QLA82XX_MINIDUMP_OCM0_SIZE];
+	uint32_t md_l1c_data[QLA82XX_MINIDUMP_L1C_SIZE];
+	uint32_t md_l2c_data[QLA82XX_MINIDUMP_L2C_SIZE];
+	uint32_t md_cs_data[QLA82XX_MINIDUMP_COMMON_STR_SIZE];
+	uint32_t md_fcoes_data[QLA82XX_MINIDUMP_FCOE_STR_SIZE];
+	uint32_t md_mem_data[QLA82XX_MINIDUMP_MEM_SIZE];
+};
+
+#define MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE	0x129
+#define RQST_TMPLT_SIZE				0x0
+#define RQST_TMPLT				0x1
+#define MD_DIRECT_ROM_WINDOW			0x42110030
+#define MD_DIRECT_ROM_READ_BASE			0x42150000
+#define MD_MIU_TEST_AGT_CTRL			0x41000090
+#define MD_MIU_TEST_AGT_ADDR_LO			0x41000094
+#define MD_MIU_TEST_AGT_ADDR_HI			0x41000098
+
+static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8,
+				0x410000AC, 0x410000B8, 0x410000BC };
 #endif