1235537Sgber/*-
2235537Sgber * Copyright (C) 2009-2012 Semihalf
3235537Sgber * All rights reserved.
4235537Sgber *
5235537Sgber * Redistribution and use in source and binary forms, with or without
6235537Sgber * modification, are permitted provided that the following conditions
7235537Sgber * are met:
8235537Sgber * 1. Redistributions of source code must retain the above copyright
9235537Sgber *    notice, this list of conditions and the following disclaimer.
10235537Sgber * 2. Redistributions in binary form must reproduce the above copyright
11235537Sgber *    notice, this list of conditions and the following disclaimer in the
12235537Sgber *    documentation and/or other materials provided with the distribution.
13235537Sgber *
14235537Sgber * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15235537Sgber * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16235537Sgber * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17235537Sgber * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18235537Sgber * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19235537Sgber * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20235537Sgber * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21235537Sgber * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22235537Sgber * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23235537Sgber * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24235537Sgber * SUCH DAMAGE.
25235537Sgber *
26235537Sgber * $FreeBSD$
27235537Sgber */
28235537Sgber
29235537Sgber#ifndef _NANDSIM_CHIP_H
30235537Sgber#define _NANDSIM_CHIP_H
31235537Sgber
32235537Sgber#include <sys/malloc.h>
33235537Sgber#include <sys/callout.h>
34235537Sgber#include <dev/nand/nand.h>
35235537Sgber#include <dev/nand/nandsim.h>
36235537Sgber#include <dev/nand/nandsim_swap.h>
37235537Sgber
38235537SgberMALLOC_DECLARE(M_NANDSIM);
39235537Sgber
40235537Sgber#define MAX_CS_NUM	4
41235537Sgberstruct nandsim_chip;
42235537Sgber
43235537Sgbertypedef void nandsim_evh_t(struct nandsim_chip *chip, uint32_t ev, void *data);
44235537Sgber
45235537Sgberenum addr_type {
46235537Sgber	ADDR_NONE,
47235537Sgber	ADDR_ID,
48235537Sgber	ADDR_ROW,
49235537Sgber	ADDR_ROWCOL
50235537Sgber};
51235537Sgber
52235537Sgberstruct nandsim_softc {
53235537Sgber	struct nand_softc	nand_dev;
54235537Sgber	device_t		dev;
55235537Sgber
56235537Sgber	struct nandsim_chip	*chips[MAX_CS_NUM];
57235537Sgber	struct nandsim_chip	*active_chip;
58235537Sgber
59235537Sgber	uint8_t			address_cycle;
60235537Sgber	enum addr_type		address_type;
61235537Sgber	int			log_idx;
62235537Sgber	char			*log_buff;
63235537Sgber	struct alq		*alq;
64235537Sgber};
65235537Sgber
66235537Sgberstruct nandsim_ev {
67235537Sgber	STAILQ_ENTRY(nandsim_ev)	links;
68235537Sgber	struct nandsim_chip		*chip;
69235537Sgber	uint8_t		type;
70235537Sgber	void		*data;
71235537Sgber};
72235537Sgber
73235537Sgberstruct nandsim_data {
74235537Sgber	uint8_t		*data_ptr;
75235537Sgber	uint32_t	index;
76235537Sgber	uint32_t	size;
77235537Sgber};
78235537Sgber
79235537Sgberstruct nandsim_block_state {
80235537Sgber	int32_t		wear_lev;
81235537Sgber	uint8_t		is_bad;
82235537Sgber};
83235537Sgber
84235537Sgber#define NANDSIM_CHIP_ACTIVE	0x1
85235537Sgber#define NANDSIM_CHIP_FROZEN	0x2
86235537Sgber#define NANDSIM_CHIP_GET_STATUS	0x4
87235537Sgber
88235537Sgberstruct nandsim_chip {
89235537Sgber	struct nandsim_softc	*sc;
90235537Sgber	struct thread		*nandsim_td;
91235537Sgber
92235537Sgber	STAILQ_HEAD(, nandsim_ev) nandsim_events;
93235537Sgber	nandsim_evh_t		*ev_handler;
94235537Sgber	struct mtx		ns_lock;
95235537Sgber	struct callout		ns_callout;
96235537Sgber
97235537Sgber	struct chip_geom	cg;
98235537Sgber	struct nand_id		id;
99235537Sgber	struct onfi_params	params;
100235537Sgber	struct nandsim_data	data;
101235537Sgber	struct nandsim_block_state *blk_state;
102235537Sgber
103235537Sgber	struct chip_swap	*swap;
104235537Sgber
105235537Sgber	uint32_t	error_ratio;
106235537Sgber	uint32_t	wear_level;
107235537Sgber	uint32_t	sm_state;
108235537Sgber	uint32_t	sm_addr_cycle;
109235537Sgber
110235537Sgber	uint32_t	erase_delay;
111235537Sgber	uint32_t	prog_delay;
112235537Sgber	uint32_t	read_delay;
113235537Sgber	struct timeval	delay_tv;
114235537Sgber
115235537Sgber	uint8_t		flags;
116235537Sgber	uint8_t		chip_status;
117235537Sgber	uint8_t		ctrl_num;
118235537Sgber	uint8_t		chip_num;
119235537Sgber};
120235537Sgber
121235537Sgberstruct sim_ctrl_conf {
122235537Sgber	uint8_t		num;
123235537Sgber	uint8_t		num_cs;
124235537Sgber	uint8_t		ecc;
125235537Sgber	uint8_t		running;
126235537Sgber	uint8_t		created;
127235537Sgber	device_t	sim_ctrl_dev;
128235537Sgber	struct sim_chip	*chips[MAX_CTRL_CS];
129235537Sgber	uint16_t	ecc_layout[MAX_ECC_BYTES];
130235537Sgber	char		filename[FILENAME_SIZE];
131235537Sgber};
132235537Sgber
133235537Sgber#define NANDSIM_STATE_IDLE		0x0
134235537Sgber#define NANDSIM_STATE_WAIT_ADDR_BYTE	0x1
135235537Sgber#define NANDSIM_STATE_WAIT_CMD		0x2
136235537Sgber#define NANDSIM_STATE_TIMEOUT		0x3
137235537Sgber#define	NANDSIM_STATE_WAIT_ADDR_ROW	0x4
138235537Sgber#define	NANDSIM_STATE_WAIT_ADDR_COL	0x5
139235537Sgber
140235537Sgber#define NANDSIM_EV_START	0x1
141235537Sgber#define NANDSIM_EV_CMD		0x2
142235537Sgber#define NANDSIM_EV_ADDR		0x3
143235537Sgber#define NANDSIM_EV_TIMEOUT	0x4
144235537Sgber#define NANDSIM_EV_EXIT		0xff
145235537Sgber
146235537Sgberstruct nandsim_chip *nandsim_chip_init(struct nandsim_softc *,
147235537Sgber    uint8_t, struct sim_chip *);
148235537Sgbervoid nandsim_chip_destroy(struct nandsim_chip *);
149235537Sgbervoid nandsim_chip_freeze(struct nandsim_chip *);
150235537Sgbervoid nandsim_chip_timeout(struct nandsim_chip *);
151235537Sgberint nandsim_chip_check_bad_block(struct nandsim_chip *, int);
152235537Sgber
153235537Sgberuint8_t nandchip_get_status(struct nandsim_chip *);
154235537Sgber
155235537Sgbervoid destroy_event(struct nandsim_ev *);
156235537Sgberint send_event(struct nandsim_ev *);
157235537Sgberstruct nandsim_ev *create_event(struct nandsim_chip *, uint8_t, uint8_t);
158235537Sgber
159235537Sgber#endif /*  _NANDSIM_CHIP_H */
160