Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*******************************************************************************
0003  * IBM Virtual SCSI Target Driver
0004  * Copyright (C) 2003-2005 Dave Boutcher (boutcher@us.ibm.com) IBM Corp.
0005  *             Santiago Leon (santil@us.ibm.com) IBM Corp.
0006  *             Linda Xie (lxie@us.ibm.com) IBM Corp.
0007  *
0008  * Copyright (C) 2005-2011 FUJITA Tomonori <tomof@acm.org>
0009  * Copyright (C) 2010 Nicholas A. Bellinger <nab@kernel.org>
0010  * Copyright (C) 2016 Bryant G. Ly <bryantly@linux.vnet.ibm.com> IBM Corp.
0011  *
0012  * Authors: Bryant G. Ly <bryantly@linux.vnet.ibm.com>
0013  * Authors: Michael Cyr <mikecyr@linux.vnet.ibm.com>
0014  *
0015  ****************************************************************************/
0016 
0017 #ifndef __H_IBMVSCSI_TGT
0018 #define __H_IBMVSCSI_TGT
0019 
0020 #include <linux/interrupt.h>
0021 #include "libsrp.h"
0022 
0023 #define SYS_ID_NAME_LEN     64
0024 #define PARTITION_NAMELEN   96
0025 #define IBMVSCSIS_NAMELEN       32
0026 
0027 #define MSG_HI  0
0028 #define MSG_LOW 1
0029 
0030 #define MAX_CMD_Q_PAGES       4
0031 #define CRQ_PER_PAGE          (PAGE_SIZE / sizeof(struct viosrp_crq))
0032 /* in terms of number of elements */
0033 #define DEFAULT_CMD_Q_SIZE    CRQ_PER_PAGE
0034 #define MAX_CMD_Q_SIZE        (DEFAULT_CMD_Q_SIZE * MAX_CMD_Q_PAGES)
0035 
0036 #define SRP_VIOLATION           0x102  /* general error code */
0037 
0038 /*
0039  * SRP buffer formats defined as of 16.a supported by this driver.
0040  */
0041 #define SUPPORTED_FORMATS  ((SRP_DATA_DESC_DIRECT << 1) | \
0042                 (SRP_DATA_DESC_INDIRECT << 1))
0043 
0044 #define SCSI_LUN_ADDR_METHOD_FLAT   1
0045 
0046 struct dma_window {
0047     u32 liobn;  /* Unique per vdevice */
0048     u64 tce_base;   /* Physical location of the TCE table */
0049     u64 tce_size;   /* Size of the TCE table in bytes */
0050 };
0051 
0052 struct target_dds {
0053     u64 unit_id;                /* 64 bit will force alignment */
0054 #define NUM_DMA_WINDOWS 2
0055 #define LOCAL  0
0056 #define REMOTE 1
0057     struct dma_window  window[NUM_DMA_WINDOWS];
0058 
0059     /* root node property "ibm,partition-no" */
0060     uint partition_num;
0061     char partition_name[PARTITION_NAMELEN];
0062 };
0063 
0064 #define MAX_NUM_PORTS        1
0065 #define MAX_H_COPY_RDMA      (128 * 1024)
0066 
0067 #define MAX_EYE   64
0068 
0069 /* Return codes */
0070 #define ADAPT_SUCCESS            0L
0071 /* choose error codes that do not conflict with PHYP */
0072 #define ERROR                   -40L
0073 
0074 struct format_code {
0075     u8 reserved;
0076     u8 buffers;
0077 };
0078 
0079 struct client_info {
0080 #define SRP_VERSION "16.a"
0081     char srp_version[8];
0082     /* root node property ibm,partition-name */
0083     char partition_name[PARTITION_NAMELEN];
0084     /* root node property ibm,partition-no */
0085     u32 partition_number;
0086     /* initially 1 */
0087     u32 mad_version;
0088     u32 os_type;
0089 };
0090 
0091 /*
0092  * Changing this constant changes the number of seconds to wait before
0093  * considering the client will never service its queue again.
0094  */
0095 #define SECONDS_TO_CONSIDER_FAILED 30
0096 /*
0097  * These constants set the polling period used to determine if the client
0098  * has freed at least one element in the response queue.
0099  */
0100 #define WAIT_SECONDS 1
0101 #define WAIT_NANO_SECONDS 5000
0102 #define MAX_TIMER_POPS ((1000000 / WAIT_NANO_SECONDS) * \
0103             SECONDS_TO_CONSIDER_FAILED)
0104 /*
0105  * general purpose timer control block
0106  * which can be used for multiple functions
0107  */
0108 struct timer_cb {
0109     struct hrtimer timer;
0110     /*
0111      * how long has it been since the client
0112      * serviced the queue. The variable is incrmented
0113      * in the service_wait_q routine and cleared
0114      * in send messages
0115      */
0116     int timer_pops;
0117     /* the timer is started */
0118     bool started;
0119 };
0120 
0121 struct cmd_queue {
0122     /* kva */
0123     struct viosrp_crq *base_addr;
0124     dma_addr_t crq_token;
0125     /* used to maintain index */
0126     uint mask;
0127     /* current element */
0128     uint index;
0129     int size;
0130 };
0131 
0132 #define SCSOLNT_RESP_SHIFT  1
0133 #define UCSOLNT_RESP_SHIFT  2
0134 
0135 #define SCSOLNT         BIT(SCSOLNT_RESP_SHIFT)
0136 #define UCSOLNT         BIT(UCSOLNT_RESP_SHIFT)
0137 
0138 enum cmd_type {
0139     SCSI_CDB    = 0x01,
0140     TASK_MANAGEMENT = 0x02,
0141     /* MAD or addressed to port 0 */
0142     ADAPTER_MAD = 0x04,
0143     UNSET_TYPE  = 0x08,
0144 };
0145 
0146 struct iu_rsp {
0147     u8 format;
0148     u8 sol_not;
0149     u16 len;
0150     /* tag is just to help client identify cmd, so don't translate be/le */
0151     u64 tag;
0152 };
0153 
0154 struct ibmvscsis_cmd {
0155     struct list_head list;
0156     /* Used for TCM Core operations */
0157     struct se_cmd se_cmd;
0158     struct iu_entry *iue;
0159     struct iu_rsp rsp;
0160     struct work_struct work;
0161     struct scsi_info *adapter;
0162     struct ibmvscsis_cmd *abort_cmd;
0163     /* Sense buffer that will be mapped into outgoing status */
0164     unsigned char sense_buf[TRANSPORT_SENSE_BUFFER];
0165     u64 init_time;
0166 #define CMD_FAST_FAIL   BIT(0)
0167 #define DELAY_SEND  BIT(1)
0168     u32 flags;
0169     char type;
0170 };
0171 
0172 struct ibmvscsis_nexus {
0173     struct se_session *se_sess;
0174 };
0175 
0176 struct ibmvscsis_tport {
0177     /* SCSI protocol the tport is providing */
0178     u8 tport_proto_id;
0179     /* ASCII formatted WWPN for SRP Target port */
0180     char tport_name[IBMVSCSIS_NAMELEN];
0181     /* Returned by ibmvscsis_make_tport() */
0182     struct se_wwn tport_wwn;
0183     /* Returned by ibmvscsis_make_tpg() */
0184     struct se_portal_group se_tpg;
0185     /* ibmvscsis port target portal group tag for TCM */
0186     u16 tport_tpgt;
0187     /* Pointer to TCM session for I_T Nexus */
0188     struct ibmvscsis_nexus *ibmv_nexus;
0189     bool enabled;
0190     bool releasing;
0191 };
0192 
0193 struct scsi_info {
0194     struct list_head list;
0195     char eye[MAX_EYE];
0196 
0197     /* commands waiting for space on repsonse queue */
0198     struct list_head waiting_rsp;
0199 #define NO_QUEUE                    0x00
0200 #define WAIT_ENABLED                0X01
0201 #define WAIT_CONNECTION             0x04
0202     /* have established a connection */
0203 #define CONNECTED                   0x08
0204     /* at least one port is processing SRP IU */
0205 #define SRP_PROCESSING              0x10
0206     /* remove request received */
0207 #define UNCONFIGURING               0x20
0208     /* disconnect by letting adapter go idle, no error */
0209 #define WAIT_IDLE                   0x40
0210     /* disconnecting to clear an error */
0211 #define ERR_DISCONNECT              0x80
0212     /* disconnect to clear error state, then come back up */
0213 #define ERR_DISCONNECT_RECONNECT    0x100
0214     /* disconnected after clearing an error */
0215 #define ERR_DISCONNECTED            0x200
0216     /* A series of errors caused unexpected errors */
0217 #define UNDEFINED                   0x400
0218     u16  state;
0219     int fast_fail;
0220     struct target_dds dds;
0221     char *cmd_pool;
0222     /* list of free commands */
0223     struct list_head free_cmd;
0224     /* command elements ready for scheduler */
0225     struct list_head schedule_q;
0226     /* commands sent to TCM */
0227     struct list_head active_q;
0228     caddr_t *map_buf;
0229     /* ioba of map buffer */
0230     dma_addr_t map_ioba;
0231     /* allowable number of outstanding SRP requests */
0232     int request_limit;
0233     /* extra credit */
0234     int credit;
0235     /* outstanding transactions against credit limit */
0236     int debit;
0237 
0238     /* allow only one outstanding mad request */
0239 #define PROCESSING_MAD                0x00002
0240     /* Waiting to go idle */
0241 #define WAIT_FOR_IDLE             0x00004
0242     /* H_REG_CRQ called */
0243 #define CRQ_CLOSED                    0x00010
0244     /* detected that client has failed */
0245 #define CLIENT_FAILED                 0x00040
0246     /* detected that transport event occurred */
0247 #define TRANS_EVENT                   0x00080
0248     /* don't attempt to send anything to the client */
0249 #define RESPONSE_Q_DOWN               0x00100
0250     /* request made to schedule disconnect handler */
0251 #define SCHEDULE_DISCONNECT           0x00400
0252     /* disconnect handler is scheduled */
0253 #define DISCONNECT_SCHEDULED          0x00800
0254     /* remove function is sleeping */
0255 #define CFG_SLEEPING                  0x01000
0256     /* Register for Prepare for Suspend Transport Events */
0257 #define PREP_FOR_SUSPEND_ENABLED      0x02000
0258     /* Prepare for Suspend event sent */
0259 #define PREP_FOR_SUSPEND_PENDING      0x04000
0260     /* Resume from Suspend event sent */
0261 #define PREP_FOR_SUSPEND_ABORTED      0x08000
0262     /* Prepare for Suspend event overwrote another CRQ entry */
0263 #define PREP_FOR_SUSPEND_OVERWRITE    0x10000
0264     u32 flags;
0265     /* adapter lock */
0266     spinlock_t intr_lock;
0267     /* information needed to manage command queue */
0268     struct cmd_queue cmd_q;
0269     /* used in hcall to copy response back into srp buffer */
0270     u64  empty_iu_id;
0271     /* used in crq, to tag what iu the response is for */
0272     u64  empty_iu_tag;
0273     uint new_state;
0274     uint resume_state;
0275     /* control block for the response queue timer */
0276     struct timer_cb rsp_q_timer;
0277     /* keep last client to enable proper accounting */
0278     struct client_info client_data;
0279     /* what can this client do */
0280     u32 client_cap;
0281     /*
0282      * The following two fields capture state and flag changes that
0283      * can occur when the lock is given up.  In the orginal design,
0284      * the lock was held during calls into phyp;
0285      * however, phyp did not meet PAPR architecture.  This is
0286      * a work around.
0287      */
0288     u16  phyp_acr_state;
0289     u32 phyp_acr_flags;
0290 
0291     struct workqueue_struct *work_q;
0292     struct completion wait_idle;
0293     struct completion unconfig;
0294     struct device dev;
0295     struct vio_dev *dma_dev;
0296     struct srp_target target;
0297     struct ibmvscsis_tport tport;
0298     struct tasklet_struct work_task;
0299     struct work_struct proc_work;
0300 };
0301 
0302 /*
0303  * Provide a constant that allows software to detect the adapter is
0304  * disconnecting from the client from one of several states.
0305  */
0306 #define IS_DISCONNECTING (UNCONFIGURING | ERR_DISCONNECT_RECONNECT | \
0307               ERR_DISCONNECT)
0308 
0309 /*
0310  * Provide a constant that can be used with interrupt handling that
0311  * essentially lets the interrupt handler know that all requests should
0312  * be thrown out,
0313  */
0314 #define DONT_PROCESS_STATE (IS_DISCONNECTING | UNDEFINED | \
0315                 ERR_DISCONNECTED  | WAIT_IDLE)
0316 
0317 /*
0318  * If any of these flag bits are set then do not allow the interrupt
0319  * handler to schedule the off level handler.
0320  */
0321 #define BLOCK (DISCONNECT_SCHEDULED)
0322 
0323 /* State and transition events that stop the interrupt handler */
0324 #define TARGET_STOP(VSCSI) (long)(((VSCSI)->state & DONT_PROCESS_STATE) | \
0325                   ((VSCSI)->flags & BLOCK))
0326 
0327 #define PREP_FOR_SUSPEND_FLAGS  (PREP_FOR_SUSPEND_ENABLED | \
0328                  PREP_FOR_SUSPEND_PENDING | \
0329                  PREP_FOR_SUSPEND_ABORTED | \
0330                  PREP_FOR_SUSPEND_OVERWRITE)
0331 
0332 /* flag bit that are not reset during disconnect */
0333 #define PRESERVE_FLAG_FIELDS (PREP_FOR_SUSPEND_FLAGS)
0334 
0335 #define vio_iu(IUE) ((union viosrp_iu *)((IUE)->sbuf->buf))
0336 
0337 #define READ_CMD(cdb)   (((cdb)[0] & 0x1F) == 8)
0338 #define WRITE_CMD(cdb)  (((cdb)[0] & 0x1F) == 0xA)
0339 
0340 #ifndef H_GET_PARTNER_INFO
0341 #define H_GET_PARTNER_INFO              0x0000000000000008LL
0342 #endif
0343 #ifndef H_ENABLE_PREPARE_FOR_SUSPEND
0344 #define H_ENABLE_PREPARE_FOR_SUSPEND    0x000000000000001DLL
0345 #endif
0346 #ifndef H_READY_FOR_SUSPEND
0347 #define H_READY_FOR_SUSPEND             0x000000000000001ELL
0348 #endif
0349 
0350 
0351 #define h_copy_rdma(l, sa, sb, da, db) \
0352         plpar_hcall_norets(H_COPY_RDMA, l, sa, sb, da, db)
0353 #define h_vioctl(u, o, a, u1, u2, u3, u4) \
0354         plpar_hcall_norets(H_VIOCTL, u, o, a, u1, u2)
0355 #define h_reg_crq(ua, tok, sz) \
0356         plpar_hcall_norets(H_REG_CRQ, ua, tok, sz)
0357 #define h_free_crq(ua) \
0358         plpar_hcall_norets(H_FREE_CRQ, ua)
0359 #define h_send_crq(ua, d1, d2) \
0360         plpar_hcall_norets(H_SEND_CRQ, ua, d1, d2)
0361 
0362 #endif