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: stable/10/sys/dev/nand/nand_geom.c 313525 2017-02-10 05:35:30Z ngie $");
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/conf.h>
33 #include <sys/bus.h>
34 #include <sys/malloc.h>
35 #include <sys/uio.h>
36 #include <sys/bio.h>
37 #include <geom/geom.h>
38 #include <geom/geom_disk.h>
39 
40 #include <dev/nand/nand.h>
41 #include <dev/nand/nandbus.h>
42 #include <dev/nand/nand_dev.h>
43 #include "nand_if.h"
44 #include "nandbus_if.h"
45 
46 #define	BIO_NAND_STD	((void *)1)
47 #define	BIO_NAND_RAW	((void *)2)
48 
49 static disk_ioctl_t nand_ioctl;
50 static disk_getattr_t nand_getattr;
51 static disk_strategy_t nand_strategy;
52 static disk_strategy_t nand_strategy_raw;
53 
54 static int
nand_read(struct nand_chip * chip,uint32_t offset,void * buf,uint32_t len)55 nand_read(struct nand_chip *chip, uint32_t offset, void *buf, uint32_t len)
56 {
57 
58 	nand_debug(NDBG_GEOM, "Read from chip %d [%p] at %d", chip->num, chip,
59 	    offset);
60 
61 	return (nand_read_pages(chip, offset, buf, len));
62 }
63 
64 static int
nand_write(struct nand_chip * chip,uint32_t offset,void * buf,uint32_t len)65 nand_write(struct nand_chip *chip, uint32_t offset, void* buf, uint32_t len)
66 {
67 
68 	nand_debug(NDBG_GEOM, "Write to chip %d [%p] at %d", chip->num, chip,
69 	    offset);
70 
71 	return (nand_prog_pages(chip, offset, buf, len));
72 }
73 
74 static int
nand_read_raw(struct nand_chip * chip,uint32_t offset,void * buf,uint32_t len)75 nand_read_raw(struct nand_chip *chip, uint32_t offset, void *buf, uint32_t len)
76 {
77 	nand_debug(NDBG_GEOM, "Raw read from chip %d [%p] at %d", chip->num,
78 	    chip, offset);
79 
80 	return (nand_read_pages_raw(chip, offset, buf, len));
81 }
82 
83 static int
nand_write_raw(struct nand_chip * chip,uint32_t offset,void * buf,uint32_t len)84 nand_write_raw(struct nand_chip *chip, uint32_t offset, void *buf, uint32_t len)
85 {
86 
87 	nand_debug(NDBG_GEOM, "Raw write to chip %d [%p] at %d", chip->num,
88 	    chip, offset);
89 
90 	return (nand_prog_pages_raw(chip, offset, buf, len));
91 }
92 
93 static void
nand_strategy(struct bio * bp)94 nand_strategy(struct bio *bp)
95 {
96 	struct nand_chip *chip;
97 
98 	chip = (struct nand_chip *)bp->bio_disk->d_drv1;
99 
100 	bp->bio_driver1 = BIO_NAND_STD;
101 
102 	nand_debug(NDBG_GEOM, "Strategy %s on chip %d [%p]",
103 	    (bp->bio_cmd & BIO_READ) == BIO_READ ? "READ" :
104 	    ((bp->bio_cmd & BIO_WRITE) == BIO_WRITE ? "WRITE" :
105 	    ((bp->bio_cmd & BIO_DELETE) == BIO_DELETE ? "DELETE" : "UNKNOWN")),
106 	    chip->num, chip);
107 
108 	mtx_lock(&chip->qlock);
109 	bioq_insert_tail(&chip->bioq, bp);
110 	mtx_unlock(&chip->qlock);
111 	taskqueue_enqueue(chip->tq, &chip->iotask);
112 }
113 
114 static void
nand_strategy_raw(struct bio * bp)115 nand_strategy_raw(struct bio *bp)
116 {
117 	struct nand_chip *chip;
118 
119 	chip = (struct nand_chip *)bp->bio_disk->d_drv1;
120 
121 	/* Inform taskqueue that it's a raw access */
122 	bp->bio_driver1 = BIO_NAND_RAW;
123 
124 	nand_debug(NDBG_GEOM, "Strategy %s on chip %d [%p]",
125 	    (bp->bio_cmd & BIO_READ) == BIO_READ ? "READ" :
126 	    ((bp->bio_cmd & BIO_WRITE) == BIO_WRITE ? "WRITE" :
127 	    ((bp->bio_cmd & BIO_DELETE) == BIO_DELETE ? "DELETE" : "UNKNOWN")),
128 	    chip->num, chip);
129 
130 	mtx_lock(&chip->qlock);
131 	bioq_insert_tail(&chip->bioq, bp);
132 	mtx_unlock(&chip->qlock);
133 	taskqueue_enqueue(chip->tq, &chip->iotask);
134 }
135 
136 static int
nand_oob_access(struct nand_chip * chip,uint32_t page,uint32_t offset,uint32_t len,uint8_t * data,uint8_t write)137 nand_oob_access(struct nand_chip *chip, uint32_t page, uint32_t offset,
138     uint32_t len, uint8_t *data, uint8_t write)
139 {
140 	struct chip_geom *cg;
141 	int ret = 0;
142 
143 	cg = &chip->chip_geom;
144 
145 	if (!write)
146 		ret = nand_read_oob(chip, page, data, cg->oob_size);
147 	else
148 		ret = nand_prog_oob(chip, page, data, cg->oob_size);
149 
150 	return (ret);
151 }
152 
153 static int
nand_getattr(struct bio * bp)154 nand_getattr(struct bio *bp)
155 {
156 	struct nand_chip *chip;
157 	struct chip_geom *cg;
158 	device_t dev;
159 	int val;
160 
161 	if (bp->bio_disk == NULL || bp->bio_disk->d_drv1 == NULL)
162 		return (ENXIO);
163 
164 	chip = (struct nand_chip *)bp->bio_disk->d_drv1;
165 	cg = &(chip->chip_geom);
166 
167 	dev = device_get_parent(chip->dev);
168 	dev = device_get_parent(dev);
169 
170 	if (strcmp(bp->bio_attribute, "NAND::device") == 0) {
171 		if (bp->bio_length != sizeof(dev))
172 			return (EFAULT);
173 		bcopy(&dev, bp->bio_data, sizeof(dev));
174 	} else {
175 		if (strcmp(bp->bio_attribute, "NAND::oobsize") == 0)
176 			val = cg->oob_size;
177 		else if (strcmp(bp->bio_attribute, "NAND::pagesize") == 0)
178 			val = cg->page_size;
179 		else if (strcmp(bp->bio_attribute, "NAND::blocksize") == 0)
180 			val = cg->block_size;
181 		else
182 			return (-1);
183 		if (bp->bio_length != sizeof(val))
184 			return (EFAULT);
185 		bcopy(&val, bp->bio_data, sizeof(val));
186 	}
187 	bp->bio_completed = bp->bio_length;
188 	return (0);
189 }
190 
191 static int
nand_ioctl(struct disk * ndisk,u_long cmd,void * data,int fflag,struct thread * td)192 nand_ioctl(struct disk *ndisk, u_long cmd, void *data, int fflag,
193     struct thread *td)
194 {
195 	struct nand_chip *chip;
196 	struct chip_geom  *cg;
197 	struct nand_oob_rw *oob_rw = NULL;
198 	struct nand_raw_rw *raw_rw = NULL;
199 	device_t nandbus;
200 	size_t bufsize = 0, len = 0;
201 	size_t raw_size;
202 	off_t off;
203 	uint8_t *buf = NULL;
204 	int ret = 0;
205 	uint8_t status;
206 
207 	chip = (struct nand_chip *)ndisk->d_drv1;
208 	cg = &chip->chip_geom;
209 	nandbus = device_get_parent(chip->dev);
210 
211 	if ((cmd == NAND_IO_RAW_READ) || (cmd == NAND_IO_RAW_PROG)) {
212 		raw_rw = (struct nand_raw_rw *)data;
213 		raw_size =  cg->pgs_per_blk * (cg->page_size + cg->oob_size);
214 
215 		/* Check if len is not bigger than chip size */
216 		if (raw_rw->len > raw_size)
217 			return (EFBIG);
218 
219 		/*
220 		 * Do not ask for too much memory, in case of large transfers
221 		 * read/write in 16-pages chunks
222 		 */
223 		bufsize = 16 * (cg->page_size + cg->oob_size);
224 		if (raw_rw->len < bufsize)
225 			bufsize = raw_rw->len;
226 
227 		buf = malloc(bufsize, M_NAND, M_WAITOK);
228 		len = raw_rw->len;
229 		off = 0;
230 	}
231 
232 	switch (cmd) {
233 	case NAND_IO_ERASE:
234 		ret = nand_erase_blocks(chip, ((off_t *)data)[0],
235 		    ((off_t *)data)[1]);
236 		break;
237 
238 	case NAND_IO_OOB_READ:
239 		oob_rw = (struct nand_oob_rw *)data;
240 		ret = nand_oob_access(chip, oob_rw->page, 0,
241 		    oob_rw->len, oob_rw->data, 0);
242 		break;
243 
244 	case NAND_IO_OOB_PROG:
245 		oob_rw = (struct nand_oob_rw *)data;
246 		ret = nand_oob_access(chip, oob_rw->page, 0,
247 		    oob_rw->len, oob_rw->data, 1);
248 		break;
249 
250 	case NAND_IO_GET_STATUS:
251 		NANDBUS_LOCK(nandbus);
252 		ret = NANDBUS_GET_STATUS(nandbus, &status);
253 		if (ret == 0)
254 			*(uint8_t *)data = status;
255 		NANDBUS_UNLOCK(nandbus);
256 		break;
257 
258 	case NAND_IO_RAW_PROG:
259 		while (len > 0) {
260 			if (len < bufsize)
261 				bufsize = len;
262 
263 			ret = copyin(raw_rw->data + off, buf, bufsize);
264 			if (ret)
265 				break;
266 			ret = nand_prog_pages_raw(chip, raw_rw->off + off, buf,
267 			    bufsize);
268 			if (ret)
269 				break;
270 			len -= bufsize;
271 			off += bufsize;
272 		}
273 		break;
274 
275 	case NAND_IO_RAW_READ:
276 		while (len > 0) {
277 			if (len < bufsize)
278 				bufsize = len;
279 
280 			ret = nand_read_pages_raw(chip, raw_rw->off + off, buf,
281 			    bufsize);
282 			if (ret)
283 				break;
284 
285 			ret = copyout(buf, raw_rw->data + off, bufsize);
286 			if (ret)
287 				break;
288 			len -= bufsize;
289 			off += bufsize;
290 		}
291 		break;
292 
293 	case NAND_IO_GET_CHIP_PARAM:
294 		nand_get_chip_param(chip, (struct chip_param_io *)data);
295 		break;
296 
297 	default:
298 		printf("Unknown nand_ioctl request \n");
299 		ret = EIO;
300 	}
301 
302 	if (buf)
303 		free(buf, M_NAND);
304 
305 	return (ret);
306 }
307 
308 static void
nand_io_proc(void * arg,int pending)309 nand_io_proc(void *arg, int pending)
310 {
311 	struct nand_chip *chip = arg;
312 	struct bio *bp;
313 	int err = 0;
314 
315 	for (;;) {
316 		mtx_lock(&chip->qlock);
317 		bp = bioq_takefirst(&chip->bioq);
318 		mtx_unlock(&chip->qlock);
319 		if (bp == NULL)
320 			break;
321 
322 		if (bp->bio_driver1 == BIO_NAND_STD) {
323 			if ((bp->bio_cmd & BIO_READ) == BIO_READ) {
324 				err = nand_read(chip,
325 				    bp->bio_offset & 0xffffffff,
326 				    bp->bio_data, bp->bio_bcount);
327 			} else if ((bp->bio_cmd & BIO_WRITE) == BIO_WRITE) {
328 				err = nand_write(chip,
329 				    bp->bio_offset & 0xffffffff,
330 				    bp->bio_data, bp->bio_bcount);
331 			}
332 		} else if (bp->bio_driver1 == BIO_NAND_RAW) {
333 			if ((bp->bio_cmd & BIO_READ) == BIO_READ) {
334 				err = nand_read_raw(chip,
335 				    bp->bio_offset & 0xffffffff,
336 				    bp->bio_data, bp->bio_bcount);
337 			} else if ((bp->bio_cmd & BIO_WRITE) == BIO_WRITE) {
338 				err = nand_write_raw(chip,
339 				    bp->bio_offset & 0xffffffff,
340 				    bp->bio_data, bp->bio_bcount);
341 			}
342 		} else
343 			panic("Unknown access type in bio->bio_driver1\n");
344 
345 		if ((bp->bio_cmd & BIO_DELETE) == BIO_DELETE) {
346 			nand_debug(NDBG_GEOM, "Delete on chip%d offset %lld "
347 			    "length %ld\n", chip->num, bp->bio_offset,
348 			    bp->bio_bcount);
349 			err = nand_erase_blocks(chip,
350 			    bp->bio_offset & 0xffffffff,
351 			    bp->bio_bcount);
352 		}
353 
354 		if (err == 0 || err == ECC_CORRECTABLE)
355 			bp->bio_resid = 0;
356 		else {
357 			nand_debug(NDBG_GEOM,"nand_[read|write|erase_blocks] "
358 			    "error: %d\n", err);
359 
360 			bp->bio_error = EIO;
361 			bp->bio_flags |= BIO_ERROR;
362 			bp->bio_resid = bp->bio_bcount;
363 		}
364 		biodone(bp);
365 	}
366 }
367 
368 int
create_geom_disk(struct nand_chip * chip)369 create_geom_disk(struct nand_chip *chip)
370 {
371 	struct disk *ndisk, *rdisk;
372 
373 	/* Create the disk device */
374 	ndisk = disk_alloc();
375 	ndisk->d_strategy = nand_strategy;
376 	ndisk->d_ioctl = nand_ioctl;
377 	ndisk->d_getattr = nand_getattr;
378 	ndisk->d_name = "gnand";
379 	ndisk->d_drv1 = chip;
380 	ndisk->d_maxsize = chip->chip_geom.block_size;
381 	ndisk->d_sectorsize = chip->chip_geom.page_size;
382 	ndisk->d_mediasize = chip->chip_geom.chip_size;
383 	ndisk->d_unit = chip->num +
384 	    10 * device_get_unit(device_get_parent(chip->dev));
385 
386 	/*
387 	 * When using BBT, make two last blocks of device unavailable
388 	 * to user (because those are used to store BBT table).
389 	 */
390 	if (chip->bbt != NULL)
391 		ndisk->d_mediasize -= (2 * chip->chip_geom.block_size);
392 
393 	ndisk->d_flags = DISKFLAG_CANDELETE;
394 
395 	snprintf(ndisk->d_ident, sizeof(ndisk->d_ident),
396 	    "nand: Man:0x%02x Dev:0x%02x", chip->id.man_id, chip->id.dev_id);
397 	ndisk->d_rotation_rate = DISK_RR_NON_ROTATING;
398 
399 	disk_create(ndisk, DISK_VERSION);
400 
401 	/* Create the RAW disk device */
402 	rdisk = disk_alloc();
403 	rdisk->d_strategy = nand_strategy_raw;
404 	rdisk->d_ioctl = nand_ioctl;
405 	rdisk->d_getattr = nand_getattr;
406 	rdisk->d_name = "gnand.raw";
407 	rdisk->d_drv1 = chip;
408 	rdisk->d_maxsize = chip->chip_geom.block_size;
409 	rdisk->d_sectorsize = chip->chip_geom.page_size;
410 	rdisk->d_mediasize = chip->chip_geom.chip_size;
411 	rdisk->d_unit = chip->num +
412 	    10 * device_get_unit(device_get_parent(chip->dev));
413 
414 	rdisk->d_flags = DISKFLAG_CANDELETE;
415 
416 	snprintf(rdisk->d_ident, sizeof(rdisk->d_ident),
417 	    "nand_raw: Man:0x%02x Dev:0x%02x", chip->id.man_id,
418 	    chip->id.dev_id);
419 	rdisk->d_rotation_rate = DISK_RR_NON_ROTATING;
420 
421 	disk_create(rdisk, DISK_VERSION);
422 
423 	chip->ndisk = ndisk;
424 	chip->rdisk = rdisk;
425 
426 	mtx_init(&chip->qlock, "NAND I/O lock", NULL, MTX_DEF);
427 	bioq_init(&chip->bioq);
428 
429 	TASK_INIT(&chip->iotask, 0, nand_io_proc, chip);
430 	chip->tq = taskqueue_create("nand_taskq", M_WAITOK,
431 	    taskqueue_thread_enqueue, &chip->tq);
432 	taskqueue_start_threads(&chip->tq, 1, PI_DISK, "nand taskq");
433 
434 	if (bootverbose)
435 		device_printf(chip->dev, "Created gnand%d for chip [0x%0x, "
436 		    "0x%0x]\n", ndisk->d_unit, chip->id.man_id,
437 		    chip->id.dev_id);
438 
439 	return (0);
440 }
441 
442 void
destroy_geom_disk(struct nand_chip * chip)443 destroy_geom_disk(struct nand_chip *chip)
444 {
445 	struct bio *bp;
446 
447 	taskqueue_free(chip->tq);
448 	disk_destroy(chip->ndisk);
449 	disk_destroy(chip->rdisk);
450 
451 	mtx_lock(&chip->qlock);
452 	for (;;) {
453 		bp = bioq_takefirst(&chip->bioq);
454 		if (bp == NULL)
455 			break;
456 		bp->bio_error = EIO;
457 		bp->bio_flags |= BIO_ERROR;
458 		bp->bio_resid = bp->bio_bcount;
459 
460 		biodone(bp);
461 	}
462 	mtx_unlock(&chip->qlock);
463 
464 	mtx_destroy(&chip->qlock);
465 }
466