Print this page
NEX-5717 import QLogic 16G FC drivers
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
@@ -17,26 +17,26 @@
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
-/* Copyright 2010 QLogic Corporation */
+/* Copyright 2015 QLogic Corporation */
/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "Copyright 2010 QLogic Corporation; ql_ioctl.c"
+#pragma ident "Copyright 2015 QLogic Corporation; ql_ioctl.c"
/*
* ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
* Fibre Channel Adapter (FCA) driver IOCTL source file.
*
* ***********************************************************************
* * **
* * NOTICE **
- * * COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION **
+ * * COPYRIGHT (C) 1996-2015 QLOGIC CORPORATION **
* * ALL RIGHTS RESERVED **
* * **
* ***********************************************************************
*
*/
@@ -45,10 +45,11 @@
#include <ql_api.h>
#include <ql_debug.h>
#include <ql_init.h>
#include <ql_ioctl.h>
#include <ql_mbx.h>
+#include <ql_nx.h>
#include <ql_xioctl.h>
/*
* Local Function Prototypes.
*/
@@ -66,10 +67,12 @@
static int ql_adm_device_list(ql_adapter_state_t *, ql_adm_op_t *, int);
static int ql_adm_update_properties(ql_adapter_state_t *);
static int ql_adm_prop_update_int(ql_adapter_state_t *, ql_adm_op_t *, int);
static int ql_adm_loop_reset(ql_adapter_state_t *);
static int ql_adm_fw_dump(ql_adapter_state_t *, ql_adm_op_t *, void *, int);
+static int ql_adm_fw_t_dump(ql_adapter_state_t *);
+static int ql_adm_beacon(ql_adapter_state_t *, ql_adm_op_t *);
static int ql_adm_nvram_dump(ql_adapter_state_t *, ql_adm_op_t *, int);
static int ql_adm_nvram_load(ql_adapter_state_t *, ql_adm_op_t *, int);
static int ql_adm_flash_load(ql_adapter_state_t *, ql_adm_op_t *, int);
static int ql_adm_vpd_dump(ql_adapter_state_t *, ql_adm_op_t *, int);
static int ql_adm_vpd_load(ql_adapter_state_t *, ql_adm_op_t *, int);
@@ -104,20 +107,19 @@
ql_adapter_state_t *ha;
int rval = 0;
ha = ddi_get_soft_state(ql_state, (int32_t)getminor(*dev_p));
if (ha == NULL) {
- QL_PRINT_2(CE_CONT, "failed, no adapter\n");
+ QL_PRINT_2(NULL, "failed, no adapter\n");
return (ENXIO);
}
- QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_3(ha, "started\n");
/* Allow only character opens */
if (otyp != OTYP_CHR) {
- QL_PRINT_2(CE_CONT, "(%d): failed, open type\n",
- ha->instance);
+ QL_PRINT_2(ha, "failed, open type\n");
return (EINVAL);
}
ADAPTER_STATE_LOCK(ha);
if (flags & FEXCL && ha->flags & QL_OPENED) {
@@ -130,11 +132,11 @@
if (rval != 0) {
EL(ha, "failed, rval = %xh\n", rval);
} else {
/*EMPTY*/
- QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_3(ha, "done\n");
}
return (rval);
}
/*
@@ -160,19 +162,18 @@
ql_adapter_state_t *ha;
int rval = 0;
ha = ddi_get_soft_state(ql_state, (int32_t)getminor(dev));
if (ha == NULL) {
- QL_PRINT_2(CE_CONT, "failed, no adapter\n");
+ QL_PRINT_2(ha, "failed, no adapter\n");
return (ENXIO);
}
- QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_3(ha, "started\n");
if (otyp != OTYP_CHR) {
- QL_PRINT_2(CE_CONT, "(%d): failed, open type\n",
- ha->instance);
+ QL_PRINT_2(ha, "failed, open type\n");
return (EINVAL);
}
ADAPTER_STATE_LOCK(ha);
ha->flags &= ~QL_OPENED;
@@ -180,11 +181,11 @@
if (rval != 0) {
EL(ha, "failed, rval = %xh\n", rval);
} else {
/*EMPTY*/
- QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_3(ha, "done\n");
}
return (rval);
}
/*
@@ -212,28 +213,28 @@
{
ql_adapter_state_t *ha;
int rval = 0;
if (ddi_in_panic()) {
- QL_PRINT_2(CE_CONT, "ql_ioctl: ddi_in_panic exit\n");
+ QL_PRINT_2(NULL, "ql_ioctl: ddi_in_panic exit\n");
return (ENOPROTOOPT);
}
ha = ddi_get_soft_state(ql_state, (int32_t)getminor(dev));
if (ha == NULL) {
- QL_PRINT_2(CE_CONT, "failed, no adapter\n");
+ QL_PRINT_2(ha, "failed, no adapter\n");
return (ENXIO);
}
- QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_3(ha, "started\n");
/*
* Quick clean exit for qla2x00 foapi calls which are
* not supported in qlc.
*/
if (cmd >= QL_FOAPI_START && cmd <= QL_FOAPI_END) {
- QL_PRINT_9(CE_CONT, "failed, fo api not supported\n");
+ QL_PRINT_9(ha, "failed, fo api not supported\n");
return (ENOTTY);
}
/* PWR management busy. */
rval = ql_busy_notification(ha);
@@ -304,11 +305,11 @@
if (cmd != EXT_CC_VPORT_CMD) {
EL(ha, "failed, cmd=%d rval=%d\n", cmd, rval);
}
} else {
/*EMPTY*/
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
}
return (rval);
}
/*
@@ -330,19 +331,21 @@
{
if (!ha->pm_capable) {
return (FC_SUCCESS);
}
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
QL_PM_LOCK(ha);
- ha->busy++;
+ ha->pm_busy++;
QL_PM_UNLOCK(ha);
if (pm_busy_component(ha->dip, 0) != DDI_SUCCESS) {
QL_PM_LOCK(ha);
- ha->busy--;
+ if (ha->pm_busy) {
+ ha->pm_busy--;
+ }
QL_PM_UNLOCK(ha);
EL(ha, "pm_busy_component failed = %xh\n", FC_FAILURE);
return (FC_FAILURE);
}
@@ -350,19 +353,21 @@
QL_PM_LOCK(ha);
if (ha->power_level != PM_LEVEL_D0) {
QL_PM_UNLOCK(ha);
if (pm_raise_power(ha->dip, 0, 1) != DDI_SUCCESS) {
QL_PM_LOCK(ha);
- ha->busy--;
+ if (ha->pm_busy) {
+ ha->pm_busy--;
+ }
QL_PM_UNLOCK(ha);
return (FC_FAILURE);
}
} else {
QL_PM_UNLOCK(ha);
}
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (FC_SUCCESS);
}
/*
@@ -384,22 +389,24 @@
{
if (!ha->pm_capable) {
return (FC_SUCCESS);
}
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
if (pm_idle_component(ha->dip, 0) != DDI_SUCCESS) {
EL(ha, "pm_idle_component failed = %xh\n", FC_FAILURE);
return (FC_FAILURE);
}
QL_PM_LOCK(ha);
- ha->busy--;
+ if (ha->pm_busy) {
+ ha->pm_busy--;
+ }
QL_PM_UNLOCK(ha);
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (FC_SUCCESS);
}
/*
@@ -413,13 +420,13 @@
uint32_t nv_cmd;
uint32_t start_addr;
int rval;
uint32_t offset = offsetof(nvram_t, adapter_features);
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
- if (CFG_IST(ha, CFG_CTRL_24258081)) {
+ if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
EL(ha, "Not supported for 24xx\n");
return (EINVAL);
}
/*
@@ -475,11 +482,11 @@
*/
WRT16_IO_REG(ha, nvram, NV_DESELECT);
ql_release_nvram(ha);
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (0);
}
/*
@@ -494,13 +501,13 @@
uint16_t *wptr;
uint8_t *bptr;
uint8_t csum;
uint32_t start_addr;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
- if (CFG_IST(ha, CFG_CTRL_24258081)) {
+ if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
EL(ha, "Not supported for 24xx\n");
return (EINVAL);
}
nv = kmem_zalloc(sizeof (*nv), KM_SLEEP);
@@ -579,11 +586,11 @@
}
kmem_free(nv, sizeof (*nv));
ql_release_nvram(ha);
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (rval);
}
/*
@@ -594,20 +601,20 @@
{
int rval;
uint32_t count;
uint32_t start_addr;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
rval = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA);
if (rval != QL_SUCCESS) {
EL(ha, "failed, ql_lock_nvram=%xh\n", rval);
return (EIO);
}
rval = 0;
- if (CFG_IST(ha, CFG_CTRL_24258081)) {
+ if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
nvram_24xx_t *nv;
uint32_t *longptr;
uint32_t csum = 0;
nv = kmem_zalloc(sizeof (*nv), KM_SLEEP);
@@ -643,11 +650,12 @@
/*
* compute the chesksum now
*/
longptr = (uint32_t *)nv;
csum = 0;
- for (count = 0; count < (sizeof (nvram_24xx_t)/4)-1; count++) {
+ for (count = 0; count < (sizeof (nvram_24xx_t) / 4) - 1;
+ count++) {
csum += *longptr;
longptr++;
}
csum = (uint32_t)(~csum + 1);
LITTLE_ENDIAN_32((long)csum);
@@ -757,11 +765,11 @@
}
kmem_free(nv, sizeof (*nv));
}
ql_release_nvram(ha);
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (rval);
}
static void
@@ -875,18 +883,18 @@
ql_24xx_load_nvram(ql_adapter_state_t *ha, uint32_t addr, uint32_t value)
{
int rval;
/* Enable flash write. */
- if (!(CFG_IST(ha, CFG_CTRL_8081))) {
+ if (!(CFG_IST(ha, CFG_FCOE_SUPPORT))) {
WRT32_IO_REG(ha, ctrl_status,
RD32_IO_REG(ha, ctrl_status) | ISP_FLASH_ENABLE);
RD32_IO_REG(ha, ctrl_status); /* PCI Posting. */
}
/* Disable NVRAM write-protection. */
- if (CFG_IST(ha, CFG_CTRL_2422)) {
+ if (CFG_IST(ha, CFG_CTRL_24XX)) {
(void) ql_24xx_write_flash(ha, NVRAM_CONF_ADDR | 0x101, 0);
} else {
if ((rval = ql_24xx_unprotect_flash(ha)) != QL_SUCCESS) {
EL(ha, "unprotect_flash failed, rval=%xh\n", rval);
return (rval);
@@ -895,11 +903,11 @@
/* Write to flash. */
rval = ql_24xx_write_flash(ha, addr, value);
/* Enable NVRAM write-protection. */
- if (CFG_IST(ha, CFG_CTRL_2422)) {
+ if (CFG_IST(ha, CFG_CTRL_24XX)) {
/* TODO: Check if 0x8c is correct -- sb: 0x9c ? */
(void) ql_24xx_write_flash(ha, NVRAM_CONF_ADDR | 0x101, 0x8c);
} else {
ql_24xx_protect_flash(ha);
}
@@ -936,11 +944,11 @@
uint16_t data;
uint32_t start_addr, *lptr, data32;
nvram_t *nptr;
int rval;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
if ((nv = kmem_zalloc(ha->nvram_cache->size, KM_SLEEP)) == NULL) {
EL(ha, "failed, kmem_zalloc\n");
return (ENOMEM);
}
@@ -974,20 +982,20 @@
ql_restart_driver(ha);
return (EIO);
}
/* Load NVRAM. */
- if (CFG_IST(ha, CFG_CTRL_258081)) {
+ if (CFG_IST(ha, CFG_CTRL_252780818283)) {
GLOBAL_HW_UNLOCK();
start_addr &= ~ha->flash_data_addr;
start_addr <<= 2;
if ((rval = ql_r_m_w_flash(ha, bp, ha->nvram_cache->size,
start_addr, mode)) != QL_SUCCESS) {
EL(ha, "nvram load failed, rval = %0xh\n", rval);
}
GLOBAL_HW_LOCK();
- } else if (CFG_IST(ha, CFG_CTRL_2422)) {
+ } else if (CFG_IST(ha, CFG_CTRL_24XX)) {
lptr = (uint32_t *)nv;
for (cnt = 0; cnt < ha->nvram_cache->size / 4; cnt++) {
data32 = *lptr++;
LITTLE_ENDIAN_32(&data32);
rval = ql_24xx_load_nvram(ha, cnt + start_addr,
@@ -1004,21 +1012,17 @@
LITTLE_ENDIAN_16(&data);
ql_load_nvram(ha, (uint8_t)(cnt + start_addr), data);
}
}
/* switch to the new one */
- NVRAM_CACHE_LOCK(ha);
-
kmem_free(ha->nvram_cache->cache, ha->nvram_cache->size);
ha->nvram_cache->cache = (void *)nptr;
- NVRAM_CACHE_UNLOCK(ha);
-
ql_release_nvram(ha);
ql_restart_driver(ha);
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
if (rval == QL_SUCCESS) {
return (0);
}
@@ -1042,11 +1046,11 @@
ql_nv_util_dump(ql_adapter_state_t *ha, void *bp, int mode)
{
uint32_t start_addr;
int rval2, rval = 0;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
if (ha->nvram_cache == NULL ||
ha->nvram_cache->size == NULL ||
ha->nvram_cache->cache == NULL) {
EL(ha, "failed, kmem_zalloc\n");
@@ -1063,23 +1067,19 @@
if (rval2 != QL_SUCCESS) {
EL(ha, "failed, ql_lock_nvram=%xh\n", rval2);
ql_restart_driver(ha);
return (EIO);
}
- NVRAM_CACHE_LOCK(ha);
-
rval2 = ql_get_nvram(ha, ha->nvram_cache->cache,
start_addr, ha->nvram_cache->size);
if (rval2 != QL_SUCCESS) {
rval = rval2;
} else {
ha->nvram_cache->valid = 1;
EL(ha, "nvram cache now valid.");
}
- NVRAM_CACHE_UNLOCK(ha);
-
ql_release_nvram(ha);
ql_restart_driver(ha);
if (rval != 0) {
EL(ha, "failed to dump nvram, rval=%x\n", rval);
@@ -1091,11 +1091,11 @@
ha->nvram_cache->size, mode) != 0) {
EL(ha, "Buffer copy failed\n");
return (EFAULT);
}
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (0);
}
int
@@ -1103,11 +1103,11 @@
uint32_t size)
{
int rval = QL_SUCCESS;
int cnt;
/* Dump NVRAM. */
- if (CFG_IST(ha, CFG_CTRL_24258081)) {
+ if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
uint32_t *lptr = (uint32_t *)dest_addr;
for (cnt = 0; cnt < size / 4; cnt++) {
rval = ql_24xx_read_flash(ha, src_addr++, lptr);
if (rval != QL_SUCCESS) {
@@ -1151,13 +1151,13 @@
uint8_t cnt;
uint8_t *vpd, *vpdptr, *vbuf;
uint32_t start_addr, vpd_size, *lptr, data32;
int rval;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
- if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
+ if (CFG_IST(ha, CFG_ISP_FW_TYPE_1)) {
EL(ha, "unsupported adapter feature\n");
return (ENOTSUP);
}
vpd_size = QL_24XX_VPD_SIZE;
@@ -1207,11 +1207,11 @@
ql_restart_driver(ha);
return (EIO);
}
/* Load VPD. */
- if (CFG_IST(ha, CFG_CTRL_258081)) {
+ if (CFG_IST(ha, CFG_CTRL_252780818283)) {
GLOBAL_HW_UNLOCK();
start_addr &= ~ha->flash_data_addr;
start_addr <<= 2;
if ((rval = ql_r_m_w_flash(ha, bp, vpd_size, start_addr,
mode)) != QL_SUCCESS) {
@@ -1233,12 +1233,10 @@
}
kmem_free(vpd, vpd_size);
/* Update the vcache */
- CACHE_LOCK(ha);
-
if (rval != QL_SUCCESS) {
EL(ha, "failed, load\n");
} else if ((ha->vcache == NULL) && ((ha->vcache =
kmem_zalloc(vpd_size, KM_SLEEP)) == NULL)) {
EL(ha, "failed, kmem_zalloc2\n");
@@ -1246,16 +1244,14 @@
EL(ha, "Buffer copy2 failed\n");
kmem_free(ha->vcache, vpd_size);
ha->vcache = NULL;
}
- CACHE_UNLOCK(ha);
-
ql_release_nvram(ha);
ql_restart_driver(ha);
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
if (rval == QL_SUCCESS) {
return (0);
}
@@ -1281,48 +1277,42 @@
uint8_t cnt;
void *vpd;
uint32_t start_addr, vpd_size, *lptr;
int rval = 0;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_3(ha, "started\n");
- if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
+ if (CFG_IST(ha, CFG_ISP_FW_TYPE_1)) {
EL(ha, "unsupported adapter feature\n");
return (EACCES);
}
vpd_size = QL_24XX_VPD_SIZE;
- CACHE_LOCK(ha);
-
if (ha->vcache != NULL) {
/* copy back the vpd cache data */
if (ddi_copyout(ha->vcache, bp, vpd_size, mode) != 0) {
EL(ha, "Buffer copy failed\n");
rval = EFAULT;
}
- CACHE_UNLOCK(ha);
return (rval);
}
if ((vpd = kmem_zalloc(vpd_size, KM_SLEEP)) == NULL) {
- CACHE_UNLOCK(ha);
EL(ha, "failed, kmem_zalloc\n");
return (ENOMEM);
}
/* Quiesce I/O */
if (ql_stall_driver(ha, 0) != QL_SUCCESS) {
- CACHE_UNLOCK(ha);
EL(ha, "ql_stall_driver failed\n");
kmem_free(vpd, vpd_size);
return (EBUSY);
}
rval = ql_lock_nvram(ha, &start_addr, LNF_VPD_DATA);
if (rval != QL_SUCCESS) {
- CACHE_UNLOCK(ha);
EL(ha, "failed, ql_lock_nvram=%xh\n", rval);
kmem_free(vpd, vpd_size);
ql_restart_driver(ha);
return (EIO);
}
@@ -1343,22 +1333,19 @@
ql_release_nvram(ha);
ql_restart_driver(ha);
if (ddi_copyout(vpd, bp, vpd_size, mode) != 0) {
- CACHE_UNLOCK(ha);
EL(ha, "Buffer copy failed\n");
kmem_free(vpd, vpd_size);
return (EFAULT);
}
ha->vcache = vpd;
- CACHE_UNLOCK(ha);
+ QL_PRINT_3(ha, "done\n");
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
-
if (rval != QL_SUCCESS) {
return (EFAULT);
} else {
return (0);
}
@@ -1385,11 +1372,11 @@
{
uint8_t *vpd = vpdbuf;
uint8_t *end = vpdbuf + QL_24XX_VPD_SIZE;
uint32_t found = 0;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_3(ha, "started\n");
if (vpdbuf == NULL || opcode == NULL) {
EL(ha, "null parameter passed!\n");
return (NULL);
}
@@ -1425,11 +1412,11 @@
} else {
vpd += vpd[2] +3;
}
}
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_3(ha, "done\n");
return (found == 1 ? vpd : NULL);
}
/*
@@ -1460,19 +1447,19 @@
{
uint8_t *vpd;
uint8_t *vpdbuf;
int32_t len = -1;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_3(ha, "started\n");
if (opcode == NULL || bp == NULL || bplen < 1) {
EL(ha, "invalid parameter passed: opcode=%ph, "
"bp=%ph, bplen=%xh\n", opcode, bp, bplen);
return (len);
}
- if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
+ if (CFG_IST(ha, CFG_ISP_FW_TYPE_1)) {
return (len);
}
if ((vpdbuf = (uint8_t *)kmem_zalloc(QL_24XX_VPD_SIZE,
KM_SLEEP)) == NULL) {
@@ -1507,11 +1494,11 @@
/*
* make sure that the vpd len doesn't exceed the
* vpd end
*/
- if (vpd+len > vpdbuf + QL_24XX_VPD_SIZE) {
+ if (vpd + len > vpdbuf + QL_24XX_VPD_SIZE) {
EL(ha, "vpd tag len (%xh) exceeds vpd buffer "
"length\n", len);
len = -1;
}
}
@@ -1519,15 +1506,15 @@
if (len >= 0) {
/*
* make sure we don't exceed callers buffer space len
*/
if (len > bplen) {
- len = bplen-1;
+ len = bplen - 1;
}
/* copy the data back */
- (void) strncpy((int8_t *)bp, (int8_t *)(vpd+3), (int64_t)len);
+ (void) strncpy((int8_t *)bp, (int8_t *)(vpd + 3), (int64_t)len);
bp[len] = NULL;
} else {
/* error -- couldn't find tag */
bp[0] = NULL;
if (opcode[1] != NULL) {
@@ -1537,11 +1524,11 @@
}
}
kmem_free(vpdbuf, QL_24XX_VPD_SIZE);
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_3(ha, "done\n");
return (len);
}
/*
@@ -1567,12 +1554,12 @@
{
uint8_t *bp;
uint32_t xfer, bsize, saddr, ofst;
int rval = 0;
- QL_PRINT_9(CE_CONT, "(%d): started, dp=%ph, faddr=%xh, bc=%xh\n",
- ha->instance, (void *)dp, faddr, bc);
+ QL_PRINT_9(ha, "started, dp=%ph, faddr=%xh, bc=%xh\n",
+ (void *)dp, faddr, bc);
bsize = ha->xioctl->fdesc.block_size;
saddr = faddr & ~(bsize - 1);
ofst = faddr & (bsize - 1);
@@ -1584,12 +1571,12 @@
while (bc) {
xfer = bc > bsize ? bsize : bc;
if (ofst + xfer > bsize) {
xfer = bsize - ofst;
}
- QL_PRINT_9(CE_CONT, "(%d): dp=%ph, saddr=%xh, bc=%xh, "
- "ofst=%xh, xfer=%xh\n", ha->instance, (void *)dp, saddr,
+ QL_PRINT_9(ha, "dp=%ph, saddr=%xh, bc=%xh, "
+ "ofst=%xh, xfer=%xh\n", (void *)dp, saddr,
bc, ofst, xfer);
if (ofst || xfer < bsize) {
/* Dump Flash sector. */
if ((rval = ql_dump_fcode(ha, bp, bsize, saddr)) !=
@@ -1620,11 +1607,11 @@
ofst = 0;
}
kmem_free(bp, bsize);
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (rval);
}
/*
@@ -1650,12 +1637,12 @@
if (ddi_copyin(arg, &dop, sizeof (ql_adm_op_t), mode) != 0) {
EL(ha, "failed, driver_op_t ddi_copyin\n");
return (EFAULT);
}
- QL_PRINT_9(CE_CONT, "(%d): started, cmd=%xh, buffer=%llx,"
- " length=%xh, option=%xh\n", ha->instance, dop.cmd, dop.buffer,
+ QL_PRINT_9(ha, "started, cmd=%xh, buffer=%llx,"
+ " length=%xh, option=%xh\n", dop.cmd, dop.buffer,
dop.length, dop.option);
switch (dop.cmd) {
case QL_ADAPTER_INFO:
rval = ql_adm_adapter_info(ha, &dop, mode);
@@ -1683,10 +1670,19 @@
case QL_FW_DUMP:
rval = ql_adm_fw_dump(ha, &dop, arg, mode);
break;
+ case QL_FW_DUMP_TRIGGER:
+ rval = ql_adm_fw_t_dump(ha);
+ break;
+
+ case QL_BEACON_ENABLE:
+ case QL_BEACON_DISABLE:
+ rval = ql_adm_beacon(ha, &dop);
+ break;
+
case QL_NVRAM_LOAD:
rval = ql_adm_nvram_load(ha, &dop, mode);
break;
case QL_NVRAM_DUMP:
@@ -1716,11 +1712,11 @@
default:
EL(ha, "unsupported driver op cmd: %x\n", dop.cmd);
return (EINVAL);
}
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (rval);
}
/*
@@ -1743,23 +1739,21 @@
ql_adapter_info_t hba;
uint8_t *dp;
uint32_t length;
int rval, i;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
hba.device_id = ha->device_id;
- dp = CFG_IST(ha, CFG_CTRL_24258081) ?
- &ha->init_ctrl_blk.cb24.port_name[0] :
- &ha->init_ctrl_blk.cb.port_name[0];
+ dp = ha->loginparams.nport_ww_name.raw_wwn;
bcopy(dp, hba.wwpn, 8);
hba.d_id = ha->d_id.b24;
if (ha->xioctl->fdesc.flash_size == 0 &&
- !(CFG_IST(ha, CFG_CTRL_2200) && !ha->subven_id)) {
+ !(CFG_IST(ha, CFG_CTRL_22XX) && !ha->subven_id)) {
if (ql_stall_driver(ha, 0) != QL_SUCCESS) {
EL(ha, "ql_stall_driver failed\n");
return (EBUSY);
}
@@ -1770,11 +1764,11 @@
}
return (EIO);
}
/* Resume I/O */
- if (CFG_IST(ha, CFG_CTRL_24258081)) {
+ if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
ql_restart_driver(ha);
} else {
EL(ha, "isp_abort_needed for restart\n");
ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED,
DRIVER_STALL);
@@ -1807,11 +1801,11 @@
dop->length, mode) != 0) {
EL(ha, "failed, ddi_copyout\n");
return (EFAULT);
}
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (0);
}
/*
@@ -1831,11 +1825,11 @@
ql_adm_extended_logging(ql_adapter_state_t *ha, ql_adm_op_t *dop)
{
char prop_name[MAX_PROP_LENGTH];
int rval;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
(void) sprintf(prop_name, "hba%d-extended-logging", ha->instance);
/*LINTED [Solaris DDI_DEV_T_NONE Lint warning]*/
rval = ddi_prop_update_int(DDI_DEV_T_NONE, ha->dip, prop_name,
@@ -1847,11 +1841,11 @@
dop->option ?
(ha->cfg_flags |= CFG_ENABLE_EXTENDED_LOGGING) :
(ha->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING);
}
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (0);
}
/*
@@ -1869,20 +1863,29 @@
static int
ql_adm_loop_reset(ql_adapter_state_t *ha)
{
int rval;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
+ if (CFG_IST(ha, CFG_CTRL_82XX)) {
+ rval = ql_8021_fw_reload(ha);
+ ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, 0);
+ if (rval != QL_SUCCESS) {
+ EL(ha, "failed, ql_8021_fw_reload=%xh\n", rval);
+ return (EIO);
+ }
+ } else {
if (ha->task_daemon_flags & LOOP_DOWN) {
(void) ql_full_login_lip(ha);
} else if ((rval = ql_full_login_lip(ha)) != QL_SUCCESS) {
EL(ha, "failed, ql_initiate_lip=%xh\n", rval);
return (EIO);
}
+ }
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (0);
}
/*
@@ -1905,11 +1908,11 @@
ql_device_info_t dev;
ql_link_t *link;
ql_tgt_t *tq;
uint32_t index, cnt;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
cnt = 0;
dev.address = 0xffffffff;
/* Scan port list for requested target and fill in the values */
@@ -1945,11 +1948,11 @@
dop->length, mode) != 0) {
EL(ha, "failed, ddi_copyout\n");
return (EFAULT);
}
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (0);
}
/*
@@ -1968,11 +1971,11 @@
ql_adm_update_properties(ql_adapter_state_t *ha)
{
ql_comb_init_cb_t init_ctrl_blk;
ql_comb_ip_init_cb_t ip_init_ctrl_blk;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
/* Stall driver instance. */
(void) ql_stall_driver(ha, 0);
/* Save init control blocks. */
@@ -2005,11 +2008,11 @@
}
/* Restart driver instance. */
ql_restart_driver(ha);
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (0);
}
/*
@@ -2030,11 +2033,11 @@
ql_adm_prop_update_int(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
{
char *prop_name;
int rval;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
prop_name = kmem_zalloc(dop->length, KM_SLEEP);
if (prop_name == NULL) {
EL(ha, "failed, kmem_zalloc\n");
return (ENOMEM);
@@ -2055,11 +2058,11 @@
return (EINVAL);
}
kmem_free(prop_name, dop->length);
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (0);
}
/*
@@ -2080,11 +2083,11 @@
static int
ql_adm_fw_dump(ql_adapter_state_t *ha, ql_adm_op_t *dop, void *udop, int mode)
{
caddr_t dmp;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
if (dop->length < ha->risc_dump_size) {
EL(ha, "failed, incorrect length=%xh, size=%xh\n",
dop->length, ha->risc_dump_size);
return (EINVAL);
@@ -2116,16 +2119,82 @@
if (ddi_copyout(dop, udop, sizeof (ql_adm_op_t), mode) != 0) {
EL(ha, "failed, driver_op_t ddi_copyout\n");
return (EFAULT);
}
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (0);
}
/*
+ * ql_adm_fw_t_dump
+ * Performs qladm QL_FW_DUMP_TRIGGER command
+ *
+ * Input:
+ * ha: adapter state pointer.
+ *
+ * Returns:
+ *
+ * Context:
+ * Kernel context.
+ */
+static int
+ql_adm_fw_t_dump(ql_adapter_state_t *ha)
+{
+ int rval;
+
+ QL_PRINT_9(ha, "started\n");
+
+ if (ha->ql_dump_state & QL_DUMP_VALID) {
+ EL(ha, "Already contains a dump file\n");
+ return (EINVAL);
+ }
+ rval = ql_dump_firmware(ha);
+
+ QL_PRINT_9(ha, "done\n");
+
+ if (rval == QL_SUCCESS || rval == QL_DATA_EXISTS) {
+ return (0);
+ }
+ return (EFAULT);
+}
+
+/*
+ * ql_adm_beacon
+ * Performs qladm QL_BEACON_ENABLE/DISABLE command
+ *
+ * Input:
+ * ha: adapter state pointer.
+ * dop: ql_adm_op_t structure pointer.
+ *
+ * Returns:
+ *
+ * Context:
+ * Kernel context.
+ */
+static int
+ql_adm_beacon(ql_adapter_state_t *ha, ql_adm_op_t *dop)
+{
+ int rval;
+ ql_mbx_data_t mr;
+
+ if (!CFG_IST(ha, CFG_CTRL_82XX)) {
+ return (EIO);
+ }
+
+ rval = ql_diag_beacon(ha, dop->cmd, &mr);
+
+ if (rval == QL_SUCCESS) {
+ return (0);
+ }
+
+ return (rval);
+}
+
+
+/*
* ql_adm_nvram_dump
* Performs qladm QL_NVRAM_DUMP command
*
* Input:
* ha: adapter state pointer.
@@ -2140,11 +2209,11 @@
static int
ql_adm_nvram_dump(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
{
int rval;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
if (dop->length < ha->nvram_cache->size) {
EL(ha, "failed, length=%xh, size=%xh\n", dop->length,
ha->nvram_cache->size);
return (EINVAL);
@@ -2153,11 +2222,11 @@
if ((rval = ql_nv_util_dump(ha, (void *)(uintptr_t)dop->buffer,
mode)) != 0) {
EL(ha, "failed, ql_nv_util_dump\n");
} else {
/*EMPTY*/
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
}
return (rval);
}
@@ -2178,11 +2247,11 @@
static int
ql_adm_nvram_load(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
{
int rval;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
if (dop->length < ha->nvram_cache->size) {
EL(ha, "failed, length=%xh, size=%xh\n", dop->length,
ha->nvram_cache->size);
return (EINVAL);
@@ -2191,11 +2260,11 @@
if ((rval = ql_nv_util_load(ha, (void *)(uintptr_t)dop->buffer,
mode)) != 0) {
EL(ha, "failed, ql_nv_util_dump\n");
} else {
/*EMPTY*/
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
}
return (rval);
}
@@ -2217,11 +2286,11 @@
ql_adm_flash_load(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
{
uint8_t *dp;
int rval;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
if ((dp = kmem_zalloc(dop->length, KM_SLEEP)) == NULL) {
EL(ha, "failed, kmem_zalloc\n");
return (ENOMEM);
}
@@ -2237,11 +2306,11 @@
EL(ha, "ql_stall_driver failed\n");
kmem_free(dp, dop->length);
return (EBUSY);
}
- rval = (CFG_IST(ha, CFG_CTRL_24258081) ?
+ rval = (CFG_IST(ha, CFG_ISP_FW_TYPE_2) ?
ql_24xx_load_flash(ha, dp, dop->length, dop->option) :
ql_load_flash(ha, dp, dop->length));
ql_restart_driver(ha);
@@ -2250,11 +2319,11 @@
if (rval != QL_SUCCESS) {
EL(ha, "failed\n");
return (EIO);
}
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (0);
}
/*
@@ -2274,13 +2343,13 @@
static int
ql_adm_vpd_dump(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
{
int rval;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
- if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
+ if (CFG_IST(ha, CFG_ISP_FW_TYPE_1)) {
EL(ha, "hba does not support VPD\n");
return (EINVAL);
}
if (dop->length < QL_24XX_VPD_SIZE) {
@@ -2292,11 +2361,11 @@
if ((rval = ql_vpd_dump(ha, (void *)(uintptr_t)dop->buffer, mode))
!= 0) {
EL(ha, "failed, ql_vpd_dump\n");
} else {
/*EMPTY*/
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
}
return (rval);
}
@@ -2317,13 +2386,13 @@
static int
ql_adm_vpd_load(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
{
int rval;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
- if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
+ if (CFG_IST(ha, CFG_ISP_FW_TYPE_1)) {
EL(ha, "hba does not support VPD\n");
return (EINVAL);
}
if (dop->length < QL_24XX_VPD_SIZE) {
@@ -2335,11 +2404,11 @@
if ((rval = ql_vpd_load(ha, (void *)(uintptr_t)dop->buffer, mode))
!= 0) {
EL(ha, "failed, ql_vpd_dump\n");
} else {
/*EMPTY*/
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
}
return (rval);
}
@@ -2361,13 +2430,13 @@
ql_adm_vpd_gettag(ql_adapter_state_t *ha, ql_adm_op_t *dop, int mode)
{
int rval = 0;
uint8_t *lbuf;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
- if ((CFG_IST(ha, CFG_CTRL_24258081)) == 0) {
+ if (CFG_IST(ha, CFG_ISP_FW_TYPE_1)) {
EL(ha, "hba does not support VPD\n");
return (EINVAL);
}
if ((lbuf = (uint8_t *)kmem_zalloc(dop->length, KM_SLEEP)) == NULL) {
@@ -2384,21 +2453,21 @@
if ((rval = ql_vpd_lookup(ha, lbuf, lbuf, (int32_t)
dop->length)) < 0) {
EL(ha, "failed vpd_lookup\n");
} else {
if (ddi_copyout(lbuf, (void *)(uintptr_t)dop->buffer,
- strlen((int8_t *)lbuf)+1, mode) != 0) {
+ strlen((int8_t *)lbuf) + 1, mode) != 0) {
EL(ha, "failed, ddi_copyout\n");
rval = EFAULT;
} else {
rval = 0;
}
}
kmem_free(lbuf, dop->length);
}
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (rval);
}
/*
@@ -2422,11 +2491,11 @@
int rval = DDI_SUCCESS;
ql_link_t *link;
ql_adapter_state_t *ha2 = NULL;
uint16_t fw_class = (uint16_t)dop->option;
- QL_PRINT_9(CE_CONT, "(%d): started\n", ha->instance);
+ QL_PRINT_9(ha, "started\n");
/* zero the firmware module reference count */
for (link = ql_hba.first; link != NULL; link = link->next) {
ha2 = link->base_address;
if (fw_class == ha2->fw_class) {
@@ -2460,9 +2529,9 @@
rval = 0;
}
}
- QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
+ QL_PRINT_9(ha, "done\n");
return (rval);
}