diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-07 21:11:05 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-07 21:11:05 -0700 |
commit | 572c01ba19ef150e98aea0b45ca17d43356521b5 (patch) | |
tree | 289381d051dfc34a86be988700ee11cb9ad0cd5b /drivers/s390 | |
parent | cef5d0f952a03d42051141742632078d488b0c6b (diff) | |
parent | 2441500a41a9b17ff657626eb81972f62bc8cc5a (diff) | |
download | op-kernel-dev-572c01ba19ef150e98aea0b45ca17d43356521b5.zip op-kernel-dev-572c01ba19ef150e98aea0b45ca17d43356521b5.tar.gz |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This is mostly updates of the usual suspects: lpfc, qla2xxx, hisi_sas,
megaraid_sas, zfcp and a host of minor updates.
The major driver change here is the elimination of the block based
cciss driver in favour of the SCSI based hpsa driver (which now drives
all the legacy cases cciss used to be required for). Plus a reset
handler clean up and the redo of the SAS SMP handler to use bsg lib"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (279 commits)
scsi: scsi-mq: Always unprepare before requeuing a request
scsi: Show .retries and .jiffies_at_alloc in debugfs
scsi: Improve requeuing behavior
scsi: Call scsi_initialize_rq() for filesystem requests
scsi: qla2xxx: Reset the logo flag, after target re-login.
scsi: qla2xxx: Fix slow mem alloc behind lock
scsi: qla2xxx: Clear fc4f_nvme flag
scsi: qla2xxx: add missing includes for qla_isr
scsi: qla2xxx: Fix an integer overflow in sysfs code
scsi: aacraid: report -ENOMEM to upper layer from aac_convert_sgraw2()
scsi: aacraid: get rid of one level of indentation
scsi: aacraid: fix indentation errors
scsi: storvsc: fix memory leak on ring buffer busy
scsi: scsi_transport_sas: switch to bsg-lib for SMP passthrough
scsi: smartpqi: remove the smp_handler stub
scsi: hpsa: remove the smp_handler stub
scsi: bsg-lib: pass the release callback through bsg_setup_queue
scsi: Rework handling of scsi_device.vpd_pg8[03]
scsi: Rework the code for caching Vital Product Data (VPD)
scsi: rcu: Introduce rcu_swap_protected()
...
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.c | 95 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.h | 25 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 5 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 52 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.h | 25 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 35 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.h | 12 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 2 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.h | 17 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 18 |
12 files changed, 178 insertions, 110 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index bcc8f3d..82ac331 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -29,7 +29,6 @@ #define KMSG_COMPONENT "zfcp" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt -#include <linux/miscdevice.h> #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/module.h> diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index d5bf36e..8227076 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -3,7 +3,7 @@ * * Debug traces for zfcp. * - * Copyright IBM Corp. 2002, 2016 + * Copyright IBM Corp. 2002, 2017 */ #define KMSG_COMPONENT "zfcp" @@ -113,8 +113,12 @@ void zfcp_dbf_hba_fsf_uss(char *tag, struct zfcp_fsf_req *req) struct zfcp_dbf *dbf = req->adapter->dbf; struct fsf_status_read_buffer *srb = req->data; struct zfcp_dbf_hba *rec = &dbf->hba_buf; + static int const level = 2; unsigned long flags; + if (unlikely(!debug_level_enabled(dbf->hba, level))) + return; + spin_lock_irqsave(&dbf->hba_lock, flags); memset(rec, 0, sizeof(*rec)); @@ -142,7 +146,7 @@ void zfcp_dbf_hba_fsf_uss(char *tag, struct zfcp_fsf_req *req) zfcp_dbf_pl_write(dbf, srb->payload.data, rec->pl_len, "fsf_uss", req->req_id); log: - debug_event(dbf->hba, 2, rec, sizeof(*rec)); + debug_event(dbf->hba, level, rec, sizeof(*rec)); spin_unlock_irqrestore(&dbf->hba_lock, flags); } @@ -156,8 +160,12 @@ void zfcp_dbf_hba_bit_err(char *tag, struct zfcp_fsf_req *req) struct zfcp_dbf *dbf = req->adapter->dbf; struct zfcp_dbf_hba *rec = &dbf->hba_buf; struct fsf_status_read_buffer *sr_buf = req->data; + static int const level = 1; unsigned long flags; + if (unlikely(!debug_level_enabled(dbf->hba, level))) + return; + spin_lock_irqsave(&dbf->hba_lock, flags); memset(rec, 0, sizeof(*rec)); @@ -169,7 +177,7 @@ void zfcp_dbf_hba_bit_err(char *tag, struct zfcp_fsf_req *req) memcpy(&rec->u.be, &sr_buf->payload.bit_error, sizeof(struct fsf_bit_error_payload)); - debug_event(dbf->hba, 1, rec, sizeof(*rec)); + debug_event(dbf->hba, level, rec, sizeof(*rec)); spin_unlock_irqrestore(&dbf->hba_lock, flags); } @@ -186,8 +194,12 @@ void zfcp_dbf_hba_def_err(struct zfcp_adapter *adapter, u64 req_id, u16 scount, struct zfcp_dbf *dbf = adapter->dbf; struct zfcp_dbf_pay *payload = &dbf->pay_buf; unsigned long flags; + static int const level = 1; u16 length; + if (unlikely(!debug_level_enabled(dbf->pay, level))) + return; + if (!pl) return; @@ -202,7 +214,7 @@ void zfcp_dbf_hba_def_err(struct zfcp_adapter *adapter, u64 req_id, u16 scount, while (payload->counter < scount && (char *)pl[payload->counter]) { memcpy(payload->data, (char *)pl[payload->counter], length); - debug_event(dbf->pay, 1, payload, zfcp_dbf_plen(length)); + debug_event(dbf->pay, level, payload, zfcp_dbf_plen(length)); payload->counter++; } @@ -217,15 +229,19 @@ void zfcp_dbf_hba_basic(char *tag, struct zfcp_adapter *adapter) { struct zfcp_dbf *dbf = adapter->dbf; struct zfcp_dbf_hba *rec = &dbf->hba_buf; + static int const level = 1; unsigned long flags; + if (unlikely(!debug_level_enabled(dbf->hba, level))) + return; + spin_lock_irqsave(&dbf->hba_lock, flags); memset(rec, 0, sizeof(*rec)); memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); rec->id = ZFCP_DBF_HBA_BASIC; - debug_event(dbf->hba, 1, rec, sizeof(*rec)); + debug_event(dbf->hba, level, rec, sizeof(*rec)); spin_unlock_irqrestore(&dbf->hba_lock, flags); } @@ -264,9 +280,13 @@ void zfcp_dbf_rec_trig(char *tag, struct zfcp_adapter *adapter, { struct zfcp_dbf *dbf = adapter->dbf; struct zfcp_dbf_rec *rec = &dbf->rec_buf; + static int const level = 1; struct list_head *entry; unsigned long flags; + if (unlikely(!debug_level_enabled(dbf->rec, level))) + return; + spin_lock_irqsave(&dbf->rec_lock, flags); memset(rec, 0, sizeof(*rec)); @@ -283,7 +303,7 @@ void zfcp_dbf_rec_trig(char *tag, struct zfcp_adapter *adapter, rec->u.trig.want = want; rec->u.trig.need = need; - debug_event(dbf->rec, 1, rec, sizeof(*rec)); + debug_event(dbf->rec, level, rec, sizeof(*rec)); spin_unlock_irqrestore(&dbf->rec_lock, flags); } @@ -300,6 +320,9 @@ void zfcp_dbf_rec_run_lvl(int level, char *tag, struct zfcp_erp_action *erp) struct zfcp_dbf_rec *rec = &dbf->rec_buf; unsigned long flags; + if (!debug_level_enabled(dbf->rec, level)) + return; + spin_lock_irqsave(&dbf->rec_lock, flags); memset(rec, 0, sizeof(*rec)); @@ -345,8 +368,12 @@ void zfcp_dbf_rec_run_wka(char *tag, struct zfcp_fc_wka_port *wka_port, { struct zfcp_dbf *dbf = wka_port->adapter->dbf; struct zfcp_dbf_rec *rec = &dbf->rec_buf; + static int const level = 1; unsigned long flags; + if (unlikely(!debug_level_enabled(dbf->rec, level))) + return; + spin_lock_irqsave(&dbf->rec_lock, flags); memset(rec, 0, sizeof(*rec)); @@ -362,10 +389,12 @@ void zfcp_dbf_rec_run_wka(char *tag, struct zfcp_fc_wka_port *wka_port, rec->u.run.rec_action = ~0; rec->u.run.rec_count = ~0; - debug_event(dbf->rec, 1, rec, sizeof(*rec)); + debug_event(dbf->rec, level, rec, sizeof(*rec)); spin_unlock_irqrestore(&dbf->rec_lock, flags); } +#define ZFCP_DBF_SAN_LEVEL 1 + static inline void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, char *paytag, struct scatterlist *sg, u8 id, u16 len, @@ -408,7 +437,7 @@ void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, (u16)(sg->length - offset)); /* cap_len <= pay_sum < cap_len+ZFCP_DBF_PAY_MAX_REC */ memcpy(payload->data, sg_virt(sg) + offset, pay_len); - debug_event(dbf->pay, 1, payload, + debug_event(dbf->pay, ZFCP_DBF_SAN_LEVEL, payload, zfcp_dbf_plen(pay_len)); payload->counter++; offset += pay_len; @@ -418,7 +447,7 @@ void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, spin_unlock(&dbf->pay_lock); out: - debug_event(dbf->san, 1, rec, sizeof(*rec)); + debug_event(dbf->san, ZFCP_DBF_SAN_LEVEL, rec, sizeof(*rec)); spin_unlock_irqrestore(&dbf->san_lock, flags); } @@ -434,6 +463,9 @@ void zfcp_dbf_san_req(char *tag, struct zfcp_fsf_req *fsf, u32 d_id) struct zfcp_fsf_ct_els *ct_els = fsf->data; u16 length; + if (unlikely(!debug_level_enabled(dbf->san, ZFCP_DBF_SAN_LEVEL))) + return; + length = (u16)zfcp_qdio_real_bytes(ct_els->req); zfcp_dbf_san(tag, dbf, "san_req", ct_els->req, ZFCP_DBF_SAN_REQ, length, fsf->req_id, d_id, length); @@ -447,6 +479,7 @@ static u16 zfcp_dbf_san_res_cap_len_if_gpn_ft(char *tag, struct fc_ct_hdr *reqh = sg_virt(ct_els->req); struct fc_ns_gid_ft *reqn = (struct fc_ns_gid_ft *)(reqh + 1); struct scatterlist *resp_entry = ct_els->resp; + struct fc_ct_hdr *resph; struct fc_gpn_ft_resp *acc; int max_entries, x, last = 0; @@ -460,7 +493,7 @@ static u16 zfcp_dbf_san_res_cap_len_if_gpn_ft(char *tag, && reqh->ct_fs_subtype == FC_NS_SUBTYPE && reqh->ct_options == 0 && reqh->_ct_resvd1 == 0 - && reqh->ct_cmd == FC_NS_GPN_FT + && reqh->ct_cmd == cpu_to_be16(FC_NS_GPN_FT) /* reqh->ct_mr_size can vary so do not match but read below */ && reqh->_ct_resvd2 == 0 && reqh->ct_reason == 0 @@ -473,7 +506,15 @@ static u16 zfcp_dbf_san_res_cap_len_if_gpn_ft(char *tag, return len; /* not GPN_FT response so do not cap */ acc = sg_virt(resp_entry); - max_entries = (reqh->ct_mr_size * 4 / sizeof(struct fc_gpn_ft_resp)) + + /* cap all but accept CT responses to at least the CT header */ + resph = (struct fc_ct_hdr *)acc; + if ((ct_els->status) || + (resph->ct_cmd != cpu_to_be16(FC_FS_ACC))) + return max(FC_CT_HDR_LEN, ZFCP_DBF_SAN_MAX_PAYLOAD); + + max_entries = (be16_to_cpu(reqh->ct_mr_size) * 4 / + sizeof(struct fc_gpn_ft_resp)) + 1 /* zfcp_fc_scan_ports: bytes correct, entries off-by-one * to account for header as 1st pseudo "entry" */; @@ -503,6 +544,9 @@ void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf) struct zfcp_fsf_ct_els *ct_els = fsf->data; u16 length; + if (unlikely(!debug_level_enabled(dbf->san, ZFCP_DBF_SAN_LEVEL))) + return; + length = (u16)zfcp_qdio_real_bytes(ct_els->resp); zfcp_dbf_san(tag, dbf, "san_res", ct_els->resp, ZFCP_DBF_SAN_RES, length, fsf->req_id, ct_els->d_id, @@ -522,6 +566,9 @@ void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf) u16 length; struct scatterlist sg; + if (unlikely(!debug_level_enabled(dbf->san, ZFCP_DBF_SAN_LEVEL))) + return; + length = (u16)(srb->length - offsetof(struct fsf_status_read_buffer, payload)); sg_init_one(&sg, srb->payload.data, length); @@ -555,8 +602,8 @@ void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc, rec->scsi_retries = sc->retries; rec->scsi_allowed = sc->allowed; rec->scsi_id = sc->device->id; - /* struct zfcp_dbf_scsi needs to be updated to handle 64bit LUNs */ rec->scsi_lun = (u32)sc->device->lun; + rec->scsi_lun_64_hi = (u32)(sc->device->lun >> 32); rec->host_scribble = (unsigned long)sc->host_scribble; memcpy(rec->scsi_opcode, sc->cmnd, @@ -564,19 +611,31 @@ void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc, if (fsf) { rec->fsf_req_id = fsf->req_id; - fcp_rsp = (struct fcp_resp_with_ext *) - &(fsf->qtcb->bottom.io.fcp_rsp); + rec->pl_len = FCP_RESP_WITH_EXT; + fcp_rsp = &(fsf->qtcb->bottom.io.fcp_rsp.iu); + /* mandatory parts of FCP_RSP IU in this SCSI record */ memcpy(&rec->fcp_rsp, fcp_rsp, FCP_RESP_WITH_EXT); if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL) { fcp_rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1]; rec->fcp_rsp_info = fcp_rsp_info->rsp_code; + rec->pl_len += be32_to_cpu(fcp_rsp->ext.fr_rsp_len); } if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) { - rec->pl_len = min((u16)SCSI_SENSE_BUFFERSIZE, - (u16)ZFCP_DBF_PAY_MAX_REC); - zfcp_dbf_pl_write(dbf, sc->sense_buffer, rec->pl_len, - "fcp_sns", fsf->req_id); + rec->pl_len += be32_to_cpu(fcp_rsp->ext.fr_sns_len); } + /* complete FCP_RSP IU in associated PAYload record + * but only if there are optional parts + */ + if (fcp_rsp->resp.fr_flags != 0) + zfcp_dbf_pl_write( + dbf, fcp_rsp, + /* at least one full PAY record + * but not beyond hardware response field + */ + min_t(u16, max_t(u16, rec->pl_len, + ZFCP_DBF_PAY_MAX_REC), + FSF_FCP_RSP_SIZE), + "fcp_riu", fsf->req_id); } debug_event(dbf->scsi, level, rec, sizeof(*rec)); diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h index db186d4..3508c00 100644 --- a/drivers/s390/scsi/zfcp_dbf.h +++ b/drivers/s390/scsi/zfcp_dbf.h @@ -2,7 +2,7 @@ * zfcp device driver * debug feature declarations * - * Copyright IBM Corp. 2008, 2016 + * Copyright IBM Corp. 2008, 2017 */ #ifndef ZFCP_DBF_H @@ -204,16 +204,17 @@ enum zfcp_dbf_scsi_id { * @id: unique number of recovery record type * @tag: identifier string specifying the location of initiation * @scsi_id: scsi device id - * @scsi_lun: scsi device logical unit number + * @scsi_lun: scsi device logical unit number, low part of 64 bit, old 32 bit * @scsi_result: scsi result * @scsi_retries: current retry number of scsi request * @scsi_allowed: allowed retries - * @fcp_rsp_info: FCP response info + * @fcp_rsp_info: FCP response info code * @scsi_opcode: scsi opcode * @fsf_req_id: request id of fsf request * @host_scribble: LLD specific data attached to SCSI request - * @pl_len: length of paload stored as zfcp_dbf_pay - * @fsf_rsp: response for fsf request + * @pl_len: length of payload stored as zfcp_dbf_pay + * @fcp_rsp: response for FCP request + * @scsi_lun_64_hi: scsi device logical unit number, high part of 64 bit */ struct zfcp_dbf_scsi { u8 id; @@ -230,6 +231,7 @@ struct zfcp_dbf_scsi { u64 host_scribble; u16 pl_len; struct fcp_resp_with_ext fcp_rsp; + u32 scsi_lun_64_hi; } __packed; /** @@ -299,7 +301,7 @@ bool zfcp_dbf_hba_fsf_resp_suppress(struct zfcp_fsf_req *req) if (qtcb->prefix.qtcb_type != FSF_IO_COMMAND) return false; /* not an FCP response */ - fcp_rsp = (struct fcp_resp *)&qtcb->bottom.io.fcp_rsp; + fcp_rsp = &qtcb->bottom.io.fcp_rsp.iu.resp; rsp_flags = fcp_rsp->fr_flags; fr_status = fcp_rsp->fr_status; return (fsf_stat == FSF_FCP_RSP_AVAILABLE) && @@ -323,7 +325,11 @@ void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req) { struct fsf_qtcb *qtcb = req->qtcb; - if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && + if (unlikely(req->status & (ZFCP_STATUS_FSFREQ_DISMISSED | + ZFCP_STATUS_FSFREQ_ERROR))) { + zfcp_dbf_hba_fsf_resp("fs_rerr", 3, req); + + } else if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) { zfcp_dbf_hba_fsf_resp("fs_perr", 1, req); @@ -401,7 +407,8 @@ void zfcp_dbf_scsi_abort(char *tag, struct scsi_cmnd *scmd, * @flag: indicates type of reset (Target Reset, Logical Unit Reset) */ static inline -void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag) +void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag, + struct zfcp_fsf_req *fsf_req) { char tmp_tag[ZFCP_DBF_TAG_LEN]; @@ -411,7 +418,7 @@ void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag) memcpy(tmp_tag, "lr_", 3); memcpy(&tmp_tag[3], tag, 4); - _zfcp_dbf_scsi(tmp_tag, 1, scmnd, NULL); + _zfcp_dbf_scsi(tmp_tag, 1, scmnd, fsf_req); } /** diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 7ccfce5..37408f5 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -572,9 +572,8 @@ static void zfcp_erp_memwait_handler(unsigned long data) static void zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action) { - init_timer(&erp_action->timer); - erp_action->timer.function = zfcp_erp_memwait_handler; - erp_action->timer.data = (unsigned long) erp_action; + setup_timer(&erp_action->timer, zfcp_erp_memwait_handler, + (unsigned long) erp_action); erp_action->timer.expires = jiffies + HZ; add_timer(&erp_action->timer); } diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 9afdbc3..a9e9687 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -41,7 +41,6 @@ extern void zfcp_dbf_rec_run_wka(char *, struct zfcp_fc_wka_port *, u64); extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *); extern void zfcp_dbf_hba_fsf_res(char *, int, struct zfcp_fsf_req *); extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *); -extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *); extern void zfcp_dbf_hba_def_err(struct zfcp_adapter *, u64, u16, void **); extern void zfcp_dbf_hba_basic(char *, struct zfcp_adapter *); extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32); diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 7331eea..8210645 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -3,7 +3,7 @@ * * Fibre Channel related functions for the zfcp device driver. * - * Copyright IBM Corp. 2008, 2010 + * Copyright IBM Corp. 2008, 2017 */ #define KMSG_COMPONENT "zfcp" @@ -29,7 +29,7 @@ static u32 zfcp_fc_rscn_range_mask[] = { }; static bool no_auto_port_rescan; -module_param_named(no_auto_port_rescan, no_auto_port_rescan, bool, 0600); +module_param(no_auto_port_rescan, bool, 0600); MODULE_PARM_DESC(no_auto_port_rescan, "no automatic port_rescan (default off)"); @@ -260,7 +260,8 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) page = (struct fc_els_rscn_page *) head; /* see FC-FS */ - no_entries = head->rscn_plen / sizeof(struct fc_els_rscn_page); + no_entries = be16_to_cpu(head->rscn_plen) / + sizeof(struct fc_els_rscn_page); for (i = 1; i < no_entries; i++) { /* skip head and start with 1st element */ @@ -296,7 +297,7 @@ static void zfcp_fc_incoming_plogi(struct zfcp_fsf_req *req) status_buffer = (struct fsf_status_read_buffer *) req->data; plogi = (struct fc_els_flogi *) status_buffer->payload.data; - zfcp_fc_incoming_wwpn(req, plogi->fl_wwpn); + zfcp_fc_incoming_wwpn(req, be64_to_cpu(plogi->fl_wwpn)); } static void zfcp_fc_incoming_logo(struct zfcp_fsf_req *req) @@ -306,7 +307,7 @@ static void zfcp_fc_incoming_logo(struct zfcp_fsf_req *req) struct fc_els_logo *logo = (struct fc_els_logo *) status_buffer->payload.data; - zfcp_fc_incoming_wwpn(req, logo->fl_n_port_wwn); + zfcp_fc_incoming_wwpn(req, be64_to_cpu(logo->fl_n_port_wwn)); } /** @@ -335,7 +336,7 @@ static void zfcp_fc_ns_gid_pn_eval(struct zfcp_fc_req *fc_req) if (ct_els->status) return; - if (gid_pn_rsp->ct_hdr.ct_cmd != FC_FS_ACC) + if (gid_pn_rsp->ct_hdr.ct_cmd != cpu_to_be16(FC_FS_ACC)) return; /* looks like a valid d_id */ @@ -352,8 +353,8 @@ static void zfcp_fc_ct_ns_init(struct fc_ct_hdr *ct_hdr, u16 cmd, u16 mr_size) ct_hdr->ct_rev = FC_CT_REV; ct_hdr->ct_fs_type = FC_FST_DIR; ct_hdr->ct_fs_subtype = FC_NS_SUBTYPE; - ct_hdr->ct_cmd = cmd; - ct_hdr->ct_mr_size = mr_size / 4; + ct_hdr->ct_cmd = cpu_to_be16(cmd); + ct_hdr->ct_mr_size = cpu_to_be16(mr_size / 4); } static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port, @@ -376,7 +377,7 @@ static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port, zfcp_fc_ct_ns_init(&gid_pn_req->ct_hdr, FC_NS_GID_PN, ZFCP_FC_CT_SIZE_PAGE); - gid_pn_req->gid_pn.fn_wwpn = port->wwpn; + gid_pn_req->gid_pn.fn_wwpn = cpu_to_be64(port->wwpn); ret = zfcp_fsf_send_ct(&adapter->gs->ds, &fc_req->ct_els, adapter->pool.gid_pn_req, @@ -460,26 +461,26 @@ void zfcp_fc_trigger_did_lookup(struct zfcp_port *port) */ void zfcp_fc_plogi_evaluate(struct zfcp_port *port, struct fc_els_flogi *plogi) { - if (plogi->fl_wwpn != port->wwpn) { + if (be64_to_cpu(plogi->fl_wwpn) != port->wwpn) { port->d_id = 0; dev_warn(&port->adapter->ccw_device->dev, "A port opened with WWPN 0x%016Lx returned data that " "identifies it as WWPN 0x%016Lx\n", (unsigned long long) port->wwpn, - (unsigned long long) plogi->fl_wwpn); + (unsigned long long) be64_to_cpu(plogi->fl_wwpn)); return; } - port->wwnn = plogi->fl_wwnn; - port->maxframe_size = plogi->fl_csp.sp_bb_data; + port->wwnn = be64_to_cpu(plogi->fl_wwnn); + port->maxframe_size = be16_to_cpu(plogi->fl_csp.sp_bb_data); - if (plogi->fl_cssp[0].cp_class & FC_CPC_VALID) + if (plogi->fl_cssp[0].cp_class & cpu_to_be16(FC_CPC_VALID)) port->supported_classes |= FC_COS_CLASS1; - if (plogi->fl_cssp[1].cp_class & FC_CPC_VALID) + if (plogi->fl_cssp[1].cp_class & cpu_to_be16(FC_CPC_VALID)) port->supported_classes |= FC_COS_CLASS2; - if (plogi->fl_cssp[2].cp_class & FC_CPC_VALID) + if (plogi->fl_cssp[2].cp_class & cpu_to_be16(FC_CPC_VALID)) port->supported_classes |= FC_COS_CLASS3; - if (plogi->fl_cssp[3].cp_class & FC_CPC_VALID) + if (plogi->fl_cssp[3].cp_class & cpu_to_be16(FC_CPC_VALID)) port->supported_classes |= FC_COS_CLASS4; } @@ -497,9 +498,9 @@ static void zfcp_fc_adisc_handler(void *data) } if (!port->wwnn) - port->wwnn = adisc_resp->adisc_wwnn; + port->wwnn = be64_to_cpu(adisc_resp->adisc_wwnn); - if ((port->wwpn != adisc_resp->adisc_wwpn) || + if ((port->wwpn != be64_to_cpu(adisc_resp->adisc_wwpn)) || !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)) { zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, "fcadh_2"); @@ -538,8 +539,8 @@ static int zfcp_fc_adisc(struct zfcp_port *port) /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports without FC-AL-2 capability, so we don't set it */ - fc_req->u.adisc.req.adisc_wwpn = fc_host_port_name(shost); - fc_req->u.adisc.req.adisc_wwnn = fc_host_node_name(shost); + fc_req->u.adisc.req.adisc_wwpn = cpu_to_be64(fc_host_port_name(shost)); + fc_req->u.adisc.req.adisc_wwnn = cpu_to_be64(fc_host_node_name(shost)); fc_req->u.adisc.req.adisc_cmd = ELS_ADISC; hton24(fc_req->u.adisc.req.adisc_port_id, fc_host_port_id(shost)); @@ -666,8 +667,8 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_fc_req *fc_req, if (ct_els->status) return -EIO; - if (hdr->ct_cmd != FC_FS_ACC) { - if (hdr->ct_reason == FC_BA_RJT_UNABLE) + if (hdr->ct_cmd != cpu_to_be16(FC_FS_ACC)) { + if (hdr->ct_reason == FC_FS_RJT_UNABL) return -EAGAIN; /* might be a temporary condition */ return -EIO; } @@ -693,10 +694,11 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_fc_req *fc_req, if (d_id >= FC_FID_WELL_KNOWN_BASE) continue; /* skip the adapter's port and known remote ports */ - if (acc->fp_wwpn == fc_host_port_name(adapter->scsi_host)) + if (be64_to_cpu(acc->fp_wwpn) == + fc_host_port_name(adapter->scsi_host)) continue; - port = zfcp_port_enqueue(adapter, acc->fp_wwpn, + port = zfcp_port_enqueue(adapter, be64_to_cpu(acc->fp_wwpn), ZFCP_STATUS_COMMON_NOESC, d_id); if (!IS_ERR(port)) zfcp_erp_port_reopen(port, 0, "fcegpf1"); diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h index df2b541..41f22d3 100644 --- a/drivers/s390/scsi/zfcp_fc.h +++ b/drivers/s390/scsi/zfcp_fc.h @@ -4,7 +4,7 @@ * Fibre Channel related definitions and inline functions for the zfcp * device driver * - * Copyright IBM Corp. 2009 + * Copyright IBM Corp. 2009, 2017 */ #ifndef ZFCP_FC_H @@ -212,6 +212,8 @@ static inline void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi, u8 tm_flags) { + u32 datalen; + int_to_scsilun(scsi->device->lun, (struct scsi_lun *) &fcp->fc_lun); if (unlikely(tm_flags)) { @@ -228,10 +230,13 @@ void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi, memcpy(fcp->fc_cdb, scsi->cmnd, scsi->cmd_len); - fcp->fc_dl = scsi_bufflen(scsi); + datalen = scsi_bufflen(scsi); + fcp->fc_dl = cpu_to_be32(datalen); - if (scsi_get_prot_type(scsi) == SCSI_PROT_DIF_TYPE1) - fcp->fc_dl += fcp->fc_dl / scsi->device->sector_size * 8; + if (scsi_get_prot_type(scsi) == SCSI_PROT_DIF_TYPE1) { + datalen += datalen / scsi->device->sector_size * 8; + fcp->fc_dl = cpu_to_be32(datalen); + } } /** @@ -266,19 +271,23 @@ void zfcp_fc_eval_fcp_rsp(struct fcp_resp_with_ext *fcp_rsp, if (unlikely(rsp_flags & FCP_SNS_LEN_VAL)) { sense = (char *) &fcp_rsp[1]; if (rsp_flags & FCP_RSP_LEN_VAL) - sense += fcp_rsp->ext.fr_rsp_len; - sense_len = min(fcp_rsp->ext.fr_sns_len, - (u32) SCSI_SENSE_BUFFERSIZE); + sense += be32_to_cpu(fcp_rsp->ext.fr_rsp_len); + sense_len = min_t(u32, be32_to_cpu(fcp_rsp->ext.fr_sns_len), + SCSI_SENSE_BUFFERSIZE); memcpy(scsi->sense_buffer, sense, sense_len); } if (unlikely(rsp_flags & FCP_RESID_UNDER)) { - resid = fcp_rsp->ext.fr_resid; + resid = be32_to_cpu(fcp_rsp->ext.fr_resid); scsi_set_resid(scsi, resid); if (scsi_bufflen(scsi) - resid < scsi->underflow && !(rsp_flags & FCP_SNS_LEN_VAL) && fcp_rsp->resp.fr_status == SAM_STAT_GOOD) set_host_byte(scsi, DID_ERROR); + } else if (unlikely(rsp_flags & FCP_RESID_OVER)) { + /* FCP_DL was not sufficient for SCSI data length */ + if (fcp_rsp->resp.fr_status == SAM_STAT_GOOD) + set_host_byte(scsi, DID_ERROR); } } diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 27ff38f..69d1dc3 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -3,7 +3,7 @@ * * Implementation of FSF commands. * - * Copyright IBM Corp. 2002, 2015 + * Copyright IBM Corp. 2002, 2017 */ #define KMSG_COMPONENT "zfcp" @@ -197,8 +197,6 @@ static void zfcp_fsf_status_read_link_down(struct zfcp_fsf_req *req) switch (sr_buf->status_subtype) { case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: - zfcp_fsf_link_down_info_eval(req, ldi); - break; case FSF_STATUS_READ_SUB_FDISC_FAILED: zfcp_fsf_link_down_info_eval(req, ldi); break; @@ -476,8 +474,8 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) if (req->data) memcpy(req->data, bottom, sizeof(*bottom)); - fc_host_port_name(shost) = nsp->fl_wwpn; - fc_host_node_name(shost) = nsp->fl_wwnn; + fc_host_port_name(shost) = be64_to_cpu(nsp->fl_wwpn); + fc_host_node_name(shost) = be64_to_cpu(nsp->fl_wwnn); fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; adapter->timer_ticks = bottom->timer_interval & ZFCP_FSF_TIMER_INT_MASK; @@ -503,8 +501,8 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) switch (bottom->fc_topology) { case FSF_TOPO_P2P: adapter->peer_d_id = ntoh24(bottom->peer_d_id); - adapter->peer_wwpn = plogi->fl_wwpn; - adapter->peer_wwnn = plogi->fl_wwnn; + adapter->peer_wwpn = be64_to_cpu(plogi->fl_wwpn); + adapter->peer_wwnn = be64_to_cpu(plogi->fl_wwnn); fc_host_port_type(shost) = FC_PORTTYPE_PTP; break; case FSF_TOPO_FABRIC: @@ -928,8 +926,8 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) switch (header->fsf_status) { case FSF_GOOD: - zfcp_dbf_san_res("fsscth2", req); ct->status = 0; + zfcp_dbf_san_res("fsscth2", req); break; case FSF_SERVICE_CLASS_NOT_SUPPORTED: zfcp_fsf_class_not_supp(req); @@ -991,8 +989,7 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, qtcb->bottom.support.resp_buf_length = zfcp_qdio_real_bytes(sg_resp); - zfcp_qdio_set_data_div(qdio, &req->qdio_req, - zfcp_qdio_sbale_count(sg_req)); + zfcp_qdio_set_data_div(qdio, &req->qdio_req, sg_nents(sg_req)); zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); zfcp_qdio_set_scount(qdio, &req->qdio_req); return 0; @@ -1109,8 +1106,8 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req) switch (header->fsf_status) { case FSF_GOOD: - zfcp_dbf_san_res("fsselh1", req); send_els->status = 0; + zfcp_dbf_san_res("fsselh1", req); break; case FSF_SERVICE_CLASS_NOT_SUPPORTED: zfcp_fsf_class_not_supp(req); @@ -1394,6 +1391,8 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) case FSF_ADAPTER_STATUS_AVAILABLE: switch (header->fsf_status_qual.word[0]) { case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: + /* no zfcp_fc_test_link() with failed open port */ + /* fall through */ case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: case FSF_SQ_NO_RETRY_POSSIBLE: req->status |= ZFCP_STATUS_FSFREQ_ERROR; @@ -2142,7 +2141,8 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req) zfcp_scsi_dif_sense_error(scpnt, 0x3); goto skip_fsfstatus; } - fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp; + BUILD_BUG_ON(sizeof(struct fcp_resp_with_ext) > FSF_FCP_RSP_SIZE); + fcp_rsp = &req->qtcb->bottom.io.fcp_rsp.iu; zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt); skip_fsfstatus: @@ -2255,10 +2255,12 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd) if (zfcp_fsf_set_data_dir(scsi_cmnd, &io->data_direction)) goto failed_scsi_cmnd; - fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; + BUILD_BUG_ON(sizeof(struct fcp_cmnd) > FSF_FCP_CMND_SIZE); + fcp_cmnd = &req->qtcb->bottom.io.fcp_cmnd.iu; zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd, 0); - if (scsi_prot_sg_count(scsi_cmnd)) { + if ((scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) && + scsi_prot_sg_count(scsi_cmnd)) { zfcp_qdio_set_data_div(qdio, &req->qdio_req, scsi_prot_sg_count(scsi_cmnd)); retval = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, @@ -2299,7 +2301,7 @@ static void zfcp_fsf_fcp_task_mgmt_handler(struct zfcp_fsf_req *req) zfcp_fsf_fcp_handler_common(req); - fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp; + fcp_rsp = &req->qtcb->bottom.io.fcp_rsp.iu; rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1]; if ((rsp_info->rsp_code != FCP_TMF_CMPL) || @@ -2348,7 +2350,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd, zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); - fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; + fcp_cmnd = &req->qtcb->bottom.io.fcp_cmnd.iu; zfcp_fc_scsi_to_fcp(fcp_cmnd, scmnd, tm_flags); zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT); @@ -2392,7 +2394,6 @@ void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx) req_id, dev_name(&adapter->ccw_device->dev)); } - fsf_req->qdio_req.sbal_response = sbal_idx; zfcp_fsf_req_complete(fsf_req); if (likely(sbale->eflags & SBAL_EFLAGS_LAST_ENTRY)) diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h index ea3c76a..88feba5 100644 --- a/drivers/s390/scsi/zfcp_fsf.h +++ b/drivers/s390/scsi/zfcp_fsf.h @@ -3,7 +3,7 @@ * * Interface to the FSF support functions. * - * Copyright IBM Corp. 2002, 2016 + * Copyright IBM Corp. 2002, 2017 */ #ifndef FSF_H @@ -312,8 +312,14 @@ struct fsf_qtcb_bottom_io { u32 data_block_length; u32 prot_data_length; u8 res2[4]; - u8 fcp_cmnd[FSF_FCP_CMND_SIZE]; - u8 fcp_rsp[FSF_FCP_RSP_SIZE]; + union { + u8 byte[FSF_FCP_CMND_SIZE]; + struct fcp_cmnd iu; + } fcp_cmnd; + union { + u8 byte[FSF_FCP_RSP_SIZE]; + struct fcp_resp_with_ext iu; + } fcp_rsp; u8 res3[64]; } __attribute__ ((packed)); diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index dbf2b547..9e358fc 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -14,7 +14,7 @@ #include "zfcp_ext.h" #include "zfcp_qdio.h" -static bool enable_multibuffer = 1; +static bool enable_multibuffer = true; module_param_named(datarouter, enable_multibuffer, bool, 0400); MODULE_PARM_DESC(datarouter, "Enable hardware data router support (default on)"); diff --git a/drivers/s390/scsi/zfcp_qdio.h b/drivers/s390/scsi/zfcp_qdio.h index 497cd37..7f647a9 100644 --- a/drivers/s390/scsi/zfcp_qdio.h +++ b/drivers/s390/scsi/zfcp_qdio.h @@ -54,7 +54,6 @@ struct zfcp_qdio { * @sbal_last: last sbal for this request * @sbal_limit: last possible sbal for this request * @sbale_curr: current sbale at creation of this request - * @sbal_response: sbal used in interrupt * @qdio_outb_usage: usage of outbound queue */ struct zfcp_qdio_req { @@ -64,7 +63,6 @@ struct zfcp_qdio_req { u8 sbal_last; u8 sbal_limit; u8 sbale_curr; - u8 sbal_response; u16 qdio_outb_usage; }; @@ -225,21 +223,6 @@ void zfcp_qdio_set_data_div(struct zfcp_qdio *qdio, } /** - * zfcp_qdio_sbale_count - count sbale used - * @sg: pointer to struct scatterlist - */ -static inline -unsigned int zfcp_qdio_sbale_count(struct scatterlist *sg) -{ - unsigned int count = 0; - - for (; sg; sg = sg_next(sg)) - count++; - - return count; -} - -/** * zfcp_qdio_real_bytes - count bytes used * @sg: pointer to struct scatterlist */ diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 0678cf7..ec3ddd1 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -3,7 +3,7 @@ * * Interface to Linux SCSI midlayer. * - * Copyright IBM Corp. 2002, 2016 + * Copyright IBM Corp. 2002, 2017 */ #define KMSG_COMPONENT "zfcp" @@ -28,7 +28,7 @@ static bool enable_dif; module_param_named(dif, enable_dif, bool, 0400); MODULE_PARM_DESC(dif, "Enable DIF/DIX data integrity support"); -static bool allow_lun_scan = 1; +static bool allow_lun_scan = true; module_param(allow_lun_scan, bool, 0600); MODULE_PARM_DESC(allow_lun_scan, "For NPIV, scan and attach all storage LUNs"); @@ -273,25 +273,29 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) zfcp_erp_wait(adapter); ret = fc_block_scsi_eh(scpnt); - if (ret) + if (ret) { + zfcp_dbf_scsi_devreset("fiof", scpnt, tm_flags, NULL); return ret; + } if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_RUNNING)) { - zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags); + zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags, NULL); return SUCCESS; } } - if (!fsf_req) + if (!fsf_req) { + zfcp_dbf_scsi_devreset("reqf", scpnt, tm_flags, NULL); return FAILED; + } wait_for_completion(&fsf_req->completion); if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) { - zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags); + zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags, fsf_req); retval = FAILED; } else { - zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags); + zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags, fsf_req); zfcp_scsi_forget_cmnds(zfcp_sdev, tm_flags); } |