Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge git://git.infradead.org/~dwmw2/cafe-2.6

+2162 -1
+7
drivers/mtd/nand/Kconfig
··· 220 220 tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" 221 221 depends on MTD_NAND && ARCH_PXA 222 222 223 + config MTD_NAND_CAFE 224 + tristate "NAND support for OLPC CAFÉ chip" 225 + depends on PCI 226 + help 227 + Use NAND flash attached to the CAFÉ chip designed for the $100 228 + laptop. 229 + 223 230 config MTD_NAND_CS553X 224 231 tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)" 225 232 depends on MTD_NAND && X86_32 && (X86_PC || X86_GENERICARCH)
+3 -1
drivers/mtd/nand/Makefile
··· 6 6 obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o 7 7 obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o 8 8 9 + obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o 9 10 obj-$(CONFIG_MTD_NAND_SPIA) += spia.o 10 11 obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o 11 12 obj-$(CONFIG_MTD_NAND_TOTO) += toto.o ··· 25 24 obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o 26 25 obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o 27 26 28 - nand-objs = nand_base.o nand_bbt.o 27 + nand-objs := nand_base.o nand_bbt.o 28 + cafe_nand-objs := cafe.o cafe_ecc.o
+771
drivers/mtd/nand/cafe.c
··· 1 + /* 2 + * Driver for One Laptop Per Child ‘CAFÉ’ controller, aka Marvell 88ALP01 3 + * 4 + * Copyright © 2006 Red Hat, Inc. 5 + * Copyright © 2006 David Woodhouse <dwmw2@infradead.org> 6 + */ 7 + 8 + #define DEBUG 9 + 10 + #include <linux/device.h> 11 + #undef DEBUG 12 + #include <linux/mtd/mtd.h> 13 + #include <linux/mtd/nand.h> 14 + #include <linux/pci.h> 15 + #include <linux/delay.h> 16 + #include <linux/interrupt.h> 17 + #include <asm/io.h> 18 + 19 + #define CAFE_NAND_CTRL1 0x00 20 + #define CAFE_NAND_CTRL2 0x04 21 + #define CAFE_NAND_CTRL3 0x08 22 + #define CAFE_NAND_STATUS 0x0c 23 + #define CAFE_NAND_IRQ 0x10 24 + #define CAFE_NAND_IRQ_MASK 0x14 25 + #define CAFE_NAND_DATA_LEN 0x18 26 + #define CAFE_NAND_ADDR1 0x1c 27 + #define CAFE_NAND_ADDR2 0x20 28 + #define CAFE_NAND_TIMING1 0x24 29 + #define CAFE_NAND_TIMING2 0x28 30 + #define CAFE_NAND_TIMING3 0x2c 31 + #define CAFE_NAND_NONMEM 0x30 32 + #define CAFE_NAND_ECC_RESULT 0x3C 33 + #define CAFE_NAND_DMA_CTRL 0x40 34 + #define CAFE_NAND_DMA_ADDR0 0x44 35 + #define CAFE_NAND_DMA_ADDR1 0x48 36 + #define CAFE_NAND_ECC_SYN01 0x50 37 + #define CAFE_NAND_ECC_SYN23 0x54 38 + #define CAFE_NAND_ECC_SYN45 0x58 39 + #define CAFE_NAND_ECC_SYN67 0x5c 40 + #define CAFE_NAND_READ_DATA 0x1000 41 + #define CAFE_NAND_WRITE_DATA 0x2000 42 + 43 + #define CAFE_GLOBAL_CTRL 0x3004 44 + #define CAFE_GLOBAL_IRQ 0x3008 45 + #define CAFE_GLOBAL_IRQ_MASK 0x300c 46 + #define CAFE_NAND_RESET 0x3034 47 + 48 + int cafe_correct_ecc(unsigned char *buf, 49 + unsigned short *chk_syndrome_list); 50 + 51 + struct cafe_priv { 52 + struct nand_chip nand; 53 + struct pci_dev *pdev; 54 + void __iomem *mmio; 55 + uint32_t ctl1; 56 + uint32_t ctl2; 57 + int datalen; 58 + int nr_data; 59 + int data_pos; 60 + int page_addr; 61 + dma_addr_t dmaaddr; 62 + unsigned char *dmabuf; 63 + 64 + }; 65 + 66 + static int usedma = 1; 67 + module_param(usedma, int, 0644); 68 + 69 + static int skipbbt = 0; 70 + module_param(skipbbt, int, 0644); 71 + 72 + static int debug = 0; 73 + module_param(debug, int, 0644); 74 + 75 + static int regdebug = 0; 76 + module_param(regdebug, int, 0644); 77 + 78 + static int checkecc = 1; 79 + module_param(checkecc, int, 0644); 80 + 81 + static int slowtiming = 0; 82 + module_param(slowtiming, int, 0644); 83 + 84 + /* Hrm. Why isn't this already conditional on something in the struct device? */ 85 + #define cafe_dev_dbg(dev, args...) do { if (debug) dev_dbg(dev, ##args); } while(0) 86 + 87 + /* Make it easier to switch to PIO if we need to */ 88 + #define cafe_readl(cafe, addr) readl((cafe)->mmio + CAFE_##addr) 89 + #define cafe_writel(cafe, datum, addr) writel(datum, (cafe)->mmio + CAFE_##addr) 90 + 91 + static int cafe_device_ready(struct mtd_info *mtd) 92 + { 93 + struct cafe_priv *cafe = mtd->priv; 94 + int result = !!(cafe_readl(cafe, NAND_STATUS) | 0x40000000); 95 + uint32_t irqs = cafe_readl(cafe, NAND_IRQ); 96 + 97 + cafe_writel(cafe, irqs, NAND_IRQ); 98 + 99 + cafe_dev_dbg(&cafe->pdev->dev, "NAND device is%s ready, IRQ %x (%x) (%x,%x)\n", 100 + result?"":" not", irqs, cafe_readl(cafe, NAND_IRQ), 101 + cafe_readl(cafe, GLOBAL_IRQ), cafe_readl(cafe, GLOBAL_IRQ_MASK)); 102 + 103 + return result; 104 + } 105 + 106 + 107 + static void cafe_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) 108 + { 109 + struct cafe_priv *cafe = mtd->priv; 110 + 111 + if (usedma) 112 + memcpy(cafe->dmabuf + cafe->datalen, buf, len); 113 + else 114 + memcpy_toio(cafe->mmio + CAFE_NAND_WRITE_DATA + cafe->datalen, buf, len); 115 + 116 + cafe->datalen += len; 117 + 118 + cafe_dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes to write buffer. datalen 0x%x\n", 119 + len, cafe->datalen); 120 + } 121 + 122 + static void cafe_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) 123 + { 124 + struct cafe_priv *cafe = mtd->priv; 125 + 126 + if (usedma) 127 + memcpy(buf, cafe->dmabuf + cafe->datalen, len); 128 + else 129 + memcpy_fromio(buf, cafe->mmio + CAFE_NAND_READ_DATA + cafe->datalen, len); 130 + 131 + cafe_dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes from position 0x%x in read buffer.\n", 132 + len, cafe->datalen); 133 + cafe->datalen += len; 134 + } 135 + 136 + static uint8_t cafe_read_byte(struct mtd_info *mtd) 137 + { 138 + struct cafe_priv *cafe = mtd->priv; 139 + uint8_t d; 140 + 141 + cafe_read_buf(mtd, &d, 1); 142 + cafe_dev_dbg(&cafe->pdev->dev, "Read %02x\n", d); 143 + 144 + return d; 145 + } 146 + 147 + static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, 148 + int column, int page_addr) 149 + { 150 + struct cafe_priv *cafe = mtd->priv; 151 + int adrbytes = 0; 152 + uint32_t ctl1; 153 + uint32_t doneint = 0x80000000; 154 + 155 + cafe_dev_dbg(&cafe->pdev->dev, "cmdfunc %02x, 0x%x, 0x%x\n", 156 + command, column, page_addr); 157 + 158 + if (command == NAND_CMD_ERASE2 || command == NAND_CMD_PAGEPROG) { 159 + /* Second half of a command we already calculated */ 160 + cafe_writel(cafe, cafe->ctl2 | 0x100 | command, NAND_CTRL2); 161 + ctl1 = cafe->ctl1; 162 + cafe->ctl2 &= ~(1<<30); 163 + cafe_dev_dbg(&cafe->pdev->dev, "Continue command, ctl1 %08x, #data %d\n", 164 + cafe->ctl1, cafe->nr_data); 165 + goto do_command; 166 + } 167 + /* Reset ECC engine */ 168 + cafe_writel(cafe, 0, NAND_CTRL2); 169 + 170 + /* Emulate NAND_CMD_READOOB on large-page chips */ 171 + if (mtd->writesize > 512 && 172 + command == NAND_CMD_READOOB) { 173 + column += mtd->writesize; 174 + command = NAND_CMD_READ0; 175 + } 176 + 177 + /* FIXME: Do we need to send read command before sending data 178 + for small-page chips, to position the buffer correctly? */ 179 + 180 + if (column != -1) { 181 + cafe_writel(cafe, column, NAND_ADDR1); 182 + adrbytes = 2; 183 + if (page_addr != -1) 184 + goto write_adr2; 185 + } else if (page_addr != -1) { 186 + cafe_writel(cafe, page_addr & 0xffff, NAND_ADDR1); 187 + page_addr >>= 16; 188 + write_adr2: 189 + cafe_writel(cafe, page_addr, NAND_ADDR2); 190 + adrbytes += 2; 191 + if (mtd->size > mtd->writesize << 16) 192 + adrbytes++; 193 + } 194 + 195 + cafe->data_pos = cafe->datalen = 0; 196 + 197 + /* Set command valid bit */ 198 + ctl1 = 0x80000000 | command; 199 + 200 + /* Set RD or WR bits as appropriate */ 201 + if (command == NAND_CMD_READID || command == NAND_CMD_STATUS) { 202 + ctl1 |= (1<<26); /* rd */ 203 + /* Always 5 bytes, for now */ 204 + cafe->datalen = 4; 205 + /* And one address cycle -- even for STATUS, since the controller doesn't work without */ 206 + adrbytes = 1; 207 + } else if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 || 208 + command == NAND_CMD_READOOB || command == NAND_CMD_RNDOUT) { 209 + ctl1 |= 1<<26; /* rd */ 210 + /* For now, assume just read to end of page */ 211 + cafe->datalen = mtd->writesize + mtd->oobsize - column; 212 + } else if (command == NAND_CMD_SEQIN) 213 + ctl1 |= 1<<25; /* wr */ 214 + 215 + /* Set number of address bytes */ 216 + if (adrbytes) 217 + ctl1 |= ((adrbytes-1)|8) << 27; 218 + 219 + if (command == NAND_CMD_SEQIN || command == NAND_CMD_ERASE1) { 220 + /* Ignore the first command of a pair; the hardware 221 + deals with them both at once, later */ 222 + cafe->ctl1 = ctl1; 223 + cafe_dev_dbg(&cafe->pdev->dev, "Setup for delayed command, ctl1 %08x, dlen %x\n", 224 + cafe->ctl1, cafe->datalen); 225 + return; 226 + } 227 + /* RNDOUT and READ0 commands need a following byte */ 228 + if (command == NAND_CMD_RNDOUT) 229 + cafe_writel(cafe, cafe->ctl2 | 0x100 | NAND_CMD_RNDOUTSTART, NAND_CTRL2); 230 + else if (command == NAND_CMD_READ0 && mtd->writesize > 512) 231 + cafe_writel(cafe, cafe->ctl2 | 0x100 | NAND_CMD_READSTART, NAND_CTRL2); 232 + 233 + do_command: 234 + cafe_dev_dbg(&cafe->pdev->dev, "dlen %x, ctl1 %x, ctl2 %x\n", 235 + cafe->datalen, ctl1, cafe_readl(cafe, NAND_CTRL2)); 236 + 237 + /* NB: The datasheet lies -- we really should be subtracting 1 here */ 238 + cafe_writel(cafe, cafe->datalen, NAND_DATA_LEN); 239 + cafe_writel(cafe, 0x90000000, NAND_IRQ); 240 + if (usedma && (ctl1 & (3<<25))) { 241 + uint32_t dmactl = 0xc0000000 + cafe->datalen; 242 + /* If WR or RD bits set, set up DMA */ 243 + if (ctl1 & (1<<26)) { 244 + /* It's a read */ 245 + dmactl |= (1<<29); 246 + /* ... so it's done when the DMA is done, not just 247 + the command. */ 248 + doneint = 0x10000000; 249 + } 250 + cafe_writel(cafe, dmactl, NAND_DMA_CTRL); 251 + } 252 + cafe->datalen = 0; 253 + 254 + if (unlikely(regdebug)) { 255 + int i; 256 + printk("About to write command %08x to register 0\n", ctl1); 257 + for (i=4; i< 0x5c; i+=4) 258 + printk("Register %x: %08x\n", i, readl(cafe->mmio + i)); 259 + } 260 + 261 + cafe_writel(cafe, ctl1, NAND_CTRL1); 262 + /* Apply this short delay always to ensure that we do wait tWB in 263 + * any case on any machine. */ 264 + ndelay(100); 265 + 266 + if (1) { 267 + int c = 500000; 268 + uint32_t irqs; 269 + 270 + while (c--) { 271 + irqs = cafe_readl(cafe, NAND_IRQ); 272 + if (irqs & doneint) 273 + break; 274 + udelay(1); 275 + if (!(c % 100000)) 276 + cafe_dev_dbg(&cafe->pdev->dev, "Wait for ready, IRQ %x\n", irqs); 277 + cpu_relax(); 278 + } 279 + cafe_writel(cafe, doneint, NAND_IRQ); 280 + cafe_dev_dbg(&cafe->pdev->dev, "Command %x completed after %d usec, irqs %x (%x)\n", 281 + command, 500000-c, irqs, cafe_readl(cafe, NAND_IRQ)); 282 + } 283 + 284 + WARN_ON(cafe->ctl2 & (1<<30)); 285 + 286 + switch (command) { 287 + 288 + case NAND_CMD_CACHEDPROG: 289 + case NAND_CMD_PAGEPROG: 290 + case NAND_CMD_ERASE1: 291 + case NAND_CMD_ERASE2: 292 + case NAND_CMD_SEQIN: 293 + case NAND_CMD_RNDIN: 294 + case NAND_CMD_STATUS: 295 + case NAND_CMD_DEPLETE1: 296 + case NAND_CMD_RNDOUT: 297 + case NAND_CMD_STATUS_ERROR: 298 + case NAND_CMD_STATUS_ERROR0: 299 + case NAND_CMD_STATUS_ERROR1: 300 + case NAND_CMD_STATUS_ERROR2: 301 + case NAND_CMD_STATUS_ERROR3: 302 + cafe_writel(cafe, cafe->ctl2, NAND_CTRL2); 303 + return; 304 + } 305 + nand_wait_ready(mtd); 306 + cafe_writel(cafe, cafe->ctl2, NAND_CTRL2); 307 + } 308 + 309 + static void cafe_select_chip(struct mtd_info *mtd, int chipnr) 310 + { 311 + //struct cafe_priv *cafe = mtd->priv; 312 + // cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr); 313 + } 314 + 315 + static int cafe_nand_interrupt(int irq, void *id, struct pt_regs *regs) 316 + { 317 + struct mtd_info *mtd = id; 318 + struct cafe_priv *cafe = mtd->priv; 319 + uint32_t irqs = cafe_readl(cafe, NAND_IRQ); 320 + cafe_writel(cafe, irqs & ~0x90000000, NAND_IRQ); 321 + if (!irqs) 322 + return IRQ_NONE; 323 + 324 + cafe_dev_dbg(&cafe->pdev->dev, "irq, bits %x (%x)\n", irqs, cafe_readl(cafe, NAND_IRQ)); 325 + return IRQ_HANDLED; 326 + } 327 + 328 + static void cafe_nand_bug(struct mtd_info *mtd) 329 + { 330 + BUG(); 331 + } 332 + 333 + static int cafe_nand_write_oob(struct mtd_info *mtd, 334 + struct nand_chip *chip, int page) 335 + { 336 + int status = 0; 337 + 338 + chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page); 339 + chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); 340 + chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); 341 + status = chip->waitfunc(mtd, chip); 342 + 343 + return status & NAND_STATUS_FAIL ? -EIO : 0; 344 + } 345 + 346 + /* Don't use -- use nand_read_oob_std for now */ 347 + static int cafe_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, 348 + int page, int sndcmd) 349 + { 350 + chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); 351 + chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); 352 + return 1; 353 + } 354 + /** 355 + * cafe_nand_read_page_syndrome - {REPLACABLE] hardware ecc syndrom based page read 356 + * @mtd: mtd info structure 357 + * @chip: nand chip info structure 358 + * @buf: buffer to store read data 359 + * 360 + * The hw generator calculates the error syndrome automatically. Therefor 361 + * we need a special oob layout and handling. 362 + */ 363 + static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, 364 + uint8_t *buf) 365 + { 366 + struct cafe_priv *cafe = mtd->priv; 367 + 368 + cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n", 369 + cafe_readl(cafe, NAND_ECC_RESULT), 370 + cafe_readl(cafe, NAND_ECC_SYN01)); 371 + 372 + chip->read_buf(mtd, buf, mtd->writesize); 373 + chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); 374 + 375 + if (checkecc && cafe_readl(cafe, NAND_ECC_RESULT) & (1<<18)) { 376 + unsigned short syn[8]; 377 + int i; 378 + 379 + for (i=0; i<8; i+=2) { 380 + uint32_t tmp = cafe_readl(cafe, NAND_ECC_SYN01 + (i*2)); 381 + syn[i] = tmp & 0xfff; 382 + syn[i+1] = (tmp >> 16) & 0xfff; 383 + } 384 + 385 + if ((i = cafe_correct_ecc(buf, syn)) < 0) { 386 + dev_dbg(&cafe->pdev->dev, "Failed to correct ECC at %08x\n", 387 + cafe_readl(cafe, NAND_ADDR2) * 2048); 388 + for (i=0; i< 0x5c; i+=4) 389 + printk("Register %x: %08x\n", i, readl(cafe->mmio + i)); 390 + mtd->ecc_stats.failed++; 391 + } else { 392 + dev_dbg(&cafe->pdev->dev, "Corrected %d symbol errors\n", i); 393 + mtd->ecc_stats.corrected += i; 394 + } 395 + } 396 + 397 + 398 + return 0; 399 + } 400 + 401 + static struct nand_ecclayout cafe_oobinfo_2048 = { 402 + .eccbytes = 14, 403 + .eccpos = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 404 + .oobfree = {{14, 50}} 405 + }; 406 + 407 + /* Ick. The BBT code really ought to be able to work this bit out 408 + for itself from the above, at least for the 2KiB case */ 409 + static uint8_t cafe_bbt_pattern_2048[] = { 'B', 'b', 't', '0' }; 410 + static uint8_t cafe_mirror_pattern_2048[] = { '1', 't', 'b', 'B' }; 411 + 412 + static uint8_t cafe_bbt_pattern_512[] = { 0xBB }; 413 + static uint8_t cafe_mirror_pattern_512[] = { 0xBC }; 414 + 415 + 416 + static struct nand_bbt_descr cafe_bbt_main_descr_2048 = { 417 + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 418 + | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 419 + .offs = 14, 420 + .len = 4, 421 + .veroffs = 18, 422 + .maxblocks = 4, 423 + .pattern = cafe_bbt_pattern_2048 424 + }; 425 + 426 + static struct nand_bbt_descr cafe_bbt_mirror_descr_2048 = { 427 + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 428 + | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 429 + .offs = 14, 430 + .len = 4, 431 + .veroffs = 18, 432 + .maxblocks = 4, 433 + .pattern = cafe_mirror_pattern_2048 434 + }; 435 + 436 + static struct nand_ecclayout cafe_oobinfo_512 = { 437 + .eccbytes = 14, 438 + .eccpos = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 439 + .oobfree = {{14, 2}} 440 + }; 441 + 442 + static struct nand_bbt_descr cafe_bbt_main_descr_512 = { 443 + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 444 + | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 445 + .offs = 14, 446 + .len = 1, 447 + .veroffs = 15, 448 + .maxblocks = 4, 449 + .pattern = cafe_bbt_pattern_512 450 + }; 451 + 452 + static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = { 453 + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 454 + | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 455 + .offs = 14, 456 + .len = 1, 457 + .veroffs = 15, 458 + .maxblocks = 4, 459 + .pattern = cafe_mirror_pattern_512 460 + }; 461 + 462 + 463 + static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd, 464 + struct nand_chip *chip, const uint8_t *buf) 465 + { 466 + struct cafe_priv *cafe = mtd->priv; 467 + 468 + chip->write_buf(mtd, buf, mtd->writesize); 469 + chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); 470 + 471 + /* Set up ECC autogeneration */ 472 + cafe->ctl2 |= (1<<30); 473 + } 474 + 475 + static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, 476 + const uint8_t *buf, int page, int cached, int raw) 477 + { 478 + int status; 479 + 480 + chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); 481 + 482 + if (unlikely(raw)) 483 + chip->ecc.write_page_raw(mtd, chip, buf); 484 + else 485 + chip->ecc.write_page(mtd, chip, buf); 486 + 487 + /* 488 + * Cached progamming disabled for now, Not sure if its worth the 489 + * trouble. The speed gain is not very impressive. (2.3->2.6Mib/s) 490 + */ 491 + cached = 0; 492 + 493 + if (!cached || !(chip->options & NAND_CACHEPRG)) { 494 + 495 + chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); 496 + status = chip->waitfunc(mtd, chip); 497 + /* 498 + * See if operation failed and additional status checks are 499 + * available 500 + */ 501 + if ((status & NAND_STATUS_FAIL) && (chip->errstat)) 502 + status = chip->errstat(mtd, chip, FL_WRITING, status, 503 + page); 504 + 505 + if (status & NAND_STATUS_FAIL) 506 + return -EIO; 507 + } else { 508 + chip->cmdfunc(mtd, NAND_CMD_CACHEDPROG, -1, -1); 509 + status = chip->waitfunc(mtd, chip); 510 + } 511 + 512 + #ifdef CONFIG_MTD_NAND_VERIFY_WRITE 513 + /* Send command to read back the data */ 514 + chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); 515 + 516 + if (chip->verify_buf(mtd, buf, mtd->writesize)) 517 + return -EIO; 518 + #endif 519 + return 0; 520 + } 521 + 522 + static int cafe_nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) 523 + { 524 + return 0; 525 + } 526 + 527 + static int __devinit cafe_nand_probe(struct pci_dev *pdev, 528 + const struct pci_device_id *ent) 529 + { 530 + struct mtd_info *mtd; 531 + struct cafe_priv *cafe; 532 + uint32_t ctrl; 533 + int err = 0; 534 + 535 + err = pci_enable_device(pdev); 536 + if (err) 537 + return err; 538 + 539 + pci_set_master(pdev); 540 + 541 + mtd = kzalloc(sizeof(*mtd) + sizeof(struct cafe_priv), GFP_KERNEL); 542 + if (!mtd) { 543 + dev_warn(&pdev->dev, "failed to alloc mtd_info\n"); 544 + return -ENOMEM; 545 + } 546 + cafe = (void *)(&mtd[1]); 547 + 548 + mtd->priv = cafe; 549 + mtd->owner = THIS_MODULE; 550 + 551 + cafe->pdev = pdev; 552 + cafe->mmio = pci_iomap(pdev, 0, 0); 553 + if (!cafe->mmio) { 554 + dev_warn(&pdev->dev, "failed to iomap\n"); 555 + err = -ENOMEM; 556 + goto out_free_mtd; 557 + } 558 + cafe->dmabuf = dma_alloc_coherent(&cafe->pdev->dev, 2112 + sizeof(struct nand_buffers), 559 + &cafe->dmaaddr, GFP_KERNEL); 560 + if (!cafe->dmabuf) { 561 + err = -ENOMEM; 562 + goto out_ior; 563 + } 564 + cafe->nand.buffers = (void *)cafe->dmabuf + 2112; 565 + 566 + cafe->nand.cmdfunc = cafe_nand_cmdfunc; 567 + cafe->nand.dev_ready = cafe_device_ready; 568 + cafe->nand.read_byte = cafe_read_byte; 569 + cafe->nand.read_buf = cafe_read_buf; 570 + cafe->nand.write_buf = cafe_write_buf; 571 + cafe->nand.select_chip = cafe_select_chip; 572 + 573 + cafe->nand.chip_delay = 0; 574 + 575 + /* Enable the following for a flash based bad block table */ 576 + cafe->nand.options = NAND_USE_FLASH_BBT | NAND_NO_AUTOINCR | NAND_OWN_BUFFERS; 577 + 578 + if (skipbbt) { 579 + cafe->nand.options |= NAND_SKIP_BBTSCAN; 580 + cafe->nand.block_bad = cafe_nand_block_bad; 581 + } 582 + 583 + /* Start off by resetting the NAND controller completely */ 584 + cafe_writel(cafe, 1, NAND_RESET); 585 + cafe_writel(cafe, 0, NAND_RESET); 586 + 587 + cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK); 588 + 589 + /* Timings from Marvell's test code (not verified or calculated by us) */ 590 + if (!slowtiming) { 591 + cafe_writel(cafe, 0x01010a0a, NAND_TIMING1); 592 + cafe_writel(cafe, 0x24121212, NAND_TIMING2); 593 + cafe_writel(cafe, 0x11000000, NAND_TIMING3); 594 + } else { 595 + cafe_writel(cafe, 0xffffffff, NAND_TIMING1); 596 + cafe_writel(cafe, 0xffffffff, NAND_TIMING2); 597 + cafe_writel(cafe, 0xffffffff, NAND_TIMING3); 598 + } 599 + cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK); 600 + err = request_irq(pdev->irq, &cafe_nand_interrupt, SA_SHIRQ, "CAFE NAND", mtd); 601 + if (err) { 602 + dev_warn(&pdev->dev, "Could not register IRQ %d\n", pdev->irq); 603 + 604 + goto out_free_dma; 605 + } 606 + #if 1 607 + /* Disable master reset, enable NAND clock */ 608 + ctrl = cafe_readl(cafe, GLOBAL_CTRL); 609 + ctrl &= 0xffffeff0; 610 + ctrl |= 0x00007000; 611 + cafe_writel(cafe, ctrl | 0x05, GLOBAL_CTRL); 612 + cafe_writel(cafe, ctrl | 0x0a, GLOBAL_CTRL); 613 + cafe_writel(cafe, 0, NAND_DMA_CTRL); 614 + 615 + cafe_writel(cafe, 0x7006, GLOBAL_CTRL); 616 + cafe_writel(cafe, 0x700a, GLOBAL_CTRL); 617 + 618 + /* Set up DMA address */ 619 + cafe_writel(cafe, cafe->dmaaddr & 0xffffffff, NAND_DMA_ADDR0); 620 + if (sizeof(cafe->dmaaddr) > 4) 621 + /* Shift in two parts to shut the compiler up */ 622 + cafe_writel(cafe, (cafe->dmaaddr >> 16) >> 16, NAND_DMA_ADDR1); 623 + else 624 + cafe_writel(cafe, 0, NAND_DMA_ADDR1); 625 + 626 + cafe_dev_dbg(&cafe->pdev->dev, "Set DMA address to %x (virt %p)\n", 627 + cafe_readl(cafe, NAND_DMA_ADDR0), cafe->dmabuf); 628 + 629 + /* Enable NAND IRQ in global IRQ mask register */ 630 + cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK); 631 + cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n", 632 + cafe_readl(cafe, GLOBAL_CTRL), cafe_readl(cafe, GLOBAL_IRQ_MASK)); 633 + #endif 634 + #if 1 635 + mtd->writesize=2048; 636 + mtd->oobsize = 0x40; 637 + memset(cafe->dmabuf, 0x5a, 2112); 638 + cafe->nand.cmdfunc(mtd, NAND_CMD_READID, 0, -1); 639 + cafe->nand.read_byte(mtd); 640 + cafe->nand.read_byte(mtd); 641 + cafe->nand.read_byte(mtd); 642 + cafe->nand.read_byte(mtd); 643 + cafe->nand.read_byte(mtd); 644 + #endif 645 + #if 0 646 + cafe->nand.cmdfunc(mtd, NAND_CMD_READ0, 0, 0); 647 + // nand_wait_ready(mtd); 648 + cafe->nand.read_byte(mtd); 649 + cafe->nand.read_byte(mtd); 650 + cafe->nand.read_byte(mtd); 651 + cafe->nand.read_byte(mtd); 652 + #endif 653 + #if 0 654 + writel(0x84600070, cafe->mmio); 655 + udelay(10); 656 + cafe_dev_dbg(&cafe->pdev->dev, "Status %x\n", cafe_readl(cafe, NAND_NONMEM)); 657 + #endif 658 + /* Scan to find existance of the device */ 659 + if (nand_scan_ident(mtd, 1)) { 660 + err = -ENXIO; 661 + goto out_irq; 662 + } 663 + 664 + cafe->ctl2 = 1<<27; /* Reed-Solomon ECC */ 665 + if (mtd->writesize == 2048) 666 + cafe->ctl2 |= 1<<29; /* 2KiB page size */ 667 + 668 + /* Set up ECC according to the type of chip we found */ 669 + if (mtd->writesize == 2048) { 670 + cafe->nand.ecc.layout = &cafe_oobinfo_2048; 671 + cafe->nand.bbt_td = &cafe_bbt_main_descr_2048; 672 + cafe->nand.bbt_md = &cafe_bbt_mirror_descr_2048; 673 + } else if (mtd->writesize == 512) { 674 + cafe->nand.ecc.layout = &cafe_oobinfo_512; 675 + cafe->nand.bbt_td = &cafe_bbt_main_descr_512; 676 + cafe->nand.bbt_md = &cafe_bbt_mirror_descr_512; 677 + } else { 678 + printk(KERN_WARNING "Unexpected NAND flash writesize %d. Aborting\n", 679 + mtd->writesize); 680 + goto out_irq; 681 + } 682 + cafe->nand.ecc.mode = NAND_ECC_HW_SYNDROME; 683 + cafe->nand.ecc.size = mtd->writesize; 684 + cafe->nand.ecc.bytes = 14; 685 + cafe->nand.ecc.hwctl = (void *)cafe_nand_bug; 686 + cafe->nand.ecc.calculate = (void *)cafe_nand_bug; 687 + cafe->nand.ecc.correct = (void *)cafe_nand_bug; 688 + cafe->nand.write_page = cafe_nand_write_page; 689 + cafe->nand.ecc.write_page = cafe_nand_write_page_lowlevel; 690 + cafe->nand.ecc.write_oob = cafe_nand_write_oob; 691 + cafe->nand.ecc.read_page = cafe_nand_read_page; 692 + cafe->nand.ecc.read_oob = cafe_nand_read_oob; 693 + 694 + err = nand_scan_tail(mtd); 695 + if (err) 696 + goto out_irq; 697 + 698 + pci_set_drvdata(pdev, mtd); 699 + add_mtd_device(mtd); 700 + goto out; 701 + 702 + out_irq: 703 + /* Disable NAND IRQ in global IRQ mask register */ 704 + cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK); 705 + free_irq(pdev->irq, mtd); 706 + out_free_dma: 707 + dma_free_coherent(&cafe->pdev->dev, 2112, cafe->dmabuf, cafe->dmaaddr); 708 + out_ior: 709 + pci_iounmap(pdev, cafe->mmio); 710 + out_free_mtd: 711 + kfree(mtd); 712 + out: 713 + return err; 714 + } 715 + 716 + static void __devexit cafe_nand_remove(struct pci_dev *pdev) 717 + { 718 + struct mtd_info *mtd = pci_get_drvdata(pdev); 719 + struct cafe_priv *cafe = mtd->priv; 720 + 721 + del_mtd_device(mtd); 722 + /* Disable NAND IRQ in global IRQ mask register */ 723 + cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK); 724 + free_irq(pdev->irq, mtd); 725 + nand_release(mtd); 726 + pci_iounmap(pdev, cafe->mmio); 727 + dma_free_coherent(&cafe->pdev->dev, 2112, cafe->dmabuf, cafe->dmaaddr); 728 + kfree(mtd); 729 + } 730 + 731 + static struct pci_device_id cafe_nand_tbl[] = { 732 + { 0x11ab, 0x4100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MEMORY_FLASH << 8, 0xFFFF0 } 733 + }; 734 + 735 + MODULE_DEVICE_TABLE(pci, cafe_nand_tbl); 736 + 737 + static struct pci_driver cafe_nand_pci_driver = { 738 + .name = "CAFÉ NAND", 739 + .id_table = cafe_nand_tbl, 740 + .probe = cafe_nand_probe, 741 + .remove = __devexit_p(cafe_nand_remove), 742 + #ifdef CONFIG_PMx 743 + .suspend = cafe_nand_suspend, 744 + .resume = cafe_nand_resume, 745 + #endif 746 + }; 747 + 748 + static int cafe_nand_init(void) 749 + { 750 + return pci_register_driver(&cafe_nand_pci_driver); 751 + } 752 + 753 + static void cafe_nand_exit(void) 754 + { 755 + pci_unregister_driver(&cafe_nand_pci_driver); 756 + } 757 + module_init(cafe_nand_init); 758 + module_exit(cafe_nand_exit); 759 + 760 + MODULE_LICENSE("GPL"); 761 + MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 762 + MODULE_DESCRIPTION("NAND flash driver for OLPC CAFE chip"); 763 + 764 + /* Correct ECC for 2048 bytes of 0xff: 765 + 41 a0 71 65 54 27 f3 93 ec a9 be ed 0b a1 */ 766 + 767 + /* dwmw2's B-test board, in case of completely screwing it: 768 + Bad eraseblock 2394 at 0x12b40000 769 + Bad eraseblock 2627 at 0x14860000 770 + Bad eraseblock 3349 at 0x1a2a0000 771 + */
+1381
drivers/mtd/nand/cafe_ecc.c
··· 1 + /* Error correction for CAFÉ NAND controller 2 + * 3 + * © 2006 Marvell, Inc. 4 + * Author: Tom Chiou 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms of the GNU General Public License as published by the Free 8 + * Software Foundation; either version 2 of the License, or (at your option) 9 + * any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program; if not, write to the Free Software Foundation, Inc., 59 18 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 + */ 20 + 21 + #include <linux/kernel.h> 22 + #include <linux/module.h> 23 + #include <linux/errno.h> 24 + 25 + static unsigned short gf4096_mul(unsigned short, unsigned short); 26 + static unsigned short gf64_mul(unsigned short, unsigned short); 27 + static unsigned short gf4096_inv(unsigned short); 28 + static unsigned short err_pos(unsigned short); 29 + static void find_4bit_err_coefs(unsigned short, unsigned short, unsigned short, 30 + unsigned short, unsigned short, unsigned short, 31 + unsigned short, unsigned short, unsigned short *); 32 + static void zero_4x5_col3(unsigned short[4][5]); 33 + static void zero_4x5_col2(unsigned short[4][5]); 34 + static void zero_4x5_col1(unsigned short[4][5]); 35 + static void swap_4x5_rows(unsigned short[4][5], int, int, int); 36 + static void swap_2x3_rows(unsigned short m[2][3]); 37 + static void solve_4x5(unsigned short m[4][5], unsigned short *, int *); 38 + static void sort_coefs(int *, unsigned short *, int); 39 + static void find_4bit_err_pats(unsigned short, unsigned short, unsigned short, 40 + unsigned short, unsigned short, unsigned short, 41 + unsigned short, unsigned short, unsigned short *); 42 + static void find_3bit_err_coefs(unsigned short, unsigned short, unsigned short, 43 + unsigned short, unsigned short, unsigned short, 44 + unsigned short *); 45 + static void zero_3x4_col2(unsigned short[3][4]); 46 + static void zero_3x4_col1(unsigned short[3][4]); 47 + static void swap_3x4_rows(unsigned short[3][4], int, int, int); 48 + static void solve_3x4(unsigned short[3][4], unsigned short *, int *); 49 + static void find_3bit_err_pats(unsigned short, unsigned short, unsigned short, 50 + unsigned short, unsigned short, unsigned short, 51 + unsigned short *); 52 + 53 + static void find_2bit_err_pats(unsigned short, unsigned short, unsigned short, 54 + unsigned short, unsigned short *); 55 + static void find_2x2_soln(unsigned short, unsigned short, unsigned short, 56 + unsigned short, unsigned short, unsigned short, 57 + unsigned short *); 58 + static void solve_2x3(unsigned short[2][3], unsigned short *); 59 + static int chk_no_err_only(unsigned short *, unsigned short *); 60 + static int chk_1_err_only(unsigned short *, unsigned short *); 61 + static int chk_2_err_only(unsigned short *, unsigned short *); 62 + static int chk_3_err_only(unsigned short *, unsigned short *); 63 + static int chk_4_err_only(unsigned short *, unsigned short *); 64 + 65 + static unsigned short gf64_mul(unsigned short a, unsigned short b) 66 + { 67 + unsigned short tmp1, tmp2, tmp3, tmp4, tmp5; 68 + unsigned short c_bit0, c_bit1, c_bit2, c_bit3, c_bit4, c_bit5, c; 69 + 70 + tmp1 = ((a) ^ (a >> 5)); 71 + tmp2 = ((a >> 4) ^ (a >> 5)); 72 + tmp3 = ((a >> 3) ^ (a >> 4)); 73 + tmp4 = ((a >> 2) ^ (a >> 3)); 74 + tmp5 = ((a >> 1) ^ (a >> 2)); 75 + 76 + c_bit0 = ((a & b) ^ ((a >> 5) & (b >> 1)) ^ ((a >> 4) & (b >> 2)) ^ 77 + ((a >> 3) & (b >> 3)) ^ ((a >> 2) & (b >> 4)) ^ ((a >> 1) & (b >> 5))) & 0x1; 78 + 79 + c_bit1 = (((a >> 1) & b) ^ (tmp1 & (b >> 1)) ^ (tmp2 & (b >> 2)) ^ 80 + (tmp3 & (b >> 3)) ^ (tmp4 & (b >> 4)) ^ (tmp5 & (b >> 5))) & 0x1; 81 + 82 + c_bit2 = (((a >> 2) & b) ^ ((a >> 1) & (b >> 1)) ^ (tmp1 & (b >> 2)) ^ 83 + (tmp2 & (b >> 3)) ^ (tmp3 & (b >> 4)) ^ (tmp4 & (b >> 5))) & 0x1; 84 + 85 + c_bit3 = (((a >> 3) & b) ^ ((a >> 2) & (b >> 1)) ^ ((a >> 1) & (b >> 2)) ^ 86 + (tmp1 & (b >> 3)) ^ (tmp2 & (b >> 4)) ^ (tmp3 & (b >> 5))) & 0x1; 87 + 88 + c_bit4 = (((a >> 4) & b) ^ ((a >> 3) & (b >> 1)) ^ ((a >> 2) & (b >> 2)) ^ 89 + ((a >> 1) & (b >> 3)) ^ (tmp1 & (b >> 4)) ^ (tmp2 & (b >> 5))) & 0x1; 90 + 91 + c_bit5 = (((a >> 5) & b) ^ ((a >> 4) & (b >> 1)) ^ ((a >> 3) & (b >> 2)) ^ 92 + ((a >> 2) & (b >> 3)) ^ ((a >> 1) & (b >> 4)) ^ (tmp1 & (b >> 5))) & 0x1; 93 + 94 + c = c_bit0 | (c_bit1 << 1) | (c_bit2 << 2) | (c_bit3 << 3) | (c_bit4 << 4) | (c_bit5 << 5); 95 + 96 + return c; 97 + } 98 + 99 + static unsigned short gf4096_mul(unsigned short a, unsigned short b) 100 + { 101 + unsigned short ah, al, bh, bl, alxah, blxbh, ablh, albl, ahbh, ahbhB, c; 102 + 103 + ah = (a >> 6) & 0x3f; 104 + al = a & 0x3f; 105 + bh = (b >> 6) & 0x3f; 106 + bl = b & 0x3f; 107 + alxah = al ^ ah; 108 + blxbh = bl ^ bh; 109 + 110 + ablh = gf64_mul(alxah, blxbh); 111 + albl = gf64_mul(al, bl); 112 + ahbh = gf64_mul(ah, bh); 113 + 114 + ahbhB = ((ahbh & 0x1) << 5) | 115 + ((ahbh & 0x20) >> 1) | 116 + ((ahbh & 0x10) >> 1) | ((ahbh & 0x8) >> 1) | ((ahbh & 0x4) >> 1) | (((ahbh >> 1) ^ ahbh) & 0x1); 117 + 118 + c = ((ablh ^ albl) << 6) | (ahbhB ^ albl); 119 + return c; 120 + } 121 + 122 + static void find_2bit_err_pats(unsigned short s0, unsigned short s1, unsigned short r0, unsigned short r1, unsigned short *pats) 123 + { 124 + find_2x2_soln(0x1, 0x1, r0, r1, s0, s1, pats); 125 + } 126 + 127 + static void find_3bit_err_coefs(unsigned short s0, unsigned short s1, 128 + unsigned short s2, unsigned short s3, unsigned short s4, unsigned short s5, unsigned short *coefs) 129 + { 130 + unsigned short m[3][4]; 131 + int row_order[3]; 132 + 133 + row_order[0] = 0; 134 + row_order[1] = 1; 135 + row_order[2] = 2; 136 + m[0][0] = s2; 137 + m[0][1] = s1; 138 + m[0][2] = s0; 139 + m[0][3] = s3; 140 + m[1][0] = s3; 141 + m[1][1] = s2; 142 + m[1][2] = s1; 143 + m[1][3] = s4; 144 + m[2][0] = s4; 145 + m[2][1] = s3; 146 + m[2][2] = s2; 147 + m[2][3] = s5; 148 + 149 + if (m[0][2] != 0x0) { 150 + zero_3x4_col2(m); 151 + } else if (m[1][2] != 0x0) { 152 + swap_3x4_rows(m, 0, 1, 4); 153 + zero_3x4_col2(m); 154 + } else if (m[2][2] != 0x0) { 155 + swap_3x4_rows(m, 0, 2, 4); 156 + zero_3x4_col2(m); 157 + } else { 158 + printk(KERN_ERR "Error: find_3bit_err_coefs, s0,s1,s2 all zeros!\n"); 159 + } 160 + 161 + if (m[1][1] != 0x0) { 162 + zero_3x4_col1(m); 163 + } else if (m[2][1] != 0x0) { 164 + swap_3x4_rows(m, 1, 2, 4); 165 + zero_3x4_col1(m); 166 + } else { 167 + printk(KERN_ERR "Error: find_3bit_err_coefs, cannot resolve col 1!\n"); 168 + } 169 + 170 + /* solve coefs */ 171 + solve_3x4(m, coefs, row_order); 172 + } 173 + 174 + static void zero_3x4_col2(unsigned short m[3][4]) 175 + { 176 + unsigned short minv1, minv2; 177 + 178 + minv1 = gf4096_mul(m[1][2], gf4096_inv(m[0][2])); 179 + minv2 = gf4096_mul(m[2][2], gf4096_inv(m[0][2])); 180 + m[1][0] = m[1][0] ^ gf4096_mul(m[0][0], minv1); 181 + m[1][1] = m[1][1] ^ gf4096_mul(m[0][1], minv1); 182 + m[1][3] = m[1][3] ^ gf4096_mul(m[0][3], minv1); 183 + m[2][0] = m[2][0] ^ gf4096_mul(m[0][0], minv2); 184 + m[2][1] = m[2][1] ^ gf4096_mul(m[0][1], minv2); 185 + m[2][3] = m[2][3] ^ gf4096_mul(m[0][3], minv2); 186 + } 187 + 188 + static void zero_3x4_col1(unsigned short m[3][4]) 189 + { 190 + unsigned short minv; 191 + minv = gf4096_mul(m[2][1], gf4096_inv(m[1][1])); 192 + m[2][0] = m[2][0] ^ gf4096_mul(m[1][0], minv); 193 + m[2][3] = m[2][3] ^ gf4096_mul(m[1][3], minv); 194 + } 195 + 196 + static void swap_3x4_rows(unsigned short m[3][4], int i, int j, int col_width) 197 + { 198 + unsigned short tmp0; 199 + int cnt; 200 + for (cnt = 0; cnt < col_width; cnt++) { 201 + tmp0 = m[i][cnt]; 202 + m[i][cnt] = m[j][cnt]; 203 + m[j][cnt] = tmp0; 204 + } 205 + } 206 + 207 + static void solve_3x4(unsigned short m[3][4], unsigned short *coefs, int *row_order) 208 + { 209 + unsigned short tmp[3]; 210 + tmp[0] = gf4096_mul(m[2][3], gf4096_inv(m[2][0])); 211 + tmp[1] = gf4096_mul((gf4096_mul(tmp[0], m[1][0]) ^ m[1][3]), gf4096_inv(m[1][1])); 212 + tmp[2] = gf4096_mul((gf4096_mul(tmp[0], m[0][0]) ^ gf4096_mul(tmp[1], m[0][1]) ^ m[0][3]), gf4096_inv(m[0][2])); 213 + sort_coefs(row_order, tmp, 3); 214 + coefs[0] = tmp[0]; 215 + coefs[1] = tmp[1]; 216 + coefs[2] = tmp[2]; 217 + } 218 + 219 + static void find_3bit_err_pats(unsigned short s0, unsigned short s1, 220 + unsigned short s2, unsigned short r0, 221 + unsigned short r1, unsigned short r2, 222 + unsigned short *pats) 223 + { 224 + find_2x2_soln(r0 ^ r2, r1 ^ r2, 225 + gf4096_mul(r0, r0 ^ r2), gf4096_mul(r1, r1 ^ r2), 226 + gf4096_mul(s0, r2) ^ s1, gf4096_mul(s1, r2) ^ s2, pats); 227 + pats[2] = s0 ^ pats[0] ^ pats[1]; 228 + } 229 + 230 + static void find_4bit_err_coefs(unsigned short s0, unsigned short s1, 231 + unsigned short s2, unsigned short s3, 232 + unsigned short s4, unsigned short s5, 233 + unsigned short s6, unsigned short s7, 234 + unsigned short *coefs) 235 + { 236 + unsigned short m[4][5]; 237 + int row_order[4]; 238 + 239 + row_order[0] = 0; 240 + row_order[1] = 1; 241 + row_order[2] = 2; 242 + row_order[3] = 3; 243 + 244 + m[0][0] = s3; 245 + m[0][1] = s2; 246 + m[0][2] = s1; 247 + m[0][3] = s0; 248 + m[0][4] = s4; 249 + m[1][0] = s4; 250 + m[1][1] = s3; 251 + m[1][2] = s2; 252 + m[1][3] = s1; 253 + m[1][4] = s5; 254 + m[2][0] = s5; 255 + m[2][1] = s4; 256 + m[2][2] = s3; 257 + m[2][3] = s2; 258 + m[2][4] = s6; 259 + m[3][0] = s6; 260 + m[3][1] = s5; 261 + m[3][2] = s4; 262 + m[3][3] = s3; 263 + m[3][4] = s7; 264 + 265 + if (m[0][3] != 0x0) { 266 + zero_4x5_col3(m); 267 + } else if (m[1][3] != 0x0) { 268 + swap_4x5_rows(m, 0, 1, 5); 269 + zero_4x5_col3(m); 270 + } else if (m[2][3] != 0x0) { 271 + swap_4x5_rows(m, 0, 2, 5); 272 + zero_4x5_col3(m); 273 + } else if (m[3][3] != 0x0) { 274 + swap_4x5_rows(m, 0, 3, 5); 275 + zero_4x5_col3(m); 276 + } else { 277 + printk(KERN_ERR "Error: find_4bit_err_coefs, s0,s1,s2,s3 all zeros!\n"); 278 + } 279 + 280 + if (m[1][2] != 0x0) { 281 + zero_4x5_col2(m); 282 + } else if (m[2][2] != 0x0) { 283 + swap_4x5_rows(m, 1, 2, 5); 284 + zero_4x5_col2(m); 285 + } else if (m[3][2] != 0x0) { 286 + swap_4x5_rows(m, 1, 3, 5); 287 + zero_4x5_col2(m); 288 + } else { 289 + printk(KERN_ERR "Error: find_4bit_err_coefs, cannot resolve col 2!\n"); 290 + } 291 + 292 + if (m[2][1] != 0x0) { 293 + zero_4x5_col1(m); 294 + } else if (m[3][1] != 0x0) { 295 + swap_4x5_rows(m, 2, 3, 5); 296 + zero_4x5_col1(m); 297 + } else { 298 + printk(KERN_ERR "Error: find_4bit_err_coefs, cannot resolve col 1!\n"); 299 + } 300 + 301 + solve_4x5(m, coefs, row_order); 302 + } 303 + 304 + static void zero_4x5_col3(unsigned short m[4][5]) 305 + { 306 + unsigned short minv1, minv2, minv3; 307 + 308 + minv1 = gf4096_mul(m[1][3], gf4096_inv(m[0][3])); 309 + minv2 = gf4096_mul(m[2][3], gf4096_inv(m[0][3])); 310 + minv3 = gf4096_mul(m[3][3], gf4096_inv(m[0][3])); 311 + 312 + m[1][0] = m[1][0] ^ gf4096_mul(m[0][0], minv1); 313 + m[1][1] = m[1][1] ^ gf4096_mul(m[0][1], minv1); 314 + m[1][2] = m[1][2] ^ gf4096_mul(m[0][2], minv1); 315 + m[1][4] = m[1][4] ^ gf4096_mul(m[0][4], minv1); 316 + m[2][0] = m[2][0] ^ gf4096_mul(m[0][0], minv2); 317 + m[2][1] = m[2][1] ^ gf4096_mul(m[0][1], minv2); 318 + m[2][2] = m[2][2] ^ gf4096_mul(m[0][2], minv2); 319 + m[2][4] = m[2][4] ^ gf4096_mul(m[0][4], minv2); 320 + m[3][0] = m[3][0] ^ gf4096_mul(m[0][0], minv3); 321 + m[3][1] = m[3][1] ^ gf4096_mul(m[0][1], minv3); 322 + m[3][2] = m[3][2] ^ gf4096_mul(m[0][2], minv3); 323 + m[3][4] = m[3][4] ^ gf4096_mul(m[0][4], minv3); 324 + } 325 + 326 + static void zero_4x5_col2(unsigned short m[4][5]) 327 + { 328 + unsigned short minv2, minv3; 329 + 330 + minv2 = gf4096_mul(m[2][2], gf4096_inv(m[1][2])); 331 + minv3 = gf4096_mul(m[3][2], gf4096_inv(m[1][2])); 332 + 333 + m[2][0] = m[2][0] ^ gf4096_mul(m[1][0], minv2); 334 + m[2][1] = m[2][1] ^ gf4096_mul(m[1][1], minv2); 335 + m[2][4] = m[2][4] ^ gf4096_mul(m[1][4], minv2); 336 + m[3][0] = m[3][0] ^ gf4096_mul(m[1][0], minv3); 337 + m[3][1] = m[3][1] ^ gf4096_mul(m[1][1], minv3); 338 + m[3][4] = m[3][4] ^ gf4096_mul(m[1][4], minv3); 339 + } 340 + 341 + static void zero_4x5_col1(unsigned short m[4][5]) 342 + { 343 + unsigned short minv; 344 + 345 + minv = gf4096_mul(m[3][1], gf4096_inv(m[2][1])); 346 + 347 + m[3][0] = m[3][0] ^ gf4096_mul(m[2][0], minv); 348 + m[3][4] = m[3][4] ^ gf4096_mul(m[2][4], minv); 349 + } 350 + 351 + static void swap_4x5_rows(unsigned short m[4][5], int i, int j, int col_width) 352 + { 353 + unsigned short tmp0; 354 + int cnt; 355 + 356 + for (cnt = 0; cnt < col_width; cnt++) { 357 + tmp0 = m[i][cnt]; 358 + m[i][cnt] = m[j][cnt]; 359 + m[j][cnt] = tmp0; 360 + } 361 + } 362 + 363 + static void solve_4x5(unsigned short m[4][5], unsigned short *coefs, int *row_order) 364 + { 365 + unsigned short tmp[4]; 366 + 367 + tmp[0] = gf4096_mul(m[3][4], gf4096_inv(m[3][0])); 368 + tmp[1] = gf4096_mul((gf4096_mul(tmp[0], m[2][0]) ^ m[2][4]), gf4096_inv(m[2][1])); 369 + tmp[2] = gf4096_mul((gf4096_mul(tmp[0], m[1][0]) ^ gf4096_mul(tmp[1], m[1][1]) ^ m[1][4]), gf4096_inv(m[1][2])); 370 + tmp[3] = gf4096_mul((gf4096_mul(tmp[0], m[0][0]) ^ 371 + gf4096_mul(tmp[1], m[0][1]) ^ gf4096_mul(tmp[2], m[0][2]) ^ m[0][4]), gf4096_inv(m[0][3])); 372 + sort_coefs(row_order, tmp, 4); 373 + coefs[0] = tmp[0]; 374 + coefs[1] = tmp[1]; 375 + coefs[2] = tmp[2]; 376 + coefs[3] = tmp[3]; 377 + } 378 + 379 + static void sort_coefs(int *order, unsigned short *soln, int len) 380 + { 381 + int cnt, start_cnt, least_ord, least_cnt; 382 + unsigned short tmp0; 383 + for (start_cnt = 0; start_cnt < len; start_cnt++) { 384 + for (cnt = start_cnt; cnt < len; cnt++) { 385 + if (cnt == start_cnt) { 386 + least_ord = order[cnt]; 387 + least_cnt = start_cnt; 388 + } else { 389 + if (least_ord > order[cnt]) { 390 + least_ord = order[cnt]; 391 + least_cnt = cnt; 392 + } 393 + } 394 + } 395 + if (least_cnt != start_cnt) { 396 + tmp0 = order[least_cnt]; 397 + order[least_cnt] = order[start_cnt]; 398 + order[start_cnt] = tmp0; 399 + tmp0 = soln[least_cnt]; 400 + soln[least_cnt] = soln[start_cnt]; 401 + soln[start_cnt] = tmp0; 402 + } 403 + } 404 + } 405 + 406 + static void find_4bit_err_pats(unsigned short s0, unsigned short s1, 407 + unsigned short s2, unsigned short s3, 408 + unsigned short z1, unsigned short z2, 409 + unsigned short z3, unsigned short z4, 410 + unsigned short *pats) 411 + { 412 + unsigned short z4_z1, z3z4_z3z3, z4_z2, s0z4_s1, z1z4_z1z1, 413 + z4_z3, z2z4_z2z2, s1z4_s2, z3z3z4_z3z3z3, z1z1z4_z1z1z1, z2z2z4_z2z2z2, s2z4_s3; 414 + unsigned short tmp0, tmp1, tmp2, tmp3; 415 + 416 + z4_z1 = z4 ^ z1; 417 + z3z4_z3z3 = gf4096_mul(z3, z4) ^ gf4096_mul(z3, z3); 418 + z4_z2 = z4 ^ z2; 419 + s0z4_s1 = gf4096_mul(s0, z4) ^ s1; 420 + z1z4_z1z1 = gf4096_mul(z1, z4) ^ gf4096_mul(z1, z1); 421 + z4_z3 = z4 ^ z3; 422 + z2z4_z2z2 = gf4096_mul(z2, z4) ^ gf4096_mul(z2, z2); 423 + s1z4_s2 = gf4096_mul(s1, z4) ^ s2; 424 + z3z3z4_z3z3z3 = gf4096_mul(gf4096_mul(z3, z3), z4) ^ gf4096_mul(gf4096_mul(z3, z3), z3); 425 + z1z1z4_z1z1z1 = gf4096_mul(gf4096_mul(z1, z1), z4) ^ gf4096_mul(gf4096_mul(z1, z1), z1); 426 + z2z2z4_z2z2z2 = gf4096_mul(gf4096_mul(z2, z2), z4) ^ gf4096_mul(gf4096_mul(z2, z2), z2); 427 + s2z4_s3 = gf4096_mul(s2, z4) ^ s3; 428 + 429 + //find err pat 0,1 430 + find_2x2_soln(gf4096_mul(z4_z1, z3z4_z3z3) ^ 431 + gf4096_mul(z1z4_z1z1, z4_z3), gf4096_mul(z4_z2, 432 + z3z4_z3z3) ^ 433 + gf4096_mul(z2z4_z2z2, z4_z3), gf4096_mul(z1z4_z1z1, 434 + z3z3z4_z3z3z3) ^ 435 + gf4096_mul(z1z1z4_z1z1z1, z3z4_z3z3), 436 + gf4096_mul(z2z4_z2z2, 437 + z3z3z4_z3z3z3) ^ gf4096_mul(z2z2z4_z2z2z2, 438 + z3z4_z3z3), 439 + gf4096_mul(s0z4_s1, z3z4_z3z3) ^ gf4096_mul(s1z4_s2, 440 + z4_z3), 441 + gf4096_mul(s1z4_s2, z3z3z4_z3z3z3) ^ gf4096_mul(s2z4_s3, z3z4_z3z3), pats); 442 + tmp0 = pats[0]; 443 + tmp1 = pats[1]; 444 + tmp2 = pats[0] ^ pats[1] ^ s0; 445 + tmp3 = gf4096_mul(pats[0], z1) ^ gf4096_mul(pats[1], z2) ^ s1; 446 + 447 + //find err pat 2,3 448 + find_2x2_soln(0x1, 0x1, z3, z4, tmp2, tmp3, pats); 449 + pats[2] = pats[0]; 450 + pats[3] = pats[1]; 451 + pats[0] = tmp0; 452 + pats[1] = tmp1; 453 + } 454 + 455 + static void find_2x2_soln(unsigned short c00, unsigned short c01, 456 + unsigned short c10, unsigned short c11, 457 + unsigned short lval0, unsigned short lval1, 458 + unsigned short *soln) 459 + { 460 + unsigned short m[2][3]; 461 + m[0][0] = c00; 462 + m[0][1] = c01; 463 + m[0][2] = lval0; 464 + m[1][0] = c10; 465 + m[1][1] = c11; 466 + m[1][2] = lval1; 467 + 468 + if (m[0][1] != 0x0) { 469 + /* */ 470 + } else if (m[1][1] != 0x0) { 471 + swap_2x3_rows(m); 472 + } else { 473 + printk(KERN_ERR "Warning: find_2bit_err_coefs, s0,s1 all zeros!\n"); 474 + } 475 + 476 + solve_2x3(m, soln); 477 + } 478 + 479 + static void swap_2x3_rows(unsigned short m[2][3]) 480 + { 481 + unsigned short tmp0; 482 + int cnt; 483 + 484 + for (cnt = 0; cnt < 3; cnt++) { 485 + tmp0 = m[0][cnt]; 486 + m[0][cnt] = m[1][cnt]; 487 + m[1][cnt] = tmp0; 488 + } 489 + } 490 + 491 + static void solve_2x3(unsigned short m[2][3], unsigned short *coefs) 492 + { 493 + unsigned short minv; 494 + 495 + minv = gf4096_mul(m[1][1], gf4096_inv(m[0][1])); 496 + m[1][0] = m[1][0] ^ gf4096_mul(m[0][0], minv); 497 + m[1][2] = m[1][2] ^ gf4096_mul(m[0][2], minv); 498 + coefs[0] = gf4096_mul(m[1][2], gf4096_inv(m[1][0])); 499 + coefs[1] = gf4096_mul((gf4096_mul(coefs[0], m[0][0]) ^ m[0][2]), gf4096_inv(m[0][1])); 500 + } 501 + 502 + static unsigned char gf64_inv[64] = { 503 + 0, 1, 33, 62, 49, 43, 31, 44, 57, 37, 52, 28, 46, 40, 22, 25, 504 + 61, 54, 51, 39, 26, 35, 14, 24, 23, 15, 20, 34, 11, 53, 45, 6, 505 + 63, 2, 27, 21, 56, 9, 50, 19, 13, 47, 48, 5, 7, 30, 12, 41, 506 + 42, 4, 38, 18, 10, 29, 17, 60, 36, 8, 59, 58, 55, 16, 3, 32 507 + }; 508 + 509 + static unsigned short gf4096_inv(unsigned short din) 510 + { 511 + unsigned short alahxal, ah2B, deno, inv, bl, bh; 512 + unsigned short ah, al, ahxal; 513 + unsigned short dout; 514 + 515 + ah = (din >> 6) & 0x3f; 516 + al = din & 0x3f; 517 + ahxal = ah ^ al; 518 + ah2B = (((ah ^ (ah >> 3)) & 0x1) << 5) | 519 + ((ah >> 1) & 0x10) | 520 + ((((ah >> 5) ^ (ah >> 2)) & 0x1) << 3) | 521 + ((ah >> 2) & 0x4) | ((((ah >> 4) ^ (ah >> 1)) & 0x1) << 1) | (ah & 0x1); 522 + alahxal = gf64_mul(ahxal, al); 523 + deno = alahxal ^ ah2B; 524 + inv = gf64_inv[deno]; 525 + bl = gf64_mul(inv, ahxal); 526 + bh = gf64_mul(inv, ah); 527 + dout = ((bh & 0x3f) << 6) | (bl & 0x3f); 528 + return (((bh & 0x3f) << 6) | (bl & 0x3f)); 529 + } 530 + 531 + static unsigned short err_pos_lut[4096] = { 532 + 0xfff, 0x000, 0x451, 0xfff, 0xfff, 0x3cf, 0xfff, 0x041, 533 + 0xfff, 0xfff, 0xfff, 0xfff, 0x28a, 0xfff, 0x492, 0xfff, 534 + 0x145, 0xfff, 0xfff, 0x514, 0xfff, 0x082, 0xfff, 0xfff, 535 + 0xfff, 0x249, 0x38e, 0x410, 0xfff, 0x104, 0x208, 0x1c7, 536 + 0xfff, 0xfff, 0xfff, 0xfff, 0x2cb, 0xfff, 0xfff, 0xfff, 537 + 0x0c3, 0x34d, 0x4d3, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 538 + 0xfff, 0xfff, 0xfff, 0x186, 0xfff, 0xfff, 0xfff, 0xfff, 539 + 0xfff, 0x30c, 0x555, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 540 + 0xfff, 0xfff, 0xfff, 0x166, 0xfff, 0xfff, 0xfff, 0xfff, 541 + 0x385, 0x14e, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4e1, 542 + 0xfff, 0xfff, 0xfff, 0xfff, 0x538, 0xfff, 0x16d, 0xfff, 543 + 0xfff, 0xfff, 0x45b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 544 + 0xfff, 0xfff, 0xfff, 0x29c, 0x2cc, 0x30b, 0x2b3, 0xfff, 545 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x0b3, 0xfff, 0x2f7, 546 + 0xfff, 0x32b, 0xfff, 0xfff, 0xfff, 0xfff, 0x0a7, 0xfff, 547 + 0xfff, 0x2da, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 548 + 0xfff, 0x07e, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 549 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x11c, 0xfff, 0xfff, 550 + 0xfff, 0xfff, 0xfff, 0x22f, 0xfff, 0x1f4, 0xfff, 0xfff, 551 + 0x2b0, 0x504, 0xfff, 0x114, 0xfff, 0xfff, 0xfff, 0x21d, 552 + 0xfff, 0xfff, 0xfff, 0xfff, 0x00d, 0x3c4, 0x340, 0x10f, 553 + 0xfff, 0xfff, 0x266, 0x02e, 0xfff, 0xfff, 0xfff, 0x4f8, 554 + 0x337, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 555 + 0xfff, 0xfff, 0xfff, 0x07b, 0x168, 0xfff, 0xfff, 0x0fe, 556 + 0xfff, 0xfff, 0x51a, 0xfff, 0x458, 0xfff, 0x36d, 0xfff, 557 + 0xfff, 0xfff, 0xfff, 0x073, 0x37d, 0x415, 0x550, 0xfff, 558 + 0xfff, 0xfff, 0x23b, 0x4b4, 0xfff, 0xfff, 0xfff, 0x1a1, 559 + 0xfff, 0xfff, 0x3aa, 0xfff, 0x117, 0x04d, 0x341, 0xfff, 560 + 0xfff, 0xfff, 0xfff, 0x518, 0x03e, 0x0f2, 0xfff, 0xfff, 561 + 0xfff, 0xfff, 0xfff, 0x363, 0xfff, 0x0b9, 0xfff, 0xfff, 562 + 0x241, 0xfff, 0xfff, 0x049, 0xfff, 0xfff, 0xfff, 0xfff, 563 + 0x15f, 0x52d, 0xfff, 0xfff, 0xfff, 0x29e, 0xfff, 0xfff, 564 + 0xfff, 0xfff, 0x4cf, 0x0fc, 0xfff, 0x36f, 0x3d3, 0xfff, 565 + 0x228, 0xfff, 0xfff, 0x45e, 0xfff, 0xfff, 0xfff, 0xfff, 566 + 0x238, 0xfff, 0xfff, 0xfff, 0xfff, 0x47f, 0xfff, 0xfff, 567 + 0x43a, 0x265, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x3e8, 568 + 0xfff, 0xfff, 0x01a, 0xfff, 0xfff, 0xfff, 0xfff, 0x21e, 569 + 0x1fc, 0x40b, 0xfff, 0xfff, 0xfff, 0x2d0, 0x159, 0xfff, 570 + 0xfff, 0x313, 0xfff, 0xfff, 0x05c, 0x4cc, 0xfff, 0xfff, 571 + 0x0f6, 0x3d5, 0xfff, 0xfff, 0xfff, 0x54f, 0xfff, 0xfff, 572 + 0xfff, 0x172, 0x1e4, 0x07c, 0xfff, 0xfff, 0xfff, 0xfff, 573 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x53c, 0x1ad, 0x535, 574 + 0x19b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 575 + 0xfff, 0xfff, 0x092, 0xfff, 0x2be, 0xfff, 0xfff, 0x482, 576 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x0e6, 0xfff, 0xfff, 577 + 0xfff, 0xfff, 0xfff, 0x476, 0xfff, 0x51d, 0xfff, 0xfff, 578 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 579 + 0xfff, 0xfff, 0x342, 0x2b5, 0x22e, 0x09a, 0xfff, 0x08d, 580 + 0x44f, 0x3ed, 0xfff, 0xfff, 0xfff, 0xfff, 0x3d1, 0xfff, 581 + 0xfff, 0x543, 0xfff, 0x48f, 0xfff, 0x3d2, 0xfff, 0x0d5, 582 + 0x113, 0x0ec, 0x427, 0xfff, 0xfff, 0xfff, 0x4c4, 0xfff, 583 + 0xfff, 0x50a, 0xfff, 0x144, 0xfff, 0x105, 0x39f, 0x294, 584 + 0x164, 0xfff, 0x31a, 0xfff, 0xfff, 0x49a, 0xfff, 0x130, 585 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 586 + 0x1be, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 587 + 0xfff, 0xfff, 0x49e, 0x371, 0xfff, 0xfff, 0xfff, 0xfff, 588 + 0xfff, 0xfff, 0xfff, 0xfff, 0x0e8, 0x49c, 0x0f4, 0xfff, 589 + 0x338, 0x1a7, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 590 + 0xfff, 0x36c, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 591 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 592 + 0xfff, 0x1ae, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 593 + 0xfff, 0x31b, 0xfff, 0xfff, 0x2dd, 0x522, 0xfff, 0xfff, 594 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2f4, 595 + 0x3c6, 0x30d, 0xfff, 0xfff, 0xfff, 0xfff, 0x34c, 0x18f, 596 + 0x30a, 0xfff, 0x01f, 0x079, 0xfff, 0xfff, 0x54d, 0x46b, 597 + 0x28c, 0x37f, 0xfff, 0xfff, 0xfff, 0xfff, 0x355, 0xfff, 598 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x14f, 0xfff, 0xfff, 599 + 0xfff, 0xfff, 0xfff, 0x359, 0x3fe, 0x3c5, 0xfff, 0xfff, 600 + 0xfff, 0xfff, 0x423, 0xfff, 0xfff, 0x34a, 0x22c, 0xfff, 601 + 0x25a, 0xfff, 0xfff, 0x4ad, 0xfff, 0x28d, 0xfff, 0xfff, 602 + 0xfff, 0xfff, 0xfff, 0x547, 0xfff, 0xfff, 0xfff, 0xfff, 603 + 0x2e2, 0xfff, 0xfff, 0x1d5, 0xfff, 0x2a8, 0xfff, 0xfff, 604 + 0x03f, 0xfff, 0xfff, 0xfff, 0xfff, 0x3eb, 0x0fa, 0xfff, 605 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x55b, 0xfff, 606 + 0x08e, 0xfff, 0x3ae, 0xfff, 0x3a4, 0xfff, 0x282, 0x158, 607 + 0xfff, 0x382, 0xfff, 0xfff, 0x499, 0xfff, 0xfff, 0x08a, 608 + 0xfff, 0xfff, 0xfff, 0x456, 0x3be, 0xfff, 0x1e2, 0xfff, 609 + 0xfff, 0xfff, 0xfff, 0xfff, 0x559, 0xfff, 0x1a0, 0xfff, 610 + 0xfff, 0x0b4, 0xfff, 0xfff, 0xfff, 0x2df, 0xfff, 0xfff, 611 + 0xfff, 0x07f, 0x4f5, 0xfff, 0xfff, 0x27c, 0x133, 0x017, 612 + 0xfff, 0x3fd, 0xfff, 0xfff, 0xfff, 0x44d, 0x4cd, 0x17a, 613 + 0x0d7, 0x537, 0xfff, 0xfff, 0x353, 0xfff, 0xfff, 0x351, 614 + 0x366, 0xfff, 0x44a, 0xfff, 0x1a6, 0xfff, 0xfff, 0xfff, 615 + 0x291, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1e3, 616 + 0xfff, 0xfff, 0xfff, 0xfff, 0x389, 0xfff, 0x07a, 0xfff, 617 + 0x1b6, 0x2ed, 0xfff, 0xfff, 0xfff, 0xfff, 0x24e, 0x074, 618 + 0xfff, 0xfff, 0x3dc, 0xfff, 0x4e3, 0xfff, 0xfff, 0xfff, 619 + 0xfff, 0x4eb, 0xfff, 0xfff, 0x3b8, 0x4de, 0xfff, 0x19c, 620 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x262, 621 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x076, 0x4e8, 0x3da, 622 + 0xfff, 0x531, 0xfff, 0xfff, 0x14a, 0xfff, 0x0a2, 0x433, 623 + 0x3df, 0x1e9, 0xfff, 0xfff, 0xfff, 0xfff, 0x3e7, 0x285, 624 + 0x2d8, 0xfff, 0xfff, 0xfff, 0x349, 0x18d, 0x098, 0xfff, 625 + 0x0df, 0x4bf, 0xfff, 0xfff, 0x0b2, 0xfff, 0x346, 0x24d, 626 + 0xfff, 0xfff, 0xfff, 0x24f, 0x4fa, 0x2f9, 0xfff, 0xfff, 627 + 0x3c9, 0xfff, 0x2b4, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 628 + 0xfff, 0x056, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 629 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 630 + 0xfff, 0x179, 0xfff, 0x0e9, 0x3f0, 0x33d, 0xfff, 0xfff, 631 + 0xfff, 0xfff, 0xfff, 0x1fd, 0xfff, 0xfff, 0x526, 0xfff, 632 + 0xfff, 0xfff, 0x53d, 0xfff, 0xfff, 0xfff, 0x170, 0x331, 633 + 0xfff, 0x068, 0xfff, 0xfff, 0xfff, 0x3f7, 0xfff, 0x3d8, 634 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 635 + 0xfff, 0x09f, 0x556, 0xfff, 0xfff, 0x02d, 0xfff, 0xfff, 636 + 0x553, 0xfff, 0xfff, 0xfff, 0x1f0, 0xfff, 0xfff, 0x4d6, 637 + 0x41e, 0xfff, 0xfff, 0xfff, 0xfff, 0x4d5, 0xfff, 0xfff, 638 + 0xfff, 0xfff, 0xfff, 0x248, 0xfff, 0xfff, 0xfff, 0x0a3, 639 + 0xfff, 0x217, 0xfff, 0xfff, 0xfff, 0x4f1, 0x209, 0xfff, 640 + 0xfff, 0x475, 0x234, 0x52b, 0x398, 0xfff, 0x08b, 0xfff, 641 + 0xfff, 0xfff, 0xfff, 0x2c2, 0xfff, 0xfff, 0xfff, 0xfff, 642 + 0xfff, 0xfff, 0x268, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 643 + 0xfff, 0x4a3, 0xfff, 0x0aa, 0xfff, 0x1d9, 0xfff, 0xfff, 644 + 0xfff, 0xfff, 0x155, 0xfff, 0xfff, 0xfff, 0xfff, 0x0bf, 645 + 0x539, 0xfff, 0xfff, 0x2f1, 0x545, 0xfff, 0xfff, 0xfff, 646 + 0xfff, 0xfff, 0xfff, 0x2a7, 0x06f, 0xfff, 0x378, 0xfff, 647 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x25e, 0xfff, 648 + 0xfff, 0xfff, 0xfff, 0x15d, 0x02a, 0xfff, 0xfff, 0x0bc, 649 + 0x235, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 650 + 0x150, 0xfff, 0x1a9, 0xfff, 0xfff, 0xfff, 0xfff, 0x381, 651 + 0xfff, 0x04e, 0x270, 0x13f, 0xfff, 0xfff, 0x405, 0xfff, 652 + 0x3cd, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 653 + 0xfff, 0x2ef, 0xfff, 0x06a, 0xfff, 0xfff, 0xfff, 0x34f, 654 + 0x212, 0xfff, 0xfff, 0x0e2, 0xfff, 0x083, 0x298, 0xfff, 655 + 0xfff, 0xfff, 0x0c2, 0xfff, 0xfff, 0x52e, 0xfff, 0x488, 656 + 0xfff, 0xfff, 0xfff, 0x36b, 0xfff, 0xfff, 0xfff, 0x442, 657 + 0x091, 0xfff, 0x41c, 0xfff, 0xfff, 0x3a5, 0xfff, 0x4e6, 658 + 0xfff, 0xfff, 0x40d, 0x31d, 0xfff, 0xfff, 0xfff, 0x4c1, 659 + 0x053, 0xfff, 0x418, 0x13c, 0xfff, 0x350, 0xfff, 0x0ae, 660 + 0xfff, 0xfff, 0x41f, 0xfff, 0x470, 0xfff, 0x4ca, 0xfff, 661 + 0xfff, 0xfff, 0x02b, 0x450, 0xfff, 0x1f8, 0xfff, 0xfff, 662 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x293, 0xfff, 663 + 0xfff, 0xfff, 0xfff, 0x411, 0xfff, 0xfff, 0xfff, 0xfff, 664 + 0xfff, 0xfff, 0xfff, 0xfff, 0x0b8, 0xfff, 0xfff, 0xfff, 665 + 0x3e1, 0xfff, 0xfff, 0xfff, 0xfff, 0x43c, 0xfff, 0x2b2, 666 + 0x2ab, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1ec, 667 + 0xfff, 0xfff, 0xfff, 0x3f8, 0x034, 0xfff, 0xfff, 0xfff, 668 + 0xfff, 0xfff, 0xfff, 0x11a, 0xfff, 0x541, 0x45c, 0x134, 669 + 0x1cc, 0xfff, 0xfff, 0xfff, 0x469, 0xfff, 0xfff, 0x44b, 670 + 0x161, 0xfff, 0xfff, 0xfff, 0x055, 0xfff, 0xfff, 0xfff, 671 + 0xfff, 0x307, 0xfff, 0xfff, 0xfff, 0xfff, 0x2d1, 0xfff, 672 + 0xfff, 0xfff, 0x124, 0x37b, 0x26b, 0x336, 0xfff, 0xfff, 673 + 0x2e4, 0x3cb, 0xfff, 0xfff, 0x0f8, 0x3c8, 0xfff, 0xfff, 674 + 0xfff, 0x461, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4b5, 675 + 0x2cf, 0xfff, 0xfff, 0xfff, 0x20f, 0xfff, 0x35a, 0xfff, 676 + 0x490, 0xfff, 0x185, 0xfff, 0xfff, 0xfff, 0xfff, 0x42e, 677 + 0xfff, 0xfff, 0xfff, 0xfff, 0x54b, 0xfff, 0xfff, 0xfff, 678 + 0x146, 0xfff, 0x412, 0xfff, 0xfff, 0xfff, 0x1ff, 0xfff, 679 + 0xfff, 0x3e0, 0xfff, 0xfff, 0xfff, 0xfff, 0x2d5, 0xfff, 680 + 0x4df, 0x505, 0xfff, 0x413, 0xfff, 0x1a5, 0xfff, 0x3b2, 681 + 0xfff, 0xfff, 0xfff, 0x35b, 0xfff, 0x116, 0xfff, 0xfff, 682 + 0x171, 0x4d0, 0xfff, 0x154, 0x12d, 0xfff, 0xfff, 0xfff, 683 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x468, 0x4db, 0xfff, 684 + 0xfff, 0x1df, 0xfff, 0xfff, 0xfff, 0xfff, 0x05a, 0xfff, 685 + 0x0f1, 0x403, 0xfff, 0x22b, 0x2e0, 0xfff, 0xfff, 0xfff, 686 + 0x2b7, 0x373, 0xfff, 0xfff, 0xfff, 0xfff, 0x13e, 0xfff, 687 + 0xfff, 0xfff, 0x0d0, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 688 + 0x329, 0x1d2, 0x3fa, 0x047, 0xfff, 0x2f2, 0xfff, 0xfff, 689 + 0x141, 0x0ac, 0x1d7, 0xfff, 0x07d, 0xfff, 0xfff, 0xfff, 690 + 0x1c1, 0xfff, 0x487, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 691 + 0xfff, 0xfff, 0xfff, 0x045, 0xfff, 0xfff, 0xfff, 0xfff, 692 + 0x288, 0x0cd, 0xfff, 0xfff, 0xfff, 0xfff, 0x226, 0x1d8, 693 + 0xfff, 0x153, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4cb, 694 + 0x528, 0xfff, 0xfff, 0xfff, 0x20a, 0x343, 0x3a1, 0xfff, 695 + 0xfff, 0xfff, 0x2d7, 0x2d3, 0x1aa, 0x4c5, 0xfff, 0xfff, 696 + 0xfff, 0x42b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 697 + 0xfff, 0xfff, 0xfff, 0xfff, 0x3e9, 0xfff, 0x20b, 0x260, 698 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x37c, 0x2fd, 699 + 0xfff, 0xfff, 0x2c8, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 700 + 0xfff, 0x31e, 0xfff, 0x335, 0xfff, 0xfff, 0xfff, 0xfff, 701 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 702 + 0xfff, 0xfff, 0x135, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 703 + 0xfff, 0xfff, 0x35c, 0x4dd, 0x129, 0xfff, 0xfff, 0xfff, 704 + 0xfff, 0xfff, 0x1ef, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 705 + 0xfff, 0x34e, 0xfff, 0xfff, 0xfff, 0xfff, 0x407, 0xfff, 706 + 0xfff, 0xfff, 0xfff, 0xfff, 0x3ad, 0xfff, 0xfff, 0xfff, 707 + 0x379, 0xfff, 0xfff, 0x1d0, 0x38d, 0xfff, 0xfff, 0x1e8, 708 + 0x184, 0x3c1, 0x1c4, 0xfff, 0x1f9, 0xfff, 0xfff, 0x424, 709 + 0xfff, 0xfff, 0xfff, 0xfff, 0x1d3, 0x0d4, 0xfff, 0x4e9, 710 + 0xfff, 0xfff, 0xfff, 0x530, 0x107, 0xfff, 0x106, 0x04f, 711 + 0xfff, 0xfff, 0x4c7, 0x503, 0xfff, 0xfff, 0xfff, 0xfff, 712 + 0xfff, 0x15c, 0xfff, 0x23f, 0xfff, 0xfff, 0xfff, 0xfff, 713 + 0xfff, 0xfff, 0xfff, 0xfff, 0x4f3, 0xfff, 0xfff, 0x3c7, 714 + 0xfff, 0x278, 0xfff, 0xfff, 0x0a6, 0xfff, 0xfff, 0xfff, 715 + 0x122, 0x1cf, 0xfff, 0x327, 0xfff, 0x2e5, 0xfff, 0x29d, 716 + 0xfff, 0xfff, 0x3f1, 0xfff, 0xfff, 0x48d, 0xfff, 0xfff, 717 + 0xfff, 0xfff, 0x054, 0xfff, 0xfff, 0xfff, 0xfff, 0x178, 718 + 0x27e, 0x4e0, 0x352, 0x02f, 0x09c, 0xfff, 0x2a0, 0xfff, 719 + 0xfff, 0x46a, 0x457, 0xfff, 0xfff, 0x501, 0xfff, 0x2ba, 720 + 0xfff, 0xfff, 0xfff, 0x54e, 0x2e7, 0xfff, 0xfff, 0xfff, 721 + 0xfff, 0xfff, 0x551, 0xfff, 0xfff, 0x1db, 0x2aa, 0xfff, 722 + 0xfff, 0x4bc, 0xfff, 0xfff, 0x395, 0xfff, 0x0de, 0xfff, 723 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x455, 0xfff, 0x17e, 724 + 0xfff, 0x221, 0x4a7, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 725 + 0x388, 0xfff, 0xfff, 0xfff, 0x308, 0xfff, 0xfff, 0xfff, 726 + 0x20e, 0x4b9, 0xfff, 0x273, 0x20c, 0x09e, 0xfff, 0x057, 727 + 0xfff, 0xfff, 0xfff, 0xfff, 0x3f2, 0xfff, 0x1a8, 0x3a6, 728 + 0x14c, 0xfff, 0xfff, 0x071, 0xfff, 0xfff, 0x53a, 0xfff, 729 + 0xfff, 0xfff, 0xfff, 0x109, 0xfff, 0xfff, 0x399, 0xfff, 730 + 0x061, 0x4f0, 0x39e, 0x244, 0xfff, 0x035, 0xfff, 0xfff, 731 + 0x305, 0x47e, 0x297, 0xfff, 0xfff, 0x2b8, 0xfff, 0xfff, 732 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1bc, 0xfff, 0x2fc, 733 + 0xfff, 0xfff, 0x554, 0xfff, 0xfff, 0xfff, 0xfff, 0x3b6, 734 + 0xfff, 0xfff, 0xfff, 0x515, 0x397, 0xfff, 0xfff, 0x12f, 735 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4e5, 736 + 0xfff, 0x4fc, 0xfff, 0xfff, 0x05e, 0xfff, 0xfff, 0xfff, 737 + 0xfff, 0xfff, 0x0a8, 0x3af, 0x015, 0xfff, 0xfff, 0xfff, 738 + 0xfff, 0x138, 0xfff, 0xfff, 0xfff, 0x540, 0xfff, 0xfff, 739 + 0xfff, 0x027, 0x523, 0x2f0, 0xfff, 0xfff, 0xfff, 0xfff, 740 + 0xfff, 0xfff, 0x16c, 0xfff, 0x27d, 0xfff, 0xfff, 0xfff, 741 + 0xfff, 0x04c, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4dc, 742 + 0xfff, 0xfff, 0x059, 0x301, 0xfff, 0xfff, 0xfff, 0xfff, 743 + 0xfff, 0xfff, 0xfff, 0x1a3, 0xfff, 0x15a, 0xfff, 0xfff, 744 + 0x0a5, 0xfff, 0x435, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 745 + 0xfff, 0x051, 0xfff, 0xfff, 0x131, 0xfff, 0x4f4, 0xfff, 746 + 0xfff, 0xfff, 0xfff, 0x441, 0xfff, 0x4fb, 0xfff, 0x03b, 747 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1ed, 0x274, 748 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x0d3, 0x55e, 0x1b3, 749 + 0xfff, 0x0bd, 0xfff, 0xfff, 0xfff, 0xfff, 0x225, 0xfff, 750 + 0xfff, 0xfff, 0xfff, 0xfff, 0x4b7, 0xfff, 0xfff, 0x2ff, 751 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4c3, 0xfff, 752 + 0x383, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2f6, 753 + 0xfff, 0xfff, 0x1ee, 0xfff, 0x03d, 0xfff, 0xfff, 0xfff, 754 + 0xfff, 0xfff, 0x26f, 0x1dc, 0xfff, 0x0db, 0xfff, 0xfff, 755 + 0xfff, 0xfff, 0xfff, 0x0ce, 0xfff, 0xfff, 0x127, 0x03a, 756 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x311, 0xfff, 757 + 0xfff, 0x13d, 0x09d, 0x47b, 0x2a6, 0x50d, 0x510, 0x19a, 758 + 0xfff, 0x354, 0x414, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 759 + 0xfff, 0xfff, 0x44c, 0x3b0, 0xfff, 0x23d, 0x429, 0xfff, 760 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 761 + 0x4c0, 0x416, 0xfff, 0x05b, 0xfff, 0xfff, 0x137, 0xfff, 762 + 0x25f, 0x49f, 0xfff, 0x279, 0x013, 0xfff, 0xfff, 0xfff, 763 + 0x269, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 764 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x3d0, 0xfff, 0xfff, 765 + 0xfff, 0xfff, 0xfff, 0xfff, 0x077, 0xfff, 0xfff, 0x3fb, 766 + 0xfff, 0xfff, 0xfff, 0xfff, 0x271, 0x3a0, 0xfff, 0xfff, 767 + 0x40f, 0xfff, 0xfff, 0x3de, 0xfff, 0xfff, 0xfff, 0xfff, 768 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1ab, 0x26a, 769 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x489, 0xfff, 0xfff, 770 + 0x252, 0xfff, 0xfff, 0xfff, 0xfff, 0x1b7, 0x42f, 0xfff, 771 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x3b7, 772 + 0xfff, 0x2bb, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 773 + 0xfff, 0xfff, 0xfff, 0x0f7, 0x01d, 0xfff, 0x067, 0xfff, 774 + 0xfff, 0xfff, 0xfff, 0x4e2, 0xfff, 0xfff, 0x4bb, 0xfff, 775 + 0xfff, 0xfff, 0x17b, 0xfff, 0x0ee, 0xfff, 0xfff, 0xfff, 776 + 0xfff, 0xfff, 0x36e, 0xfff, 0xfff, 0xfff, 0x533, 0xfff, 777 + 0xfff, 0xfff, 0x4d4, 0x356, 0xfff, 0xfff, 0x375, 0xfff, 778 + 0xfff, 0xfff, 0xfff, 0x4a4, 0x513, 0xfff, 0xfff, 0xfff, 779 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4ff, 0xfff, 0x2af, 780 + 0xfff, 0xfff, 0x026, 0xfff, 0x0ad, 0xfff, 0xfff, 0xfff, 781 + 0xfff, 0x26e, 0xfff, 0xfff, 0xfff, 0xfff, 0x493, 0xfff, 782 + 0x463, 0x4d2, 0x4be, 0xfff, 0xfff, 0xfff, 0xfff, 0x4f2, 783 + 0x0b6, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 784 + 0xfff, 0x32d, 0x315, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 785 + 0xfff, 0x13a, 0x4a1, 0xfff, 0x27a, 0xfff, 0xfff, 0xfff, 786 + 0x47a, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 787 + 0x334, 0xfff, 0xfff, 0xfff, 0xfff, 0x54c, 0xfff, 0xfff, 788 + 0xfff, 0x0c9, 0x007, 0xfff, 0xfff, 0x12e, 0xfff, 0x0ff, 789 + 0xfff, 0xfff, 0x3f5, 0x509, 0xfff, 0xfff, 0xfff, 0xfff, 790 + 0x1c3, 0x2ad, 0xfff, 0xfff, 0x47c, 0x261, 0xfff, 0xfff, 791 + 0xfff, 0xfff, 0xfff, 0x152, 0xfff, 0xfff, 0xfff, 0x339, 792 + 0xfff, 0x243, 0x1c0, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 793 + 0x063, 0xfff, 0xfff, 0x254, 0xfff, 0xfff, 0x173, 0xfff, 794 + 0x0c7, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 795 + 0xfff, 0x362, 0x259, 0x485, 0x374, 0x0dc, 0x3ab, 0xfff, 796 + 0x1c5, 0x534, 0x544, 0xfff, 0xfff, 0x508, 0xfff, 0x402, 797 + 0x408, 0xfff, 0x0e7, 0xfff, 0xfff, 0x00a, 0x205, 0xfff, 798 + 0xfff, 0x2b9, 0xfff, 0xfff, 0xfff, 0x465, 0xfff, 0xfff, 799 + 0xfff, 0xfff, 0xfff, 0xfff, 0x23a, 0xfff, 0xfff, 0xfff, 800 + 0xfff, 0x147, 0x19d, 0x115, 0x214, 0xfff, 0x090, 0x368, 801 + 0xfff, 0x210, 0xfff, 0xfff, 0x280, 0x52a, 0x163, 0x148, 802 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x326, 0xfff, 0xfff, 803 + 0xfff, 0xfff, 0xfff, 0x2de, 0xfff, 0xfff, 0xfff, 0xfff, 804 + 0x206, 0x2c1, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 805 + 0x189, 0xfff, 0xfff, 0xfff, 0xfff, 0x367, 0xfff, 0x1a4, 806 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x443, 0xfff, 0x27b, 807 + 0xfff, 0xfff, 0x251, 0x549, 0xfff, 0xfff, 0xfff, 0xfff, 808 + 0xfff, 0xfff, 0x188, 0x04b, 0xfff, 0xfff, 0xfff, 0x31f, 809 + 0x4a6, 0xfff, 0x246, 0x1de, 0x156, 0xfff, 0xfff, 0xfff, 810 + 0x3a9, 0xfff, 0xfff, 0xfff, 0x2fa, 0xfff, 0x128, 0x0d1, 811 + 0x449, 0x255, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 812 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 813 + 0xfff, 0xfff, 0xfff, 0xfff, 0x258, 0xfff, 0xfff, 0xfff, 814 + 0x532, 0xfff, 0xfff, 0xfff, 0x303, 0x517, 0xfff, 0xfff, 815 + 0x2a9, 0x24a, 0xfff, 0xfff, 0x231, 0xfff, 0xfff, 0xfff, 816 + 0xfff, 0xfff, 0x4b6, 0x516, 0xfff, 0xfff, 0x0e4, 0x0eb, 817 + 0xfff, 0x4e4, 0xfff, 0x275, 0xfff, 0xfff, 0x031, 0xfff, 818 + 0xfff, 0xfff, 0xfff, 0xfff, 0x025, 0x21a, 0xfff, 0x0cc, 819 + 0x45f, 0x3d9, 0x289, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 820 + 0xfff, 0xfff, 0x23e, 0xfff, 0xfff, 0xfff, 0x438, 0x097, 821 + 0x419, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 822 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 823 + 0xfff, 0xfff, 0x0a9, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 824 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 825 + 0x37e, 0x0e0, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x431, 826 + 0x372, 0xfff, 0xfff, 0xfff, 0x1ba, 0x06e, 0xfff, 0x1b1, 827 + 0xfff, 0xfff, 0x12a, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 828 + 0xfff, 0xfff, 0x193, 0xfff, 0xfff, 0xfff, 0xfff, 0x10a, 829 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x048, 0x1b4, 830 + 0xfff, 0xfff, 0xfff, 0xfff, 0x295, 0x140, 0x108, 0xfff, 831 + 0xfff, 0xfff, 0xfff, 0x16f, 0xfff, 0x0a4, 0x37a, 0xfff, 832 + 0x29a, 0xfff, 0x284, 0xfff, 0xfff, 0xfff, 0xfff, 0x4c6, 833 + 0x2a2, 0x3a3, 0xfff, 0x201, 0xfff, 0xfff, 0xfff, 0x4bd, 834 + 0x005, 0x54a, 0x3b5, 0x204, 0x2ee, 0x11d, 0x436, 0xfff, 835 + 0xfff, 0xfff, 0xfff, 0xfff, 0x3ec, 0xfff, 0xfff, 0xfff, 836 + 0xfff, 0xfff, 0xfff, 0xfff, 0x11f, 0x498, 0x21c, 0xfff, 837 + 0xfff, 0xfff, 0x3d6, 0xfff, 0x4ab, 0xfff, 0x432, 0x2eb, 838 + 0x542, 0x4fd, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 839 + 0xfff, 0xfff, 0xfff, 0x4ce, 0xfff, 0xfff, 0x2fb, 0xfff, 840 + 0xfff, 0x2e1, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 841 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x1b9, 0x037, 0x0dd, 842 + 0xfff, 0xfff, 0xfff, 0x2bf, 0x521, 0x496, 0x095, 0xfff, 843 + 0xfff, 0x328, 0x070, 0x1bf, 0xfff, 0x393, 0xfff, 0xfff, 844 + 0x102, 0xfff, 0xfff, 0x21b, 0xfff, 0x142, 0x263, 0x519, 845 + 0xfff, 0x2a5, 0x177, 0xfff, 0x14d, 0x471, 0x4ae, 0xfff, 846 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 847 + 0x1f6, 0xfff, 0x481, 0xfff, 0xfff, 0xfff, 0x151, 0xfff, 848 + 0xfff, 0xfff, 0x085, 0x33f, 0xfff, 0xfff, 0xfff, 0x084, 849 + 0xfff, 0xfff, 0xfff, 0x345, 0x3a2, 0xfff, 0xfff, 0x0a0, 850 + 0x0da, 0x024, 0xfff, 0xfff, 0xfff, 0x1bd, 0xfff, 0x55c, 851 + 0x467, 0x445, 0xfff, 0xfff, 0xfff, 0x052, 0xfff, 0xfff, 852 + 0xfff, 0xfff, 0x51e, 0xfff, 0xfff, 0x39d, 0xfff, 0x35f, 853 + 0xfff, 0x376, 0x3ee, 0xfff, 0xfff, 0xfff, 0xfff, 0x448, 854 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x16a, 855 + 0xfff, 0x036, 0x38f, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 856 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x211, 857 + 0xfff, 0xfff, 0xfff, 0x230, 0xfff, 0xfff, 0x3ba, 0xfff, 858 + 0xfff, 0xfff, 0x3ce, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 859 + 0xfff, 0xfff, 0xfff, 0x229, 0xfff, 0x176, 0xfff, 0xfff, 860 + 0xfff, 0xfff, 0xfff, 0x00b, 0xfff, 0x162, 0x018, 0xfff, 861 + 0xfff, 0x233, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 862 + 0x400, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 863 + 0xfff, 0xfff, 0xfff, 0x12b, 0xfff, 0xfff, 0xfff, 0xfff, 864 + 0xfff, 0x3f4, 0xfff, 0x0f0, 0xfff, 0x1ac, 0xfff, 0xfff, 865 + 0x119, 0xfff, 0x2c0, 0xfff, 0xfff, 0xfff, 0x49b, 0xfff, 866 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x23c, 0xfff, 867 + 0x4b3, 0x010, 0x064, 0xfff, 0xfff, 0x4ba, 0xfff, 0xfff, 868 + 0xfff, 0xfff, 0xfff, 0x3c2, 0xfff, 0xfff, 0xfff, 0xfff, 869 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x006, 0x196, 0xfff, 870 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x100, 0x191, 0xfff, 871 + 0x1ea, 0x29f, 0xfff, 0xfff, 0xfff, 0x276, 0xfff, 0xfff, 872 + 0x2b1, 0x3b9, 0xfff, 0x03c, 0xfff, 0xfff, 0xfff, 0x180, 873 + 0xfff, 0x08f, 0xfff, 0xfff, 0x19e, 0x019, 0xfff, 0x0b0, 874 + 0x0fd, 0x332, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 875 + 0xfff, 0x06b, 0x2e8, 0xfff, 0x446, 0xfff, 0xfff, 0x004, 876 + 0x247, 0x197, 0xfff, 0x112, 0x169, 0x292, 0xfff, 0x302, 877 + 0xfff, 0xfff, 0x33b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 878 + 0xfff, 0xfff, 0xfff, 0x287, 0x21f, 0xfff, 0x3ea, 0xfff, 879 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x4e7, 0xfff, 0xfff, 880 + 0xfff, 0xfff, 0xfff, 0x3a8, 0xfff, 0xfff, 0x2bc, 0xfff, 881 + 0x484, 0x296, 0xfff, 0x1c9, 0x08c, 0x1e5, 0x48a, 0xfff, 882 + 0x360, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 883 + 0x1ca, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 884 + 0xfff, 0xfff, 0xfff, 0x10d, 0xfff, 0xfff, 0xfff, 0xfff, 885 + 0xfff, 0xfff, 0x066, 0x2ea, 0x28b, 0x25b, 0xfff, 0x072, 886 + 0xfff, 0xfff, 0xfff, 0xfff, 0x2b6, 0xfff, 0xfff, 0x272, 887 + 0xfff, 0xfff, 0x525, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 888 + 0x2ca, 0xfff, 0xfff, 0xfff, 0x299, 0xfff, 0xfff, 0xfff, 889 + 0x558, 0x41a, 0xfff, 0x4f7, 0x557, 0xfff, 0x4a0, 0x344, 890 + 0x12c, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x125, 891 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 892 + 0x40e, 0xfff, 0xfff, 0x502, 0xfff, 0x103, 0x3e6, 0xfff, 893 + 0x527, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 894 + 0xfff, 0xfff, 0xfff, 0x45d, 0xfff, 0xfff, 0xfff, 0xfff, 895 + 0x44e, 0xfff, 0xfff, 0xfff, 0xfff, 0x0d2, 0x4c9, 0x35e, 896 + 0x459, 0x2d9, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x17d, 897 + 0x0c4, 0xfff, 0xfff, 0xfff, 0x3ac, 0x390, 0x094, 0xfff, 898 + 0x483, 0x0ab, 0xfff, 0x253, 0xfff, 0x391, 0xfff, 0xfff, 899 + 0xfff, 0xfff, 0x123, 0x0ef, 0xfff, 0xfff, 0xfff, 0x330, 900 + 0x38c, 0xfff, 0xfff, 0x2ae, 0xfff, 0xfff, 0xfff, 0x042, 901 + 0x012, 0x06d, 0xfff, 0xfff, 0xfff, 0x32a, 0x3db, 0x364, 902 + 0x2dc, 0xfff, 0x30f, 0x3d7, 0x4a5, 0x050, 0xfff, 0xfff, 903 + 0x029, 0xfff, 0xfff, 0xfff, 0xfff, 0x1d1, 0xfff, 0xfff, 904 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x480, 0xfff, 905 + 0x4ed, 0x081, 0x0a1, 0xfff, 0xfff, 0xfff, 0x30e, 0x52f, 906 + 0x257, 0xfff, 0xfff, 0x447, 0xfff, 0xfff, 0xfff, 0xfff, 907 + 0xfff, 0xfff, 0xfff, 0x401, 0x3cc, 0xfff, 0xfff, 0x0fb, 908 + 0x2c9, 0x42a, 0x314, 0x33e, 0x3bd, 0x318, 0xfff, 0x10e, 909 + 0x2a1, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x24c, 910 + 0x506, 0xfff, 0x267, 0xfff, 0xfff, 0x219, 0xfff, 0x1eb, 911 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 912 + 0x309, 0x3e2, 0x46c, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 913 + 0x384, 0xfff, 0xfff, 0xfff, 0xfff, 0x50c, 0xfff, 0x24b, 914 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x038, 915 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x194, 916 + 0x143, 0x3e3, 0xfff, 0xfff, 0xfff, 0x4c2, 0xfff, 0xfff, 917 + 0x0e1, 0x25c, 0xfff, 0x237, 0xfff, 0x1fe, 0xfff, 0xfff, 918 + 0xfff, 0x065, 0x2a4, 0xfff, 0x386, 0x55a, 0x11b, 0xfff, 919 + 0xfff, 0x192, 0xfff, 0x183, 0x00e, 0xfff, 0xfff, 0xfff, 920 + 0xfff, 0xfff, 0xfff, 0x4b2, 0x18e, 0xfff, 0xfff, 0xfff, 921 + 0xfff, 0x486, 0x4ef, 0x0c6, 0x380, 0xfff, 0x4a8, 0xfff, 922 + 0x0c5, 0xfff, 0xfff, 0xfff, 0xfff, 0x093, 0x1b8, 0xfff, 923 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2e6, 924 + 0xfff, 0x0f3, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 925 + 0x28e, 0xfff, 0x53b, 0x420, 0x22a, 0x33a, 0xfff, 0x387, 926 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2a3, 0xfff, 0xfff, 927 + 0xfff, 0x428, 0x500, 0xfff, 0xfff, 0x120, 0x2c6, 0x290, 928 + 0x2f5, 0x0e3, 0xfff, 0x0b7, 0xfff, 0x319, 0x474, 0xfff, 929 + 0xfff, 0xfff, 0x529, 0x014, 0xfff, 0x41b, 0x40a, 0x18b, 930 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x0d9, 931 + 0xfff, 0x38a, 0xfff, 0xfff, 0xfff, 0xfff, 0x1ce, 0xfff, 932 + 0xfff, 0xfff, 0xfff, 0xfff, 0x3b1, 0xfff, 0xfff, 0x05d, 933 + 0x2c4, 0xfff, 0xfff, 0x4af, 0xfff, 0x030, 0xfff, 0xfff, 934 + 0x203, 0xfff, 0x277, 0x256, 0xfff, 0xfff, 0xfff, 0x4f9, 935 + 0xfff, 0x2c7, 0xfff, 0x466, 0x016, 0x1cd, 0xfff, 0x167, 936 + 0xfff, 0xfff, 0x0c8, 0xfff, 0x43d, 0xfff, 0xfff, 0x020, 937 + 0xfff, 0xfff, 0x232, 0x1cb, 0x1e0, 0xfff, 0xfff, 0x347, 938 + 0xfff, 0x478, 0xfff, 0x365, 0xfff, 0xfff, 0xfff, 0xfff, 939 + 0x358, 0xfff, 0x10b, 0xfff, 0x35d, 0xfff, 0xfff, 0xfff, 940 + 0xfff, 0xfff, 0x452, 0x22d, 0xfff, 0xfff, 0x47d, 0xfff, 941 + 0x2f3, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x460, 0xfff, 942 + 0xfff, 0xfff, 0x50b, 0xfff, 0xfff, 0xfff, 0x2ec, 0xfff, 943 + 0xfff, 0xfff, 0xfff, 0xfff, 0x4b1, 0x422, 0xfff, 0xfff, 944 + 0xfff, 0x2d4, 0xfff, 0x239, 0xfff, 0xfff, 0xfff, 0x439, 945 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 946 + 0xfff, 0x491, 0x075, 0xfff, 0xfff, 0xfff, 0x06c, 0xfff, 947 + 0xfff, 0x0f9, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 948 + 0xfff, 0x139, 0xfff, 0x4f6, 0xfff, 0xfff, 0x409, 0xfff, 949 + 0xfff, 0x15b, 0xfff, 0xfff, 0x348, 0xfff, 0xfff, 0xfff, 950 + 0xfff, 0x4a2, 0x49d, 0xfff, 0x033, 0x175, 0xfff, 0x039, 951 + 0xfff, 0x312, 0x40c, 0xfff, 0xfff, 0x325, 0xfff, 0xfff, 952 + 0xfff, 0xfff, 0xfff, 0xfff, 0x4aa, 0xfff, 0xfff, 0xfff, 953 + 0xfff, 0xfff, 0xfff, 0x165, 0x3bc, 0x48c, 0x310, 0x096, 954 + 0xfff, 0xfff, 0x250, 0x1a2, 0xfff, 0xfff, 0xfff, 0xfff, 955 + 0x20d, 0x2ac, 0xfff, 0xfff, 0x39b, 0xfff, 0x377, 0xfff, 956 + 0x512, 0x495, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 957 + 0xfff, 0xfff, 0xfff, 0xfff, 0x357, 0x4ea, 0xfff, 0xfff, 958 + 0xfff, 0xfff, 0x198, 0xfff, 0xfff, 0xfff, 0x434, 0x04a, 959 + 0xfff, 0xfff, 0xfff, 0xfff, 0x062, 0xfff, 0x1d6, 0x1c8, 960 + 0xfff, 0x1f3, 0x281, 0xfff, 0x462, 0xfff, 0xfff, 0xfff, 961 + 0x4b0, 0xfff, 0x207, 0xfff, 0xfff, 0xfff, 0xfff, 0x3dd, 962 + 0xfff, 0xfff, 0x55d, 0xfff, 0x552, 0x494, 0x1af, 0xfff, 963 + 0xfff, 0xfff, 0xfff, 0xfff, 0x227, 0xfff, 0xfff, 0x069, 964 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x43e, 965 + 0x0b5, 0xfff, 0x524, 0x2d2, 0xfff, 0xfff, 0xfff, 0x28f, 966 + 0xfff, 0x01b, 0x50e, 0xfff, 0xfff, 0x1bb, 0xfff, 0xfff, 967 + 0x41d, 0xfff, 0x32e, 0x48e, 0xfff, 0x1f7, 0x224, 0xfff, 968 + 0xfff, 0xfff, 0xfff, 0xfff, 0x394, 0xfff, 0xfff, 0xfff, 969 + 0xfff, 0x52c, 0xfff, 0xfff, 0xfff, 0x392, 0xfff, 0x1e7, 970 + 0xfff, 0xfff, 0x3f9, 0x3a7, 0xfff, 0x51f, 0xfff, 0x0bb, 971 + 0x118, 0x3ca, 0xfff, 0x1dd, 0xfff, 0x48b, 0xfff, 0xfff, 972 + 0xfff, 0xfff, 0x50f, 0xfff, 0x0d6, 0xfff, 0x1fa, 0xfff, 973 + 0x11e, 0xfff, 0xfff, 0xfff, 0xfff, 0x4d7, 0xfff, 0x078, 974 + 0x008, 0xfff, 0x25d, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 975 + 0x032, 0x33c, 0xfff, 0x4d9, 0x160, 0xfff, 0xfff, 0x300, 976 + 0x0b1, 0xfff, 0x322, 0xfff, 0x4ec, 0xfff, 0xfff, 0x200, 977 + 0x00c, 0x369, 0x473, 0xfff, 0xfff, 0x32c, 0xfff, 0xfff, 978 + 0xfff, 0xfff, 0xfff, 0xfff, 0x53e, 0x3d4, 0x417, 0xfff, 979 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 980 + 0x34b, 0x001, 0x39a, 0x02c, 0xfff, 0xfff, 0x2ce, 0x00f, 981 + 0xfff, 0x0ba, 0xfff, 0xfff, 0xfff, 0xfff, 0x060, 0xfff, 982 + 0x406, 0xfff, 0xfff, 0xfff, 0x4ee, 0x4ac, 0xfff, 0x43f, 983 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x29b, 0xfff, 0xfff, 984 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x216, 985 + 0x190, 0xfff, 0x396, 0x464, 0xfff, 0xfff, 0x323, 0xfff, 986 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x2e9, 0xfff, 0x26d, 987 + 0x2cd, 0x040, 0xfff, 0xfff, 0xfff, 0xfff, 0x38b, 0x3c0, 988 + 0xfff, 0xfff, 0xfff, 0x1f2, 0xfff, 0x0ea, 0xfff, 0xfff, 989 + 0x472, 0xfff, 0x1fb, 0xfff, 0xfff, 0x0af, 0x27f, 0xfff, 990 + 0xfff, 0xfff, 0x479, 0x023, 0xfff, 0x0d8, 0x3b3, 0xfff, 991 + 0xfff, 0xfff, 0x121, 0xfff, 0xfff, 0x3bf, 0xfff, 0xfff, 992 + 0x16b, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 993 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 994 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 995 + 0x45a, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 996 + 0xfff, 0x0be, 0xfff, 0xfff, 0xfff, 0x111, 0xfff, 0x220, 997 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 998 + 0xfff, 0xfff, 0x09b, 0x218, 0xfff, 0x022, 0x202, 0xfff, 999 + 0x4c8, 0xfff, 0x0ed, 0xfff, 0xfff, 0x182, 0xfff, 0xfff, 1000 + 0xfff, 0x17f, 0x213, 0xfff, 0x321, 0x36a, 0xfff, 0x086, 1001 + 0xfff, 0xfff, 0xfff, 0x43b, 0x088, 0xfff, 0xfff, 0xfff, 1002 + 0xfff, 0x26c, 0xfff, 0x2f8, 0x3b4, 0xfff, 0xfff, 0xfff, 1003 + 0x132, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x333, 0x444, 1004 + 0x0c1, 0x4d8, 0x46d, 0x264, 0xfff, 0xfff, 0xfff, 0xfff, 1005 + 0x426, 0xfff, 0xfff, 0xfff, 0xfff, 0x2fe, 0xfff, 0xfff, 1006 + 0xfff, 0xfff, 0x011, 0xfff, 0x05f, 0xfff, 0xfff, 0xfff, 1007 + 0xfff, 0x10c, 0x101, 0xfff, 0xfff, 0xfff, 0xfff, 0x110, 1008 + 0xfff, 0x044, 0x304, 0x361, 0x404, 0xfff, 0x51b, 0x099, 1009 + 0xfff, 0x440, 0xfff, 0xfff, 0xfff, 0x222, 0xfff, 0xfff, 1010 + 0xfff, 0xfff, 0x1b5, 0xfff, 0x136, 0x430, 0xfff, 0x1da, 1011 + 0xfff, 0xfff, 0xfff, 0x043, 0xfff, 0x17c, 0xfff, 0xfff, 1012 + 0xfff, 0x01c, 0xfff, 0xfff, 0xfff, 0x425, 0x236, 0xfff, 1013 + 0x317, 0xfff, 0xfff, 0x437, 0x3fc, 0xfff, 0x1f1, 0xfff, 1014 + 0x324, 0xfff, 0xfff, 0x0ca, 0x306, 0xfff, 0x548, 0xfff, 1015 + 0x46e, 0xfff, 0xfff, 0xfff, 0x4b8, 0x1c2, 0x286, 0xfff, 1016 + 0xfff, 0x087, 0x18a, 0x19f, 0xfff, 0xfff, 0xfff, 0xfff, 1017 + 0x18c, 0xfff, 0x215, 0xfff, 0xfff, 0xfff, 0xfff, 0x283, 1018 + 0xfff, 0xfff, 0xfff, 0x126, 0xfff, 0xfff, 0x370, 0xfff, 1019 + 0x53f, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0x31c, 0xfff, 1020 + 0x4d1, 0xfff, 0xfff, 0xfff, 0x021, 0xfff, 0x157, 0xfff, 1021 + 0xfff, 0x028, 0x16e, 0xfff, 0x421, 0xfff, 0x1c6, 0xfff, 1022 + 0xfff, 0x511, 0xfff, 0xfff, 0x39c, 0x46f, 0x1b2, 0xfff, 1023 + 0xfff, 0x316, 0xfff, 0xfff, 0x009, 0xfff, 0xfff, 0x195, 1024 + 0xfff, 0x240, 0x546, 0xfff, 0xfff, 0x520, 0xfff, 0xfff, 1025 + 0xfff, 0xfff, 0xfff, 0xfff, 0x454, 0xfff, 0xfff, 0xfff, 1026 + 0x3f3, 0xfff, 0xfff, 0x187, 0xfff, 0x4a9, 0xfff, 0xfff, 1027 + 0xfff, 0xfff, 0xfff, 0xfff, 0x51c, 0x453, 0x1e6, 0xfff, 1028 + 0xfff, 0xfff, 0x1b0, 0xfff, 0x477, 0xfff, 0xfff, 0xfff, 1029 + 0x4fe, 0xfff, 0x32f, 0xfff, 0xfff, 0x15e, 0x1d4, 0xfff, 1030 + 0x0e5, 0xfff, 0xfff, 0xfff, 0x242, 0x14b, 0x046, 0xfff, 1031 + 0x3f6, 0x3bb, 0x3e4, 0xfff, 0xfff, 0x2e3, 0xfff, 0x245, 1032 + 0xfff, 0x149, 0xfff, 0xfff, 0xfff, 0x2db, 0xfff, 0xfff, 1033 + 0x181, 0xfff, 0x089, 0x2c5, 0xfff, 0x1f5, 0xfff, 0x2d6, 1034 + 0x507, 0xfff, 0x42d, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 1035 + 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 1036 + 0x080, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 1037 + 0xfff, 0xfff, 0xfff, 0xfff, 0x3c3, 0x320, 0xfff, 0x1e1, 1038 + 0xfff, 0x0f5, 0x13b, 0xfff, 0xfff, 0xfff, 0x003, 0x4da, 1039 + 0xfff, 0xfff, 0xfff, 0x42c, 0xfff, 0xfff, 0x0cb, 0xfff, 1040 + 0x536, 0x2c3, 0xfff, 0xfff, 0xfff, 0xfff, 0x199, 0xfff, 1041 + 0xfff, 0x0c0, 0xfff, 0x01e, 0x497, 0xfff, 0xfff, 0x3e5, 1042 + 0xfff, 0xfff, 0xfff, 0x0cf, 0xfff, 0x2bd, 0xfff, 0x223, 1043 + 0xfff, 0x3ff, 0xfff, 0x058, 0x174, 0x3ef, 0xfff, 0x002 1044 + }; 1045 + 1046 + static unsigned short err_pos(unsigned short din) 1047 + { 1048 + BUG_ON(din > 4096); 1049 + return err_pos_lut[din]; 1050 + } 1051 + static int chk_no_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info) 1052 + { 1053 + if ((chk_syndrome_list[0] | chk_syndrome_list[1] | 1054 + chk_syndrome_list[2] | chk_syndrome_list[3] | 1055 + chk_syndrome_list[4] | chk_syndrome_list[5] | 1056 + chk_syndrome_list[6] | chk_syndrome_list[7]) != 0x0) { 1057 + return -EINVAL; 1058 + } else { 1059 + err_info[0] = 0x0; 1060 + return 0; 1061 + } 1062 + } 1063 + static int chk_1_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info) 1064 + { 1065 + unsigned short tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6; 1066 + tmp0 = gf4096_mul(chk_syndrome_list[1], gf4096_inv(chk_syndrome_list[0])); 1067 + tmp1 = gf4096_mul(chk_syndrome_list[2], gf4096_inv(chk_syndrome_list[1])); 1068 + tmp2 = gf4096_mul(chk_syndrome_list[3], gf4096_inv(chk_syndrome_list[2])); 1069 + tmp3 = gf4096_mul(chk_syndrome_list[4], gf4096_inv(chk_syndrome_list[3])); 1070 + tmp4 = gf4096_mul(chk_syndrome_list[5], gf4096_inv(chk_syndrome_list[4])); 1071 + tmp5 = gf4096_mul(chk_syndrome_list[6], gf4096_inv(chk_syndrome_list[5])); 1072 + tmp6 = gf4096_mul(chk_syndrome_list[7], gf4096_inv(chk_syndrome_list[6])); 1073 + if ((tmp0 == tmp1) & (tmp1 == tmp2) & (tmp2 == tmp3) & (tmp3 == tmp4) & (tmp4 == tmp5) & (tmp5 == tmp6)) { 1074 + err_info[0] = 0x1; // encode 1-symbol error as 0x1 1075 + err_info[1] = err_pos(tmp0); 1076 + err_info[1] = (unsigned short)(0x55e - err_info[1]); 1077 + err_info[5] = chk_syndrome_list[0]; 1078 + return 0; 1079 + } else 1080 + return -EINVAL; 1081 + } 1082 + static int chk_2_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info) 1083 + { 1084 + unsigned short tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; 1085 + unsigned short coefs[4]; 1086 + unsigned short err_pats[4]; 1087 + int found_num_root = 0; 1088 + unsigned short bit2_root0, bit2_root1; 1089 + unsigned short bit2_root0_inv, bit2_root1_inv; 1090 + unsigned short err_loc_eqn, test_root; 1091 + unsigned short bit2_loc0, bit2_loc1; 1092 + unsigned short bit2_pat0, bit2_pat1; 1093 + 1094 + find_2x2_soln(chk_syndrome_list[1], 1095 + chk_syndrome_list[0], 1096 + chk_syndrome_list[2], chk_syndrome_list[1], chk_syndrome_list[2], chk_syndrome_list[3], coefs); 1097 + for (test_root = 0x1; test_root < 0xfff; test_root++) { 1098 + err_loc_eqn = 1099 + gf4096_mul(coefs[1], gf4096_mul(test_root, test_root)) ^ gf4096_mul(coefs[0], test_root) ^ 0x1; 1100 + if (err_loc_eqn == 0x0) { 1101 + if (found_num_root == 0) { 1102 + bit2_root0 = test_root; 1103 + found_num_root = 1; 1104 + } else if (found_num_root == 1) { 1105 + bit2_root1 = test_root; 1106 + found_num_root = 2; 1107 + break; 1108 + } 1109 + } 1110 + } 1111 + if (found_num_root != 2) 1112 + return -EINVAL; 1113 + else { 1114 + bit2_root0_inv = gf4096_inv(bit2_root0); 1115 + bit2_root1_inv = gf4096_inv(bit2_root1); 1116 + find_2bit_err_pats(chk_syndrome_list[0], 1117 + chk_syndrome_list[1], bit2_root0_inv, bit2_root1_inv, err_pats); 1118 + bit2_pat0 = err_pats[0]; 1119 + bit2_pat1 = err_pats[1]; 1120 + //for(x+1) 1121 + tmp0 = gf4096_mul(gf4096_mul(bit2_root0_inv, bit2_root0_inv), gf4096_mul(bit2_root0_inv, bit2_root0_inv)); //rinv0^4 1122 + tmp1 = gf4096_mul(bit2_root0_inv, tmp0); //rinv0^5 1123 + tmp2 = gf4096_mul(bit2_root0_inv, tmp1); //rinv0^6 1124 + tmp3 = gf4096_mul(bit2_root0_inv, tmp2); //rinv0^7 1125 + tmp4 = gf4096_mul(gf4096_mul(bit2_root1_inv, bit2_root1_inv), gf4096_mul(bit2_root1_inv, bit2_root1_inv)); //rinv1^4 1126 + tmp5 = gf4096_mul(bit2_root1_inv, tmp4); //rinv1^5 1127 + tmp6 = gf4096_mul(bit2_root1_inv, tmp5); //rinv1^6 1128 + tmp7 = gf4096_mul(bit2_root1_inv, tmp6); //rinv1^7 1129 + //check if only 2-bit error 1130 + if ((chk_syndrome_list[4] == 1131 + (gf4096_mul(bit2_pat0, tmp0) ^ 1132 + gf4096_mul(bit2_pat1, 1133 + tmp4))) & (chk_syndrome_list[5] == 1134 + (gf4096_mul(bit2_pat0, tmp1) ^ 1135 + gf4096_mul(bit2_pat1, 1136 + tmp5))) & 1137 + (chk_syndrome_list[6] == 1138 + (gf4096_mul(bit2_pat0, tmp2) ^ 1139 + gf4096_mul(bit2_pat1, 1140 + tmp6))) & (chk_syndrome_list[7] == 1141 + (gf4096_mul(bit2_pat0, tmp3) ^ gf4096_mul(bit2_pat1, tmp7)))) { 1142 + if ((err_pos(bit2_root0_inv) == 0xfff) | (err_pos(bit2_root1_inv) == 0xfff)) { 1143 + return -EINVAL; 1144 + } else { 1145 + bit2_loc0 = 0x55e - err_pos(bit2_root0_inv); 1146 + bit2_loc1 = 0x55e - err_pos(bit2_root1_inv); 1147 + err_info[0] = 0x2; // encode 2-symbol error as 0x2 1148 + err_info[1] = bit2_loc0; 1149 + err_info[2] = bit2_loc1; 1150 + err_info[5] = bit2_pat0; 1151 + err_info[6] = bit2_pat1; 1152 + return 0; 1153 + } 1154 + } else 1155 + return -EINVAL; 1156 + } 1157 + } 1158 + static int chk_3_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info) 1159 + { 1160 + unsigned short tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; 1161 + unsigned short coefs[4]; 1162 + unsigned short err_pats[4]; 1163 + int found_num_root = 0; 1164 + unsigned short bit3_root0, bit3_root1, bit3_root2; 1165 + unsigned short bit3_root0_inv, bit3_root1_inv, bit3_root2_inv; 1166 + unsigned short err_loc_eqn, test_root; 1167 + 1168 + find_3bit_err_coefs(chk_syndrome_list[0], chk_syndrome_list[1], 1169 + chk_syndrome_list[2], chk_syndrome_list[3], 1170 + chk_syndrome_list[4], chk_syndrome_list[5], coefs); 1171 + 1172 + for (test_root = 0x1; test_root < 0xfff; test_root++) { 1173 + err_loc_eqn = gf4096_mul(coefs[2], 1174 + gf4096_mul(gf4096_mul(test_root, test_root), 1175 + test_root)) ^ gf4096_mul(coefs[1], gf4096_mul(test_root, test_root)) 1176 + ^ gf4096_mul(coefs[0], test_root) ^ 0x1; 1177 + 1178 + if (err_loc_eqn == 0x0) { 1179 + if (found_num_root == 0) { 1180 + bit3_root0 = test_root; 1181 + found_num_root = 1; 1182 + } else if (found_num_root == 1) { 1183 + bit3_root1 = test_root; 1184 + found_num_root = 2; 1185 + } else if (found_num_root == 2) { 1186 + bit3_root2 = test_root; 1187 + found_num_root = 3; 1188 + break; 1189 + } 1190 + } 1191 + } 1192 + if (found_num_root != 3) 1193 + return -EINVAL; 1194 + else { 1195 + bit3_root0_inv = gf4096_inv(bit3_root0); 1196 + bit3_root1_inv = gf4096_inv(bit3_root1); 1197 + bit3_root2_inv = gf4096_inv(bit3_root2); 1198 + 1199 + find_3bit_err_pats(chk_syndrome_list[0], chk_syndrome_list[1], 1200 + chk_syndrome_list[2], bit3_root0_inv, 1201 + bit3_root1_inv, bit3_root2_inv, err_pats); 1202 + 1203 + //check if only 3-bit error 1204 + tmp0 = gf4096_mul(bit3_root0_inv, bit3_root0_inv); 1205 + tmp0 = gf4096_mul(tmp0, tmp0); 1206 + tmp0 = gf4096_mul(tmp0, bit3_root0_inv); 1207 + tmp0 = gf4096_mul(tmp0, bit3_root0_inv); //rinv0^6 1208 + tmp1 = gf4096_mul(tmp0, bit3_root0_inv); //rinv0^7 1209 + tmp2 = gf4096_mul(bit3_root1_inv, bit3_root1_inv); 1210 + tmp2 = gf4096_mul(tmp2, tmp2); 1211 + tmp2 = gf4096_mul(tmp2, bit3_root1_inv); 1212 + tmp2 = gf4096_mul(tmp2, bit3_root1_inv); //rinv1^6 1213 + tmp3 = gf4096_mul(tmp2, bit3_root1_inv); //rinv1^7 1214 + tmp4 = gf4096_mul(bit3_root2_inv, bit3_root2_inv); 1215 + tmp4 = gf4096_mul(tmp4, tmp4); 1216 + tmp4 = gf4096_mul(tmp4, bit3_root2_inv); 1217 + tmp4 = gf4096_mul(tmp4, bit3_root2_inv); //rinv2^6 1218 + tmp5 = gf4096_mul(tmp4, bit3_root2_inv); //rinv2^7 1219 + 1220 + //check if only 3 errors 1221 + if ((chk_syndrome_list[6] == (gf4096_mul(err_pats[0], tmp0) ^ 1222 + gf4096_mul(err_pats[1], tmp2) ^ 1223 + gf4096_mul(err_pats[2], tmp4))) & 1224 + (chk_syndrome_list[7] == (gf4096_mul(err_pats[0], tmp1) ^ 1225 + gf4096_mul(err_pats[1], tmp3) ^ gf4096_mul(err_pats[2], tmp5)))) { 1226 + if ((err_pos(bit3_root0_inv) == 0xfff) | 1227 + (err_pos(bit3_root1_inv) == 0xfff) | (err_pos(bit3_root2_inv) == 0xfff)) { 1228 + return -EINVAL; 1229 + } else { 1230 + err_info[0] = 0x3; 1231 + err_info[1] = (0x55e - err_pos(bit3_root0_inv)); 1232 + err_info[2] = (0x55e - err_pos(bit3_root1_inv)); 1233 + err_info[3] = (0x55e - err_pos(bit3_root2_inv)); 1234 + err_info[5] = err_pats[0]; 1235 + err_info[6] = err_pats[1]; 1236 + err_info[7] = err_pats[2]; 1237 + return 0; 1238 + } 1239 + } else 1240 + return -EINVAL; 1241 + } 1242 + } 1243 + static int chk_4_err_only(unsigned short *chk_syndrome_list, unsigned short *err_info) 1244 + { 1245 + unsigned short coefs[4]; 1246 + unsigned short err_pats[4]; 1247 + int found_num_root = 0; 1248 + unsigned short bit4_root0, bit4_root1, bit4_root2, bit4_root3; 1249 + unsigned short bit4_root0_inv, bit4_root1_inv, bit4_root2_inv, bit4_root3_inv; 1250 + unsigned short err_loc_eqn, test_root; 1251 + 1252 + find_4bit_err_coefs(chk_syndrome_list[0], 1253 + chk_syndrome_list[1], 1254 + chk_syndrome_list[2], 1255 + chk_syndrome_list[3], 1256 + chk_syndrome_list[4], 1257 + chk_syndrome_list[5], chk_syndrome_list[6], chk_syndrome_list[7], coefs); 1258 + 1259 + for (test_root = 0x1; test_root < 0xfff; test_root++) { 1260 + err_loc_eqn = 1261 + gf4096_mul(coefs[3], 1262 + gf4096_mul(gf4096_mul 1263 + (gf4096_mul(test_root, test_root), 1264 + test_root), 1265 + test_root)) ^ gf4096_mul(coefs[2], 1266 + gf4096_mul 1267 + (gf4096_mul(test_root, test_root), test_root)) 1268 + ^ gf4096_mul(coefs[1], gf4096_mul(test_root, test_root)) ^ gf4096_mul(coefs[0], test_root) 1269 + ^ 0x1; 1270 + if (err_loc_eqn == 0x0) { 1271 + if (found_num_root == 0) { 1272 + bit4_root0 = test_root; 1273 + found_num_root = 1; 1274 + } else if (found_num_root == 1) { 1275 + bit4_root1 = test_root; 1276 + found_num_root = 2; 1277 + } else if (found_num_root == 2) { 1278 + bit4_root2 = test_root; 1279 + found_num_root = 3; 1280 + } else { 1281 + found_num_root = 4; 1282 + bit4_root3 = test_root; 1283 + break; 1284 + } 1285 + } 1286 + } 1287 + if (found_num_root != 4) { 1288 + return -EINVAL; 1289 + } else { 1290 + bit4_root0_inv = gf4096_inv(bit4_root0); 1291 + bit4_root1_inv = gf4096_inv(bit4_root1); 1292 + bit4_root2_inv = gf4096_inv(bit4_root2); 1293 + bit4_root3_inv = gf4096_inv(bit4_root3); 1294 + find_4bit_err_pats(chk_syndrome_list[0], 1295 + chk_syndrome_list[1], 1296 + chk_syndrome_list[2], 1297 + chk_syndrome_list[3], 1298 + bit4_root0_inv, bit4_root1_inv, bit4_root2_inv, bit4_root3_inv, err_pats); 1299 + err_info[0] = 0x4; 1300 + err_info[1] = (0x55e - err_pos(bit4_root0_inv)); 1301 + err_info[2] = (0x55e - err_pos(bit4_root1_inv)); 1302 + err_info[3] = (0x55e - err_pos(bit4_root2_inv)); 1303 + err_info[4] = (0x55e - err_pos(bit4_root3_inv)); 1304 + err_info[5] = err_pats[0]; 1305 + err_info[6] = err_pats[1]; 1306 + err_info[7] = err_pats[2]; 1307 + err_info[8] = err_pats[3]; 1308 + return 0; 1309 + } 1310 + } 1311 + 1312 + void correct_12bit_symbol(unsigned char *buf, unsigned short sym, 1313 + unsigned short val) 1314 + { 1315 + if (unlikely(sym > 1366)) { 1316 + printk(KERN_ERR "Error: symbol %d out of range; cannot correct\n", sym); 1317 + } else if (sym == 0) { 1318 + buf[0] ^= val; 1319 + } else if (sym & 1) { 1320 + buf[1+(3*(sym-1))/2] ^= (val >> 4); 1321 + buf[2+(3*(sym-1))/2] ^= ((val & 0xf) << 4); 1322 + } else { 1323 + buf[2+(3*(sym-2))/2] ^= (val >> 8); 1324 + buf[3+(3*(sym-2))/2] ^= (val & 0xff); 1325 + } 1326 + } 1327 + 1328 + static int debugecc = 0; 1329 + module_param(debugecc, int, 0644); 1330 + 1331 + int cafe_correct_ecc(unsigned char *buf, 1332 + unsigned short *chk_syndrome_list) 1333 + { 1334 + unsigned short err_info[9]; 1335 + int i; 1336 + 1337 + if (debugecc) { 1338 + printk(KERN_WARNING "cafe_correct_ecc invoked. Syndromes %x %x %x %x %x %x %x %x\n", 1339 + chk_syndrome_list[0], chk_syndrome_list[1], 1340 + chk_syndrome_list[2], chk_syndrome_list[3], 1341 + chk_syndrome_list[4], chk_syndrome_list[5], 1342 + chk_syndrome_list[6], chk_syndrome_list[7]); 1343 + for (i=0; i < 2048; i+=16) { 1344 + printk(KERN_WARNING "D %04x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 1345 + i, 1346 + buf[i], buf[i+1], buf[i+2], buf[i+3], 1347 + buf[i+4], buf[i+5], buf[i+6], buf[i+7], 1348 + buf[i+8], buf[i+9], buf[i+10], buf[i+11], 1349 + buf[i+12], buf[i+13], buf[i+14], buf[i+15]); 1350 + } 1351 + for ( ; i < 2112; i+=16) { 1352 + printk(KERN_WARNING "O %02x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 1353 + i - 2048, 1354 + buf[i], buf[i+1], buf[i+2], buf[i+3], 1355 + buf[i+4], buf[i+5], buf[i+6], buf[i+7], 1356 + buf[i+8], buf[i+9], buf[i+10], buf[i+11], 1357 + buf[i+12], buf[i+13], buf[i+14], buf[i+15]); 1358 + } 1359 + } 1360 + 1361 + 1362 + 1363 + if (chk_no_err_only(chk_syndrome_list, err_info) && 1364 + chk_1_err_only(chk_syndrome_list, err_info) && 1365 + chk_2_err_only(chk_syndrome_list, err_info) && 1366 + chk_3_err_only(chk_syndrome_list, err_info) && 1367 + chk_4_err_only(chk_syndrome_list, err_info)) { 1368 + return -EIO; 1369 + } 1370 + 1371 + for (i=0; i < err_info[0]; i++) { 1372 + if (debugecc) 1373 + printk(KERN_WARNING "Correct symbol %d with 0x%03x\n", 1374 + err_info[1+i], err_info[5+i]); 1375 + 1376 + correct_12bit_symbol(buf, err_info[1+i], err_info[5+i]); 1377 + } 1378 + 1379 + return err_info[0]; 1380 + } 1381 +