Remove hardcoded number of CFI chips
PATCH 1/1 Remove hardcoded number of CFI chips
This is a resend of a patch originally posted by Andrzej Mialkowski from Intel a few months ago that removes the hardcoded MAX_CFI_CHIPS and replaces it with a dynamic bitmap. I believe it got approved but never checked in, but not 100% sure so I'm reposting it to see if it should be pushed into CVS, cleaned up, or dropped. I need this for several platforms with large numbers of chips, so I'd rather not see it just die.
Tnx,
~Deepak
Index: drivers/mtd/chips/cfi_probe.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_probe.c,v retrieving revision 1.72
mtd/chips/cfi_probe.c +15 -15
@@ -26,7 +26,7 @@#endif static int cfi_probe_chip (struct map_info *map,__u32 base, -struct flchip *chips,struct cfi_private *cfi); +struct probe_info *probe,struct cfi_private *cfi);static int cfi_chip_setup (struct map_info *map,struct cfi_private *cfi);struct mtd_info *cfi_probe (struct map_info *map);
@@ -49,7 +49,7 @@ }static int cfi_probe_chip (struct map_info *map,__u32 base, -struct flchip *chips,struct cfi_private *cfi) +struct probe_info *probe,struct cfi_private *cfi) {int i;
@@ -78,18 +78,24 @@ }/* Check each previous chip to see if it's an alias */ -for (i=0 ; i<cfi->numchips; i++) { +for (i=0 ; i < (base >> cfi->chipshift); i++) { +unsigned long start; +if (!test_bit (i, probe->chip_map)) { +/* Skip location; no valid chip at this address */ +continue ; + } + start = i << cfi->chipshift;/* This chip should be in read mode if it's one we've already touched. */ -if (qry_present (map,chips[i].start,cfi)) { +if (qry_present (map, start, cfi)) {/* Eep. This chip also had the QRY marker. * Is it an alias for the new one? */ -cfi_send_gen_cmd (0xF0 ,0 , chips[i].start, map, cfi, cfi->device_type,NULL ); +cfi_send_gen_cmd (0xF0 ,0 , start, map, cfi, cfi->device_type,NULL );/* If the QRY marker goes away, it's an alias */ -if (!qry_present (map, chips[i].start, cfi)) { +if (!qry_present (map, start, cfi)) {printk (KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n" , - map->name, base, chips[i].start); + map->name, base, start);return 0 ; }/* Yes, it's actually got QRY for data. Most
@@ -100,7 +106,7 @@if (qry_present (map, base, cfi)) {printk (KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n" , - map->name, base, chips[i].start); + map->name, base, start);return 0 ; } }
@@ -108,13 +114,7 @@/* OK, if we got to here, then none of the previous chips appear to be aliases for the current one. */ -if (cfi->numchips ==MAX_CFI_CHIPS ) { -printk (KERN_WARNING "%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n" , map->name,MAX_CFI_CHIPS ); -/* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */ -return -1 ; - } - chips[cfi->numchips].start = base; - chips[cfi->numchips].state =FL_READY ; +set_bit ((base >> cfi->chipshift), probe->chip_map);/* Update chip map */ cfi->numchips++;/* Put it back into Read Mode */
Index: drivers/mtd/chips/gen_probe.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/gen_probe.c,v retrieving revision 1.13
mtd/chips/gen_probe.c +30 -21
92 lines not on this page · raw message
Index: drivers/mtd/chips/jedec_probe.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/jedec_probe.c,v retrieving revision 1.32
mtd/chips/jedec_probe.c +15 -18
@@ -1365,7 +1365,7 @@static int cfi_jedec_setup (struct cfi_private *p_cfi,int index);static int jedec_probe_chip (struct map_info *map,__u32 base, -struct flchip *chips,struct cfi_private *cfi); +struct probe_info *probe,struct cfi_private *cfi);struct mtd_info *jedec_probe (struct map_info *map);
@@ -1593,7 +1593,7 @@static int jedec_probe_chip (struct map_info *map,__u32 base, -struct flchip *chips,struct cfi_private *cfi) +struct probe_info *probe,struct cfi_private *cfi) {int i;enum uaddr uaddr_idx =MTD_UADDR_NOT_SUPPORTED ;
@@ -1679,21 +1679,24 @@ } } -/* Check each previous chip to see if it's an alias */ -for (i=0 ; i<cfi->numchips; i++) { -/* This chip should be in read mode if it's one -we've already touched. */ -if (jedec_read_mfr (map, chips[i].start, cfi) == cfi->mfr && -jedec_read_id (map, chips[i].start, cfi) == cfi->id) { +/* Check each previous chip locations to see if it's an alias */ +for (i=0 ; i < (base >> cfi->chipshift); i++) { +unsigned long start; +if (!test_bit (i, probe->chip_map)) { +continue ;/* Skip location; no valid chip at this address */ + } + start = i << cfi->chipshift; +if (jedec_read_mfr (map, start, cfi) == cfi->mfr && +jedec_read_id (map, start, cfi) == cfi->id) {/* Eep. This chip also looks like it's in autoselect mode. Is it an alias for the new one? */ -jedec_reset (chips[i].start, map, cfi); +jedec_reset (start, map, cfi);/* If the device IDs go away, it's an alias */ if (jedec_read_mfr (map, base, cfi) != cfi->mfr ||jedec_read_id (map, base, cfi) != cfi->id) {printk (KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n" , - map->name, base, chips[i].start); + map->name, base, start);return 0 ; }
@@ -1705,7 +1708,7 @@if (jedec_read_mfr (map, base, cfi) == cfi->mfr &&jedec_read_id (map, base, cfi) == cfi->id) {printk (KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n" , - map->name, base, chips[i].start); + map->name, base, start);return 0 ; } }
@@ -1713,13 +1716,7 @@/* OK, if we got to here, then none of the previous chips appear to be aliases for the current one. */ -if (cfi->numchips ==MAX_CFI_CHIPS ) { -printk (KERN_WARNING "%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n" , map->name,MAX_CFI_CHIPS ); -/* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */ -return -1 ; - } - chips[cfi->numchips].start = base; - chips[cfi->numchips].state =FL_READY ; +set_bit ((base >> cfi->chipshift), probe->chip_map);/* Update chip map */ cfi->numchips++; ok_out:
Index: include/linux/mtd/cfi.h
===================================================================
RCS file: /home/cvs/mtd/include/linux/mtd/cfi.h,v
retrieving revision 1.36
linux/mtd/cfi.h +0 -2
@@ -334,8 +334,6 @@struct flchip chips[0 ];/* per-chip data structure for each chip */ }; -#define MAX_CFI_CHIPS 8/* Entirely arbitrary to avoid realloc() */ -/* * Returns the command address according to the given geometry. */
Index: include/linux/mtd/gen_probe.h
===================================================================
RCS file: /home/cvs/mtd/include/linux/mtd/gen_probe.h,v retrieving revision 1.1
linux/mtd/gen_probe.h +6 -2
@@ -10,12 +10,16 @@#include <linux/mtd/flashchip.h> #include <linux/mtd/map.h> #include <linux/mtd/cfi.h> +#include <asm/bitops.h> + +struct probe_info { +long *chip_map;/* bitmap of valid chips in mtd map */ +};struct chip_probe {char *name;int (*probe_chip)(struct map_info *map,__u32 base, -struct flchip *chips,struct cfi_private *cfi); - +struct probe_info *probe,struct cfi_private *cfi); };struct mtd_info *mtd_do_chip_probe (struct map_info *map,struct chip_probe *cp);
Signature · 6 lines
Deepak Saxena - [email protected] "To eliminate the concept of waste means to design things - products, packaging, and systems - from the very beggining on the understanding that waste does not exist" - William McDonough & Michael Braungart, From Cradle to Cradle: Remaking the Way We Make Things