Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 328834
b: refs/heads/master
c: a9b6f72
h: refs/heads/master
v: v3
  • Loading branch information
Saurav Kashyap authored and James Bottomley committed Sep 24, 2012
1 parent bc1f8b1 commit 9556e74
Show file tree
Hide file tree
Showing 12 changed files with 657 additions and 13 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: 5f16b331d83757ad5154af07b449c722fef45d5e
refs/heads/master: a9b6f722f62d0a302b980a4fdcdf9c9933955772
29 changes: 29 additions & 0 deletions trunk/drivers/scsi/qla2xxx/qla_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1251,6 +1251,31 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
state[1], state[2], state[3], state[4]);
}

static ssize_t
qla2x00_diag_requests_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));

if (!IS_BIDI_CAPABLE(vha->hw))
return snprintf(buf, PAGE_SIZE, "\n");

return snprintf(buf, PAGE_SIZE, "%llu\n", vha->bidi_stats.io_count);
}

static ssize_t
qla2x00_diag_megabytes_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));

if (!IS_BIDI_CAPABLE(vha->hw))
return snprintf(buf, PAGE_SIZE, "\n");

return snprintf(buf, PAGE_SIZE, "%llu\n",
vha->bidi_stats.transfer_bytes >> 20);
}

static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
Expand Down Expand Up @@ -1289,6 +1314,8 @@ static DEVICE_ATTR(vn_port_mac_address, S_IRUGO,
static DEVICE_ATTR(fabric_param, S_IRUGO, qla2x00_fabric_param_show, NULL);
static DEVICE_ATTR(fw_state, S_IRUGO, qla2x00_fw_state_show, NULL);
static DEVICE_ATTR(thermal_temp, S_IRUGO, qla2x00_thermal_temp_show, NULL);
static DEVICE_ATTR(diag_requests, S_IRUGO, qla2x00_diag_requests_show, NULL);
static DEVICE_ATTR(diag_megabytes, S_IRUGO, qla2x00_diag_megabytes_show, NULL);

struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_driver_version,
Expand Down Expand Up @@ -1318,6 +1345,8 @@ struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_fw_state,
&dev_attr_optrom_gold_fw_version,
&dev_attr_thermal_temp,
&dev_attr_diag_requests,
&dev_attr_diag_megabytes,
NULL,
};

Expand Down
183 changes: 183 additions & 0 deletions trunk/drivers/scsi/qla2xxx/qla_bsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1649,6 +1649,186 @@ qla2x00_read_i2c(struct fc_bsg_job *bsg_job)
return 0;
}

static int
qla24xx_process_bidir_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;
uint16_t thread_id;
uint32_t rval = EXT_STATUS_OK;
uint16_t req_sg_cnt = 0;
uint16_t rsp_sg_cnt = 0;
uint16_t nextlid = 0;
uint32_t tot_dsds;
srb_t *sp = NULL;
uint32_t req_data_len = 0;
uint32_t rsp_data_len = 0;

/* Check the type of the adapter */
if (!IS_BIDI_CAPABLE(ha)) {
ql_log(ql_log_warn, vha, 0x70a0,
"This adapter is not supported\n");
rval = EXT_STATUS_NOT_SUPPORTED;
goto done;
}

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)) {
rval = EXT_STATUS_BUSY;
goto done;
}

/* Check if host is online */
if (!vha->flags.online) {
ql_log(ql_log_warn, vha, 0x70a1,
"Host is not online\n");
rval = EXT_STATUS_DEVICE_OFFLINE;
goto done;
}

/* Check if cable is plugged in or not */
if (vha->device_flags & DFLG_NO_CABLE) {
ql_log(ql_log_warn, vha, 0x70a2,
"Cable is unplugged...\n");
rval = EXT_STATUS_INVALID_CFG;
goto done;
}

/* Check if the switch is connected or not */
if (ha->current_topology != ISP_CFG_F) {
ql_log(ql_log_warn, vha, 0x70a3,
"Host is not connected to the switch\n");
rval = EXT_STATUS_INVALID_CFG;
goto done;
}

/* Check if operating mode is P2P */
if (ha->operating_mode != P2P) {
ql_log(ql_log_warn, vha, 0x70a4,
"Host is operating mode is not P2p\n");
rval = EXT_STATUS_INVALID_CFG;
goto done;
}

thread_id = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];

mutex_lock(&ha->selflogin_lock);
if (vha->self_login_loop_id == 0) {
/* Initialize all required fields of fcport */
vha->bidir_fcport.vha = vha;
vha->bidir_fcport.d_id.b.al_pa = vha->d_id.b.al_pa;
vha->bidir_fcport.d_id.b.area = vha->d_id.b.area;
vha->bidir_fcport.d_id.b.domain = vha->d_id.b.domain;
vha->bidir_fcport.loop_id = vha->loop_id;

if (qla2x00_fabric_login(vha, &(vha->bidir_fcport), &nextlid)) {
ql_log(ql_log_warn, vha, 0x70a7,
"Failed to login port %06X for bidirectional IOCB\n",
vha->bidir_fcport.d_id.b24);
mutex_unlock(&ha->selflogin_lock);
rval = EXT_STATUS_MAILBOX;
goto done;
}
vha->self_login_loop_id = nextlid - 1;

}
/* Assign the self login loop id to fcport */
mutex_unlock(&ha->selflogin_lock);

