Import changeset
[linux-flexiantxendom0-3.2.10.git] / drivers / mtd / cfi_cmdset_0001.c
1 /*
2  * Common Flash Interface support:
3  *   Intel Extended Vendor Command Set (ID 0x0001)
4  *
5  * (C) 2000 Red Hat. GPL'd
6  *
7  * $Id: cfi_cmdset_0001.c,v 1.21 2000/07/13 10:36:14 dwmw2 Exp $
8  */
9
10 #include <linux/module.h>
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <asm/io.h>
15 #include <asm/byteorder.h>
16
17 #include <linux/errno.h>
18 #include <linux/malloc.h>
19 #include <linux/delay.h>
20 #include <linux/mtd/map.h>
21 #include <linux/mtd/cfi.h>
22
23 #if LINUX_VERSION_CODE < 0x20300
24 #define set_current_state(x) current->state = (x);
25 #endif
26 static int cfi_intelext_read_1_by_16 (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
27 static int cfi_intelext_write_1_by_16(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
28 static int cfi_intelext_erase_1_by_16 (struct mtd_info *, struct erase_info *);
29 static void cfi_intelext_sync (struct mtd_info *);
30 static int cfi_intelext_suspend (struct mtd_info *);
31 static void cfi_intelext_resume (struct mtd_info *);
32
33 static void cfi_intelext_destroy(struct mtd_info *);
34
35 static void cfi_cmdset_0001(struct map_info *, int, unsigned long);
36
37 static struct mtd_info *cfi_intelext_setup (struct map_info *);
38
39 static const char im_name[] = "cfi_cmdset_0001";
40
41 /* This routine is made available to other mtd code via
42  * inter_module_register.  It must only be accessed through
43  * inter_module_get which will bump the use count of this module.  The
44  * addresses passed back in cfi are valid as long as the use count of
45  * this module is non-zero, i.e. between inter_module_get and
46  * inter_module_put.  Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
47  */
48 static void cfi_cmdset_0001(struct map_info *map, int primary, unsigned long base)
49 {
50         struct cfi_private *cfi = map->fldrv_priv;
51         int i;
52         struct cfi_pri_intelext *extp;
53
54         __u16 adr = primary?cfi->cfiq.P_ADR:cfi->cfiq.A_ADR;
55
56         printk(" Intel/Sharp Extended Query Table at 0x%4.4X\n", adr);
57
58         if (!adr)
59                 return;
60
61         /* Switch it into Query Mode */
62         switch(map->buswidth) {
63         case 1:
64                 map->write8(map, 0x98, 0x55);
65                 break;
66         case 2:
67                 map->write16(map, 0x9898, 0xaa);
68                 break;
69         case 4:
70                 map->write32(map, 0x98989898, 0x154);
71                 break;
72         }
73
74         extp = kmalloc(sizeof(*extp), GFP_KERNEL);
75         if (!extp) {
76                 printk("Failed to allocate memory\n");
77                 return;
78         }
79
80         /* Read in the Extended Query Table */
81         for (i=0; i<sizeof(*extp); i++) {
82                 ((unsigned char *)extp)[i] = 
83                         map->read8(map, (base+((adr+i)*map->buswidth)));
84         }
85
86         if (extp->MajorVersion != '1' || 
87             (extp->MinorVersion < '0' || extp->MinorVersion > '2')) {
88                 printk("  Unknown IntelExt Extended Query version %c.%c.\n",
89                        extp->MajorVersion, extp->MinorVersion);
90                 kfree(extp);
91                 return;
92         }
93
94         /* Do some byteswapping if necessary */
95         extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport);
96         extp->BlkStatusRegMask = le32_to_cpu(extp->BlkStatusRegMask);
97
98         
99         /* Tell the user about it in lots of lovely detail */
100 #if 0  
101         printk("  Feature/Command Support: %4.4X\n", extp->FeatureSupport);
102         printk("     - Chip Erase:         %s\n", extp->FeatureSupport&1?"supported":"unsupported");
103         printk("     - Suspend Erase:      %s\n", extp->FeatureSupport&2?"supported":"unsupported");
104         printk("     - Suspend Program:    %s\n", extp->FeatureSupport&4?"supported":"unsupported");
105         printk("     - Legacy Lock/Unlock: %s\n", extp->FeatureSupport&8?"supported":"unsupported");
106         printk("     - Queued Erase:       %s\n", extp->FeatureSupport&16?"supported":"unsupported");
107         printk("     - Instant block lock: %s\n", extp->FeatureSupport&32?"supported":"unsupported");
108         printk("     - Protection Bits:    %s\n", extp->FeatureSupport&64?"supported":"unsupported");
109         printk("     - Page-mode read:     %s\n", extp->FeatureSupport&128?"supported":"unsupported");
110         printk("     - Synchronous read:   %s\n", extp->FeatureSupport&256?"supported":"unsupported");
111         for (i=9; i<32; i++) {
112                 if (extp->FeatureSupport & (1<<i)) 
113                         printk("     - Unknown Bit %X:      supported\n", i);
114         }
115         
116         printk("  Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);
117         printk("     - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported");
118         for (i=1; i<8; i++) {
119                 if (extp->SuspendCmdSupport & (1<<i))
120                         printk("     - Unknown Bit %X:               supported\n", i);
121         }
122         
123         printk("  Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
124         printk("     - Lock Bit Active:      %s\n", extp->BlkStatusRegMask&1?"yes":"no");
125         printk("     - Valid Bit Active:     %s\n", extp->BlkStatusRegMask&2?"yes":"no");
126         for (i=2; i<16; i++) {
127                 if (extp->BlkStatusRegMask & (1<<i))
128                         printk("     - Unknown Bit %X Active: yes\n",i);
129         }
130         
131         printk("  Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", 
132                extp->VccOptimal >> 8, extp->VccOptimal & 0xf);
133         if (extp->VppOptimal)
134                 printk("  Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", 
135                        extp->VppOptimal >> 8, extp->VppOptimal & 0xf);
136 #endif  
137         /* OK. We like it. Take over the control of it. */
138
139         /* Switch it into Read Mode */
140         switch(map->buswidth) {
141         case 1:
142                 map->write8(map, 0xff, 0x55);
143                 break;
144         case 2:
145                 map->write16(map, 0xffff, 0xaa);
146                 break;
147         case 4:
148                 map->write32(map, 0xffffffff, 0x154);
149                 break;
150         }
151
152
153         /* If there was an old setup function, decrease its use count */
154         if (cfi->cmdset_setup)
155                 inter_module_put(cfi->im_name);
156         if (cfi->cmdset_priv)
157                 kfree(cfi->cmdset_priv);
158
159         for (i=0; i< cfi->numchips; i++) {
160                 cfi->chips[i].word_write_time = 128;
161                 cfi->chips[i].buffer_write_time = 128;
162                 cfi->chips[i].erase_time = 1024;
163         }               
164                 
165
166         cfi->cmdset_setup = cfi_intelext_setup;
167         cfi->im_name = im_name;
168         cfi->cmdset_priv = extp;
169         
170         return;
171 }
172
173 static struct mtd_info *cfi_intelext_setup(struct map_info *map)
174 {
175         struct cfi_private *cfi = map->fldrv_priv;
176         struct mtd_info *mtd;
177
178         mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
179         printk("number of CFI chips: %d\n", cfi->numchips);
180
181         if (!mtd) {
182           printk("Failed to allocate memory for MTD device\n");
183           kfree(cfi->cmdset_priv);
184           return NULL;
185         }
186
187         memset(mtd, 0, sizeof(*mtd));
188         mtd->priv = map;
189         mtd->type = MTD_NORFLASH;
190         mtd->erasesize = 0x20000; /* FIXME */
191         /* Also select the correct geometry setup too */ 
192         mtd->size = (1 << cfi->cfiq.DevSize) * cfi->numchips;
193         mtd->erase = cfi_intelext_erase_1_by_16;
194         mtd->read = cfi_intelext_read_1_by_16;
195         mtd->write = cfi_intelext_write_1_by_16;
196         mtd->sync = cfi_intelext_sync;
197         mtd->suspend = cfi_intelext_suspend;
198         mtd->resume = cfi_intelext_resume;
199         mtd->flags = MTD_CAP_NORFLASH;
200         map->fldrv_destroy = cfi_intelext_destroy;
201         mtd->name = map->name;
202         return mtd;
203 }
204
205 static inline int do_read_1_by_16_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
206 {
207         __u16 status;
208         unsigned long timeo = jiffies + HZ;
209         DECLARE_WAITQUEUE(wait, current);
210
211         adr += chip->start;
212
213  retry:
214         spin_lock_bh(chip->mutex);
215
216         /* Check that the chip's ready to talk to us.
217          * Later, we can actually think about interrupting it
218          * if it's in FL_ERASING or FL_WRITING state.
219          * Not just yet, though.
220          */
221         switch (chip->state) {
222 #if 0
223         case FL_ERASING:
224         case FL_WRITING:
225                 /* Suspend the operation, set state to FL_xxx_SUSPENDED */
226 #endif
227
228         case FL_CFI_QUERY:
229         case FL_JEDEC_QUERY:
230         case FL_READY:
231                 map->write16(map, cpu_to_le16(0x0070), adr);
232                 chip->state = FL_STATUS;
233
234         case FL_STATUS:
235                 status = le16_to_cpu(map->read16(map, adr));
236
237                 if (!(status & (1<<7))) {
238                         static int z=0;
239                         /* Urgh. Chip not yet ready to talk to us. */
240                         if (time_after(jiffies, timeo)) {
241                                 spin_unlock_bh(chip->mutex);
242                                 printk("waiting for chip to be ready timed out in read");
243                                 return -EIO;
244                         }
245
246                         /* Latency issues. Drop the lock, wait a while and retry */
247                         spin_unlock_bh(chip->mutex);
248
249                         z++;
250                         if ( 0 && !(z % 100 )) 
251                                 printk("chip not ready yet before read. looping\n");
252
253                         udelay(1);
254
255                         goto retry;
256                 }
257                 break;
258
259         default:
260                 printk("Waiting for chip, status = %d\n", chip->state);
261
262                 /* Stick ourselves on a wait queue to be woken when
263                    someone changes the status */
264
265                 set_current_state(TASK_INTERRUPTIBLE);
266                 add_wait_queue(&chip->wq, &wait);
267                 
268                 spin_unlock_bh(chip->mutex);
269
270                 schedule();
271                 remove_wait_queue(&chip->wq, &wait);
272
273                 if(signal_pending(current))
274                         return -EINTR;
275
276
277                 timeo = jiffies + HZ;
278
279                 goto retry;
280         }
281
282         map->write16(map, cpu_to_le16(0x00ff), adr);
283         chip->state = FL_READY;
284
285         map->copy_from(map, buf, adr, len);
286
287         if (chip->state == FL_ERASE_SUSPENDED || 
288             chip->state == FL_WRITE_SUSPENDED) {
289                 printk("Who in hell suspended the pending operation? I didn't write that code yet!\n");
290                 /* Restart it and set the state accordingly */
291         }
292
293         wake_up(&chip->wq);
294         spin_unlock_bh(chip->mutex);
295
296         return 0;
297 }
298
299 static int cfi_intelext_read_1_by_16 (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
300 {
301         struct map_info *map = mtd->priv;
302         struct cfi_private *cfi = map->fldrv_priv;
303         unsigned long ofs;
304         int chipnum;
305         int ret = 0;
306
307         /* ofs: offset within the first chip that the first read should start */
308         chipnum = (from >> cfi->chipshift);
309         ofs = from - (chipnum <<  cfi->chipshift);
310
311         *retlen = 0;
312
313         while (len) {
314                 unsigned long thislen;
315
316                 if (chipnum >= cfi->numchips)
317                         break;
318
319                 if ((len + ofs -1) >> cfi->chipshift)
320                         thislen = (1<<cfi->chipshift) - ofs;
321                 else
322                         thislen = len;
323
324                 ret = do_read_1_by_16_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);
325                 if (ret)
326                         break;
327
328                 *retlen += thislen;
329                 len -= thislen;
330                 buf += thislen;
331                 
332                 ofs = 0;
333                 chipnum++;
334         }
335         return ret;
336 }
337
338 static inline int do_write_1_by_16_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u16 datum)
339 {
340         __u16 status;
341         unsigned long timeo = jiffies + HZ;
342         DECLARE_WAITQUEUE(wait, current);
343         int z = 0;
344         adr += chip->start;
345
346  retry:
347         spin_lock_bh(chip->mutex);
348
349         /* Check that the chip's ready to talk to us.
350          * Later, we can actually think about interrupting it
351          * if it's in FL_ERASING state.
352          * Not just yet, though.
353          */
354         switch (chip->state) {
355         case FL_CFI_QUERY:
356         case FL_JEDEC_QUERY:
357         case FL_READY:
358                 map->write16(map, cpu_to_le16(0x0070), adr);
359                 chip->state = FL_STATUS;
360                 timeo = jiffies + HZ;
361
362         case FL_STATUS:
363                 status = le16_to_cpu(map->read16(map, adr));
364
365                 if (!(status & (1<<7))) {
366
367                         /* Urgh. Chip not yet ready to talk to us. */
368                         if (time_after(jiffies, timeo)) {
369                                 spin_unlock_bh(chip->mutex);
370                                 printk("waiting for chip to be ready timed out in read");
371                                 return -EIO;
372                         }
373
374                         /* Latency issues. Drop the lock, wait a while and retry */
375                         spin_unlock_bh(chip->mutex);
376
377                         z++;
378                         if ( 0 && !(z % 100 ))
379                                 printk("chip not ready yet before write. looping\n");
380                         
381                         udelay(1);
382
383                         goto retry;
384                 }
385                 break;
386
387         default:
388                 printk("Waiting for chip, status = %d\n", chip->state);
389
390                 /* Stick ourselves on a wait queue to be woken when
391                    someone changes the status */
392
393                 set_current_state(TASK_INTERRUPTIBLE);
394                 add_wait_queue(&chip->wq, &wait);
395                 
396                 spin_unlock_bh(chip->mutex);
397
398                 schedule();
399                 remove_wait_queue(&chip->wq, &wait);
400
401                 if(signal_pending(current))
402                         return -EINTR;
403
404                 timeo = jiffies + HZ;
405
406                 goto retry;
407         }
408         
409         map->write16(map, cpu_to_le16(0x0040), adr);
410         map->write16(map, datum, adr);
411         chip->state = FL_WRITING;
412
413         timeo = jiffies + (HZ/2);
414
415         spin_unlock_bh(chip->mutex);
416         udelay(chip->word_write_time);
417         spin_lock_bh(chip->mutex);
418
419         z = 0;
420         while ( !( (status = le16_to_cpu(map->read16(map, adr)))  & 0x80 ) ) {
421
422                 if (chip->state != FL_WRITING) {
423                         /* Someone's suspended the write. Sleep */
424                         set_current_state(TASK_INTERRUPTIBLE);
425                         add_wait_queue(&chip->wq, &wait);
426                         
427                         spin_unlock_bh(chip->mutex);
428                         
429                         schedule();
430                         remove_wait_queue(&chip->wq, &wait);
431                         
432                         if (signal_pending(current))
433                                 return -EINTR;
434                         
435                         timeo = jiffies + (HZ / 2); /* FIXME */
436
437                         spin_lock_bh(chip->mutex);
438                         continue;
439                 }
440
441                 /* OK Still waiting */
442                 if (time_after(jiffies, timeo)) {
443                         chip->state = FL_STATUS;
444                         spin_unlock_bh(chip->mutex);
445                         printk("waiting for chip to be ready timed out in read");
446                         return -EIO;
447                 }
448                 
449                 /* Latency issues. Drop the lock, wait a while and retry */
450                 spin_unlock_bh(chip->mutex);
451                 
452                 z++;
453                 if ( 0 && !(z % 100 )) 
454                   printk("chip not ready yet after write. looping\n");
455                 
456                 udelay(1);
457                 
458                 spin_lock_bh(chip->mutex);
459                 continue;
460         }
461         if (!z) {
462                 chip->word_write_time--;
463                 if (!chip->word_write_time)
464                         chip->word_write_time++;
465         }
466         if (z > 1) 
467                 chip->word_write_time++;
468
469         /* Done and happy. */
470         chip->state = FL_STATUS;
471         wake_up(&chip->wq);
472         spin_unlock_bh(chip->mutex);
473         //      printk("write ret OK at %lx\n", adr);
474         return 0;
475 }
476
477
478 /* This version only uses the 'word write' instruction. We should update it
479  * to write using 'buffer write' if it's available 
480  */
481 static int cfi_intelext_write_1_by_16 (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf)
482 {
483         struct map_info *map = mtd->priv;
484         struct cfi_private *cfi = map->fldrv_priv;
485         int ret = 0;
486         int chipnum;
487         unsigned long ofs;
488
489         *retlen = 0;
490         chipnum = to >> cfi->chipshift;
491         ofs = to  - (chipnum << cfi->chipshift);
492
493         /* If it's not word-aligned, do the first byte write */
494         if (ofs & 1) {
495 #if defined(__LITTLE_ENDIAN)
496                 ret = do_write_1_by_16_oneword(map, &cfi->chips[chipnum],
497                                                ofs, 0xFF | (*buf << 8));
498 #elif defined(__BIG_ENDIAN) 
499                 ret = do_write_1_by_16_oneword(map, &cfi->chips[chipnum],
500                                                ofs, 0xFF00 | (*buf));
501 #else
502 #error define a sensible endianness
503 #endif
504                 if (ret) 
505                         return ret;
506                 
507                 ofs++;
508                 buf++;
509                 (*retlen)++;
510                 len--;
511
512                 if (ofs >> cfi->chipshift) {
513                         chipnum ++; 
514                         ofs = 0;
515                         if (chipnum == cfi->numchips)
516                                 return 0;
517                 }
518         }
519         
520         while(len > 1) {
521                 ret = do_write_1_by_16_oneword(map, &cfi->chips[chipnum],
522                                                ofs, *(__u16 *)buf);
523                 if (ret)
524                         return ret;
525
526                 ofs += 2;
527                 buf += 2;
528                 (*retlen) += 2;
529                 len -= 2;
530
531                 if (ofs >> cfi->chipshift) {
532                         chipnum ++; 
533                         ofs = 0;
534                         if (chipnum == cfi->numchips)
535                                 return 0;
536                 }
537         }
538
539         if (len) {
540                 /* Final byte to write */
541 #if defined(__LITTLE_ENDIAN)
542                 ret = do_write_1_by_16_oneword(map, &cfi->chips[chipnum],
543                                                ofs, 0xFF00 | (*buf));
544 #elif defined(__BIG_ENDIAN) 
545                 ret = do_write_1_by_16_oneword(map, &cfi->chips[chipnum],
546                                                ofs, 0xFF | (*buf << 8));
547 #else
548 #error define a sensible endianness
549 #endif
550                 if (ret) 
551                         return ret;
552                 
553                 (*retlen)++;
554         }
555
556         return 0;
557 }
558
559
560 static inline int do_erase_1_by_16_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
561 {
562         __u16 status;
563         unsigned long timeo = jiffies + HZ;
564         DECLARE_WAITQUEUE(wait, current);
565
566         adr += chip->start;
567
568  retry:
569         spin_lock_bh(chip->mutex);
570
571         /* Check that the chip's ready to talk to us. */
572         switch (chip->state) {
573         case FL_CFI_QUERY:
574         case FL_JEDEC_QUERY:
575         case FL_READY:
576                 map->write16(map, cpu_to_le16(0x0070), adr);
577                 chip->state = FL_STATUS;
578                 timeo = jiffies + HZ;
579
580         case FL_STATUS:
581                 status = le16_to_cpu(map->read16(map, adr));
582
583                 if (!(status & (1<<7))) {
584                         static int z=0;
585                         /* Urgh. Chip not yet ready to talk to us. */
586                         if (time_after(jiffies, timeo)) {
587                                 spin_unlock_bh(chip->mutex);
588                                 printk("waiting for chip to be ready timed out in erase");
589                                 return -EIO;
590                         }
591
592                         /* Latency issues. Drop the lock, wait a while and retry */
593                         spin_unlock_bh(chip->mutex);
594
595                         z++;
596                         if ( 0 && !(z % 100 )) 
597                                 printk("chip not ready yet before erase. looping\n");
598
599                         udelay(1);
600
601                         goto retry;
602                 }
603                 break;
604
605         default:
606                 printk("Waiting for chip, status = %d\n", chip->state);
607
608                 /* Stick ourselves on a wait queue to be woken when
609                    someone changes the status */
610
611                 set_current_state(TASK_INTERRUPTIBLE);
612                 add_wait_queue(&chip->wq, &wait);
613                 
614                 spin_unlock_bh(chip->mutex);
615
616                 schedule();
617                 remove_wait_queue(&chip->wq, &wait);
618
619                 if(signal_pending(current))
620                         return -EINTR;
621
622                 timeo = jiffies + HZ;
623
624                 goto retry;
625         }
626         
627         map->write16(map, cpu_to_le16(0x0020), adr);
628         map->write16(map, cpu_to_le16(0x00D0), adr);
629
630         chip->state = FL_ERASING;
631         
632         timeo = jiffies + (HZ*2);
633         spin_unlock_bh(chip->mutex);
634         schedule_timeout(HZ);
635         spin_lock_bh(chip->mutex);
636
637         /* FIXME. Use a timer to check this, and return immediately. */
638         /* Once the state machine's known to be working I'll do that */
639
640         while ( !( (status = le16_to_cpu(map->read16(map, adr)))  & 0x80 ) ) {
641                 static int z=0;
642
643                 if (chip->state != FL_ERASING) {
644                         /* Someone's suspended the erase. Sleep */
645                         set_current_state(TASK_INTERRUPTIBLE);
646                         add_wait_queue(&chip->wq, &wait);
647                         
648                         spin_unlock_bh(chip->mutex);
649                         printk("erase suspended. Sleeping\n");
650                         
651                         schedule();
652                         remove_wait_queue(&chip->wq, &wait);
653                         
654                         if (signal_pending(current))
655                                 return -EINTR;
656                         
657                         timeo = jiffies + (HZ*2); /* FIXME */
658                         spin_lock_bh(chip->mutex);
659                         continue;
660                 }
661
662                 /* OK Still waiting */
663                 if (time_after(jiffies, timeo)) {
664                         chip->state = FL_STATUS;
665                         spin_unlock_bh(chip->mutex);
666                         printk("waiting for erase to complete timed out.");
667                         return -EIO;
668                 }
669                 
670                 /* Latency issues. Drop the lock, wait a while and retry */
671                 spin_unlock_bh(chip->mutex);
672
673                 z++;
674                 if ( 0 && !(z % 100 )) 
675                         printk("chip not ready yet after erase. looping\n");
676
677                 udelay(1);
678                 
679                 spin_lock_bh(chip->mutex);
680                 continue;
681         }
682         
683         /* Done and happy. */
684         chip->state = FL_STATUS;
685         wake_up(&chip->wq);
686         spin_unlock_bh(chip->mutex);
687         //printk("erase ret OK\n");
688         return 0;
689 }
690
691 static int cfi_intelext_erase_1_by_16 (struct mtd_info *mtd, struct erase_info *instr)
692 {
693         struct map_info *map = mtd->priv;
694         struct cfi_private *cfi = map->fldrv_priv;
695         unsigned long adr, len;
696         int chipnum, ret = 0;
697
698         if (instr->addr & (mtd->erasesize - 1))
699                 return -EINVAL;
700
701         if (instr->len & (mtd->erasesize -1))
702                 return -EINVAL;
703
704         if ((instr->len + instr->addr) > mtd->size)
705                 return -EINVAL;
706
707         chipnum = instr->addr >> cfi->chipshift;
708         adr = instr->addr - (chipnum << cfi->chipshift);
709         len = instr->len;
710
711         while(len) {
712                 ret = do_erase_1_by_16_oneblock(map, &cfi->chips[chipnum], adr);
713                 
714                 if (ret)
715                         return ret;
716
717                 adr += mtd->erasesize;
718                 len -= mtd->erasesize;
719
720                 if (adr >> cfi->chipshift) {
721                         adr = 0;
722                         chipnum++;
723                         
724                         if (chipnum >= cfi->numchips)
725                         break;
726                 }
727         }
728                 
729         if (instr->callback)
730                 instr->callback(instr);
731         
732         return 0;
733 }
734
735
736
737 static void cfi_intelext_sync (struct mtd_info *mtd)
738 {
739         struct map_info *map = mtd->priv;
740         struct cfi_private *cfi = map->fldrv_priv;
741         int i;
742         struct flchip *chip;
743         int ret = 0;
744         DECLARE_WAITQUEUE(wait, current);
745
746         for (i=0; !ret && i<cfi->numchips; i++) {
747                 chip = &cfi->chips[i];
748
749         retry:
750                 spin_lock_bh(chip->mutex);
751
752                 switch(chip->state) {
753                 case FL_READY:
754                 case FL_STATUS:
755                 case FL_CFI_QUERY:
756                 case FL_JEDEC_QUERY:
757                         chip->oldstate = chip->state;
758                         chip->state = FL_SYNCING;
759                         /* No need to wake_up() on this state change - 
760                          * as the whole point is that nobody can do anything
761                          * with the chip now anyway.
762                          */
763                         spin_unlock_bh(chip->mutex);
764                         break;
765
766                 default:
767                         /* Not an idle state */
768                         add_wait_queue(&chip->wq, &wait);
769                         
770                         spin_unlock_bh(chip->mutex);
771                         schedule();
772                         
773                         remove_wait_queue(&chip->wq, &wait);
774
775                         goto retry;
776                 }
777         }
778
779         /* Unlock the chips again */
780
781         for (i--; i >=0; i--) {
782                 chip = &cfi->chips[i];
783
784                 spin_lock_bh(chip->mutex);
785                 
786                 if (chip->state == FL_SYNCING) {
787                         chip->state = chip->oldstate;
788                         wake_up(&chip->wq);
789                 }
790                 spin_unlock_bh(chip->mutex);
791         }
792 }
793
794
795 static int cfi_intelext_suspend(struct mtd_info *mtd)
796 {
797         struct map_info *map = mtd->priv;
798         struct cfi_private *cfi = map->fldrv_priv;
799         int i;
800         struct flchip *chip;
801         int ret = 0;
802
803         for (i=0; !ret && i<cfi->numchips; i++) {
804                 chip = &cfi->chips[i];
805
806                 spin_lock_bh(chip->mutex);
807
808                 switch(chip->state) {
809                 case FL_READY:
810                 case FL_STATUS:
811                 case FL_CFI_QUERY:
812                 case FL_JEDEC_QUERY:
813                         chip->oldstate = chip->state;
814                         chip->state = FL_PM_SUSPENDED;
815                         /* No need to wake_up() on this state change - 
816                          * as the whole point is that nobody can do anything
817                          * with the chip now anyway.
818                          */
819                         spin_unlock_bh(chip->mutex);
820                         break;
821
822                 default:
823                         ret = -EAGAIN;
824                         break;
825                 }
826         }
827
828         /* Unlock the chips again */
829
830         for (i--; i >=0; i--) {
831                 chip = &cfi->chips[i];
832
833                 spin_lock_bh(chip->mutex);
834                 
835                 if (chip->state == FL_PM_SUSPENDED) {
836                         chip->state = chip->oldstate;
837                         wake_up(&chip->wq);
838                 }
839                 spin_unlock_bh(chip->mutex);
840         }
841         
842         return ret;
843 }
844
845 static void cfi_intelext_resume(struct mtd_info *mtd)
846 {
847         struct map_info *map = mtd->priv;
848         struct cfi_private *cfi = map->fldrv_priv;
849         int i;
850         struct flchip *chip;
851
852         for (i=0; i<cfi->numchips; i++) {
853         
854                 chip = &cfi->chips[i];
855
856                 spin_lock_bh(chip->mutex);
857                 
858                 if (chip->state == FL_PM_SUSPENDED) {
859                         chip->state = chip->oldstate;
860                         wake_up(&chip->wq);
861                 }
862                 else
863                         printk("Argh. Chip not in PM_SUSPENDED state upon resume()\n");
864
865                 spin_unlock_bh(chip->mutex);
866         }
867 }
868
869 static void cfi_intelext_destroy(struct mtd_info *mtd)
870 {
871         struct map_info *map = mtd->priv;
872         struct cfi_private *cfi = map->fldrv_priv;
873         kfree(cfi->cmdset_priv);
874         inter_module_put(cfi->im_name);
875         kfree(cfi);
876 }
877
878
879 static int __init cfi_intelext_init(void)
880 {
881         inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0001);
882         return 0;
883 }
884
885 static void __exit cfi_intelext_exit(void)
886 {
887         inter_module_unregister(im_name);
888 }
889
890 module_init(cfi_intelext_init);
891 module_exit(cfi_intelext_exit);