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