vha->bidir_fcport.loop_id = vha->self_login_loop_id;

req_sg_cnt = dma_map_sg(&ha->pdev->dev,
bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt,
DMA_TO_DEVICE);

if (!req_sg_cnt) {
rval = EXT_STATUS_NO_MEMORY;
goto done;
}

rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt,
DMA_FROM_DEVICE);

if (!rsp_sg_cnt) {
rval = EXT_STATUS_NO_MEMORY;
goto done_unmap_req_sg;
}

if ((req_sg_cnt != bsg_job->request_payload.sg_cnt) ||
(rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
ql_dbg(ql_dbg_user, vha, 0x70a9,
"Dma mapping resulted in different sg counts "
"[request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt: "
"%x dma_reply_sg_cnt: %x]\n",
bsg_job->request_payload.sg_cnt, req_sg_cnt,
bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
rval = EXT_STATUS_NO_MEMORY;
goto done_unmap_sg;
}

if (req_data_len != rsp_data_len) {
rval = EXT_STATUS_BUSY;
ql_log(ql_log_warn, vha, 0x70aa,
"req_data_len != rsp_data_len\n");
goto done_unmap_sg;
}

req_data_len = bsg_job->request_payload.payload_len;
rsp_data_len = bsg_job->reply_payload.payload_len;


/* Alloc SRB structure */
sp = qla2x00_get_sp(vha, &(vha->bidir_fcport), GFP_KERNEL);
if (!sp) {
ql_dbg(ql_dbg_user, vha, 0x70ac,
"Alloc SRB structure failed\n");
rval = EXT_STATUS_NO_MEMORY;
goto done_unmap_sg;
}

/*Populate srb->ctx with bidir ctx*/
sp->u.bsg_job = bsg_job;
sp->free = qla2x00_bsg_sp_free;
sp->type = SRB_BIDI_CMD;
sp->done = qla2x00_bsg_job_done;

/* Add the read and write sg count */
tot_dsds = rsp_sg_cnt + req_sg_cnt;

rval = qla2x00_start_bidir(sp, vha, tot_dsds);
if (rval != EXT_STATUS_OK)
goto done_free_srb;
/* the bsg request will be completed in the interrupt handler */
return rval;

done_free_srb:
mempool_free(sp, ha->srb_mempool);
done_unmap_sg:
dma_unmap_sg(&ha->pdev->dev,
bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
done_unmap_req_sg:
dma_unmap_sg(&ha->pdev->dev,
bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
done:

/* Return an error vendor specific response
* and complete the bsg request
*/
bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
bsg_job->reply->reply_payload_rcv_len = 0;
bsg_job->reply->result = (DID_OK) << 16;
bsg_job->job_done(bsg_job);
/* Always retrun success, vendor rsp carries correct status */
return 0;
}

static int
qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
{
Expand Down Expand Up @@ -1692,6 +1872,9 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
case QL_VND_READ_I2C:
return qla2x00_read_i2c(bsg_job);

case QL_VND_DIAG_IO_CMD:
return qla24xx_process_bidir_cmd(bsg_job);

default:
bsg_job->reply->result = (DID_ERROR << 16);
bsg_job->job_done(bsg_job);
Expand Down
16 changes: 16 additions & 0 deletions trunk/drivers/scsi/qla2xxx/qla_bsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,31 @@
#define QL_VND_SET_FRU_VERSION 0x0B
#define QL_VND_READ_FRU_STATUS 0x0C
#define QL_VND_WRITE_FRU_STATUS 0x0D
#define QL_VND_DIAG_IO_CMD 0x0A
#define QL_VND_WRITE_I2C 0x10
#define QL_VND_READ_I2C 0x11

/* BSG Vendor specific subcode returns */
#define EXT_STATUS_OK 0
#define EXT_STATUS_ERR 1
#define EXT_STATUS_BUSY 2
#define EXT_STATUS_INVALID_PARAM 6
#define EXT_STATUS_DATA_OVERRUN 7
#define EXT_STATUS_DATA_UNDERRUN 8
#define EXT_STATUS_MAILBOX 11
#define EXT_STATUS_NO_MEMORY 17
#define EXT_STATUS_DEVICE_OFFLINE 22

/*
* To support bidirectional iocb
* BSG Vendor specific returns
*/
#define EXT_STATUS_NOT_SUPPORTED 27
#define EXT_STATUS_INVALID_CFG 28
#define EXT_STATUS_DMA_ERR 29
#define EXT_STATUS_TIMEOUT 30
#define EXT_STATUS_THREAD_FAILED 31
#define EXT_STATUS_DATA_CMP_FAILED 32

/* BSG definations for interpreting CommandSent field */
#define INT_DEF_LB_LOOPBACK_CMD 0
Expand Down
9 changes: 6 additions & 3 deletions trunk/drivers/scsi/qla2xxx/qla_dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,20 @@
* | Mailbox commands | 0x1140 | 0x111a-0x111b |
* | | | 0x112c-0x112e |
* | | | 0x113a |
* | Device Discovery | 0x2086 | 0x2020-0x2022 |
* | Device Discovery | 0x2087 | 0x2020-0x2022 |
* | Queue Command and IO tracing | 0x3030 | 0x3006,0x3008 |
* | | | 0x302d-0x302e |
* | DPC Thread | 0x401c | 0x4002,0x4013 |
* | Async Events | 0x505f | 0x502b-0x502f |
* | | | 0x5047,0x5052 |
* | Timer Routines | 0x6011 | |
* | User Space Interactions | 0x709f | 0x7018,0x702e, |
* | User Space Interactions | 0x70bb | 0x7018,0x702e, |
* | | | 0x7039,0x7045, |
* | | | 0x7073-0x7075, |
* | | | 0x708c |
* | | | 0x708c, |
* | | | 0x70a5,0x70a6, |
* | | | 0x70a8,0x70ab, |
* | | | 0x70ad-0x70ae |
* | Task Management | 0x803c | 0x8025-0x8026 |
* | | | 0x800b,0x8039 |
* | AER/EEH | 0x9011 | |
Expand Down
23 changes: 23 additions & 0 deletions trunk/drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ struct srb_iocb {
#define SRB_ADISC_CMD 6
#define SRB_TM_CMD 7
#define SRB_SCSI_CMD 8
#define SRB_BIDI_CMD 9

typedef struct srb {
atomic_t ref_count;
Expand Down Expand Up @@ -1510,6 +1511,13 @@ typedef struct {
#define CS_RETRY 0x82 /* Driver defined */
#define CS_LOOP_DOWN_ABORT 0x83 /* Driver defined */

#define CS_BIDIR_RD_OVERRUN 0x700
#define CS_BIDIR_RD_WR_OVERRUN 0x707
#define CS_BIDIR_RD_OVERRUN_WR_UNDERRUN 0x715
#define CS_BIDIR_RD_UNDERRUN 0x1500
#define CS_BIDIR_RD_UNDERRUN_WR_OVERRUN 0x1507
#define CS_BIDIR_RD_WR_UNDERRUN 0x1515
#define CS_BIDIR_DMA 0x200
/*
* Status entry status flags
*/
Expand Down Expand Up @@ -2374,6 +2382,11 @@ struct qla_statistics {
uint64_t output_bytes;
};

struct bidi_statistics {
unsigned long long io_count;
unsigned long long transfer_bytes;
};

/* Multi queue support */
#define MBC_INITIALIZE_MULTIQ 0x1f
#define QLA_QUE_PAGE 0X1000
Expand Down Expand Up @@ -2671,6 +2684,7 @@ struct qla_hw_data {
#define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS)
#define IS_CT6_SUPPORTED(ha) ((ha)->device_type & DT_CT6_SUPPORTED)
#define IS_MQUE_CAPABLE(ha) ((ha)->mqenable || IS_QLA83XX(ha))
#define IS_BIDI_CAPABLE(ha) ((IS_QLA25XX(ha) || IS_QLA2031(ha)))

/* HBA serial number */
uint8_t serial0;
Expand Down Expand Up @@ -2754,6 +2768,7 @@ struct qla_hw_data {
struct completion mbx_intr_comp; /* Used for completion notification */
struct completion dcbx_comp; /* For set port config notification */
int notify_dcbx_comp;
struct mutex selflogin_lock;

/* Basic firmware related information. */
uint16_t fw_major_version;
Expand Down Expand Up @@ -2987,6 +3002,13 @@ typedef struct scsi_qla_host {

/* ISP configuration data. */
uint16_t loop_id; /* Host adapter loop id */
uint16_t self_login_loop_id; /* host adapter loop id
* get it on self login
*/
fc_port_t bidir_fcport; /* fcport used for bidir cmnds
* no need of allocating it for
* each command
*/

port_id_t d_id; /* Host adapter port id */
uint8_t marker_needed;
Expand Down Expand Up @@ -3040,6 +3062,7 @@ typedef struct scsi_qla_host {
int seconds_since_last_heartbeat;
struct fc_host_statistics fc_host_stat;
struct qla_statistics qla_stats;
struct bidi_statistics bidi_stats;

atomic_t vref_count;
} scsi_qla_host_t;
Expand Down
Loading

0 comments on commit 9556e74

Please sign in to comment.