]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/nand/nandsim_chip.c
Merge llvm, clang, lld and lldb trunk r300890, and update build glue.
[FreeBSD/FreeBSD.git] / sys / dev / nand / nandsim_chip.c
1 /*-
2  * Copyright (C) 2009-2012 Semihalf
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include <sys/param.h>
31 #include <sys/types.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/lock.h>
35 #include <sys/malloc.h>
36 #include <sys/module.h>
37 #include <sys/mutex.h>
38 #include <sys/proc.h>
39 #include <sys/sched.h>
40 #include <sys/kthread.h>
41 #include <sys/unistd.h>
42
43 #include <dev/nand/nand.h>
44 #include <dev/nand/nandsim_chip.h>
45 #include <dev/nand/nandsim_log.h>
46 #include <dev/nand/nandsim_swap.h>
47
48 MALLOC_DEFINE(M_NANDSIM, "NANDsim", "NANDsim dynamic data");
49
50 #define NANDSIM_CHIP_LOCK(chip)         mtx_lock(&(chip)->ns_lock)
51 #define NANDSIM_CHIP_UNLOCK(chip)       mtx_unlock(&(chip)->ns_lock)
52
53 static nandsim_evh_t erase_evh;
54 static nandsim_evh_t idle_evh;
55 static nandsim_evh_t poweron_evh;
56 static nandsim_evh_t reset_evh;
57 static nandsim_evh_t read_evh;
58 static nandsim_evh_t readid_evh;
59 static nandsim_evh_t readparam_evh;
60 static nandsim_evh_t write_evh;
61
62 static void nandsim_loop(void *);
63 static void nandsim_undefined(struct nandsim_chip *, uint8_t);
64 static void nandsim_bad_address(struct nandsim_chip *, uint8_t *);
65 static void nandsim_ignore_address(struct nandsim_chip *, uint8_t);
66 static void nandsim_sm_error(struct nandsim_chip *);
67 static void nandsim_start_handler(struct nandsim_chip *, nandsim_evh_t);
68
69 static void nandsim_callout_eh(void *);
70 static int  nandsim_delay(struct nandsim_chip *, int);
71
72 static int  nandsim_bbm_init(struct nandsim_chip *, uint32_t, uint32_t *);
73 static int  nandsim_blk_state_init(struct nandsim_chip *, uint32_t, uint32_t);
74 static void nandsim_blk_state_destroy(struct nandsim_chip *);
75 static int  nandchip_is_block_valid(struct nandsim_chip *, int);
76
77 static void nandchip_set_status(struct nandsim_chip *, uint8_t);
78 static void nandchip_clear_status(struct nandsim_chip *, uint8_t);
79
80 struct proc *nandsim_proc;
81
82 struct nandsim_chip *
83 nandsim_chip_init(struct nandsim_softc* sc, uint8_t chip_num,
84     struct sim_chip *sim_chip)
85 {
86         struct nandsim_chip *chip;
87         struct onfi_params *chip_param;
88         char swapfile[20];
89         uint32_t size;
90         int error;
91
92         chip = malloc(sizeof(*chip), M_NANDSIM, M_WAITOK | M_ZERO);
93
94         mtx_init(&chip->ns_lock, "nandsim lock", NULL, MTX_DEF);
95         callout_init(&chip->ns_callout, 1);
96         STAILQ_INIT(&chip->nandsim_events);
97
98         chip->chip_num = chip_num;
99         chip->ctrl_num = sim_chip->ctrl_num;
100         chip->sc = sc;
101
102         if (!sim_chip->is_wp)
103                 nandchip_set_status(chip, NAND_STATUS_WP);
104
105         chip_param = &chip->params;
106
107         chip->id.dev_id = sim_chip->device_id;
108         chip->id.man_id = sim_chip->manufact_id;
109
110         chip->error_ratio = sim_chip->error_ratio;
111         chip->wear_level = sim_chip->wear_level;
112         chip->prog_delay = sim_chip->prog_time;
113         chip->erase_delay = sim_chip->erase_time;
114         chip->read_delay = sim_chip->read_time;
115
116         chip_param->t_prog = sim_chip->prog_time;
117         chip_param->t_bers = sim_chip->erase_time;
118         chip_param->t_r = sim_chip->read_time;
119         bcopy("onfi", &chip_param->signature, 4);
120
121         chip_param->manufacturer_id = sim_chip->manufact_id;
122         strncpy(chip_param->manufacturer_name, sim_chip->manufacturer, 12);
123         chip_param->manufacturer_name[11] = 0;
124         strncpy(chip_param->device_model, sim_chip->device_model, 20);
125         chip_param->device_model[19] = 0;
126
127         chip_param->bytes_per_page = sim_chip->page_size;
128         chip_param->spare_bytes_per_page = sim_chip->oob_size;
129         chip_param->pages_per_block = sim_chip->pgs_per_blk;
130         chip_param->blocks_per_lun = sim_chip->blks_per_lun;
131         chip_param->luns = sim_chip->luns;
132
133         init_chip_geom(&chip->cg, chip_param->luns, chip_param->blocks_per_lun,
134             chip_param->pages_per_block, chip_param->bytes_per_page,
135             chip_param->spare_bytes_per_page);
136
137         chip_param->address_cycles = sim_chip->row_addr_cycles |
138             (sim_chip->col_addr_cycles << 4);
139         chip_param->features = sim_chip->features;
140         if (sim_chip->width == 16)
141                 chip_param->features |= ONFI_FEAT_16BIT;
142
143         size = chip_param->blocks_per_lun * chip_param->luns;
144
145         error = nandsim_blk_state_init(chip, size, sim_chip->wear_level);
146         if (error) {
147                 mtx_destroy(&chip->ns_lock);
148                 free(chip, M_NANDSIM);
149                 return (NULL);
150         }
151
152         error = nandsim_bbm_init(chip, size, sim_chip->bad_block_map);
153         if (error) {
154                 mtx_destroy(&chip->ns_lock);
155                 nandsim_blk_state_destroy(chip);
156                 free(chip, M_NANDSIM);
157                 return (NULL);
158         }
159
160         nandsim_start_handler(chip, poweron_evh);
161
162         nand_debug(NDBG_SIM,"Create thread for chip%d [%8p]", chip->chip_num,
163             chip);
164         /* Create chip thread */
165         error = kproc_kthread_add(nandsim_loop, chip, &nandsim_proc,
166             &chip->nandsim_td, RFSTOPPED | RFHIGHPID,
167             0, "nandsim", "chip");
168         if (error) {
169                 mtx_destroy(&chip->ns_lock);
170                 nandsim_blk_state_destroy(chip);
171                 free(chip, M_NANDSIM);
172                 return (NULL);
173         }
174
175         thread_lock(chip->nandsim_td);
176         sched_class(chip->nandsim_td, PRI_REALTIME);
177         sched_add(chip->nandsim_td, SRQ_BORING);
178         thread_unlock(chip->nandsim_td);
179
180         size = (chip_param->bytes_per_page +
181             chip_param->spare_bytes_per_page) *
182             chip_param->pages_per_block;
183
184         sprintf(swapfile, "chip%d%d.swp", chip->ctrl_num, chip->chip_num);
185         chip->swap = nandsim_swap_init(swapfile, chip_param->blocks_per_lun *
186             chip_param->luns, size);
187         if (!chip->swap)
188                 nandsim_chip_destroy(chip);
189
190         /* Wait for new thread to enter main loop */
191         tsleep(chip->nandsim_td, PWAIT, "ns_chip", 1 * hz);
192
193         return (chip);
194 }
195
196 static int
197 nandsim_blk_state_init(struct nandsim_chip *chip, uint32_t size,
198     uint32_t wear_lev)
199 {
200         int i;
201
202         if (!chip || size == 0)
203                 return (-1);
204
205         chip->blk_state = malloc(size * sizeof(struct nandsim_block_state),
206             M_NANDSIM, M_WAITOK | M_ZERO);
207
208         for (i = 0; i < size; i++) {
209                 if (wear_lev)
210                         chip->blk_state[i].wear_lev = wear_lev;
211                 else
212                         chip->blk_state[i].wear_lev = -1;
213         }
214
215         return (0);
216 }
217
218 static void
219 nandsim_blk_state_destroy(struct nandsim_chip *chip)
220 {
221
222         if (chip && chip->blk_state)
223                 free(chip->blk_state, M_NANDSIM);
224 }
225
226 static int
227 nandsim_bbm_init(struct nandsim_chip *chip, uint32_t size,
228     uint32_t *sim_bbm)
229 {
230         uint32_t index;
231         int i;
232
233         if ((chip == NULL) || (size == 0))
234                 return (-1);
235
236         if (chip->blk_state == NULL)
237                 return (-1);
238
239         if (sim_bbm == NULL)
240                 return (0);
241
242         for (i = 0; i < MAX_BAD_BLOCKS; i++) {
243                 index = sim_bbm[i];
244
245                 if (index == 0xffffffff)
246                         break;
247                 else if (index > size)
248                         return (-1);
249                 else
250                         chip->blk_state[index].is_bad = 1;
251         }
252
253         return (0);
254 }
255
256 void
257 nandsim_chip_destroy(struct nandsim_chip *chip)
258 {
259         struct nandsim_ev *ev;
260
261         ev = create_event(chip, NANDSIM_EV_EXIT, 0);
262         if (ev)
263                 send_event(ev);
264 }
265
266 void
267 nandsim_chip_freeze(struct nandsim_chip *chip)
268 {
269
270         chip->flags |= NANDSIM_CHIP_FROZEN;
271 }
272
273 static void
274 nandsim_loop(void *arg)
275 {
276         struct nandsim_chip *chip = (struct nandsim_chip *)arg;
277         struct nandsim_ev *ev;
278
279         nand_debug(NDBG_SIM,"Start main loop for chip%d [%8p]", chip->chip_num,
280             chip);
281         for(;;) {
282                 NANDSIM_CHIP_LOCK(chip);
283                 if (!(chip->flags & NANDSIM_CHIP_ACTIVE)) {
284                         chip->flags |= NANDSIM_CHIP_ACTIVE;
285                         wakeup(chip->nandsim_td);
286                 }
287
288                 if (STAILQ_EMPTY(&chip->nandsim_events)) {
289                         nand_debug(NDBG_SIM,"Chip%d [%8p] going sleep",
290                             chip->chip_num, chip);
291                         msleep(chip, &chip->ns_lock, PRIBIO, "nandev", 0);
292                 }
293
294                 ev = STAILQ_FIRST(&chip->nandsim_events);
295                 STAILQ_REMOVE_HEAD(&chip->nandsim_events, links);
296                 NANDSIM_CHIP_UNLOCK(chip);
297                 if (ev->type == NANDSIM_EV_EXIT) {
298                         NANDSIM_CHIP_LOCK(chip);
299                         destroy_event(ev);
300                         wakeup(ev);
301                         while (!STAILQ_EMPTY(&chip->nandsim_events)) {
302                                 ev = STAILQ_FIRST(&chip->nandsim_events);
303                                 STAILQ_REMOVE_HEAD(&chip->nandsim_events,
304                                     links);
305                                 destroy_event(ev);
306                                 wakeup(ev);
307                         }
308                         NANDSIM_CHIP_UNLOCK(chip);
309                         nandsim_log(chip, NANDSIM_LOG_SM, "destroyed\n");
310                         mtx_destroy(&chip->ns_lock);
311                         nandsim_blk_state_destroy(chip);
312                         nandsim_swap_destroy(chip->swap);
313                         free(chip, M_NANDSIM);
314                         nandsim_proc = NULL;
315
316                         kthread_exit();
317                 }
318
319                 if (!(chip->flags & NANDSIM_CHIP_FROZEN)) {
320                         nand_debug(NDBG_SIM,"Chip [%x] get event [%x]",
321                             chip->chip_num, ev->type);
322                         chip->ev_handler(chip, ev->type, ev->data);
323                 }
324
325                 wakeup(ev);
326                 destroy_event(ev);
327         }
328
329 }
330
331 struct nandsim_ev *
332 create_event(struct nandsim_chip *chip, uint8_t type, uint8_t data_size)
333 {
334         struct nandsim_ev *ev;
335
336         ev = malloc(sizeof(*ev), M_NANDSIM, M_NOWAIT | M_ZERO);
337         if (!ev) {
338                 nand_debug(NDBG_SIM,"Cannot create event");
339                 return (NULL);
340         }
341
342         if (data_size > 0)
343                 ev->data = malloc(sizeof(*ev), M_NANDSIM, M_NOWAIT | M_ZERO);
344         ev->type = type;
345         ev->chip = chip;
346
347         return (ev);
348 }
349
350 void
351 destroy_event(struct nandsim_ev *ev)
352 {
353
354         if (ev->data)
355                 free(ev->data, M_NANDSIM);
356         free(ev, M_NANDSIM);
357 }
358
359 int
360 send_event(struct nandsim_ev *ev)
361 {
362         struct nandsim_chip *chip = ev->chip;
363
364         if (!(chip->flags & NANDSIM_CHIP_FROZEN)) {
365                 nand_debug(NDBG_SIM,"Chip%d [%p] send event %x",
366                     chip->chip_num, chip, ev->type);
367
368                 NANDSIM_CHIP_LOCK(chip);
369                 STAILQ_INSERT_TAIL(&chip->nandsim_events, ev, links);
370                 NANDSIM_CHIP_UNLOCK(chip);
371
372                 wakeup(chip);
373                 if ((ev->type != NANDSIM_EV_TIMEOUT) && chip->nandsim_td &&
374                     (curthread != chip->nandsim_td))
375                         tsleep(ev, PWAIT, "ns_ev", 5 * hz);
376         }
377
378         return (0);
379 }
380
381 static void
382 nandsim_callout_eh(void *arg)
383 {
384         struct nandsim_ev *ev = (struct nandsim_ev *)arg;
385
386         send_event(ev);
387 }
388
389 static int
390 nandsim_delay(struct nandsim_chip *chip, int timeout)
391 {
392         struct nandsim_ev *ev;
393         struct timeval delay;
394         int tm;
395
396         nand_debug(NDBG_SIM,"Chip[%d] Set delay: %d", chip->chip_num, timeout);
397
398         ev = create_event(chip, NANDSIM_EV_TIMEOUT, 0);
399         if (!ev)
400                 return (-1);
401
402         chip->sm_state = NANDSIM_STATE_TIMEOUT;
403         tm = (timeout/10000) * (hz / 100);
404         if (callout_reset(&chip->ns_callout, tm, nandsim_callout_eh, ev))
405                 return (-1);
406
407         delay.tv_sec = chip->read_delay / 1000000;
408         delay.tv_usec = chip->read_delay % 1000000;
409         timevaladd(&chip->delay_tv, &delay);
410
411         return (0);
412 }
413
414 static void
415 nandsim_start_handler(struct nandsim_chip *chip, nandsim_evh_t evh)
416 {
417         struct nandsim_ev *ev;
418
419         chip->ev_handler = evh;
420
421         nand_debug(NDBG_SIM,"Start handler %p for chip%d [%p]", evh,
422             chip->chip_num, chip);
423         ev = create_event(chip, NANDSIM_EV_START, 0);
424         if (!ev)
425                 nandsim_sm_error(chip);
426
427         send_event(ev);
428 }
429
430 static void
431 nandchip_set_data(struct nandsim_chip *chip, uint8_t *data, uint32_t len,
432     uint32_t idx)
433 {
434
435         nand_debug(NDBG_SIM,"Chip [%x] data %p [%x] at %x", chip->chip_num,
436             data, len, idx);
437         chip->data.data_ptr = data;
438         chip->data.size = len;
439         chip->data.index = idx;
440 }
441
442 static int
443 nandchip_chip_space(struct nandsim_chip *chip, int32_t row, int32_t column,
444     size_t size, uint8_t writing)
445 {
446         struct block_space *blk_space;
447         uint32_t lun, block, page, offset, block_size;
448         int err;
449
450         block_size = chip->cg.block_size +
451             (chip->cg.oob_size * chip->cg.pgs_per_blk);
452
453         err = nand_row_to_blkpg(&chip->cg, row, &lun, &block, &page);
454         if (err) {
455                 nand_debug(NDBG_SIM,"cannot get address\n");
456                 return (-1);
457         }
458
459         if (!nandchip_is_block_valid(chip, block)) {
460                 nandchip_set_data(chip, NULL, 0, 0);
461                 return (-1);
462         }
463
464         blk_space = get_bs(chip->swap, block, writing);
465         if (!blk_space) {
466                 nandchip_set_data(chip, NULL, 0, 0);
467                 return (-1);
468         }
469
470         if (size > block_size)
471                 size = block_size;
472
473         if (size == block_size) {
474                 offset = 0;
475                 column = 0;
476         } else
477                 offset = page * (chip->cg.page_size + chip->cg.oob_size);
478
479         nandchip_set_data(chip, &blk_space->blk_ptr[offset], size, column);
480
481         return (0);
482 }
483
484 static int
485 nandchip_get_addr_byte(struct nandsim_chip *chip, void *data, uint32_t *value)
486 {
487         int ncycles = 0;
488         uint8_t byte;
489         uint8_t *buffer;
490
491         buffer = (uint8_t *)value;
492         byte = *((uint8_t *)data);
493
494         KASSERT((chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW ||
495             chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL),
496             ("unexpected state"));
497
498         if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) {
499                 ncycles = chip->params.address_cycles & 0xf;
500                 buffer[chip->sm_addr_cycle++] = byte;
501         } else if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL) {
502                 ncycles = (chip->params.address_cycles >> 4) & 0xf;
503                 buffer[chip->sm_addr_cycle++] = byte;
504         }
505
506         nand_debug(NDBG_SIM, "Chip [%x] read addr byte: %02x (%d of %d)\n",
507             chip->chip_num, byte, chip->sm_addr_cycle, ncycles);
508
509         if (chip->sm_addr_cycle == ncycles) {
510                 chip->sm_addr_cycle = 0;
511                 return (0);
512         }
513
514         return (1);
515 }
516
517 static int
518 nandchip_is_block_valid(struct nandsim_chip *chip, int block_num)
519 {
520
521         if (!chip || !chip->blk_state)
522                 return (0);
523
524         if (chip->blk_state[block_num].wear_lev == 0 ||
525             chip->blk_state[block_num].is_bad)
526                 return (0);
527
528         return (1);
529 }
530
531 static void
532 nandchip_set_status(struct nandsim_chip *chip, uint8_t flags)
533 {
534
535         chip->chip_status |= flags;
536 }
537
538 static void
539 nandchip_clear_status(struct nandsim_chip *chip, uint8_t flags)
540 {
541
542         chip->chip_status &= ~flags;
543 }
544
545 uint8_t
546 nandchip_get_status(struct nandsim_chip *chip)
547 {
548         return (chip->chip_status);
549 }
550
551 void
552 nandsim_chip_timeout(struct nandsim_chip *chip)
553 {
554         struct timeval tv;
555
556         getmicrotime(&tv);
557
558         if (chip->sm_state == NANDSIM_STATE_TIMEOUT &&
559             timevalcmp(&tv, &chip->delay_tv, >=)) {
560                 nandchip_set_status(chip, NAND_STATUS_RDY);
561         }
562 }
563 void
564 poweron_evh(struct nandsim_chip *chip, uint32_t type, void *data)
565 {
566         uint8_t cmd;
567
568         if (type == NANDSIM_EV_START)
569                 chip->sm_state = NANDSIM_STATE_IDLE;
570         else if (type == NANDSIM_EV_CMD) {
571                 cmd = *(uint8_t *)data;
572                 switch(cmd) {
573                 case NAND_CMD_RESET:
574                         nandsim_log(chip, NANDSIM_LOG_SM, "in RESET state\n");
575                         nandsim_start_handler(chip, reset_evh);
576                         break;
577                 default:
578                         nandsim_undefined(chip, type);
579                         break;
580                 }
581         } else
582                 nandsim_undefined(chip, type);
583 }
584
585 void
586 idle_evh(struct nandsim_chip *chip, uint32_t type, void *data)
587 {
588         uint8_t cmd;
589
590         if (type == NANDSIM_EV_START) {
591                 nandsim_log(chip, NANDSIM_LOG_SM, "in IDLE state\n");
592                 chip->sm_state = NANDSIM_STATE_WAIT_CMD;
593         } else if (type == NANDSIM_EV_CMD) {
594                 nandchip_clear_status(chip, NAND_STATUS_FAIL);
595                 getmicrotime(&chip->delay_tv);
596                 cmd = *(uint8_t *)data;
597                 switch(cmd) {
598                 case NAND_CMD_READ_ID:
599                         nandsim_start_handler(chip, readid_evh);
600                         break;
601                 case NAND_CMD_READ_PARAMETER:
602                         nandsim_start_handler(chip, readparam_evh);
603                         break;
604                 case NAND_CMD_READ:
605                         nandsim_start_handler(chip, read_evh);
606                         break;
607                 case NAND_CMD_PROG:
608                         nandsim_start_handler(chip, write_evh);
609                         break;
610                 case NAND_CMD_ERASE:
611                         nandsim_start_handler(chip, erase_evh);
612                         break;
613                 default:
614                         nandsim_undefined(chip, type);
615                         break;
616                 }
617         } else
618                 nandsim_undefined(chip, type);
619 }
620
621 void
622 readid_evh(struct nandsim_chip *chip, uint32_t type, void *data)
623 {
624         struct onfi_params *params;
625         uint8_t addr;
626
627         params = &chip->params;
628
629         if (type == NANDSIM_EV_START) {
630                 nandsim_log(chip, NANDSIM_LOG_SM, "in READID state\n");
631                 chip->sm_state = NANDSIM_STATE_WAIT_ADDR_BYTE;
632         } else if (type == NANDSIM_EV_ADDR) {
633
634                 addr = *((uint8_t *)data);
635
636                 if (addr == 0x0)
637                         nandchip_set_data(chip, (uint8_t *)&chip->id, 2, 0);
638                 else if (addr == ONFI_SIG_ADDR)
639                         nandchip_set_data(chip, (uint8_t *)&params->signature,
640                             4, 0);
641                 else
642                         nandsim_bad_address(chip, &addr);
643
644                 nandsim_start_handler(chip, idle_evh);
645         } else
646                 nandsim_undefined(chip, type);
647 }
648
649 void
650 readparam_evh(struct nandsim_chip *chip, uint32_t type, void *data)
651 {
652         struct onfi_params *params;
653         uint8_t addr;
654
655         params = &chip->params;
656
657         if (type == NANDSIM_EV_START) {
658                 nandsim_log(chip, NANDSIM_LOG_SM, "in READPARAM state\n");
659                 chip->sm_state = NANDSIM_STATE_WAIT_ADDR_BYTE;
660         } else if (type == NANDSIM_EV_ADDR) {
661                 addr = *((uint8_t *)data);
662
663                 if (addr == 0) {
664                         nandchip_set_data(chip, (uint8_t *)params,
665                             sizeof(*params), 0);
666                 } else
667                         nandsim_bad_address(chip, &addr);
668
669                 nandsim_start_handler(chip, idle_evh);
670         } else
671                 nandsim_undefined(chip, type);
672 }
673
674 void
675 read_evh(struct nandsim_chip *chip, uint32_t type, void *data)
676 {
677         static uint32_t column = 0, row = 0;
678         uint32_t size;
679         uint8_t cmd;
680
681         size = chip->cg.page_size + chip->cg.oob_size;
682
683         switch (type) {
684         case NANDSIM_EV_START:
685                 nandsim_log(chip, NANDSIM_LOG_SM, "in READ state\n");
686                 chip->sm_state = NANDSIM_STATE_WAIT_ADDR_COL;
687                 break;
688         case NANDSIM_EV_ADDR:
689                 if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL) {
690                         if (nandchip_get_addr_byte(chip, data, &column))
691                                 break;
692
693                         chip->sm_state = NANDSIM_STATE_WAIT_ADDR_ROW;
694                 } else if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) {
695                         if (nandchip_get_addr_byte(chip, data, &row))
696                                 break;
697
698                         chip->sm_state = NANDSIM_STATE_WAIT_CMD;
699                 } else
700                         nandsim_ignore_address(chip, *((uint8_t *)data));
701                 break;
702         case NANDSIM_EV_CMD:
703                 cmd = *(uint8_t *)data;
704                 if (chip->sm_state == NANDSIM_STATE_WAIT_CMD &&
705                     cmd == NAND_CMD_READ_END) {
706                         if (chip->read_delay != 0 &&
707                             nandsim_delay(chip, chip->read_delay) == 0)
708                                 nandchip_clear_status(chip, NAND_STATUS_RDY);
709                         else {
710                                 nandchip_chip_space(chip, row, column, size, 0);
711                                 nandchip_set_status(chip, NAND_STATUS_RDY);
712                                 nandsim_start_handler(chip, idle_evh);
713                         }
714                 } else
715                         nandsim_undefined(chip, type);
716                 break;
717         case NANDSIM_EV_TIMEOUT:
718                 if (chip->sm_state == NANDSIM_STATE_TIMEOUT) {
719                         nandchip_chip_space(chip, row, column, size, 0);
720                         nandchip_set_status(chip, NAND_STATUS_RDY);
721                         nandsim_start_handler(chip, idle_evh);
722                 } else
723                         nandsim_undefined(chip, type);
724                 break;
725         }
726 }
727 void
728 write_evh(struct nandsim_chip *chip, uint32_t type, void *data)
729 {
730         static uint32_t column, row;
731         uint32_t size;
732         uint8_t cmd;
733         int err;
734
735         size = chip->cg.page_size + chip->cg.oob_size;
736
737         switch(type) {
738         case NANDSIM_EV_START:
739                 nandsim_log(chip, NANDSIM_LOG_SM, "in WRITE state\n");
740                 chip->sm_state = NANDSIM_STATE_WAIT_ADDR_COL;
741                 break;
742         case NANDSIM_EV_ADDR:
743                 if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL) {
744                         if (nandchip_get_addr_byte(chip, data, &column))
745                                 break;
746
747                         chip->sm_state = NANDSIM_STATE_WAIT_ADDR_ROW;
748                 } else if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) {
749                         if (nandchip_get_addr_byte(chip, data, &row))
750                                 break;
751
752                         err = nandchip_chip_space(chip, row, column, size, 1);
753                         if (err == -1)
754                                 nandchip_set_status(chip, NAND_STATUS_FAIL);
755
756                         chip->sm_state = NANDSIM_STATE_WAIT_CMD;
757                 } else
758                         nandsim_ignore_address(chip, *((uint8_t *)data));
759                 break;
760         case NANDSIM_EV_CMD:
761                 cmd = *(uint8_t *)data;
762                 if (chip->sm_state == NANDSIM_STATE_WAIT_CMD &&
763                     cmd == NAND_CMD_PROG_END) {
764                         if (chip->prog_delay != 0 &&
765                             nandsim_delay(chip, chip->prog_delay) == 0)
766                                 nandchip_clear_status(chip, NAND_STATUS_RDY);
767                         else {
768                                 nandchip_set_status(chip, NAND_STATUS_RDY);
769                                 nandsim_start_handler(chip, idle_evh);
770                         }
771                 } else
772                         nandsim_undefined(chip, type);
773                 break;
774         case NANDSIM_EV_TIMEOUT:
775                 if (chip->sm_state == NANDSIM_STATE_TIMEOUT) {
776                         nandsim_start_handler(chip, idle_evh);
777                         nandchip_set_status(chip, NAND_STATUS_RDY);
778                 } else
779                         nandsim_undefined(chip, type);
780                 break;
781         }
782 }
783
784 void
785 erase_evh(struct nandsim_chip *chip, uint32_t type, void *data)
786 {
787         static uint32_t row, block_size;
788         uint32_t lun, block, page;
789         int err;
790         uint8_t cmd;
791
792         block_size = chip->cg.block_size +
793             (chip->cg.oob_size * chip->cg.pgs_per_blk);
794
795         switch (type) {
796         case NANDSIM_EV_START:
797                 nandsim_log(chip, NANDSIM_LOG_SM, "in ERASE state\n");
798                 chip->sm_state = NANDSIM_STATE_WAIT_ADDR_ROW;
799                 break;
800         case NANDSIM_EV_CMD:
801                 cmd = *(uint8_t *)data;
802                 if (chip->sm_state == NANDSIM_STATE_WAIT_CMD &&
803                     cmd == NAND_CMD_ERASE_END) {
804                         if (chip->data.data_ptr != NULL &&
805                             chip->data.size == block_size)
806                                 memset(chip->data.data_ptr, 0xff, block_size);
807                         else
808                                 nand_debug(NDBG_SIM,"Bad block erase data\n");
809
810                         err = nand_row_to_blkpg(&chip->cg, row, &lun,
811                             &block, &page);
812                         if (!err) {
813                                 if (chip->blk_state[block].wear_lev > 0)
814                                         chip->blk_state[block].wear_lev--;
815                         }
816
817                         if (chip->erase_delay != 0 &&
818                             nandsim_delay(chip, chip->erase_delay) == 0)
819                                 nandchip_clear_status(chip, NAND_STATUS_RDY);
820                         else {
821                                 nandchip_set_status(chip, NAND_STATUS_RDY);
822                                 nandsim_start_handler(chip, idle_evh);
823                         }
824                 } else
825                         nandsim_undefined(chip, type);
826                 break;
827         case NANDSIM_EV_ADDR:
828                 if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) {
829                         if (nandchip_get_addr_byte(chip, data, &row))
830                                 break;
831
832                         err = nandchip_chip_space(chip, row, 0, block_size, 1);
833                         if (err == -1) {
834                                 nandchip_set_status(chip, NAND_STATUS_FAIL);
835                         }
836                         chip->sm_state = NANDSIM_STATE_WAIT_CMD;
837                 } else
838                         nandsim_ignore_address(chip, *((uint8_t *)data));
839                 break;
840         case NANDSIM_EV_TIMEOUT:
841                 if (chip->sm_state == NANDSIM_STATE_TIMEOUT) {
842                         nandchip_set_status(chip, NAND_STATUS_RDY);
843                         nandsim_start_handler(chip, idle_evh);
844                 } else
845                         nandsim_undefined(chip, type);
846                 break;
847         }
848 }
849
850 void
851 reset_evh(struct nandsim_chip *chip, uint32_t type, void *data)
852 {
853
854         if (type == NANDSIM_EV_START) {
855                 nandsim_log(chip, NANDSIM_LOG_SM, "in RESET state\n");
856                 chip->sm_state = NANDSIM_STATE_TIMEOUT;
857                 nandchip_set_data(chip, NULL, 0, 0);
858                 DELAY(500);
859                 nandsim_start_handler(chip, idle_evh);
860         } else
861                 nandsim_undefined(chip, type);
862 }
863
864 static void
865 nandsim_undefined(struct nandsim_chip *chip, uint8_t type)
866 {
867
868         nandsim_log(chip, NANDSIM_LOG_ERR,
869             "ERR: Chip received ev %x in state %x\n",
870             type, chip->sm_state);
871         nandsim_start_handler(chip, idle_evh);
872 }
873
874 static void
875 nandsim_bad_address(struct nandsim_chip *chip, uint8_t *addr)
876 {
877
878         nandsim_log(chip, NANDSIM_LOG_ERR,
879             "ERR: Chip received out of range address"
880             "%02x%02x - %02x%02x%02x\n", addr[0], addr[1], addr[2],
881             addr[3], addr[4]);
882 }
883
884 static void
885 nandsim_ignore_address(struct nandsim_chip *chip, uint8_t byte)
886 {
887         nandsim_log(chip, NANDSIM_LOG_SM, "ignored address byte: %d\n", byte);
888 }
889
890 static void
891 nandsim_sm_error(struct nandsim_chip *chip)
892 {
893
894         nandsim_log(chip, NANDSIM_LOG_ERR, "ERR: State machine error."
895             "Restart required.\n");
896 }