[patch 5/9] ipr: add hardware assisted smart dump functionality

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds the hardware assisted smart dump functionality for the next
generation IOA PCI interface chip.

Signea-off-by: Wayne Boyer <wayneb@xxxxxxxxxxxxxxxxxx>
---

 drivers/scsi/ipr.c |   79 ++++++++++++++++++++++++++++++++++++++++++-----------
 drivers/scsi/ipr.h |   16 ++++++----
 2 files changed, 74 insertions(+), 21 deletions(-)

Index: b/drivers/scsi/ipr.c
===================================================================
--- a/drivers/scsi/ipr.c	2010-02-19 08:08:33.000000000 -0800
+++ b/drivers/scsi/ipr.c	2010-02-19 08:08:37.000000000 -0800
@@ -142,7 +142,9 @@ static const struct ipr_chip_cfg_t ipr_c
 			.ioarrin_reg = 0x00070,
 			.sense_uproc_interrupt_reg = 0x00020,
 			.set_uproc_interrupt_reg = 0x00020,
-			.clr_uproc_interrupt_reg = 0x00028
+			.clr_uproc_interrupt_reg = 0x00028,
+			.dump_addr_reg = 0x00064,
+			.dump_data_reg = 0x00068
 		}
 	},
 };
@@ -2514,6 +2516,31 @@ static int ipr_wait_iodbg_ack(struct ipr
 }

 /**
+ * ipr_get_sis64_dump_data_section - Dump IOA memory
+ * @ioa_cfg:			ioa config struct
+ * @start_addr:			adapter address to dump
+ * @dest:			destination kernel buffer
+ * @length_in_words:		length to dump in 4 byte words
+ *
+ * Return value:
+ * 	0 on success
+ **/
+static int ipr_get_sis64_dump_data_section(struct ipr_ioa_cfg *ioa_cfg,
+					   u32 start_addr,
+					   __be32 *dest, u32 length_in_words)
+{
+	int i;
+
+	for (i = 0; i < length_in_words; i++) {
+		writel(start_addr+(i*4), ioa_cfg->regs.dump_addr_reg);
+		*dest = cpu_to_be32(readl(ioa_cfg->regs.dump_data_reg));
+		dest++;
+	}
+
+	return 0;
+}
+
+/**
  * ipr_get_ldump_data_section - Dump IOA memory
  * @ioa_cfg:			ioa config struct
  * @start_addr:			adapter address to dump
@@ -2530,6 +2557,10 @@ static int ipr_get_ldump_data_section(st
 	volatile u32 temp_pcii_reg;
 	int i, delay = 0;

+	if (ioa_cfg->sis64)
+		return ipr_get_sis64_dump_data_section(ioa_cfg, start_addr,
+						       dest, length_in_words);
+
 	/* Write IOA interrupt reg starting LDUMP state  */
 	writel((IPR_UPROCI_RESET_ALERT | IPR_UPROCI_IO_DEBUG_ALERT),
 	       ioa_cfg->regs.set_uproc_interrupt_reg);
