18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __BLK_NULL_BLK_H 38c2ecf20Sopenharmony_ci#define __BLK_NULL_BLK_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#undef pr_fmt 68c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/blkdev.h> 98c2ecf20Sopenharmony_ci#include <linux/slab.h> 108c2ecf20Sopenharmony_ci#include <linux/blk-mq.h> 118c2ecf20Sopenharmony_ci#include <linux/hrtimer.h> 128c2ecf20Sopenharmony_ci#include <linux/configfs.h> 138c2ecf20Sopenharmony_ci#include <linux/badblocks.h> 148c2ecf20Sopenharmony_ci#include <linux/fault-inject.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistruct nullb_cmd { 178c2ecf20Sopenharmony_ci struct request *rq; 188c2ecf20Sopenharmony_ci struct bio *bio; 198c2ecf20Sopenharmony_ci unsigned int tag; 208c2ecf20Sopenharmony_ci blk_status_t error; 218c2ecf20Sopenharmony_ci struct nullb_queue *nq; 228c2ecf20Sopenharmony_ci struct hrtimer timer; 238c2ecf20Sopenharmony_ci bool fake_timeout; 248c2ecf20Sopenharmony_ci}; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistruct nullb_queue { 278c2ecf20Sopenharmony_ci unsigned long *tag_map; 288c2ecf20Sopenharmony_ci wait_queue_head_t wait; 298c2ecf20Sopenharmony_ci unsigned int queue_depth; 308c2ecf20Sopenharmony_ci struct nullb_device *dev; 318c2ecf20Sopenharmony_ci unsigned int requeue_selection; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci struct nullb_cmd *cmds; 348c2ecf20Sopenharmony_ci}; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistruct nullb_device { 378c2ecf20Sopenharmony_ci struct nullb *nullb; 388c2ecf20Sopenharmony_ci struct config_item item; 398c2ecf20Sopenharmony_ci struct radix_tree_root data; /* data stored in the disk */ 408c2ecf20Sopenharmony_ci struct radix_tree_root cache; /* disk cache data */ 418c2ecf20Sopenharmony_ci unsigned long flags; /* device flags */ 428c2ecf20Sopenharmony_ci unsigned int curr_cache; 438c2ecf20Sopenharmony_ci struct badblocks badblocks; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci unsigned int nr_zones; 468c2ecf20Sopenharmony_ci unsigned int nr_zones_imp_open; 478c2ecf20Sopenharmony_ci unsigned int nr_zones_exp_open; 488c2ecf20Sopenharmony_ci unsigned int nr_zones_closed; 498c2ecf20Sopenharmony_ci struct blk_zone *zones; 508c2ecf20Sopenharmony_ci sector_t zone_size_sects; 518c2ecf20Sopenharmony_ci spinlock_t zone_lock; 528c2ecf20Sopenharmony_ci unsigned long *zone_locks; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci unsigned long size; /* device size in MB */ 558c2ecf20Sopenharmony_ci unsigned long completion_nsec; /* time in ns to complete a request */ 568c2ecf20Sopenharmony_ci unsigned long cache_size; /* disk cache size in MB */ 578c2ecf20Sopenharmony_ci unsigned long zone_size; /* zone size in MB if device is zoned */ 588c2ecf20Sopenharmony_ci unsigned long zone_capacity; /* zone capacity in MB if device is zoned */ 598c2ecf20Sopenharmony_ci unsigned int zone_nr_conv; /* number of conventional zones */ 608c2ecf20Sopenharmony_ci unsigned int zone_max_open; /* max number of open zones */ 618c2ecf20Sopenharmony_ci unsigned int zone_max_active; /* max number of active zones */ 628c2ecf20Sopenharmony_ci unsigned int submit_queues; /* number of submission queues */ 638c2ecf20Sopenharmony_ci unsigned int home_node; /* home node for the device */ 648c2ecf20Sopenharmony_ci unsigned int queue_mode; /* block interface */ 658c2ecf20Sopenharmony_ci unsigned int blocksize; /* block size */ 668c2ecf20Sopenharmony_ci unsigned int irqmode; /* IRQ completion handler */ 678c2ecf20Sopenharmony_ci unsigned int hw_queue_depth; /* queue depth */ 688c2ecf20Sopenharmony_ci unsigned int index; /* index of the disk, only valid with a disk */ 698c2ecf20Sopenharmony_ci unsigned int mbps; /* Bandwidth throttle cap (in MB/s) */ 708c2ecf20Sopenharmony_ci bool blocking; /* blocking blk-mq device */ 718c2ecf20Sopenharmony_ci bool use_per_node_hctx; /* use per-node allocation for hardware context */ 728c2ecf20Sopenharmony_ci bool power; /* power on/off the device */ 738c2ecf20Sopenharmony_ci bool memory_backed; /* if data is stored in memory */ 748c2ecf20Sopenharmony_ci bool discard; /* if support discard */ 758c2ecf20Sopenharmony_ci bool zoned; /* if device is zoned */ 768c2ecf20Sopenharmony_ci}; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_cistruct nullb { 798c2ecf20Sopenharmony_ci struct nullb_device *dev; 808c2ecf20Sopenharmony_ci struct list_head list; 818c2ecf20Sopenharmony_ci unsigned int index; 828c2ecf20Sopenharmony_ci struct request_queue *q; 838c2ecf20Sopenharmony_ci struct gendisk *disk; 848c2ecf20Sopenharmony_ci struct blk_mq_tag_set *tag_set; 858c2ecf20Sopenharmony_ci struct blk_mq_tag_set __tag_set; 868c2ecf20Sopenharmony_ci unsigned int queue_depth; 878c2ecf20Sopenharmony_ci atomic_long_t cur_bytes; 888c2ecf20Sopenharmony_ci struct hrtimer bw_timer; 898c2ecf20Sopenharmony_ci unsigned long cache_flush_pos; 908c2ecf20Sopenharmony_ci spinlock_t lock; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci struct nullb_queue *queues; 938c2ecf20Sopenharmony_ci unsigned int nr_queues; 948c2ecf20Sopenharmony_ci char disk_name[DISK_NAME_LEN]; 958c2ecf20Sopenharmony_ci}; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ciblk_status_t null_process_cmd(struct nullb_cmd *cmd, 988c2ecf20Sopenharmony_ci enum req_opf op, sector_t sector, 998c2ecf20Sopenharmony_ci unsigned int nr_sectors); 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci#ifdef CONFIG_BLK_DEV_ZONED 1028c2ecf20Sopenharmony_ciint null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q); 1038c2ecf20Sopenharmony_ciint null_register_zoned_dev(struct nullb *nullb); 1048c2ecf20Sopenharmony_civoid null_free_zoned_dev(struct nullb_device *dev); 1058c2ecf20Sopenharmony_ciint null_report_zones(struct gendisk *disk, sector_t sector, 1068c2ecf20Sopenharmony_ci unsigned int nr_zones, report_zones_cb cb, void *data); 1078c2ecf20Sopenharmony_ciblk_status_t null_process_zoned_cmd(struct nullb_cmd *cmd, 1088c2ecf20Sopenharmony_ci enum req_opf op, sector_t sector, 1098c2ecf20Sopenharmony_ci sector_t nr_sectors); 1108c2ecf20Sopenharmony_cisize_t null_zone_valid_read_len(struct nullb *nullb, 1118c2ecf20Sopenharmony_ci sector_t sector, unsigned int len); 1128c2ecf20Sopenharmony_ci#else 1138c2ecf20Sopenharmony_cistatic inline int null_init_zoned_dev(struct nullb_device *dev, 1148c2ecf20Sopenharmony_ci struct request_queue *q) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci pr_err("CONFIG_BLK_DEV_ZONED not enabled\n"); 1178c2ecf20Sopenharmony_ci return -EINVAL; 1188c2ecf20Sopenharmony_ci} 1198c2ecf20Sopenharmony_cistatic inline int null_register_zoned_dev(struct nullb *nullb) 1208c2ecf20Sopenharmony_ci{ 1218c2ecf20Sopenharmony_ci return -ENODEV; 1228c2ecf20Sopenharmony_ci} 1238c2ecf20Sopenharmony_cistatic inline void null_free_zoned_dev(struct nullb_device *dev) {} 1248c2ecf20Sopenharmony_cistatic inline blk_status_t null_process_zoned_cmd(struct nullb_cmd *cmd, 1258c2ecf20Sopenharmony_ci enum req_opf op, sector_t sector, sector_t nr_sectors) 1268c2ecf20Sopenharmony_ci{ 1278c2ecf20Sopenharmony_ci return BLK_STS_NOTSUPP; 1288c2ecf20Sopenharmony_ci} 1298c2ecf20Sopenharmony_cistatic inline size_t null_zone_valid_read_len(struct nullb *nullb, 1308c2ecf20Sopenharmony_ci sector_t sector, 1318c2ecf20Sopenharmony_ci unsigned int len) 1328c2ecf20Sopenharmony_ci{ 1338c2ecf20Sopenharmony_ci return len; 1348c2ecf20Sopenharmony_ci} 1358c2ecf20Sopenharmony_ci#define null_report_zones NULL 1368c2ecf20Sopenharmony_ci#endif /* CONFIG_BLK_DEV_ZONED */ 1378c2ecf20Sopenharmony_ci#endif /* __NULL_BLK_H */ 138