提交 d04baa15 编写于 作者: L Linus Torvalds

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

SCSI updates for post 3.2 merge window

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (67 commits)
  [SCSI] lpfc 8.3.28: Update driver version to 8.3.28
  [SCSI] lpfc 8.3.28: Add Loopback support for SLI4 adapters
  [SCSI] lpfc 8.3.28: Critical Miscellaneous fixes
  [SCSI] Lpfc 8.3.28: FC and SCSI Discovery Fixes
  [SCSI] lpfc 8.3.28: Add support for ABTS failure handling
  [SCSI] lpfc 8.3.28: SLI fixes and added SLI4 support
  [SCSI] lpfc 8.3.28: Miscellaneous fixes in sysfs and mgmt interfaces
  [SCSI] mpt2sas: Removed redundant calling of _scsih_probe_devices() from _scsih_probe
  [SCSI] mac_scsi: Remove obsolete IRQ_FLG_* users
  [SCSI] qla4xxx: Update driver version to 5.02.00-k10
  [SCSI] qla4xxx: check for FW alive before calling chip_reset
  [SCSI] qla4xxx: Fix qla4xxx_dump_buffer to dump buffer correctly
  [SCSI] qla4xxx: Fix the IDC locking mechanism
  [SCSI] qla4xxx: Wait for disable_acb before doing set_acb
  [SCSI] qla4xxx: Don't recover adapter if device state is FAILED
  [SCSI] qla4xxx: fix call trace on rmmod with ql4xdontresethba=1
  [SCSI] qla4xxx: Fix CPU lockups when ql4xdontresethba set
  [SCSI] qla4xxx: Perform context resets in case of context failures.
  [SCSI] iscsi class: export pid of process that created
  [SCSI] mpt2sas: Remove unused duplicate diag_buffer_enable param
  ...
