Lines Matching refs:ftl
57 struct attribute_group *sm_create_sysfs_attributes(struct sm_ftl *ftl)
63 int vendor_len = strnlen(ftl->cis_buffer + SM_CIS_VENDOR_OFFSET,
67 memcpy(vendor, ftl->cis_buffer + SM_CIS_VENDOR_OFFSET, vendor_len);
94 void sm_delete_sysfs_attributes(struct sm_ftl *ftl)
96 struct attribute **attributes = ftl->disk_attributes->attrs;
112 kfree(ftl->disk_attributes->attrs);
113 kfree(ftl->disk_attributes);
182 static loff_t sm_mkoffset(struct sm_ftl *ftl, int zone, int block, int boffset)
185 WARN_ON(zone < 0 || zone >= ftl->zone_count);
186 WARN_ON(block >= ftl->zone_size);
187 WARN_ON(boffset >= ftl->block_size);
192 return (zone * SM_MAX_ZONE_SIZE + block) * ftl->block_size + boffset;
196 static void sm_break_offset(struct sm_ftl *ftl, loff_t offset,
199 *boffset = do_div(offset, ftl->block_size);
200 *block = do_div(offset, ftl->max_lba);
201 *zone = offset >= ftl->zone_count ? -1 : offset;
223 static int sm_read_sector(struct sm_ftl *ftl,
227 struct mtd_info *mtd = ftl->trans->mtd;
243 ops.mode = ftl->smallpagenand ? MTD_OOB_RAW : MTD_OOB_PLACE;
254 if (zone == 0 && block == ftl->cis_block && boffset ==
255 ftl->cis_boffset)
259 if (try == 3 || sm_recheck_media(ftl))
265 ret = mtd->read_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
294 (ftl->smallpagenand && sm_correct_sector(buffer, oob))) {
305 static int sm_write_sector(struct sm_ftl *ftl,
310 struct mtd_info *mtd = ftl->trans->mtd;
313 BUG_ON(ftl->readonly);
315 if (zone == 0 && (block == ftl->cis_block || block == 0)) {
320 if (ftl->unstable)
323 ops.mode = ftl->smallpagenand ? MTD_OOB_RAW : MTD_OOB_PLACE;
330 ret = mtd->write_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
339 sm_recheck_media(ftl);
353 static int sm_write_block(struct sm_ftl *ftl, uint8_t *buf,
365 if (ftl->unstable)
368 for (boffset = 0; boffset < ftl->block_size;
382 if (ftl->smallpagenand) {
389 if (!sm_write_sector(ftl, zone, block, boffset,
401 if (sm_erase_block(ftl, zone, block, 0))
407 sm_mark_block_bad(ftl, zone, block);
416 static void sm_mark_block_bad(struct sm_ftl *ftl, int zone, int block)
424 if (ftl->unstable)
427 if (sm_recheck_media(ftl))
435 for (boffset = 0; boffset < ftl->block_size; boffset += SM_SECTOR_SIZE)
436 sm_write_sector(ftl, zone, block, boffset, NULL, &oob);
443 static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
446 struct ftl_zone *zone = &ftl->zones[zone_num];
447 struct mtd_info *mtd = ftl->trans->mtd;
452 erase.addr = sm_mkoffset(ftl, zone_num, block, 0);
453 erase.len = ftl->block_size;
454 erase.priv = (u_long)ftl;
456 if (ftl->unstable)
459 BUG_ON(ftl->readonly);
461 if (zone_num == 0 && (block == ftl->cis_block || block == 0)) {
473 wait_for_completion(&ftl->erase_completion);
487 sm_mark_block_bad(ftl, zone_num, block);
493 struct sm_ftl *ftl = (struct sm_ftl *)self->priv;
494 complete(&ftl->erase_completion);
498 static int sm_check_block(struct sm_ftl *ftl, int zone, int block)
510 for (boffset = 0; boffset < ftl->block_size;
514 if (sm_read_sector(ftl, zone, block, boffset, NULL, &oob))
529 sm_erase_block(ftl, zone, block, 1);
559 int sm_get_media_info(struct sm_ftl *ftl, struct mtd_info *mtd)
564 ftl->readonly = mtd->type == MTD_ROM;
567 ftl->zone_count = 1;
568 ftl->smallpagenand = 0;
573 ftl->zone_size = 256;
574 ftl->max_lba = 250;
575 ftl->block_size = 8 * SM_SECTOR_SIZE;
576 ftl->smallpagenand = 1;
582 ftl->zone_size = 512;
583 ftl->max_lba = 500;
584 ftl->block_size = 8 * SM_SECTOR_SIZE;
585 ftl->smallpagenand = 1;
589 if (!ftl->readonly)
592 ftl->zone_size = 256;
593 ftl->max_lba = 250;
594 ftl->block_size = 16 * SM_SECTOR_SIZE;
599 ftl->zone_size = 512;
600 ftl->max_lba = 500;
601 ftl->block_size = 16 * SM_SECTOR_SIZE;
605 ftl->zone_size = 1024;
606 ftl->max_lba = 1000;
607 ftl->block_size = 16 * SM_SECTOR_SIZE;
613 ftl->zone_count = size_in_megs / 16;
614 ftl->zone_size = 1024;
615 ftl->max_lba = 1000;
616 ftl->block_size = 32 * SM_SECTOR_SIZE;
620 if (mtd->erasesize > ftl->block_size)
626 if (ftl->smallpagenand && mtd->oobsize < SM_SMALL_OOB_SIZE)
629 if (!ftl->smallpagenand && mtd->oobsize < SM_OOB_SIZE)
639 ftl->cylinders = chs_table[i].cyl;
640 ftl->heads = chs_table[i].head;
641 ftl->sectors = chs_table[i].sec;
647 ftl->cylinders = 985;
648 ftl->heads = 33;
649 ftl->sectors = 63;
654 static int sm_read_cis(struct sm_ftl *ftl)
658 if (sm_read_sector(ftl,
659 0, ftl->cis_block, ftl->cis_boffset, ftl->cis_buffer, &oob))
665 if (!memcmp(ftl->cis_buffer + ftl->cis_page_offset,
674 static int sm_find_cis(struct sm_ftl *ftl)
682 for (block = 0 ; block < ftl->zone_size - ftl->max_lba ; block++) {
684 if (sm_read_sector(ftl, 0, block, 0, NULL, &oob))
697 for (boffset = 0 ; boffset < ftl->block_size;
700 if (sm_read_sector(ftl, 0, block, boffset, NULL, &oob))
708 if (boffset == ftl->block_size)
711 ftl->cis_block = block;
712 ftl->cis_boffset = boffset;
713 ftl->cis_page_offset = 0;
715 cis_found = !sm_read_cis(ftl);
718 ftl->cis_page_offset = SM_SMALL_PAGE;
719 cis_found = !sm_read_cis(ftl);
724 block * ftl->block_size +
725 boffset + ftl->cis_page_offset);
732 static int sm_recheck_media(struct sm_ftl *ftl)
734 if (sm_read_cis(ftl)) {
736 if (!ftl->unstable) {
738 ftl->unstable = 1;
746 static int sm_init_zone(struct sm_ftl *ftl, int zone_num)
748 struct ftl_zone *zone = &ftl->zones[zone_num];
758 zone->lba_to_phys_table = kmalloc(ftl->max_lba * 2, GFP_KERNEL);
762 memset(zone->lba_to_phys_table, -1, ftl->max_lba * 2);
766 if (kfifo_alloc(&zone->free_sectors, ftl->zone_size * 2, GFP_KERNEL)) {
772 for (block = 0 ; block < ftl->zone_size ; block++) {
775 if (zone_num == 0 && block <= ftl->cis_block)
779 if (sm_read_sector(ftl, zone_num, block, 0, NULL, &oob))
805 if (lba == -2 || lba >= ftl->max_lba) {
824 if (sm_check_block(ftl, zone_num, block))
828 if (sm_check_block(ftl, zone_num,
839 sm_erase_block(ftl, zone_num, block, 1);
866 struct ftl_zone *sm_get_zone(struct sm_ftl *ftl, int zone_num)
871 BUG_ON(zone_num >= ftl->zone_count);
872 zone = &ftl->zones[zone_num];
875 error = sm_init_zone(ftl, zone_num);
887 void sm_cache_init(struct sm_ftl *ftl)
889 ftl->cache_data_invalid_bitmap = 0xFFFFFFFF;
890 ftl->cache_clean = 1;
891 ftl->cache_zone = -1;
892 ftl->cache_block = -1;
893 /*memset(ftl->cache_data, 0xAA, ftl->block_size);*/
897 void sm_cache_put(struct sm_ftl *ftl, char *buffer, int boffset)
899 memcpy(ftl->cache_data + boffset, buffer, SM_SECTOR_SIZE);
900 clear_bit(boffset / SM_SECTOR_SIZE, &ftl->cache_data_invalid_bitmap);
901 ftl->cache_clean = 0;
905 int sm_cache_get(struct sm_ftl *ftl, char *buffer, int boffset)
908 &ftl->cache_data_invalid_bitmap))
911 memcpy(buffer, ftl->cache_data + boffset, SM_SECTOR_SIZE);
916 int sm_cache_flush(struct sm_ftl *ftl)
922 int zone_num = ftl->cache_zone;
925 if (ftl->cache_clean)
928 if (ftl->unstable)
932 zone = &ftl->zones[zone_num];
933 block_num = zone->lba_to_phys_table[ftl->cache_block];
937 for_each_set_bit(sector_num, &ftl->cache_data_invalid_bitmap,
938 ftl->block_size / SM_SECTOR_SIZE) {
940 if (!sm_read_sector(ftl,
942 ftl->cache_data + sector_num * SM_SECTOR_SIZE, NULL))
944 &ftl->cache_data_invalid_bitmap);
948 if (ftl->unstable)
962 if (sm_write_block(ftl, ftl->cache_data, zone_num, write_sector,
963 ftl->cache_block, ftl->cache_data_invalid_bitmap))
967 zone->lba_to_phys_table[ftl->cache_block] = write_sector;
971 sm_erase_block(ftl, zone_num, block_num, 1);
973 sm_cache_init(ftl);
981 struct sm_ftl *ftl = (struct sm_ftl *)data;
982 queue_work(cache_flush_workqueue, &ftl->flush_work);
988 struct sm_ftl *ftl = container_of(work, struct sm_ftl, flush_work);
989 mutex_lock(&ftl->mutex);
990 sm_cache_flush(ftl);
991 mutex_unlock(&ftl->mutex);
1001 struct sm_ftl *ftl = dev->priv;
1006 sm_break_offset(ftl, sect_no << 9, &zone_num, &block, &boffset);
1007 mutex_lock(&ftl->mutex);
1010 zone = sm_get_zone(ftl, zone_num);
1017 if (ftl->cache_zone == zone_num && ftl->cache_block == block) {
1019 if (!sm_cache_get(ftl, buf, boffset))
1031 if (sm_read_sector(ftl, zone_num, block, boffset, buf, NULL)) {
1037 sm_cache_put(ftl, buf, boffset);
1039 mutex_unlock(&ftl->mutex);
1047 struct sm_ftl *ftl = dev->priv;
1051 BUG_ON(ftl->readonly);
1052 sm_break_offset(ftl, sec_no << 9, &zone_num, &block, &boffset);
1055 del_timer(&ftl->timer);
1056 mutex_lock(&ftl->mutex);
1058 zone = sm_get_zone(ftl, zone_num);
1065 if (ftl->cache_block != block || ftl->cache_zone != zone_num) {
1067 error = sm_cache_flush(ftl);
1071 ftl->cache_block = block;
1072 ftl->cache_zone = zone_num;
1075 sm_cache_put(ftl, buf, boffset);
1077 mod_timer(&ftl->timer, jiffies + msecs_to_jiffies(cache_timeout));
1078 mutex_unlock(&ftl->mutex);
1085 struct sm_ftl *ftl = dev->priv;
1088 mutex_lock(&ftl->mutex);
1089 retval = sm_cache_flush(ftl);
1090 mutex_unlock(&ftl->mutex);
1097 struct sm_ftl *ftl = dev->priv;
1099 mutex_lock(&ftl->mutex);
1100 del_timer_sync(&ftl->timer);
1101 cancel_work_sync(&ftl->flush_work);
1102 sm_cache_flush(ftl);
1103 mutex_unlock(&ftl->mutex);
1110 struct sm_ftl *ftl = dev->priv;
1111 geo->heads = ftl->heads;
1112 geo->sectors = ftl->sectors;
1113 geo->cylinders = ftl->cylinders;
1121 struct sm_ftl *ftl;
1124 ftl = kzalloc(sizeof(struct sm_ftl), GFP_KERNEL);
1125 if (!ftl)
1129 mutex_init(&ftl->mutex);
1130 setup_timer(&ftl->timer, sm_cache_flush_timer, (unsigned long)ftl);
1131 INIT_WORK(&ftl->flush_work, sm_cache_flush_work);
1132 init_completion(&ftl->erase_completion);
1135 if (sm_get_media_info(ftl, mtd)) {
1142 ftl->cis_buffer = kzalloc(SM_SECTOR_SIZE, GFP_KERNEL);
1143 if (!ftl->cis_buffer)
1147 ftl->zones = kzalloc(sizeof(struct ftl_zone) * ftl->zone_count,
1149 if (!ftl->zones)
1153 ftl->cache_data = kzalloc(ftl->block_size, GFP_KERNEL);
1155 if (!ftl->cache_data)
1158 sm_cache_init(ftl);
1166 ftl->trans = trans;
1167 trans->priv = ftl;
1172 trans->size = (ftl->block_size * ftl->max_lba * ftl->zone_count) >> 9;
1173 trans->readonly = ftl->readonly;
1175 if (sm_find_cis(ftl)) {
1180 ftl->disk_attributes = sm_create_sysfs_attributes(ftl);
1181 trans->disk_attributes = ftl->disk_attributes;
1188 ftl->zone_count, ftl->max_lba,
1189 ftl->zone_size - ftl->max_lba);
1191 ftl->block_size);
1203 kfree(ftl->cache_data);
1205 kfree(ftl->zones);
1207 kfree(ftl->cis_buffer);
1209 kfree(ftl);
1217 struct sm_ftl *ftl = dev->priv;
1221 ftl->trans = NULL;
1223 for (i = 0 ; i < ftl->zone_count; i++) {
1225 if (!ftl->zones[i].initialized)
1228 kfree(ftl->zones[i].lba_to_phys_table);
1229 kfifo_free(&ftl->zones[i].free_sectors);
1232 sm_delete_sysfs_attributes(ftl);
1233 kfree(ftl->cis_buffer);
1234 kfree(ftl->zones);
1235 kfree(ftl->cache_data);
1236 kfree(ftl);