diff options
Diffstat (limited to 'drivers/scsi/be2iscsi/be_cmds.c')
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.c | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index a79a5e72c777..2eb66df3e3d6 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -1,5 +1,5 @@ /* - * Copyright 2017 Broadcom. All Rights Reserved. + * Copyright 2017 Broadcom. All Rights Reserved. * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -675,8 +675,8 @@ static int be_mbox_notify(struct be_ctrl_info *ctrl) return status; } -void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len, - bool embedded, u8 sge_cnt) +void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, u32 payload_len, + bool embedded, u8 sge_cnt) { if (embedded) wrb->emb_sgecnt_special |= MCC_WRB_EMBEDDED_MASK; @@ -688,7 +688,7 @@ void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len, } void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr, - u8 subsystem, u8 opcode, int cmd_len) + u8 subsystem, u8 opcode, u32 cmd_len) { req_hdr->opcode = opcode; req_hdr->subsystem = subsystem; @@ -947,7 +947,6 @@ int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q, default: mutex_unlock(&ctrl->mbox_lock); BUG(); - return -ENXIO; } be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req)); if (queue_type != QTYPE_SGL) @@ -1522,6 +1521,52 @@ int beiscsi_get_port_name(struct be_ctrl_info *ctrl, struct beiscsi_hba *phba) return ret; } +int beiscsi_set_host_data(struct beiscsi_hba *phba) +{ + struct be_ctrl_info *ctrl = &phba->ctrl; + struct be_cmd_set_host_data *ioctl; + struct be_mcc_wrb *wrb; + int ret = 0; + + if (is_chip_be2_be3r(phba)) + return ret; + + mutex_lock(&ctrl->mbox_lock); + wrb = wrb_from_mbox(&ctrl->mbox_mem); + memset(wrb, 0, sizeof(*wrb)); + ioctl = embedded_payload(wrb); + + be_wrb_hdr_prepare(wrb, sizeof(*ioctl), true, 0); + be_cmd_hdr_prepare(&ioctl->h.req_hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_SET_HOST_DATA, + EMBED_MBX_MAX_PAYLOAD_SIZE); + ioctl->param.req.param_id = BE_CMD_SET_HOST_PARAM_ID; + ioctl->param.req.param_len = + snprintf((char *)ioctl->param.req.param_data, + sizeof(ioctl->param.req.param_data), + "Linux iSCSI v%s", BUILD_STR); + ioctl->param.req.param_len = ALIGN(ioctl->param.req.param_len, 4); + if (ioctl->param.req.param_len > BE_CMD_MAX_DRV_VERSION) + ioctl->param.req.param_len = BE_CMD_MAX_DRV_VERSION; + ret = be_mbox_notify(ctrl); + if (!ret) { + beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, + "BG_%d : HBA set host driver version\n"); + } else { + /** + * Check "MCC_STATUS_INVALID_LENGTH" for SKH. + * Older FW versions return this error. + */ + if (ret == MCC_STATUS_ILLEGAL_REQUEST || + ret == MCC_STATUS_INVALID_LENGTH) + __beiscsi_log(phba, KERN_INFO, + "BG_%d : HBA failed to set host driver version\n"); + } + + mutex_unlock(&ctrl->mbox_lock); + return ret; +} + int beiscsi_set_uer_feature(struct beiscsi_hba *phba) { struct be_ctrl_info *ctrl = &phba->ctrl; |