...@@ -583,6 +583,7 @@ typedef struct _MSG_CONFIG_REPLY ...@@ -583,6 +583,7 @@ typedef struct _MSG_CONFIG_REPLY
#define MPI_MANUFACTPAGE_DEVID_SAS1066E (0x005A) #define MPI_MANUFACTPAGE_DEVID_SAS1066E (0x005A)
#define MPI_MANUFACTPAGE_DEVID_SAS1068 (0x0054) #define MPI_MANUFACTPAGE_DEVID_SAS1068 (0x0054)
#define MPI_MANUFACTPAGE_DEVID_SAS1068E (0x0058) #define MPI_MANUFACTPAGE_DEVID_SAS1068E (0x0058)
#define MPI_MANUFACTPAGE_DEVID_SAS1068_820XELP (0x0059)
#define MPI_MANUFACTPAGE_DEVID_SAS1078 (0x0062) #define MPI_MANUFACTPAGE_DEVID_SAS1078 (0x0062)
......
...@@ -115,7 +115,8 @@ module_param(mpt_fwfault_debug, int, 0600); ...@@ -115,7 +115,8 @@ module_param(mpt_fwfault_debug, int, 0600);
MODULE_PARM_DESC(mpt_fwfault_debug, MODULE_PARM_DESC(mpt_fwfault_debug,
"Enable detection of Firmware fault and halt Firmware on fault - (default=0)"); "Enable detection of Firmware fault and halt Firmware on fault - (default=0)");
static char MptCallbacksName[MPT_MAX_PROTOCOL_DRIVERS][50]; static char MptCallbacksName[MPT_MAX_PROTOCOL_DRIVERS]
[MPT_MAX_CALLBACKNAME_LEN+1];
#ifdef MFCNT #ifdef MFCNT
static int mfcounter = 0; static int mfcounter = 0;
...@@ -717,8 +718,8 @@ mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass, char *func_name) ...@@ -717,8 +718,8 @@ mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass, char *func_name)
MptDriverClass[cb_idx] = dclass; MptDriverClass[cb_idx] = dclass;
MptEvHandlers[cb_idx] = NULL; MptEvHandlers[cb_idx] = NULL;
last_drv_idx = cb_idx; last_drv_idx = cb_idx;
memcpy(MptCallbacksName[cb_idx], func_name, strlcpy(MptCallbacksName[cb_idx], func_name,
strlen(func_name) > 50 ? 50 : strlen(func_name)); MPT_MAX_CALLBACKNAME_LEN+1);
break; break;
} }
} }
......
...@@ -89,6 +89,7 @@ ...@@ -89,6 +89,7 @@
*/ */
#define MPT_MAX_ADAPTERS 18 #define MPT_MAX_ADAPTERS 18
#define MPT_MAX_PROTOCOL_DRIVERS 16 #define MPT_MAX_PROTOCOL_DRIVERS 16
#define MPT_MAX_CALLBACKNAME_LEN 49
#define MPT_MAX_BUS 1 /* Do not change */ #define MPT_MAX_BUS 1 /* Do not change */
#define MPT_MAX_FC_DEVICES 255 #define MPT_MAX_FC_DEVICES 255
#define MPT_MAX_SCSI_DEVICES 16 #define MPT_MAX_SCSI_DEVICES 16
......
...@@ -5376,6 +5376,8 @@ static struct pci_device_id mptsas_pci_table[] = { ...@@ -5376,6 +5376,8 @@ static struct pci_device_id mptsas_pci_table[] = {
PCI_ANY_ID, PCI_ANY_ID }, PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078, { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
PCI_ANY_ID, PCI_ANY_ID }, PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068_820XELP,
PCI_ANY_ID, PCI_ANY_ID },
{0} /* Terminating entry */ {0} /* Terminating entry */
}; };
MODULE_DEVICE_TABLE(pci, mptsas_pci_table); MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
......
...@@ -1105,7 +1105,6 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn, ...@@ -1105,7 +1105,6 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,
struct be_status_bhs *sts_bhs = struct be_status_bhs *sts_bhs =
(struct be_status_bhs *)io_task->cmd_bhs; (struct be_status_bhs *)io_task->cmd_bhs;
struct iscsi_conn *conn = beiscsi_conn->conn; struct iscsi_conn *conn = beiscsi_conn->conn;
unsigned int sense_len;
unsigned char *sense; unsigned char *sense;
u32 resid = 0, exp_cmdsn, max_cmdsn; u32 resid = 0, exp_cmdsn, max_cmdsn;
u8 rsp, status, flags; u8 rsp, status, flags;
...@@ -1153,9 +1152,11 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn, ...@@ -1153,9 +1152,11 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,
} }
if (status == SAM_STAT_CHECK_CONDITION) { if (status == SAM_STAT_CHECK_CONDITION) {
u16 sense_len;
unsigned short *slen = (unsigned short *)sts_bhs->sense_info; unsigned short *slen = (unsigned short *)sts_bhs->sense_info;
sense = sts_bhs->sense_info + sizeof(unsigned short); sense = sts_bhs->sense_info + sizeof(unsigned short);
sense_len = cpu_to_be16(*slen); sense_len = be16_to_cpu(*slen);
memcpy(task->sc->sense_buffer, sense, memcpy(task->sc->sense_buffer, sense,
min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE)); min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE));
} }
......
...@@ -902,7 +902,7 @@ struct sfp_mem_s { ...@@ -902,7 +902,7 @@ struct sfp_mem_s {
union sfp_xcvr_e10g_code_u { union sfp_xcvr_e10g_code_u {
u8 b; u8 b;
struct { struct {
#ifdef __BIGENDIAN #ifdef __BIG_ENDIAN
u8 e10g_unall:1; /* 10G Ethernet compliance */ u8 e10g_unall:1; /* 10G Ethernet compliance */
u8 e10g_lrm:1; u8 e10g_lrm:1;
u8 e10g_lr:1; u8 e10g_lr:1;
...@@ -982,7 +982,7 @@ union sfp_xcvr_fc2_code_u { ...@@ -982,7 +982,7 @@ union sfp_xcvr_fc2_code_u {
union sfp_xcvr_fc3_code_u { union sfp_xcvr_fc3_code_u {
u8 b; u8 b;
struct { struct {
#ifdef __BIGENDIAN #ifdef __BIG_ENDIAN
u8 rsv4:1; u8 rsv4:1;
u8 mb800:1; /* 800 Mbytes/sec */ u8 mb800:1; /* 800 Mbytes/sec */
u8 mb1600:1; /* 1600 Mbytes/sec */ u8 mb1600:1; /* 1600 Mbytes/sec */
......
此差异已折叠。
...@@ -3727,11 +3727,11 @@ bfa_sfp_media_get(struct bfa_sfp_s *sfp) ...@@ -3727,11 +3727,11 @@ bfa_sfp_media_get(struct bfa_sfp_s *sfp)
(xmtr_tech & SFP_XMTR_TECH_SA)) (xmtr_tech & SFP_XMTR_TECH_SA))
*media = BFA_SFP_MEDIA_SW; *media = BFA_SFP_MEDIA_SW;
/* Check 10G Ethernet Compilance code */ /* Check 10G Ethernet Compilance code */
else if (e10g.b & 0x10) else if (e10g.r.e10g_sr)
*media = BFA_SFP_MEDIA_SW; *media = BFA_SFP_MEDIA_SW;
else if (e10g.b & 0x60) else if (e10g.r.e10g_lrm && e10g.r.e10g_lr)
*media = BFA_SFP_MEDIA_LW; *media = BFA_SFP_MEDIA_LW;
else if (e10g.r.e10g_unall & 0x80) else if (e10g.r.e10g_unall)
*media = BFA_SFP_MEDIA_UNKNOWN; *media = BFA_SFP_MEDIA_UNKNOWN;
else else
bfa_trc(sfp, 0); bfa_trc(sfp, 0);
......
...@@ -557,8 +557,7 @@ bfad_debugfs_exit(struct bfad_port_s *port) ...@@ -557,8 +557,7 @@ bfad_debugfs_exit(struct bfad_port_s *port)
} }
} }
/* /* Remove the pci_dev debugfs directory for the port */
* Remove the pci_dev debugfs directory for the port */
if (port->port_debugfs_root) { if (port->port_debugfs_root) {
debugfs_remove(port->port_debugfs_root); debugfs_remove(port->port_debugfs_root);
port->port_debugfs_root = NULL; port->port_debugfs_root = NULL;
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
static DEFINE_SPINLOCK(list_lock); static DEFINE_SPINLOCK(list_lock);
static LIST_HEAD(scsi_dh_list); static LIST_HEAD(scsi_dh_list);
static int scsi_dh_list_idx = 1;
static struct scsi_device_handler *get_device_handler(const char *name) static struct scsi_device_handler *get_device_handler(const char *name)
{ {
...@@ -45,21 +44,6 @@ static struct scsi_device_handler *get_device_handler(const char *name) ...@@ -45,21 +44,6 @@ static struct scsi_device_handler *get_device_handler(const char *name)
return found; return found;
} }
static struct scsi_device_handler *get_device_handler_by_idx(int idx)
{
struct scsi_device_handler *tmp, *found = NULL;
spin_lock(&list_lock);
list_for_each_entry(tmp, &scsi_dh_list, list) {
if (tmp->idx == idx) {
found = tmp;
break;
}
}
spin_unlock(&list_lock);
return found;
}
/* /*
* device_handler_match_function - Match a device handler to a device * device_handler_match_function - Match a device handler to a device
* @sdev - SCSI device to be tested * @sdev - SCSI device to be tested
...@@ -83,23 +67,6 @@ device_handler_match_function(struct scsi_device *sdev) ...@@ -83,23 +67,6 @@ device_handler_match_function(struct scsi_device *sdev)
return found_dh; return found_dh;
} }
/*
* device_handler_match_devlist - Match a device handler to a device
* @sdev - SCSI device to be tested
*
* Tests @sdev against all device_handler registered in the devlist.
* Returns the found device handler or NULL if not found.
*/
static struct scsi_device_handler *
device_handler_match_devlist(struct scsi_device *sdev)
{
int idx;
idx = scsi_get_device_flags_keyed(sdev, sdev->vendor, sdev->model,
SCSI_DEVINFO_DH);
return get_device_handler_by_idx(idx);
}
/* /*
* device_handler_match - Attach a device handler to a device * device_handler_match - Attach a device handler to a device
* @scsi_dh - The device handler to match against or NULL * @scsi_dh - The device handler to match against or NULL
...@@ -116,8 +83,6 @@ device_handler_match(struct scsi_device_handler *scsi_dh, ...@@ -116,8 +83,6 @@ device_handler_match(struct scsi_device_handler *scsi_dh,
struct scsi_device_handler *found_dh; struct scsi_device_handler *found_dh;
found_dh = device_handler_match_function(sdev); found_dh = device_handler_match_function(sdev);
if (!found_dh)
found_dh = device_handler_match_devlist(sdev);
if (scsi_dh && found_dh != scsi_dh) if (scsi_dh && found_dh != scsi_dh)
found_dh = NULL; found_dh = NULL;
...@@ -361,25 +326,14 @@ static int scsi_dh_notifier_remove(struct device *dev, void *data) ...@@ -361,25 +326,14 @@ static int scsi_dh_notifier_remove(struct device *dev, void *data)
*/ */
int scsi_register_device_handler(struct scsi_device_handler *scsi_dh) int scsi_register_device_handler(struct scsi_device_handler *scsi_dh)
{ {
int i;
if (get_device_handler(scsi_dh->name)) if (get_device_handler(scsi_dh->name))
return -EBUSY; return -EBUSY;
spin_lock(&list_lock); spin_lock(&list_lock);
scsi_dh->idx = scsi_dh_list_idx++;
list_add(&scsi_dh->list, &scsi_dh_list); list_add(&scsi_dh->list, &scsi_dh_list);
spin_unlock(&list_lock); spin_unlock(&list_lock);
for (i = 0; scsi_dh->devlist && scsi_dh->devlist[i].vendor; i++) {
scsi_dev_info_list_add_keyed(0,
scsi_dh->devlist[i].vendor,
scsi_dh->devlist[i].model,
NULL,
scsi_dh->idx,
SCSI_DEVINFO_DH);
}
bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, scsi_dh_notifier_add); bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, scsi_dh_notifier_add);
printk(KERN_INFO "%s: device handler registered\n", scsi_dh->name); printk(KERN_INFO "%s: device handler registered\n", scsi_dh->name);
...@@ -396,7 +350,6 @@ EXPORT_SYMBOL_GPL(scsi_register_device_handler); ...@@ -396,7 +350,6 @@ EXPORT_SYMBOL_GPL(scsi_register_device_handler);
*/ */
int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh) int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh)
{ {
int i;
if (!get_device_handler(scsi_dh->name)) if (!get_device_handler(scsi_dh->name))
return -ENODEV; return -ENODEV;
...@@ -404,12 +357,6 @@ int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh) ...@@ -404,12 +357,6 @@ int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh)
bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh,
scsi_dh_notifier_remove); scsi_dh_notifier_remove);
for (i = 0; scsi_dh->devlist && scsi_dh->devlist[i].vendor; i++) {
scsi_dev_info_list_del_keyed(scsi_dh->devlist[i].vendor,
scsi_dh->devlist[i].model,
SCSI_DEVINFO_DH);
}
spin_lock(&list_lock); spin_lock(&list_lock);
list_del(&scsi_dh->list); list_del(&scsi_dh->list);
spin_unlock(&list_lock); spin_unlock(&list_lock);
...@@ -588,10 +535,6 @@ static int __init scsi_dh_init(void) ...@@ -588,10 +535,6 @@ static int __init scsi_dh_init(void)
{ {
int r; int r;
r = scsi_dev_info_add_list(SCSI_DEVINFO_DH, "SCSI Device Handler");
if (r)
return r;
r = bus_register_notifier(&scsi_bus_type, &scsi_dh_nb); r = bus_register_notifier(&scsi_bus_type, &scsi_dh_nb);
if (!r) if (!r)
...@@ -606,7 +549,6 @@ static void __exit scsi_dh_exit(void) ...@@ -606,7 +549,6 @@ static void __exit scsi_dh_exit(void)
bus_for_each_dev(&scsi_bus_type, NULL, NULL, bus_for_each_dev(&scsi_bus_type, NULL, NULL,
scsi_dh_sysfs_attr_remove); scsi_dh_sysfs_attr_remove);
bus_unregister_notifier(&scsi_bus_type, &scsi_dh_nb); bus_unregister_notifier(&scsi_bus_type, &scsi_dh_nb);
scsi_dev_info_remove_list(SCSI_DEVINFO_DH);
} }
module_init(scsi_dh_init); module_init(scsi_dh_init);
......
...@@ -629,6 +629,24 @@ static const struct scsi_dh_devlist clariion_dev_list[] = { ...@@ -629,6 +629,24 @@ static const struct scsi_dh_devlist clariion_dev_list[] = {
{NULL, NULL}, {NULL, NULL},
}; };
static bool clariion_match(struct scsi_device *sdev)
{
int i;
if (scsi_device_tpgs(sdev))
return false;
for (i = 0; clariion_dev_list[i].vendor; i++) {
if (!strncmp(sdev->vendor, clariion_dev_list[i].vendor,
strlen(clariion_dev_list[i].vendor)) &&
!strncmp(sdev->model, clariion_dev_list[i].model,
strlen(clariion_dev_list[i].model))) {
return true;
}
}
return false;
}
static int clariion_bus_attach(struct scsi_device *sdev); static int clariion_bus_attach(struct scsi_device *sdev);
static void clariion_bus_detach(struct scsi_device *sdev); static void clariion_bus_detach(struct scsi_device *sdev);
...@@ -642,6 +660,7 @@ static struct scsi_device_handler clariion_dh = { ...@@ -642,6 +660,7 @@ static struct scsi_device_handler clariion_dh = {
.activate = clariion_activate, .activate = clariion_activate,
.prep_fn = clariion_prep_fn, .prep_fn = clariion_prep_fn,
.set_params = clariion_set_params, .set_params = clariion_set_params,
.match = clariion_match,
}; };
static int clariion_bus_attach(struct scsi_device *sdev) static int clariion_bus_attach(struct scsi_device *sdev)
......
...@@ -320,6 +320,24 @@ static const struct scsi_dh_devlist hp_sw_dh_data_list[] = { ...@@ -320,6 +320,24 @@ static const struct scsi_dh_devlist hp_sw_dh_data_list[] = {
{NULL, NULL}, {NULL, NULL},
}; };
static bool hp_sw_match(struct scsi_device *sdev)
{
int i;
if (scsi_device_tpgs(sdev))
return false;
for (i = 0; hp_sw_dh_data_list[i].vendor; i++) {
if (!strncmp(sdev->vendor, hp_sw_dh_data_list[i].vendor,
strlen(hp_sw_dh_data_list[i].vendor)) &&
!strncmp(sdev->model, hp_sw_dh_data_list[i].model,
strlen(hp_sw_dh_data_list[i].model))) {
return true;
}
}
return false;
}
static int hp_sw_bus_attach(struct scsi_device *sdev); static int hp_sw_bus_attach(struct scsi_device *sdev);
static void hp_sw_bus_detach(struct scsi_device *sdev); static void hp_sw_bus_detach(struct scsi_device *sdev);
...@@ -331,6 +349,7 @@ static struct scsi_device_handler hp_sw_dh = { ...@@ -331,6 +349,7 @@ static struct scsi_device_handler hp_sw_dh = {
.detach = hp_sw_bus_detach, .detach = hp_sw_bus_detach,
.activate = hp_sw_activate, .activate = hp_sw_activate,
.prep_fn = hp_sw_prep_fn, .prep_fn = hp_sw_prep_fn,
.match = hp_sw_match,
}; };
static int hp_sw_bus_attach(struct scsi_device *sdev) static int hp_sw_bus_attach(struct scsi_device *sdev)
......
...@@ -820,6 +820,24 @@ static const struct scsi_dh_devlist rdac_dev_list[] = { ...@@ -820,6 +820,24 @@ static const struct scsi_dh_devlist rdac_dev_list[] = {
{NULL, NULL}, {NULL, NULL},
}; };
static bool rdac_match(struct scsi_device *sdev)
{
int i;
if (scsi_device_tpgs(sdev))
return false;
for (i = 0; rdac_dev_list[i].vendor; i++) {
if (!strncmp(sdev->vendor, rdac_dev_list[i].vendor,
strlen(rdac_dev_list[i].vendor)) &&
!strncmp(sdev->model, rdac_dev_list[i].model,
strlen(rdac_dev_list[i].model))) {
return true;
}
}
return false;
}
static int rdac_bus_attach(struct scsi_device *sdev); static int rdac_bus_attach(struct scsi_device *sdev);
static void rdac_bus_detach(struct scsi_device *sdev); static void rdac_bus_detach(struct scsi_device *sdev);
...@@ -832,6 +850,7 @@ static struct scsi_device_handler rdac_dh = { ...@@ -832,6 +850,7 @@ static struct scsi_device_handler rdac_dh = {
.attach = rdac_bus_attach, .attach = rdac_bus_attach,
.detach = rdac_bus_detach, .detach = rdac_bus_detach,
.activate = rdac_activate, .activate = rdac_activate,
.match = rdac_match,
}; };
static int rdac_bus_attach(struct scsi_device *sdev) static int rdac_bus_attach(struct scsi_device *sdev)
......
...@@ -293,12 +293,14 @@ static u32 unresettable_controller[] = { ...@@ -293,12 +293,14 @@ static u32 unresettable_controller[] = {
0x3215103C, /* Smart Array E200i */ 0x3215103C, /* Smart Array E200i */
0x3237103C, /* Smart Array E500 */ 0x3237103C, /* Smart Array E500 */
0x323D103C, /* Smart Array P700m */ 0x323D103C, /* Smart Array P700m */
0x40800E11, /* Smart Array 5i */
0x409C0E11, /* Smart Array 6400 */ 0x409C0E11, /* Smart Array 6400 */
0x409D0E11, /* Smart Array 6400 EM */ 0x409D0E11, /* Smart Array 6400 EM */
}; };
/* List of controllers which cannot even be soft reset */ /* List of controllers which cannot even be soft reset */
static u32 soft_unresettable_controller[] = { static u32 soft_unresettable_controller[] = {
0x40800E11, /* Smart Array 5i */
/* Exclude 640x boards. These are two pci devices in one slot /* Exclude 640x boards. These are two pci devices in one slot
* which share a battery backed cache module. One controls the * which share a battery backed cache module. One controls the
* cache, the other accesses the cache through the one that controls * cache, the other accesses the cache through the one that controls
...@@ -4072,10 +4074,10 @@ static int hpsa_request_irq(struct ctlr_info *h, ...@@ -4072,10 +4074,10 @@ static int hpsa_request_irq(struct ctlr_info *h,
if (h->msix_vector || h->msi_vector) if (h->msix_vector || h->msi_vector)
rc = request_irq(h->intr[h->intr_mode], msixhandler, rc = request_irq(h->intr[h->intr_mode], msixhandler,
IRQF_DISABLED, h->devname, h); 0, h->devname, h);
else else
rc = request_irq(h->intr[h->intr_mode], intxhandler, rc = request_irq(h->intr[h->intr_mode], intxhandler,
IRQF_DISABLED, h->devname, h); IRQF_SHARED, h->devname, h);
if (rc) { if (rc) {
dev_err(&h->pdev->dev, "unable to get irq %d for %s\n", dev_err(&h->pdev->dev, "unable to get irq %d for %s\n",
h->intr[h->intr_mode], h->devname); h->intr[h->intr_mode], h->devname);
......
...@@ -247,18 +247,6 @@ struct lpfc_stats { ...@@ -247,18 +247,6 @@ struct lpfc_stats {
uint32_t fcpLocalErr; uint32_t fcpLocalErr;
}; };
enum sysfs_mbox_state {
SMBOX_IDLE,
SMBOX_WRITING,
SMBOX_READING
};
struct lpfc_sysfs_mbox {
enum sysfs_mbox_state state;
size_t offset;
struct lpfcMboxq * mbox;
};
struct lpfc_hba; struct lpfc_hba;
...@@ -783,8 +771,6 @@ struct lpfc_hba { ...@@ -783,8 +771,6 @@ struct lpfc_hba {
uint64_t bg_apptag_err_cnt; uint64_t bg_apptag_err_cnt;
uint64_t bg_reftag_err_cnt; uint64_t bg_reftag_err_cnt;
struct lpfc_sysfs_mbox sysfs_mbox;
/* fastpath list. */ /* fastpath list. */
spinlock_t scsi_buf_list_lock; spinlock_t scsi_buf_list_lock;
struct list_head lpfc_scsi_buf_list; struct list_head lpfc_scsi_buf_list;
......
...@@ -351,10 +351,23 @@ lpfc_fwrev_show(struct device *dev, struct device_attribute *attr, ...@@ -351,10 +351,23 @@ lpfc_fwrev_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;
uint32_t if_type;
uint8_t sli_family;
char fwrev[32]; char fwrev[32];
int len;
lpfc_decode_firmware_rev(phba, fwrev, 1); lpfc_decode_firmware_rev(phba, fwrev, 1);
return snprintf(buf, PAGE_SIZE, "%s, sli-%d\n", fwrev, phba->sli_rev); if_type = phba->sli4_hba.pc_sli4_params.if_type;
sli_family = phba->sli4_hba.pc_sli4_params.sli_family;
if (phba->sli_rev < LPFC_SLI_REV4)
len = snprintf(buf, PAGE_SIZE, "%s, sli-%d\n",
fwrev, phba->sli_rev);
else
len = snprintf(buf, PAGE_SIZE, "%s, sli-%d:%d:%x\n",
fwrev, phba->sli_rev, if_type, sli_family);
return len;
} }
/** /**
...@@ -487,6 +500,34 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr, ...@@ -487,6 +500,34 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr,
return len; return len;
} }
/**
* lpfc_sli4_protocol_show - Return the fip mode of the HBA
* @dev: class unused variable.
* @attr: device attribute, not used.
* @buf: on return contains the module description text.
*
* Returns: size of formatted string.
**/
static ssize_t
lpfc_sli4_protocol_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct Scsi_Host *shost = class_to_shost(dev);
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
struct lpfc_hba *phba = vport->phba;
if (phba->sli_rev < LPFC_SLI_REV4)
return snprintf(buf, PAGE_SIZE, "fc\n");
if (phba->sli4_hba.lnk_info.lnk_dv == LPFC_LNK_DAT_VAL) {
if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_GE)
return snprintf(buf, PAGE_SIZE, "fcoe\n");
if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC)
return snprintf(buf, PAGE_SIZE, "fc\n");
}
return snprintf(buf, PAGE_SIZE, "unknown\n");
}
/** /**
* lpfc_link_state_store - Transition the link_state on an HBA port * lpfc_link_state_store - Transition the link_state on an HBA port
* @dev: class device that is converted into a Scsi_host. * @dev: class device that is converted into a Scsi_host.
...@@ -773,7 +814,12 @@ lpfc_issue_reset(struct device *dev, struct device_attribute *attr, ...@@ -773,7 +814,12 @@ lpfc_issue_reset(struct device *dev, struct device_attribute *attr,
* the readyness after performing a firmware reset. * the readyness after performing a firmware reset.
* *
* Returns: * Returns:
* zero for success * zero for success, -EPERM when port does not have privilage to perform the
* reset, -EIO when port timeout from recovering from the reset.
*
* Note:
* As the caller will interpret the return code by value, be careful in making
* change or addition to return codes.
**/ **/
int int
lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba) lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba)
...@@ -826,9 +872,11 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) ...@@ -826,9 +872,11 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode)
{ {
struct completion online_compl; struct completion online_compl;
struct pci_dev *pdev = phba->pcidev; struct pci_dev *pdev = phba->pcidev;
uint32_t before_fc_flag;
uint32_t sriov_nr_virtfn;
uint32_t reg_val; uint32_t reg_val;
int status = 0; int status = 0, rc = 0;
int rc; int job_posted = 1, sriov_err;
if (!phba->cfg_enable_hba_reset) if (!phba->cfg_enable_hba_reset)
return -EACCES; return -EACCES;
...@@ -838,6 +886,10 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) ...@@ -838,6 +886,10 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode)
LPFC_SLI_INTF_IF_TYPE_2)) LPFC_SLI_INTF_IF_TYPE_2))
return -EPERM; return -EPERM;
/* Keep state if we need to restore back */
before_fc_flag = phba->pport->fc_flag;
sriov_nr_virtfn = phba->cfg_sriov_nr_virtfn;
/* Disable SR-IOV virtual functions if enabled */ /* Disable SR-IOV virtual functions if enabled */
if (phba->cfg_sriov_nr_virtfn) { if (phba->cfg_sriov_nr_virtfn) {
pci_disable_sriov(pdev); pci_disable_sriov(pdev);
...@@ -869,21 +921,44 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) ...@@ -869,21 +921,44 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode)
/* delay driver action following IF_TYPE_2 reset */ /* delay driver action following IF_TYPE_2 reset */
rc = lpfc_sli4_pdev_status_reg_wait(phba); rc = lpfc_sli4_pdev_status_reg_wait(phba);
if (rc) if (rc == -EPERM) {
/* no privilage for reset, restore if needed */
if (before_fc_flag & FC_OFFLINE_MODE)
goto out;
} else if (rc == -EIO) {
/* reset failed, there is nothing more we can do */
return rc; return rc;
}
/* keep the original port state */
if (before_fc_flag & FC_OFFLINE_MODE)
goto out;
init_completion(&online_compl); init_completion(&online_compl);
rc = lpfc_workq_post_event(phba, &status, &online_compl, job_posted = lpfc_workq_post_event(phba, &status, &online_compl,
LPFC_EVT_ONLINE); LPFC_EVT_ONLINE);
if (rc == 0) if (!job_posted)
return -ENOMEM; goto out;
wait_for_completion(&online_compl); wait_for_completion(&online_compl);
if (status != 0) out:
return -EIO; /* in any case, restore the virtual functions enabled as before */
if (sriov_nr_virtfn) {
sriov_err =
lpfc_sli_probe_sriov_nr_virtfn(phba, sriov_nr_virtfn);
if (!sriov_err)
phba->cfg_sriov_nr_virtfn = sriov_nr_virtfn;
}
return 0; /* return proper error code */
if (!rc) {
if (!job_posted)
rc = -ENOMEM;
else if (status)
rc = -EIO;
}
return rc;
} }
/** /**
...@@ -955,33 +1030,38 @@ lpfc_board_mode_store(struct device *dev, struct device_attribute *attr, ...@@ -955,33 +1030,38 @@ lpfc_board_mode_store(struct device *dev, struct device_attribute *attr,
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;
struct completion online_compl; struct completion online_compl;
int status=0; char *board_mode_str = NULL;
int status = 0;
int rc; int rc;
if (!phba->cfg_enable_hba_reset) if (!phba->cfg_enable_hba_reset) {
return -EACCES; status = -EACCES;
goto board_mode_out;
}
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"3050 lpfc_board_mode set to %s\n", buf); "3050 lpfc_board_mode set to %s\n", buf);
init_completion(&online_compl); init_completion(&online_compl);
if(strncmp(buf, "online", sizeof("online") - 1) == 0) { if(strncmp(buf, "online", sizeof("online") - 1) == 0) {
rc = lpfc_workq_post_event(phba, &status, &online_compl, rc = lpfc_workq_post_event(phba, &status, &online_compl,
LPFC_EVT_ONLINE); LPFC_EVT_ONLINE);
if (rc == 0) if (rc == 0) {
return -ENOMEM; status = -ENOMEM;
goto board_mode_out;
}
wait_for_completion(&online_compl); wait_for_completion(&online_compl);
} else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0) } else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0) else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0)
if (phba->sli_rev == LPFC_SLI_REV4) if (phba->sli_rev == LPFC_SLI_REV4)
return -EINVAL; status = -EINVAL;
else else
status = lpfc_do_offline(phba, LPFC_EVT_WARM_START); status = lpfc_do_offline(phba, LPFC_EVT_WARM_START);
else if (strncmp(buf, "error", sizeof("error") - 1) == 0) else if (strncmp(buf, "error", sizeof("error") - 1) == 0)
if (phba->sli_rev == LPFC_SLI_REV4) if (phba->sli_rev == LPFC_SLI_REV4)
return -EINVAL; status = -EINVAL;
else else
status = lpfc_do_offline(phba, LPFC_EVT_KILL); status = lpfc_do_offline(phba, LPFC_EVT_KILL);
else if (strncmp(buf, "dump", sizeof("dump") - 1) == 0) else if (strncmp(buf, "dump", sizeof("dump") - 1) == 0)
...@@ -991,12 +1071,21 @@ lpfc_board_mode_store(struct device *dev, struct device_attribute *attr, ...@@ -991,12 +1071,21 @@ lpfc_board_mode_store(struct device *dev, struct device_attribute *attr,
else if (strncmp(buf, "dv_reset", sizeof("dv_reset") - 1) == 0) else if (strncmp(buf, "dv_reset", sizeof("dv_reset") - 1) == 0)
status = lpfc_sli4_pdev_reg_request(phba, LPFC_DV_RESET); status = lpfc_sli4_pdev_reg_request(phba, LPFC_DV_RESET);
else else
return -EINVAL; status = -EINVAL;
board_mode_out:
if (!status) if (!status)
return strlen(buf); return strlen(buf);
else else {
board_mode_str = strchr(buf, '\n');
if (board_mode_str)
*board_mode_str = '\0';
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"3097 Failed \"%s\", status(%d), "
"fc_flag(x%x)\n",
buf, status, phba->pport->fc_flag);
return status; return status;
}
} }
/** /**
...@@ -1942,6 +2031,7 @@ static DEVICE_ATTR(lpfc_fips_rev, S_IRUGO, lpfc_fips_rev_show, NULL); ...@@ -1942,6 +2031,7 @@ static DEVICE_ATTR(lpfc_fips_rev, S_IRUGO, lpfc_fips_rev_show, NULL);
static DEVICE_ATTR(lpfc_dss, S_IRUGO, lpfc_dss_show, NULL); static DEVICE_ATTR(lpfc_dss, S_IRUGO, lpfc_dss_show, NULL);
static DEVICE_ATTR(lpfc_sriov_hw_max_virtfn, S_IRUGO, static DEVICE_ATTR(lpfc_sriov_hw_max_virtfn, S_IRUGO,
lpfc_sriov_hw_max_virtfn_show, NULL); lpfc_sriov_hw_max_virtfn_show, NULL);
static DEVICE_ATTR(protocol, S_IRUGO, lpfc_sli4_protocol_show, NULL);
static char *lpfc_soft_wwn_key = "C99G71SL8032A"; static char *lpfc_soft_wwn_key = "C99G71SL8032A";
...@@ -2687,6 +2777,14 @@ lpfc_topology_store(struct device *dev, struct device_attribute *attr, ...@@ -2687,6 +2777,14 @@ 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; phba->cfg_topology = val;
if (phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G &&
val == 4) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"3113 Loop mode not supported at speed %d\n",
phba->cfg_link_speed);
phba->cfg_topology = prev_val;
return -EINVAL;
}
if (nolip) if (nolip)
return strlen(buf); return strlen(buf);
...@@ -3132,6 +3230,14 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr, ...@@ -3132,6 +3230,14 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
val); val);
return -EINVAL; return -EINVAL;
} }
if (val == LPFC_USER_LINK_SPEED_16G &&
phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3112 lpfc_link_speed attribute cannot be set "
"to %d. Speed is not supported in loop mode.\n",
val);
return -EINVAL;
}
if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) && if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
(LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) { (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
prev_val = phba->cfg_link_speed; prev_val = phba->cfg_link_speed;
...@@ -3176,6 +3282,13 @@ lpfc_param_show(link_speed) ...@@ -3176,6 +3282,13 @@ lpfc_param_show(link_speed)
static int static int
lpfc_link_speed_init(struct lpfc_hba *phba, int val) lpfc_link_speed_init(struct lpfc_hba *phba, int val)
{ {
if (val == LPFC_USER_LINK_SPEED_16G && phba->cfg_topology == 4) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3111 lpfc_link_speed of %d cannot "
"support loop mode, setting topology to default.\n",
val);
phba->cfg_topology = 0;
}
if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) && if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
(LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) { (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
phba->cfg_link_speed = val; phba->cfg_link_speed = val;
...@@ -3830,6 +3943,7 @@ struct device_attribute *lpfc_hba_attrs[] = { ...@@ -3830,6 +3943,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_fips_rev, &dev_attr_lpfc_fips_rev,
&dev_attr_lpfc_dss, &dev_attr_lpfc_dss,
&dev_attr_lpfc_sriov_hw_max_virtfn, &dev_attr_lpfc_sriov_hw_max_virtfn,
&dev_attr_protocol,
NULL, NULL,
}; };
...@@ -3987,23 +4101,6 @@ static struct bin_attribute sysfs_ctlreg_attr = { ...@@ -3987,23 +4101,6 @@ static struct bin_attribute sysfs_ctlreg_attr = {
.write = sysfs_ctlreg_write, .write = sysfs_ctlreg_write,
}; };
/**
* sysfs_mbox_idle - frees the sysfs mailbox
* @phba: lpfc_hba pointer
**/
static void
sysfs_mbox_idle(struct lpfc_hba *phba)
{
phba->sysfs_mbox.state = SMBOX_IDLE;
phba->sysfs_mbox.offset = 0;
if (phba->sysfs_mbox.mbox) {
mempool_free(phba->sysfs_mbox.mbox,
phba->mbox_mem_pool);
phba->sysfs_mbox.mbox = NULL;
}
}
/** /**
* sysfs_mbox_write - Write method for writing information via mbox * sysfs_mbox_write - Write method for writing information via mbox
* @filp: open sysfs file * @filp: open sysfs file
...@@ -4014,71 +4111,18 @@ sysfs_mbox_idle(struct lpfc_hba *phba) ...@@ -4014,71 +4111,18 @@ sysfs_mbox_idle(struct lpfc_hba *phba)
* @count: bytes to transfer. * @count: bytes to transfer.
* *
* Description: * Description:
* Accessed via /sys/class/scsi_host/hostxxx/mbox. * Deprecated function. All mailbox access from user space is performed via the
* Uses the sysfs mbox to send buf contents to the adapter. * bsg interface.
* *
* Returns: * Returns:
* -ERANGE off and count combo out of range * -EPERM operation not permitted
* -EINVAL off, count or buff address invalid
* zero if count is zero
* -EPERM adapter is offline
* -ENOMEM failed to allocate memory for the mail box
* -EAGAIN offset, state or mbox is NULL
* count number of bytes transferred
**/ **/
static ssize_t static ssize_t
sysfs_mbox_write(struct file *filp, struct kobject *kobj, sysfs_mbox_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count) char *buf, loff_t off, size_t count)
{ {
struct device *dev = container_of(kobj, struct device, kobj); return -EPERM;
struct Scsi_Host *shost = class_to_shost(dev);
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
struct lpfc_hba *phba = vport->phba;
struct lpfcMboxq *mbox = NULL;
if ((count + off) > MAILBOX_CMD_SIZE)
return -ERANGE;
if (off % 4 || count % 4 || (unsigned long)buf % 4)
return -EINVAL;
if (count == 0)
return 0;
if (off == 0) {
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!mbox)
return -ENOMEM;
memset(mbox, 0, sizeof (LPFC_MBOXQ_t));
}
spin_lock_irq(&phba->hbalock);
if (off == 0) {
if (phba->sysfs_mbox.mbox)
mempool_free(mbox, phba->mbox_mem_pool);
else
phba->sysfs_mbox.mbox = mbox;
phba->sysfs_mbox.state = SMBOX_WRITING;
} else {
if (phba->sysfs_mbox.state != SMBOX_WRITING ||
phba->sysfs_mbox.offset != off ||
phba->sysfs_mbox.mbox == NULL) {
sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock);
return -EAGAIN;
}
}
memcpy((uint8_t *) &phba->sysfs_mbox.mbox->u.mb + off,
buf, count);
phba->sysfs_mbox.offset = off + count;
spin_unlock_irq(&phba->hbalock);
return count;
} }
/** /**
...@@ -4091,201 +4135,18 @@ sysfs_mbox_write(struct file *filp, struct kobject *kobj, ...@@ -4091,201 +4135,18 @@ sysfs_mbox_write(struct file *filp, struct kobject *kobj,
* @count: bytes to transfer. * @count: bytes to transfer.
* *
* Description: * Description:
* Accessed via /sys/class/scsi_host/hostxxx/mbox. * Deprecated function. All mailbox access from user space is performed via the
* Uses the sysfs mbox to receive data from to the adapter. * bsg interface.
* *
* Returns: * Returns:
* -ERANGE off greater than mailbox command size * -EPERM operation not permitted
* -EINVAL off, count or buff address invalid
* zero if off and count are zero
* -EACCES adapter over temp
* -EPERM garbage can value to catch a multitude of errors
* -EAGAIN management IO not permitted, state or off error
* -ETIME mailbox timeout
* -ENODEV mailbox error
* count number of bytes transferred
**/ **/
static ssize_t static ssize_t
sysfs_mbox_read(struct file *filp, struct kobject *kobj, sysfs_mbox_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count) char *buf, loff_t off, size_t count)
{ {
struct device *dev = container_of(kobj, struct device, kobj); return -EPERM;
struct Scsi_Host *shost = class_to_shost(dev);
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
struct lpfc_hba *phba = vport->phba;
LPFC_MBOXQ_t *mboxq;
MAILBOX_t *pmb;
uint32_t mbox_tmo;
int rc;
if (off > MAILBOX_CMD_SIZE)
return -ERANGE;
if ((count + off) > MAILBOX_CMD_SIZE)
count = MAILBOX_CMD_SIZE - off;
if (off % 4 || count % 4 || (unsigned long)buf % 4)
return -EINVAL;
if (off && count == 0)
return 0;
spin_lock_irq(&phba->hbalock);
if (phba->over_temp_state == HBA_OVER_TEMP) {
sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock);
return -EACCES;
}
if (off == 0 &&
phba->sysfs_mbox.state == SMBOX_WRITING &&
phba->sysfs_mbox.offset >= 2 * sizeof(uint32_t)) {
mboxq = (LPFC_MBOXQ_t *)&phba->sysfs_mbox.mbox;
pmb = &mboxq->u.mb;
switch (pmb->mbxCommand) {
/* Offline only */
case MBX_INIT_LINK:
case MBX_DOWN_LINK:
case MBX_CONFIG_LINK:
case MBX_CONFIG_RING:
case MBX_RESET_RING:
case MBX_UNREG_LOGIN:
case MBX_CLEAR_LA:
case MBX_DUMP_CONTEXT:
case MBX_RUN_DIAGS:
case MBX_RESTART:
case MBX_SET_MASK:
case MBX_SET_DEBUG:
if (!(vport->fc_flag & FC_OFFLINE_MODE)) {
printk(KERN_WARNING "mbox_read:Command 0x%x "
"is illegal in on-line state\n",
pmb->mbxCommand);
sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock);
return -EPERM;
}
case MBX_WRITE_NV:
case MBX_WRITE_VPARMS:
case MBX_LOAD_SM:
case MBX_READ_NV:
case MBX_READ_CONFIG:
case MBX_READ_RCONFIG:
case MBX_READ_STATUS:
case MBX_READ_XRI:
case MBX_READ_REV:
case MBX_READ_LNK_STAT:
case MBX_DUMP_MEMORY:
case MBX_DOWN_LOAD:
case MBX_UPDATE_CFG:
case MBX_KILL_BOARD:
case MBX_LOAD_AREA:
case MBX_LOAD_EXP_ROM:
case MBX_BEACON:
case MBX_DEL_LD_ENTRY:
case MBX_SET_VARIABLE:
case MBX_WRITE_WWN:
case MBX_PORT_CAPABILITIES:
case MBX_PORT_IOV_CONTROL:
break;
case MBX_SECURITY_MGMT:
case MBX_AUTH_PORT:
if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) {
printk(KERN_WARNING "mbox_read:Command 0x%x "
"is not permitted\n", pmb->mbxCommand);
sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock);
return -EPERM;
}
break;
case MBX_READ_SPARM64:
case MBX_READ_TOPOLOGY:
case MBX_REG_LOGIN:
case MBX_REG_LOGIN64:
case MBX_CONFIG_PORT:
case MBX_RUN_BIU_DIAG:
printk(KERN_WARNING "mbox_read: Illegal Command 0x%x\n",
pmb->mbxCommand);
sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock);
return -EPERM;
default:
printk(KERN_WARNING "mbox_read: Unknown Command 0x%x\n",
pmb->mbxCommand);
sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock);
return -EPERM;
}
/* If HBA encountered an error attention, allow only DUMP
* or RESTART mailbox commands until the HBA is restarted.
*/
if (phba->pport->stopped &&
pmb->mbxCommand != MBX_DUMP_MEMORY &&
pmb->mbxCommand != MBX_RESTART &&
pmb->mbxCommand != MBX_WRITE_VPARMS &&
pmb->mbxCommand != MBX_WRITE_WWN)
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
"1259 mbox: Issued mailbox cmd "
"0x%x while in stopped state.\n",
pmb->mbxCommand);
phba->sysfs_mbox.mbox->vport = vport;
/* Don't allow mailbox commands to be sent when blocked
* or when in the middle of discovery
*/
if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) {
sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock);
return -EAGAIN;
}
if ((vport->fc_flag & FC_OFFLINE_MODE) ||
(!(phba->sli.sli_flag & LPFC_SLI_ACTIVE))) {
spin_unlock_irq(&phba->hbalock);
rc = lpfc_sli_issue_mbox (phba,
phba->sysfs_mbox.mbox,
MBX_POLL);
spin_lock_irq(&phba->hbalock);
} else {
spin_unlock_irq(&phba->hbalock);
mbox_tmo = lpfc_mbox_tmo_val(phba, mboxq);
rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo);
spin_lock_irq(&phba->hbalock);
}
if (rc != MBX_SUCCESS) {
if (rc == MBX_TIMEOUT) {
phba->sysfs_mbox.mbox = NULL;
}
sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock);
return (rc == MBX_TIMEOUT) ? -ETIME : -ENODEV;
}
phba->sysfs_mbox.state = SMBOX_READING;
}
else if (phba->sysfs_mbox.offset != off ||
phba->sysfs_mbox.state != SMBOX_READING) {
printk(KERN_WARNING "mbox_read: Bad State\n");
sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock);
return -EAGAIN;
}
memcpy(buf, (uint8_t *) &pmb + off, count);
phba->sysfs_mbox.offset = off + count;
if (phba->sysfs_mbox.offset == MAILBOX_CMD_SIZE)
sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock);
return count;
} }
static struct bin_attribute sysfs_mbox_attr = { static struct bin_attribute sysfs_mbox_attr = {
...@@ -4429,8 +4290,13 @@ lpfc_get_host_port_state(struct Scsi_Host *shost) ...@@ -4429,8 +4290,13 @@ lpfc_get_host_port_state(struct Scsi_Host *shost)
case LPFC_LINK_UP: case LPFC_LINK_UP:
case LPFC_CLEAR_LA: case LPFC_CLEAR_LA:
case LPFC_HBA_READY: case LPFC_HBA_READY:
/* Links up, beyond this port_type reports state */ /* Links up, reports port state accordingly */
fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; if (vport->port_state < LPFC_VPORT_READY)
fc_host_port_state(shost) =
FC_PORTSTATE_BYPASSED;
else
fc_host_port_state(shost) =
FC_PORTSTATE_ONLINE;
break; break;
case LPFC_HBA_ERROR: case LPFC_HBA_ERROR:
fc_host_port_state(shost) = FC_PORTSTATE_ERROR; fc_host_port_state(shost) = FC_PORTSTATE_ERROR;
......
此差异已折叠。
...@@ -96,7 +96,7 @@ struct get_mgmt_rev { ...@@ -96,7 +96,7 @@ struct get_mgmt_rev {
}; };
#define MANAGEMENT_MAJOR_REV 1 #define MANAGEMENT_MAJOR_REV 1
#define MANAGEMENT_MINOR_REV 0 #define MANAGEMENT_MINOR_REV 1
/* the MgmtRevInfo structure */ /* the MgmtRevInfo structure */
struct MgmtRevInfo { struct MgmtRevInfo {
...@@ -248,6 +248,7 @@ struct lpfc_sli_config_emb1_subsys { ...@@ -248,6 +248,7 @@ struct lpfc_sli_config_emb1_subsys {
#define COMN_OPCODE_WRITE_OBJECT 0xAC #define COMN_OPCODE_WRITE_OBJECT 0xAC
#define COMN_OPCODE_READ_OBJECT_LIST 0xAD #define COMN_OPCODE_READ_OBJECT_LIST 0xAD
#define COMN_OPCODE_DELETE_OBJECT 0xAE #define COMN_OPCODE_DELETE_OBJECT 0xAE
#define COMN_OPCODE_GET_CNTL_ADDL_ATTRIBUTES 0x79
uint32_t timeout; uint32_t timeout;
uint32_t request_length; uint32_t request_length;
uint32_t word9; uint32_t word9;
......
/******************************************************************* /*******************************************************************
* This file is part of the Emulex Linux Device Driver for * * This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. * * Fibre Channel Host Bus Adapters. *
* Copyright (C) 2004-2005 Emulex. All rights reserved. * * Copyright (C) 2004-2011 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. * * EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com * * www.emulex.com *
* * * *
...@@ -82,7 +82,8 @@ lpfc_memcpy_from_slim( void *dest, void __iomem *src, unsigned int bytes) ...@@ -82,7 +82,8 @@ lpfc_memcpy_from_slim( void *dest, void __iomem *src, unsigned int bytes)
static inline void static inline void
lpfc_memcpy_to_slim( void __iomem *dest, void *src, unsigned int bytes) lpfc_memcpy_to_slim( void __iomem *dest, void *src, unsigned int bytes)
{ {
__iowrite32_copy(dest, src, bytes); /* convert bytes in argument list to word count for copy function */
__iowrite32_copy(dest, src, bytes / sizeof(uint32_t));
} }
static inline void static inline void
......
...@@ -26,7 +26,7 @@ void lpfc_sli_read_link_ste(struct lpfc_hba *); ...@@ -26,7 +26,7 @@ void lpfc_sli_read_link_ste(struct lpfc_hba *);
void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t, uint16_t); void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t, uint16_t);
void lpfc_dump_wakeup_param(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_dump_wakeup_param(struct lpfc_hba *, LPFC_MBOXQ_t *);
int lpfc_dump_static_vport(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); int lpfc_dump_static_vport(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
int lpfc_dump_fcoe_param(struct lpfc_hba *, struct lpfcMboxq *); int lpfc_sli4_dump_cfg_rg23(struct lpfc_hba *, struct lpfcMboxq *);
void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
...@@ -78,6 +78,7 @@ void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); ...@@ -78,6 +78,7 @@ void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_unregister_vfi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_enqueue_node(struct lpfc_vport *, struct lpfc_nodelist *); void lpfc_enqueue_node(struct lpfc_vport *, struct lpfc_nodelist *);
void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *); void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *);
struct lpfc_nodelist *lpfc_enable_node(struct lpfc_vport *, struct lpfc_nodelist *lpfc_enable_node(struct lpfc_vport *,
...@@ -106,7 +107,7 @@ void lpfc_cleanup(struct lpfc_vport *); ...@@ -106,7 +107,7 @@ void lpfc_cleanup(struct lpfc_vport *);
void lpfc_disc_timeout(unsigned long); void lpfc_disc_timeout(unsigned long);
struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t); struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t);
struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_vport *, uint16_t);
void lpfc_worker_wake_up(struct lpfc_hba *); void lpfc_worker_wake_up(struct lpfc_hba *);
int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t); int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t);
int lpfc_do_work(void *); int lpfc_do_work(void *);
...@@ -453,3 +454,11 @@ int lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *, int); ...@@ -453,3 +454,11 @@ int lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *, int);
uint16_t lpfc_sli_sriov_nr_virtfn_get(struct lpfc_hba *); uint16_t lpfc_sli_sriov_nr_virtfn_get(struct lpfc_hba *);
int lpfc_sli4_queue_create(struct lpfc_hba *); int lpfc_sli4_queue_create(struct lpfc_hba *);
void lpfc_sli4_queue_destroy(struct lpfc_hba *); void lpfc_sli4_queue_destroy(struct lpfc_hba *);
void lpfc_sli4_abts_err_handler(struct lpfc_hba *, struct lpfc_nodelist *,
struct sli4_wcqe_xri_aborted *);
int lpfc_hba_init_link_fc_topology(struct lpfc_hba *, uint32_t, uint32_t);
int lpfc_issue_reg_vfi(struct lpfc_vport *);
int lpfc_issue_unreg_vfi(struct lpfc_vport *);
int lpfc_selective_reset(struct lpfc_hba *);
int lpfc_sli4_read_config(struct lpfc_hba *phba);
int lpfc_scsi_buf_update(struct lpfc_hba *phba);
...@@ -1997,7 +1997,8 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, ...@@ -1997,7 +1997,8 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
/* Get slow-path event queue information */ /* Get slow-path event queue information */
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Slow-path EQ information:\n"); "Slow-path EQ information:\n");
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, if (phba->sli4_hba.sp_eq) {
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"\tEQID[%02d], " "\tEQID[%02d], "
"QE-COUNT[%04d], QE-SIZE[%04d], " "QE-COUNT[%04d], QE-SIZE[%04d], "
"HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n", "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
...@@ -2006,12 +2007,17 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, ...@@ -2006,12 +2007,17 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
phba->sli4_hba.sp_eq->entry_size, phba->sli4_hba.sp_eq->entry_size,
phba->sli4_hba.sp_eq->host_index, phba->sli4_hba.sp_eq->host_index,
phba->sli4_hba.sp_eq->hba_index); phba->sli4_hba.sp_eq->hba_index);
}
/* Get fast-path event queue information */ /* Get fast-path event queue information */
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Fast-path EQ information:\n"); "Fast-path EQ information:\n");
for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count; fcp_qidx++) { if (phba->sli4_hba.fp_eq) {
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count;
fcp_qidx++) {
if (phba->sli4_hba.fp_eq[fcp_qidx]) {
len += snprintf(pbuffer+len,
LPFC_QUE_INFO_GET_BUF_SIZE-len,
"\tEQID[%02d], " "\tEQID[%02d], "
"QE-COUNT[%04d], QE-SIZE[%04d], " "QE-COUNT[%04d], QE-SIZE[%04d], "
"HOST-INDEX[%04d], PORT-INDEX[%04d]\n", "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
...@@ -2020,16 +2026,19 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, ...@@ -2020,16 +2026,19 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
phba->sli4_hba.fp_eq[fcp_qidx]->entry_size, phba->sli4_hba.fp_eq[fcp_qidx]->entry_size,
phba->sli4_hba.fp_eq[fcp_qidx]->host_index, phba->sli4_hba.fp_eq[fcp_qidx]->host_index,
phba->sli4_hba.fp_eq[fcp_qidx]->hba_index); phba->sli4_hba.fp_eq[fcp_qidx]->hba_index);
}
}
} }
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n"); len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
/* Get mailbox complete queue information */ /* Get mailbox complete queue information */
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Slow-path MBX CQ information:\n"); "Slow-path MBX CQ information:\n");
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, if (phba->sli4_hba.mbx_cq) {
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Associated EQID[%02d]:\n", "Associated EQID[%02d]:\n",
phba->sli4_hba.mbx_cq->assoc_qid); phba->sli4_hba.mbx_cq->assoc_qid);
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"\tCQID[%02d], " "\tCQID[%02d], "
"QE-COUNT[%04d], QE-SIZE[%04d], " "QE-COUNT[%04d], QE-SIZE[%04d], "
"HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n", "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
...@@ -2038,14 +2047,16 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, ...@@ -2038,14 +2047,16 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
phba->sli4_hba.mbx_cq->entry_size, phba->sli4_hba.mbx_cq->entry_size,
phba->sli4_hba.mbx_cq->host_index, phba->sli4_hba.mbx_cq->host_index,
phba->sli4_hba.mbx_cq->hba_index); phba->sli4_hba.mbx_cq->hba_index);
}
/* Get slow-path complete queue information */ /* Get slow-path complete queue information */
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Slow-path ELS CQ information:\n"); "Slow-path ELS CQ information:\n");
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, if (phba->sli4_hba.els_cq) {
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Associated EQID[%02d]:\n", "Associated EQID[%02d]:\n",
phba->sli4_hba.els_cq->assoc_qid); phba->sli4_hba.els_cq->assoc_qid);
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"\tCQID [%02d], " "\tCQID [%02d], "
"QE-COUNT[%04d], QE-SIZE[%04d], " "QE-COUNT[%04d], QE-SIZE[%04d], "
"HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n", "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
...@@ -2054,16 +2065,21 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, ...@@ -2054,16 +2065,21 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
phba->sli4_hba.els_cq->entry_size, phba->sli4_hba.els_cq->entry_size,
phba->sli4_hba.els_cq->host_index, phba->sli4_hba.els_cq->host_index,
phba->sli4_hba.els_cq->hba_index); phba->sli4_hba.els_cq->hba_index);
}
/* Get fast-path complete queue information */ /* Get fast-path complete queue information */
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Fast-path FCP CQ information:\n"); "Fast-path FCP CQ information:\n");
fcp_qidx = 0; fcp_qidx = 0;
do { if (phba->sli4_hba.fcp_cq) {
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, do {
if (phba->sli4_hba.fcp_cq[fcp_qidx]) {
len += snprintf(pbuffer+len,
LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Associated EQID[%02d]:\n", "Associated EQID[%02d]:\n",
phba->sli4_hba.fcp_cq[fcp_qidx]->assoc_qid); phba->sli4_hba.fcp_cq[fcp_qidx]->assoc_qid);
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len,
LPFC_QUE_INFO_GET_BUF_SIZE-len,
"\tCQID[%02d], " "\tCQID[%02d], "
"QE-COUNT[%04d], QE-SIZE[%04d], " "QE-COUNT[%04d], QE-SIZE[%04d], "
"HOST-INDEX[%04d], PORT-INDEX[%04d]\n", "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
...@@ -2072,16 +2088,20 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, ...@@ -2072,16 +2088,20 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
phba->sli4_hba.fcp_cq[fcp_qidx]->entry_size, phba->sli4_hba.fcp_cq[fcp_qidx]->entry_size,
phba->sli4_hba.fcp_cq[fcp_qidx]->host_index, phba->sli4_hba.fcp_cq[fcp_qidx]->host_index,
phba->sli4_hba.fcp_cq[fcp_qidx]->hba_index); phba->sli4_hba.fcp_cq[fcp_qidx]->hba_index);
} while (++fcp_qidx < phba->cfg_fcp_eq_count); }
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n"); } while (++fcp_qidx < phba->cfg_fcp_eq_count);
len += snprintf(pbuffer+len,
LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
}
/* Get mailbox queue information */ /* Get mailbox queue information */
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Slow-path MBX MQ information:\n"); "Slow-path MBX MQ information:\n");
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, if (phba->sli4_hba.mbx_wq) {
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Associated CQID[%02d]:\n", "Associated CQID[%02d]:\n",
phba->sli4_hba.mbx_wq->assoc_qid); phba->sli4_hba.mbx_wq->assoc_qid);
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"\tWQID[%02d], " "\tWQID[%02d], "
"QE-COUNT[%04d], QE-SIZE[%04d], " "QE-COUNT[%04d], QE-SIZE[%04d], "
"HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n", "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
...@@ -2090,14 +2110,16 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, ...@@ -2090,14 +2110,16 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
phba->sli4_hba.mbx_wq->entry_size, phba->sli4_hba.mbx_wq->entry_size,
phba->sli4_hba.mbx_wq->host_index, phba->sli4_hba.mbx_wq->host_index,
phba->sli4_hba.mbx_wq->hba_index); phba->sli4_hba.mbx_wq->hba_index);
}
/* Get slow-path work queue information */ /* Get slow-path work queue information */
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Slow-path ELS WQ information:\n"); "Slow-path ELS WQ information:\n");
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, if (phba->sli4_hba.els_wq) {
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Associated CQID[%02d]:\n", "Associated CQID[%02d]:\n",
phba->sli4_hba.els_wq->assoc_qid); phba->sli4_hba.els_wq->assoc_qid);
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"\tWQID[%02d], " "\tWQID[%02d], "
"QE-COUNT[%04d], QE-SIZE[%04d], " "QE-COUNT[%04d], QE-SIZE[%04d], "
"HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n", "HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
...@@ -2106,15 +2128,22 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, ...@@ -2106,15 +2128,22 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
phba->sli4_hba.els_wq->entry_size, phba->sli4_hba.els_wq->entry_size,
phba->sli4_hba.els_wq->host_index, phba->sli4_hba.els_wq->host_index,
phba->sli4_hba.els_wq->hba_index); phba->sli4_hba.els_wq->hba_index);
}
/* Get fast-path work queue information */ /* Get fast-path work queue information */
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Fast-path FCP WQ information:\n"); "Fast-path FCP WQ information:\n");
for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_wq_count; fcp_qidx++) { if (phba->sli4_hba.fcp_wq) {
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_wq_count;
fcp_qidx++) {
if (!phba->sli4_hba.fcp_wq[fcp_qidx])
continue;
len += snprintf(pbuffer+len,
LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Associated CQID[%02d]:\n", "Associated CQID[%02d]:\n",
phba->sli4_hba.fcp_wq[fcp_qidx]->assoc_qid); phba->sli4_hba.fcp_wq[fcp_qidx]->assoc_qid);
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len,
LPFC_QUE_INFO_GET_BUF_SIZE-len,
"\tWQID[%02d], " "\tWQID[%02d], "
"QE-COUNT[%04d], WQE-SIZE[%04d], " "QE-COUNT[%04d], WQE-SIZE[%04d], "
"HOST-INDEX[%04d], PORT-INDEX[%04d]\n", "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
...@@ -2123,16 +2152,19 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, ...@@ -2123,16 +2152,19 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
phba->sli4_hba.fcp_wq[fcp_qidx]->entry_size, phba->sli4_hba.fcp_wq[fcp_qidx]->entry_size,
phba->sli4_hba.fcp_wq[fcp_qidx]->host_index, phba->sli4_hba.fcp_wq[fcp_qidx]->host_index,
phba->sli4_hba.fcp_wq[fcp_qidx]->hba_index); phba->sli4_hba.fcp_wq[fcp_qidx]->hba_index);
}
len += snprintf(pbuffer+len,
LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
} }
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
/* Get receive queue information */ /* Get receive queue information */
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Slow-path RQ information:\n"); "Slow-path RQ information:\n");
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, if (phba->sli4_hba.hdr_rq && phba->sli4_hba.dat_rq) {
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"Associated CQID[%02d]:\n", "Associated CQID[%02d]:\n",
phba->sli4_hba.hdr_rq->assoc_qid); phba->sli4_hba.hdr_rq->assoc_qid);
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"\tHQID[%02d], " "\tHQID[%02d], "
"QE-COUNT[%04d], QE-SIZE[%04d], " "QE-COUNT[%04d], QE-SIZE[%04d], "
"HOST-INDEX[%04d], PORT-INDEX[%04d]\n", "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
...@@ -2141,7 +2173,7 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, ...@@ -2141,7 +2173,7 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
phba->sli4_hba.hdr_rq->entry_size, phba->sli4_hba.hdr_rq->entry_size,
phba->sli4_hba.hdr_rq->host_index, phba->sli4_hba.hdr_rq->host_index,
phba->sli4_hba.hdr_rq->hba_index); phba->sli4_hba.hdr_rq->hba_index);
len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
"\tDQID[%02d], " "\tDQID[%02d], "
"QE-COUNT[%04d], QE-SIZE[%04d], " "QE-COUNT[%04d], QE-SIZE[%04d], "
"HOST-INDEX[%04d], PORT-INDEX[%04d]\n", "HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
...@@ -2150,7 +2182,7 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, ...@@ -2150,7 +2182,7 @@ lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
phba->sli4_hba.dat_rq->entry_size, phba->sli4_hba.dat_rq->entry_size,
phba->sli4_hba.dat_rq->host_index, phba->sli4_hba.dat_rq->host_index,
phba->sli4_hba.dat_rq->hba_index); phba->sli4_hba.dat_rq->hba_index);
}
return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
} }
...@@ -2360,7 +2392,8 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf, ...@@ -2360,7 +2392,8 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
switch (quetp) { switch (quetp) {
case LPFC_IDIAG_EQ: case LPFC_IDIAG_EQ:
/* Slow-path event queue */ /* Slow-path event queue */
if (phba->sli4_hba.sp_eq->queue_id == queid) { if (phba->sli4_hba.sp_eq &&
phba->sli4_hba.sp_eq->queue_id == queid) {
/* Sanity check */ /* Sanity check */
rc = lpfc_idiag_que_param_check( rc = lpfc_idiag_que_param_check(
phba->sli4_hba.sp_eq, index, count); phba->sli4_hba.sp_eq, index, count);
...@@ -2370,23 +2403,29 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf, ...@@ -2370,23 +2403,29 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
goto pass_check; goto pass_check;
} }
/* Fast-path event queue */ /* Fast-path event queue */
for (qidx = 0; qidx < phba->cfg_fcp_eq_count; qidx++) { if (phba->sli4_hba.fp_eq) {
if (phba->sli4_hba.fp_eq[qidx]->queue_id == queid) { for (qidx = 0; qidx < phba->cfg_fcp_eq_count; qidx++) {
/* Sanity check */ if (phba->sli4_hba.fp_eq[qidx] &&
rc = lpfc_idiag_que_param_check( phba->sli4_hba.fp_eq[qidx]->queue_id ==
queid) {
/* Sanity check */
rc = lpfc_idiag_que_param_check(
phba->sli4_hba.fp_eq[qidx], phba->sli4_hba.fp_eq[qidx],
index, count); index, count);
if (rc) if (rc)
goto error_out; goto error_out;
idiag.ptr_private = phba->sli4_hba.fp_eq[qidx]; idiag.ptr_private =
goto pass_check; phba->sli4_hba.fp_eq[qidx];
goto pass_check;
}
} }
} }
goto error_out; goto error_out;
break; break;
case LPFC_IDIAG_CQ: case LPFC_IDIAG_CQ:
/* MBX complete queue */ /* MBX complete queue */
if (phba->sli4_hba.mbx_cq->queue_id == queid) { if (phba->sli4_hba.mbx_cq &&
phba->sli4_hba.mbx_cq->queue_id == queid) {
/* Sanity check */ /* Sanity check */
rc = lpfc_idiag_que_param_check( rc = lpfc_idiag_que_param_check(
phba->sli4_hba.mbx_cq, index, count); phba->sli4_hba.mbx_cq, index, count);
...@@ -2396,7 +2435,8 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf, ...@@ -2396,7 +2435,8 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
goto pass_check; goto pass_check;
} }
/* ELS complete queue */ /* ELS complete queue */
if (phba->sli4_hba.els_cq->queue_id == queid) { if (phba->sli4_hba.els_cq &&
phba->sli4_hba.els_cq->queue_id == queid) {
/* Sanity check */ /* Sanity check */
rc = lpfc_idiag_que_param_check( rc = lpfc_idiag_que_param_check(
phba->sli4_hba.els_cq, index, count); phba->sli4_hba.els_cq, index, count);
...@@ -2406,25 +2446,30 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf, ...@@ -2406,25 +2446,30 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
goto pass_check; goto pass_check;
} }
/* FCP complete queue */ /* FCP complete queue */
qidx = 0; if (phba->sli4_hba.fcp_cq) {
do { qidx = 0;
if (phba->sli4_hba.fcp_cq[qidx]->queue_id == queid) { do {
/* Sanity check */ if (phba->sli4_hba.fcp_cq[qidx] &&
rc = lpfc_idiag_que_param_check( phba->sli4_hba.fcp_cq[qidx]->queue_id ==
queid) {
/* Sanity check */
rc = lpfc_idiag_que_param_check(
phba->sli4_hba.fcp_cq[qidx], phba->sli4_hba.fcp_cq[qidx],
index, count); index, count);
if (rc) if (rc)
goto error_out; goto error_out;
idiag.ptr_private = idiag.ptr_private =
phba->sli4_hba.fcp_cq[qidx]; phba->sli4_hba.fcp_cq[qidx];
goto pass_check; goto pass_check;
} }
} while (++qidx < phba->cfg_fcp_eq_count); } while (++qidx < phba->cfg_fcp_eq_count);
}
goto error_out; goto error_out;
break; break;
case LPFC_IDIAG_MQ: case LPFC_IDIAG_MQ:
/* MBX work queue */ /* MBX work queue */
if (phba->sli4_hba.mbx_wq->queue_id == queid) { if (phba->sli4_hba.mbx_wq &&
phba->sli4_hba.mbx_wq->queue_id == queid) {
/* Sanity check */ /* Sanity check */
rc = lpfc_idiag_que_param_check( rc = lpfc_idiag_que_param_check(
phba->sli4_hba.mbx_wq, index, count); phba->sli4_hba.mbx_wq, index, count);
...@@ -2433,10 +2478,12 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf, ...@@ -2433,10 +2478,12 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
idiag.ptr_private = phba->sli4_hba.mbx_wq; idiag.ptr_private = phba->sli4_hba.mbx_wq;
goto pass_check; goto pass_check;
} }
goto error_out;
break; break;
case LPFC_IDIAG_WQ: case LPFC_IDIAG_WQ:
/* ELS work queue */ /* ELS work queue */
if (phba->sli4_hba.els_wq->queue_id == queid) { if (phba->sli4_hba.els_wq &&
phba->sli4_hba.els_wq->queue_id == queid) {
/* Sanity check */ /* Sanity check */
rc = lpfc_idiag_que_param_check( rc = lpfc_idiag_que_param_check(
phba->sli4_hba.els_wq, index, count); phba->sli4_hba.els_wq, index, count);
...@@ -2446,24 +2493,30 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf, ...@@ -2446,24 +2493,30 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
goto pass_check; goto pass_check;
} }
/* FCP work queue */ /* FCP work queue */
for (qidx = 0; qidx < phba->cfg_fcp_wq_count; qidx++) { if (phba->sli4_hba.fcp_wq) {
if (phba->sli4_hba.fcp_wq[qidx]->queue_id == queid) { for (qidx = 0; qidx < phba->cfg_fcp_wq_count; qidx++) {
/* Sanity check */ if (!phba->sli4_hba.fcp_wq[qidx])
rc = lpfc_idiag_que_param_check( continue;
if (phba->sli4_hba.fcp_wq[qidx]->queue_id ==
queid) {
/* Sanity check */
rc = lpfc_idiag_que_param_check(
phba->sli4_hba.fcp_wq[qidx], phba->sli4_hba.fcp_wq[qidx],
index, count); index, count);
if (rc) if (rc)
goto error_out; goto error_out;
idiag.ptr_private = idiag.ptr_private =
phba->sli4_hba.fcp_wq[qidx]; phba->sli4_hba.fcp_wq[qidx];
goto pass_check; goto pass_check;
}
} }
} }
goto error_out; goto error_out;
break; break;
case LPFC_IDIAG_RQ: case LPFC_IDIAG_RQ:
/* HDR queue */ /* HDR queue */
if (phba->sli4_hba.hdr_rq->queue_id == queid) { if (phba->sli4_hba.hdr_rq &&
phba->sli4_hba.hdr_rq->queue_id == queid) {
/* Sanity check */ /* Sanity check */
rc = lpfc_idiag_que_param_check( rc = lpfc_idiag_que_param_check(
phba->sli4_hba.hdr_rq, index, count); phba->sli4_hba.hdr_rq, index, count);
...@@ -2473,7 +2526,8 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf, ...@@ -2473,7 +2526,8 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
goto pass_check; goto pass_check;
} }
/* DAT queue */ /* DAT queue */
if (phba->sli4_hba.dat_rq->queue_id == queid) { if (phba->sli4_hba.dat_rq &&
phba->sli4_hba.dat_rq->queue_id == queid) {
/* Sanity check */ /* Sanity check */
rc = lpfc_idiag_que_param_check( rc = lpfc_idiag_que_param_check(
phba->sli4_hba.dat_rq, index, count); phba->sli4_hba.dat_rq, index, count);
......
...@@ -421,13 +421,13 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) ...@@ -421,13 +421,13 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
* @vport: pointer to a host virtual N_Port data structure. * @vport: pointer to a host virtual N_Port data structure.
* *
* This routine issues a REG_VFI mailbox for the vfi, vpi, fcfi triplet for * This routine issues a REG_VFI mailbox for the vfi, vpi, fcfi triplet for
* the @vport. This mailbox command is necessary for FCoE only. * the @vport. This mailbox command is necessary for SLI4 port only.
* *
* Return code * Return code
* 0 - successfully issued REG_VFI for @vport * 0 - successfully issued REG_VFI for @vport
* A failure code otherwise. * A failure code otherwise.
**/ **/
static int int
lpfc_issue_reg_vfi(struct lpfc_vport *vport) lpfc_issue_reg_vfi(struct lpfc_vport *vport)
{ {
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
...@@ -438,10 +438,14 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport) ...@@ -438,10 +438,14 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport)
int rc = 0; int rc = 0;
sp = &phba->fc_fabparam; sp = &phba->fc_fabparam;
ndlp = lpfc_findnode_did(vport, Fabric_DID); /* move forward in case of SLI4 FC port loopback test */
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { if ((phba->sli_rev == LPFC_SLI_REV4) &&
rc = -ENODEV; !(phba->link_flag & LS_LOOPBACK_MODE)) {
goto fail; ndlp = lpfc_findnode_did(vport, Fabric_DID);
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
rc = -ENODEV;
goto fail;
}
} }
dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
...@@ -486,6 +490,54 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport) ...@@ -486,6 +490,54 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport)
return rc; return rc;
} }
/**
* lpfc_issue_unreg_vfi - Unregister VFI for this vport's fabric login
* @vport: pointer to a host virtual N_Port data structure.
*
* This routine issues a UNREG_VFI mailbox with the vfi, vpi, fcfi triplet for
* the @vport. This mailbox command is necessary for SLI4 port only.
*
* Return code
* 0 - successfully issued REG_VFI for @vport
* A failure code otherwise.
**/
int
lpfc_issue_unreg_vfi(struct lpfc_vport *vport)
{
struct lpfc_hba *phba = vport->phba;
struct Scsi_Host *shost;
LPFC_MBOXQ_t *mboxq;
int rc;
mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!mboxq) {
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
"2556 UNREG_VFI mbox allocation failed"
"HBA state x%x\n", phba->pport->port_state);
return -ENOMEM;
}
lpfc_unreg_vfi(mboxq, vport);
mboxq->vport = vport;
mboxq->mbox_cmpl = lpfc_unregister_vfi_cmpl;
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
if (rc == MBX_NOT_FINISHED) {
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
"2557 UNREG_VFI issue mbox failed rc x%x "
"HBA state x%x\n",
rc, phba->pport->port_state);
mempool_free(mboxq, phba->mbox_mem_pool);
return -EIO;
}
shost = lpfc_shost_from_vport(vport);
spin_lock_irq(shost->host_lock);
vport->fc_flag &= ~FC_VFI_REGISTERED;
spin_unlock_irq(shost->host_lock);
return 0;
}
/** /**
* lpfc_check_clean_addr_bit - Check whether assigned FCID is clean. * lpfc_check_clean_addr_bit - Check whether assigned FCID is clean.
* @vport: pointer to a host virtual N_Port data structure. * @vport: pointer to a host virtual N_Port data structure.
...@@ -615,7 +667,9 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -615,7 +667,9 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
"1816 FLOGI NPIV supported, " "1816 FLOGI NPIV supported, "
"response data 0x%x\n", "response data 0x%x\n",
sp->cmn.response_multiple_NPort); sp->cmn.response_multiple_NPort);
spin_lock_irq(&phba->hbalock);
phba->link_flag |= LS_NPIV_FAB_SUPPORTED; phba->link_flag |= LS_NPIV_FAB_SUPPORTED;
spin_unlock_irq(&phba->hbalock);
} else { } else {
/* Because we asked f/w for NPIV it still expects us /* Because we asked f/w for NPIV it still expects us
to call reg_vnpid atleast for the physcial host */ to call reg_vnpid atleast for the physcial host */
...@@ -623,7 +677,9 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -623,7 +677,9 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
LOG_ELS | LOG_VPORT, LOG_ELS | LOG_VPORT,
"1817 Fabric does not support NPIV " "1817 Fabric does not support NPIV "
"- configuring single port mode.\n"); "- configuring single port mode.\n");
spin_lock_irq(&phba->hbalock);
phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED; phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED;
spin_unlock_irq(&phba->hbalock);
} }
} }
...@@ -686,11 +742,16 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -686,11 +742,16 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
lpfc_do_scr_ns_plogi(phba, vport); lpfc_do_scr_ns_plogi(phba, vport);
} else if (vport->fc_flag & FC_VFI_REGISTERED) } else if (vport->fc_flag & FC_VFI_REGISTERED)
lpfc_issue_init_vpi(vport); lpfc_issue_init_vpi(vport);
else else {
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
"3135 Need register VFI: (x%x/%x)\n",
vport->fc_prevDID, vport->fc_myDID);
lpfc_issue_reg_vfi(vport); lpfc_issue_reg_vfi(vport);
}
} }
return 0; return 0;
} }
/** /**
* lpfc_cmpl_els_flogi_nport - Completion function for flogi to an N_Port * lpfc_cmpl_els_flogi_nport - Completion function for flogi to an N_Port
* @vport: pointer to a host virtual N_Port data structure. * @vport: pointer to a host virtual N_Port data structure.
...@@ -907,17 +968,16 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -907,17 +968,16 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
* LPFC_MAX_DISC_THREADS (32). Scanning in the case of no * LPFC_MAX_DISC_THREADS (32). Scanning in the case of no
* alpa map would take too long otherwise. * alpa map would take too long otherwise.
*/ */
if (phba->alpa_map[0] == 0) { if (phba->alpa_map[0] == 0)
vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS; vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
if ((phba->sli_rev == LPFC_SLI_REV4) && if ((phba->sli_rev == LPFC_SLI_REV4) &&
(!(vport->fc_flag & FC_VFI_REGISTERED) || (!(vport->fc_flag & FC_VFI_REGISTERED) ||
(vport->fc_prevDID != vport->fc_myDID))) { (vport->fc_prevDID != vport->fc_myDID))) {
if (vport->fc_flag & FC_VFI_REGISTERED) if (vport->fc_flag & FC_VFI_REGISTERED)
lpfc_sli4_unreg_all_rpis(vport); lpfc_sli4_unreg_all_rpis(vport);
lpfc_issue_reg_vfi(vport); lpfc_issue_reg_vfi(vport);
lpfc_nlp_put(ndlp); lpfc_nlp_put(ndlp);
goto out; goto out;
}
} }
goto flogifail; goto flogifail;
} }
...@@ -1075,6 +1135,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -1075,6 +1135,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
/* Setup CSPs accordingly for Fabric */ /* Setup CSPs accordingly for Fabric */
sp->cmn.e_d_tov = 0; sp->cmn.e_d_tov = 0;
sp->cmn.w2.r_a_tov = 0; sp->cmn.w2.r_a_tov = 0;
sp->cmn.virtual_fabric_support = 0;
sp->cls1.classValid = 0; sp->cls1.classValid = 0;
sp->cls2.seqDelivery = 1; sp->cls2.seqDelivery = 1;
sp->cls3.seqDelivery = 1; sp->cls3.seqDelivery = 1;
...@@ -1163,8 +1224,7 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba) ...@@ -1163,8 +1224,7 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba)
spin_lock_irq(&phba->hbalock); spin_lock_irq(&phba->hbalock);
list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
icmd = &iocb->iocb; icmd = &iocb->iocb;
if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR && if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR) {
icmd->un.elsreq64.bdl.ulpIoTag32) {
ndlp = (struct lpfc_nodelist *)(iocb->context1); ndlp = (struct lpfc_nodelist *)(iocb->context1);
if (ndlp && NLP_CHK_NODE_ACT(ndlp) && if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
(ndlp->nlp_DID == Fabric_DID)) (ndlp->nlp_DID == Fabric_DID))
...@@ -3066,17 +3126,22 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -3066,17 +3126,22 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if (did == FDMI_DID) if (did == FDMI_DID)
retry = 1; retry = 1;
if (((cmd == ELS_CMD_FLOGI) || (cmd == ELS_CMD_FDISC)) && if ((cmd == ELS_CMD_FLOGI) &&
(phba->fc_topology != LPFC_TOPOLOGY_LOOP) && (phba->fc_topology != LPFC_TOPOLOGY_LOOP) &&
!lpfc_error_lost_link(irsp)) { !lpfc_error_lost_link(irsp)) {
/* FLOGI retry policy */ /* FLOGI retry policy */
retry = 1; retry = 1;
/* retry forever */ /* retry FLOGI forever */
maxretry = 0; maxretry = 0;
if (cmdiocb->retry >= 100) if (cmdiocb->retry >= 100)
delay = 5000; delay = 5000;
else if (cmdiocb->retry >= 32) else if (cmdiocb->retry >= 32)
delay = 1000; delay = 1000;
} else if ((cmd == ELS_CMD_FDISC) && !lpfc_error_lost_link(irsp)) {
/* retry FDISCs every second up to devloss */
retry = 1;
maxretry = vport->cfg_devloss_tmo;
delay = 1000;
} }
cmdiocb->retry++; cmdiocb->retry++;
...@@ -3389,11 +3454,17 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -3389,11 +3454,17 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
/* /*
* The driver received a LOGO from the rport and has ACK'd it. * The driver received a LOGO from the rport and has ACK'd it.
* At this point, the driver is done so release the IOCB and * At this point, the driver is done so release the IOCB
* remove the ndlp reference.
*/ */
lpfc_els_free_iocb(phba, cmdiocb); lpfc_els_free_iocb(phba, cmdiocb);
lpfc_nlp_put(ndlp);
/*
* Remove the ndlp reference if it's a fabric node that has
* sent us an unsolicted LOGO.
*/
if (ndlp->nlp_type & NLP_FABRIC)
lpfc_nlp_put(ndlp);
return; return;
} }
...@@ -4867,23 +4938,31 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, ...@@ -4867,23 +4938,31 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
sizeof(struct lpfc_name)); sizeof(struct lpfc_name));
if (!rc) { if (!rc) {
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (phba->sli_rev < LPFC_SLI_REV4) {
if (!mbox) mbox = mempool_alloc(phba->mbox_mem_pool,
GFP_KERNEL);
if (!mbox)
return 1;
lpfc_linkdown(phba);
lpfc_init_link(phba, mbox,
phba->cfg_topology,
phba->cfg_link_speed);
mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0;
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
mbox->vport = vport;
rc = lpfc_sli_issue_mbox(phba, mbox,
MBX_NOWAIT);
lpfc_set_loopback_flag(phba);
if (rc == MBX_NOT_FINISHED)
mempool_free(mbox, phba->mbox_mem_pool);
return 1; return 1;
} else {
lpfc_linkdown(phba); /* abort the flogi coming back to ourselves
lpfc_init_link(phba, mbox, * due to external loopback on the port.
phba->cfg_topology, */
phba->cfg_link_speed); lpfc_els_abort_flogi(phba);
mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0; return 0;
mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
mbox->vport = vport;
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
lpfc_set_loopback_flag(phba);
if (rc == MBX_NOT_FINISHED) {
mempool_free(mbox, phba->mbox_mem_pool);
} }
return 1;
} else if (rc > 0) { /* greater than */ } else if (rc > 0) { /* greater than */
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
vport->fc_flag |= FC_PT2PT_PLOGI; vport->fc_flag |= FC_PT2PT_PLOGI;
...@@ -5838,8 +5917,12 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, ...@@ -5838,8 +5917,12 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
vport->fc_myDID = vport->fc_prevDID; vport->fc_myDID = vport->fc_prevDID;
if (phba->sli_rev < LPFC_SLI_REV4) if (phba->sli_rev < LPFC_SLI_REV4)
lpfc_issue_fabric_reglogin(vport); lpfc_issue_fabric_reglogin(vport);
else else {
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
"3138 Need register VFI: (x%x/%x)\n",
vport->fc_prevDID, vport->fc_myDID);
lpfc_issue_reg_vfi(vport); lpfc_issue_reg_vfi(vport);
}
} }
} }
return 0; return 0;
...@@ -6595,56 +6678,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -6595,56 +6678,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
phba->fc_stat.elsRcvDrop++; phba->fc_stat.elsRcvDrop++;
} }
/**
* lpfc_find_vport_by_vpid - Find a vport on a HBA through vport identifier
* @phba: pointer to lpfc hba data structure.
* @vpi: host virtual N_Port identifier.
*
* This routine finds a vport on a HBA (referred by @phba) through a
* @vpi. The function walks the HBA's vport list and returns the address
* of the vport with the matching @vpi.
*
* Return code
* NULL - No vport with the matching @vpi found
* Otherwise - Address to the vport with the matching @vpi.
**/
struct lpfc_vport *
lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
{
struct lpfc_vport *vport;
unsigned long flags;
int i = 0;
/* The physical ports are always vpi 0 - translate is unnecessary. */
if (vpi > 0) {
/*
* Translate the physical vpi to the logical vpi. The
* vport stores the logical vpi.
*/
for (i = 0; i < phba->max_vpi; i++) {
if (vpi == phba->vpi_ids[i])
break;
}
if (i >= phba->max_vpi) {
lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
"2936 Could not find Vport mapped "
"to vpi %d\n", vpi);
return NULL;
}
}
spin_lock_irqsave(&phba->hbalock, flags);
list_for_each_entry(vport, &phba->port_list, listentry) {
if (vport->vpi == i) {
spin_unlock_irqrestore(&phba->hbalock, flags);
return vport;
}
}
spin_unlock_irqrestore(&phba->hbalock, flags);
return NULL;
}
/** /**
* lpfc_els_unsol_event - Process an unsolicited event from an els sli ring * lpfc_els_unsol_event - Process an unsolicited event from an els sli ring
* @phba: pointer to lpfc hba data structure. * @phba: pointer to lpfc hba data structure.
...@@ -7281,6 +7314,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -7281,6 +7314,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
/* Setup CSPs accordingly for Fabric */ /* Setup CSPs accordingly for Fabric */
sp->cmn.e_d_tov = 0; sp->cmn.e_d_tov = 0;
sp->cmn.w2.r_a_tov = 0; sp->cmn.w2.r_a_tov = 0;
sp->cmn.virtual_fabric_support = 0;
sp->cls1.classValid = 0; sp->cls1.classValid = 0;
sp->cls2.seqDelivery = 1; sp->cls2.seqDelivery = 1;
sp->cls3.seqDelivery = 1; sp->cls3.seqDelivery = 1;
......
...@@ -1074,6 +1074,12 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ...@@ -1074,6 +1074,12 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
mempool_free(pmb, phba->mbox_mem_pool); mempool_free(pmb, phba->mbox_mem_pool);
/* don't perform discovery for SLI4 loopback diagnostic test */
if ((phba->sli_rev == LPFC_SLI_REV4) &&
!(phba->hba_flag & HBA_FCOE_MODE) &&
(phba->link_flag & LS_LOOPBACK_MODE))
return;
if (phba->fc_topology == LPFC_TOPOLOGY_LOOP && if (phba->fc_topology == LPFC_TOPOLOGY_LOOP &&
vport->fc_flag & FC_PUBLIC_LOOP && vport->fc_flag & FC_PUBLIC_LOOP &&
!(vport->fc_flag & FC_LBIT)) { !(vport->fc_flag & FC_LBIT)) {
...@@ -2646,9 +2652,14 @@ lpfc_init_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) ...@@ -2646,9 +2652,14 @@ lpfc_init_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
{ {
struct lpfc_vport *vport = mboxq->vport; struct lpfc_vport *vport = mboxq->vport;
/* VFI not supported on interface type 0, just do the flogi */ /*
if (mboxq->u.mb.mbxStatus && (bf_get(lpfc_sli_intf_if_type, * VFI not supported on interface type 0, just do the flogi
&phba->sli4_hba.sli_intf) != LPFC_SLI_INTF_IF_TYPE_0)) { * Also continue if the VFI is in use - just use the same one.
*/
if (mboxq->u.mb.mbxStatus &&
(bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
LPFC_SLI_INTF_IF_TYPE_0) &&
mboxq->u.mb.mbxStatus != MBX_VFI_IN_USE) {
lpfc_printf_vlog(vport, KERN_ERR, lpfc_printf_vlog(vport, KERN_ERR,
LOG_MBOX, LOG_MBOX,
"2891 Init VFI mailbox failed 0x%x\n", "2891 Init VFI mailbox failed 0x%x\n",
...@@ -2842,10 +2853,10 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) ...@@ -2842,10 +2853,10 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
lpfc_disc_list_loopmap(vport); lpfc_disc_list_loopmap(vport);
/* Start discovery */ /* Start discovery */
lpfc_disc_start(vport); lpfc_disc_start(vport);
goto fail_free_mem; goto out_free_mem;
} }
lpfc_vport_set_state(vport, FC_VPORT_FAILED); lpfc_vport_set_state(vport, FC_VPORT_FAILED);
goto fail_free_mem; goto out_free_mem;
} }
/* The VPI is implicitly registered when the VFI is registered */ /* The VPI is implicitly registered when the VFI is registered */
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
...@@ -2855,10 +2866,16 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) ...@@ -2855,10 +2866,16 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI;
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
/* In case SLI4 FC loopback test, we are ready */
if ((phba->sli_rev == LPFC_SLI_REV4) &&
(phba->link_flag & LS_LOOPBACK_MODE)) {
phba->link_state = LPFC_HBA_READY;
goto out_free_mem;
}
if (vport->port_state == LPFC_FABRIC_CFG_LINK) { if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
/* For private loop just start discovery and we are done. */ /* For private loop just start discovery and we are done. */
if ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) && if ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
(phba->alpa_map[0] == 0) &&
!(vport->fc_flag & FC_PUBLIC_LOOP)) { !(vport->fc_flag & FC_PUBLIC_LOOP)) {
/* Use loop map to make discovery list */ /* Use loop map to make discovery list */
lpfc_disc_list_loopmap(vport); lpfc_disc_list_loopmap(vport);
...@@ -2870,7 +2887,7 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) ...@@ -2870,7 +2887,7 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
} }
} }
fail_free_mem: out_free_mem:
mempool_free(mboxq, phba->mbox_mem_pool); mempool_free(mboxq, phba->mbox_mem_pool);
lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys);
kfree(dmabuf); kfree(dmabuf);
...@@ -2923,6 +2940,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) ...@@ -2923,6 +2940,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
{ {
struct lpfc_vport *vport = phba->pport; struct lpfc_vport *vport = phba->pport;
LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox = NULL; LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox = NULL;
struct Scsi_Host *shost;
int i; int i;
struct lpfc_dmabuf *mp; struct lpfc_dmabuf *mp;
int rc; int rc;
...@@ -2946,6 +2964,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) ...@@ -2946,6 +2964,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
phba->fc_topology = bf_get(lpfc_mbx_read_top_topology, la); phba->fc_topology = bf_get(lpfc_mbx_read_top_topology, la);
phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED; phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED;
shost = lpfc_shost_from_vport(vport);
if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) { if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED; phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;
...@@ -2957,8 +2976,11 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) ...@@ -2957,8 +2976,11 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
"1309 Link Up Event npiv not supported in loop " "1309 Link Up Event npiv not supported in loop "
"topology\n"); "topology\n");
/* Get Loop Map information */ /* Get Loop Map information */
if (bf_get(lpfc_mbx_read_top_il, la)) if (bf_get(lpfc_mbx_read_top_il, la)) {
spin_lock_irq(shost->host_lock);
vport->fc_flag |= FC_LBIT; vport->fc_flag |= FC_LBIT;
spin_unlock_irq(shost->host_lock);
}
vport->fc_myDID = bf_get(lpfc_mbx_read_top_alpa_granted, la); vport->fc_myDID = bf_get(lpfc_mbx_read_top_alpa_granted, la);
i = la->lilpBde64.tus.f.bdeSize; i = la->lilpBde64.tus.f.bdeSize;
...@@ -3003,11 +3025,13 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) ...@@ -3003,11 +3025,13 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
} else { } else {
if (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) { if (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) {
if (phba->max_vpi && phba->cfg_enable_npiv && if (phba->max_vpi && phba->cfg_enable_npiv &&
(phba->sli_rev == 3)) (phba->sli_rev >= LPFC_SLI_REV3))
phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED; phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED;
} }
vport->fc_myDID = phba->fc_pref_DID; vport->fc_myDID = phba->fc_pref_DID;
spin_lock_irq(shost->host_lock);
vport->fc_flag |= FC_LBIT; vport->fc_flag |= FC_LBIT;
spin_unlock_irq(shost->host_lock);
} }
spin_unlock_irq(&phba->hbalock); spin_unlock_irq(&phba->hbalock);
...@@ -3224,15 +3248,14 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ...@@ -3224,15 +3248,14 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
} else if (bf_get(lpfc_mbx_read_top_att_type, la) == } else if (bf_get(lpfc_mbx_read_top_att_type, la) ==
LPFC_ATT_LINK_DOWN) { LPFC_ATT_LINK_DOWN) {
phba->fc_stat.LinkDown++; phba->fc_stat.LinkDown++;
if (phba->link_flag & LS_LOOPBACK_MODE) { if (phba->link_flag & LS_LOOPBACK_MODE)
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
"1308 Link Down Event in loop back mode " "1308 Link Down Event in loop back mode "
"x%x received " "x%x received "
"Data: x%x x%x x%x\n", "Data: x%x x%x x%x\n",
la->eventTag, phba->fc_eventTag, la->eventTag, phba->fc_eventTag,
phba->pport->port_state, vport->fc_flag); phba->pport->port_state, vport->fc_flag);
} else
else {
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
"1305 Link Down Event x%x received " "1305 Link Down Event x%x received "
"Data: x%x x%x x%x x%x x%x\n", "Data: x%x x%x x%x x%x x%x\n",
...@@ -3240,7 +3263,6 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ...@@ -3240,7 +3263,6 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
phba->pport->port_state, vport->fc_flag, phba->pport->port_state, vport->fc_flag,
bf_get(lpfc_mbx_read_top_mm, la), bf_get(lpfc_mbx_read_top_mm, la),
bf_get(lpfc_mbx_read_top_fa, la)); bf_get(lpfc_mbx_read_top_fa, la));
}
lpfc_mbx_issue_link_down(phba); lpfc_mbx_issue_link_down(phba);
} }
if ((bf_get(lpfc_mbx_read_top_mm, la)) && if ((bf_get(lpfc_mbx_read_top_mm, la)) &&
...@@ -3594,6 +3616,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ...@@ -3594,6 +3616,7 @@ lpfc_mbx_cmpl_fabric_reg_login(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_nodelist *ndlp; struct lpfc_nodelist *ndlp;
struct Scsi_Host *shost;
ndlp = (struct lpfc_nodelist *) pmb->context2; ndlp = (struct lpfc_nodelist *) pmb->context2;
pmb->context1 = NULL; pmb->context1 = NULL;
...@@ -3639,8 +3662,12 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ...@@ -3639,8 +3662,12 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
* vport discovery */ * vport discovery */
if (!(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG)) if (!(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG))
lpfc_start_fdiscs(phba); lpfc_start_fdiscs(phba);
else else {
shost = lpfc_shost_from_vport(vport);
spin_lock_irq(shost->host_lock);
vport->fc_flag &= ~FC_LOGO_RCVD_DID_CHNG ; vport->fc_flag &= ~FC_LOGO_RCVD_DID_CHNG ;
spin_unlock_irq(shost->host_lock);
}
lpfc_do_scr_ns_plogi(phba, vport); lpfc_do_scr_ns_plogi(phba, vport);
} }
...@@ -5353,6 +5380,73 @@ lpfc_findnode_wwpn(struct lpfc_vport *vport, struct lpfc_name *wwpn) ...@@ -5353,6 +5380,73 @@ lpfc_findnode_wwpn(struct lpfc_vport *vport, struct lpfc_name *wwpn)
return ndlp; return ndlp;
} }
/*
* This routine looks up the ndlp lists for the given RPI. If the rpi
* is found, the routine returns the node element list pointer else
* return NULL.
*/
struct lpfc_nodelist *
lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi)
{
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_nodelist *ndlp;
spin_lock_irq(shost->host_lock);
ndlp = __lpfc_findnode_rpi(vport, rpi);
spin_unlock_irq(shost->host_lock);
return ndlp;
}
/**
* lpfc_find_vport_by_vpid - Find a vport on a HBA through vport identifier
* @phba: pointer to lpfc hba data structure.
* @vpi: the physical host virtual N_Port identifier.
*
* This routine finds a vport on a HBA (referred by @phba) through a
* @vpi. The function walks the HBA's vport list and returns the address
* of the vport with the matching @vpi.
*
* Return code
* NULL - No vport with the matching @vpi found
* Otherwise - Address to the vport with the matching @vpi.
**/
struct lpfc_vport *
lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
{
struct lpfc_vport *vport;
unsigned long flags;
int i = 0;
/* The physical ports are always vpi 0 - translate is unnecessary. */
if (vpi > 0) {
/*
* Translate the physical vpi to the logical vpi. The
* vport stores the logical vpi.
*/
for (i = 0; i < phba->max_vpi; i++) {
if (vpi == phba->vpi_ids[i])
break;
}
if (i >= phba->max_vpi) {
lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
"2936 Could not find Vport mapped "
"to vpi %d\n", vpi);
return NULL;
}
}
spin_lock_irqsave(&phba->hbalock, flags);
list_for_each_entry(vport, &phba->port_list, listentry) {
if (vport->vpi == i) {
spin_unlock_irqrestore(&phba->hbalock, flags);
return vport;
}
}
spin_unlock_irqrestore(&phba->hbalock, flags);
return NULL;
}
void void
lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
uint32_t did) uint32_t did)
...@@ -5599,7 +5693,7 @@ lpfc_fcf_inuse(struct lpfc_hba *phba) ...@@ -5599,7 +5693,7 @@ lpfc_fcf_inuse(struct lpfc_hba *phba)
* *
* This function frees memory associated with the mailbox command. * This function frees memory associated with the mailbox command.
*/ */
static void void
lpfc_unregister_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) lpfc_unregister_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
{ {
struct lpfc_vport *vport = mboxq->vport; struct lpfc_vport *vport = mboxq->vport;
...@@ -5651,7 +5745,6 @@ lpfc_unregister_fcfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) ...@@ -5651,7 +5745,6 @@ lpfc_unregister_fcfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
int int
lpfc_unregister_fcf_prep(struct lpfc_hba *phba) lpfc_unregister_fcf_prep(struct lpfc_hba *phba)
{ {
LPFC_MBOXQ_t *mbox;
struct lpfc_vport **vports; struct lpfc_vport **vports;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
struct Scsi_Host *shost; struct Scsi_Host *shost;
...@@ -5687,35 +5780,9 @@ lpfc_unregister_fcf_prep(struct lpfc_hba *phba) ...@@ -5687,35 +5780,9 @@ lpfc_unregister_fcf_prep(struct lpfc_hba *phba)
/* Cleanup any outstanding ELS commands */ /* Cleanup any outstanding ELS commands */
lpfc_els_flush_all_cmd(phba); lpfc_els_flush_all_cmd(phba);
/* Unregister VFI */ /* Unregister the physical port VFI */
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); rc = lpfc_issue_unreg_vfi(phba->pport);
if (!mbox) { return rc;
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
"2556 UNREG_VFI mbox allocation failed"
"HBA state x%x\n", phba->pport->port_state);
return -ENOMEM;
}
lpfc_unreg_vfi(mbox, phba->pport);
mbox->vport = phba->pport;
mbox->mbox_cmpl = lpfc_unregister_vfi_cmpl;
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
if (rc == MBX_NOT_FINISHED) {
lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
"2557 UNREG_VFI issue mbox failed rc x%x "
"HBA state x%x\n",
rc, phba->pport->port_state);
mempool_free(mbox, phba->mbox_mem_pool);
return -EIO;
}
shost = lpfc_shost_from_vport(phba->pport);
spin_lock_irq(shost->host_lock);
phba->pport->fc_flag &= ~FC_VFI_REGISTERED;
spin_unlock_irq(shost->host_lock);
return 0;
} }
/** /**
......
...@@ -349,6 +349,12 @@ struct csp { ...@@ -349,6 +349,12 @@ struct csp {
* Word 1 Bit 31 in FLOGI response is clean address bit * Word 1 Bit 31 in FLOGI response is clean address bit
*/ */
#define clean_address_bit request_multiple_Nport /* Word 1, bit 31 */ #define clean_address_bit request_multiple_Nport /* Word 1, bit 31 */
/*
* Word 1 Bit 30 in common service parameter is overloaded.
* Word 1 Bit 30 in FLOGI request is Virtual Fabrics
* Word 1 Bit 30 in PLOGI request is random offset
*/
#define virtual_fabric_support randomOffset /* Word 1, bit 30 */
#ifdef __BIG_ENDIAN_BITFIELD #ifdef __BIG_ENDIAN_BITFIELD
uint16_t request_multiple_Nport:1; /* FC Word 1, bit 31 */ uint16_t request_multiple_Nport:1; /* FC Word 1, bit 31 */
uint16_t randomOffset:1; /* FC Word 1, bit 30 */ uint16_t randomOffset:1; /* FC Word 1, bit 30 */
...@@ -1852,8 +1858,8 @@ typedef struct { ...@@ -1852,8 +1858,8 @@ typedef struct {
uint8_t fabric_AL_PA; /* If using a Fabric Assigned AL_PA */ uint8_t fabric_AL_PA; /* If using a Fabric Assigned AL_PA */
#endif #endif
#define FLAGS_LOCAL_LB 0x01 /* link_flags (=1) ENDEC loopback */
#define FLAGS_TOPOLOGY_MODE_LOOP_PT 0x00 /* Attempt loop then pt-pt */ #define FLAGS_TOPOLOGY_MODE_LOOP_PT 0x00 /* Attempt loop then pt-pt */
#define FLAGS_LOCAL_LB 0x01 /* link_flags (=1) ENDEC loopback */
#define FLAGS_TOPOLOGY_MODE_PT_PT 0x02 /* Attempt pt-pt only */ #define FLAGS_TOPOLOGY_MODE_PT_PT 0x02 /* Attempt pt-pt only */
#define FLAGS_TOPOLOGY_MODE_LOOP 0x04 /* Attempt loop only */ #define FLAGS_TOPOLOGY_MODE_LOOP 0x04 /* Attempt loop only */
#define FLAGS_TOPOLOGY_MODE_PT_LOOP 0x06 /* Attempt pt-pt then loop */ #define FLAGS_TOPOLOGY_MODE_PT_LOOP 0x06 /* Attempt pt-pt then loop */
...@@ -2819,7 +2825,8 @@ typedef struct { ...@@ -2819,7 +2825,8 @@ typedef struct {
#ifdef __BIG_ENDIAN_BITFIELD #ifdef __BIG_ENDIAN_BITFIELD
uint32_t rsvd1 : 19; /* Reserved */ uint32_t rsvd1 : 19; /* Reserved */
uint32_t cdss : 1; /* Configure Data Security SLI */ uint32_t cdss : 1; /* Configure Data Security SLI */
uint32_t rsvd2 : 3; /* Reserved */ uint32_t casabt : 1; /* Configure async abts status notice */
uint32_t rsvd2 : 2; /* Reserved */
uint32_t cbg : 1; /* Configure BlockGuard */ uint32_t cbg : 1; /* Configure BlockGuard */
uint32_t cmv : 1; /* Configure Max VPIs */ uint32_t cmv : 1; /* Configure Max VPIs */
uint32_t ccrp : 1; /* Config Command Ring Polling */ uint32_t ccrp : 1; /* Config Command Ring Polling */
...@@ -2839,14 +2846,16 @@ typedef struct { ...@@ -2839,14 +2846,16 @@ typedef struct {
uint32_t ccrp : 1; /* Config Command Ring Polling */ uint32_t ccrp : 1; /* Config Command Ring Polling */
uint32_t cmv : 1; /* Configure Max VPIs */ uint32_t cmv : 1; /* Configure Max VPIs */
uint32_t cbg : 1; /* Configure BlockGuard */ uint32_t cbg : 1; /* Configure BlockGuard */
uint32_t rsvd2 : 3; /* Reserved */ uint32_t rsvd2 : 2; /* Reserved */
uint32_t casabt : 1; /* Configure async abts status notice */
uint32_t cdss : 1; /* Configure Data Security SLI */ uint32_t cdss : 1; /* Configure Data Security SLI */
uint32_t rsvd1 : 19; /* Reserved */ uint32_t rsvd1 : 19; /* Reserved */
#endif #endif
#ifdef __BIG_ENDIAN_BITFIELD #ifdef __BIG_ENDIAN_BITFIELD
uint32_t rsvd3 : 19; /* Reserved */ uint32_t rsvd3 : 19; /* Reserved */
uint32_t gdss : 1; /* Configure Data Security SLI */ uint32_t gdss : 1; /* Configure Data Security SLI */
uint32_t rsvd4 : 3; /* Reserved */ uint32_t gasabt : 1; /* Grant async abts status notice */
uint32_t rsvd4 : 2; /* Reserved */
uint32_t gbg : 1; /* Grant BlockGuard */ uint32_t gbg : 1; /* Grant BlockGuard */
uint32_t gmv : 1; /* Grant Max VPIs */ uint32_t gmv : 1; /* Grant Max VPIs */
uint32_t gcrp : 1; /* Grant Command Ring Polling */ uint32_t gcrp : 1; /* Grant Command Ring Polling */
...@@ -2866,7 +2875,8 @@ typedef struct { ...@@ -2866,7 +2875,8 @@ typedef struct {
uint32_t gcrp : 1; /* Grant Command Ring Polling */ uint32_t gcrp : 1; /* Grant Command Ring Polling */
uint32_t gmv : 1; /* Grant Max VPIs */ uint32_t gmv : 1; /* Grant Max VPIs */
uint32_t gbg : 1; /* Grant BlockGuard */ uint32_t gbg : 1; /* Grant BlockGuard */
uint32_t rsvd4 : 3; /* Reserved */ uint32_t rsvd4 : 2; /* Reserved */
uint32_t gasabt : 1; /* Grant async abts status notice */
uint32_t gdss : 1; /* Configure Data Security SLI */ uint32_t gdss : 1; /* Configure Data Security SLI */
uint32_t rsvd3 : 19; /* Reserved */ uint32_t rsvd3 : 19; /* Reserved */
#endif #endif
...@@ -3465,6 +3475,7 @@ typedef struct { ...@@ -3465,6 +3475,7 @@ typedef struct {
} ASYNCSTAT_FIELDS; } ASYNCSTAT_FIELDS;
#define ASYNC_TEMP_WARN 0x100 #define ASYNC_TEMP_WARN 0x100
#define ASYNC_TEMP_SAFE 0x101 #define ASYNC_TEMP_SAFE 0x101
#define ASYNC_STATUS_CN 0x102
/* IOCB Command template for CMD_IOCB_RCV_ELS64_CX (0xB7) /* IOCB Command template for CMD_IOCB_RCV_ELS64_CX (0xB7)
or CMD_IOCB_RCV_SEQ64_CX (0xB5) */ or CMD_IOCB_RCV_SEQ64_CX (0xB5) */
......
...@@ -1351,11 +1351,11 @@ struct lpfc_mbx_set_link_diag_loopback { ...@@ -1351,11 +1351,11 @@ struct lpfc_mbx_set_link_diag_loopback {
struct { struct {
uint32_t word0; uint32_t word0;
#define lpfc_mbx_set_diag_lpbk_type_SHIFT 0 #define lpfc_mbx_set_diag_lpbk_type_SHIFT 0
#define lpfc_mbx_set_diag_lpbk_type_MASK 0x00000001 #define lpfc_mbx_set_diag_lpbk_type_MASK 0x00000003
#define lpfc_mbx_set_diag_lpbk_type_WORD word0 #define lpfc_mbx_set_diag_lpbk_type_WORD word0
#define LPFC_DIAG_LOOPBACK_TYPE_DISABLE 0x0 #define LPFC_DIAG_LOOPBACK_TYPE_DISABLE 0x0
#define LPFC_DIAG_LOOPBACK_TYPE_INTERNAL 0x1 #define LPFC_DIAG_LOOPBACK_TYPE_INTERNAL 0x1
#define LPFC_DIAG_LOOPBACK_TYPE_EXTERNAL 0x2 #define LPFC_DIAG_LOOPBACK_TYPE_SERDES 0x2
#define lpfc_mbx_set_diag_lpbk_link_num_SHIFT 16 #define lpfc_mbx_set_diag_lpbk_link_num_SHIFT 16
#define lpfc_mbx_set_diag_lpbk_link_num_MASK 0x0000003F #define lpfc_mbx_set_diag_lpbk_link_num_MASK 0x0000003F
#define lpfc_mbx_set_diag_lpbk_link_num_WORD word0 #define lpfc_mbx_set_diag_lpbk_link_num_WORD word0
...@@ -1830,6 +1830,8 @@ struct lpfc_mbx_init_vfi { ...@@ -1830,6 +1830,8 @@ struct lpfc_mbx_init_vfi {
#define lpfc_init_vfi_hop_count_MASK 0x000000FF #define lpfc_init_vfi_hop_count_MASK 0x000000FF
#define lpfc_init_vfi_hop_count_WORD word4 #define lpfc_init_vfi_hop_count_WORD word4
}; };
#define MBX_VFI_IN_USE 0x9F02
struct lpfc_mbx_reg_vfi { struct lpfc_mbx_reg_vfi {
uint32_t word1; uint32_t word1;
...@@ -2104,6 +2106,8 @@ struct lpfc_mbx_read_config { ...@@ -2104,6 +2106,8 @@ struct lpfc_mbx_read_config {
#define lpfc_mbx_rd_conf_lnk_type_SHIFT 6 #define lpfc_mbx_rd_conf_lnk_type_SHIFT 6
#define lpfc_mbx_rd_conf_lnk_type_MASK 0x00000003 #define lpfc_mbx_rd_conf_lnk_type_MASK 0x00000003
#define lpfc_mbx_rd_conf_lnk_type_WORD word2 #define lpfc_mbx_rd_conf_lnk_type_WORD word2
#define LPFC_LNK_TYPE_GE 0
#define LPFC_LNK_TYPE_FC 1
#define lpfc_mbx_rd_conf_lnk_ldv_SHIFT 8 #define lpfc_mbx_rd_conf_lnk_ldv_SHIFT 8
#define lpfc_mbx_rd_conf_lnk_ldv_MASK 0x00000001 #define lpfc_mbx_rd_conf_lnk_ldv_MASK 0x00000001
#define lpfc_mbx_rd_conf_lnk_ldv_WORD word2 #define lpfc_mbx_rd_conf_lnk_ldv_WORD word2
...@@ -3320,6 +3324,9 @@ struct wqe_rctl_dfctl { ...@@ -3320,6 +3324,9 @@ struct wqe_rctl_dfctl {
#define wqe_la_SHIFT 3 #define wqe_la_SHIFT 3
#define wqe_la_MASK 0x000000001 #define wqe_la_MASK 0x000000001
#define wqe_la_WORD word5 #define wqe_la_WORD word5
#define wqe_xo_SHIFT 6
#define wqe_xo_MASK 0x000000001
#define wqe_xo_WORD word5
#define wqe_ls_SHIFT 7 #define wqe_ls_SHIFT 7
#define wqe_ls_MASK 0x000000001 #define wqe_ls_MASK 0x000000001
#define wqe_ls_WORD word5 #define wqe_ls_WORD word5
......
此差异已折叠。
...@@ -1293,6 +1293,10 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ...@@ -1293,6 +1293,10 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
phba->sli_rev = LPFC_SLI_REV2; phba->sli_rev = LPFC_SLI_REV2;
mb->un.varCfgPort.sli_mode = phba->sli_rev; mb->un.varCfgPort.sli_mode = phba->sli_rev;
/* If this is an SLI3 port, configure async status notification. */
if (phba->sli_rev == LPFC_SLI_REV3)
mb->un.varCfgPort.casabt = 1;
/* Now setup pcb */ /* Now setup pcb */
phba->pcb->type = TYPE_NATIVE_SLI2; phba->pcb->type = TYPE_NATIVE_SLI2;
phba->pcb->feature = FEATURE_INITIAL_SLI2; phba->pcb->feature = FEATURE_INITIAL_SLI2;
...@@ -2129,6 +2133,14 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys) ...@@ -2129,6 +2133,14 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys)
reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam); reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam);
reg_vfi->bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64; reg_vfi->bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64;
bf_set(lpfc_reg_vfi_nport_id, reg_vfi, vport->fc_myDID); bf_set(lpfc_reg_vfi_nport_id, reg_vfi, vport->fc_myDID);
lpfc_printf_vlog(vport, KERN_INFO, LOG_MBOX,
"3134 Register VFI, mydid:x%x, fcfi:%d, "
" vfi:%d, vpi:%d, fc_pname:%x%x\n",
vport->fc_myDID,
vport->phba->fcf.fcfi,
vport->phba->sli4_hba.vfi_ids[vport->vfi],
vport->phba->vpi_ids[vport->vpi],
reg_vfi->wwn[0], reg_vfi->wwn[1]);
} }
/** /**
...@@ -2175,16 +2187,15 @@ lpfc_unreg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport) ...@@ -2175,16 +2187,15 @@ lpfc_unreg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport)
} }
/** /**
* lpfc_dump_fcoe_param - Dump config region 23 to get FCoe parameters. * lpfc_sli4_dump_cfg_rg23 - Dump sli4 port config region 23
* @phba: pointer to the hba structure containing. * @phba: pointer to the hba structure containing.
* @mbox: pointer to lpfc mbox command to initialize. * @mbox: pointer to lpfc mbox command to initialize.
* *
* This function create a SLI4 dump mailbox command to dump FCoE * This function create a SLI4 dump mailbox command to dump configure
* parameters stored in region 23. * region 23.
**/ **/
int int
lpfc_dump_fcoe_param(struct lpfc_hba *phba, lpfc_sli4_dump_cfg_rg23(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
struct lpfcMboxq *mbox)
{ {
struct lpfc_dmabuf *mp = NULL; struct lpfc_dmabuf *mp = NULL;
MAILBOX_t *mb; MAILBOX_t *mb;
...@@ -2198,9 +2209,9 @@ lpfc_dump_fcoe_param(struct lpfc_hba *phba, ...@@ -2198,9 +2209,9 @@ lpfc_dump_fcoe_param(struct lpfc_hba *phba,
if (!mp || !mp->virt) { if (!mp || !mp->virt) {
kfree(mp); kfree(mp);
/* dump_fcoe_param failed to allocate memory */ /* dump config region 23 failed to allocate memory */
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
"2569 lpfc_dump_fcoe_param: memory" "2569 lpfc dump config region 23: memory"
" allocation failed\n"); " allocation failed\n");
return 1; return 1;
} }
......
...@@ -389,7 +389,7 @@ lpfc_els_hbq_alloc(struct lpfc_hba *phba) ...@@ -389,7 +389,7 @@ lpfc_els_hbq_alloc(struct lpfc_hba *phba)
{ {
struct hbq_dmabuf *hbqbp; struct hbq_dmabuf *hbqbp;
hbqbp = kmalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL); hbqbp = kzalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL);
if (!hbqbp) if (!hbqbp)
return NULL; return NULL;
...@@ -441,7 +441,7 @@ lpfc_sli4_rb_alloc(struct lpfc_hba *phba) ...@@ -441,7 +441,7 @@ lpfc_sli4_rb_alloc(struct lpfc_hba *phba)
{ {
struct hbq_dmabuf *dma_buf; struct hbq_dmabuf *dma_buf;
dma_buf = kmalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL); dma_buf = kzalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL);
if (!dma_buf) if (!dma_buf)
return NULL; return NULL;
......
...@@ -782,6 +782,14 @@ lpfc_device_rm_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -782,6 +782,14 @@ lpfc_device_rm_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
return NLP_STE_FREED_NODE; return NLP_STE_FREED_NODE;
} }
static uint32_t
lpfc_device_recov_unused_node(struct lpfc_vport *vport,
struct lpfc_nodelist *ndlp,
void *arg, uint32_t evt)
{
return ndlp->nlp_state;
}
static uint32_t static uint32_t
lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
void *arg, uint32_t evt) void *arg, uint32_t evt)
...@@ -2147,7 +2155,7 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) ...@@ -2147,7 +2155,7 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
lpfc_disc_illegal, /* CMPL_ADISC */ lpfc_disc_illegal, /* CMPL_ADISC */
lpfc_disc_illegal, /* CMPL_REG_LOGIN */ lpfc_disc_illegal, /* CMPL_REG_LOGIN */
lpfc_device_rm_unused_node, /* DEVICE_RM */ lpfc_device_rm_unused_node, /* DEVICE_RM */
lpfc_disc_illegal, /* DEVICE_RECOVERY */ lpfc_device_recov_unused_node, /* DEVICE_RECOVERY */
lpfc_rcv_plogi_plogi_issue, /* RCV_PLOGI PLOGI_ISSUE */ lpfc_rcv_plogi_plogi_issue, /* RCV_PLOGI PLOGI_ISSUE */
lpfc_rcv_prli_plogi_issue, /* RCV_PRLI */ lpfc_rcv_prli_plogi_issue, /* RCV_PRLI */
......
...@@ -681,8 +681,10 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba, ...@@ -681,8 +681,10 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
rrq_empty = list_empty(&phba->active_rrq_list); rrq_empty = list_empty(&phba->active_rrq_list);
spin_unlock_irqrestore(&phba->hbalock, iflag); spin_unlock_irqrestore(&phba->hbalock, iflag);
if (ndlp) if (ndlp) {
lpfc_set_rrq_active(phba, ndlp, xri, rxid, 1); lpfc_set_rrq_active(phba, ndlp, xri, rxid, 1);
lpfc_sli4_abts_err_handler(phba, ndlp, axri);
}
lpfc_release_scsi_buf_s4(phba, psb); lpfc_release_scsi_buf_s4(phba, psb);
if (rrq_empty) if (rrq_empty)
lpfc_worker_wake_up(phba); lpfc_worker_wake_up(phba);
...@@ -2911,8 +2913,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, ...@@ -2911,8 +2913,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
int_to_scsilun(lpfc_cmd->pCmd->device->lun, int_to_scsilun(lpfc_cmd->pCmd->device->lun,
&lpfc_cmd->fcp_cmnd->fcp_lun); &lpfc_cmd->fcp_cmnd->fcp_lun);
memcpy(&fcp_cmnd->fcpCdb[0], scsi_cmnd->cmnd, 16); memset(&fcp_cmnd->fcpCdb[0], 0, LPFC_FCP_CDB_LEN);
memcpy(&fcp_cmnd->fcpCdb[0], scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
if (scsi_populate_tag_msg(scsi_cmnd, tag)) { if (scsi_populate_tag_msg(scsi_cmnd, tag)) {
switch (tag[0]) { switch (tag[0]) {
case HEAD_OF_QUEUE_TAG: case HEAD_OF_QUEUE_TAG:
...@@ -3236,6 +3238,15 @@ lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) ...@@ -3236,6 +3238,15 @@ lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
cmnd->result = err; cmnd->result = err;
goto out_fail_command; goto out_fail_command;
} }
/*
* Do not let the mid-layer retry I/O too fast. If an I/O is retried
* without waiting a bit then indicate that the device is busy.
*/
if (cmnd->retries &&
time_before(jiffies, (cmnd->jiffies_at_alloc +
msecs_to_jiffies(LPFC_RETRY_PAUSE *
cmnd->retries))))
return SCSI_MLQUEUE_DEVICE_BUSY;
ndlp = rdata->pnode; ndlp = rdata->pnode;
if ((scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) && if ((scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) &&
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <asm/byteorder.h> #include <asm/byteorder.h>
struct lpfc_hba; struct lpfc_hba;
#define LPFC_FCP_CDB_LEN 16
#define list_remove_head(list, entry, type, member) \ #define list_remove_head(list, entry, type, member) \
do { \ do { \
...@@ -102,7 +103,7 @@ struct fcp_cmnd { ...@@ -102,7 +103,7 @@ struct fcp_cmnd {
#define WRITE_DATA 0x01 /* Bit 0 */ #define WRITE_DATA 0x01 /* Bit 0 */
#define READ_DATA 0x02 /* Bit 1 */ #define READ_DATA 0x02 /* Bit 1 */
uint8_t fcpCdb[16]; /* SRB cdb field is copied here */ uint8_t fcpCdb[LPFC_FCP_CDB_LEN]; /* SRB cdb field is copied here */
uint32_t fcpDl; /* Total transfer length */ uint32_t fcpDl; /* Total transfer length */
}; };
...@@ -153,5 +154,5 @@ struct lpfc_scsi_buf { ...@@ -153,5 +154,5 @@ struct lpfc_scsi_buf {
#define LPFC_SCSI_DMA_EXT_SIZE 264 #define LPFC_SCSI_DMA_EXT_SIZE 264
#define LPFC_BPL_SIZE 1024 #define LPFC_BPL_SIZE 1024
#define LPFC_RETRY_PAUSE 300
#define MDAC_DIRECT_CMD 0x22 #define MDAC_DIRECT_CMD 0x22
此差异已折叠。
...@@ -291,7 +291,7 @@ struct lpfc_bmbx { ...@@ -291,7 +291,7 @@ struct lpfc_bmbx {
#define LPFC_RQE_SIZE 8 #define LPFC_RQE_SIZE 8
#define LPFC_EQE_DEF_COUNT 1024 #define LPFC_EQE_DEF_COUNT 1024
#define LPFC_CQE_DEF_COUNT 256 #define LPFC_CQE_DEF_COUNT 1024
#define LPFC_WQE_DEF_COUNT 256 #define LPFC_WQE_DEF_COUNT 256
#define LPFC_MQE_DEF_COUNT 16 #define LPFC_MQE_DEF_COUNT 16
#define LPFC_RQE_DEF_COUNT 512 #define LPFC_RQE_DEF_COUNT 512
...@@ -420,7 +420,16 @@ struct lpfc_sli4_hba { ...@@ -420,7 +420,16 @@ struct lpfc_sli4_hba {
void __iomem *STATUSregaddr; void __iomem *STATUSregaddr;
void __iomem *CTRLregaddr; void __iomem *CTRLregaddr;
void __iomem *ERR1regaddr; void __iomem *ERR1regaddr;
#define SLIPORT_ERR1_REG_ERR_CODE_1 0x1
#define SLIPORT_ERR1_REG_ERR_CODE_2 0x2
void __iomem *ERR2regaddr; void __iomem *ERR2regaddr;
#define SLIPORT_ERR2_REG_FW_RESTART 0x0
#define SLIPORT_ERR2_REG_FUNC_PROVISON 0x1
#define SLIPORT_ERR2_REG_FORCED_DUMP 0x2
#define SLIPORT_ERR2_REG_FAILURE_EQ 0x3
#define SLIPORT_ERR2_REG_FAILURE_CQ 0x4
#define SLIPORT_ERR2_REG_FAILURE_BUS 0x5
#define SLIPORT_ERR2_REG_FAILURE_RQ 0x6
} if_type2; } if_type2;
} u; } u;
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* included with this package. * * included with this package. *
*******************************************************************/ *******************************************************************/
#define LPFC_DRIVER_VERSION "8.3.27" #define LPFC_DRIVER_VERSION "8.3.28"
#define LPFC_DRIVER_NAME "lpfc" #define LPFC_DRIVER_NAME "lpfc"
#define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp"
#define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" #define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp"
......
...@@ -774,10 +774,10 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba) ...@@ -774,10 +774,10 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba)
return NULL; return NULL;
spin_lock_irq(&phba->hbalock); spin_lock_irq(&phba->hbalock);
list_for_each_entry(port_iterator, &phba->port_list, listentry) { list_for_each_entry(port_iterator, &phba->port_list, listentry) {
if (port_iterator->load_flag & FC_UNLOADING)
continue;
if (!scsi_host_get(lpfc_shost_from_vport(port_iterator))) { if (!scsi_host_get(lpfc_shost_from_vport(port_iterator))) {
if (!(port_iterator->load_flag & FC_UNLOADING)) lpfc_printf_vlog(port_iterator, KERN_ERR, LOG_VPORT,
lpfc_printf_vlog(port_iterator, KERN_ERR,
LOG_VPORT,
"1801 Create vport work array FAILED: " "1801 Create vport work array FAILED: "
"cannot do scsi_host_get\n"); "cannot do scsi_host_get\n");
continue; continue;
......
...@@ -291,8 +291,7 @@ int __init macscsi_detect(struct scsi_host_template * tpnt) ...@@ -291,8 +291,7 @@ int __init macscsi_detect(struct scsi_host_template * tpnt)
((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0; ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0;
if (instance->irq != SCSI_IRQ_NONE) if (instance->irq != SCSI_IRQ_NONE)
if (request_irq(instance->irq, NCR5380_intr, IRQ_FLG_SLOW, if (request_irq(instance->irq, NCR5380_intr, 0, "ncr5380", instance)) {
"ncr5380", instance)) {
printk(KERN_WARNING "scsi%d: IRQ%d not free, interrupts disabled\n", printk(KERN_WARNING "scsi%d: IRQ%d not free, interrupts disabled\n",
instance->host_no, instance->irq); instance->host_no, instance->irq);
instance->irq = SCSI_IRQ_NONE; instance->irq = SCSI_IRQ_NONE;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* scatter/gather formats. * scatter/gather formats.
* Creation Date: June 21, 2006 * Creation Date: June 21, 2006
* *
* mpi2.h Version: 02.00.20 * mpi2.h Version: 02.00.22
* *
* Version History * Version History
* --------------- * ---------------
...@@ -69,6 +69,8 @@ ...@@ -69,6 +69,8 @@
* 02-23-11 02.00.19 Bumped MPI2_HEADER_VERSION_UNIT. * 02-23-11 02.00.19 Bumped MPI2_HEADER_VERSION_UNIT.
* Added MPI2_FUNCTION_SEND_HOST_MESSAGE. * Added MPI2_FUNCTION_SEND_HOST_MESSAGE.
* 03-09-11 02.00.20 Bumped MPI2_HEADER_VERSION_UNIT. * 03-09-11 02.00.20 Bumped MPI2_HEADER_VERSION_UNIT.
* 05-25-11 02.00.21 Bumped MPI2_HEADER_VERSION_UNIT.
* 08-24-11 02.00.22 Bumped MPI2_HEADER_VERSION_UNIT.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -94,7 +96,7 @@ ...@@ -94,7 +96,7 @@
#define MPI2_VERSION_02_00 (0x0200) #define MPI2_VERSION_02_00 (0x0200)
/* versioning for this MPI header set */ /* versioning for this MPI header set */
#define MPI2_HEADER_VERSION_UNIT (0x14) #define MPI2_HEADER_VERSION_UNIT (0x16)
#define MPI2_HEADER_VERSION_DEV (0x00) #define MPI2_HEADER_VERSION_DEV (0x00)
#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
#define MPI2_HEADER_VERSION_UNIT_SHIFT (8) #define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
...@@ -1073,8 +1075,10 @@ typedef struct _MPI2_IEEE_SGE_UNION ...@@ -1073,8 +1075,10 @@ typedef struct _MPI2_IEEE_SGE_UNION
#define MPI2_IEEE_SGE_FLAGS_IOCPLB_ADDR (0x02) #define MPI2_IEEE_SGE_FLAGS_IOCPLB_ADDR (0x02)
#define MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR (0x03) #define MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR (0x03)
/* IEEE Simple Element only */ /* IEEE Simple Element only */
#define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR (0x03) #define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBPCI_ADDR (0x03)
/* IEEE Chain Element only */ /* IEEE Chain Element only */
#define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR \
(MPI2_IEEE_SGE_FLAGS_SYSTEMPLBPCI_ADDR) /* typo in name */
/**************************************************************************** /****************************************************************************
* IEEE SGE operation Macros * IEEE SGE operation Macros
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI Configuration messages and pages * Title: MPI Configuration messages and pages
* Creation Date: November 10, 2006 * Creation Date: November 10, 2006
* *
* mpi2_cnfg.h Version: 02.00.19 * mpi2_cnfg.h Version: 02.00.21
* *
* Version History * Version History
* --------------- * ---------------
...@@ -140,6 +140,13 @@ ...@@ -140,6 +140,13 @@
* Added SASNotifyPrimitiveMasks field to * Added SASNotifyPrimitiveMasks field to
* MPI2_CONFIG_PAGE_IOC_7. * MPI2_CONFIG_PAGE_IOC_7.
* 03-09-11 02.00.19 Fixed IO Unit Page 10 (to match the spec). * 03-09-11 02.00.19 Fixed IO Unit Page 10 (to match the spec).
* 05-25-11 02.00.20 Cleaned up a few comments.
* 08-24-11 02.00.21 Marked the IO Unit Page 7 PowerManagementCapabilities
* for PCIe link as obsolete.
* Added SpinupFlags field containing a Disable Spin-up
* bit to the MPI2_SAS_IOUNIT4_SPINUP_GROUP fields of
* SAS IO Unit Page 4.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -904,8 +911,8 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 { ...@@ -904,8 +911,8 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
#define MPI2_IOUNITPAGE7_PMCAP_12_5_PCT_IOCSPEED (0x00000400) #define MPI2_IOUNITPAGE7_PMCAP_12_5_PCT_IOCSPEED (0x00000400)
#define MPI2_IOUNITPAGE7_PMCAP_25_0_PCT_IOCSPEED (0x00000200) #define MPI2_IOUNITPAGE7_PMCAP_25_0_PCT_IOCSPEED (0x00000200)
#define MPI2_IOUNITPAGE7_PMCAP_50_0_PCT_IOCSPEED (0x00000100) #define MPI2_IOUNITPAGE7_PMCAP_50_0_PCT_IOCSPEED (0x00000100)
#define MPI2_IOUNITPAGE7_PMCAP_PCIE_WIDTH_CHANGE (0x00000008) #define MPI2_IOUNITPAGE7_PMCAP_PCIE_WIDTH_CHANGE (0x00000008) /* obsolete */
#define MPI2_IOUNITPAGE7_PMCAP_PCIE_SPEED_CHANGE (0x00000004) #define MPI2_IOUNITPAGE7_PMCAP_PCIE_SPEED_CHANGE (0x00000004) /* obsolete */
/* defines for IO Unit Page 7 IOCTemperatureUnits field */ /* defines for IO Unit Page 7 IOCTemperatureUnits field */
#define MPI2_IOUNITPAGE7_IOC_TEMP_NOT_PRESENT (0x00) #define MPI2_IOUNITPAGE7_IOC_TEMP_NOT_PRESENT (0x00)
...@@ -1970,10 +1977,14 @@ typedef struct _MPI2_SAS_IOUNIT4_SPINUP_GROUP ...@@ -1970,10 +1977,14 @@ typedef struct _MPI2_SAS_IOUNIT4_SPINUP_GROUP
{ {
U8 MaxTargetSpinup; /* 0x00 */ U8 MaxTargetSpinup; /* 0x00 */
U8 SpinupDelay; /* 0x01 */ U8 SpinupDelay; /* 0x01 */
U16 Reserved1; /* 0x02 */ U8 SpinupFlags; /* 0x02 */
U8 Reserved1; /* 0x03 */
} MPI2_SAS_IOUNIT4_SPINUP_GROUP, MPI2_POINTER PTR_MPI2_SAS_IOUNIT4_SPINUP_GROUP, } MPI2_SAS_IOUNIT4_SPINUP_GROUP, MPI2_POINTER PTR_MPI2_SAS_IOUNIT4_SPINUP_GROUP,
Mpi2SasIOUnit4SpinupGroup_t, MPI2_POINTER pMpi2SasIOUnit4SpinupGroup_t; Mpi2SasIOUnit4SpinupGroup_t, MPI2_POINTER pMpi2SasIOUnit4SpinupGroup_t;
/* defines for SAS IO Unit Page 4 SpinupFlags */
#define MPI2_SASIOUNIT4_SPINUP_DISABLE_FLAG (0x01)
/* /*
* Host code (drivers, BIOS, utilities, etc.) should leave this define set to * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
* one and check the value returned for NumPhys at runtime. * one and check the value returned for NumPhys at runtime.
...@@ -2321,13 +2332,12 @@ typedef struct _MPI2_CONFIG_PAGE_EXPANDER_1 ...@@ -2321,13 +2332,12 @@ typedef struct _MPI2_CONFIG_PAGE_EXPANDER_1
/* use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */ /* use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
/* use MPI2_SAS_APHYINFO_ defines for AttachedPhyInfo field */
/* values for SAS Expander Page 1 DiscoveryInfo field */ /* values for SAS Expander Page 1 DiscoveryInfo field */
#define MPI2_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED (0x04) #define MPI2_SAS_EXPANDER1_DISCINFO_BAD_PHY_DISABLED (0x04)
#define MPI2_SAS_EXPANDER1_DISCINFO_LINK_STATUS_CHANGE (0x02) #define MPI2_SAS_EXPANDER1_DISCINFO_LINK_STATUS_CHANGE (0x02)
#define MPI2_SAS_EXPANDER1_DISCINFO_NO_ROUTING_ENTRIES (0x01) #define MPI2_SAS_EXPANDER1_DISCINFO_NO_ROUTING_ENTRIES (0x01)
/* use MPI2_SAS_APHYINFO_ defines for AttachedPhyInfo field */
/**************************************************************************** /****************************************************************************
* SAS Device Config Pages * SAS Device Config Pages
...@@ -2447,6 +2457,8 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_0 ...@@ -2447,6 +2457,8 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_0
#define MPI2_SASPHY0_PAGEVERSION (0x03) #define MPI2_SASPHY0_PAGEVERSION (0x03)
/* use MPI2_SAS_APHYINFO_ defines for AttachedPhyInfo field */
/* use MPI2_SAS_PRATE_ defines for the ProgrammedLinkRate field */ /* use MPI2_SAS_PRATE_ defines for the ProgrammedLinkRate field */
/* use MPI2_SAS_HWRATE_ defines for the HwLinkRate field */ /* use MPI2_SAS_HWRATE_ defines for the HwLinkRate field */
...@@ -2454,12 +2466,10 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_0 ...@@ -2454,12 +2466,10 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_0
/* values for SAS PHY Page 0 Flags field */ /* values for SAS PHY Page 0 Flags field */
#define MPI2_SAS_PHY0_FLAGS_SGPIO_DIRECT_ATTACH_ENC (0x01) #define MPI2_SAS_PHY0_FLAGS_SGPIO_DIRECT_ATTACH_ENC (0x01)
/* use MPI2_SAS_APHYINFO_ defines for AttachedPhyInfo field */ /* use MPI2_SAS_PHYINFO_ for the PhyInfo field */
/* use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */ /* use MPI2_SAS_NEG_LINK_RATE_ defines for the NegotiatedLinkRate field */
/* use MPI2_SAS_PHYINFO_ for the PhyInfo field */
/* SAS PHY Page 1 */ /* SAS PHY Page 1 */
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
* Creation Date: October 11, 2006 * Creation Date: October 11, 2006
* *
* mpi2_ioc.h Version: 02.00.17 * mpi2_ioc.h Version: 02.00.19
* *
* Version History * Version History
* --------------- * ---------------
...@@ -110,6 +110,13 @@ ...@@ -110,6 +110,13 @@
* Added Temperature Threshold Event. * Added Temperature Threshold Event.
* Added Host Message Event. * Added Host Message Event.
* Added Send Host Message request and reply. * Added Send Host Message request and reply.
* 05-25-11 02.00.18 For Extended Image Header, added
* MPI2_EXT_IMAGE_TYPE_MIN_PRODUCT_SPECIFIC and
* MPI2_EXT_IMAGE_TYPE_MAX_PRODUCT_SPECIFIC defines.
* Deprecated MPI2_EXT_IMAGE_TYPE_MAX define.
* 08-24-11 02.00.19 Added PhysicalPort field to
* MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE structure.
* Marked MPI2_PM_CONTROL_FEATURE_PCIE_LINK as obsolete.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -578,7 +585,7 @@ typedef struct _MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE ...@@ -578,7 +585,7 @@ typedef struct _MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
{ {
U16 TaskTag; /* 0x00 */ U16 TaskTag; /* 0x00 */
U8 ReasonCode; /* 0x02 */ U8 ReasonCode; /* 0x02 */
U8 Reserved1; /* 0x03 */ U8 PhysicalPort; /* 0x03 */
U8 ASC; /* 0x04 */ U8 ASC; /* 0x04 */
U8 ASCQ; /* 0x05 */ U8 ASCQ; /* 0x05 */
U16 DevHandle; /* 0x06 */ U16 DevHandle; /* 0x06 */
...@@ -1366,16 +1373,18 @@ typedef struct _MPI2_EXT_IMAGE_HEADER ...@@ -1366,16 +1373,18 @@ typedef struct _MPI2_EXT_IMAGE_HEADER
#define MPI2_EXT_IMAGE_HEADER_SIZE (0x40) #define MPI2_EXT_IMAGE_HEADER_SIZE (0x40)
/* defines for the ImageType field */ /* defines for the ImageType field */
#define MPI2_EXT_IMAGE_TYPE_UNSPECIFIED (0x00) #define MPI2_EXT_IMAGE_TYPE_UNSPECIFIED (0x00)
#define MPI2_EXT_IMAGE_TYPE_FW (0x01) #define MPI2_EXT_IMAGE_TYPE_FW (0x01)
#define MPI2_EXT_IMAGE_TYPE_NVDATA (0x03) #define MPI2_EXT_IMAGE_TYPE_NVDATA (0x03)
#define MPI2_EXT_IMAGE_TYPE_BOOTLOADER (0x04) #define MPI2_EXT_IMAGE_TYPE_BOOTLOADER (0x04)
#define MPI2_EXT_IMAGE_TYPE_INITIALIZATION (0x05) #define MPI2_EXT_IMAGE_TYPE_INITIALIZATION (0x05)
#define MPI2_EXT_IMAGE_TYPE_FLASH_LAYOUT (0x06) #define MPI2_EXT_IMAGE_TYPE_FLASH_LAYOUT (0x06)
#define MPI2_EXT_IMAGE_TYPE_SUPPORTED_DEVICES (0x07) #define MPI2_EXT_IMAGE_TYPE_SUPPORTED_DEVICES (0x07)
#define MPI2_EXT_IMAGE_TYPE_MEGARAID (0x08) #define MPI2_EXT_IMAGE_TYPE_MEGARAID (0x08)
#define MPI2_EXT_IMAGE_TYPE_MIN_PRODUCT_SPECIFIC (0x80)
#define MPI2_EXT_IMAGE_TYPE_MAX (MPI2_EXT_IMAGE_TYPE_MEGARAID) #define MPI2_EXT_IMAGE_TYPE_MAX_PRODUCT_SPECIFIC (0xFF)
#define MPI2_EXT_IMAGE_TYPE_MAX \
(MPI2_EXT_IMAGE_TYPE_MAX_PRODUCT_SPECIFIC) /* deprecated */
...@@ -1568,7 +1577,7 @@ typedef struct _MPI2_PWR_MGMT_CONTROL_REQUEST { ...@@ -1568,7 +1577,7 @@ typedef struct _MPI2_PWR_MGMT_CONTROL_REQUEST {
/* defines for the Feature field */ /* defines for the Feature field */
#define MPI2_PM_CONTROL_FEATURE_DA_PHY_POWER_COND (0x01) #define MPI2_PM_CONTROL_FEATURE_DA_PHY_POWER_COND (0x01)
#define MPI2_PM_CONTROL_FEATURE_PORT_WIDTH_MODULATION (0x02) #define MPI2_PM_CONTROL_FEATURE_PORT_WIDTH_MODULATION (0x02)
#define MPI2_PM_CONTROL_FEATURE_PCIE_LINK (0x03) #define MPI2_PM_CONTROL_FEATURE_PCIE_LINK (0x03) /* obsolete */
#define MPI2_PM_CONTROL_FEATURE_IOC_SPEED (0x04) #define MPI2_PM_CONTROL_FEATURE_IOC_SPEED (0x04)
#define MPI2_PM_CONTROL_FEATURE_MIN_PRODUCT_SPECIFIC (0x80) #define MPI2_PM_CONTROL_FEATURE_MIN_PRODUCT_SPECIFIC (0x80)
#define MPI2_PM_CONTROL_FEATURE_MAX_PRODUCT_SPECIFIC (0xFF) #define MPI2_PM_CONTROL_FEATURE_MAX_PRODUCT_SPECIFIC (0xFF)
...@@ -1597,14 +1606,14 @@ typedef struct _MPI2_PWR_MGMT_CONTROL_REQUEST { ...@@ -1597,14 +1606,14 @@ typedef struct _MPI2_PWR_MGMT_CONTROL_REQUEST {
/* parameter usage for the MPI2_PM_CONTROL_FEATURE_PCIE_LINK Feature */ /* parameter usage for the MPI2_PM_CONTROL_FEATURE_PCIE_LINK Feature */
/* Parameter1 indicates desired PCIe link speed using these defines */ /* Parameter1 indicates desired PCIe link speed using these defines */
#define MPI2_PM_CONTROL_PARAM1_PCIE_2_5_GBPS (0x00) #define MPI2_PM_CONTROL_PARAM1_PCIE_2_5_GBPS (0x00) /* obsolete */
#define MPI2_PM_CONTROL_PARAM1_PCIE_5_0_GBPS (0x01) #define MPI2_PM_CONTROL_PARAM1_PCIE_5_0_GBPS (0x01) /* obsolete */
#define MPI2_PM_CONTROL_PARAM1_PCIE_8_0_GBPS (0x02) #define MPI2_PM_CONTROL_PARAM1_PCIE_8_0_GBPS (0x02) /* obsolete */
/* Parameter2 indicates desired PCIe link width using these defines */ /* Parameter2 indicates desired PCIe link width using these defines */
#define MPI2_PM_CONTROL_PARAM2_WIDTH_X1 (0x01) #define MPI2_PM_CONTROL_PARAM2_WIDTH_X1 (0x01) /* obsolete */
#define MPI2_PM_CONTROL_PARAM2_WIDTH_X2 (0x02) #define MPI2_PM_CONTROL_PARAM2_WIDTH_X2 (0x02) /* obsolete */
#define MPI2_PM_CONTROL_PARAM2_WIDTH_X4 (0x04) #define MPI2_PM_CONTROL_PARAM2_WIDTH_X4 (0x04) /* obsolete */
#define MPI2_PM_CONTROL_PARAM2_WIDTH_X8 (0x08) #define MPI2_PM_CONTROL_PARAM2_WIDTH_X8 (0x08) /* obsolete */
/* Parameter3 and Parameter4 are reserved */ /* Parameter3 and Parameter4 are reserved */
/* parameter usage for the MPI2_PM_CONTROL_FEATURE_IOC_SPEED Feature */ /* parameter usage for the MPI2_PM_CONTROL_FEATURE_IOC_SPEED Feature */
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI Integrated RAID messages and structures * Title: MPI Integrated RAID messages and structures
* Creation Date: April 26, 2007 * Creation Date: April 26, 2007
* *
* mpi2_raid.h Version: 02.00.05 * mpi2_raid.h Version: 02.00.06
* *
* Version History * Version History
* --------------- * ---------------
...@@ -23,6 +23,10 @@ ...@@ -23,6 +23,10 @@
* 07-30-09 02.00.04 Added proper define for the Use Default Settings bit of * 07-30-09 02.00.04 Added proper define for the Use Default Settings bit of
* VolumeCreationFlags and marked the old one as obsolete. * VolumeCreationFlags and marked the old one as obsolete.
* 05-12-10 02.00.05 Added MPI2_RAID_VOL_FLAGS_OP_MDC define. * 05-12-10 02.00.05 Added MPI2_RAID_VOL_FLAGS_OP_MDC define.
* 08-24-10 02.00.06 Added MPI2_RAID_ACTION_COMPATIBILITY_CHECK along with
* related structures and defines.
* Added product-specific range to RAID Action values.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -176,7 +180,9 @@ typedef struct _MPI2_RAID_ACTION_REQUEST ...@@ -176,7 +180,9 @@ typedef struct _MPI2_RAID_ACTION_REQUEST
#define MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED (0x20) #define MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED (0x20)
#define MPI2_RAID_ACTION_START_RAID_FUNCTION (0x21) #define MPI2_RAID_ACTION_START_RAID_FUNCTION (0x21)
#define MPI2_RAID_ACTION_STOP_RAID_FUNCTION (0x22) #define MPI2_RAID_ACTION_STOP_RAID_FUNCTION (0x22)
#define MPI2_RAID_ACTION_COMPATIBILITY_CHECK (0x23)
#define MPI2_RAID_ACTION_MIN_PRODUCT_SPECIFIC (0x80)
#define MPI2_RAID_ACTION_MAX_PRODUCT_SPECIFIC (0xFF)
/* RAID Volume Creation Structure */ /* RAID Volume Creation Structure */
...@@ -244,6 +250,23 @@ typedef struct _MPI2_RAID_ONLINE_CAPACITY_EXPANSION ...@@ -244,6 +250,23 @@ typedef struct _MPI2_RAID_ONLINE_CAPACITY_EXPANSION
Mpi2RaidOnlineCapacityExpansion_t, Mpi2RaidOnlineCapacityExpansion_t,
MPI2_POINTER pMpi2RaidOnlineCapacityExpansion_t; MPI2_POINTER pMpi2RaidOnlineCapacityExpansion_t;
/* RAID Compatibility Input Structure */
typedef struct _MPI2_RAID_COMPATIBILITY_INPUT_STRUCT {
U16 SourceDevHandle; /* 0x00 */
U16 CandidateDevHandle; /* 0x02 */
U32 Flags; /* 0x04 */
U32 Reserved1; /* 0x08 */
U32 Reserved2; /* 0x0C */
} MPI2_RAID_COMPATIBILITY_INPUT_STRUCT,
MPI2_POINTER PTR_MPI2_RAID_COMPATIBILITY_INPUT_STRUCT,
Mpi2RaidCompatibilityInputStruct_t,
MPI2_POINTER pMpi2RaidCompatibilityInputStruct_t;
/* defines for RAID Compatibility Structure Flags field */
#define MPI2_RAID_COMPAT_SOURCE_IS_VOLUME_FLAG (0x00000002)
#define MPI2_RAID_COMPAT_REPORT_SOURCE_INFO_FLAG (0x00000001)
/* RAID Volume Indicator Structure */ /* RAID Volume Indicator Structure */
...@@ -263,15 +286,45 @@ typedef struct _MPI2_RAID_VOL_INDICATOR ...@@ -263,15 +286,45 @@ typedef struct _MPI2_RAID_VOL_INDICATOR
#define MPI2_RAID_VOL_FLAGS_OP_RESYNC (0x00000003) #define MPI2_RAID_VOL_FLAGS_OP_RESYNC (0x00000003)
#define MPI2_RAID_VOL_FLAGS_OP_MDC (0x00000004) #define MPI2_RAID_VOL_FLAGS_OP_MDC (0x00000004)
/* RAID Compatibility Result Structure */
typedef struct _MPI2_RAID_COMPATIBILITY_RESULT_STRUCT {
U8 State; /* 0x00 */
U8 Reserved1; /* 0x01 */
U16 Reserved2; /* 0x02 */
U32 GenericAttributes; /* 0x04 */
U32 OEMSpecificAttributes; /* 0x08 */
U32 Reserved3; /* 0x0C */
U32 Reserved4; /* 0x10 */
} MPI2_RAID_COMPATIBILITY_RESULT_STRUCT,
MPI2_POINTER PTR_MPI2_RAID_COMPATIBILITY_RESULT_STRUCT,
Mpi2RaidCompatibilityResultStruct_t,
MPI2_POINTER pMpi2RaidCompatibilityResultStruct_t;
/* defines for RAID Compatibility Result Structure State field */
#define MPI2_RAID_COMPAT_STATE_COMPATIBLE (0x00)
#define MPI2_RAID_COMPAT_STATE_NOT_COMPATIBLE (0x01)
/* defines for RAID Compatibility Result Structure GenericAttributes field */
#define MPI2_RAID_COMPAT_GENATTRIB_4K_SECTOR (0x00000010)
#define MPI2_RAID_COMPAT_GENATTRIB_MEDIA_MASK (0x0000000C)
#define MPI2_RAID_COMPAT_GENATTRIB_SOLID_STATE_DRIVE (0x00000008)
#define MPI2_RAID_COMPAT_GENATTRIB_HARD_DISK_DRIVE (0x00000004)
#define MPI2_RAID_COMPAT_GENATTRIB_PROTOCOL_MASK (0x00000003)
#define MPI2_RAID_COMPAT_GENATTRIB_SAS_PROTOCOL (0x00000002)
#define MPI2_RAID_COMPAT_GENATTRIB_SATA_PROTOCOL (0x00000001)
/* RAID Action Reply ActionData union */ /* RAID Action Reply ActionData union */
typedef union _MPI2_RAID_ACTION_REPLY_DATA typedef union _MPI2_RAID_ACTION_REPLY_DATA
{ {
U32 Word[5]; U32 Word[5];
MPI2_RAID_VOL_INDICATOR RaidVolumeIndicator; MPI2_RAID_VOL_INDICATOR RaidVolumeIndicator;
U16 VolDevHandle; U16 VolDevHandle;
U8 VolumeState; U8 VolumeState;
U8 PhysDiskNum; U8 PhysDiskNum;
MPI2_RAID_COMPATIBILITY_RESULT_STRUCT RaidCompatibilityResult;
} MPI2_RAID_ACTION_REPLY_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_REPLY_DATA, } MPI2_RAID_ACTION_REPLY_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_REPLY_DATA,
Mpi2RaidActionReplyData_t, MPI2_POINTER pMpi2RaidActionReplyData_t; Mpi2RaidActionReplyData_t, MPI2_POINTER pMpi2RaidActionReplyData_t;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI diagnostic tool structures and definitions * Title: MPI diagnostic tool structures and definitions
* Creation Date: March 26, 2007 * Creation Date: March 26, 2007
* *
* mpi2_tool.h Version: 02.00.06 * mpi2_tool.h Version: 02.00.07
* *
* Version History * Version History
* --------------- * ---------------
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
* 05-12-10 02.00.05 Added Diagnostic Data Upload tool. * 05-12-10 02.00.05 Added Diagnostic Data Upload tool.
* 08-11-10 02.00.06 Added defines that were missing for Diagnostic Buffer * 08-11-10 02.00.06 Added defines that were missing for Diagnostic Buffer
* Post Request. * Post Request.
* 05-25-11 02.00.07 Added Flags field and related defines to
* MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -181,7 +183,7 @@ typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST { ...@@ -181,7 +183,7 @@ typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST {
U8 DevIndex; /* 0x14 */ U8 DevIndex; /* 0x14 */
U8 Action; /* 0x15 */ U8 Action; /* 0x15 */
U8 SGLFlags; /* 0x16 */ U8 SGLFlags; /* 0x16 */
U8 Reserved7; /* 0x17 */ U8 Flags; /* 0x17 */
U16 TxDataLength; /* 0x18 */ U16 TxDataLength; /* 0x18 */
U16 RxDataLength; /* 0x1A */ U16 RxDataLength; /* 0x1A */
U32 Reserved8; /* 0x1C */ U32 Reserved8; /* 0x1C */
...@@ -205,6 +207,9 @@ typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST { ...@@ -205,6 +207,9 @@ typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST {
/* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ /* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */
/* values for the Flags field */
#define MPI2_TOOL_ISTWI_FLAG_AUTO_RESERVE_RELEASE (0x80)
#define MPI2_TOOL_ISTWI_FLAG_PAGE_ADDR_MASK (0x07)
/* Toolbox ISTWI Read Write Tool reply message */ /* Toolbox ISTWI Read Write Tool reply message */
typedef struct _MPI2_TOOLBOX_ISTWI_REPLY { typedef struct _MPI2_TOOLBOX_ISTWI_REPLY {
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#include <linux/sort.h> #include <linux/sort.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/kthread.h>
#include <linux/aer.h> #include <linux/aer.h>
#include "mpt2sas_base.h" #include "mpt2sas_base.h"
...@@ -65,6 +66,8 @@ static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS]; ...@@ -65,6 +66,8 @@ static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS];
#define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */ #define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */
#define MAX_HBA_QUEUE_DEPTH 30000
#define MAX_CHAIN_DEPTH 100000
static int max_queue_depth = -1; static int max_queue_depth = -1;
module_param(max_queue_depth, int, 0); module_param(max_queue_depth, int, 0);
MODULE_PARM_DESC(max_queue_depth, " max controller queue depth "); MODULE_PARM_DESC(max_queue_depth, " max controller queue depth ");
...@@ -89,19 +92,6 @@ static int disable_discovery = -1; ...@@ -89,19 +92,6 @@ static int disable_discovery = -1;
module_param(disable_discovery, int, 0); module_param(disable_discovery, int, 0);
MODULE_PARM_DESC(disable_discovery, " disable discovery "); MODULE_PARM_DESC(disable_discovery, " disable discovery ");
/* diag_buffer_enable is bitwise
* bit 0 set = TRACE
* bit 1 set = SNAPSHOT
* bit 2 set = EXTENDED
*
* Either bit can be set, or both
*/
static int diag_buffer_enable;
module_param(diag_buffer_enable, int, 0);
MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers "
"(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)");
/** /**
* _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug.
* *
...@@ -120,9 +110,33 @@ _scsih_set_fwfault_debug(const char *val, struct kernel_param *kp) ...@@ -120,9 +110,33 @@ _scsih_set_fwfault_debug(const char *val, struct kernel_param *kp)
ioc->fwfault_debug = mpt2sas_fwfault_debug; ioc->fwfault_debug = mpt2sas_fwfault_debug;
return 0; return 0;
} }
module_param_call(mpt2sas_fwfault_debug, _scsih_set_fwfault_debug, module_param_call(mpt2sas_fwfault_debug, _scsih_set_fwfault_debug,
param_get_int, &mpt2sas_fwfault_debug, 0644); param_get_int, &mpt2sas_fwfault_debug, 0644);
/**
* mpt2sas_remove_dead_ioc_func - kthread context to remove dead ioc
* @arg: input argument, used to derive ioc
*
* Return 0 if controller is removed from pci subsystem.
* Return -1 for other case.
*/
static int mpt2sas_remove_dead_ioc_func(void *arg)
{
struct MPT2SAS_ADAPTER *ioc = (struct MPT2SAS_ADAPTER *)arg;
struct pci_dev *pdev;
if ((ioc == NULL))
return -1;
pdev = ioc->pdev;
if ((pdev == NULL))
return -1;
pci_remove_bus_device(pdev);
return 0;
}
/** /**
* _base_fault_reset_work - workq handling ioc fault conditions * _base_fault_reset_work - workq handling ioc fault conditions
* @work: input argument, used to derive ioc * @work: input argument, used to derive ioc
...@@ -138,6 +152,7 @@ _base_fault_reset_work(struct work_struct *work) ...@@ -138,6 +152,7 @@ _base_fault_reset_work(struct work_struct *work)
unsigned long flags; unsigned long flags;
u32 doorbell; u32 doorbell;
int rc; int rc;
struct task_struct *p;
spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
if (ioc->shost_recovery) if (ioc->shost_recovery)
...@@ -145,6 +160,39 @@ _base_fault_reset_work(struct work_struct *work) ...@@ -145,6 +160,39 @@ _base_fault_reset_work(struct work_struct *work)
spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
doorbell = mpt2sas_base_get_iocstate(ioc, 0); doorbell = mpt2sas_base_get_iocstate(ioc, 0);
if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_MASK) {
printk(MPT2SAS_INFO_FMT "%s : SAS host is non-operational !!!!\n",
ioc->name, __func__);
/*
* Call _scsih_flush_pending_cmds callback so that we flush all
* pending commands back to OS. This call is required to aovid
* deadlock at block layer. Dead IOC will fail to do diag reset,
* and this call is safe since dead ioc will never return any
* command back from HW.
*/
ioc->schedule_dead_ioc_flush_running_cmds(ioc);
/*
* Set remove_host flag early since kernel thread will
* take some time to execute.
*/
ioc->remove_host = 1;
/*Remove the Dead Host */
p = kthread_run(mpt2sas_remove_dead_ioc_func, ioc,
"mpt2sas_dead_ioc_%d", ioc->id);
if (IS_ERR(p)) {
printk(MPT2SAS_ERR_FMT
"%s: Running mpt2sas_dead_ioc thread failed !!!!\n",
ioc->name, __func__);
} else {
printk(MPT2SAS_ERR_FMT
"%s: Running mpt2sas_dead_ioc thread success !!!!\n",
ioc->name, __func__);
}
return; /* don't rearm timer */
}
if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, rc = mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
FORCE_BIG_HAMMER); FORCE_BIG_HAMMER);
...@@ -1346,7 +1394,7 @@ _base_enable_msix(struct MPT2SAS_ADAPTER *ioc) ...@@ -1346,7 +1394,7 @@ _base_enable_msix(struct MPT2SAS_ADAPTER *ioc)
if (_base_check_enable_msix(ioc) != 0) if (_base_check_enable_msix(ioc) != 0)
goto try_ioapic; goto try_ioapic;
ioc->reply_queue_count = min_t(u8, ioc->cpu_count, ioc->reply_queue_count = min_t(int, ioc->cpu_count,
ioc->msix_vector_count); ioc->msix_vector_count);
entries = kcalloc(ioc->reply_queue_count, sizeof(struct msix_entry), entries = kcalloc(ioc->reply_queue_count, sizeof(struct msix_entry),
...@@ -1916,6 +1964,10 @@ _base_display_intel_branding(struct MPT2SAS_ADAPTER *ioc) ...@@ -1916,6 +1964,10 @@ _base_display_intel_branding(struct MPT2SAS_ADAPTER *ioc)
printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
MPT2SAS_INTEL_RMS2LL040_BRANDING); MPT2SAS_INTEL_RMS2LL040_BRANDING);
break; break;
case MPT2SAS_INTEL_RAMSDALE_SSDID:
printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
MPT2SAS_INTEL_RAMSDALE_BRANDING);
break;
default: default:
break; break;
} }
...@@ -1925,6 +1977,22 @@ _base_display_intel_branding(struct MPT2SAS_ADAPTER *ioc) ...@@ -1925,6 +1977,22 @@ _base_display_intel_branding(struct MPT2SAS_ADAPTER *ioc)
printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
MPT2SAS_INTEL_RS25GB008_BRANDING); MPT2SAS_INTEL_RS25GB008_BRANDING);
break; break;
case MPT2SAS_INTEL_RMS25JB080_SSDID:
printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
MPT2SAS_INTEL_RMS25JB080_BRANDING);
break;
case MPT2SAS_INTEL_RMS25JB040_SSDID:
printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
MPT2SAS_INTEL_RMS25JB040_BRANDING);
break;
case MPT2SAS_INTEL_RMS25KB080_SSDID:
printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
MPT2SAS_INTEL_RMS25KB080_BRANDING);
break;
case MPT2SAS_INTEL_RMS25KB040_SSDID:
printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
MPT2SAS_INTEL_RMS25KB040_BRANDING);
break;
default: default:
break; break;
} }
...@@ -2311,8 +2379,6 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) ...@@ -2311,8 +2379,6 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
} }
if (ioc->chain_dma_pool) if (ioc->chain_dma_pool)
pci_pool_destroy(ioc->chain_dma_pool); pci_pool_destroy(ioc->chain_dma_pool);
}
if (ioc->chain_lookup) {
free_pages((ulong)ioc->chain_lookup, ioc->chain_pages); free_pages((ulong)ioc->chain_lookup, ioc->chain_pages);
ioc->chain_lookup = NULL; ioc->chain_lookup = NULL;
} }
...@@ -2330,9 +2396,7 @@ static int ...@@ -2330,9 +2396,7 @@ static int
_base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
{ {
struct mpt2sas_facts *facts; struct mpt2sas_facts *facts;
u32 queue_size, queue_diff;
u16 max_sge_elements; u16 max_sge_elements;
u16 num_of_reply_frames;
u16 chains_needed_per_io; u16 chains_needed_per_io;
u32 sz, total_sz, reply_post_free_sz; u32 sz, total_sz, reply_post_free_sz;
u32 retry_sz; u32 retry_sz;
...@@ -2359,7 +2423,8 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) ...@@ -2359,7 +2423,8 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
max_request_credit = (max_queue_depth < facts->RequestCredit) max_request_credit = (max_queue_depth < facts->RequestCredit)
? max_queue_depth : facts->RequestCredit; ? max_queue_depth : facts->RequestCredit;
else else
max_request_credit = facts->RequestCredit; max_request_credit = min_t(u16, facts->RequestCredit,
MAX_HBA_QUEUE_DEPTH);
ioc->hba_queue_depth = max_request_credit; ioc->hba_queue_depth = max_request_credit;
ioc->hi_priority_depth = facts->HighPriorityCredit; ioc->hi_priority_depth = facts->HighPriorityCredit;
...@@ -2400,50 +2465,25 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) ...@@ -2400,50 +2465,25 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
} }
ioc->chains_needed_per_io = chains_needed_per_io; ioc->chains_needed_per_io = chains_needed_per_io;
/* reply free queue sizing - taking into account for events */ /* reply free queue sizing - taking into account for 64 FW events */
num_of_reply_frames = ioc->hba_queue_depth + 32; ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64;
/* number of replies frames can't be a multiple of 16 */
/* decrease number of reply frames by 1 */
if (!(num_of_reply_frames % 16))
num_of_reply_frames--;
/* calculate number of reply free queue entries
* (must be multiple of 16)
*/
/* (we know reply_free_queue_depth is not a multiple of 16) */
queue_size = num_of_reply_frames;
queue_size += 16 - (queue_size % 16);
ioc->reply_free_queue_depth = queue_size;
/* reply descriptor post queue sizing */
/* this size should be the number of request frames + number of reply
* frames
*/
queue_size = ioc->hba_queue_depth + num_of_reply_frames + 1;
/* round up to 16 byte boundary */
if (queue_size % 16)
queue_size += 16 - (queue_size % 16);
/* check against IOC maximum reply post queue depth */
if (queue_size > facts->MaxReplyDescriptorPostQueueDepth) {
queue_diff = queue_size -
facts->MaxReplyDescriptorPostQueueDepth;
/* round queue_diff up to multiple of 16 */ /* align the reply post queue on the next 16 count boundary */
if (queue_diff % 16) if (!ioc->reply_free_queue_depth % 16)
queue_diff += 16 - (queue_diff % 16); ioc->reply_post_queue_depth = ioc->reply_free_queue_depth + 16;
else
/* adjust hba_queue_depth, reply_free_queue_depth, ioc->reply_post_queue_depth = ioc->reply_free_queue_depth +
* and queue_size 32 - (ioc->reply_free_queue_depth % 16);
*/ if (ioc->reply_post_queue_depth >
ioc->hba_queue_depth -= (queue_diff / 2); facts->MaxReplyDescriptorPostQueueDepth) {
ioc->reply_free_queue_depth -= (queue_diff / 2); ioc->reply_post_queue_depth = min_t(u16,
queue_size = facts->MaxReplyDescriptorPostQueueDepth; (facts->MaxReplyDescriptorPostQueueDepth -
(facts->MaxReplyDescriptorPostQueueDepth % 16)),
(ioc->hba_queue_depth - (ioc->hba_queue_depth % 16)));
ioc->reply_free_queue_depth = ioc->reply_post_queue_depth - 16;
ioc->hba_queue_depth = ioc->reply_free_queue_depth - 64;
} }
ioc->reply_post_queue_depth = queue_size;
dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scatter gather: " dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scatter gather: "
"sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), " "sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), "
...@@ -2529,15 +2569,12 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) ...@@ -2529,15 +2569,12 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
"depth(%d)\n", ioc->name, ioc->request, "depth(%d)\n", ioc->name, ioc->request,
ioc->scsiio_depth)); ioc->scsiio_depth));
/* loop till the allocation succeeds */ ioc->chain_depth = min_t(u32, ioc->chain_depth, MAX_CHAIN_DEPTH);
do { sz = ioc->chain_depth * sizeof(struct chain_tracker);
sz = ioc->chain_depth * sizeof(struct chain_tracker); ioc->chain_pages = get_order(sz);
ioc->chain_pages = get_order(sz);
ioc->chain_lookup = (struct chain_tracker *)__get_free_pages( ioc->chain_lookup = (struct chain_tracker *)__get_free_pages(
GFP_KERNEL, ioc->chain_pages); GFP_KERNEL, ioc->chain_pages);
if (ioc->chain_lookup == NULL)
ioc->chain_depth -= 100;
} while (ioc->chain_lookup == NULL);
ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev, ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev,
ioc->request_sz, 16, 0); ioc->request_sz, 16, 0);
if (!ioc->chain_dma_pool) { if (!ioc->chain_dma_pool) {
...@@ -3136,8 +3173,8 @@ mpt2sas_base_sas_iounit_control(struct MPT2SAS_ADAPTER *ioc, ...@@ -3136,8 +3173,8 @@ mpt2sas_base_sas_iounit_control(struct MPT2SAS_ADAPTER *ioc,
if (mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET || if (mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET ||
mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET) mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET)
ioc->ioc_link_reset_in_progress = 1; ioc->ioc_link_reset_in_progress = 1;
mpt2sas_base_put_smid_default(ioc, smid);
init_completion(&ioc->base_cmds.done); init_completion(&ioc->base_cmds.done);
mpt2sas_base_put_smid_default(ioc, smid);
timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, timeleft = wait_for_completion_timeout(&ioc->base_cmds.done,
msecs_to_jiffies(10000)); msecs_to_jiffies(10000));
if ((mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET || if ((mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET ||
...@@ -3238,8 +3275,8 @@ mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc, ...@@ -3238,8 +3275,8 @@ mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc,
request = mpt2sas_base_get_msg_frame(ioc, smid); request = mpt2sas_base_get_msg_frame(ioc, smid);
ioc->base_cmds.smid = smid; ioc->base_cmds.smid = smid;
memcpy(request, mpi_request, sizeof(Mpi2SepReply_t)); memcpy(request, mpi_request, sizeof(Mpi2SepReply_t));
mpt2sas_base_put_smid_default(ioc, smid);
init_completion(&ioc->base_cmds.done); init_completion(&ioc->base_cmds.done);
mpt2sas_base_put_smid_default(ioc, smid);
timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, timeleft = wait_for_completion_timeout(&ioc->base_cmds.done,
msecs_to_jiffies(10000)); msecs_to_jiffies(10000));
if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) { if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) {
...@@ -3746,8 +3783,8 @@ _base_event_notification(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) ...@@ -3746,8 +3783,8 @@ _base_event_notification(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
mpi_request->EventMasks[i] = mpi_request->EventMasks[i] =
cpu_to_le32(ioc->event_masks[i]); cpu_to_le32(ioc->event_masks[i]);
mpt2sas_base_put_smid_default(ioc, smid);
init_completion(&ioc->base_cmds.done); init_completion(&ioc->base_cmds.done);
mpt2sas_base_put_smid_default(ioc, smid);
timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ); timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ);
if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) { if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) {
printk(MPT2SAS_ERR_FMT "%s: timeout\n", printk(MPT2SAS_ERR_FMT "%s: timeout\n",
...@@ -4062,7 +4099,8 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) ...@@ -4062,7 +4099,8 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
ioc->reply_free[i] = cpu_to_le32(reply_address); ioc->reply_free[i] = cpu_to_le32(reply_address);
/* initialize reply queues */ /* initialize reply queues */
_base_assign_reply_queues(ioc); if (ioc->is_driver_loading)
_base_assign_reply_queues(ioc);
/* initialize Reply Post Free Queue */ /* initialize Reply Post Free Queue */
reply_post_free = (long)ioc->reply_post_free; reply_post_free = (long)ioc->reply_post_free;
...@@ -4110,24 +4148,17 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) ...@@ -4110,24 +4148,17 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
if (ioc->is_driver_loading) { if (ioc->is_driver_loading) {
if (ioc->is_warpdrive && ioc->manu_pg10.OEMIdentifier
== 0x80) {
ioc->wait_for_discovery_to_complete =
_base_determine_wait_on_discovery(ioc);
return r; /* scan_start and scan_finished support */
}
if (ioc->wait_for_discovery_to_complete && ioc->is_warpdrive) {
if (ioc->manu_pg10.OEMIdentifier == 0x80) {
hide_flag = (u8) (ioc->manu_pg10.OEMSpecificFlags0 & hide_flag = (u8) (ioc->manu_pg10.OEMSpecificFlags0 &
MFG_PAGE10_HIDE_SSDS_MASK); MFG_PAGE10_HIDE_SSDS_MASK);
if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK) if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK)
ioc->mfg_pg10_hide_flag = hide_flag; ioc->mfg_pg10_hide_flag = hide_flag;
} }
ioc->wait_for_discovery_to_complete =
_base_determine_wait_on_discovery(ioc);
return r; /* scan_start and scan_finished support */
} }
r = _base_send_port_enable(ioc, sleep_flag); r = _base_send_port_enable(ioc, sleep_flag);
if (r) if (r)
return r; return r;
...@@ -4206,7 +4237,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) ...@@ -4206,7 +4237,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
r = mpt2sas_base_map_resources(ioc); r = mpt2sas_base_map_resources(ioc);
if (r) if (r)
return r; goto out_free_resources;
if (ioc->is_warpdrive) { if (ioc->is_warpdrive) {
ioc->reply_post_host_index[0] = ioc->reply_post_host_index[0] =
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -271,6 +271,7 @@ struct srb_iocb { ...@@ -271,6 +271,7 @@ struct srb_iocb {
struct srb_ctx { struct srb_ctx {
uint16_t type; uint16_t type;
char *name; char *name;
int iocbs;
union { union {
struct srb_iocb *iocb_cmd; struct srb_iocb *iocb_cmd;
struct fc_bsg_job *bsg_job; struct fc_bsg_job *bsg_job;
...@@ -2244,6 +2245,7 @@ struct isp_operations { ...@@ -2244,6 +2245,7 @@ struct isp_operations {
int (*get_flash_version) (struct scsi_qla_host *, void *); int (*get_flash_version) (struct scsi_qla_host *, void *);
int (*start_scsi) (srb_t *); int (*start_scsi) (srb_t *);
int (*abort_isp) (struct scsi_qla_host *); int (*abort_isp) (struct scsi_qla_host *);
int (*iospace_config)(struct qla_hw_data*);
}; };
/* MSI-X Support *************************************************************/ /* MSI-X Support *************************************************************/
...@@ -2978,10 +2980,6 @@ typedef struct scsi_qla_host { ...@@ -2978,10 +2980,6 @@ typedef struct scsi_qla_host {
atomic_dec(&__vha->vref_count); \ atomic_dec(&__vha->vref_count); \
} while (0) } while (0)
#define qla_printk(level, ha, format, arg...) \
dev_printk(level , &((ha)->pdev->dev) , format , ## arg)
/* /*
* qla2x00 local function return status codes * qla2x00 local function return status codes
*/ */
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册