lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1287791637-10329-20-git-send-email-maximlevitsky@gmail.com>
Date:	Sat, 23 Oct 2010 01:53:47 +0200
From:	Maxim Levitsky <maximlevitsky@...il.com>
To:	Alex Dubov <oakad@...oo.com>
Cc:	Andrew Morton <akpm@...ux-foundation.org>,
	LKML <linux-kernel@...r.kernel.org>,
	Maxim Levitsky <maximlevitsky@...il.com>
Subject: [PATCH 19/29] memstick: jmb38x_ms: add register read/write functions

All over the code it is a bit easier to see the
register access with this patch. Also set/clear mask
helpers refactor code a bit, but the biggest reason
for this patch is to make it possible to trace register
read/writes with a flip of a module param.

Currently these functions are unused, but will be by later code

Signed-off-by: Maxim Levitsky <maximlevitsky@...il.com>
---
 drivers/memstick/host/jmb38x_ms.c |  102 ++++++++++++++++++++++++++++++++++++-
 drivers/memstick/host/jmb38x_ms.h |    1 +
 2 files changed, 102 insertions(+), 1 deletions(-)

diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index 295f755..bcdb785 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -22,8 +22,86 @@
 static int no_dma;
 static int debug;
 
+/* Read a register*/
+static inline u32 j38ms_read_reg(struct j38ms_host *host, int address)
+{
+	u32 value =  readl(host->addr + address);
+	dbg_reg(host, "reg 0x%02x == 0x%08x", address, value);
+	return value;
+}
+
+/* Write a register */
+static inline void j38ms_write_reg(struct j38ms_host *host,
+						int address, u32 value)
+{
+	dbg_reg(host, "reg 0x%02x <- 0x%08x", address, cpu_to_le32(value));
+	writel(value, host->addr + address);
+}
+
+/* Read a register without endiannes conversion*/
+static inline u32 j38ms_read_reg_raw(struct j38ms_host *host, int address)
+{
+	u32 value =  __raw_readl(host->addr + address);
+	dbg_reg(host, "reg 0x%02x == 0x%08x", address, cpu_to_le32(value));
+	return value;
+}
+
+/* Write a register without endiannes conversion */
+static inline void j38ms_write_reg_raw(struct j38ms_host *host,
+						int address, u32 value)
+{
+	dbg_reg(host, "reg 0x%02x <- 0x%08x", address, value);
+	__raw_writel(value, host->addr + address);
+}
+
+/* Set specific bits in a register*/
+static inline void j38ms_set_reg_mask(struct j38ms_host *host,
+						int address, u32 mask)
+{
+	u32 reg = readl(host->addr + address);
+	dbg_reg(host, "reg 0x%02x |= 0x%08x (old =0x%08x)", address, mask, reg);
+	writel(reg | mask , host->addr + address);
+}
+
+/* Clear specific bits in a register*/
+static inline void j38ms_clear_reg_mask(struct j38ms_host *host,
+						int address, u32 mask)
+{
+	u32 reg = readl(host->addr + address);
+	dbg_reg(host, "reg 0x%02x &= 0x%08x (old = 0x%08x, mask = 0x%08x)",
+						address, ~mask, reg, mask);
+	writel(reg & ~mask, host->addr + address);
+}
+
+/* Reads one DWORD via PIO. returns -EAGAIN if fifo is empty */
+static inline int j38ms_read_fifo_dword_pio(struct j38ms_host *host, u32 *dword)
+{
+	if (unlikely(j38ms_read_reg(host, STATUS) & STATUS_FIFO_EMPTY)) {
+		dbg(host, "PIO: FIFO empty");
+		return -EAGAIN;
+	}
+
+	*dword = j38ms_read_reg_raw(host, DATA);
+	dbg(host, "PIO: read: %08x", *dword);
+	return 0;
+}
+
+/* Writes one DWORD via PIO. returns -EAGAIN if fifo is full */
+static inline int j38ms_write_fifo_dword_pio(struct j38ms_host *host, u32 dword)
+{
+	if (unlikely(j38ms_read_reg(host, STATUS) & STATUS_FIFO_FULL)) {
+		dbg(host, "PIO: FIFO full");
+		return -EAGAIN;
+	}
+
+	dbg(host, "PIO: writing: %08x", dword);
+	j38ms_write_reg_raw(host, DATA, dword);
+	return 0;
+}
+
+/* Read TPC data using PIO */
 static unsigned int j38ms_read_fifo_pio(struct j38ms_host *host,
-					unsigned char *buf, unsigned int length)
+				unsigned char *buf, unsigned int length)
 {
 	unsigned int off = 0;
 
@@ -60,6 +138,7 @@ static unsigned int j38ms_read_fifo_pio(struct j38ms_host *host,
 	return off;
 }
 
+/* Write TPC data through normal PIO fifo */
 static unsigned int j38ms_write_fifo_pio(struct j38ms_host *host,
 					 unsigned char *buf,
 					 unsigned int length)
@@ -113,6 +192,7 @@ static unsigned int j38ms_write_fifo_pio(struct j38ms_host *host,
 	return off;
 }
 
+/* Transfer data between current request and FIFO */
 static int j38ms_transfer_data(struct j38ms_host *host)
 {
 	unsigned int length;
@@ -180,6 +260,7 @@ static int j38ms_transfer_data(struct j38ms_host *host)
 	return length;
 }
 
+/* Read short TPC data (up to 8 bytes) via 2 special registers*/
 static unsigned int j38ms_read_tpc_inline(struct j38ms_host *host,
 					    unsigned char *buf,
 					    unsigned int length)
@@ -206,6 +287,7 @@ static unsigned int j38ms_read_tpc_inline(struct j38ms_host *host,
 	return off;
 }
 
+/* Write short TPC data (up to 8 bytes) through 2 special registers */
 static unsigned int j38ms_write_tpc_inline(struct j38ms_host *host,
 					     unsigned char *buf,
 					     unsigned int length)
@@ -232,6 +314,19 @@ static unsigned int j38ms_write_tpc_inline(struct j38ms_host *host,
 	return off;
 }
 
+/*
+ * Start execution of a TPC:
+ * NOTES:
+ *
+ * PIO writes trigger wierd hardware bug that causes DMA writes
+ *  to fail.
+ *
+ * length alignmemt:
+ *	Short (<=8) TPC don't have any alignment problems.
+ *	DMA read/writes must be 4 aligned
+ *	PIO _reads_ must be aligned. Writes can be not aligned
+ *
+ */
 static int j38ms_execute_tpc(struct memstick_host *msh)
 {
 	struct j38ms_host *host = memstick_priv(msh);
@@ -330,6 +425,7 @@ static int j38ms_execute_tpc(struct memstick_host *msh)
 	return 0;
 }
 
+/* Cleanups execution of current TPC */
 static void j38ms_complete_tpc(struct memstick_host *msh, int last)
 {
 	struct j38ms_host *host = memstick_priv(msh);
@@ -380,6 +476,7 @@ static void j38ms_complete_tpc(struct memstick_host *msh, int last)
 	}
 }
 
