[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <6a66c3ec-1b43-44ce-a3ab-65ec794a2dc6@suse.de>
Date: Thu, 24 Oct 2024 09:04:34 +0200
From: Hannes Reinecke <hare@...e.de>
To: Karan Tilak Kumar <kartilak@...co.com>, sebaddel@...co.com
Cc: arulponn@...co.com, djhawar@...co.com, gcboffa@...co.com,
mkai2@...co.com, satishkh@...co.com, aeasi@...co.com, jejb@...ux.ibm.com,
martin.petersen@...cle.com, linux-scsi@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH v5 09/14] scsi: fnic: Modify IO path to use FDLS
On 10/18/24 18:14, Karan Tilak Kumar wrote:
> Modify IO path to use FDLS.
> Add helper functions to process IOs.
> Remove unused template functions.
> Cleanup obsolete code.
> Refactor old function definitions.
>
> Reviewed-by: Sesidhar Baddela <sebaddel@...co.com>
> Reviewed-by: Arulprabhu Ponnusamy <arulponn@...co.com>
> Reviewed-by: Gian Carlo Boffa <gcboffa@...co.com>
> Reviewed-by: Arun Easi <aeasi@...co.com>
> Signed-off-by: Karan Tilak Kumar <kartilak@...co.com>
> ---
> Changes between v2 and v3:
> Replace fnic->host with fnic->lport->host to prevent compilation
> errors.
>
> Changes between v1 and v2:
> Replace pr_err with printk.
> Incorporate review comments by Hannes:
> Restore usage of tagset iterators.
> ---
> drivers/scsi/fnic/fnic.h | 20 +-
> drivers/scsi/fnic/fnic_io.h | 3 +
> drivers/scsi/fnic/fnic_main.c | 5 +-
> drivers/scsi/fnic/fnic_scsi.c | 846 +++++++++++++++++++--------------
> drivers/scsi/fnic/fnic_stats.h | 2 -
> 5 files changed, 513 insertions(+), 363 deletions(-)
>
> diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
> index 4f38cbae1994..c6fe9eec9a0c 100644
> --- a/drivers/scsi/fnic/fnic.h
> +++ b/drivers/scsi/fnic/fnic.h
> @@ -40,6 +40,7 @@
> #define FNIC_DFLT_IO_REQ 256 /* Default scsi_cmnd tag map entries */
> #define FNIC_DFLT_QUEUE_DEPTH 256
> #define FNIC_STATS_RATE_LIMIT 4 /* limit rate at which stats are pulled up */
> +#define LUN0_DELAY_TIME 9
>
> /*
> * Tag bits used for special requests.
> @@ -472,7 +473,6 @@ int fnic_set_intr_mode_msix(struct fnic *fnic);
> void fnic_free_intr(struct fnic *fnic);
> int fnic_request_intr(struct fnic *fnic);
>
> -int fnic_send(struct fc_lport *, struct fc_frame *);
> void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf);
> void fnic_handle_frame(struct work_struct *work);
> void fnic_tport_event_handler(struct work_struct *work);
> @@ -489,11 +489,9 @@ int fnic_abort_cmd(struct scsi_cmnd *);
> int fnic_device_reset(struct scsi_cmnd *);
> int fnic_eh_host_reset_handler(struct scsi_cmnd *sc);
> int fnic_host_reset(struct Scsi_Host *shost);
> -int fnic_reset(struct Scsi_Host *);
> -void fnic_scsi_cleanup(struct fc_lport *);
> -void fnic_scsi_abort_io(struct fc_lport *);
> -void fnic_empty_scsi_cleanup(struct fc_lport *);
> -void fnic_exch_mgr_reset(struct fc_lport *, u32, u32);
> +void fnic_reset(struct Scsi_Host *shost);
> +int fnic_issue_fc_host_lip(struct Scsi_Host *shost);
> +void fnic_scsi_fcpio_reset(struct fnic *fnic);
> int fnic_wq_copy_cmpl_handler(struct fnic *fnic, int copy_work_to_do, unsigned int cq_index);
> int fnic_wq_cmpl_handler(struct fnic *fnic, int);
> int fnic_flogi_reg_handler(struct fnic *fnic, u32);
> @@ -505,7 +503,8 @@ const char *fnic_state_to_str(unsigned int state);
> void fnic_mq_map_queues_cpus(struct Scsi_Host *host);
> void fnic_log_q_error(struct fnic *fnic);
> void fnic_handle_link_event(struct fnic *fnic);
> -
> +void fnic_stats_debugfs_init(struct fnic *fnic);
> +void fnic_stats_debugfs_remove(struct fnic *fnic);
> int fnic_is_abts_pending(struct fnic *, struct scsi_cmnd *);
>
> void fnic_handle_fip_frame(struct work_struct *work);
> @@ -526,5 +525,12 @@ int fnic_get_desc_by_devid(struct pci_dev *pdev, char **desc,
> void fnic_fdls_link_status_change(struct fnic *fnic, int linkup);
> void fnic_delete_fcp_tports(struct fnic *fnic);
> void fnic_flush_tport_event_list(struct fnic *fnic);
> +int fnic_count_ioreqs_wq(struct fnic *fnic, u32 hwq, u32 portid);
> +unsigned int fnic_count_ioreqs(struct fnic *fnic, u32 portid);
> +unsigned int fnic_count_all_ioreqs(struct fnic *fnic);
> +unsigned int fnic_count_lun_ioreqs_wq(struct fnic *fnic, u32 hwq,
> + struct scsi_device *device);
> +unsigned int fnic_count_lun_ioreqs(struct fnic *fnic,
> + struct scsi_device *device);
>
> #endif /* _FNIC_H_ */
> diff --git a/drivers/scsi/fnic/fnic_io.h b/drivers/scsi/fnic/fnic_io.h
> index 6fe642cb387b..0d974e040ab7 100644
> --- a/drivers/scsi/fnic/fnic_io.h
> +++ b/drivers/scsi/fnic/fnic_io.h
> @@ -7,6 +7,7 @@
> #define _FNIC_IO_H_
>
> #include <scsi/fc/fc_fcp.h>
> +#include "fnic_fdls.h"
>
> #define FNIC_DFLT_SG_DESC_CNT 32
> #define FNIC_MAX_SG_DESC_CNT 256 /* Maximum descriptors per sgl */
> @@ -41,6 +42,8 @@ enum fnic_ioreq_state {
> };
>
> struct fnic_io_req {
> + struct fnic_iport_s *iport;
> + struct fnic_tport_s *tport;
> struct host_sg_desc *sgl_list; /* sgl list */
> void *sgl_list_alloc; /* sgl list address used for free */
> dma_addr_t sense_buf_pa; /* dma address for sense buffer*/
> diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
> index 33c63d7a9787..dadbe47c0bbb 100644
> --- a/drivers/scsi/fnic/fnic_main.c
> +++ b/drivers/scsi/fnic/fnic_main.c
> @@ -85,9 +85,6 @@ module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR);
> MODULE_PARM_DESC(fnic_max_qdepth, "Queue depth to report for each LUN");
>
> static struct libfc_function_template fnic_transport_template = {
> - .fcp_abort_io = fnic_empty_scsi_cleanup,
> - .fcp_cleanup = fnic_empty_scsi_cleanup,
> - .exch_mgr_reset = fnic_exch_mgr_reset
> };
>
The template is now empty; can't you delete it completely?
> struct workqueue_struct *fnic_fip_queue;
> @@ -162,7 +159,7 @@ static struct fc_function_template fnic_fc_functions = {
> .show_starget_port_id = 1,
> .show_rport_dev_loss_tmo = 1,
> .set_rport_dev_loss_tmo = fnic_set_rport_dev_loss_tmo,
> - .issue_fc_host_lip = fnic_reset,
> + .issue_fc_host_lip = fnic_issue_fc_host_lip,
> .get_fc_host_stats = fnic_get_stats,
> .reset_fc_host_stats = fnic_reset_host_stats,
> .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
> diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
> index 74298f9a34e5..af729637ef2d 100644
> --- a/drivers/scsi/fnic/fnic_scsi.c
> +++ b/drivers/scsi/fnic/fnic_scsi.c
> @@ -25,9 +25,12 @@
> #include <scsi/fc/fc_fcoe.h>
> #include <scsi/libfc.h>
> #include <scsi/fc_frame.h>
> +#include <scsi/scsi_transport_fc.h>
> #include "fnic_io.h"
> #include "fnic.h"
>
> +static void fnic_cleanup_io(struct fnic *fnic, int exclude_id);
> +
> const char *fnic_state_str[] = {
> [FNIC_IN_FC_MODE] = "FNIC_IN_FC_MODE",
> [FNIC_IN_FC_TRANS_ETH_MODE] = "FNIC_IN_FC_TRANS_ETH_MODE",
> @@ -65,6 +68,18 @@ static const char *fcpio_status_str[] = {
> [FCPIO_LUNMAP_CHNG_PEND] = "FCPIO_LUNHMAP_CHNG_PEND",
> };
>
> +enum terminate_io_return {
> + TERM_SUCCESS = 0,
> + TERM_NO_SC = 1,
> + TERM_IO_REQ_NOT_FOUND,
> + TERM_ANOTHER_PORT,
> + TERM_GSTATE,
> + TERM_IO_BLOCKED,
> + TERM_OUT_OF_WQ_DESC,
> + TERM_TIMED_OUT,
> + TERM_MISC,
> +};
> +
> const char *fnic_state_to_str(unsigned int state)
> {
> if (state >= ARRAY_SIZE(fnic_state_str) || !fnic_state_str[state])
> @@ -90,8 +105,6 @@ static const char *fnic_fcpio_status_to_str(unsigned int status)
> return fcpio_status_str[status];
> }
>
> -static void fnic_cleanup_io(struct fnic *fnic);
> -
> /*
> * Unmap the data buffer and sense buffer for an io_req,
> * also unmap and free the device-private scatter/gather list.
> @@ -114,6 +127,80 @@ static void fnic_release_ioreq_buf(struct fnic *fnic,
> SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
> }
>
> +int fnic_count_ioreqs_wq(struct fnic *fnic, u32 hwq, u32 portid)
> +{
> + unsigned long flags = 0;
> + int i = 0, count = 0;
> +
> + spin_lock_irqsave(&fnic->wq_copy_lock[hwq], flags);
> + for (i = 0; i != fnic->sw_copy_wq[hwq].ioreq_table_size; ++i) {
> + if (fnic->sw_copy_wq[hwq].io_req_table[i] != NULL &&
> + (!portid
> + || fnic->sw_copy_wq[hwq].io_req_table[i]->port_id == portid))
> + count++;
> + }
> + spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
> +
> + return count;
> +}
> +
> +unsigned int fnic_count_ioreqs(struct fnic *fnic, u32 portid)
> +{
> + int i;
> + unsigned int count = 0;
> +
> + for (i = 0; i < fnic->wq_copy_count; i++)
> + count += fnic_count_ioreqs_wq(fnic, i, portid);
> +
> + return count;
> +}
> +
> +unsigned int fnic_count_all_ioreqs(struct fnic *fnic)
> +{
> + return fnic_count_ioreqs(fnic, 0);
> +}
> +
> +unsigned int fnic_count_lun_ioreqs_wq(struct fnic *fnic, u32 hwq,
> + struct scsi_device *device)
> +{
> + struct fnic_io_req *io_req;
> + int i;
> + unsigned int count = 0;
> + unsigned long flags = 0;
> +
> + spin_lock_irqsave(&fnic->wq_copy_lock[hwq], flags);
> + for (i = 0; i != fnic->sw_copy_wq[hwq].ioreq_table_size; ++i) {
> + io_req = fnic->sw_copy_wq[hwq].io_req_table[i];
> +
> + if (io_req != NULL) {
> + struct scsi_cmnd *sc =
> + scsi_host_find_tag(fnic->lport->host, io_req->tag);
> +
Be careful. 'scsi_host_find_tag()' finds requests on _all_ hwqs.
But here you are interested in tags for a specific hwq only.
> + if (!sc)
> + continue;
> +
> + if (sc->device == device)
> + count++;
> + }
> + }
> + spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
> +
> + return count;
> +}
> +
And now this is pretty pointless. Please use the block layer
blk_mq_tagset_busy_iter() to iterate over busy/active tags.
> +unsigned int fnic_count_lun_ioreqs(struct fnic *fnic,
> + struct scsi_device *device)
> +{
> + int hwq;
> + unsigned int count = 0;
> +
> + /*count if any pending IOs on this lun */
> + for (hwq = 0; hwq < fnic->wq_copy_count; hwq++)
> + count += fnic_count_lun_ioreqs_wq(fnic, hwq, device);
> +
> + return count;
> +}
> +
Same here.
> /* Free up Copy Wq descriptors. Called with copy_wq lock held */
> static int free_wq_copy_descs(struct fnic *fnic, struct vnic_wq_copy *wq, unsigned int hwq)
> {
> @@ -179,12 +266,11 @@ int fnic_fw_reset_handler(struct fnic *fnic)
> struct vnic_wq_copy *wq = &fnic->hw_copy_wq[0];
> int ret = 0;
> unsigned long flags;
> + unsigned int ioreq_count;
>
> /* indicate fwreset to io path */
> fnic_set_state_flags(fnic, FNIC_FLAGS_FWRESET);
> -
> - fnic_free_txq(&fnic->frame_queue);
> - fnic_free_txq(&fnic->tx_queue);
> + ioreq_count = fnic_count_all_ioreqs(fnic);
>
> /* wait for io cmpl */
> while (atomic_read(&fnic->in_flight))
> @@ -231,10 +317,10 @@ int fnic_flogi_reg_handler(struct fnic *fnic, u32 fc_id)
> {
> struct vnic_wq_copy *wq = &fnic->hw_copy_wq[0];
> enum fcpio_flogi_reg_format_type format;
> - struct fc_lport *lp = fnic->lport;
> u8 gw_mac[ETH_ALEN];
> int ret = 0;
> unsigned long flags;
> + struct fnic_iport_s *iport = &fnic->iport;
>
> spin_lock_irqsave(&fnic->wq_copy_lock[0], flags);
>
> @@ -246,28 +332,23 @@ int fnic_flogi_reg_handler(struct fnic *fnic, u32 fc_id)
> goto flogi_reg_ioreq_end;
> }
>
> - if (fnic->ctlr.map_dest) {
> - eth_broadcast_addr(gw_mac);
> - format = FCPIO_FLOGI_REG_DEF_DEST;
> - } else {
> - memcpy(gw_mac, fnic->ctlr.dest_addr, ETH_ALEN);
> - format = FCPIO_FLOGI_REG_GW_DEST;
> - }
> + memcpy(gw_mac, fnic->iport.fcfmac, ETH_ALEN);
> + format = FCPIO_FLOGI_REG_GW_DEST;
>
> - if ((fnic->config.flags & VFCF_FIP_CAPABLE) && !fnic->ctlr.map_dest) {
> + if (fnic->config.flags & VFCF_FIP_CAPABLE) {
> fnic_queue_wq_copy_desc_fip_reg(wq, SCSI_NO_TAG,
> fc_id, gw_mac,
> - fnic->data_src_addr,
> - lp->r_a_tov, lp->e_d_tov);
> - FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> - "FLOGI FIP reg issued fcid %x src %pM dest %pM\n",
> - fc_id, fnic->data_src_addr, gw_mac);
> + fnic->iport.fpma,
> + iport->r_a_tov, iport->e_d_tov);
> + FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
> + "FLOGI FIP reg issued fcid: 0x%x src %p dest %p\n",
> + fc_id, fnic->iport.fpma, gw_mac);
> } else {
> fnic_queue_wq_copy_desc_flogi_reg(wq, SCSI_NO_TAG,
> format, fc_id, gw_mac);
> FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
> - "FLOGI reg issued fcid 0x%x map %d dest 0x%p\n",
> - fc_id, fnic->ctlr.map_dest, gw_mac);
> + "FLOGI reg issued fcid 0x%x dest %p\n",
> + fc_id, gw_mac);
> }
>
> atomic64_inc(&fnic->fnic_stats.fw_stats.active_fw_reqs);
> @@ -295,13 +376,17 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
> {
> struct scatterlist *sg;
> struct fc_rport *rport = starget_to_rport(scsi_target(sc->device));
> - struct fc_rport_libfc_priv *rp = rport->dd_data;
> struct host_sg_desc *desc;
> struct misc_stats *misc_stats = &fnic->fnic_stats.misc_stats;
> unsigned int i;
> int flags;
> u8 exch_flags;
> struct scsi_lun fc_lun;
> + struct fnic_tport_s *tport;
> + struct rport_dd_data_s *rdd_data;
> +
> + rdd_data = rport->dd_data;
> + tport = rdd_data->tport;
>
> if (sg_count) {
> /* For each SGE, create a device desc entry */
> @@ -356,7 +441,7 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
>
> exch_flags = 0;
> if ((fnic->config.flags & VFCF_FCP_SEQ_LVL_ERR) &&
> - (rp->flags & FC_RP_FLAGS_RETRY))
> + (tport->tgt_flags & FDLS_FC_RP_FLAGS_RETRY))
> exch_flags |= FCPIO_ICMND_SRFLAG_RETRY;
>
> fnic_queue_wq_copy_desc_icmnd_16(wq, mqtag,
> @@ -371,8 +456,8 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
> sc->cmnd, sc->cmd_len,
> scsi_bufflen(sc),
> fc_lun.scsi_lun, io_req->port_id,
> - rport->maxframe_size, rp->r_a_tov,
> - rp->e_d_tov);
> + tport->max_payload_size,
> + tport->r_a_tov, tport->e_d_tov);
>
> atomic64_inc(&fnic->fnic_stats.fw_stats.active_fw_reqs);
> if (atomic64_read(&fnic->fnic_stats.fw_stats.active_fw_reqs) >
> @@ -388,10 +473,10 @@ int fnic_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc)
> struct request *const rq = scsi_cmd_to_rq(sc);
> uint32_t mqtag = 0;
> void (*done)(struct scsi_cmnd *) = scsi_done;
> - struct fc_lport *lp = shost_priv(sc->device->host);
> struct fc_rport *rport;
> struct fnic_io_req *io_req = NULL;
> - struct fnic *fnic = lport_priv(lp);
> + struct fnic *fnic = *((struct fnic **) shost_priv(sc->device->host));
> + struct fnic_iport_s *iport = NULL;
> struct fnic_stats *fnic_stats = &fnic->fnic_stats;
> struct vnic_wq_copy *wq;
> int ret = 1;
> @@ -400,32 +485,14 @@ int fnic_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc)
> unsigned long flags = 0;
> unsigned long ptr;
> int io_lock_acquired = 0;
> - struct fc_rport_libfc_priv *rp;
> uint16_t hwq = 0;
> -
> - mqtag = blk_mq_unique_tag(rq);
> - spin_lock_irqsave(&fnic->fnic_lock, flags);
> -
> - if (unlikely(fnic_chk_state_flags_locked(fnic, FNIC_FLAGS_IO_BLOCKED))) {
> - spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> - FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> - "fnic IO blocked flags: 0x%lx. Returning SCSI_MLQUEUE_HOST_BUSY\n",
> - fnic->state_flags);
> - return SCSI_MLQUEUE_HOST_BUSY;
> - }
> -
> - if (unlikely(fnic_chk_state_flags_locked(fnic, FNIC_FLAGS_FWRESET))) {
> - spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> - FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> - "fnic flags: 0x%lx. Returning SCSI_MLQUEUE_HOST_BUSY\n",
> - fnic->state_flags);
> - return SCSI_MLQUEUE_HOST_BUSY;
> - }
> + struct fnic_tport_s *tport = NULL;
> + struct rport_dd_data_s *rdd_data;
> + uint16_t lun0_delay = 0;
>
> rport = starget_to_rport(scsi_target(sc->device));
> if (!rport) {
> - spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> - FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> + FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> "returning DID_NO_CONNECT for IO as rport is NULL\n");
> sc->result = DID_NO_CONNECT << 16;
> done(sc);
> @@ -434,50 +501,95 @@ int fnic_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc)
>
> ret = fc_remote_port_chkready(rport);
> if (ret) {
> - spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> - FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> + FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> "rport is not ready\n");
> - atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
> sc->result = ret;
> done(sc);
> return 0;
> }
>
> - rp = rport->dd_data;
> - if (!rp || rp->rp_state == RPORT_ST_DELETE) {
> - spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> - FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> - "rport 0x%x removed, returning DID_NO_CONNECT\n",
> - rport->port_id);
> + mqtag = blk_mq_unique_tag(rq);
> + spin_lock_irqsave(&fnic->fnic_lock, flags);
> + iport = &fnic->iport;
>
> - atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
> - sc->result = DID_NO_CONNECT<<16;
> + if (iport->state != FNIC_IPORT_STATE_READY) {
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> + FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> + "returning DID_NO_CONNECT for IO as iport state: %d\n",
> + iport->state);
> + sc->result = DID_NO_CONNECT << 16;
> done(sc);
> return 0;
> }
>
> - if (rp->rp_state != RPORT_ST_READY) {
> - spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> - FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> - "rport 0x%x in state 0x%x, returning DID_IMM_RETRY\n",
> - rport->port_id, rp->rp_state);
> + /* fc_remote_port_add() may have added the tport to
> + * fc_transport but dd_data not yet set
> + */
> + rdd_data = rport->dd_data;
> + tport = rdd_data->tport;
> + if (!tport || (rdd_data->iport != iport)) {
> + FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> + "dd_data not yet set in SCSI for rport portid: 0x%x\n",
> + rport->port_id);
> + tport = fnic_find_tport_by_fcid(iport, rport->port_id);
> + if (!tport) {
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> + FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> + "returning DID_BUS_BUSY for IO as tport not found for: 0x%x\n",
> + rport->port_id);
> + sc->result = DID_BUS_BUSY << 16;
> + done(sc);
> + return 0;
> + }
> +
> + /* Re-assign same params as in fnic_fdls_add_tport */
> + rport->maxframe_size = FNIC_FC_MAX_PAYLOAD_LEN;
> + rport->supported_classes =
> + FC_COS_CLASS3 | FC_RPORT_ROLE_FCP_TARGET;
> + /* the dd_data is allocated by fctransport of size dd_fcrport_size */
> + rdd_data = rport->dd_data;
> + rdd_data->tport = tport;
> + rdd_data->iport = iport;
> + tport->rport = rport;
> + tport->flags |= FNIC_FDLS_SCSI_REGISTERED;
> + }
>
> - sc->result = DID_IMM_RETRY << 16;
> + if ((tport->state != FDLS_TGT_STATE_READY)
> + && (tport->state != FDLS_TGT_STATE_ADISC)) {
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> + FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> + "returning DID_NO_CONNECT for IO as tport state: %d\n",
> + tport->state);
> + sc->result = DID_NO_CONNECT << 16;
> done(sc);
> return 0;
> }
>
> - if (lp->state != LPORT_ST_READY || !(lp->link_up)) {
> + atomic_inc(&fnic->in_flight);
> + atomic_inc(&tport->in_flight);
> +
> + if (unlikely(fnic_chk_state_flags_locked(fnic, FNIC_FLAGS_IO_BLOCKED))) {
> + atomic_dec(&fnic->in_flight);
> + atomic_dec(&tport->in_flight);
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> + return SCSI_MLQUEUE_HOST_BUSY;
> + }
> +
> + if (unlikely(fnic_chk_state_flags_locked(fnic, FNIC_FLAGS_FWRESET))) {
> spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> - "state not ready: %d/link not up: %d Returning HOST_BUSY\n",
> - lp->state, lp->link_up);
> + "fnic flags FW reset: 0x%lx. Returning SCSI_MLQUEUE_HOST_BUSY\n",
> + fnic->state_flags);
> return SCSI_MLQUEUE_HOST_BUSY;
> }
>
> - atomic_inc(&fnic->in_flight);
> + if (!tport->lun0_delay) {
> + lun0_delay = 1;
> + tport->lun0_delay++;
> + }
>
> spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> +
> fnic_priv(sc)->state = FNIC_IOREQ_NOT_INITED;
> fnic_priv(sc)->flags = FNIC_NO_FLAGS;
>
> @@ -499,6 +611,7 @@ int fnic_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc)
> goto out;
> }
>
> + io_req->tport = tport;
> /* Determine the type of scatter/gather list we need */
> io_req->sgl_cnt = sg_count;
> io_req->sgl_type = FNIC_SGL_CACHE_DFLT;
> @@ -575,6 +688,7 @@ int fnic_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc)
> mempool_free(io_req, fnic->io_req_pool);
> }
> atomic_dec(&fnic->in_flight);
> + atomic_dec(&tport->in_flight);
> return ret;
> } else {
> atomic64_inc(&fnic_stats->io_stats.active_ios);
> @@ -602,6 +716,14 @@ int fnic_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc)
> spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
>
> atomic_dec(&fnic->in_flight);
> + atomic_dec(&tport->in_flight);
> +
> + if (lun0_delay) {
> + FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
> + "LUN0 delay\n");
> + mdelay(LUN0_DELAY_TIME);
> + }
> +
> return ret;
> }
>
> @@ -625,7 +747,7 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic,
> atomic64_inc(&reset_stats->fw_reset_completions);
>
> /* Clean up all outstanding io requests */
> - fnic_cleanup_io(fnic);
> + fnic_cleanup_io(fnic, SCSI_NO_TAG);
>
> atomic64_set(&fnic->fnic_stats.fw_stats.active_fw_reqs, 0);
> atomic64_set(&fnic->fnic_stats.io_stats.active_ios, 0);
> @@ -646,12 +768,6 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic,
> "reset failed with header status: %s\n",
> fnic_fcpio_status_to_str(hdr_status));
>
> - /*
> - * Unable to change to eth mode, cannot send out flogi
> - * Change state to fc mode, so that subsequent Flogi
> - * requests from libFC will cause more attempts to
> - * reset the firmware. Free the cached flogi
> - */
> fnic->state = FNIC_IN_FC_MODE;
> atomic64_inc(&reset_stats->fw_reset_failures);
> ret = -1;
> @@ -664,15 +780,14 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic,
> ret = -1;
> }
>
> - /* Thread removing device blocks till firmware reset is complete */
> - if (fnic->remove_wait)
> - complete(fnic->remove_wait);
> + if (fnic->fw_reset_done)
> + complete(fnic->fw_reset_done);
>
> /*
> * If fnic is being removed, or fw reset failed
> * free the flogi frame. Else, send it out
> */
> - if (fnic->remove_wait || ret) {
> + if (ret) {
> spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> fnic_free_txq(&fnic->tx_queue);
> goto reset_cmpl_handler_end;
> @@ -711,12 +826,12 @@ static int fnic_fcpio_flogi_reg_cmpl_handler(struct fnic *fnic,
> /* Check flogi registration completion status */
> if (!hdr_status) {
> FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> - "flog reg succeeded\n");
> + "FLOGI reg succeeded\n");
> fnic->state = FNIC_IN_FC_MODE;
> } else {
> FNIC_SCSI_DBG(KERN_DEBUG,
> fnic->lport->host, fnic->fnic_num,
> - "fnic flogi reg :failed %s\n",
> + "fnic flogi reg failed: %s\n",
> fnic_fcpio_status_to_str(hdr_status));
> fnic->state = FNIC_IN_ETH_MODE;
> ret = -1;
> @@ -1023,15 +1138,6 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic, unsigned int cq_ind
> jiffies_to_msecs(jiffies - start_time)),
> desc, cmd_trace, fnic_flags_and_state(sc));
>
> - if (sc->sc_data_direction == DMA_FROM_DEVICE) {
> - fnic->lport->host_stats.fcp_input_requests++;
> - fnic->fcp_input_bytes += xfer_len;
> - } else if (sc->sc_data_direction == DMA_TO_DEVICE) {
> - fnic->lport->host_stats.fcp_output_requests++;
> - fnic->fcp_output_bytes += xfer_len;
> - } else
> - fnic->lport->host_stats.fcp_control_requests++;
> -
> /* Call SCSI completion function to complete the IO */
> scsi_done(sc);
>
> @@ -1414,8 +1520,8 @@ static bool fnic_cleanup_io_iter(struct scsi_cmnd *sc, void *data)
> struct request *const rq = scsi_cmd_to_rq(sc);
> struct fnic *fnic = data;
> struct fnic_io_req *io_req;
> - unsigned long flags = 0;
> unsigned long start_time = 0;
> + unsigned long flags;
> struct fnic_stats *fnic_stats = &fnic->fnic_stats;
> uint16_t hwq = 0;
> int tag;
> @@ -1439,7 +1545,7 @@ static bool fnic_cleanup_io_iter(struct scsi_cmnd *sc, void *data)
> }
>
> if ((fnic_priv(sc)->flags & FNIC_DEVICE_RESET) &&
> - !(fnic_priv(sc)->flags & FNIC_DEV_RST_DONE)) {
> + !(fnic_priv(sc)->flags & FNIC_DEV_RST_DONE)) {
> /*
> * We will be here only when FW completes reset
> * without sending completions for outstanding ios.
> @@ -1449,6 +1555,7 @@ static bool fnic_cleanup_io_iter(struct scsi_cmnd *sc, void *data)
> complete(io_req->dr_done);
> else if (io_req && io_req->abts_done)
> complete(io_req->abts_done);
> +
> spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
> return true;
> } else if (fnic_priv(sc)->flags & FNIC_DEVICE_RESET) {
> @@ -1458,19 +1565,19 @@ static bool fnic_cleanup_io_iter(struct scsi_cmnd *sc, void *data)
>
> fnic_priv(sc)->io_req = NULL;
> io_req->sc = NULL;
> + start_time = io_req->start_time;
> spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
>
> /*
> * If there is a scsi_cmnd associated with this io_req, then
> * free the corresponding state
> */
> - start_time = io_req->start_time;
> fnic_release_ioreq_buf(fnic, io_req, sc);
> mempool_free(io_req, fnic->io_req_pool);
>
> sc->result = DID_TRANSPORT_DISRUPTED << 16;
> FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> - "mqtag:0x%x tag: 0x%x sc:0x%p duration = %lu DID_TRANSPORT_DISRUPTED\n",
> + "mqtag: 0x%x tag: 0x%x sc: 0x%p duration = %lu DID_TRANSPORT_DISRUPTED\n",
> mqtag, tag, sc, (jiffies - start_time));
>
> if (atomic64_read(&fnic->io_cmpl_skip))
> @@ -1479,23 +1586,60 @@ static bool fnic_cleanup_io_iter(struct scsi_cmnd *sc, void *data)
> atomic64_inc(&fnic_stats->io_stats.io_completions);
>
> FNIC_TRACE(fnic_cleanup_io,
> - sc->device->host->host_no, tag, sc,
> - jiffies_to_msecs(jiffies - start_time),
> - 0, ((u64)sc->cmnd[0] << 32 |
> - (u64)sc->cmnd[2] << 24 |
> - (u64)sc->cmnd[3] << 16 |
> - (u64)sc->cmnd[4] << 8 | sc->cmnd[5]),
> - fnic_flags_and_state(sc));
> -
> + sc->device->host->host_no, tag, sc,
> + jiffies_to_msecs(jiffies - start_time),
> + 0, ((u64) sc->cmnd[0] << 32 |
> + (u64) sc->cmnd[2] << 24 |
> + (u64) sc->cmnd[3] << 16 |
> + (u64) sc->cmnd[4] << 8 | sc->cmnd[5]),
> + (((u64) fnic_priv(sc)->flags << 32) | fnic_priv(sc)->
> + state));
> +
> + /* Complete the command to SCSI */
> scsi_done(sc);
> -
> return true;
> }
>
> -static void fnic_cleanup_io(struct fnic *fnic)
> +static void fnic_cleanup_io(struct fnic *fnic, int exclude_id)
> {
> + unsigned int io_count = 0;
> + unsigned long flags;
> + struct fnic_io_req *io_req = NULL;
> + struct scsi_cmnd *sc = NULL;
> +
> + io_count = fnic_count_all_ioreqs(fnic);
> + FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> + "Outstanding ioreq count: %d active io count: %lld Waiting\n",
> + io_count,
> + atomic64_read(&fnic->fnic_stats.io_stats.active_ios));
> +
> scsi_host_busy_iter(fnic->lport->host,
> - fnic_cleanup_io_iter, fnic);
> + fnic_cleanup_io_iter, fnic);
> +
> + /* with sg3utils device reset, SC needs to be retrieved from ioreq */
> + spin_lock_irqsave(&fnic->wq_copy_lock[0], flags);
> + io_req = fnic->sw_copy_wq[0].io_req_table[fnic->fnic_max_tag_id];
> + if (io_req) {
> + sc = io_req->sc;
> + if (sc) {
> + if ((fnic_priv(sc)->flags & FNIC_DEVICE_RESET)
> + && !(fnic_priv(sc)->flags & FNIC_DEV_RST_DONE)) {
> + fnic_priv(sc)->flags |= FNIC_DEV_RST_DONE;
> + if (io_req && io_req->dr_done)
> + complete(io_req->dr_done);
> + }
> + }
> + }
> + spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags);
> +
> + while ((io_count = fnic_count_all_ioreqs(fnic))) {
> + FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> + "Outstanding ioreq count: %d active io count: %lld Waiting\n",
> + io_count,
> + atomic64_read(&fnic->fnic_stats.io_stats.active_ios));
> +
> + schedule_timeout(msecs_to_jiffies(100));
> + }
> }
>
> void fnic_wq_copy_cleanup_handler(struct vnic_wq_copy *wq,
> @@ -1567,10 +1711,13 @@ static inline int fnic_queue_abort_io_req(struct fnic *fnic, int tag,
> struct vnic_wq_copy *wq = &fnic->hw_copy_wq[hwq];
> struct misc_stats *misc_stats = &fnic->fnic_stats.misc_stats;
> unsigned long flags;
> + struct fnic_tport_s *tport = io_req->tport;
>
> spin_lock_irqsave(&fnic->fnic_lock, flags);
> if (unlikely(fnic_chk_state_flags_locked(fnic,
> FNIC_FLAGS_IO_BLOCKED))) {
> + atomic_dec(&fnic->in_flight);
> + atomic_dec(&tport->in_flight);
> spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> return 1;
> } else
> @@ -1585,6 +1732,7 @@ static inline int fnic_queue_abort_io_req(struct fnic *fnic, int tag,
> if (!vnic_wq_copy_desc_avail(wq)) {
> spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
> atomic_dec(&fnic->in_flight);
> + atomic_dec(&tport->in_flight);
> FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> "fnic_queue_abort_io_req: failure: no descriptors\n");
> atomic64_inc(&misc_stats->abts_cpwq_alloc_failures);
> @@ -1619,20 +1767,24 @@ static bool fnic_rport_abort_io_iter(struct scsi_cmnd *sc, void *data)
> struct fnic *fnic = iter_data->fnic;
> int abt_tag = 0;
> struct fnic_io_req *io_req;
> - unsigned long flags;
> struct reset_stats *reset_stats = &fnic->fnic_stats.reset_stats;
> struct terminate_stats *term_stats = &fnic->fnic_stats.term_stats;
> struct scsi_lun fc_lun;
> enum fnic_ioreq_state old_ioreq_state;
> uint16_t hwq = 0;
> + unsigned long flags;
>
> abt_tag = blk_mq_unique_tag(rq);
> hwq = blk_mq_unique_tag_to_hwq(abt_tag);
>
> - spin_lock_irqsave(&fnic->wq_copy_lock[hwq], flags);
> + if (!sc) {
> + FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> + "sc is NULL abt_tag: 0x%x hwq: %d\n", abt_tag, hwq);
> + return true;
> + }
>
> + spin_lock_irqsave(&fnic->wq_copy_lock[hwq], flags);
> io_req = fnic_priv(sc)->io_req;
> -
> if (!io_req || io_req->port_id != iter_data->port_id) {
> spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
> return true;
> @@ -1655,37 +1807,38 @@ static bool fnic_rport_abort_io_iter(struct scsi_cmnd *sc, void *data)
> spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
> return true;
> }
> +
> if (io_req->abts_done) {
> shost_printk(KERN_ERR, fnic->lport->host,
> - "fnic_rport_exch_reset: io_req->abts_done is set "
> - "state is %s\n",
> + "fnic_rport_exch_reset: io_req->abts_done is set state is %s\n",
> fnic_ioreq_state_to_str(fnic_priv(sc)->state));
> }
>
> if (!(fnic_priv(sc)->flags & FNIC_IO_ISSUED)) {
> shost_printk(KERN_ERR, fnic->lport->host,
> - "rport_exch_reset "
> - "IO not yet issued %p tag 0x%x flags "
> - "%x state %d\n",
> - sc, abt_tag, fnic_priv(sc)->flags, fnic_priv(sc)->state);
> + "rport_exch_reset IO not yet issued %p abt_tag 0x%x",
> + sc, abt_tag);
> + shost_printk(KERN_ERR, fnic->lport->host,
> + "flags %x state %d\n", fnic_priv(sc)->flags,
> + fnic_priv(sc)->state);
> }
> old_ioreq_state = fnic_priv(sc)->state;
> fnic_priv(sc)->state = FNIC_IOREQ_ABTS_PENDING;
> fnic_priv(sc)->abts_status = FCPIO_INVALID_CODE;
> +
> if (fnic_priv(sc)->flags & FNIC_DEVICE_RESET) {
> atomic64_inc(&reset_stats->device_reset_terminates);
> abt_tag |= FNIC_TAG_DEV_RST;
> }
> FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> - "fnic_rport_exch_reset dev rst sc 0x%p\n", sc);
> - BUG_ON(io_req->abts_done);
> -
> + "fnic_rport_exch_reset: dev rst sc 0x%p\n", sc);
> + WARN_ON_ONCE(io_req->abts_done);
> FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> "fnic_rport_reset_exch: Issuing abts\n");
>
> spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
>
> - /* Now queue the abort command to firmware */
> + /* Queue the abort command to firmware */
> int_to_scsilun(sc->device->lun, &fc_lun);
>
> if (fnic_queue_abort_io_req(fnic, abt_tag,
> @@ -1714,11 +1867,14 @@ static bool fnic_rport_abort_io_iter(struct scsi_cmnd *sc, void *data)
> atomic64_inc(&term_stats->terminates);
> iter_data->term_cnt++;
> }
> +
> return true;
> }
>
> void fnic_rport_exch_reset(struct fnic *fnic, u32 port_id)
> {
> + unsigned int io_count = 0;
> + unsigned long flags;
> struct terminate_stats *term_stats = &fnic->fnic_stats.term_stats;
> struct fnic_rport_abort_io_iter_data iter_data = {
> .fnic = fnic,
> @@ -1726,53 +1882,75 @@ void fnic_rport_exch_reset(struct fnic *fnic, u32 port_id)
> .term_cnt = 0,
> };
>
> - FNIC_SCSI_DBG(KERN_DEBUG,
> - fnic->lport->host, fnic->fnic_num,
> - "fnic_rport_exch_reset called portid 0x%06x\n",
> - port_id);
> + FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> + "fnic rport exchange reset for tport: 0x%06x\n",
> + port_id);
>
> if (fnic->in_remove)
> return;
>
> + io_count = fnic_count_ioreqs(fnic, port_id);
> + FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> + "Starting terminates: rport:0x%x portid-io-count: %d active-io-count: %lld\n",
> + port_id, io_count,
> + atomic64_read(&fnic->fnic_stats.io_stats.active_ios));
> +
> + spin_lock_irqsave(&fnic->fnic_lock, flags);
> + atomic_inc(&fnic->in_flight);
> + if (unlikely(fnic_chk_state_flags_locked(fnic, FNIC_FLAGS_IO_BLOCKED))) {
> + atomic_dec(&fnic->in_flight);
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> + return;
> + }
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> +
> scsi_host_busy_iter(fnic->lport->host, fnic_rport_abort_io_iter,
> &iter_data);
> +
> if (iter_data.term_cnt > atomic64_read(&term_stats->max_terminates))
> atomic64_set(&term_stats->max_terminates, iter_data.term_cnt);
>
> + atomic_dec(&fnic->in_flight);
> +
> + while ((io_count = fnic_count_ioreqs(fnic, port_id)))
> + schedule_timeout(msecs_to_jiffies(1000));
> +
That really feels overly complex.
You send the aborts with the previous 'scsi_host_busy_iter()' call, and
now you wait for the I/Os to complete.
But you already have an atomic counter for I/Os in flight to the tport;
can't you just wait for that counter to drop to zero?
> + FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> + "rport: 0x%x remaining portid-io-count: %d ",
> + port_id, io_count);
> }
>
> void fnic_terminate_rport_io(struct fc_rport *rport)
> {
> - struct fc_rport_libfc_priv *rdata;
> - struct fc_lport *lport;
> - struct fnic *fnic;
> + struct fnic_tport_s *tport;
> + struct rport_dd_data_s *rdd_data;
> + struct fnic_iport_s *iport = NULL;
> + struct fnic *fnic = NULL;
>
> if (!rport) {
> - printk(KERN_ERR "fnic_terminate_rport_io: rport is NULL\n");
> + pr_err("rport is NULL\n");
> return;
> }
> - rdata = rport->dd_data;
>
> - if (!rdata) {
> - printk(KERN_ERR "fnic_terminate_rport_io: rdata is NULL\n");
> - return;
> - }
> - lport = rdata->local_port;
> -
> - if (!lport) {
> - printk(KERN_ERR "fnic_terminate_rport_io: lport is NULL\n");
> - return;
> + rdd_data = rport->dd_data;
> + if (rdd_data) {
> + tport = rdd_data->tport;
> + if (!tport) {
> + pr_err(
> + "term rport io called after tport is deleted. Returning 0x%8x\n",
> + rport->port_id);
> + } else {
> + pr_err(
> + "term rport io called after tport is set 0x%8x\n",
> + rport->port_id);
> + pr_err(
> + "tport maybe rediscovered\n");
> +
> + iport = (struct fnic_iport_s *) tport->iport;
> + fnic = iport->fnic;
> + fnic_rport_exch_reset(fnic, rport->port_id);
> + }
> }
> - fnic = lport_priv(lport);
> - FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> - "wwpn 0x%llx, wwnn0x%llx, rport 0x%p, portid 0x%06x\n",
> - rport->port_name, rport->node_name, rport,
> - rport->port_id);
> -
> - if (fnic->in_remove)
> - return;
> -
> - fnic_rport_exch_reset(fnic, rport->port_id);
> }
>
> /*
> @@ -1783,10 +1961,12 @@ void fnic_terminate_rport_io(struct fc_rport *rport)
> int fnic_abort_cmd(struct scsi_cmnd *sc)
> {
> struct request *const rq = scsi_cmd_to_rq(sc);
> - struct fc_lport *lp;
> + struct fnic_iport_s *iport;
> + struct fnic_tport_s *tport;
> struct fnic *fnic;
> struct fnic_io_req *io_req = NULL;
> struct fc_rport *rport;
> + struct rport_dd_data_s *rdd_data;
> unsigned long flags;
> unsigned long start_time = 0;
> int ret = SUCCESS;
> @@ -1806,11 +1986,11 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
> fc_block_scsi_eh(sc);
>
> /* Get local-port, check ready and link up */
> - lp = shost_priv(sc->device->host);
> -
> - fnic = lport_priv(lp);
> + fnic = *((struct fnic **) shost_priv(sc->device->host));
>
> spin_lock_irqsave(&fnic->fnic_lock, flags);
> + iport = &fnic->iport;
> +
> fnic_stats = &fnic->fnic_stats;
> abts_stats = &fnic->fnic_stats.abts_stats;
> term_stats = &fnic->fnic_stats.term_stats;
> @@ -1821,7 +2001,43 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
>
> fnic_priv(sc)->flags = FNIC_NO_FLAGS;
>
> - if (lp->state != LPORT_ST_READY || !(lp->link_up)) {
> + rdd_data = rport->dd_data;
> + tport = rdd_data->tport;
> +
> + if (!tport) {
> + FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> + "Abort cmd called after tport delete! rport fcid: 0x%x",
> + rport->port_id);
> + FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> + "lun: %llu hwq: 0x%x mqtag: 0x%x Op: 0x%x flags: 0x%x\n",
> + sc->device->lun, hwq, mqtag,
> + sc->cmnd[0], fnic_priv(sc)->flags);
> + ret = FAILED;
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> + goto fnic_abort_cmd_end;
> + }
> +
> + FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
> + "Abort cmd called rport fcid: 0x%x lun: %llu hwq: 0x%x mqtag: 0x%x",
> + rport->port_id, sc->device->lun, hwq, mqtag);
> +
> + FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
> + "Op: 0x%x flags: 0x%x\n",
> + sc->cmnd[0],
> + fnic_priv(sc)->flags);
> +
> + if (iport->state != FNIC_IPORT_STATE_READY) {
> + FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
> + "iport NOT in READY state");
> + ret = FAILED;
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> + goto fnic_abort_cmd_end;
> + }
> +
> + if ((tport->state != FDLS_TGT_STATE_READY) &&
> + (tport->state != FDLS_TGT_STATE_ADISC)) {
> + FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> + "tport state: %d\n", tport->state);
> ret = FAILED;
> spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> goto fnic_abort_cmd_end;
> @@ -1843,6 +2059,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
> spin_lock_irqsave(&fnic->wq_copy_lock[hwq], flags);
> io_req = fnic_priv(sc)->io_req;
> if (!io_req) {
> + ret = FAILED;
> spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
> goto fnic_abort_cmd_end;
> }
> @@ -1893,7 +2110,6 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
> if (fc_remote_port_chkready(rport) == 0)
> task_req = FCPIO_ITMF_ABT_TASK;
> else {
> - atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
> task_req = FCPIO_ITMF_ABT_TASK_TERM;
> }
>
> @@ -2027,6 +2243,7 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic,
> unsigned long flags;
> uint16_t hwq = 0;
> uint32_t tag = 0;
> + struct fnic_tport_s *tport = io_req->tport;
>
> tag = io_req->tag;
> hwq = blk_mq_unique_tag_to_hwq(tag);
> @@ -2037,8 +2254,10 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic,
> FNIC_FLAGS_IO_BLOCKED))) {
> spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> return FAILED;
> - } else
> + } else {
> atomic_inc(&fnic->in_flight);
> + atomic_inc(&tport->in_flight);
> + }
> spin_unlock_irqrestore(&fnic->fnic_lock, flags);
>
> spin_lock_irqsave(&fnic->wq_copy_lock[hwq], flags);
> @@ -2072,6 +2291,7 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic,
> lr_io_req_end:
> spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
> atomic_dec(&fnic->in_flight);
> + atomic_inc(&tport->in_flight);
>
> return ret;
> }
> @@ -2274,11 +2494,11 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
> int fnic_device_reset(struct scsi_cmnd *sc)
> {
> struct request *rq = scsi_cmd_to_rq(sc);
> - struct fc_lport *lp;
> struct fnic *fnic;
> struct fnic_io_req *io_req = NULL;
> struct fc_rport *rport;
> int status;
> + int count = 0;
> int ret = FAILED;
> unsigned long flags;
> unsigned long start_time = 0;
> @@ -2289,31 +2509,61 @@ int fnic_device_reset(struct scsi_cmnd *sc)
> DECLARE_COMPLETION_ONSTACK(tm_done);
> bool new_sc = 0;
> uint16_t hwq = 0;
> + struct fnic_iport_s *iport = NULL;
> + struct rport_dd_data_s *rdd_data;
> + struct fnic_tport_s *tport;
> + u32 old_soft_reset_count;
> + u32 old_link_down_cnt;
> + int exit_dr = 0;
>
> /* Wait for rport to unblock */
> fc_block_scsi_eh(sc);
>
> /* Get local-port, check ready and link up */
> - lp = shost_priv(sc->device->host);
> + fnic = *((struct fnic **) shost_priv(sc->device->host));
> + iport = &fnic->iport;
>
> - fnic = lport_priv(lp);
> fnic_stats = &fnic->fnic_stats;
> reset_stats = &fnic->fnic_stats.reset_stats;
>
> atomic64_inc(&reset_stats->device_resets);
>
> rport = starget_to_rport(scsi_target(sc->device));
> +
> + spin_lock_irqsave(&fnic->fnic_lock, flags);
> FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> - "fcid: 0x%x lun: 0x%llx hwq: %d mqtag: 0x%x flags: 0x%x Device reset\n",
> + "fcid: 0x%x lun: %llu hwq: %d mqtag: 0x%x flags: 0x%x Device reset\n",
> rport->port_id, sc->device->lun, hwq, mqtag,
> fnic_priv(sc)->flags);
>
> - if (lp->state != LPORT_ST_READY || !(lp->link_up))
> + rdd_data = rport->dd_data;
> + tport = rdd_data->tport;
> + if (!tport) {
> + FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> + "Dev rst called after tport delete! rport fcid: 0x%x lun: %llu\n",
> + rport->port_id, sc->device->lun);
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> + goto fnic_device_reset_end;
> + }
> +
> + if (iport->state != FNIC_IPORT_STATE_READY) {
> + FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
> + "iport NOT in READY state");
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> goto fnic_device_reset_end;
> + }
> +
> + if ((tport->state != FDLS_TGT_STATE_READY) &&
> + (tport->state != FDLS_TGT_STATE_ADISC)) {
> + FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> + "tport state: %d\n", tport->state);
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> + goto fnic_device_reset_end;
> + }
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
>
Please check if returning FAST_IO_FAIL here wouldn't be a better option.
Most of the time a device reset is triggered by a command timeout, which
typically happens due to a transport issue (eg link is down or something).
So returning 'FAILED' will just escalate to host reset, and that can
take for a really long time trying to abort all commands.
> /* Check if remote port up */
> if (fc_remote_port_chkready(rport)) {
> - atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
> goto fnic_device_reset_end;
> }
>
> @@ -2352,6 +2602,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
> io_req->port_id = rport->port_id;
> io_req->tag = mqtag;
> fnic_priv(sc)->io_req = io_req;
> + io_req->tport = tport;
> io_req->sc = sc;
>
> if (fnic->sw_copy_wq[hwq].io_req_table[blk_mq_unique_tag_to_tag(mqtag)] != NULL)
> @@ -2383,6 +2634,11 @@ int fnic_device_reset(struct scsi_cmnd *sc)
> fnic_priv(sc)->flags |= FNIC_DEV_RST_ISSUED;
> spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
>
> + spin_lock_irqsave(&fnic->fnic_lock, flags);
> + old_link_down_cnt = iport->fnic->link_down_cnt;
> + old_soft_reset_count = fnic->soft_reset_count;
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> +
> /*
> * Wait on the local completion for LUN reset. The io_req may be
> * freed while we wait since we hold no lock.
> @@ -2390,6 +2646,24 @@ int fnic_device_reset(struct scsi_cmnd *sc)
> wait_for_completion_timeout(&tm_done,
> msecs_to_jiffies(FNIC_LUN_RESET_TIMEOUT));
>
> + /*
> + * Wake up can be due to the following reasons:
> + * 1) The device reset completed from target.
> + * 2) Device reset timed out.
> + * 3) A link-down/host_reset may have happened in between.
> + * 4) The device reset was aborted and io_req->dr_done was called.
> + */
> +
> + exit_dr = 0;
> + spin_lock_irqsave(&fnic->fnic_lock, flags);
> + if ((old_link_down_cnt != fnic->link_down_cnt) ||
> + (fnic->reset_in_progress) ||
> + (fnic->soft_reset_count != old_soft_reset_count) ||
> + (iport->state != FNIC_IPORT_STATE_READY))
> + exit_dr = 1;
> +
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> +
> spin_lock_irqsave(&fnic->wq_copy_lock[hwq], flags);
> io_req = fnic_priv(sc)->io_req;
> if (!io_req) {
> @@ -2398,6 +2672,13 @@ int fnic_device_reset(struct scsi_cmnd *sc)
> "io_req is null mqtag 0x%x sc 0x%p\n", mqtag, sc);
> goto fnic_device_reset_end;
> }
> +
> + if (exit_dr) {
> + FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> + "Host reset called for fnic. Exit device reset\n");
> + io_req->dr_done = NULL;
> + goto fnic_device_reset_clean;
> + }
> io_req->dr_done = NULL;
>
> status = fnic_priv(sc)->lr_status;
> @@ -2411,50 +2692,8 @@ int fnic_device_reset(struct scsi_cmnd *sc)
> FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> "Device reset timed out\n");
> fnic_priv(sc)->flags |= FNIC_DEV_RST_TIMED_OUT;
> - spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
> int_to_scsilun(sc->device->lun, &fc_lun);
> - /*
> - * Issue abort and terminate on device reset request.
> - * If q'ing of terminate fails, retry it after a delay.
> - */
> - while (1) {
> - spin_lock_irqsave(&fnic->wq_copy_lock[hwq], flags);
> - if (fnic_priv(sc)->flags & FNIC_DEV_RST_TERM_ISSUED) {
> - spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
> - break;
> - }
> - spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
> - if (fnic_queue_abort_io_req(fnic,
> - mqtag | FNIC_TAG_DEV_RST,
> - FCPIO_ITMF_ABT_TASK_TERM,
> - fc_lun.scsi_lun, io_req, hwq)) {
> - wait_for_completion_timeout(&tm_done,
> - msecs_to_jiffies(FNIC_ABT_TERM_DELAY_TIMEOUT));
> - } else {
> - spin_lock_irqsave(&fnic->wq_copy_lock[hwq], flags);
> - fnic_priv(sc)->flags |= FNIC_DEV_RST_TERM_ISSUED;
> - fnic_priv(sc)->state = FNIC_IOREQ_ABTS_PENDING;
> - io_req->abts_done = &tm_done;
> - spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
> - FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> - "Abort and terminate issued on Device reset mqtag 0x%x sc 0x%p\n",
> - mqtag, sc);
> - break;
> - }
> - }
> - while (1) {
> - spin_lock_irqsave(&fnic->wq_copy_lock[hwq], flags);
> - if (!(fnic_priv(sc)->flags & FNIC_DEV_RST_DONE)) {
> - spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
> - wait_for_completion_timeout(&tm_done,
> - msecs_to_jiffies(FNIC_LUN_RESET_TIMEOUT));
> - break;
> - } else {
> - io_req = fnic_priv(sc)->io_req;
> - io_req->abts_done = NULL;
> - goto fnic_device_reset_clean;
> - }
> - }
> + goto fnic_device_reset_clean;
> } else {
> spin_unlock_irqrestore(&fnic->wq_copy_lock[hwq], flags);
> }
> @@ -2480,8 +2719,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
> spin_lock_irqsave(&fnic->wq_copy_lock[hwq], flags);
> io_req = fnic_priv(sc)->io_req;
> FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> - "Device reset failed"
> - " since could not abort all IOs\n");
> + "Device reset failed: Cannot abort all IOs\n");
> goto fnic_device_reset_clean;
> }
>
> @@ -2507,6 +2745,15 @@ int fnic_device_reset(struct scsi_cmnd *sc)
> mempool_free(io_req, fnic->io_req_pool);
> }
>
> + /*
> + * If link-event is seen while LUN reset is issued we need
> + * to complete the LUN reset here
> + */
> + if (!new_sc) {
> + sc->result = DID_RESET << 16;
> + scsi_done(sc);
> + }
> +
> fnic_device_reset_end:
> FNIC_TRACE(fnic_device_reset, sc->device->host->host_no, rq->tag, sc,
> jiffies_to_msecs(jiffies - start_time),
> @@ -2520,6 +2767,17 @@ int fnic_device_reset(struct scsi_cmnd *sc)
> mutex_unlock(&fnic->sgreset_mutex);
> }
>
> + while ((ret == SUCCESS) && fnic_count_lun_ioreqs(fnic, sc->device)) {
> + if (count >= 2) {
> + ret = FAILED;
> + break;
> + }
> + FNIC_SCSI_DBG(KERN_ERR, fnic->lport->host, fnic->fnic_num,
> + "Cannot clean up all IOs for the LUN\n");
> + schedule_timeout(msecs_to_jiffies(1000));
> + count++;
> + }
> +
> FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> "Returning from device reset %s\n",
> (ret == SUCCESS) ?
> @@ -2531,50 +2789,54 @@ int fnic_device_reset(struct scsi_cmnd *sc)
> return ret;
> }
>
> -/* Clean up all IOs, clean up libFC local port */
> -int fnic_reset(struct Scsi_Host *shost)
> +static void fnic_post_flogo_linkflap(struct fnic *fnic)
> +{
> + unsigned long flags;
> +
> + fnic_fdls_link_status_change(fnic, 0);
> + spin_lock_irqsave(&fnic->fnic_lock, flags);
> +
> + if (fnic->link_status) {
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> + fnic_fdls_link_status_change(fnic, 1);
> + return;
> + }
> + spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> +}
> +
> +/* Logout from all the targets and simulate link flap */
> +void fnic_reset(struct Scsi_Host *shost)
> {
> - struct fc_lport *lp;
> struct fnic *fnic;
> - int ret = 0;
> struct reset_stats *reset_stats;
>
> - lp = shost_priv(shost);
> - fnic = lport_priv(lp);
> + fnic = *((struct fnic **) shost_priv(shost));
> reset_stats = &fnic->fnic_stats.reset_stats;
>
> FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
> - "Issuing fnic reset\n");
> + "Issuing fnic reset\n");
>
> atomic64_inc(&reset_stats->fnic_resets);
> -
> - /*
> - * Reset local port, this will clean up libFC exchanges,
> - * reset remote port sessions, and if link is up, begin flogi
> - */
> - ret = fc_lport_reset(lp);
> + fnic_post_flogo_linkflap(fnic);
>
> FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
> - "Returning from fnic reset with: %s\n",
> - (ret == 0) ? "SUCCESS" : "FAILED");
> + "Returning from fnic reset");
>
> - if (ret == 0)
> - atomic64_inc(&reset_stats->fnic_reset_completions);
> - else
> - atomic64_inc(&reset_stats->fnic_reset_failures);
> + atomic64_inc(&reset_stats->fnic_reset_completions);
> +}
> +
> +int fnic_issue_fc_host_lip(struct Scsi_Host *shost)
> +{
> + int ret = 0;
> + struct fnic *fnic = *((struct fnic **) shost_priv(shost));
> +
> + FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
> + "FC host lip issued");
>
> + ret = fnic_host_reset(shost);
> return ret;
> }
>
> -/*
> - * SCSI Error handling calls driver's eh_host_reset if all prior
> - * error handling levels return FAILED. If host reset completes
> - * successfully, and if link is up, then Fabric login begins.
> - *
> - * Host Reset is the highest level of error recovery. If this fails, then
> - * host is offlined by SCSI.
> - *
> - */
> int fnic_host_reset(struct Scsi_Host *shost)
> {
> int ret = SUCCESS;
> @@ -2637,122 +2899,6 @@ int fnic_host_reset(struct Scsi_Host *shost)
> return ret;
> }
>
> -/*
> - * This fxn is called from libFC when host is removed
> - */
> -void fnic_scsi_abort_io(struct fc_lport *lp)
> -{
> - int err = 0;
> - unsigned long flags;
> - enum fnic_state old_state;
> - struct fnic *fnic = lport_priv(lp);
> - DECLARE_COMPLETION_ONSTACK(remove_wait);
> -
> - /* Issue firmware reset for fnic, wait for reset to complete */
> -retry_fw_reset:
> - spin_lock_irqsave(&fnic->fnic_lock, flags);
> - if (unlikely(fnic->state == FNIC_IN_FC_TRANS_ETH_MODE) &&
> - fnic->link_events) {
> - /* fw reset is in progress, poll for its completion */
> - spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> - schedule_timeout(msecs_to_jiffies(100));
> - goto retry_fw_reset;
> - }
> -
> - fnic->remove_wait = &remove_wait;
> - old_state = fnic->state;
> - fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
> - fnic_update_mac_locked(fnic, fnic->ctlr.ctl_src_addr);
> - spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> -
> - err = fnic_fw_reset_handler(fnic);
> - if (err) {
> - spin_lock_irqsave(&fnic->fnic_lock, flags);
> - if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE)
> - fnic->state = old_state;
> - fnic->remove_wait = NULL;
> - spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> - return;
> - }
> -
> - /* Wait for firmware reset to complete */
> - wait_for_completion_timeout(&remove_wait,
> - msecs_to_jiffies(FNIC_RMDEVICE_TIMEOUT));
> -
> - spin_lock_irqsave(&fnic->fnic_lock, flags);
> - fnic->remove_wait = NULL;
> - FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, fnic->fnic_num,
> - "fnic_scsi_abort_io %s\n",
> - (fnic->state == FNIC_IN_ETH_MODE) ?
> - "SUCCESS" : "FAILED");
> - spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> -
> -}
> -
> -/*
> - * This fxn called from libFC to clean up driver IO state on link down
> - */
> -void fnic_scsi_cleanup(struct fc_lport *lp)
> -{
> - unsigned long flags;
> - enum fnic_state old_state;
> - struct fnic *fnic = lport_priv(lp);
> -
> - /* issue fw reset */
> -retry_fw_reset:
> - spin_lock_irqsave(&fnic->fnic_lock, flags);
> - if (unlikely(fnic->state == FNIC_IN_FC_TRANS_ETH_MODE)) {
> - /* fw reset is in progress, poll for its completion */
> - spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> - schedule_timeout(msecs_to_jiffies(100));
> - goto retry_fw_reset;
> - }
> - old_state = fnic->state;
> - fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
> - fnic_update_mac_locked(fnic, fnic->ctlr.ctl_src_addr);
> - spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> -
> - if (fnic_fw_reset_handler(fnic)) {
> - spin_lock_irqsave(&fnic->fnic_lock, flags);
> - if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE)
> - fnic->state = old_state;
> - spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> - }
> -
> -}
> -
> -void fnic_empty_scsi_cleanup(struct fc_lport *lp)
> -{
> -}
> -
> -void fnic_exch_mgr_reset(struct fc_lport *lp, u32 sid, u32 did)
> -{
> - struct fnic *fnic = lport_priv(lp);
> -
> - /* Non-zero sid, nothing to do */
> - if (sid)
> - goto call_fc_exch_mgr_reset;
> -
> - if (did) {
> - fnic_rport_exch_reset(fnic, did);
> - goto call_fc_exch_mgr_reset;
> - }
> -
> - /*
> - * sid = 0, did = 0
> - * link down or device being removed
> - */
> - if (!fnic->in_remove)
> - fnic_scsi_cleanup(lp);
> - else
> - fnic_scsi_abort_io(lp);
> -
> - /* call libFC exch mgr reset to reset its exchanges */
> -call_fc_exch_mgr_reset:
> - fc_exch_mgr_reset(lp, sid, did);
> -
> -}
> -
> static bool fnic_abts_pending_iter(struct scsi_cmnd *sc, void *data)
> {
> struct request *const rq = scsi_cmd_to_rq(sc);
> diff --git a/drivers/scsi/fnic/fnic_stats.h b/drivers/scsi/fnic/fnic_stats.h
> index 9d7f98c452dd..1f1a1ec90a23 100644
> --- a/drivers/scsi/fnic/fnic_stats.h
> +++ b/drivers/scsi/fnic/fnic_stats.h
> @@ -127,6 +127,4 @@ struct stats_debug_info {
> };
>
> int fnic_get_stats_data(struct stats_debug_info *, struct fnic_stats *);
> -void fnic_stats_debugfs_init(struct fnic *);
> -void fnic_stats_debugfs_remove(struct fnic *);
> #endif /* _FNIC_STATS_H_ */
Cheers,
Hannes
--
Dr. Hannes Reinecke Kernel Storage Architect
hare@...e.de +49 911 74053 688
SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg
HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich
Powered by blists - more mailing lists