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/systm.h> 34 #include <sys/conf.h> 35 #include <sys/bus.h> 36 #include <sys/malloc.h> 37 #include <sys/uio.h> 38 #include <sys/bio.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 static int nand_page_stat(struct nand_chip *, struct page_stat_io *); 47 static int nand_block_stat(struct nand_chip *, struct block_stat_io *); 48 49 static d_ioctl_t nand_ioctl; 50 static d_open_t nand_open; 51 static d_strategy_t nand_strategy; 52 53 static struct cdevsw nand_cdevsw = { 54 .d_version = D_VERSION, 55 .d_name = "nand", 56 .d_open = nand_open, 57 .d_read = physread, 58 .d_write = physwrite, 59 .d_ioctl = nand_ioctl, 60 .d_strategy = nand_strategy, 61 }; 62 63 static int 64 offset_to_page(struct chip_geom *cg, uint32_t offset) 65 { 66 67 return (offset / cg->page_size); 68 } 69 70 static int 71 offset_to_page_off(struct chip_geom *cg, uint32_t offset) 72 { 73 74 return (offset % cg->page_size); 75 } 76 77 int 78 nand_make_dev(struct nand_chip *chip) 79 { 80 struct nandbus_ivar *ivar; 81 device_t parent, nandbus; 82 int parent_unit, unit; 83 char *name; 84 85 ivar = device_get_ivars(chip->dev); 86 nandbus = device_get_parent(chip->dev); 87 88 if (ivar->chip_cdev_name) { 89 name = ivar->chip_cdev_name; 90 91 /* 92 * If we got distinct name for chip device we can enumarete it 93 * based on contoller number. 94 */ 95 parent = device_get_parent(nandbus); 96 } else { 97 name = "nand"; 98 parent = nandbus; 99 } 100 101 parent_unit = device_get_unit(parent); 102 unit = parent_unit * 4 + chip->num; 103 chip->cdev = make_dev(&nand_cdevsw, unit, UID_ROOT, GID_WHEEL, 104 0666, "%s%d.%d", name, parent_unit, chip->num); 105 106 if (chip->cdev == NULL) 107 return (ENXIO); 108 109 if (bootverbose) 110 device_printf(chip->dev, "Created cdev %s%d.%d for chip " 111 "[0x%0x, 0x%0x]\n", name, parent_unit, chip->num, 112 ivar->man_id, ivar->dev_id); 113 114 chip->cdev->si_drv1 = chip; 115 116 return (0); 117 } 118 119 void 120 nand_destroy_dev(struct nand_chip *chip) 121 { 122 123 if (chip->cdev) 124 destroy_dev(chip->cdev); 125 } 126 127 static int 128 nand_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 129 { 130 131 return (0); 132 } 133 134 static int 135 nand_read(struct nand_chip *chip, uint32_t offset, void *buf, uint32_t len) 136 { 137 struct chip_geom *cg; 138 device_t nandbus; 139 int start_page, count, off, err = 0; 140 uint8_t *ptr, *tmp; 141 142 nand_debug(NDBG_CDEV, "Read from chip%d [%p] at %d\n", chip->num, 143 chip, offset); 144 145 nandbus = device_get_parent(chip->dev); 146 NANDBUS_LOCK(nandbus); 147 NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); 148 149 cg = &chip->chip_geom; 150 start_page = offset_to_page(cg, offset); 151 off = offset_to_page_off(cg, offset); 152 count = (len > cg->page_size - off) ? cg->page_size - off : len; 153 154 ptr = (uint8_t *)buf; 155 while (len > 0) { 156 if (len < cg->page_size) { 157 tmp = malloc(cg->page_size, M_NAND, M_WAITOK); 158 if (!tmp) { 159 err = ENOMEM; 160 break; 161 } 162 err = NAND_READ_PAGE(chip->dev, start_page, 163 tmp, cg->page_size, 0); 164 if (err) { 165 free(tmp, M_NAND); 166 break; 167 } 168 bcopy(tmp + off, ptr, count); 169 free(tmp, M_NAND); 170 } else { 171 err = NAND_READ_PAGE(chip->dev, start_page, 172 ptr, cg->page_size, 0); 173 if (err) 174 break; 175 } 176 177 len -= count; 178 start_page++; 179 ptr += count; 180 count = (len > cg->page_size) ? cg->page_size : len; 181 off = 0; 182 } 183 184 NANDBUS_UNLOCK(nandbus); 185 return (err); 186 } 187 188 static int 189 nand_write(struct nand_chip *chip, uint32_t offset, void* buf, uint32_t len) 190 { 191 struct chip_geom *cg; 192 device_t nandbus; 193 int off, start_page, err = 0; 194 uint8_t *ptr; 195 196 nand_debug(NDBG_CDEV, "Write to chip %d [%p] at %d\n", chip->num, 197 chip, offset); 198 199 nandbus = device_get_parent(chip->dev); 200 NANDBUS_LOCK(nandbus); 201 NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); 202 203 cg = &chip->chip_geom; 204 start_page = offset_to_page(cg, offset); 205 off = offset_to_page_off(cg, offset); 206 207 if (off != 0 || (len % cg->page_size) != 0) { 208 printf("Not aligned write start [0x%08x] size [0x%08x]\n", 209 off, len); 210 NANDBUS_UNLOCK(nandbus); 211 return (EINVAL); 212 } 213 214 ptr = (uint8_t *)buf; 215 while (len > 0) { 216 err = NAND_PROGRAM_PAGE(chip->dev, start_page, ptr, 217 cg->page_size, 0); 218 if (err) 219 break; 220 221 len -= cg->page_size; 222 start_page++; 223 ptr += cg->page_size; 224 } 225 226 NANDBUS_UNLOCK(nandbus); 227 return (err); 228 } 229 230 static void 231 nand_strategy(struct bio *bp) 232 { 233 struct nand_chip *chip; 234 struct cdev *dev; 235 int err = 0; 236 237 dev = bp->bio_dev; 238 chip = dev->si_drv1; 239 240 nand_debug(NDBG_CDEV, "Strategy %s on chip %d [%p]\n", 241 bp->bio_cmd == BIO_READ ? "READ" : "WRITE", 242 chip->num, chip); 243 244 if (bp->bio_cmd == BIO_READ) { 245 err = nand_read(chip, 246 bp->bio_offset & 0xffffffff, 247 bp->bio_data, bp->bio_bcount); 248 } else { 249 err = nand_write(chip, 250 bp->bio_offset & 0xffffffff, 251 bp->bio_data, bp->bio_bcount); 252 } 253 254 if (err == 0) 255 bp->bio_resid = 0; 256 else { 257 bp->bio_error = EIO; 258 bp->bio_flags |= BIO_ERROR; 259 bp->bio_resid = bp->bio_bcount; 260 } 261 262 biodone(bp); 263 } 264 265 static int 266 nand_oob_access(struct nand_chip *chip, uint32_t page, uint32_t offset, 267 uint32_t len, uint8_t *data, uint8_t write) 268 { 269 struct chip_geom *cg; 270 uint8_t *buf = NULL; 271 int ret = 0; 272 273 cg = &chip->chip_geom; 274 275 buf = malloc(cg->oob_size, M_NAND, M_WAITOK); 276 if (!buf) 277 return (ENOMEM); 278 279 memset(buf, 0xff, cg->oob_size); 280 281 if (!write) { 282 ret = nand_read_oob(chip, page, buf, cg->oob_size); 283 copyout(buf, data, len); 284 } else { 285 copyin(data, buf, len); 286 ret = nand_prog_oob(chip, page, buf, cg->oob_size); 287 } 288 289 free(buf, M_NAND); 290 291 return (ret); 292 } 293 294 static int 295 nand_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, 296 struct thread *td) 297 { 298 struct nand_chip *chip; 299 struct chip_geom *cg; 300 struct nand_oob_rw *oob_rw = NULL; 301 struct nand_raw_rw *raw_rw = NULL; 302 device_t nandbus; 303 size_t bufsize = 0, len = 0; 304 size_t raw_size; 305 off_t off; 306 uint8_t *buf = NULL; 307 int ret = 0; 308 uint8_t status; 309 310 chip = (struct nand_chip *)dev->si_drv1; 311 cg = &chip->chip_geom; 312 nandbus = device_get_parent(chip->dev); 313 314 if ((cmd == NAND_IO_RAW_READ) || (cmd == NAND_IO_RAW_PROG)) { 315 raw_rw = (struct nand_raw_rw *)data; 316 raw_size = cg->pgs_per_blk * (cg->page_size + cg->oob_size); 317 318 /* Check if len is not bigger than chip size */ 319 if (raw_rw->len > raw_size) 320 return (EFBIG); 321 322 /* 323 * Do not ask for too much memory, in case of large transfers 324 * read/write in 16-pages chunks 325 */ 326 bufsize = 16 * (cg->page_size + cg->oob_size); 327 if (raw_rw->len < bufsize) 328 bufsize = raw_rw->len; 329 330 buf = malloc(bufsize, M_NAND, M_WAITOK); 331 len = raw_rw->len; 332 off = 0; 333 } 334 switch(cmd) { 335 case NAND_IO_ERASE: 336 ret = nand_erase_blocks(chip, ((off_t *)data)[0], 337 ((off_t *)data)[1]); 338 break; 339 340 case NAND_IO_OOB_READ: 341 oob_rw = (struct nand_oob_rw *)data; 342 ret = nand_oob_access(chip, oob_rw->page, 0, 343 oob_rw->len, oob_rw->data, 0); 344 break; 345 346 case NAND_IO_OOB_PROG: 347 oob_rw = (struct nand_oob_rw *)data; 348 ret = nand_oob_access(chip, oob_rw->page, 0, 349 oob_rw->len, oob_rw->data, 1); 350 break; 351 352 case NAND_IO_GET_STATUS: 353 NANDBUS_LOCK(nandbus); 354 ret = NANDBUS_GET_STATUS(nandbus, &status); 355 if (ret == 0) 356 *(uint8_t *)data = status; 357 NANDBUS_UNLOCK(nandbus); 358 break; 359 360 case NAND_IO_RAW_PROG: 361 while (len > 0) { 362 if (len < bufsize) 363 bufsize = len; 364 ret = copyin(raw_rw->data + off, buf, bufsize); 365 if (ret) 366 break; 367 ret = nand_prog_pages_raw(chip, raw_rw->off + off, buf, 368 bufsize); 369 if (ret) 370 break; 371 len -= bufsize; 372 off += bufsize; 373 } 374 break; 375 376 case NAND_IO_RAW_READ: 377 while (len > 0) { 378 if (len < bufsize) 379 bufsize = len; 380 381 ret = nand_read_pages_raw(chip, raw_rw->off + off, buf, 382 bufsize); 383 if (ret) 384 break; 385 386 ret = copyout(buf, raw_rw->data + off, bufsize); 387 if (ret) 388 break; 389 len -= bufsize; 390 off += bufsize; 391 } 392 break; 393 394 case NAND_IO_PAGE_STAT: 395 ret = nand_page_stat(chip, (struct page_stat_io *)data); 396 break; 397 398 case NAND_IO_BLOCK_STAT: 399 ret = nand_block_stat(chip, (struct block_stat_io *)data); 400 break; 401 402 case NAND_IO_GET_CHIP_PARAM: 403 nand_get_chip_param(chip, (struct chip_param_io *)data); 404 break; 405 406 default: 407 printf("Unknown nand_ioctl request \n"); 408 ret = EIO; 409 } 410 411 if (buf) 412 free(buf, M_NAND); 413 414 return (ret); 415 } 416 417 static int 418 nand_page_stat(struct nand_chip *chip, struct page_stat_io *page_stat) 419 { 420 struct chip_geom *cg; 421 struct page_stat *stat; 422 int num_pages; 423 424 cg = &chip->chip_geom; 425 num_pages = cg->pgs_per_blk * cg->blks_per_lun * cg->luns; 426 if (page_stat->page_num >= num_pages) 427 return (EINVAL); 428 429 stat = &chip->pg_stat[page_stat->page_num]; 430 page_stat->page_read = stat->page_read; 431 page_stat->page_written = stat->page_written; 432 page_stat->page_raw_read = stat->page_raw_read; 433 page_stat->page_raw_written = stat->page_raw_written; 434 page_stat->ecc_succeded = stat->ecc_stat.ecc_succeded; 435 page_stat->ecc_corrected = stat->ecc_stat.ecc_corrected; 436 page_stat->ecc_failed = stat->ecc_stat.ecc_failed; 437 438 return (0); 439 } 440 441 static int 442 nand_block_stat(struct nand_chip *chip, struct block_stat_io *block_stat) 443 { 444 struct chip_geom *cg; 445 uint32_t block_num = block_stat->block_num; 446 447 cg = &chip->chip_geom; 448 if (block_num >= cg->blks_per_lun * cg->luns) 449 return (EINVAL); 450 451 block_stat->block_erased = chip->blk_stat[block_num].block_erased; 452 453 return (0); 454 } 455