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;
237 static int sm_read_sector(struct sm_ftl *ftl,
241 struct mtd_info *mtd = ftl->trans->mtd;
258 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))
282 ret = mtd_read_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
311 (ftl->smallpagenand && sm_correct_sector(buffer, oob))) {
322 static int sm_write_sector(struct sm_ftl *ftl,
327 struct mtd_info *mtd = ftl->trans->mtd;
330 BUG_ON(ftl->readonly);
332 if (zone == 0 && (block == ftl->cis_block || block == 0)) {
337 if (ftl->unstable)
340 ops.mode = ftl->smallpagenand ? MTD_OPS_RAW : MTD_OPS_PLACE_OOB;
347 ret = mtd_write_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
355 sm_recheck_media(ftl);
369 static int sm_write_block(struct sm_ftl *ftl, uint8_t *buf,
382 if (ftl->unstable)
385 for (boffset = 0; boffset < ftl->block_size;
399 if (ftl->smallpagenand) {
408 if (!sm_write_sector(ftl, zone, block, boffset,
421 if (sm_erase_block(ftl, zone, block, 0))
427 sm_mark_block_bad(ftl, zone, block);
436 static void sm_mark_block_bad(struct sm_ftl *ftl, int zone, int block)
444 if (ftl->unstable)
447 if (sm_recheck_media(ftl))
456 for (boffset = 0; boffset < ftl->block_size; boffset += SM_SECTOR_SIZE)
457 sm_write_sector(ftl, zone, block, boffset, NULL, &oob);
464 static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
467 struct ftl_zone *zone = &ftl->zones[zone_num];
468 struct mtd_info *mtd = ftl->trans->mtd;
471 erase.addr = sm_mkoffset(ftl, zone_num, block, 0);
472 erase.len = ftl->block_size;
474 if (ftl->unstable)
477 BUG_ON(ftl->readonly);
479 if (zone_num == 0 && (block == ftl->cis_block || block == 0)) {
496 sm_mark_block_bad(ftl, zone_num, block);
501 static int sm_check_block(struct sm_ftl *ftl, int zone, int block)
514 for (boffset = 0; boffset < ftl->block_size;
518 if (sm_read_sector(ftl, zone, block, boffset, NULL, &oob))
533 sm_erase_block(ftl, zone, block, 1);
564 static int sm_get_media_info(struct sm_ftl *ftl, struct mtd_info *mtd)
569 ftl->readonly = mtd->type == MTD_ROM;
572 ftl->zone_count = 1;
573 ftl->smallpagenand = 0;
578 ftl->zone_size = 256;
579 ftl->max_lba = 250;
580 ftl->block_size = 8 * SM_SECTOR_SIZE;
581 ftl->smallpagenand = 1;
587 ftl->zone_size = 512;
588 ftl->max_lba = 500;
589 ftl->block_size = 8 * SM_SECTOR_SIZE;
590 ftl->smallpagenand = 1;
594 if (!ftl->readonly)
597 ftl->zone_size = 256;
598 ftl->max_lba = 250;
599 ftl->block_size = 16 * SM_SECTOR_SIZE;
604 ftl->zone_size = 512;
605 ftl->max_lba = 500;
606 ftl->block_size = 16 * SM_SECTOR_SIZE;
610 ftl->zone_size = 1024;
611 ftl->max_lba = 1000;
612 ftl->block_size = 16 * SM_SECTOR_SIZE;
619 ftl->zone_count = size_in_megs / 16;
620 ftl->zone_size = 1024;
621 ftl->max_lba = 1000;
622 ftl->block_size = 32 * SM_SECTOR_SIZE;
626 if (mtd->erasesize > ftl->block_size)
632 if (ftl->smallpagenand && mtd->oobsize < SM_SMALL_OOB_SIZE)
635 if (!ftl->smallpagenand && mtd->oobsize < SM_OOB_SIZE)
645 ftl->cylinders = chs_table[i].cyl;
646 ftl->heads = chs_table[i].head;
647 ftl->sectors = chs_table[i].sec;
653 ftl->cylinders = 985;
654 ftl->heads = 33;
655 ftl->sectors = 63;
660 static int sm_read_cis(struct sm_ftl *ftl)
664 if (sm_read_sector(ftl,
665 0, ftl->cis_block, ftl->cis_boffset, ftl->cis_buffer, &oob))
671 if (!memcmp(ftl->cis_buffer + ftl->cis_page_offset,
680 static int sm_find_cis(struct sm_ftl *ftl)
688 for (block = 0 ; block < ftl->zone_size - ftl->max_lba ; block++) {
690 if (sm_read_sector(ftl, 0, block, 0, NULL, &oob))
703 for (boffset = 0 ; boffset < ftl->block_size;
706 if (sm_read_sector(ftl, 0, block, boffset, NULL, &oob))
714 if (boffset == ftl->block_size)
717 ftl->cis_block = block;
718 ftl->cis_boffset = boffset;
719 ftl->cis_page_offset = 0;
721 cis_found = !sm_read_cis(ftl);
724 ftl->cis_page_offset = SM_SMALL_PAGE;
725 cis_found = !sm_read_cis(ftl);
730 block * ftl->block_size +
731 boffset + ftl->cis_page_offset);
738 static int sm_recheck_media(struct sm_ftl *ftl)
740 if (sm_read_cis(ftl)) {
742 if (!ftl->unstable) {
744 ftl->unstable = 1;
752 static int sm_init_zone(struct sm_ftl *ftl, int zone_num)
754 struct ftl_zone *zone = &ftl->zones[zone_num];
764 zone->lba_to_phys_table = kmalloc_array(ftl->max_lba, 2, GFP_KERNEL);
768 memset(zone->lba_to_phys_table, -1, ftl->max_lba * 2);
772 if (kfifo_alloc(&zone->free_sectors, ftl->zone_size * 2, GFP_KERNEL)) {
778 for (block = 0 ; block < ftl->zone_size ; block++) {
781 if (zone_num == 0 && block <= ftl->cis_block)
785 if (sm_read_sector(ftl, zone_num, block, 0, NULL, &oob)) {
817 if (lba == -2 || lba >= ftl->max_lba) {
837 if (sm_check_block(ftl, zone_num, block))
841 if (sm_check_block(ftl, zone_num,
852 sm_erase_block(ftl, zone_num, block, 1);
880 static struct ftl_zone *sm_get_zone(struct sm_ftl *ftl, int zone_num)
885 BUG_ON(zone_num >= ftl->zone_count);
886 zone = &ftl->zones[zone_num];
889 error = sm_init_zone(ftl, zone_num);
901 static void sm_cache_init(struct sm_ftl *ftl)
903 ftl->cache_data_invalid_bitmap = 0xFFFFFFFF;
904 ftl->cache_clean = 1;
905 ftl->cache_zone = -1;
906 ftl->cache_block = -1;
907 /*memset(ftl->cache_data, 0xAA, ftl->block_size);*/
911 static void sm_cache_put(struct sm_ftl *ftl, char *buffer, int boffset)
913 memcpy(ftl->cache_data + boffset, buffer, SM_SECTOR_SIZE);
914 clear_bit(boffset / SM_SECTOR_SIZE, &ftl->cache_data_invalid_bitmap);
915 ftl->cache_clean = 0;
919 static int sm_cache_get(struct sm_ftl *ftl, char *buffer, int boffset)
922 &ftl->cache_data_invalid_bitmap))
925 memcpy(buffer, ftl->cache_data + boffset, SM_SECTOR_SIZE);
930 static int sm_cache_flush(struct sm_ftl *ftl)
936 int zone_num = ftl->cache_zone;
939 if (ftl->cache_clean)
942 if (ftl->unstable)
946 zone = &ftl->zones[zone_num];
947 block_num = zone->lba_to_phys_table[ftl->cache_block];
951 for_each_set_bit(sector_num, &ftl->cache_data_invalid_bitmap,
952 ftl->block_size / SM_SECTOR_SIZE) {
954 if (!sm_read_sector(ftl,
956 ftl->cache_data + sector_num * SM_SECTOR_SIZE, NULL))
958 &ftl->cache_data_invalid_bitmap);
962 if (ftl->unstable)
977 if (sm_write_block(ftl, ftl->cache_data, zone_num, write_sector,
978 ftl->cache_block, ftl->cache_data_invalid_bitmap))
982 zone->lba_to_phys_table[ftl->cache_block] = write_sector;
986 sm_erase_block(ftl, zone_num, block_num, 1);
988 sm_cache_init(ftl);
996 struct sm_ftl *ftl = from_timer(ftl, t, timer);
997 queue_work(cache_flush_workqueue, &ftl->flush_work);
1003 struct sm_ftl *ftl = container_of(work, struct sm_ftl, flush_work);
1004 mutex_lock(&ftl->mutex);
1005 sm_cache_flush(ftl);
1006 mutex_unlock(&ftl->mutex);
1016 struct sm_ftl *ftl = dev->priv;
1021 sm_break_offset(ftl, sect_no << 9, &zone_num, &block, &boffset);
1022 mutex_lock(&ftl->mutex);
1025 zone = sm_get_zone(ftl, zone_num);
1032 if (ftl->cache_zone == zone_num && ftl->cache_block == block) {
1034 if (!sm_cache_get(ftl, buf, boffset))
1046 if (sm_read_sector(ftl, zone_num, block, boffset, buf, NULL)) {
1052 sm_cache_put(ftl, buf, boffset);
1054 mutex_unlock(&ftl->mutex);
1062 struct sm_ftl *ftl = dev->priv;
1066 BUG_ON(ftl->readonly);
1067 sm_break_offset(ftl, sec_no << 9, &zone_num, &block, &boffset);
1070 del_timer(&ftl->timer);
1071 mutex_lock(&ftl->mutex);
1073 zone = sm_get_zone(ftl, zone_num);
1080 if (ftl->cache_block != block || ftl->cache_zone != zone_num) {
1082 error = sm_cache_flush(ftl);
1086 ftl->cache_block = block;
1087 ftl->cache_zone = zone_num;
1090 sm_cache_put(ftl, buf, boffset);
1092 mod_timer(&ftl->timer, jiffies + msecs_to_jiffies(cache_timeout));
1093 mutex_unlock(&ftl->mutex);
1100 struct sm_ftl *ftl = dev->priv;
1103 mutex_lock(&ftl->mutex);
1104 retval = sm_cache_flush(ftl);
1105 mutex_unlock(&ftl->mutex);
1112 struct sm_ftl *ftl = dev->priv;
1114 del_timer_sync(&ftl->timer);
1115 cancel_work_sync(&ftl->flush_work);
1116 mutex_lock(&ftl->mutex);
1117 sm_cache_flush(ftl);
1118 mutex_unlock(&ftl->mutex);
1124 struct sm_ftl *ftl = dev->priv;
1125 geo->heads = ftl->heads;
1126 geo->sectors = ftl->sectors;
1127 geo->cylinders = ftl->cylinders;
1135 struct sm_ftl *ftl;
1138 ftl = kzalloc(sizeof(struct sm_ftl), GFP_KERNEL);
1139 if (!ftl)
1143 mutex_init(&ftl->mutex);
1144 timer_setup(&ftl->timer, sm_cache_flush_timer, 0);
1145 INIT_WORK(&ftl->flush_work, sm_cache_flush_work);
1148 if (sm_get_media_info(ftl, mtd)) {
1155 ftl->cis_buffer = kzalloc(SM_SECTOR_SIZE, GFP_KERNEL);
1156 if (!ftl->cis_buffer)
1160 ftl->zones = kcalloc(ftl->zone_count, sizeof(struct ftl_zone),
1162 if (!ftl->zones)
1166 ftl->cache_data = kzalloc(ftl->block_size, GFP_KERNEL);
1168 if (!ftl->cache_data)
1171 sm_cache_init(ftl);
1179 ftl->trans = trans;
1180 trans->priv = ftl;
1185 trans->size = (ftl->block_size * ftl->max_lba * ftl->zone_count) >> 9;
1186 trans->readonly = ftl->readonly;
1188 if (sm_find_cis(ftl)) {
1193 ftl->disk_attributes = sm_create_sysfs_attributes(ftl);
1194 if (!ftl->disk_attributes)
1196 trans->disk_attributes = ftl->disk_attributes;
1203 ftl->zone_count, ftl->max_lba,
1204 ftl->zone_size - ftl->max_lba);
1206 ftl->block_size);
1218 kfree(ftl->cache_data);
1220 kfree(ftl->zones);
1222 kfree(ftl->cis_buffer);
1224 kfree(ftl);
1232 struct sm_ftl *ftl = dev->priv;
1236 ftl->trans = NULL;
1238 for (i = 0 ; i < ftl->zone_count; i++) {
1240 if (!ftl->zones[i].initialized)
1243 kfree(ftl->zones[i].lba_to_phys_table);
1244 kfifo_free(&ftl->zones[i].free_sectors);
1247 sm_delete_sysfs_attributes(ftl);
1248 kfree(ftl->cis_buffer);
1249 kfree(ftl->zones);
1250 kfree(ftl->cache_data);
1251 kfree(ftl);