@@ -2787,6 +2818,7 @@ static void ipr_get_ioa_dump(struct ipr_
 	u32 num_entries, start_off, end_off;
 	u32 bytes_to_copy, bytes_copied, rc;
 	struct ipr_sdt *sdt;
+	int valid = 1;
 	int i;

 	ENTER;
@@ -2800,7 +2832,7 @@ static void ipr_get_ioa_dump(struct ipr_

 	start_addr = readl(ioa_cfg->ioa_mailbox);

-	if (!ipr_sdt_is_fmt2(start_addr)) {
+	if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(start_addr)) {
 		dev_err(&ioa_cfg->pdev->dev,
 			"Invalid dump table format: %lx\n", start_addr);
 		spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -2829,7 +2861,6 @@ static void ipr_get_ioa_dump(struct ipr_

 	/* IOA Dump entry */
 	ipr_init_dump_entry_hdr(&ioa_dump->hdr);
-	ioa_dump->format = IPR_SDT_FMT2;
 	ioa_dump->hdr.len = 0;
 	ioa_dump->hdr.data_type = IPR_DUMP_DATA_TYPE_BINARY;
 	ioa_dump->hdr.id = IPR_DUMP_IOA_DUMP_ID;
@@ -2844,7 +2875,8 @@ static void ipr_get_ioa_dump(struct ipr_
 					sizeof(struct ipr_sdt) / sizeof(__be32));

 	/* Smart Dump table is ready to use and the first entry is valid */
-	if (rc || (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE)) {
+	if (rc || ((be32_to_cpu(sdt->hdr.state) != IPR_FMT3_SDT_READY_TO_USE) &&
+	    (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) {
 		dev_err(&ioa_cfg->pdev->dev,
 			"Dump of IOA failed. Dump table not valid: %d, %X.\n",
 			rc, be32_to_cpu(sdt->hdr.state));
@@ -2868,12 +2900,19 @@ static void ipr_get_ioa_dump(struct ipr_
 		}

 		if (sdt->entry[i].flags & IPR_SDT_VALID_ENTRY) {
-			sdt_word = be32_to_cpu(sdt->entry[i].bar_str_offset);
-			start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK;
-			end_off = be32_to_cpu(sdt->entry[i].end_offset);
+			sdt_word = be32_to_cpu(sdt->entry[i].start_token);
+			if (ioa_cfg->sis64)
+				bytes_to_copy = be32_to_cpu(sdt->entry[i].end_token);
+			else {
+				start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK;
+				end_off = be32_to_cpu(sdt->entry[i].end_token);

-			if (ipr_sdt_is_fmt2(sdt_word) && sdt_word) {
-				bytes_to_copy = end_off - start_off;
+				if (ipr_sdt_is_fmt2(sdt_word) && sdt_word)
+					bytes_to_copy = end_off - start_off;
+				else
+					valid = 0;
+			}
+			if (valid) {
 				if (bytes_to_copy > IPR_MAX_IOA_DUMP_SIZE) {
 					sdt->entry[i].flags &= ~IPR_SDT_VALID_ENTRY;
 					continue;
@@ -7202,7 +7241,7 @@ static void ipr_get_unit_check_buffer(st

 	mailbox = readl(ioa_cfg->ioa_mailbox);

-	if (!ipr_sdt_is_fmt2(mailbox)) {
+	if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(mailbox)) {
 		ipr_unit_check_no_data(ioa_cfg);
 		return;
 	}
@@ -7211,15 +7250,20 @@ static void ipr_get_unit_check_buffer(st
 	rc = ipr_get_ldump_data_section(ioa_cfg, mailbox, (__be32 *) &sdt,
 					(sizeof(struct ipr_uc_sdt)) / sizeof(__be32));

-	if (rc || (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE) ||
-	    !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY)) {
+	if (rc || !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY) ||
+	    ((be32_to_cpu(sdt.hdr.state) != IPR_FMT3_SDT_READY_TO_USE) &&
+	    (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) {
 		ipr_unit_check_no_data(ioa_cfg);
 		return;
 	}

 	/* Find length of the first sdt entry (UC buffer) */
-	length = (be32_to_cpu(sdt.entry[0].end_offset) -
-		  be32_to_cpu(sdt.entry[0].bar_str_offset)) & IPR_FMT2_MBX_ADDR_MASK;
+	if (be32_to_cpu(sdt.hdr.state) == IPR_FMT3_SDT_READY_TO_USE)
+		length = be32_to_cpu(sdt.entry[0].end_token);
+	else
+		length = (be32_to_cpu(sdt.entry[0].end_token) -
+			  be32_to_cpu(sdt.entry[0].start_token)) &
+			  IPR_FMT2_MBX_ADDR_MASK;

 	hostrcb = list_entry(ioa_cfg->hostrcb_free_q.next,
 			     struct ipr_hostrcb, queue);
@@ -7227,7 +7271,7 @@ static void ipr_get_unit_check_buffer(st
 	memset(&hostrcb->hcam, 0, sizeof(hostrcb->hcam));

 	rc = ipr_get_ldump_data_section(ioa_cfg,
-					be32_to_cpu(sdt.entry[0].bar_str_offset),
+					be32_to_cpu(sdt.entry[0].start_token),
 					(__be32 *)&hostrcb->hcam,
 					min(length, (int)sizeof(hostrcb->hcam)) / sizeof(__be32));

@@ -8202,6 +8246,11 @@ static void __devinit ipr_init_ioa_cfg(s
 	t->sense_uproc_interrupt_reg = base + p->sense_uproc_interrupt_reg;
 	t->set_uproc_interrupt_reg = base + p->set_uproc_interrupt_reg;
 	t->clr_uproc_interrupt_reg = base + p->clr_uproc_interrupt_reg;
+
+	if (ioa_cfg->sis64) {
+		t->dump_addr_reg = base + p->dump_addr_reg;
+		t->dump_data_reg = base + p->dump_data_reg;
+	}
 }

 /**
Index: b/drivers/scsi/ipr.h
===================================================================
--- a/drivers/scsi/ipr.h	2010-02-19 08:08:33.000000000 -0800
+++ b/drivers/scsi/ipr.h	2010-02-19 08:08:37.000000000 -0800
@@ -228,6 +228,7 @@
 #define IPR_SDT_FMT2_BAR5_SEL				0x5
 #define IPR_SDT_FMT2_EXP_ROM_SEL			0x8
 #define IPR_FMT2_SDT_READY_TO_USE			0xC4D4E3F2
+#define IPR_FMT3_SDT_READY_TO_USE			0xC4D4E3F3
 #define IPR_DOORBELL					0x82800000
 #define IPR_RUNTIME_RESET				0x40000000

@@ -1093,10 +1094,9 @@ struct ipr_hostrcb {

 /* IPR smart dump table structures */
 struct ipr_sdt_entry {
-	__be32 bar_str_offset;
-	__be32 end_offset;
-	u8 entry_byte;
-	u8 reserved[3];
+	__be32 start_token;
+	__be32 end_token;
+	u8 reserved[4];

 	u8 flags;
 #define IPR_SDT_ENDIAN		0x80
@@ -1204,6 +1204,9 @@ struct ipr_interrupt_offsets {
 	unsigned long sense_uproc_interrupt_reg;
 	unsigned long set_uproc_interrupt_reg;
 	unsigned long clr_uproc_interrupt_reg;
+
+	unsigned long dump_addr_reg;
+	unsigned long dump_data_reg;
 };

 struct ipr_interrupts {
@@ -1217,6 +1220,9 @@ struct ipr_interrupts {
 	void __iomem *sense_uproc_interrupt_reg;
 	void __iomem *set_uproc_interrupt_reg;
 	void __iomem *clr_uproc_interrupt_reg;
+
+	void __iomem *dump_addr_reg;
+	void __iomem *dump_data_reg;
 };

 struct ipr_chip_cfg_t {
@@ -1536,8 +1542,6 @@ struct ipr_ioa_dump {
 	u32 next_page_index;
 	u32 page_offset;
 	u32 format;
-#define IPR_SDT_FMT2		2
-#define IPR_SDT_UNKNOWN		3
 }__attribute__((packed, aligned (4)));

 struct ipr_dump {

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux