/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2015 IT University of Copenhagen (rrpc.h)
* Copyright (C) 2016 CNEX Labs
* Initial release: Matias Bjorling <matias@cnexlabs.com>
* Write buffering: Javier Gonzalez <javier@cnexlabs.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* Implementation of a Physical Block-device target for Open-channel SSDs.
*
*/
#ifndef PBLK_H_
#define PBLK_H_
#include <linux/blkdev.h>
#include <linux/blk-mq.h>
#include <linux/bio.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/vmalloc.h>
#include <linux/crc32.h>
#include <linux/uuid.h>
#include <linux/lightnvm.h>
/* Run only GC if less than 1/X blocks are free */
#define GC_LIMIT_INVERSE 5
#define GC_TIME_MSECS 1000
#define PBLK_SECTOR (512)
#define PBLK_EXPOSED_PAGE_SIZE (4096)
#define PBLK_NR_CLOSE_JOBS (4)
#define PBLK_CACHE_NAME_LEN (DISK_NAME_LEN + 16)
/* Max 512 LUNs per device */
#define PBLK_MAX_LUNS_BITMAP (4)
#define NR_PHY_IN_LOG (PBLK_EXPOSED_PAGE_SIZE / PBLK_SECTOR)
/* Static pool sizes */
#define PBLK_GEN_WS_POOL_SIZE (2)
#define PBLK_DEFAULT_OP (11)
enum {
PBLK_READ = READ,
PBLK_WRITE = WRITE,/* Write from write buffer */
PBLK_WRITE_INT, /* Internal write - no write buffer */
PBLK_READ_RECOV, /* Recovery read - errors allowed */
PBLK_ERASE,
};
enum {
/* IO Types */
PBLK_IOTYPE_USER = 1 << 0,
PBLK_IOTYPE_GC = 1 << 1,
/* Write buffer flags */
PBLK_FLUSH_ENTRY = 1 << 2,
PBLK_WRITTEN_DATA = 1 << 3,
PBLK_SUBMITTED_ENTRY = 1 << 4,
PBLK_WRITABLE_ENTRY = 1 << 5,
};
enum {
PBLK_BLK_ST_OPEN = 0x1,
PBLK_BLK_ST_CLOSED = 0x2,
};
enum {
PBLK_CHUNK_RESET_START,
PBLK_CHUNK_RESET_DONE,
PBLK_CHUNK_RESET_FAILED,
};
struct pblk_sec_meta {
u64 reserved;
__le64 lba;
};
/* The number of GC lists and the rate-limiter states go together. This way the
* rate-limiter can dictate how much GC is needed based on resource utilization.
*/
#define PBLK_GC_NR_LISTS 4
enum {
PBLK_RL_OFF = 0,
PBLK_RL_WERR = 1,
PBLK_RL_HIGH = 2,
PBLK_RL_MID = 3,
PBLK_RL_LOW = 4
};
#define pblk_dma_ppa_size (sizeof(u64) * NVM_MAX_VLBA)
/* write buffer completion context */
struct pblk_c_ctx {
struct list_head list; /* Head for out-of-order completion */
unsigned long *lun_bitmap; /* Luns used on current request */
unsigned int sentry;
unsigned int nr_valid;
unsigned int nr_padded;
};
/* read context */
struct pblk_g_ctx {
void *private;
unsigned long start_time;
u64 lba;
};
/* Pad context */
struct pblk_pad_rq {
struct pblk