[BACK]Return to zaurus_flash.c CVS log [TXT][DIR] Up to [local] / sys / arch / zaurus / dev

Annotation of sys/arch/zaurus/dev/zaurus_flash.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: zaurus_flash.c,v 1.4 2007/06/20 18:15:46 deraadt Exp $        */
                      2:
                      3: /*
                      4:  * Copyright (c) 2005 Uwe Stuehler <uwe@openbsd.org>
                      5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
                     18:
                     19: /*
                     20:  * Samsung NAND flash controlled by some unspecified CPLD device.
                     21:  */
                     22:
                     23: #include <sys/param.h>
                     24: #include <sys/buf.h>
                     25: #include <sys/device.h>
                     26: #include <sys/disk.h>
                     27: #include <sys/disklabel.h>
                     28: #include <sys/kernel.h>
                     29: #include <sys/malloc.h>
                     30: #include <sys/systm.h>
                     31:
                     32: #include <dev/flashvar.h>
                     33: #include <dev/rndvar.h>
                     34:
                     35: #include <machine/zaurus_var.h>
                     36:
                     37: #include <arch/arm/xscale/pxa2x0var.h>
                     38:
                     39: #define DEBUG
                     40: #ifdef DEBUG
                     41: #define DPRINTF(x) printf x
                     42: #else
                     43: #define DPRINTF(x)
                     44: #endif
                     45:
                     46: /* CPLD register definitions */
                     47: #define CPLD_REG_ECCLPLB       0x00
                     48: #define CPLD_REG_ECCLPUB       0x04
                     49: #define CPLD_REG_ECCCP         0x08
                     50: #define CPLD_REG_ECCCNTR       0x0c
                     51: #define CPLD_REG_ECCCLRR       0x10
                     52: #define CPLD_REG_FLASHIO       0x14
                     53: #define CPLD_REG_FLASHCTL      0x18
                     54: #define  FLASHCTL_NCE0         (1<<0)
                     55: #define  FLASHCTL_CLE          (1<<1)
                     56: #define  FLASHCTL_ALE          (1<<2)
                     57: #define  FLASHCTL_NWP          (1<<3)
                     58: #define  FLASHCTL_NCE1         (1<<4)
                     59: #define  FLASHCTL_RYBY         (1<<5)
                     60: #define  FLASHCTL_NCE          (FLASHCTL_NCE0|FLASHCTL_NCE1)
                     61:
                     62: /* CPLD register accesses */
                     63: #define CPLD_READ(sc, r)                                               \
                     64:        bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (r))
                     65: #define CPLD_WRITE(sc, r, v)                                           \
                     66:        bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (r), (v))
                     67: #define CPLD_SET(sc, r, v)                                             \
                     68:        CPLD_WRITE((sc), (r), CPLD_READ((sc), (r)) | (v))
                     69: #define CPLD_CLR(sc, r, v)                                             \
                     70:        CPLD_WRITE((sc), (r), CPLD_READ((sc), (r)) & ~(v))
                     71: #define CPLD_SETORCLR(sc, r, m, v)                                     \
                     72:        ((v) ? CPLD_SET((sc), (r), (m)) : CPLD_CLR((sc), (r), (m)))
                     73:
                     74: /* Offsets into OOB data. */
                     75: #define OOB_JFFS2_ECC0         0
                     76: #define OOB_JFFS2_ECC1         1
                     77: #define OOB_JFFS2_ECC2         2
                     78: #define OOB_JFFS2_ECC3         3
                     79: #define OOB_JFFS2_ECC4         6
                     80: #define OOB_JFFS2_ECC5         7
                     81: #define OOB_LOGADDR_0_LO       8
                     82: #define OOB_LOGADDR_0_HI       9
                     83: #define OOB_LOGADDR_1_LO       10
                     84: #define OOB_LOGADDR_1_HI       11
                     85: #define OOB_LOGADDR_2_LO       12
                     86: #define OOB_LOGADDR_2_HI       13
                     87:
                     88: /*
                     89:  * Structure for managing logical blocks in a partition; allocated on
                     90:  * first use of each partition on a "safe" flash device.
                     91:  */
                     92: struct zflash_safe {
                     93:        dev_t                    sp_dev;
                     94:        u_long                   sp_pblks;      /* physical block count */
                     95:        u_long                   sp_lblks;      /* logical block count */
                     96:        u_int16_t               *sp_phyuse;     /* physical block usage */
                     97:        u_int                   *sp_logmap;     /* logical to physical */
                     98:        u_int                    sp_pnext;      /* next physical block */
                     99: };
                    100:
                    101: struct zflash_softc {
                    102:        struct flash_softc       sc_flash;
                    103:        bus_space_tag_t          sc_iot;
                    104:        bus_space_handle_t       sc_ioh;
                    105:        int                      sc_ioobbadblk;
                    106:        int                      sc_ioobpostbadblk;
                    107:        struct zflash_safe      *sc_safe[MAXPARTITIONS];
                    108: };
                    109:
                    110: int     zflashmatch(struct device *, void *, void *);
                    111: void    zflashattach(struct device *, struct device *, void *);
                    112: int     zflashdetach(struct device *, int);
                    113:
                    114: u_int8_t zflash_reg8_read(void *, int);
                    115: int     zflash_regx_read_page(void *, caddr_t, caddr_t);
                    116: void    zflash_reg8_write(void *, int, u_int8_t);
                    117: int     zflash_regx_write_page(void *, caddr_t, caddr_t);
                    118: void    zflash_default_disklabel(void *, dev_t, struct disklabel *);
                    119: int     zflash_safe_strategy(void *, struct buf *);
                    120:
                    121: int     zflash_safe_start(struct zflash_softc *, dev_t);
                    122: void    zflash_safe_stop(struct zflash_softc *, dev_t);
                    123:
                    124: struct cfattach flash_pxaip_ca = {
                    125:        sizeof(struct zflash_softc), zflashmatch, zflashattach,
                    126:        zflashdetach, flashactivate
                    127: };
                    128:
                    129: struct flash_ctl_tag zflash_ctl_tag = {
                    130:        zflash_reg8_read,
                    131:        zflash_regx_read_page,
                    132:        zflash_reg8_write,
                    133:        zflash_regx_write_page,
                    134:        zflash_default_disklabel,
                    135:        zflash_safe_strategy
                    136: };
                    137:
                    138: int
                    139: zflashmatch(struct device *parent, void *match, void *aux)
                    140: {
                    141:        /* XXX call flashprobe(), yet to be implemented */
                    142:        return ZAURUS_ISC3000;
                    143: }
                    144:
                    145: void
                    146: zflashattach(struct device *parent, struct device *self, void *aux)
                    147: {
                    148:        struct zflash_softc *sc = (struct zflash_softc *)self;
                    149:        struct pxaip_attach_args *pxa = aux;
                    150:        bus_addr_t addr = pxa->pxa_addr;
                    151:        bus_size_t size = pxa->pxa_size;
                    152:
                    153:        sc->sc_iot = pxa->pxa_iot;
                    154:
                    155:        if ((int)addr == -1 || (int)size == 0) {
                    156:                addr = 0x0c000000;
                    157:                size = 0x00001000;
                    158:        }
                    159:
                    160:        if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) {
                    161:                printf(": failed to map controller\n");
                    162:                return;
                    163:        }
                    164:
                    165:        /* Disable and write-protect the chip. */
                    166:        CPLD_WRITE(sc, CPLD_REG_FLASHCTL, FLASHCTL_NCE);
                    167:
                    168:        flashattach(&sc->sc_flash, &zflash_ctl_tag, sc);
                    169:
                    170:        switch (sc->sc_flash.sc_flashdev->id) {
                    171:        case FLASH_DEVICE_SAMSUNG_K9F2808U0C: /* C3000 */
                    172:                sc->sc_ioobpostbadblk = 4;
                    173:                sc->sc_ioobbadblk = 5;
                    174:                break;
                    175:        case FLASH_DEVICE_SAMSUNG_K9F1G08U0A: /* C3100 */
                    176:                sc->sc_ioobpostbadblk = 4;
                    177:                sc->sc_ioobbadblk = 0;
                    178:                break;
                    179:        }
                    180: }
                    181:
                    182: int
                    183: zflashdetach(struct device *self, int flags)
                    184: {
                    185:        struct zflash_softc *sc = (struct zflash_softc *)self;
                    186:        int part;
                    187:
                    188:        for (part = 0; part < MAXPARTITIONS; part++)
                    189:                zflash_safe_stop(sc, part);
                    190:
                    191:        return (flashdetach(self, flags));
                    192: }
                    193:
                    194: u_int8_t
                    195: zflash_reg8_read(void *arg, int reg)
                    196: {
                    197:        struct zflash_softc *sc = arg;
                    198:        u_int8_t value;
                    199:
                    200:        switch (reg) {
                    201:        case FLASH_REG_DATA:
                    202:                value = CPLD_READ(sc, CPLD_REG_FLASHIO);
                    203:                break;
                    204:        case FLASH_REG_READY:
                    205:                value = (CPLD_READ(sc, CPLD_REG_FLASHCTL) &
                    206:                    FLASHCTL_RYBY) != 0;
                    207:                break;
                    208:        default:
                    209: #ifdef DIAGNOSTIC
                    210:                printf("%s: read from pseudo-register %02x\n",
                    211:                    sc->sc_flash.sc_dev.dv_xname, reg);
                    212: #endif
                    213:                value = 0;
                    214:                break;
                    215:        }
                    216:        return value;
                    217: }
                    218:
                    219: void
                    220: zflash_reg8_write(void *arg, int reg, u_int8_t value)
                    221: {
                    222:        struct zflash_softc *sc = arg;
                    223:
                    224:        switch (reg) {
                    225:        case FLASH_REG_DATA:
                    226:        case FLASH_REG_COL:
                    227:        case FLASH_REG_ROW:
                    228:        case FLASH_REG_CMD:
                    229:                CPLD_WRITE(sc, CPLD_REG_FLASHIO, value);
                    230:                break;
                    231:        case FLASH_REG_ALE:
                    232:                CPLD_SETORCLR(sc, CPLD_REG_FLASHCTL, FLASHCTL_ALE, value);
                    233:                break;
                    234:        case FLASH_REG_CLE:
                    235:                CPLD_SETORCLR(sc, CPLD_REG_FLASHCTL, FLASHCTL_CLE, value);
                    236:                break;
                    237:        case FLASH_REG_CE:
                    238:                CPLD_SETORCLR(sc, CPLD_REG_FLASHCTL, FLASHCTL_NCE, !value);
                    239:                break;
                    240:        case FLASH_REG_WP:
                    241:                CPLD_SETORCLR(sc, CPLD_REG_FLASHCTL, FLASHCTL_NWP, !value);
                    242:                break;
                    243: #ifdef DIAGNOSTIC
                    244:        default:
                    245:                printf("%s: write to pseudo-register %02x\n",
                    246:                    sc->sc_flash.sc_dev.dv_xname, reg);
                    247: #endif
                    248:        }
                    249: }
                    250:
                    251: int
                    252: zflash_regx_read_page(void *arg, caddr_t data, caddr_t oob)
                    253: {
                    254:        struct zflash_softc *sc = arg;
                    255:
                    256:        if (oob == NULL || sc->sc_flash.sc_flashdev->pagesize != 512) {
                    257:                flash_reg8_read_page(&sc->sc_flash, data, oob);
                    258:                return 0;
                    259:        }
                    260:
                    261:        flash_reg8_read_page(&sc->sc_flash, data, oob);
                    262:
                    263:        oob[OOB_JFFS2_ECC0] = 0xff;
                    264:        oob[OOB_JFFS2_ECC1] = 0xff;
                    265:        oob[OOB_JFFS2_ECC2] = 0xff;
                    266:        oob[OOB_JFFS2_ECC3] = 0xff;
                    267:        oob[OOB_JFFS2_ECC4] = 0xff;
                    268:        oob[OOB_JFFS2_ECC5] = 0xff;
                    269:        return 0;
                    270: }
                    271:
                    272: int
                    273: zflash_regx_write_page(void *arg, caddr_t data, caddr_t oob)
                    274: {
                    275:        struct zflash_softc *sc = arg;
                    276:        int i;
                    277:
                    278:        if (oob == NULL || sc->sc_flash.sc_flashdev->pagesize != 512) {
                    279:                flash_reg8_write_page(&sc->sc_flash, data, oob);
                    280:                return 0;
                    281:        }
                    282:
                    283:        if (oob[OOB_JFFS2_ECC0] != 0xff || oob[OOB_JFFS2_ECC1] != 0xff ||
                    284:            oob[OOB_JFFS2_ECC2] != 0xff || oob[OOB_JFFS2_ECC3] != 0xff ||
                    285:            oob[OOB_JFFS2_ECC4] != 0xff || oob[OOB_JFFS2_ECC5] != 0xff) {
                    286: #ifdef DIAGNOSTIC
                    287:                printf("%s: non-FF ECC bytes in OOB data\n",
                    288:                    sc->sc_flash.sc_dev.dv_xname);
                    289: #endif
                    290:                return EINVAL;
                    291:        }
                    292:
                    293:        CPLD_WRITE(sc, CPLD_REG_ECCCLRR, 0x00);
                    294:        for (i = 0; i < sc->sc_flash.sc_flashdev->pagesize / 2; i++)
                    295:                flash_reg8_write(&sc->sc_flash, FLASH_REG_DATA, data[i]);
                    296:
                    297:        oob[OOB_JFFS2_ECC0] = ~CPLD_READ(sc, CPLD_REG_ECCLPUB);
                    298:        oob[OOB_JFFS2_ECC1] = ~CPLD_READ(sc, CPLD_REG_ECCLPLB);
                    299:        oob[OOB_JFFS2_ECC2] = (~CPLD_READ(sc, CPLD_REG_ECCCP) << 2) | 0x03;
                    300:
                    301:        if (CPLD_READ(sc, CPLD_REG_ECCCNTR) != 0) {
                    302:                printf("%s: ECC failed\n", sc->sc_flash.sc_dev.dv_xname);
                    303:                oob[OOB_JFFS2_ECC0] = 0xff;
                    304:                oob[OOB_JFFS2_ECC1] = 0xff;
                    305:                oob[OOB_JFFS2_ECC2] = 0xff;
                    306:                return EIO;
                    307:        }
                    308:
                    309:        CPLD_WRITE(sc, CPLD_REG_ECCCLRR, 0x00);
                    310:        for (; i < sc->sc_flash.sc_flashdev->pagesize; i++)
                    311:                flash_reg8_write(&sc->sc_flash, FLASH_REG_DATA, data[i]);
                    312:
                    313:        oob[OOB_JFFS2_ECC3] = ~CPLD_READ(sc, CPLD_REG_ECCLPUB);
                    314:        oob[OOB_JFFS2_ECC4] = ~CPLD_READ(sc, CPLD_REG_ECCLPLB);
                    315:        oob[OOB_JFFS2_ECC5] = (~CPLD_READ(sc, CPLD_REG_ECCCP) << 2) | 0x03;
                    316:
                    317:        if (CPLD_READ(sc, CPLD_REG_ECCCNTR) != 0) {
                    318:                printf("%s: ECC failed\n", sc->sc_flash.sc_dev.dv_xname);
                    319:                oob[OOB_JFFS2_ECC0] = 0xff;
                    320:                oob[OOB_JFFS2_ECC1] = 0xff;
                    321:                oob[OOB_JFFS2_ECC2] = 0xff;
                    322:                oob[OOB_JFFS2_ECC3] = 0xff;
                    323:                oob[OOB_JFFS2_ECC4] = 0xff;
                    324:                oob[OOB_JFFS2_ECC5] = 0xff;
                    325:                return EIO;
                    326:        }
                    327:
                    328:        for (i = 0; i < sc->sc_flash.sc_flashdev->oobsize; i++)
                    329:                flash_reg8_write(&sc->sc_flash, FLASH_REG_DATA, oob[i]);
                    330:
                    331:        oob[OOB_JFFS2_ECC0] = 0xff;
                    332:        oob[OOB_JFFS2_ECC1] = 0xff;
                    333:        oob[OOB_JFFS2_ECC2] = 0xff;
                    334:        oob[OOB_JFFS2_ECC3] = 0xff;
                    335:        oob[OOB_JFFS2_ECC4] = 0xff;
                    336:        oob[OOB_JFFS2_ECC5] = 0xff;
                    337:        return 0;
                    338: }
                    339:
                    340: /*
                    341:  * A default disklabel with only one RAW_PART spanning the whole
                    342:  * device is passed to us. We add the partitions besides RAW_PART.
                    343:  */
                    344: void
                    345: zflash_default_disklabel(void *arg, dev_t dev, struct disklabel *lp)
                    346: {
                    347:        struct zflash_softc *sc = arg;
                    348:        long bsize = sc->sc_flash.sc_flashdev->pagesize;
                    349:
                    350:        switch (sc->sc_flash.sc_flashdev->id) {
                    351:        case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
                    352:                DL_SETPSIZE(&lp->d_partitions[8], 7*1024*1024 / bsize);
                    353:                DL_SETPSIZE(&lp->d_partitions[9], 5*1024*1024 / bsize);
                    354:                DL_SETPSIZE(&lp->d_partitions[10], 4*1024*1024 / bsize);
                    355:                break;
                    356:        case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
                    357:                DL_SETPSIZE(&lp->d_partitions[8], 7*1024*1024 / bsize);
                    358:                DL_SETPSIZE(&lp->d_partitions[9], 32*1024*1024 / bsize);
                    359:                DL_SETPSIZE(&lp->d_partitions[10], 89*1024*1024 / bsize);
                    360:                break;
                    361:        default:
                    362:                return;
                    363:        }
                    364:
                    365:        /* The "smf" partition uses logical addressing. */
                    366:        DL_SETPOFFSET(&lp->d_partitions[8], 0);
                    367:        lp->d_partitions[8].p_fstype = FS_OTHER;
                    368:
                    369:        /* The "root" partition uses physical addressing. */
                    370:        DL_SETPSIZE(&lp->d_partitions[9], DL_GETPSIZE(&lp->d_partitions[8]));
                    371:        lp->d_partitions[9].p_fstype = FS_OTHER;
                    372:
                    373:        /* The "home" partition uses physical addressing. */
                    374:        DL_SETPOFFSET(&lp->d_partitions[10],
                    375:            DL_GETPOFFSET(&lp->d_partitions[9]) + DL_GETPSIZE(&lp->d_partitions[9]));
                    376:        lp->d_partitions[10].p_fstype = FS_OTHER;
                    377:        lp->d_npartitions = 11;
                    378:
                    379:        lp->d_version = 1;
                    380:        /* Re-calculate the checksum. */
                    381:        lp->d_checksum = dkcksum(lp);
                    382: }
                    383:
                    384: /*
                    385:  * Sharp's access strategy for bad blocks management and wear-leveling.
                    386:  */
                    387:
                    388: #define PHYUSE_STATUS(v)       ((v) & 0x00ff)
                    389: #define  P_BADBLOCK            0x0000
                    390: #define  P_POSTBADBLOCK                0x00f0
                    391: #define  P_NORMALBLOCK         0x00ff
                    392: #define PHYUSE_WRITTEN(v)      ((v) & 0xff00)
                    393: #define  P_DUST                        0x0000
                    394: #define  P_LOGICAL             0x0100
                    395: #define  P_JFFS2               0x0300
                    396:
                    397: void     zflash_write_strategy(struct zflash_softc *, struct buf *,
                    398:     struct zflash_safe *, u_int, u_int);
                    399: u_int    zflash_safe_next_block(struct zflash_safe *);
                    400:
                    401: u_char   zflash_oob_status_decode(u_char);
                    402: u_int16_t zflash_oob_status(struct zflash_softc *, u_char *);
                    403: u_int    zflash_oob_logno(struct zflash_softc *, u_char *);
                    404: void     zflash_oob_set_status(struct zflash_softc *, u_char *, u_int16_t);
                    405: void     zflash_oob_set_logno(struct zflash_softc *, u_char *, u_int);
                    406:
                    407: int
                    408: zflash_safe_strategy(void *arg, struct buf *bp)
                    409: {
                    410:        struct zflash_softc *sc = arg;
                    411:        struct zflash_safe *sp;
                    412:        u_int logno;
                    413:        u_int blkofs;
                    414:        u_int blkno;
                    415:        int error;
                    416:        int part;
                    417:        int i;
                    418:
                    419:        /* Initialize logical blocks management on the fly. */
                    420:        /* XXX toss everything when the disklabel has changed. */
                    421:        if ((error = zflash_safe_start(sc, bp->b_dev)) != 0) {
                    422:                bp->b_error = error;
                    423:                bp->b_flags |= B_ERROR;
                    424:                return 0;
                    425:        }
                    426:
                    427:        part = flashpart(bp->b_dev);
                    428:        sp = sc->sc_safe[part];
                    429:
                    430:        logno = bp->b_blkno / (sc->sc_flash.sc_flashdev->blkpages *
                    431:            sc->sc_flash.sc_flashdev->pagesize / DEV_BSIZE);
                    432:        blkofs = bp->b_blkno % (sc->sc_flash.sc_flashdev->blkpages *
                    433:            sc->sc_flash.sc_flashdev->pagesize / DEV_BSIZE);
                    434:
                    435:        /* If exactly at end of logical flash, return EOF, else error. */
                    436:        if (logno == sp->sp_lblks && blkofs == 0) {
                    437:                bp->b_resid = bp->b_bcount;
                    438:                return 0;
                    439:        } else if (logno >= sp->sp_lblks) {
                    440:                bp->b_error = EINVAL;
                    441:                bp->b_flags |= B_ERROR;
                    442:                return 0;
                    443:        }
                    444:
                    445:        /* Writing is more complicated, so handle it separately. */
                    446:        if ((bp->b_flags & B_READ) == 0) {
                    447:                flash_chip_enable(&sc->sc_flash);
                    448:                zflash_write_strategy(sc, bp, sp, logno, blkofs);
                    449:                flash_chip_disable(&sc->sc_flash);
                    450:                return 0;
                    451:        }
                    452:
                    453:        /* Get the physical flash block number for this logical one. */
                    454:        blkno = sp->sp_logmap[logno];
                    455:
                    456:        /* Unused logical blocks read as all 0xff. */
                    457:        if ((bp->b_flags & B_READ) != 0 && blkno == UINT_MAX) {
                    458:                for (i = 0; i < sc->sc_flash.sc_flashdev->pagesize; i++)
                    459:                        ((u_char *)bp->b_data)[i] = 0xff;
                    460:                bp->b_resid = bp->b_bcount -
                    461:                    sc->sc_flash.sc_flashdev->pagesize;
                    462:                return 0;
                    463:        }
                    464:
                    465:        /* Update the block number in the buffer with the physical one. */
                    466:        bp->b_blkno = blkno * (sc->sc_flash.sc_flashdev->blkpages *
                    467:            sc->sc_flash.sc_flashdev->pagesize / DEV_BSIZE) + blkofs;
                    468:
                    469:        /* Process the modified transfer buffer normally. */
                    470:        return 1;
                    471: }
                    472:
                    473: void
                    474: zflash_write_strategy(struct zflash_softc *sc, struct buf *bp,
                    475:     struct zflash_safe *sp, u_int logno, u_int logofs)
                    476: {
                    477:        size_t  bufsize;
                    478:        u_char *buf = NULL;
                    479:        size_t  oobsize;
                    480:        u_char *oob = NULL;
                    481:        u_int   oblkno;
                    482:        u_int   nblkno;
                    483:        int     error;
                    484:
                    485:        /* Not efficient, but we always transfer one page for now. */
                    486:        if (bp->b_bcount < sc->sc_flash.sc_flashdev->pagesize) {
                    487:                bp->b_error = EINVAL;
                    488:                goto bad;
                    489:        }
                    490:
                    491:        /* Allocate a temporary buffer for one flash block. */
                    492:        bufsize = sc->sc_flash.sc_flashdev->blkpages *
                    493:            sc->sc_flash.sc_flashdev->pagesize;
                    494:        buf = (u_char *)malloc(bufsize, M_DEVBUF, M_NOWAIT);
                    495:        if (buf == NULL) {
                    496:                bp->b_error = ENOMEM;
                    497:                goto bad;
                    498:        }
                    499:
                    500:        /* Allocate a temporary buffer for one spare area. */
                    501:        oobsize = sc->sc_flash.sc_flashdev->oobsize;
                    502:        oob = (u_char *)malloc(oobsize, M_DEVBUF, M_NOWAIT);
                    503:        if (oob == NULL) {
                    504:                bp->b_error = ENOMEM;
                    505:                goto bad;
                    506:        }
                    507:
                    508:        /* Read the old logical block into the temporary buffer. */
                    509:        oblkno = sp->sp_logmap[logno];
                    510:        if (oblkno != UINT_MAX) {
                    511:                error = flash_chip_read_block(&sc->sc_flash, oblkno, buf);
                    512:                if (error != 0) {
                    513:                        bp->b_error = error;
                    514:                        goto bad;
                    515:                }
                    516:        } else
                    517:                /* Unused logical blocks read as all 0xff. */
                    518:                memset(buf, 0xff, bufsize);
                    519:
                    520:        /* Transfer the page into the logical block buffer. */
                    521:        bcopy(bp->b_data, buf + logofs * sc->sc_flash.sc_flashdev->pagesize,
                    522:            sc->sc_flash.sc_flashdev->pagesize);
                    523:
                    524:        /* Generate OOB data for the spare area of this logical block. */
                    525:        memset(oob, 0xff, oobsize);
                    526:        zflash_oob_set_status(sc, oob, P_NORMALBLOCK);
                    527:        zflash_oob_set_logno(sc, oob, logno);
                    528:
                    529:        while (1) {
                    530:                /* Search for a free physical block. */
                    531:                nblkno = zflash_safe_next_block(sp);
                    532:                if (nblkno == UINT_MAX) {
                    533:                        printf("%s: no spare block, giving up on logical"
                    534:                            " block %u\n", sc->sc_flash.sc_dev.dv_xname,
                    535:                            logno);
                    536:                        bp->b_error = ENOSPC;
                    537:                        goto bad;
                    538:                }
                    539:
                    540: #if 0
                    541:                DPRINTF(("%s: moving logical block %u from physical %u to %u\n",
                    542:                    sc->sc_flash.sc_dev.dv_xname, logno, oblkno, nblkno));
                    543: #endif
                    544:
                    545:                /* Erase the free physical block. */
                    546:                if (flash_chip_erase_block(&sc->sc_flash, nblkno) != 0) {
                    547:                        printf("%s: can't erase block %u, retrying\n",
                    548:                            sc->sc_flash.sc_dev.dv_xname, nblkno);
                    549:                        sp->sp_phyuse[nblkno] = P_POSTBADBLOCK | P_DUST;
                    550:                        continue;
                    551:                }
                    552:
                    553:                /* Write the logical block to the free physical block. */
                    554:                if (flash_chip_write_block(&sc->sc_flash, nblkno, buf, oob)) {
                    555:                        printf("%s: can't write block %u, retrying\n",
                    556:                            sc->sc_flash.sc_dev.dv_xname, nblkno);
                    557:                        goto trynext;
                    558:                }
                    559:
                    560:                /* Yeah, we re-wrote that logical block! */
                    561:                break;
                    562:        trynext:
                    563:                sp->sp_phyuse[nblkno] = P_POSTBADBLOCK | P_DUST;
                    564:                (void)flash_chip_erase_block(&sc->sc_flash, nblkno);
                    565:        }
                    566:
                    567:        /* Map the new physical block. */
                    568:        sp->sp_logmap[logno] = nblkno;
                    569:        sp->sp_phyuse[nblkno] = PHYUSE_STATUS(sp->sp_phyuse[nblkno])
                    570:            | P_LOGICAL;
                    571:
                    572:        /* Erase the old physical block. */
                    573:        if (oblkno != UINT_MAX) {
                    574:                sp->sp_phyuse[oblkno] = PHYUSE_STATUS(sp->sp_phyuse[oblkno])
                    575:                    | P_DUST;
                    576:                error = flash_chip_erase_block(&sc->sc_flash, oblkno);
                    577:                if (error != 0) {
                    578:                        printf("%s: can't erase old block %u\n",
                    579:                            sc->sc_flash.sc_dev.dv_xname, oblkno);
                    580:                        bp->b_error = error;
                    581:                        goto bad;
                    582:                }
                    583:        }
                    584:
                    585:        bp->b_resid = bp->b_bcount - sc->sc_flash.sc_flashdev->pagesize;
                    586:        free(oob, M_DEVBUF);
                    587:        free(buf, M_DEVBUF);
                    588:        return;
                    589: bad:
                    590:        bp->b_flags |= B_ERROR;
                    591:        if (oob != NULL)
                    592:                free(oob, M_DEVBUF);
                    593:        if (buf != NULL)
                    594:                free(buf, M_DEVBUF);
                    595: }
                    596:
                    597: int
                    598: zflash_safe_start(struct zflash_softc *sc, dev_t dev)
                    599: {
                    600:        u_char oob[FLASH_MAXOOBSIZE];
                    601:        struct disklabel *lp = sc->sc_flash.sc_dk.dk_label;
                    602:        struct zflash_safe *sp;
                    603:        u_int16_t *phyuse;
                    604:        u_int *logmap;
                    605:        u_int blksect;
                    606:        u_int blkno;
                    607:        u_int logno;
                    608:        u_int unusable;
                    609:        int part;
                    610:
                    611:        part = flashpart(dev);
                    612:        if (sc->sc_safe[part] != NULL)
                    613:                return 0;
                    614:
                    615:        /* We can only handle so much OOB data here. */
                    616:        if (sc->sc_flash.sc_flashdev->oobsize > FLASH_MAXOOBSIZE)
                    617:                return EIO;
                    618:
                    619:        /* Safe partitions must start on a flash block boundary. */
                    620:        blksect = (sc->sc_flash.sc_flashdev->blkpages *
                    621:            sc->sc_flash.sc_flashdev->pagesize) / lp->d_secsize;
                    622:        if (DL_GETPOFFSET(&lp->d_partitions[part]) % blksect)
                    623:                return EIO;
                    624:
                    625:        MALLOC(sp, struct zflash_safe *, sizeof(struct zflash_safe),
                    626:            M_DEVBUF, M_NOWAIT);
                    627:        if (sp == NULL)
                    628:                return ENOMEM;
                    629:
                    630:        bzero(sp, sizeof(struct zflash_safe));
                    631:        sp->sp_dev = dev;
                    632:
                    633:        sp->sp_pblks = DL_GETPSIZE(&lp->d_partitions[part]) / blksect;
                    634:        sp->sp_lblks = sp->sp_pblks;
                    635:
                    636:        /* Try to reserve a number of spare physical blocks. */
                    637:        switch (sc->sc_flash.sc_flashdev->id) {
                    638:        case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
                    639:                sp->sp_lblks -= 24; /* C3000 */
                    640:                break;
                    641:        case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
                    642:                sp->sp_lblks -= 4;  /* C3100 */
                    643:                break;
                    644:        }
                    645:
                    646:        DPRINTF(("pblks %u lblks %u\n", sp->sp_pblks, sp->sp_lblks));
                    647:
                    648:        /* Next physical block to use; randomize for wear-leveling. */
                    649:        sp->sp_pnext = arc4random() % sp->sp_pblks;
                    650:
                    651:        /* Allocate physical block usage map. */
                    652:        phyuse = (u_int16_t *)malloc(sp->sp_pblks * sizeof(u_int16_t),
                    653:            M_DEVBUF, M_NOWAIT);
                    654:        if (phyuse == NULL) {
                    655:                FREE(sp, M_DEVBUF);
                    656:                return ENOMEM;
                    657:        }
                    658:        sp->sp_phyuse = phyuse;
                    659:
                    660:        /* Allocate logical to physical block map. */
                    661:        logmap = (u_int *)malloc(sp->sp_lblks * sizeof(u_int),
                    662:            M_DEVBUF, M_NOWAIT);
                    663:        if (logmap == NULL) {
                    664:                FREE(phyuse, M_DEVBUF);
                    665:                FREE(sp, M_DEVBUF);
                    666:                return ENOMEM;
                    667:        }
                    668:        sp->sp_logmap = logmap;
                    669:
                    670:        /* Initialize the physical and logical block maps. */
                    671:        for (blkno = 0; blkno < sp->sp_pblks; blkno++)
                    672:                phyuse[blkno] = P_BADBLOCK | P_DUST;
                    673:        for (blkno = 0; blkno < sp->sp_lblks; blkno++)
                    674:                logmap[blkno] = UINT_MAX;
                    675:
                    676:        /* Update physical block usage map with real data. */
                    677:        unusable = 0;
                    678:        flash_chip_enable(&sc->sc_flash);
                    679:        for (blkno = 0; blkno < sp->sp_pblks; blkno++) {
                    680:                long pageno;
                    681:
                    682:                pageno = blkno * sc->sc_flash.sc_flashdev->blkpages;
                    683:                if (flash_chip_read_oob(&sc->sc_flash, pageno, oob) != 0) {
                    684:                        DPRINTF(("blkno %u: can't read oob data\n", blkno));
                    685:                        phyuse[blkno] = P_POSTBADBLOCK | P_DUST;
                    686:                        unusable++;
                    687:                        continue;
                    688:                }
                    689:
                    690:                phyuse[blkno] = zflash_oob_status(sc, oob);
                    691:                if (PHYUSE_STATUS(phyuse[blkno]) != P_NORMALBLOCK) {
                    692:                        DPRINTF(("blkno %u: badblock status %x\n", blkno,
                    693:                            PHYUSE_STATUS(phyuse[blkno])));
                    694:                        phyuse[blkno] |= P_DUST;
                    695:                        unusable++;
                    696:                        continue;
                    697:                }
                    698:
                    699:                logno = zflash_oob_logno(sc, oob);
                    700:                if (logno == UINT_MAX) {
                    701:                        DPRINTF(("blkno %u: can't read logno\n", blkno));
                    702:                        phyuse[blkno] |= P_JFFS2;
                    703:                        unusable++;
                    704:                        continue;
                    705:                }
                    706:
                    707:                if (logno == USHRT_MAX) {
                    708:                        phyuse[blkno] |= P_DUST;
                    709:                        /* Block is usable and available. */
                    710:                        continue;
                    711:                }
                    712:
                    713:                if (logno >= sp->sp_lblks) {
                    714:                        DPRINTF(("blkno %u: logno %u too big\n", blkno,
                    715:                            logno));
                    716:                        phyuse[blkno] |= P_JFFS2;
                    717:                        unusable++;
                    718:                        continue;
                    719:                }
                    720:
                    721:                if (logmap[logno] == UINT_MAX) {
                    722:                        phyuse[blkno] |= P_LOGICAL;
                    723:                        logmap[logno] = blkno;
                    724:                } else {
                    725:                        /* Duplicate logical block! */
                    726:                        DPRINTF(("blkno %u: duplicate logno %u\n", blkno,
                    727:                            logno));
                    728:                        phyuse[blkno] |= P_DUST;
                    729:                }
                    730:        }
                    731:        flash_chip_disable(&sc->sc_flash);
                    732:
                    733:        if (unusable > 0)
                    734:                printf("%s: %u unusable blocks\n",
                    735:                    sc->sc_flash.sc_dev.dv_xname, unusable);
                    736:
                    737:        sc->sc_safe[part] = sp;
                    738:        return 0;
                    739: }
                    740:
                    741: void
                    742: zflash_safe_stop(struct zflash_softc *sc, dev_t dev)
                    743: {
                    744:        struct zflash_safe *sp;
                    745:        int part;
                    746:
                    747:        part = flashpart(dev);
                    748:        if (sc->sc_safe[part] == NULL)
                    749:                return;
                    750:
                    751:        sp = sc->sc_safe[part];
                    752:        free(sp->sp_phyuse, M_DEVBUF);
                    753:        free(sp->sp_logmap, M_DEVBUF);
                    754:        FREE(sp, M_DEVBUF);
                    755:        sc->sc_safe[part] = NULL;
                    756: }
                    757:
                    758: u_int
                    759: zflash_safe_next_block(struct zflash_safe *sp)
                    760: {
                    761:        u_int blkno;
                    762:
                    763:        for (blkno = sp->sp_pnext; blkno < sp->sp_pblks; blkno++)
                    764:                if (sp->sp_phyuse[blkno] == (P_NORMALBLOCK|P_DUST)) {
                    765:                        sp->sp_pnext = blkno + 1;
                    766:                        return blkno;
                    767:                }
                    768:
                    769:        for (blkno = 0; blkno < sp->sp_pnext; blkno++)
                    770:                if (sp->sp_phyuse[blkno] == (P_NORMALBLOCK|P_DUST)) {
                    771:                        sp->sp_pnext = blkno + 1;
                    772:                        return blkno;
                    773:                }
                    774:
                    775:        return UINT_MAX;
                    776: }
                    777:
                    778: /*
                    779:  * Correct single bit errors in the block's status byte.
                    780:  */
                    781: u_char
                    782: zflash_oob_status_decode(u_char status)
                    783: {
                    784:        u_char bit;
                    785:        int count;
                    786:
                    787:        /* Speed-up. */
                    788:        if (status == 0xff)
                    789:                return 0xff;
                    790:
                    791:        /* Count the number of bits set in the byte. */
                    792:        for (count = 0, bit = 0x01; bit != 0x00; bit <<= 1)
                    793:                if ((status & bit) != 0)
                    794:                        count++;
                    795:
                    796:        return (count > 6) ? 0xff : 0x00;
                    797: }
                    798:
                    799: /*
                    800:  * Decode the block's status byte into a value for the phyuse map.
                    801:  */
                    802: u_int16_t
                    803: zflash_oob_status(struct zflash_softc *sc, u_char *oob)
                    804: {
                    805:        u_char status;
                    806:
                    807:        status = zflash_oob_status_decode(oob[sc->sc_ioobbadblk]);
                    808:        if (status != 0xff)
                    809:                return P_BADBLOCK;
                    810:
                    811:        status = zflash_oob_status_decode(oob[sc->sc_ioobpostbadblk]);
                    812:        if (status != 0xff)
                    813:                return P_POSTBADBLOCK;
                    814:
                    815:        return P_NORMALBLOCK;
                    816: }
                    817:
                    818: /*
                    819:  * Extract the 16-bit logical block number corresponding to a physical
                    820:  * block from the physical block's OOB data.
                    821:  */
                    822: u_int
                    823: zflash_oob_logno(struct zflash_softc *sc, u_char *oob)
                    824: {
                    825:        int idx_lo, idx_hi;
                    826:        u_int16_t word;
                    827:        u_int16_t bit;
                    828:        int parity;
                    829:
                    830:        /* Find a matching pair of high and low bytes. */
                    831:        if (oob[OOB_LOGADDR_0_LO] == oob[OOB_LOGADDR_1_LO] &&
                    832:            oob[OOB_LOGADDR_0_HI] == oob[OOB_LOGADDR_1_HI]) {
                    833:                idx_lo = OOB_LOGADDR_0_LO;
                    834:                idx_hi = OOB_LOGADDR_0_HI;
                    835:        } else if (oob[OOB_LOGADDR_1_LO] == oob[OOB_LOGADDR_2_LO] &&
                    836:            oob[OOB_LOGADDR_1_HI] == oob[OOB_LOGADDR_2_HI]) {
                    837:                idx_lo = OOB_LOGADDR_1_LO;
                    838:                idx_hi = OOB_LOGADDR_1_HI;
                    839:        } else if (oob[OOB_LOGADDR_2_LO] == oob[OOB_LOGADDR_0_LO] &&
                    840:            oob[OOB_LOGADDR_2_HI] == oob[OOB_LOGADDR_0_HI]) {
                    841:                idx_lo = OOB_LOGADDR_2_LO;
                    842:                idx_hi = OOB_LOGADDR_2_HI;
                    843:        } else
                    844:                /* Block's OOB data may be invalid. */
                    845:                return UINT_MAX;
                    846:
                    847:        word = ((u_int16_t)oob[idx_lo] << 0) |
                    848:            ((u_int16_t)oob[idx_hi] << 8);
                    849:
                    850:        /* Check for parity error in the logical block number. */
                    851:        for (parity = 0, bit = 0x0001; bit != 0x0000; bit <<= 1)
                    852:                if ((word & bit) != 0)
                    853:                        parity++;
                    854:        if ((parity & 1) != 0)
                    855:                return UINT_MAX;
                    856:
                    857:        /* No logical block number assigned to this block? */
                    858:        if (word == USHRT_MAX)
                    859:                return word;
                    860:
                    861:        /* Return the validated logical block number. */
                    862:        return (word & 0x07fe) >> 1;
                    863: }
                    864:
                    865: void
                    866: zflash_oob_set_status(struct zflash_softc *sc, u_char *oob, u_int16_t phyuse)
                    867: {
                    868:        switch (PHYUSE_STATUS(phyuse)) {
                    869:        case P_NORMALBLOCK:
                    870:                oob[sc->sc_ioobbadblk] = 0xff;
                    871:                oob[sc->sc_ioobpostbadblk] = 0xff;
                    872:                break;
                    873:        case P_BADBLOCK:
                    874:                oob[sc->sc_ioobbadblk] = 0x00;
                    875:                oob[sc->sc_ioobpostbadblk] = 0x00;
                    876:                break;
                    877:        case P_POSTBADBLOCK:
                    878:                oob[sc->sc_ioobbadblk] = 0xff;
                    879:                oob[sc->sc_ioobpostbadblk] = 0x00;
                    880:                break;
                    881:        }
                    882: }
                    883:
                    884: void
                    885: zflash_oob_set_logno(struct zflash_softc *sc, u_char *oob, u_int logno)
                    886: {
                    887:        u_int16_t word;
                    888:        u_int16_t bit;
                    889:        u_char lo;
                    890:        u_char hi;
                    891:        int parity;
                    892:
                    893:        /* Why do we set the most significant bit? */
                    894:        word = ((logno & 0x03ff) << 1) | 0x1000;
                    895:
                    896:        /* Calculate the parity. */
                    897:        for (bit = 0x0001; bit != 0x0000; bit <<= 1)
                    898:                if ((word & bit) != 0)
                    899:                        parity++;
                    900:        if ((parity & 1) != 0)
                    901:                word |= 0x0001;
                    902:
                    903:        lo = word & 0x00ff;
                    904:        hi = (word & 0xff00) >> 8;
                    905:
                    906:        oob[OOB_LOGADDR_0_LO] = lo;
                    907:        oob[OOB_LOGADDR_0_HI] = hi;
                    908:        oob[OOB_LOGADDR_1_LO] = lo;
                    909:        oob[OOB_LOGADDR_1_HI] = hi;
                    910:        oob[OOB_LOGADDR_2_LO] = lo;
                    911:        oob[OOB_LOGADDR_2_HI] = hi;
                    912: }

CVSweb