Lines Matching refs:ftl

54 static struct attribute_group *sm_create_sysfs_attributes(struct sm_ftl *ftl)
61 vendor = kstrndup(ftl->cis_buffer + SM_CIS_VENDOR_OFFSET,
104 static void sm_delete_sysfs_attributes(struct sm_ftl *ftl)
106 struct attribute **attributes = ftl->disk_attributes->attrs;
122 kfree(ftl->disk_attributes->attrs);
123 kfree(ftl->disk_attributes);
192 static loff_t sm_mkoffset(struct sm_ftl *ftl, int zone, int block, int boffset)
195 WARN_ON(zone < 0 || zone >= ftl->zone_count);
196 WARN_ON(block >= ftl->zone_size);
197 WARN_ON(boffset >= ftl->block_size);
202 return (zone * SM_MAX_ZONE_SIZE + block) * ftl->block_size + boffset;
206 static void sm_break_offset(struct sm_ftl *ftl, loff_t loffset,
210 *boffset = do_div(offset, ftl->block_size);
211 *block = do_div(offset, ftl->max_lba);
212 *zone = offset >= ftl->zone_count ? -1 : offset;
238 static int sm_read_sector(struct sm_ftl *ftl,
242 struct mtd_info *mtd = ftl->trans->mtd;
259 ops.mode = ftl->smallpagenand ? MTD_OPS_RAW : MTD_OPS_PLACE_OOB;
270 if (zone == 0 && block == ftl->cis_block && boffset ==
271 ftl->cis_boffset)
275 if (try == 3 || sm_recheck_media(ftl))
281 ret = mtd_read_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
310 (ftl->smallpagenand && sm_correct_sector(buffer, oob))) {
321 static int sm_write_sector(struct sm_ftl *ftl,
326 struct mtd_info *mtd = ftl->trans->mtd;
329 BUG_ON(ftl->readonly);
331 if (zone == 0 && (block == ftl->cis_block || block == 0)) {
336 if (ftl->unstable)
339 ops.mode = ftl->smallpagenand ? MTD_OPS_RAW : MTD_OPS_PLACE_OOB;
346 ret = mtd_write_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
354 sm_recheck_media(ftl);
368 static int sm_write_block(struct sm_ftl *ftl, uint8_t *buf,
380 if (ftl->unstable)
383 for (boffset = 0; boffset < ftl->block_size;
397 if (ftl->smallpagenand) {
406 if (!sm_write_sector(ftl, zone, block, boffset,
418 if (sm_erase_block(ftl, zone, block, 0))
424 sm_mark_block_bad(ftl, zone, block);
433 static void sm_mark_block_bad(struct sm_ftl *ftl, int zone, int block)
441 if (ftl->unstable)
444 if (sm_recheck_media(ftl))
452 for (boffset = 0; boffset < ftl->block_size; boffset += SM_SECTOR_SIZE)
453 sm_write_sector(ftl, zone, block, boffset, NULL, &oob);
460 static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
463 struct ftl_zone *zone = &ftl->zones[zone_num];
464 struct mtd_info *mtd = ftl->trans->mtd;
467 erase.addr = sm_mkoffset(ftl, zone_num, block, 0);
468 erase.len = ftl->block_size;
470 if (ftl->unstable)
473 BUG_ON(ftl->readonly);
475 if (zone_num == 0 && (block == ftl->cis_block || block == 0)) {
492 sm_mark_block_bad(ftl, zone_num, block);
497 static int sm_check_block(struct sm_ftl *ftl, int zone, int block)
509 for (boffset = 0; boffset < ftl->block_size;
513 if (sm_read_sector(ftl, zone, block, boffset, NULL, &oob))
528 sm_erase_block(ftl, zone, block, 1);
558 static int sm_get_media_info(struct sm_ftl *ftl, struct mtd_info *mtd)
563 ftl->readonly = mtd->type == MTD_ROM;
566 ftl->zone_count = 1;
567 ftl->smallpagenand = 0;
572 ftl->zone_size = 256;
573 ftl->max_lba = 250;
574 ftl->block_size = 8 * SM_SECTOR_SIZE;
575 ftl->smallpagenand = 1;
581 ftl->zone_size = 512;
582 ftl->max_lba = 500;
583 ftl->block_size = 8 * SM_SECTOR_SIZE;
584 ftl->smallpagenand = 1;
588 if (!ftl->readonly)
591 ftl->zone_size = 256;
592 ftl->max_lba = 250;
593 ftl->block_size = 16 * SM_SECTOR_SIZE;
598 ftl->zone_size = 512;
599 ftl->max_lba = 500;
600 ftl->block_size = 16 * SM_SECTOR_SIZE;
604 ftl->zone_size = 1024;
605 ftl->max_lba = 1000;
606 ftl->block_size = 16 * SM_SECTOR_SIZE;
612 ftl->zone_count = size_in_megs / 16;
613 ftl->zone_size = 1024;
614 ftl->max_lba = 1000;
615 ftl->block_size = 32 * SM_SECTOR_SIZE;
619 if (mtd->erasesize > ftl->block_size)
625 if (ftl->smallpagenand && mtd->oobsize < SM_SMALL_OOB_SIZE)
628 if (!ftl->smallpagenand && mtd->oobsize < SM_OOB_SIZE)
638 ftl->cylinders = chs_table[i].cyl;
639 ftl->heads = chs_table[i].head;
640 ftl->sectors = chs_table[i].sec;
646 ftl->cylinders = 985;
647 ftl->heads = 33;
648 ftl->sectors = 63;
653 static int sm_read_cis(struct sm_ftl *ftl)
657 if (sm_read_sector(ftl,
658 0, ftl->cis_block, ftl->cis_boffset, ftl->cis_buffer, &oob))
664 if (!memcmp(ftl->cis_buffer + ftl->cis_page_offset,
673 static int sm_find_cis(struct sm_ftl *ftl)
681 for (block = 0 ; block < ftl->zone_size - ftl->max_lba ; block++) {
683 if (sm_read_sector(ftl, 0, block, 0, NULL, &oob))
696 for (boffset = 0 ; boffset < ftl->block_size;
699 if (sm_read_sector(ftl, 0, block, boffset, NULL, &oob))
707 if (boffset == ftl->block_size)
710 ftl->cis_block = block;
711 ftl->cis_boffset = boffset;
712 ftl->cis_page_offset = 0;
714 cis_found = !sm_read_cis(ftl);
717 ftl->cis_page_offset = SM_SMALL_PAGE;
718 cis_found = !sm_read_cis(ftl);
723 block * ftl->block_size +
724 boffset + ftl->cis_page_offset);
731 static int sm_recheck_media(struct sm_ftl *ftl)
733 if (sm_read_cis(ftl)) {
735 if (!ftl->unstable) {
737 ftl->unstable = 1;
745 static int sm_init_zone(struct sm_ftl *ftl, int zone_num)
747 struct ftl_zone *zone = &ftl->zones[zone_num];
757 zone->lba_to_phys_table = kmalloc_array(ftl->max_lba, 2, GFP_KERNEL);
761 memset(zone->lba_to_phys_table, -1, ftl->max_lba * 2);
765 if (kfifo_alloc(&zone->free_sectors, ftl->zone_size * 2, GFP_KERNEL)) {
771 for (block = 0 ; block < ftl->zone_size ; block++) {
774 if (zone_num == 0 && block <= ftl->cis_block)
778 if (sm_read_sector(ftl, zone_num, block, 0, NULL, &oob)) {
807 if (lba == -2 || lba >= ftl->max_lba) {
826 if (sm_check_block(ftl, zone_num, block))
830 if (sm_check_block(ftl, zone_num,
841 sm_erase_block(ftl, zone_num, block, 1);
868 static struct ftl_zone *sm_get_zone(struct sm_ftl *ftl, int zone_num)
873 BUG_ON(zone_num >= ftl->zone_count);
874 zone = &ftl->zones[zone_num];
877 error = sm_init_zone(ftl, zone_num);
889 static void sm_cache_init(struct sm_ftl *ftl)
891 ftl->cache_data_invalid_bitmap = 0xFFFFFFFF;
892 ftl->cache_clean = 1;
893 ftl->cache_zone = -1;
894 ftl->cache_block = -1;
895 /*memset(ftl->cache_data, 0xAA, ftl->block_size);*/
899 static void sm_cache_put(struct sm_ftl *ftl, char *buffer, int boffset)
901 memcpy(ftl->cache_data + boffset, buffer, SM_SECTOR_SIZE);
902 clear_bit(boffset / SM_SECTOR_SIZE, &ftl->cache_data_invalid_bitmap);
903 ftl->cache_clean = 0;
907 static int sm_cache_get(struct sm_ftl *ftl, char *buffer, int boffset)
910 &ftl->cache_data_invalid_bitmap))
913 memcpy(buffer, ftl->cache_data + boffset, SM_SECTOR_SIZE);
918 static int sm_cache_flush(struct sm_ftl *ftl)
924 int zone_num = ftl->cache_zone;
927 if (ftl->cache_clean)
930 if (ftl->unstable)
934 zone = &ftl->zones[zone_num];
935 block_num = zone->lba_to_phys_table[ftl->cache_block];
939 for_each_set_bit(sector_num, &ftl->cache_data_invalid_bitmap,
940 ftl->block_size / SM_SECTOR_SIZE) {
942 if (!sm_read_sector(ftl,
944 ftl->cache_data + sector_num * SM_SECTOR_SIZE, NULL))
946 &ftl->cache_data_invalid_bitmap);
950 if (ftl->unstable)
964 if (sm_write_block(ftl, ftl->cache_data, zone_num, write_sector,
965 ftl->cache_block, ftl->cache_data_invalid_bitmap))
969 zone->lba_to_phys_table[ftl->cache_block] = write_sector;
973 sm_erase_block(ftl, zone_num, block_num, 1);
975 sm_cache_init(ftl);
983 struct sm_ftl *ftl = from_timer(ftl, t, timer);
984 queue_work(cache_flush_workqueue, &ftl->flush_work);
990 struct sm_ftl *ftl = container_of(work, struct sm_ftl, flush_work);
991 mutex_lock(&ftl->mutex);
992 sm_cache_flush(ftl);
993 mutex_unlock(&ftl->mutex);
1003 struct sm_ftl *ftl = dev->priv;
1008 sm_break_offset(ftl, sect_no << 9, &zone_num, &block, &boffset);
1009 mutex_lock(&ftl->mutex);
1012 zone = sm_get_zone(ftl, zone_num);
1019 if (ftl->cache_zone == zone_num && ftl->cache_block == block) {
1021 if (!sm_cache_get(ftl, buf, boffset))
1033 if (sm_read_sector(ftl, zone_num, block, boffset, buf, NULL)) {
1039 sm_cache_put(ftl, buf, boffset);
1041 mutex_unlock(&ftl->mutex);
1049 struct sm_ftl *ftl = dev->priv;
1053 BUG_ON(ftl->readonly);
1054 sm_break_offset(ftl, sec_no << 9, &zone_num, &block, &boffset);
1057 del_timer(&ftl->timer);
1058 mutex_lock(&ftl->mutex);
1060 zone = sm_get_zone(ftl, zone_num);
1067 if (ftl->cache_block != block || ftl->cache_zone != zone_num) {
1069 error = sm_cache_flush(ftl);
1073 ftl->cache_block = block;
1074 ftl->cache_zone = zone_num;
1077 sm_cache_put(ftl, buf, boffset);
1079 mod_timer(&ftl->timer, jiffies + msecs_to_jiffies(cache_timeout));
1080 mutex_unlock(&ftl->mutex);
1087 struct sm_ftl *ftl = dev->priv;
1090 mutex_lock(&ftl->mutex);
1091 retval = sm_cache_flush(ftl);
1092 mutex_unlock(&ftl->mutex);
1099 struct sm_ftl *ftl = dev->priv;
1101 del_timer_sync(&ftl->timer);
1102 cancel_work_sync(&ftl->flush_work);
1103 mutex_lock(&ftl->mutex);
1104 sm_cache_flush(ftl);
1105 mutex_unlock(&ftl->mutex);
1111 struct sm_ftl *ftl = dev->priv;
1112 geo->heads = ftl->heads;
1113 geo->sectors = ftl->sectors;
1114 geo->cylinders = ftl->cylinders;
1122 struct sm_ftl *ftl;
1125 ftl = kzalloc(sizeof(struct sm_ftl), GFP_KERNEL);
1126 if (!ftl)
1130 mutex_init(&ftl->mutex);
1131 timer_setup(&ftl->timer, sm_cache_flush_timer, 0);
1132 INIT_WORK(&ftl->flush_work, sm_cache_flush_work);
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 = kcalloc(ftl->zone_count, sizeof(struct ftl_zone),
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 if (!ftl->disk_attributes)
1183 trans->disk_attributes = ftl->disk_attributes;
1190 ftl->zone_count, ftl->max_lba,
1191 ftl->zone_size - ftl->max_lba);
1193 ftl->block_size);
1205 kfree(ftl->cache_data);
1207 kfree(ftl->zones);
1209 kfree(ftl->cis_buffer);
1211 kfree(ftl);
1219 struct sm_ftl *ftl = dev->priv;
1223 ftl->trans = NULL;
1225 for (i = 0 ; i < ftl->zone_count; i++) {
1227 if (!ftl->zones[i].initialized)
1230 kfree(ftl->zones[i].lba_to_phys_table);
1231 kfifo_free(&ftl->zones[i].free_sectors);
1234 sm_delete_sysfs_attributes(ftl);
1235 kfree(ftl->cis_buffer);
1236 kfree(ftl->zones);
1237 kfree(ftl->cache_data);
1238 kfree(ftl);