Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 195607
b: refs/heads/master
c: 09ff701
h: refs/heads/master
i:
  195605: 9c5111c
  195603: f7f66b7
  195599: b3146f2
v: v3
  • Loading branch information
Sarang Radke authored and James Bottomley committed Apr 11, 2010
1 parent f02fdbc commit a0e20da
Show file tree
Hide file tree
Showing 8 changed files with 519 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6e98016ca077c5c751167bfdb1a3a2a3bee581cf
refs/heads/master: 09ff701a177b116c6c15b6e501e58fbfb306b424
163 changes: 163 additions & 0 deletions trunk/drivers/scsi/qla2xxx/qla_bsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,166 @@ qla2x00_get_ctx_bsg_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size)
return sp;
}

int
qla24xx_fcp_prio_cfg_valid(struct qla_fcp_prio_cfg *pri_cfg, uint8_t flag)
{
int i, ret, num_valid;
uint8_t *bcode;
struct qla_fcp_prio_entry *pri_entry;

ret = 1;
num_valid = 0;
bcode = (uint8_t *)pri_cfg;

if (bcode[0x0] != 'H' || bcode[0x1] != 'Q' || bcode[0x2] != 'O' ||
bcode[0x3] != 'S') {
return 0;
}
if (flag != 1)
return ret;

pri_entry = &pri_cfg->entry[0];
for (i = 0; i < pri_cfg->num_entries; i++) {
if (pri_entry->flags & FCP_PRIO_ENTRY_TAG_VALID)
num_valid++;
pri_entry++;
}

if (num_valid == 0)
ret = 0;

return ret;
}

static int
qla24xx_proc_fcp_prio_cfg_cmd(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 ret = 0;
uint32_t len;
uint32_t oper;

bsg_job->reply->reply_payload_rcv_len = 0;

if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
ret = -EBUSY;
goto exit_fcp_prio_cfg;
}

/* Get the sub command */
oper = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];

