SCSI misc on 20151105

This patch includes a couple of minor fixes, some core changes to help issues
 we're still seeing with the suspend/resume code and updates to lpfc and
 cxlflash.
 
 Signed-off-by: James Bottomley <JBottomley@Odin.com>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQEcBAABAgAGBQJWO48UAAoJEDeqqVYsXL0MLH0H/AqGdwI1GD9rGwQ0kRoGMpnv
 IaSu9cYooTmMJKKd1jrOBoJ9sZzESQ0bjOo+O5XJYmuTMnb9HJjSUHkrd1XWcN+r
 NNhllY22MJSQO/yvx9YhVG4qiWvBs46NPU/itEvTm9kXlWFRo9pwlC07JS3CuQZD
 0AuLaCnpDYBu4km0guw72/fMyZj18vdFu6KI3GtlRSyvWVIPe9A4vZB9R/m4wzER
 fX//uh0ULaUDkDensGe/6k/l035X5s7AzIqN0l6BBXdQf8Nh6r62Y9rplmKmpSXQ
 f9VtHM+v4hmXODOM7voXofiWQDFiOJrnPkLmJVixS5nCdhvD+FAU5tE5peZa2Eo=
 =mNLs
 -----END PGP SIGNATURE-----

Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI updates from James Bottomley:
 "First round of SCSI updates for the 4.4 merge window.

  This batch includes a couple of minor fixes, some core changes to help
  issues we're still seeing with the suspend/resume code and updates to
  lpfc and cxlflash.

  We're (actually Martin Petersen is) trying to wrangle a mpt2/mpt3sas
  merger for the merge window which will help enormously with the
  maintenance burden, so there will be another round before it closes"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (56 commits)
  cxlflash: Fix to avoid bypassing context cleanup
  cxlflash: Fix to avoid lock instrumentation rejection
  cxlflash: Fix to avoid corrupting port selection mask
  cxlflash: Fix to escalate to LINK_RESET on login timeout
  cxlflash: Fix to avoid leaving dangling interrupt resources
  cxlflash: Fix to avoid potential deadlock on EEH
  cxlflash: Correct trace string
  cxlflash: Fix to avoid corrupting adapter fops
  cxlflash: Fix to double the delay each time
  MAINTAINERS: Add cxlflash driver
  cxlflash: Fix to prevent stale AFU RRQ
  cxlflash: Correct spelling, grammar, and alignment mistakes
  cxlflash: Fix to prevent EEH recovery failure
  cxlflash: Fix MMIO and endianness errors
  cxlflash: Fix function prolog parameters and return codes
  cxlflash: Remove unnecessary scsi_block_requests
  cxlflash: Correct behavior in device reset handler following EEH
  cxlflash: Fix to prevent workq from accessing freed memory
  cxlflash: Correct usage of scsi_host_put()
  cxlflash: Fix AFU version access/storage and add check
  ...
This commit is contained in:
Linus Torvalds 2015-11-05 16:20:21 -08:00
commit a3e7531535
37 changed files with 1317 additions and 1138 deletions

View File

@ -3186,6 +3186,15 @@ F: Documentation/powerpc/cxl.txt
F: Documentation/powerpc/cxl.txt F: Documentation/powerpc/cxl.txt
F: Documentation/ABI/testing/sysfs-class-cxl F: Documentation/ABI/testing/sysfs-class-cxl
CXLFLASH (IBM Coherent Accelerator Processor Interface CAPI Flash) SCSI DRIVER
M: Manoj N. Kumar <manoj@linux.vnet.ibm.com>
M: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/scsi/cxlflash/
F: include/uapi/scsi/cxlflash_ioctls.h
F: Documentation/powerpc/cxlflash.txt
STMMAC ETHERNET DRIVER STMMAC ETHERNET DRIVER
M: Giuseppe Cavallaro <peppe.cavallaro@st.com> M: Giuseppe Cavallaro <peppe.cavallaro@st.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
@ -9473,8 +9482,8 @@ F: include/uapi/linux/phantom.h
SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER
M: Jayamohan Kallickal <jayamohan.kallickal@avagotech.com> M: Jayamohan Kallickal <jayamohan.kallickal@avagotech.com>
M: Minh Tran <minh.tran@avagotech.com> M: Ketan Mukadam <ketan.mukadam@avagotech.com>
M: John Soni Jose <sony.john-n@avagotech.com> M: John Soni Jose <sony.john@avagotech.com>
L: linux-scsi@vger.kernel.org L: linux-scsi@vger.kernel.org
W: http://www.avagotech.com W: http://www.avagotech.com
S: Supported S: Supported

View File

@ -1,9 +1,9 @@
config BE2ISCSI config BE2ISCSI
tristate "ServerEngines' 10Gbps iSCSI - BladeEngine 2" tristate "Emulex 10Gbps iSCSI - BladeEngine 2"
depends on PCI && SCSI && NET depends on PCI && SCSI && NET
select SCSI_ISCSI_ATTRS select SCSI_ISCSI_ATTRS
select ISCSI_BOOT_SYSFS select ISCSI_BOOT_SYSFS
help help
This driver implements the iSCSI functionality for ServerEngines' This driver implements the iSCSI functionality for Emulex
10Gbps Storage adapter - BladeEngine 2. 10Gbps Storage adapter - BladeEngine 2.

View File

@ -1,5 +1,5 @@
# #
# Makefile to build the iSCSI driver for ServerEngine's BladeEngine. # Makefile to build the iSCSI driver for Emulex OneConnect.
# #
# #

View File

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2005 - 2015 Avago Technologies * Copyright (C) 2005 - 2015 Emulex
* All rights reserved. * All rights reserved.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -10,7 +10,7 @@
* Contact Information: * Contact Information:
* linux-drivers@avagotech.com * linux-drivers@avagotech.com
* *
* Avago Technologies * Emulex
* 3333 Susan Street * 3333 Susan Street
* Costa Mesa, CA 92626 * Costa Mesa, CA 92626
*/ */

View File

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2005 - 2015 Avago Technologies * Copyright (C) 2005 - 2015 Emulex
* All rights reserved. * All rights reserved.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -10,7 +10,7 @@
* Contact Information: * Contact Information:
* linux-drivers@avagotech.com * linux-drivers@avagotech.com
* *
* Avago Technologies * Emulex
* 3333 Susan Street * 3333 Susan Street
* Costa Mesa, CA 92626 * Costa Mesa, CA 92626
*/ */

View File

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2005 - 2015 Avago Technologies * Copyright (C) 2005 - 2015 Emulex
* All rights reserved. * All rights reserved.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -10,7 +10,7 @@
* Contact Information: * Contact Information:
* linux-drivers@avagotech.com * linux-drivers@avagotech.com
* *
* Avago Technologies * Emulex
* 3333 Susan Street * 3333 Susan Street
* Costa Mesa, CA 92626 * Costa Mesa, CA 92626
*/ */

View File

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2005 - 2015 Avago Technologies * Copyright (C) 2005 - 2015 Emulex
* All rights reserved. * All rights reserved.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -12,7 +12,7 @@
* Contact Information: * Contact Information:
* linux-drivers@avagotech.com * linux-drivers@avagotech.com
* *
* Avago Technologies * Emulex
* 3333 Susan Street * 3333 Susan Street
* Costa Mesa, CA 92626 * Costa Mesa, CA 92626
*/ */

View File

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2005 - 2015 Avago Technologies * Copyright (C) 2005 - 2015 Emulex
* All rights reserved. * All rights reserved.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -12,7 +12,7 @@
* Contact Information: * Contact Information:
* linux-drivers@avagotech.com * linux-drivers@avagotech.com
* *
* Avago Technologies * Emulex
* 3333 Susan Street * 3333 Susan Street
* Costa Mesa, CA 92626 * Costa Mesa, CA 92626
*/ */
@ -50,7 +50,7 @@ static unsigned int enable_msix = 1;
MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR);
MODULE_VERSION(BUILD_STR); MODULE_VERSION(BUILD_STR);
MODULE_AUTHOR("Avago Technologies"); MODULE_AUTHOR("Emulex Corporation");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
module_param(be_iopoll_budget, int, 0); module_param(be_iopoll_budget, int, 0);
module_param(enable_msix, int, 0); module_param(enable_msix, int, 0);
@ -552,7 +552,7 @@ MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
static struct scsi_host_template beiscsi_sht = { static struct scsi_host_template beiscsi_sht = {
.module = THIS_MODULE, .module = THIS_MODULE,
.name = "Avago Technologies 10Gbe open-iscsi Initiator Driver", .name = "Emulex 10Gbe open-iscsi Initiator Driver",
.proc_name = DRV_NAME, .proc_name = DRV_NAME,
.queuecommand = iscsi_queuecommand, .queuecommand = iscsi_queuecommand,
.change_queue_depth = scsi_change_queue_depth, .change_queue_depth = scsi_change_queue_depth,

View File

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2005 - 2015 Avago Technologies * Copyright (C) 2005 - 2015 Emulex
* All rights reserved. * All rights reserved.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -12,7 +12,7 @@
* Contact Information: * Contact Information:
* linux-drivers@avagotech.com * linux-drivers@avagotech.com
* *
* Avago Technologies * Emulex
* 3333 Susan Street * 3333 Susan Street
* Costa Mesa, CA 92626 * Costa Mesa, CA 92626
*/ */
@ -37,7 +37,7 @@
#define DRV_NAME "be2iscsi" #define DRV_NAME "be2iscsi"
#define BUILD_STR "10.6.0.0" #define BUILD_STR "10.6.0.0"
#define BE_NAME "Avago Technologies OneConnect" \ #define BE_NAME "Emulex OneConnect" \
"Open-iSCSI Driver version" BUILD_STR "Open-iSCSI Driver version" BUILD_STR
#define DRV_DESC BE_NAME " " "Driver" #define DRV_DESC BE_NAME " " "Driver"

View File

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2005 - 2015 Avago Technologies * Copyright (C) 2005 - 2015 Emulex
* All rights reserved. * All rights reserved.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -12,7 +12,7 @@
* Contact Information: * Contact Information:
* linux-drivers@avagotech.com * linux-drivers@avagotech.com
* *
* Avago Technologies * Emulex
* 3333 Susan Street * 3333 Susan Street
* Costa Mesa, CA 92626 * Costa Mesa, CA 92626
*/ */

View File

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2005 - 2015 Avago Technologies * Copyright (C) 2005 - 2015 Emulex
* All rights reserved. * All rights reserved.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -12,7 +12,7 @@
* Contact Information: * Contact Information:
* linux-drivers@avagotech.com * linux-drivers@avagotech.com
* *
* Avago Technologies * Emulex
* 3333 Susan Street * 3333 Susan Street
* Costa Mesa, CA 92626 * Costa Mesa, CA 92626
*/ */

View File

@ -856,7 +856,6 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event,
return; return;
default: default:
printk(KERN_ERR PFX "Unknown netevent %ld", event);
return; return;
} }

View File

@ -16,10 +16,12 @@
#define _CXLFLASH_COMMON_H #define _CXLFLASH_COMMON_H
#include <linux/list.h> #include <linux/list.h>
#include <linux/rwsem.h>
#include <linux/types.h> #include <linux/types.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_device.h> #include <scsi/scsi_device.h>
extern const struct file_operations cxlflash_cxl_fops;
#define MAX_CONTEXT CXLFLASH_MAX_CONTEXT /* num contexts per afu */ #define MAX_CONTEXT CXLFLASH_MAX_CONTEXT /* num contexts per afu */
@ -78,7 +80,7 @@ enum cxlflash_init_state {
enum cxlflash_state { enum cxlflash_state {
STATE_NORMAL, /* Normal running state, everything good */ STATE_NORMAL, /* Normal running state, everything good */
STATE_LIMBO, /* Limbo running state, trying to reset/recover */ STATE_RESET, /* Reset state, trying to reset/recover */
STATE_FAILTERM /* Failed/terminating state, error out users/threads */ STATE_FAILTERM /* Failed/terminating state, error out users/threads */
}; };
@ -101,29 +103,28 @@ struct cxlflash_cfg {
enum cxlflash_init_state init_state; enum cxlflash_init_state init_state;
enum cxlflash_lr_state lr_state; enum cxlflash_lr_state lr_state;
int lr_port; int lr_port;
atomic_t scan_host_needed;
struct cxl_afu *cxl_afu; struct cxl_afu *cxl_afu;
struct pci_pool *cxlflash_cmd_pool;
struct pci_dev *parent_dev; struct pci_dev *parent_dev;
atomic_t recovery_threads; atomic_t recovery_threads;
struct mutex ctx_recovery_mutex; struct mutex ctx_recovery_mutex;
struct mutex ctx_tbl_list_mutex; struct mutex ctx_tbl_list_mutex;
struct rw_semaphore ioctl_rwsem;
struct ctx_info *ctx_tbl[MAX_CONTEXT]; struct ctx_info *ctx_tbl[MAX_CONTEXT];
struct list_head ctx_err_recovery; /* contexts w/ recovery pending */ struct list_head ctx_err_recovery; /* contexts w/ recovery pending */
struct file_operations cxl_fops; struct file_operations cxl_fops;
atomic_t num_user_contexts;
/* Parameters that are LUN table related */ /* Parameters that are LUN table related */
int last_lun_index[CXLFLASH_NUM_FC_PORTS]; int last_lun_index[CXLFLASH_NUM_FC_PORTS];
int promote_lun_index; int promote_lun_index;
struct list_head lluns; /* list of llun_info structs */ struct list_head lluns; /* list of llun_info structs */
wait_queue_head_t tmf_waitq; wait_queue_head_t tmf_waitq;
spinlock_t tmf_slock;
bool tmf_active; bool tmf_active;
wait_queue_head_t limbo_waitq; wait_queue_head_t reset_waitq;
enum cxlflash_state state; enum cxlflash_state state;
}; };
@ -160,9 +161,9 @@ struct afu {
/* AFU HW */ /* AFU HW */
struct cxl_ioctl_start_work work; struct cxl_ioctl_start_work work;
struct cxlflash_afu_map *afu_map; /* entire MMIO map */ struct cxlflash_afu_map __iomem *afu_map; /* entire MMIO map */
struct sisl_host_map *host_map; /* MC host map */ struct sisl_host_map __iomem *host_map; /* MC host map */
struct sisl_ctrl_map *ctrl_map; /* MC control map */ struct sisl_ctrl_map __iomem *ctrl_map; /* MC control map */
ctx_hndl_t ctx_hndl; /* master's context handle */ ctx_hndl_t ctx_hndl; /* master's context handle */
u64 *hrrq_start; u64 *hrrq_start;
@ -175,7 +176,7 @@ struct afu {
u32 cmd_couts; /* Number of command checkouts */ u32 cmd_couts; /* Number of command checkouts */
u32 internal_lun; /* User-desired LUN mode for this AFU */ u32 internal_lun; /* User-desired LUN mode for this AFU */
char version[8]; char version[16];
u64 interface_version; u64 interface_version;
struct cxlflash_cfg *parent; /* Pointer back to parent cxlflash_cfg */ struct cxlflash_cfg *parent; /* Pointer back to parent cxlflash_cfg */
@ -184,17 +185,12 @@ struct afu {
static inline u64 lun_to_lunid(u64 lun) static inline u64 lun_to_lunid(u64 lun)
{ {
u64 lun_id; __be64 lun_id;
int_to_scsilun(lun, (struct scsi_lun *)&lun_id); int_to_scsilun(lun, (struct scsi_lun *)&lun_id);
return swab64(lun_id); return be64_to_cpu(lun_id);
} }
int cxlflash_send_cmd(struct afu *, struct afu_cmd *);
void cxlflash_wait_resp(struct afu *, struct afu_cmd *);
int cxlflash_afu_reset(struct cxlflash_cfg *);
struct afu_cmd *cxlflash_cmd_checkout(struct afu *);
void cxlflash_cmd_checkin(struct afu_cmd *);
int cxlflash_afu_sync(struct afu *, ctx_hndl_t, res_hndl_t, u8); int cxlflash_afu_sync(struct afu *, ctx_hndl_t, res_hndl_t, u8);
void cxlflash_list_init(void); void cxlflash_list_init(void);
void cxlflash_term_global_luns(void); void cxlflash_term_global_luns(void);

View File

@ -41,7 +41,6 @@ static struct llun_info *create_local(struct scsi_device *sdev, u8 *wwid)
} }
lli->sdev = sdev; lli->sdev = sdev;
lli->newly_created = true;
lli->host_no = sdev->host->host_no; lli->host_no = sdev->host->host_no;
lli->in_table = false; lli->in_table = false;
@ -74,24 +73,19 @@ out:
} }
/** /**
* refresh_local() - find and update local LUN information structure by WWID * lookup_local() - find a local LUN information structure by WWID
* @cfg: Internal structure associated with the host. * @cfg: Internal structure associated with the host.
* @wwid: WWID associated with LUN. * @wwid: WWID associated with LUN.
* *
* When the LUN is found, mark it by updating it's newly_created field.
*
* Return: Found local lun_info structure on success, NULL on failure * Return: Found local lun_info structure on success, NULL on failure
* If a LUN with the WWID is found in the list, refresh it's state.
*/ */
static struct llun_info *refresh_local(struct cxlflash_cfg *cfg, u8 *wwid) static struct llun_info *lookup_local(struct cxlflash_cfg *cfg, u8 *wwid)
{ {
struct llun_info *lli, *temp; struct llun_info *lli, *temp;
list_for_each_entry_safe(lli, temp, &cfg->lluns, list) list_for_each_entry_safe(lli, temp, &cfg->lluns, list)
if (!memcmp(lli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN)) { if (!memcmp(lli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN))
lli->newly_created = false;
return lli; return lli;
}
return NULL; return NULL;
} }
@ -120,7 +114,8 @@ static struct glun_info *lookup_global(u8 *wwid)
* *
* The LUN is kept both in a local list (per adapter) and in a global list * The LUN is kept both in a local list (per adapter) and in a global list
* (across all adapters). Certain attributes of the LUN are local to the * (across all adapters). Certain attributes of the LUN are local to the
* adapter (such as index, port selection mask etc.). * adapter (such as index, port selection mask, etc.).
*
* The block allocation map is shared across all adapters (i.e. associated * The block allocation map is shared across all adapters (i.e. associated
* wih the global list). Since different attributes are associated with * wih the global list). Since different attributes are associated with
* the per adapter and global entries, allocate two separate structures for each * the per adapter and global entries, allocate two separate structures for each
@ -128,6 +123,8 @@ static struct glun_info *lookup_global(u8 *wwid)
* *
* Keep a pointer back from the local to the global entry. * Keep a pointer back from the local to the global entry.
* *
* This routine assumes the caller holds the global mutex.
*
* Return: Found/Allocated local lun_info structure on success, NULL on failure * Return: Found/Allocated local lun_info structure on success, NULL on failure
*/ */
static struct llun_info *find_and_create_lun(struct scsi_device *sdev, u8 *wwid) static struct llun_info *find_and_create_lun(struct scsi_device *sdev, u8 *wwid)
@ -137,11 +134,10 @@ static struct llun_info *find_and_create_lun(struct scsi_device *sdev, u8 *wwid)
struct Scsi_Host *shost = sdev->host; struct Scsi_Host *shost = sdev->host;
struct cxlflash_cfg *cfg = shost_priv(shost); struct cxlflash_cfg *cfg = shost_priv(shost);
mutex_lock(&global.mutex);
if (unlikely(!wwid)) if (unlikely(!wwid))
goto out; goto out;
lli = refresh_local(cfg, wwid); lli = lookup_local(cfg, wwid);
if (lli) if (lli)
goto out; goto out;
@ -169,7 +165,6 @@ static struct llun_info *find_and_create_lun(struct scsi_device *sdev, u8 *wwid)
list_add(&gli->list, &global.gluns); list_add(&gli->list, &global.gluns);
out: out:
mutex_unlock(&global.mutex);
pr_debug("%s: returning %p\n", __func__, lli); pr_debug("%s: returning %p\n", __func__, lli);
return lli; return lli;
} }
@ -235,10 +230,11 @@ int cxlflash_manage_lun(struct scsi_device *sdev,
u64 flags = manage->hdr.flags; u64 flags = manage->hdr.flags;
u32 chan = sdev->channel; u32 chan = sdev->channel;
mutex_lock(&global.mutex);
lli = find_and_create_lun(sdev, manage->wwid); lli = find_and_create_lun(sdev, manage->wwid);
pr_debug("%s: ENTER: WWID = %016llX%016llX, flags = %016llX li = %p\n", pr_debug("%s: ENTER: WWID = %016llX%016llX, flags = %016llX li = %p\n",
__func__, get_unaligned_le64(&manage->wwid[0]), __func__, get_unaligned_be64(&manage->wwid[0]),
get_unaligned_le64(&manage->wwid[8]), get_unaligned_be64(&manage->wwid[8]),
manage->hdr.flags, lli); manage->hdr.flags, lli);
if (unlikely(!lli)) { if (unlikely(!lli)) {
rc = -ENOMEM; rc = -ENOMEM;
@ -246,21 +242,28 @@ int cxlflash_manage_lun(struct scsi_device *sdev,
} }
if (flags & DK_CXLFLASH_MANAGE_LUN_ENABLE_SUPERPIPE) { if (flags & DK_CXLFLASH_MANAGE_LUN_ENABLE_SUPERPIPE) {
if (lli->newly_created) /*
lli->port_sel = CHAN2PORT(chan); * Update port selection mask based upon channel, store off LUN
else * in unpacked, AFU-friendly format, and hang LUN reference in
lli->port_sel = BOTH_PORTS; * the sdev.
/* Store off lun in unpacked, AFU-friendly format */ */
lli->port_sel |= CHAN2PORT(chan);
lli->lun_id[chan] = lun_to_lunid(sdev->lun); lli->lun_id[chan] = lun_to_lunid(sdev->lun);
sdev->hostdata = lli; sdev->hostdata = lli;
} else if (flags & DK_CXLFLASH_MANAGE_LUN_DISABLE_SUPERPIPE) { } else if (flags & DK_CXLFLASH_MANAGE_LUN_DISABLE_SUPERPIPE) {
if (lli->parent->mode != MODE_NONE) if (lli->parent->mode != MODE_NONE)
rc = -EBUSY; rc = -EBUSY;
else else {
sdev->hostdata = NULL; sdev->hostdata = NULL;
lli->port_sel &= ~CHAN2PORT(chan);
}
} }
pr_debug("%s: port_sel = %08X chan = %u lun_id = %016llX\n", __func__,
lli->port_sel, chan, lli->lun_id[chan]);
out: out:
mutex_unlock(&global.mutex);
pr_debug("%s: returning rc=%d\n", __func__, rc); pr_debug("%s: returning rc=%d\n", __func__, rc);
return rc; return rc;
} }

