mtd/drivers/mtd/maps ichxrom.c,1.4,1.5
ebiederman at lnxi.com
ebiederman at lnxi.com
Wed Jul 14 01:17:58 EDT 2004
Update of /home/cvs/mtd/drivers/mtd/maps
In directory phoenix.infradead.org:/tmp/cvs-serv32012/drivers/mtd/maps
Modified Files:
ichxrom.c
Log Message:
- In cfi_cmdset_0002 add error detection
- In cfi_cmdset_0002 add retries in do_write_one_word
For transient errors this make progress more likely.
user space can only really retry at the block/sector level.
- In ichxrom add support for using non-firmware hub flash parts
- In ichxrom add support for using cfi flash parts
- In ichxrom add support for probing multiple bank widths.
I still don't support multiple bank widths but this is as close as I come.
Index: ichxrom.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/maps/ichxrom.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ichxrom.c 12 Jul 2004 22:38:29 -0000 1.4
+++ ichxrom.c 14 Jul 2004 05:17:56 -0000 1.5
@@ -15,6 +15,7 @@
#include <linux/config.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
+#include <linux/mtd/cfi.h>
#define xstr(s) str(s)
#define str(s) #s
@@ -24,6 +25,11 @@
#define RESERVE_MEM_REGION 0
+
+#define MANUFACTURER_INTEL 0x0089
+#define I82802AB 0x00ad
+#define I82802AC 0x00ac
+
#define ICHX_FWH_REGION_START 0xFF000000UL
#define ICHX_FWH_REGION_SIZE 0x01000000UL
#define BIOS_CNTL 0x4e
@@ -57,10 +63,22 @@
return addr - map->map_priv_1 + ICHX_FWH_REGION_START;
}
-static map_word ichxrom_read8(struct map_info *map, unsigned long ofs)
+static map_word ichxrom_read(struct map_info *map, unsigned long ofs)
{
map_word val;
- val.x[0] = __raw_readb(addr(map, ofs));
+ int i;
+ switch(map->bankwidth) {
+ case 1: val.x[0] = __raw_readb(addr(map, ofs)); break;
+ case 2: val.x[0] = __raw_readw(addr(map, ofs)); break;
+ case 4: val.x[0] = __raw_readl(addr(map, ofs)); break;
+#if BITS_PER_LONG >= 64
+ case 8: val.x[0] = __raw_readq(addr(map, ofs)); break;
+#endif
+ default: val.x[0] = 0; break;
+ }
+ for(i = 1; i < map_words(map); i++) {
+ val.x[i] = 0;
+ }
return val;
}
@@ -69,9 +87,16 @@
memcpy_fromio(to, addr(map, from), len);
}
-static void ichxrom_write8(struct map_info *map, map_word d, unsigned long ofs)
+static void ichxrom_write(struct map_info *map, map_word d, unsigned long ofs)
{
- __raw_writeb(d.x[0], addr(map,ofs));
+ switch(map->bankwidth) {
+ case 1: __raw_writeb(d.x[0], addr(map,ofs)); break;
+ case 2: __raw_writew(d.x[0], addr(map,ofs)); break;
+ case 4: __raw_writel(d.x[0], addr(map,ofs)); break;
+#if BITS_PER_LONG >= 64
+ case 8: __raw_writeq(d.x[0], addr(map,ofs)); break;
+#endif
+ }
mb();
}
@@ -86,9 +111,9 @@
.phys = NO_XIP,
.size = 0,
.bankwidth = 1,
- .read = ichxrom_read8,
+ .read = ichxrom_read,
.copy_from = ichxrom_copy_from,
- .write = ichxrom_write8,
+ .write = ichxrom_write,
.copy_to = ichxrom_copy_to,
/* Firmware hubs only use vpp when being programmed
* in a factory setting. So in-place programming
@@ -166,6 +191,8 @@
u16 word;
struct ichxrom_map_info *info = &ichxrom_map;
unsigned long map_size;
+ static char *probes[] = { "cfi_probe", "jedec_probe" };
+ struct cfi_private *cfi;
/* For now I just handle the ichx and I assume there
* are not a lot of resources up at the top of the address
@@ -228,20 +255,41 @@
info->mtd = NULL;
info->map.map_priv_1 = info->window_addr;
- map_size = ICHX_FWH_REGION_SIZE;
- while(!info->mtd && (map_size > 0)) {
- info->map.size = map_size;
- info->mtd = do_map_probe("jedec_probe", &ichxrom_map.map);
- map_size -= 512*1024;
+ /* Loop through the possible bankwidths */
+ for(ichxrom_map.map.bankwidth = 4; ichxrom_map.map.bankwidth; ichxrom_map.map.bankwidth >>= 1) {
+ map_size = ICHX_FWH_REGION_SIZE;
+ while(!info->mtd && (map_size > 0)) {
+ int i;
+ info->map.size = map_size;
+ for(i = 0; i < sizeof(probes)/sizeof(char *); i++) {
+ info->mtd = do_map_probe(probes[i], &ichxrom_map.map);
+ if (info->mtd)
+ break;
+ }
+ map_size -= 512*1024;
+ }
+ if (info->mtd)
+ break;
}
if (!info->mtd) {
goto failed;
}
- /* I know I can only be a firmware hub here so put
- * in the special lock and unlock routines.
- */
- info->mtd->lock = ichxrom_lock;
- info->mtd->unlock = ichxrom_unlock;
+ cfi = ichxrom_map.map.fldrv_priv;
+ if ((cfi->mfr == MANUFACTURER_INTEL) && (
+ (cfi->id == I82802AB) ||
+ (cfi->id == I82802AC)))
+ {
+ /* If it is a firmware hub put in the special lock
+ * and unlock routines.
+ */
+ info->mtd->lock = ichxrom_lock;
+ info->mtd->unlock = ichxrom_unlock;
+ }
+ if (info->mtd->size > info->map.size) {
+ printk(KERN_WARNING MOD_NAME " rom(%u) larger than window(%u). fixing...\n",
+ info->mtd->size, info->map.size);
+ info->mtd->size = info->map.size;
+ }
info->mtd->owner = THIS_MODULE;
add_mtd_device(info->mtd);
@@ -298,7 +346,7 @@
#endif
}
-static struct pci_device_id ichxrom_pci_tbl[] = {
+static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,
PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
@@ -324,9 +372,10 @@
static struct pci_dev *mydev;
int __init init_ichxrom(void)
{
- struct pci_dev *pdev = NULL;
+ struct pci_dev *pdev;
struct pci_device_id *id;
+ pdev = NULL;
for (id = ichxrom_pci_tbl; id->vendor; id++) {
pdev = pci_find_device(id->vendor, id->device, NULL);
if (pdev) {
More information about the linux-mtd-cvs
mailing list