Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * zfcp device driver
0004  *
0005  * Fibre Channel related definitions and inline functions for the zfcp
0006  * device driver
0007  *
0008  * Copyright IBM Corp. 2009, 2017
0009  */
0010 
0011 #ifndef ZFCP_FC_H
0012 #define ZFCP_FC_H
0013 
0014 #include <scsi/fc/fc_els.h>
0015 #include <scsi/fc/fc_fcp.h>
0016 #include <scsi/fc/fc_ns.h>
0017 #include <scsi/scsi_cmnd.h>
0018 #include <scsi/scsi_tcq.h>
0019 #include "zfcp_fsf.h"
0020 
0021 #define ZFCP_FC_CT_SIZE_PAGE      (PAGE_SIZE - sizeof(struct fc_ct_hdr))
0022 #define ZFCP_FC_GPN_FT_ENT_PAGE   (ZFCP_FC_CT_SIZE_PAGE \
0023                     / sizeof(struct fc_gpn_ft_resp))
0024 #define ZFCP_FC_GPN_FT_NUM_BUFS   4 /* memory pages */
0025 
0026 #define ZFCP_FC_GPN_FT_MAX_SIZE   (ZFCP_FC_GPN_FT_NUM_BUFS * PAGE_SIZE \
0027                     - sizeof(struct fc_ct_hdr))
0028 #define ZFCP_FC_GPN_FT_MAX_ENT    (ZFCP_FC_GPN_FT_NUM_BUFS * \
0029                     (ZFCP_FC_GPN_FT_ENT_PAGE + 1))
0030 
0031 #define ZFCP_FC_CTELS_TMO   (2 * FC_DEF_R_A_TOV / 1000)
0032 
0033 /**
0034  * struct zfcp_fc_event - FC HBAAPI event for internal queueing from irq context
0035  * @code: Event code
0036  * @data: Event data
0037  * @list: list_head for zfcp_fc_events list
0038  */
0039 struct zfcp_fc_event {
0040     enum fc_host_event_code code;
0041     u32 data;
0042     struct list_head list;
0043 };
0044 
0045 /**
0046  * struct zfcp_fc_events - Infrastructure for posting FC events from irq context
0047  * @list: List for queueing of events from irq context to workqueue
0048  * @list_lock: Lock for event list
0049  * @work: work_struct for forwarding events in workqueue
0050 */
0051 struct zfcp_fc_events {
0052     struct list_head list;
0053     spinlock_t list_lock;
0054     struct work_struct work;
0055 };
0056 
0057 /**
0058  * struct zfcp_fc_gid_pn_req - container for ct header plus gid_pn request
0059  * @ct_hdr: FC GS common transport header
0060  * @gid_pn: GID_PN request
0061  */
0062 struct zfcp_fc_gid_pn_req {
0063     struct fc_ct_hdr    ct_hdr;
0064     struct fc_ns_gid_pn gid_pn;
0065 } __packed;
0066 
0067 /**
0068  * struct zfcp_fc_gid_pn_rsp - container for ct header plus gid_pn response
0069  * @ct_hdr: FC GS common transport header
0070  * @gid_pn: GID_PN response
0071  */
0072 struct zfcp_fc_gid_pn_rsp {
0073     struct fc_ct_hdr    ct_hdr;
0074     struct fc_gid_pn_resp   gid_pn;
0075 } __packed;
0076 
0077 /**
0078  * struct zfcp_fc_gpn_ft - container for ct header plus gpn_ft request
0079  * @ct_hdr: FC GS common transport header
0080  * @gpn_ft: GPN_FT request
0081  */
0082 struct zfcp_fc_gpn_ft_req {
0083     struct fc_ct_hdr    ct_hdr;
0084     struct fc_ns_gid_ft gpn_ft;
0085 } __packed;
0086 
0087 /**
0088  * struct zfcp_fc_gspn_req - container for ct header plus GSPN_ID request
0089  * @ct_hdr: FC GS common transport header
0090  * @gspn: GSPN_ID request
0091  */
0092 struct zfcp_fc_gspn_req {
0093     struct fc_ct_hdr    ct_hdr;
0094     struct fc_gid_pn_resp   gspn;
0095 } __packed;
0096 
0097 /**
0098  * struct zfcp_fc_gspn_rsp - container for ct header plus GSPN_ID response
0099  * @ct_hdr: FC GS common transport header
0100  * @gspn: GSPN_ID response
0101  * @name: The name string of the GSPN_ID response
0102  */
0103 struct zfcp_fc_gspn_rsp {
0104     struct fc_ct_hdr    ct_hdr;
0105     struct fc_gspn_resp gspn;
0106     char            name[FC_SYMBOLIC_NAME_SIZE];
0107 } __packed;
0108 
0109 /**
0110  * struct zfcp_fc_rspn_req - container for ct header plus RSPN_ID request
0111  * @ct_hdr: FC GS common transport header
0112  * @rspn: RSPN_ID request
0113  * @name: The name string of the RSPN_ID request
0114  */
0115 struct zfcp_fc_rspn_req {
0116     struct fc_ct_hdr    ct_hdr;
0117     struct fc_ns_rspn   rspn;
0118     char            name[FC_SYMBOLIC_NAME_SIZE];
0119 } __packed;
0120 
0121 /**
0122  * struct zfcp_fc_req - Container for FC ELS and CT requests sent from zfcp
0123  * @ct_els: data required for issuing fsf command
0124  * @sg_req: scatterlist entry for request data, refers to embedded @u submember
0125  * @sg_rsp: scatterlist entry for response data, refers to embedded @u submember
0126  * @u: request and response specific data
0127  * @u.adisc: ADISC specific data
0128  * @u.adisc.req: ADISC request
0129  * @u.adisc.rsp: ADISC response
0130  * @u.gid_pn: GID_PN specific data
0131  * @u.gid_pn.req: GID_PN request
0132  * @u.gid_pn.rsp: GID_PN response
0133  * @u.gpn_ft: GPN_FT specific data
0134  * @u.gpn_ft.sg_rsp2: GPN_FT response, not embedded here, allocated elsewhere
0135  * @u.gpn_ft.req: GPN_FT request
0136  * @u.gspn: GSPN specific data
0137  * @u.gspn.req: GSPN request
0138  * @u.gspn.rsp: GSPN response
0139  * @u.rspn: RSPN specific data
0140  * @u.rspn.req: RSPN request
0141  * @u.rspn.rsp: RSPN response
0142  */
0143 struct zfcp_fc_req {
0144     struct zfcp_fsf_ct_els              ct_els;
0145     struct scatterlist              sg_req;
0146     struct scatterlist              sg_rsp;
0147     union {
0148         struct {
0149             struct fc_els_adisc     req;
0150             struct fc_els_adisc     rsp;
0151         } adisc;
0152         struct {
0153             struct zfcp_fc_gid_pn_req   req;
0154             struct zfcp_fc_gid_pn_rsp   rsp;
0155         } gid_pn;
0156         struct {
0157             struct scatterlist sg_rsp2[ZFCP_FC_GPN_FT_NUM_BUFS - 1];
0158             struct zfcp_fc_gpn_ft_req   req;
0159         } gpn_ft;
0160         struct {
0161             struct zfcp_fc_gspn_req     req;
0162             struct zfcp_fc_gspn_rsp     rsp;
0163         } gspn;
0164         struct {
0165             struct zfcp_fc_rspn_req     req;
0166             struct fc_ct_hdr        rsp;
0167         } rspn;
0168     } u;
0169 };
0170 
0171 /**
0172  * enum zfcp_fc_wka_status - FC WKA port status in zfcp
0173  * @ZFCP_FC_WKA_PORT_OFFLINE: Port is closed and not in use
0174  * @ZFCP_FC_WKA_PORT_CLOSING: The FSF "close port" request is pending
0175  * @ZFCP_FC_WKA_PORT_OPENING: The FSF "open port" request is pending
0176  * @ZFCP_FC_WKA_PORT_ONLINE: The port is open and the port handle is valid
0177  */
0178 enum zfcp_fc_wka_status {
0179     ZFCP_FC_WKA_PORT_OFFLINE,
0180     ZFCP_FC_WKA_PORT_CLOSING,
0181     ZFCP_FC_WKA_PORT_OPENING,
0182     ZFCP_FC_WKA_PORT_ONLINE,
0183 };
0184 
0185 /**
0186  * struct zfcp_fc_wka_port - representation of well-known-address (WKA) FC port
0187  * @adapter: Pointer to adapter structure this WKA port belongs to
0188  * @opened: Wait for completion of open command
0189  * @closed: Wait for completion of close command
0190  * @status: Current status of WKA port
0191  * @refcount: Reference count to keep port open as long as it is in use
0192  * @d_id: FC destination id or well-known-address
0193  * @handle: FSF handle for the open WKA port
0194  * @mutex: Mutex used during opening/closing state changes
0195  * @work: For delaying the closing of the WKA port
0196  */
0197 struct zfcp_fc_wka_port {
0198     struct zfcp_adapter *adapter;
0199     wait_queue_head_t   opened;
0200     wait_queue_head_t   closed;
0201     enum zfcp_fc_wka_status status;
0202     atomic_t        refcount;
0203     u32         d_id;
0204     u32         handle;
0205     struct mutex        mutex;
0206     struct delayed_work work;
0207 };
0208 
0209 /**
0210  * struct zfcp_fc_wka_ports - Data structures for FC generic services
0211  * @ms: FC Management service
0212  * @ts: FC time service
0213  * @ds: FC directory service
0214  * @as: FC alias service
0215  */
0216 struct zfcp_fc_wka_ports {
0217     struct zfcp_fc_wka_port ms;
0218     struct zfcp_fc_wka_port ts;
0219     struct zfcp_fc_wka_port ds;
0220     struct zfcp_fc_wka_port as;
0221 };
0222 
0223 /**
0224  * zfcp_fc_scsi_to_fcp - setup FCP command with data from scsi_cmnd
0225  * @fcp: fcp_cmnd to setup
0226  * @scsi: scsi_cmnd where to get LUN, task attributes/flags and CDB
0227  */
0228 static inline
0229 void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi)
0230 {
0231     u32 datalen;
0232 
0233     int_to_scsilun(scsi->device->lun, (struct scsi_lun *) &fcp->fc_lun);
0234 
0235     fcp->fc_pri_ta = FCP_PTA_SIMPLE;
0236 
0237     if (scsi->sc_data_direction == DMA_FROM_DEVICE)
0238         fcp->fc_flags |= FCP_CFL_RDDATA;
0239     if (scsi->sc_data_direction == DMA_TO_DEVICE)
0240         fcp->fc_flags |= FCP_CFL_WRDATA;
0241 
0242     memcpy(fcp->fc_cdb, scsi->cmnd, scsi->cmd_len);
0243 
0244     datalen = scsi_bufflen(scsi);
0245     fcp->fc_dl = cpu_to_be32(datalen);
0246 
0247     if (scsi_get_prot_type(scsi) == SCSI_PROT_DIF_TYPE1) {
0248         datalen += datalen / scsi->device->sector_size * 8;
0249         fcp->fc_dl = cpu_to_be32(datalen);
0250     }
0251 }
0252 
0253 /**
0254  * zfcp_fc_fcp_tm() - Setup FCP command as task management command.
0255  * @fcp: Pointer to FCP_CMND IU to set up.
0256  * @dev: Pointer to SCSI_device where to send the task management command.
0257  * @tm_flags: Task management flags to setup tm command.
0258  */
0259 static inline
0260 void zfcp_fc_fcp_tm(struct fcp_cmnd *fcp, struct scsi_device *dev, u8 tm_flags)
0261 {
0262     int_to_scsilun(dev->lun, (struct scsi_lun *) &fcp->fc_lun);
0263     fcp->fc_tm_flags = tm_flags;
0264 }
0265 
0266 /**
0267  * zfcp_fc_evap_fcp_rsp - evaluate FCP RSP IU and update scsi_cmnd accordingly
0268  * @fcp_rsp: FCP RSP IU to evaluate
0269  * @scsi: SCSI command where to update status and sense buffer
0270  */
0271 static inline
0272 void zfcp_fc_eval_fcp_rsp(struct fcp_resp_with_ext *fcp_rsp,
0273               struct scsi_cmnd *scsi)
0274 {
0275     struct fcp_resp_rsp_info *rsp_info;
0276     char *sense;
0277     u32 sense_len, resid;
0278     u8 rsp_flags;
0279 
0280     scsi->result |= fcp_rsp->resp.fr_status;
0281 
0282     rsp_flags = fcp_rsp->resp.fr_flags;
0283 
0284     if (unlikely(rsp_flags & FCP_RSP_LEN_VAL)) {
0285         rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
0286         if (rsp_info->rsp_code == FCP_TMF_CMPL)
0287             set_host_byte(scsi, DID_OK);
0288         else {
0289             set_host_byte(scsi, DID_ERROR);
0290             return;
0291         }
0292     }
0293 
0294     if (unlikely(rsp_flags & FCP_SNS_LEN_VAL)) {
0295         sense = (char *) &fcp_rsp[1];
0296         if (rsp_flags & FCP_RSP_LEN_VAL)
0297             sense += be32_to_cpu(fcp_rsp->ext.fr_rsp_len);
0298         sense_len = min_t(u32, be32_to_cpu(fcp_rsp->ext.fr_sns_len),
0299                   SCSI_SENSE_BUFFERSIZE);
0300         memcpy(scsi->sense_buffer, sense, sense_len);
0301     }
0302 
0303     if (unlikely(rsp_flags & FCP_RESID_UNDER)) {
0304         resid = be32_to_cpu(fcp_rsp->ext.fr_resid);
0305         scsi_set_resid(scsi, resid);
0306         if (scsi_bufflen(scsi) - resid < scsi->underflow &&
0307              !(rsp_flags & FCP_SNS_LEN_VAL) &&
0308              fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
0309             set_host_byte(scsi, DID_ERROR);
0310     } else if (unlikely(rsp_flags & FCP_RESID_OVER)) {
0311         /* FCP_DL was not sufficient for SCSI data length */
0312         if (fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
0313             set_host_byte(scsi, DID_ERROR);
0314     }
0315 }
0316 
0317 #endif