From c65d94f7d0e0c511794ea1f42ddf01e66f97e236 Mon Sep 17 00:00:00 2001
From: Zachary T Welch <zw@superlucidity.net>
Date: Thu, 3 Dec 2009 17:14:07 -0800
Subject: add flash/nor/core.[ch]

The newly moved flash TCL routines access the internals of the module
too much.  Fix the layering issues by adding new core NOR flash APIs:

<flash/nor/core.h>:
  - flash_driver_find_by_name() - self-descriptive

<flash/nor/imp.h>:
  - flash_bank_add()            - encapsulates adding banks to bank list
  - flash_bank_list()           - encapsulates retreiving bank list

This allows the externs in flash/nor/imp.h to be removed, and
these mechanisms may now be re-used by other flash module code.
---
 src/flash/nor/Makefile.am |  1 +
 src/flash/nor/core.c      | 65 +++++++++++++++++++++++++++++++
 src/flash/nor/core.h      | 31 +++++++++++++++
 src/flash/nor/imp.h       | 15 +++++--
 src/flash/nor/tcl.c       | 99 +++++++++++++++++++----------------------------
 5 files changed, 149 insertions(+), 62 deletions(-)
 create mode 100644 src/flash/nor/core.c
 create mode 100644 src/flash/nor/core.h

diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am
index ed9ebb30..499ebfa2 100644
--- a/src/flash/nor/Makefile.am
+++ b/src/flash/nor/Makefile.am
@@ -2,6 +2,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src
 
 noinst_LTLIBRARIES = libocdflashnor.la
 libocdflashnor_la_SOURCES = \
+	core.c \
 	tcl.c \
 	$(NOR_DRIVERS)
 
diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c
new file mode 100644
index 00000000..a69c3f49
--- /dev/null
+++ b/src/flash/nor/core.c
@@ -0,0 +1,65 @@
+/***************************************************************************
+ *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <flash/flash.h>
+#include <flash/nor/imp.h>
+
+// in flash.c, to be moved here
+extern struct flash_driver *flash_drivers[];
+extern struct flash_bank *flash_banks;
+
+struct flash_driver *flash_driver_find_by_name(const char *name)
+{
+	for (unsigned i = 0; flash_drivers[i]; i++)
+	{
+		if (strcmp(name, flash_drivers[i]->name) == 0)
+			return flash_drivers[i];
+	}
+	return NULL;
+}
+
+void flash_bank_add(struct flash_bank *bank)
+{
+	/* put flash bank in linked list */
+	unsigned bank_num = 0;
+	if (flash_banks)
+	{
+		/* find last flash bank */
+		struct flash_bank *p = flash_banks;
+		while (NULL != p->next)
+		{
+			bank_num += 1;
+			p = p->next;
+		}
+		p->next = bank;
+		bank_num += 1;
+	}
+	else
+		flash_banks = bank;
+
+	bank->bank_number = bank_num;
+}
+
+struct flash_bank *flash_bank_list(void)
+{
+	return flash_banks;
+}
diff --git a/src/flash/nor/core.h b/src/flash/nor/core.h
new file mode 100644
index 00000000..0c6a804f
--- /dev/null
+++ b/src/flash/nor/core.h
@@ -0,0 +1,31 @@
+/***************************************************************************
+ *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifndef FLASH_NOR_CORE_H
+#define FLASH_NOR_CORE_H
+
+#include <flash/flash.h>
+
+/**
+ * Find a NOR flash driver by its name.
+ * @param name The name of the requested driver.
+ * @returns The flash_driver called @c name, or NULL if not found.
+ */
+struct flash_driver *flash_driver_find_by_name(const char *name);
+
+#endif // FLASH_NOR_CORE_H
diff --git a/src/flash/nor/imp.h b/src/flash/nor/imp.h
index 29d7f7eb..23ac476e 100644
--- a/src/flash/nor/imp.h
+++ b/src/flash/nor/imp.h
@@ -19,9 +19,18 @@
 #ifndef FLASH_NOR_IMP_H
 #define FLASH_NOR_IMP_H
 
-#include <flash/flash.h>
+// this is an internal header
+#include "core.h"
 
