10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/random.h>
17 #include <linux/bitops.h>
18 #include <linux/slab.h>
27 static int cache_timeout = 1000;
30 "Timeout (in ms) for cache flush (1000 ms default");
55 #define NUM_ATTRIBUTES 1
56 #define SM_CIS_VENDOR_OFFSET 0x59
70 vendor[vendor_len] = 0;
75 if (!vendor_attribute)
81 vendor_attribute->
len = vendor_len;
82 vendor_attribute->
dev_attr.attr.name =
"vendor";
92 attributes[0] = &vendor_attribute->
dev_attr.attr;
103 kfree(vendor_attribute);
115 for (i = 0; attributes[
i] ; i++) {
138 if ((lba[0] & 0xF8) != 0x10)
145 return (lba[1] >> 1) | ((lba[0] & 0x07) << 7);
154 static int sm_read_lba(
struct sm_oob *oob)
156 static const uint32_t erased_pattern[4] = {
157 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
186 tmp[0] = 0x10 | ((lba >> 7) & 0x07);
187 tmp[1] = (lba << 1) & 0xFF;
198 static loff_t sm_mkoffset(
struct sm_ftl *ftl,
int zone,
int block,
int boffset)
212 static void sm_break_offset(
struct sm_ftl *ftl, loff_t
offset,
213 int *zone,
int *block,
int *boffset)
239 static int sm_read_sector(
struct sm_ftl *ftl,
240 int zone,
int block,
int boffset,
262 ops.oobbuf = (
void *)oob;
270 if (zone == 0 && block == ftl->
cis_block && boffset ==
275 if (
try == 3 || sm_recheck_media(ftl))
281 ret =
mtd_read_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
284 if (ret != 0 && !mtd_is_bitflip_or_eccerr(ret)) {
285 dbg(
"read of block %d at zone %d, failed due to error (%d)",
302 if (!sm_sector_valid(oob)) {
303 dbg(
"read of block %d at zone %d, failed because it is marked"
304 " as bad" , block, zone);
309 if (mtd_is_eccerr(ret) ||
312 dbg(
"read of block %d at zone %d, failed due to ECC error",
321 static int sm_write_sector(
struct sm_ftl *ftl,
322 int zone,
int block,
int boffset,
331 if (zone == 0 && (block == ftl->
cis_block || block == 0)) {
332 dbg(
"attempted to write the CIS!");
344 ops.oobbuf = (
void *)oob;
346 ret = mtd_write_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
351 dbg(
"write to block %d at zone %d, failed with error %d",
354 sm_recheck_media(ftl);
369 int zone,
int block,
int lba,
370 unsigned long invalid_bitmap)
378 sm_write_lba(&oob, lba);
390 sm_printk(
"sector %d of block at LBA %d of zone %d"
391 " coudn't be read, marking it as invalid",
404 if (!sm_write_sector(ftl, zone, block, boffset,
405 buf + boffset, &oob))
416 if (sm_erase_block(ftl, zone, block, 0))
422 sm_mark_block_bad(ftl, zone, block);
431 static void sm_mark_block_bad(
struct sm_ftl *ftl,
int zone,
int block)
442 if (sm_recheck_media(ftl))
445 sm_printk(
"marking block %d of zone %d as bad", block, zone);
451 sm_write_sector(ftl, zone, block, boffset,
NULL, &oob);
458 static int sm_erase_block(
struct sm_ftl *ftl,
int zone_num,
uint16_t block,
466 erase.callback = sm_erase_callback;
467 erase.addr = sm_mkoffset(ftl, zone_num, block, 0);
476 if (zone_num == 0 && (block == ftl->
cis_block || block == 0)) {
477 sm_printk(
"attempted to erase the CIS!");
482 sm_printk(
"erase of block %d in zone %d failed",
491 sm_printk(
"erase of block %d in zone %d failed after wait",
498 (
const unsigned char *)&block,
sizeof(block));
502 sm_mark_block_bad(ftl, zone_num, block);
506 static void sm_erase_callback(
struct erase_info *
self)
513 static int sm_check_block(
struct sm_ftl *ftl,
int zone,
int block)
517 int lbas[] = { -3, 0, 0, 0 };
529 if (sm_read_sector(ftl, zone, block, boffset,
NULL, &oob))
532 test_lba = sm_read_lba(&oob);
534 if (lbas[i] != test_lba)
535 lbas[++
i] = test_lba;
544 sm_erase_block(ftl, zone, block, 1);
552 static const struct chs_entry chs_table[] = {
560 { 128, 500, 16, 32 },
561 { 256, 1000, 16, 32 },
562 { 512, 1015, 32, 63 },
563 { 1024, 985, 33, 63 },
564 { 2048, 985, 33, 63 },
569 static const uint8_t cis_signature[] = {
570 0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02, 0xDF, 0x01, 0x20
577 int size_in_megs = mtd->
size / (1024 * 1024);
585 switch (size_in_megs) {
627 if (size_in_megs >= 16) {
648 if (!mtd_has_oob(mtd))
652 for (i = 0 ; i <
ARRAY_SIZE(chs_table) ; i++) {
653 if (chs_table[i].
size == size_in_megs) {
661 sm_printk(
"media has unknown size : %dMiB", size_in_megs);
669 static int sm_read_cis(
struct sm_ftl *ftl)
673 if (sm_read_sector(ftl,
677 if (!sm_sector_valid(&oob) || !sm_block_valid(&oob))
681 cis_signature,
sizeof(cis_signature))) {
689 static int sm_find_cis(
struct sm_ftl *ftl)
699 if (sm_read_sector(ftl, 0, block, 0,
NULL, &oob))
702 if (!sm_block_valid(&oob))
715 if (sm_read_sector(ftl, 0, block, boffset,
NULL, &oob))
718 if (!sm_sector_valid(&oob))
730 cis_found = !sm_read_cis(ftl);
734 cis_found = !sm_read_cis(ftl);
738 dbg(
"CIS block found at offset %x",
747 static int sm_recheck_media(
struct sm_ftl *ftl)
749 if (sm_read_cis(ftl)) {
752 sm_printk(
"media unstable, not allowing writes");
761 static int sm_init_zone(
struct sm_ftl *ftl,
int zone_num)
770 dbg(
"initializing zone %d", zone_num);
787 for (block = 0 ; block < ftl->
zone_size ; block++) {
794 if (sm_read_sector(ftl, zone_num, block, 0,
NULL, &oob))
799 if (sm_block_erased(&oob)) {
801 (
unsigned char *)&block, 2);
809 if (!sm_block_valid(&oob)) {
810 dbg(
"PH %04d <-> <marked bad>", block);
815 lba = sm_read_lba(&oob);
820 if (lba == -2 || lba >= ftl->
max_lba) {
821 dbg(
"PH %04d <-> LBA %04d(bad)", block, lba);
835 " of LBA %d between blocks %d and %d in zone %d",
839 if (sm_check_block(ftl, zone_num, block))
843 if (sm_check_block(ftl, zone_num,
853 sm_printk(
"both blocks are valid, erasing the later");
854 sm_erase_block(ftl, zone_num, block, 1);
857 dbg(
"zone initialized");
863 sm_printk(
"no free blocks in zone %d", zone_num);
873 (
unsigned char *)&block, 2);
887 zone = &ftl->
zones[zone_num];
890 error = sm_init_zone(ftl, zone_num);
893 return ERR_PTR(error);
947 zone = &ftl->
zones[zone_num];
955 if (!sm_read_sector(ftl,
971 (
unsigned char *)&write_sector, 2) != 2) {
972 dbg(
"no free sectors for write!");
977 if (sm_write_block(ftl, ftl->
cache_data, zone_num, write_sector,
986 sm_erase_block(ftl, zone_num, block_num, 1);
994 static void sm_cache_flush_timer(
unsigned long data)
1014 unsigned long sect_no,
char *buf)
1018 int error = 0, in_cache = 0;
1019 int zone_num,
block, boffset;
1021 sm_break_offset(ftl, sect_no << 9, &zone_num, &block, &boffset);
1027 error = PTR_ERR(zone);
1046 if (sm_read_sector(ftl, zone_num, block, boffset, buf,
NULL)) {
1060 unsigned long sec_no,
char *buf)
1067 sm_break_offset(ftl, sec_no << 9, &zone_num, &block, &boffset);
1075 error = PTR_ERR(zone);
1151 dbg(
"found unsupported mtd device, aborting");
1190 if (sm_find_cis(ftl)) {
1191 dbg(
"CIS not found on mtd device, aborting");
1200 sm_printk(
"Found %d MiB xD/SmartMedia FTL on mtd%d",
1201 (
int)(mtd->
size / (1024 * 1024)), mtd->
index);
1204 dbg(
"%d zone(s), each consists of %d blocks (+%d spares)",
1207 dbg(
"each block consists of %d bytes",
1213 dbg(
"error in mtdblktrans layer");
1242 if (!ftl->
zones[i].initialized)
1261 .getgeo = sm_getgeo,
1263 .add_mtd = sm_add_mtd,
1264 .remove_dev = sm_remove_dev,
1266 .readsect = sm_read,
1267 .writesect = sm_write,
1270 .release = sm_release,
1275 static __init int sm_module_init(
void)
1280 if (IS_ERR(cache_flush_workqueue))
1281 return PTR_ERR(cache_flush_workqueue);
1290 static void __exit sm_module_exit(
void)