This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / mtd / chips / cfi_util.c
1 /*
2  * Common Flash Interface support:
3  *   Generic utility functions not dependant on command set
4  *
5  * Copyright (C) 2002 Red Hat
6  * Copyright (C) 2003 STMicroelectronics Limited
7  *
8  * This code is covered by the GPL.
9  *
10  * $Id: cfi_util.c,v 1.4 2004/07/14 08:38:44 dwmw2 Exp $
11  *
12  */
13
14 #include <linux/module.h>
15 #include <linux/types.h>
16 #include <linux/kernel.h>
17 #include <linux/sched.h>
18 #include <asm/io.h>
19 #include <asm/byteorder.h>
20
21 #include <linux/errno.h>
22 #include <linux/slab.h>
23 #include <linux/delay.h>
24 #include <linux/interrupt.h>
25 #include <linux/mtd/map.h>
26 #include <linux/mtd/cfi.h>
27 #include <linux/mtd/compatmac.h>
28
29 struct cfi_extquery *
30 cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name)
31 {
32         struct cfi_private *cfi = map->fldrv_priv;
33         __u32 base = 0; // cfi->chips[0].start;
34         int ofs_factor = cfi->interleave * cfi->device_type;
35         int i;
36         struct cfi_extquery *extp = NULL;
37
38         printk(" %s Extended Query Table at 0x%4.4X\n", name, adr);
39         if (!adr)
40                 goto out;
41
42         /* Switch it into Query Mode */
43         cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
44
45         extp = kmalloc(size, GFP_KERNEL);
46         if (!extp) {
47                 printk(KERN_ERR "Failed to allocate memory\n");
48                 goto out;
49         }
50                 
51         /* Read in the Extended Query Table */
52         for (i=0; i<size; i++) {
53                 ((unsigned char *)extp)[i] = 
54                         cfi_read_query(map, base+((adr+i)*ofs_factor));
55         }
56
57         if (extp->MajorVersion != '1' || 
58             (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
59                 printk(KERN_WARNING "  Unknown %s Extended Query "
60                        "version %c.%c.\n",  name, extp->MajorVersion,
61                        extp->MinorVersion);
62                 kfree(extp);
63                 extp = NULL;
64                 goto out;
65         }
66
67 out:
68         /* Make sure it's in read mode */
69         cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL);
70         cfi_send_gen_cmd(0xff, 0, base, map, cfi, cfi->device_type, NULL);
71
72         return extp;
73 }
74
75 EXPORT_SYMBOL(cfi_read_pri);
76
77 void cfi_fixup(struct map_info *map, struct cfi_fixup* fixups)
78 {
79         struct cfi_private *cfi = map->fldrv_priv;
80         struct cfi_fixup *f;
81
82         for (f=fixups; f->fixup; f++) {
83                 if (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi->mfr)) &&
84                     ((f->id  == CFI_ID_ANY)  || (f->id  == cfi->id))) {
85                         f->fixup(map, f->param);
86                 }
87         }
88 }
89
90 EXPORT_SYMBOL(cfi_fixup);
91
92 MODULE_LICENSE("GPL");