File diff suppressed because it is too large Load Diff

View File

@ -99,6 +99,7 @@ struct asyc_intr_info {
u8 action; u8 action;
#define CLR_FC_ERROR 0x01 #define CLR_FC_ERROR 0x01
#define LINK_RESET 0x02 #define LINK_RESET 0x02
#define SCAN_HOST 0x04
}; };
#ifndef CONFIG_CXL_EEH #ifndef CONFIG_CXL_EEH

View File

@ -146,7 +146,7 @@ struct sisl_rc {
#define SISL_FC_RC_ABORTFAIL 0x59 /* pending abort completed w/fail */ #define SISL_FC_RC_ABORTFAIL 0x59 /* pending abort completed w/fail */
#define SISL_FC_RC_RESID 0x5A /* ioasa underrun/overrun flags set */ #define SISL_FC_RC_RESID 0x5A /* ioasa underrun/overrun flags set */
#define SISL_FC_RC_RESIDERR 0x5B /* actual data len does not match SCSI #define SISL_FC_RC_RESIDERR 0x5B /* actual data len does not match SCSI
reported len, possbly due to dropped reported len, possibly due to dropped
frames */ frames */
#define SISL_FC_RC_TGTABORT 0x5C /* command aborted by target */ #define SISL_FC_RC_TGTABORT 0x5C /* command aborted by target */
}; };
@ -258,7 +258,7 @@ struct sisl_host_map {
__be64 rrq_start; /* start & end are both inclusive */ __be64 rrq_start; /* start & end are both inclusive */
__be64 rrq_end; /* write sequence: start followed by end */ __be64 rrq_end; /* write sequence: start followed by end */
__be64 cmd_room; __be64 cmd_room;
__be64 ctx_ctrl; /* least signiifcant byte or b56:63 is LISN# */ __be64 ctx_ctrl; /* least significant byte or b56:63 is LISN# */
__be64 mbox_w; /* restricted use */ __be64 mbox_w; /* restricted use */
}; };
@ -290,7 +290,7 @@ struct sisl_global_regs {
#define SISL_ASTATUS_FC0_LOGO 0x4000ULL /* b49, target sent FLOGI/PLOGI/LOGO #define SISL_ASTATUS_FC0_LOGO 0x4000ULL /* b49, target sent FLOGI/PLOGI/LOGO
while logged in */ while logged in */
#define SISL_ASTATUS_FC0_CRC_T 0x2000ULL /* b50, CRC threshold exceeded */ #define SISL_ASTATUS_FC0_CRC_T 0x2000ULL /* b50, CRC threshold exceeded */
#define SISL_ASTATUS_FC0_LOGI_R 0x1000ULL /* b51, login state mechine timed out #define SISL_ASTATUS_FC0_LOGI_R 0x1000ULL /* b51, login state machine timed out
and retrying */ and retrying */
#define SISL_ASTATUS_FC0_LOGI_F 0x0800ULL /* b52, login failed, #define SISL_ASTATUS_FC0_LOGI_F 0x0800ULL /* b52, login failed,
FC_ERROR[19:0] */ FC_ERROR[19:0] */
@ -340,7 +340,7 @@ struct sisl_global_regs {
#define SISL_AFUCONF_MBOX_CLR_READ 0x0010ULL #define SISL_AFUCONF_MBOX_CLR_READ 0x0010ULL
__be64 afu_config; __be64 afu_config;
__be64 rsvd[0xf8]; __be64 rsvd[0xf8];
__be64 afu_version; __le64 afu_version;
__be64 interface_version; __be64 interface_version;
}; };

View File

