File: /usr/src/linux/drivers/mtd/chips/cfi_cmdset_0002.c

1     /*
2      * Common Flash Interface support:
3      *   AMD & Fujitsu Standard Vendor Command Set (ID 0x0002)
4      *
5      * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
6      *
7      * 2_by_8 routines added by Simon Munton
8      *
9      * This code is GPL
10      *
11      * $Id: cfi_cmdset_0002.c,v 1.48 2001/06/03 01:32:57 nico Exp $
12      *
13      */
14     
15     #include <linux/module.h>
16     #include <linux/types.h>
17     #include <linux/kernel.h>
18     #include <linux/sched.h>
19     #include <asm/io.h>
20     #include <asm/byteorder.h>
21     
22     #include <linux/errno.h>
23     #include <linux/slab.h>
24     #include <linux/delay.h>
25     #include <linux/mtd/map.h>
26     #include <linux/mtd/cfi.h>
27     
28     #define AMD_BOOTLOC_BUG
29     
30     static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
31     static int cfi_amdstd_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
32     static int cfi_amdstd_erase_onesize(struct mtd_info *, struct erase_info *);
33     static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
34     static void cfi_amdstd_sync (struct mtd_info *);
35     static int cfi_amdstd_suspend (struct mtd_info *);
36     static void cfi_amdstd_resume (struct mtd_info *);
37     
38     static void cfi_amdstd_destroy(struct mtd_info *);
39     
40     void cfi_cmdset_0002(struct map_info *, int, unsigned long);
41     static struct mtd_info *cfi_amdstd_setup (struct map_info *);
42     
43     
44     static struct mtd_chip_driver cfi_amdstd_chipdrv = {
45     	probe: cfi_amdstd_setup,
46     	destroy: cfi_amdstd_destroy,
47     	name: "cfi_cmdset_0002",
48     	module: THIS_MODULE
49     };
50     
51     void cfi_cmdset_0002(struct map_info *map, int primary, unsigned long base)
52     {
53     	struct cfi_private *cfi = map->fldrv_priv;
54     	unsigned char bootloc;
55     	int ofs_factor = cfi->interleave * cfi->device_type;
56     	int i;
57     	__u8 major, minor;
58     //	struct cfi_pri_intelext *extp;
59     
60         if (cfi->cfi_mode==0){
61     	__u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
62     
63     	cfi_send_gen_cmd(0x98, 0x55, 0, map, cfi, cfi->device_type, NULL);
64     
65     	major = cfi_read_query(map, (adr+3)*ofs_factor);
66     	minor = cfi_read_query(map, (adr+4)*ofs_factor);
67     
68     	printk(" Amd/Fujitsu Extended Query Table v%c.%c at 0x%4.4X\n",
69     	       major, minor, adr);
70     
71     	cfi_send_gen_cmd(0xf0, 0x55, 0, map, cfi, cfi->device_type, NULL);
72     
73     	cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
74     	cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
75     	cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
76     	cfi->mfr = cfi_read_query(map, base);
77     	cfi->id = cfi_read_query(map, base + ofs_factor);
78     
79     	/* Wheee. Bring me the head of someone at AMD. */
80     #ifdef AMD_BOOTLOC_BUG
81     	if (((major << 8) | minor) < 0x3131) {
82     		/* CFI version 1.0 => don't trust bootloc */
83     		if (cfi->id & 0x80) {
84     			printk(KERN_WARNING "%s: JEDEC Device ID is 0x%02X. Assuming broken CFI table.\n", map->name, cfi->id);
85     			bootloc = 3;	/* top boot */
86     		} else {
87     			bootloc = 2;	/* bottom boot */
88     		}
89     	} else
90     #endif
91     	{
92     		cfi_send_gen_cmd(0x98, 0x55, 0, map, cfi, cfi->device_type, NULL);
93     		bootloc = cfi_read_query(map, (adr+15)*ofs_factor);
94     	}
95     	if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
96     		printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name);
97     
98     		for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) {
99     			int j = (cfi->cfiq->NumEraseRegions-1)-i;
100     			__u32 swap;
101     
102     			swap = cfi->cfiq->EraseRegionInfo[i];
103     			cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j];
104     			cfi->cfiq->EraseRegionInfo[j] = swap;
105     		}
106     	}
107         }
108     
109         /* If there was an old setup function, decrease its use count */
110         if (map->fldrv)
111           if(map->fldrv->module)
112     	__MOD_DEC_USE_COUNT(map->fldrv->module);
113         
114         if (cfi->cmdset_priv)
115     		kfree(cfi->cmdset_priv);
116     
117         for (i=0; i< cfi->numchips; i++) {
118     		cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
119     		cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
120     		cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
121         }		
122     
123         map->fldrv = &cfi_amdstd_chipdrv;
124         MOD_INC_USE_COUNT;
125         cfi_send_gen_cmd(0xf0, 0x55, 0, map, cfi, cfi->device_type, NULL);
126         return;
127     }
128     
129     static struct mtd_info *cfi_amdstd_setup(struct map_info *map)
130     {
131     	struct cfi_private *cfi = map->fldrv_priv;
132     	struct mtd_info *mtd;
133     	unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
134     
135     	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
136     	printk("number of %s chips: %d\n", (cfi->cfi_mode)?"JEDEC":"CFI",cfi->numchips);
137     
138     	if (!mtd) {
139     	  printk("Failed to allocate memory for MTD device\n");
140     	  kfree(cfi->cmdset_priv);
141     	  return NULL;
142     	}
143     
144     	memset(mtd, 0, sizeof(*mtd));
145     	mtd->priv = map;
146     	mtd->type = MTD_NORFLASH;
147     	/* Also select the correct geometry setup too */ 
148     	mtd->size = devsize * cfi->numchips;
149     	
150     	if (cfi->cfiq->NumEraseRegions == 1) {
151     		/* No need to muck about with multiple erase sizes */
152     		mtd->erasesize = ((cfi->cfiq->EraseRegionInfo[0] >> 8) & ~0xff) * cfi->interleave;
153     	} else {
154     		unsigned long offset = 0;
155     		int i,j;
156     
157     		mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
158     		mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * mtd->numeraseregions, GFP_KERNEL);
159     		if (!mtd->eraseregions) { 
160     			printk("Failed to allocate memory for MTD erase region info\n");
161     			kfree(cfi->cmdset_priv);
162     			return NULL;
163     		}
164     			
165     		for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
166     			unsigned long ernum, ersize;
167     			ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
168     			ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
169     			
170     			if (mtd->erasesize < ersize) {
171     				mtd->erasesize = ersize;
172     			}
173     			for (j=0; j<cfi->numchips; j++) {
174     				mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset;
175     				mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize;
176     				mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum;
177     			}
178     			offset += (ersize * ernum);
179     		}
180     		if (offset != devsize) {
181     			/* Argh */
182     			printk("Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
183     			kfree(mtd->eraseregions);
184     			kfree(cfi->cmdset_priv);
185     			return NULL;
186     		}
187     		// debug
188     		for (i=0; i<mtd->numeraseregions;i++){
189     			printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
190     			       i,mtd->eraseregions[i].offset,
191     			       mtd->eraseregions[i].erasesize,
192     			       mtd->eraseregions[i].numblocks);
193     		}
194     	}
195     
196     	switch (CFIDEV_BUSWIDTH)
197     	{
198     	case 1:
199     	case 2:
200     	case 4:
201     #if 1
202     		if (mtd->numeraseregions > 1)
203     			mtd->erase = cfi_amdstd_erase_varsize;
204     		else
205     #endif
206     			mtd->erase = cfi_amdstd_erase_onesize;
207     		mtd->read = cfi_amdstd_read;
208     		mtd->write = cfi_amdstd_write;
209     		break;
210     
211     	default:
212     	        printk("Unsupported buswidth\n");
213     		kfree(mtd);
214     		kfree(cfi->cmdset_priv);
215     		return NULL;
216     		break;
217     	}
218     	mtd->sync = cfi_amdstd_sync;
219     	mtd->suspend = cfi_amdstd_suspend;
220     	mtd->resume = cfi_amdstd_resume;
221     	mtd->flags = MTD_CAP_NORFLASH;
222     	map->fldrv = &cfi_amdstd_chipdrv;
223     	mtd->name = map->name;
224     	MOD_INC_USE_COUNT;
225     	return mtd;
226     }
227     
228     static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
229     {
230     	DECLARE_WAITQUEUE(wait, current);
231     	unsigned long timeo = jiffies + HZ;
232     
233      retry:
234     	cfi_spin_lock(chip->mutex);
235     
236     	if (chip->state != FL_READY){
237     	        printk("Waiting for chip to read, status = %d\n", chip->state);
238     		set_current_state(TASK_UNINTERRUPTIBLE);
239     		add_wait_queue(&chip->wq, &wait);
240                     
241     		cfi_spin_unlock(chip->mutex);
242     
243     		schedule();
244     		remove_wait_queue(&chip->wq, &wait);
245     #if 0
246     		if(signal_pending(current))
247     			return -EINTR;
248     #endif
249     		timeo = jiffies + HZ;
250     
251     		goto retry;
252     	}	
253     
254     	adr += chip->start;
255     
256     	chip->state = FL_READY;
257     
258     	map->copy_from(map, buf, adr, len);
259     
260     	wake_up(&chip->wq);
261     	cfi_spin_unlock(chip->mutex);
262     
263     	return 0;
264     }
265     
266     static int cfi_amdstd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
267     {
268     	struct map_info *map = mtd->priv;
269     	struct cfi_private *cfi = map->fldrv_priv;
270     	unsigned long ofs;
271     	int chipnum;
272     	int ret = 0;
273     
274     	/* ofs: offset within the first chip that the first read should start */
275     
276     	chipnum = (from >> cfi->chipshift);
277     	ofs = from - (chipnum <<  cfi->chipshift);
278     
279     
280     	*retlen = 0;
281     
282     	while (len) {
283     		unsigned long thislen;
284     
285     		if (chipnum >= cfi->numchips)
286     			break;
287     
288     		if ((len + ofs -1) >> cfi->chipshift)
289     			thislen = (1<<cfi->chipshift) - ofs;
290     		else
291     			thislen = len;
292     
293     		ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);
294     		if (ret)
295     			break;
296     
297     		*retlen += thislen;
298     		len -= thislen;
299     		buf += thislen;
300     
301     		ofs = 0;
302     		chipnum++;
303     	}
304     	return ret;
305     }
306     
307     static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum, int fast)
308     {
309     	unsigned long timeo = jiffies + HZ;
310     	unsigned int Last[4];
311     	unsigned long Count = 0;
312     	struct cfi_private *cfi = map->fldrv_priv;
313     	DECLARE_WAITQUEUE(wait, current);
314     	int ret = 0;
315     
316      retry:
317     	cfi_spin_lock(chip->mutex);
318     
319     	if (chip->state != FL_READY){
320     	        printk("Waiting for chip to write, status = %d\n", chip->state);
321     		set_current_state(TASK_UNINTERRUPTIBLE);
322     		add_wait_queue(&chip->wq, &wait);
323                     
324     		cfi_spin_unlock(chip->mutex);
325     
326     		schedule();
327     		remove_wait_queue(&chip->wq, &wait);
328     		printk("Wake up to write:\n");
329     #if 0
330     		if(signal_pending(current))
331     			return -EINTR;
332     #endif
333     		timeo = jiffies + HZ;
334     
335     		goto retry;
336     	}	
337     
338     	chip->state = FL_WRITING;
339     
340     	adr += chip->start;
341     	ENABLE_VPP(map);
342     	if (fast) { /* Unlock bypass */
343     		cfi_send_gen_cmd(0xA0, 0, chip->start, map, cfi, cfi->device_type, NULL);
344     	}
345     	else {
346     	        cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
347     	        cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
348     	        cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
349     	}
350     
351     	cfi_write(map, datum, adr);
352     
353     	cfi_spin_unlock(chip->mutex);
354     	cfi_udelay(chip->word_write_time);
355     	cfi_spin_lock(chip->mutex);
356     
357     	Last[0] = cfi_read(map, adr);
358     	//	printk("Last[0] is %x\n", Last[0]);
359     	Last[1] = cfi_read(map, adr);
360     	//	printk("Last[1] is %x\n", Last[1]);
361     	Last[2] = cfi_read(map, adr);
362     	//	printk("Last[2] is %x\n", Last[2]);
363     
364     	for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && Count < 10000; Count++){
365     		cfi_spin_unlock(chip->mutex);
366     		cfi_udelay(10);
367     		cfi_spin_lock(chip->mutex);
368     		
369     	        Last[Count % 4] = cfi_read(map, adr);
370     		//		printk("Last[%d%%4] is %x\n", Count, Last[Count%4]);
371     	}
372     	
373     	if (Last[(Count - 1) % 4] != datum){
374     		printk("Last[%ld] is %x, datum is %x\n",(Count - 1) % 4,Last[(Count - 1) % 4],datum);
375     	        cfi_send_gen_cmd(0xF0, 0, chip->start, map, cfi, cfi->device_type, NULL);
376     		DISABLE_VPP(map);
377     		ret = -EIO;
378     	}       
379     	DISABLE_VPP(map);
380     	chip->state = FL_READY;
381     	wake_up(&chip->wq);
382     	cfi_spin_unlock(chip->mutex);
383     	
384     	return ret;
385     }
386     
387     static int cfi_amdstd_write (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf)
388     {
389     	struct map_info *map = mtd->priv;
390     	struct cfi_private *cfi = map->fldrv_priv;
391     	int ret = 0;
392     	int chipnum;
393     	unsigned long ofs, chipstart;
394     
395     	*retlen = 0;
396     	if (!len)
397     		return 0;
398     
399     	chipnum = to >> cfi->chipshift;
400     	ofs = to  - (chipnum << cfi->chipshift);
401     	chipstart = cfi->chips[chipnum].start;
402     
403     	/* If it's not bus-aligned, do the first byte write */
404     	if (ofs & (CFIDEV_BUSWIDTH-1)) {
405     		unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1);
406     		int i = ofs - bus_ofs;
407     		int n = 0;
408     		u_char tmp_buf[4];
409     		__u32 datum;
410     
411     		map->copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
412     		while (len && i < CFIDEV_BUSWIDTH)
413     			tmp_buf[i++] = buf[n++], len--;
414     
415     		if (cfi_buswidth_is_2()) {
416     			datum = *(__u16*)tmp_buf;
417     		} else if (cfi_buswidth_is_4()) {
418     			datum = *(__u32*)tmp_buf;
419     		} else {
420     			return -EINVAL;  /* should never happen, but be safe */
421     		}
422     
423     		ret = do_write_oneword(map, &cfi->chips[chipnum], 
424     				bus_ofs, datum, 0);
425     		if (ret) 
426     			return ret;
427     		
428     		ofs += n;
429     		buf += n;
430     		(*retlen) += n;
431     
432     		if (ofs >> cfi->chipshift) {
433     			chipnum ++; 
434     			ofs = 0;
435     			if (chipnum == cfi->numchips)
436     				return 0;
437     		}
438     	}
439     	
440     	/* Go into unlock bypass mode */
441     	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
442     	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
443     	cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
444     
445     	/* We are now aligned, write as much as possible */
446     	while(len >= CFIDEV_BUSWIDTH) {
447     		__u32 datum;
448     
449     		if (cfi_buswidth_is_1()) {
450     			datum = *(__u8*)buf;
451     		} else if (cfi_buswidth_is_2()) {
452     			datum = *(__u16*)buf;
453     		} else if (cfi_buswidth_is_4()) {
454     			datum = *(__u32*)buf;
455     		} else {
456     			return -EINVAL;
457     		}
458     		ret = do_write_oneword(map, &cfi->chips[chipnum],
459     				       ofs, datum, cfi->fast_prog);
460     		if (ret) {
461     			if (cfi->fast_prog){
462     				/* Get out of unlock bypass mode */
463     				cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL);
464     				cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL);
465     			}
466     			return ret;
467     		}
468     
469     		ofs += CFIDEV_BUSWIDTH;
470     		buf += CFIDEV_BUSWIDTH;
471     		(*retlen) += CFIDEV_BUSWIDTH;
472     		len -= CFIDEV_BUSWIDTH;
473     
474     		if (ofs >> cfi->chipshift) {
475     			if (cfi->fast_prog){
476     				/* Get out of unlock bypass mode */
477     				cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL);
478     				cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL);
479     			}
480     
481     			chipnum ++; 
482     			ofs = 0;
483     			if (chipnum == cfi->numchips)
484     				return 0;
485     			chipstart = cfi->chips[chipnum].start;
486     			if (cfi->fast_prog){
487     				/* Go into unlock bypass mode for next set of chips */
488     				cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
489     				cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
490     				cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVICETYPE_X8, NULL);
491     			}
492     		}
493     	}
494     
495     	if (cfi->fast_prog){
496     		/* Get out of unlock bypass mode */
497     		cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL);
498     		cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL);
499     	}
500     
501     	if (len & (CFIDEV_BUSWIDTH-1)) {
502     		int i = 0, n = 0;
503     		u_char tmp_buf[4];
504     		__u32 datum;
505     
506     		map->copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
507     		while (len--)
508     			tmp_buf[i++] = buf[n++];
509     
510     		if (cfi_buswidth_is_2()) {
511     			datum = *(__u16*)tmp_buf;
512     		} else if (cfi_buswidth_is_4()) {
513     			datum = *(__u32*)tmp_buf;
514     		} else {
515     			return -EINVAL;  /* should never happen, but be safe */
516     		}
517     
518     		ret = do_write_oneword(map, &cfi->chips[chipnum], 
519     				ofs, datum, 0);
520     		if (ret) 
521     			return ret;
522     		
523     		(*retlen) += n;
524     	}
525     
526     	return 0;
527     }
528     
529     static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
530     {
531     	unsigned int status;
532     	unsigned long timeo = jiffies + HZ;
533     	struct cfi_private *cfi = map->fldrv_priv;
534     	unsigned int rdy_mask;
535     	DECLARE_WAITQUEUE(wait, current);
536     
537      retry:
538     	cfi_spin_lock(chip->mutex);
539     
540     	if (chip->state != FL_READY){
541     		set_current_state(TASK_UNINTERRUPTIBLE);
542     		add_wait_queue(&chip->wq, &wait);
543                     
544     		cfi_spin_unlock(chip->mutex);
545     
546     		schedule();
547     		remove_wait_queue(&chip->wq, &wait);
548     #if 0
549     		if(signal_pending(current))
550     			return -EINTR;
551     #endif
552     		timeo = jiffies + HZ;
553     
554     		goto retry;
555     	}	
556     
557     	chip->state = FL_ERASING;
558     
559     	adr += chip->start;
560     	ENABLE_VPP(map);
561     	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
562     	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
563     	cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
564     	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
565     	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
566     	cfi_write(map, CMD(0x30), adr);
567     	
568     	timeo = jiffies + (HZ*20);
569     
570     	cfi_spin_unlock(chip->mutex);
571     	schedule_timeout(HZ);
572     	cfi_spin_lock(chip->mutex);
573     	
574     	rdy_mask = CMD(0x80);
575     
576     	/* FIXME. Use a timer to check this, and return immediately. */
577     	/* Once the state machine's known to be working I'll do that */
578     
579     	while ( ( (status = cfi_read(map,adr)) & rdy_mask ) != rdy_mask ) {
580     		static int z=0;
581     
582     		if (chip->state != FL_ERASING) {
583     			/* Someone's suspended the erase. Sleep */
584     			set_current_state(TASK_UNINTERRUPTIBLE);
585     			add_wait_queue(&chip->wq, &wait);
586     			
587     			cfi_spin_unlock(chip->mutex);
588     			printk("erase suspended. Sleeping\n");
589     			
590     			schedule();
591     			remove_wait_queue(&chip->wq, &wait);
592     #if 0			
593     			if (signal_pending(current))
594     				return -EINTR;
595     #endif			
596     			timeo = jiffies + (HZ*2); /* FIXME */
597     			cfi_spin_lock(chip->mutex);
598     			continue;
599     		}
600     
601     		/* OK Still waiting */
602     		if (time_after(jiffies, timeo)) {
603     			chip->state = FL_READY;
604     			cfi_spin_unlock(chip->mutex);
605     			printk("waiting for erase to complete timed out.");
606     			DISABLE_VPP(map);
607     			return -EIO;
608     		}
609     		
610     		/* Latency issues. Drop the lock, wait a while and retry */
611     		cfi_spin_unlock(chip->mutex);
612     
613     		z++;
614     		if ( 0 && !(z % 100 )) 
615     			printk("chip not ready yet after erase. looping\n");
616     
617     		cfi_udelay(1);
618     		
619     		cfi_spin_lock(chip->mutex);
620     		continue;
621     	}
622     	
623     	/* Done and happy. */
624     	DISABLE_VPP(map);
625     	chip->state = FL_READY;
626     	wake_up(&chip->wq);
627     	cfi_spin_unlock(chip->mutex);
628     	return 0;
629     }
630     
631     static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
632     {
633     	struct map_info *map = mtd->priv;
634     	struct cfi_private *cfi = map->fldrv_priv;
635     	unsigned long adr, len;
636     	int chipnum, ret = 0;
637     	int i, first;
638     	struct mtd_erase_region_info *regions = mtd->eraseregions;
639     
640     	if (instr->addr > mtd->size)
641     		return -EINVAL;
642     
643     	if ((instr->len + instr->addr) > mtd->size)
644     		return -EINVAL;
645     
646     	/* Check that both start and end of the requested erase are
647     	 * aligned with the erasesize at the appropriate addresses.
648     	 */
649     
650     	i = 0;
651     
652     	/* Skip all erase regions which are ended before the start of 
653     	   the requested erase. Actually, to save on the calculations,
654     	   we skip to the first erase region which starts after the
655     	   start of the requested erase, and then go back one.
656     	*/
657     	
658     	while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
659     	       i++;
660     	i--;
661     
662     	/* OK, now i is pointing at the erase region in which this 
663     	   erase request starts. Check the start of the requested
664     	   erase range is aligned with the erase size which is in
665     	   effect here.
666     	*/
667     
668     	if (instr->addr & (regions[i].erasesize-1))
669     		return -EINVAL;
670     
671     	/* Remember the erase region we start on */
672     	first = i;
673     
674     	/* Next, check that the end of the requested erase is aligned
675     	 * with the erase region at that address.
676     	 */
677     
678     	while (i<mtd->numeraseregions && (instr->addr + instr->len) >= regions[i].offset)
679     		i++;
680     
681     	/* As before, drop back one to point at the region in which
682     	   the address actually falls
683     	*/
684     	i--;
685     	
686     	if ((instr->addr + instr->len) & (regions[i].erasesize-1))
687     		return -EINVAL;
688     	
689     	chipnum = instr->addr >> cfi->chipshift;
690     	adr = instr->addr - (chipnum << cfi->chipshift);
691     	len = instr->len;
692     
693     	i=first;
694     
695     	while(len) {
696     		ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
697     
698     		if (ret)
699     			return ret;
700     
701     		adr += regions[i].erasesize;
702     		len -= regions[i].erasesize;
703     
704     		if (adr % (1<< cfi->chipshift) == ((regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift)))
705     			i++;
706     
707     		if (adr >> cfi->chipshift) {
708     			adr = 0;
709     			chipnum++;
710     			
711     			if (chipnum >= cfi->numchips)
712     			break;
713     		}
714     	}
715     
716     	instr->state = MTD_ERASE_DONE;
717     	if (instr->callback)
718     		instr->callback(instr);
719     	
720     	return 0;
721     }
722     
723     static int cfi_amdstd_erase_onesize(struct mtd_info *mtd, struct erase_info *instr)
724     {
725     	struct map_info *map = mtd->priv;
726     	struct cfi_private *cfi = map->fldrv_priv;
727     	unsigned long adr, len;
728     	int chipnum, ret = 0;
729     
730     	if (instr->addr & (mtd->erasesize - 1))
731     		return -EINVAL;
732     
733     	if (instr->len & (mtd->erasesize -1))
734     		return -EINVAL;
735     
736     	if ((instr->len + instr->addr) > mtd->size)
737     		return -EINVAL;
738     
739     	chipnum = instr->addr >> cfi->chipshift;
740     	adr = instr->addr - (chipnum << cfi->chipshift);
741     	len = instr->len;
742     
743     	while(len) {
744     		ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
745     
746     		if (ret)
747     			return ret;
748     
749     		adr += mtd->erasesize;
750     		len -= mtd->erasesize;
751     
752     		if (adr >> cfi->chipshift) {
753     			adr = 0;
754     			chipnum++;
755     			
756     			if (chipnum >= cfi->numchips)
757     			break;
758     		}
759     	}
760     		
761     	instr->state = MTD_ERASE_DONE;
762     	if (instr->callback)
763     		instr->callback(instr);
764     	
765     	return 0;
766     }
767     
768     static void cfi_amdstd_sync (struct mtd_info *mtd)
769     {
770     	struct map_info *map = mtd->priv;
771     	struct cfi_private *cfi = map->fldrv_priv;
772     	int i;
773     	struct flchip *chip;
774     	int ret = 0;
775     	DECLARE_WAITQUEUE(wait, current);
776     
777     	for (i=0; !ret && i<cfi->numchips; i++) {
778     		chip = &cfi->chips[i];
779     
780     	retry:
781     		cfi_spin_lock(chip->mutex);
782     
783     		switch(chip->state) {
784     		case FL_READY:
785     		case FL_STATUS:
786     		case FL_CFI_QUERY:
787     		case FL_JEDEC_QUERY:
788     			chip->oldstate = chip->state;
789     			chip->state = FL_SYNCING;
790     			/* No need to wake_up() on this state change - 
791     			 * as the whole point is that nobody can do anything
792     			 * with the chip now anyway.
793     			 */
794     		case FL_SYNCING:
795     			cfi_spin_unlock(chip->mutex);
796     			break;
797     
798     		default:
799     			/* Not an idle state */
800     			add_wait_queue(&chip->wq, &wait);
801     			
802     			cfi_spin_unlock(chip->mutex);
803     
804     			schedule();
805     
806     		        remove_wait_queue(&chip->wq, &wait);
807     			
808     			goto retry;
809     		}
810     	}
811     
812     	/* Unlock the chips again */
813     
814     	for (i--; i >=0; i--) {
815     		chip = &cfi->chips[i];
816     
817     		cfi_spin_lock(chip->mutex);
818     		
819     		if (chip->state == FL_SYNCING) {
820     			chip->state = chip->oldstate;
821     			wake_up(&chip->wq);
822     		}
823     		cfi_spin_unlock(chip->mutex);
824     	}
825     }
826     
827     
828     static int cfi_amdstd_suspend(struct mtd_info *mtd)
829     {
830     	struct map_info *map = mtd->priv;
831     	struct cfi_private *cfi = map->fldrv_priv;
832     	int i;
833     	struct flchip *chip;
834     	int ret = 0;
835     //printk("suspend\n");
836     
837     	for (i=0; !ret && i<cfi->numchips; i++) {
838     		chip = &cfi->chips[i];
839     
840     		cfi_spin_lock(chip->mutex);
841     
842     		switch(chip->state) {
843     		case FL_READY:
844     		case FL_STATUS:
845     		case FL_CFI_QUERY:
846     		case FL_JEDEC_QUERY:
847     			chip->oldstate = chip->state;
848     			chip->state = FL_PM_SUSPENDED;
849     			/* No need to wake_up() on this state change - 
850     			 * as the whole point is that nobody can do anything
851     			 * with the chip now anyway.
852     			 */
853     		case FL_PM_SUSPENDED:
854     			break;
855     
856     		default:
857     			ret = -EAGAIN;
858     			break;
859     		}
860     		cfi_spin_unlock(chip->mutex);
861     	}
862     
863     	/* Unlock the chips again */
864     
865     	if (ret) {
866         		for (i--; i >=0; i--) {
867     			chip = &cfi->chips[i];
868     
869     			cfi_spin_lock(chip->mutex);
870     		
871     			if (chip->state == FL_PM_SUSPENDED) {
872     				chip->state = chip->oldstate;
873     				wake_up(&chip->wq);
874     			}
875     			cfi_spin_unlock(chip->mutex);
876     		}
877     	}
878     	
879     	return ret;
880     }
881     
882     static void cfi_amdstd_resume(struct mtd_info *mtd)
883     {
884     	struct map_info *map = mtd->priv;
885     	struct cfi_private *cfi = map->fldrv_priv;
886     	int i;
887     	struct flchip *chip;
888     //printk("resume\n");
889     
890     	for (i=0; i<cfi->numchips; i++) {
891     	
892     		chip = &cfi->chips[i];
893     
894     		cfi_spin_lock(chip->mutex);
895     		
896     		if (chip->state == FL_PM_SUSPENDED) {
897     			chip->state = FL_READY;
898     			cfi_write(map, CMD(0xF0), chip->start);
899     			wake_up(&chip->wq);
900     		}
901     		else
902     			printk("Argh. Chip not in PM_SUSPENDED state upon resume()\n");
903     
904     		cfi_spin_unlock(chip->mutex);
905     	}
906     }
907     
908     static void cfi_amdstd_destroy(struct mtd_info *mtd)
909     {
910     	struct map_info *map = mtd->priv;
911     	struct cfi_private *cfi = map->fldrv_priv;
912     	kfree(cfi->cmdset_priv);
913     	kfree(cfi);
914     }
915     
916     #if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
917     #define cfi_amdstd_init init_module
918     #define cfi_amdstd_exit cleanup_module
919     #endif
920     
921     static char im_name[]="cfi_cmdset_0002";
922     
923     mod_init_t cfi_amdstd_init(void)
924     {
925     	inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0002);
926     	return 0;
927     }
928     
929     mod_exit_t cfi_amdstd_exit(void)
930     {
931     	inter_module_unregister(im_name);
932     }
933     
934     module_init(cfi_amdstd_init);
935     module_exit(cfi_amdstd_exit);
936     
937