2015-06-10 01:15:52 +03:00
/*
* CXL Flash Device Driver
*
* Written by : Manoj N . Kumar < manoj @ linux . vnet . ibm . com > , IBM Corporation
* Matthew R . Ochs < mrochs @ linux . vnet . ibm . com > , IBM Corporation
*
* Copyright ( C ) 2015 IBM Corporation
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version
* 2 of the License , or ( at your option ) any later version .
*/
# ifndef _CXLFLASH_COMMON_H
# define _CXLFLASH_COMMON_H
# include <linux/list.h>
2015-10-21 23:11:52 +03:00
# include <linux/rwsem.h>
2015-06-10 01:15:52 +03:00
# include <linux/types.h>
# include <scsi/scsi.h>
# include <scsi/scsi_device.h>
# define MAX_CONTEXT CXLFLASH_MAX_CONTEXT /* num contexts per afu */
# define CXLFLASH_BLOCK_SIZE 4096 /* 4K blocks */
# define CXLFLASH_MAX_XFER_SIZE 16777216 /* 16MB transfer */
# define CXLFLASH_MAX_SECTORS (CXLFLASH_MAX_XFER_SIZE / 512) / * SCSI wants
max_sectors
in units of
512 byte
sectors
*/
# define NUM_RRQ_ENTRY 16 /* for master issued cmds */
# define MAX_RHT_PER_CONTEXT (PAGE_SIZE / sizeof(struct sisl_rht_entry))
/* AFU command retry limit */
# define MC_RETRY_CNT 5 / * sufficient for SCSI check and
certain AFU errors */
/* Command management definitions */
# define CXLFLASH_NUM_CMDS (2 * CXLFLASH_MAX_CMDS) / * Must be a pow2 for
alignment and more
efficient array
index derivation
*/
# define CXLFLASH_MAX_CMDS 16
# define CXLFLASH_MAX_CMDS_PER_LUN CXLFLASH_MAX_CMDS
static inline void check_sizes ( void )
{
BUILD_BUG_ON_NOT_POWER_OF_2 ( CXLFLASH_NUM_CMDS ) ;
}
/* AFU defines a fixed size of 4K for command buffers (borrow 4K page define) */
# define CMD_BUFSIZE SIZE_4K
/* flags in IOA status area for host use */
# define B_DONE 0x01
# define B_ERROR 0x02 /* set with B_DONE */
# define B_TIMEOUT 0x04 /* set with B_DONE & B_ERROR */
enum cxlflash_lr_state {
LINK_RESET_INVALID ,
LINK_RESET_REQUIRED ,
LINK_RESET_COMPLETE
} ;
enum cxlflash_init_state {
INIT_STATE_NONE ,
INIT_STATE_PCI ,
INIT_STATE_AFU ,
INIT_STATE_SCSI
} ;
2015-08-14 05:47:34 +03:00
enum cxlflash_state {
STATE_NORMAL , /* Normal running state, everything good */
2015-10-21 23:12:00 +03:00
STATE_RESET , /* Reset state, trying to reset/recover */
2015-08-14 05:47:34 +03:00
STATE_FAILTERM /* Failed/terminating state, error out users/threads */
} ;
2015-06-10 01:15:52 +03:00
/*
* Each context has its own set of resource handles that is visible
* only from that context .
*/
struct cxlflash_cfg {
struct afu * afu ;
struct cxl_context * mcctx ;
struct pci_dev * dev ;
struct pci_device_id * dev_id ;
struct Scsi_Host * host ;
ulong cxlflash_regs_pci ;
struct work_struct work_q ;
enum cxlflash_init_state init_state ;
enum cxlflash_lr_state lr_state ;
int lr_port ;
2015-10-21 23:13:37 +03:00
atomic_t scan_host_needed ;
2015-06-10 01:15:52 +03:00
struct cxl_afu * cxl_afu ;
struct pci_dev * parent_dev ;
2015-08-14 05:47:43 +03:00
atomic_t recovery_threads ;
struct mutex ctx_recovery_mutex ;
struct mutex ctx_tbl_list_mutex ;
2015-10-21 23:11:52 +03:00
struct rw_semaphore ioctl_rwsem ;
2015-08-14 05:47:43 +03:00
struct ctx_info * ctx_tbl [ MAX_CONTEXT ] ;
struct list_head ctx_err_recovery ; /* contexts w/ recovery pending */
struct file_operations cxl_fops ;
atomic_t num_user_contexts ;
2015-08-14 05:47:53 +03:00
/* Parameters that are LUN table related */
int last_lun_index [ CXLFLASH_NUM_FC_PORTS ] ;
int promote_lun_index ;
2015-08-14 05:47:43 +03:00
struct list_head lluns ; /* list of llun_info structs */
2015-06-10 01:15:52 +03:00
wait_queue_head_t tmf_waitq ;
2015-10-21 23:13:21 +03:00
spinlock_t tmf_slock ;
2015-06-10 01:15:52 +03:00
bool tmf_active ;
2015-10-21 23:12:00 +03:00
wait_queue_head_t reset_waitq ;
2015-08-14 05:47:34 +03:00
enum cxlflash_state state ;
2015-06-10 01:15:52 +03:00
} ;
struct afu_cmd {
struct sisl_ioarcb rcb ; /* IOARCB (cache line aligned) */
struct sisl_ioasa sa ; /* IOASA must follow IOARCB */
spinlock_t slock ;
struct completion cevent ;
char * buf ; /* per command buffer */
struct afu * parent ;
int slot ;
atomic_t free ;
u8 cmd_tmf : 1 ;
/* As per the SISLITE spec the IOARCB EA has to be 16-byte aligned.
* However for performance reasons the IOARCB / IOASA should be
* cache line aligned .
*/
} __aligned ( cache_line_size ( ) ) ;
struct afu {
/* Stuff requiring alignment go first. */
u64 rrq_entry [ NUM_RRQ_ENTRY ] ; /* 128B RRQ */
/*
* Command & data for AFU commands .
*/
struct afu_cmd cmd [ CXLFLASH_NUM_CMDS ] ;
/* Beware of alignment till here. Preferably introduce new
* fields after this point
*/
/* AFU HW */
struct cxl_ioctl_start_work work ;
2015-10-21 23:14:48 +03:00
struct cxlflash_afu_map __iomem * afu_map ; /* entire MMIO map */
struct sisl_host_map __iomem * host_map ; /* MC host map */
struct sisl_ctrl_map __iomem * ctrl_map ; /* MC control map */
2015-06-10 01:15:52 +03:00
ctx_hndl_t ctx_hndl ; /* master's context handle */
u64 * hrrq_start ;
u64 * hrrq_end ;
u64 * hrrq_curr ;
bool toggle ;
bool read_room ;
atomic64_t room ;
u64 hb ;
u32 cmd_couts ; /* Number of command checkouts */
u32 internal_lun ; /* User-desired LUN mode for this AFU */
2015-10-21 23:14:01 +03:00
char version [ 16 ] ;
2015-06-10 01:15:52 +03:00
u64 interface_version ;
struct cxlflash_cfg * parent ; /* Pointer back to parent cxlflash_cfg */
} ;
static inline u64 lun_to_lunid ( u64 lun )
{
2015-10-21 23:14:48 +03:00
__be64 lun_id ;
2015-06-10 01:15:52 +03:00
int_to_scsilun ( lun , ( struct scsi_lun * ) & lun_id ) ;
2015-10-21 23:14:48 +03:00
return be64_to_cpu ( lun_id ) ;
2015-06-10 01:15:52 +03:00
}
int cxlflash_afu_sync ( struct afu * , ctx_hndl_t , res_hndl_t , u8 ) ;
2015-08-14 05:47:43 +03:00
void cxlflash_list_init ( void ) ;
void cxlflash_term_global_luns ( void ) ;
void cxlflash_free_errpage ( void ) ;
int cxlflash_ioctl ( struct scsi_device * , int , void __user * ) ;
void cxlflash_stop_term_user_contexts ( struct cxlflash_cfg * ) ;
int cxlflash_mark_contexts_error ( struct cxlflash_cfg * ) ;
void cxlflash_term_local_luns ( struct cxlflash_cfg * ) ;
2015-08-14 05:47:53 +03:00
void cxlflash_restore_luntable ( struct cxlflash_cfg * ) ;
2015-08-14 05:47:43 +03:00
2015-06-10 01:15:52 +03:00
# endif /* ifndef _CXLFLASH_COMMON_H */