@ -76,7 +76,7 @@ void cxlflash_free_errpage(void)
* *
* When the host needs to go down, all users must be quiesced and their * When the host needs to go down, all users must be quiesced and their
* memory freed. This is accomplished by putting the contexts in error * memory freed. This is accomplished by putting the contexts in error
* state which will notify the user and let them 'drive' the tear-down. * state which will notify the user and let them 'drive' the tear down.
* Meanwhile, this routine camps until all user contexts have been removed. * Meanwhile, this routine camps until all user contexts have been removed.
*/ */
void cxlflash_stop_term_user_contexts(struct cxlflash_cfg *cfg) void cxlflash_stop_term_user_contexts(struct cxlflash_cfg *cfg)
@ -100,7 +100,7 @@ void cxlflash_stop_term_user_contexts(struct cxlflash_cfg *cfg)
dev_dbg(dev, "%s: Wait for user contexts to quiesce...\n", dev_dbg(dev, "%s: Wait for user contexts to quiesce...\n",
__func__); __func__);
wake_up_all(&cfg->limbo_waitq); wake_up_all(&cfg->reset_waitq);
ssleep(1); ssleep(1);
} }
} }
@ -162,10 +162,7 @@ struct ctx_info *get_context(struct cxlflash_cfg *cfg, u64 rctxid,
if (likely(ctxid < MAX_CONTEXT)) { if (likely(ctxid < MAX_CONTEXT)) {
while (true) { while (true) {
rc = mutex_lock_interruptible(&cfg->ctx_tbl_list_mutex); mutex_lock(&cfg->ctx_tbl_list_mutex);
if (rc)
goto out;
ctxi = cfg->ctx_tbl[ctxid]; ctxi = cfg->ctx_tbl[ctxid];
if (ctxi) if (ctxi)
if ((file && (ctxi->file != file)) || if ((file && (ctxi->file != file)) ||
@ -253,7 +250,7 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi)
{ {
struct device *dev = &cfg->dev->dev; struct device *dev = &cfg->dev->dev;
struct afu *afu = cfg->afu; struct afu *afu = cfg->afu;
struct sisl_ctrl_map *ctrl_map = ctxi->ctrl_map; struct sisl_ctrl_map __iomem *ctrl_map = ctxi->ctrl_map;
int rc = 0; int rc = 0;
u64 val; u64 val;
@ -283,6 +280,24 @@ out:
* @sdev: SCSI device associated with LUN. * @sdev: SCSI device associated with LUN.
* @lli: LUN destined for capacity request. * @lli: LUN destined for capacity request.
* *
* The READ_CAP16 can take quite a while to complete. Should an EEH occur while
* in scsi_execute(), the EEH handler will attempt to recover. As part of the
* recovery, the handler drains all currently running ioctls, waiting until they
* have completed before proceeding with a reset. As this routine is used on the
* ioctl path, this can create a condition where the EEH handler becomes stuck,
* infinitely waiting for this ioctl thread. To avoid this behavior, temporarily
* unmark this thread as an ioctl thread by releasing the ioctl read semaphore.
* This will allow the EEH handler to proceed with a recovery while this thread
* is still running. Once the scsi_execute() returns, reacquire the ioctl read
* semaphore and check the adapter state in case it changed while inside of
* scsi_execute(). The state check will wait if the adapter is still being
* recovered or return a failure if the recovery failed. In the event that the
* adapter reset failed, simply return the failure as the ioctl would be unable
* to continue.
*
* Note that the above puts a requirement on this routine to only be called on
* an ioctl thread.
*
* Return: 0 on success, -errno on failure * Return: 0 on success, -errno on failure
*/ */
static int read_cap16(struct scsi_device *sdev, struct llun_info *lli) static int read_cap16(struct scsi_device *sdev, struct llun_info *lli)
@ -296,7 +311,7 @@ static int read_cap16(struct scsi_device *sdev, struct llun_info *lli)
int rc = 0; int rc = 0;
int result = 0; int result = 0;
int retry_cnt = 0; int retry_cnt = 0;
u32 tout = (MC_DISCOVERY_TIMEOUT * HZ); u32 to = CMD_TIMEOUT * HZ;
retry: retry:
cmd_buf = kzalloc(CMD_BUFSIZE, GFP_KERNEL); cmd_buf = kzalloc(CMD_BUFSIZE, GFP_KERNEL);
@ -314,8 +329,18 @@ retry:
dev_dbg(dev, "%s: %ssending cmd(0x%x)\n", __func__, dev_dbg(dev, "%s: %ssending cmd(0x%x)\n", __func__,
retry_cnt ? "re" : "", scsi_cmd[0]); retry_cnt ? "re" : "", scsi_cmd[0]);
/* Drop the ioctl read semahpore across lengthy call */
up_read(&cfg->ioctl_rwsem);
result = scsi_execute(sdev, scsi_cmd, DMA_FROM_DEVICE, cmd_buf, result = scsi_execute(sdev, scsi_cmd, DMA_FROM_DEVICE, cmd_buf,
CMD_BUFSIZE, sense_buf, tout, 5, 0, NULL); CMD_BUFSIZE, sense_buf, to, CMD_RETRIES, 0, NULL);
down_read(&cfg->ioctl_rwsem);
rc = check_state(cfg);
if (rc) {
dev_err(dev, "%s: Failed state! result=0x08%X\n",
__func__, result);
rc = -ENODEV;
goto out;
}
if (driver_byte(result) == DRIVER_SENSE) { if (driver_byte(result) == DRIVER_SENSE) {
result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */ result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
@ -365,8 +390,8 @@ retry:
* as the buffer is allocated on an aligned boundary. * as the buffer is allocated on an aligned boundary.
*/ */
mutex_lock(&gli->mutex); mutex_lock(&gli->mutex);
gli->max_lba = be64_to_cpu(*((u64 *)&cmd_buf[0])); gli->max_lba = be64_to_cpu(*((__be64 *)&cmd_buf[0]));
gli->blk_len = be32_to_cpu(*((u32 *)&cmd_buf[8])); gli->blk_len = be32_to_cpu(*((__be32 *)&cmd_buf[8]));
mutex_unlock(&gli->mutex); mutex_unlock(&gli->mutex);
out: out:
@ -712,7 +737,6 @@ static void destroy_context(struct cxlflash_cfg *cfg,
kfree(ctxi->rht_needs_ws); kfree(ctxi->rht_needs_ws);
kfree(ctxi->rht_lun); kfree(ctxi->rht_lun);
kfree(ctxi); kfree(ctxi);
atomic_dec_if_positive(&cfg->num_user_contexts);
} }
/** /**
@ -737,7 +761,7 @@ static struct ctx_info *create_context(struct cxlflash_cfg *cfg,
struct afu *afu = cfg->afu; struct afu *afu = cfg->afu;
struct ctx_info *ctxi = NULL; struct ctx_info *ctxi = NULL;
struct llun_info **lli = NULL; struct llun_info **lli = NULL;
bool *ws = NULL; u8 *ws = NULL;
struct sisl_rht_entry *rhte; struct sisl_rht_entry *rhte;
ctxi = kzalloc(sizeof(*ctxi), GFP_KERNEL); ctxi = kzalloc(sizeof(*ctxi), GFP_KERNEL);
@ -769,7 +793,6 @@ static struct ctx_info *create_context(struct cxlflash_cfg *cfg,
INIT_LIST_HEAD(&ctxi->luns); INIT_LIST_HEAD(&ctxi->luns);
INIT_LIST_HEAD(&ctxi->list); /* initialize for list_empty() */ INIT_LIST_HEAD(&ctxi->list); /* initialize for list_empty() */
atomic_inc(&cfg->num_user_contexts);
mutex_lock(&ctxi->mutex); mutex_lock(&ctxi->mutex);
out: out:
return ctxi; return ctxi;
@ -880,6 +903,9 @@ static int _cxlflash_disk_detach(struct scsi_device *sdev,
sys_close(lfd); sys_close(lfd);
} }
/* Release the sdev reference that bound this LUN to the context */
scsi_device_put(sdev);
out: out:
if (put_ctx) if (put_ctx)
put_context(ctxi); put_context(ctxi);
@ -1161,10 +1187,7 @@ out:
return rc; return rc;
} }
/* const struct file_operations cxlflash_cxl_fops = {
* Local fops for adapter file descriptor
*/
static const struct file_operations cxlflash_cxl_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.mmap = cxlflash_cxl_mmap, .mmap = cxlflash_cxl_mmap,
.release = cxlflash_cxl_release, .release = cxlflash_cxl_release,
@ -1210,6 +1233,46 @@ static const struct file_operations null_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
/**
* check_state() - checks and responds to the current adapter state
* @cfg: Internal structure associated with the host.
*
* This routine can block and should only be used on process context.
* It assumes that the caller is an ioctl thread and holding the ioctl
* read semaphore. This is temporarily let up across the wait to allow
* for draining actively running ioctls. Also note that when waking up
* from waiting in reset, the state is unknown and must be checked again
* before proceeding.
*
* Return: 0 on success, -errno on failure
*/
int check_state(struct cxlflash_cfg *cfg)
{
struct device *dev = &cfg->dev->dev;
int rc = 0;
retry:
switch (cfg->state) {
case STATE_RESET:
dev_dbg(dev, "%s: Reset state, going to wait...\n", __func__);
up_read(&cfg->ioctl_rwsem);
rc = wait_event_interruptible(cfg->reset_waitq,
cfg->state != STATE_RESET);
down_read(&cfg->ioctl_rwsem);
if (unlikely(rc))
break;
goto retry;
case STATE_FAILTERM:
dev_dbg(dev, "%s: Failed/Terminating!\n", __func__);
rc = -ENODEV;
break;
default:
break;
}
return rc;
}
/** /**
* cxlflash_disk_attach() - attach a LUN to a context * cxlflash_disk_attach() - attach a LUN to a context
* @sdev: SCSI device associated with LUN. * @sdev: SCSI device associated with LUN.
@ -1243,10 +1306,6 @@ static int cxlflash_disk_attach(struct scsi_device *sdev,
int fd = -1; int fd = -1;
/* On first attach set fileops */
if (atomic_read(&cfg->num_user_contexts) == 0)
cfg->cxl_fops = cxlflash_cxl_fops;
if (attach->num_interrupts > 4) { if (attach->num_interrupts > 4) {
dev_dbg(dev, "%s: Cannot support this many interrupts %llu\n", dev_dbg(dev, "%s: Cannot support this many interrupts %llu\n",
__func__, attach->num_interrupts); __func__, attach->num_interrupts);
@ -1287,11 +1346,17 @@ static int cxlflash_disk_attach(struct scsi_device *sdev,
} }
} }
rc = scsi_device_get(sdev);
if (unlikely(rc)) {
dev_err(dev, "%s: Unable to get sdev reference!\n", __func__);
goto out;
}
lun_access = kzalloc(sizeof(*lun_access), GFP_KERNEL); lun_access = kzalloc(sizeof(*lun_access), GFP_KERNEL);
if (unlikely(!lun_access)) { if (unlikely(!lun_access)) {
dev_err(dev, "%s: Unable to allocate lun_access!\n", __func__); dev_err(dev, "%s: Unable to allocate lun_access!\n", __func__);
rc = -ENOMEM; rc = -ENOMEM;
goto out; goto err0;
} }
lun_access->lli = lli; lun_access->lli = lli;
@ -1311,21 +1376,21 @@ static int cxlflash_disk_attach(struct scsi_device *sdev,
dev_err(dev, "%s: Could not initialize context %p\n", dev_err(dev, "%s: Could not initialize context %p\n",
__func__, ctx); __func__, ctx);
rc = -ENODEV; rc = -ENODEV;
goto err0; goto err1;
} }
ctxid = cxl_process_element(ctx); ctxid = cxl_process_element(ctx);
if (unlikely((ctxid > MAX_CONTEXT) || (ctxid < 0))) { if (unlikely((ctxid > MAX_CONTEXT) || (ctxid < 0))) {
dev_err(dev, "%s: ctxid (%d) invalid!\n", __func__, ctxid); dev_err(dev, "%s: ctxid (%d) invalid!\n", __func__, ctxid);
rc = -EPERM; rc = -EPERM;
goto err1; goto err2;
} }
file = cxl_get_fd(ctx, &cfg->cxl_fops, &fd); file = cxl_get_fd(ctx, &cfg->cxl_fops, &fd);
if (unlikely(fd < 0)) { if (unlikely(fd < 0)) {
rc = -ENODEV; rc = -ENODEV;
dev_err(dev, "%s: Could not get file descriptor\n", __func__); dev_err(dev, "%s: Could not get file descriptor\n", __func__);
goto err1; goto err2;
} }
/* Translate read/write O_* flags from fcntl.h to AFU permission bits */ /* Translate read/write O_* flags from fcntl.h to AFU permission bits */
@ -1335,7 +1400,7 @@ static int cxlflash_disk_attach(struct scsi_device *sdev,
if (unlikely(!ctxi)) { if (unlikely(!ctxi)) {
dev_err(dev, "%s: Failed to create context! (%d)\n", dev_err(dev, "%s: Failed to create context! (%d)\n",
__func__, ctxid); __func__, ctxid);
goto err2; goto err3;
} }
work = &ctxi->work; work = &ctxi->work;
@ -1346,13 +1411,13 @@ static int cxlflash_disk_attach(struct scsi_device *sdev,
if (unlikely(rc)) { if (unlikely(rc)) {
dev_dbg(dev, "%s: Could not start context rc=%d\n", dev_dbg(dev, "%s: Could not start context rc=%d\n",
__func__, rc); __func__, rc);
goto err3; goto err4;
} }
rc = afu_attach(cfg, ctxi); rc = afu_attach(cfg, ctxi);
if (unlikely(rc)) { if (unlikely(rc)) {
dev_err(dev, "%s: Could not attach AFU rc %d\n", __func__, rc); dev_err(dev, "%s: Could not attach AFU rc %d\n", __func__, rc);
goto err4; goto err5;
} }
/* /*
@ -1375,7 +1440,8 @@ out_attach:
attach->block_size = gli->blk_len; attach->block_size = gli->blk_len;
attach->mmio_size = sizeof(afu->afu_map->hosts[0].harea); attach->mmio_size = sizeof(afu->afu_map->hosts[0].harea);
attach->last_lba = gli->max_lba; attach->last_lba = gli->max_lba;
attach->max_xfer = (sdev->host->max_sectors * 512) / gli->blk_len; attach->max_xfer = sdev->host->max_sectors * MAX_SECTOR_UNIT;
attach->max_xfer /= gli->blk_len;
out: out:
attach->adap_fd = fd; attach->adap_fd = fd;
@ -1387,13 +1453,13 @@ out:
__func__, ctxid, fd, attach->block_size, rc, attach->last_lba); __func__, ctxid, fd, attach->block_size, rc, attach->last_lba);
return rc; return rc;
err4: err5:
cxl_stop_context(ctx); cxl_stop_context(ctx);
err3: err4:
put_context(ctxi); put_context(ctxi);
destroy_context(cfg, ctxi); destroy_context(cfg, ctxi);
ctxi = NULL; ctxi = NULL;
err2: err3:
/* /*
* Here, we're overriding the fops with a dummy all-NULL fops because * Here, we're overriding the fops with a dummy all-NULL fops because
* fput() calls the release fop, which will cause us to mistakenly * fput() calls the release fop, which will cause us to mistakenly
@ -1405,10 +1471,12 @@ err2:
fput(file); fput(file);
put_unused_fd(fd); put_unused_fd(fd);
fd = -1; fd = -1;
err1: err2:
cxl_release_context(ctx); cxl_release_context(ctx);
err0: err1:
kfree(lun_access); kfree(lun_access);
err0:
scsi_device_put(sdev);
goto out; goto out;
} }
@ -1510,41 +1578,6 @@ err1:
goto out; goto out;
} }
/**
* check_state() - checks and responds to the current adapter state
* @cfg: Internal structure associated with the host.
*
* This routine can block and should only be used on process context.
* Note that when waking up from waiting in limbo, the state is unknown
* and must be checked again before proceeding.
*
* Return: 0 on success, -errno on failure
*/
static int check_state(struct cxlflash_cfg *cfg)
{
struct device *dev = &cfg->dev->dev;
int rc = 0;
retry:
switch (cfg->state) {
case STATE_LIMBO:
dev_dbg(dev, "%s: Limbo, going to wait...\n", __func__);
rc = wait_event_interruptible(cfg->limbo_waitq,
cfg->state != STATE_LIMBO);
if (unlikely(rc))
break;
goto retry;
case STATE_FAILTERM:
dev_dbg(dev, "%s: Failed/Terminating!\n", __func__);
rc = -ENODEV;
break;
default:
break;
}
return rc;
}
/** /**
* cxlflash_afu_recover() - initiates AFU recovery * cxlflash_afu_recover() - initiates AFU recovery
* @sdev: SCSI device associated with LUN. * @sdev: SCSI device associated with LUN.
@ -1561,10 +1594,10 @@ retry:
* quite possible for this routine to act as the kernel's EEH detection * quite possible for this routine to act as the kernel's EEH detection
* source (MMIO read of mbox_r). Because of this, there is a window of * source (MMIO read of mbox_r). Because of this, there is a window of
* time where an EEH might have been detected but not yet 'serviced' * time where an EEH might have been detected but not yet 'serviced'
* (callback invoked, causing the device to enter limbo state). To avoid * (callback invoked, causing the device to enter reset state). To avoid
* looping in this routine during that window, a 1 second sleep is in place * looping in this routine during that window, a 1 second sleep is in place
* between the time the MMIO failure is detected and the time a wait on the * between the time the MMIO failure is detected and the time a wait on the
* limbo wait queue is attempted via check_state(). * reset wait queue is attempted via check_state().
* *
* Return: 0 on success, -errno on failure * Return: 0 on success, -errno on failure
*/ */
@ -1634,9 +1667,14 @@ retry_recover:
/* Test if in error state */ /* Test if in error state */
reg = readq_be(&afu->ctrl_map->mbox_r); reg = readq_be(&afu->ctrl_map->mbox_r);
if (reg == -1) { if (reg == -1) {
dev_dbg(dev, "%s: MMIO read fail! Wait for recovery...\n", dev_dbg(dev, "%s: MMIO fail, wait for recovery.\n", __func__);
__func__);
mutex_unlock(&ctxi->mutex); /*
* Before checking the state, put back the context obtained with
* get_context() as it is no longer needed and sleep for a short
* period of time (see prolog notes).
*/
put_context(ctxi);
ctxi = NULL; ctxi = NULL;
ssleep(1); ssleep(1);
rc = check_state(cfg); rc = check_state(cfg);
@ -1765,12 +1803,21 @@ static int cxlflash_disk_verify(struct scsi_device *sdev,
* inquiry (i.e. the Unit attention is due to the WWN changing). * inquiry (i.e. the Unit attention is due to the WWN changing).
*/ */
if (verify->hint & DK_CXLFLASH_VERIFY_HINT_SENSE) { if (verify->hint & DK_CXLFLASH_VERIFY_HINT_SENSE) {
/* Can't hold mutex across process_sense/read_cap16,
* since we could have an intervening EEH event.
*/
ctxi->unavail = true;
mutex_unlock(&ctxi->mutex);
rc = process_sense(sdev, verify); rc = process_sense(sdev, verify);
if (unlikely(rc)) { if (unlikely(rc)) {
dev_err(dev, "%s: Failed to validate sense data (%d)\n", dev_err(dev, "%s: Failed to validate sense data (%d)\n",
__func__, rc); __func__, rc);
mutex_lock(&ctxi->mutex);
ctxi->unavail = false;
goto out; goto out;
} }
mutex_lock(&ctxi->mutex);
ctxi->unavail = false;
} }
switch (gli->mode) { switch (gli->mode) {
@ -1955,6 +2002,14 @@ out:
* @cmd: IOCTL command. * @cmd: IOCTL command.
* @arg: Userspace ioctl data structure. * @arg: Userspace ioctl data structure.
* *
* A read/write semaphore is used to implement a 'drain' of currently
* running ioctls. The read semaphore is taken at the beginning of each
* ioctl thread and released upon concluding execution. Additionally the
* semaphore should be released and then reacquired in any ioctl execution
* path which will wait for an event to occur that is outside the scope of
* the ioctl (i.e. an adapter reset). To drain the ioctls currently running,
* a thread simply needs to acquire the write semaphore.
*
* Return: 0 on success, -errno on failure * Return: 0 on success, -errno on failure
*/ */
int cxlflash_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) int cxlflash_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
@ -1989,6 +2044,9 @@ int cxlflash_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
{sizeof(struct dk_cxlflash_clone), (sioctl)cxlflash_disk_clone}, {sizeof(struct dk_cxlflash_clone), (sioctl)cxlflash_disk_clone},
}; };
/* Hold read semaphore so we can drain if needed */
down_read(&cfg->ioctl_rwsem);
/* Restrict command set to physical support only for internal LUN */ /* Restrict command set to physical support only for internal LUN */
if (afu->internal_lun) if (afu->internal_lun)
switch (cmd) { switch (cmd) {
@ -2070,6 +2128,7 @@ int cxlflash_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
/* fall through to exit */ /* fall through to exit */
cxlflash_ioctl_exit: cxlflash_ioctl_exit:
up_read(&cfg->ioctl_rwsem);
if (unlikely(rc && known_ioctl)) if (unlikely(rc && known_ioctl))
dev_err(dev, "%s: ioctl %s (%08X) on dev(%d/%d/%d/%llu) " dev_err(dev, "%s: ioctl %s (%08X) on dev(%d/%d/%d/%llu) "
"returned rc %d\n", __func__, "returned rc %d\n", __func__,

View File

@ -28,7 +28,10 @@ extern struct cxlflash_global global;
*/ */
#define MC_CHUNK_SIZE (1 << MC_RHT_NMASK) /* in LBAs */ #define MC_CHUNK_SIZE (1 << MC_RHT_NMASK) /* in LBAs */
#define MC_DISCOVERY_TIMEOUT 5 /* 5 secs */ #define CMD_TIMEOUT 30 /* 30 secs */
#define CMD_RETRIES 5 /* 5 retries for scsi_execute */
#define MAX_SECTOR_UNIT 512 /* max_sector is in 512 byte multiples */
#define CHAN2PORT(_x) ((_x) + 1) #define CHAN2PORT(_x) ((_x) + 1)
#define PORT2CHAN(_x) ((_x) - 1) #define PORT2CHAN(_x) ((_x) - 1)
@ -60,7 +63,6 @@ struct llun_info {
u32 lun_index; /* Index in the LUN table */ u32 lun_index; /* Index in the LUN table */
u32 host_no; /* host_no from Scsi_host */ u32 host_no; /* host_no from Scsi_host */
u32 port_sel; /* What port to use for this LUN */ u32 port_sel; /* What port to use for this LUN */
bool newly_created; /* Whether the LUN was just discovered */
bool in_table; /* Whether a LUN table entry was created */ bool in_table; /* Whether a LUN table entry was created */
u8 wwid[16]; /* Keep a duplicate copy here? */ u8 wwid[16]; /* Keep a duplicate copy here? */
@ -84,17 +86,17 @@ enum ctx_ctrl {
CTX_CTRL_FILE = (1 << 5) CTX_CTRL_FILE = (1 << 5)
}; };
#define ENCODE_CTXID(_ctx, _id) (((((u64)_ctx) & 0xFFFFFFFF0) << 28) | _id) #define ENCODE_CTXID(_ctx, _id) (((((u64)_ctx) & 0xFFFFFFFF0ULL) << 28) | _id)
#define DECODE_CTXID(_val) (_val & 0xFFFFFFFF) #define DECODE_CTXID(_val) (_val & 0xFFFFFFFF)
struct ctx_info { struct ctx_info {
struct sisl_ctrl_map *ctrl_map; /* initialized at startup */ struct sisl_ctrl_map __iomem *ctrl_map; /* initialized at startup */
struct sisl_rht_entry *rht_start; /* 1 page (req'd for alignment), struct sisl_rht_entry *rht_start; /* 1 page (req'd for alignment),
alloc/free on attach/detach */ alloc/free on attach/detach */
u32 rht_out; /* Number of checked out RHT entries */ u32 rht_out; /* Number of checked out RHT entries */
u32 rht_perms; /* User-defined permissions for RHT entries */ u32 rht_perms; /* User-defined permissions for RHT entries */
struct llun_info **rht_lun; /* Mapping of RHT entries to LUNs */ struct llun_info **rht_lun; /* Mapping of RHT entries to LUNs */
bool *rht_needs_ws; /* User-desired write-same function per RHTE */ u8 *rht_needs_ws; /* User-desired write-same function per RHTE */
struct cxl_ioctl_start_work work; struct cxl_ioctl_start_work work;
u64 ctxid; u64 ctxid;
@ -144,4 +146,6 @@ void cxlflash_ba_terminate(struct ba_lun *);
int cxlflash_manage_lun(struct scsi_device *, struct dk_cxlflash_manage_lun *); int cxlflash_manage_lun(struct scsi_device *, struct dk_cxlflash_manage_lun *);
int check_state(struct cxlflash_cfg *);
#endif /* ifndef _CXLFLASH_SUPERPIPE_H */ #endif /* ifndef _CXLFLASH_SUPERPIPE_H */

View File

@ -132,7 +132,7 @@ static int ba_init(struct ba_lun *ba_lun)
return -ENOMEM; return -ENOMEM;
} }
/* Pass the allocated lun info as a handle to the user */ /* Pass the allocated LUN info as a handle to the user */
ba_lun->ba_lun_handle = bali; ba_lun->ba_lun_handle = bali;
pr_debug("%s: Successfully initialized the LUN: " pr_debug("%s: Successfully initialized the LUN: "
@ -165,7 +165,7 @@ static int find_free_range(u32 low,
num_bits = (sizeof(*lam) * BITS_PER_BYTE); num_bits = (sizeof(*lam) * BITS_PER_BYTE);
bit_pos = find_first_bit(lam, num_bits); bit_pos = find_first_bit(lam, num_bits);
pr_devel("%s: Found free bit %llX in lun " pr_devel("%s: Found free bit %llX in LUN "
"map entry %llX at bitmap index = %X\n", "map entry %llX at bitmap index = %X\n",
__func__, bit_pos, bali->lun_alloc_map[i], __func__, bit_pos, bali->lun_alloc_map[i],
i); i);
@ -400,6 +400,24 @@ static int init_vlun(struct llun_info *lli)
* @lba: Logical block address to start write same. * @lba: Logical block address to start write same.
* @nblks: Number of logical blocks to write same. * @nblks: Number of logical blocks to write same.
* *
* The SCSI WRITE_SAME16 can take quite a while to complete. Should an EEH occur
* while in scsi_execute(), the EEH handler will attempt to recover. As part of
* the recovery, the handler drains all currently running ioctls, waiting until
* they have completed before proceeding with a reset. As this routine is used
* on the ioctl path, this can create a condition where the EEH handler becomes
* stuck, infinitely waiting for this ioctl thread. To avoid this behavior,
* temporarily unmark this thread as an ioctl thread by releasing the ioctl read
* semaphore. This will allow the EEH handler to proceed with a recovery while
* this thread is still running. Once the scsi_execute() returns, reacquire the
* ioctl read semaphore and check the adapter state in case it changed while
* inside of scsi_execute(). The state check will wait if the adapter is still
* being recovered or return a failure if the recovery failed. In the event that
* the adapter reset failed, simply return the failure as the ioctl would be
* unable to continue.
*
* Note that the above puts a requirement on this routine to only be called on
* an ioctl thread.
*
* Return: 0 on success, -errno on failure * Return: 0 on success, -errno on failure
*/ */
static int write_same16(struct scsi_device *sdev, static int write_same16(struct scsi_device *sdev,
@ -414,7 +432,7 @@ static int write_same16(struct scsi_device *sdev,
int ws_limit = SISLITE_MAX_WS_BLOCKS; int ws_limit = SISLITE_MAX_WS_BLOCKS;
u64 offset = lba; u64 offset = lba;
int left = nblks; int left = nblks;
u32 tout = sdev->request_queue->rq_timeout; u32 to = sdev->request_queue->rq_timeout;
struct cxlflash_cfg *cfg = (struct cxlflash_cfg *)sdev->host->hostdata; struct cxlflash_cfg *cfg = (struct cxlflash_cfg *)sdev->host->hostdata;
struct device *dev = &cfg->dev->dev; struct device *dev = &cfg->dev->dev;
@ -433,8 +451,20 @@ static int write_same16(struct scsi_device *sdev,
put_unaligned_be32(ws_limit < left ? ws_limit : left, put_unaligned_be32(ws_limit < left ? ws_limit : left,
&scsi_cmd[10]); &scsi_cmd[10]);
/* Drop the ioctl read semahpore across lengthy call */
up_read(&cfg->ioctl_rwsem);
result = scsi_execute(sdev, scsi_cmd, DMA_TO_DEVICE, cmd_buf, result = scsi_execute(sdev, scsi_cmd, DMA_TO_DEVICE, cmd_buf,
CMD_BUFSIZE, sense_buf, tout, 5, 0, NULL); CMD_BUFSIZE, sense_buf, to, CMD_RETRIES,
0, NULL);
down_read(&cfg->ioctl_rwsem);
rc = check_state(cfg);
if (rc) {
dev_err(dev, "%s: Failed state! result=0x08%X\n",
__func__, result);
rc = -ENODEV;
goto out;
}
if (result) { if (result) {
dev_err_ratelimited(dev, "%s: command failed for " dev_err_ratelimited(dev, "%s: command failed for "
"offset %lld result=0x%x\n", "offset %lld result=0x%x\n",
@ -681,14 +711,14 @@ out:
} }
/** /**
* _cxlflash_vlun_resize() - changes the size of a virtual lun * _cxlflash_vlun_resize() - changes the size of a virtual LUN
* @sdev: SCSI device associated with LUN owning virtual LUN. * @sdev: SCSI device associated with LUN owning virtual LUN.
* @ctxi: Context owning resources. * @ctxi: Context owning resources.
* @resize: Resize ioctl data structure. * @resize: Resize ioctl data structure.
* *
* On successful return, the user is informed of the new size (in blocks) * On successful return, the user is informed of the new size (in blocks)
* of the virtual lun in last LBA format. When the size of the virtual * of the virtual LUN in last LBA format. When the size of the virtual
* lun is zero, the last LBA is reflected as -1. See comment in the * LUN is zero, the last LBA is reflected as -1. See comment in the
* prologue for _cxlflash_disk_release() regarding AFU syncs and contexts * prologue for _cxlflash_disk_release() regarding AFU syncs and contexts
* on the error recovery list. * on the error recovery list.
* *
@ -785,7 +815,7 @@ void cxlflash_restore_luntable(struct cxlflash_cfg *cfg)
u32 chan; u32 chan;
u32 lind; u32 lind;
struct afu *afu = cfg->afu; struct afu *afu = cfg->afu;
struct sisl_global_map *agm = &afu->afu_map->global; struct sisl_global_map __iomem *agm = &afu->afu_map->global;
mutex_lock(&global.mutex); mutex_lock(&global.mutex);
@ -830,7 +860,7 @@ static int init_luntable(struct cxlflash_cfg *cfg, struct llun_info *lli)
u32 lind; u32 lind;
int rc = 0; int rc = 0;
struct afu *afu = cfg->afu; struct afu *afu = cfg->afu;
struct sisl_global_map *agm = &afu->afu_map->global; struct sisl_global_map __iomem *agm = &afu->afu_map->global;
mutex_lock(&global.mutex); mutex_lock(&global.mutex);
@ -885,8 +915,8 @@ out:
* @arg: UVirtual ioctl data structure. * @arg: UVirtual ioctl data structure.
* *
* On successful return, the user is informed of the resource handle * On successful return, the user is informed of the resource handle
* to be used to identify the virtual lun and the size (in blocks) of * to be used to identify the virtual LUN and the size (in blocks) of
* the virtual lun in last LBA format. When the size of the virtual lun * the virtual LUN in last LBA format. When the size of the virtual LUN
* is zero, the last LBA is reflected as -1. * is zero, the last LBA is reflected as -1.
* *
* Return: 0 on success, -errno on failure * Return: 0 on success, -errno on failure
@ -914,16 +944,9 @@ int cxlflash_disk_virtual_open(struct scsi_device *sdev, void *arg)
pr_debug("%s: ctxid=%llu ls=0x%llx\n", __func__, ctxid, lun_size); pr_debug("%s: ctxid=%llu ls=0x%llx\n", __func__, ctxid, lun_size);
/* Setup the LUNs block allocator on first call */
mutex_lock(&gli->mutex); mutex_lock(&gli->mutex);
if (gli->mode == MODE_NONE) { if (gli->mode == MODE_NONE) {
/* Setup the LUN table and block allocator on first call */
rc = init_luntable(cfg, lli);
if (rc) {
dev_err(dev, "%s: call to init_luntable failed "
"rc=%d!\n", __func__, rc);
goto err0;
}
rc = init_vlun(lli); rc = init_vlun(lli);
if (rc) { if (rc) {
dev_err(dev, "%s: call to init_vlun failed rc=%d!\n", dev_err(dev, "%s: call to init_vlun failed rc=%d!\n",
@ -941,6 +964,13 @@ int cxlflash_disk_virtual_open(struct scsi_device *sdev, void *arg)
} }
mutex_unlock(&gli->mutex); mutex_unlock(&gli->mutex);
rc = init_luntable(cfg, lli);
if (rc) {
dev_err(dev, "%s: call to init_luntable failed rc=%d!\n",
__func__, rc);
goto err1;
}
ctxi = get_context(cfg, rctxid, lli, 0); ctxi = get_context(cfg, rctxid, lli, 0);
if (unlikely(!ctxi)) { if (unlikely(!ctxi)) {
dev_err(dev, "%s: Bad context! (%llu)\n", __func__, ctxid); dev_err(dev, "%s: Bad context! (%llu)\n", __func__, ctxid);

View File

@ -939,6 +939,7 @@ int fnic_alloc_rq_frame(struct vnic_rq *rq)
struct sk_buff *skb; struct sk_buff *skb;
u16 len; u16 len;
dma_addr_t pa; dma_addr_t pa;
int r;
len = FC_FRAME_HEADROOM + FC_MAX_FRAME + FC_FRAME_TAILROOM; len = FC_FRAME_HEADROOM + FC_MAX_FRAME + FC_FRAME_TAILROOM;
skb = dev_alloc_skb(len); skb = dev_alloc_skb(len);
@ -952,8 +953,19 @@ int fnic_alloc_rq_frame(struct vnic_rq *rq)
skb_reset_network_header(skb); skb_reset_network_header(skb);
skb_put(skb, len); skb_put(skb, len);
pa = pci_map_single(fnic->pdev, skb->data, len, PCI_DMA_FROMDEVICE); pa = pci_map_single(fnic->pdev, skb->data, len, PCI_DMA_FROMDEVICE);
r = pci_dma_mapping_error(fnic->pdev, pa);
if (r) {
printk(KERN_ERR "PCI mapping failed with error %d\n", r);
goto free_skb;
}
fnic_queue_rq_desc(rq, skb, pa, len); fnic_queue_rq_desc(rq, skb, pa, len);
return 0; return 0;
free_skb:
kfree_skb(skb);
return r;
} }
void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf) void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf)
@ -981,6 +993,7 @@ void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
struct ethhdr *eth_hdr; struct ethhdr *eth_hdr;
struct vlan_ethhdr *vlan_hdr; struct vlan_ethhdr *vlan_hdr;
unsigned long flags; unsigned long flags;
int r;
if (!fnic->vlan_hw_insert) { if (!fnic->vlan_hw_insert) {
eth_hdr = (struct ethhdr *)skb_mac_header(skb); eth_hdr = (struct ethhdr *)skb_mac_header(skb);
@ -1003,18 +1016,27 @@ void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
pa = pci_map_single(fnic->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); pa = pci_map_single(fnic->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
spin_lock_irqsave(&fnic->wq_lock[0], flags); r = pci_dma_mapping_error(fnic->pdev, pa);
if (!vnic_wq_desc_avail(wq)) { if (r) {
pci_unmap_single(fnic->pdev, pa, skb->len, PCI_DMA_TODEVICE); printk(KERN_ERR "PCI mapping failed with error %d\n", r);
spin_unlock_irqrestore(&fnic->wq_lock[0], flags); goto free_skb;
kfree_skb(skb);
return;
} }
spin_lock_irqsave(&fnic->wq_lock[0], flags);
if (!vnic_wq_desc_avail(wq))
goto irq_restore;
fnic_queue_wq_eth_desc(wq, skb, pa, skb->len, fnic_queue_wq_eth_desc(wq, skb, pa, skb->len,
0 /* hw inserts cos value */, 0 /* hw inserts cos value */,
fnic->vlan_id, 1); fnic->vlan_id, 1);
spin_unlock_irqrestore(&fnic->wq_lock[0], flags); spin_unlock_irqrestore(&fnic->wq_lock[0], flags);
return;
irq_restore:
spin_unlock_irqrestore(&fnic->wq_lock[0], flags);
pci_unmap_single(fnic->pdev, pa, skb->len, PCI_DMA_TODEVICE);
free_skb:
kfree_skb(skb);
} }
/* /*
@ -1071,6 +1093,12 @@ static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp)
pa = pci_map_single(fnic->pdev, eth_hdr, tot_len, PCI_DMA_TODEVICE); pa = pci_map_single(fnic->pdev, eth_hdr, tot_len, PCI_DMA_TODEVICE);
ret = pci_dma_mapping_error(fnic->pdev, pa);
if (ret) {
printk(KERN_ERR "DMA map failed with error %d\n", ret);
goto free_skb_on_err;
}
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_SEND, if ((fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_SEND,
(char *)eth_hdr, tot_len)) != 0) { (char *)eth_hdr, tot_len)) != 0) {
printk(KERN_ERR "fnic ctlr frame trace error!!!"); printk(KERN_ERR "fnic ctlr frame trace error!!!");
@ -1082,15 +1110,17 @@ static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp)
pci_unmap_single(fnic->pdev, pa, pci_unmap_single(fnic->pdev, pa,
tot_len, PCI_DMA_TODEVICE); tot_len, PCI_DMA_TODEVICE);
ret = -1; ret = -1;
goto fnic_send_frame_end; goto irq_restore;
} }
fnic_queue_wq_desc(wq, skb, pa, tot_len, fr_eof(fp), fnic_queue_wq_desc(wq, skb, pa, tot_len, fr_eof(fp),
0 /* hw inserts cos value */, 0 /* hw inserts cos value */,
fnic->vlan_id, 1, 1, 1); fnic->vlan_id, 1, 1, 1);
fnic_send_frame_end:
irq_restore:
spin_unlock_irqrestore(&fnic->wq_lock[0], flags); spin_unlock_irqrestore(&fnic->wq_lock[0], flags);
free_skb_on_err:
if (ret) if (ret)
dev_kfree_skb_any(fp_skb(fp)); dev_kfree_skb_any(fp_skb(fp));

View File

@ -330,6 +330,7 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
int flags; int flags;
u8 exch_flags; u8 exch_flags;
struct scsi_lun fc_lun; struct scsi_lun fc_lun;
int r;
if (sg_count) { if (sg_count) {
/* For each SGE, create a device desc entry */ /* For each SGE, create a device desc entry */
@ -346,6 +347,12 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
io_req->sgl_list, io_req->sgl_list,
sizeof(io_req->sgl_list[0]) * sg_count, sizeof(io_req->sgl_list[0]) * sg_count,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
r = pci_dma_mapping_error(fnic->pdev, io_req->sgl_list_pa);
if (r) {
printk(KERN_ERR "PCI mapping failed with error %d\n", r);
return SCSI_MLQUEUE_HOST_BUSY;
}
} }
io_req->sense_buf_pa = pci_map_single(fnic->pdev, io_req->sense_buf_pa = pci_map_single(fnic->pdev,
@ -353,6 +360,15 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
SCSI_SENSE_BUFFERSIZE, SCSI_SENSE_BUFFERSIZE,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
r = pci_dma_mapping_error(fnic->pdev, io_req->sense_buf_pa);
if (r) {
pci_unmap_single(fnic->pdev, io_req->sgl_list_pa,
sizeof(io_req->sgl_list[0]) * sg_count,
PCI_DMA_TODEVICE);
printk(KERN_ERR "PCI mapping failed with error %d\n", r);
return SCSI_MLQUEUE_HOST_BUSY;
}
int_to_scsilun(sc->device->lun, &fc_lun); int_to_scsilun(sc->device->lun, &fc_lun);
/* Enqueue the descriptor in the Copy WQ */ /* Enqueue the descriptor in the Copy WQ */

View File

@ -495,15 +495,17 @@ struct unsol_rcv_ct_ctx {
#define LPFC_USER_LINK_SPEED_8G 8 /* 8 Gigabaud */ #define LPFC_USER_LINK_SPEED_8G 8 /* 8 Gigabaud */
#define LPFC_USER_LINK_SPEED_10G 10 /* 10 Gigabaud */ #define LPFC_USER_LINK_SPEED_10G 10 /* 10 Gigabaud */
#define LPFC_USER_LINK_SPEED_16G 16 /* 16 Gigabaud */ #define LPFC_USER_LINK_SPEED_16G 16 /* 16 Gigabaud */
#define LPFC_USER_LINK_SPEED_MAX LPFC_USER_LINK_SPEED_16G #define LPFC_USER_LINK_SPEED_32G 32 /* 32 Gigabaud */
#define LPFC_USER_LINK_SPEED_BITMAP ((1 << LPFC_USER_LINK_SPEED_16G) | \ #define LPFC_USER_LINK_SPEED_MAX LPFC_USER_LINK_SPEED_32G
#define LPFC_USER_LINK_SPEED_BITMAP ((1ULL << LPFC_USER_LINK_SPEED_32G) | \
(1 << LPFC_USER_LINK_SPEED_16G) | \
(1 << LPFC_USER_LINK_SPEED_10G) | \ (1 << LPFC_USER_LINK_SPEED_10G) | \
(1 << LPFC_USER_LINK_SPEED_8G) | \ (1 << LPFC_USER_LINK_SPEED_8G) | \
(1 << LPFC_USER_LINK_SPEED_4G) | \ (1 << LPFC_USER_LINK_SPEED_4G) | \
(1 << LPFC_USER_LINK_SPEED_2G) | \ (1 << LPFC_USER_LINK_SPEED_2G) | \
(1 << LPFC_USER_LINK_SPEED_1G) | \ (1 << LPFC_USER_LINK_SPEED_1G) | \
(1 << LPFC_USER_LINK_SPEED_AUTO)) (1 << LPFC_USER_LINK_SPEED_AUTO))
#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16" #define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32"
enum nemb_type { enum nemb_type {
nemb_mse = 1, nemb_mse = 1,

View File

@ -1642,8 +1642,6 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
struct Scsi_Host *shost = class_to_shost(dev);\ struct Scsi_Host *shost = class_to_shost(dev);\
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
struct lpfc_hba *phba = vport->phba;\ struct lpfc_hba *phba = vport->phba;\
uint val = 0;\
val = phba->cfg_##attr;\
return snprintf(buf, PAGE_SIZE, "%d\n",\ return snprintf(buf, PAGE_SIZE, "%d\n",\
phba->cfg_##attr);\ phba->cfg_##attr);\
} }
@ -1808,8 +1806,6 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
{ \ { \
struct Scsi_Host *shost = class_to_shost(dev);\ struct Scsi_Host *shost = class_to_shost(dev);\
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
uint val = 0;\
val = vport->cfg_##attr;\
return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\ return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\
} }
@ -1835,8 +1831,6 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
{ \ { \
struct Scsi_Host *shost = class_to_shost(dev);\ struct Scsi_Host *shost = class_to_shost(dev);\
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
uint val = 0;\
val = vport->cfg_##attr;\
return snprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\ return snprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\
} }
@ -3282,15 +3276,20 @@ lpfc_topology_store(struct device *dev, struct device_attribute *attr,
if (val >= 0 && val <= 6) { if (val >= 0 && val <= 6) {
prev_val = phba->cfg_topology; prev_val = phba->cfg_topology;
phba->cfg_topology = val;
if (phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G && if (phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G &&
val == 4) { val == 4) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"3113 Loop mode not supported at speed %d\n", "3113 Loop mode not supported at speed %d\n",
phba->cfg_link_speed); val);
phba->cfg_topology = prev_val;
return -EINVAL; return -EINVAL;
} }
if (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC &&
val == 4) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"3114 Loop mode not supported\n");
return -EINVAL;
}
phba->cfg_topology = val;
if (nolip) if (nolip)
return strlen(buf); return strlen(buf);
@ -3731,7 +3730,8 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
((val == LPFC_USER_LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) || ((val == LPFC_USER_LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) || ((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) || ((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb))) { ((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) ||
((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb))) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"2879 lpfc_link_speed attribute cannot be set " "2879 lpfc_link_speed attribute cannot be set "
"to %d. Speed is not supported by this port.\n", "to %d. Speed is not supported by this port.\n",
@ -5267,6 +5267,9 @@ lpfc_get_host_speed(struct Scsi_Host *shost)
case LPFC_LINK_SPEED_16GHZ: case LPFC_LINK_SPEED_16GHZ:
fc_host_speed(shost) = FC_PORTSPEED_16GBIT; fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
break; break;
case LPFC_LINK_SPEED_32GHZ:
fc_host_speed(shost) = FC_PORTSPEED_32GBIT;
break;
default: default:
fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
break; break;

View File

@ -904,7 +904,6 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
{ {
uint32_t evt_req_id = 0; uint32_t evt_req_id = 0;
uint32_t cmd; uint32_t cmd;
uint32_t len;
struct lpfc_dmabuf *dmabuf = NULL; struct lpfc_dmabuf *dmabuf = NULL;
struct lpfc_bsg_event *evt; struct lpfc_bsg_event *evt;
struct event_data *evt_dat = NULL; struct event_data *evt_dat = NULL;
@ -946,7 +945,6 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
ct_req = (struct lpfc_sli_ct_request *)dmabuf->virt; ct_req = (struct lpfc_sli_ct_request *)dmabuf->virt;
evt_req_id = ct_req->FsType; evt_req_id = ct_req->FsType;
cmd = ct_req->CommandResponse.bits.CmdRsp; cmd = ct_req->CommandResponse.bits.CmdRsp;
len = ct_req->CommandResponse.bits.Size;
if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
lpfc_sli_ringpostbuf_put(phba, pring, dmabuf); lpfc_sli_ringpostbuf_put(phba, pring, dmabuf);
@ -2988,7 +2986,6 @@ lpfc_bsg_diag_loopback_run(struct fc_bsg_job *job)
{ {
struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata; struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct diag_mode_test *diag_mode;
struct lpfc_bsg_event *evt; struct lpfc_bsg_event *evt;
struct event_data *evdat; struct event_data *evdat;
struct lpfc_sli *psli = &phba->sli; struct lpfc_sli *psli = &phba->sli;
@ -3031,8 +3028,6 @@ lpfc_bsg_diag_loopback_run(struct fc_bsg_job *job)
rc = -EINVAL; rc = -EINVAL;
goto loopback_test_exit; goto loopback_test_exit;
} }
diag_mode = (struct diag_mode_test *)
job->request->rqst_data.h_vendor.vendor_cmd;
if ((phba->link_state == LPFC_HBA_ERROR) || if ((phba->link_state == LPFC_HBA_ERROR) ||
(psli->sli_flag & LPFC_BLOCK_MGMT_IO) || (psli->sli_flag & LPFC_BLOCK_MGMT_IO) ||
@ -3293,7 +3288,6 @@ lpfc_bsg_get_dfc_rev(struct fc_bsg_job *job)
{ {
struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata; struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct get_mgmt_rev *event_req;
struct get_mgmt_rev_reply *event_reply; struct get_mgmt_rev_reply *event_reply;
int rc = 0; int rc = 0;
@ -3306,9 +3300,6 @@ lpfc_bsg_get_dfc_rev(struct fc_bsg_job *job)
goto job_error; goto job_error;
} }
event_req = (struct get_mgmt_rev *)
job->request->rqst_data.h_vendor.vendor_cmd;
event_reply = (struct get_mgmt_rev_reply *) event_reply = (struct get_mgmt_rev_reply *)
job->reply->reply_data.vendor_reply.vendor_rsp; job->reply->reply_data.vendor_reply.vendor_rsp;
@ -4348,7 +4339,6 @@ static int
lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job, lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job,
struct lpfc_dmabuf *dmabuf) struct lpfc_dmabuf *dmabuf)
{ {
struct lpfc_sli_config_mbox *sli_cfg_mbx;
struct bsg_job_data *dd_data = NULL; struct bsg_job_data *dd_data = NULL;
LPFC_MBOXQ_t *pmboxq = NULL; LPFC_MBOXQ_t *pmboxq = NULL;
MAILBOX_t *pmb; MAILBOX_t *pmb;
@ -4362,9 +4352,6 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job,
phba->mbox_ext_buf_ctx.seqNum++; phba->mbox_ext_buf_ctx.seqNum++;
nemb_tp = phba->mbox_ext_buf_ctx.nembType; nemb_tp = phba->mbox_ext_buf_ctx.nembType;
sli_cfg_mbx = (struct lpfc_sli_config_mbox *)
phba->mbox_ext_buf_ctx.mbx_dmabuf->virt;
dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
if (!dd_data) { if (!dd_data) {
rc = -ENOMEM; rc = -ENOMEM;
@ -4606,7 +4593,6 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
uint32_t transmit_length, receive_length, mode; uint32_t transmit_length, receive_length, mode;
struct lpfc_mbx_sli4_config *sli4_config; struct lpfc_mbx_sli4_config *sli4_config;
struct lpfc_mbx_nembed_cmd *nembed_sge; struct lpfc_mbx_nembed_cmd *nembed_sge;
struct mbox_header *header;
struct ulp_bde64 *bde; struct ulp_bde64 *bde;
uint8_t *ext = NULL; uint8_t *ext = NULL;
int rc = 0; int rc = 0;
@ -4804,8 +4790,6 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
/* rebuild the command for sli4 using our /* rebuild the command for sli4 using our
* own buffers like we do for biu diags * own buffers like we do for biu diags
*/ */
header = (struct mbox_header *)
&pmb->un.varWords[0];
nembed_sge = (struct lpfc_mbx_nembed_cmd *) nembed_sge = (struct lpfc_mbx_nembed_cmd *)
&pmb->un.varWords[0]; &pmb->un.varWords[0];
receive_length = nembed_sge->sge[0].length; receive_length = nembed_sge->sge[0].length;
@ -5048,7 +5032,6 @@ lpfc_menlo_cmd(struct fc_bsg_job *job)
IOCB_t *cmd; IOCB_t *cmd;
int rc = 0; int rc = 0;
struct menlo_command *menlo_cmd; struct menlo_command *menlo_cmd;
struct menlo_response *menlo_resp;
struct lpfc_dmabuf *bmp = NULL, *cmp = NULL, *rmp = NULL; struct lpfc_dmabuf *bmp = NULL, *cmp = NULL, *rmp = NULL;
int request_nseg; int request_nseg;
int reply_nseg; int reply_nseg;
@ -5088,9 +5071,6 @@ lpfc_menlo_cmd(struct fc_bsg_job *job)
menlo_cmd = (struct menlo_command *) menlo_cmd = (struct menlo_command *)
job->request->rqst_data.h_vendor.vendor_cmd; job->request->rqst_data.h_vendor.vendor_cmd;
menlo_resp = (struct menlo_response *)
job->reply->reply_data.vendor_reply.vendor_rsp;
/* allocate our bsg tracking structure */ /* allocate our bsg tracking structure */
dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
if (!dd_data) { if (!dd_data) {

View File

@ -55,6 +55,7 @@
#define HBA_PORTSPEED_10GBIT 0x0004 /* 10 GBit/sec */ #define HBA_PORTSPEED_10GBIT 0x0004 /* 10 GBit/sec */
#define HBA_PORTSPEED_8GBIT 0x0010 /* 8 GBit/sec */ #define HBA_PORTSPEED_8GBIT 0x0010 /* 8 GBit/sec */
#define HBA_PORTSPEED_16GBIT 0x0020 /* 16 GBit/sec */ #define HBA_PORTSPEED_16GBIT 0x0020 /* 16 GBit/sec */
#define HBA_PORTSPEED_32GBIT 0x0040 /* 32 GBit/sec */
#define HBA_PORTSPEED_UNKNOWN 0x0800 /* Unknown */ #define HBA_PORTSPEED_UNKNOWN 0x0800 /* Unknown */
#define FOURBYTES 4 #define FOURBYTES 4
@ -575,7 +576,6 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_vport *vport = cmdiocb->vport; struct lpfc_vport *vport = cmdiocb->vport;
struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
IOCB_t *irsp; IOCB_t *irsp;
struct lpfc_dmabuf *bmp;
struct lpfc_dmabuf *outp; struct lpfc_dmabuf *outp;
struct lpfc_sli_ct_request *CTrsp; struct lpfc_sli_ct_request *CTrsp;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
@ -588,7 +588,6 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
cmdiocb->context_un.rsp_iocb = rspiocb; cmdiocb->context_un.rsp_iocb = rspiocb;
outp = (struct lpfc_dmabuf *) cmdiocb->context2; outp = (struct lpfc_dmabuf *) cmdiocb->context2;
bmp = (struct lpfc_dmabuf *) cmdiocb->context3;
irsp = &rspiocb->iocb; irsp = &rspiocb->iocb;
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
@ -1733,12 +1732,9 @@ hba_out:
case SLI_MGMT_RPRT: case SLI_MGMT_RPRT:
case SLI_MGMT_RPA: case SLI_MGMT_RPA:
{ {
lpfc_vpd_t *vp;
struct serv_parm *hsp; struct serv_parm *hsp;
int len = 0; int len = 0;
vp = &phba->vpd;
if (cmdcode == SLI_MGMT_RPRT) { if (cmdcode == SLI_MGMT_RPRT) {
rh = (struct lpfc_fdmi_reg_hba *) rh = (struct lpfc_fdmi_reg_hba *)
&CtReq->un.PortID; &CtReq->un.PortID;
@ -1778,6 +1774,8 @@ hba_out:
ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED); ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED);
ad->AttrLen = cpu_to_be16(FOURBYTES + 4); ad->AttrLen = cpu_to_be16(FOURBYTES + 4);
ae->un.SupportSpeed = 0; ae->un.SupportSpeed = 0;
if (phba->lmt & LMT_32Gb)
ae->un.SupportSpeed |= HBA_PORTSPEED_32GBIT;
if (phba->lmt & LMT_16Gb) if (phba->lmt & LMT_16Gb)
ae->un.SupportSpeed |= HBA_PORTSPEED_16GBIT; ae->un.SupportSpeed |= HBA_PORTSPEED_16GBIT;
if (phba->lmt & LMT_10Gb) if (phba->lmt & LMT_10Gb)
@ -1821,6 +1819,9 @@ hba_out:
case LPFC_LINK_SPEED_16GHZ: case LPFC_LINK_SPEED_16GHZ:
ae->un.PortSpeed = HBA_PORTSPEED_16GBIT; ae->un.PortSpeed = HBA_PORTSPEED_16GBIT;
break; break;
case LPFC_LINK_SPEED_32GHZ:
ae->un.PortSpeed = HBA_PORTSPEED_32GBIT;
break;
default: default:
ae->un.PortSpeed = HBA_PORTSPEED_UNKNOWN; ae->un.PortSpeed = HBA_PORTSPEED_UNKNOWN;
break; break;

View File

@ -457,11 +457,9 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport)
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
LPFC_MBOXQ_t *mboxq; LPFC_MBOXQ_t *mboxq;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
struct serv_parm *sp;
struct lpfc_dmabuf *dmabuf; struct lpfc_dmabuf *dmabuf;
int rc = 0; int rc = 0;
sp = &phba->fc_fabparam;
/* move forward in case of SLI4 FC port loopback test and pt2pt mode */ /* move forward in case of SLI4 FC port loopback test and pt2pt mode */
if ((phba->sli_rev == LPFC_SLI_REV4) && if ((phba->sli_rev == LPFC_SLI_REV4) &&
!(phba->link_flag & LS_LOOPBACK_MODE) && !(phba->link_flag & LS_LOOPBACK_MODE) &&
@ -1028,9 +1026,11 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
stop_rr_fcf_flogi: stop_rr_fcf_flogi:
/* FLOGI failure */ /* FLOGI failure */
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
"2858 FLOGI failure Status:x%x/x%x TMO:x%x\n", "2858 FLOGI failure Status:x%x/x%x TMO:x%x "
"Data x%x x%x\n",
irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpStatus, irsp->un.ulpWord[4],
irsp->ulpTimeout); irsp->ulpTimeout, phba->hba_flag,
phba->fcf.fcf_flag);
/* Check for retry */ /* Check for retry */
if (lpfc_els_retry(phba, cmdiocb, rspiocb)) if (lpfc_els_retry(phba, cmdiocb, rspiocb))
@ -1154,6 +1154,9 @@ stop_rr_fcf_flogi:
} }
flogifail: flogifail:
spin_lock_irq(&phba->hbalock);
phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
spin_unlock_irq(&phba->hbalock);
lpfc_nlp_put(ndlp); lpfc_nlp_put(ndlp);
if (!lpfc_error_lost_link(irsp)) { if (!lpfc_error_lost_link(irsp)) {
@ -1205,14 +1208,11 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
struct serv_parm *sp; struct serv_parm *sp;
IOCB_t *icmd; IOCB_t *icmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli_ring *pring;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
uint32_t tmo; uint32_t tmo;
int rc; int rc;
pring = &phba->sli.ring[LPFC_ELS_RING];
cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
ndlp->nlp_DID, ELS_CMD_FLOGI); ndlp->nlp_DID, ELS_CMD_FLOGI);
@ -1454,8 +1454,6 @@ lpfc_initial_fdisc(struct lpfc_vport *vport)
void void
lpfc_more_plogi(struct lpfc_vport *vport) lpfc_more_plogi(struct lpfc_vport *vport)
{ {
int sentplogi;
if (vport->num_disc_nodes) if (vport->num_disc_nodes)
vport->num_disc_nodes--; vport->num_disc_nodes--;
@ -1468,7 +1466,7 @@ lpfc_more_plogi(struct lpfc_vport *vport)
/* Check to see if there are more PLOGIs to be sent */ /* Check to see if there are more PLOGIs to be sent */
if (vport->fc_flag & FC_NLP_MORE) if (vport->fc_flag & FC_NLP_MORE)
/* go thru NPR nodes and issue any remaining ELS PLOGIs */ /* go thru NPR nodes and issue any remaining ELS PLOGIs */
sentplogi = lpfc_els_disc_plogi(vport); lpfc_els_disc_plogi(vport);
return; return;
} }
@ -1956,16 +1954,12 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
{ {
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct serv_parm *sp; struct serv_parm *sp;
IOCB_t *icmd;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
int ret; int ret;
psli = &phba->sli;
ndlp = lpfc_findnode_did(vport, did); ndlp = lpfc_findnode_did(vport, did);
if (ndlp && !NLP_CHK_NODE_ACT(ndlp)) if (ndlp && !NLP_CHK_NODE_ACT(ndlp))
ndlp = NULL; ndlp = NULL;
@ -1977,7 +1971,6 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
if (!elsiocb) if (!elsiocb)
return 1; return 1;
icmd = &elsiocb->iocb;
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
/* For PLOGI request, remainder of payload is service parameters */ /* For PLOGI request, remainder of payload is service parameters */
@ -2034,10 +2027,8 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_vport *vport = cmdiocb->vport; struct lpfc_vport *vport = cmdiocb->vport;
struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
IOCB_t *irsp; IOCB_t *irsp;
struct lpfc_sli *psli;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
psli = &phba->sli;
/* we pass cmdiocb to state machine which needs rspiocb as well */ /* we pass cmdiocb to state machine which needs rspiocb as well */
cmdiocb->context_un.rsp_iocb = rspiocb; cmdiocb->context_un.rsp_iocb = rspiocb;
@ -2117,7 +2108,6 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
PRLI *npr; PRLI *npr;
IOCB_t *icmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
@ -2128,7 +2118,6 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
if (!elsiocb) if (!elsiocb)
return 1; return 1;
icmd = &elsiocb->iocb;
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
/* For PRLI request, remainder of payload is service parameters */ /* For PRLI request, remainder of payload is service parameters */
@ -2413,7 +2402,6 @@ lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
ADISC *ap; ADISC *ap;
IOCB_t *icmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
@ -2424,7 +2412,6 @@ lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
if (!elsiocb) if (!elsiocb)
return 1; return 1;
icmd = &elsiocb->iocb;
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
/* For ADISC request, remainder of payload is service parameters */ /* For ADISC request, remainder of payload is service parameters */
@ -2478,12 +2465,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_vport *vport = ndlp->vport; struct lpfc_vport *vport = ndlp->vport;
struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
IOCB_t *irsp; IOCB_t *irsp;
struct lpfc_sli *psli;
struct lpfcMboxq *mbox; struct lpfcMboxq *mbox;
unsigned long flags; unsigned long flags;
uint32_t skip_recovery = 0; uint32_t skip_recovery = 0;
psli = &phba->sli;
/* we pass cmdiocb to state machine which needs rspiocb as well */ /* we pass cmdiocb to state machine which needs rspiocb as well */
cmdiocb->context_un.rsp_iocb = rspiocb; cmdiocb->context_un.rsp_iocb = rspiocb;
@ -2609,7 +2594,6 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
{ {
struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
IOCB_t *icmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
@ -2628,7 +2612,6 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
if (!elsiocb) if (!elsiocb)
return 1; return 1;
icmd = &elsiocb->iocb;
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
*((uint32_t *) (pcmd)) = ELS_CMD_LOGO; *((uint32_t *) (pcmd)) = ELS_CMD_LOGO;
pcmd += sizeof(uint32_t); pcmd += sizeof(uint32_t);
@ -2742,14 +2725,11 @@ int
lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
{ {
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
IOCB_t *icmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
psli = &phba->sli;
cmdsize = (sizeof(uint32_t) + sizeof(SCR)); cmdsize = (sizeof(uint32_t) + sizeof(SCR));
ndlp = lpfc_findnode_did(vport, nportid); ndlp = lpfc_findnode_did(vport, nportid);
@ -2776,7 +2756,6 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
return 1; return 1;
} }
icmd = &elsiocb->iocb;
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
*((uint32_t *) (pcmd)) = ELS_CMD_SCR; *((uint32_t *) (pcmd)) = ELS_CMD_SCR;
@ -2836,9 +2815,7 @@ static int
lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
{ {
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
IOCB_t *icmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli *psli;
FARP *fp; FARP *fp;
uint8_t *pcmd; uint8_t *pcmd;
uint32_t *lp; uint32_t *lp;
@ -2846,7 +2823,6 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
struct lpfc_nodelist *ondlp; struct lpfc_nodelist *ondlp;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
psli = &phba->sli;
cmdsize = (sizeof(uint32_t) + sizeof(FARP)); cmdsize = (sizeof(uint32_t) + sizeof(FARP));
ndlp = lpfc_findnode_did(vport, nportid); ndlp = lpfc_findnode_did(vport, nportid);
@ -2872,7 +2848,6 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
return 1; return 1;
} }
icmd = &elsiocb->iocb;
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
*((uint32_t *) (pcmd)) = ELS_CMD_FARPR; *((uint32_t *) (pcmd)) = ELS_CMD_FARPR;
@ -3922,13 +3897,11 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
IOCB_t *icmd; IOCB_t *icmd;
IOCB_t *oldcmd; IOCB_t *oldcmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
int rc; int rc;
ELS_PKT *els_pkt_ptr; ELS_PKT *els_pkt_ptr;
psli = &phba->sli;
oldcmd = &oldiocb->iocb; oldcmd = &oldiocb->iocb;
switch (flag) { switch (flag) {
@ -4061,12 +4034,10 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
IOCB_t *icmd; IOCB_t *icmd;
IOCB_t *oldcmd; IOCB_t *oldcmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
int rc; int rc;
psli = &phba->sli;
cmdsize = 2 * sizeof(uint32_t); cmdsize = 2 * sizeof(uint32_t);
elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
ndlp->nlp_DID, ELS_CMD_LS_RJT); ndlp->nlp_DID, ELS_CMD_LS_RJT);
@ -4212,13 +4183,10 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
IOCB_t *icmd; IOCB_t *icmd;
IOCB_t *oldcmd; IOCB_t *oldcmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
int rc; int rc;
psli = &phba->sli;
cmdsize = sizeof(uint32_t) + sizeof(PRLI); cmdsize = sizeof(uint32_t) + sizeof(PRLI);
elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
ndlp->nlp_DID, (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK))); ndlp->nlp_DID, (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)));
@ -4315,12 +4283,10 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
RNID *rn; RNID *rn;
IOCB_t *icmd, *oldcmd; IOCB_t *icmd, *oldcmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
int rc; int rc;
psli = &phba->sli;
cmdsize = sizeof(uint32_t) + sizeof(uint32_t) cmdsize = sizeof(uint32_t) + sizeof(uint32_t)
+ (2 * sizeof(struct lpfc_name)); + (2 * sizeof(struct lpfc_name));
if (format) if (format)
@ -4447,12 +4413,10 @@ lpfc_els_rsp_echo_acc(struct lpfc_vport *vport, uint8_t *data,
{ {
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
struct lpfc_sli *psli;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
int rc; int rc;
psli = &phba->sli;
cmdsize = oldiocb->iocb.unsli3.rcvsli3.acc_len; cmdsize = oldiocb->iocb.unsli3.rcvsli3.acc_len;
/* The accumulated length can exceed the BPL_SIZE. For /* The accumulated length can exceed the BPL_SIZE. For
@ -4746,6 +4710,8 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba)
desc->info.port_speed.speed = cpu_to_be16(rdp_speed); desc->info.port_speed.speed = cpu_to_be16(rdp_speed);
if (phba->lmt & LMT_32Gb)
rdp_cap |= RDP_PS_32GB;
if (phba->lmt & LMT_16Gb) if (phba->lmt & LMT_16Gb)
rdp_cap |= RDP_PS_16GB; rdp_cap |= RDP_PS_16GB;
if (phba->lmt & LMT_10Gb) if (phba->lmt & LMT_10Gb)
@ -5181,14 +5147,12 @@ lpfc_els_rcv_lcb(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
{ {
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct lpfc_dmabuf *pcmd; struct lpfc_dmabuf *pcmd;
IOCB_t *icmd;
uint8_t *lp; uint8_t *lp;
struct fc_lcb_request_frame *beacon; struct fc_lcb_request_frame *beacon;
struct lpfc_lcb_context *lcb_context; struct lpfc_lcb_context *lcb_context;
uint8_t state, rjt_err; uint8_t state, rjt_err;
struct ls_rjt stat; struct ls_rjt stat;
icmd = &cmdiocb->iocb;
pcmd = (struct lpfc_dmabuf *)cmdiocb->context2; pcmd = (struct lpfc_dmabuf *)cmdiocb->context2;
lp = (uint8_t *)pcmd->virt; lp = (uint8_t *)pcmd->virt;
beacon = (struct fc_lcb_request_frame *)pcmd->virt; beacon = (struct fc_lcb_request_frame *)pcmd->virt;
@ -5444,7 +5408,7 @@ lpfc_send_rscn_event(struct lpfc_vport *vport,
fc_host_post_vendor_event(shost, fc_host_post_vendor_event(shost,
fc_get_event_number(), fc_get_event_number(),
sizeof(struct lpfc_els_event_header) + payload_len, sizeof(struct lpfc_rscn_event_header) + payload_len,
(char *)rscn_event_data, (char *)rscn_event_data,
LPFC_NL_VENDOR_ID); LPFC_NL_VENDOR_ID);
@ -5481,13 +5445,11 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct lpfc_dmabuf *pcmd; struct lpfc_dmabuf *pcmd;
uint32_t *lp, *datap; uint32_t *lp, *datap;
IOCB_t *icmd;
uint32_t payload_len, length, nportid, *cmd; uint32_t payload_len, length, nportid, *cmd;
int rscn_cnt; int rscn_cnt;
int rscn_id = 0, hba_id = 0; int rscn_id = 0, hba_id = 0;
int i; int i;
icmd = &cmdiocb->iocb;
pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
lp = (uint32_t *) pcmd->virt; lp = (uint32_t *) pcmd->virt;
@ -5893,6 +5855,13 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
return 1; return 1;
} }
/* send our FLOGI first */
if (vport->port_state < LPFC_FLOGI) {
vport->fc_myDID = 0;
lpfc_initial_flogi(vport);
vport->fc_myDID = Fabric_DID;
}
/* Send back ACC */ /* Send back ACC */
lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL); lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL);
@ -5943,12 +5912,10 @@ lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
{ {
struct lpfc_dmabuf *pcmd; struct lpfc_dmabuf *pcmd;
uint32_t *lp; uint32_t *lp;
IOCB_t *icmd;
RNID *rn; RNID *rn;
struct ls_rjt stat; struct ls_rjt stat;
uint32_t cmd; uint32_t cmd;
icmd = &cmdiocb->iocb;
pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
lp = (uint32_t *) pcmd->virt; lp = (uint32_t *) pcmd->virt;
@ -6259,7 +6226,6 @@ lpfc_els_rcv_rls(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
{ {
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
LPFC_MBOXQ_t *mbox; LPFC_MBOXQ_t *mbox;
struct lpfc_dmabuf *pcmd;
struct ls_rjt stat; struct ls_rjt stat;
if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) && if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
@ -6267,8 +6233,6 @@ lpfc_els_rcv_rls(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
/* reject the unsolicited RPS request and done with it */ /* reject the unsolicited RPS request and done with it */
goto reject_out; goto reject_out;
pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC); mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
if (mbox) { if (mbox) {
lpfc_read_lnk_stat(phba, mbox); lpfc_read_lnk_stat(phba, mbox);
@ -6482,7 +6446,6 @@ lpfc_issue_els_rrq(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
{ {
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct RRQ *els_rrq; struct RRQ *els_rrq;
IOCB_t *icmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
@ -6501,7 +6464,6 @@ lpfc_issue_els_rrq(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
if (!elsiocb) if (!elsiocb)
return 1; return 1;
icmd = &elsiocb->iocb;
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
/* For RRQ request, remainder of payload is Exchange IDs */ /* For RRQ request, remainder of payload is Exchange IDs */
@ -7374,6 +7336,15 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
"Data: x%x x%x x%x x%x\n", "Data: x%x x%x x%x x%x\n",
cmd, did, vport->port_state, vport->fc_flag, cmd, did, vport->port_state, vport->fc_flag,
vport->fc_myDID, vport->fc_prevDID); vport->fc_myDID, vport->fc_prevDID);
/* reject till our FLOGI completes */
if ((vport->port_state < LPFC_FABRIC_CFG_LINK) &&
(cmd != ELS_CMD_FLOGI)) {
rjt_err = LSRJT_UNABLE_TPC;
rjt_exp = LSEXP_NOTHING_MORE;
goto lsrjt;
}
switch (cmd) { switch (cmd) {
case ELS_CMD_PLOGI: case ELS_CMD_PLOGI:
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
@ -7411,20 +7382,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
rjt_exp = LSEXP_NOTHING_MORE; rjt_exp = LSEXP_NOTHING_MORE;
break; break;
} }
/* We get here, and drop thru, if we are PT2PT with
* another NPort and the other side has initiated
* the PLOGI before responding to our FLOGI.
*/
if (phba->sli_rev == LPFC_SLI_REV4 &&
(phba->fc_topology_changed ||
vport->fc_myDID != vport->fc_prevDID)) {
lpfc_unregister_fcf_prep(phba);
spin_lock_irq(shost->host_lock);
vport->fc_flag &= ~FC_VFI_REGISTERED;
spin_unlock_irq(shost->host_lock);
phba->fc_topology_changed = 0;
lpfc_issue_reg_vfi(vport);
}
} }
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
@ -7655,6 +7612,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
break; break;
} }
lsrjt:
/* check if need to LS_RJT received ELS cmd */ /* check if need to LS_RJT received ELS cmd */
if (rjt_err) { if (rjt_err) {
memset(&stat, 0, sizeof(stat)); memset(&stat, 0, sizeof(stat));
@ -8428,7 +8386,6 @@ lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
{ {
struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
IOCB_t *icmd;
struct lpfc_iocbq *elsiocb; struct lpfc_iocbq *elsiocb;
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
@ -8439,7 +8396,6 @@ lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
if (!elsiocb) if (!elsiocb)
return 1; return 1;
icmd = &elsiocb->iocb;
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
*((uint32_t *) (pcmd)) = ELS_CMD_LOGO; *((uint32_t *) (pcmd)) = ELS_CMD_LOGO;
pcmd += sizeof(uint32_t); pcmd += sizeof(uint32_t);

View File

@ -800,7 +800,6 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove)
struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct lpfc_nodelist *ndlp, *next_ndlp; struct lpfc_nodelist *ndlp, *next_ndlp;
int rc;
list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
if (!NLP_CHK_NODE_ACT(ndlp)) if (!NLP_CHK_NODE_ACT(ndlp))
@ -816,7 +815,7 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove)
if ((phba->sli_rev < LPFC_SLI_REV4) && if ((phba->sli_rev < LPFC_SLI_REV4) &&
(!remove && ndlp->nlp_type & NLP_FABRIC)) (!remove && ndlp->nlp_type & NLP_FABRIC))
continue; continue;
rc = lpfc_disc_state_machine(vport, ndlp, NULL, lpfc_disc_state_machine(vport, ndlp, NULL,
remove remove
? NLP_EVT_DEVICE_RM ? NLP_EVT_DEVICE_RM
: NLP_EVT_DEVICE_RECOVERY); : NLP_EVT_DEVICE_RECOVERY);
@ -1774,7 +1773,6 @@ lpfc_sli4_fcf_rec_mbox_parse(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq,
uint16_t *next_fcf_index) uint16_t *next_fcf_index)
{ {
void *virt_addr; void *virt_addr;
dma_addr_t phys_addr;
struct lpfc_mbx_sge sge; struct lpfc_mbx_sge sge;
struct lpfc_mbx_read_fcf_tbl *read_fcf; struct lpfc_mbx_read_fcf_tbl *read_fcf;
uint32_t shdr_status, shdr_add_status, if_type; uint32_t shdr_status, shdr_add_status, if_type;
@ -1785,7 +1783,6 @@ lpfc_sli4_fcf_rec_mbox_parse(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq,
* routine only uses a single SGE. * routine only uses a single SGE.
*/ */
lpfc_sli4_mbx_sge_get(mboxq, 0, &sge); lpfc_sli4_mbx_sge_get(mboxq, 0, &sge);
phys_addr = getPaddr(sge.pa_hi, sge.pa_lo);
if (unlikely(!mboxq->sge_array)) { if (unlikely(!mboxq->sge_array)) {
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
"2524 Failed to get the non-embedded SGE " "2524 Failed to get the non-embedded SGE "
@ -2977,7 +2974,8 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
MAILBOX_t *mb = &pmb->u.mb; MAILBOX_t *mb = &pmb->u.mb;
struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1; struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1;
struct lpfc_vport *vport = pmb->vport; struct lpfc_vport *vport = pmb->vport;
struct serv_parm *sp = &vport->fc_sparam;
uint32_t ed_tov;
/* Check for error */ /* Check for error */
if (mb->mbxStatus) { if (mb->mbxStatus) {
@ -2992,6 +2990,18 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
memcpy((uint8_t *) &vport->fc_sparam, (uint8_t *) mp->virt, memcpy((uint8_t *) &vport->fc_sparam, (uint8_t *) mp->virt,
sizeof (struct serv_parm)); sizeof (struct serv_parm));
ed_tov = be32_to_cpu(sp->cmn.e_d_tov);
if (sp->cmn.edtovResolution) /* E_D_TOV ticks are in nanoseconds */
ed_tov = (ed_tov + 999999) / 1000000;
phba->fc_edtov = ed_tov;
phba->fc_ratov = (2 * ed_tov) / 1000;
if (phba->fc_ratov < FF_DEF_RATOV) {
/* RA_TOV should be atleast 10sec for initial flogi */
phba->fc_ratov = FF_DEF_RATOV;
}
lpfc_update_vport_wwn(vport); lpfc_update_vport_wwn(vport);
if (vport->port_type == LPFC_PHYSICAL_PORT) { if (vport->port_type == LPFC_PHYSICAL_PORT) {
memcpy(&phba->wwnn, &vport->fc_nodename, sizeof(phba->wwnn)); memcpy(&phba->wwnn, &vport->fc_nodename, sizeof(phba->wwnn));
@ -3032,6 +3042,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
case LPFC_LINK_SPEED_8GHZ: case LPFC_LINK_SPEED_8GHZ:
case LPFC_LINK_SPEED_10GHZ: case LPFC_LINK_SPEED_10GHZ:
case LPFC_LINK_SPEED_16GHZ: case LPFC_LINK_SPEED_16GHZ:
case LPFC_LINK_SPEED_32GHZ:
phba->fc_linkspeed = bf_get(lpfc_mbx_read_top_link_spd, la); phba->fc_linkspeed = bf_get(lpfc_mbx_read_top_link_spd, la);
break; break;
default: default:

View File

@ -33,7 +33,7 @@
#define FF_DEF_EDTOV 2000 /* Default E_D_TOV (2000ms) */ #define FF_DEF_EDTOV 2000 /* Default E_D_TOV (2000ms) */
#define FF_DEF_ALTOV 15 /* Default AL_TIME (15ms) */ #define FF_DEF_ALTOV 15 /* Default AL_TIME (15ms) */
#define FF_DEF_RATOV 2 /* Default RA_TOV (2s) */ #define FF_DEF_RATOV 10 /* Default RA_TOV (10s) */
#define FF_DEF_ARBTOV 1900 /* Default ARB_TOV (1900ms) */ #define FF_DEF_ARBTOV 1900 /* Default ARB_TOV (1900ms) */
#define LPFC_BUF_RING0 64 /* Number of buffers to post to RING #define LPFC_BUF_RING0 64 /* Number of buffers to post to RING
@ -1400,6 +1400,7 @@ struct lpfc_fdmi_reg_portattr {
#define PCI_DEVICE_ID_LANCER_FC_VF 0xe208 #define PCI_DEVICE_ID_LANCER_FC_VF 0xe208
#define PCI_DEVICE_ID_LANCER_FCOE 0xe260 #define PCI_DEVICE_ID_LANCER_FCOE 0xe260
#define PCI_DEVICE_ID_LANCER_FCOE_VF 0xe268 #define PCI_DEVICE_ID_LANCER_FCOE_VF 0xe268
#define PCI_DEVICE_ID_LANCER_G6_FC 0xe300
#define PCI_DEVICE_ID_SAT_SMB 0xf011 #define PCI_DEVICE_ID_SAT_SMB 0xf011
#define PCI_DEVICE_ID_SAT_MID 0xf015 #define PCI_DEVICE_ID_SAT_MID 0xf015
#define PCI_DEVICE_ID_RFLY 0xf095 #define PCI_DEVICE_ID_RFLY 0xf095
@ -2075,6 +2076,7 @@ typedef struct {
#define LINK_SPEED_8G 0x8 /* 8 Gigabaud */ #define LINK_SPEED_8G 0x8 /* 8 Gigabaud */
#define LINK_SPEED_10G 0x10 /* 10 Gigabaud */ #define LINK_SPEED_10G 0x10 /* 10 Gigabaud */
#define LINK_SPEED_16G 0x11 /* 16 Gigabaud */ #define LINK_SPEED_16G 0x11 /* 16 Gigabaud */
#define LINK_SPEED_32G 0x14 /* 32 Gigabaud */
} INIT_LINK_VAR; } INIT_LINK_VAR;
@ -2246,6 +2248,7 @@ typedef struct {
#define LMT_8Gb 0x080 #define LMT_8Gb 0x080
#define LMT_10Gb 0x100 #define LMT_10Gb 0x100
#define LMT_16Gb 0x200 #define LMT_16Gb 0x200
#define LMT_32Gb 0x400
uint32_t rsvd2; uint32_t rsvd2;
uint32_t rsvd3; uint32_t rsvd3;
uint32_t max_xri; uint32_t max_xri;
@ -2727,6 +2730,7 @@ struct lpfc_mbx_read_top {
#define LPFC_LINK_SPEED_8GHZ 0x20 #define LPFC_LINK_SPEED_8GHZ 0x20
#define LPFC_LINK_SPEED_10GHZ 0x40 #define LPFC_LINK_SPEED_10GHZ 0x40
#define LPFC_LINK_SPEED_16GHZ 0x80 #define LPFC_LINK_SPEED_16GHZ 0x80
#define LPFC_LINK_SPEED_32GHZ 0x90
}; };
/* Structure for MB Command CLEAR_LA (22) */ /* Structure for MB Command CLEAR_LA (22) */

View File

@ -699,7 +699,9 @@ lpfc_hba_init_link_fc_topology(struct lpfc_hba *phba, uint32_t fc_topology,
((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_10G) && ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_10G) &&
!(phba->lmt & LMT_10Gb)) || !(phba->lmt & LMT_10Gb)) ||
((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G) && ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G) &&
!(phba->lmt & LMT_16Gb))) { !(phba->lmt & LMT_16Gb)) ||
((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_32G) &&
!(phba->lmt & LMT_32Gb))) {
/* Reset link speed to auto */ /* Reset link speed to auto */
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
"1302 Invalid speed for this board:%d " "1302 Invalid speed for this board:%d "
@ -2035,7 +2037,9 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
&& descp && descp[0] != '\0') && descp && descp[0] != '\0')
return; return;
if (phba->lmt & LMT_16Gb) if (phba->lmt & LMT_32Gb)
max_speed = 32;
else if (phba->lmt & LMT_16Gb)
max_speed = 16; max_speed = 16;
else if (phba->lmt & LMT_10Gb) else if (phba->lmt & LMT_10Gb)
max_speed = 10; max_speed = 10;
@ -2229,6 +2233,9 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
m = (typeof(m)){"OCe15100", "PCIe", m = (typeof(m)){"OCe15100", "PCIe",
"Obsolete, Unsupported FCoE"}; "Obsolete, Unsupported FCoE"};
break; break;
case PCI_DEVICE_ID_LANCER_G6_FC:
m = (typeof(m)){"LPe32000", "PCIe", "Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_SKYHAWK: case PCI_DEVICE_ID_SKYHAWK:
case PCI_DEVICE_ID_SKYHAWK_VF: case PCI_DEVICE_ID_SKYHAWK_VF:
oneConnect = 1; oneConnect = 1;
@ -3491,6 +3498,8 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost)
sizeof fc_host_symbolic_name(shost)); sizeof fc_host_symbolic_name(shost));
fc_host_supported_speeds(shost) = 0; fc_host_supported_speeds(shost) = 0;
if (phba->lmt & LMT_32Gb)
fc_host_supported_speeds(shost) |= FC_PORTSPEED_32GBIT;
if (phba->lmt & LMT_16Gb) if (phba->lmt & LMT_16Gb)
fc_host_supported_speeds(shost) |= FC_PORTSPEED_16GBIT; fc_host_supported_speeds(shost) |= FC_PORTSPEED_16GBIT;
if (phba->lmt & LMT_10Gb) if (phba->lmt & LMT_10Gb)
@ -3854,6 +3863,9 @@ lpfc_sli4_port_speed_parse(struct lpfc_hba *phba, uint32_t evt_code,
case LPFC_FC_LA_SPEED_16G: case LPFC_FC_LA_SPEED_16G:
port_speed = 16000; port_speed = 16000;
break; break;
case LPFC_FC_LA_SPEED_32G:
port_speed = 32000;
break;
default: default:
port_speed = 0; port_speed = 0;
} }
@ -4982,8 +4994,7 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba)
} }
if (!phba->sli.ring) if (!phba->sli.ring)
phba->sli.ring = (struct lpfc_sli_ring *) phba->sli.ring = kzalloc(LPFC_SLI3_MAX_RING *
kzalloc(LPFC_SLI3_MAX_RING *
sizeof(struct lpfc_sli_ring), GFP_KERNEL); sizeof(struct lpfc_sli_ring), GFP_KERNEL);
if (!phba->sli.ring) if (!phba->sli.ring)
return -ENOMEM; return -ENOMEM;
@ -4995,7 +5006,7 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba)
/* Initialize the host templates the configured values. */ /* Initialize the host templates the configured values. */
lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt; lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt;
lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt; lpfc_template_s3.sg_tablesize = phba->cfg_sg_seg_cnt;
/* There are going to be 2 reserved BDEs: 1 FCP cmnd + 1 FCP rsp */ /* There are going to be 2 reserved BDEs: 1 FCP cmnd + 1 FCP rsp */
if (phba->cfg_enable_bg) { if (phba->cfg_enable_bg) {
@ -8679,7 +8690,6 @@ lpfc_sli4_set_affinity(struct lpfc_hba *phba, int vectors)
#ifdef CONFIG_X86 #ifdef CONFIG_X86
struct cpuinfo_x86 *cpuinfo; struct cpuinfo_x86 *cpuinfo;
#endif #endif
struct cpumask *mask;
uint8_t chann[LPFC_FCP_IO_CHAN_MAX+1]; uint8_t chann[LPFC_FCP_IO_CHAN_MAX+1];
/* If there is no mapping, just return */ /* If there is no mapping, just return */
@ -8773,11 +8783,8 @@ found:
first_cpu = cpu; first_cpu = cpu;
/* Now affinitize to the selected CPU */ /* Now affinitize to the selected CPU */
mask = &cpup->maskbits;
cpumask_clear(mask);
cpumask_set_cpu(cpu, mask);
i = irq_set_affinity_hint(phba->sli4_hba.msix_entries[idx]. i = irq_set_affinity_hint(phba->sli4_hba.msix_entries[idx].
vector, mask); vector, get_cpu_mask(cpu));
lpfc_printf_log(phba, KERN_INFO, LOG_INIT, lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"3330 Set Affinity: CPU %d channel %d " "3330 Set Affinity: CPU %d channel %d "
@ -10287,7 +10294,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
struct lpfc_hba *phba; struct lpfc_hba *phba;
struct lpfc_vport *vport = NULL; struct lpfc_vport *vport = NULL;
struct Scsi_Host *shost = NULL; struct Scsi_Host *shost = NULL;
int error, ret; int error;
uint32_t cfg_mode, intr_mode; uint32_t cfg_mode, intr_mode;
int adjusted_fcp_io_channel; int adjusted_fcp_io_channel;
@ -10411,7 +10418,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
/* check for firmware upgrade or downgrade */ /* check for firmware upgrade or downgrade */
if (phba->cfg_request_firmware_upgrade) if (phba->cfg_request_firmware_upgrade)
ret = lpfc_sli4_request_firmware_update(phba, INT_FW_UPGRADE); lpfc_sli4_request_firmware_update(phba, INT_FW_UPGRADE);
/* Check if there are static vports to be created. */ /* Check if there are static vports to be created. */
lpfc_create_static_vport(phba); lpfc_create_static_vport(phba);
@ -11354,6 +11361,8 @@ static struct pci_device_id lpfc_id_table[] = {
PCI_ANY_ID, PCI_ANY_ID, }, PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_FCOE_VF, {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_FCOE_VF,
PCI_ANY_ID, PCI_ANY_ID, }, PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G6_FC,
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK, {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK,
PCI_ANY_ID, PCI_ANY_ID, }, PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK_VF, {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK_VF,
@ -11477,6 +11486,7 @@ lpfc_exit(void)
free_pages((unsigned long)_dump_buf_dif, _dump_buf_dif_order); free_pages((unsigned long)_dump_buf_dif, _dump_buf_dif_order);
} }
kfree(lpfc_used_cpu); kfree(lpfc_used_cpu);
idr_destroy(&lpfc_hba_index);
} }
module_init(lpfc_init); module_init(lpfc_init);

View File

@ -289,9 +289,7 @@ lpfc_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb,
struct lpfc_dmabuf *mp) struct lpfc_dmabuf *mp)
{ {
MAILBOX_t *mb; MAILBOX_t *mb;
struct lpfc_sli *psli;
psli = &phba->sli;
mb = &pmb->u.mb; mb = &pmb->u.mb;
memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
@ -483,13 +481,11 @@ lpfc_init_link(struct lpfc_hba * phba,
LPFC_MBOXQ_t * pmb, uint32_t topology, uint32_t linkspeed) LPFC_MBOXQ_t * pmb, uint32_t topology, uint32_t linkspeed)
{ {
lpfc_vpd_t *vpd; lpfc_vpd_t *vpd;
struct lpfc_sli *psli;
MAILBOX_t *mb; MAILBOX_t *mb;
mb = &pmb->u.mb; mb = &pmb->u.mb;
memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
psli = &phba->sli;
switch (topology) { switch (topology) {
case FLAGS_TOPOLOGY_MODE_LOOP_PT: case FLAGS_TOPOLOGY_MODE_LOOP_PT:
mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP; mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
@ -510,6 +506,13 @@ lpfc_init_link(struct lpfc_hba * phba,
break; break;
} }
if (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC &&
mb->un.varInitLnk.link_flags & FLAGS_TOPOLOGY_MODE_LOOP) {
/* Failover is not tried for Lancer G6 */
mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
phba->cfg_topology = FLAGS_TOPOLOGY_MODE_PT_PT;
}
/* Enable asynchronous ABTS responses from firmware */ /* Enable asynchronous ABTS responses from firmware */
mb->un.varInitLnk.link_flags |= FLAGS_IMED_ABORT; mb->un.varInitLnk.link_flags |= FLAGS_IMED_ABORT;
@ -543,6 +546,10 @@ lpfc_init_link(struct lpfc_hba * phba,
mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED; mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
mb->un.varInitLnk.link_speed = LINK_SPEED_16G; mb->un.varInitLnk.link_speed = LINK_SPEED_16G;
break; break;
case LPFC_USER_LINK_SPEED_32G:
mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
mb->un.varInitLnk.link_speed = LINK_SPEED_32G;
break;
case LPFC_USER_LINK_SPEED_AUTO: case LPFC_USER_LINK_SPEED_AUTO:
default: default:
mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO; mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO;
@ -585,9 +592,7 @@ lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi)
{ {
struct lpfc_dmabuf *mp; struct lpfc_dmabuf *mp;
MAILBOX_t *mb; MAILBOX_t *mb;
struct lpfc_sli *psli;
psli = &phba->sli;
mb = &pmb->u.mb; mb = &pmb->u.mb;
memset(pmb, 0, sizeof (LPFC_MBOXQ_t)); memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
@ -2010,7 +2015,6 @@ lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *phba,
uint16_t fcf_index) uint16_t fcf_index)
{ {
void *virt_addr; void *virt_addr;
dma_addr_t phys_addr;
uint8_t *bytep; uint8_t *bytep;
struct lpfc_mbx_sge sge; struct lpfc_mbx_sge sge;
uint32_t alloc_len, req_len; uint32_t alloc_len, req_len;
@ -2039,7 +2043,6 @@ lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *phba,
* routine only uses a single SGE. * routine only uses a single SGE.
*/ */
lpfc_sli4_mbx_sge_get(mboxq, 0, &sge); lpfc_sli4_mbx_sge_get(mboxq, 0, &sge);
phys_addr = getPaddr(sge.pa_hi, sge.pa_lo);
virt_addr = mboxq->sge_array->addr[0]; virt_addr = mboxq->sge_array->addr[0];
read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr;

View File

@ -820,7 +820,6 @@ lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
{ {
struct lpfc_hba *phba; struct lpfc_hba *phba;
LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg; LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
MAILBOX_t *mb;
uint16_t rpi; uint16_t rpi;
phba = vport->phba; phba = vport->phba;
@ -828,7 +827,6 @@ lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
if (!(phba->pport->load_flag & FC_UNLOADING) && if (!(phba->pport->load_flag & FC_UNLOADING) &&
(evt == NLP_EVT_CMPL_REG_LOGIN) && (evt == NLP_EVT_CMPL_REG_LOGIN) &&
(!pmb->u.mb.mbxStatus)) { (!pmb->u.mb.mbxStatus)) {
mb = &pmb->u.mb;
rpi = pmb->u.mb.un.varWords[0]; rpi = pmb->u.mb.un.varWords[0];
lpfc_release_rpi(phba, vport, rpi); lpfc_release_rpi(phba, vport, rpi);
} }

View File

@ -1293,7 +1293,6 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,
uint32_t *reftag, uint16_t *apptag, uint32_t new_guard) uint32_t *reftag, uint16_t *apptag, uint32_t new_guard)
{ {
struct scatterlist *sgpe; /* s/g prot entry */ struct scatterlist *sgpe; /* s/g prot entry */
struct scatterlist *sgde; /* s/g data entry */
struct lpfc_scsi_buf *lpfc_cmd = NULL; struct lpfc_scsi_buf *lpfc_cmd = NULL;
struct scsi_dif_tuple *src = NULL; struct scsi_dif_tuple *src = NULL;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
@ -1309,7 +1308,6 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,
return 0; return 0;
sgpe = scsi_prot_sglist(sc); sgpe = scsi_prot_sglist(sc);
sgde = scsi_sglist(sc);
lba = scsi_get_lba(sc); lba = scsi_get_lba(sc);
/* First check if we need to match the LBA */ /* First check if we need to match the LBA */
@ -1882,7 +1880,6 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
#endif #endif
uint32_t checking = 1; uint32_t checking = 1;
uint32_t reftag; uint32_t reftag;
unsigned blksize;
uint8_t txop, rxop; uint8_t txop, rxop;
status = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop); status = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop);
@ -1890,7 +1887,6 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
goto out; goto out;
/* extract some info from the scsi command for pde*/ /* extract some info from the scsi command for pde*/
blksize = lpfc_cmd_blksize(sc);
reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */ reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
@ -2263,7 +2259,6 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
dma_addr_t physaddr; dma_addr_t physaddr;
int i = 0, num_sge = 0, status; int i = 0, num_sge = 0, status;
uint32_t reftag; uint32_t reftag;
unsigned blksize;
uint8_t txop, rxop; uint8_t txop, rxop;
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
uint32_t rc; uint32_t rc;
@ -2277,7 +2272,6 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
goto out; goto out;
/* extract some info from the scsi command for pde*/ /* extract some info from the scsi command for pde*/
blksize = lpfc_cmd_blksize(sc);
reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */ reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
@ -2881,7 +2875,7 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
struct scsi_cmnd *cmd = lpfc_cmd->pCmd; struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
struct scsi_dif_tuple *src = NULL; struct scsi_dif_tuple *src = NULL;
uint8_t *data_src = NULL; uint8_t *data_src = NULL;
uint16_t guard_tag, guard_type; uint16_t guard_tag;
uint16_t start_app_tag, app_tag; uint16_t start_app_tag, app_tag;
uint32_t start_ref_tag, ref_tag; uint32_t start_ref_tag, ref_tag;
int prot, protsegcnt; int prot, protsegcnt;
@ -2922,7 +2916,6 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
data_len = sgde->length; data_len = sgde->length;
if ((data_len & (blksize - 1)) == 0) if ((data_len & (blksize - 1)) == 0)
chk_guard = 1; chk_guard = 1;
guard_type = scsi_host_get_guard(cmd->device->host);
src = (struct scsi_dif_tuple *)sg_virt(sgpe); src = (struct scsi_dif_tuple *)sg_virt(sgpe);
start_ref_tag = (uint32_t)scsi_get_lba(cmd); /* Truncate LBA */ start_ref_tag = (uint32_t)scsi_get_lba(cmd); /* Truncate LBA */
@ -3908,12 +3901,10 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
struct lpfc_rport_data *rdata = lpfc_cmd->rdata; struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
struct lpfc_nodelist *pnode = rdata->pnode; struct lpfc_nodelist *pnode = rdata->pnode;
struct scsi_cmnd *cmd; struct scsi_cmnd *cmd;
int result;
int depth; int depth;
unsigned long flags; unsigned long flags;
struct lpfc_fast_path_event *fast_path_evt; struct lpfc_fast_path_event *fast_path_evt;
struct Scsi_Host *shost; struct Scsi_Host *shost;
uint32_t queue_depth, scsi_id;
uint32_t logit = LOG_FCP; uint32_t logit = LOG_FCP;
/* Sanity check on return of outstanding command */ /* Sanity check on return of outstanding command */
@ -4095,7 +4086,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
} }
lpfc_update_stats(phba, lpfc_cmd); lpfc_update_stats(phba, lpfc_cmd);
result = cmd->result;
if (vport->cfg_max_scsicmpl_time && if (vport->cfg_max_scsicmpl_time &&
time_after(jiffies, lpfc_cmd->start_time + time_after(jiffies, lpfc_cmd->start_time +
msecs_to_jiffies(vport->cfg_max_scsicmpl_time))) { msecs_to_jiffies(vport->cfg_max_scsicmpl_time))) {
@ -4132,8 +4122,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
/* The sdev is not guaranteed to be valid post scsi_done upcall. */ /* The sdev is not guaranteed to be valid post scsi_done upcall. */
queue_depth = cmd->device->queue_depth;
scsi_id = cmd->device->id;
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {

View File

@ -6696,7 +6696,7 @@ lpfc_mbox_timeout(unsigned long ptr)
* This function checks if any mailbox completions are present on the mailbox * This function checks if any mailbox completions are present on the mailbox
* completion queue. * completion queue.
**/ **/
bool static bool
lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba) lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba)
{ {
@ -12491,12 +12491,10 @@ lpfc_sli4_fof_intr_handler(int irq, void *dev_id)
struct lpfc_eqe *eqe; struct lpfc_eqe *eqe;
unsigned long iflag; unsigned long iflag;
int ecount = 0; int ecount = 0;
uint32_t eqidx;
/* Get the driver's phba structure from the dev_id */ /* Get the driver's phba structure from the dev_id */
fcp_eq_hdl = (struct lpfc_fcp_eq_hdl *)dev_id; fcp_eq_hdl = (struct lpfc_fcp_eq_hdl *)dev_id;
phba = fcp_eq_hdl->phba; phba = fcp_eq_hdl->phba;
eqidx = fcp_eq_hdl->idx;
if (unlikely(!phba)) if (unlikely(!phba))
return IRQ_NONE; return IRQ_NONE;
@ -12831,12 +12829,8 @@ out_fail:
static void __iomem * static void __iomem *
lpfc_dual_chute_pci_bar_map(struct lpfc_hba *phba, uint16_t pci_barset) lpfc_dual_chute_pci_bar_map(struct lpfc_hba *phba, uint16_t pci_barset)
{ {
struct pci_dev *pdev;
if (!phba->pcidev) if (!phba->pcidev)
return NULL; return NULL;
else
pdev = phba->pcidev;
switch (pci_barset) { switch (pci_barset) {
case WQ_PCI_BAR_0_AND_1: case WQ_PCI_BAR_0_AND_1:
@ -15920,7 +15914,6 @@ lpfc_sli4_add_fcf_record(struct lpfc_hba *phba, struct fcf_record *fcf_record)
LPFC_MBOXQ_t *mboxq; LPFC_MBOXQ_t *mboxq;
uint8_t *bytep; uint8_t *bytep;
void *virt_addr; void *virt_addr;
dma_addr_t phys_addr;
struct lpfc_mbx_sge sge; struct lpfc_mbx_sge sge;
uint32_t alloc_len, req_len; uint32_t alloc_len, req_len;
uint32_t fcfindex; uint32_t fcfindex;
@ -15953,7 +15946,6 @@ lpfc_sli4_add_fcf_record(struct lpfc_hba *phba, struct fcf_record *fcf_record)
* routine only uses a single SGE. * routine only uses a single SGE.
*/ */
lpfc_sli4_mbx_sge_get(mboxq, 0, &sge); lpfc_sli4_mbx_sge_get(mboxq, 0, &sge);
phys_addr = getPaddr(sge.pa_hi, sge.pa_lo);
virt_addr = mboxq->sge_array->addr[0]; virt_addr = mboxq->sge_array->addr[0];
/* /*
* Configure the FCF record for FCFI 0. This is the driver's * Configure the FCF record for FCFI 0. This is the driver's

View File

@ -454,7 +454,6 @@ struct lpfc_vector_map_info {
uint16_t core_id; uint16_t core_id;
uint16_t irq; uint16_t irq;
uint16_t channel_id; uint16_t channel_id;
struct cpumask maskbits;
}; };
#define LPFC_VECTOR_MAP_EMPTY 0xffff #define LPFC_VECTOR_MAP_EMPTY 0xffff

View File

@ -18,7 +18,7 @@
* included with this package. * * included with this package. *
*******************************************************************/ *******************************************************************/
#define LPFC_DRIVER_VERSION "10.7.0.0." #define LPFC_DRIVER_VERSION "11.0.0.0."
#define LPFC_DRIVER_NAME "lpfc" #define LPFC_DRIVER_NAME "lpfc"
/* Used for SLI 2/3 */ /* Used for SLI 2/3 */

View File

@ -389,6 +389,84 @@ int scsi_dev_info_list_add_keyed(int compatible, char *vendor, char *model,
} }
EXPORT_SYMBOL(scsi_dev_info_list_add_keyed); EXPORT_SYMBOL(scsi_dev_info_list_add_keyed);
/**
* scsi_dev_info_list_find - find a matching dev_info list entry.
* @vendor: vendor string
* @model: model (product) string
* @key: specify list to use
*
* Description:
* Finds the first dev_info entry matching @vendor, @model
* in list specified by @key.
*
* Returns: pointer to matching entry, or ERR_PTR on failure.
**/
static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor,
const char *model, int key)
{
struct scsi_dev_info_list *devinfo;
struct scsi_dev_info_list_table *devinfo_table =
scsi_devinfo_lookup_by_key(key);
size_t vmax, mmax;
const char *vskip, *mskip;
if (IS_ERR(devinfo_table))
return (struct scsi_dev_info_list *) devinfo_table;
/* Prepare for "compatible" matches */
/*
* XXX why skip leading spaces? If an odd INQUIRY
* value, that should have been part of the
* scsi_static_device_list[] entry, such as " FOO"
* rather than "FOO". Since this code is already
* here, and we don't know what device it is
* trying to work with, leave it as-is.
*/
vmax = 8; /* max length of vendor */
vskip = vendor;
while (vmax > 0 && *vskip == ' ') {
vmax--;
vskip++;
}
/* Also skip trailing spaces */
while (vmax > 0 && vskip[vmax - 1] == ' ')
--vmax;
mmax = 16; /* max length of model */
mskip = model;
while (mmax > 0 && *mskip == ' ') {
mmax--;
mskip++;
}
while (mmax > 0 && mskip[mmax - 1] == ' ')
--mmax;
list_for_each_entry(devinfo, &devinfo_table->scsi_dev_info_list,
dev_info_list) {
if (devinfo->compatible) {
/*
* Behave like the older version of get_device_flags.
*/
if (memcmp(devinfo->vendor, vskip, vmax) ||
devinfo->vendor[vmax])
continue;
if (memcmp(devinfo->model, mskip, mmax) ||
devinfo->model[mmax])
continue;
return devinfo;
} else {
if (!memcmp(devinfo->vendor, vendor,
sizeof(devinfo->vendor)) &&
!memcmp(devinfo->model, model,
sizeof(devinfo->model)))
return devinfo;
}
}
return ERR_PTR(-ENOENT);
}
/** /**
* scsi_dev_info_list_del_keyed - remove one dev_info list entry. * scsi_dev_info_list_del_keyed - remove one dev_info list entry.
* @vendor: vendor string * @vendor: vendor string
@ -403,75 +481,16 @@ EXPORT_SYMBOL(scsi_dev_info_list_add_keyed);
**/ **/
int scsi_dev_info_list_del_keyed(char *vendor, char *model, int key) int scsi_dev_info_list_del_keyed(char *vendor, char *model, int key)
{ {
struct scsi_dev_info_list *devinfo, *found = NULL; struct scsi_dev_info_list *found;
struct scsi_dev_info_list_table *devinfo_table =
scsi_devinfo_lookup_by_key(key);
if (IS_ERR(devinfo_table)) found = scsi_dev_info_list_find(vendor, model, key);
return PTR_ERR(devinfo_table); if (IS_ERR(found))
return PTR_ERR(found);
list_for_each_entry(devinfo, &devinfo_table->scsi_dev_info_list,
dev_info_list) {
if (devinfo->compatible) {
/*
* Behave like the older version of get_device_flags.
*/
size_t max;
/*
* XXX why skip leading spaces? If an odd INQUIRY
* value, that should have been part of the
* scsi_static_device_list[] entry, such as " FOO"
* rather than "FOO". Since this code is already
* here, and we don't know what device it is
* trying to work with, leave it as-is.
*/
max = 8; /* max length of vendor */
while ((max > 0) && *vendor == ' ') {
max--;
vendor++;
}
/*
* XXX removing the following strlen() would be
* good, using it means that for a an entry not in
* the list, we scan every byte of every vendor
* listed in scsi_static_device_list[], and never match
* a single one (and still have to compare at
* least the first byte of each vendor).
*/
if (memcmp(devinfo->vendor, vendor,
min(max, strlen(devinfo->vendor))))
continue;
/*
* Skip spaces again.
*/
max = 16; /* max length of model */
while ((max > 0) && *model == ' ') {
max--;
model++;
}
if (memcmp(devinfo->model, model,
min(max, strlen(devinfo->model))))
continue;
found = devinfo;
} else {
if (!memcmp(devinfo->vendor, vendor,
sizeof(devinfo->vendor)) &&
!memcmp(devinfo->model, model,
sizeof(devinfo->model)))
found = devinfo;
}
if (found)
break;
}
if (found) {
list_del(&found->dev_info_list); list_del(&found->dev_info_list);
kfree(found); kfree(found);
return 0; return 0;
} }
return -ENOENT;
}
EXPORT_SYMBOL(scsi_dev_info_list_del_keyed); EXPORT_SYMBOL(scsi_dev_info_list_del_keyed);
/** /**
@ -565,64 +584,16 @@ int scsi_get_device_flags_keyed(struct scsi_device *sdev,
int key) int key)
{ {
struct scsi_dev_info_list *devinfo; struct scsi_dev_info_list *devinfo;
struct scsi_dev_info_list_table *devinfo_table; int err;
devinfo_table = scsi_devinfo_lookup_by_key(key); devinfo = scsi_dev_info_list_find(vendor, model, key);
if (!IS_ERR(devinfo))
if (IS_ERR(devinfo_table))
return PTR_ERR(devinfo_table);
list_for_each_entry(devinfo, &devinfo_table->scsi_dev_info_list,
dev_info_list) {
if (devinfo->compatible) {
/*
* Behave like the older version of get_device_flags.
*/
size_t max;
/*
* XXX why skip leading spaces? If an odd INQUIRY
* value, that should have been part of the
* scsi_static_device_list[] entry, such as " FOO"
* rather than "FOO". Since this code is already
* here, and we don't know what device it is
* trying to work with, leave it as-is.
*/
max = 8; /* max length of vendor */
while ((max > 0) && *vendor == ' ') {
max--;
vendor++;
}
/*
* XXX removing the following strlen() would be
* good, using it means that for a an entry not in
* the list, we scan every byte of every vendor
* listed in scsi_static_device_list[], and never match
* a single one (and still have to compare at
* least the first byte of each vendor).
*/
if (memcmp(devinfo->vendor, vendor,
min(max, strlen(devinfo->vendor))))
continue;
/*
* Skip spaces again.
*/
max = 16; /* max length of model */
while ((max > 0) && *model == ' ') {
max--;
model++;
}
if (memcmp(devinfo->model, model,
min(max, strlen(devinfo->model))))
continue;
return devinfo->flags; return devinfo->flags;
} else {
if (!memcmp(devinfo->vendor, vendor, err = PTR_ERR(devinfo);
sizeof(devinfo->vendor)) && if (err != -ENOENT)
!memcmp(devinfo->model, model, return err;
sizeof(devinfo->model)))
return devinfo->flags;
}
}
/* nothing found, return nothing */ /* nothing found, return nothing */
if (key != SCSI_DEVINFO_GLOBAL) if (key != SCSI_DEVINFO_GLOBAL)
return 0; return 0;