-extern struct flash_driver *flash_drivers[];
-extern struct flash_bank *flash_banks;
+/**
+ * Adds a new NOR bank to the global list of banks.
+ * @params bank The bank that should be added.
+ */
+void flash_bank_add(struct flash_bank *bank);
+
+/**
+ * @return The first bank in the global list.
+ */
+struct flash_bank *flash_bank_list(void);
 
 #endif // FLASH_NOR_IMP_H
diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c
index 8c13241d..b00516d9 100644
--- a/src/flash/nor/tcl.c
+++ b/src/flash/nor/tcl.c
@@ -44,84 +44,65 @@ COMMAND_HANDLER(handle_flash_bank_command)
 	}
 
 	const char *driver_name = CMD_ARGV[0];
-	for (unsigned i = 0; flash_drivers[i]; i++)
+	struct flash_driver *driver = flash_driver_find_by_name(driver_name);
+	if (NULL == driver)
 	{
-		if (strcmp(driver_name, flash_drivers[i]->name) != 0)
-			continue;
-
-		/* register flash specific commands */
-		if (NULL != flash_drivers[i]->commands)
-		{
-			int retval = register_commands(CMD_CTX, NULL,
-					flash_drivers[i]->commands);
-			if (ERROR_OK != retval)
-			{
-				LOG_ERROR("couldn't register '%s' commands",
-						driver_name);
-				return ERROR_FAIL;
-			}
-		}
+		/* no matching flash driver found */
+		LOG_ERROR("flash driver '%s' not found", driver_name);
+		return ERROR_FAIL;
+	}
 
-		struct flash_bank *p, *c;
-		c = malloc(sizeof(struct flash_bank));
-		c->name = strdup(bank_name);
-		c->target = target;
-		c->driver = flash_drivers[i];
-		c->driver_priv = NULL;
-		COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], c->base);
-		COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], c->size);
-		COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], c->chip_width);
-		COMMAND_PARSE_NUMBER(int, CMD_ARGV[4], c->bus_width);
-		c->num_sectors = 0;
-		c->sectors = NULL;
-		c->next = NULL;
-
-		int retval;
-		retval = CALL_COMMAND_HANDLER(flash_drivers[i]->flash_bank_command, c);
+	/* register flash specific commands */
+	if (NULL != driver->commands)
+	{
+		int retval = register_commands(CMD_CTX, NULL,
+				driver->commands);
 		if (ERROR_OK != retval)
 		{
-			LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32,
-					driver_name, c->base);
-			free(c);
-			return retval;
-		}
-
-		/* put flash bank in linked list */
-		if (flash_banks)
-		{
-			int	bank_num = 0;
-			/* find last flash bank */
-			for (p = flash_banks; p && p->next; p = p->next) bank_num++;
-			if (p)
-				p->next = c;
-			c->bank_number = bank_num + 1;
-		}
-		else
-		{
-			flash_banks = c;
-			c->bank_number = 0;
+			LOG_ERROR("couldn't register '%s' commands",
+					driver_name);
+			return ERROR_FAIL;
 		}
+	}
 
-		return ERROR_OK;
+	struct flash_bank *c = malloc(sizeof(*c));
+	c->name = strdup(bank_name);
+	c->target = target;
+	c->driver = driver;
+	c->driver_priv = NULL;
+	COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], c->base);
+	COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], c->size);
+	COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], c->chip_width);
+	COMMAND_PARSE_NUMBER(int, CMD_ARGV[4], c->bus_width);
+	c->num_sectors = 0;
+	c->sectors = NULL;
+	c->next = NULL;
+
+	int retval;
+	retval = CALL_COMMAND_HANDLER(driver->flash_bank_command, c);
+	if (ERROR_OK != retval)
+	{
+		LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32,
+				driver_name, c->base);
+		free(c);
+		return retval;
 	}
 
-	/* no matching flash driver found */
-	LOG_ERROR("flash driver '%s' not found", driver_name);
-	return ERROR_FAIL;
+	return ERROR_OK;
+
 }
 
 
 static int jim_flash_banks(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 {
-	struct flash_bank *p;
-
 	if (argc != 1) {
 		Jim_WrongNumArgs(interp, 1, argv, "no arguments to flash_banks command");
 		return JIM_ERR;
 	}
 
 	Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
-	for (p = flash_banks; p; p = p->next)
+
+	for (struct flash_bank *p = flash_bank_list(); p; p = p->next)
 	{
 		Jim_Obj *elem = Jim_NewListObj(interp, NULL, 0);
 
-- 
cgit v1.2.3