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/11/sys/dev/nand/nand_geom.c 312858 2017-01-27 03:44:50Z kan $"); 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 49static disk_ioctl_t nand_ioctl; 50static disk_getattr_t nand_getattr; 51static disk_strategy_t nand_strategy; 52static disk_strategy_t nand_strategy_raw; 53 54static int 55nand_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 64static int 65nand_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 74static int 75nand_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 83static int 84nand_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 93static void 94nand_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 ? "READ" : 104 (bp->bio_cmd == BIO_WRITE ? "WRITE" : 105 (bp->bio_cmd == 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 114static void 115nand_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 ? "READ" : 126 (bp->bio_cmd == BIO_WRITE ? "WRITE" : 127 (bp->bio_cmd == 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 136static int 137nand_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 153static int 154nand_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 191static int 192nand_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 308static void 309nand_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) { 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) { 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) { 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) { 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) { 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 368int 369create_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 442void 443destroy_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