mirror of https://gitee.com/openkylin/linux.git
[SCSI] qla2xxx: Provide method for updating I2C attached VPD.
Provide bsg interface for updating VPD attached on the I2C serial bus. Signed-off-by: Joe Carnuccio <joe.carnuccio@qlogic.com> Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
1fedd80f9c
commit
697a4bc691
|
@ -1447,6 +1447,148 @@ qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
|
|||
return rval;
|
||||
}
|
||||
|
||||
static int
|
||||
qla2x00_update_fru_versions(struct fc_bsg_job *bsg_job)
|
||||
{
|
||||
struct Scsi_Host *host = bsg_job->shost;
|
||||
scsi_qla_host_t *vha = shost_priv(host);
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
int rval = 0;
|
||||
uint8_t bsg[DMA_POOL_SIZE];
|
||||
struct qla_image_version_list *list = (void *)bsg;
|
||||
struct qla_image_version *image;
|
||||
uint32_t count;
|
||||
dma_addr_t sfp_dma;
|
||||
void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
|
||||
if (!sfp) {
|
||||
bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
EXT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
sg_copy_to_buffer(bsg_job->request_payload.sg_list,
|
||||
bsg_job->request_payload.sg_cnt, list, sizeof(bsg));
|
||||
|
||||
image = list->version;
|
||||
count = list->count;
|
||||
while (count--) {
|
||||
memcpy(sfp, &image->field_info, sizeof(image->field_info));
|
||||
rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
|
||||
image->field_address.device, image->field_address.offset,
|
||||
sizeof(image->field_info), image->field_address.option);
|
||||
if (rval) {
|
||||
bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
EXT_STATUS_MAILBOX;
|
||||
goto dealloc;
|
||||
}
|
||||
image++;
|
||||
}
|
||||
|
||||
bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
|
||||
|
||||
dealloc:
|
||||
dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
|
||||
|
||||
done:
|
||||
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
|
||||
bsg_job->reply->result = DID_OK << 16;
|
||||
bsg_job->job_done(bsg_job);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
qla2x00_read_fru_status(struct fc_bsg_job *bsg_job)
|
||||
{
|
||||
struct Scsi_Host *host = bsg_job->shost;
|
||||
scsi_qla_host_t *vha = shost_priv(host);
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
int rval = 0;
|
||||
uint8_t bsg[DMA_POOL_SIZE];
|
||||
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_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
EXT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
sg_copy_to_buffer(bsg_job->request_payload.sg_list,
|
||||
bsg_job->request_payload.sg_cnt, sr, sizeof(*sr));
|
||||
|
||||
rval = qla2x00_read_sfp(vha, sfp_dma, sfp,
|
||||
sr->field_address.device, sr->field_address.offset,
|
||||
sizeof(sr->status_reg), sr->field_address.option);
|
||||
sr->status_reg = *sfp;
|
||||
|
||||
if (rval) {
|
||||
bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
EXT_STATUS_MAILBOX;
|
||||
goto dealloc;
|
||||
}
|
||||
|
||||
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
|
||||
bsg_job->reply_payload.sg_cnt, sr, sizeof(*sr));
|
||||
|
||||
bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
|
||||
|
||||
dealloc:
|
||||
dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
|
||||
|
||||
done:
|
||||
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
|
||||
bsg_job->reply->reply_payload_rcv_len = sizeof(*sr);
|
||||
bsg_job->reply->result = DID_OK << 16;
|
||||
bsg_job->job_done(bsg_job);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
qla2x00_write_fru_status(struct fc_bsg_job *bsg_job)
|
||||
{
|
||||
struct Scsi_Host *host = bsg_job->shost;
|
||||
scsi_qla_host_t *vha = shost_priv(host);
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
int rval = 0;
|
||||
uint8_t bsg[DMA_POOL_SIZE];
|
||||
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_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
EXT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
sg_copy_to_buffer(bsg_job->request_payload.sg_list,
|
||||
bsg_job->request_payload.sg_cnt, sr, sizeof(*sr));
|
||||
|
||||
*sfp = sr->status_reg;
|
||||
rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
|
||||
sr->field_address.device, sr->field_address.offset,
|
||||
sizeof(sr->status_reg), sr->field_address.option);
|
||||
|
||||
if (rval) {
|
||||
bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||
EXT_STATUS_MAILBOX;
|
||||
goto dealloc;
|
||||
}
|
||||
|
||||
bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
|
||||
|
||||
dealloc:
|
||||
dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
|
||||
|
||||
done:
|
||||
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
|
||||
bsg_job->reply->result = DID_OK << 16;
|
||||
bsg_job->job_done(bsg_job);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
|
||||
{
|
||||
|
@ -1475,6 +1617,15 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
|
|||
case QL_VND_UPDATE_FLASH:
|
||||
return qla2x00_update_optrom(bsg_job);
|
||||
|
||||
case QL_VND_SET_FRU_VERSION:
|
||||
return qla2x00_update_fru_versions(bsg_job);
|
||||
|
||||
case QL_VND_READ_FRU_STATUS:
|
||||
return qla2x00_read_fru_status(bsg_job);
|
||||
|
||||
case QL_VND_WRITE_FRU_STATUS:
|
||||
return qla2x00_write_fru_status(bsg_job);
|
||||
|
||||
default:
|
||||
bsg_job->reply->result = (DID_ERROR << 16);
|
||||
bsg_job->job_done(bsg_job);
|
||||
|
|
|
@ -16,6 +16,16 @@
|
|||
#define QL_VND_FCP_PRIO_CFG_CMD 0x06
|
||||
#define QL_VND_READ_FLASH 0x07
|
||||
#define QL_VND_UPDATE_FLASH 0x08
|
||||
#define QL_VND_SET_FRU_VERSION 0x0B
|
||||
#define QL_VND_READ_FRU_STATUS 0x0C
|
||||
#define QL_VND_WRITE_FRU_STATUS 0x0D
|
||||
|
||||
/* BSG Vendor specific subcode returns */
|
||||
#define EXT_STATUS_OK 0
|
||||
#define EXT_STATUS_ERR 1
|
||||
#define EXT_STATUS_INVALID_PARAM 6
|
||||
#define EXT_STATUS_MAILBOX 11
|
||||
#define EXT_STATUS_NO_MEMORY 17
|
||||
|
||||
/* BSG definations for interpreting CommandSent field */
|
||||
#define INT_DEF_LB_LOOPBACK_CMD 0
|
||||
|
@ -141,4 +151,36 @@ struct qla_port_param {
|
|||
uint16_t mode;
|
||||
uint16_t speed;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* FRU VPD */
|
||||
|
||||
#define MAX_FRU_SIZE 36
|
||||
|
||||
struct qla_field_address {
|
||||
uint16_t offset;
|
||||
uint16_t device;
|
||||
uint16_t option;
|
||||
} __packed;
|
||||
|
||||
struct qla_field_info {
|
||||
uint8_t version[MAX_FRU_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct qla_image_version {
|
||||
struct qla_field_address field_address;
|
||||
struct qla_field_info field_info;
|
||||
} __packed;
|
||||
|
||||
struct qla_image_version_list {
|
||||
uint32_t count;
|
||||
struct qla_image_version version[0];
|
||||
} __packed;
|
||||
|
||||
struct qla_status_reg {
|
||||
struct qla_field_address field_address;
|
||||
uint8_t status_reg;
|
||||
uint8_t reserved[7];
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue