Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 271013
b: refs/heads/master
c: 697a4bc
h: refs/heads/master
i:
  271011: 404772e
v: v3
  • Loading branch information
Joe Carnuccio authored and James Bottomley committed Aug 29, 2011
1 parent 1326b89 commit 38f30af
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1fedd80f9c2e1da9e6c2fa6a1b75ad077c70f291
refs/heads/master: 697a4bc69159c3396035b0506ffa55c4b2d0b1f4
151 changes: 151 additions & 0 deletions trunk/drivers/scsi/qla2xxx/qla_bsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down
42 changes: 42 additions & 0 deletions trunk/drivers/scsi/qla2xxx/qla_bsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

0 comments on commit 38f30af

Please sign in to comment.