/* Only set config is allowed if config memory is not allocated */
if (!ha->fcp_prio_cfg && (oper != QLFC_FCP_PRIO_SET_CONFIG)) {
ret = -EINVAL;
goto exit_fcp_prio_cfg;
}
switch (oper) {
case QLFC_FCP_PRIO_DISABLE:
if (ha->flags.fcp_prio_enabled) {
ha->flags.fcp_prio_enabled = 0;
ha->fcp_prio_cfg->attributes &=
~FCP_PRIO_ATTR_ENABLE;
qla24xx_update_all_fcp_prio(vha);
bsg_job->reply->result = DID_OK;
} else {
ret = -EINVAL;
bsg_job->reply->result = (DID_ERROR << 16);
goto exit_fcp_prio_cfg;
}
break;

case QLFC_FCP_PRIO_ENABLE:
if (!ha->flags.fcp_prio_enabled) {
if (ha->fcp_prio_cfg) {
ha->flags.fcp_prio_enabled = 1;
ha->fcp_prio_cfg->attributes |=
FCP_PRIO_ATTR_ENABLE;
qla24xx_update_all_fcp_prio(vha);
bsg_job->reply->result = DID_OK;
} else {
ret = -EINVAL;
bsg_job->reply->result = (DID_ERROR << 16);
goto exit_fcp_prio_cfg;
}
}
break;

case QLFC_FCP_PRIO_GET_CONFIG:
len = bsg_job->reply_payload.payload_len;
if (!len || len > FCP_PRIO_CFG_SIZE) {
ret = -EINVAL;
bsg_job->reply->result = (DID_ERROR << 16);
goto exit_fcp_prio_cfg;
}

bsg_job->reply->result = DID_OK;
bsg_job->reply->reply_payload_rcv_len =
sg_copy_from_buffer(
bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, ha->fcp_prio_cfg,
len);

break;

case QLFC_FCP_PRIO_SET_CONFIG:
len = bsg_job->request_payload.payload_len;
if (!len || len > FCP_PRIO_CFG_SIZE) {
bsg_job->reply->result = (DID_ERROR << 16);
ret = -EINVAL;
goto exit_fcp_prio_cfg;
}

if (!ha->fcp_prio_cfg) {
ha->fcp_prio_cfg = vmalloc(FCP_PRIO_CFG_SIZE);
if (!ha->fcp_prio_cfg) {
qla_printk(KERN_WARNING, ha,
"Unable to allocate memory "
"for fcp prio config data (%x).\n",
FCP_PRIO_CFG_SIZE);
bsg_job->reply->result = (DID_ERROR << 16);
ret = -ENOMEM;
goto exit_fcp_prio_cfg;
}
}

memset(ha->fcp_prio_cfg, 0, FCP_PRIO_CFG_SIZE);
sg_copy_to_buffer(bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt, ha->fcp_prio_cfg,
FCP_PRIO_CFG_SIZE);

/* validate fcp priority data */
if (!qla24xx_fcp_prio_cfg_valid(
(struct qla_fcp_prio_cfg *)
ha->fcp_prio_cfg, 1)) {
bsg_job->reply->result = (DID_ERROR << 16);
ret = -EINVAL;
/* If buffer was invalidatic int
* fcp_prio_cfg is of no use
*/
vfree(ha->fcp_prio_cfg);
ha->fcp_prio_cfg = NULL;
goto exit_fcp_prio_cfg;
}

ha->flags.fcp_prio_enabled = 0;
if (ha->fcp_prio_cfg->attributes & FCP_PRIO_ATTR_ENABLE)
ha->flags.fcp_prio_enabled = 1;
qla24xx_update_all_fcp_prio(vha);
bsg_job->reply->result = DID_OK;
break;
default:
ret = -EINVAL;
break;
}
exit_fcp_prio_cfg:
bsg_job->job_done(bsg_job);
return ret;
}
static int
qla2x00_process_els(struct fc_bsg_job *bsg_job)
{
Expand Down Expand Up @@ -948,6 +1108,9 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
case QL_VND_IIDMA:
return qla24xx_iidma(bsg_job);

case QL_VND_FCP_PRIO_CFG_CMD:
return qla24xx_proc_fcp_prio_cfg_cmd(bsg_job);

default:
bsg_job->reply->result = (DID_ERROR << 16);
bsg_job->job_done(bsg_job);
Expand Down
7 changes: 7 additions & 0 deletions trunk/drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -1580,6 +1580,8 @@ typedef struct fc_port {
uint16_t loop_id;
uint16_t old_loop_id;

uint8_t fcp_prio;

uint8_t fabric_port_name[WWN_SIZE];
uint16_t fp_speed;

Expand Down Expand Up @@ -2296,6 +2298,7 @@ struct qla_hw_data {
uint32_t eeh_busy :1;
uint32_t cpu_affinity_enabled :1;
uint32_t disable_msix_handshake :1;
uint32_t fcp_prio_enabled :1;
} flags;

/* This spinlock is used to protect "io transactions", you must
Expand Down Expand Up @@ -2599,6 +2602,7 @@ struct qla_hw_data {
uint32_t flt_region_nvram;
uint32_t flt_region_npiv_conf;
uint32_t flt_region_gold_fw;
uint32_t flt_region_fcp_prio;

/* Needed for BEACON */
uint16_t beacon_blink_led;
Expand Down Expand Up @@ -2627,6 +2631,9 @@ struct qla_hw_data {
struct isp_operations *isp_ops;
struct workqueue_struct *wq;
struct qlfc_fw fw_buf;

/* FCP_CMND priority support */
struct qla_fcp_prio_cfg *fcp_prio_cfg;
};

/*
Expand Down
59 changes: 59 additions & 0 deletions trunk/drivers/scsi/qla2xxx/qla_fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,8 @@ struct device_reg_24xx {
#define FA_HW_EVENT_ENTRY_SIZE 4
#define FA_NPIV_CONF0_ADDR 0x5C000
#define FA_NPIV_CONF1_ADDR 0x5D000
#define FA_FCP_PRIO0_ADDR 0x10000
#define FA_FCP_PRIO1_ADDR 0x12000

/*
* Flash Error Log Event Codes.
Expand Down Expand Up @@ -1274,6 +1276,8 @@ struct qla_flt_header {
#define FLT_REG_NPIV_CONF_0 0x29
#define FLT_REG_NPIV_CONF_1 0x2a
#define FLT_REG_GOLD_FW 0x2f
#define FLT_REG_FCP_PRIO_0 0x87
#define FLT_REG_FCP_PRIO_1 0x88

struct qla_flt_region {
uint32_t code;
Expand Down Expand Up @@ -1750,6 +1754,61 @@ struct ex_init_cb_81xx {
#define FARX_ACCESS_FLASH_CONF_81XX 0x7FFD0000
#define FARX_ACCESS_FLASH_DATA_81XX 0x7F800000

/* FCP priority config defines *************************************/
/* operations */
#define QLFC_FCP_PRIO_DISABLE 0x0
#define QLFC_FCP_PRIO_ENABLE 0x1
#define QLFC_FCP_PRIO_GET_CONFIG 0x2
#define QLFC_FCP_PRIO_SET_CONFIG 0x3

struct qla_fcp_prio_entry {
uint16_t flags; /* Describes parameter(s) in FCP */
/* priority entry that are valid */
#define FCP_PRIO_ENTRY_VALID 0x1
#define FCP_PRIO_ENTRY_TAG_VALID 0x2
#define FCP_PRIO_ENTRY_SPID_VALID 0x4
#define FCP_PRIO_ENTRY_DPID_VALID 0x8
#define FCP_PRIO_ENTRY_LUNB_VALID 0x10
#define FCP_PRIO_ENTRY_LUNE_VALID 0x20
#define FCP_PRIO_ENTRY_SWWN_VALID 0x40
#define FCP_PRIO_ENTRY_DWWN_VALID 0x80
uint8_t tag; /* Priority value */
uint8_t reserved; /* Reserved for future use */
uint32_t src_pid; /* Src port id. high order byte */
/* unused; -1 (wild card) */
uint32_t dst_pid; /* Src port id. high order byte */
/* unused; -1 (wild card) */
uint16_t lun_beg; /* 1st lun num of lun range. */
/* -1 (wild card) */
uint16_t lun_end; /* 2nd lun num of lun range. */
/* -1 (wild card) */
uint8_t src_wwpn[8]; /* Source WWPN: -1 (wild card) */
uint8_t dst_wwpn[8]; /* Destination WWPN: -1 (wild card) */
};

struct qla_fcp_prio_cfg {
uint8_t signature[4]; /* "HQOS" signature of config data */
uint16_t version; /* 1: Initial version */
uint16_t length; /* config data size in num bytes */
uint16_t checksum; /* config data bytes checksum */
uint16_t num_entries; /* Number of entries */
uint16_t size_of_entry; /* Size of each entry in num bytes */
uint8_t attributes; /* enable/disable, persistence */
#define FCP_PRIO_ATTR_DISABLE 0x0
#define FCP_PRIO_ATTR_ENABLE 0x1
#define FCP_PRIO_ATTR_PERSIST 0x2
uint8_t reserved; /* Reserved for future use */
#define FCP_PRIO_CFG_HDR_SIZE 0x10
struct qla_fcp_prio_entry entry[1]; /* fcp priority entries */
#define FCP_PRIO_CFG_ENTRY_SIZE 0x20
};

#define FCP_PRIO_CFG_SIZE (32*1024) /* fcp prio data per port*/

/* 25XX Support ****************************************************/
#define FA_FCP_PRIO0_ADDR_25 0x3C000
#define FA_FCP_PRIO1_ADDR_25 0x3E000

/* 81XX Flash locations -- occupies second 2MB region. */
#define FA_BOOT_CODE_ADDR_81 0x80000
#define FA_RISC_CODE_ADDR_81 0xA0000
Expand Down
9 changes: 8 additions & 1 deletion trunk/drivers/scsi/qla2xxx/qla_gbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,9 @@ extern int
qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t);

extern int qla2x00_get_data_rate(scsi_qla_host_t *);
extern int qla24xx_set_fcp_prio(scsi_qla_host_t *, uint16_t, uint16_t,
uint16_t *);

/*
* Global Function Prototypes in qla_isr.c source file.
*/
Expand Down Expand Up @@ -384,6 +387,7 @@ extern int qla2xxx_get_flash_info(scsi_qla_host_t *);
extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t);

extern void qla2xxx_flash_npiv_conf(scsi_qla_host_t *);
extern int qla24xx_read_fcp_prio_cfg(scsi_qla_host_t *);

/*
* Global Function Prototypes in qla_dbg.c source file.
Expand Down Expand Up @@ -430,7 +434,10 @@ extern void qla2x00_init_host_attr(scsi_qla_host_t *);
extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
extern int qla2x00_loopback_test(scsi_qla_host_t *, struct msg_echo_lb *, uint16_t *);
extern int qla2x00_echo_test(scsi_qla_host_t *, struct msg_echo_lb *, uint16_t *);
extern int qla2x00_echo_test(scsi_qla_host_t *,
struct msg_echo_lb *, uint16_t *);
extern int qla24xx_update_all_fcp_prio(scsi_qla_host_t *);
extern int qla24xx_fcp_prio_cfg_valid(struct qla_fcp_prio_cfg *, uint8_t);

/*
* Global Function Prototypes in qla_dfs.c source file.
Expand Down
Loading

0 comments on commit a0e20da

Please sign in to comment.