summaryrefslogtreecommitdiff
path: root/drivers/scsi/qla2xxx/qla_bsg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_bsg.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c84
1 files changed, 65 insertions, 19 deletions
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 17d42658ad9a..5441557b424b 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -1,4 +1,4 @@
- /*
+/*
* QLogic Fibre Channel HBA Driver
* Copyright (c) 2003-2014 QLogic Corporation
*
@@ -84,8 +84,7 @@ qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *vha,
return 0;
}
- if (bcode[0] != 'H' || bcode[1] != 'Q' || bcode[2] != 'O' ||
- bcode[3] != 'S') {
+ if (memcmp(bcode, "HQOS", 4)) {
/* Invalid FCP priority data header*/
ql_dbg(ql_dbg_user, vha, 0x7052,
"Invalid FCP Priority data header. bcode=0x%x.\n",
@@ -1044,7 +1043,7 @@ qla84xx_updatefw(struct bsg_job *bsg_job)
}
flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
- fw_ver = le32_to_cpu(*((uint32_t *)((uint32_t *)fw_buf + 2)));
+ fw_ver = get_unaligned_le32((uint32_t *)fw_buf + 2);
mn->entry_type = VERIFY_CHIP_IOCB_TYPE;
mn->entry_count = 1;
@@ -1057,9 +1056,8 @@ qla84xx_updatefw(struct bsg_job *bsg_job)
mn->fw_ver = cpu_to_le32(fw_ver);
mn->fw_size = cpu_to_le32(data_len);
mn->fw_seq_size = cpu_to_le32(data_len);
- mn->dseg_address[0] = cpu_to_le32(LSD(fw_dma));
- mn->dseg_address[1] = cpu_to_le32(MSD(fw_dma));
- mn->dseg_length = cpu_to_le32(data_len);
+ put_unaligned_le64(fw_dma, &mn->dsd.address);
+ mn->dsd.length = cpu_to_le32(data_len);
mn->data_seg_cnt = cpu_to_le16(1);
rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
@@ -1238,9 +1236,8 @@ qla84xx_mgmt_cmd(struct bsg_job *bsg_job)
if (ql84_mgmt->mgmt.cmd != QLA84_MGMT_CHNG_CONFIG) {
mn->total_byte_cnt = cpu_to_le32(ql84_mgmt->mgmt.len);
mn->dseg_count = cpu_to_le16(1);
- mn->dseg_address[0] = cpu_to_le32(LSD(mgmt_dma));
- mn->dseg_address[1] = cpu_to_le32(MSD(mgmt_dma));
- mn->dseg_length = cpu_to_le32(ql84_mgmt->mgmt.len);
+ put_unaligned_le64(mgmt_dma, &mn->dsd.address);
+ mn->dsd.length = cpu_to_le32(ql84_mgmt->mgmt.len);
}
rval = qla2x00_issue_iocb(vha, mn, mn_dma, 0);
@@ -1354,7 +1351,7 @@ qla24xx_iidma(struct bsg_job *bsg_job)
if (rval) {
ql_log(ql_log_warn, vha, 0x704c,
- "iIDMA cmd failed for %8phN -- "
+ "iiDMA cmd failed for %8phN -- "
"%04x %x %04x %04x.\n", fcport->port_name,
rval, fcport->fp_speed, mb[0], mb[1]);
rval = (DID_ERROR << 16);
@@ -1412,7 +1409,8 @@ qla2x00_optrom_setup(struct bsg_job *bsg_job, scsi_qla_host_t *vha,
start == (ha->flt_region_fw * 4))
valid = 1;
else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
- IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha))
+ IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) ||
+ IS_QLA28XX(ha))
valid = 1;
if (!valid) {
ql_log(ql_log_warn, vha, 0x7058,
@@ -1534,6 +1532,7 @@ qla2x00_update_fru_versions(struct bsg_job *bsg_job)
uint32_t count;
dma_addr_t sfp_dma;
void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
+
if (!sfp) {
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_NO_MEMORY;
@@ -1584,6 +1583,7 @@ qla2x00_read_fru_status(struct bsg_job *bsg_job)
struct qla_status_reg *sr = (void *)bsg;
dma_addr_t sfp_dma;
uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
+
if (!sfp) {
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_NO_MEMORY;
@@ -1634,6 +1634,7 @@ qla2x00_write_fru_status(struct bsg_job *bsg_job)
struct qla_status_reg *sr = (void *)bsg;
dma_addr_t sfp_dma;
uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
+
if (!sfp) {
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_NO_MEMORY;
@@ -1680,6 +1681,7 @@ qla2x00_write_i2c(struct bsg_job *bsg_job)
struct qla_i2c_access *i2c = (void *)bsg;
dma_addr_t sfp_dma;
uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
+
if (!sfp) {
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_NO_MEMORY;
@@ -1725,6 +1727,7 @@ qla2x00_read_i2c(struct bsg_job *bsg_job)
struct qla_i2c_access *i2c = (void *)bsg;
dma_addr_t sfp_dma;
uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
+
if (!sfp) {
bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
EXT_STATUS_NO_MEMORY;
@@ -1961,7 +1964,7 @@ qlafx00_mgmt_cmd(struct bsg_job *bsg_job)
/* Dump the vendor information */
ql_dump_buffer(ql_dbg_user + ql_dbg_verbose , vha, 0x70cf,
- (uint8_t *)piocb_rqst, sizeof(struct qla_mt_iocb_rqst_fx00));
+ piocb_rqst, sizeof(*piocb_rqst));
if (!vha->flags.online) {
ql_log(ql_log_warn, vha, 0x70d0,
@@ -2157,7 +2160,7 @@ qla27xx_get_flash_upd_cap(struct bsg_job *bsg_job)
struct qla_hw_data *ha = vha->hw;
struct qla_flash_update_caps cap;
- if (!(IS_QLA27XX(ha)))
+ if (!(IS_QLA27XX(ha)) && !IS_QLA28XX(ha))
return -EPERM;
memset(&cap, 0, sizeof(cap));
@@ -2190,7 +2193,7 @@ qla27xx_set_flash_upd_cap(struct bsg_job *bsg_job)
uint64_t online_fw_attr = 0;
struct qla_flash_update_caps cap;
- if (!(IS_QLA27XX(ha)))
+ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
return -EPERM;
memset(&cap, 0, sizeof(cap));
@@ -2238,7 +2241,7 @@ qla27xx_get_bbcr_data(struct bsg_job *bsg_job)
uint8_t domain, area, al_pa, state;
int rval;
- if (!(IS_QLA27XX(ha)))
+ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
return -EPERM;
memset(&bbcr, 0, sizeof(bbcr));
@@ -2323,8 +2326,8 @@ qla2x00_get_priv_stats(struct bsg_job *bsg_job)
rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, options);
if (rval == QLA_SUCCESS) {
- ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, vha, 0x70e3,
- (uint8_t *)stats, sizeof(*stats));
+ ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, vha, 0x70e5,
+ stats, sizeof(*stats));
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, stats, sizeof(*stats));
}
@@ -2353,7 +2356,8 @@ qla2x00_do_dport_diagnostics(struct bsg_job *bsg_job)
int rval;
struct qla_dport_diag *dd;
- if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
+ if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) &&
+ !IS_QLA28XX(vha->hw))
return -EPERM;
dd = kmalloc(sizeof(*dd), GFP_KERNEL);
@@ -2388,6 +2392,45 @@ qla2x00_do_dport_diagnostics(struct bsg_job *bsg_job)
}
static int
+qla2x00_get_flash_image_status(struct bsg_job *bsg_job)
+{
+ scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
+ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
+ struct qla_hw_data *ha = vha->hw;
+ struct qla_active_regions regions = { };
+ struct active_regions active_regions = { };
+
+ qla28xx_get_aux_images(vha, &active_regions);
+ regions.global_image = active_regions.global;
+
+ if (IS_QLA28XX(ha)) {
+ qla27xx_get_active_image(vha, &active_regions);
+ regions.board_config = active_regions.aux.board_config;
+ regions.vpd_nvram = active_regions.aux.vpd_nvram;
+ regions.npiv_config_0_1 = active_regions.aux.npiv_config_0_1;
+ regions.npiv_config_2_3 = active_regions.aux.npiv_config_2_3;
+ }
+
+ ql_dbg(ql_dbg_user, vha, 0x70e1,
+ "%s(%lu): FW=%u BCFG=%u VPDNVR=%u NPIV01=%u NPIV02=%u\n",
+ __func__, vha->host_no, regions.global_image,
+ regions.board_config, regions.vpd_nvram,
+ regions.npiv_config_0_1, regions.npiv_config_2_3);
+
+ sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
+ bsg_job->reply_payload.sg_cnt, &regions, sizeof(regions));
+
+ bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
+ bsg_reply->reply_payload_rcv_len = sizeof(regions);
+ bsg_reply->result = DID_OK << 16;
+ bsg_job->reply_len = sizeof(struct fc_bsg_reply);
+ bsg_job_done(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
+
+ return 0;
+}
+
+static int
qla2x00_process_vendor_specific(struct bsg_job *bsg_job)
{
struct fc_bsg_request *bsg_request = bsg_job->request;
@@ -2460,6 +2503,9 @@ qla2x00_process_vendor_specific(struct bsg_job *bsg_job)
case QL_VND_DPORT_DIAGNOSTICS:
return qla2x00_do_dport_diagnostics(bsg_job);
+ case QL_VND_SS_GET_FLASH_IMAGE_STATUS:
+ return qla2x00_get_flash_image_status(bsg_job);
+
default:
return -ENOSYS;
}