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