diff options
Diffstat (limited to 'drivers/scsi/libfc/fc_fcp.c')
| -rw-r--r-- | drivers/scsi/libfc/fc_fcp.c | 136 |
1 files changed, 60 insertions, 76 deletions
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index b1bd283be51c..31d08c115521 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -1,21 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright(c) 2007 Intel Corporation. All rights reserved. * Copyright(c) 2008 Red Hat, Inc. All rights reserved. * Copyright(c) 2008 Mike Christie * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * * Maintained at www.Open-FCoE.org */ @@ -38,8 +26,8 @@ #include <scsi/fc/fc_fc2.h> #include <scsi/libfc.h> -#include <scsi/fc_encode.h> +#include "fc_encode.h" #include "fc_libfc.h" static struct kmem_cache *scsi_pkt_cachep; @@ -57,14 +45,10 @@ static struct kmem_cache *scsi_pkt_cachep; #define FC_SRB_READ (1 << 1) #define FC_SRB_WRITE (1 << 0) -/* - * The SCp.ptr should be tested and set under the scsi_pkt_queue lock - */ -#define CMD_SP(Cmnd) ((struct fc_fcp_pkt *)(Cmnd)->SCp.ptr) -#define CMD_ENTRY_STATUS(Cmnd) ((Cmnd)->SCp.have_data_in) -#define CMD_COMPL_STATUS(Cmnd) ((Cmnd)->SCp.this_residual) -#define CMD_SCSI_STATUS(Cmnd) ((Cmnd)->SCp.Status) -#define CMD_RESID_LEN(Cmnd) ((Cmnd)->SCp.buffers_residual) +static struct libfc_cmd_priv *libfc_priv(struct scsi_cmnd *cmd) +{ + return scsi_cmd_priv(cmd); +} /** * struct fc_fcp_internal - FCP layer internal data @@ -159,8 +143,7 @@ static struct fc_fcp_pkt *fc_fcp_pkt_alloc(struct fc_lport *lport, gfp_t gfp) INIT_LIST_HEAD(&fsp->list); spin_lock_init(&fsp->scsi_pkt_lock); } else { - per_cpu_ptr(lport->stats, get_cpu())->FcpPktAllocFails++; - put_cpu(); + this_cpu_inc(lport->stats->FcpPktAllocFails); } return fsp; } @@ -282,8 +265,12 @@ static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp) if (!fsp->seq_ptr) return -EINVAL; - per_cpu_ptr(fsp->lp->stats, get_cpu())->FcpPktAborts++; - put_cpu(); + if (fsp->state & FC_SRB_ABORT_PENDING) { + FC_FCP_DBG(fsp, "abort already pending\n"); + return -EBUSY; + } + + this_cpu_inc(fsp->lp->stats->FcpPktAborts); fsp->state |= FC_SRB_ABORT_PENDING; rc = fc_seq_exch_abort(fsp->seq_ptr, 0); @@ -301,6 +288,7 @@ static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp) /** * fc_fcp_retry_cmd() - Retry a fcp_pkt * @fsp: The FCP packet to be retried + * @status_code: The FCP status code to set * * Sets the status code to be FC_ERROR and then calls * fc_fcp_complete_locked() which in turn calls fc_io_compl(). @@ -451,8 +439,7 @@ static inline struct fc_frame *fc_fcp_frame_alloc(struct fc_lport *lport, if (likely(fp)) return fp; - per_cpu_ptr(lport->stats, get_cpu())->FcpFrameAllocFails++; - put_cpu(); + this_cpu_inc(lport->stats->FcpFrameAllocFails); /* error case */ fc_fcp_can_queue_ramp_down(lport); shost_printk(KERN_ERR, lport->host, @@ -486,7 +473,6 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) { struct scsi_cmnd *sc = fsp->cmd; struct fc_lport *lport = fsp->lp; - struct fc_stats *stats; struct fc_frame_header *fh; size_t start_offset; size_t offset; @@ -517,7 +503,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) host_bcode = FC_ERROR; goto err; } - if (offset + len > fsp->data_len) { + if (size_add(offset, len) > fsp->data_len) { /* this should never happen */ if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) && fc_frame_crc_check(fp)) @@ -548,14 +534,12 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) if (~crc != le32_to_cpu(fr_crc(fp))) { crc_err: - stats = per_cpu_ptr(lport->stats, get_cpu()); - stats->ErrorFrames++; + this_cpu_inc(lport->stats->ErrorFrames); /* per cpu count, not total count, but OK for limit */ - if (stats->InvalidCRCCount++ < FC_MAX_ERROR_CNT) + if (this_cpu_inc_return(lport->stats->InvalidCRCCount) < FC_MAX_ERROR_CNT) printk(KERN_WARNING "libfc: CRC error on data " "frame for port (%6.6x)\n", lport->port_id); - put_cpu(); /* * Assume the frame is total garbage. * We may have copied it over the good part @@ -592,7 +576,7 @@ err: /** * fc_fcp_send_data() - Send SCSI data to a target * @fsp: The FCP packet the data is on - * @sp: The sequence the data is to be sent on + * @seq: The sequence the data is to be sent on * @offset: The starting offset for this data request * @seq_blen: The burst length for this data request * @@ -763,7 +747,7 @@ static void fc_fcp_abts_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) brp = fc_frame_payload_get(fp, sizeof(*brp)); if (brp && brp->br_reason == FC_BA_RJT_LOG_ERR) break; - /* fall thru */ + fallthrough; default: /* * we will let the command timeout @@ -1148,7 +1132,7 @@ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp) unsigned long flags; int rc; - fsp->cmd->SCp.ptr = (char *)fsp; + libfc_priv(fsp->cmd)->fsp = fsp; fsp->cdb_cmd.fc_dl = htonl(fsp->data_len); fsp->cdb_cmd.fc_flags = fsp->req_flags & ~FCP_CFL_LEN_MASK; @@ -1161,7 +1145,7 @@ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp) rc = lport->tt.fcp_cmd_send(lport, fsp, fc_fcp_recv); if (unlikely(rc)) { spin_lock_irqsave(&si->scsi_queue_lock, flags); - fsp->cmd->SCp.ptr = NULL; + libfc_priv(fsp->cmd)->fsp = NULL; list_del(&fsp->list); spin_unlock_irqrestore(&si->scsi_queue_lock, flags); } @@ -1295,11 +1279,11 @@ static int fc_fcp_pkt_abort(struct fc_fcp_pkt *fsp) /** * fc_lun_reset_send() - Send LUN reset command - * @data: The FCP packet that identifies the LUN to be reset + * @t: Timer context used to fetch the FSP packet */ static void fc_lun_reset_send(struct timer_list *t) { - struct fc_fcp_pkt *fsp = from_timer(fsp, t, timer); + struct fc_fcp_pkt *fsp = timer_container_of(fsp, t, timer); struct fc_lport *lport = fsp->lp; if (lport->tt.fcp_cmd_send(lport, fsp, fc_tm_done)) { @@ -1345,7 +1329,7 @@ static int fc_lun_reset(struct fc_lport *lport, struct fc_fcp_pkt *fsp, fsp->state |= FC_SRB_COMPL; spin_unlock_bh(&fsp->scsi_pkt_lock); - del_timer_sync(&fsp->timer); + timer_delete_sync(&fsp->timer); spin_lock_bh(&fsp->scsi_pkt_lock); if (fsp->seq_ptr) { @@ -1421,7 +1405,7 @@ static void fc_fcp_cleanup(struct fc_lport *lport) /** * fc_fcp_timeout() - Handler for fcp_pkt timeouts - * @data: The FCP packet that has timed out + * @t: Timer context used to fetch the FSP packet * * If REC is supported then just issue it and return. The REC exchange will * complete or time out and recovery can continue at that point. Otherwise, @@ -1432,7 +1416,7 @@ static void fc_fcp_cleanup(struct fc_lport *lport) */ static void fc_fcp_timeout(struct timer_list *t) { - struct fc_fcp_pkt *fsp = from_timer(fsp, t, timer); + struct fc_fcp_pkt *fsp = timer_container_of(fsp, t, timer); struct fc_rport *rport = fsp->rport; struct fc_rport_libfc_priv *rpriv = rport->dd_data; @@ -1547,7 +1531,7 @@ static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) "device %x invalid REC reject %d/%d\n", fsp->rport->port_id, rjt->er_reason, rjt->er_explan); - /* fall through */ + fallthrough; case ELS_RJT_UNSUP: FC_FCP_DBG(fsp, "device does not support REC\n"); rpriv = fsp->rport->dd_data; @@ -1679,7 +1663,7 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) FC_FCP_DBG(fsp, "REC %p fid %6.6x error unexpected error %d\n", fsp, fsp->rport->port_id, error); fsp->status_code = FC_CMD_PLOGO; - /* fall through */ + fallthrough; case -FC_EX_TIMEOUT: /* @@ -1692,7 +1676,7 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) fc_fcp_rec(fsp); else - fc_fcp_recovery(fsp, FC_ERROR); + fc_fcp_recovery(fsp, FC_TIMED_OUT); break; } fc_fcp_unlock_pkt(fsp); @@ -1703,6 +1687,7 @@ out: /** * fc_fcp_recovery() - Handler for fcp_pkt recovery * @fsp: The FCP pkt that needs to be aborted + * @code: The FCP status code to set */ static void fc_fcp_recovery(struct fc_fcp_pkt *fsp, u8 code) { @@ -1710,17 +1695,19 @@ static void fc_fcp_recovery(struct fc_fcp_pkt *fsp, u8 code) fsp->status_code = code; fsp->cdb_status = 0; fsp->io_status = 0; - /* - * if this fails then we let the scsi command timer fire and - * scsi-ml escalate. - */ - fc_fcp_send_abort(fsp); + if (!fsp->cmd) + /* + * Only abort non-scsi commands; otherwise let the + * scsi command timer fire and scsi-ml escalate. + */ + fc_fcp_send_abort(fsp); } /** * fc_fcp_srr() - Send a SRR request (Sequence Retransmission Request) * @fsp: The FCP packet the SRR is to be sent on * @r_ctl: The R_CTL field for the SRR request + * @offset: The SRR relative offset * This is called after receiving status but insufficient data, or * when expecting status but the request has timed out. */ @@ -1839,7 +1826,7 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) break; case -FC_EX_CLOSED: /* e.g., link failure */ FC_FCP_DBG(fsp, "SRR error, exchange closed\n"); - /* fall through */ + fallthrough; default: fc_fcp_retry_cmd(fsp, FC_ERROR); break; @@ -1863,7 +1850,7 @@ static inline int fc_fcp_lport_queue_ready(struct fc_lport *lport) /** * fc_queuecommand() - The queuecommand function of the SCSI template * @shost: The Scsi_Host that the command was issued to - * @cmd: The scsi_cmnd to be executed + * @sc_cmd: The scsi_cmnd to be executed * * This is the i/o strategy routine, called by the SCSI layer. */ @@ -1874,12 +1861,11 @@ int fc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc_cmd) struct fc_fcp_pkt *fsp; int rval; int rc = 0; - struct fc_stats *stats; rval = fc_remote_port_chkready(rport); if (rval) { sc_cmd->result = rval; - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); return 0; } @@ -1889,7 +1875,7 @@ int fc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc_cmd) * online */ sc_cmd->result = DID_IMM_RETRY << 16; - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); goto out; } @@ -1926,20 +1912,18 @@ int fc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc_cmd) /* * setup the data direction */ - stats = per_cpu_ptr(lport->stats, get_cpu()); if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) { fsp->req_flags = FC_SRB_READ; - stats->InputRequests++; - stats->InputBytes += fsp->data_len; + this_cpu_inc(lport->stats->InputRequests); + this_cpu_add(lport->stats->InputBytes, fsp->data_len); } else if (sc_cmd->sc_data_direction == DMA_TO_DEVICE) { fsp->req_flags = FC_SRB_WRITE; - stats->OutputRequests++; - stats->OutputBytes += fsp->data_len; + this_cpu_inc(lport->stats->OutputRequests); + this_cpu_add(lport->stats->OutputBytes, fsp->data_len); } else { fsp->req_flags = 0; - stats->ControlRequests++; + this_cpu_inc(lport->stats->ControlRequests); } - put_cpu(); /* * send it to the lower layer @@ -1977,7 +1961,7 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) fsp->state |= FC_SRB_COMPL; if (!(fsp->state & FC_SRB_FCP_PROCESSING_TMO)) { spin_unlock_bh(&fsp->scsi_pkt_lock); - del_timer_sync(&fsp->timer); + timer_delete_sync(&fsp->timer); spin_lock_bh(&fsp->scsi_pkt_lock); } @@ -1992,7 +1976,7 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) fc_fcp_can_queue_ramp_up(lport); sc_cmd = fsp->cmd; - CMD_SCSI_STATUS(sc_cmd) = fsp->cdb_status; + libfc_priv(sc_cmd)->status = fsp->cdb_status; switch (fsp->status_code) { case FC_COMPLETE: if (fsp->cdb_status == 0) { @@ -2001,7 +1985,7 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) */ sc_cmd->result = DID_OK << 16; if (fsp->scsi_resid) - CMD_RESID_LEN(sc_cmd) = fsp->scsi_resid; + libfc_priv(sc_cmd)->resid_len = fsp->scsi_resid; } else { /* * transport level I/O was ok but scsi @@ -2034,7 +2018,7 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) */ FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml " "due to FC_DATA_UNDRUN (scsi)\n"); - CMD_RESID_LEN(sc_cmd) = fsp->scsi_resid; + libfc_priv(sc_cmd)->resid_len = fsp->scsi_resid; sc_cmd->result = (DID_ERROR << 16) | fsp->cdb_status; } break; @@ -2078,9 +2062,9 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) sc_cmd->result = (DID_PARITY << 16); break; case FC_TIMED_OUT: - FC_FCP_DBG(fsp, "Returning DID_BUS_BUSY to scsi-ml " + FC_FCP_DBG(fsp, "Returning DID_TIME_OUT to scsi-ml " "due to FC_TIMED_OUT\n"); - sc_cmd->result = (DID_BUS_BUSY << 16) | fsp->io_status; + sc_cmd->result = (DID_TIME_OUT << 16); break; default: FC_FCP_DBG(fsp, "Returning DID_ERROR to scsi-ml " @@ -2094,9 +2078,9 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) spin_lock_irqsave(&si->scsi_queue_lock, flags); list_del(&fsp->list); - sc_cmd->SCp.ptr = NULL; + libfc_priv(sc_cmd)->fsp = NULL; spin_unlock_irqrestore(&si->scsi_queue_lock, flags); - sc_cmd->scsi_done(sc_cmd); + scsi_done(sc_cmd); /* release ref from initial allocation in queue command */ fc_fcp_pkt_release(fsp); @@ -2130,7 +2114,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd) si = fc_get_scsi_internal(lport); spin_lock_irqsave(&si->scsi_queue_lock, flags); - fsp = CMD_SP(sc_cmd); + fsp = libfc_priv(sc_cmd)->fsp; if (!fsp) { /* command completed while scsi eh was setting up */ spin_unlock_irqrestore(&si->scsi_queue_lock, flags); @@ -2238,13 +2222,13 @@ int fc_eh_host_reset(struct scsi_cmnd *sc_cmd) EXPORT_SYMBOL(fc_eh_host_reset); /** - * fc_slave_alloc() - Configure the queue depth of a Scsi_Host + * fc_sdev_init() - Configure the queue depth of a Scsi_Host * @sdev: The SCSI device that identifies the SCSI host * * Configures queue depth based on host's cmd_per_len. If not set * then we use the libfc default. */ -int fc_slave_alloc(struct scsi_device *sdev) +int fc_sdev_init(struct scsi_device *sdev) { struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); @@ -2254,10 +2238,10 @@ int fc_slave_alloc(struct scsi_device *sdev) scsi_change_queue_depth(sdev, FC_FCP_DFLT_QUEUE_DEPTH); return 0; } -EXPORT_SYMBOL(fc_slave_alloc); +EXPORT_SYMBOL(fc_sdev_init); /** - * fc_fcp_destory() - Tear down the FCP layer for a given local port + * fc_fcp_destroy() - Tear down the FCP layer for a given local port * @lport: The local port that no longer needs the FCP layer */ void fc_fcp_destroy(struct fc_lport *lport) |
