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