+/* Interrupt handler */
 static irqreturn_t j38ms_isr(int irq, void *dev_id)
 {
 	struct memstick_host *msh = dev_id;
@@ -452,6 +549,7 @@ static irqreturn_t j38ms_isr(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+/* Timer that is executed in absense of the interrupt */
 static void j38ms_irq_timeout(unsigned long data)
 {
 	struct memstick_host *msh = (struct memstick_host *)data;
@@ -496,6 +594,7 @@ static void j38ms_submit_req(struct memstick_host *msh)
 	tasklet_schedule(&host->notify);
 }
 
+/* hardware reset */
 static int j38ms_reset(struct j38ms_host *host)
 {
 	int cnt;
@@ -700,6 +799,7 @@ static struct memstick_host *j38ms_alloc_host(struct j38ms *jm, int cnt)
 		return NULL;
 
 	host = memstick_priv(msh);
+	host->msh = msh;
 	host->chip = jm;
 	host->addr = ioremap(pci_resource_start(jm->pdev, cnt),
 			     pci_resource_len(jm->pdev, cnt));
diff --git a/drivers/memstick/host/jmb38x_ms.h b/drivers/memstick/host/jmb38x_ms.h
index 44e1fc1..35b8bca 100644
--- a/drivers/memstick/host/jmb38x_ms.h
+++ b/drivers/memstick/host/jmb38x_ms.h
@@ -144,6 +144,7 @@
 
 struct j38ms_host {
 	struct j38ms            *chip;
+	struct memstick_host    *msh;
 	void __iomem            *addr;
 	spinlock_t              lock;
 	struct tasklet_struct   notify;
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